diff options
Diffstat (limited to 'include/orcus/spreadsheet')
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: */ |