summaryrefslogtreecommitdiffstats
path: root/include/orcus/spreadsheet
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:48:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:48:59 +0000
commitc484829272cd13a738e35412498e12f2c9a194ac (patch)
treea1f5ec09629ee895bd3963fa8820b45f2f4c574b /include/orcus/spreadsheet
parentInitial commit. (diff)
downloadliborcus-c484829272cd13a738e35412498e12f2c9a194ac.tar.xz
liborcus-c484829272cd13a738e35412498e12f2c9a194ac.zip
Adding upstream version 0.19.2.upstream/0.19.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/orcus/spreadsheet')
-rw-r--r--include/orcus/spreadsheet/Makefile.am26
-rw-r--r--include/orcus/spreadsheet/Makefile.in680
-rw-r--r--include/orcus/spreadsheet/auto_filter.hpp149
-rw-r--r--include/orcus/spreadsheet/config.hpp37
-rw-r--r--include/orcus/spreadsheet/document.hpp166
-rw-r--r--include/orcus/spreadsheet/document_types.hpp77
-rw-r--r--include/orcus/spreadsheet/export_interface.hpp60
-rw-r--r--include/orcus/spreadsheet/factory.hpp143
-rw-r--r--include/orcus/spreadsheet/import_interface.hpp1332
-rw-r--r--include/orcus/spreadsheet/import_interface_pivot.hpp351
-rw-r--r--include/orcus/spreadsheet/import_interface_styles.hpp774
-rw-r--r--include/orcus/spreadsheet/import_interface_view.hpp78
-rw-r--r--include/orcus/spreadsheet/pivot.hpp254
-rw-r--r--include/orcus/spreadsheet/shared_strings.hpp77
-rw-r--r--include/orcus/spreadsheet/sheet.hpp150
-rw-r--r--include/orcus/spreadsheet/styles.hpp268
-rw-r--r--include/orcus/spreadsheet/types.hpp751
-rw-r--r--include/orcus/spreadsheet/view.hpp65
-rw-r--r--include/orcus/spreadsheet/view_types.hpp95
19 files changed, 5533 insertions, 0 deletions
diff --git a/include/orcus/spreadsheet/Makefile.am b/include/orcus/spreadsheet/Makefile.am
new file mode 100644
index 0000000..b01bce7
--- /dev/null
+++ b/include/orcus/spreadsheet/Makefile.am
@@ -0,0 +1,26 @@
+
+liborcusdir = $(includedir)/liborcus-@ORCUS_API_VERSION@/orcus/spreadsheet
+liborcus_HEADERS = \
+ types.hpp \
+ view_types.hpp \
+ export_interface.hpp \
+ import_interface.hpp \
+ import_interface_pivot.hpp \
+ import_interface_styles.hpp \
+ import_interface_view.hpp
+
+if BUILD_SPREADSHEET_MODEL
+
+liborcus_HEADERS += \
+ auto_filter.hpp \
+ config.hpp \
+ document.hpp \
+ document_types.hpp \
+ factory.hpp \
+ pivot.hpp \
+ shared_strings.hpp \
+ sheet.hpp \
+ styles.hpp \
+ view.hpp
+
+endif
diff --git a/include/orcus/spreadsheet/Makefile.in b/include/orcus/spreadsheet/Makefile.in
new file mode 100644
index 0000000..2331067
--- /dev/null
+++ b/include/orcus/spreadsheet/Makefile.in
@@ -0,0 +1,680 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@BUILD_SPREADSHEET_MODEL_TRUE@am__append_1 = \
+@BUILD_SPREADSHEET_MODEL_TRUE@ auto_filter.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ config.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ document.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ document_types.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ factory.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ pivot.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ shared_strings.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ sheet.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ styles.hpp \
+@BUILD_SPREADSHEET_MODEL_TRUE@ view.hpp
+
+subdir = include/orcus/spreadsheet
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \
+ $(top_srcdir)/m4/boost.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/m4_ax_valgrind_check.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__liborcus_HEADERS_DIST) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__liborcus_HEADERS_DIST = types.hpp view_types.hpp \
+ export_interface.hpp import_interface.hpp \
+ import_interface_pivot.hpp import_interface_styles.hpp \
+ import_interface_view.hpp auto_filter.hpp config.hpp \
+ document.hpp document_types.hpp factory.hpp pivot.hpp \
+ shared_strings.hpp sheet.hpp styles.hpp view.hpp
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(liborcusdir)"
+HEADERS = $(liborcus_HEADERS)
+am__extra_recursive_targets = check-valgrind-recursive \
+ check-valgrind-memcheck-recursive \
+ check-valgrind-helgrind-recursive check-valgrind-drd-recursive \
+ check-valgrind-sgcheck-recursive
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
+BOOST_DATE_TIME_LDFLAGS = @BOOST_DATE_TIME_LDFLAGS@
+BOOST_DATE_TIME_LDPATH = @BOOST_DATE_TIME_LDPATH@
+BOOST_DATE_TIME_LIBS = @BOOST_DATE_TIME_LIBS@
+BOOST_FILESYSTEM_LDFLAGS = @BOOST_FILESYSTEM_LDFLAGS@
+BOOST_FILESYSTEM_LDPATH = @BOOST_FILESYSTEM_LDPATH@
+BOOST_FILESYSTEM_LIBS = @BOOST_FILESYSTEM_LIBS@
+BOOST_IOSTREAMS_LDFLAGS = @BOOST_IOSTREAMS_LDFLAGS@
+BOOST_IOSTREAMS_LDPATH = @BOOST_IOSTREAMS_LDPATH@
+BOOST_IOSTREAMS_LIBS = @BOOST_IOSTREAMS_LIBS@
+BOOST_LDPATH = @BOOST_LDPATH@
+BOOST_PROGRAM_OPTIONS_LDFLAGS = @BOOST_PROGRAM_OPTIONS_LDFLAGS@
+BOOST_PROGRAM_OPTIONS_LDPATH = @BOOST_PROGRAM_OPTIONS_LDPATH@
+BOOST_PROGRAM_OPTIONS_LIBS = @BOOST_PROGRAM_OPTIONS_LIBS@
+BOOST_ROOT = @BOOST_ROOT@
+BOOST_SYSTEM_LDFLAGS = @BOOST_SYSTEM_LDFLAGS@
+BOOST_SYSTEM_LDPATH = @BOOST_SYSTEM_LDPATH@
+BOOST_SYSTEM_LIBS = @BOOST_SYSTEM_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_VALGRIND_drd = @ENABLE_VALGRIND_drd@
+ENABLE_VALGRIND_helgrind = @ENABLE_VALGRIND_helgrind@
+ENABLE_VALGRIND_memcheck = @ENABLE_VALGRIND_memcheck@
+ENABLE_VALGRIND_sgcheck = @ENABLE_VALGRIND_sgcheck@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HAVE_CXX17 = @HAVE_CXX17@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IXION_REQUIRED_API_VERSION = @IXION_REQUIRED_API_VERSION@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBIXION_CFLAGS = @LIBIXION_CFLAGS@
+LIBIXION_LIBS = @LIBIXION_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MDDS_CFLAGS = @MDDS_CFLAGS@
+MDDS_LIBS = @MDDS_LIBS@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+ORCUS_API_VERSION = @ORCUS_API_VERSION@
+ORCUS_MAJOR_VERSION = @ORCUS_MAJOR_VERSION@
+ORCUS_MICRO_VERSION = @ORCUS_MICRO_VERSION@
+ORCUS_MINOR_VERSION = @ORCUS_MINOR_VERSION@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PARQUET_CFLAGS = @PARQUET_CFLAGS@
+PARQUET_LIBS = @PARQUET_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POW_LIB = @POW_LIB@
+PYTHON = @PYTHON@
+PYTHON_CFLAGS = @PYTHON_CFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_LIBS = @PYTHON_LIBS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VALGRIND = @VALGRIND@
+VALGRIND_ENABLED = @VALGRIND_ENABLED@
+VERSION = @VERSION@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+valgrind_enabled_tools = @valgrind_enabled_tools@
+valgrind_tools = @valgrind_tools@
+liborcusdir = $(includedir)/liborcus-@ORCUS_API_VERSION@/orcus/spreadsheet
+liborcus_HEADERS = types.hpp view_types.hpp export_interface.hpp \
+ import_interface.hpp import_interface_pivot.hpp \
+ import_interface_styles.hpp import_interface_view.hpp \
+ $(am__append_1)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/orcus/spreadsheet/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign include/orcus/spreadsheet/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-liborcusHEADERS: $(liborcus_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(liborcus_HEADERS)'; test -n "$(liborcusdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(liborcusdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(liborcusdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(liborcusdir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(liborcusdir)" || exit $$?; \
+ done
+
+uninstall-liborcusHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(liborcus_HEADERS)'; test -n "$(liborcusdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(liborcusdir)'; $(am__uninstall_files_from_dir)
+check-valgrind-local:
+check-valgrind-memcheck-local:
+check-valgrind-helgrind-local:
+check-valgrind-drd-local:
+check-valgrind-sgcheck-local:
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(liborcusdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+check-valgrind: check-valgrind-am
+
+check-valgrind-am: check-valgrind-local
+
+check-valgrind-drd: check-valgrind-drd-am
+
+check-valgrind-drd-am: check-valgrind-drd-local
+
+check-valgrind-helgrind: check-valgrind-helgrind-am
+
+check-valgrind-helgrind-am: check-valgrind-helgrind-local
+
+check-valgrind-memcheck: check-valgrind-memcheck-am
+
+check-valgrind-memcheck-am: check-valgrind-memcheck-local
+
+check-valgrind-sgcheck: check-valgrind-sgcheck-am
+
+check-valgrind-sgcheck-am: check-valgrind-sgcheck-local
+
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-liborcusHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-liborcusHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-valgrind-am \
+ check-valgrind-drd-am check-valgrind-drd-local \
+ check-valgrind-helgrind-am check-valgrind-helgrind-local \
+ check-valgrind-local check-valgrind-memcheck-am \
+ check-valgrind-memcheck-local check-valgrind-sgcheck-am \
+ check-valgrind-sgcheck-local clean clean-generic clean-libtool \
+ cscopelist-am ctags ctags-am distclean distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-liborcusHEADERS install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-liborcusHEADERS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/include/orcus/spreadsheet/auto_filter.hpp b/include/orcus/spreadsheet/auto_filter.hpp
new file mode 100644
index 0000000..b6f2959
--- /dev/null
+++ b/include/orcus/spreadsheet/auto_filter.hpp
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_AUTO_FILTER_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_AUTO_FILTER_HPP
+
+#include "types.hpp"
+#include "../env.hpp"
+
+#include <map>
+#include <unordered_set>
+
+#include <ixion/address.hpp>
+
+namespace orcus { namespace spreadsheet {
+
+/**
+ * Data for a single column inside autofilter range.
+ */
+struct ORCUS_SPM_DLLPUBLIC auto_filter_column_t
+{
+ using match_values_type = std::unordered_set<std::string_view>;
+ match_values_type match_values;
+
+ auto_filter_column_t();
+ auto_filter_column_t(const auto_filter_column_t& other);
+ auto_filter_column_t(auto_filter_column_t&& other);
+ ~auto_filter_column_t();
+
+ auto_filter_column_t& operator=(const auto_filter_column_t& other);
+ auto_filter_column_t& operator=(auto_filter_column_t&& other);
+
+ void reset();
+ void swap(auto_filter_column_t& r);
+};
+
+/**
+ * Data for a single autofilter entry. An autofilter can belong to either a
+ * sheet or a table.
+ */
+struct ORCUS_SPM_DLLPUBLIC auto_filter_t
+{
+ typedef std::map<col_t, auto_filter_column_t> columns_type;
+
+ ixion::abs_range_t range;
+
+ columns_type columns;
+
+ auto_filter_t();
+ auto_filter_t(const auto_filter_t& other);
+ auto_filter_t(auto_filter_t&& other);
+ ~auto_filter_t();
+
+ auto_filter_t& operator=(const auto_filter_t& other);
+ auto_filter_t& operator=(auto_filter_t&& other);
+
+ void reset();
+ void swap(auto_filter_t& r);
+
+ /**
+ * Set column data to specified column index.
+ *
+ * @param col column index to associate the data to.
+ * @param data column data.
+ */
+ void commit_column(col_t col, auto_filter_column_t data);
+};
+
+/**
+ * Single column entry in table.
+ */
+struct ORCUS_SPM_DLLPUBLIC table_column_t
+{
+ std::size_t identifier;
+ std::string_view name;
+ std::string_view totals_row_label;
+ totals_row_function_t totals_row_function;
+
+ table_column_t();
+ table_column_t(const table_column_t& other);
+ ~table_column_t();
+
+ table_column_t& operator=(const table_column_t& other);
+
+ void reset();
+};
+
+/**
+ * Table style information.
+ */
+struct ORCUS_SPM_DLLPUBLIC table_style_t
+{
+ std::string_view name;
+
+ bool show_first_column:1;
+ bool show_last_column:1;
+ bool show_row_stripes:1;
+ bool show_column_stripes:1;
+
+ table_style_t();
+ table_style_t(const table_style_t& other);
+ ~table_style_t();
+
+ table_style_t& operator=(const table_style_t& other);
+
+ void reset();
+};
+
+/**
+ * Single table entry. A table is a range in a spreadsheet that represents
+ * a single set of data that can be used as a data source.
+ */
+struct ORCUS_SPM_DLLPUBLIC table_t
+{
+ typedef std::vector<table_column_t> columns_type;
+
+ size_t identifier;
+
+ std::string_view name;
+ std::string_view display_name;
+
+ ixion::abs_range_t range;
+
+ size_t totals_row_count;
+
+ auto_filter_t filter;
+ columns_type columns;
+ table_style_t style;
+
+ table_t();
+ table_t(const table_t& other);
+ table_t(table_t&& other);
+ ~table_t();
+
+ table_t& operator=(const table_t& other);
+ table_t& operator=(table_t&& other);
+
+ void reset();
+};
+
+}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/config.hpp b/include/orcus/spreadsheet/config.hpp
new file mode 100644
index 0000000..11eebfc
--- /dev/null
+++ b/include/orcus/spreadsheet/config.hpp
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_CONFIG_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_CONFIG_HPP
+
+#include "orcus/env.hpp"
+
+#include <cstdint>
+
+namespace orcus { namespace spreadsheet {
+
+struct ORCUS_SPM_DLLPUBLIC document_config
+{
+ /**
+ * Precision to use when converting numeric values to their string
+ * representations. A negative value indicates the precision is not being
+ * specified.
+ */
+ int8_t output_precision;
+
+ document_config();
+ document_config(const document_config& r);
+ ~document_config();
+
+ document_config& operator= (const document_config& r);
+};
+
+}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/document.hpp b/include/orcus/spreadsheet/document.hpp
new file mode 100644
index 0000000..4f20b6e
--- /dev/null
+++ b/include/orcus/spreadsheet/document.hpp
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_DOCUMENT_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_DOCUMENT_HPP
+
+#include "orcus/env.hpp"
+#include "orcus/interface.hpp"
+#include "orcus/spreadsheet/types.hpp"
+
+#include <ostream>
+#include <memory>
+
+namespace ixion {
+
+class formula_name_resolver;
+class model_context;
+struct abs_address_t;
+
+}
+
+namespace orcus {
+
+class string_pool;
+struct date_time_t;
+
+namespace spreadsheet {
+
+class shared_strings;
+class styles;
+class pivot_collection;
+class sheet;
+class import_factory;
+
+struct document_config;
+struct table_t;
+
+namespace detail {
+
+struct document_impl;
+
+}
+
+/**
+ * Store spreadsheet document content. It uses the @p model_context class
+ * from the ixion library to store raw cell values required in the computation
+ * of formula expressions.
+ */
+class ORCUS_SPM_DLLPUBLIC document : public orcus::iface::document_dumper
+{
+ friend class sheet;
+ friend class import_factory;
+
+public:
+ document(const document&) = delete;
+ document& operator= (const document&) = delete;
+
+ document(const range_size_t& sheet_size);
+ ~document();
+
+ /** See @ref iface::document_dumper. */
+ virtual void dump(dump_format_t format, const std::string& output) const override;
+
+ /** See @ref iface::document_dumper. */
+ virtual void dump_check(std::ostream& os) const override;
+
+ shared_strings& get_shared_strings();
+ const shared_strings& get_shared_strings() const;
+
+ styles& get_styles();
+ const styles& get_styles() const;
+
+ pivot_collection& get_pivot_collection();
+ const pivot_collection& get_pivot_collection() const;
+
+ sheet* append_sheet(std::string_view sheet_name);
+ sheet* get_sheet(std::string_view sheet_name);
+ const sheet* get_sheet(std::string_view sheet_name) const;
+ sheet* get_sheet(sheet_t sheet_pos);
+ const sheet* get_sheet(sheet_t sheet_pos) const;
+
+ /**
+ * Clear document content, to make it empty.
+ */
+ void clear();
+
+ /**
+ * Calculate those formula cells that have been newly inserted and have
+ * not yet been calculated.
+ */
+ void recalc_formula_cells();
+
+ sheet_t get_sheet_index(std::string_view name) const;
+ std::string_view get_sheet_name(sheet_t sheet_pos) const;
+
+ /**
+ * Set a new name to a sheet.
+ *
+ * @param sheet_pos 0-based position of a sheet.
+ * @param name New name to set to a sheet.
+ */
+ void set_sheet_name(sheet_t sheet_pos, std::string name);
+
+ range_size_t get_sheet_size() const;
+ void set_sheet_size(const range_size_t& sheet_size);
+ size_t get_sheet_count() const;
+
+ void set_origin_date(int year, int month, int day);
+ date_time_t get_origin_date() const;
+
+ void set_formula_grammar(formula_grammar_t grammar);
+ formula_grammar_t get_formula_grammar() const;
+
+ const ixion::formula_name_resolver* get_formula_name_resolver(formula_ref_context_t cxt) const;
+
+ ixion::model_context& get_model_context();
+ const ixion::model_context& get_model_context() const;
+
+ const document_config& get_config() const;
+ void set_config(const document_config& cfg);
+
+ string_pool& get_string_pool();
+ const string_pool& get_string_pool() const;
+
+ /**
+ * Insert a new table object into the document. The document will take
+ * ownership of the inserted object after the call. The object will get
+ * inserted only when there is no pre-existing table object of the same
+ * name. The object not being inserted will be deleted.
+ *
+ * @param p table object to insert.
+ */
+ void insert_table(table_t* p);
+
+ /**
+ * Get a structure containing properties of a named table.
+ *
+ * @param name Name of the table.
+ *
+ * @return Pointer to the structure containing the properties of a named
+ * table, or @p nullptr if no such table exists for the given name.
+ */
+ const table_t* get_table(std::string_view name) const;
+
+private:
+ void dump_flat(const std::string& outdir) const;
+ void dump_html(const ::std::string& outdir) const;
+ void dump_json(const ::std::string& outdir) const;
+ void dump_csv(const std::string& outdir) const;
+ void dump_debug_state(const std::string& outdir) const;
+
+ void finalize_import();
+ void insert_dirty_cell(const ixion::abs_address_t& pos);
+
+private:
+ std::unique_ptr<detail::document_impl> mp_impl;
+};
+
+}}
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/document_types.hpp b/include/orcus/spreadsheet/document_types.hpp
new file mode 100644
index 0000000..b1a864f
--- /dev/null
+++ b/include/orcus/spreadsheet/document_types.hpp
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include "types.hpp"
+#include <vector>
+
+namespace orcus { namespace spreadsheet {
+
+/**
+ * Stores a color value in ARGB format. Each color component ranges from 0 to
+ * 255 (8-bit).
+ */
+struct ORCUS_SPM_DLLPUBLIC color_t
+{
+ color_elem_t alpha;
+ color_elem_t red;
+ color_elem_t green;
+ color_elem_t blue;
+
+ color_t();
+ color_t(color_elem_t _red, color_elem_t _green, color_elem_t _blue);
+ color_t(color_elem_t _alpha, color_elem_t _red, color_elem_t _green, color_elem_t _blue);
+
+ void reset();
+
+ bool operator==(const color_t& other) const;
+ bool operator!=(const color_t& other) const;
+};
+
+/**
+ * Contains formatting properties of a section of a string. This is used in
+ * the stroage of rich-text strings.
+ */
+struct ORCUS_SPM_DLLPUBLIC format_run
+{
+ /** Position of the section where the formatting starts. */
+ std::size_t pos;
+ /** Length of the section. */
+ std::size_t size;
+ /** Name of the font. */
+ std::string_view font;
+ /** Size of the font. */
+ double font_size;
+ /** Color of the section. */
+ color_t color;
+ /** Whether or not the font is bold. */
+ bool bold:1;
+ /** Whether or not the font is italic. */
+ bool italic:1;
+
+ format_run();
+
+ /**
+ * Reset the properties to unformatted state.
+ */
+ void reset();
+
+ /**
+ * Query whether or not the section contains non-default format properties.
+ *
+ * @return @p true of it's formatted, otherwise @p false.
+ */
+ bool formatted() const;
+};
+
+/** Collection of format properties of a string. */
+using format_runs_t = std::vector<format_run>;
+
+}} // namespace orcus::spreadsheet
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/export_interface.hpp b/include/orcus/spreadsheet/export_interface.hpp
new file mode 100644
index 0000000..3c3104d
--- /dev/null
+++ b/include/orcus/spreadsheet/export_interface.hpp
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_EXPORT_INTERFACE_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_EXPORT_INTERFACE_HPP
+
+#include "types.hpp"
+#include "../env.hpp"
+
+#include <ostream>
+
+namespace orcus { namespace spreadsheet { namespace iface {
+
+/**
+ * Interface for exporting sheet contents.
+ */
+class export_sheet
+{
+public:
+ ORCUS_DLLPUBLIC virtual ~export_sheet() = 0;
+
+ /**
+ * Write the content of a cell to an output stream.
+ *
+ * @param os output stream to write the cell content to.
+ * @param row 0-based row position of a cell.
+ * @param col 0-based column position of a cell.
+ */
+ virtual void write_string(std::ostream& os, orcus::spreadsheet::row_t row, orcus::spreadsheet::col_t col) const = 0;
+};
+
+/**
+ * Entry-point interface for exporting document contents.
+ */
+class export_factory
+{
+public:
+ ORCUS_DLLPUBLIC virtual ~export_factory() = 0;
+
+ /**
+ * Obtain an interface for exporting sheet content.
+ *
+ * @param sheet_name name of the sheet to export.
+ *
+ * @return pointer to an interface for exporting sheet content.
+ */
+ virtual const export_sheet* get_sheet(std::string_view sheet_name) const = 0;
+};
+
+}}}
+
+
+
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/factory.hpp b/include/orcus/spreadsheet/factory.hpp
new file mode 100644
index 0000000..e1423fa
--- /dev/null
+++ b/include/orcus/spreadsheet/factory.hpp
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_IMPORT_FACTORY_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_IMPORT_FACTORY_HPP
+
+#include <orcus/spreadsheet/import_interface.hpp>
+#include <orcus/spreadsheet/import_interface_styles.hpp>
+#include <orcus/spreadsheet/export_interface.hpp>
+#include <orcus/env.hpp>
+
+#include <memory>
+
+namespace orcus {
+
+class string_pool;
+
+namespace spreadsheet {
+
+class document;
+class view;
+class styles;
+
+struct ORCUS_SPM_DLLPUBLIC import_factory_config
+{
+ /**
+ * When the font cache is enabled, the import factory checks each incoming
+ * font entry against the pool of existing font entries and insert it only
+ * when an equal entry doesn't already exist in the pool.
+ *
+ * @note It should not be enabled for a file format that already has
+ * font entries normalized, such as xlsx.
+ */
+ bool enable_font_cache = true;
+
+ import_factory_config();
+ import_factory_config(const import_factory_config& other);
+ ~import_factory_config();
+
+ import_factory_config& operator=(const import_factory_config& other);
+};
+
+/**
+ * Wraps @ref document and @ref view stores. This is to be used by the import
+ * filter to populate the document and view stores.
+ */
+class ORCUS_SPM_DLLPUBLIC import_factory : public iface::import_factory
+{
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+public:
+ import_factory(document& doc);
+ import_factory(document& doc, view& view_store);
+ virtual ~import_factory();
+
+ virtual iface::import_global_settings* get_global_settings() override;
+ virtual iface::import_shared_strings* get_shared_strings() override;
+ virtual iface::import_styles* get_styles() override;
+ virtual iface::import_named_expression* get_named_expression() override;
+ virtual iface::import_reference_resolver* get_reference_resolver(formula_ref_context_t cxt) override;
+ virtual iface::import_pivot_cache_definition* create_pivot_cache_definition(
+ orcus::spreadsheet::pivot_cache_id_t cache_id) override;
+ virtual iface::import_pivot_cache_records* create_pivot_cache_records(
+ orcus::spreadsheet::pivot_cache_id_t cache_id) override;
+ virtual iface::import_sheet* append_sheet(sheet_t sheet_index, std::string_view name) override;
+ virtual iface::import_sheet* get_sheet(std::string_view name) override;
+ virtual iface::import_sheet* get_sheet(sheet_t sheet_index) override;
+ virtual void finalize() override;
+
+ void set_config(const import_factory_config& config);
+
+ void set_default_row_size(row_t row_size);
+ void set_default_column_size(col_t col_size);
+
+ void set_character_set(character_set_t charset);
+ character_set_t get_character_set() const;
+
+ /**
+ * When setting this flag to true, those formula cells with no cached
+ * results will be re-calculated upon loading.
+ *
+ *
+ * @param b value of this flag.
+ */
+ void set_recalc_formula_cells(bool b);
+
+ void set_formula_error_policy(formula_error_policy_t policy);
+};
+
+/**
+ * Wraps @ref styles store. This is to be used by an import styles parser to
+ * populate the styles store.
+ */
+class ORCUS_SPM_DLLPUBLIC import_styles : public iface::import_styles
+{
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+public:
+ import_styles(styles& styles_store, string_pool& sp);
+ import_styles(std::shared_ptr<import_factory_config> config, styles& styles_store, string_pool& sp);
+ virtual ~import_styles() override;
+
+ virtual iface::import_font_style* start_font_style() override;
+ virtual iface::import_fill_style* start_fill_style() override;
+ virtual iface::import_border_style* start_border_style() override;
+ virtual iface::import_cell_protection* start_cell_protection() override;
+ virtual iface::import_number_format* start_number_format() override;
+ virtual iface::import_xf* start_xf(xf_category_t cat) override;
+ virtual iface::import_cell_style* start_cell_style() override;
+
+ virtual void set_font_count(size_t n) override;
+ virtual void set_fill_count(size_t n) override;
+ virtual void set_border_count(size_t n) override;
+ virtual void set_number_format_count(size_t n) override;
+ virtual void set_xf_count(xf_category_t cat, size_t n) override;
+ virtual void set_cell_style_count(size_t n) override;
+};
+
+/**
+ * Wraps @ref document store and faciliates export of its content.
+ *
+ * @warning It currently provides very limited functionality especially when
+ * compared to that of the @ref import_factory.
+ */
+class ORCUS_SPM_DLLPUBLIC export_factory : public iface::export_factory
+{
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+public:
+ export_factory(const document& doc);
+ virtual ~export_factory();
+
+ virtual const iface::export_sheet* get_sheet(std::string_view sheet_name) const override;
+};
+
+}}
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/import_interface.hpp b/include/orcus/spreadsheet/import_interface.hpp
new file mode 100644
index 0000000..2ba80a7
--- /dev/null
+++ b/include/orcus/spreadsheet/import_interface.hpp
@@ -0,0 +1,1332 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef ORCUS_SPREADSHEET_IMPORT_INTERFACE_HPP
+#define ORCUS_SPREADSHEET_IMPORT_INTERFACE_HPP
+
+#include <cstdlib>
+
+#include "types.hpp"
+#include "../types.hpp"
+#include "../env.hpp"
+
+// NB: This header must not depend on ixion, as it needs to be usable for
+// those clients that provide their own formula engine. Other headers in
+// the orcus::spreadsheet namespace may depend on ixion.
+
+namespace orcus { namespace spreadsheet { namespace iface {
+
+class import_styles;
+class import_pivot_cache_definition;
+class import_pivot_cache_records;
+class import_sheet_view;
+
+/**
+ * Interface for importing raw string values shared in string cells. String
+ * values may be either with or without formatted segments.
+ *
+ * To insert an unformatted string, simply use either append() or add()
+ * method. The string will then be immediately pushed to the pool.
+ *
+ * To insert a string with mixed formatted segments, you need to first use one
+ * or more of:
+ *
+ * @li set_segment_font()
+ * @li set_segment_bold()
+ * @li set_segment_italic()
+ * @li set_segment_font_name()
+ * @li set_segment_font_size()
+ * @li set_segment_font_color()
+ *
+ * to define the format attribute(s) of a string segment followed by a call to
+ * append_segment(). This may be repeated as many times as necessary. Then
+ * as the final step, call commit_segments() to insert the entire series of
+ * formatted segments to the pool as a single string entry. The following
+ * example demonstrates how the code may look like:
+ *
+ * @code{.cpp}
+ * import_shared_strings* iface = ...;
+ *
+ * // store a segment with specific font, size and boldness.
+ * iface->set_segment_font_name("FreeMono");
+ * iface->set_segment_font_size(14);
+ * iface->set_segment_font_bold(true);
+ * iface->append_segment("a bold and big segment");
+ *
+ * // store an unformatted segment.
+ * iface->append_segment(" followed by ");
+ *
+ * // store a segment with smaller, italic font.
+ * iface->set_segment_font_size(7);
+ * iface->set_segment_font_italic(true);
+ * iface->append_segment("a small and italic segment");
+ *
+ * iface->commit_segments(); // commit the whole formatted string to the pool.
+ * @endcode
+ */
+class ORCUS_DLLPUBLIC import_shared_strings
+{
+public:
+ virtual ~import_shared_strings();
+
+ /**
+ * Append a new string to the sequence of strings. Order of insertion
+ * determines the numerical ID value of an inserted string. Note that this
+ * method assumes that the caller knows the string being appended is not yet
+ * in the pool; it does not check on duplicated strings.
+ *
+ * @param s string to append to the pool.
+ *
+ * @return ID of the inserted string.
+ */
+ virtual size_t append(std::string_view s) = 0;
+
+ /**
+ * Similar to the append() method, it adds a new string to the string pool;
+ * however, this method checks if the string being added is already in the
+ * pool before each insertion, to avoid duplicated strings.
+ *
+ * @param s string to add to the pool.
+ *
+ * @return ID of the inserted string.
+ */
+ virtual size_t add(std::string_view s) = 0;
+
+ /**
+ * Set the index of a font to apply to the current format attributes. Refer
+ * to the import_font_style interface on how to obtain a font index. Note
+ * that a single font index is associated with multiple font-related
+ * formatting attributes, such as font name, font color, boldness and
+ * italics.
+ *
+ * @param font_index positive integer representing the font to use.
+ */
+ virtual void set_segment_font(size_t font_index) = 0;
+
+ /**
+ * Set whether or not to make the current segment bold.
+ *
+ * @param b true if it's bold, false otherwise.
+ */
+ virtual void set_segment_bold(bool b) = 0;
+
+ /**
+ * Set whether or not to make the current segment italic.
+ *
+ * @param b true if it's italic, false otherwise.
+ */
+ virtual void set_segment_italic(bool b) = 0;
+
+ /**
+ * Set the name of a font to the current segment.
+ *
+ * @param s font name.
+ */
+ virtual void set_segment_font_name(std::string_view s) = 0;
+
+ /**
+ * Set a font size to the current segment.
+ *
+ * @param point font size in points.
+ */
+ virtual void set_segment_font_size(double point) = 0;
+
+ /**
+ * Set the color of a font in ARGB format to the current segment.
+ *
+ * @param alpha alpha component value (0-255).
+ * @param red red component value (0-255).
+ * @param green green component value (0-255).
+ * @param blue blue component value (0-255).
+ */
+ virtual void set_segment_font_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Push the current string segment to the buffer. Any formatting attributes
+ * defined so far will be applied to this segment.
+ *
+ * @param s string value for the segment.
+ */
+ virtual void append_segment(std::string_view s) = 0;
+
+ /**
+ * Store the entire formatted string in the current buffer to the shared
+ * strings pool. The implementor may choose to unconditionally append the
+ * string to the pool, or choose to find an existing duplicate and reuse
+ * it instead.
+ *
+ * @return ID of the string just inserted, or the ID of an existing string
+ * with identical formatting.
+ */
+ virtual size_t commit_segments() = 0;
+};
+
+/**
+ * Interface for importing sheet properties. Sheet properties include:
+ *
+ * @li column widths and row heights,
+ * @li hidden flags for columns and rows, and
+ * @li merged cell ranges.
+ *
+ * These properties are independent of the cell contents of a sheet.
+ */
+class ORCUS_DLLPUBLIC import_sheet_properties
+{
+public:
+ virtual ~import_sheet_properties();
+
+ /**
+ * Set a column width to one or more columns.
+ *
+ * @param col 0-based position of the first column.
+ * @param col_span number of contiguous columns to apply the width to.
+ * @param width column width to apply.
+ * @param unit unit of measurement to use for the width value.
+ */
+ virtual void set_column_width(col_t col, col_t col_span, double width, orcus::length_unit_t unit) = 0;
+
+ /**
+ * Set a column hidden flag to one or more columns.
+ *
+ * @param col 0-based position of the first column.
+ * @param col_span number of contiguous columns to apply the flag to.
+ * @param hidden flag indicating whether or not the columns are hidden.
+ */
+ virtual void set_column_hidden(col_t col, col_t col_span, bool hidden) = 0;
+
+ /**
+ * Set a row height to specified row.
+ *
+ * @param row 0-based position of a row.
+ * @param height new row height value to set.
+ * @param unit unit of the new row height value.
+ *
+ * @todo Convert this to take a raw span.
+ */
+ virtual void set_row_height(row_t row, double height, orcus::length_unit_t unit) = 0;
+
+ /**
+ * Set a row hidden flag to a specified row.
+ *
+ * @param row 0-based position of a row.
+ * @param hidden flag indicating whether or not the row is hidden.
+ *
+ * @todo Convert this to take a raw span.
+ */
+ virtual void set_row_hidden(row_t row, bool hidden) = 0;
+
+ /**
+ * Set a merged cell range.
+ *
+ * @param range structure containing the top-left and bottom-right
+ * positions of a merged cell range.
+ */
+ virtual void set_merge_cell_range(const range_t& range) = 0;
+};
+
+/**
+ * Interface for importing named expressions or ranges.
+ *
+ * This interface has two different methods for defining named expressions:
+ *
+ * @li set_named_expression() and
+ * @li set_named_range().
+ *
+ * Generally speaking, set_named_expression() can be used to define both named
+ * expression and named range. However, the implementor may choose to apply a
+ * different syntax rule to parse an expression passed to set_named_range(),
+ * depending on the formula grammar defined via @ref
+ * import_global_settings::set_default_formula_grammar(). For instance, the
+ * OpenDocument Spreadsheet format is known to use different syntax rules
+ * between named expressions and named ranges.
+ *
+ * A named range is a special case of a named expression where the expression
+ * consists of only one single cell range token.
+ *
+ * Here is a code example of how a named expression is defined:
+ *
+ * @code{.cpp}
+ * import_named_expression* iface = ...;
+ *
+ * // set the A1 on the first sheet as its origin (optional).
+ * src_address_t origin{0, 0, 0};
+ * iface->set_base_position(origin);
+ * iface->set_named_expression("MyExpression", "SUM(A1:B10)+SUM(D1:D4)");
+ * iface->commit();
+ * @endcode
+ *
+ * Replace the above set_named_expression() call with set_named_range() if you
+ * wish to define a named range instead.
+ */
+class ORCUS_DLLPUBLIC import_named_expression
+{
+public:
+ virtual ~import_named_expression();
+
+ /**
+ * Specify an optional base position, or origin, from which to evaluate a
+ * named expression. If not specified, the implementor should use the
+ * top-left corner cell on the first sheet as its origin.
+ *
+ * @param pos cell position to be used as the origin.
+ */
+ virtual void set_base_position(const src_address_t& pos) = 0;
+
+ /**
+ * Set a named expression to the buffer.
+ *
+ * @param name name of the expression to be defined.
+ * @param expression expression to be associated with the name.
+ */
+ virtual void set_named_expression(std::string_view name, std::string_view expression) = 0;
+
+ /**
+ * Set a named range to the buffer.
+ *
+ * @param name name of the expression to be defined.
+ * @param range range to be associated with the name.
+ */
+ virtual void set_named_range(std::string_view name, std::string_view range) = 0;
+
+ /**
+ * Commit the named expression or range currently in the buffer to the
+ * document.
+ */
+ virtual void commit() = 0;
+};
+
+/**
+ * Interface for importing data tables.
+ */
+class ORCUS_DLLPUBLIC import_data_table
+{
+public:
+ virtual ~import_data_table();
+
+ /**
+ * Set the type of a data table. A data table can either:
+ *
+ * @li be a single-variable column-oriented,
+ * @li be a single-variable row-oriented, or
+ * @li use two variables that use both column and row.
+ *
+ * @param type type of a data table.
+ */
+ virtual void set_type(data_table_type_t type) = 0;
+
+ /**
+ * Set the range of a data table.
+ *
+ * @param range range of a data table.
+ */
+ virtual void set_range(const range_t& range) = 0;
+
+ /**
+ * Set the reference of the first input cell.
+ *
+ * @param ref reference of the first input cell.
+ * @param deleted whether or not this input cell has been deleted.
+ */
+ virtual void set_first_reference(std::string_view ref, bool deleted) = 0;
+
+ /**
+ * Set the reference of the second input cell but only if the data table
+ * uses two variables.
+ *
+ * @note This method gets called only if the data table uses two variables.
+ *
+ * @param ref reference of the second input cell.
+ * @param deleted whether or not this input cell has been deleted.
+ */
+ virtual void set_second_reference(std::string_view ref, bool deleted) = 0;
+
+ /**
+ * Store the current data table data in the buffer to the backend sheet
+ * storage.
+ */
+ virtual void commit() = 0;
+};
+
+/**
+ * Interface for importing auto filters.
+ *
+ * Importing a single auto filter would roughly follow the following flow:
+ *
+ * @code{.cpp}
+ * import_auto_filter* iface = ... ;
+ *
+ * range_t range;
+ * range.first.column = 0;
+ * range.first.row = 0;
+ * range.last.column = 3;
+ * range.last.row = 1000;
+ * iface->set_range(range); // Auto filter is applied for A1:D1001.
+ *
+ * // Column A is filtered for a value of "A".
+ * iface->set_column(0);
+ * iface->append_column_match_value("A");
+ * iface->commit_column();
+ *
+ * // Column D is filtered for values of 1 and 4.
+ * iface->set_column(3);
+ * iface->append_column_match_value("1");
+ * iface->append_column_match_value("4");
+ * iface->commit_column();
+ *
+ * // Push the autofilter data in the current buffer to the sheet store.
+ * iface->commit();
+ * @endcode
+ */
+class ORCUS_DLLPUBLIC import_auto_filter
+{
+public:
+ virtual ~import_auto_filter();
+
+ /**
+ * Specify the range where the auto filter is applied.
+ *
+ * @param range structure containing the top-left and bottom-right
+ * positions of the auto filter range.
+ */
+ virtual void set_range(const range_t& range) = 0;
+
+ /**
+ * Specify the column position of a filter. The position is relative to
+ * the first column in the auto filter range. This method gets called at
+ * the beginning of each column filter data. The implementor may initialize
+ * the column filter data buffer when this method is called.
+ *
+ * @note This column position is relative to the first column in the
+ * autofilter range.
+ *
+ * @param col 0-based column position of a filter relative to the first
+ * column of the auto filter range.
+ */
+ virtual void set_column(col_t col) = 0;
+
+ /**
+ * Append a match value to the current column filter. A single column
+ * filter may have one or more match values.
+ *
+ * @param value match value to append to the current column filter.
+ */
+ virtual void append_column_match_value(std::string_view value) = 0;
+
+ /**
+ * Commit the current column filter data to the current auto filter buffer.
+ * The implementor may clear the current column filter buffer after this
+ * call.
+ */
+ virtual void commit_column() = 0;
+
+ /**
+ * Commit current auto filter data stored in the buffer to the sheet store.
+ */
+ virtual void commit() = 0;
+};
+
+/**
+ * This is an optional interface to import conditional formatting.
+ *
+ * In general, a single conditional format consists of:
+ *
+ * @li a cell range the format is applied to, and
+ * @li one or more rule entries.
+ *
+ * Each rule entry consists of:
+ *
+ * @li a type of rule,
+ * @li zero or more rule properties, and
+ * @li zero or more conditions depending on the rule type.
+ *
+ * Lastly, each condition consists of:
+ *
+ * @li a formula, value, or string,
+ * @li an optional color.
+ *
+ * The flow of the import process varies depending on the type of the
+ * conditional formatting being imported. The following is an example of
+ * importing a conditional formatting that consists of a rule that applies a
+ * format when the cell value is greather than 2:
+ *
+ * @code{.cpp}
+ * import_conditional_format* iface = ... ;
+ *
+ * iface->set_range("A2:A13");
+ * iface->set_xf_id(14); // apply differential format (dxf) whose ID is 14
+ * iface->set_type(conditional_format_t::condition); // rule entry type
+ * iface->set_operator(condition_operator_t::expression);
+ * iface->set_operator(condition_operator_t::greater);
+ *
+ * iface->set_formula("2");
+ * iface->commit_condition();
+ *
+ * iface->commit_entry();
+ *
+ * iface->commit_format();
+ * @endcode
+ *
+ * @todo Revise this API for simplification.
+ */
+class ORCUS_DLLPUBLIC import_conditional_format
+{
+public:
+ virtual ~import_conditional_format();
+
+ /**
+ * Sets the color of the current condition.
+ * only valid for type == databar or type == colorscale.
+ */
+ virtual void set_color(color_elem_t alpha, color_elem_t red,
+ color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Sets the formula, value or string of the current condition.
+ */
+ virtual void set_formula(std::string_view formula) = 0;
+
+ /**
+ * Sets the type for the formula, value or string of the current condition.
+ * Only valid for type = iconset, databar or colorscale.
+ */
+ virtual void set_condition_type(condition_type_t type) = 0;
+
+ /**
+ * Only valid for type = date.
+ */
+ virtual void set_date(condition_date_t date) = 0;
+
+ /**
+ * commits the current condition to the current entry.
+ */
+ virtual void commit_condition() = 0;
+
+ /**
+ * Name of the icons to use in the current entry.
+ * only valid for type = iconset
+ */
+ virtual void set_icon_name(std::string_view name) = 0;
+
+ /**
+ * Use a gradient for the current entry.
+ * only valid for type == databar
+ */
+ virtual void set_databar_gradient(bool gradient) = 0;
+
+ /**
+ * Position of the 0 axis in the current entry.
+ * only valid for type == databar.
+ */
+ virtual void set_databar_axis(databar_axis_t axis) = 0;
+
+ /**
+ * Databar color for positive values.
+ * only valid for type == databar.
+ */
+ virtual void set_databar_color_positive(color_elem_t alpha, color_elem_t red,
+ color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Databar color for negative values.
+ * only valid for type == databar.
+ */
+ virtual void set_databar_color_negative(color_elem_t alpha, color_elem_t red,
+ color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Sets the minimum length for a databar.
+ * only valid for type == databar.
+ */
+ virtual void set_min_databar_length(double length) = 0;
+
+ /**
+ * Sets the maximum length for a databar.
+ * only valid for type == databar.
+ */
+ virtual void set_max_databar_length(double length) = 0;
+
+ /**
+ * Don't show the value in the cell.
+ * only valid for type = databar, iconset, colorscale.
+ */
+ virtual void set_show_value(bool show) = 0;
+
+ /**
+ * Use the icons in reverse order.
+ * only valid for type == iconset.
+ */
+ virtual void set_iconset_reverse(bool reverse) = 0;
+
+ /**
+ * TODO: In OOXML the style is stored as dxf and in ODF as named style.
+ */
+ virtual void set_xf_id(size_t xf) = 0;
+
+ /**
+ * Sets the current operation used for the current entry.
+ * only valid for type == condition
+ */
+ virtual void set_operator(condition_operator_t condition_type) = 0;
+
+ virtual void set_type(conditional_format_t type) = 0;
+
+ virtual void commit_entry() = 0;
+
+ virtual void set_range(std::string_view range) = 0;
+
+ virtual void set_range(row_t row_start, col_t col_start,
+ row_t row_end, col_t col_end) = 0;
+
+ virtual void commit_format() = 0;
+};
+
+/**
+ * Interface for table. A table is a range of cells within a sheet that
+ * consists of one or more data columns with a header row that contains their
+ * labels.
+ */
+class ORCUS_DLLPUBLIC import_table
+{
+public:
+ virtual ~import_table();
+
+ /**
+ * Get an optional interface for importing auto filter data stored as part
+ * of a table.
+ *
+ * The implementor should initialize the internal state of the temporary
+ * auto filter object when this method is called.
+ *
+ * @return pointer to the auto filter interface object, or a @p nullptr if
+ * the implementor doesn't support it.
+ */
+ virtual import_auto_filter* get_auto_filter();
+
+ /**
+ * Set an integral identifier unique to the table.
+ *
+ * @param id identifier associated with the table.
+ */
+ virtual void set_identifier(size_t id) = 0;
+
+ /**
+ * Set a 2-dimensional cell range associated with the table.
+ *
+ * @param range cell range associated with the table.
+ */
+ virtual void set_range(const range_t& range) = 0;
+
+ /**
+ * Set the number of totals rows.
+ *
+ * @param row_count number of totals rows.
+ */
+ virtual void set_totals_row_count(size_t row_count) = 0;
+
+ /**
+ * Set the internal name of the table.
+ *
+ * @param name name of the table.
+ */
+ virtual void set_name(std::string_view name) = 0;
+
+ /**
+ * Set the displayed name of the table.
+ *
+ * @param name displayed name of the table.
+ */
+ virtual void set_display_name(std::string_view name) = 0;
+
+ /**
+ * Set the number of columns the table contains.
+ *
+ * @param n number of columns in the table.
+ *
+ * @note This method gets called before the column data gets imported. The
+ * implementor can use this call to initialize the buffer for storing
+ * the column data.
+ */
+ virtual void set_column_count(size_t n) = 0;
+
+ /**
+ * Set an integral identifier for a column.
+ *
+ * @param id integral identifier for a column.
+ */
+ virtual void set_column_identifier(size_t id) = 0;
+
+ /**
+ * Set a name of a column.
+ *
+ * @param name name of a column.
+ */
+ virtual void set_column_name(std::string_view name) = 0;
+
+ /**
+ * Set the totals row label for a column.
+ *
+ * @param label row label for a column.
+ */
+ virtual void set_column_totals_row_label(std::string_view label) = 0;
+
+ /**
+ * Set the totals row function for a column.
+ *
+ * @param func totals row function for a column.
+ */
+ virtual void set_column_totals_row_function(totals_row_function_t func) = 0;
+
+ /**
+ * Push and append the column data stored in the current column data buffer
+ * into the table buffer.
+ */
+ virtual void commit_column() = 0;
+
+ /**
+ * Set the name of a style to apply to the table.
+ *
+ * @param name name of a style to apply to the table.
+ */
+ virtual void set_style_name(std::string_view name) = 0;
+
+ /**
+ * Specify whether or not the first column in the table should have the
+ * style applied.
+ *
+ * @param b whether or not the first column in the table should have the
+ * style applied.
+ */
+ virtual void set_style_show_first_column(bool b) = 0;
+
+ /**
+ * Specify whether or not the last column in the table should have the style
+ * applied.
+ *
+ * @param b whether or not the last column in the table should have the
+ * style applied.
+ */
+ virtual void set_style_show_last_column(bool b) = 0;
+
+ /**
+ * Specify whether or not row stripe formatting is applied.
+ *
+ * @param b whether or not row stripe formatting is applied.
+ */
+ virtual void set_style_show_row_stripes(bool b) = 0;
+
+ /**
+ * Specify whether or not column stripe formatting is applied.
+ *
+ * @param b whether or not column stripe formatting is applied.
+ */
+ virtual void set_style_show_column_stripes(bool b) = 0;
+
+ /**
+ * Push the data stored in the table buffer into the document store.
+ */
+ virtual void commit() = 0;
+};
+
+/**
+ * Interface for importing the properties of a single formula cell. A formula
+ * cell contains a formula expression that can be computed, and optionally a
+ * cached result of the last computation performed on the expression.
+ */
+class ORCUS_DLLPUBLIC import_formula
+{
+public:
+ virtual ~import_formula();
+
+ /**
+ * Set the position of a cell.
+ *
+ * @param row row position.
+ * @param col column position.
+ */
+ virtual void set_position(row_t row, col_t col) = 0;
+
+ /**
+ * Set formula string to a cell.
+ *
+ * @param grammar grammar to use to compile the formula string into
+ * tokens.
+ * @param formula formula expression to store.
+ */
+ virtual void set_formula(formula_grammar_t grammar, std::string_view formula) = 0;
+
+ /**
+ * Register the formula stored in a cell as a shared formula to be shared
+ * with other cells, if the cell contains a formula string.
+ *
+ * If a cell references a shared formula stored in another cell, only
+ * specify the index of that shared formula without specifying a formula
+ * string of its own. In that case, it is expected that another formula
+ * cell registers its formula string for that index.
+ *
+ * @param index shared string index to register the formula with.
+ */
+ virtual void set_shared_formula_index(size_t index) = 0;
+
+ /**
+ * Set cached result of string type.
+ *
+ * @param value string result value.
+ */
+ virtual void set_result_string(std::string_view value) = 0;
+
+ /**
+ * Set cached result of numeric type.
+ *
+ * @param value numeric value to set as a cached result.
+ */
+ virtual void set_result_value(double value) = 0;
+
+ /**
+ * Set cached result of boolean type.
+ *
+ * @param value boolean value to set as a cached result.
+ */
+ virtual void set_result_bool(bool value) = 0;
+
+ /**
+ * Set empty value as a cached result.
+ */
+ virtual void set_result_empty() = 0;
+
+ /**
+ * Commit all the formula data to the specified cell.
+ */
+ virtual void commit() = 0;
+};
+
+/**
+ * Interface for importing the properties of an array formula which occupies a
+ * range of cells. Cells that are part of an array formula share the same
+ * formula expression but may have different calculation results.
+ */
+class ORCUS_DLLPUBLIC import_array_formula
+{
+public:
+ virtual ~import_array_formula();
+
+ /**
+ * Set the range of an array formula.
+ *
+ * @param range range of an array formula.
+ */
+ virtual void set_range(const range_t& range) = 0;
+
+ /**
+ * Set the formula expression of an array formula.
+ *
+ * @param grammar grammar to use to compile the formula string into
+ * tokens.
+ * @param formula formula expression of an array formula.
+ */
+ virtual void set_formula(formula_grammar_t grammar, std::string_view formula) = 0;
+
+ /**
+ * Set a cached string result of a cell within the array formula range.
+ *
+ * @param row 0-based row position of a cell.
+ * @param col 0-based column position of a cell.
+ * @param value cached string value to set.
+ */
+ virtual void set_result_string(row_t row, col_t col, std::string_view value) = 0;
+
+ /**
+ * Set a cached numeric result of a cell within the array formula range.
+ *
+ * @param row 0-based row position of a cell.
+ * @param col 0-based column position of a cell.
+ * @param value cached numeric value to set.
+ */
+ virtual void set_result_value(row_t row, col_t col, double value) = 0;
+
+ /**
+ * Set a cached boolean result of a cell within the array formula range.
+ *
+ * @param row 0-based row position of a cell.
+ * @param col 0-based column position of a cell.
+ * @param value cached boolean value to set.
+ */
+ virtual void set_result_bool(row_t row, col_t col, bool value) = 0;
+
+ /**
+ * Set an empty value as a cached result to a cell within the array formula
+ * range.
+ *
+ * @param row 0-based row position of a cell.
+ * @param col 0-based column position of a cell.
+ */
+ virtual void set_result_empty(row_t row, col_t col) = 0;
+
+ /**
+ * Push the properties of an array formula currently stored in the buffer to
+ * the sheet store.
+ */
+ virtual void commit() = 0;
+};
+
+/**
+ * Interface for importing the content and properties of a sheet.
+ */
+class ORCUS_DLLPUBLIC import_sheet
+{
+public:
+ virtual ~import_sheet();
+
+ /**
+ * Get an optional interface for importing properties that are specific to a
+ * view of a sheet.
+ *
+ * @return pointer to the interface for importing view properties, or a @p
+ * nullptr if the implementor doesn't support it.
+ */
+ virtual import_sheet_view* get_sheet_view();
+
+ /**
+ * Get an optional interface for importing sheet properties.
+ *
+ * @return pointer to the interface for importing sheet properties, or a @p
+ * nullptr if the implementor doesn't support it.
+ */
+ virtual import_sheet_properties* get_sheet_properties();
+
+ /**
+ * Get an optional interface for importing data tables. Note that the
+ * implementer may decide not to support this feature in which case this
+ * method should return a @p nullptr.
+ *
+ * The implementor should initialize the internal state of the temporary
+ * data table object when this method is called.
+ *
+ * @return pointer to the data table interface object, or a @p nullptr if
+ * the implementor doesn't support it.
+ */
+ virtual import_data_table* get_data_table();
+
+ /**
+ * Get an optional interface for importing auto filter ranges.
+ *
+ * The implementor should initialize the internal state of the temporary
+ * auto filter object when this method is called.
+ *
+ * @return pointer to the auto filter interface object, or a @p nullptr if
+ * the implementor doesn't support it.
+ */
+ virtual import_auto_filter* get_auto_filter();
+
+ /**
+ * Get an interface for importing tables.
+ *
+ * The implementor should initialize the internal state of the temporary
+ * table object when this method is called.
+ *
+ * @return pointer to the table interface object, or @p nullptr if the
+ * implementer doesn't support importing of tables.
+ */
+ virtual import_table* get_table();
+
+ /**
+ * Get an optional interface for importing conditional formats.
+ *
+ * @return pointer to the conditional format interface object, or @p nullptr
+ * if the implementer doesn't support importing conditional
+ * formats.
+ */
+ virtual import_conditional_format* get_conditional_format();
+
+ /**
+ * Get an optional interface for importing sheet-local named expressions.
+ *
+ * @return pointer to the sheet-local named expression interface, or a @p
+ * nullptr if the implementor doesn't support it.
+ */
+ virtual import_named_expression* get_named_expression();
+
+ /**
+ * Get an optional interface for importing array formulas. An array formula
+ * is a formula expression applied to a range of cells where each cell may
+ * have a different result value.
+ *
+ * @return pointer to the array formula import interface, or a @p nullptr if
+ * the implementor doesn't support it.
+ */
+ virtual import_array_formula* get_array_formula();
+
+ /**
+ * Get an optional interface for importing formula cells.
+ *
+ * @return pointer to the formula interface object, or a @p nullptr if the
+ * implementer doesn't support importing of formula cells.
+ */
+ virtual import_formula* get_formula();
+
+ /**
+ * Set raw string value to a cell and have the implementation
+ * auto-recognize its data type.
+ *
+ * @param row row ID
+ * @param col column ID
+ * @param s raw string value.
+ */
+ virtual void set_auto(row_t row, col_t col, std::string_view s) = 0;
+
+ /**
+ * Set string value to a cell.
+ *
+ * @param row row ID
+ * @param col column ID
+ * @param sindex 0-based string index in the shared string table.
+ */
+ virtual void set_string(row_t row, col_t col, string_id_t sindex) = 0;
+
+ /**
+ * Set numerical value to a cell.
+ *
+ * @param row row ID
+ * @param col column ID
+ * @param value value being assigned to the cell.
+ */
+ virtual void set_value(row_t row, col_t col, double value) = 0;
+
+ /**
+ * Set a boolean value to a cell.
+ *
+ * @param row row ID
+ * @param col col ID
+ * @param value boolean value being assigned to the cell
+ */
+ virtual void set_bool(row_t row, col_t col, bool value) = 0;
+
+ /**
+ * Set date and time value to a cell.
+ *
+ * @param row row ID
+ * @param col column ID
+ * @param year 1-based value representing year
+ * @param month 1-based value representing month, varying from 1 through
+ * 12.
+ * @param day 1-based value representing day, varying from 1 through 31.
+ * @param hour the hour of a day, ranging from 0 through 23.
+ * @param minute the minute of an hour, ranging from 0 through 59.
+ * @param second the second of a minute, ranging from 0 through 59.
+ */
+ virtual void set_date_time(
+ row_t row, col_t col,
+ int year, int month, int day, int hour, int minute, double second) = 0;
+
+ /**
+ * Set cell format to specified cell. The cell format is referred to by
+ * the xf (cell format) index in the styles table.
+ *
+ * @note This method gets called after both set_column_format() and
+ * set_row_format().
+ *
+ * @param row row ID
+ * @param col column ID
+ * @param xf_index 0-based xf (cell format) index
+ */
+ virtual void set_format(row_t row, col_t col, size_t xf_index) = 0;
+
+ /**
+ * Set cell format to specified cell range. The cell format is referred
+ * to by the xf (cell format) index in the styles table.
+ *
+ * @param row_start start row ID
+ * @param col_start start column ID
+ * @param row_end end row ID
+ * @param col_end end column ID
+ * @param xf_index 0-based xf (cell format) index
+ */
+ virtual void set_format(row_t row_start, col_t col_start,
+ row_t row_end, col_t col_end, size_t xf_index) = 0;
+
+ /**
+ * Set cell format to a specified column. The cell format is referred to by
+ * the xf (cell format) index in the styles table.
+ *
+ * @note This method gets called first before set_row_format() or
+ * set_format() variants.
+ *
+ * @param col column ID
+ * @param col_span number of contiguous columns to apply the format to. It
+ * must be at least one.
+ * @param xf_index 0-based xf (cell format) index
+ */
+ virtual void set_column_format(col_t col, col_t col_span, std::size_t xf_index) = 0;
+
+ /**
+ * Set cell format to a specified row. The cell format is referred to by
+ * the xf (cell format) index in the styles table.
+ *
+ * @note This method gets called after set_column_format() but before
+ * set_format().
+ *
+ * @param row row ID
+ * @param xf_index 0-based xf (cell format) index
+ */
+ virtual void set_row_format(row_t row, std::size_t xf_index) = 0;
+
+ /**
+ * Duplicate the value of the source cell to one or more cells located
+ * immediately below it.
+ *
+ * @param src_row row ID of the source cell
+ * @param src_col column ID of the source cell
+ * @param range_size number of cells below the source cell to copy the
+ * source cell value to. It must be at least one.
+ */
+ virtual void fill_down_cells(row_t src_row, col_t src_col, row_t range_size) = 0;
+
+ /**
+ * Get the size of the sheet.
+ *
+ * @return structure containing the numbers of rows and columns of the
+ * sheet.
+ */
+ virtual range_size_t get_sheet_size() const = 0;
+};
+
+/**
+ * Interface for specifying global settings that may affect how the
+ * implementor should process certain values and properties.
+ */
+class ORCUS_DLLPUBLIC import_global_settings
+{
+public:
+ virtual ~import_global_settings();
+
+ /**
+ * Set the date that is to be represented by a value of 0. All date
+ * values should be represented relative to this date. This may affect, for
+ * instance, values imported via @ref import_sheet::set_date_time().
+ *
+ * @param year 1-based value representing year
+ * @param month 1-based value representing month, varying from 1 through
+ * 12.
+ * @param day 1-based value representing day, varying from 1 through 31.
+ */
+ virtual void set_origin_date(int year, int month, int day) = 0;
+
+ /**
+ * Set the formula grammar to be used globally when parsing formulas if the
+ * grammar is not specified. This grammar should also be used when parsing
+ * range strings associated with shared formula ranges, array formula
+ * ranges, autofilter ranges etc.
+ *
+ * Note that the import filter may specify what formula grammar to use
+ * locally when importing formula expressions for cells via @ref
+ * import_formula::set_formula(), in which case the implementor should honor
+ * that one instead.
+ *
+ * @param grammar default formula grammar to use globally unless otherwise
+ * specified.
+ */
+ virtual void set_default_formula_grammar(formula_grammar_t grammar) = 0;
+
+ /**
+ * Get current global formula grammar. The import filter may use this
+ * method to query the current global formula grammar.
+ *
+ * @return current default formula grammar.
+ */
+ virtual formula_grammar_t get_default_formula_grammar() const = 0;
+
+ /**
+ * Set the character set to use when parsing encoded string values.
+ *
+ * @param charset character set to use when parsing encoded string values.
+ */
+ virtual void set_character_set(character_set_t charset) = 0;
+};
+
+/**
+ * This is an interface to allow the implementor to provide its own reference
+ * address parsers, for both single cell references and cell range references.
+ * The implementor may choose to provide a different parser depending of the
+ * type of formula_ref_context_t argument given to the @ref
+ * import_factory::get_reference_resolver() call.
+ */
+class ORCUS_DLLPUBLIC import_reference_resolver
+{
+public:
+ virtual ~import_reference_resolver();
+
+ /**
+ * Resolve a textural representation of a single cell address.
+ *
+ * @param address single cell address string.
+ *
+ * @return structure containing the column and row positions of the
+ * address.
+ *
+ * @exception orcus::invalid_arg_error the string is not a valid
+ * single cell addreess.
+ */
+ virtual src_address_t resolve_address(std::string_view address) = 0;
+
+ /**
+ * Resolve a textural representation of a range address. Note that a
+ * string representing a valid single cell address should be considered a
+ * valid range address.
+ *
+ * @param range range address string.
+ *
+ * @return structure containing the start and end positions of the range
+ * address.
+ *
+ * @exception invalid_arg_error the string is not a valid range addreess.
+ */
+ virtual src_range_t resolve_range(std::string_view range) = 0;
+};
+
+/**
+ * This interface is the entry point for the import filter code to instantiate
+ * other, more specialized interfaces. The life cycles of any specialized
+ * interfaces returned from this interface shall be managed by the implementor
+ * of this interface.
+ *
+ * The implementer of this interface may wrap a backend document store that
+ * needs to be populated.
+ */
+class ORCUS_DLLPUBLIC import_factory
+{
+public:
+ virtual ~import_factory();
+
+ /**
+ * Obtain an optional interface for global settings, which the import filter
+ * uses to specify global filter settings that may affect how certain values
+ * and properties should be processed. The implementor can use this
+ * interface to decide how to process relevant values and properties.
+ *
+ * @return pointer to the global settings interface, or a @p nullptr if the
+ * implementor doesn't support it.
+ */
+ virtual import_global_settings* get_global_settings();
+
+ /**
+ * Obtain an optional interface for importing shared strings for string
+ * cells. Implementing this interface is required in order to import string
+ * cell values.
+ *
+ * @return pointer to the shared strings interface, or a @p nullptr if the
+ * implementor doesn't support it.
+ */
+ virtual import_shared_strings* get_shared_strings();
+
+ /**
+ * Obtain an optional interface for importing global named expressions.
+ *
+ * Note that @ref import_sheet also provides the same interface, but its
+ * interface is for importing sheet-local named expressions.
+ *
+ * @return pointer to the global named expression interface, or a @p nullptr
+ * if the implementor doesn't support it.
+ */
+ virtual import_named_expression* get_named_expression();
+
+ /**
+ * Obtain an optional interface for importing styles used to add formatting
+ * properties to cell values.
+ *
+ * @return pointer to the styles interface, or a @p nullptr if the
+ * implementor doesn't support it.
+ */
+ virtual import_styles* get_styles();
+
+ /**
+ * Obtain an optional interface for resolving cell and cell-range references
+ * from string values.
+ *
+ * @param cxt context in which the formula expression containing the
+ * references to be resolved occurs.
+ *
+ * @return pointer to the reference resolve interfance, or a @p nullptr if
+ * the implementor doesn't support it.
+ */
+ virtual import_reference_resolver* get_reference_resolver(formula_ref_context_t cxt);
+
+ /**
+ * Obtain an optional interface for pivot cache definition import for a
+ * specified cache ID. In case a pivot cache alrady exists for the passed
+ * ID, the implementor should overwrite the existing cache with a brand-new
+ * cache instance.
+ *
+ * @param cache_id numeric ID associated with the pivot cache.
+ *
+ * @return pointer to the pivot cache interface, or a @p nullptr if the
+ * implementor doesn't support pivot cache import.
+ */
+ virtual import_pivot_cache_definition* create_pivot_cache_definition(
+ pivot_cache_id_t cache_id);
+
+ /**
+ * Obtain an optional interface for pivot cache records import for a
+ * specified cache ID.
+ *
+ * @param cache_id numeric ID associated with the pivot cache.
+ *
+ * @return pointer to the pivot cache records interface, or a @p nullptr if
+ * the implementor doesn't support pivot cache import.
+ */
+ virtual import_pivot_cache_records* create_pivot_cache_records(
+ pivot_cache_id_t cache_id);
+
+ /**
+ * Append a sheet with a specified sheet position index and name and return
+ * an interface for importing its content. The implementor can use a call
+ * to this method as a signal to create and append a new sheet instance to
+ * the document store.
+ *
+ * @param sheet_index position index of the sheet to be appended. It is
+ * 0-based i.e. the first sheet to be appended will
+ * have an index value of 0.
+ * @param name sheet name.
+ *
+ * @return pointer to the sheet instance, or a @p nullptr if the implementor
+ * doesn't support it. Note, however, that if the implementor
+ * doesn't support this interface, no cell values will get imported.
+ */
+ virtual import_sheet* append_sheet(sheet_t sheet_index, std::string_view name) = 0;
+
+ /**
+ * Get a sheet instance by name. The import filter may use this method to
+ * get access to an existing sheet after it has been created.
+ *
+ * @param name sheet name.
+ *
+ * @return pointer to the sheet instance whose name matches the name
+ * passed to this method. It returns a @p nullptr if no sheet
+ * instance exists by the specified name.
+ */
+ virtual import_sheet* get_sheet(std::string_view name) = 0;
+
+ /**
+ * Retrieve a sheet instance by a specified numerical sheet index.
+ *
+ * @param sheet_index sheet index.
+ *
+ * @return pointer to the sheet instance, or a @p nullptr if no sheet
+ * instance exists at the specified sheet index.
+ */
+ virtual import_sheet* get_sheet(sheet_t sheet_index) = 0;
+
+ /**
+ * The import filter calls this method after completing its import, to give
+ * the implementor a chance to perform post-processing.
+ */
+ virtual void finalize() = 0;
+};
+
+}}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/import_interface_pivot.hpp b/include/orcus/spreadsheet/import_interface_pivot.hpp
new file mode 100644
index 0000000..275ed44
--- /dev/null
+++ b/include/orcus/spreadsheet/import_interface_pivot.hpp
@@ -0,0 +1,351 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_IMPORT_INTERFACE_PIVOT_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_IMPORT_INTERFACE_PIVOT_HPP
+
+#include <cstdlib>
+
+#include "types.hpp"
+#include "../types.hpp"
+#include "../env.hpp"
+
+// NB: This header must not depend on ixion, as it needs to be usable for
+// those clients that provide their own formula engine. Other headers in
+// the orcus::spreadsheet namespace may depend on ixion.
+
+namespace orcus { namespace spreadsheet { namespace iface {
+
+class import_pivot_cache_field_group;
+
+/**
+ * Interface for importing pivot cache definitions.
+ */
+class ORCUS_DLLPUBLIC import_pivot_cache_definition
+{
+public:
+ virtual ~import_pivot_cache_definition();
+
+ /**
+ * Specify that the source data of this pivot cache is located on a local
+ * worksheet.
+ *
+ * @param ref range string specifying the source range.
+ * @param sheet_name name of the worksheet where the source data is located.
+ *
+ * @todo use the ref resolver to resolve the range.
+ */
+ virtual void set_worksheet_source(std::string_view ref, std::string_view sheet_name) = 0;
+
+ /**
+ * Specify that the source data of this pivot cache is associated with a
+ * table.
+ *
+ * @param table_name name of the table.
+ */
+ virtual void set_worksheet_source(std::string_view table_name) = 0;
+
+ /**
+ * Set the total number of fields present in this pivot cache.
+ *
+ * @param n total number of fields in this pivot cache.
+ */
+ virtual void set_field_count(size_t n) = 0;
+
+ /**
+ * Set the name of the field in the current field buffer.
+ *
+ * @param name field name.
+ */
+ virtual void set_field_name(std::string_view name) = 0;
+
+ /**
+ * Set the lowest value of the field in the current field buffer.
+ *
+ * @param v lowest value of the field.
+ */
+ virtual void set_field_min_value(double v) = 0;
+
+ /**
+ * Set the highest value of the field in the current field buffer.
+ *
+ * @param v highest value of the field.
+ */
+ virtual void set_field_max_value(double v) = 0;
+
+ /**
+ * Set the lowest date value of the field in the current field buffer.
+ *
+ * @param dt lowest date value of the field.
+ */
+ virtual void set_field_min_date(const date_time_t& dt) = 0;
+
+ /**
+ * Set the highest date value of the field in the current field buffer.
+ *
+ * @param dt highest date value of the field.
+ */
+ virtual void set_field_max_date(const date_time_t& dt) = 0;
+
+ /**
+ * Mark the current field as a group field and initiate its import.
+ *
+ * The implementor should create an internal storage to prepare for the
+ * importing of field group data when this method gets called.
+ *
+ * @param base_index 0-based index of the field this group field uses as its
+ * base.
+ * @return interface for importing group field data, or a @p nullptr if the
+ * implementor doesn't support it.
+ */
+ virtual import_pivot_cache_field_group* start_field_group(size_t base_index) = 0;
+
+ /**
+ * Commit the field in the current field buffer to the pivot cache model.
+ */
+ virtual void commit_field() = 0;
+
+ /**
+ * Set a string value to the current field item buffer.
+ *
+ * @param value string value.
+ */
+ virtual void set_field_item_string(std::string_view value) = 0;
+
+ /**
+ * Set a numeric value to the current field item buffer.
+ *
+ * @param v numeric value.
+ */
+ virtual void set_field_item_numeric(double v) = 0;
+
+ /**
+ * Set a date-time value to the current field item buffer.
+ *
+ * @param dt date-time value.
+ */
+ virtual void set_field_item_date_time(const date_time_t& dt) = 0;
+
+ /**
+ * Set an error value to the current field item buffer,
+ *
+ * @param ev error value.
+ */
+ virtual void set_field_item_error(error_value_t ev) = 0;
+
+ /**
+ * Commit the field item in current field item buffer to the current field
+ * model.
+ */
+ virtual void commit_field_item() = 0;
+
+ /**
+ * Commit the current pivot cache model to the document model.
+ */
+ virtual void commit() = 0;
+};
+
+/**
+ * Interface for importing group field settings in a pivot cache definition.
+ */
+class ORCUS_DLLPUBLIC import_pivot_cache_field_group
+{
+public:
+ virtual ~import_pivot_cache_field_group();
+
+ /**
+ * Establish a linkage between a base item to a group item.
+ *
+ * The index to corresponding base item is inferred from the order of this
+ * method being called; the first call to this method implies a base item
+ * index of 0, the second call implies an index of 1, and so on.
+ *
+ * This method is called only for a non-range group field; a group field
+ * where parent-to-child item relationships are manually defined.
+ *
+ * @param group_item_index 0-based index for the group item.
+ */
+ virtual void link_base_to_group_items(size_t group_item_index) = 0;
+
+ /**
+ * Set an individual field item value that is of string type to the
+ * current internal buffer.
+ *
+ * This method can be called either for a range group field or a non-range
+ * one.
+ *
+ * @param value field item value.
+ */
+ virtual void set_field_item_string(std::string_view value) = 0;
+
+ /**
+ * Set an individual field item value that is of numeric type to the
+ * current internal buffer.
+ *
+ * This method can be called either for a range group field or a non-range
+ * one.
+ *
+ * @param v field item value.
+ */
+ virtual void set_field_item_numeric(double v) = 0;
+
+ /**
+ * Commit the current internal field item buffer to the group.
+ */
+ virtual void commit_field_item() = 0;
+
+ /**
+ * Set the range grouping type.
+ *
+ * The current group field implicitly becomes a range group field when
+ * this method is called.
+ *
+ * @param group_by type of range grouping.
+ */
+ virtual void set_range_grouping_type(pivot_cache_group_by_t group_by) = 0;
+
+ /**
+ * Set whether the current range group field has an automatic start
+ * position.
+ *
+ * The current group field implicitly becomes a range group field when
+ * this method is called.
+ *
+ * @param b whether or not the current range group field has an automatic
+ * start position.
+ */
+ virtual void set_range_auto_start(bool b) = 0;
+
+ /**
+ * Set whether the current range group field has an automatic end
+ * position.
+ *
+ * The current group field implicitly becomes a range group field when
+ * this method is called.
+ *
+ * @param b whether or not the current range group field has an automatic
+ * end position.
+ */
+ virtual void set_range_auto_end(bool b) = 0;
+
+ /**
+ * Set the start number of the current range group field.
+ *
+ * The current group field implicitly becomes a range group field when
+ * this method is called.
+ *
+ * @param v start number of the current range group field.
+ */
+ virtual void set_range_start_number(double v) = 0;
+
+ /**
+ * Set the end number of the current range group field.
+ *
+ * The current group field implicitly becomes a range group field when
+ * this method is called.
+ *
+ * @param v end number of the current range group field.
+ */
+ virtual void set_range_end_number(double v) = 0;
+
+ /**
+ * Set the start date of the current range group field.
+ *
+ * The current group field implicitly becomes a range group field when
+ * this method is called.
+ *
+ * @param dt start date of the current range group field.
+ */
+ virtual void set_range_start_date(const date_time_t& dt) = 0;
+
+ /**
+ * Set the end date of the current range group field.
+ *
+ * The current group field implicitly becomes a range group field when
+ * this method is called.
+ *
+ * @param dt end date of the current range group field.
+ */
+ virtual void set_range_end_date(const date_time_t& dt) = 0;
+
+ /**
+ * Set the interval of the current range group field. If the current
+ * range is a date range, the value represents the number of days.
+ *
+ * @param v interval of the current range group field.
+ */
+ virtual void set_range_interval(double v) = 0;
+
+ /**
+ * Commit the current field group data to the parent field.
+ */
+ virtual void commit() = 0;
+};
+
+/**
+ * Interface for importing pivot cache records.
+ */
+class ORCUS_DLLPUBLIC import_pivot_cache_records
+{
+public:
+ virtual ~import_pivot_cache_records();
+
+ /**
+ * Set the number of records included in pivot cache records.
+ *
+ * @note This method gets called before the very first record gets imported.
+ * The implementor can use this call as an opportunity to initialize
+ * any internal buffers used to store the imported records.
+ *
+ * @param n number of records included in pivot cache records.
+ */
+ virtual void set_record_count(size_t n) = 0;
+
+ /**
+ * Append to the current record buffer a numeric value as a column value.
+ *
+ * @param v numeric value to append to the current record buffer as a column
+ * value.
+ */
+ virtual void append_record_value_numeric(double v) = 0;
+
+ /**
+ * Append to the current record buffer a character value as a column value.
+ *
+ * @param s character value to append to the current record buffer as a
+ * column value.
+ */
+ virtual void append_record_value_character(std::string_view s) = 0;
+
+ /**
+ * Append to the current record buffer a column value referenced by an index
+ * into the shared items table of a pivot cache field. The corresponding
+ * field in the pivot cache definition should provide the shared items table
+ * that this index references.
+ *
+ * @param index index into the shared items table of a pivot cache field.
+ */
+ virtual void append_record_value_shared_item(size_t index) = 0;
+
+ /**
+ * Commit the record in the current record buffer.
+ *
+ * The implementor can clear the buffer afterward.
+ */
+ virtual void commit_record() = 0;
+
+ /**
+ * Commit the entire records set to the document store.
+ */
+ virtual void commit() = 0;
+};
+
+}}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/import_interface_styles.hpp b/include/orcus/spreadsheet/import_interface_styles.hpp
new file mode 100644
index 0000000..6ad94a8
--- /dev/null
+++ b/include/orcus/spreadsheet/import_interface_styles.hpp
@@ -0,0 +1,774 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <cstdlib>
+
+#include "types.hpp"
+#include "../types.hpp"
+#include "../env.hpp"
+
+// NB: This header must not depend on ixion, as it needs to be usable for
+// those clients that provide their own formula engine. Other headers in
+// the orcus::spreadsheet namespace may depend on ixion.
+
+namespace orcus { namespace spreadsheet { namespace iface {
+
+class import_font_style;
+class import_fill_style;
+class import_border_style;
+class import_cell_protection;
+class import_number_format;
+class import_xf;
+class import_cell_style;
+
+/**
+ * Interface for importing styles. This one acts as an entry point and
+ * provides other interfaces for the style categories.
+ *
+ * The styles are to be stored in a <a
+ * href="https://en.wikipedia.org/wiki/Flyweight_pattern">flyweight</a>
+ * fashion where each style category maintains an array of stored style
+ * items, which are referenced by their indices. Each time a style
+ * item is pushed through the interface, it returns an index representing the
+ * item. The indices are to be assigned sequentially starting with 0 in each
+ * style category, and <em>the default style must get an index of 0</em>.
+ * Because of this, the import filter imports the default styles first before
+ * importing other non-default styles.
+ *
+ * The appreviation @p xf stands for cell format, and is used throughout the
+ * styles API. Similarly, the @p dxf stands for differential cell format, and
+ * stores partial format properties that are to be applied on top of the base
+ * format properties.
+ *
+ * @note The implementor of this interface @em must implement all interfaces
+ * for all the style categories that this interface returns.
+ */
+class ORCUS_DLLPUBLIC import_styles
+{
+public:
+ virtual ~import_styles();
+
+ /**
+ * Signal the start of the import of font style attributes, and return a
+ * pointer to the interface instance for importing the attributes.
+ *
+ * @note Note that the import_styles implementer <i>must</i> return a
+ * non-null pointer.
+ *
+ * @return pointer to the interface instance for importing font style
+ * attributes.
+ */
+ virtual import_font_style* start_font_style() = 0;
+
+ /**
+ * Signal the start of the import of fill style attributes, and return a
+ * pointer to the interface instance for importing the attributes.
+ *
+ * @note Note that the import_styles implementer <i>must</i> return a
+ * non-null pointer.
+ *
+ * @return pointer to the interface instance for importing fill style
+ * attributes.
+ */
+ virtual import_fill_style* start_fill_style() = 0;
+
+ /**
+ * Signal the start of the import of border style attributes, and return a
+ * pointer to the interface instance for importing the attributes.
+ *
+ * @note Note that the import_styles implementer <i>must</i> return a
+ * non-null pointer.
+ *
+ * @return pointer to the interface instance for importing border style
+ * attributes.
+ */
+ virtual import_border_style* start_border_style() = 0;
+
+ /**
+ * Signal the start of the import of cell protection attributes, and return
+ * a pointer to the interface instance for importing the attributes.
+ *
+ * @note Note that the import_styles implementer <i>must</i> return a
+ * non-null pointer.
+ *
+ * @return pointer to the interface instance for importing cell protection
+ * attributes.
+ */
+ virtual import_cell_protection* start_cell_protection() = 0;
+
+ /**
+ * Signal the start of the import of number format attributes and return a
+ * pointer to the interface instance for importing the attributes.
+ *
+ * @note Note that the import_styles implementer <i>must</i> return a
+ * non-null pointer.
+ *
+ * @return pointer to the interface instance for importing number format
+ * attributes.
+ */
+ virtual import_number_format* start_number_format() = 0;
+
+ /**
+ * Signal the start of the import of cell format (xf) indices that each
+ * reference different format attributes in their respective pools, and
+ * return a pointer to the interface instance for importing the indices.
+ *
+ * @note Note that the import_styles implementer <i>must</i> return a
+ * non-null pointer.
+ *
+ * @return pointer to the interface instance for importing cell format (xf)
+ * indices.
+ */
+ virtual import_xf* start_xf(xf_category_t cat) = 0;
+
+ /**
+ * Signal the start of the import of named cell style information, and
+ * return a pointer to the interface instance for importing the information.
+ *
+ * @note Note that the import_styles implementer <i>must</i> return a
+ * non-null pointer.
+ *
+ * @return pointer to the interface instance for importing named cell style
+ * information.
+ */
+ virtual import_cell_style* start_cell_style() = 0;
+
+ /**
+ * Set the total number of font styles. This may be called before importing
+ * any of the font styles. This will give the implementer a chance to
+ * allocate storage. Note that it may not always be called.
+ *
+ * @param n number of font styles.
+ */
+ virtual void set_font_count(size_t n) = 0;
+
+ /**
+ * Set the total number of fill styles. This may be called before importing
+ * any of the fill styles. This will give the implementer a chance to
+ * allocate storage. Note that it may not always be called.
+ *
+ * @param n number of fill styles.
+ */
+ virtual void set_fill_count(size_t n) = 0;
+
+ /**
+ * Set the total number of border styles. This may be called before
+ * importing any of the border styles. This will give the implementer a
+ * chance to allocate storage. Note that it may not always be called.
+ *
+ * @param n number of border styles.
+ */
+ virtual void set_border_count(size_t n) = 0;
+
+ /**
+ * Set the total number of number format styles. This may be called before
+ * importing any of the number format styles. This will give the implementer
+ * a chance to allocate storage. Note that it may not always be called.
+ *
+ * @param n number of number format styles.
+ */
+ virtual void set_number_format_count(size_t n) = 0;
+
+ /**
+ * Set the total number of cell format styles for a specified cell format
+ * category. This may be called before importing any of the cell format
+ * styles for the specified category. This will give the implementer a
+ * chance to allocate storage. Note that it may not always be called.
+ *
+ * @param cat cell format category.
+ * @param n number of cell formats styles for the specified cell format
+ * category.
+ */
+ virtual void set_xf_count(xf_category_t cat, size_t n) = 0;
+
+ /**
+ * Set the total number of named cell styles. This may be called before
+ * importing any cell styles to give the implementer a chance to allocate
+ * storage. Note that it may not always be called.
+ *
+ * @param n number of named cell styles.
+ */
+ virtual void set_cell_style_count(size_t n) = 0;
+};
+
+/**
+ * Interface for importing font style items. The following font style
+ * properties store different values for western, asian and complex scripts:
+ *
+ * @li font name
+ * @li font size
+ * @li font weight (normal or bold)
+ * @li font style (normal or italic)
+ */
+class ORCUS_DLLPUBLIC import_font_style
+{
+public:
+ virtual ~import_font_style();
+
+ /**
+ * Set the font weight to either normal or bold, for western script.
+ *
+ * @param b whether the font has normal (false) or bold weight (true).
+ */
+ virtual void set_bold(bool b) = 0;
+
+ /**
+ * Set the font weight to either normal or bold, for asian script.
+ *
+ * @param b whether the font has normal (false) or bold weight (true).
+ */
+ virtual void set_bold_asian(bool b) = 0;
+
+ /**
+ * Set the font weight to either normal or bold, for complex script.
+ *
+ * @param b whether the font has normal (false) or bold weight (true).
+ */
+ virtual void set_bold_complex(bool b) = 0;
+
+ /**
+ * Set the font style to either normal or italic, for western script.
+ *
+ * @param b whether the font has normal (false) or italic style (true).
+ */
+ virtual void set_italic(bool b) = 0;
+
+ /**
+ * Set the font style to either normal or italic, for asian script.
+ *
+ * @param b whether the font has normal (false) or italic style (true).
+ */
+ virtual void set_italic_asian(bool b) = 0;
+
+ /**
+ * Set the font style to either normal or italic, for complex script.
+ *
+ * @param b whether the font has normal (false) or italic style (true).
+ */
+ virtual void set_italic_complex(bool b) = 0;
+
+ /**
+ * Set the name of a font, for western script.
+ *
+ * @param s font name.
+ */
+ virtual void set_name(std::string_view s) = 0;
+
+ /**
+ * Set the name of a font, for asian script.
+ *
+ * @param s font name.
+ */
+ virtual void set_name_asian(std::string_view s) = 0;
+
+ /**
+ * Set the name of a font, for complex script.
+ *
+ * @param s font name.
+ */
+ virtual void set_name_complex(std::string_view s) = 0;
+
+ /**
+ * Set the size of a font in points, for western script.
+ *
+ * @param point font size in points.
+ */
+ virtual void set_size(double point) = 0;
+
+ /**
+ * Set the size of a font in points, for asian script.
+ *
+ * @param point font size in points.
+ */
+ virtual void set_size_asian(double point) = 0;
+
+ /**
+ * Set the size of a font in points, for complex script.
+ *
+ * @param point font size in points.
+ */
+ virtual void set_size_complex(double point) = 0;
+
+ /**
+ * Set the underline type of a font.
+ *
+ * @param e underline type of a font.
+ */
+ virtual void set_underline(underline_t e) = 0;
+
+ /**
+ * Set the width of the underline of a font.
+ *
+ * @param e width of the underline of a font.
+ */
+ virtual void set_underline_width(underline_width_t e) = 0;
+
+ /**
+ * Set whether the underline of a font is continuous over the gaps, or skip
+ * the gaps.
+ *
+ * @param e whether the underline of a font is continuous over the gaps or
+ * skip the gaps.
+ */
+ virtual void set_underline_mode(underline_mode_t e) = 0;
+
+ /**
+ * Set whether the underline of a font consists of a single line, or a
+ * double line.
+ *
+ * @param e whether the underline of a font consists of a single line, or a
+ * double line.
+ *
+ * @todo Look into merging this with set_underline().
+ */
+ virtual void set_underline_type(underline_type_t e) = 0;
+
+ /**
+ * Specify the color of an underline in ARGB format.
+ *
+ * @param alpha alpha component of the color.
+ * @param red red component of the color.
+ * @param green green component of the color.
+ * @param blue blue component of the color.
+ *
+ * @note If this value is not explicitly set, the font color should be used.
+ */
+ virtual void set_underline_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Specify the color of font in ARGB format.
+ *
+ * @param alpha alpha component of the color.
+ * @param red red component of the color.
+ * @param green green component of the color.
+ * @param blue blue component of the color.
+ */
+ virtual void set_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Set the strikethrough style of a font.
+ *
+ * @param s strikethrough style of a font.
+ */
+ virtual void set_strikethrough_style(strikethrough_style_t s) = 0;
+
+ /**
+ * Set whether the strikethrough of a font consists of a single line or a
+ * double line.
+ *
+ * @param s whether the strikethrough of a font consists of a single line or
+ * a double line.
+ */
+ virtual void set_strikethrough_type(strikethrough_type_t s) = 0;
+
+ /**
+ * Set the width of the strikethrough of a font.
+ *
+ * @param s the width of the strikethrough of a font.
+ */
+ virtual void set_strikethrough_width(strikethrough_width_t s) = 0;
+
+ /**
+ * Set the text to use as a strikethrough.
+ *
+ * @param s text to use as a strikethrough.
+ */
+ virtual void set_strikethrough_text(strikethrough_text_t s) = 0;
+
+ /**
+ * Commit the font style in the current buffer.
+ *
+ * @return index of the committed font style, to be passed on to the
+ * import_xf::set_font() method as its argument.
+ */
+ virtual std::size_t commit() = 0;
+};
+
+/**
+ * Interface for importing fill style items.
+ */
+class ORCUS_DLLPUBLIC import_fill_style
+{
+public:
+ virtual ~import_fill_style();
+
+ /**
+ * Set the type of fill pattern.
+ *
+ * @param fp fill pattern type.
+ */
+ virtual void set_pattern_type(fill_pattern_t fp) = 0;
+
+ /**
+ * Set the foreground color of a fill. <i>Note that for a solid fill
+ * type, the foreground color will be used.</i>
+ *
+ * @param alpha alpha component ranging from 0 (fully transparent) to 255
+ * (fully opaque).
+ * @param red red component ranging from 0 to 255.
+ * @param green green component ranging from 0 to 255.
+ * @param blue blue component ranging from 0 to 255.
+ */
+ virtual void set_fg_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Set the background color of a fill. <i>Note that this color will
+ * be ignored for a solid fill type.</i>
+ *
+ * @param alpha alpha component ranging from 0 (fully transparent) to 255
+ * (fully opaque).
+ * @param red red component ranging from 0 to 255.
+ * @param green green component ranging from 0 to 255.
+ * @param blue blue component ranging from 0 to 255.
+ */
+ virtual void set_bg_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Commit the fill style in the current buffer.
+ *
+ * @return index of the committed fill style, to be passed on to the
+ * import_xf::set_fill() method as its argument.
+ */
+ virtual size_t commit() = 0;
+};
+
+/**
+ * Interface for importing border style items.
+ */
+class ORCUS_DLLPUBLIC import_border_style
+{
+public:
+ virtual ~import_border_style();
+
+ /**
+ * Set the border style to a specified border position.
+ *
+ * @param dir position of a border to set the style to.
+ * @param style border style to set.
+ */
+ virtual void set_style(border_direction_t dir, border_style_t style) = 0;
+
+ /**
+ * Set the color of a border.
+ *
+ * @param dir position of a border to set the color to.
+ * @param alpha alpha element of the color.
+ * @param red red element of the color.
+ * @param green green element of the color.
+ * @param blue blue element of the color.
+ */
+ virtual void set_color(
+ border_direction_t dir, color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) = 0;
+
+ /**
+ * Set the width of a border.
+ *
+ * @param dir position of a border.
+ * @param width width of a border.
+ * @param unit unit of measurement to use in the border width.
+ */
+ virtual void set_width(border_direction_t dir, double width, orcus::length_unit_t unit) = 0;
+
+ /**
+ * Commit the border style in the current buffer.
+ *
+ * @return index of the committed border style, to be passed on to the
+ * import_xf::set_border() method as its argument.
+ */
+ virtual size_t commit() = 0;
+};
+
+/**
+ * Interface for importing cell protection items.
+ */
+class ORCUS_DLLPUBLIC import_cell_protection
+{
+public:
+ virtual ~import_cell_protection();
+
+ /**
+ * Hide the entire cell content when the sheet is protected.
+ *
+ * @param b whether to hide the entire cell content when the sheet is
+ * protected.
+ */
+ virtual void set_hidden(bool b) = 0;
+
+ /**
+ * Lock the cell when the sheet is protected.
+ *
+ * @param b whether or not to lock the cell when the sheet is protected.
+ */
+ virtual void set_locked(bool b) = 0;
+
+ /**
+ * Specify whether or not to print the cell content when the sheet is
+ * protected.
+ *
+ *
+ * @param b whether or not to print the cell content when the sheet is
+ * protected.
+ */
+ virtual void set_print_content(bool b) = 0;
+
+ /**
+ * Hide the formula when the sheet is protected and the cell contains
+ * formula.
+ *
+ * @param b whether or not to hide the formula when the sheet is protected
+ * and the cell contains formula.
+ */
+ virtual void set_formula_hidden(bool b) = 0;
+
+ /**
+ * Commit the cell protection data in the current buffer.
+ *
+ * @return index of the committed cell protection data, to be passed on to
+ * the import_xf::set_protection() method as its argument.
+ */
+ virtual std::size_t commit() = 0;
+};
+
+/**
+ * Interface for importing number format items.
+ */
+class ORCUS_DLLPUBLIC import_number_format
+{
+public:
+ virtual ~import_number_format();
+
+ /**
+ * Set the integral identifier of a number format.
+ *
+ * @param id integral indentifier of a number format.
+ *
+ * @note This is specific to xlsx format. In xlsx, this identifier gets
+ * used to reference number formats instead of the identifier returned
+ * by the commit() method.
+ *
+ * @todo Perhaps when this method is called, the commit() method of the
+ * corresponding item should return the value set in this method
+ * instead.
+ */
+ virtual void set_identifier(std::size_t id) = 0;
+
+ /**
+ * Set the number format code.
+ *
+ * @param s number format code.
+ */
+ virtual void set_code(std::string_view s) = 0;
+
+ /**
+ * Commit the number format item in the current buffer.
+ *
+ * @return index of the committed number format item, to be passed on to the
+ * import_xf::set_number_format() method as its argument.
+ *
+ * @todo Look into returning the identifier set through the set_identifier()
+ * method.
+ */
+ virtual size_t commit() = 0;
+};
+
+/**
+ * This interface is used to import cell format records for direct cell
+ * formats, named cell style formats, and differential cell formats.
+ *
+ * The following cell format types:
+ * <ul>
+ * <li>font</li>
+ * <li>fill</li>
+ * <li>border</li>
+ * <li>protection</li>
+ * <li>number format</li>
+ * </ul>
+ * use indices to reference their records in their respective record pools.
+ *
+ * The horizontal and vertical alignments are specified directly.
+ */
+class ORCUS_DLLPUBLIC import_xf
+{
+public:
+ virtual ~import_xf();
+
+ /**
+ * Set the index of the font record, as returned from the
+ * import_font_style::commit() method.
+ *
+ * @param index index of the font record to reference.
+ */
+ virtual void set_font(size_t index) = 0;
+
+ /**
+ * Set the index of the fill record, as returned from the
+ * import_fill_style::commit() method.
+ *
+ * @param index index of the fill record to reference.
+ */
+ virtual void set_fill(size_t index) = 0;
+
+ /**
+ * Set the index of the border record, as returned from the
+ * import_border_style::commit() method.
+ *
+ * @param index index of the border record to reference.
+ */
+ virtual void set_border(size_t index) = 0;
+
+ /**
+ * Set the index of the cell protection record, as returned from the
+ * import_cell_protection::commit() method.
+ *
+ * @param index index of the cell protection record to reference.
+ */
+ virtual void set_protection(size_t index) = 0;
+
+ /**
+ * Set the index of the number format record, as returned from the
+ * import_number_format::commit() method.
+ *
+ * @param index index of the number format record to reference.
+ */
+ virtual void set_number_format(size_t index) = 0;
+
+ /**
+ * Set the index into the cell style record to specify a named cell style it
+ * uses as its base format in case the cell has an underlying style applied.
+ * This can be used for a direct cell format i.e. when the xf category is
+ * xf_category_t::cell or for a cell style format i.e. the xf category is
+ * xf_category_t::cell_style. In a cell style format, this can be used to
+ * reference a parent style.
+ *
+ * @param index index into the cell style record it uses as its basis.
+ */
+ virtual void set_style_xf(size_t index) = 0;
+
+ /**
+ * Set the flag indicating whether or not to apply the alignment attribute.
+ *
+ * @param b flag indicating whether or not to apply the alignment attribute.
+ *
+ * @note This is specific to Excel format.
+ */
+ virtual void set_apply_alignment(bool b) = 0;
+
+ /**
+ * Set the horizontal alignment of a style.
+ *
+ * @param align horizontal alignment of a style.
+ */
+ virtual void set_horizontal_alignment(hor_alignment_t align) = 0;
+
+ /**
+ * Set the vertical alignment of a style.
+ *
+ * @param align vertical alignment of a style.
+ */
+ virtual void set_vertical_alignment(ver_alignment_t align) = 0;
+
+ /**
+ * Specify whether or not to wrap text when the text spills over the cell
+ * region.
+ *
+ * @param b whether or not to wrap text when the text spills over the cell
+ * region.
+ */
+ virtual void set_wrap_text(bool b) = 0;
+
+ /**
+ * Specify whether or not to shrink the text within cell until it fits
+ * inside the cell.
+ *
+ * @param b whether or not to shrink the text.
+ */
+ virtual void set_shrink_to_fit(bool b) = 0;
+
+ /**
+ * Commit the cell format in the current buffer to the storage.
+ *
+ * @return index of the cell format data in the storage. This index may be
+ * passed to the import_cell_style::set_xf() method.
+ */
+ virtual size_t commit() = 0;
+};
+
+/**
+ * This interface is used to import named cell style records.
+ *
+ * @note The actual cell format data for named cell styles are imported
+ * through import_xf, and this interface references its index through
+ * the import_cell_style::set_xf() method.
+ *
+ */
+class ORCUS_DLLPUBLIC import_cell_style
+{
+public:
+ virtual ~import_cell_style();
+
+ /**
+ * Set the name associated with the named cell style.
+ *
+ * @param s name of the named cell style.
+ */
+ virtual void set_name(std::string_view s) = 0;
+
+ /**
+ * Set the name associated with the named cell style intended for display
+ * purposes.
+ *
+ * @param s name to use for display purposes.
+ *
+ * @note Not all supported formats make use of this property. Also, the
+ * style may not always have this property even if the format supports
+ * it. ODF uses this property when the original name contains
+ * characters that cannot be used in internal symbols.
+ */
+ virtual void set_display_name(std::string_view s) = 0;
+
+ /**
+ * Set the index into the cell format record. The named cell style applies
+ * the format referenced by this index.
+ *
+ * @param index index into the cell format record.
+ */
+ virtual void set_xf(size_t index) = 0;
+
+ /**
+ * Set the index into the built-in cell style record.
+ *
+ * @note This is Excel-specific, and unclear whether it's useful outside of
+ * Excel's implementation. Built-in styles are not stored in file, and
+ * Excel likely has its own internal styles stored in the application
+ * itself.
+ *
+ * @param index index into the built-in cell style record.
+ */
+ virtual void set_builtin(size_t index) = 0;
+
+ /**
+ * Set the name of the parent cell style it uses as its basis.
+ *
+ * @note ODF uses this but Excel does not use this value.
+ *
+ * @param s name of the parent cell style.
+ */
+ virtual void set_parent_name(std::string_view s) = 0;
+
+ /**
+ * Commit the cell style format in the current buffer to the storage.
+ *
+ * @note This method does @em not return an index.
+ */
+ virtual void commit() = 0;
+};
+
+}}}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/import_interface_view.hpp b/include/orcus/spreadsheet/import_interface_view.hpp
new file mode 100644
index 0000000..8e6b53e
--- /dev/null
+++ b/include/orcus/spreadsheet/import_interface_view.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef IMPORT_ORCUS_SPREADSHEET_IMPORT_INTERFACE_VIEW_HPP
+#define IMPORT_ORCUS_SPREADSHEET_IMPORT_INTERFACE_VIEW_HPP
+
+#include <cstdlib>
+
+#include "view_types.hpp"
+#include "../types.hpp"
+#include "../env.hpp"
+
+namespace orcus { namespace spreadsheet { namespace iface {
+
+/**
+ * Interface for importing view properties. This interface may be obtained
+ * from the import_sheet interface.
+ */
+class ORCUS_DLLPUBLIC import_sheet_view
+{
+public:
+ virtual ~import_sheet_view();
+
+ /**
+ * Set the current sheet as the active sheet.
+ */
+ virtual void set_sheet_active() = 0;
+
+ /**
+ * Set the information about split view in the current sheet.
+ *
+ * @param hor_split horizontal position of the split in 1/20th of a point,
+ * or 0 if none. "Horizontal" in this case indicates the
+ * column direction.
+ * @param ver_split vertical position of the split in 1/20th of a point,
+ * or 0 if none. "Vertical" in this case indicates the
+ * row direction.
+ * @param top_left_cell the top left visible cell in the bottom right
+ * pane.
+ * @param active_pane active pane in this sheet.
+ */
+ virtual void set_split_pane(
+ double hor_split, double ver_split, const address_t& top_left_cell,
+ sheet_pane_t active_pane) = 0;
+
+ /**
+ * Set the state of frozen view in the current sheet.
+ *
+ * @param visible_columns number of visible columns in the left pane.
+ * @param visible_rows number of visible rows in the top pane.
+ * @param top_left_cell the top left visible cell in the bottom right
+ * pane.
+ * @param active_pane active pane in this sheet.
+ */
+ virtual void set_frozen_pane(
+ col_t visible_columns, row_t visible_rows, const address_t& top_left_cell,
+ sheet_pane_t active_pane) = 0;
+
+ /**
+ * Set the selected cursor range in a specified sheet pane.
+ *
+ * @param pane sheet pane associated with the selection. The top-left
+ * pane is used for a non-split sheet view.
+ * @param range selected cursor range. The range will be 1 column by 1
+ * row when the cursor is on a single cell only.
+ */
+ virtual void set_selected_range(sheet_pane_t pane, range_t range) = 0;
+};
+
+}}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/pivot.hpp b/include/orcus/spreadsheet/pivot.hpp
new file mode 100644
index 0000000..dee2559
--- /dev/null
+++ b/include/orcus/spreadsheet/pivot.hpp
@@ -0,0 +1,254 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_PIVOT_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_PIVOT_HPP
+
+#include "../env.hpp"
+#include "../types.hpp"
+#include "types.hpp"
+
+#include <memory>
+#include <vector>
+#include <limits>
+#include <variant>
+#include <optional>
+
+namespace ixion {
+
+struct abs_range_t;
+
+}
+
+namespace orcus {
+
+class string_pool;
+
+namespace spreadsheet {
+
+class document;
+
+using pivot_cache_indices_t = std::vector<size_t>;
+
+struct ORCUS_SPM_DLLPUBLIC pivot_cache_record_value_t
+{
+ using value_type = std::variant<bool, double, std::size_t, std::string_view, date_time_t>;
+
+ enum class record_type
+ {
+ unknown = 0,
+ boolean,
+ date_time,
+ character,
+ numeric,
+ blank,
+ error,
+ shared_item_index
+ };
+
+ record_type type;
+ value_type value;
+
+ pivot_cache_record_value_t();
+ pivot_cache_record_value_t(std::string_view s);
+ pivot_cache_record_value_t(double v);
+ pivot_cache_record_value_t(size_t index);
+
+ bool operator== (const pivot_cache_record_value_t& other) const;
+ bool operator!= (const pivot_cache_record_value_t& other) const;
+};
+
+using pivot_cache_record_t = std::vector<pivot_cache_record_value_t>;
+
+struct ORCUS_SPM_DLLPUBLIC pivot_cache_item_t
+{
+ using value_type = std::variant<bool, double, std::string_view, date_time_t, error_value_t>;
+
+ enum class item_type
+ {
+ unknown = 0, boolean, date_time, character, numeric, blank, error
+ };
+
+ item_type type;
+ value_type value;
+
+ pivot_cache_item_t();
+ pivot_cache_item_t(std::string_view s);
+ pivot_cache_item_t(double numeric);
+ pivot_cache_item_t(bool boolean);
+ pivot_cache_item_t(const date_time_t& date_time);
+ pivot_cache_item_t(error_value_t error);
+
+ pivot_cache_item_t(const pivot_cache_item_t& other);
+ pivot_cache_item_t(pivot_cache_item_t&& other);
+
+ bool operator< (const pivot_cache_item_t& other) const;
+ bool operator== (const pivot_cache_item_t& other) const;
+
+ pivot_cache_item_t& operator= (pivot_cache_item_t other);
+
+ void swap(pivot_cache_item_t& other);
+};
+
+using pivot_cache_items_t = std::vector<pivot_cache_item_t>;
+
+/**
+ * Group data for a pivot cache field.
+ */
+struct ORCUS_SPM_DLLPUBLIC pivot_cache_group_data_t
+{
+ struct ORCUS_SPM_DLLPUBLIC range_grouping_type
+ {
+ pivot_cache_group_by_t group_by = pivot_cache_group_by_t::range;
+
+ bool auto_start = true;
+ bool auto_end = true;
+
+ double start = 0.0;
+ double end = 0.0;
+ double interval = 1.0;
+
+ date_time_t start_date;
+ date_time_t end_date;
+
+ range_grouping_type() = default;
+ range_grouping_type(const range_grouping_type& other) = default;
+ };
+
+ /**
+ * Mapping of base field member indices to the group field item indices.
+ */
+ pivot_cache_indices_t base_to_group_indices;
+
+ std::optional<range_grouping_type> range_grouping;
+
+ /**
+ * Individual items comprising the group.
+ */
+ pivot_cache_items_t items;
+
+ /** 0-based index of the base field. */
+ size_t base_field;
+
+ pivot_cache_group_data_t(size_t _base_field);
+ pivot_cache_group_data_t(const pivot_cache_group_data_t& other);
+ pivot_cache_group_data_t(pivot_cache_group_data_t&& other);
+
+ pivot_cache_group_data_t() = delete;
+};
+
+struct ORCUS_SPM_DLLPUBLIC pivot_cache_field_t
+{
+ /**
+ * Field name. It must be interned with the string pool belonging to the
+ * document.
+ */
+ std::string_view name;
+
+ pivot_cache_items_t items;
+
+ std::optional<double> min_value;
+ std::optional<double> max_value;
+
+ std::optional<date_time_t> min_date;
+ std::optional<date_time_t> max_date;
+
+ std::unique_ptr<pivot_cache_group_data_t> group_data;
+
+ pivot_cache_field_t();
+ pivot_cache_field_t(std::string_view _name);
+ pivot_cache_field_t(const pivot_cache_field_t& other);
+ pivot_cache_field_t(pivot_cache_field_t&& other);
+};
+
+class ORCUS_SPM_DLLPUBLIC pivot_cache
+{
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+
+public:
+ using fields_type = std::vector<pivot_cache_field_t>;
+ using records_type = std::vector<pivot_cache_record_t>;
+
+ pivot_cache(pivot_cache_id_t cache_id, string_pool& sp);
+ ~pivot_cache();
+
+ /**
+ * Bulk-insert all the fields in one step. Note that this will replace any
+ * pre-existing fields if any.
+ *
+ * @param fields field instances to move into storage.
+ */
+ void insert_fields(fields_type fields);
+
+ void insert_records(records_type record);
+
+ size_t get_field_count() const;
+
+ /**
+ * Retrieve a field data by its index.
+ *
+ * @param index index of the field to retrieve.
+ *
+ * @return pointer to the field instance, or nullptr if the index is
+ * out-of-range.
+ */
+ const pivot_cache_field_t* get_field(size_t index) const;
+
+ pivot_cache_id_t get_id() const;
+
+ const records_type& get_all_records() const;
+};
+
+class ORCUS_SPM_DLLPUBLIC pivot_collection
+{
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+
+public:
+ pivot_collection(document& doc);
+ ~pivot_collection();
+
+ /**
+ * Insert a new pivot cache associated with a worksheet source.
+ *
+ * @param sheet_name name of the sheet where the source data is.
+ * @param range range of the source data. Note that the sheet indices are
+ * not used.
+ * @param cache pivot cache instance to store.
+ */
+ void insert_worksheet_cache(
+ std::string_view sheet_name, const ixion::abs_range_t& range, std::unique_ptr<pivot_cache>&& cache);
+
+ /**
+ * Insert a new pivot cache associated with a table name.
+ *
+ * @param table_name source table name.
+ * @param cache pivot cache instance to store.
+ */
+ void insert_worksheet_cache(std::string_view table_name, std::unique_ptr<pivot_cache>&& cache);
+
+ /**
+ * Count the number of pivot caches currently stored.
+ *
+ * @return number of pivot caches currently stored in the document.
+ */
+ size_t get_cache_count() const;
+
+ const pivot_cache* get_cache(
+ std::string_view sheet_name, const ixion::abs_range_t& range) const;
+
+ pivot_cache* get_cache(pivot_cache_id_t cache_id);
+
+ const pivot_cache* get_cache(pivot_cache_id_t cache_id) const;
+};
+
+}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/shared_strings.hpp b/include/orcus/spreadsheet/shared_strings.hpp
new file mode 100644
index 0000000..d447cb3
--- /dev/null
+++ b/include/orcus/spreadsheet/shared_strings.hpp
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_SHARED_STRINGS_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_SHARED_STRINGS_HPP
+
+#include "document_types.hpp"
+
+#include <vector>
+#include <memory>
+#include <string>
+
+namespace ixion { class model_context; }
+
+namespace orcus {
+
+namespace spreadsheet {
+
+/**
+ * This class manages access to a pool of shared string instances for both
+ * unformatted strings and rich-text strings. The underlying string values
+ * themselves are stored externally in the `ixion::model_context` instance
+ * which this class references; this class itself only stores the format
+ * properties of the rich-text strings.
+ */
+class ORCUS_SPM_DLLPUBLIC shared_strings
+{
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+
+public:
+ shared_strings() = delete;
+ shared_strings(const shared_strings&) = delete;
+ shared_strings& operator=(const shared_strings&) = delete;
+
+ shared_strings(ixion::model_context& cxt);
+ ~shared_strings();
+
+ /**
+ * Set the entire format runs of a string.
+ *
+ * @param sindex index of the string to associate the format runs with.
+ * @param runs format runs.
+ */
+ void set_format_runs(std::size_t sindex, std::unique_ptr<format_runs_t> runs);
+
+ /**
+ * Get the entire format runs of a string.
+ *
+ * @param index index of the string to get the format runs of.
+ *
+ * @return pointer to the format runs, or @p nullptr if no format runs exist
+ * for the specified string index.
+ */
+ const format_runs_t* get_format_runs(std::size_t index) const;
+
+ /**
+ * Get an underlying string value associated with an index.
+ *
+ * @param index index of a string value.
+ *
+ * @return pointer to a string value associated with the index, or @p
+ * nullptr in case of an invalid string index.
+ */
+ const std::string* get_string(std::size_t index) const;
+
+ void dump(std::ostream& os) const;
+};
+
+}}
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/sheet.hpp b/include/orcus/spreadsheet/sheet.hpp
new file mode 100644
index 0000000..2ea6392
--- /dev/null
+++ b/include/orcus/spreadsheet/sheet.hpp
@@ -0,0 +1,150 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_ODSTABLE_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_ODSTABLE_HPP
+
+#include "../env.hpp"
+#include "types.hpp"
+
+#include <ostream>
+#include <memory>
+
+#include <ixion/address.hpp>
+#include <ixion/formula_tokens.hpp>
+#include <ixion/formula_result.hpp>
+
+namespace orcus {
+
+struct date_time_t;
+
+namespace spreadsheet {
+
+class document;
+struct auto_filter_t;
+
+namespace detail {
+
+struct sheet_impl;
+
+}
+
+/**
+ * This class represents a single sheet instance in the internal document
+ * model.
+ */
+class ORCUS_SPM_DLLPUBLIC sheet
+{
+ friend class document;
+ friend struct detail::sheet_impl;
+
+ static const row_t max_row_limit;
+ static const col_t max_col_limit;
+
+public:
+ sheet(document& doc, sheet_t sheet_index);
+ ~sheet() noexcept;
+
+ void set_auto(row_t row, col_t col, std::string_view s);
+ void set_string(row_t row, col_t col, string_id_t sindex);
+ void set_value(row_t row, col_t col, double value);
+ void set_bool(row_t row, col_t col, bool value);
+ void set_date_time(row_t row, col_t col, int year, int month, int day, int hour, int minute, double second);
+ void set_format(row_t row, col_t col, size_t index);
+ void set_format(row_t row_start, col_t col_start, row_t row_end, col_t col_end, size_t index);
+ void set_column_format(col_t col, col_t col_span, std::size_t index);
+ void set_row_format(row_t row, std::size_t index);
+
+ void set_formula(row_t row, col_t col, const ixion::formula_tokens_store_ptr_t& tokens);
+ void set_formula(row_t row, col_t col, const ixion::formula_tokens_store_ptr_t& tokens, ixion::formula_result result);
+ void set_grouped_formula(const range_t& range, ixion::formula_tokens_t tokens);
+ void set_grouped_formula(const range_t& range, ixion::formula_tokens_t tokens, ixion::formula_result result);
+
+ void set_col_width(col_t col, col_t col_span, col_width_t width);
+
+ /**
+ * Get column width in twips.
+ *
+ * @param col column index
+ * @param col_start pointer to a variable to store the index of the starting
+ * column of the range with the same width. Pass nullptr if
+ * the caller doesn't need this information.
+ * @param col_end pointer to a variable to store the index of the ending
+ * column plus one, of the range with the same width. Pass
+ * nullptr if the caller doesn't need this information.
+ *
+ * @return width of the specified column index (in twips).
+ */
+ col_width_t get_col_width(col_t col, col_t* col_start, col_t* col_end) const;
+
+ void set_col_hidden(col_t col, col_t col_span, bool hidden);
+ bool is_col_hidden(col_t col, col_t* col_start, col_t* col_end) const;
+
+ void set_row_height(row_t row, row_height_t height);
+ row_height_t get_row_height(row_t row, row_t* row_start, row_t* row_end) const;
+
+ void set_row_hidden(row_t row, bool hidden);
+ bool is_row_hidden(row_t row, row_t* row_start, row_t* row_end) const;
+
+ void set_merge_cell_range(const range_t& range);
+
+ void fill_down_cells(row_t src_row, col_t src_col, row_t range_size);
+
+ /**
+ * Return the size of a merged cell range.
+ *
+ * @param row row position of the upper-left cell.
+ * @param col column position of the upper-left cell.
+ *
+ * @return merged cell range.
+ */
+ range_t get_merge_cell_range(row_t row, col_t col) const;
+
+ size_t get_string_identifier(row_t row, col_t col) const;
+
+ auto_filter_t* get_auto_filter_data();
+ const auto_filter_t* get_auto_filter_data() const;
+ void set_auto_filter_data(auto_filter_t* p);
+
+ // Sheet dimension methods
+
+ /**
+ * Return the smallest range that contains all non-empty cells in this
+ * sheet. The top-left corner of the returned range is always column 0 and
+ * row 0.
+ *
+ * @return smallest range that contains all non-empty cells.
+ */
+ ixion::abs_range_t get_data_range() const;
+
+ sheet_t get_index() const;
+
+ date_time_t get_date_time(row_t row, col_t col) const;
+
+ void dump_flat(std::ostream& os) const;
+ void dump_check(std::ostream& os, std::string_view sheet_name) const;
+ void dump_html(std::ostream& os) const;
+ void dump_json(std::ostream& os) const;
+ void dump_csv(std::ostream& os) const;
+
+ void dump_debug_state(const std::string& output_dir, std::string_view sheet_name) const;
+
+ /**
+ * Get the cell format ID of specified cell.
+ */
+ size_t get_cell_format(row_t row, col_t col) const;
+
+private:
+ void finalize_import();
+
+ std::unique_ptr<detail::sheet_impl> mp_impl;
+};
+
+}}
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/styles.hpp b/include/orcus/spreadsheet/styles.hpp
new file mode 100644
index 0000000..5458b1f
--- /dev/null
+++ b/include/orcus/spreadsheet/styles.hpp
@@ -0,0 +1,268 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_STYLES_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_STYLES_HPP
+
+#include "../env.hpp"
+#include "../measurement.hpp"
+#include "document_types.hpp"
+
+#include <memory>
+#include <string_view>
+#include <optional>
+
+namespace orcus { namespace spreadsheet {
+
+class document;
+
+/**
+ * Font style record.
+ */
+struct ORCUS_SPM_DLLPUBLIC font_t
+{
+ std::optional<std::string_view> name;
+ std::optional<std::string_view> name_asian;
+ std::optional<std::string_view> name_complex;
+ std::optional<double> size;
+ std::optional<double> size_asian;
+ std::optional<double> size_complex;
+ std::optional<bool> bold;
+ std::optional<bool> bold_asian;
+ std::optional<bool> bold_complex;
+ std::optional<bool> italic;
+ std::optional<bool> italic_asian;
+ std::optional<bool> italic_complex;
+ std::optional<underline_t> underline_style;
+ std::optional<underline_width_t> underline_width;
+ std::optional<underline_mode_t> underline_mode;
+ std::optional<underline_type_t> underline_type;
+ std::optional<color_t> underline_color;
+ std::optional<color_t> color;
+ std::optional<strikethrough_style_t> strikethrough_style;
+ std::optional<strikethrough_width_t> strikethrough_width;
+ std::optional<strikethrough_type_t> strikethrough_type;
+ std::optional<strikethrough_text_t> strikethrough_text;
+
+ font_t();
+ font_t(const font_t& other);
+ ~font_t();
+
+ font_t& operator=(const font_t& other);
+
+ bool operator==(const font_t& other) const;
+ bool operator!=(const font_t& other) const;
+
+ void reset();
+
+ struct ORCUS_SPM_DLLPUBLIC hash
+ {
+ std::size_t operator()(const font_t& v) const;
+ };
+};
+
+/**
+ * Fill style record.
+ */
+struct ORCUS_SPM_DLLPUBLIC fill_t
+{
+ std::optional<fill_pattern_t> pattern_type;
+ std::optional<color_t> fg_color;
+ std::optional<color_t> bg_color;
+
+ fill_t();
+ void reset();
+};
+
+/**
+ * Attributes for a single border.
+ */
+struct ORCUS_SPM_DLLPUBLIC border_attrs_t
+{
+ std::optional<border_style_t> style;
+ std::optional<color_t> border_color;
+ std::optional<length_t> border_width;
+
+ border_attrs_t();
+ void reset();
+};
+
+/**
+ * Style record for the borders of a single cell.
+ */
+struct ORCUS_SPM_DLLPUBLIC border_t
+{
+ border_attrs_t top;
+ border_attrs_t bottom;
+ border_attrs_t left;
+ border_attrs_t right;
+ border_attrs_t diagonal;
+ border_attrs_t diagonal_bl_tr;
+ border_attrs_t diagonal_tl_br;
+
+ border_t();
+ void reset();
+};
+
+/**
+ * Style record for cell protection attributes.
+ */
+struct ORCUS_SPM_DLLPUBLIC protection_t
+{
+ std::optional<bool> locked;
+ std::optional<bool> hidden;
+ std::optional<bool> print_content;
+ std::optional<bool> formula_hidden;
+
+ protection_t();
+ void reset();
+};
+
+/**
+ * Style record for a number format.
+ */
+struct ORCUS_SPM_DLLPUBLIC number_format_t
+{
+ std::optional<std::size_t> identifier;
+ std::optional<std::string_view> format_string;
+
+ number_format_t();
+ void reset();
+
+ bool operator== (const number_format_t& other) const noexcept;
+ bool operator!= (const number_format_t& other) const noexcept;
+};
+
+/**
+ * Format attributes for a single cell. It references the format entries via
+ * integer indices, with some exceptions.
+ */
+struct ORCUS_SPM_DLLPUBLIC cell_format_t
+{
+ /** ID of a font style record. */
+ std::size_t font;
+ /** ID of a fill style record. */
+ std::size_t fill;
+ /** ID of a border style record. */
+ std::size_t border;
+ /** ID for a cell protection record. */
+ std::size_t protection;
+ /** ID for a number format record. */
+ std::size_t number_format;
+ /** ID for a parent named style. */
+ std::size_t style_xf;
+ /** Horizontal alignment of a cell. */
+ hor_alignment_t hor_align;
+ /** Vertical alignment of a cell. */
+ ver_alignment_t ver_align;
+ /** Flag on whether or not wrap text is enabled. */
+ std::optional<bool> wrap_text;
+ /** Flag on whether or not shrink to fit is enabled. */
+ std::optional<bool> shrink_to_fit;
+ bool apply_num_format:1;
+ bool apply_font:1;
+ bool apply_fill:1;
+ bool apply_border:1;
+ bool apply_alignment:1;
+ bool apply_protection:1;
+
+ cell_format_t();
+ void reset();
+};
+
+/**
+ * Attributes of a named cell style.
+ *
+ * Refer to @ref orcus::spreadsheet::iface::import_cell_style for how the data
+ * members of this struct are used in practice.
+ */
+struct ORCUS_SPM_DLLPUBLIC cell_style_t
+{
+ std::string_view name;
+ std::string_view display_name;
+ std::size_t xf;
+ std::size_t builtin;
+ std::string_view parent_name;
+
+ cell_style_t();
+ void reset();
+};
+
+ORCUS_SPM_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const color_t& c);
+
+/**
+ * Stores various styles records such that they can be referenced via integer
+ * indices.
+ */
+class ORCUS_SPM_DLLPUBLIC styles
+{
+ friend class document;
+
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+
+public:
+ styles();
+ ~styles();
+
+ void reserve_font_store(size_t n);
+ std::size_t append_font(const font_t& font);
+
+ void reserve_fill_store(size_t n);
+ std::size_t append_fill(const fill_t& fill);
+
+ void reserve_border_store(size_t n);
+ std::size_t append_border(const border_t& border);
+
+ std::size_t append_protection(const protection_t& protection);
+
+ void reserve_number_format_store(size_t n);
+ std::size_t append_number_format(const number_format_t& nf);
+
+ void reserve_cell_style_format_store(size_t n);
+ size_t append_cell_style_format(const cell_format_t& cf);
+
+ void reserve_cell_format_store(size_t n);
+ size_t append_cell_format(const cell_format_t& cf);
+
+ void reserve_diff_cell_format_store(size_t n);
+ size_t append_diff_cell_format(const cell_format_t& cf);
+
+ void reserve_cell_style_store(size_t n);
+ void append_cell_style(const cell_style_t& cs);
+
+ const font_t* get_font(size_t index) const;
+ const fill_t* get_fill(size_t index) const;
+ const border_t* get_border(size_t index) const;
+ const protection_t* get_protection(size_t index) const;
+ const number_format_t* get_number_format(size_t index) const;
+ const cell_format_t* get_cell_format(size_t index) const;
+ const cell_format_t* get_cell_style_format(size_t index) const;
+ const cell_format_t* get_dxf_format(size_t index) const;
+ const cell_style_t* get_cell_style(size_t index) const;
+ const cell_style_t* get_cell_style_by_xf(size_t xfid) const;
+
+ size_t get_font_count() const;
+ size_t get_fill_count() const;
+ size_t get_border_count() const;
+ size_t get_protection_count() const;
+ size_t get_number_format_count() const;
+ size_t get_cell_formats_count() const;
+ size_t get_cell_style_formats_count() const;
+ size_t get_dxf_count() const;
+ size_t get_cell_styles_count() const;
+
+ void clear();
+
+private:
+ void finalize_import();
+};
+
+}}
+
+#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/types.hpp b/include/orcus/spreadsheet/types.hpp
new file mode 100644
index 0000000..df7b27e
--- /dev/null
+++ b/include/orcus/spreadsheet/types.hpp
@@ -0,0 +1,751 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef ORCUS_SPREADSHEET_TYPES_HPP
+#define ORCUS_SPREADSHEET_TYPES_HPP
+
+#include "../env.hpp"
+
+#include <cstdlib>
+#include <cstdint>
+#include <iosfwd>
+#include <initializer_list>
+#include <string_view>
+#include <vector>
+
+// NB: This header should only define primitive data types, enums and structs.
+
+namespace orcus { namespace spreadsheet {
+
+/** Row ID type. */
+using row_t = int32_t;
+/** Column ID type. */
+using col_t = int32_t;
+/** Sheet ID type. */
+using sheet_t = int32_t;
+/** Individual color element type. */
+using color_elem_t = uint8_t;
+/** Type for column width values. Column width values are stored in twips. */
+using col_width_t = uint16_t;
+/** Type for row height values. Row height values are stored in twips. */
+using row_height_t = uint16_t;
+/** Type for string ID's for string cells. */
+using string_id_t = uint32_t;
+/** Pivot cache ID type. */
+using pivot_cache_id_t = uint32_t;
+
+/**
+ * Get the special column width value that represents the default column
+ * width. The value itself is not to be used as an actual width value.
+ *
+ * @return value that represents the default column width.
+ */
+ORCUS_DLLPUBLIC col_width_t get_default_column_width();
+
+/**
+ * Get the special row height value that represents the default row height.
+ * The value itself is not to be used as an actual row height value.
+ *
+ * @return value that represents the default row height.
+ */
+ORCUS_DLLPUBLIC row_height_t get_default_row_height();
+
+/**
+ * Type of error value in cells.
+ */
+enum class error_value_t
+{
+ /**
+ * Error type unknown, typically used as an initial error value or generic
+ * default value.
+ */
+ unknown = 0,
+ /** Null reference error, displayed as `#NULL!`. */
+ null,
+ /** Division-by-zero error, displayed as `#DIV/0`. */
+ div0,
+ /** Formula expression error, displayed as `#VALUE!`. */
+ value,
+ /** Reference error, displayed as `#REF!`. */
+ ref,
+ /** Invalid named-expression error, displayed as `#NAME?` */
+ name,
+ /** Invalid numeric value error, displayed as `#NUM!`. */
+ num,
+ /** No value is available error, displayed as `#N/A!`. */
+ na
+};
+
+/**
+ * Type of border direction, used to reference the position of a border in a
+ * cell.
+ */
+enum class border_direction_t
+{
+ /** Unknown or uninitialized border direction value. */
+ unknown = 0,
+ /** Top border of a cell. */
+ top,
+ /** Bottom border of a cell. */
+ bottom,
+ /** Left border of a cell. */
+ left,
+ /** Right border of a cell. */
+ right,
+ /**
+ * Cross-diagonal borders of a cell. This is equivalent of both
+ * @p diagonal_bl_tr and @p diagonal_tl_br combined.
+ */
+ diagonal,
+ /** Diagonal border of a cell that runs from bottom-left to top-right. */
+ diagonal_bl_tr,
+ /** Diagonal border of a cell that runs from top-left to bottom-right. */
+ diagonal_tl_br
+};
+
+/**
+ * Type of border style.
+ */
+enum class border_style_t
+{
+ unknown = 0,
+ none,
+ solid,
+ dash_dot,
+ dash_dot_dot,
+ dashed,
+ dotted,
+ double_border,
+ hair,
+ medium,
+ medium_dash_dot,
+ medium_dash_dot_dot,
+ medium_dashed,
+ slant_dash_dot,
+ thick,
+ thin,
+ double_thin,
+ fine_dashed
+};
+
+/**
+ * Type of fill pattern for cell background.
+ */
+enum class fill_pattern_t
+{
+ none = 0,
+ solid,
+ dark_down,
+ dark_gray,
+ dark_grid,
+ dark_horizontal,
+ dark_trellis,
+ dark_up,
+ dark_vertical,
+ gray_0625,
+ gray_125,
+ light_down,
+ light_gray,
+ light_grid,
+ light_horizontal,
+ light_trellis,
+ light_up,
+ light_vertical,
+ medium_gray
+};
+
+/**
+ * Strikethrough style as applied to a cell value.
+ *
+ * @note This is specific to ODS format.
+ */
+enum class strikethrough_style_t
+{
+ none = 0,
+ solid,
+ dash,
+ dot_dash,
+ dot_dot_dash,
+ dotted,
+ long_dash,
+ wave
+};
+
+/**
+ * Strikethrough type as applied to a cell value.
+ *
+ * @note This is specific to ODS format.
+ */
+enum class strikethrough_type_t
+{
+ unknown = 0,
+ none,
+ single_type,
+ double_type
+};
+
+/**
+ * Width of strikethrough applied to a cell value.
+ *
+ * @note This is specific to ODS format.
+ */
+enum class strikethrough_width_t
+{
+ unknown = 0,
+ width_auto,
+ thin,
+ medium,
+ thick,
+ bold
+};
+
+/**
+ * Text used for strike-through.
+ *
+ * @note This is specific to ODS format.
+ */
+enum class strikethrough_text_t
+{
+ unknown = 0,
+ /** `/` is used as the text. */
+ slash,
+ /** `X` is used as the text. */
+ cross
+};
+
+/**
+ * Type that specifies the grammar of a formula expression. Each grammar
+ * may exhibit a different set of syntax rules.
+ */
+enum class formula_grammar_t
+{
+ /** Grammar type is either unknown or unspecified. */
+ unknown = 0,
+ /** Grammar used by the Excel 2003 XML (aka XML Spreadsheet) format. */
+ xls_xml,
+ /** Grammar used by the Office Open XML spreadsheet format. */
+ xlsx,
+ /** Grammar used by the OpenDocument Spreadsheet format. */
+ ods,
+ /** Grammar used by the Gnumeric XML format. */
+ gnumeric
+};
+
+/**
+ * Type of formula expression.
+ */
+enum class formula_t
+{
+ /** Formula expression type unknown, or generic default value. */
+ unknown = 0,
+ /** Formula expression in an array of cells. */
+ array,
+ /** Formula expression in a data table. */
+ data_table,
+ /** Formula expression in a normal formula cell. */
+ normal,
+ /** Formula expression in a shared formula cell. */
+ shared
+};
+
+/**
+ * Formula reference context specifies the location where a formula
+ * expression is used. This is used mainly for those document formats that
+ * make use of multiple formula reference syntaxes, such as ODS.
+ */
+enum class formula_ref_context_t
+{
+ /**
+ * Default context, that is, the context that is NOT any of the other
+ * contexts specified below.
+ */
+ global = 0,
+
+ /** Base cell position of either a named range or expression. */
+ named_expression_base,
+
+ /**
+ * Named range is a special case of named expression where the expression
+ * consists of only one range token.
+ */
+ named_range,
+};
+
+/**
+ * Type of policy on how to handle a formula cell with an erroneous expression
+ * that has been parsed unsuccessfully.
+ */
+enum class formula_error_policy_t
+{
+ unknown,
+ /** Loading of the document will be halted. */
+ fail,
+ /** The error cell will be skipped. */
+ skip
+};
+
+/**
+ * Underline type for a cell value.
+ */
+enum class underline_t
+{
+ /** Underline is absent. */
+ none = 0,
+ /** Underline consists of a single line. */
+ single_line,
+ /**
+ * Single line for accounting format.
+ *
+ * @note This is unique to xlsx format.
+ */
+ single_accounting,
+ /** Underline consists of a double line. */
+ double_line,
+ /**
+ * Double line for accounting format.
+ *
+ * @note This is unique to xlsx format.
+ */
+ double_accounting,
+ /** Underline is dotted. */
+ dotted,
+ /** Underline is dashed. */
+ dash,
+ /** Underline consists of repeated long dash segments. */
+ long_dash,
+ /** Underline consists of repeated dot and dash segments. */
+ dot_dash,
+ /** Underline consists of repeated dot, dot and dash segments. */
+ dot_dot_dash,
+ /** Underline is waved. */
+ wave
+};
+
+/**
+ * Underline width types, specific to ODF. When the enum value is either
+ * percent, positive_integer, or positive_length, the actual value should be
+ * given separately.
+ *
+ * @note The automatic enum value corresponds with the "auto" text value,
+ * which could not be used since it's a keyword in C++.
+ */
+enum class underline_width_t
+{
+ none = 0,
+ automatic,
+ bold,
+ dash,
+ medium,
+ thick,
+ thin,
+ percent,
+ positive_integer,
+ positive_length
+};
+
+/**
+ * Underline mode that determines whether an underline is applied to both
+ * words and spaces, or words only.
+ *
+ * @note This is specific to ODS format.
+ */
+enum class underline_mode_t
+{
+ /** Underline is applied to both words and spaces. */
+ continuous = 0,
+ /** Underline is applied only to words. */
+ skip_white_space
+};
+
+/**
+ * Whether a single line or a double line is used as an underline.
+ *
+ * @todo Perhaps we should merge this with underline_t.
+ */
+enum class underline_type_t
+{
+ none = 0,
+ /** A single line is used as an underline. */
+ single_type,
+ /** A double line is used as an underline. */
+ double_type
+};
+
+/**
+ * Type of horizontal alignment applied to a cell content.
+ */
+enum class hor_alignment_t
+{
+ unknown = 0,
+ left,
+ center,
+ right,
+ justified,
+ distributed,
+ filled
+};
+
+/**
+ * Type of vertical alignment applied to a cell content.
+ */
+enum class ver_alignment_t
+{
+ unknown = 0,
+ top,
+ middle,
+ bottom,
+ justified,
+ distributed
+};
+
+/**
+ * Cell format categories. The abbreviation "xf" stands for "cell format"
+ * where the "x" is short for cell.
+ */
+enum class xf_category_t
+{
+ unknown,
+ /** Direct cell format, also often referenced as xf. */
+ cell,
+ /** Cell format for named styles. */
+ cell_style,
+ /** Incremental cell format, also referenced as dxf. */
+ differential,
+};
+
+/**
+ * Type of data table. A data table can be either of a single-variable
+ * column, a single-variable row, or a double-variable type that uses both
+ * column and row input cells.
+ */
+enum class data_table_type_t
+{
+ column,
+ row,
+ both
+};
+
+/**
+ * Function type used in the totals row of a table.
+ */
+enum class totals_row_function_t
+{
+ none = 0,
+ sum,
+ minimum,
+ maximum,
+ average,
+ count,
+ count_numbers,
+ standard_deviation,
+ variance,
+ custom
+};
+
+/**
+ * Type of conditional format.
+ */
+enum class conditional_format_t
+{
+ unknown = 0,
+ condition,
+ date,
+ formula,
+ colorscale,
+ databar,
+ iconset
+};
+
+/**
+ * Operator type associated with a conditional format rule.
+ */
+enum class condition_operator_t
+{
+ unknown = 0,
+ equal,
+ less,
+ greater,
+ greater_equal,
+ less_equal,
+ not_equal,
+ between,
+ not_between,
+ duplicate,
+ unique,
+ top_n,
+ bottom_n,
+ above_average,
+ below_average,
+ above_equal_average,
+ below_equal_average,
+ contains_error,
+ contains_no_error,
+ begins_with,
+ ends_with,
+ contains,
+ contains_blanks,
+ not_contains,
+ expression
+};
+
+/**
+ * Type of a condition in a conditional format rule. This is applicable only
+ * when the type of a conditional format entry is either:
+ *
+ * @li @p colorscale,
+ * @li @p databar or
+ * @li @p iconset.
+ */
+enum class condition_type_t
+{
+ unknown = 0,
+ value,
+ automatic,
+ max,
+ min,
+ formula,
+ percent,
+ percentile
+};
+
+/**
+ * Type of a date condition when the type of a conditional format entry is
+ * @p date.
+ */
+enum class condition_date_t
+{
+ unknown = 0,
+ today,
+ yesterday,
+ tomorrow,
+ last_7_days,
+ this_week,
+ next_week,
+ last_week,
+ this_month,
+ next_month,
+ last_month,
+ this_year,
+ next_year,
+ last_year,
+};
+
+/**
+ * Databar axis type, applicable only when the type of a conditional format
+ * entry is @p databar.
+ */
+enum class databar_axis_t
+{
+ none = 0,
+ middle,
+ automatic
+};
+
+/**
+ * Type of range grouping in a group field of a pivot table cache.
+ */
+enum class pivot_cache_group_by_t
+{
+ /**
+ * Type of range grouping is unknown.
+ *
+ * This is an implicit default value of this type.
+ */
+ unknown = 0,
+ /** Grouping on "days" for date values. */
+ days,
+ /** Grouping on "hours" for date values. */
+ hours,
+ /** Grouping on "minutes" for date values. */
+ minutes,
+ /** Grouping on "months" for date values. */
+ months,
+ /** Grouping on "quarters" for date values. */
+ quarters,
+ /** Grouping by numeric ranges for numeric values. */
+ range,
+ /** Grouping on "seconds" for date values. */
+ seconds,
+ /** Grouping on "years" for date values. */
+ years
+};
+
+/**
+ * Stores a 2-dimensional cell address.
+ */
+struct address_t
+{
+ row_t row;
+ col_t column;
+};
+
+/**
+ * Stores the size of a range of a spreadsheet.
+ */
+struct range_size_t
+{
+ row_t rows;
+ col_t columns;
+};
+
+/**
+ * Stores a 2-dimensional cell range by storing the positions of the top-left
+ * and bottom-right corners of the range.
+ */
+struct range_t
+{
+ address_t first;
+ address_t last;
+};
+
+/**
+ * Stores 3-dimensional cell address. The 'src' abbreviation stands for
+ * sheet-row-column.
+ */
+struct src_address_t
+{
+ sheet_t sheet;
+ row_t row;
+ col_t column;
+};
+
+/**
+ * Stores 3-dimensional cell range address. The 'src' abbreviation stands for
+ * sheet-row-column.
+ */
+struct src_range_t
+{
+ src_address_t first;
+ src_address_t last;
+};
+
+/**
+ * Convert a 3-dimensional cell address to a 2-dimensional counterpart by
+ * dropping the sheet index.
+ */
+ORCUS_DLLPUBLIC address_t to_rc_address(const src_address_t& r);
+
+/**
+ * Convert a 3-dimensional cell range address to a 2-dimensional counterpart
+ * by dropping the sheet indices.
+ */
+ORCUS_DLLPUBLIC range_t to_rc_range(const src_range_t& r);
+
+ORCUS_DLLPUBLIC bool operator== (const address_t& left, const address_t& right);
+ORCUS_DLLPUBLIC bool operator!= (const address_t& left, const address_t& right);
+
+ORCUS_DLLPUBLIC bool operator== (const src_address_t& left, const src_address_t& right);
+ORCUS_DLLPUBLIC bool operator!= (const src_address_t& left, const src_address_t& right);
+
+ORCUS_DLLPUBLIC bool operator== (const range_t& left, const range_t& right);
+ORCUS_DLLPUBLIC bool operator!= (const range_t& left, const range_t& right);
+
+ORCUS_DLLPUBLIC bool operator== (const src_range_t& left, const src_range_t& right);
+ORCUS_DLLPUBLIC bool operator!= (const src_range_t& left, const src_range_t& right);
+
+ORCUS_DLLPUBLIC bool operator< (const range_t& left, const range_t& right);
+ORCUS_DLLPUBLIC bool operator> (const range_t& left, const range_t& right);
+
+ORCUS_DLLPUBLIC range_t& operator+= (range_t& left, const address_t& right);
+ORCUS_DLLPUBLIC range_t& operator-= (range_t& left, const address_t& right);
+
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const address_t& v);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const src_address_t& v);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const range_t& v);
+
+/**
+ * Stores a color value in RGB format.
+ */
+struct color_rgb_t
+{
+ color_elem_t red;
+ color_elem_t green;
+ color_elem_t blue;
+};
+
+/**
+ * Convert a string representation of a totals row function name to its
+ * equivalent enum value.
+ *
+ * @param s string value for totals row function name.
+ *
+ * @return enum value representing the totals row function.
+ */
+ORCUS_DLLPUBLIC totals_row_function_t to_totals_row_function_enum(std::string_view s);
+
+/**
+ * Convert a string representation of a pivot cache group-by type to its
+ * equivalent enum value.
+ *
+ * @param s string value for pivot cache group-by type.
+ *
+ * @return enum value representing the pivot cache group-by type.
+ */
+ORCUS_DLLPUBLIC pivot_cache_group_by_t to_pivot_cache_group_by_enum(std::string_view s);
+
+/**
+ * Convert a string representation of a error value to its equivalent enum
+ * value.
+ *
+ * @param s error value string.
+ *
+ * @return enum value representing the error value.
+ */
+ORCUS_DLLPUBLIC error_value_t to_error_value_enum(std::string_view s);
+
+/**
+ * Convert a string representation of a RGB value to an equivalent struct
+ * value. The string representation is expected to be a 6 digit hexadecimal
+ * value string that may or may not be prefixed with a '#'.
+ *
+ * @param s string representation of the RGB value.
+ *
+ * @return struct value representing an RGB value.
+ */
+ORCUS_DLLPUBLIC color_rgb_t to_color_rgb(std::string_view s);
+
+/**
+ * Convert a color name to an RGB value. It supports SVG 1.0 color keyword
+ * names minus those gray colors with 'grey' spelling variants. Note that
+ * the name must be all in lowercase.
+ *
+ * @param s color name.
+ *
+ * @return struct value representing an RGB value.
+ */
+ORCUS_DLLPUBLIC color_rgb_t to_color_rgb_from_name(std::string_view s);
+
+/**
+ * Convert a formula error policy name to its enum value equivalent.
+ *
+ * @param s policy name.
+ *
+ * @return enum value equivalent for the original error policy name.
+ */
+ORCUS_DLLPUBLIC formula_error_policy_t to_formula_error_policy(std::string_view s);
+
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, error_value_t ev);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, border_style_t border);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, formula_grammar_t grammar);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, underline_t uline);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, underline_width_t ulwidth);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, underline_mode_t ulmode);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, underline_type_t ultype);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, hor_alignment_t halign);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, ver_alignment_t valign);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const color_rgb_t& color);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const fill_pattern_t& fill);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const strikethrough_style_t& ss);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const strikethrough_type_t& st);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const strikethrough_width_t& sw);
+ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const strikethrough_text_t& st);
+
+}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/view.hpp b/include/orcus/spreadsheet/view.hpp
new file mode 100644
index 0000000..7b5552f
--- /dev/null
+++ b/include/orcus/spreadsheet/view.hpp
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_ORCUS_SPREADSHEET_VIEW_HPP
+#define INCLUDED_ORCUS_SPREADSHEET_VIEW_HPP
+
+#include "orcus/env.hpp"
+#include "orcus/spreadsheet/types.hpp"
+#include "orcus/spreadsheet/view_types.hpp"
+
+#include <memory>
+
+namespace orcus { namespace spreadsheet {
+
+class sheet_view;
+class document;
+
+class ORCUS_SPM_DLLPUBLIC view
+{
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+public:
+ view(document& doc);
+ ~view();
+
+ sheet_view* get_or_create_sheet_view(sheet_t sheet);
+ const sheet_view* get_sheet_view(sheet_t sheet) const;
+
+ void set_active_sheet(sheet_t sheet);
+ sheet_t get_active_sheet() const;
+};
+
+class ORCUS_SPM_DLLPUBLIC sheet_view
+{
+ struct impl;
+ std::unique_ptr<impl> mp_impl;
+public:
+ sheet_view(view& doc_view);
+ ~sheet_view();
+
+ const range_t& get_selection(sheet_pane_t pos) const;
+
+ void set_selection(sheet_pane_t pos, const range_t& range);
+
+ void set_active_pane(sheet_pane_t pos);
+ sheet_pane_t get_active_pane() const;
+
+ void set_split_pane(double hor_split, double ver_split, const address_t& top_left_cell);
+ const split_pane_t& get_split_pane() const;
+
+ void set_frozen_pane(col_t visible_cols, row_t visible_rows, const address_t& top_left_cell);
+ const frozen_pane_t& get_frozen_pane() const;
+
+ view& get_document_view();
+};
+
+}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/orcus/spreadsheet/view_types.hpp b/include/orcus/spreadsheet/view_types.hpp
new file mode 100644
index 0000000..ae6e728
--- /dev/null
+++ b/include/orcus/spreadsheet/view_types.hpp
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef ORCUS_SPREADSHEET_VIEW_TYPES_HPP
+#define ORCUS_SPREADSHEET_VIEW_TYPES_HPP
+
+#include "orcus/spreadsheet/types.hpp"
+
+namespace orcus { namespace spreadsheet {
+
+/**
+ * Sheet pane position in a split sheet view. When the sheet is split, it is
+ * split into four panes.
+ */
+enum class sheet_pane_t : uint8_t
+{
+ unspecified = 0,
+ /** Top-left pane. */
+ top_left,
+ /** Top-right pane. */
+ top_right,
+ /** Bottom-left pane. */
+ bottom_left,
+ /** Bottom-right pane. */
+ bottom_right
+};
+
+/**
+ * State of a split pane - whether it's frozen, split, or both.
+ */
+enum class pane_state_t : uint8_t
+{
+ /** The state of the pane is not specified. */
+ unspecified = 0,
+ /** The pane is frozen. */
+ frozen,
+ /** The pane is split. */
+ split,
+ /** The pane is both frozen and split. */
+ frozen_split
+};
+
+/**
+ * Store information about the state of a split sheet view.
+ */
+struct split_pane_t
+{
+ /**
+ * Horizontal distance to the vertical split bar in 1/20th of a point, or
+ * 0 if not horizontally split.
+ */
+ double hor_split;
+
+ /**
+ * Vertical distance to the horizontal split bar in 1/20th of a point, or
+ * 0 if not vertically split.
+ */
+ double ver_split;
+
+ /**
+ * Top-left visible cell of the bottom-right pane. This value is valid
+ * only when either the horizontal distance or the vertical distance is
+ * non-zero.
+ */
+ address_t top_left_cell;
+};
+
+/**
+ * Store the state of a frozen sheet view.
+ */
+struct frozen_pane_t
+{
+ /**
+ * The number of visible columns in the top-left pane.
+ */
+ col_t visible_columns;
+ /**
+ * The number of visible rows in the top-left pane.
+ */
+ row_t visible_rows;
+ /**
+ * The position of the top-left cell in the bottom-right pane.
+ */
+ address_t top_left_cell;
+};
+
+}}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */