summaryrefslogtreecommitdiff
path: root/starmath
diff options
context:
space:
mode:
Diffstat (limited to 'starmath')
-rw-r--r--starmath/AllLangResTarget_sm.mk44
-rw-r--r--starmath/JunitTest_starmath_unoapi.mk49
-rw-r--r--starmath/Library_sm.mk107
-rw-r--r--starmath/Library_smd.mk58
-rw-r--r--starmath/Makefile33
-rw-r--r--starmath/Module_starmath.mk34
-rw-r--r--starmath/Package_uiconfig.mk28
-rw-r--r--starmath/inc/action.hxx54
-rw-r--r--starmath/inc/applicat.hxx69
-rw-r--r--starmath/inc/caret.hxx480
-rw-r--r--starmath/inc/config.hxx60
-rw-r--r--starmath/inc/cursor.hxx482
-rw-r--r--starmath/inc/dialog.hxx519
-rw-r--r--starmath/inc/document.hxx248
-rw-r--r--starmath/inc/edit.hxx151
-rw-r--r--starmath/inc/format.hxx173
-rw-r--r--starmath/inc/helpids.h326
-rw-r--r--starmath/inc/makefile.mk47
-rw-r--r--starmath/inc/node.hxx1227
-rw-r--r--starmath/inc/parse.hxx303
-rw-r--r--starmath/inc/pch/precompiled_starmath.cxx31
-rw-r--r--starmath/inc/pch/precompiled_starmath.hxx34
-rw-r--r--starmath/inc/rect.hxx256
-rw-r--r--starmath/inc/smcommands.h68
-rw-r--r--starmath/inc/smdll.hxx52
-rw-r--r--starmath/inc/smmod.hxx178
-rwxr-xr-xstarmath/inc/starmath.hrc463
-rw-r--r--starmath/inc/symbol.hxx192
-rw-r--r--starmath/inc/toolbox.hxx89
-rw-r--r--starmath/inc/types.hxx208
-rw-r--r--starmath/inc/unomodel.hxx111
-rw-r--r--starmath/inc/utility.hxx270
-rw-r--r--starmath/inc/view.hxx333
-rw-r--r--starmath/inc/visitors.hxx499
-rw-r--r--starmath/prj/build.lst9
-rw-r--r--starmath/prj/d.lst23
-rw-r--r--starmath/prj/gbuild.lst2
-rw-r--r--starmath/prj/makefile.mk40
-rw-r--r--starmath/qa/cppunit/makefile.mk147
-rw-r--r--starmath/qa/cppunit/test_nodetotextvisitors.cxx683
-rw-r--r--starmath/qa/cppunit/test_starmath.cxx457
-rw-r--r--starmath/qa/cppunit/version.map34
-rw-r--r--starmath/qa/unoapi/knownissues.xcl21
-rw-r--r--starmath/qa/unoapi/sm.sce9
-rw-r--r--starmath/sdi/makefile.mk58
-rwxr-xr-xstarmath/sdi/smath.sdi964
-rw-r--r--starmath/sdi/smitems.sdi595
-rwxr-xr-xstarmath/sdi/smslots.sdi332
-rw-r--r--starmath/source/accessibility.cxx1986
-rw-r--r--starmath/source/accessibility.hxx402
-rw-r--r--starmath/source/action.cxx69
-rw-r--r--starmath/source/caret.cxx66
-rw-r--r--starmath/source/cfgitem.cxx1302
-rw-r--r--starmath/source/cfgitem.hxx207
-rw-r--r--starmath/source/commands.src1561
-rw-r--r--starmath/source/config.cxx133
-rw-r--r--starmath/source/cursor.cxx1646
-rw-r--r--starmath/source/detreg.cxx91
-rw-r--r--starmath/source/dialog.cxx2441
-rwxr-xr-xstarmath/source/dialog.hrc52
-rw-r--r--starmath/source/document.cxx1439
-rw-r--r--starmath/source/edit.cxx995
-rw-r--r--starmath/source/eqnolefilehdr.cxx92
-rw-r--r--starmath/source/eqnolefilehdr.hxx65
-rw-r--r--starmath/source/format.cxx244
-rwxr-xr-xstarmath/source/makefile.mk113
-rw-r--r--starmath/source/math_pch.cxx433
-rw-r--r--starmath/source/mathmlexport.cxx1508
-rw-r--r--starmath/source/mathmlexport.hxx144
-rw-r--r--starmath/source/mathmlimport.cxx3042
-rw-r--r--starmath/source/mathmlimport.hxx348
-rw-r--r--starmath/source/mathtype.cxx3372
-rw-r--r--starmath/source/mathtype.hxx179
-rw-r--r--starmath/source/node.cxx3152
-rw-r--r--starmath/source/parse.cxx2527
-rw-r--r--starmath/source/rect.cxx696
-rw-r--r--starmath/source/register.cxx235
-rw-r--r--starmath/source/smdetect.cxx476
-rw-r--r--starmath/source/smdetect.hxx98
-rw-r--r--starmath/source/smdll.cxx108
-rw-r--r--starmath/source/smmod.cxx375
-rw-r--r--starmath/source/smres.src1670
-rw-r--r--starmath/source/symbol.cxx338
-rw-r--r--starmath/source/symbol.src344
-rw-r--r--starmath/source/toolbox.cxx383
-rwxr-xr-xstarmath/source/toolbox.hrc46
-rw-r--r--starmath/source/toolbox.src1777
-rw-r--r--starmath/source/typemap.cxx138
-rw-r--r--starmath/source/types.cxx55
-rw-r--r--starmath/source/unodoc.cxx73
-rw-r--r--starmath/source/unomodel.cxx1143
-rw-r--r--starmath/source/utility.cxx378
-rw-r--r--starmath/source/view.cxx2124
-rw-r--r--starmath/source/visitors.cxx2541
-rwxr-xr-xstarmath/uiconfig/smath/menubar/menubar.xml121
-rw-r--r--starmath/uiconfig/smath/statusbar/statusbar.xml8
-rw-r--r--starmath/uiconfig/smath/toolbar/fullscreenbar.xml5
-rw-r--r--starmath/uiconfig/smath/toolbar/standardbar.xml26
-rw-r--r--starmath/uiconfig/smath/toolbar/toolbar.xml12
-rw-r--r--starmath/util/hidother.src116
-rw-r--r--starmath/util/makefile.mk127
-rw-r--r--starmath/util/sm.component61
-rw-r--r--starmath/util/smd.component34
-rw-r--r--starmath/visual-editor-todo43
-rwxr-xr-xstarmath/workben/smath-dump-watch.sh26
-rw-r--r--starmath/xml/math.xml92
106 files changed, 51928 insertions, 0 deletions
diff --git a/starmath/AllLangResTarget_sm.mk b/starmath/AllLangResTarget_sm.mk
new file mode 100644
index 000000000000..5f606d97efa6
--- /dev/null
+++ b/starmath/AllLangResTarget_sm.mk
@@ -0,0 +1,44 @@
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Norbert Thiebaud <nthiebaud@gmail.com> (C) 2010, All Rights Reserved.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+
+$(eval $(call gb_AllLangResTarget_AllLangResTarget,sm))
+
+$(eval $(call gb_AllLangResTarget_set_reslocation,sm,starmath))
+
+$(eval $(call gb_AllLangResTarget_add_srs,sm,\
+ starmath/res \
+))
+
+$(eval $(call gb_SrsTarget_SrsTarget,starmath/res))
+
+$(eval $(call gb_SrsTarget_set_include,starmath/res,\
+ $$(INCLUDE) \
+ -I$(OUTDIR)/inc \
+ -I$(WORKDIR)/inc/starmath \
+ -I$(realpath $(SRCDIR)/starmath/inc) \
+))
+
+$(eval $(call gb_SrsTarget_add_files,starmath/res,\
+ starmath/source/smres.src \
+ starmath/source/commands.src \
+ starmath/source/symbol.src \
+))
diff --git a/starmath/JunitTest_starmath_unoapi.mk b/starmath/JunitTest_starmath_unoapi.mk
new file mode 100644
index 000000000000..27a18d934657
--- /dev/null
+++ b/starmath/JunitTest_starmath_unoapi.mk
@@ -0,0 +1,49 @@
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License or as specified alternatively below. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Bjoern Michaelsen, Canonical Ltd. <bjoern.michaelsen@canonical.com>
+# Portions created by the Initial Developer are Copyright (C) 2010 the
+# Initial Developer. All Rights Reserved.
+#
+# Major Contributor(s):
+#
+# For minor contributions see the git repository.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_JunitTest_JunitTest,starmath_unoapi))
+
+$(eval $(call gb_JunitTest_set_defs,starmath_unoapi,\
+ $$(DEFS) \
+ -Dorg.openoffice.test.arg.sce=$(realpath $(SRCDIR)/starmath/qa/unoapi/sm.sce) \
+ -Dorg.openoffice.test.arg.xcl=$(realpath $(SRCDIR)/starmath/qa/unoapi/knownissues.xcl) \
+ -Dorg.openoffice.test.arg.tdoc=$(realpath $(SRCDIR)/starmath/qa/unoapi/testdocuments) \
+))
+
+$(eval $(call gb_JunitTest_add_jars,starmath_unoapi,\
+ $(OUTDIR)/bin/OOoRunner.jar \
+ $(OUTDIR)/bin/ridl.jar \
+ $(OUTDIR)/bin/test.jar \
+ $(OUTDIR)/bin/unoil.jar \
+ $(OUTDIR)/bin/jurt.jar \
+))
+
+$(eval $(call gb_JunitTest_add_classes,starmath_unoapi,\
+ org.openoffice.test.UnoApiTest \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/starmath/Library_sm.mk b/starmath/Library_sm.mk
new file mode 100644
index 000000000000..1fc0a763bf11
--- /dev/null
+++ b/starmath/Library_sm.mk
@@ -0,0 +1,107 @@
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Norbert Thiebaud <nthiebaud@gmail.com> (C) 2010, All Rights Reserved.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_Library_Library,sm))
+
+$(eval $(call gb_Library_add_sdi_headers,sm,starmath/sdi/smslots))
+
+$(eval $(call gb_Library_add_precompiled_header,sm,$(SRCDIR)/starmath/inc/pch/precompiled_starmath))
+
+$(eval $(call gb_Library_set_componentfile,sm,starmath/util/sm))
+
+$(eval $(call gb_Library_set_include,sm,\
+ -I$(realpath $(SRCDIR)/starmath/inc/pch) \
+ -I$(realpath $(SRCDIR)/starmath/inc) \
+ -I$(WORKDIR)/SdiTarget/starmath/sdi \
+ -I$(WORKDIR)/Misc/starmath/ \
+ $$(INCLUDE) \
+ -I$(OUTDIR)/inc/offuh \
+ -I$(OUTDIR)/inc \
+))
+
+$(eval $(call gb_Library_set_defs,sm,\
+ $$(DEFS) \
+ -DSMDLL \
+ -DSC_INFO_OSVERSION=\"$(OS)\" \
+))
+
+$(eval $(call gb_Library_add_linked_libs,sm,\
+ comphelper \
+ cppu \
+ cppuhelper \
+ editeng \
+ i18npaper \
+ sal \
+ sfx \
+ sot \
+ svl \
+ svt \
+ svx \
+ svxcore \
+ tk \
+ tl \
+ utl \
+ vcl \
+ ucbhelper \
+ xo \
+))
+
+$(eval $(call gb_Library_add_exception_objects,sm,\
+ starmath/source/accessibility \
+ starmath/source/action \
+ starmath/source/caret \
+ starmath/source/cfgitem \
+ starmath/source/config \
+ starmath/source/cursor \
+ starmath/source/dialog \
+ starmath/source/document \
+ starmath/source/edit \
+ starmath/source/eqnolefilehdr \
+ starmath/source/format \
+ starmath/source/mathmlexport \
+ starmath/source/mathmlimport \
+ starmath/source/mathtype \
+ starmath/source/node \
+ starmath/source/parse \
+ starmath/source/rect \
+ starmath/source/register \
+ starmath/source/smdll \
+ starmath/source/smmod \
+ starmath/source/symbol \
+ starmath/source/toolbox \
+ starmath/source/typemap \
+ starmath/source/types \
+ starmath/source/unodoc \
+ starmath/source/unomodel \
+ starmath/source/utility \
+ starmath/source/view \
+ starmath/source/visitors \
+))
+
+
+$(eval $(call gb_SdiTarget_SdiTarget,starmath/sdi/smslots,starmath/sdi/smath))
+
+$(eval $(call gb_SdiTarget_set_include,starmath/sdi/smslots,\
+ -I$(realpath $(SRCDIR)/starmath/inc) \
+ -I$(realpath $(SRCDIR)/starmath/sdi) \
+ $$(INCLUDE) \
+ -I$(OUTDIR)/inc \
+))
diff --git a/starmath/Library_smd.mk b/starmath/Library_smd.mk
new file mode 100644
index 000000000000..538f92104d56
--- /dev/null
+++ b/starmath/Library_smd.mk
@@ -0,0 +1,58 @@
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Norbert Thiebaud <nthiebaud@gmail.com> (C) 2010, All Rights Reserved.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_Library_Library,smd))
+
+$(eval $(call gb_Library_add_precompiled_header,smd,$(SRCDIR)/starmath/inc/pch/precompiled_starmath))
+
+$(eval $(call gb_Library_set_componentfile,smd,starmath/util/smd))
+
+$(eval $(call gb_Library_set_include,smd,\
+ -I$(realpath $(SRCDIR)/starmath/inc/pch) \
+ -I$(realpath $(SRCDIR)/starmath/inc) \
+ -I$(WORKDIR)/Misc/sm/ \
+ $$(INCLUDE) \
+ -I$(OUTDIR)/inc/offuh \
+ -I$(OUTDIR)/inc \
+))
+
+$(eval $(call gb_Library_set_defs,smd,\
+ $$(DEFS) \
+))
+
+$(eval $(call gb_Library_add_linked_libs,smd,\
+ cppu \
+ cppuhelper \
+ sal \
+ sfx \
+ sot \
+ svl \
+ svt \
+ tl \
+ ucbhelper \
+ vcl \
+))
+
+$(eval $(call gb_Library_add_exception_objects,smd,\
+ starmath/source/detreg \
+ starmath/source/smdetect \
+ starmath/source/eqnolefilehdr \
+))
diff --git a/starmath/Makefile b/starmath/Makefile
new file mode 100644
index 000000000000..de837bea620f
--- /dev/null
+++ b/starmath/Makefile
@@ -0,0 +1,33 @@
+#
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Norbert Thiebaud <nthiebaud@gmail.com> (C) 2010, All Rights Reserved.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+ifeq ($(strip $(SOLARENV)),)
+$(error No environment set!)
+endif
+
+gb_PARTIALBUILD := T
+GBUILDDIR := $(SOLARENV)/gbuild
+include $(GBUILDDIR)/gbuild.mk
+
+$(eval $(call gb_Module_make_global_targets,$(shell ls $(dir $(realpath $(firstword $(MAKEFILE_LIST))))/Module*.mk)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/starmath/Module_starmath.mk b/starmath/Module_starmath.mk
new file mode 100644
index 000000000000..9f7de2dad03f
--- /dev/null
+++ b/starmath/Module_starmath.mk
@@ -0,0 +1,34 @@
+#
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Norbert Thiebaud <nthiebaud@gmail.com> (C) 2010, All Rights Reserved.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_Module_Module,sm))
+
+$(eval $(call gb_Module_add_targets,sm,\
+ AllLangResTarget_sm \
+ Library_sm \
+ Library_smd \
+ Package_uiconfig \
+))
+
+$(eval $(call gb_Module_add_subsequentcheck_targets,sm,\
+ JunitTest_starmath_unoapi \
+))
diff --git a/starmath/Package_uiconfig.mk b/starmath/Package_uiconfig.mk
new file mode 100644
index 000000000000..d83485ccf07c
--- /dev/null
+++ b/starmath/Package_uiconfig.mk
@@ -0,0 +1,28 @@
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Norbert Thiebaud <nthiebaud@gmail.com> (C) 2010, All Rights Reserved.
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+$(eval $(call gb_Package_Package,sm_uiconfig,$(realpath $(SRCDIR)/starmath/uiconfig)))
+$(eval $(call gb_Package_add_file,sm_uiconfig,xml/uiconfig/modules/smath/menubar/menubar.xml,smath/menubar/menubar.xml))
+$(eval $(call gb_Package_add_file,sm_uiconfig,xml/uiconfig/modules/smath/statusbar/statusbar.xml,smath/statusbar/statusbar.xml))
+$(eval $(call gb_Package_add_file,sm_uiconfig,xml/uiconfig/modules/smath/toolbar/toolbar.xml,smath/toolbar/toolbar.xml))
+$(eval $(call gb_Package_add_file,sm_uiconfig,xml/uiconfig/modules/smath/toolbar/standardbar.xml,smath/toolbar/standardbar.xml))
+$(eval $(call gb_Package_add_file,sm_uiconfig,xml/uiconfig/modules/smath/toolbar/fullscreenbar.xml,smath/toolbar/fullscreenbar.xml))
+
diff --git a/starmath/inc/action.hxx b/starmath/inc/action.hxx
new file mode 100644
index 000000000000..2463edc983f0
--- /dev/null
+++ b/starmath/inc/action.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef ACTION_HXX
+#define ACTION_HXX
+
+#include <svl/undo.hxx>
+#include "format.hxx"
+
+class SmDocShell;
+
+
+class SmFormatAction: public SfxUndoAction
+{
+ SmDocShell *pDoc;
+ SmFormat aOldFormat;
+ SmFormat aNewFormat;
+
+public:
+ SmFormatAction(SmDocShell *pDocSh, const SmFormat& rOldFormat, const SmFormat& rNewFormat);
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rDocSh);
+ virtual UniString GetComment() const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/applicat.hxx b/starmath/inc/applicat.hxx
new file mode 100644
index 000000000000..d708d3d76c2d
--- /dev/null
+++ b/starmath/inc/applicat.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef APPLICAT_HXX
+#define APPLICAT_HXX
+
+class SvxErrorHandler;
+
+#include <sfx2/app.hxx>
+
+
+#define SMDLL 1
+#define APPLICATIONNAME "smath3"
+
+
+#ifdef PM2
+#define RELEASE "PM304"
+#endif
+
+#ifdef WNT
+#define RELEASE "WNT304"
+#endif
+
+#ifdef UNX
+#define RELEASE "UNX304"
+#endif
+
+#ifndef SMDLL
+class SmResId : public ResId
+{
+public:
+ SmResId(sal_uInt16 nId) :
+ ResId(nId)
+ {
+ }
+
+};
+
+#endif
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/caret.hxx b/starmath/inc/caret.hxx
new file mode 100644
index 000000000000..c0bda175746b
--- /dev/null
+++ b/starmath/inc/caret.hxx
@@ -0,0 +1,480 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Jonas Finnemann Jensen <jopsen@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jonas Finnemann Jensen <jopsen@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#ifndef CARET_H
+#define CARET_H
+
+#include "node.hxx"
+
+/** Representation of caret position with an equantion */
+struct SmCaretPos{
+ SmCaretPos(SmNode* selectedNode = NULL, int iIndex = 0) {
+ pSelectedNode = selectedNode;
+ Index = iIndex;
+ }
+ /** Selected node */
+ SmNode* pSelectedNode;
+ /** Index within the selected node
+ *
+ * 0: Position infront of a node
+ * 1: Position after a node or after first char in SmTextNode
+ * n: Position after n char in SmTextNode
+ *
+ * Notice how there's special cases for SmTextNode.
+ */
+ //TODO: Special cases for SmBlankNode is needed
+ //TODO: Consider forgetting about the todo above... As it's really unpleasent.
+ int Index;
+ /** True, if this is a valid caret position */
+ bool IsValid() { return pSelectedNode != NULL; }
+ bool operator!=(SmCaretPos pos) const {
+ return pos.pSelectedNode != pSelectedNode || Index != pos.Index;
+ }
+ bool operator==(SmCaretPos pos) const {
+ return pos.pSelectedNode == pSelectedNode && Index == pos.Index;
+ }
+ /** Get the caret position after pNode, regardless of pNode
+ *
+ * Gets the caret position following pNode, this is SmCaretPos(pNode, 1).
+ * Unless pNode is an instance of SmTextNode, then the index is the text length.
+ */
+ static SmCaretPos GetPosAfter(SmNode* pNode) {
+ if(pNode && pNode->GetType() == NTEXT)
+ return SmCaretPos(pNode, ((SmTextNode*)pNode)->GetText().Len());
+ return SmCaretPos(pNode, 1);
+ }
+};
+
+/** A line that represents a caret */
+class SmCaretLine{
+public:
+ SmCaretLine(long left = 0, long top = 0, long height = 0) {
+ _top = top;
+ _left = left;
+ _height = height;
+ }
+ long GetTop() const {return _top;}
+ long GetLeft() const {return _left;}
+ long GetHeight() const {return _height;}
+ long SquaredDistanceX(SmCaretLine line) const{
+ return (GetLeft() - line.GetLeft()) * (GetLeft() - line.GetLeft());
+ }
+ long SquaredDistanceX(Point pos) const{
+ return (GetLeft() - pos.X()) * (GetLeft() - pos.X());
+ }
+ long SquaredDistanceY(SmCaretLine line) const{
+ long d = GetTop() - line.GetTop();
+ if(d < 0)
+ d = (d * -1) - GetHeight();
+ else
+ d = d - line.GetHeight();
+ if(d < 0)
+ return 0;
+ return d * d;
+ }
+ long SquaredDistanceY(Point pos) const{
+ long d = GetTop() - pos.Y();
+ if(d < 0)
+ d = (d * -1) - GetHeight();
+ if(d < 0)
+ return 0;
+ return d * d;
+ }
+private:
+ long _top;
+ long _left;
+ long _height;
+};
+
+/////////////////////////////// SmCaretPosGraph////////////////////////////////
+
+/** An entry in SmCaretPosGraph */
+struct SmCaretPosGraphEntry{
+ SmCaretPosGraphEntry(SmCaretPos pos = SmCaretPos(),
+ SmCaretPosGraphEntry* left = NULL,
+ SmCaretPosGraphEntry* right = NULL){
+ CaretPos = pos;
+ Left = left;
+ Right = right;
+ }
+ /** Caret position */
+ SmCaretPos CaretPos;
+ /** Entry to the left visually */
+ SmCaretPosGraphEntry* Left;
+ /** Entry to the right visually */
+ SmCaretPosGraphEntry* Right;
+ void SetRight(SmCaretPosGraphEntry* right){
+ Right = right;
+ }
+ void SetLeft(SmCaretPosGraphEntry* left){
+ Left = left;
+ }
+};
+
+/** Define SmCaretPosGraph to be less than one page 4096 */
+#define SmCaretPosGraphSize 255
+
+class SmCaretPosGraph;
+
+/** Iterator for SmCaretPosGraph */
+class SmCaretPosGraphIterator{
+public:
+ SmCaretPosGraphIterator(SmCaretPosGraph* graph){
+ pGraph = graph;
+ nOffset = 0;
+ pEntry = NULL;
+ }
+ /** Get the next entry, NULL if none */
+ SmCaretPosGraphEntry* Next();
+ /** Get the current entry, NULL if none */
+ SmCaretPosGraphEntry* Current(){
+ return pEntry;
+ }
+ /** Get the current entry, NULL if none */
+ SmCaretPosGraphEntry* operator->(){
+ return pEntry;
+ }
+private:
+ /** Next entry to return */
+ int nOffset;
+ /** Current graph */
+ SmCaretPosGraph* pGraph;
+ /** Current entry */
+ SmCaretPosGraphEntry* pEntry;
+};
+
+
+/** A graph over all caret positions
+ * @remarks Graphs can only grow, entries cannot be removed!
+ */
+class SmCaretPosGraph{
+public:
+ SmCaretPosGraph(){
+ pNext = NULL;
+ nOffset = 0;
+ }
+ ~SmCaretPosGraph();
+ /** Add a caret position
+ * @remarks If Left and/or Right are set NULL, they will point back to the entry.
+ */
+ SmCaretPosGraphEntry* Add(SmCaretPosGraphEntry entry);
+ /** Add a caret position
+ * @remarks If left and/or right are set NULL, they will point back to the entry.
+ */
+ SmCaretPosGraphEntry* Add(SmCaretPos pos,
+ SmCaretPosGraphEntry* left = NULL,
+ SmCaretPosGraphEntry* right = NULL){
+ OSL_ENSURE(pos.Index >= 0, "Index shouldn't be -1!");
+ return Add(SmCaretPosGraphEntry(pos, left, right));
+ }
+ /** Get an iterator for this graph */
+ SmCaretPosGraphIterator GetIterator(){
+ return SmCaretPosGraphIterator(this);
+ }
+ friend class SmCaretPosGraphIterator;
+private:
+ /** Next graph, to be used when this graph is full */
+ SmCaretPosGraph* pNext;
+ /** Next free entry in graph */
+ int nOffset;
+ /** Entries in this graph segment */
+ SmCaretPosGraphEntry Graph[SmCaretPosGraphSize];
+};
+
+/** \page visual_formula_editing Visual Formula Editing
+ * A visual formula editor allows users to easily edit formulas without having to learn and
+ * use complicated commands. A visual formula editor is a WYSIWYG editor. For OpenOffice Math
+ * this essentially means that you can click on the formula image, to get a caret, which you
+ * can move with arrow keys, and use to modify the formula by entering text, clicking buttons
+ * or using shortcuts.
+ *
+ * \subsection formula_trees Formula Trees
+ * A formula in OpenOffice Math is a tree of nodes, take for instance the formula
+ * "A + {B cdot C} over D", it looks like this
+ * \f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$. The tree for this formula
+ * looks like this:
+ *
+ * \dot
+ * digraph {
+ * labelloc = "t";
+ * label= "Equation: \"A + {B cdot C} over D\"";
+ * size = "9,9";
+ * n0 [label="SmTableNode (1)"];
+ * n0 -> n1 [label="0"];
+ * n1 [label="SmLineNode (2)"];
+ * n1 -> n2 [label="0"];
+ * n2 [label="SmExpressionNode (3)"];
+ * n2 -> n3 [label="0"];
+ * n3 [label="SmBinHorNode (4)"];
+ * n3 -> n4 [label="0"];
+ * n4 [label="SmTextNode: A (5)"];
+ * n3 -> n5 [label="1"];
+ * n5 [label="SmMathSymbolNode:  (6)"];
+ * n3 -> n6 [label="2"];
+ * n6 [label="SmBinVerNode (7)"];
+ * n6 -> n7 [label="0"];
+ * n7 [label="SmExpressionNode (8)"];
+ * n7 -> n8 [label="0"];
+ * n8 [label="SmBinHorNode (9)"];
+ * n8 -> n9 [label="0"];
+ * n9 [label="SmTextNode: B (10)"];
+ * n8 -> n10 [label="1"];
+ * n10 [label="SmMathSymbolNode: â‹… (11)"];
+ * n8 -> n11 [label="2"];
+ * n11 [label="SmTextNode: C (12)"];
+ * n6 -> n12 [label="1"];
+ * n12 [label="SmRectangleNode (13)"];
+ * n6 -> n13 [label="2"];
+ * n13 [label="SmTextNode: D (14)"];
+ * }
+ * \enddot
+ *
+ * The vertices are nodes, their label says what kind of node and the number in parentheses is
+ * the identifier of the node (In practices a pointer is used instead of the id). The direction
+ * of the edges tells which node is parent and which is child. The label of the edges are the
+ * child node index number, given to SmNode::GetSubNode() of the parent to get the child node.
+ *
+ *
+ * \subsection visual_lines Visual Lines
+ *
+ * Inorder to do caret movement in visual lines, we need a definition of caret position and
+ * visual line. In a tree such as the above there are three visual lines. There's the outer most
+ * line, with entries such as
+ * \f$\mbox{A}\f$, \f$ + \f$ and \f$ \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$. Then there's
+ * the numerator line of the fraction it has entries \f$ \mbox{B} \f$, \f$ \cdot \f$ and \f$ \mbox{C} \f$.
+ * And last by not least there's the denominator line of the fraction it's only entry is \f$ \mbox{D} \f$.
+ *
+ * For visual editing it should be possible to place a caret on both sides of any line entry,
+ * consider a line entry a character or construction that in a line is treated as a character.
+ * Imagine the caret is placed to the right of the plus sign (id: 6), now if user presses
+ * backspace this should delete the plus sign (id: 6), and if the user presses delete this
+ * should delete the entire fraction (id: 7). This is because the caret is in the outer most
+ * line where the fraction is considered a line entry.
+ *
+ * However, inorder to prevent users from accidentally deleting large subtrees, just because
+ * they logically placed there caret a in the wrong line, require that complex constructions
+ * such as a fraction is selected before it is deleted. Thus in this case it wouldn't be
+ * deleted, but only selected and then deleted if the user hit delete again. Anyway, this is
+ * slightly off topic for now.
+ *
+ * Important about visual lines is that they don't always have an SmExpressionNode as root
+ * and the entries in a visual line is all the nodes of a subtree ordered left to right that
+ * isn't either an SmExpressionNode, SmBinHorNode or SmUnHorNode.
+ *
+ *
+ * \subsection caret_positions Caret Positions
+ *
+ * A caret position in OpenOffice Math is representated by an instance of SmCaretPos.
+ * That is a caret position is a node and an index related to this node. For most nodes the
+ * index 0, means caret is infront of this node, the index 1 means caret is after this node.
+ * For SmTextNode the index is the caret position after the specified number of characters,
+ * imagine an SmTextNode with the number 1337. The index 3 in such SmTextNode would mean a
+ * caret placed right before 7, e.g. "133|7".
+ *
+ * For SmExpressionNode, SmBinHorNode and SmUnHorNode the only legal index is 0, which means
+ * infront of the node. Actually the index 0 may only because for the first caret position
+ * in a visual line. From the example above, consider the following subtree that constitutes
+ * a visual line:
+ *
+ * \dot
+ * digraph {
+ * labelloc = "t";
+ * label= "Subtree that constitutes a visual line";
+ * size = "7,5";
+ * n7 [label="SmExpressionNode (8)"];
+ * n7 -> n8 [label="0"];
+ * n8 [label="SmBinHorNode (9)"];
+ * n8 -> n9 [label="0"];
+ * n9 [label="SmTextNode: B (10)"];
+ * n8 -> n10 [label="1"];
+ * n10 [label="SmMathSymbolNode: â‹… (11)"];
+ * n8 -> n11 [label="2"];
+ * n11 [label="SmTextNode: C (12)"];
+ * }
+ * \enddot
+ * Here the caret positions are:
+ *
+ * <TABLE>
+ * <TR><TD><B>Caret position:</B></TD><TD><B>Example:</B></TD>
+ * </TR><TR>
+ * <TD>{id: 8, index: 0}</TD>
+ * <TD>\f$ \mid \mbox{C} \cdot \mbox{C} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 10, index: 1}</TD>
+ * <TD>\f$ \mbox{C} \mid \cdot \mbox{C} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 11, index: 1}</TD>
+ * <TD>\f$ \mbox{C} \cdot \mid \mbox{C} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 12, index: 1}</TD>
+ * <TD>\f$ \mbox{C} \cdot \mbox{C} \mid \f$</TD>
+ * </TR><TR>
+ * </TABLE>
+ *
+ * Where \f$ \mid \f$ is used to denote caret position.
+ *
+ * With these exceptions included in the definition the id and index: {id: 11, index: 0} does
+ * \b not constitute a caret position in the given context. Note the method
+ * SmCaretPos::IsValid() does not check if this invariant holds true, but code in SmCaret,
+ * SmSetSelectionVisitor and other places depends on this invariant to hold.
+ *
+ *
+ * \subsection caret_movement Caret Movement
+ *
+ * As the placement of caret positions depends very much on the context within which a node
+ * appears it is not trivial to find all caret positions and determine which follows which.
+ * In OpenOffice Math this is done by the SmCaretPosGraphBuildingVisitor. This visitor builds
+ * graph (an instnce of SmCaretPosGraph) over the caret positions. For details on how this
+ * graph is build, and how new methods should be implemented see SmCaretPosGraphBuildingVisitor.
+ *
+ * The result of the SmCaretPosGraphBuildingVisitor is a graph over the caret positions in a
+ * formula, representated by an instance of SmCaretPosGraph. Each entry (instances of SmCaretPosGraphEntry)
+ * has a pointer to the entry to the left and right of itself. This way we can easily find
+ * the caret position to a right or left of a given caret position. Note each caret position
+ * only appears once in this graph.
+ *
+ * When searching for a caret position after a left click on the formula this map is also used.
+ * We simply iterate over all entries, uses the SmCaretPos2LineVisitor to find a line for each
+ * caret position. Then the distance from the click to the line is computed and we choose the
+ * caret position closest to the click.
+ *
+ * For up and down movement, we also iterator over all caret positions and use SmCaretPos2LineVisitor
+ * to find a line for each caret position. Then we compute the distance from the current
+ * caret position to every other caret position and chooses the one closest that is either
+ * above or below the current caret position, depending on wether we're doing up or down movement.
+ *
+ * This result of this approach to caret movement is that we have logically predictable
+ * movement for left and right, whilst leftclick, up and down movement depends on the sizes
+ * and placement of all node and may be less logically predictable. This solution also means
+ * that we only have one complex visitor generating the graph, imagine the nightmare if we
+ * had a visitor for movement in each direction.
+ *
+ * Making up and down movement independent of node sizes and placement wouldn't necessarily
+ * be a good thing either. Consider the formula \f$ \frac{1+2+3+4+5}{6} \f$, if the caret is
+ * placed as displayed here: \f$ \frac{1+2+3+4+5}{6 \mid} \f$, up movement should move to right
+ * after "3": \f$ \frac{1+2+3|+4+5}{6} \f$. However, such a move depends on the sizes and placement
+ * of all nodes in the fraction.
+ *
+ *
+ * \subsubsection caretpos_graph_example Example of Caret Position Graph
+ *
+ * If we consider the formula
+ * \f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$ from \ref formula_trees.
+ * It has the following caret positions:
+ *
+ * <TABLE>
+ * <TR>
+ * <TD><B>Caret position:</B></TD>
+ * <TD><B>Example:</B></TD>
+ * </TR><TR>
+ * <TD>{id: 3, index: 0}</TD>
+ * <TD>\f$ \mid\mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 5, index: 1}</TD>
+ * <TD>\f$ \mbox{A}\mid + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 6, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \mid \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 8, index: 0}</TD>
+ * <TD>\f$ \mbox{A} + \frac{ \mid \mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 10, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \mid \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 11, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mid \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 12, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C} \mid}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 14, index: 0}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mid \mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 14, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D} \mid} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 7, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \mid \f$</TD>
+ * </TR>
+ * </TABLE>
+ *
+ * Below is a directed graph over the caret postions and how you can move between them.
+ * \dot
+ * digraph {
+ * labelloc = "t";
+ * label= "Caret Position Graph";
+ * size = "4,6";
+ * p0 [label = "{id: 3, index: 0}"];
+ * p0 -> p1 [fontsize = 10.0, label = "right"];
+ * p1 [label = "{id: 5, index: 1}"];
+ * p1 -> p0 [fontsize = 10.0, label = "left"];
+ * p1 -> p2 [fontsize = 10.0, label = "right"];
+ * p2 [label = "{id: 6, index: 1}"];
+ * p2 -> p1 [fontsize = 10.0, label = "left"];
+ * p2 -> p3 [fontsize = 10.0, label = "right"];
+ * p3 [label = "{id: 8, index: 0}"];
+ * p3 -> p2 [fontsize = 10.0, label = "left"];
+ * p3 -> p4 [fontsize = 10.0, label = "right"];
+ * p4 [label = "{id: 10, index: 1}"];
+ * p4 -> p3 [fontsize = 10.0, label = "left"];
+ * p4 -> p5 [fontsize = 10.0, label = "right"];
+ * p5 [label = "{id: 11, index: 1}"];
+ * p5 -> p4 [fontsize = 10.0, label = "left"];
+ * p5 -> p6 [fontsize = 10.0, label = "right"];
+ * p6 [label = "{id: 12, index: 1}"];
+ * p6 -> p5 [fontsize = 10.0, label = "left"];
+ * p6 -> p9 [fontsize = 10.0, label = "right"];
+ * p7 [label = "{id: 14, index: 0}"];
+ * p7 -> p2 [fontsize = 10.0, label = "left"];
+ * p7 -> p8 [fontsize = 10.0, label = "right"];
+ * p8 [label = "{id: 14, index: 1}"];
+ * p8 -> p7 [fontsize = 10.0, label = "left"];
+ * p8 -> p9 [fontsize = 10.0, label = "right"];
+ * p9 [label = "{id: 7, index: 1}"];
+ * p9 -> p6 [fontsize = 10.0, label = "left"];
+ * }
+ * \enddot
+ */
+
+/* TODO: Write documentation about the following keywords:
+ *
+ * Visual Selections:
+ * - Show images
+ * - Talk about how the visitor does this
+ *
+ * Modifying a Visual Line:
+ * - Find top most non-compo of the line (e.g. The subtree that constitutes a line)
+ * - Make the line into a list
+ * - Edit the list, add/remove/modify nodes
+ * - Parse the list back into a subtree
+ * - Insert the new subtree where the old was taken
+ */
+
+#endif /* CARET_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/config.hxx b/starmath/inc/config.hxx
new file mode 100644
index 000000000000..9fc397eca0cc
--- /dev/null
+++ b/starmath/inc/config.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIG_HXX
+#define CONFIG_HXX
+
+#include <svl/brdcst.hxx>
+#include <svl/lstner.hxx>
+#include "format.hxx"
+
+#include "cfgitem.hxx"
+
+
+class SmPreferenceDialog;
+class SmPrintDialog;
+class SmPrintOptionDialog;
+class SfxItemSet;
+
+class SmConfig : public SmMathConfig, public SfxBroadcaster
+{
+ SmFontPickList vFontPickList[7];
+
+public:
+ SmConfig();
+ virtual ~SmConfig();
+
+ SmFontPickList & GetFontPickList(sal_uInt16 nIdent) { return vFontPickList[nIdent]; }
+
+ void ItemSetToConfig(const SfxItemSet &rSet);
+ void ConfigToItemSet(SfxItemSet &rSet) const;
+};
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/cursor.hxx b/starmath/inc/cursor.hxx
new file mode 100644
index 000000000000..0de8931673d9
--- /dev/null
+++ b/starmath/inc/cursor.hxx
@@ -0,0 +1,482 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Jonas Finnemann Jensen <jopsen@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jonas Finnemann Jensen <jopsen@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#ifndef SMCURSOR_H
+#define SMCURSOR_H
+
+#include "node.hxx"
+#include "caret.hxx"
+
+/** Factor to multiple the squared horizontical distance with
+ * Used for Up and Down movement.
+ */
+#define HORIZONTICAL_DISTANCE_FACTOR 10
+
+/** Enum of direction for movement */
+enum SmMovementDirection{
+ MoveUp,
+ MoveDown,
+ MoveLeft,
+ MoveRight
+};
+
+/** Enum of elements that can inserted into a formula */
+enum SmFormulaElement{
+ BlankElement,
+ FactorialElement,
+ PlusElement,
+ MinusElement,
+ CDotElement,
+ EqualElement,
+ LessThanElement,
+ GreaterThanElement,
+ PercentElement
+};
+
+/** Bracket types that can be inserted */
+enum SmBracketType {
+ /** None brackets, left command "none" */
+ NoneBrackets,
+ /** Round brackets, left command "(" */
+ RoundBrackets,
+ /**Square brackets, left command "[" */
+ SquareBrackets,
+ /** Double square brackets, left command "ldbracket" */
+ DoubleSquareBrackets,
+ /** Line brackets, left command "lline" */
+ LineBrackets,
+ /** Double line brackets, left command "ldline" */
+ DoubleLineBrackets,
+ /** Curly brackets, left command "lbrace" */
+ CurlyBrackets,
+ /** Angle brackets, left command "langle" */
+ AngleBrackets,
+ /** Ceiling brackets, left command "lceil" */
+ CeilBrackets,
+ /** Floor brackets, left command "lfloor" */
+ FloorBrackets
+};
+
+/** A list of nodes */
+typedef std::list<SmNode*> SmNodeList;
+
+class SmDocShell;
+
+/** Formula cursor
+ *
+ * This class is used to represent a cursor in a formula, which can be used to manipulate
+ * an formula programmatically.
+ * @remarks This class is a very intimite friend of SmDocShell.
+ */
+class SmCursor{
+public:
+ SmCursor(SmNode* tree, SmDocShell* pShell){
+ //Initialize members
+ pTree = tree;
+ anchor = NULL;
+ position = NULL;
+ pGraph = NULL;
+ pDocShell = pShell;
+ pClipboard = NULL;
+ nEditSections = 0;
+ //Build graph
+ BuildGraph();
+ }
+
+ ~SmCursor(){
+ SetClipboard();
+ if(pGraph)
+ delete pGraph;
+ pGraph = NULL;
+ }
+
+ /** Gets the anchor */
+ SmCaretPos GetAnchor(){ return anchor->CaretPos; }
+
+ /** Get position */
+ SmCaretPos GetPosition() { return position->CaretPos; }
+
+ /** True, if the cursor has a selection */
+ bool HasSelection() { return anchor != position; }
+
+ /** Move the position of this cursor */
+ void Move(OutputDevice* pDev, SmMovementDirection direction, bool bMoveAnchor = true);
+
+ /** Move to the caret position closet to a given point */
+ void MoveTo(OutputDevice* pDev, Point pos, bool bMoveAnchor = true);
+
+ /** Delete the current selection or do nothing */
+ void Delete();
+
+ /** Delete selection, previous element or merge lines
+ *
+ * This method implements the behaviour of backspace.
+ */
+ void DeletePrev(OutputDevice* pDev);
+
+ /** Insert text at the current position */
+ void InsertText(XubString aString);
+
+ /** Insert an element into the formula */
+ void InsertElement(SmFormulaElement element);
+
+ /** Insert a command specified in commands.src*/
+ void InsertCommand(sal_uInt16 nCommand);
+
+ /** Insert command text translated into line entries at position
+ *
+ * Note: This method uses the parser to translate a command text into a
+ * tree, then it copies line entries from this tree into the current tree.
+ * Will not work for commands such as newline or ##, if position is in a matrix.
+ * This will work for stuff like "A intersection B". But stuff spaning multiple lines
+ * or dependent on the context which position is placed in will not work!
+ */
+ void InsertCommandText(String aCommandText);
+
+ /** Insert a special node created from aString
+ *
+ * Used for handling insert request from the "catalog" dialog.
+ * The provided string should be formatet as the desired command: %phi
+ * Note: this method ONLY supports commands defined in Math.xcu
+ *
+ * For more complex expressions use InsertCommandText, this method doesn't
+ * use SmParser, this means that it's faster, but not as strong.
+ */
+ void InsertSpecial(XubString aString);
+
+ /** Create sub-/super script
+ *
+ * If there's a selection, it will be move into the appropriate sub-/super scription
+ * of the node infront of it. If there's no node infront of position (or the selection),
+ * a sub-/super scription of a new SmPlaceNode will be made.
+ *
+ * If there's is an existing subscription of the node, the caret will be moved into it,
+ * and any selection will replace it.
+ */
+ void InsertSubSup(SmSubSup eSubSup);
+
+ /** Create a limit on an SmOperNode
+ *
+ * This this method only work if the caret is inside an SmOperNode, or to the right of one.
+ * Notice also that this method ignores any selection made.
+ *
+ * @param bMoveCaret If true that caret will be moved into the limit.
+ *
+ * @returns True, if the caret was in a context where this operation was possible.
+ */
+ bool InsertLimit(SmSubSup eSubSup, bool bMoveCaret = true);
+
+ /** Insert a new row or newline
+ *
+ * Inserts a new row if position is in an matrix or stack command.
+ * Otherwise a newline is inserted if we're in a toplevel line.
+ *
+ * @returns True, if a new row/line could be inserted.
+ *
+ * @remarks If the caret is placed in a subline of a command that doesn't support
+ * this operator the method returns FALSE, and doesn't do anything.
+ */
+ bool InsertRow();
+
+ /** Insert a fraction, use selection as numerator */
+ void InsertFraction();
+
+ /** Create brackets around current selection, or new SmPlaceNode */
+ void InsertBrackets(SmBracketType eBracketType);
+
+ /** Copy the current selection */
+ void Copy();
+ /** Cut the current selection */
+ void Cut(){
+ Copy();
+ Delete();
+ }
+ /** Paste the clipboard */
+ void Paste();
+
+ /** Returns true if more than one node is selected
+ *
+ * This method is used for implementing backspace and delete.
+ * If one of these causes a complex selection, e.g. a node with
+ * subnodes or similar, this should not be deleted imidiately.
+ */
+ bool HasComplexSelection();
+
+ /** Finds the topmost node in a visual line
+ *
+ * If MoveUpIfSelected is true, this will move up to the parent line
+ * if the parent of the current line is selected.
+ */
+ static SmNode* FindTopMostNodeInLine(SmNode* pSNode, bool MoveUpIfSelected = false);
+
+ /** Draw the caret */
+ void Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible);
+
+private:
+ friend class SmDocShell;
+
+ SmCaretPosGraphEntry *anchor,
+ *position;
+ /** Formula tree */
+ SmNode* pTree;
+ /** Owner of the formula tree */
+ SmDocShell* pDocShell;
+ /** Graph over caret position in the current tree */
+ SmCaretPosGraph* pGraph;
+ /** Clipboard holder */
+ SmNodeList* pClipboard;
+
+ /** Returns a node that is selected, if any could be found */
+ SmNode* FindSelectedNode(SmNode* pNode);
+
+ /** Is this one of the nodes used to compose a line
+ *
+ * These are SmExpression, SmBinHorNode, SmUnHorNode etc.
+ */
+ static bool IsLineCompositionNode(SmNode* pNode);
+
+ /** Count number of selected nodes, excluding line composition nodes
+ *
+ * Note this function doesn't count line composition nodes and it
+ * does count all subnodes as well as the owner nodes.
+ *
+ * Used by SmCursor::HasComplexSelection()
+ */
+ int CountSelectedNodes(SmNode* pNode);
+
+ /** Convert a visual line to a list
+ *
+ * Note this method will delete all the nodes that will no longer be needed.
+ * that includes pLine!
+ * This method also deletes SmErrorNode's as they're just meta info in the line.
+ */
+ static SmNodeList* LineToList(SmStructureNode* pLine, SmNodeList* pList = new SmNodeList());
+
+ /** Auxiliary function for calling LineToList on a node
+ *
+ * This method sets pNode = NULL and remove it from it's parent.
+ * (Assuming it has a parent, and is a child of it).
+ */
+ static SmNodeList* NodeToList(SmNode*& rpNode, SmNodeList* pList = new SmNodeList()){
+ //Remove from parent and NULL rpNode
+ SmNode* pNode = rpNode;
+ if(rpNode && rpNode->GetParent()){ //Don't remove this, correctness relies on it
+ int index = rpNode->GetParent()->IndexOfSubNode(rpNode);
+ if(index != -1)
+ rpNode->GetParent()->SetSubNode(index, NULL);
+ }
+ rpNode = NULL;
+ //Create line from node
+ if(pNode && IsLineCompositionNode(pNode))
+ return LineToList((SmStructureNode*)pNode, pList);
+ if(pNode)
+ pList->push_front(pNode);
+ return pList;
+ }
+
+ /** Clone a visual line to a list
+ *
+ * Doesn't clone SmErrorNode's these are ignored, as they are context dependent metadata.
+ */
+ static SmNodeList* CloneLineToList(SmStructureNode* pLine,
+ bool bOnlyIfSelected = false,
+ SmNodeList* pList = new SmNodeList());
+
+ /** Build pGraph over caret positions */
+ void BuildGraph();
+
+ /** Insert new nodes in the tree after position */
+ void InsertNodes(SmNodeList* pNewNodes);
+
+ /** tries to set position to a specific SmCaretPos
+ *
+ * @returns false on failure to find the position in pGraph.
+ */
+ bool SetCaretPosition(SmCaretPos pos, bool moveAnchor = false);
+
+ /** Set selected on nodes of the tree */
+ void AnnotateSelection();
+
+ /** Set the clipboard, and release current clipboard
+ *
+ * Call this method with NULL to reset the clipboard
+ * @remarks: This method takes ownership of pList.
+ */
+ void SetClipboard(SmNodeList* pList = NULL);
+
+ /** Clone list of nodes (creates a deep clone) */
+ static SmNodeList* CloneList(SmNodeList* pList);
+
+ /** Find an iterator pointing to the node in pLineList following aCaretPos
+ *
+ * If aCaretPos::pSelectedNode cannot be found it is assumed that it's infront of pLineList,
+ * thus not an element in pLineList. In this case this method returns an iterator to the
+ * first element in pLineList.
+ *
+ * If the current position is inside an SmTextNode, this node will be split in two, for this
+ * reason you should beaware that iterators to elements in pLineList may be invalidated, and
+ * that you should call PatchLineList() with this iterator if no action is taken.
+ */
+ static SmNodeList::iterator FindPositionInLineList(SmNodeList* pLineList, SmCaretPos aCaretPos);
+
+ /** Patch a line list after modification, merge SmTextNode, remove SmPlaceNode etc.
+ *
+ * @param pLineList The line list to patch
+ * @param aIter Iterator pointing to the element that needs to be patched with it's previous.
+ *
+ * When the list is patched text nodes before and after aIter will be merged.
+ * If there's an, in the context, inappropriate SmPlaceNode before or after aIter it will also be
+ * removed.
+ *
+ * @returns A caret position equivalent to one selecting the node before aIter, the method returns
+ * an invalid SmCaretPos to indicate placement infront of the line.
+ */
+ static SmCaretPos PatchLineList(SmNodeList* pLineList, SmNodeList::iterator aIter);
+
+ /** Take selected nodes from a list
+ *
+ * Puts the selected nodes into pSelectedNodes, or if pSelectedNodes is NULL deletes
+ * the selected nodes.
+ * Note: If there's a selection inside an SmTextNode this node will be split, and it
+ * will not be merged when the selection have been taken. Use PatchLineList on the
+ * iterator returns to fix this.
+ *
+ * @returns An iterator pointing to the element following the selection taken.
+ */
+ static SmNodeList::iterator TakeSelectedNodesFromList(SmNodeList *pLineList,
+ SmNodeList *pSelectedNodes = NULL);
+
+ /** Create an instance of SmMathSymbolNode usable for brackets */
+ static SmNode *CreateBracket(SmBracketType eBracketType, bool bIsLeft);
+
+ /** The number of times BeginEdit have been called
+ * Used to allow nesting of BeginEdit() and EndEdit() sections
+ */
+ int nEditSections;
+ /** Holds data for BeginEdit() and EndEdit() */
+ bool bIsEnabledSetModifiedSmDocShell;
+ /** Begin edit section where the tree will be modified */
+ void BeginEdit();
+ /** End edit section where the tree will be modified */
+ void EndEdit();
+ /** Finish editing
+ *
+ * Finishes editing by parsing pLineList and inserting back into pParent at nParentIndex.
+ * This method also rebuilts the graph, annotates the selection, sets caret position and
+ * Calls EndEdit.
+ *
+ * @remarks Please note that this method will delete pLineList, as the elements are taken.
+ *
+ * @param pLineList List the constitutes the edited line.
+ * @param pParent Parent to which the line should be inserted.
+ * @param nParentIndex Index in parent where the line should be inserted.
+ * @param PosAfterEdit Caret position to look for after rebuilding graph.
+ * @param pStartLine Line to take first position in, if PosAfterEdit cannot be found,
+ * leave it NULL for pLineList.
+ */
+ void FinishEdit(SmNodeList* pLineList,
+ SmStructureNode* pParent,
+ int nParentIndex,
+ SmCaretPos PosAfterEdit,
+ SmNode* pStartLine = NULL);
+ /** Request the formula is repainted */
+ void RequestRepaint();
+};
+
+/** Minimalistic recursive decent SmNodeList parser
+ *
+ * This parser is used to take a list of nodes that constitues a line
+ * and parse them to a tree of SmBinHorNode, SmUnHorNode and SmExpression.
+ *
+ * Please note, this will not handle all kinds of nodes, only nodes that
+ * constitues and entry in a line.
+ *
+ * Below is an EBNF representation of the grammar used for this parser:
+ * \code
+ * Expression -> Relation*
+ * Relation -> Sum [(=|<|>|...) Sum]*
+ * Sum -> Product [(+|-) Product]*
+ * Product -> Factor [(*|/) Factor]*
+ * Factor -> [+|-|-+|...]* Factor | Postfix
+ * Postfix -> node [!]*
+ * \endcode
+ */
+class SmNodeListParser{
+public:
+ /** Create an instance of SmNodeListParser */
+ SmNodeListParser(){
+ pList = NULL;
+ }
+ /** Parse a list of nodes to an expression
+ *
+ * If bDeleteErrorNodes is true, old error nodes will be deleted.
+ */
+ SmNode* Parse(SmNodeList* list, bool bDeleteErrorNodes = true);
+ /** True, if the token is an operator */
+ static bool IsOperator(const SmToken &token);
+ /** True, if the token is a relation operator */
+ static bool IsRelationOperator(const SmToken &token);
+ /** True, if the token is a sum operator */
+ static bool IsSumOperator(const SmToken &token);
+ /** True, if the token is a product operator */
+ static bool IsProductOperator(const SmToken &token);
+ /** True, if the token is a unary operator */
+ static bool IsUnaryOperator(const SmToken &token);
+ /** True, if the token is a postfix operator */
+ static bool IsPostfixOperator(const SmToken &token);
+private:
+ SmNodeList* pList;
+ /** Get the current terminal */
+ SmNode* Terminal(){
+ if(pList->size() > 0)
+ return pList->front();
+ return NULL;
+ }
+ /** Move to next terminal */
+ SmNode* Next(){
+ pList->pop_front();
+ return Terminal();
+ }
+ /** Take the current terminal */
+ SmNode* Take(){
+ SmNode* pRetVal = Terminal();
+ Next();
+ return pRetVal;
+ }
+ SmNode* Expression();
+ SmNode* Relation();
+ SmNode* Sum();
+ SmNode* Product();
+ SmNode* Factor();
+ SmNode* Postfix();
+ SmNode* Error();
+};
+
+
+#endif /* SMCURSOR_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/dialog.hxx b/starmath/inc/dialog.hxx
new file mode 100644
index 000000000000..316d1fb7ca62
--- /dev/null
+++ b/starmath/inc/dialog.hxx
@@ -0,0 +1,519 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef DIALOG_HXX
+#define DIALOG_HXX
+
+#include <vcl/image.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/button.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <vcl/combobox.hxx>
+#include <svx/charmap.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <vcl/field.hxx>
+#include <vcl/menubtn.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/ctrl.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/outdev.hxx>
+#include <svtools/ctrlbox.hxx>
+#include <svtools/ctrltool.hxx>
+#include "utility.hxx"
+#include "format.hxx"
+#include "symbol.hxx"
+
+class SubsetMap;
+#define CATEGORY_NONE 0xFFFF
+
+/**************************************************************************/
+
+void SetFontStyle(const XubString &rStyleName, Font &rFont);
+
+/**************************************************************************/
+
+class SmPrintOptionsTabPage : public SfxTabPage
+{
+ FixedLine aFixedLine1;
+ CheckBox aTitle;
+ CheckBox aText;
+ CheckBox aFrame;
+ FixedLine aFixedLine2;
+ RadioButton aSizeNormal;
+ RadioButton aSizeScaled;
+ RadioButton aSizeZoomed;
+ MetricField aZoom;
+ FixedLine aFixedLine3;
+ CheckBox aNoRightSpaces;
+ CheckBox aSaveOnlyUsedSymbols;
+
+ DECL_LINK(SizeButtonClickHdl, Button *);
+
+ virtual sal_Bool FillItemSet(SfxItemSet& rSet);
+ virtual void Reset(const SfxItemSet& rSet);
+
+public:
+ static SfxTabPage* Create(Window *pWindow, const SfxItemSet &rSet);
+
+ SmPrintOptionsTabPage(Window *pParent, const SfxItemSet &rOptions);
+};
+
+/**************************************************************************/
+
+class SmShowFont : public Control
+{
+ virtual void Paint(const Rectangle&);
+
+public:
+ SmShowFont(Window *pParent, const ResId& rResId) :
+ Control(pParent, rResId)
+ {
+ }
+
+ void SetFont(const Font& rFont);
+};
+
+class SmFontDialog : public ModalDialog
+{
+ FixedText aFixedText1;
+ ComboBox aFontBox;
+ CheckBox aBoldCheckBox;
+ CheckBox aItalicCheckBox;
+ OKButton aOKButton1;
+ CancelButton aCancelButton1;
+ SmShowFont aShowFont;
+ FixedText aFixedText2;
+
+ Font Face;
+
+ DECL_LINK(FontSelectHdl, ComboBox *);
+ DECL_LINK(FontModifyHdl, ComboBox *);
+ DECL_LINK(AttrChangeHdl, CheckBox *);
+
+ void InitColor_Impl();
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+public:
+ SmFontDialog(Window * pParent, OutputDevice *pFntListDevice, bool bHideCheckboxes, bool bFreeRes = true);
+
+ const Font& GetFont() const { return Face; }
+ void SetFont(const Font &rFont);
+};
+
+/**************************************************************************/
+
+class SmFontSizeDialog : public ModalDialog
+{
+ FixedText aFixedText1;
+ MetricField aBaseSize;
+ FixedText aFixedText4;
+ MetricField aTextSize;
+ FixedText aFixedText5;
+ MetricField aIndexSize;
+ FixedText aFixedText6;
+ MetricField aFunctionSize;
+ FixedText aFixedText7;
+ MetricField aOperatorSize;
+ FixedText aFixedText8;
+ MetricField aBorderSize;
+ FixedLine aFixedLine1;
+ OKButton aOKButton1;
+ CancelButton aCancelButton1;
+ PushButton aDefaultButton;
+
+ DECL_LINK(DefaultButtonClickHdl, Button *);
+
+public:
+ SmFontSizeDialog(Window *pParent, bool bFreeRes = true);
+
+ void ReadFrom(const SmFormat &rFormat);
+ void WriteTo (SmFormat &rFormat) const;
+};
+
+/**************************************************************************/
+
+class SmFontTypeDialog : public ModalDialog
+{
+ FixedText aFixedText1;
+ SmFontPickListBox aVariableFont;
+ FixedText aFixedText2;
+ SmFontPickListBox aFunctionFont;
+ FixedText aFixedText3;
+ SmFontPickListBox aNumberFont;
+ FixedText aFixedText4;
+ SmFontPickListBox aTextFont;
+ FixedText aFixedText5;
+ SmFontPickListBox aSerifFont;
+ FixedText aFixedText6;
+ SmFontPickListBox aSansFont;
+ FixedText aFixedText7;
+ SmFontPickListBox aFixedFont;
+ FixedLine aFixedLine1;
+ FixedLine aFixedLine2;
+ OKButton aOKButton1;
+ CancelButton aCancelButton1;
+ MenuButton aMenuButton;
+ PushButton aDefaultButton;
+
+ OutputDevice *pFontListDev;
+
+ DECL_LINK(MenuSelectHdl, Menu *);
+ DECL_LINK(DefaultButtonClickHdl, Button *);
+
+public:
+ SmFontTypeDialog(Window *pParent, OutputDevice *pFntListDevice, bool bFreeRes = true);
+
+ void ReadFrom(const SmFormat &rFormat);
+ void WriteTo (SmFormat &rFormat) const;
+};
+
+/**************************************************************************/
+
+#define NOCATEGORIES 10
+
+class SmCategoryDesc : public Resource
+{
+ XubString Name;
+ XubString *Strings[4];
+ Bitmap *Graphics[4]; /* regular bitmaps */
+ sal_uInt16 Minimum[4];
+ sal_uInt16 Maximum[4];
+ sal_uInt16 Value[4];
+
+public:
+ SmCategoryDesc(const ResId &rResId, sal_uInt16 nCategoryIdx);
+ ~SmCategoryDesc();
+
+ const XubString & GetName() const { return Name; }
+ const XubString * GetString(sal_uInt16 Index) const { return Strings[Index]; }
+ sal_uInt16 GetMinimum(sal_uInt16 Index) { return Minimum[Index]; }
+ sal_uInt16 GetMaximum(sal_uInt16 Index) { return Maximum[Index]; }
+ sal_uInt16 GetValue(sal_uInt16 Index) const { return Value[Index]; }
+ void SetValue(sal_uInt16 Index, sal_uInt16 nVal) { Value[Index] = nVal;}
+
+ const Bitmap * GetGraphic(sal_uInt16 Index) const
+ {
+ return Graphics[Index];
+ }
+};
+
+
+class SmDistanceDialog : public ModalDialog
+{
+ FixedText aFixedText1;
+ MetricField aMetricField1;
+ FixedText aFixedText2;
+ MetricField aMetricField2;
+ FixedText aFixedText3;
+ MetricField aMetricField3;
+ CheckBox aCheckBox1;
+ FixedText aFixedText4;
+ MetricField aMetricField4;
+ OKButton aOKButton1;
+ CancelButton aCancelButton1;
+ MenuButton aMenuButton;
+ PushButton aDefaultButton;
+ FixedBitmap aBitmap;
+ FixedLine aFixedLine;
+
+ SmCategoryDesc *Categories[NOCATEGORIES];
+ sal_uInt16 nActiveCategory;
+ bool bScaleAllBrackets;
+
+ DECL_LINK(GetFocusHdl, Control *);
+ DECL_LINK(MenuSelectHdl, Menu *);
+ DECL_LINK(DefaultButtonClickHdl, Button *);
+ DECL_LINK(CheckBoxClickHdl, CheckBox *);
+
+ using Window::SetHelpId;
+ void SetHelpId(MetricField &rField, const rtl::OString& sHelpId);
+ void SetCategory(sal_uInt16 Category);
+
+public:
+ SmDistanceDialog(Window *pParent, bool bFreeRes = true);
+ ~SmDistanceDialog();
+
+ void ReadFrom(const SmFormat &rFormat);
+ void WriteTo (SmFormat &rFormat) /*const*/;
+
+ // Window
+ virtual void DataChanged( const DataChangedEvent &rEvt );
+};
+
+
+/**************************************************************************/
+
+
+class SmAlignDialog : public ModalDialog
+{
+ RadioButton aLeft;
+ RadioButton aCenter;
+ RadioButton aRight;
+ FixedLine aFixedLine1;
+ OKButton aOKButton1;
+ CancelButton aCancelButton1;
+ PushButton aDefaultButton;
+
+ DECL_LINK(DefaultButtonClickHdl, Button *);
+
+public:
+ SmAlignDialog(Window *pParent, bool bFreeRes = true);
+
+ void ReadFrom(const SmFormat &rFormat);
+ void WriteTo (SmFormat &rFormat) const;
+};
+
+/**************************************************************************/
+
+class SmShowSymbolSet : public Control
+{
+ SymbolPtrVec_t aSymbolSet;
+ ScrollBar aVScrollBar;
+ Size aOutputSize;
+ Link aSelectHdlLink;
+ Link aDblClickHdlLink;
+ sal_uInt16 nLen;
+ sal_uInt16 nRows, nColumns;
+ sal_uInt16 nSelectSymbol;
+
+ virtual void Paint(const Rectangle&);
+ virtual void MouseButtonDown(const MouseEvent& rMEvt);
+ virtual void KeyInput(const KeyEvent& rKEvt);
+
+ DECL_LINK( ScrollHdl, ScrollBar* );
+
+public:
+ SmShowSymbolSet(Window *pParent, const ResId& rResId);
+
+ void SetSymbolSet(const SymbolPtrVec_t& rSymbolSet);
+
+ void SelectSymbol(sal_uInt16 nSymbol);
+ sal_uInt16 GetSelectSymbol() const { return nSelectSymbol; }
+
+ void SetSelectHdl(const Link& rLink) { aSelectHdlLink = rLink; }
+ void SetDblClickHdl(const Link& rLink) { aDblClickHdlLink = rLink; }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SmShowSymbol : public Control
+{
+ Link aDblClickHdlLink;
+
+ virtual void Paint(const Rectangle&);
+ virtual void MouseButtonDown(const MouseEvent& rMEvt);
+
+public:
+ SmShowSymbol(Window *pParent, const ResId& rResId) :
+ Control(pParent, rResId) {}
+
+ void SetSymbol(const SmSym *pSymbol);
+ void SetDblClickHdl(const Link &rLink) { aDblClickHdlLink = rLink; }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SmSymDefineDialog;
+
+class SmSymbolDialog : public ModalDialog
+{
+ FixedText aSymbolSetText;
+ ListBox aSymbolSets;
+ SmShowSymbolSet aSymbolSetDisplay;
+ FixedText aSymbolName;
+ SmShowSymbol aSymbolDisplay;
+ PushButton aGetBtn;
+ PushButton aCloseBtn;
+ PushButton aEditBtn;
+
+ SmViewShell &rViewSh;
+ SmSymbolManager &rSymbolMgr;
+
+ String aSymbolSetName;
+ SymbolPtrVec_t aSymbolSet;
+
+ OutputDevice *pFontListDev;
+
+ DECL_LINK(SymbolSetChangeHdl, ListBox *);
+ DECL_LINK(SymbolChangeHdl, SmShowSymbolSet *);
+ DECL_LINK(SymbolDblClickHdl, SmShowSymbolSet *);
+ DECL_LINK(CloseClickHdl, Button *);
+ DECL_LINK(EditClickHdl, Button *);
+ DECL_LINK(GetClickHdl, Button *);
+
+ void FillSymbolSets(bool bDeleteText = true);
+ void SetSymbolSetManager(SmSymbolManager &rMgr);
+ const SmSym *GetSymbol() const;
+ void InitColor_Impl();
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+public:
+ SmSymbolDialog(Window * pParent, OutputDevice *pFntListDevice,
+ SmSymbolManager &rSymbolMgr, SmViewShell &rViewShell, bool bFreeRes = true);
+ virtual ~SmSymbolDialog();
+
+ bool SelectSymbolSet(const XubString &rSymbolSetName);
+ void SelectSymbol(sal_uInt16 nSymbolPos);
+ sal_uInt16 GetSelectedSymbol() const { return aSymbolSetDisplay.GetSelectSymbol(); }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SmShowChar : public Control
+{
+ virtual void Paint(const Rectangle&);
+
+public:
+ SmShowChar(Window *pParent, const ResId& rResId)
+ : Control(pParent, rResId)
+ {
+ }
+
+ void SetSymbol( const SmSym *pSym );
+ void SetSymbol( sal_UCS4 cChar, const Font &rFont );
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SmSymDefineDialog : public ModalDialog
+{
+ FixedText aOldSymbolText;
+ ComboBox aOldSymbols;
+ FixedText aOldSymbolSetText;
+ ComboBox aOldSymbolSets;
+ SvxShowCharSet aCharsetDisplay;
+ FixedText aSymbolText;
+ ComboBox aSymbols;
+ FixedText aSymbolSetText;
+ ComboBox aSymbolSets;
+ FixedText aFontText;
+ ListBox aFonts;
+ FixedText aFontsSubsetFT;
+ ListBox aFontsSubsetLB;
+ FixedText aStyleText;
+ FontStyleBox aStyles;
+ FixedText aOldSymbolName;
+ SmShowChar aOldSymbolDisplay;
+ FixedText aOldSymbolSetName;
+ FixedText aSymbolName;
+ SmShowChar aSymbolDisplay;
+ FixedText aSymbolSetName;
+ OKButton aOkBtn;
+ CancelButton aCancelBtn;
+ PushButton aAddBtn;
+ PushButton aChangeBtn;
+ PushButton aDeleteBtn;
+ FixedImage aRightArrow;
+ Image aRigthArrow_Im;
+
+ SmSymbolManager aSymbolMgrCopy,
+ &rSymbolMgr;
+ const SmSym *pOrigSymbol;
+
+ const SubsetMap *pSubsetMap;
+ FontList *pFontList;
+
+ DECL_LINK(OldSymbolChangeHdl, ComboBox *);
+ DECL_LINK(OldSymbolSetChangeHdl, ComboBox *);
+ DECL_LINK(ModifyHdl, ComboBox *);
+ DECL_LINK(FontChangeHdl, ListBox *);
+ DECL_LINK(SubsetChangeHdl, ListBox*);
+ DECL_LINK(StyleChangeHdl, ComboBox *);
+ DECL_LINK(CharHighlightHdl, Control* pControl);
+ DECL_LINK(AddClickHdl, Button *);
+ DECL_LINK(ChangeClickHdl, Button *);
+ DECL_LINK(DeleteClickHdl, Button *);
+
+ void FillSymbols(ComboBox &rComboBox, bool bDeleteText = true);
+ void FillSymbolSets(ComboBox &rComboBox, bool bDeleteText = true);
+ void FillFonts(bool bDeleteText = true);
+ void FillStyles(bool bDeleteText = true);
+
+ void SetSymbolSetManager(const SmSymbolManager &rMgr);
+ void SetFont(const XubString &rFontName, const XubString &rStyleName);
+ void SetOrigSymbol(const SmSym *pSymbol, const XubString &rSymbolSetName);
+ void UpdateButtons();
+
+ bool SelectSymbolSet(ComboBox &rComboBox, const XubString &rSymbolSetName,
+ bool bDeleteText);
+ bool SelectSymbol(ComboBox &rComboBox, const XubString &rSymbolName,
+ bool bDeleteText);
+ bool SelectFont(const XubString &rFontName, bool bApplyFont);
+ bool SelectStyle(const XubString &rStyleName, bool bApplyFont);
+
+ SmSym * GetSymbol(const ComboBox &rComboBox);
+ const SmSym * GetSymbol(const ComboBox &rComboBox) const
+ {
+ return ((SmSymDefineDialog *) this)->GetSymbol(rComboBox);
+ }
+
+ void InitColor_Impl();
+
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+
+public:
+ SmSymDefineDialog(Window *pParent, OutputDevice *pFntListDevice, SmSymbolManager &rMgr, bool bFreeRes = true);
+ ~SmSymDefineDialog();
+
+ using OutputDevice::SetFont;
+
+ // Dialog
+ virtual short Execute();
+
+ bool SelectOldSymbolSet(const XubString &rSymbolSetName)
+ {
+ return SelectSymbolSet(aOldSymbolSets, rSymbolSetName, false);
+ }
+
+ bool SelectOldSymbol(const XubString &rSymbolName)
+ {
+ return SelectSymbol(aOldSymbols, rSymbolName, false);
+ }
+
+ bool SelectSymbolSet(const XubString &rSymbolSetName)
+ {
+ return SelectSymbolSet(aSymbolSets, rSymbolSetName, false);
+ }
+
+ bool SelectSymbol(const XubString &rSymbolName)
+ {
+ return SelectSymbol(aSymbols, rSymbolName, false);
+ }
+
+ bool SelectFont(const XubString &rFontName) { return SelectFont(rFontName, true); }
+ bool SelectStyle(const XubString &rStyleName) { return SelectStyle(rStyleName, true); };
+ void SelectChar(xub_Unicode cChar);
+};
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/document.hxx b/starmath/inc/document.hxx
new file mode 100644
index 000000000000..97753d9446e1
--- /dev/null
+++ b/starmath/inc/document.hxx
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef DOCUMENT_HXX
+#define DOCUMENT_HXX
+
+#define SMDLL 1
+
+#include <rtl/ustring.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/objsh.hxx>
+#include <sot/sotref.hxx>
+#include <sot/storage.hxx>
+#include <svl/lstner.hxx>
+#include <vcl/jobset.hxx>
+#include <vcl/virdev.hxx>
+
+#include <set>
+
+#include "format.hxx"
+#include "parse.hxx"
+#include "smmod.hxx"
+
+class SmNode;
+class SfxMenuBarManager;
+class SfxPrinter;
+class Printer;
+class SmCursor;
+
+#define HINT_DATACHANGED 1004
+
+#define SM30BIDENT ((sal_uLong)0x534D3033L)
+#define SM30IDENT ((sal_uLong)0x30334d53L)
+#define SM304AIDENT ((sal_uLong)0x34303330L)
+#define SM30VERSION ((sal_uLong)0x00010000L)
+#define SM50VERSION ((ULONG)0x00010001L) //Difference to SM30VERSION is
+ //the new border in the format.
+
+#define FRMIDENT ((sal_uLong)0x03031963L)
+#define FRMVERSION ((sal_uLong)0x00010001L)
+
+#define STAROFFICE_XML "StarOffice XML (Math)"
+#define MATHML_XML "MathML XML (Math)"
+
+/* Access to printer should happen through this class only
+ * ==========================================================================
+ *
+ * The printer can belong to the document or the OLE-Container. If the document
+ * is an OLE-Document the printer generally belongs to the container too.
+ * But the container mayby works with a different MapUnit than the server.
+ * Referring to the MapMode the printer will be accordingly adjusted in the
+ * constructor and restored in the destructor. This brings that this class
+ * is always allowed to exists only a short time (e.g. while painting).
+ * The control whether the printer is self-generated, gotten from the server
+ * or is NULL then, is taken by the DocShell in the method GetPrt(), for
+ * which the access is friend of the DocShell too.
+ */
+
+class SmDocShell;
+class EditEngine;
+
+////////////////////////////////////////////////////////////
+
+class SmPrinterAccess
+{
+ Printer* pPrinter;
+ OutputDevice* pRefDev;
+public:
+ SmPrinterAccess( SmDocShell &rDocShell );
+ ~SmPrinterAccess();
+ Printer* GetPrinter() { return pPrinter; }
+ OutputDevice* GetRefDev() { return pRefDev; }
+};
+
+
+////////////////////////////////////////////////////////////
+
+void SetEditEngineDefaultFonts(
+ EditEngine &rEditEngine,
+ SfxItemPool &rEditEngineItemPool );
+
+////////////////////////////////////////////////////////////
+
+class SmDocShell : public SfxObjectShell, public SfxListener
+{
+ friend class SmPrinterAccess;
+ friend class SmModel;
+ friend class SmCursor;
+
+ String aText;
+ SmFormat aFormat;
+ SmParser aInterpreter;
+ String aAccText;
+ SmNode *pTree;
+ SfxMenuBarManager *pMenuMgr;
+ SfxItemPool *pEditEngineItemPool;
+ EditEngine *pEditEngine;
+ SfxPrinter *pPrinter; //q.v. comment to SmPrinter Access!
+ Printer *pTmpPrinter; //ditto
+ long nLeftBorder,
+ nRightBorder,
+ nTopBorder,
+ nBottomBorder;
+ sal_uInt16 nModifyCount;
+ bool bIsFormulaArranged;
+ SmCursor *pCursor;
+ std::set< rtl::OUString > aUsedSymbols; // to export used symbols only when saving
+
+
+
+ virtual void SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType);
+
+ bool WriteAsMathType3( SfxMedium& );
+
+ virtual void Draw(OutputDevice *pDevice,
+ const JobSetup & rSetup,
+ sal_uInt16 nAspect = ASPECT_CONTENT);
+
+ virtual void FillClass(SvGlobalName* pClassName,
+ sal_uInt32* pFormat,
+ String* pAppName,
+ String* pFullTypeName,
+ String* pShortTypeName,
+ sal_Int32 nFileFormat,
+ sal_Bool bTemplate = sal_False ) const;
+
+ virtual sal_Bool SetData( const String& rData );
+ virtual sal_uLong GetMiscStatus() const;
+ virtual void OnDocumentPrinterChanged( Printer * );
+ virtual sal_Bool InitNew( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );
+ virtual sal_Bool Load( SfxMedium& rMedium );
+ void ImplSave( SvStorageStreamRef xStrm );
+ virtual sal_Bool Save();
+ virtual sal_Bool SaveAs( SfxMedium& rMedium );
+ virtual sal_Bool ConvertTo( SfxMedium &rMedium );
+ virtual sal_Bool SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );
+
+ Printer *GetPrt();
+ OutputDevice* GetRefDev();
+
+ bool IsFormulaArranged() const { return bIsFormulaArranged; }
+ void SetFormulaArranged(bool bVal) { bIsFormulaArranged = bVal; }
+
+ virtual sal_Bool ConvertFrom(SfxMedium &rMedium);
+
+ /** Called whenever the formula is changed
+ * Deletes the current cursor
+ */
+ void InvalidateCursor();
+
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START+1)
+ using SotObject::GetInterface;
+ SFX_DECL_OBJECTFACTORY();
+
+ SmDocShell( const sal_uInt64 i_nSfxCreationFlags );
+ virtual ~SmDocShell();
+
+ void LoadSymbols();
+ void SaveSymbols();
+
+ void ArrangeFormula();
+
+ //Access for the View. This access is not for the OLE-case!
+ //and for the communication with the SFX!
+ //All internal printer uses should work with the SmPrinterAccess only
+ bool HasPrinter() { return 0 != pPrinter; }
+ SfxPrinter *GetPrinter() { GetPrt(); return pPrinter; }
+ void SetPrinter( SfxPrinter * );
+
+ const String GetComment() const;
+
+ // to replace chars that can not be saved with the document...
+ sal_Bool ReplaceBadChars();
+
+ void UpdateText();
+ void SetText(const String& rBuffer);
+ String& GetText() { return (aText); }
+ void SetFormat(SmFormat& rFormat);
+ const SmFormat& GetFormat() { return (aFormat); }
+
+ void Parse();
+ SmParser & GetParser() { return aInterpreter; }
+ const SmNode * GetFormulaTree() const { return pTree; }
+ void SetFormulaTree(SmNode *&rTree) { pTree = rTree; }
+
+ const std::set< rtl::OUString > & GetUsedSymbols() const { return aUsedSymbols; }
+
+ String GetAccessibleText();
+
+ EditEngine & GetEditEngine();
+ SfxItemPool & GetEditEngineItemPool();
+
+ void DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSelection = false);
+ Size GetSize();
+
+ void Repaint();
+
+ virtual ::svl::IUndoManager *GetUndoManager ();
+
+ virtual SfxItemPool& GetPool() const;
+
+ void Execute( SfxRequest& rReq );
+ void GetState(SfxItemSet &);
+
+ virtual void SetVisArea (const Rectangle & rVisArea);
+ virtual void SetModified(sal_Bool bModified);
+
+ /** Get a cursor for modifying this document
+ * @remarks Don't store this reference, a new cursor may be made...
+ */
+ SmCursor& GetCursor();
+ /** True, if cursor have previously been requested and thus
+ * has some sort of position.
+ */
+ bool HasCursor() { return pCursor != NULL; }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/edit.hxx b/starmath/inc/edit.hxx
new file mode 100644
index 000000000000..454877dcaa7e
--- /dev/null
+++ b/starmath/inc/edit.hxx
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef EDIT_HXX
+#define EDIT_HXX
+
+#include <vcl/window.hxx>
+#include <vcl/timer.hxx>
+#include <svtools/transfer.hxx>
+#include <editeng/editdata.hxx>
+#include <svtools/colorcfg.hxx>
+
+class SmDocShell;
+class SmViewShell;
+class EditView;
+class EditEngine;
+class EditStatus;
+class ScrollBar;
+class ScrollBarBox;
+class DataChangedEvent;
+class Menu;
+class SmCmdBoxWindow;
+class SmEditAccessible;
+class CommandEvent;
+
+/**************************************************************************/
+
+ void SmGetLeftSelectionPart(const ESelection &rSelection,
+ sal_uInt16 &nPara, sal_uInt16 &nPos);
+
+/**************************************************************************/
+
+class SmEditWindow : public Window, public DropTargetHelper
+{
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > xAccessible;
+ SmEditAccessible * pAccessible;
+
+ SmCmdBoxWindow &rCmdBox;
+ EditView *pEditView;
+ ScrollBar *pHScrollBar,
+ *pVScrollBar;
+ ScrollBarBox *pScrollBox;
+ Timer aModifyTimer,
+ aCursorMoveTimer;
+ ESelection aOldSelection;
+
+ virtual void KeyInput(const KeyEvent& rKEvt);
+ virtual void Command(const CommandEvent& rCEvt);
+ DECL_LINK(MenuSelectHdl, Menu *);
+ DECL_LINK(ModifyTimerHdl, Timer *);
+ DECL_LINK(CursorMoveTimerHdl, Timer *);
+
+ virtual void DataChanged( const DataChangedEvent& );
+ virtual void Resize();
+ virtual void MouseMove(const MouseEvent &rEvt);
+ virtual void MouseButtonUp(const MouseEvent &rEvt);
+ virtual void MouseButtonDown(const MouseEvent &rEvt);
+
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt );
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt );
+ virtual void Paint(const Rectangle& rRect);
+
+ DECL_LINK(EditStatusHdl ,EditStatus *);
+ DECL_LINK(ScrollHdl, ScrollBar *);
+
+ void CreateEditView();
+
+ Rectangle AdjustScrollBars();
+ void SetScrollBarRanges();
+ void InitScrollBars();
+ void InvalidateSlots();
+
+public:
+ SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin );
+ ~SmEditWindow();
+
+ SmDocShell * GetDoc();
+ SmViewShell * GetView();
+ EditView * GetEditView() { return pEditView; }
+ EditEngine * GetEditEngine();
+ SfxItemPool * GetEditEngineItemPool();
+
+ // Window
+ virtual void SetText(const XubString &rText);
+ virtual String GetText() const;
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ ESelection GetSelection() const;
+ void SetSelection(const ESelection &rSel);
+
+ bool IsEmpty() const;
+ bool IsSelected() const;
+ bool IsAllSelected() const;
+ void Cut();
+ void Copy();
+ void Paste();
+ void Delete();
+ void SelectAll();
+ void InsertText(const String &rText);
+ void InsertCommand(sal_uInt16 nCommand);
+ void MarkError(const Point &rPos);
+ void SelNextMark();
+ void SelPrevMark();
+ bool HasMark(const String &rText) const;
+
+ void Flush();
+ void DeleteEditView( SmViewShell &rView );
+
+ void ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg );
+
+ bool HandleWheelCommands( const CommandEvent &rCEvt );
+ bool IsInlineEditEnabled();
+ void StartCursorMove();
+
+ // for Accessibility
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ using Window::GetAccessible;
+ SmEditAccessible * GetAccessible() { return pAccessible; }
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/format.hxx b/starmath/inc/format.hxx
new file mode 100644
index 000000000000..98c34c4f4dc2
--- /dev/null
+++ b/starmath/inc/format.hxx
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef FORMAT_HXX
+#define FORMAT_HXX
+
+
+#include <svl/smplhint.hxx>
+#include <svl/brdcst.hxx>
+#include "utility.hxx"
+#include <types.hxx>
+
+
+#define SM_FMT_VERSION_51 ((sal_uInt8) 0x01)
+#define SM_FMT_VERSION_NOW SM_FMT_VERSION_51
+
+#define FNTNAME_TIMES "Times New Roman"
+#define FNTNAME_HELV "Helvetica"
+#define FNTNAME_COUR "Courier"
+#define FNTNAME_MATH FONTNAME_MATH
+
+
+// symbolic names used as array indices
+#define SIZ_BEGIN 0
+#define SIZ_TEXT 0
+#define SIZ_INDEX 1
+#define SIZ_FUNCTION 2
+#define SIZ_OPERATOR 3
+#define SIZ_LIMITS 4
+#define SIZ_END 4
+
+// symbolic names used as array indices
+#define FNT_BEGIN 0
+#define FNT_VARIABLE 0
+#define FNT_FUNCTION 1
+#define FNT_NUMBER 2
+#define FNT_TEXT 3
+#define FNT_SERIF 4
+#define FNT_SANS 5
+#define FNT_FIXED 6
+#define FNT_MATH 7
+#define FNT_END 7
+
+// symbolic names used as array indices
+#define DIS_BEGIN 0
+#define DIS_HORIZONTAL 0
+#define DIS_VERTICAL 1
+#define DIS_ROOT 2
+#define DIS_SUPERSCRIPT 3
+#define DIS_SUBSCRIPT 4
+#define DIS_NUMERATOR 5
+#define DIS_DENOMINATOR 6
+#define DIS_FRACTION 7
+#define DIS_STROKEWIDTH 8
+#define DIS_UPPERLIMIT 9
+#define DIS_LOWERLIMIT 10
+#define DIS_BRACKETSIZE 11
+#define DIS_BRACKETSPACE 12
+#define DIS_MATRIXROW 13
+#define DIS_MATRIXCOL 14
+#define DIS_ORNAMENTSIZE 15
+#define DIS_ORNAMENTSPACE 16
+#define DIS_OPERATORSIZE 17
+#define DIS_OPERATORSPACE 18
+#define DIS_LEFTSPACE 19
+#define DIS_RIGHTSPACE 20
+#define DIS_TOPSPACE 21
+#define DIS_BOTTOMSPACE 22
+#define DIS_NORMALBRACKETSIZE 23
+#define DIS_END 23
+
+
+// to be broadcastet on format changes:
+#define HINT_FORMATCHANGED 10003
+
+enum SmHorAlign { AlignLeft, AlignCenter, AlignRight };
+
+String GetDefaultFontName( LanguageType nLang, sal_uInt16 nIdent );
+
+class SmFormat : public SfxBroadcaster
+{
+ SmFace vFont[FNT_END + 1];
+ bool bDefaultFont[FNT_END + 1];
+ Size aBaseSize;
+ long nVersion;
+ sal_uInt16 vSize[SIZ_END + 1];
+ sal_uInt16 vDist[DIS_END + 1];
+ SmHorAlign eHorAlign;
+ sal_Int16 nGreekCharStyle;
+ bool bIsTextmode,
+ bScaleNormalBrackets;
+
+public:
+ SmFormat();
+ SmFormat(const SmFormat &rFormat) : SfxBroadcaster() { *this = rFormat; }
+
+ const Size & GetBaseSize() const { return aBaseSize; }
+ void SetBaseSize(const Size &rSize) { aBaseSize = rSize; }
+
+ const SmFace & GetFont(sal_uInt16 nIdent) const { return vFont[nIdent]; }
+ void SetFont(sal_uInt16 nIdent, const SmFace &rFont, bool bDefault = false);
+ void SetFontSize(sal_uInt16 nIdent, const Size &rSize) { vFont[nIdent].SetSize( rSize ); }
+
+ void SetDefaultFont(sal_uInt16 nIdent, bool bVal) { bDefaultFont[nIdent] = bVal; }
+ bool IsDefaultFont(sal_uInt16 nIdent) const { return bDefaultFont[nIdent]; }
+
+ sal_uInt16 GetRelSize(sal_uInt16 nIdent) const { return vSize[nIdent]; }
+ void SetRelSize(sal_uInt16 nIdent, sal_uInt16 nVal) { vSize[nIdent] = nVal;}
+
+ sal_uInt16 GetDistance(sal_uInt16 nIdent) const { return vDist[nIdent]; }
+ void SetDistance(sal_uInt16 nIdent, sal_uInt16 nVal) { vDist[nIdent] = nVal; }
+
+ SmHorAlign GetHorAlign() const { return eHorAlign; }
+ void SetHorAlign(SmHorAlign eAlign) { eHorAlign = eAlign; }
+
+ bool IsTextmode() const { return bIsTextmode; }
+ void SetTextmode(bool bVal) { bIsTextmode = bVal; }
+
+ sal_Int16 GetGreekCharStyle() const { return nGreekCharStyle; }
+ void SetGreekCharStyle(sal_Int16 nVal) { nGreekCharStyle = nVal; }
+
+ bool IsScaleNormalBrackets() const { return bScaleNormalBrackets; }
+ void SetScaleNormalBrackets(bool bVal) { bScaleNormalBrackets = bVal; }
+
+ long GetVersion() const { return nVersion; }
+
+ //! at time (5.1) use only the lower byte!!!
+ void SetVersion(long nVer) { nVersion = nVer; }
+
+ SmFormat & operator = (const SmFormat &rFormat);
+
+ bool operator == (const SmFormat &rFormat) const;
+ inline bool operator != (const SmFormat &rFormat) const;
+
+ void RequestApplyChanges() const
+ {
+ ((SmFormat *) this)->Broadcast(SfxSimpleHint(HINT_FORMATCHANGED));
+ }
+
+};
+
+inline bool SmFormat::operator != (const SmFormat &rFormat) const
+{
+ return !(*this == rFormat);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/helpids.h b/starmath/inc/helpids.h
new file mode 100644
index 000000000000..f27b47edcdf3
--- /dev/null
+++ b/starmath/inc/helpids.h
@@ -0,0 +1,326 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef STARMATH_HELPIDS_H
+#define STARMATH_HELPIDS_H
+
+#define HID_SMA_OPTIONSDIALOG "STARMATH_HID_SMA_OPTIONSDIALOG"
+#define HID_SMA_FONTDIALOG "STARMATH_HID_SMA_FONTDIALOG"
+#define HID_SMA_FONTSIZEDIALOG "STARMATH_HID_SMA_FONTSIZEDIALOG"
+#define HID_SMA_FONTTYPEDIALOG "STARMATH_HID_SMA_FONTTYPEDIALOG"
+#define HID_SMA_DISTANCEDIALOG "STARMATH_HID_SMA_DISTANCEDIALOG"
+#define HID_SMA_ALIGNDIALOG "STARMATH_HID_SMA_ALIGNDIALOG"
+#define HID_SMA_PRINTOPTIONPAGE "STARMATH_HID_SMA_PRINTOPTIONPAGE"
+#define HID_SMA_SYMBOLDIALOG "STARMATH_HID_SMA_SYMBOLDIALOG"
+#define HID_SMA_SYMDEFINEDIALOG "STARMATH_HID_SMA_SYMDEFINEDIALOG"
+#define HID_SMA_EXTRAOPTIONPAGE "STARMATH_HID_SMA_EXTRAOPTIONPAGE"
+#define HID_SMA_DOCSAVEQUERY "STARMATH_HID_SMA_DOCSAVEQUERY"
+#define HID_SMA_OBJECTSAVEQUERY "STARMATH_HID_SMA_OBJECTSAVEQUERY"
+#define HID_SMA_DEFAULTSAVEQUERY "STARMATH_HID_SMA_DEFAULTSAVEQUERY"
+#define HID_SMA_ILLEGALOBJECTERROR "STARMATH_HID_SMA_ILLEGALOBJECTERROR"
+#define HID_SMA_ILLEGALFILEERROR "STARMATH_HID_SMA_ILLEGALFILEERROR"
+#define HID_SMA_WRITESYMBOLERROR "STARMATH_HID_SMA_WRITESYMBOLERROR"
+#define HID_SMA_READSYMBOLERROR "STARMATH_HID_SMA_READSYMBOLERROR"
+#define HID_SMA_NOMATHTYPEFACEWARNING "STARMATH_HID_SMA_NOMATHTYPEFACEWARNING"
+#define HID_SMA_OBJECTNAME "STARMATH_HID_SMA_OBJECTNAME"
+#define HID_SMA_VIEWNAME "STARMATH_HID_SMA_VIEWNAME"
+#define HID_SMA_UNDOEDITNAME "STARMATH_HID_SMA_UNDOEDITNAME"
+#define HID_SMA_UNDOFORMATNAME "STARMATH_HID_SMA_UNDOFORMATNAME"
+#define HID_SMA_APPICO "STARMATH_HID_SMA_APPICO"
+#define HID_SMA_DOCICO "STARMATH_HID_SMA_DOCICO"
+#define HID_SMA_TMPICO "STARMATH_HID_SMA_TMPICO"
+#define HID_SMA_COMMANDMENU "STARMATH_HID_SMA_COMMANDMENU"
+#define HID_SMA_VIEWMENU "STARMATH_HID_SMA_VIEWMENU"
+#define HID_SMA_DISTANCEMENU "STARMATH_HID_SMA_DISTANCEMENU"
+#define HID_SMA_FONTMENU "STARMATH_HID_SMA_FONTMENU"
+#define HID_SMA_STARTUPWINDOW "STARMATH_HID_SMA_STARTUPWINDOW"
+#define HID_SMA_TOOLBOXWINDOW "STARMATH_HID_SMA_TOOLBOXWINDOW"
+#define HID_SMA_CMDBOXWINDOW "STARMATH_HID_SMA_CMDBOXWINDOW"
+#define HID_SMA_UPDATEOBJECT "STARMATH_HID_SMA_UPDATEOBJECT"
+#define HID_SMA_FONTREGULAR "STARMATH_HID_SMA_FONTREGULAR"
+#define HID_SMA_FONTITALIC "STARMATH_HID_SMA_FONTITALIC"
+#define HID_SMA_FONTBOLD "STARMATH_HID_SMA_FONTBOLD"
+#define HID_SMA_PRINTOPTION "STARMATH_HID_SMA_PRINTOPTION"
+#define HID_SMA_DOCUMENTSTR "STARMATH_HID_SMA_DOCUMENTSTR"
+#define HID_SMA_SYMBOLFILESSTR "STARMATH_HID_SMA_SYMBOLFILESSTR"
+#define HID_SMA_ALLFILESSTR "STARMATH_HID_SMA_ALLFILESSTR"
+#define HID_SMA_CREATORSTR "STARMATH_HID_SMA_CREATORSTR"
+#define HID_SMA_FILESMFTYP "STARMATH_HID_SMA_FILESMFTYP"
+#define HID_SMA_FILESYMTYP "STARMATH_HID_SMA_FILESYMTYP"
+#define HID_SMA_WIN_DOCUMENT "STARMATH_HID_SMA_WIN_DOCUMENT"
+#define HID_SMA_COMMAND_WIN_EDIT "STARMATH_HID_SMA_COMMAND_WIN_EDIT"
+
+#define HID_SMA_PLUSX "STARMATH_HID_SMA_PLUSX"
+#define HID_SMA_MINUSX "STARMATH_HID_SMA_MINUSX"
+#define HID_SMA_PLUSMINUSX "STARMATH_HID_SMA_PLUSMINUSX"
+#define HID_SMA_MINUSPLUSX "STARMATH_HID_SMA_MINUSPLUSX"
+#define HID_SMA_NEGX "STARMATH_HID_SMA_NEGX"
+#define HID_SMA_XPLUSY "STARMATH_HID_SMA_XPLUSY"
+#define HID_SMA_XMINUSY "STARMATH_HID_SMA_XMINUSY"
+#define HID_SMA_XCDOTY "STARMATH_HID_SMA_XCDOTY"
+#define HID_SMA_XTIMESY "STARMATH_HID_SMA_XTIMESY"
+#define HID_SMA_XSYMTIMESY "STARMATH_HID_SMA_XSYMTIMESY"
+#define HID_SMA_XSYMDIVIDEY "STARMATH_HID_SMA_XSYMDIVIDEY"
+#define HID_SMA_XDIVY "STARMATH_HID_SMA_XDIVY"
+#define HID_SMA_XOVERY "STARMATH_HID_SMA_XOVERY"
+#define HID_SMA_XODIVIDEY "STARMATH_HID_SMA_XODIVIDEY"
+#define HID_SMA_XODOTY "STARMATH_HID_SMA_XODOTY"
+#define HID_SMA_XOMINUSY "STARMATH_HID_SMA_XOMINUSY"
+#define HID_SMA_XOPLUSY "STARMATH_HID_SMA_XOPLUSY"
+#define HID_SMA_XOTIMESY "STARMATH_HID_SMA_XOTIMESY"
+#define HID_SMA_XANDY "STARMATH_HID_SMA_XANDY"
+#define HID_SMA_XORY "STARMATH_HID_SMA_XORY"
+#define HID_SMA_XEQY "STARMATH_HID_SMA_XEQY"
+#define HID_SMA_XNEQY "STARMATH_HID_SMA_XNEQY"
+#define HID_SMA_XLTY "STARMATH_HID_SMA_XLTY"
+#define HID_SMA_XGTY "STARMATH_HID_SMA_XGTY"
+#define HID_SMA_XLEY "STARMATH_HID_SMA_XLEY"
+#define HID_SMA_XGEY "STARMATH_HID_SMA_XGEY"
+#define HID_SMA_XLESLANTY "STARMATH_HID_SMA_XLESLANTY"
+#define HID_SMA_XGESLANTY "STARMATH_HID_SMA_XGESLANTY"
+#define HID_SMA_XLLY "STARMATH_HID_SMA_XLLY"
+#define HID_SMA_XGGY "STARMATH_HID_SMA_XGGY"
+#define HID_SMA_XDEFY "STARMATH_HID_SMA_XDEFY"
+#define HID_SMA_XEQUIVY "STARMATH_HID_SMA_XEQUIVY"
+#define HID_SMA_XAPPROXY "STARMATH_HID_SMA_XAPPROXY"
+#define HID_SMA_XSIMY "STARMATH_HID_SMA_XSIMY"
+#define HID_SMA_XSIMEQY "STARMATH_HID_SMA_XSIMEQY"
+#define HID_SMA_XPROPY "STARMATH_HID_SMA_XPROPY"
+#define HID_SMA_XORTHOY "STARMATH_HID_SMA_XORTHOY"
+#define HID_SMA_XPARALLELY "STARMATH_HID_SMA_XPARALLELY"
+#define HID_SMA_XTOWARDY "STARMATH_HID_SMA_XTOWARDY"
+#define HID_SMA_XTRANSLY "STARMATH_HID_SMA_XTRANSLY"
+#define HID_SMA_XTRANSRY "STARMATH_HID_SMA_XTRANSRY"
+#define HID_SMA_XINY "STARMATH_HID_SMA_XINY"
+#define HID_SMA_XNOTINY "STARMATH_HID_SMA_XNOTINY"
+#define HID_SMA_XOWNSY "STARMATH_HID_SMA_XOWNSY"
+#define HID_SMA_XUNIONY "STARMATH_HID_SMA_XUNIONY"
+#define HID_SMA_XINTERSECTIONY "STARMATH_HID_SMA_XINTERSECTIONY"
+#define HID_SMA_XSETMINUSY "STARMATH_HID_SMA_XSETMINUSY"
+#define HID_SMA_XSLASHY "STARMATH_HID_SMA_XSLASHY"
+#define HID_SMA_XSUBSETY "STARMATH_HID_SMA_XSUBSETY"
+#define HID_SMA_XSUBSETEQY "STARMATH_HID_SMA_XSUBSETEQY"
+#define HID_SMA_XSUPSETY "STARMATH_HID_SMA_XSUPSETY"
+#define HID_SMA_XSUPSETEQY "STARMATH_HID_SMA_XSUPSETEQY"
+#define HID_SMA_XNSUBSETY "STARMATH_HID_SMA_XNSUBSETY"
+#define HID_SMA_XNSUBSETEQY "STARMATH_HID_SMA_XNSUBSETEQY"
+#define HID_SMA_XNSUPSETY "STARMATH_HID_SMA_XNSUPSETY"
+#define HID_SMA_XNSUPSETEQY "STARMATH_HID_SMA_XNSUPSETEQY"
+#define HID_SMA_ABSX "STARMATH_HID_SMA_ABSX"
+#define HID_SMA_FACTX "STARMATH_HID_SMA_FACTX"
+#define HID_SMA_SQRTX "STARMATH_HID_SMA_SQRTX"
+#define HID_SMA_NROOTXY "STARMATH_HID_SMA_NROOTXY"
+#define HID_SMA_EX "STARMATH_HID_SMA_EX"
+#define HID_SMA_EXPX "STARMATH_HID_SMA_EXPX"
+#define HID_SMA_LNX "STARMATH_HID_SMA_LNX"
+#define HID_SMA_LOGX "STARMATH_HID_SMA_LOGX"
+#define HID_SMA_SINX "STARMATH_HID_SMA_SINX"
+#define HID_SMA_COSX "STARMATH_HID_SMA_COSX"
+#define HID_SMA_TANX "STARMATH_HID_SMA_TANX"
+#define HID_SMA_COTX "STARMATH_HID_SMA_COTX"
+#define HID_SMA_ARCSINX "STARMATH_HID_SMA_ARCSINX"
+#define HID_SMA_ARCCOSX "STARMATH_HID_SMA_ARCCOSX"
+#define HID_SMA_ARCTANX "STARMATH_HID_SMA_ARCTANX"
+#define HID_SMA_ARCCOTX "STARMATH_HID_SMA_ARCCOTX"
+#define HID_SMA_SINHX "STARMATH_HID_SMA_SINHX"
+#define HID_SMA_COSHX "STARMATH_HID_SMA_COSHX"
+#define HID_SMA_TANHX "STARMATH_HID_SMA_TANHX"
+#define HID_SMA_COTHX "STARMATH_HID_SMA_COTHX"
+#define HID_SMA_ARSINHX "STARMATH_HID_SMA_ARSINHX"
+#define HID_SMA_ARCOSHX "STARMATH_HID_SMA_ARCOSHX"
+#define HID_SMA_ARTANHX "STARMATH_HID_SMA_ARTANHX"
+#define HID_SMA_ARCOTHX "STARMATH_HID_SMA_ARCOTHX"
+#define HID_SMA_SUMX "STARMATH_HID_SMA_SUMX"
+#define HID_SMA_PRODX "STARMATH_HID_SMA_PRODX"
+#define HID_SMA_COPRODX "STARMATH_HID_SMA_COPRODX"
+#define HID_SMA_LIMX "STARMATH_HID_SMA_LIMX"
+#define HID_SMA_LIMINFX "STARMATH_HID_SMA_LIMINFX"
+#define HID_SMA_LIMSUPX "STARMATH_HID_SMA_LIMSUPX"
+#define HID_SMA_EXISTS "STARMATH_HID_SMA_EXISTS"
+#define HID_SMA_FORALL "STARMATH_HID_SMA_FORALL"
+#define HID_SMA_NABLA "STARMATH_HID_SMA_NABLA"
+#define HID_SMA_INTX "STARMATH_HID_SMA_INTX"
+#define HID_SMA_IINTX "STARMATH_HID_SMA_IINTX"
+#define HID_SMA_IIINTX "STARMATH_HID_SMA_IIINTX"
+#define HID_SMA_LINTX "STARMATH_HID_SMA_LINTX"
+#define HID_SMA_LLINTX "STARMATH_HID_SMA_LLINTX"
+#define HID_SMA_LLLINTX "STARMATH_HID_SMA_LLLINTX"
+#define HID_SMA_FROMX "STARMATH_HID_SMA_FROMX"
+#define HID_SMA_TOX "STARMATH_HID_SMA_TOX"
+#define HID_SMA_FROMXTOY "STARMATH_HID_SMA_FROMXTOY"
+#define HID_SMA_XCIRCY "STARMATH_HID_SMA_XCIRCY"
+#define HID_SMA_XDIVIDESY "STARMATH_HID_SMA_XDIVIDESY"
+#define HID_SMA_XNDIVIDESY "STARMATH_HID_SMA_XNDIVIDESY"
+#define HID_SMA_DLARROW "STARMATH_HID_SMA_DLARROW"
+#define HID_SMA_DLRARROW "STARMATH_HID_SMA_DLRARROW"
+#define HID_SMA_DRARROW "STARMATH_HID_SMA_DRARROW"
+
+#define HID_SMA_MISC_CAT "STARMATH_HID_SMA_MISC_CAT"
+#define HID_SMA_UNBINOPS_CAT "STARMATH_HID_SMA_UNBINOPS_CAT"
+#define HID_SMA_RELATIONS_CAT "STARMATH_HID_SMA_RELATIONS_CAT"
+#define HID_SMA_SETOPERATIONS_CAT "STARMATH_HID_SMA_SETOPERATIONS_CAT"
+#define HID_SMA_FUNCTIONS_CAT "STARMATH_HID_SMA_FUNCTIONS_CAT"
+#define HID_SMA_OPERATORS_CAT "STARMATH_HID_SMA_OPERATORS_CAT"
+#define HID_SMA_ATTRIBUTES_CAT "STARMATH_HID_SMA_ATTRIBUTES_CAT"
+#define HID_SMA_BRACKETS_CAT "STARMATH_HID_SMA_BRACKETS_CAT"
+#define HID_SMA_FORMAT_CAT "STARMATH_HID_SMA_FORMAT_CAT"
+
+#define HID_SMA_OPERATOR_WIN "STARMATH_HID_SMA_OPERATOR_WIN"
+#define HID_SMA_UNBINOPS_TBX "STARMATH_HID_SMA_UNBINOPS_TBX"
+#define HID_SMA_RELATIONS_TBX "STARMATH_HID_SMA_RELATIONS_TBX"
+#define HID_SMA_SETOPERATIONS_TBX "STARMATH_HID_SMA_SETOPERATIONS_TBX"
+#define HID_SMA_FUNCTIONS_TBX "STARMATH_HID_SMA_FUNCTIONS_TBX"
+#define HID_SMA_OPERATORS_TBX "STARMATH_HID_SMA_OPERATORS_TBX"
+#define HID_SMA_ATTRIBUTES_TBX "STARMATH_HID_SMA_ATTRIBUTES_TBX"
+#define HID_SMA_BRACKETS_TBX "STARMATH_HID_SMA_BRACKETS_TBX"
+#define HID_SMA_FORMAT_TBX "STARMATH_HID_SMA_FORMAT_TBX"
+#define HID_SMA_SELECTION_TBX "STARMATH_HID_SMA_SELECTION_TBX"
+#define HID_SMA_COMMAND_WIN "STARMATH_HID_SMA_COMMAND_WIN"
+#define HID_SMA_MISC_MENU "STARMATH_HID_SMA_MISC_MENU"
+#define HID_SMA_FUNCTIONSOTHER1_MENU "STARMATH_HID_SMA_FUNCTIONSOTHER1_MENU"
+
+#define HID_SMA_ACUTEX "STARMATH_HID_SMA_ACUTEX"
+#define HID_SMA_BARX "STARMATH_HID_SMA_BARX"
+#define HID_SMA_BREVEX "STARMATH_HID_SMA_BREVEX"
+#define HID_SMA_CHECKX "STARMATH_HID_SMA_CHECKX"
+#define HID_SMA_CIRCLEX "STARMATH_HID_SMA_CIRCLEX"
+#define HID_SMA_DOTX "STARMATH_HID_SMA_DOTX"
+#define HID_SMA_DDOTX "STARMATH_HID_SMA_DDOTX"
+#define HID_SMA_DDDOTX "STARMATH_HID_SMA_DDDOTX"
+#define HID_SMA_GRAVEX "STARMATH_HID_SMA_GRAVEX"
+#define HID_SMA_HATX "STARMATH_HID_SMA_HATX"
+#define HID_SMA_TILDEX "STARMATH_HID_SMA_TILDEX"
+#define HID_SMA_VECX "STARMATH_HID_SMA_VECX"
+#define HID_SMA_UNDERLINEX "STARMATH_HID_SMA_UNDERLINEX"
+#define HID_SMA_OVERLINEX "STARMATH_HID_SMA_OVERLINEX"
+#define HID_SMA_OVERSTRIKEX "STARMATH_HID_SMA_OVERSTRIKEX"
+#define HID_SMA_PHANTOMX "STARMATH_HID_SMA_PHANTOMX"
+#define HID_SMA_BOLDX "STARMATH_HID_SMA_BOLDX"
+#define HID_SMA_ITALX "STARMATH_HID_SMA_ITALX"
+#define HID_SMA_SIZEXY "STARMATH_HID_SMA_SIZEXY"
+#define HID_SMA_FONTXY "STARMATH_HID_SMA_FONTXY"
+#define HID_SMA_COLORX "STARMATH_HID_SMA_COLORX"
+#define HID_SMA_LRGROUPX "STARMATH_HID_SMA_LRGROUPX"
+#define HID_SMA_LRPARENTX "STARMATH_HID_SMA_LRPARENTX"
+#define HID_SMA_LRBRACKETX "STARMATH_HID_SMA_LRBRACKETX"
+#define HID_SMA_LRBRACEX "STARMATH_HID_SMA_LRBRACEX"
+#define HID_SMA_LRANGLEX "STARMATH_HID_SMA_LRANGLEX"
+#define HID_SMA_LRCEILX "STARMATH_HID_SMA_LRCEILX"
+#define HID_SMA_LRFLOORX "STARMATH_HID_SMA_LRFLOORX"
+#define HID_SMA_LRLINEX "STARMATH_HID_SMA_LRLINEX"
+#define HID_SMA_LRDLINEX "STARMATH_HID_SMA_LRDLINEX"
+#define HID_SMA_SLRPARENTX "STARMATH_HID_SMA_SLRPARENTX"
+#define HID_SMA_SLRBRACKETX "STARMATH_HID_SMA_SLRBRACKETX"
+#define HID_SMA_SLRBRACEX "STARMATH_HID_SMA_SLRBRACEX"
+#define HID_SMA_SLRANGLEX "STARMATH_HID_SMA_SLRANGLEX"
+#define HID_SMA_SLRCEILX "STARMATH_HID_SMA_SLRCEILX"
+#define HID_SMA_SLRFLOORX "STARMATH_HID_SMA_SLRFLOORX"
+#define HID_SMA_SLRLINEX "STARMATH_HID_SMA_SLRLINEX"
+#define HID_SMA_SLRDLINEX "STARMATH_HID_SMA_SLRDLINEX"
+#define HID_SMA_RSUBX "STARMATH_HID_SMA_RSUBX"
+#define HID_SMA_RSUPX "STARMATH_HID_SMA_RSUPX"
+#define HID_SMA_LSUBX "STARMATH_HID_SMA_LSUBX"
+#define HID_SMA_LSUPX "STARMATH_HID_SMA_LSUPX"
+#define HID_SMA_SBLANK "STARMATH_HID_SMA_SBLANK"
+#define HID_SMA_BLANK "STARMATH_HID_SMA_BLANK"
+#define HID_SMA_NEWLINE "STARMATH_HID_SMA_NEWLINE"
+#define HID_SMA_BINOMXY "STARMATH_HID_SMA_BINOMXY"
+#define HID_SMA_STACK "STARMATH_HID_SMA_STACK"
+#define HID_SMA_MATRIX "STARMATH_HID_SMA_MATRIX"
+#define HID_SMA_ALIGNLX "STARMATH_HID_SMA_ALIGNLX"
+#define HID_SMA_ALIGNCX "STARMATH_HID_SMA_ALIGNCX"
+#define HID_SMA_ALIGNRX "STARMATH_HID_SMA_ALIGNRX"
+#define HID_SMA_ALEPH "STARMATH_HID_SMA_ALEPH"
+#define HID_SMA_EMPTYSET "STARMATH_HID_SMA_EMPTYSET"
+#define HID_SMA_RE "STARMATH_HID_SMA_RE"
+#define HID_SMA_IM "STARMATH_HID_SMA_IM"
+#define HID_SMA_INFINITY "STARMATH_HID_SMA_INFINITY"
+#define HID_SMA_PARTIAL "STARMATH_HID_SMA_PARTIAL"
+#define HID_SMA_WP "STARMATH_HID_SMA_WP"
+#define HID_SMA_DOTSAXIS "STARMATH_HID_SMA_DOTSAXIS"
+#define HID_SMA_DOTSUP "STARMATH_HID_SMA_DOTSUP"
+#define HID_SMA_DOTSDOWN "STARMATH_HID_SMA_DOTSDOWN"
+#define HID_SMA_DOTSLOW "STARMATH_HID_SMA_DOTSLOW"
+#define HID_SMA_DOTSVERT "STARMATH_HID_SMA_DOTSVERT"
+
+#define HID_SMA_SETN "STARMATH_HID_SMA_SETN"
+#define HID_SMA_SETZ "STARMATH_HID_SMA_SETZ"
+#define HID_SMA_SETQ "STARMATH_HID_SMA_SETQ"
+#define HID_SMA_SETR "STARMATH_HID_SMA_SETR"
+#define HID_SMA_SETC "STARMATH_HID_SMA_SETC"
+#define HID_SMA_WIDEHATX "STARMATH_HID_SMA_WIDEHATX"
+#define HID_SMA_WIDETILDEX "STARMATH_HID_SMA_WIDETILDEX"
+#define HID_SMA_WIDEVECX "STARMATH_HID_SMA_WIDEVECX"
+#define HID_SMA_CSUBX "STARMATH_HID_SMA_CSUBX"
+#define HID_SMA_CSUPX "STARMATH_HID_SMA_CSUPX"
+#define HID_SMA_HBAR "STARMATH_HID_SMA_HBAR"
+#define HID_SMA_LAMBDABAR "STARMATH_HID_SMA_LAMBDABAR"
+#define HID_SMA_LEFTARROW "STARMATH_HID_SMA_LEFTARROW"
+#define HID_SMA_RIGHTARROW "STARMATH_HID_SMA_RIGHTARROW"
+#define HID_SMA_UPARROW "STARMATH_HID_SMA_UPARROW"
+#define HID_SMA_DOWNARROW "STARMATH_HID_SMA_DOWNARROW"
+
+#define HID_SMA_DEFAULT_DIST "STARMATH_HID_SMA_DEFAULT_DIST"
+#define HID_SMA_LINE_DIST "STARMATH_HID_SMA_LINE_DIST"
+#define HID_SMA_ROOT_DIST "STARMATH_HID_SMA_ROOT_DIST"
+#define HID_SMA_SUP_DIST "STARMATH_HID_SMA_SUP_DIST"
+#define HID_SMA_SUB_DIST "STARMATH_HID_SMA_SUB_DIST"
+#define HID_SMA_NUMERATOR_DIST "STARMATH_HID_SMA_NUMERATOR_DIST"
+#define HID_SMA_DENOMINATOR_DIST "STARMATH_HID_SMA_DENOMINATOR_DIST"
+#define HID_SMA_FRACLINE_EXCWIDTH "STARMATH_HID_SMA_FRACLINE_EXCWIDTH"
+#define HID_SMA_FRACLINE_LINEWIDTH "STARMATH_HID_SMA_FRACLINE_LINEWIDTH"
+#define HID_SMA_UPPERLIMIT_DIST "STARMATH_HID_SMA_UPPERLIMIT_DIST"
+#define HID_SMA_LOWERLIMIT_DIST "STARMATH_HID_SMA_LOWERLIMIT_DIST"
+#define HID_SMA_BRACKET_EXCHEIGHT "STARMATH_HID_SMA_BRACKET_EXCHEIGHT"
+#define HID_SMA_BRACKET_DIST "STARMATH_HID_SMA_BRACKET_DIST"
+#define HID_SMA_MATRIXROW_DIST "STARMATH_HID_SMA_MATRIXROW_DIST"
+#define HID_SMA_MATRIXCOL_DIST "STARMATH_HID_SMA_MATRIXCOL_DIST"
+#define HID_SMA_ATTRIBUT_DIST "STARMATH_HID_SMA_ATTRIBUT_DIST"
+#define HID_SMA_INTERATTRIBUT_DIST "STARMATH_HID_SMA_INTERATTRIBUT_DIST"
+#define HID_SMA_OPERATOR_EXCHEIGHT "STARMATH_HID_SMA_OPERATOR_EXCHEIGHT"
+#define HID_SMA_OPERATOR_DIST "STARMATH_HID_SMA_OPERATOR_DIST"
+#define HID_SMA_LEFTBORDER_DIST "STARMATH_HID_SMA_LEFTBORDER_DIST"
+#define HID_SMA_RIGHTBORDER_DIST "STARMATH_HID_SMA_RIGHTBORDER_DIST"
+#define HID_SMA_UPPERBORDER_DIST "STARMATH_HID_SMA_UPPERBORDER_DIST"
+#define HID_SMA_LOWERBORDER_DIST "STARMATH_HID_SMA_LOWERBORDER_DIST"
+#define HID_SMA_SCALE_ALL_BRACKETS "STARMATH_HID_SMA_SCALE_ALL_BRACKETS"
+#define HID_SMA_BRACKET_EXCHEIGHT2 "STARMATH_HID_SMA_BRACKET_EXCHEIGHT2"
+#define HID_SMA_LMRANGLEXY "STARMATH_HID_SMA_LMRANGLEXY"
+#define HID_SMA_SLMRANGLEXY "STARMATH_HID_SMA_SLMRANGLEXY"
+#define HID_SMA_XWIDESLASHY "STARMATH_HID_SMA_XWIDESLASHY"
+#define HID_SMA_XWIDEBSLASHY "STARMATH_HID_SMA_XWIDEBSLASHY"
+#define HID_SMA_XOVERBRACEY "STARMATH_HID_SMA_XOVERBRACEY"
+#define HID_SMA_XUNDERBRACEY "STARMATH_HID_SMA_XUNDERBRACEY"
+#define HID_SMA_LRDBRACKETX "STARMATH_HID_SMA_LRDBRACKETX"
+#define HID_SMA_SLRDBRACKETX "STARMATH_HID_SMA_SLRDBRACKETX"
+
+#define HID_SMA_CONTROL_SYMBOLSET_VIEW "STARMATH_HID_SMA_CONTROL_SYMBOLSET_VIEW"
+#define HID_SMA_CONTROL_FONTCHAR_VIEW "STARMATH_HID_SMA_CONTROL_FONTCHAR_VIEW"
+
+#define HID_SMA_NOSPACE "STARMATH_HID_SMA_NOSPACE"
+
+#endif
+
diff --git a/starmath/inc/makefile.mk b/starmath/inc/makefile.mk
new file mode 100644
index 000000000000..930e5281c6fb
--- /dev/null
+++ b/starmath/inc/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..
+
+PRJNAME=starmath
+TARGET=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
new file mode 100644
index 000000000000..83e54451764e
--- /dev/null
+++ b/starmath/inc/node.hxx
@@ -0,0 +1,1227 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef NODE_HXX
+#define NODE_HXX
+
+#include <vector>
+#include <fstream>
+#include <iostream>
+#include <stdio.h>
+
+#include "parse.hxx"
+#include "types.hxx"
+#include "rect.hxx"
+#include "format.hxx"
+
+
+#define ATTR_BOLD 0x0001
+#define ATTR_ITALIC 0x0002
+
+
+#define FNTSIZ_ABSOLUT 1
+#define FNTSIZ_PLUS 2
+#define FNTSIZ_MINUS 3
+#define FNTSIZ_MULTIPLY 4
+#define FNTSIZ_DIVIDE 5
+
+// flags to interdict respective status changes
+#define FLG_FONT 0x0001
+#define FLG_SIZE 0x0002
+#define FLG_BOLD 0x0004
+#define FLG_ITALIC 0x0008
+#define FLG_COLOR 0x0010
+#define FLG_VISIBLE 0x0020
+#define FLG_HORALIGN 0x0040
+
+
+extern SmFormat *pActiveFormat;
+
+class SmVisitor;
+class SmDocShell;
+class SmNode;
+class SmStructureNode;
+
+typedef std::vector< SmNode * > SmNodeArray;
+typedef std::vector< SmStructureNode * > SmStructureNodeArray;
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+enum SmScaleMode { SCALE_NONE, SCALE_WIDTH, SCALE_HEIGHT };
+
+enum SmNodeType
+{
+ NTABLE, NBRACE, NBRACEBODY, NOPER, NALIGN,
+ NATTRIBUT, NFONT, NUNHOR, NBINHOR, NBINVER,
+ NBINDIAGONAL, NSUBSUP, NMATRIX, NPLACE, NTEXT,
+ NSPECIAL, NGLYPH_SPECIAL, NMATH, NBLANK, NERROR,
+ NLINE, NEXPRESSION, NPOLYLINE, NROOT, NROOTSYMBOL,
+ NRECTANGLE, NVERTICAL_BRACE
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+class SmNode : public SmRect
+{
+ SmFace aFace;
+
+ SmToken aNodeToken;
+ SmNodeType eType;
+ SmScaleMode eScaleMode;
+ RectHorAlign eRectHorAlign;
+ sal_uInt16 nFlags,
+ nAttributes;
+ bool bIsPhantom,
+ bIsDebug;
+
+ bool bIsSelected;
+
+protected:
+ SmNode(SmNodeType eNodeType, const SmToken &rNodeToken);
+
+ // index in accessible text -1 if not (yet) applicable
+ sal_Int32 nAccIndex;
+
+public:
+ virtual ~SmNode();
+
+ virtual bool IsVisible() const;
+
+ virtual sal_uInt16 GetNumSubNodes() const;
+ virtual SmNode * GetSubNode(sal_uInt16 nIndex);
+ const SmNode * GetSubNode(sal_uInt16 nIndex) const
+ {
+ return ((SmNode *) this)->GetSubNode(nIndex);
+ }
+
+ virtual SmNode * GetLeftMost();
+ const SmNode * GetLeftMost() const
+ {
+ return ((SmNode *) this)->GetLeftMost();
+ }
+
+ sal_uInt16 & Flags() { return nFlags; }
+ sal_uInt16 & Attributes() { return nAttributes; }
+
+ bool IsDebug() const { return bIsDebug; }
+ bool IsPhantom() const { return bIsPhantom; }
+ void SetPhantom(bool bIsPhantom);
+ void SetColor(const Color &rColor);
+
+ void SetAttribut(sal_uInt16 nAttrib);
+ void ClearAttribut(sal_uInt16 nAttrib);
+
+ const SmFace & GetFont() const { return aFace; };
+ SmFace & GetFont() { return aFace; };
+
+ void SetFont(const SmFace &rFace);
+ void SetFontSize(const Fraction &rRelSize, sal_uInt16 nType);
+ void SetSize(const Fraction &rScale);
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void PrepareAttributes();
+
+#if OSL_DEBUG_LEVEL
+ void ToggleDebug() const;
+#endif
+
+ void SetRectHorAlign(RectHorAlign eHorAlign, bool bApplyToSubTree = true );
+ RectHorAlign GetRectHorAlign() const { return eRectHorAlign; }
+
+ const SmRect & GetRect() const { return *this; }
+ SmRect & GetRect() { return *this; }
+
+ virtual void Move(const Point &rPosition);
+ void MoveTo(const Point &rPosition) { Move(rPosition - GetTopLeft()); }
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ virtual void CreateTextFromNode(String &rText);
+
+ virtual void GetAccessibleText( String &rText ) const;
+ sal_Int32 GetAccessibleIndex() const { return nAccIndex; }
+ const SmNode * FindNodeWithAccessibleIndex(xub_StrLen nAccIndex) const;
+
+ sal_uInt16 GetRow() const { return (sal_uInt16)aNodeToken.nRow; }
+ sal_uInt16 GetColumn() const { return (sal_uInt16)aNodeToken.nCol; }
+
+ SmScaleMode GetScaleMode() const { return eScaleMode; }
+ void SetScaleMode(SmScaleMode eMode) { eScaleMode = eMode; }
+
+ virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth);
+ virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
+
+ SmNodeType GetType() const { return eType; }
+ const SmToken & GetToken() const { return aNodeToken; }
+
+ const SmNode * FindTokenAt(sal_uInt16 nRow, sal_uInt16 nCol) const;
+ const SmNode * FindRectClosestTo(const Point &rPoint) const;
+
+ virtual long GetFormulaBaseline() const;
+
+ /** Accept a visitor
+ * Calls the method for this class on the visitor
+ */
+ virtual void Accept(SmVisitor* pVisitor);
+
+ /** True if this node is selected */
+ bool IsSelected() const {return bIsSelected;}
+ void SetSelected(bool Selected = true) {bIsSelected = Selected;}
+
+#ifdef DEBUG_ENABLE_DUMPASDOT
+ /** The tree as dot graph for graphviz, usable for debugging
+ * Convert the output to a image using $ dot graph.gv -Tpng > graph.png
+ */
+ inline void DumpAsDot(std::ostream &out, String* label = NULL) const{
+ int id = 0;
+ DumpAsDot(out, label, -1, id, -1);
+ }
+#endif /* DEBUG_ENABLE_DUMPASDOT */
+
+ /** Get the parent node of this node */
+ SmStructureNode* GetParent(){ return aParentNode; }
+ /** Set the parent node */
+ void SetParent(SmStructureNode* parent){
+ aParentNode = parent;
+ }
+
+ /** Get the index of a child node
+ *
+ * Returns -1, if pSubNode isn't a subnode of this.
+ */
+ int IndexOfSubNode(SmNode* pSubNode){
+ sal_uInt16 nSize = GetNumSubNodes();
+ for(sal_uInt16 i = 0; i < nSize; i++)
+ if(pSubNode == GetSubNode(i))
+ return i;
+ return -1;
+ }
+ /** Set the token for this node */
+ void SetToken(SmToken& token){
+ aNodeToken = token;
+ }
+protected:
+ /** Sets parent on children of this node */
+ void ClaimPaternity(){
+ SmNode* pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->SetParent((SmStructureNode*)this); //Cast is valid if we have children
+ }
+private:
+ SmStructureNode* aParentNode;
+ void DumpAsDot(std::ostream &out, String* label, int number, int& id, int parent) const;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** A simple auxiliary iterator class for SmNode
+ *
+ * Example of iteration over children of pMyNode:
+ * \code
+ * //Node to iterate over:
+ * SmNode* pMyNode = 0;// A pointer from somewhere
+ * //The iterator:
+ * SmNodeIterator it(pMyNode);
+ * //The iteration:
+ * while(it.Next()) {
+ * it->SetSelected(true);
+ * }
+ * \endcode
+ */
+class SmNodeIterator{
+public:
+ SmNodeIterator(SmNode* node, bool bReverse = false){
+ pNode = node;
+ nSize = pNode->GetNumSubNodes();
+ nIndex = 0;
+ pChildNode = NULL;
+ bIsReverse = bReverse;
+ }
+ /** Get the subnode or NULL if none */
+ SmNode* Next(){
+ while(!bIsReverse && nIndex < nSize){
+ if(NULL != (pChildNode = pNode->GetSubNode(nIndex++)))
+ return pChildNode;
+ }
+ while(bIsReverse && nSize > 0){
+ if(NULL != (pChildNode = pNode->GetSubNode((nSize--)-1)))
+ return pChildNode;
+ }
+ pChildNode = NULL;
+ return NULL;
+ }
+ /** Get the current child node, NULL if none */
+ SmNode* Current(){
+ return pChildNode;
+ }
+ /** Get the current child node, NULL if none */
+ SmNode* operator->(){
+ return pChildNode;
+ }
+private:
+ /** Current child */
+ SmNode* pChildNode;
+ /** Node whos children we're iterating over */
+ SmNode* pNode;
+ /** Size of the node */
+ sal_uInt16 nSize;
+ /** Current index in the node */
+ sal_uInt16 nIndex;
+ /** Move reverse */
+ bool bIsReverse;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Abstract baseclass for all composite node
+ *
+ * Subclasses of this class can have subnodes. Nodes that doesn't derivate from
+ * this class does not have subnodes.
+ */
+class SmStructureNode : public SmNode
+{
+ SmNodeArray aSubNodes;
+
+protected:
+ SmStructureNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmNode(eNodeType, rNodeToken)
+ {}
+
+public:
+ SmStructureNode( const SmStructureNode &rNode );
+ virtual ~SmStructureNode();
+
+ virtual bool IsVisible() const;
+
+ virtual sal_uInt16 GetNumSubNodes() const;
+ void SetNumSubNodes(sal_uInt16 nSize) { aSubNodes.resize(nSize); }
+
+ using SmNode::GetSubNode;
+ virtual SmNode * GetSubNode(sal_uInt16 nIndex);
+ void SetSubNodes(SmNode *pFirst, SmNode *pSecond, SmNode *pThird = NULL);
+ void SetSubNodes(const SmNodeArray &rNodeArray);
+
+ SmStructureNode & operator = ( const SmStructureNode &rNode );
+
+ virtual void GetAccessibleText( String &rText ) const;
+
+ void SetSubNode(size_t nIndex, SmNode* pNode)
+ {
+ size_t size = aSubNodes.size();
+ if (size <= nIndex)
+ {
+ //Resize subnodes array
+ aSubNodes.resize(nIndex + 1);
+ //Set new slots to NULL
+ for (size_t i = size; i < nIndex+1; i++)
+ aSubNodes[i] = NULL;
+ }
+ aSubNodes[nIndex] = pNode;
+ ClaimPaternity();
+ }
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Abstract base class for all visible node
+ *
+ * Nodes that doesn't derivate from this class doesn't draw anything, but their
+ * children.
+ */
+class SmVisibleNode : public SmNode
+{
+protected:
+ SmVisibleNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmNode(eNodeType, rNodeToken)
+ {}
+
+public:
+
+ virtual bool IsVisible() const;
+ virtual sal_uInt16 GetNumSubNodes() const;
+ using SmNode::GetSubNode;
+ virtual SmNode * GetSubNode(sal_uInt16 nIndex);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+class SmGraphicNode : public SmVisibleNode
+{
+protected:
+ SmGraphicNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmVisibleNode(eNodeType, rNodeToken)
+ {}
+
+public:
+
+ virtual void GetAccessibleText( String &rText ) const;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Draws a rectangle
+ *
+ * Used for drawing the line in the OVER and OVERSTRIKE commands.
+ */
+class SmRectangleNode : public SmGraphicNode
+{
+ Size aToSize;
+
+public:
+ SmRectangleNode(const SmToken &rNodeToken)
+ : SmGraphicNode(NRECTANGLE, rNodeToken)
+ {}
+
+ virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth);
+ virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Polygon line node
+ *
+ * Used to draw the slash of the WIDESLASH command by SmBinDiagonalNode.
+ */
+class SmPolyLineNode : public SmGraphicNode
+{
+ Polygon aPoly;
+ Size aToSize;
+ long nWidth;
+
+public:
+ SmPolyLineNode(const SmToken &rNodeToken);
+
+ long GetWidth() const { return nWidth; }
+ Size GetToSize() const { return aToSize; }
+ Polygon &GetPolygon() { return aPoly; }
+
+ virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth);
+ virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Text node
+ *
+ * @remarks This class also serves as baseclass for all nodes that contains text.
+ */
+class SmTextNode : public SmVisibleNode
+{
+ XubString aText;
+ sal_uInt16 nFontDesc;
+ /** Index within text where the selection starts
+ * @remarks Only valid if SmNode::IsSelected() is true
+ */
+ xub_StrLen nSelectionStart;
+ /** Index within text where the selection ends
+ * @remarks Only valid if SmNode::IsSelected() is true
+ */
+ xub_StrLen nSelectionEnd;
+
+protected:
+ SmTextNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 nFontDescP );
+
+public:
+ SmTextNode(const SmToken &rNodeToken, sal_uInt16 nFontDescP );
+
+ sal_uInt16 GetFontDesc() const { return nFontDesc; }
+ void SetText(const XubString &rText) { aText = rText; }
+ const XubString & GetText() const { return aText; }
+ /** Change the text of this node, including the underlying token */
+ void ChangeText(const XubString &rText) {
+ aText = rText;
+ SmToken token = GetToken();
+ token.aText = rText;
+ SetToken(token); //TODO: Merge this with AdjustFontDesc for better performance
+ AdjustFontDesc();
+ }
+ /** Try to guess the correct FontDesc, used during visual editing */
+ void AdjustFontDesc();
+ /** Index within GetText() where the selection starts
+ * @remarks Only valid of SmNode::IsSelected() is true
+ */
+ xub_StrLen GetSelectionStart() const {return nSelectionStart;}
+ /** Index within GetText() where the selection end
+ * @remarks Only valid of SmNode::IsSelected() is true
+ */
+ xub_StrLen GetSelectionEnd() const {return nSelectionEnd;}
+ /** Set the index within GetText() where the selection starts */
+ void SetSelectionStart(xub_StrLen index) {nSelectionStart = index;}
+ /** Set the index within GetText() where the selection end */
+ void SetSelectionEnd(xub_StrLen index) {nSelectionEnd = index;}
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ virtual void CreateTextFromNode(String &rText);
+
+ virtual void GetAccessibleText( String &rText ) const;
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Special node for user defined characters
+ *
+ * Node used for pre- and user-defined characters from:
+ * officecfg/registry/data/org/openoffice/Office/Math.xcu
+ *
+ * This is just single characters, I think.
+ */
+class SmSpecialNode : public SmTextNode
+{
+ bool bIsFromGreekSymbolSet;
+
+protected:
+ SmSpecialNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 _nFontDesc);
+
+public:
+ SmSpecialNode(const SmToken &rNodeToken);
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Glyph node for custom operators
+ *
+ * This node is used with commands: oper, uoper and boper.
+ * E.g. in "A boper op B", "op" will be an instance of SmGlyphSpecialNode.
+ * "boper" simply inteprets "op", the following token, as an binary operator.
+ * The command "uoper" interprets the following token as unary operator.
+ * For these commands an instance of SmGlyphSpecialNode is used for the
+ * operator token, following the command.
+ */
+class SmGlyphSpecialNode : public SmSpecialNode
+{
+public:
+ SmGlyphSpecialNode(const SmToken &rNodeToken)
+ : SmSpecialNode(NGLYPH_SPECIAL, rNodeToken, FNT_MATH)
+ {}
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Math symbol node
+ *
+ * Use for math symbols such as plus, minus and integrale in the INT command.
+ */
+class SmMathSymbolNode : public SmSpecialNode
+{
+protected:
+ SmMathSymbolNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmSpecialNode(eNodeType, rNodeToken, FNT_MATH)
+ {
+ xub_Unicode cChar = GetToken().cMathChar;
+ if ((xub_Unicode) '\0' != cChar)
+ SetText( cChar );
+ }
+
+public:
+ SmMathSymbolNode(const SmToken &rNodeToken);
+
+ virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth);
+ virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Root symbol node
+ *
+ * Root symbol node used by SmRootNode to create the root symbol, infront of
+ * the line with the line above. I don't think this node should be used for
+ * anything else.
+ */
+class SmRootSymbolNode : public SmMathSymbolNode
+{
+ sal_uLong nBodyWidth; // width of body (argument) of root sign
+
+public:
+ SmRootSymbolNode(const SmToken &rNodeToken)
+ : SmMathSymbolNode(NROOTSYMBOL, rNodeToken)
+ {}
+
+ sal_uLong GetBodyWidth() const {return nBodyWidth;};
+ virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nHeight);
+ virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
+
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Place node
+ *
+ * Used to create the <?> command, that denotes place where something can be
+ * written.
+ * It is drawn as a square with a shadow.
+ */
+class SmPlaceNode : public SmMathSymbolNode
+{
+public:
+ SmPlaceNode(const SmToken &rNodeToken)
+ : SmMathSymbolNode(NPLACE, rNodeToken)
+ {
+ }
+ SmPlaceNode() : SmMathSymbolNode(NPLACE, SmToken(TPLACE, MS_PLACE, "<?>")) {};
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Error node, for parsing errors
+ *
+ * This node is used for parsing errors and draws an questionmark turned upside
+ * down (inverted question mark).
+ */
+class SmErrorNode : public SmMathSymbolNode
+{
+public:
+ SmErrorNode(SmParseError /*eError*/, const SmToken &rNodeToken)
+ : SmMathSymbolNode(NERROR, rNodeToken)
+ {
+ SetText((xub_Unicode) MS_ERROR);
+ }
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Table node
+ *
+ * This is the root node for the formula tree. This node is also used for the
+ * STACK and BINOM commands. When used for root node, its
+ * children are instances of SmLineNode, and in some obscure cases the a child
+ * can be an instance of SmExpressionNode, mainly when errors occur.
+ */
+class SmTableNode : public SmStructureNode
+{
+ long nFormulaBaseline;
+public:
+ SmTableNode(const SmToken &rNodeToken)
+ : SmStructureNode(NTABLE, rNodeToken)
+ {}
+
+ using SmNode::GetLeftMost;
+ virtual SmNode * GetLeftMost();
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ virtual long GetFormulaBaseline() const;
+
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** A line
+ *
+ * Used as child of SmTableNode when the SmTableNode is the root node of the
+ * formula tree.
+ */
+class SmLineNode : public SmStructureNode
+{
+ bool bUseExtraSpaces;
+
+protected:
+ SmLineNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmStructureNode(eNodeType, rNodeToken)
+ {
+ bUseExtraSpaces = true;
+ }
+
+public:
+ SmLineNode(const SmToken &rNodeToken)
+ : SmStructureNode(NLINE, rNodeToken)
+ {
+ bUseExtraSpaces = true;
+ }
+
+ void SetUseExtraSpaces(bool bVal) { bUseExtraSpaces = bVal; }
+ bool IsUseExtraSpaces() const { return bUseExtraSpaces; };
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Expression node
+ *
+ * Used whenever you have an expression such as "A OVER {B + C}", here there is
+ * an expression node that allows "B + C" to be the denominator of the
+ * SmBinVerNode, that the OVER command creates.
+ */
+class SmExpressionNode : public SmLineNode
+{
+public:
+ SmExpressionNode(const SmToken &rNodeToken)
+ : SmLineNode(NEXPRESSION, rNodeToken)
+ {}
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Unary horizontical node
+ *
+ * The same as SmBinHorNode except this is for unary operators.
+ */
+class SmUnHorNode : public SmStructureNode
+{
+public:
+ SmUnHorNode(const SmToken &rNodeToken)
+ : SmStructureNode(NUNHOR, rNodeToken)
+ {
+ SetNumSubNodes(2);
+ }
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Root node
+ *
+ * Used for create square roots and other roots, example:
+ * \f$ \sqrt[\mbox{[Argument]}]{\mbox{[Body]}} \f$.
+ *
+ * Children:<BR>
+ * 0: Argument (optional)<BR>
+ * 1: Symbol (instance of SmRootSymbolNode)<BR>
+ * 2: Body<BR>
+ * Where argument is optinal and may be NULL.
+ */
+class SmRootNode : public SmStructureNode
+{
+protected:
+ void GetHeightVerOffset(const SmRect &rRect,
+ long &rHeight, long &rVerOffset) const;
+ Point GetExtraPos(const SmRect &rRootSymbol, const SmRect &rExtra) const;
+
+public:
+ SmRootNode(const SmToken &rNodeToken)
+ : SmStructureNode(NROOT, rNodeToken)
+ {
+ SetNumSubNodes(3);
+ }
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Binary horizontial node
+ *
+ * This node is used for binary operators. In a formula such as "A + B".
+ *
+ * Children:<BR>
+ * 0: Left operand<BR>
+ * 1: Binary operator<BR>
+ * 2: Right operand<BR>
+ *
+ * None of the children may be NULL.
+ */
+class SmBinHorNode : public SmStructureNode
+{
+public:
+ SmBinHorNode(const SmToken &rNodeToken)
+ : SmStructureNode(NBINHOR, rNodeToken)
+ {
+ SetNumSubNodes(3);
+ }
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Binary horizontical node
+ *
+ * This node is used for creating the OVER command, consider the formula:
+ * "numerator OVER denominator", which looks like
+ * \f$ \frac{\mbox{numerator}}{\mbox{denominator}} \f$
+ *
+ * Children:<BR>
+ * 0: Numerator<BR>
+ * 1: Line (instance of SmRectangleNode)<BR>
+ * 2: Denominator<BR>
+ * None of the children may be NULL.
+ */
+class SmBinVerNode : public SmStructureNode
+{
+public:
+ SmBinVerNode(const SmToken &rNodeToken)
+ : SmStructureNode(NBINVER, rNodeToken)
+ {
+ SetNumSubNodes(3);
+ }
+
+ using SmNode::GetLeftMost;
+ virtual SmNode * GetLeftMost();
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Binary diagonal node
+ *
+ * Used for implementing the WIDESLASH command, example: "A WIDESLASH B".
+ *
+ * Children:<BR>
+ * 0: Left operand<BR>
+ * 1: right operand<BR>
+ * 2: Line (instance of SmPolyLineNode).<BR>
+ * None of the children may be NULL.
+ */
+class SmBinDiagonalNode : public SmStructureNode
+{
+ bool bAscending;
+
+ void GetOperPosSize(Point &rPos, Size &rSize,
+ const Point &rDiagPoint, double fAngleDeg) const;
+
+public:
+ SmBinDiagonalNode(const SmToken &rNodeToken);
+
+ bool IsAscending() const { return bAscending; }
+ void SetAscending(bool bVal) { bAscending = bVal; }
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+/** Enum used to index sub-/supscripts in the 'aSubNodes' array
+ * in 'SmSubSupNode'
+ *
+ * See graphic for positions at char:
+ *
+ * \code
+ * CSUP
+ *
+ * LSUP H H RSUP
+ * H H
+ * HHHH
+ * H H
+ * LSUB H H RSUB
+ *
+ * CSUB
+ * \endcode
+ */
+enum SmSubSup
+{ CSUB, CSUP, RSUB, RSUP, LSUB, LSUP
+};
+
+/** numbers of entries in the above enum (that is: the number of possible
+ * sub-/supscripts)
+ */
+#define SUBSUP_NUM_ENTRIES 6
+
+/** Super- and subscript node
+ *
+ * Used for creating super- and subscripts for commands such as:
+ * "^", "_", "lsup", "lsub", "csup" and "csub".
+ * Example: "A^2" which looks like: \f$ A^2 \f$
+ *
+ * This node is also used for creating limits on SmOperNode, when
+ * "FROM" and "TO" commands are used with "INT", "SUM" or similar.
+ *
+ * Children of this node can be enumerated using the SmSubSup enum.
+ * Please note that children may be NULL, except for the body.
+ * It is recommended that you access children using GetBody() and
+ * GetSubSup().
+ */
+class SmSubSupNode : public SmStructureNode
+{
+ bool bUseLimits;
+
+public:
+ SmSubSupNode(const SmToken &rNodeToken)
+ : SmStructureNode(NSUBSUP, rNodeToken)
+ {
+ SetNumSubNodes(1 + SUBSUP_NUM_ENTRIES);
+ bUseLimits = false;
+ }
+
+ /** Get body (Not NULL) */
+ SmNode * GetBody() { return GetSubNode(0); }
+ /** Get body (Not NULL) */
+ const SmNode * GetBody() const
+ {
+ return ((SmSubSupNode *) this)->GetBody();
+ }
+
+ void SetUseLimits(bool bVal) { bUseLimits = bVal; }
+ bool IsUseLimits() const { return bUseLimits; };
+
+ /** Get super- or subscript
+ * @remarks this method may return NULL.
+ */
+ SmNode * GetSubSup(SmSubSup eSubSup) { return GetSubNode( sal::static_int_cast< sal_uInt16 >(1 + eSubSup) ); };
+
+ /** Set the body */
+ void SetBody(SmNode* pBody) { SetSubNode(0, pBody); }
+ void SetSubSup(SmSubSup eSubSup, SmNode* pScript) { SetSubNode( 1 + eSubSup, pScript); }
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Node for brace construction
+ *
+ * Used for "lbrace [body] rbrace" and similar constructions.
+ * Should look like \f$ \{\mbox{[body]}\} \f$
+ *
+ * Children:<BR>
+ * 0: Opening brace<BR>
+ * 1: Body (usually SmBracebodyNode)<BR>
+ * 2: Closing brace<BR>
+ * None of the children can be NULL.
+ *
+ * Note that child 1 (Body) is usually SmBracebodyNode, I don't know if it can
+ * be an SmExpressionNode, haven't seen the case. But didn't quite read parser.cxx
+ * enought to exclude this possibility.
+ */
+class SmBraceNode : public SmStructureNode
+{
+public:
+ SmBraceNode(const SmToken &rNodeToken)
+ : SmStructureNode(NBRACE, rNodeToken)
+ {
+ SetNumSubNodes(3);
+ }
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Body of an SmBraceNode
+ *
+ * This usually only has one child an SmExpressionNode, however, it can also
+ * have other children.
+ * Consider the formula "lbrace [body1] mline [body2] rbrace", looks like:
+ * \f$ \{\mbox{[body1] | [body2]}\} \f$.
+ * In this case SmBracebodyNode will have three children, "[body1]", "|" and
+ * [body2].
+ */
+class SmBracebodyNode : public SmStructureNode
+{
+ long nBodyHeight;
+
+public:
+ inline SmBracebodyNode(const SmToken &rNodeToken);
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ long GetBodyHeight() const { return nBodyHeight; }
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+inline SmBracebodyNode::SmBracebodyNode(const SmToken &rNodeToken) :
+ SmStructureNode(NBRACEBODY, rNodeToken)
+{
+ nBodyHeight = 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Node for vertical brace construction
+ *
+ * Used to implement commands "[body] underbrace [script]" and
+ * "[body] overbrace [script]".
+ * Underbrace should look like this \f$ \underbrace{\mbox{body}}_{\mbox{script}}\f$.
+ *
+ * Children:<BR>
+ * 0: body<BR>
+ * 1: brace<BR>
+ * 2: script<BR>
+ * (None of these children are optional, e.g. they must all be not NULL).
+ */
+class SmVerticalBraceNode : public SmStructureNode
+{
+public:
+ inline SmVerticalBraceNode(const SmToken &rNodeToken);
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+inline SmVerticalBraceNode::SmVerticalBraceNode(const SmToken &rNodeToken) :
+ SmStructureNode(NVERTICAL_BRACE, rNodeToken)
+{
+ SetNumSubNodes(3);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+/** Operation Node
+ *
+ * Used for commands like SUM, INT and similar.
+ *
+ * Children:<BR>
+ * 0: Operation (instance of SmMathSymbolNode)<BR>
+ * 1: Body<BR>
+ * None of the children may be NULL.
+ *
+ * If there are boundaries on the operation the body will an instance of
+ * SmSubSupNode.
+ */
+class SmOperNode : public SmStructureNode
+{
+public:
+ SmOperNode(const SmToken &rNodeToken)
+ : SmStructureNode(NOPER, rNodeToken)
+ {
+ SetNumSubNodes(2);
+ }
+
+ SmNode * GetSymbol();
+ const SmNode * GetSymbol() const
+ {
+ return ((SmOperNode *) this)->GetSymbol();
+ }
+
+ long CalcSymbolHeight(const SmNode &rSymbol, const SmFormat &rFormat) const;
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Node used for alignment
+ */
+class SmAlignNode : public SmStructureNode
+{
+public:
+ SmAlignNode(const SmToken &rNodeToken)
+ : SmStructureNode(NALIGN, rNodeToken)
+ {}
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Attribute node
+ *
+ * Used to give an attribute to another node. Used for commands such as:
+ * UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHAT and WIDETILDE.
+ *
+ * Children:<BR>
+ * 0: Attribute<BR>
+ * 1: Body<BR>
+ * None of these may be NULL.
+ */
+class SmAttributNode : public SmStructureNode
+{
+public:
+ SmAttributNode(const SmToken &rNodeToken)
+ : SmStructureNode(NATTRIBUT, rNodeToken)
+ {}
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Font node
+ *
+ * Used to change the font of it's children.
+ */
+class SmFontNode : public SmStructureNode
+{
+ sal_uInt16 nSizeType;
+ Fraction aFontSize;
+
+public:
+ SmFontNode(const SmToken &rNodeToken)
+ : SmStructureNode(NFONT, rNodeToken)
+ {
+ nSizeType = FNTSIZ_MULTIPLY;
+ aFontSize = Fraction(1L);
+ }
+
+ void SetSizeParameter(const Fraction &rValue, sal_uInt16 nType);
+ const Fraction & GetSizeParameter() const {return aFontSize;}
+ const sal_uInt16& GetSizeType() const {return nSizeType;}
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Matrix node
+ *
+ * Used to implement the MATRIX command, example:
+ * "matrix{ 1 # 2 ## 3 # 4}".
+ */
+class SmMatrixNode : public SmStructureNode
+{
+ sal_uInt16 nNumRows,
+ nNumCols;
+
+public:
+ SmMatrixNode(const SmToken &rNodeToken)
+ : SmStructureNode(NMATRIX, rNodeToken)
+ {
+ nNumRows = nNumCols = 0;
+ }
+
+ sal_uInt16 GetNumRows() const {return nNumRows;}
+ sal_uInt16 GetNumCols() const {return nNumCols;}
+ void SetRowCol(sal_uInt16 nMatrixRows, sal_uInt16 nMatrixCols);
+
+ using SmNode::GetLeftMost;
+ virtual SmNode * GetLeftMost();
+
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void CreateTextFromNode(String &rText);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+/** Node for whitespace
+ *
+ * Used to implement the "~" command. This node is just a blank space.
+ */
+class SmBlankNode : public SmGraphicNode
+{
+ sal_uInt16 nNum;
+
+public:
+ SmBlankNode(const SmToken &rNodeToken)
+ : SmGraphicNode(NBLANK, rNodeToken)
+ {
+ nNum = 0;
+ }
+
+ void IncreaseBy(const SmToken &rToken);
+ void Clear() { nNum = 0; }
+ sal_uInt16 GetBlankNum() const { return nNum; }
+ void SetBlankNum(sal_uInt16 nNumber) { nNum = nNumber; }
+
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
+ virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+ void Accept(SmVisitor* pVisitor);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/parse.hxx b/starmath/inc/parse.hxx
new file mode 100644
index 000000000000..cc17e951df28
--- /dev/null
+++ b/starmath/inc/parse.hxx
@@ -0,0 +1,303 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef PARSE_HXX
+#define PARSE_HXX
+
+
+#include <vcl/svapp.hxx>
+#include <tools/stack.hxx>
+#include <tools/string.hxx>
+
+#include <set>
+#include <stack>
+#include <list>
+
+#include "types.hxx"
+
+#include <vector>
+
+class SmNode;
+class SmDocShell;
+
+//////////////////////////////////////////////////////////////////////
+
+// TokenGroups
+#define TGOPER 0x00000001
+#define TGRELATION 0x00000002
+#define TGSUM 0x00000004
+#define TGPRODUCT 0x00000008
+#define TGUNOPER 0x00000010
+#define TGPOWER 0x00000020
+#define TGATTRIBUT 0x00000040
+#define TGALIGN 0x00000080
+#define TGFUNCTION 0x00000100
+#define TGBLANK 0x00000200
+#define TGLBRACES 0x00000400
+#define TGRBRACES 0x00000800
+#define TGCOLOR 0x00001000
+#define TGFONT 0x00002000
+#define TGSTANDALONE 0x00004000
+#define TGDISCARDED 0x00008000
+#define TGLIMIT 0x00010000
+#define TGFONTATTR 0x00020000
+
+
+enum SmTokenType
+{
+ TEND, TLGROUP, TRGROUP, TLPARENT, TRPARENT,
+ TLBRACKET, TRBRACKET, TPLUS, TMINUS, TMULTIPLY,
+ TDIVIDEBY, TASSIGN, TPOUND, TSPECIAL, TSLASH,
+ TBACKSLASH, TBLANK, TSBLANK, TRSUB, TRSUP,
+ TCSUB, TCSUP, TLSUB, TLSUP, TGT,
+ TLT, TAND, TOR, TINTERSECT, TUNION,
+ TNEWLINE, TBINOM, TFROM, TTO, TINT,
+ TSUM, TOPER, TABS, TSQRT, TFACT,
+ TNROOT, TOVER, TTIMES, TGE, TLE,
+ TGG, TLL, TDOTSAXIS, TDOTSLOW, TDOTSVERT,
+ TDOTSDIAG, TDOTSUP, TDOTSDOWN, TACUTE, TBAR,
+ TBREVE, TCHECK, TCIRCLE, TDOT, TDDOT,
+ TDDDOT, TGRAVE, THAT, TTILDE, TVEC,
+ TUNDERLINE, TOVERLINE, TOVERSTRIKE, TITALIC, TNITALIC,
+ TBOLD, TNBOLD, TPHANTOM, TFONT, TSIZE,
+ TCOLOR, TALIGNL, TALIGNC, TALIGNR, TLEFT,
+ TRIGHT, TLANGLE, TLBRACE, TLLINE, TLDLINE,
+ TLCEIL, TLFLOOR, TNONE, TMLINE, TRANGLE,
+ TRBRACE, TRLINE, TRDLINE, TRCEIL, TRFLOOR,
+ TSIN, TCOS, TTAN, TCOT, TFUNC,
+ TSTACK, TMATRIX, TMATFORM, TDPOUND, TPLACE,
+ TTEXT, TNUMBER, TCHARACTER, TIDENT, TNEQ,
+ TEQUIV, TDEF, TPROP, TSIM, TSIMEQ,
+ TAPPROX, TPARALLEL, TORTHO, TIN, TNOTIN,
+ TSUBSET, TSUBSETEQ, TSUPSET, TSUPSETEQ, TPLUSMINUS,
+ TMINUSPLUS, TOPLUS, TOMINUS, TDIV, TOTIMES,
+ TODIVIDE, TTRANSL, TTRANSR, TIINT, TIIINT,
+ TLINT, TLLINT, TLLLINT, TPROD, TCOPROD,
+ TFORALL, TEXISTS, TLIM, TNABLA, TTOWARD,
+ TSINH, TCOSH, TTANH, TCOTH, TASIN,
+ TACOS, TATAN, TLN, TLOG, TUOPER,
+ TBOPER, TBLACK, TWHITE, TRED, TGREEN,
+ TBLUE, TCYAN, TMAGENTA, TYELLOW, TFIXED,
+ TSANS, TSERIF, TPOINT, TASINH, TACOSH,
+ TATANH, TACOTH, TACOT, TEXP, TCDOT,
+ TODOT, TLESLANT, TGESLANT, TNSUBSET, TNSUPSET,
+ TNSUBSETEQ, TNSUPSETEQ, TPARTIAL, TNEG, TNI,
+ TBACKEPSILON, TALEPH, TIM, TRE, TWP,
+ TEMPTYSET, TINFINITY, TESCAPE, TLIMSUP, TLIMINF,
+ TNDIVIDES, TDRARROW, TDLARROW, TDLRARROW, TUNDERBRACE,
+ TOVERBRACE, TCIRC, TTOP, THBAR, TLAMBDABAR,
+ TLEFTARROW, TRIGHTARROW, TUPARROW, TDOWNARROW, TDIVIDES,
+ TNDIBVIDES, TSETN, TSETZ, TSETQ, TSETR,
+ TSETC, TWIDEVEC, TWIDETILDE, TWIDEHAT, TWIDESLASH,
+ TWIDEBACKSLASH, TLDBRACKET, TRDBRACKET, TNOSPACE,
+ TUNKNOWN, TDEBUG
+};
+
+
+struct SmToken
+{
+
+ String aText; // token text
+ SmTokenType eType; // token info
+ sal_Unicode cMathChar;
+
+ // parse-help info
+ sal_uLong nGroup;
+ sal_uInt16 nLevel;
+
+ // token position
+ sal_uInt16 nRow;
+ xub_StrLen nCol;
+
+ SmToken();
+ SmToken(SmTokenType eTokenType,
+ sal_Unicode cMath,
+ const sal_Char* pText,
+ sal_uLong nTokenGroup = 0,
+ sal_uInt16 nTokenLevel = 0);
+};
+
+
+enum SmParseError
+{
+ PE_NONE, PE_UNEXPECTED_END_OF_INPUT,
+ PE_UNEXPECTED_CHAR, PE_UNEXPECTED_TOKEN,
+ PE_FUNC_EXPECTED, PE_UNOPER_EXPECTED,
+ PE_BINOPER_EXPECTED, PE_SYMBOL_EXPECTED,
+ PE_IDENTIFIER_EXPECTED, PE_POUND_EXPECTED,
+ PE_COLOR_EXPECTED, PE_LGROUP_EXPECTED,
+ PE_RGROUP_EXPECTED, PE_LBRACE_EXPECTED,
+ PE_RBRACE_EXPECTED, PE_PARENT_MISMATCH,
+ PE_RIGHT_EXPECTED, PE_FONT_EXPECTED,
+ PE_SIZE_EXPECTED, PE_DOUBLE_ALIGN,
+ PE_DOUBLE_SUBSUPSCRIPT
+};
+
+
+struct SmErrorDesc
+{
+ SmParseError Type;
+ SmNode *pNode;
+ String Text;
+};
+
+
+DECLARE_STACK(SmNodeStack, SmNode *)
+typedef ::std::vector< SmErrorDesc* > SmErrDescList;
+
+/**************************************************************************/
+
+// defines possible conversions of the formula text from the format of
+// one release to the one of another.
+enum SmConvert
+{
+ CONVERT_NONE,
+ CONVERT_40_TO_50,
+ CONVERT_50_TO_60,
+ CONVERT_60_TO_50
+};
+
+struct SmTokenTableEntry
+{
+ const sal_Char* pIdent;
+ SmTokenType eType;
+ sal_Unicode cMathChar;
+ sal_uLong nGroup;
+ sal_uInt16 nLevel;
+};
+
+class SmParser
+{
+ String m_aBufferString;
+ SmToken m_aCurToken;
+ SmNodeStack m_aNodeStack;
+ SmErrDescList m_aErrDescList;
+ int m_nCurError;
+ LanguageType m_nLang;
+ xub_StrLen m_nBufferIndex,
+ m_nTokenIndex;
+ sal_uInt16 m_Row,
+ m_nColOff;
+ SmConvert m_eConversion;
+ bool bImportSymNames,
+ m_bExportSymNames;
+
+ // map of used symbols (used to reduce file size by exporting only actually used symbols)
+ std::set< rtl::OUString > m_aUsedSymbols;
+
+ // declare copy-constructor and assignment-operator private
+ SmParser(const SmParser &);
+ SmParser & operator = (const SmParser &);
+
+protected:
+#if OSL_DEBUG_LEVEL
+ bool IsDelimiter( const String &rTxt, xub_StrLen nPos );
+#endif
+ void NextToken();
+ xub_StrLen GetTokenIndex() const { return m_nTokenIndex; }
+ void Insert(const String &rText, sal_uInt16 nPos);
+ void Replace( sal_uInt16 nPos, sal_uInt16 nLen, const String &rText );
+
+ inline bool TokenInGroup( sal_uLong nGroup );
+
+ // grammar
+ void Table();
+ void Line();
+ void Expression();
+ void Relation();
+ void Sum();
+ void Product();
+ void SubSup(sal_uLong nActiveGroup);
+ void OpSubSup();
+ void Power();
+ void Blank();
+ void Term();
+ void Escape();
+ void Operator();
+ void Oper();
+ void UnOper();
+ void Align();
+ void FontAttribut();
+ void Attribut();
+ void Font();
+ void FontSize();
+ void Color();
+ void Brace();
+ void Bracebody(bool bIsLeftRight);
+ void Function();
+ void Binom();
+ void Stack();
+ void Matrix();
+ void Special();
+ void GlyphSpecial();
+ // end of grammar
+
+ LanguageType GetLanguage() const { return m_nLang; }
+ void SetLanguage( LanguageType nNewLang ) { m_nLang = nNewLang; }
+
+ void Error(SmParseError Error);
+
+ void ClearUsedSymbols() { m_aUsedSymbols.clear(); }
+ void AddToUsedSymbols( const String &rSymbolName ) { m_aUsedSymbols.insert( rSymbolName ); }
+
+public:
+ SmParser();
+
+ /** Parse rBuffer to formula tree */
+ SmNode *Parse(const String &rBuffer);
+ /** Parse rBuffer to formula subtree that constitutes an expression */
+ SmNode *ParseExpression(const String &rBuffer);
+
+ const String & GetText() const { return m_aBufferString; };
+
+ SmConvert GetConversion() const { return m_eConversion; }
+ void SetConversion(SmConvert eConv) { m_eConversion = eConv; }
+
+ bool IsImportSymbolNames() const { return bImportSymNames; }
+ void SetImportSymbolNames(bool bVal) { bImportSymNames = bVal; }
+ bool IsExportSymbolNames() const { return m_bExportSymNames; }
+ void SetExportSymbolNames(bool bVal) { m_bExportSymNames = bVal; }
+
+ size_t AddError(SmParseError Type, SmNode *pNode);
+ const SmErrorDesc* NextError();
+ const SmErrorDesc* PrevError();
+ const SmErrorDesc* GetError(size_t i = size_t(-1) );
+ static const SmTokenTableEntry* GetTokenTableEntry( const String &rName );
+ bool IsUsedSymbol( const String &rSymbolName ) const { return m_aUsedSymbols.find( rSymbolName ) != m_aUsedSymbols.end(); }
+ std::set< rtl::OUString > GetUsedSymbols() const { return m_aUsedSymbols; }
+};
+
+
+inline bool SmParser::TokenInGroup( sal_uLong nGroup)
+{
+ return (m_aCurToken.nGroup & nGroup) ? true : false;
+}
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/pch/precompiled_starmath.cxx b/starmath/inc/pch/precompiled_starmath.cxx
new file mode 100644
index 000000000000..c25af02d9f18
--- /dev/null
+++ b/starmath/inc/pch/precompiled_starmath.cxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_starmath.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/pch/precompiled_starmath.hxx b/starmath/inc/pch/precompiled_starmath.hxx
new file mode 100644
index 000000000000..7d2363e50a94
--- /dev/null
+++ b/starmath/inc/pch/precompiled_starmath.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): Generated on 2006-09-01 17:50:02.482976
+
+#ifdef PRECOMPILED_HEADERS
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/rect.hxx b/starmath/inc/rect.hxx
new file mode 100644
index 000000000000..e486b1f7c7d5
--- /dev/null
+++ b/starmath/inc/rect.hxx
@@ -0,0 +1,256 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef RECT_HXX
+#define RECT_HXX
+
+#include <new>
+
+#include <tools/gen.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/metric.hxx>
+#include <tools/debug.hxx>
+
+#include "format.hxx"
+
+
+bool SmGetGlyphBoundRect(const OutputDevice &rDev,
+ const XubString &rText, Rectangle &rRect);
+
+bool SmIsMathAlpha(const XubString &rText);
+
+
+inline long SmFromTo(long nFrom, long nTo, double fRelDist)
+{
+ return nFrom + (long) (fRelDist * (nTo - nFrom));
+}
+
+
+////////////////////////////////////////
+// SmRect
+// ... (to be done)
+// This Implementation assumes that the x-axis points to the right and the
+// y-axis to the bottom.
+// Note: however, italic spaces can be negative!
+//
+
+// possible flags for the 'Draw' function below (just for debugging)
+#define SM_RECT_CORE 0x0001
+#define SM_RECT_ITALIC 0x0002
+#define SM_RECT_LINES 0x0004
+#define SM_RECT_MID 0x0008
+
+// possible positions and alignments for the 'AlignTo' function
+enum RectPos
+ // (RP_LEFT : align the current object to the left of the argument, ...)
+{ RP_LEFT, RP_RIGHT,
+ RP_TOP, RP_BOTTOM,
+ RP_ATTRIBUT
+};
+enum RectHorAlign
+{ RHA_LEFT, RHA_CENTER, RHA_RIGHT
+};
+enum RectVerAlign
+{ RVA_TOP, RVA_MID, RVA_BOTTOM, RVA_BASELINE, RVA_CENTERY,
+ RVA_ATTRIBUT_HI, RVA_ATTRIBUT_MID, RVA_ATTRIBUT_LO
+};
+
+// different methods of copying baselines and mid's in 'ExtendBy' function
+enum RectCopyMBL
+{ RCP_THIS, // keep baseline of current object even if it has none
+ RCP_ARG, // as above but for the argument
+ RCP_NONE, // result will have no baseline
+ RCP_XOR // if current object has a baseline keep it else copy
+ // the arguments baseline (even if it has none)
+};
+
+
+class SmRect
+{
+ Point aTopLeft;
+ Size aSize;
+ long nBaseline,
+ nAlignT,
+ nAlignM,
+ nAlignB,
+ nGlyphTop,
+ nGlyphBottom,
+ nItalicLeftSpace,
+ nItalicRightSpace,
+ nLoAttrFence,
+ nHiAttrFence;
+ sal_uInt16 nBorderWidth;
+ bool bHasBaseline,
+ bHasAlignInfo;
+
+protected:
+ void BuildRect (const OutputDevice &rDev, const SmFormat *pFormat,
+ const XubString &rText, sal_uInt16 nBorderWidth);
+ void Init(const OutputDevice &rDev, const SmFormat *pFormat,
+ const XubString &rText, sal_uInt16 nBorderWidth);
+
+ void ClearBaseline() { bHasBaseline = false; };
+ inline void CopyMBL(const SmRect& rRect);
+ void CopyAlignInfo(const SmRect& rRect);
+
+ SmRect & Union(const SmRect &rRect);
+
+public:
+ SmRect();
+ SmRect(const OutputDevice &rDev, const SmFormat *pFormat,
+ const XubString &rText, long nBorderWidth);
+ SmRect(long nWidth, long nHeight);
+ SmRect(const SmRect &rRect);
+
+
+ sal_uInt16 GetBorderWidth() const { return nBorderWidth; }
+
+ void SetItalicSpaces(long nLeftSpace, long nRightSpace);
+
+ void SetWidth(sal_uLong nWidth) { aSize.Width() = nWidth; }
+ void SetHeight(sal_uLong nHeight) { aSize.Height() = nHeight; }
+
+ void SetLeft(long nLeft);
+ void SetRight(long nRight);
+ void SetBottom(long nBottom);
+ void SetTop(long nTop);
+
+ const Point & GetTopLeft() const { return aTopLeft; }
+
+ long GetTop() const { return GetTopLeft().Y(); }
+ long GetLeft() const { return GetTopLeft().X(); }
+ long GetBottom() const { return GetTop() + GetHeight() - 1; }
+ long GetRight() const { return GetLeft() + GetWidth() - 1; }
+ long GetCenterX() const { return (GetLeft() + GetRight()) / 2L; }
+ long GetCenterY() const { return (GetTop() + GetBottom()) / 2L; }
+ long GetWidth() const { return GetSize().Width(); }
+ long GetHeight() const { return GetSize().Height(); }
+
+ long GetItalicLeftSpace() const { return nItalicLeftSpace; }
+ long GetItalicRightSpace() const { return nItalicRightSpace; }
+
+ void SetHiAttrFence(long nVal) { nHiAttrFence = nVal; }
+ void SetLoAttrFence(long nVal) { nLoAttrFence = nVal; }
+ long GetHiAttrFence() const { return nHiAttrFence; }
+ long GetLoAttrFence() const { return nLoAttrFence; }
+
+ long GetItalicLeft() const { return GetLeft() - GetItalicLeftSpace(); }
+ long GetItalicCenterX() const { return (GetItalicLeft() + GetItalicRight()) / 2; }
+ long GetItalicRight() const { return GetRight() + GetItalicRightSpace(); }
+ long GetItalicWidth() const { return GetWidth() + GetItalicLeftSpace() + GetItalicRightSpace(); }
+
+ bool HasBaseline() const { return bHasBaseline; }
+ inline long GetBaseline() const;
+ long GetBaselineOffset() const { return GetBaseline() - GetTop(); }
+
+ void SetAlignTop(long nVal) { nAlignT = nVal; }
+
+ long GetAlignT() const { return nAlignT; }
+ long GetAlignM() const { return nAlignM; }
+ long GetAlignB() const { return nAlignB; }
+
+ void SetAlignT(long nVal) { nAlignT = nVal; }
+
+ const Point GetCenter() const
+ { return Point(GetCenterX(), GetCenterY()); }
+
+ const Size & GetSize() const { return aSize; }
+
+ const Size GetItalicSize() const
+ { return Size(GetItalicWidth(), GetHeight()); }
+
+ void Move (const Point &rPosition);
+ void MoveTo(const Point &rPosition) { Move(rPosition - GetTopLeft()); }
+
+ bool IsEmpty() const
+ {
+ return GetWidth() == 0 || GetHeight() == 0;
+ }
+
+ bool HasAlignInfo() const { return bHasAlignInfo; }
+
+ const Point AlignTo(const SmRect &rRect, RectPos ePos,
+ RectHorAlign eHor, RectVerAlign eVer) const;
+
+ SmRect & ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode);
+ SmRect & ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode,
+ long nNewAlignM);
+ SmRect & ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode,
+ bool bKeepVerAlignParams);
+
+ long OrientedDist(const Point &rPoint) const;
+ bool IsInsideRect(const Point &rPoint) const;
+ bool IsInsideItalicRect(const Point &rPoint) const;
+
+ inline SmRect & operator = (const SmRect &rRect);
+
+ inline Rectangle AsRectangle() const;
+ SmRect AsGlyphRect() const;
+};
+
+
+inline void SmRect::SetItalicSpaces(long nLeftSpace, long nRightSpace)
+ // set extra spacing to the left and right for (italic)
+ // letters/text
+{
+ nItalicLeftSpace = nLeftSpace;
+ nItalicRightSpace = nRightSpace;
+}
+
+
+inline void SmRect::CopyMBL(const SmRect &rRect)
+ // copy AlignM baseline and value of 'rRect'
+{
+ nBaseline = rRect.nBaseline;
+ bHasBaseline = rRect.bHasBaseline;
+ nAlignM = rRect.nAlignM;
+}
+
+
+inline long SmRect::GetBaseline() const
+{
+ DBG_ASSERT(HasBaseline(), "Sm: Baseline nicht vorhanden");
+ return nBaseline;
+}
+
+
+inline SmRect & SmRect::operator = (const SmRect &rRect)
+{
+ new (this) SmRect(rRect); // placement new
+ return *this;
+}
+
+
+inline Rectangle SmRect::AsRectangle() const
+{
+ return Rectangle(Point(GetItalicLeft(), GetTop()), GetItalicSize());
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/smcommands.h b/starmath/inc/smcommands.h
new file mode 100644
index 000000000000..d2f08c55f4c4
--- /dev/null
+++ b/starmath/inc/smcommands.h
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SM_SNCOMMANDS_HRC
+#define SM_SMCOMMANDS_HRC
+
+#define CMD_SID_ADJUST ".uno:Adjust"
+#define CMD_SID_ALIGN ".uno:ChangeAlignment"
+#define CMD_SID_DISTANCE ".uno:ChangeDistance"
+#define CMD_SID_FONT ".uno:ChangeFont"
+#define CMD_SID_FONTSIZE ".uno:ChangeFontSize"
+#define CMD_SID_CMDBOXWINDOW ".uno:CommandWindow"
+#define CMD_SID_PREFERENCES ".uno:Preferences"
+#define CMD_SID_TEXT ".uno:ConfigName"
+#define CMD_SID_COPYOBJECT ".uno:CopyObject"
+#define CMD_SID_DRAW ".uno:Draw"
+#define CMD_SID_FITINWINDOW ".uno:FitInWindow"
+#define CMD_SID_FORMULACURSOR ".uno:FormelCursor"
+#define CMD_SID_GAPHIC_SM ".uno:Graphic"
+#define CMD_SID_INSERTCOMMAND ".uno:InsertCommand"
+#define CMD_SID_INSERTTEXT ".uno:InsertConfigName"
+#define CMD_SID_INSERT_FORMULA ".uno:InsertFormula"
+#define CMD_SID_LOADSYMBOLS ".uno:LoadSymbols"
+#define CMD_SID_MODIFYSTATUS ".uno:ModifyStatus"
+#define CMD_SID_NEXTERR ".uno:NextError"
+#define CMD_SID_NEXTMARK ".uno:NextMark"
+#define CMD_SID_PASTEOBJECT ".uno:PasteObject"
+#define CMD_SID_PREVERR ".uno:PrevError"
+#define CMD_SID_PREVMARK ".uno:PrevMark"
+#define CMD_SID_AUTO_REDRAW ".uno:RedrawAutomatic"
+#define CMD_SID_SAVESYMBOLS ".uno:SaveSymbols"
+#define CMD_SID_GETEDITTEXT ".uno:SetPaperSize"
+#define CMD_SID_SYMBOLS_CATALOGUE ".uno:SymbolCatalogue"
+#define CMD_SID_SYMBOLS ".uno:Symbols"
+#define CMD_SID_TEXTMODE ".uno:Textmode"
+#define CMD_SID_TEXTSTATUS ".uno:TextStatus"
+#define CMD_SID_TOOLBOXWINDOW ".uno:ToolBowWindow"
+#define CMD_SID_TOOLBOX ".uno:ToolBox"
+#define CMD_SID_VIEW100 ".uno:View100"
+#define CMD_SID_VIEW200 ".uno:View200"
+#define CMD_SID_VIEW050 ".uno:View50"
+#define CMD_SID_ZOOMIN ".uno:ZoomIn"
+#define CMD_SID_ZOOMOUT ".uno:ZoomOut"
+
+#endif
diff --git a/starmath/inc/smdll.hxx b/starmath/inc/smdll.hxx
new file mode 100644
index 000000000000..3894c67e144d
--- /dev/null
+++ b/starmath/inc/smdll.hxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef SMDLL_HXX
+#define SMDLL_HXX
+
+#include <tools/resid.hxx>
+#include <sfx2/sfxdefs.hxx>
+#include "smmod.hxx"
+
+class SmData;
+class SfxMedium;
+class SfxFilter;
+
+class SmDLL
+{
+ static bool bInitialized;
+public:
+ static void Init();
+ static void Exit();
+
+ static sal_uLong DetectFilter( SfxMedium& rMedium, const SfxFilter **ppFilter,
+ SfxFilterFlags nMust, SfxFilterFlags nDont );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/smmod.hxx b/starmath/inc/smmod.hxx
new file mode 100644
index 000000000000..a75aee02c0a5
--- /dev/null
+++ b/starmath/inc/smmod.hxx
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SMMOD_HXX
+#define _SMMOD_HXX
+
+#include <tools/resary.hxx>
+#include <svl/lstner.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include <tools/shl.hxx>
+#include <sfx2/module.hxx>
+
+#include "starmath.hrc"
+
+#include <unotools/options.hxx>
+
+class SvxErrorHandler;
+class SfxObjectFactory;
+class SmConfig;
+class SmModule;
+class SmSymbolManager;
+
+/*************************************************************************
+|*
+|* This subclass of <SfxModule> (which is a subclass of <SfxShell>) is
+|* linked to the DLL. One instance of this class exists while the DLL is
+|* loaded.
+|*
+|* SdModule is like to be compared with the <SfxApplication>-subclass.
+|*
+|* Remember: Don`t export this class! It uses DLL-internal symbols.
+|*
+\************************************************************************/
+
+class SvtSysLocale;
+class VirtualDevice;
+
+/////////////////////////////////////////////////////////////////
+
+class SmResId : public ResId
+{
+public:
+ SmResId(sal_uInt16 nId);
+};
+
+class SmNamesArray : public Resource
+{
+ ResStringArray aNamesAry;
+ LanguageType nLanguage;
+
+public:
+ SmNamesArray( LanguageType nLang, int nRID ) :
+ Resource( SmResId(RID_LOCALIZED_NAMES) ),
+ aNamesAry (SmResId( static_cast < sal_uInt16 > ( nRID ))),
+ nLanguage (nLang)
+ {
+ FreeResource();
+ }
+
+ LanguageType GetLanguage() const { return nLanguage; }
+ const ResStringArray& GetNamesArray() const { return aNamesAry; }
+};
+
+/////////////////////////////////////////////////////////////////
+
+class SmLocalizedSymbolData : public Resource
+{
+ ResStringArray aUiSymbolNamesAry;
+ ResStringArray aExportSymbolNamesAry;
+ ResStringArray aUiSymbolSetNamesAry;
+ ResStringArray aExportSymbolSetNamesAry;
+ SmNamesArray *p50NamesAry;
+ SmNamesArray *p60NamesAry;
+ LanguageType n50NamesLang;
+ LanguageType n60NamesLang;
+
+public:
+ SmLocalizedSymbolData();
+ ~SmLocalizedSymbolData();
+
+ const ResStringArray& GetUiSymbolNamesArray() const { return aUiSymbolNamesAry; }
+ const ResStringArray& GetExportSymbolNamesArray() const { return aExportSymbolNamesAry; }
+ const String GetUiSymbolName( const String &rExportName ) const;
+ const String GetExportSymbolName( const String &rUiName ) const;
+
+ const ResStringArray& GetUiSymbolSetNamesArray() const { return aUiSymbolSetNamesAry; }
+ const ResStringArray& GetExportSymbolSetNamesArray() const { return aExportSymbolSetNamesAry; }
+ const String GetUiSymbolSetName( const String &rExportName ) const;
+ const String GetExportSymbolSetName( const String &rUiName ) const;
+
+ const ResStringArray* Get50NamesArray( LanguageType nLang );
+ const ResStringArray* Get60NamesArray( LanguageType nLang );
+};
+
+/////////////////////////////////////////////////////////////////
+
+class SmModule : public SfxModule, utl::ConfigurationListener
+{
+ svtools::ColorConfig *pColorConfig;
+ SmConfig *pConfig;
+ SmLocalizedSymbolData *pLocSymbolData;
+ SvtSysLocale *pSysLocale;
+ VirtualDevice *pVirtualDev;
+
+ void _CreateSysLocale() const;
+ void _CreateVirtualDev() const;
+
+ void ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg );
+
+public:
+ TYPEINFO();
+ SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START + 0)
+
+ SmModule(SfxObjectFactory* pObjFact);
+ virtual ~SmModule();
+
+ virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 );
+
+ svtools::ColorConfig & GetColorConfig();
+
+ SmConfig * GetConfig();
+ SmSymbolManager & GetSymbolManager();
+
+ SmLocalizedSymbolData & GetLocSymbolData() const;
+
+ void GetState(SfxItemSet&);
+
+ const SvtSysLocale& GetSysLocale() const
+ {
+ if( !pSysLocale )
+ _CreateSysLocale();
+ return *pSysLocale;
+ }
+
+ VirtualDevice & GetDefaultVirtualDev()
+ {
+ if (!pVirtualDev)
+ _CreateVirtualDev();
+ return *pVirtualDev;
+ }
+
+ //virtual methods for options dialog
+ virtual SfxItemSet* CreateItemSet( sal_uInt16 nId );
+ virtual void ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet );
+ virtual SfxTabPage* CreateTabPage( sal_uInt16 nId, Window* pParent, const SfxItemSet& rSet );
+};
+
+#define SM_MOD() ( *(SmModule**) GetAppData(SHL_SM) )
+
+#endif // _SDMOD_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/starmath.hrc b/starmath/inc/starmath.hrc
new file mode 100755
index 000000000000..f7aa0f21f03f
--- /dev/null
+++ b/starmath/inc/starmath.hrc
@@ -0,0 +1,463 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _STARMATH_HRC
+#define _STARMATH_HRC
+
+#include <svl/solar.hrc>
+#include <sfx2/sfxsids.hrc>
+#include <editeng/memberids.hrc>
+#include "helpids.h"
+
+#define SID_NEXTERR (SID_SMA_START + 1)
+#define SID_PREVERR (SID_SMA_START + 2)
+#define SID_NEXTMARK (SID_SMA_START + 3)
+#define SID_PREVMARK (SID_SMA_START + 4)
+#define SID_SYMBOLS_CATALOGUE (SID_SMA_START + 5)
+#define SID_PREFERENCES (SID_SMA_START + 6)
+#define SID_VIEW050 (SID_SMA_START + 7)
+#define SID_VIEW100 (SID_SMA_START + 8)
+#define SID_VIEW200 (SID_SMA_START + 9)
+#define SID_ZOOMIN (SID_SMA_START + 10)
+#define SID_ZOOMOUT (SID_SMA_START + 11)
+#define SID_DRAW (SID_SMA_START + 12)
+#define SID_ADJUST (SID_SMA_START + 13)
+#define SID_TOOLBOX (SID_SMA_START + 14)
+#define SID_FORMULACURSOR (SID_SMA_START + 15)
+#define SID_FONT (SID_SMA_START + 50)
+#define SID_FONTSIZE (SID_SMA_START + 51)
+#define SID_DISTANCE (SID_SMA_START + 52)
+#define SID_ALIGN (SID_SMA_START + 53)
+
+#define SID_AUTO_REDRAW (SID_SMA_START + 55)
+#define SID_SYMBOLS (SID_SMA_START + 56) // Has to be picked up again for now!
+#define SID_TEXTMODE (SID_SMA_START + 57)
+#define SID_IMPORT_FORMULA (SID_SMA_START + 58)
+#define SID_TEXT (SID_SMA_START + 100)
+#define SID_GAPHIC_SM (SID_SMA_START + 101)
+#define SID_FITINWINDOW (SID_SMA_START + 103)
+/** Command for inserting a symbol specified by a string (Inserts an SmSpecialNode) */
+#define SID_INSERTSYMBOL (SID_SMA_START + 104)
+/** Command for inserting a math construction specified in commands.src */
+#define SID_INSERTCOMMAND (SID_SMA_START + 105)
+
+#define SID_LOADSYMBOLS (SID_SMA_START + 107)
+#define SID_SAVESYMBOLS (SID_SMA_START + 108)
+#define SID_ZOOMSTATUS (SID_SMA_START + 109)
+#define SID_MODIFYSTATUS (SID_SMA_START + 110)
+#define SID_TEXTSTATUS (SID_SMA_START + 111)
+
+#define SID_PRINTTITLE (SID_SMA_START + 112)
+#define SID_PRINTTEXT (SID_SMA_START + 113)
+#define SID_PRINTFRAME (SID_SMA_START + 114)
+#define SID_PRINTSIZE (SID_SMA_START + 115)
+#define SID_PRINTZOOM (SID_SMA_START + 116)
+
+#define SID_COPYOBJECT (SID_SMA_START + 117)
+#define SID_PASTEOBJECT (SID_SMA_START + 118)
+#define SID_AUTOREDRAW (SID_SMA_START + 119)
+
+#define SID_GETEDITTEXT (SID_SMA_START + 121)
+#define SID_CMDBOXWINDOW (SID_SMA_START + 122)
+#define SID_TOOLBOXWINDOW (SID_SMA_START + 123)
+#define SID_NO_RIGHT_SPACES (SID_SMA_START + 124)
+#define SID_SAVE_ONLY_USED_SYMBOLS (SID_SMA_START + 125)
+#define SID_DUMMY (SID_SMA_START + 254)
+
+
+//#define RID_OPTIONSDIALOG (RID_APP_START + 1)
+#define RID_FONTDIALOG (RID_APP_START + 2)
+#define RID_FONTSIZEDIALOG (RID_APP_START + 3)
+#define RID_FONTTYPEDIALOG (RID_APP_START + 4)
+#define RID_DISTANCEDIALOG (RID_APP_START + 5)
+#define RID_ALIGNDIALOG (RID_APP_START + 6)
+#define RID_PRINTOPTIONPAGE (RID_APP_START + 7)
+#define RID_SYMBOLDIALOG (RID_APP_START + 8)
+#define RID_SYMDEFINEDIALOG (RID_APP_START + 9)
+#define RID_EXTRAOPTIONPAGE (RID_APP_START + 10)
+#define RID_PRINTUIOPTIONS (RID_APP_START + 11)
+
+#define RID_MATH_TOOLBOX (RID_APP_START + 50)
+
+#define RID_DEFAULTSAVEQUERY (RID_APP_START + 102)
+#define RID_WRITESYMBOLERROR (RID_APP_START + 202)
+#define RID_READSYMBOLERROR (RID_APP_START + 203)
+#define RID_NOMATHTYPEFACEWARNING (RID_APP_START + 204)
+#define RID_OBJECTNAME (RID_APP_START + 501)
+ // free
+#define RID_UNDOEDITNAME (RID_APP_START + 503)
+#define RID_UNDOFORMATNAME (RID_APP_START + 504)
+#define RID_APPICO (RID_APP_START + 601)
+#define RID_TMPICO (RID_APP_START + 603)
+#define RID_COMMANDMENU (RID_APP_START + 701)
+#define RID_VIEWMENU (RID_APP_START + 702)
+#define RID_DISTANCEMENU (RID_APP_START + 703)
+#define RID_FONTMENU (RID_APP_START + 704)
+#define RID_STARTUPWINDOW (RID_APP_START + 800)
+#define RID_TOOLBOXWINDOW (RID_APP_START + 801)
+#define RID_CMDBOXWINDOW (RID_APP_START + 802)
+#define RID_FONTREGULAR (RID_APP_START + 804)
+#define RID_FONTITALIC (RID_APP_START + 805)
+#define RID_FONTBOLD (RID_APP_START + 806)
+//#define RID_PRINTOPTION (RID_APP_START + 807)
+#define RID_DOCUMENTSTR (RID_APP_START + 808)
+#define RID_SYMBOLFILESSTR (RID_APP_START + 809)
+#define RID_ALLFILESSTR (RID_APP_START + 810)
+#define RID_CREATORSTR (RID_APP_START + 811)
+#define RID_FILESMFTYP (RID_APP_START + 812)
+#define RID_FILESYMTYP (RID_APP_START + 813)
+#define RID_SMMENU (RID_APP_START + 814)
+#define RID_SMACCEL (RID_APP_START + 815)
+#define RID_STATUSBAR (RID_APP_START + 816)
+#define RID_APPNAMESTR (RID_APP_START + 817)
+
+#define STR_MATH_DOCUMENT_FULLTYPE_CURRENT (RID_APP_START + 821)
+#define RID_SMPLUGINMENU (RID_APP_START + 822)
+#define STR_STATSTR_READING (RID_APP_START + 823)
+#define STR_STATSTR_WRITING (RID_APP_START + 824)
+#define STR_CMDBOXWINDOW (RID_APP_START + 825)
+
+#define RID_ERR_IDENT (RID_APP_START + 920)
+#define RID_ERR_UNKOWN (RID_APP_START + 921)
+#define RID_ERR_UNEXPECTEDCHARACTER (RID_APP_START + 922)
+#define RID_ERR_LGROUPEXPECTED (RID_APP_START + 923)
+#define RID_ERR_RGROUPEXPECTED (RID_APP_START + 924)
+#define RID_ERR_LBRACEEXPECTED (RID_APP_START + 925)
+#define RID_ERR_RBRACEEXPECTED (RID_APP_START + 926)
+#define RID_ERR_FUNCEXPECTED (RID_APP_START + 927)
+#define RID_ERR_UNOPEREXPECTED (RID_APP_START + 928)
+#define RID_ERR_BINOPEREXPECTED (RID_APP_START + 929)
+#define RID_ERR_SYMBOLEXPECTED (RID_APP_START + 930)
+#define RID_ERR_IDENTEXPECTED (RID_APP_START + 931)
+#define RID_ERR_POUNDEXPECTED (RID_APP_START + 932)
+#define RID_ERR_COLOREXPECTED (RID_APP_START + 933)
+#define RID_ERR_LPARENTEXPECTED (RID_APP_START + 934)
+#define RID_ERR_RPARENTEXPECTED (RID_APP_START + 935)
+#define RID_ERR_RIGHTEXPECTED (RID_APP_START + 936)
+#define RID_ERR_OVERFLOW (RID_APP_START + 937)
+
+// toolbox image lists for 'Selection' window
+#define RID_IL_CATALOG (RID_APP_START + 950)
+#define RID_IL_UNBINOPS (RID_APP_START + 952)
+#define RID_IL_RELATIONS (RID_APP_START + 954)
+#define RID_IL_SETOPERATIONS (RID_APP_START + 956)
+#define RID_IL_FUNCTIONS (RID_APP_START + 958)
+#define RID_IL_OPERATORS (RID_APP_START + 960)
+#define RID_IL_ATTRIBUTES (RID_APP_START + 962)
+#define RID_IL_BRACKETS (RID_APP_START + 964)
+#define RID_IL_FORMAT (RID_APP_START + 966)
+#define RID_IL_MISC (RID_APP_START + 968)
+
+#define RID_UNBINOPS_CAT (RID_APP_START + 1101)
+#define RID_RELATIONS_CAT (RID_APP_START + 1102)
+#define RID_SETOPERATIONS_CAT (RID_APP_START + 1103)
+#define RID_FUNCTIONS_CAT (RID_APP_START + 1104)
+#define RID_OPERATORS_CAT (RID_APP_START + 1105)
+#define RID_ATTRIBUTES_CAT (RID_APP_START + 1106)
+#define RID_BRACKETS_CAT (RID_APP_START + 1107)
+#define RID_FORMAT_CAT (RID_APP_START + 1108)
+#define RID_UNBINOPS_CAT_HLP (RID_APP_START + 1109)
+#define RID_RELATIONS_CAT_HLP (RID_APP_START + 1110)
+#define RID_SETOPEROPERATIONS_CAT_HLP (RID_APP_START + 1111)
+#define RID_FUNCTIONS_CAT_HLP (RID_APP_START + 1112)
+#define RID_OPERATORS_CAT_HLP (RID_APP_START + 1113)
+#define RID_ATTRIBUTES_CAT_HLP (RID_APP_START + 1114)
+#define RID_BRACKETS_CAT_HLP (RID_APP_START + 1115)
+#define RID_FORMAT_CAT_HLP (RID_APP_START + 1116)
+#define RID_MISC_CAT (RID_APP_START + 1117)
+#define RID_MISC_CAT_HLP (RID_APP_START + 1118)
+
+// new resource ID's
+#define RID_PLUSX (RID_APP_START + 1201)
+#define RID_MINUSX (RID_APP_START + 1202)
+#define RID_PLUSMINUSX (RID_APP_START + 1203)
+#define RID_MINUSPLUSX (RID_APP_START + 1204)
+#define RID_XPLUSY (RID_APP_START + 1205)
+#define RID_XCDOTY (RID_APP_START + 1206)
+#define RID_XTIMESY (RID_APP_START + 1207)
+#define RID_XSYMTIMESY (RID_APP_START + 1208)
+#define RID_XMINUSY (RID_APP_START + 1209)
+#define RID_XOVERY (RID_APP_START + 1210)
+#define RID_XDIVY (RID_APP_START + 1211)
+#define RID_XSYMDIVIDEY (RID_APP_START + 1212)
+#define RID_NEGX (RID_APP_START + 1213)
+#define RID_XANDY (RID_APP_START + 1214)
+#define RID_XORY (RID_APP_START + 1215)
+#define RID_XODIVIDEY (RID_APP_START + 1216)
+#define RID_XODOTY (RID_APP_START + 1217)
+#define RID_XOMINUSY (RID_APP_START + 1218)
+#define RID_XOPLUSY (RID_APP_START + 1219)
+#define RID_XOTIMESY (RID_APP_START + 1220)
+#define RID_XCIRCY (RID_APP_START + 1221)
+#define RID_XWIDESLASHY (RID_APP_START + 1222)
+#define RID_XWIDEBSLASHY (RID_APP_START + 1223)
+
+#define RID_XEQY (RID_APP_START + 1301)
+#define RID_XNEQY (RID_APP_START + 1302)
+#define RID_XEQUIVY (RID_APP_START + 1303)
+#define RID_XORTHOY (RID_APP_START + 1304)
+#define RID_XLTY (RID_APP_START + 1305)
+#define RID_XGTY (RID_APP_START + 1306)
+#define RID_XAPPROXY (RID_APP_START + 1307)
+#define RID_XPARALLELY (RID_APP_START + 1308)
+#define RID_XLESLANTY (RID_APP_START + 1309)
+#define RID_XGESLANTY (RID_APP_START + 1310)
+#define RID_XSIMEQY (RID_APP_START + 1311)
+#define RID_XPROPY (RID_APP_START + 1312)
+#define RID_XLEY (RID_APP_START + 1313)
+#define RID_XGEY (RID_APP_START + 1314)
+#define RID_XSIMY (RID_APP_START + 1315)
+#define RID_XTOWARDY (RID_APP_START + 1316)
+#define RID_XLLY (RID_APP_START + 1317)
+#define RID_XGGY (RID_APP_START + 1318)
+#define RID_XDEFY (RID_APP_START + 1319)
+#define RID_XTRANSLY (RID_APP_START + 1320)
+#define RID_XTRANSRY (RID_APP_START + 1321)
+#define RID_XDIVIDESY (RID_APP_START + 1322)
+#define RID_XNDIVIDESY (RID_APP_START + 1323)
+#define RID_DLARROW (RID_APP_START + 1324)
+#define RID_DLRARROW (RID_APP_START + 1325)
+#define RID_DRARROW (RID_APP_START + 1326)
+
+#define RID_XINY (RID_APP_START + 1401)
+#define RID_XNOTINY (RID_APP_START + 1402)
+#define RID_XOWNSY (RID_APP_START + 1403)
+#define RID_XINTERSECTIONY (RID_APP_START + 1405)
+#define RID_XUNIONY (RID_APP_START + 1406)
+#define RID_XSETMINUSY (RID_APP_START + 1407)
+#define RID_XSLASHY (RID_APP_START + 1408)
+#define RID_XSUBSETY (RID_APP_START + 1409)
+#define RID_XSUBSETEQY (RID_APP_START + 1410)
+#define RID_XSUPSETY (RID_APP_START + 1411)
+#define RID_XSUPSETEQY (RID_APP_START + 1412)
+#define RID_XNSUBSETY (RID_APP_START + 1413)
+#define RID_XNSUBSETEQY (RID_APP_START + 1414)
+#define RID_XNSUPSETY (RID_APP_START + 1415)
+#define RID_XNSUPSETEQY (RID_APP_START + 1416)
+#define RID_SETN (RID_APP_START + 1417)
+#define RID_SETZ (RID_APP_START + 1418)
+#define RID_SETQ (RID_APP_START + 1419)
+#define RID_SETR (RID_APP_START + 1420)
+#define RID_SETC (RID_APP_START + 1421)
+
+#define RID_ABSX (RID_APP_START + 1501)
+#define RID_FACTX (RID_APP_START + 1502)
+#define RID_SQRTX (RID_APP_START + 1503)
+#define RID_NROOTXY (RID_APP_START + 1504)
+#define RID_EX (RID_APP_START + 1505)
+#define RID_LNX (RID_APP_START + 1506)
+#define RID_EXPX (RID_APP_START + 1507)
+#define RID_LOGX (RID_APP_START + 1508)
+#define RID_SINX (RID_APP_START + 1509)
+#define RID_COSX (RID_APP_START + 1510)
+#define RID_TANX (RID_APP_START + 1511)
+#define RID_COTX (RID_APP_START + 1512)
+#define RID_SINHX (RID_APP_START + 1513)
+#define RID_COSHX (RID_APP_START + 1514)
+#define RID_TANHX (RID_APP_START + 1515)
+#define RID_COTHX (RID_APP_START + 1516)
+#define RID_ARCSINX (RID_APP_START + 1517)
+#define RID_ARCCOSX (RID_APP_START + 1518)
+#define RID_ARCTANX (RID_APP_START + 1519)
+#define RID_ARCCOTX (RID_APP_START + 1520)
+#define RID_ARSINHX (RID_APP_START + 1521)
+#define RID_ARCOSHX (RID_APP_START + 1522)
+#define RID_ARTANHX (RID_APP_START + 1523)
+#define RID_ARCOTHX (RID_APP_START + 1524)
+
+#define RID_LIMX (RID_APP_START + 1601)
+#define RID_SUMX (RID_APP_START + 1602)
+#define RID_PRODX (RID_APP_START + 1603)
+#define RID_COPRODX (RID_APP_START + 1604)
+#define RID_INTX (RID_APP_START + 1605)
+#define RID_IINTX (RID_APP_START + 1606)
+#define RID_IIINTX (RID_APP_START + 1607)
+#define RID_LINTX (RID_APP_START + 1609)
+#define RID_LLINTX (RID_APP_START + 1610)
+#define RID_LLLINTX (RID_APP_START + 1611)
+#define RID_FROMXTOY (RID_APP_START + 1613)
+#define RID_FROMX (RID_APP_START + 1614)
+#define RID_TOX (RID_APP_START + 1615)
+#define RID_LIMINFX (RID_APP_START + 1616)
+#define RID_LIMSUPX (RID_APP_START + 1617)
+
+#define RID_ACUTEX (RID_APP_START + 1701)
+#define RID_GRAVEX (RID_APP_START + 1702)
+#define RID_CHECKX (RID_APP_START + 1703)
+#define RID_BREVEX (RID_APP_START + 1704)
+#define RID_BARX (RID_APP_START + 1705)
+#define RID_VECX (RID_APP_START + 1706)
+#define RID_HATX (RID_APP_START + 1707)
+#define RID_TILDEX (RID_APP_START + 1708)
+#define RID_CIRCLEX (RID_APP_START + 1709)
+#define RID_DOTX (RID_APP_START + 1710)
+#define RID_DDOTX (RID_APP_START + 1711)
+#define RID_DDDOTX (RID_APP_START + 1712)
+#define RID_OVERLINEX (RID_APP_START + 1713)
+#define RID_UNDERLINEX (RID_APP_START + 1714)
+#define RID_OVERSTRIKEX (RID_APP_START + 1715)
+#define RID_PHANTOMX (RID_APP_START + 1716)
+#define RID_BOLDX (RID_APP_START + 1717)
+#define RID_ITALX (RID_APP_START + 1718)
+#define RID_SIZEXY (RID_APP_START + 1719)
+#define RID_FONTXY (RID_APP_START + 1720)
+#define RID_COLORX (RID_APP_START + 1721)
+#define RID_WIDEHATX (RID_APP_START + 1722)
+#define RID_WIDETILDEX (RID_APP_START + 1723)
+#define RID_WIDEVECX (RID_APP_START + 1724)
+
+#define RID_LRPARENTX (RID_APP_START + 1801)
+#define RID_LRBRACKETX (RID_APP_START + 1802)
+#define RID_LRANGLEX (RID_APP_START + 1803)
+#define RID_LRBRACEX (RID_APP_START + 1804)
+#define RID_LRLINEX (RID_APP_START + 1805)
+#define RID_LRDLINEX (RID_APP_START + 1806)
+#define RID_LRGROUPX (RID_APP_START + 1808)
+#define RID_SLRPARENTX (RID_APP_START + 1809)
+#define RID_SLRBRACKETX (RID_APP_START + 1810)
+#define RID_SLRANGLEX (RID_APP_START + 1811)
+#define RID_SLRBRACEX (RID_APP_START + 1812)
+#define RID_SLRLINEX (RID_APP_START + 1813)
+#define RID_SLRDLINEX (RID_APP_START + 1814)
+#define RID_LRCEILX (RID_APP_START + 1817)
+#define RID_LRFLOORX (RID_APP_START + 1818)
+#define RID_SLRCEILX (RID_APP_START + 1819)
+#define RID_SLRFLOORX (RID_APP_START + 1820)
+#define RID_LMRANGLEXY (RID_APP_START + 1821)
+#define RID_SLMRANGLEXY (RID_APP_START + 1822)
+#define RID_LRDBRACKETX (RID_APP_START + 1823)
+#define RID_SLRDBRACKETX (RID_APP_START + 1824)
+#define RID_XOVERBRACEY (RID_APP_START + 1825)
+#define RID_XUNDERBRACEY (RID_APP_START + 1826)
+
+#define RID_NEWLINE (RID_APP_START + 1901)
+#define RID_SBLANK (RID_APP_START + 1902)
+#define RID_BLANK (RID_APP_START + 1903)
+#define RID_RSUBX (RID_APP_START + 1904)
+#define RID_BINOMXY (RID_APP_START + 1905)
+#define RID_STACK (RID_APP_START + 1906)
+#define RID_MATRIX (RID_APP_START + 1907)
+#define RID_RSUPX (RID_APP_START + 1908)
+#define RID_ALIGNLX (RID_APP_START + 1909)
+#define RID_ALIGNCX (RID_APP_START + 1910)
+#define RID_ALIGNRX (RID_APP_START + 1911)
+#define RID_LSUBX (RID_APP_START + 1912)
+#define RID_LSUPX (RID_APP_START + 1916)
+#define RID_CSUBX (RID_APP_START + 1917)
+#define RID_CSUPX (RID_APP_START + 1918)
+#define RID_NOSPACE (RID_APP_START + 1919)
+
+#define RID_ALEPH (RID_APP_START + 2001)
+#define RID_EMPTYSET (RID_APP_START + 2002)
+#define RID_RE (RID_APP_START + 2003)
+#define RID_IM (RID_APP_START + 2004)
+#define RID_INFINITY (RID_APP_START + 2005)
+#define RID_PARTIAL (RID_APP_START + 2006)
+#define RID_WP (RID_APP_START + 2007)
+#define RID_DOTSAXIS (RID_APP_START + 2008)
+#define RID_DOTSUP (RID_APP_START + 2009)
+#define RID_DOTSDOWN (RID_APP_START + 2010)
+#define RID_DOTSLOW (RID_APP_START + 2011)
+#define RID_DOTSVERT (RID_APP_START + 2012)
+#define RID_NABLA (RID_APP_START + 2013)
+#define RID_HBAR (RID_APP_START + 2014)
+#define RID_LAMBDABAR (RID_APP_START + 2015)
+#define RID_LEFTARROW (RID_APP_START + 2016)
+#define RID_RIGHTARROW (RID_APP_START + 2017)
+#define RID_UPARROW (RID_APP_START + 2018)
+#define RID_DOWNARROW (RID_APP_START + 2019)
+#define RID_EXISTS (RID_APP_START + 1608)
+#define RID_FORALL (RID_APP_START + 1612)
+
+// new menue resource ID's
+#define RID_UNBINOPS_MENU (RID_APP_START + 2164)
+#define RID_RELATIONS_MENU (RID_APP_START + 2165)
+#define RID_SETOPERATIONS_MENU (RID_APP_START + 2166)
+#define RID_FUNCTIONS_MENU (RID_APP_START + 2167)
+#define RID_OPERATORS_MENU (RID_APP_START + 2168)
+#define RID_ATTRIBUTES_MENU (RID_APP_START + 2169)
+#define RID_BRACKETS_MENU (RID_APP_START + 2170)
+#define RID_FORMAT_MENU (RID_APP_START + 2171)
+#define RID_MISC_MENU (RID_APP_START + 2172)
+#define RID_FUNCTIONSOTHER1_MENU (RID_APP_START + 2173)
+
+#define RID_XPP_LINE (RID_APP_START + 3000)
+#define RID_XPP_DLINE (RID_APP_START + 3001)
+#define RID_XPP_SQRT (RID_APP_START + 3002)
+#define RID_XPP_SQRT2 (RID_APP_START + 3003)
+#define RID_XPP_HAT (RID_APP_START + 3004)
+#define RID_XPP_TILDE (RID_APP_START + 3005)
+#define RID_XPP_BAR (RID_APP_START + 3006)
+#define RID_XPP_VEC (RID_APP_START + 3007)
+#define RID_XPP_LBRACE (RID_APP_START + 3008)
+#define RID_XPP_RBRACE (RID_APP_START + 3009)
+#define RID_XPP_LPARENT (RID_APP_START + 3010)
+#define RID_XPP_RPARENT (RID_APP_START + 3011)
+#define RID_XPP_LANGLE (RID_APP_START + 3012)
+#define RID_XPP_RANGLE (RID_APP_START + 3013)
+#define RID_XPP_LBRACKET (RID_APP_START + 3014)
+#define RID_XPP_RBRACKET (RID_APP_START + 3015)
+#define RID_XPP_LDBRACKET (RID_APP_START + 3016)
+#define RID_XPP_RDBRACKET (RID_APP_START + 3017)
+#define RID_XPP_LCEIL (RID_APP_START + 3018)
+#define RID_XPP_RCEIL (RID_APP_START + 3019)
+#define RID_XPP_LFLOOR (RID_APP_START + 3020)
+#define RID_XPP_RFLOOR (RID_APP_START + 3021)
+#define RID_XPP_OVERBRACE (RID_APP_START + 3022)
+#define RID_XPP_UNDERBRACE (RID_APP_START + 3023)
+
+#define RID_LOCALIZED_NAMES (RID_APP_START + 3101)
+#define RID_UI_SYMBOL_NAMES (RID_APP_START + 3102)
+#define RID_EXPORT_SYMBOL_NAMES (RID_APP_START + 3103)
+#define RID_LOCALIZED_SYMBOLSET_NAMES (RID_APP_START + 3104)
+#define RID_UI_SYMBOLSET_NAMES (RID_APP_START + 3105)
+#define RID_EXPORT_SYMBOLSET_NAMES (RID_APP_START + 3106)
+#define RID_FRENCH_50_NAMES (RID_APP_START + 3107)
+#define RID_FRENCH_60_NAMES (RID_APP_START + 3108)
+#define RID_ITALIAN_50_NAMES (RID_APP_START + 3109)
+#define RID_ITALIAN_60_NAMES (RID_APP_START + 3110)
+#define RID_SWEDISH_50_NAMES (RID_APP_START + 3111)
+#define RID_SWEDISH_60_NAMES (RID_APP_START + 3112)
+#define RID_SPANISH_50_NAMES (RID_APP_START + 3113)
+#define RID_SPANISH_60_NAMES (RID_APP_START + 3114)
+
+#define MN_SUB_SENDTO (RID_APP_START + 3120)
+
+#define BMP_ARROW_RIGHT 1
+
+#define MN_WIN 60
+#define MN_SUB_VIEW 31
+#define MN_SUB_TOOLBAR 32
+#define MN_SUB_GRAPHIC 33
+#define MN_SUB_SPELLING 34
+#define MN_SUB_TEMPLATES 35
+
+// 342 == SCH_IF_SMAVIEWSHELL, because SFX_INTERFACE_LIB is no
+// Define but latterly an Enum
+#define HID_SMA_VIEWSHELL_DOCUMENT (342)
+
+#endif
+
diff --git a/starmath/inc/symbol.hxx b/starmath/inc/symbol.hxx
new file mode 100644
index 000000000000..aa6264989bcd
--- /dev/null
+++ b/starmath/inc/symbol.hxx
@@ -0,0 +1,192 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SYMBOL_HXX
+#define SYMBOL_HXX
+
+#include <vcl/font.hxx>
+#include <tools/debug.hxx>
+#include <tools/dynary.hxx>
+#include <svl/lstner.hxx>
+#include <svl/svarray.hxx>
+
+#include <map>
+#include <vector>
+#include <set>
+#include <functional>
+#include <algorithm>
+
+#include "unomodel.hxx"
+#include "utility.hxx"
+#include "smmod.hxx"
+
+
+#define SYMBOLSET_NONE 0xFFFF
+#define SYMBOL_NONE 0xFFFF
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+inline const String GetExportSymbolName( const String &rUiSymbolName )
+{
+ return SM_MOD()->GetLocSymbolData().GetExportSymbolName( rUiSymbolName );
+}
+
+
+inline const String GetUiSymbolName( const String &rExportSymbolName )
+{
+ return SM_MOD()->GetLocSymbolData().GetUiSymbolName( rExportSymbolName );
+}
+
+inline const String GetExportSymbolSetName( const String &rUiSymbolSetName )
+{
+ return SM_MOD()->GetLocSymbolData().GetExportSymbolSetName( rUiSymbolSetName );
+}
+
+
+inline const String GetUiSymbolSetName( const String &rExportSymbolSetName )
+{
+ return SM_MOD()->GetLocSymbolData().GetUiSymbolSetName( rExportSymbolSetName );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+class SmSym
+{
+private:
+ SmFace m_aFace;
+ String m_aName;
+ String m_aExportName;
+ String m_aSetName;
+ sal_UCS4 m_cChar;
+ bool m_bPredefined;
+ bool m_bDocSymbol;
+
+public:
+ SmSym();
+ SmSym(const String& rName, const Font& rFont, sal_UCS4 cChar,
+ const String& rSet, bool bIsPredefined = false);
+ SmSym(const SmSym& rSymbol);
+
+ SmSym& operator = (const SmSym& rSymbol);
+
+ const Font& GetFace() const { return m_aFace; }
+ sal_UCS4 GetCharacter() const { return m_cChar; }
+ const String& GetName() const { return m_aName; }
+
+ void SetFace( const Font& rFont ) { m_aFace = rFont; }
+ void SetCharacter( sal_UCS4 cChar ) { m_cChar = cChar; }
+
+//! since the symbol name is also used as key in the map it should not be possible to change the name
+//! because ten the key would not be the same as its supposed copy here
+// void SetName( const String &rTxt ) { m_aName = rTxt; }
+
+ bool IsPredefined() const { return m_bPredefined; }
+ const String & GetSymbolSetName() const { return m_aSetName; }
+ void SetSymbolSetName( const String &rName ) { m_aSetName = rName; }
+ const String & GetExportName() const { return m_aExportName; }
+ void SetExportName( const String &rName ) { m_aExportName = rName; }
+
+ bool IsDocSymbol() const { return m_bDocSymbol; }
+ void SetDocSymbol( bool bVal ) { m_bDocSymbol = bVal; }
+
+ // true if rSymbol has the same name, font and character
+ bool IsEqualInUI( const SmSym& rSymbol ) const;
+};
+
+/**************************************************************************/
+
+struct lt_String
+{
+ bool operator()( const String &r1, const String &r2 ) const
+ {
+ // r1 < r2 ?
+ return r1.CompareTo( r2 ) == COMPARE_LESS;
+ }
+};
+
+
+// type of the actual container to hold the symbols
+typedef std::map< String, SmSym, lt_String > SymbolMap_t;
+
+// vector of pointers to the actual symbols in the above container
+typedef std::vector< const SmSym * > SymbolPtrVec_t;
+
+struct lt_SmSymPtr : public std::binary_function< const SmSym *, const SmSym *, bool >
+{
+ bool operator() ( const SmSym *pSym1, const SmSym *pSym2 ) const
+ {
+ return pSym1->GetCharacter() < pSym2->GetCharacter();
+ }
+};
+
+
+class SmSymbolManager : public SfxListener
+{
+private:
+ SymbolMap_t m_aSymbols;
+ bool m_bModified;
+
+ virtual void SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType,
+ const SfxHint& rHint, const TypeId& rHintType);
+
+ void Init();
+ void Exit();
+
+public:
+ SmSymbolManager();
+ SmSymbolManager(const SmSymbolManager& rSymbolSetManager);
+ ~SmSymbolManager();
+
+ SmSymbolManager & operator = (const SmSymbolManager& rSymbolSetManager);
+
+ // symbol sets are for UI purpose only, thus we assemble them here
+ std::set< String > GetSymbolSetNames() const;
+ const SymbolPtrVec_t GetSymbolSet( const String& rSymbolSetName );
+
+ sal_uInt16 GetSymbolCount() const { return static_cast< sal_uInt16 >(m_aSymbols.size()); }
+ const SymbolPtrVec_t GetSymbols() const;
+ bool AddOrReplaceSymbol( const SmSym & rSymbol, bool bForceChange = false );
+ void RemoveSymbol( const String & rSymbolName );
+
+ SmSym * GetSymbolByName(const String& rSymbolName);
+ const SmSym * GetSymbolByName(const String& rSymbolName) const
+ {
+ return ((SmSymbolManager *) this)->GetSymbolByName(rSymbolName);
+ }
+
+ bool IsModified() const { return m_bModified; }
+ void SetModified(bool bModify) { m_bModified = bModify; }
+
+ void Load();
+ void Save();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/toolbox.hxx b/starmath/inc/toolbox.hxx
new file mode 100644
index 000000000000..4242867f3130
--- /dev/null
+++ b/starmath/inc/toolbox.hxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef TOOLBOX_HXX
+#define TOOLBOX_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/childwin.hxx>
+#include <vcl/toolbox.hxx>
+
+#include "smmod.hxx"
+#include "config.hxx"
+#include "toolbox.hrc"
+
+class SmToolBoxWindow : public SfxFloatingWindow
+{
+
+protected:
+ ToolBox aToolBoxCat;
+ FixedLine aToolBoxCat_Delim; // to visualy seperate the catalog part
+ ToolBox *pToolBoxCmd;
+ ToolBox *vToolBoxCategories[NUM_TBX_CATEGORIES];
+ ImageList *aImageLists [NUM_TBX_CATEGORIES + 1]; /* regular */
+ sal_uInt16 nActiveCategoryRID;
+
+ virtual sal_Bool Close();
+ virtual void GetFocus();
+
+ void ApplyImageLists( sal_uInt16 nCategoryRID );
+
+ DECL_LINK( CategoryClickHdl, ToolBox* );
+ DECL_LINK( CmdSelectHdl, ToolBox* );
+
+ SmViewShell * GetView();
+ const ImageList * GetImageList( sal_uInt16 nResId );
+
+public:
+ SmToolBoxWindow(SfxBindings *pBindings,
+ SfxChildWindow *pChildWindow,
+ Window *pParent);
+ ~SmToolBoxWindow();
+
+ // Window
+ virtual void StateChanged( StateChangedType nStateChange );
+ virtual void DataChanged( const DataChangedEvent &rEvt );
+
+ void AdjustPosSize( bool bSetPos );
+ void SetCategory(sal_uInt16 nCategory);
+};
+
+/**************************************************************************/
+
+class SmToolBoxWrapper : public SfxChildWindow
+{
+ SFX_DECL_CHILDWINDOW(SmToolBoxWrapper);
+
+protected:
+ SmToolBoxWrapper(Window *pParentWindow,
+ sal_uInt16, SfxBindings*, SfxChildWinInfo*);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/types.hxx b/starmath/inc/types.hxx
new file mode 100644
index 000000000000..818b114f2de6
--- /dev/null
+++ b/starmath/inc/types.hxx
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef TYPES_HXX
+#define TYPES_HXX
+
+#include <sal/types.h>
+#include <tools/debug.hxx>
+
+#define FONTNAME_MATH "OpenSymbol"
+
+/////////////////////////////////////////////////////////////////
+
+enum SmPrintSize { PRINT_SIZE_NORMAL, PRINT_SIZE_SCALED, PRINT_SIZE_ZOOMED };
+
+/////////////////////////////////////////////////////////////////
+
+#define FONT_ARIAL "Arial"
+#define FONT_SYMBOL "Symbol"
+#define FONT_MS_PMINCHO "MS PMincho"
+#define FONT_MS_PGOTHIC "MS PGothic"
+#define FONT_SUN_BATANG "SunBatang"
+
+
+inline sal_Bool IsInPrivateUseArea( sal_Unicode cChar ) { return 0xE000 <= cChar && cChar <= 0xF8FF; }
+
+// Greek char range as seen in svx/.../charmap.cxx RID_SUBSETSTR_BASIC_GREEK
+inline sal_Bool IsGreekChar( sal_Unicode cChar ) { return 0x0370 <= cChar && cChar <= 0x03FF; }
+
+sal_Unicode ConvertMathPrivateUseAreaToUnicode( sal_Unicode cChar );
+
+sal_Unicode ConvertMathToMathML( sal_Unicode cChar );
+
+/////////////////////////////////////////////////////////////////
+// enum definitions for characters from the 'StarSymbol' font
+// (some chars have more than one alias!)
+//! Note: not listed here does not(!) mean "not used"
+//! (see %alpha ... %gamma for example)
+//
+enum MathSymbol
+{
+ MS_FACT = (sal_Unicode) 0x0021,
+ MS_INFINITY = (sal_Unicode) 0x221E,
+ MS_SLASH = (sal_Unicode) 0x002F,
+
+ MS_NDIVIDES = (sal_Unicode) 0x2224,
+ MS_DRARROW = (sal_Unicode) 0x21D2,
+ MS_DLARROW = (sal_Unicode) 0x21D0,
+ MS_DLRARROW = (sal_Unicode) 0x21D4,
+ MS_OVERBRACE = (sal_Unicode) 0x23DE,
+ MS_UNDERBRACE = (sal_Unicode) 0x23DF,
+ MS_CIRC = (sal_Unicode) 0x2218,
+ MS_ASSIGN = (sal_Unicode) 0x003D,
+ MS_ERROR = (sal_Unicode) 0x00BF,
+
+ MS_NEQ = (sal_Unicode) 0x2260,
+ MS_PLUS = (sal_Unicode) 0x002B,
+ MS_MINUS = (sal_Unicode) 0x2212,
+ MS_MULTIPLY = (sal_Unicode) 0x2217,
+ MS_TIMES = (sal_Unicode) 0x00D7,
+ MS_CDOT = (sal_Unicode) 0x22C5,
+ MS_DIV = (sal_Unicode) 0x00F7,
+ MS_PLUSMINUS = (sal_Unicode) 0x00B1,
+ MS_MINUSPLUS = (sal_Unicode) 0x2213,
+ MS_OPLUS = (sal_Unicode) 0x2295,
+ MS_OMINUS = (sal_Unicode) 0x2296,
+ MS_OTIMES = (sal_Unicode) 0x2297,
+ MS_ODIVIDE = (sal_Unicode) 0x2298,
+ MS_ODOT = (sal_Unicode) 0x2299,
+ MS_UNION = (sal_Unicode) 0x222A,
+ MS_INTERSECT = (sal_Unicode) 0x2229,
+
+ MS_LT = (sal_Unicode) 0x003C,
+ MS_GT = (sal_Unicode) 0x003E,
+ MS_LE = (sal_Unicode) 0x2264,
+ MS_GE = (sal_Unicode) 0x2265,
+ MS_LESLANT = (sal_Unicode) 0x2A7D,
+ MS_GESLANT = (sal_Unicode) 0x2A7E,
+ MS_LL = (sal_Unicode) 0x226A,
+ MS_GG = (sal_Unicode) 0x226B,
+ MS_SIM = (sal_Unicode) 0x223C,
+ MS_SIMEQ = (sal_Unicode) 0x2243,
+ MS_APPROX = (sal_Unicode) 0x2248,
+ MS_DEF = (sal_Unicode) 0x225D,
+ MS_EQUIV = (sal_Unicode) 0x2261,
+ MS_PROP = (sal_Unicode) 0x221D,
+ MS_PARTIAL = (sal_Unicode) 0x2202,
+
+ MS_SUBSET = (sal_Unicode) 0x2282,
+ MS_SUPSET = (sal_Unicode) 0x2283,
+ MS_SUBSETEQ = (sal_Unicode) 0x2286,
+ MS_SUPSETEQ = (sal_Unicode) 0x2287,
+ MS_NSUBSET = (sal_Unicode) 0x2284,
+ MS_NSUPSET = (sal_Unicode) 0x2285,
+ MS_NSUBSETEQ = (sal_Unicode) 0x2288,
+ MS_NSUPSETEQ = (sal_Unicode) 0x2289,
+ MS_IN = (sal_Unicode) 0x2208,
+ MS_NOTIN = (sal_Unicode) 0x2209,
+ MS_EXISTS = (sal_Unicode) 0x2203,
+ MS_BACKEPSILON = (sal_Unicode) 0x220D,
+ MS_ALEPH = (sal_Unicode) 0x2135,
+ MS_IM = (sal_Unicode) 0x2111,
+ MS_RE = (sal_Unicode) 0x211C,
+ MS_WP = (sal_Unicode) 0x2118,
+
+ MS_LINE = (sal_Unicode) 0x2223,
+ MS_DLINE = (sal_Unicode) 0x2225,
+ MS_ORTHO = (sal_Unicode) 0x22A5,
+ MS_DOTSLOW = (sal_Unicode) 0x2026,
+ MS_DOTSAXIS = (sal_Unicode) 0x22EF,
+ MS_DOTSVERT = (sal_Unicode) 0x22EE,
+ MS_DOTSUP = (sal_Unicode) 0x22F0,
+ MS_DOTSDOWN = (sal_Unicode) 0x22F1,
+ MS_TRANSR = (sal_Unicode) 0x22B6,
+ MS_TRANSL = (sal_Unicode) 0x22B7,
+ MS_BACKSLASH = (sal_Unicode) 0x2216,
+ MS_NEG = (sal_Unicode) 0x00AC,
+
+ MS_FORALL = (sal_Unicode) 0x2200,
+ MS_NABLA = (sal_Unicode) 0x2207,
+ MS_PROD = (sal_Unicode) 0x220F,
+ MS_COPROD = (sal_Unicode) 0x2210,
+ MS_SUM = (sal_Unicode) 0x2211,
+ MS_SQRT = (sal_Unicode) 0x221A,
+ MS_INT = (sal_Unicode) 0x222B,
+ MS_IINT = (sal_Unicode) 0x222C,
+ MS_IIINT = (sal_Unicode) 0x222D,
+ MS_LINT = (sal_Unicode) 0x222E,
+ MS_LLINT = (sal_Unicode) 0x222F,
+ MS_LLLINT = (sal_Unicode) 0x2230,
+
+ MS_GRAVE = (sal_Unicode) 0x0300,
+ MS_ACUTE = (sal_Unicode) 0x0301,
+ MS_HAT = (sal_Unicode) 0x0302,
+ MS_TILDE = (sal_Unicode) 0x0303,
+ MS_BAR = (sal_Unicode) 0x0304,
+ MS_BREVE = (sal_Unicode) 0x0306,
+ MS_CIRCLE = (sal_Unicode) 0x030A,
+ MS_CHECK = (sal_Unicode) 0x030C,
+ MS_VEC = (sal_Unicode) 0x20D7,
+ MS_DOT = (sal_Unicode) 0x02D9,
+ MS_DDOT = (sal_Unicode) 0x00A8,
+ MS_DDDOT = (sal_Unicode) 0x20DB,
+ MS_AND = (sal_Unicode) 0x2227,
+ MS_OR = (sal_Unicode) 0x2228,
+ MS_NI = (sal_Unicode) 0x220B,
+ MS_EMPTYSET = (sal_Unicode) 0x2205,
+
+ MS_LPARENT = (sal_Unicode) 0x0028,
+ MS_RPARENT = (sal_Unicode) 0x0029,
+ MS_LBRACKET = (sal_Unicode) 0x005B,
+ MS_RBRACKET = (sal_Unicode) 0x005D,
+ MS_LBRACE = (sal_Unicode) 0x007B,
+ MS_RBRACE = (sal_Unicode) 0x007D,
+ MS_LCEIL = (sal_Unicode) 0x2308,
+ MS_RCEIL = (sal_Unicode) 0x2309,
+ MS_LFLOOR = (sal_Unicode) 0x230A,
+ MS_RFLOOR = (sal_Unicode) 0x230B,
+ MS_LANGLE = (sal_Unicode) 0x2329,
+ MS_RANGLE = (sal_Unicode) 0x232A,
+ MS_LDBRACKET = (sal_Unicode) 0x27E6,
+ MS_RDBRACKET = (sal_Unicode) 0x27E7,
+
+ MS_PLACE = (sal_Unicode) 0x2751,
+
+ MS_LAMBDABAR = (sal_Unicode) 0x019B,
+ MS_HBAR = (sal_Unicode) 0x210F,
+ MS_LEFTARROW = (sal_Unicode) 0x2190,
+ MS_UPARROW = (sal_Unicode) 0x2191,
+ MS_RIGHTARROW = (sal_Unicode) 0x2192,
+ MS_DOWNARROW = (sal_Unicode) 0x2193,
+ MS_SETN = (sal_Unicode) 0x2115,
+ MS_SETZ = (sal_Unicode) 0x2124,
+ MS_SETQ = (sal_Unicode) 0x211A,
+ MS_SETR = (sal_Unicode) 0x211D,
+ MS_SETC = (sal_Unicode) 0x2102,
+
+ MS_PERCENT = (sal_Unicode) 0x0025
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/unomodel.hxx b/starmath/inc/unomodel.hxx
new file mode 100644
index 000000000000..693ea3bc9b2e
--- /dev/null
+++ b/starmath/inc/unomodel.hxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef UNOMODEL_HXX
+#define UNOMODEL_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/view/XRenderable.hpp>
+
+#include <sfx2/sfxbasemodel.hxx>
+#include <comphelper/propertysethelper.hxx>
+#include <vcl/print.hxx>
+
+class SmFormat;
+
+////////////////////////////////////////////////////////////
+
+#define PRTUIOPT_TITLE_ROW "TitleRow"
+#define PRTUIOPT_FORMULA_TEXT "FormulaText"
+#define PRTUIOPT_BORDER "Border"
+#define PRTUIOPT_PRINT_FORMAT "PrintFormat"
+#define PRTUIOPT_PRINT_SCALE "PrintScale"
+
+class SmPrintUIOptions : public vcl::PrinterOptionsHelper
+{
+public:
+ SmPrintUIOptions();
+};
+
+
+////////////////////////////////////////////////////////////
+
+#define A2OU(pText) rtl::OUString::createFromAscii(pText)
+
+//-----------------------------------------------------------------------------
+class SmModel : public SfxBaseModel,
+ public comphelper::PropertySetHelper,
+ public com::sun::star::lang::XServiceInfo,
+ public com::sun::star::view::XRenderable
+{
+ SmPrintUIOptions* m_pPrintUIOptions;
+protected:
+ virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const ::com::sun::star::uno::Any* pValues )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException );
+ virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, ::com::sun::star::uno::Any* pValue )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException );
+public:
+ SmModel( SfxObjectShell *pObjSh = 0 );
+ virtual ~SmModel() throw ();
+
+ //XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire( ) throw();
+ virtual void SAL_CALL release( ) throw();
+
+ //XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw(::com::sun::star::uno::RuntimeException);
+
+ static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId();
+
+ //XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
+
+ //XRenderable
+ virtual sal_Int32 SAL_CALL getRendererCount( const ::com::sun::star::uno::Any& rSelection, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rxOptions ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getRenderer( sal_Int32 nRenderer, const ::com::sun::star::uno::Any& rSelection, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rxOptions ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL render( sal_Int32 nRenderer, const ::com::sun::star::uno::Any& rSelection, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rxOptions ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ //XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName(void) throw( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xParent ) throw( ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException );
+
+ static ::com::sun::star::uno::Sequence< rtl::OUString > getSupportedServiceNames_Static();
+ static ::rtl::OUString getImplementationName_Static();
+};
+
+////////////////////////////////////////////////////////////
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/utility.hxx b/starmath/inc/utility.hxx
new file mode 100644
index 000000000000..a4e70e1b648d
--- /dev/null
+++ b/starmath/inc/utility.hxx
@@ -0,0 +1,270 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef UTILITY_HXX
+#define UTILITY_HXX
+
+#include <sfx2/minarray.hxx>
+#include <vcl/font.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/lstbox.hxx>
+#include <tools/fract.hxx>
+
+
+class SmRect;
+class String;
+
+#define C2S(cChar) String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(cChar))
+
+
+/////////////////////////////////////////////////////////////////
+
+inline long SmPtsTo100th_mm(long nNumPts)
+ // returns the length (in 100th of mm) that corresponds to the length
+ // 'nNumPts' (in units points).
+ // 72.27 [pt] = 1 [inch] = 2,54 [cm] = 2540 [100th of mm].
+ // result is being rounded to the nearest integer.
+{
+ DBG_ASSERT(nNumPts >= 0, "Sm : Ooops...");
+ // broken into multiple and fraction of 'nNumPts' to reduce chance
+ // of overflow
+ // (7227 / 2) is added in order to round to the nearest integer
+ return 35 * nNumPts + (nNumPts * 1055L + (7227 / 2)) / 7227L;
+}
+
+
+inline long SmPtsTo100th_mm(const Fraction &rNumPts)
+ // as above but with argument 'rNumPts' as 'Fraction'
+{
+ Fraction aTmp (254000L, 7227L);
+ return aTmp *= rNumPts;
+}
+
+
+inline Fraction Sm100th_mmToPts(long nNum100th_mm)
+ // returns the length (in points) that corresponds to the length
+ // 'nNum100th_mm' (in 100th of mm).
+{
+ DBG_ASSERT(nNum100th_mm >= 0, "Sm : Ooops...");
+ Fraction aTmp (7227L, 254000L);
+ return aTmp *= Fraction(nNum100th_mm);
+}
+
+
+inline long SmRoundFraction(const Fraction &rFrac)
+{
+ DBG_ASSERT(rFrac > Fraction(), "Sm : Ooops...");
+ return (rFrac.GetNumerator() + rFrac.GetDenominator() / 2) / rFrac.GetDenominator();
+}
+
+
+class SmViewShell;
+SmViewShell * SmGetActiveView();
+
+
+////////////////////////////////////////////////////////////
+//
+// SmFace
+//
+
+bool IsItalic( const Font &rFont );
+bool IsBold( const Font &rFont );
+
+class SmFace : public Font
+{
+ long nBorderWidth;
+
+ void Impl_Init();
+
+public:
+ SmFace() :
+ Font(), nBorderWidth(-1) { Impl_Init(); }
+ SmFace(const Font& rFont) :
+ Font(rFont), nBorderWidth(-1) { Impl_Init(); }
+ SmFace(const String& rName, const Size& rSize) :
+ Font(rName, rSize), nBorderWidth(-1) { Impl_Init(); }
+ SmFace( FontFamily eFamily, const Size& rSize) :
+ Font(eFamily, rSize), nBorderWidth(-1) { Impl_Init(); }
+
+ SmFace(const SmFace &rFace) :
+ Font(rFace), nBorderWidth(-1) { Impl_Init(); }
+
+ // overloaded version in order to supply a min value
+ // for font size (height). (Also used in ctor's to do so.)
+ void SetSize(const Size& rSize);
+
+ void SetBorderWidth(long nWidth) { nBorderWidth = nWidth; }
+ long GetBorderWidth() const;
+ long GetDefaultBorderWidth() const { return GetSize().Height() / 20 ; }
+ void FreezeBorderWidth() { nBorderWidth = GetDefaultBorderWidth(); }
+
+ SmFace & operator = (const SmFace &rFace);
+};
+
+SmFace & operator *= (SmFace &rFace, const Fraction &rFrac);
+
+
+////////////////////////////////////////////////////////////
+//
+// SmPickList
+//
+
+class SmPickList : public SfxPtrArr
+{
+protected:
+ sal_uInt16 nSize;
+
+ virtual void *CreateItem(const String& rString) = 0;
+ virtual void *CreateItem(const void *pItem) = 0;
+ virtual void DestroyItem(void *pItem) = 0;
+
+ virtual bool CompareItem(const void *pFirstItem, const void *pSecondItem) const = 0;
+
+ virtual String GetStringItem(void *pItem) = 0;
+
+ void *GetPtr(sal_uInt16 nPos) const { return SfxPtrArr::GetObject(nPos); }
+ void *&GetPtr(sal_uInt16 nPos) { return SfxPtrArr::GetObject(nPos); }
+ void InsertPtr(sal_uInt16 nPos, void *pItem) { SfxPtrArr::Insert(nPos, pItem); }
+ void RemovePtr(sal_uInt16 nPos, sal_uInt16 nCount = 1) { SfxPtrArr::Remove(nPos, nCount); }
+
+public:
+ SmPickList(sal_uInt16 nInitSize = 0, sal_uInt16 nMaxSize = 5);
+ virtual ~SmPickList();
+
+ SmPickList& operator = (const SmPickList& rList);
+
+ void *Get(sal_uInt16 nPos = 0) const { return GetPtr(nPos); }
+ using SfxPtrArr::Insert;
+ void Insert(const void* pItem);
+ void Update(const void* pItem, const void *pNewItem);
+ using SfxPtrArr::Remove;
+ void Remove(const void* pItem);
+
+ using SfxPtrArr::operator [];
+ void *operator [] (sal_uInt16 nPos) const { return GetPtr(nPos); }
+
+ sal_uInt16 GetSize() const { return nSize; }
+ sal_uInt16 Count() const { return SfxPtrArr::Count(); }
+
+ void Clear();
+};
+
+
+////////////////////////////////////////////////////////////
+//
+// SmFontPickList
+//
+
+class SmFontDialog;
+
+class SmFontPickList : public SmPickList
+{
+protected:
+ virtual void *CreateItem(const String& rString);
+ virtual void *CreateItem(const void *pItem);
+ virtual void DestroyItem(void *pItem);
+
+ virtual bool CompareItem(const void *pFirstItem, const void *pSecondItem) const;
+
+ virtual String GetStringItem(void *pItem);
+
+public:
+ SmFontPickList()
+ : SmPickList(0, 5) {}
+ SmFontPickList(sal_uInt16 nInitSize, sal_uInt16 nMaxSize)
+ : SmPickList(nInitSize, nMaxSize) {}
+ SmFontPickList(const SmPickList& rOrig )
+ : SmPickList(rOrig) {}
+ virtual ~SmFontPickList() { Clear(); }
+
+ using SfxPtrArr::Insert;
+ virtual void Insert(const Font &rFont);
+ using SmPickList::Update;
+ virtual void Update(const Font &rFont, const Font &rNewFont);
+ using SfxPtrArr::Remove;
+ virtual void Remove(const Font &rFont);
+
+ using SmPickList::Contains;
+ inline bool Contains(const Font &rFont) const;
+ inline Font Get(sal_uInt16 nPos = 0) const;
+
+ inline SmFontPickList& operator = (const SmFontPickList& rList);
+ using SfxPtrArr::operator [];
+ inline Font operator [] (sal_uInt16 nPos) const;
+
+ void ReadFrom(const SmFontDialog& rDialog);
+ void WriteTo(SmFontDialog& rDialog) const;
+};
+
+inline SmFontPickList& SmFontPickList::operator = (const SmFontPickList& rList)
+{
+ *(SmPickList *)this = *(SmPickList *)&rList; return *this;
+}
+
+inline Font SmFontPickList::operator [] (sal_uInt16 nPos) const
+{
+ return *((Font *)SmPickList::operator[](nPos));
+}
+
+inline Font SmFontPickList::Get(sal_uInt16 nPos) const
+{
+ return nPos < Count() ? *((Font *)SmPickList::Get(nPos)) : Font();
+}
+
+inline bool SmFontPickList::Contains(const Font &rFont) const
+{
+ return SmPickList::Contains((void *)&rFont);
+}
+
+
+////////////////////////////////////////////////////////////
+//
+// SmFontPickListBox
+//
+
+class SmFontPickListBox : public SmFontPickList, public ListBox
+{
+protected:
+ DECL_LINK(SelectHdl, ListBox *);
+
+public:
+ SmFontPickListBox(Window* pParent, const ResId& rResId, sal_uInt16 nMax = 4);
+
+ SmFontPickListBox& operator = (const SmFontPickList& rList);
+
+ using SfxPtrArr::Insert;
+ virtual void Insert(const Font &rFont);
+ using Window::Update;
+ virtual void Update(const Font &rFont, const Font &rNewFont);
+ using SfxPtrArr::Remove;
+ virtual void Remove(const Font &rFont);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/view.hxx b/starmath/inc/view.hxx
new file mode 100644
index 000000000000..d716e72f9c07
--- /dev/null
+++ b/starmath/inc/view.hxx
@@ -0,0 +1,333 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef VIEW_HXX
+#define VIEW_HXX
+
+#include <sfx2/dockwin.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svtools/scrwin.hxx>
+#include <sfx2/ctrlitem.hxx>
+#include <sfx2/shell.hxx>
+#include <sfx2/viewfac.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/timer.hxx>
+#include <svtools/colorcfg.hxx>
+#include "edit.hxx"
+#include "node.hxx"
+
+class Menu;
+class DataChangedEvent;
+class SmClipboardChangeListener;
+class SmDocShell;
+class SmViewShell;
+class SmPrintUIOptions;
+class SmGraphicAccessible;
+
+/**************************************************************************/
+
+class SmGraphicWindow : public ScrollableWindow
+{
+ Point aFormulaDrawPos;
+
+ // old style editing pieces
+ Rectangle aCursorRect;
+ bool bIsCursorVisible;
+ bool bIsLineVisible;
+ AutoTimer aCaretBlinkTimer;
+public:
+ bool IsCursorVisible() const { return bIsCursorVisible; }
+ void ShowCursor(bool bShow);
+ bool IsLineVisible() const { return bIsLineVisible; }
+ void ShowLine(bool bShow);
+ const SmNode * SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol);
+protected:
+ void SetIsCursorVisible(bool bVis) { bIsCursorVisible = bVis; }
+ using Window::SetCursor;
+ void SetCursor(const SmNode *pNode);
+ void SetCursor(const Rectangle &rRect);
+ bool IsInlineEditEnabled() const;
+
+private:
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > xAccessible;
+ SmGraphicAccessible * pAccessible;
+
+ SmViewShell *pViewShell;
+ sal_uInt16 nZoom;
+ short nModifyCount;
+
+protected:
+ void SetFormulaDrawPos(const Point &rPos) { aFormulaDrawPos = rPos; }
+
+ virtual void DataChanged( const DataChangedEvent& );
+ virtual void Paint(const Rectangle&);
+ virtual void KeyInput(const KeyEvent& rKEvt);
+ virtual void Command(const CommandEvent& rCEvt);
+ virtual void StateChanged( StateChangedType eChanged );
+ DECL_LINK(MenuSelectHdl, Menu *);
+
+private:
+ void RepaintViewShellDoc();
+ DECL_LINK(CaretBlinkTimerHdl, AutoTimer *);
+ void CaretBlinkInit();
+ void CaretBlinkStart();
+ void CaretBlinkStop();
+public:
+ SmGraphicWindow(SmViewShell* pShell);
+ ~SmGraphicWindow();
+
+ // Window
+ virtual void MouseButtonDown(const MouseEvent &rMEvt);
+ virtual void GetFocus();
+ virtual void LoseFocus();
+
+ SmViewShell * GetView() { return pViewShell; }
+
+ using Window::SetZoom;
+ void SetZoom(sal_uInt16 Factor);
+ using Window::GetZoom;
+ sal_uInt16 GetZoom() const { return nZoom; }
+
+ const Point & GetFormulaDrawPos() const { return aFormulaDrawPos; }
+
+ void ZoomToFitInWindow();
+ using ScrollableWindow::SetTotalSize;
+ void SetTotalSize();
+
+ void ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg );
+
+ // for Accessibility
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ using Window::GetAccessible;
+ SmGraphicAccessible * GetAccessible_Impl() { return pAccessible; }
+};
+
+/**************************************************************************/
+
+class SmGraphicController: public SfxControllerItem
+{
+protected:
+ SmGraphicWindow &rGraphic;
+public:
+ SmGraphicController(SmGraphicWindow &, sal_uInt16, SfxBindings & );
+ virtual void StateChanged(sal_uInt16 nSID,
+ SfxItemState eState,
+ const SfxPoolItem* pState);
+};
+
+/**************************************************************************/
+
+class SmEditController: public SfxControllerItem
+{
+protected:
+ SmEditWindow &rEdit;
+
+public:
+ SmEditController(SmEditWindow &, sal_uInt16, SfxBindings & );
+#if OSL_DEBUG_LEVEL > 1
+ virtual ~SmEditController();
+#endif
+
+ virtual void StateChanged(sal_uInt16 nSID,
+ SfxItemState eState,
+ const SfxPoolItem* pState);
+};
+
+/**************************************************************************/
+
+class SmCmdBoxWindow : public SfxDockingWindow
+{
+ SmEditWindow aEdit;
+ SmEditController aController;
+ bool bExiting;
+
+ Timer aInitialFocusTimer;
+
+ DECL_LINK(InitialFocusTimerHdl, Timer *);
+
+protected :
+
+ // Window
+ virtual void GetFocus();
+ virtual void Resize();
+ virtual void Paint(const Rectangle& rRect);
+ virtual void StateChanged( StateChangedType nStateChange );
+
+ virtual Size CalcDockingSize(SfxChildAlignment eAlign);
+ virtual SfxChildAlignment CheckAlignment(SfxChildAlignment eActual,
+ SfxChildAlignment eWish);
+
+ virtual void ToggleFloatingMode();
+
+public:
+ SmCmdBoxWindow(SfxBindings *pBindings,
+ SfxChildWindow *pChildWindow,
+ Window *pParent);
+
+ virtual ~SmCmdBoxWindow ();
+
+ void AdjustPosition();
+
+ SmEditWindow *GetEditWindow() { return (&aEdit); }
+ SmViewShell *GetView();
+};
+
+/**************************************************************************/
+
+class SmCmdBoxWrapper : public SfxChildWindow
+{
+ SFX_DECL_CHILDWINDOW(SmCmdBoxWrapper);
+
+protected:
+ SmCmdBoxWrapper(Window *pParentWindow,
+ sal_uInt16 nId,
+ SfxBindings *pBindings,
+ SfxChildWinInfo *pInfo);
+
+#if OSL_DEBUG_LEVEL > 1
+ virtual ~SmCmdBoxWrapper();
+#endif
+
+public:
+
+ SmEditWindow *GetEditWindow()
+ {
+ return (((SmCmdBoxWindow *)pWindow)->GetEditWindow());
+ }
+
+};
+
+/**************************************************************************/
+
+namespace sfx2 { class FileDialogHelper; }
+struct SmViewShell_Impl;
+
+class SmViewShell: public SfxViewShell
+{
+ // for handling the PasteClipboardState
+ friend class SmClipboardChangeListener;
+
+ SmViewShell_Impl* pImpl;
+
+ SmGraphicWindow aGraphic;
+ SmGraphicController aGraphicController;
+ String StatusText;
+
+ ::com::sun::star::uno:: Reference <
+ ::com::sun::star::lang:: XEventListener > xClipEvtLstnr;
+ SmClipboardChangeListener* pClipEvtLstnr;
+ bool bPasteState;
+
+ DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper* );
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+ /** Used to determine whether insertions using SID_INSERTSYMBOL and SID_INSERTCOMMAND
+ * should be inserted into SmEditWindow or directly into the SmDocShell as done if the
+ * visual editor was last to have focus.
+ */
+ bool bInsertIntoEditWindow;
+protected:
+
+ Size GetTextLineSize(OutputDevice& rDevice,
+ const String& rLine);
+ Size GetTextSize(OutputDevice& rDevice,
+ const String& rText,
+ long MaxWidth);
+ void DrawTextLine(OutputDevice& rDevice,
+ const Point& rPosition,
+ const String& rLine);
+ void DrawText(OutputDevice& rDevice,
+ const Point& rPosition,
+ const String& rText,
+ sal_uInt16 MaxWidth);
+
+ virtual sal_uInt16 Print(SfxProgress &rProgress, sal_Bool bIsAPI);
+ virtual SfxPrinter *GetPrinter(sal_Bool bCreate = sal_False);
+ virtual sal_uInt16 SetPrinter(SfxPrinter *pNewPrinter,
+ sal_uInt16 nDiffFlags = SFX_PRINTER_ALL, bool bIsAPI=false);
+
+ bool Insert( SfxMedium& rMedium );
+ bool InsertFrom(SfxMedium &rMedium);
+
+ virtual SfxTabPage *CreatePrintOptionsPage(Window *pParent,
+ const SfxItemSet &rOptions);
+ virtual void Deactivate(sal_Bool IsMDIActivate);
+ virtual void Activate(sal_Bool IsMDIActivate);
+ virtual Size GetOptimalSizePixel() const;
+ virtual void AdjustPosSizePixel(const Point &rPos, const Size &rSize);
+ virtual void InnerResizePixel(const Point &rOfs, const Size &rSize);
+ virtual void OuterResizePixel(const Point &rOfs, const Size &rSize);
+ virtual void QueryObjAreaPixel( Rectangle& rRect ) const;
+ virtual void SetZoomFactor( const Fraction &rX, const Fraction &rY );
+
+public:
+ TYPEINFO();
+
+ SmViewShell(SfxViewFrame *pFrame, SfxViewShell *pOldSh);
+ ~SmViewShell();
+
+ SmDocShell * GetDoc()
+ {
+ return (SmDocShell *) GetViewFrame()->GetObjectShell();
+ }
+
+ SmEditWindow * GetEditWindow();
+ SmGraphicWindow & GetGraphicWindow() { return aGraphic; }
+ const SmGraphicWindow & GetGraphicWindow() const { return aGraphic; }
+
+ void SetStatusText(const String& Text);
+
+ void ShowError( const SmErrorDesc *pErrorDesc );
+ void NextError();
+ void PrevError();
+
+ SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START+2)
+ SFX_DECL_VIEWFACTORY(SmViewShell);
+
+ virtual void Execute( SfxRequest& rReq );
+ virtual void GetState(SfxItemSet &);
+
+ void Impl_Print( OutputDevice &rOutDev, const SmPrintUIOptions &rPrintUIOptions,
+ Rectangle aOutRect, Point aZeroPoint );
+
+ /** Set bInsertIntoEditWindow so we know where to insert
+ *
+ * This method is called whenever SmGraphicWindow or SmEditWindow gets focus,
+ * so that when text is inserted from catalog or elsewhere we know whether to
+ * insert for the visual editor, or the text editor.
+ */
+ void SetInsertIntoEditWindow(bool bEditWindowHadFocusLast = true){
+ bInsertIntoEditWindow = bEditWindowHadFocusLast;
+ }
+ bool IsInlineEditEnabled() const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/visitors.hxx b/starmath/inc/visitors.hxx
new file mode 100644
index 000000000000..56fb0e30e032
--- /dev/null
+++ b/starmath/inc/visitors.hxx
@@ -0,0 +1,499 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Jonas Finnemann Jensen <jopsen@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jonas Finnemann Jensen <jopsen@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#ifndef SMVISITORS_H
+#define SMVISITORS_H
+
+#include "node.hxx"
+#include "caret.hxx"
+
+/** Base class for visitors that visits a tree of SmNodes
+ * @remarks all methods have been left abstract to ensure that implementers
+ * don't forget to implement one.
+ */
+class SmVisitor
+{
+public:
+ virtual void Visit( SmTableNode* pNode ) = 0;
+ virtual void Visit( SmBraceNode* pNode ) = 0;
+ virtual void Visit( SmBracebodyNode* pNode ) = 0;
+ virtual void Visit( SmOperNode* pNode ) = 0;
+ virtual void Visit( SmAlignNode* pNode ) = 0;
+ virtual void Visit( SmAttributNode* pNode ) = 0;
+ virtual void Visit( SmFontNode* pNode ) = 0;
+ virtual void Visit( SmUnHorNode* pNode ) = 0;
+ virtual void Visit( SmBinHorNode* pNode ) = 0;
+ virtual void Visit( SmBinVerNode* pNode ) = 0;
+ virtual void Visit( SmBinDiagonalNode* pNode ) = 0;
+ virtual void Visit( SmSubSupNode* pNode ) = 0;
+ virtual void Visit( SmMatrixNode* pNode ) = 0;
+ virtual void Visit( SmPlaceNode* pNode ) = 0;
+ virtual void Visit( SmTextNode* pNode ) = 0;
+ virtual void Visit( SmSpecialNode* pNode ) = 0;
+ virtual void Visit( SmGlyphSpecialNode* pNode ) = 0;
+ virtual void Visit( SmMathSymbolNode* pNode ) = 0;
+ virtual void Visit( SmBlankNode* pNode ) = 0;
+ virtual void Visit( SmErrorNode* pNode ) = 0;
+ virtual void Visit( SmLineNode* pNode ) = 0;
+ virtual void Visit( SmExpressionNode* pNode ) = 0;
+ virtual void Visit( SmPolyLineNode* pNode ) = 0;
+ virtual void Visit( SmRootNode* pNode ) = 0;
+ virtual void Visit( SmRootSymbolNode* pNode ) = 0;
+ virtual void Visit( SmRectangleNode* pNode ) = 0;
+ virtual void Visit( SmVerticalBraceNode* pNode ) = 0;
+};
+
+/** Simple visitor for testing SmVisitor */
+class SmVisitorTest : public SmVisitor
+{
+public:
+ void Visit( SmTableNode* pNode );
+ void Visit( SmBraceNode* pNode );
+ void Visit( SmBracebodyNode* pNode );
+ void Visit( SmOperNode* pNode );
+ void Visit( SmAlignNode* pNode );
+ void Visit( SmAttributNode* pNode );
+ void Visit( SmFontNode* pNode );
+ void Visit( SmUnHorNode* pNode );
+ void Visit( SmBinHorNode* pNode );
+ void Visit( SmBinVerNode* pNode );
+ void Visit( SmBinDiagonalNode* pNode );
+ void Visit( SmSubSupNode* pNode );
+ void Visit( SmMatrixNode* pNode );
+ void Visit( SmPlaceNode* pNode );
+ void Visit( SmTextNode* pNode );
+ void Visit( SmSpecialNode* pNode );
+ void Visit( SmGlyphSpecialNode* pNode );
+ void Visit( SmMathSymbolNode* pNode );
+ void Visit( SmBlankNode* pNode );
+ void Visit( SmErrorNode* pNode );
+ void Visit( SmLineNode* pNode );
+ void Visit( SmExpressionNode* pNode );
+ void Visit( SmPolyLineNode* pNode );
+ void Visit( SmRootNode* pNode );
+ void Visit( SmRootSymbolNode* pNode );
+ void Visit( SmRectangleNode* pNode );
+ void Visit( SmVerticalBraceNode* pNode );
+private:
+ /** Auxiliary method for visiting the children of a pNode */
+ void VisitChildren( SmNode* pNode );
+};
+
+/////////////////////////////// SmDefaultingVisitor ////////////////////////////////
+
+
+/** Visitor that uses DefaultVisit for handling visits by default
+ *
+ * This abstract baseclass is useful for visitors where many methods share the same
+ * implementation.
+ */
+class SmDefaultingVisitor : public SmVisitor
+{
+public:
+ void Visit( SmTableNode* pNode );
+ void Visit( SmBraceNode* pNode );
+ void Visit( SmBracebodyNode* pNode );
+ void Visit( SmOperNode* pNode );
+ void Visit( SmAlignNode* pNode );
+ void Visit( SmAttributNode* pNode );
+ void Visit( SmFontNode* pNode );
+ void Visit( SmUnHorNode* pNode );
+ void Visit( SmBinHorNode* pNode );
+ void Visit( SmBinVerNode* pNode );
+ void Visit( SmBinDiagonalNode* pNode );
+ void Visit( SmSubSupNode* pNode );
+ void Visit( SmMatrixNode* pNode );
+ void Visit( SmPlaceNode* pNode );
+ void Visit( SmTextNode* pNode );
+ void Visit( SmSpecialNode* pNode );
+ void Visit( SmGlyphSpecialNode* pNode );
+ void Visit( SmMathSymbolNode* pNode );
+ void Visit( SmBlankNode* pNode );
+ void Visit( SmErrorNode* pNode );
+ void Visit( SmLineNode* pNode );
+ void Visit( SmExpressionNode* pNode );
+ void Visit( SmPolyLineNode* pNode );
+ void Visit( SmRootNode* pNode );
+ void Visit( SmRootSymbolNode* pNode );
+ void Visit( SmRectangleNode* pNode );
+ void Visit( SmVerticalBraceNode* pNode );
+protected:
+ /** Method invoked by Visit methods by default */
+ virtual void DefaultVisit( SmNode* pNode ) = 0;
+};
+
+/////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
+
+/** Visitor for drawing a caret position */
+class SmCaretDrawingVisitor : public SmDefaultingVisitor
+{
+public:
+ /** Given position and device this constructor will draw the caret */
+ SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible );
+ void Visit( SmTextNode* pNode );
+ using SmDefaultingVisitor::Visit;
+private:
+ OutputDevice &rDev;
+ SmCaretPos pos;
+ /** Offset to draw from */
+ Point Offset;
+ bool isCaretVisible;
+protected:
+ /** Default method for drawing pNodes */
+ void DefaultVisit( SmNode* pNode );
+};
+
+/////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
+
+/** Visitor getting a line from a caret position */
+class SmCaretPos2LineVisitor : public SmDefaultingVisitor
+{
+public:
+ /** Given position and device this constructor will compute a line for the caret */
+ SmCaretPos2LineVisitor( OutputDevice *pDevice, SmCaretPos position ) {
+ pDev = pDevice;
+ pos = position;
+ OSL_ENSURE( position.IsValid( ), "Cannot draw invalid position!" );
+
+ pos.pSelectedNode->Accept( this );
+ }
+ void Visit( SmTextNode* pNode );
+ using SmDefaultingVisitor::Visit;
+ SmCaretLine GetResult( ){
+ return line;
+ }
+private:
+ SmCaretLine line;
+ OutputDevice *pDev;
+ SmCaretPos pos;
+protected:
+ /** Default method for computing lines for pNodes */
+ void DefaultVisit( SmNode* pNode );
+};
+
+/////////////////////////////// SmDrawingVisitor ////////////////////////////////
+
+/** Visitor for drawing SmNodes to OutputDevice */
+class SmDrawingVisitor : public SmVisitor
+{
+public:
+ /** Create an instance of SmDrawingVisitor, and use it to draw a formula
+ * @param rDevice Device to draw on
+ * @param position Offset on device to draw the formula
+ * @param pTree Formula tree to draw
+ * @remarks This constructor will do the drawing, no need to anything more.
+ */
+ SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree )
+ : rDev( rDevice ) {
+ this->Position = position;
+ pTree->Accept( this );
+ }
+ void Visit( SmTableNode* pNode );
+ void Visit( SmBraceNode* pNode );
+ void Visit( SmBracebodyNode* pNode );
+ void Visit( SmOperNode* pNode );
+ void Visit( SmAlignNode* pNode );
+ void Visit( SmAttributNode* pNode );
+ void Visit( SmFontNode* pNode );
+ void Visit( SmUnHorNode* pNode );
+ void Visit( SmBinHorNode* pNode );
+ void Visit( SmBinVerNode* pNode );
+ void Visit( SmBinDiagonalNode* pNode );
+ void Visit( SmSubSupNode* pNode );
+ void Visit( SmMatrixNode* pNode );
+ void Visit( SmPlaceNode* pNode );
+ void Visit( SmTextNode* pNode );
+ void Visit( SmSpecialNode* pNode );
+ void Visit( SmGlyphSpecialNode* pNode );
+ void Visit( SmMathSymbolNode* pNode );
+ void Visit( SmBlankNode* pNode );
+ void Visit( SmErrorNode* pNode );
+ void Visit( SmLineNode* pNode );
+ void Visit( SmExpressionNode* pNode );
+ void Visit( SmPolyLineNode* pNode );
+ void Visit( SmRootNode* pNode );
+ void Visit( SmRootSymbolNode* pNode );
+ void Visit( SmRectangleNode* pNode );
+ void Visit( SmVerticalBraceNode* pNode );
+private:
+ /** Draw the children of a pNode
+ * This the default method, use by most pNodes
+ */
+ void DrawChildren( SmNode* pNode );
+
+ /** Draw an SmTextNode or a subclass of this */
+ void DrawTextNode( SmTextNode* pNode );
+ /** Draw an SmSpecialNode or a subclass of this */
+ void DrawSpecialNode( SmSpecialNode* pNode );
+ /** OutputDevice to draw on */
+ OutputDevice& rDev;
+ /** Position to draw on the rDev
+ * @remarks This variable is used to pass parameters in DrawChildren( ), this means
+ that after a call to DrawChildren( ) the contents of this method is undefined
+ so if needed cache it locally on the stack.
+ */
+ Point Position;
+};
+
+/////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
+
+/** Set Selection Visitor
+ * Sets the IsSelected( ) property on all SmNodes of the tree
+ */
+class SmSetSelectionVisitor : public SmDefaultingVisitor
+{
+public:
+ SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
+ void Visit( SmBinHorNode* pNode );
+ void Visit( SmUnHorNode* pNode );
+ void Visit( SmFontNode* pNode );
+ void Visit( SmTextNode* pNode );
+ void Visit( SmExpressionNode* pNode );
+ void Visit( SmLineNode* pNode );
+ void Visit( SmAlignNode* pNode );
+ using SmDefaultingVisitor::Visit;
+ /** Set IsSelected on all pNodes of pSubTree */
+ static void SetSelectedOnAll( SmNode* pSubTree, bool IsSelected = true );
+private:
+ /** Visit a selectable pNode
+ * Can be used to handle pNodes that can be selected, that doesn't have more SmCaretPos'
+ * than 0 and 1 inside them. SmTextNode should be handle seperately!
+ * Also note that pNodes such as SmBinVerNode cannot be selected, don't this method for
+ * it.
+ */
+ void DefaultVisit( SmNode* pNode );
+ void VisitCompositionNode( SmNode* pNode );
+ /** Caret position where the selection starts */
+ SmCaretPos StartPos;
+ /** Caret position where the selection ends */
+ SmCaretPos EndPos;
+ /** The current state of this visitor
+ * This property changes when the visitor meets either StartPos
+ * or EndPos. This means that anything visited in between will be
+ * selected.
+ */
+ bool IsSelecting;
+};
+
+
+/////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
+
+
+/** A visitor for building a SmCaretPosGraph
+ *
+ * Visit invariant:
+ * Each pNode, except SmExpressionNode, SmBinHorNode and a few others, constitues an entry
+ * in a line. Consider the line entry "H", this entry creates one carat position, here
+ * denoted by | in "H|".
+ *
+ * Parameter variables:
+ * The following variables are used to transfer parameters in to calls and results out
+ * of calls.
+ * pRightMost : SmCaretPosGraphEntry*
+ *
+ * Prior to a Visit call:
+ * pRightMost: A pointer to right most position infront of the current line entry.
+ *
+ * After a Visit call:
+ * pRightMost: A pointer to the right most position in the called line entry, if no there's
+ * no caret positions in called line entry don't change this variable.
+ */
+class SmCaretPosGraphBuildingVisitor : public SmVisitor
+{
+public:
+ /** Builds a caret position graph for pRootNode */
+ SmCaretPosGraphBuildingVisitor( SmNode* pRootNode );
+ void Visit( SmTableNode* pNode );
+ void Visit( SmBraceNode* pNode );
+ void Visit( SmBracebodyNode* pNode );
+ void Visit( SmOperNode* pNode );
+ void Visit( SmAlignNode* pNode );
+ void Visit( SmAttributNode* pNode );
+ void Visit( SmFontNode* pNode );
+ void Visit( SmUnHorNode* pNode );
+ void Visit( SmBinHorNode* pNode );
+ void Visit( SmBinVerNode* pNode );
+ void Visit( SmBinDiagonalNode* pNode );
+ void Visit( SmSubSupNode* pNode );
+ void Visit( SmMatrixNode* pNode );
+ void Visit( SmPlaceNode* pNode );
+ void Visit( SmTextNode* pNode );
+ void Visit( SmSpecialNode* pNode );
+ void Visit( SmGlyphSpecialNode* pNode );
+ void Visit( SmMathSymbolNode* pNode );
+ void Visit( SmBlankNode* pNode );
+ void Visit( SmErrorNode* pNode );
+ void Visit( SmLineNode* pNode );
+ void Visit( SmExpressionNode* pNode );
+ void Visit( SmPolyLineNode* pNode );
+ void Visit( SmRootNode* pNode );
+ void Visit( SmRootSymbolNode* pNode );
+ void Visit( SmRectangleNode* pNode );
+ void Visit( SmVerticalBraceNode* pNode );
+ SmCaretPosGraph* Graph( ){
+ return pGraph;
+ }
+private:
+ SmCaretPosGraphEntry* pRightMost;
+ SmCaretPosGraph* pGraph;
+};
+
+/////////////////////////////// SmCloningVisitor ///////////////////////////////
+
+/** Visitor for cloning a pNode
+ *
+ * This visitor creates deep clones.
+ */
+class SmCloningVisitor : public SmVisitor
+{
+public:
+ SmCloningVisitor( ){ pResult = NULL; }
+ void Visit( SmTableNode* pNode );
+ void Visit( SmBraceNode* pNode );
+ void Visit( SmBracebodyNode* pNode );
+ void Visit( SmOperNode* pNode );
+ void Visit( SmAlignNode* pNode );
+ void Visit( SmAttributNode* pNode );
+ void Visit( SmFontNode* pNode );
+ void Visit( SmUnHorNode* pNode );
+ void Visit( SmBinHorNode* pNode );
+ void Visit( SmBinVerNode* pNode );
+ void Visit( SmBinDiagonalNode* pNode );
+ void Visit( SmSubSupNode* pNode );
+ void Visit( SmMatrixNode* pNode );
+ void Visit( SmPlaceNode* pNode );
+ void Visit( SmTextNode* pNode );
+ void Visit( SmSpecialNode* pNode );
+ void Visit( SmGlyphSpecialNode* pNode );
+ void Visit( SmMathSymbolNode* pNode );
+ void Visit( SmBlankNode* pNode );
+ void Visit( SmErrorNode* pNode );
+ void Visit( SmLineNode* pNode );
+ void Visit( SmExpressionNode* pNode );
+ void Visit( SmPolyLineNode* pNode );
+ void Visit( SmRootNode* pNode );
+ void Visit( SmRootSymbolNode* pNode );
+ void Visit( SmRectangleNode* pNode );
+ void Visit( SmVerticalBraceNode* pNode );
+ /** Clone a pNode */
+ SmNode* Clone( SmNode* pNode );
+private:
+ SmNode* pResult;
+ /** Clone children of pSource and give them to pTarget */
+ void CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget );
+ /** Clone attributes on a pNode */
+ void CloneNodeAttr( SmNode* pSource, SmNode* pTarget );
+};
+
+
+/////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
+
+class SmSelectionDrawingVisitor : public SmDefaultingVisitor
+{
+public:
+ /** Draws a selection on rDevice for the selection on pTree */
+ SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, Point Offset );
+ void Visit( SmTextNode* pNode );
+ using SmDefaultingVisitor::Visit;
+private:
+ /** Reference to drawing device */
+ OutputDevice& rDev;
+ /** True if aSelectionArea have been initialized */
+ bool bHasSelectionArea;
+ /** The current area that is selected */
+ Rectangle aSelectionArea;
+ /** Extend the area that must be selected */
+ void ExtendSelectionArea( Rectangle aArea );
+ /** Default visiting method */
+ void DefaultVisit( SmNode* pNode );
+ /** Visit the children of a given pNode */
+ void VisitChildren( SmNode* pNode );
+};
+
+/////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
+
+/** Extract command text from pNodes */
+class SmNodeToTextVisitor : public SmVisitor
+{
+public:
+ SmNodeToTextVisitor( SmNode* pNode, String &rText )
+ : rCmdText( rText ) {
+ pNode->Accept( this );
+ }
+ void Visit( SmTableNode* pNode );
+ void Visit( SmBraceNode* pNode );
+ void Visit( SmBracebodyNode* pNode );
+ void Visit( SmOperNode* pNode );
+ void Visit( SmAlignNode* pNode );
+ void Visit( SmAttributNode* pNode );
+ void Visit( SmFontNode* pNode );
+ void Visit( SmUnHorNode* pNode );
+ void Visit( SmBinHorNode* pNode );
+ void Visit( SmBinVerNode* pNode );
+ void Visit( SmBinDiagonalNode* pNode );
+ void Visit( SmSubSupNode* pNode );
+ void Visit( SmMatrixNode* pNode );
+ void Visit( SmPlaceNode* pNode );
+ void Visit( SmTextNode* pNode );
+ void Visit( SmSpecialNode* pNode );
+ void Visit( SmGlyphSpecialNode* pNode );
+ void Visit( SmMathSymbolNode* pNode );
+ void Visit( SmBlankNode* pNode );
+ void Visit( SmErrorNode* pNode );
+ void Visit( SmLineNode* pNode );
+ void Visit( SmExpressionNode* pNode );
+ void Visit( SmPolyLineNode* pNode );
+ void Visit( SmRootNode* pNode );
+ void Visit( SmRootSymbolNode* pNode );
+ void Visit( SmRectangleNode* pNode );
+ void Visit( SmVerticalBraceNode* pNode );
+private:
+ /** Extract text from a pNode that constitues a line */
+ void LineToText( SmNode* pNode ) {
+ Separate( );
+ if( pNode )
+ pNode->Accept( this );
+ Separate( );
+ }
+ inline void Append( const sal_Char* pCharStr ) {
+ rCmdText.AppendAscii( pCharStr );
+ }
+ inline void Append( const String &rText ) {
+ rCmdText.Append( rText );
+ }
+ /** Append a blank for separation, if needed */
+ inline void Separate( ){
+ if( !rCmdText.Len() || rCmdText.GetChar( rCmdText.Len( ) - 1 ) != ' ' )
+ rCmdText.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " " ) );
+ }
+ /** Output text generated from the pNodes */
+ String &rCmdText;
+};
+
+#endif /* SMVISITORS_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/prj/build.lst b/starmath/prj/build.lst
new file mode 100644
index 000000000000..4afbef9468ab
--- /dev/null
+++ b/starmath/prj/build.lst
@@ -0,0 +1,9 @@
+sm starmath : LIBXSLT:libxslt TRANSLATIONS:translations svx ure NULL
+sm starmath usr1 - all sm_mkout NULL
+sm starmath\inc nmake - all sm_inc NULL
+sm starmath\prj get - all sm_prj NULL
+sm starmath\res get - all sm_res NULL
+sm starmath\sdi nmake - all sm_sdi NULL
+sm starmath\source nmake - all sm_sorce sm_sdi sm_inc NULL
+sm starmath\util nmake - all sm_util sm_sorce NULL
+sm starmath\qa\cppunit nmake - u sm_qa_cppunit sm_util NULL
diff --git a/starmath/prj/d.lst b/starmath/prj/d.lst
new file mode 100644
index 000000000000..78bae57498ea
--- /dev/null
+++ b/starmath/prj/d.lst
@@ -0,0 +1,23 @@
+mkdir: %COMMON_DEST%\bin%_EXT%\hid
+mkdir: %_DEST%\xml%_EXT%\uiconfig
+mkdir: %_DEST%\xml%_EXT%\uiconfig\modules
+mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\smath
+mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\smath\menubar
+mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\smath\toolbar
+mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\smath\statusbar
+
+..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid
+..\%__SRC%\lib\lib*.* %_DEST%\lib%_EXT%\lib*.*
+..\%__SRC%\misc\*.map %_DEST%\bin%_EXT%\*.map
+..\xml\*.xml %_DEST%\xml%_EXT%\*.xml
+..\%__SRC%\bin\sm?????.dll %_DEST%\bin%_EXT%\sm?????.dll
+..\%__SRC%\bin\smd?????.dll %_DEST%\bin%_EXT%\smd?????.dll
+..\%__SRC%\bin\sm*.res %_DEST%\bin%_EXT%\sm*.res
+..\%__SRC%\bin\sm?????.sym %_DEST%\bin%_EXT%\sm?????.sym
+mkdir: %_DEST%\inc%_EXT%\starmath
+
+..\uiconfig\smath\menubar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\smath\menubar\*.xml
+..\uiconfig\smath\toolbar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\smath\toolbar\*.xml
+..\uiconfig\smath\statusbar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\smath\statusbar\*.xml
+..\%__SRC%\misc\sm.component %_DEST%\xml%_EXT%\sm.component
+..\%__SRC%\misc\smd.component %_DEST%\xml%_EXT%\smd.component
diff --git a/starmath/prj/gbuild.lst b/starmath/prj/gbuild.lst
new file mode 100644
index 000000000000..da2383eb27e8
--- /dev/null
+++ b/starmath/prj/gbuild.lst
@@ -0,0 +1,2 @@
+sm starmath : LIBXSLT:libxslt TRANSLATIONS:translations svx ure NULL
+sm starmath\prj nmake - all sm_prj NULL
diff --git a/starmath/prj/makefile.mk b/starmath/prj/makefile.mk
new file mode 100644
index 000000000000..e312a7ccab65
--- /dev/null
+++ b/starmath/prj/makefile.mk
@@ -0,0 +1,40 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+TARGET=prj
+
+.INCLUDE : settings.mk
+
+.IF "$(VERBOSE)"!=""
+VERBOSEFLAG :=
+.ELSE
+VERBOSEFLAG := -s
+.ENDIF
+
+all:
+ cd $(PRJ) && $(GNUMAKE) $(VERBOSEFLAG) -r -j$(MAXPROCESS) $(gb_MAKETARGET) && $(GNUMAKE) $(VERBOSEFLAG) -r deliverlog
diff --git a/starmath/qa/cppunit/makefile.mk b/starmath/qa/cppunit/makefile.mk
new file mode 100644
index 000000000000..a61a13ed3783
--- /dev/null
+++ b/starmath/qa/cppunit/makefile.mk
@@ -0,0 +1,147 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=../..
+PRJNAME=starmath
+TARGET=qa_cppunit
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+CFLAGSCXX += $(CPPUNIT_CFLAGS)
+
+# --- Libs ---------------------------------------------------------
+
+SHL1OBJS= \
+ $(SLO)/test_starmath.obj \
+ $(SLO)/test_nodetotextvisitors.obj
+
+
+SHL1STDLIBS= \
+ $(CPPUNITLIB) \
+ $(EDITENGLIB) \
+ $(SVXCORELIB) \
+ $(SVXLIB) \
+ $(SFX2LIB) \
+ $(XMLOFFLIB) \
+ $(SVTOOLLIB) \
+ $(TKLIB) \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(I18NPAPERLIB) \
+ $(SOTLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1LIBS=$(SLB)$/starmath.lib
+
+SHL1TARGET= test_starmath
+SHL1RPATH = NONE
+SHL1IMPLIB= i$(SHL1TARGET)
+# SHL1DEF= $(MISC)/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+# DEF1EXPORTFILE= export.exp
+SHL1VERSIONMAP= version.map
+
+# --- All object files ---------------------------------------------
+
+SLOFILES= \
+ $(SHL1OBJS) \
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(OS)" == "WNT"
+my_file = file:///
+.ELSE
+my_file = file://
+.END
+
+ALLTAR: test
+
+test_components = \
+ component/framework/util/fwk \
+ component/toolkit/util/tk \
+ component/sfx2/util/sfx \
+ configmgr \
+ vcl \
+ mcnttype \
+ i18npool
+.IF "$(OS)" == "WNT"
+test_components += \
+ sysdtrans \
+ ftransl
+.ENDIF
+
+# Make a services.rdb with the services we know we need to get up and running
+$(MISC)/services.input : makefile.mk
+ $(MKDIRHIER) $(@:d)
+ echo \
+ '<list>$(test_components:^"<filename>":+".component</filename>")</list>' \
+ > $@
+
+$(MISC)/$(TARGET)/services.rdb .ERRREMOVE : makefile.mk $(MISC)/services.input
+ $(MKDIRHIER) $(@:d)
+ $(XSLTPROC) --nonet --stringparam prefix $(SOLARXMLDIR)/ -o $@.tmp \
+ $(SOLARENV)/bin/packcomponents.xslt $(MISC)/services.input
+ cat $(MISC)/$@.tmp | sed 's|/program/|/|g' > $@
+
+#Tweak things so that we use the .res files in the solver
+STAR_RESOURCEPATH:=$(PWD)/$(BIN)$(PATH_SEPERATOR)$(SOLARBINDIR)
+.EXPORT : STAR_RESOURCEPATH
+
+.IF "$(OS)" != "DRAGONFLY"
+
+test .PHONY: $(SHL1TARGETN) $(MISC)/$(TARGET)/services.rdb
+ @echo ----------------------------------------------------------
+ @echo - start unit test \#1 on library $(SHL1TARGETN)
+ @echo ----------------------------------------------------------
+ $(CPPUNITTESTER) $(SHL1TARGETN) --headless --invisible \
+ '-env:UNO_TYPES=$(my_file)$(SOLARBINDIR)/udkapi.rdb $(my_file)$(SOLARBINDIR)$/types.rdb' \
+ '-env:UNO_SERVICES=$(my_file)$(SOLARXMLDIR)/ure/services.rdb $(my_file)$(PWD)/$(MISC)/$(TARGET)/services.rdb'\
+ -env:URE_INTERNAL_LIB_DIR="$(my_file)$(SOLARSHAREDBIN)" \
+ -env:OOO_BASE_DIR="$(my_file)$(SOLARSHAREDBIN)" \
+ -env:BRAND_BASE_DIR="$(my_file)$(SOLARSHAREDBIN)"
+
+.ELSE
+
+test .PHONY: $(SHL1TARGETN)
+ @echo ----------------------------------------------------------
+ @echo - WARNING!!, test disabled on your platform
+ @echo - Please test manually, and enable if it works
+ @echo ----------------------------------------------------------
+
+.ENDIF
diff --git a/starmath/qa/cppunit/test_nodetotextvisitors.cxx b/starmath/qa/cppunit/test_nodetotextvisitors.cxx
new file mode 100644
index 000000000000..aec9be0efa46
--- /dev/null
+++ b/starmath/qa/cppunit/test_nodetotextvisitors.cxx
@@ -0,0 +1,683 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Luke Dixon <6b8b4567@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+#include <cppunit/TestSuite.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestAssert.h>
+
+#include <sal/config.h>
+
+#include <cppuhelper/bootstrap.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <vcl/svapp.hxx>
+#include <smdll.hxx>
+
+#include <document.hxx>
+#include <node.hxx>
+#include <visitors.hxx>
+#include <cursor.hxx>
+
+namespace CppUnit {
+template<>
+struct assertion_traits<String>
+{
+ static bool equal(const String& x, const String& y)
+ {
+ return x == y;
+ }
+
+ static std::string toString(const String& x)
+ {
+ std::string text = ByteString(x, RTL_TEXTENCODING_UTF8).GetBuffer();
+ OStringStream ost;
+ ost << text;
+ return ost.str();
+ }
+};
+}
+
+SO2_DECL_REF(SmDocShell)
+SO2_IMPL_REF(SmDocShell)
+
+class TestOutputDevice : public OutputDevice
+{
+public:
+ TestOutputDevice()
+ {
+ }
+};
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class Test : public CppUnit::TestFixture {
+public:
+ Test();
+ ~Test();
+
+ // init
+ virtual void setUp();
+ virtual void tearDown();
+
+ // tests
+ void SimpleUnaryOp();
+ void SimpleBinaryOp();
+ void SimpleRelationalOp();
+ void SimpleSetOp();
+ void SimpleFunctions();
+ void SimpleOperators();
+ void SimpleAttributes();
+ void SimpleMisc();
+ void SimpleBrackets();
+ void SimpleFormats();
+ void SimpleGreekChars();
+ void SimpleSpecialChars();
+ void testBinomInBinHor();
+ void testBinVerInUnary();
+ void testBinHorInSubSup();
+ void testUnaryInMixedNumberAsNumerator();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(SimpleUnaryOp);
+ CPPUNIT_TEST(SimpleBinaryOp);
+ CPPUNIT_TEST(SimpleRelationalOp);
+ CPPUNIT_TEST(SimpleSetOp);
+ CPPUNIT_TEST(SimpleFunctions);
+ CPPUNIT_TEST(SimpleOperators);
+ CPPUNIT_TEST(SimpleAttributes);
+ CPPUNIT_TEST(SimpleMisc);
+ CPPUNIT_TEST(SimpleBrackets);
+ CPPUNIT_TEST(SimpleFormats);
+ CPPUNIT_TEST(SimpleGreekChars);
+ CPPUNIT_TEST(SimpleSpecialChars);
+ CPPUNIT_TEST(testBinomInBinHor);
+ CPPUNIT_TEST(testBinVerInUnary);
+ CPPUNIT_TEST(testBinHorInSubSup);
+ CPPUNIT_TEST(testUnaryInMixedNumberAsNumerator);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ uno::Reference< uno::XComponentContext > m_context;
+ SmDocShellRef xDocShRef;
+ void parseandparseagain(const char *input, const char *test_name);
+ void ParseAndCheck(const char *input, const char *expected, const char *test_name);
+};
+
+Test::Test()
+{
+ m_context = cppu::defaultBootstrap_InitialComponentContext();
+
+ uno::Reference<lang::XMultiComponentFactory> xFactory(m_context->getServiceManager());
+ uno::Reference<lang::XMultiServiceFactory> xSM(xFactory, uno::UNO_QUERY_THROW);
+
+ //Without this we're crashing because callees are using
+ //getProcessServiceFactory. In general those should be removed in favour
+ //of retaining references to the root ServiceFactory as its passed around
+ comphelper::setProcessServiceFactory(xSM);
+
+ InitVCL(xSM);
+
+ SmDLL::Init();
+}
+
+void Test::setUp()
+{
+ xDocShRef = new SmDocShell(SFXOBJECTSHELL_STD_NORMAL);
+}
+
+void Test::tearDown()
+{
+ xDocShRef.Clear();
+}
+
+Test::~Test()
+{
+}
+
+/*
+ * Most of the formula commands in this file came from:
+ * http://wiki.services.openoffice.org/wiki/Template:Math_commands_reference
+ * which was licensed with a
+ * Creative Common Attribution 3.0 license and written by:
+ * Jeanweber, Weegreenblobbie, Jdpipe, TJFrazier, Ysangkok, B michaelsen, Spellbreaker
+ */
+
+void Test::SimpleUnaryOp()
+{
+ parseandparseagain("+1", "Positive (plus)");
+ parseandparseagain("-2", "Negative (minus)");
+ parseandparseagain("+-3", "Plus/minus");
+ parseandparseagain("-+4", "Minus/plus");
+ parseandparseagain("neg a", "Boolean 'not'");
+ parseandparseagain("fact a", "Factorial");
+ parseandparseagain(" - { 1 over 2 } ", "BinVer in Unary 1");
+ ParseAndCheck(" - { 1 over 2 } ", " - { 1 over 2 } ", "BinVer in Unary 1");
+ parseandparseagain(" { - { 1 over 2 } } ", "BinVer in Unary 2");
+ parseandparseagain(" - 1 over 2 ", "Unary in BinVer as numerator 1");
+ parseandparseagain(" { - 1 } over 2 ", "Unary in BinVer as numerator 2");
+ parseandparseagain(" 1 over - 2 ", "Unary in BinVer as denominator 1");
+ parseandparseagain(" 1 over { - 2 } ", "Unary in BinVer as denominator 2");
+ parseandparseagain(" 2 { - 1 over 2 } ", "Mixed number with Unary in denominator 1");
+ parseandparseagain(" 2 { - 1 } over 2 ", "Mixed number with Unary in denominator 2");
+ parseandparseagain(" - 1 + 2 ", "Unary in BinHor");
+}
+
+void Test::SimpleBinaryOp()
+{
+ parseandparseagain("a + b", "Addition");
+ parseandparseagain("a cdot b", "Dot product");
+ parseandparseagain("a times b", "Cross product");
+ parseandparseagain("a * b", "Multiplication (asterisk)");
+ parseandparseagain("a and b", "Boolean 'and'");
+ parseandparseagain("a - b", "Subtraction");
+ parseandparseagain("a over b", "Division (as a fraction)");
+ parseandparseagain("a div b", "Division (as an operator)");
+ parseandparseagain("a / b", "Division (with a slash)");
+ parseandparseagain("a or b", "Boolean 'or'");
+ parseandparseagain("a circ b", "Concatenation");
+}
+
+void Test::SimpleRelationalOp()
+{
+ parseandparseagain("a = b", "Is equal");
+ parseandparseagain("a <> b", "Is not equal");
+ parseandparseagain("a approx 2", "Approximately");
+ parseandparseagain("a divides b", "Divides");
+ parseandparseagain("a ndivides b", "Does not divide");
+ parseandparseagain("a < 2", "Less than");
+ parseandparseagain("a > 2", "Greater than");
+ parseandparseagain("a simeq b", "Similar to or equal");
+ parseandparseagain("a parallel b", "Parallel");
+ parseandparseagain("a ortho b", "Orthogonal to");
+ parseandparseagain("a leslant b", "Less than or equal to");
+ parseandparseagain("a geslant b", "Greater than or equal to");
+ parseandparseagain("a sim b", "Similar to");
+ parseandparseagain("a equiv b", "Congruent");
+ parseandparseagain("a <= b", "Less than or equal to");
+ parseandparseagain("a >= b", "Greater than or equal to");
+ parseandparseagain("a prop b", "Proportional");
+ parseandparseagain("a toward b", "Toward");
+ parseandparseagain("a dlarrow b", "Arrow left");
+ parseandparseagain("a dlrarrow b", "Double arrow left and right");
+ parseandparseagain("drarrow b", "Arrow right");
+}
+
+void Test::SimpleSetOp()
+{
+ parseandparseagain("a in B", "Is in");
+ parseandparseagain("a notin B", "Is not in");
+ parseandparseagain("A owns b", "Owns");
+ parseandparseagain("emptyset", "Empty set");
+ parseandparseagain("A intersection B", "Intersection");
+ parseandparseagain("A union B", "Union");
+ parseandparseagain("A setminus B", "Difference");
+ parseandparseagain("A slash B", "Quotient");
+ parseandparseagain("aleph", "Aleph");
+ parseandparseagain("A subset B", "Subset");
+ parseandparseagain("A subseteq B", "Subset or equal to");
+ parseandparseagain("A supset B", "Superset");
+ parseandparseagain("A supseteq B", "Superset or equal to");
+ parseandparseagain("A nsubset B", "Not subset");
+ parseandparseagain("A nsubseteq B", "Not subset or equal");
+ parseandparseagain("A nsupset B", "Not superset");
+ parseandparseagain("A nsupseteq B", "Not superset or equal");
+ parseandparseagain("setN", "Set of natural numbers");
+ parseandparseagain("setZ", "Set of integers");
+ parseandparseagain("setQ", "Set of rational numbers");
+ parseandparseagain("setR", "Set of real numbers");
+ parseandparseagain("setC", "Set of complex numbers");
+}
+
+void Test::SimpleFunctions()
+{
+ parseandparseagain("func e^{a}", "Exponential");
+ parseandparseagain("ln(a)", "Natural logarithm");
+ parseandparseagain("exp(a)", "Exponential function");
+ parseandparseagain("log(a)", "Logarithm");
+ parseandparseagain("a^{b}", "Power");
+ parseandparseagain("sin(a)", "Sine");
+ parseandparseagain("cos(a)", "Cosine");
+ parseandparseagain("tan(a)", "Tangent");
+ parseandparseagain("cot(a)", "Cotangent");
+ parseandparseagain("sqrt{a}", "Square root");
+ parseandparseagain("arcsin(a)", "Arcsine");
+ parseandparseagain("arccos(a)", "Arccosine");
+ parseandparseagain("arctan(a)", "Arctangent");
+ parseandparseagain("arccot(a)", "Arc cotangent");
+ parseandparseagain("nroot{a}{b}", "nth root");
+ parseandparseagain("sinh(a)", "Hyperbolic sine");
+ parseandparseagain("cosh(a)", "Hyperbolic cosine");
+ parseandparseagain("tanh(a)", "Hyperbolic tangent");
+ parseandparseagain("coth(a)", "Hyperbolic cotangent");
+ parseandparseagain("abs{a}", "Absolute value");
+ parseandparseagain("arsinh(a)", "Arc hyperbolic sine");
+ parseandparseagain("arcosh(a)", "Arc hyperbolic cosine");
+ parseandparseagain("artanh(a)", "Arc hyperbolic tangent");
+ parseandparseagain("arcoth(a)", "Arc hyperbolic cotangent");
+}
+
+void Test::SimpleOperators()
+{
+ parseandparseagain("lim{a}", "Limit");
+ parseandparseagain("sum{a}", "Sum");
+ parseandparseagain("prod{a}", "Product");
+ parseandparseagain("coprod{a}", "Coproduct");
+ parseandparseagain("int from {r_0} to {r_t} a", "Upper and lower bounds shown with integral (from & to)");
+ ParseAndCheck("int csup {r_0} csub {r_t} a", "int csup { r rsub 0 } csub { r rsub t } a ", "Upper and lower bounds shown with integral (csub & csup)");
+ ParseAndCheck("sum csup { size 8 { x - 1 } } csub { size 8 a } b ", "sum csup { size 8 { x - 1 } } csub { size 8 a } b ", "Sum with sized upper and lower bounds");
+ parseandparseagain("int{a}", "Integral");
+ parseandparseagain("iint{a}", "Double integral");
+ parseandparseagain("iiint{a}", "Triple integral");
+ parseandparseagain("sum from{3}b", "Lower bound shown with summation symbol");
+ parseandparseagain("lint a", "Contour integral");
+ parseandparseagain("llint a", "Double curved integral");
+ parseandparseagain("lllint a", "Triple curved integral");
+ parseandparseagain("prod from {i=1} to {n} {(i+1)}", "Product with range");
+}
+
+void Test::SimpleAttributes()
+{
+ parseandparseagain("acute a", "Acute accent");
+ parseandparseagain("grave a", "Grave accent");
+ parseandparseagain("check a", "Reverse circumflex");
+ parseandparseagain("breve a", "Breve");
+ parseandparseagain("circle a", "Circle");
+ parseandparseagain("vec a", "Vector arrow");
+ parseandparseagain("tilde a", "Tilde");
+ parseandparseagain("hat a", "Circumflex");
+ parseandparseagain("bar a", "Line above");
+ parseandparseagain("dot a", "Dot");
+ parseandparseagain("widevec abc", "Wide vector arrow");
+ parseandparseagain("widetilde abc", "Wide tilde");
+ parseandparseagain("widehat abc", "Wide circumflex");
+ parseandparseagain("ddot a", "Double dot");
+ parseandparseagain("overline abc", "Line over");
+ parseandparseagain("underline abc", "Line under");
+ parseandparseagain("overstrike abc", "Line through");
+ parseandparseagain("dddot a", "Triple dot");
+ parseandparseagain("phantom a", "Transparent (useful to get a placeholder of a given size)");
+ parseandparseagain("bold a", "Bold font");
+ parseandparseagain("ital a", "Italic font");
+ parseandparseagain("nitalic a", "Roman (non-italic) font 1");
+ parseandparseagain("\"a\"", "Roman (non-italic) font 2");
+ parseandparseagain("size 16 qv", "Resize font");
+ parseandparseagain("font sans qv", "Sans serif font");
+ parseandparseagain("font serif qv", "Serif font");
+ parseandparseagain("font fixed qv", "Fixed font");
+ parseandparseagain("color cyan qv", "Cyan color");
+ parseandparseagain("color yellow qv", "Yellow color");
+ parseandparseagain("color white qv", "White color");
+ parseandparseagain("color green qv", "Green color");
+ parseandparseagain("color blue qv", "Blue color");
+ parseandparseagain("color red qv", "Red color");
+ parseandparseagain("color green X qv", "Green color changes back");
+ parseandparseagain("color green {X qv}", "Green color, more than one item");
+}
+
+void Test::SimpleMisc()
+{
+ parseandparseagain("infinity", "Infinity");
+ parseandparseagain("partial", "Partial");
+ parseandparseagain("nabla", "Nabla");
+ parseandparseagain("exists", "There exists");
+ parseandparseagain("forall", "For all");
+ parseandparseagain("hbar", "H bar");
+ parseandparseagain("lambdabar", "Lambda bar");
+ parseandparseagain("re", "Real part");
+ parseandparseagain("im", "Imaginary part");
+ parseandparseagain("wp", "Weierstrass p");
+ parseandparseagain("leftarrow", "Left arrow");
+ parseandparseagain("rightarrow", "Right arrow");
+ parseandparseagain("uparrow", "Up arrow");
+ parseandparseagain("downarrow", "Down arrow");
+ parseandparseagain("dotslow", "Dots at bottom");
+ parseandparseagain("dotsaxis", "Dots at middle");
+ parseandparseagain("dotsvert", "Dots vertical");
+ parseandparseagain("dotsup", "Dots diagonal upward");
+ parseandparseagain("dotsdown", "Dots diagonal downward");
+}
+
+void Test::SimpleBrackets()
+{
+ parseandparseagain("(a)", "Round Brackets");
+ parseandparseagain("[b]", "Square Brackets");
+ parseandparseagain("ldbracket c rdbracket", "Double Square Brackets");
+ parseandparseagain("lline a rline", "Single line or absolute");
+ parseandparseagain("abs a", "Single line or absolute 2");
+ parseandparseagain("ldline a rdline", "Double line");
+ parseandparseagain("lbrace w rbrace", "Braces");
+ parseandparseagain("left lbrace stack{0, n <> 0 # 1, n = 1} right none", "Single left brace");
+ parseandparseagain("langle d rangle", "Angle Brackets");
+ parseandparseagain("langle a mline b rangle", "Operator Brackets");
+ parseandparseagain("{a}", "Group brackets (used for program control)");
+ parseandparseagain("left ( stack{a # b # z} right )", "Round brackets scalable");
+ parseandparseagain("left [ stack{x # y} right ]", "Square brackets scalable");
+ parseandparseagain("left ldbracket c right rdbracket", "Double square brackets scalable");
+ parseandparseagain("left lline a right rline", "Line scalable");
+ parseandparseagain("left ldline d right rdline", "Double line scalable");
+ parseandparseagain("left lbrace e right rbrace", "Brace scalable");
+ parseandparseagain("left langle f right rangle", "Angle bracket scalable");
+ parseandparseagain("left langle g mline h right rangle", "Operator brackets scalable");
+ parseandparseagain("{a} overbrace b", "Over brace scalable");
+ parseandparseagain("{b} underbrace a", "Under brace scalable");
+}
+
+void Test::SimpleFormats()
+{
+ parseandparseagain("a lsup{b}", "Left superscript");
+ parseandparseagain("a csup{b}", "Center superscript");
+ parseandparseagain("a^{b}", "Right superscript");
+ parseandparseagain("a lsub{b}", "Left subscript");
+ parseandparseagain("a csub{b}", "Center subscript");
+ parseandparseagain("a_{b}", "Right subscript");
+ parseandparseagain("stack { Hello world # alignl (a) }", "Align character to left");
+ parseandparseagain("stack{Hello world # alignc(a)}", "Align character to center");
+ parseandparseagain("stack { Hello world # alignr(a)}", "Align character to right");
+ parseandparseagain("binom{a}{b}", "Vertical stack of 2");
+ parseandparseagain("stack{a # b # z}", "Vertical stack, more than 2");
+ parseandparseagain("matrix{a # b ## c # d}", "Matrix");
+ parseandparseagain("matrix{a # \"=\" # alignl{b} ## {} # \"=\" # alignl{c+1}}", "Equations aligned at '=' (using 'matrix') ");
+ parseandparseagain("stack{alignl{a} = b # alignl{phantom{a} = c+1}}", "Equations aligned at '=' (using 'phantom') ");
+ parseandparseagain("asldkfjo newline sadkfj", "New line");
+ parseandparseagain("stuff `stuff", "Small gap (grave)");
+ parseandparseagain("stuff~stuff", "Large gap (tilde)");
+}
+
+void Test::SimpleGreekChars()
+{
+ parseandparseagain("%ALPHA", "Capital alpha");
+ parseandparseagain("%BETA", "Capital beta");
+ parseandparseagain("%CHI", "Capital chi");
+ parseandparseagain("%DELTA", "Capital delta");
+ parseandparseagain("%EPSILON", "Capital epsilon");
+ parseandparseagain("%ETA", "Capital eta");
+ parseandparseagain("%GAMMA", "Capital gamma");
+ parseandparseagain("%IOTA", "Capital iota");
+ parseandparseagain("%LAMBDA", "Capital lambda");
+ parseandparseagain("%MU", "Capital mu");
+ parseandparseagain("%NU", "Capital nu");
+ parseandparseagain("%OMEGA", "Capital omega");
+ parseandparseagain("%OMICRON", "Capital omicron");
+ parseandparseagain("%PHI", "Capital phi");
+ parseandparseagain("%PI", "Capital pi");
+ parseandparseagain("%PSI", "Capital psi");
+ parseandparseagain("%RHO", "Capital rho");
+ parseandparseagain("%SIGMA", "Capital sigma");
+ parseandparseagain("%TAU", "Capital tau");
+ parseandparseagain("%THETA", "Capital theta");
+ parseandparseagain("%UPSILON", "Capital upsilon");
+ parseandparseagain("%XI", "Capital xi");
+ parseandparseagain("%ZETA", "Capital zeta");
+ parseandparseagain("%alpha", "lowercase alpha");
+ parseandparseagain("%beta", "lowercase beta");
+ parseandparseagain("%chi", "lowercase chi");
+ parseandparseagain("%delta", "lowercase delta");
+ parseandparseagain("%epsilon", "lowercase epsilon");
+ parseandparseagain("%eta", "lowercase eta");
+ parseandparseagain("%gamma", "lowercase gamma");
+ parseandparseagain("%iota", "lowercase iota");
+ parseandparseagain("%kappa", "lowercase kappa");
+ parseandparseagain("%lambda", "lowercase lambda");
+ parseandparseagain("%mu", "lowercase mu");
+ parseandparseagain("%nu", "lowercase nu");
+ parseandparseagain("%omega", "lowercase omega");
+ parseandparseagain("%omicron", "lowercase omicron");
+ parseandparseagain("%phi", "lowercase phi");
+ parseandparseagain("%pi", "lowercase pi");
+ parseandparseagain("%psi", "lowercase psi");
+ parseandparseagain("%rho", "lowercase rho");
+ parseandparseagain("%sigma", "lowercase sigma");
+ parseandparseagain("%tau", "lowercase tau");
+ parseandparseagain("%theta", "lowercase theta");
+ parseandparseagain("%upsilon", "lowercase upsilon");
+ parseandparseagain("%varepsilon", "Varepsilon");
+ parseandparseagain("%varphi", "Varphi");
+ parseandparseagain("%varpi", "Varpi");
+ parseandparseagain("%varrho", "Varrho");
+ parseandparseagain("%varsigma", "Varsigma");
+ parseandparseagain("%vartheta", "Vartheta");
+ parseandparseagain("%xi", "lowercase xi");
+ parseandparseagain("%zeta", "lowercase zeta");
+}
+
+void Test::SimpleSpecialChars()
+{
+ parseandparseagain("%and", "And");
+ parseandparseagain("%angle", "Angle");
+ parseandparseagain("%element", "Element");
+ parseandparseagain("%identical", "Identical");
+ parseandparseagain("%infinite", "Infinite");
+ parseandparseagain("%noelement", "No element");
+ parseandparseagain("%notequal", "Not equal");
+ parseandparseagain("%or", "Or");
+ parseandparseagain("%perthousand", "Per thousand");
+ parseandparseagain("%strictlygreaterthan", "Strictly greater than");
+ parseandparseagain("%strictlylessthan", "Strictly less than");
+ parseandparseagain("%tendto", "Tend to");
+}
+
+/* This test takes a formula command, parses it, converts the node to text,
+ * parses it again, converts it to text again, and compares the values.
+ * Doing this doesn't prove that it is correct, but it should prove that the
+ * meaning of the original command is not being changed.
+ */
+void Test::parseandparseagain(const char *formula, const char *test_name)
+{
+ String input, output1, output2;
+ SmNode *pNode1, *pNode2;
+
+ // parse 1
+ input.AppendAscii(formula);
+ pNode1 = SmParser().ParseExpression(input);
+ pNode1->Prepare(xDocShRef->GetFormat(), *xDocShRef);
+ SmNodeToTextVisitor(pNode1, output1);
+
+ // parse 2
+ pNode2 = SmParser().ParseExpression(output1);
+ pNode2->Prepare(xDocShRef->GetFormat(), *xDocShRef);
+ SmNodeToTextVisitor(pNode2, output2);
+
+ // compare
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(test_name,
+ output1,
+ output2);
+
+ delete pNode1;
+ delete pNode2;
+}
+
+void Test::ParseAndCheck(const char *formula, const char * expected, const char *test_name)
+{
+ String sInput, sOutput, sExpected;
+ SmNode *pNode;
+
+ // parse
+ sInput.AppendAscii(formula);
+ pNode = SmParser().ParseExpression(sInput);
+ pNode->Prepare(xDocShRef->GetFormat(), *xDocShRef);
+ SmNodeToTextVisitor(pNode, sOutput);
+
+ // compare
+ sExpected.AppendAscii(expected);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(test_name,
+ sExpected,
+ sOutput);
+
+ delete pNode;
+}
+
+void Test::testBinomInBinHor()
+{
+ String sInput, sExpected, sOutput;
+ SmNode* pTree;
+
+ // set up a binom (table) node
+ sInput.AppendAscii("binom a b + c");
+ pTree = SmParser().Parse(sInput);
+ pTree->Prepare(xDocShRef->GetFormat(), *xDocShRef);
+
+ SmCursor aCursor(pTree, xDocShRef);
+ TestOutputDevice aOutputDevice;
+
+ // move forward (more than) enough places to be at the end
+ int i;
+ for (i = 0; i < 8; ++i)
+ aCursor.Move(&aOutputDevice, MoveRight);
+
+ // tack +d on the end, which will put the binom into an SmBinHorNode
+ aCursor.InsertElement(PlusElement);
+ aCursor.InsertText('d');
+
+ sExpected.AppendAscii(" { { binom a b + c } + d } ");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Binom Node in BinHor Node", sExpected, xDocShRef->GetText());
+
+ delete pTree;
+}
+
+void Test::testBinVerInUnary()
+{
+ String sInput, sExpected, sOutput;
+ SmNode* pTree;
+
+ // set up a unary operator with operand
+ sInput.AppendAscii("- 1");
+ pTree = SmParser().Parse(sInput);
+ pTree->Prepare(xDocShRef->GetFormat(), *xDocShRef);
+
+ SmCursor aCursor(pTree, xDocShRef);
+ TestOutputDevice aOutputDevice;
+
+ // move forward (more than) enough places to be at the end
+ int i;
+ for (i = 0; i < 3; ++i)
+ aCursor.Move(&aOutputDevice, MoveRight);
+
+ // select the operand
+ aCursor.Move(&aOutputDevice, MoveLeft, false);
+ // set up a fraction
+ aCursor.InsertFraction();
+ aCursor.Move(&aOutputDevice, MoveDown);
+ aCursor.InsertText('2');
+
+ sExpected.AppendAscii(" - { 1 over 2 } ");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Binary Vertical in Unary Operator", sExpected, xDocShRef->GetText());
+
+ delete pTree;
+}
+
+void Test::testBinHorInSubSup()
+{
+ String sInput, sExpected, sOutput;
+ SmNode* pTree;
+
+ // set up a blank formula
+ sInput.AppendAscii("");
+ pTree = SmParser().Parse(sInput);
+ pTree->Prepare(xDocShRef->GetFormat(), *xDocShRef);
+
+ SmCursor aCursor(pTree, xDocShRef);
+ TestOutputDevice aOutputDevice;
+
+ // Insert an RSup expression with a BinHor for the exponent
+ aCursor.InsertText('a');
+ aCursor.InsertSubSup(RSUP);
+ aCursor.InsertText('b');
+ aCursor.InsertElement(PlusElement);
+ aCursor.InsertText('c');
+
+ // Move to the end and add d to the expression
+ aCursor.Move(&aOutputDevice, MoveRight);
+ aCursor.InsertElement(PlusElement);
+ aCursor.InsertText('d');
+
+ sExpected.AppendAscii(" { a rsup { b + c } + d } ");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("BinHor in SubSup", sExpected, xDocShRef->GetText());
+
+ delete pTree;
+}
+
+void Test::testUnaryInMixedNumberAsNumerator()
+{
+ String sInput, sExpected, sOutput;
+ SmNode* pTree;
+
+ // set up a unary operator
+ sInput.AppendAscii("- 1");
+ pTree = SmParser().Parse(sInput);
+ pTree->Prepare(xDocShRef->GetFormat(), *xDocShRef);
+
+ SmCursor aCursor(pTree, xDocShRef);
+ TestOutputDevice aOutputDevice;
+
+ // move forward (more than) enough places to be at the end
+ int i;
+ for (i = 0; i < 3; ++i)
+ aCursor.Move(&aOutputDevice, MoveRight);
+
+ // Select the whole Unary Horizontal Node
+ aCursor.Move(&aOutputDevice, MoveLeft, false);
+ aCursor.Move(&aOutputDevice, MoveLeft, false);
+
+ // Set up a fraction
+ aCursor.InsertFraction();
+ aCursor.Move(&aOutputDevice, MoveDown);
+ aCursor.InsertText('2');
+
+ // Move left and turn this into a mixed number
+ // (bad form, but this could happen right?)
+ aCursor.Move(&aOutputDevice, MoveLeft);
+ aCursor.Move(&aOutputDevice, MoveLeft);
+ aCursor.InsertText('2');
+
+ // move forward (more than) enough places to be at the end
+ for (i = 0; i < 8; ++i)
+ aCursor.Move(&aOutputDevice, MoveRight);
+
+ // add 4 to the end
+ aCursor.InsertElement(PlusElement);
+ aCursor.InsertText('4');
+
+ sExpected.AppendAscii(" { 2 { - 1 over 2 } + 4 } ");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Unary in mixed number as Numerator", sExpected, xDocShRef->GetText());
+
+ delete pTree;
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/qa/cppunit/test_starmath.cxx b/starmath/qa/cppunit/test_starmath.cxx
new file mode 100644
index 000000000000..310f0140d7a3
--- /dev/null
+++ b/starmath/qa/cppunit/test_starmath.cxx
@@ -0,0 +1,457 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Caolán McNamara <caolanm@redhat.com> (Red Hat, Inc.)
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Caolán McNamara <caolanm@redhat.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+#ifdef WNT
+#include <windows.h>
+#endif
+
+#include <cppunit/TestSuite.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <sal/config.h>
+
+#include <cppuhelper/bootstrap.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+
+#include <vcl/svapp.hxx>
+#include <smdll.hxx>
+#include <document.hxx>
+#include <view.hxx>
+
+#include <sfx2/sfxmodelfactory.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include <svl/stritem.hxx>
+
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+
+#include <svx/zoomitem.hxx>
+
+SO2_DECL_REF(SmDocShell)
+SO2_IMPL_REF(SmDocShell)
+
+using namespace ::com::sun::star;
+
+namespace {
+
+class Test : public CppUnit::TestFixture {
+public:
+ Test();
+ ~Test();
+
+ // init
+ virtual void setUp();
+ virtual void tearDown();
+
+ // tests
+ void tmEditUndoRedo();
+ void tmEditAllClipboard();
+ void tmEditMarker();
+ void tmEditFailure();
+
+ void tViewZoom();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(tmEditUndoRedo);
+ CPPUNIT_TEST(tmEditAllClipboard);
+ CPPUNIT_TEST(tmEditMarker);
+ CPPUNIT_TEST(tmEditFailure);
+ CPPUNIT_TEST(tViewZoom);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ uno::Reference<uno::XComponentContext> m_xContext;
+ uno::Reference<lang::XMultiComponentFactory> m_xFactory;
+
+ SfxBindings m_aBindings;
+ SfxDispatcher *m_pDispatcher;
+ SmCmdBoxWindow *m_pSmCmdBoxWindow;
+ SmEditWindow *m_pEditWindow;
+ SmDocShellRef m_xDocShRef;
+ SmViewShell *m_pViewShell;
+};
+
+Test::Test()
+ : m_pDispatcher(NULL)
+ , m_pSmCmdBoxWindow(NULL)
+ , m_pEditWindow(NULL)
+ , m_pViewShell(NULL)
+{
+ m_xContext = cppu::defaultBootstrap_InitialComponentContext();
+ m_xFactory = m_xContext->getServiceManager();
+
+ uno::Reference<lang::XMultiServiceFactory> xSM(m_xFactory, uno::UNO_QUERY_THROW);
+
+ //Without this we're crashing because callees are using
+ //getProcessServiceFactory. In general those should be removed in favour
+ //of retaining references to the root ServiceFactory as its passed around
+ comphelper::setProcessServiceFactory(xSM);
+
+ InitVCL(xSM);
+
+ SmDLL::Init();
+}
+
+void Test::setUp()
+{
+ m_xDocShRef = new SmDocShell(
+ SFXMODEL_STANDARD |
+ SFXMODEL_DISABLE_EMBEDDED_SCRIPTS |
+ SFXMODEL_DISABLE_DOCUMENT_RECOVERY);
+ m_xDocShRef->DoInitNew(0);
+
+ SfxViewFrame *pViewFrame = SfxViewFrame::LoadHiddenDocument(*m_xDocShRef, 0);
+
+ CPPUNIT_ASSERT_MESSAGE("Should have a SfxViewFrame", pViewFrame);
+
+ m_pDispatcher = new SfxDispatcher(pViewFrame);
+ m_aBindings.SetDispatcher(m_pDispatcher);
+ m_pSmCmdBoxWindow = new SmCmdBoxWindow(&m_aBindings, NULL, NULL);
+ m_pEditWindow = new SmEditWindow(*m_pSmCmdBoxWindow);
+ m_pViewShell = m_pEditWindow->GetView();
+ CPPUNIT_ASSERT_MESSAGE("Should have a SmViewShell", m_pViewShell);
+}
+
+void Test::tearDown()
+{
+ delete m_pEditWindow;
+ delete m_pSmCmdBoxWindow;
+ delete m_pDispatcher;
+ m_xDocShRef.Clear();
+}
+
+Test::~Test()
+{
+}
+
+void Test::tmEditMarker()
+{
+ {
+ rtl::OUString sMarkedText(RTL_CONSTASCII_USTRINGPARAM("<?> under <?> under <?>"));
+ m_pEditWindow->SetText(sMarkedText);
+ m_pEditWindow->Flush();
+ rtl::OUString sFinalText = m_pEditWindow->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Should be equal text", sFinalText == sMarkedText);
+ }
+
+ {
+ rtl::OUString sTargetText(RTL_CONSTASCII_USTRINGPARAM("a under b under c"));
+
+ m_pEditWindow->SelNextMark();
+ m_pEditWindow->Cut();
+ m_pEditWindow->InsertText(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("a")));
+
+ m_pEditWindow->SelNextMark();
+ m_pEditWindow->SelNextMark();
+ m_pEditWindow->Cut();
+ m_pEditWindow->InsertText(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("c")));
+
+ m_pEditWindow->SelPrevMark();
+ m_pEditWindow->Cut();
+ m_pEditWindow->InsertText(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("b")));
+
+ m_pEditWindow->Flush();
+ rtl::OUString sFinalText = m_pEditWindow->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Should be a under b under c", sFinalText == sTargetText);
+ }
+
+ {
+ m_pEditWindow->SetText(rtl::OUString());
+ m_pEditWindow->Flush();
+ }
+}
+
+void Test::tmEditAllClipboard()
+{
+ rtl::OUString sOriginalText(RTL_CONSTASCII_USTRINGPARAM("a over b"));
+
+ {
+ m_pEditWindow->SetText(sOriginalText);
+ m_pEditWindow->Flush();
+ rtl::OUString sFinalText = m_pEditWindow->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Should be equal text", sFinalText == sOriginalText);
+ }
+
+ {
+ m_pEditWindow->SelectAll();
+ m_pEditWindow->Cut();
+ m_pEditWindow->Flush();
+ rtl::OUString sFinalText = m_pEditWindow->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Should be empty", !sFinalText.getLength());
+ }
+
+ {
+ m_pEditWindow->Paste();
+ m_pEditWindow->Flush();
+ rtl::OUString sFinalText = m_pEditWindow->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Should be equal text", sFinalText == sOriginalText);
+ }
+
+ {
+ m_pEditWindow->SelectAll();
+ m_pEditWindow->Copy();
+ }
+
+ {
+ rtl::OUString sExpectedText(RTL_CONSTASCII_USTRINGPARAM("a over ba over b"));
+
+ m_pEditWindow->Paste();
+ m_pEditWindow->Paste();
+ m_pEditWindow->Flush();
+ rtl::OUString sFinalText = m_pEditWindow->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Should be equal text", sFinalText == sExpectedText);
+ }
+
+ {
+ m_pEditWindow->SetText(rtl::OUString());
+ m_pEditWindow->Flush();
+ }
+}
+
+void Test::tmEditFailure()
+{
+ m_xDocShRef->SetText(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("color a b over {a/}")));
+
+ const SmErrorDesc *pErrorDesc = m_xDocShRef->GetParser().NextError();
+
+ CPPUNIT_ASSERT_MESSAGE("Should be a PE_COLOR_EXPECTED",
+ pErrorDesc && pErrorDesc->Type == PE_COLOR_EXPECTED);
+
+ pErrorDesc = m_xDocShRef->GetParser().PrevError();
+
+ CPPUNIT_ASSERT_MESSAGE("Should be a PE_UNEXPECTED_CHAR",
+ pErrorDesc && pErrorDesc->Type == PE_UNEXPECTED_CHAR);
+
+ pErrorDesc = m_xDocShRef->GetParser().PrevError();
+
+ CPPUNIT_ASSERT_MESSAGE("Should be a PE_RGROUP_EXPECTED",
+ pErrorDesc && pErrorDesc->Type == PE_RGROUP_EXPECTED);
+
+ const SmErrorDesc *pLastErrorDesc = m_xDocShRef->GetParser().PrevError();
+
+ CPPUNIT_ASSERT_MESSAGE("Should be three syntax errors",
+ pLastErrorDesc && pLastErrorDesc == pErrorDesc);
+}
+
+void Test::tmEditUndoRedo()
+{
+ EditEngine &rEditEngine = m_xDocShRef->GetEditEngine();
+
+ rtl::OUString sStringOne(RTL_CONSTASCII_USTRINGPARAM("a under b"));
+ {
+ rEditEngine.SetText(0, sStringOne);
+ m_xDocShRef->UpdateText();
+ rtl::OUString sFinalText = m_xDocShRef->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Strings must match", sStringOne == sFinalText);
+ }
+
+ rtl::OUString sStringTwo(RTL_CONSTASCII_USTRINGPARAM("a over b"));
+ {
+ rEditEngine.SetText(0, sStringTwo);
+ m_xDocShRef->UpdateText();
+ rtl::OUString sFinalText = m_xDocShRef->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Strings must match", sStringTwo == sFinalText);
+ }
+
+ SfxRequest aUndo(SID_UNDO, SFX_CALLMODE_SYNCHRON, m_xDocShRef->GetPool());
+
+ {
+ m_xDocShRef->Execute(aUndo);
+ rtl::OUString sFoo = rEditEngine.GetText();
+ m_xDocShRef->UpdateText();
+ rtl::OUString sFinalText = m_xDocShRef->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Strings much match", sStringOne == sFinalText);
+ }
+
+ {
+ m_xDocShRef->Execute(aUndo);
+ rtl::OUString sFoo = rEditEngine.GetText();
+ m_xDocShRef->UpdateText();
+ rtl::OUString sFinalText = m_xDocShRef->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Must now be empty", !sFinalText.getLength());
+ }
+
+ SfxRequest aRedo(SID_REDO, SFX_CALLMODE_SYNCHRON, m_xDocShRef->GetPool());
+ {
+ m_xDocShRef->Execute(aRedo);
+ rtl::OUString sFoo = rEditEngine.GetText();
+ m_xDocShRef->UpdateText();
+ rtl::OUString sFinalText = m_xDocShRef->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Strings much match", sStringOne == sFinalText);
+ }
+
+ {
+ rEditEngine.SetText(0, rtl::OUString());
+ m_xDocShRef->UpdateText();
+ rEditEngine.ClearModifyFlag();
+ rtl::OUString sFinalText = m_xDocShRef->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Must be empty", !sFinalText.getLength());
+ }
+
+}
+
+void Test::tViewZoom()
+{
+ sal_uInt16 nOrigZoom, nNextZoom, nFinalZoom;
+
+ EditEngine &rEditEngine = m_xDocShRef->GetEditEngine();
+
+ rtl::OUString sStringOne(RTL_CONSTASCII_USTRINGPARAM("a under b"));
+ {
+ rEditEngine.SetText(0, sStringOne);
+ m_xDocShRef->UpdateText();
+ rtl::OUString sFinalText = m_xDocShRef->GetText();
+ CPPUNIT_ASSERT_MESSAGE("Strings must match", sStringOne == sFinalText);
+ }
+
+ SmGraphicWindow &rGraphicWindow = m_pViewShell->GetGraphicWindow();
+ rGraphicWindow.SetSizePixel(Size(1024, 800));
+ nOrigZoom = rGraphicWindow.GetZoom();
+
+ {
+ SfxRequest aZoomIn(SID_ZOOMIN, SFX_CALLMODE_SYNCHRON, m_pViewShell->GetPool());
+ m_pViewShell->Execute(aZoomIn);
+ nNextZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be bigger", nNextZoom > nOrigZoom);
+ }
+
+ {
+ SfxRequest aZoomOut(SID_ZOOMOUT, SFX_CALLMODE_SYNCHRON, m_pViewShell->GetPool());
+ m_pViewShell->Execute(aZoomOut);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be equal", nFinalZoom == nOrigZoom);
+ }
+
+ sal_uInt16 nOptimalZoom=0;
+
+ {
+ SfxRequest aZoom(SID_FITINWINDOW, SFX_CALLMODE_SYNCHRON, m_pViewShell->GetPool());
+ m_pViewShell->Execute(aZoom);
+ nOptimalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be about 800%", nOptimalZoom > nOrigZoom);
+ }
+
+ {
+ SfxItemSet aSet(m_xDocShRef->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
+ aSet.Put(SvxZoomItem(SVX_ZOOM_OPTIMAL, 0));
+ SfxRequest aZoom(SID_ATTR_ZOOM, SFX_CALLMODE_SYNCHRON, aSet);
+ m_pViewShell->Execute(aZoom);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be optimal zoom", nFinalZoom == nOptimalZoom);
+ }
+
+//To-Do: investigate GetPrinter logic of SVX_ZOOM_PAGEWIDTH/SVX_ZOOM_WHOLEPAGE to ensure
+//consistent value regardless of
+#if 0
+ {
+ SfxRequest aZoomOut(SID_ZOOMOUT, SFX_CALLMODE_SYNCHRON, m_pViewShell->GetPool());
+ m_pViewShell->Execute(aZoomOut);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should not be optimal zoom", nFinalZoom != nOptimalZoom);
+
+ SfxItemSet aSet(m_xDocShRef->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
+ aSet.Put(SvxZoomItem(SVX_ZOOM_PAGEWIDTH, 0));
+ SfxRequest aZoom(SID_ATTR_ZOOM, SFX_CALLMODE_SYNCHRON, aSet);
+ m_pViewShell->Execute(aZoom);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be same as optimal zoom", nFinalZoom == nOptimalZoom);
+ }
+
+ {
+ SfxRequest aZoomOut(SID_ZOOMOUT, SFX_CALLMODE_SYNCHRON, m_pViewShell->GetPool());
+ m_pViewShell->Execute(aZoomOut);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should not be optimal zoom", nFinalZoom != nOptimalZoom);
+
+ SfxItemSet aSet(m_xDocShRef->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
+ aSet.Put(SvxZoomItem(SVX_ZOOM_WHOLEPAGE, 0));
+ SfxRequest aZoom(SID_ATTR_ZOOM, SFX_CALLMODE_SYNCHRON, aSet);
+ m_pViewShell->Execute(aZoom);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be same as optimal zoom", nFinalZoom == nOptimalZoom);
+ }
+#endif
+
+ {
+ SfxRequest aZoomOut(SID_ZOOMOUT, SFX_CALLMODE_SYNCHRON, m_pViewShell->GetPool());
+ m_pViewShell->Execute(aZoomOut);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should not be optimal zoom", nFinalZoom != nOptimalZoom);
+
+ SfxItemSet aSet(m_xDocShRef->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
+ aSet.Put(SvxZoomItem(SVX_ZOOM_PERCENT, 50));
+ SfxRequest aZoom(SID_ATTR_ZOOM, SFX_CALLMODE_SYNCHRON, aSet);
+ m_pViewShell->Execute(aZoom);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be 50%", nFinalZoom == 50);
+ }
+
+ {
+ SfxItemSet aSet(m_xDocShRef->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
+ aSet.Put(SvxZoomItem(SVX_ZOOM_PERCENT, 5));
+ SfxRequest aZoom(SID_ATTR_ZOOM, SFX_CALLMODE_SYNCHRON, aSet);
+ m_pViewShell->Execute(aZoom);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be Clipped to 25%", nFinalZoom == 25);
+ }
+
+ {
+ SfxItemSet aSet(m_xDocShRef->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
+ aSet.Put(SvxZoomItem(SVX_ZOOM_PERCENT, 1000));
+ SfxRequest aZoom(SID_ATTR_ZOOM, SFX_CALLMODE_SYNCHRON, aSet);
+ m_pViewShell->Execute(aZoom);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be Clipped to 800%", nFinalZoom == 800);
+ }
+
+ {
+ SfxRequest aZoom(SID_ADJUST, SFX_CALLMODE_SYNCHRON, m_pViewShell->GetPool());
+ m_pViewShell->Execute(aZoom);
+ nFinalZoom = rGraphicWindow.GetZoom();
+ CPPUNIT_ASSERT_MESSAGE("Should be the same as optimal", nOptimalZoom == nFinalZoom);
+ }
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/qa/cppunit/version.map b/starmath/qa/cppunit/version.map
new file mode 100644
index 000000000000..3308588ef6f8
--- /dev/null
+++ b/starmath/qa/cppunit/version.map
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ cppunitTestPlugIn;
+
+ local:
+ *;
+};
diff --git a/starmath/qa/unoapi/knownissues.xcl b/starmath/qa/unoapi/knownissues.xcl
new file mode 100644
index 000000000000..f82014a51a33
--- /dev/null
+++ b/starmath/qa/unoapi/knownissues.xcl
@@ -0,0 +1,21 @@
+### i23394 ###
+sm.XMLImporter::com::sun::star::xml::sax::XDocumentHandler
+sm.XMLMetaImporter::com::sun::star::xml::sax::XDocumentHandler
+
+### i88645 ###
+sm.XMLExporter::com::sun::star::document::XFilter
+
+### i94322 ###
+sm.SmEditAccessible::com::sun::star::accessibility::XAccessibleEventBroadcaster
+
+### i94320 ###
+sm.SmGraphicAccessible::com::sun::star::accessibility::XAccessibleEventBroadcaster
+
+### i94275 ###
+sm.SmGraphicAccessible::com::sun::star::accessibility::XAccessibleText
+
+### i111220 ###
+sm.XMLMetaExporter::com::sun::star::document::XFilter
+
+### i112743 ###
+sm.XMLSettingsExporter::com::sun::star::document::XFilter
diff --git a/starmath/qa/unoapi/sm.sce b/starmath/qa/unoapi/sm.sce
new file mode 100644
index 000000000000..c68d48d74d44
--- /dev/null
+++ b/starmath/qa/unoapi/sm.sce
@@ -0,0 +1,9 @@
+-o sm.SmEditAccessible
+-o sm.SmGraphicAccessible
+-o sm.SmModel
+-o sm.XMLExporter
+-o sm.XMLImporter
+-o sm.XMLMetaExporter
+-o sm.XMLMetaImporter
+-o sm.XMLSettingsExporter
+-o sm.XMLSettingsImporter
diff --git a/starmath/sdi/makefile.mk b/starmath/sdi/makefile.mk
new file mode 100644
index 000000000000..a2d965bc2275
--- /dev/null
+++ b/starmath/sdi/makefile.mk
@@ -0,0 +1,58 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=starmath
+TARGET=smslots
+SDI1EXPORT=smath
+SVSDIINC=$(PRJ)$/inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
+# --- Files --------------------------------------------------------
+
+
+SDI1NAME=$(TARGET)
+
+SVSDI1DEPEND= \
+ $(SOLARINCXDIR)$/sfx2/sfx.sdi \
+ $(SOLARINCXDIR)$/sfx2/sfxitems.sdi \
+ $(SOLARINCXDIR)$/svx/svx.sdi \
+ $(SOLARINCXDIR)$/svx/svxitems.sdi \
+ $(SOLARINCXDIR)$/svx/xoitems.sdi \
+ smath.sdi \
+ smslots.sdi \
+ $(SVSDIINC)$/starmath.hrc
+
+# --- Targets -------------------------------------------------------
+.ENDIF
+
+.INCLUDE : target.mk
+
diff --git a/starmath/sdi/smath.sdi b/starmath/sdi/smath.sdi
new file mode 100755
index 000000000000..8779706b08e2
--- /dev/null
+++ b/starmath/sdi/smath.sdi
@@ -0,0 +1,964 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+SfxVoidItem Adjust SID_ADJUST
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem ChangeAlignment SID_ALIGN
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = TRUE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_FORMAT;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem ChangeDistance SID_DISTANCE
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = TRUE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_FORMAT;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem ChangeFont SID_FONT
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = TRUE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_FORMAT;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem ChangeFontSize SID_FONTSIZE
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = TRUE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_FORMAT;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem CommandWindow SID_CMDBOXWINDOW
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem Preferences SID_PREFERENCES
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = TRUE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_OPTIONS;
+]
+
+//--------------------------------------------------------------------------
+SfxStringItem ConfigName SID_TEXT
+
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ Readonly = FALSE,
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem CopyObject SID_COPYOBJECT
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_EDIT;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem Draw SID_DRAW
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem FitInWindow SID_FITINWINDOW
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxBoolItem FormelCursor SID_FORMULACURSOR
+()
+[
+ /* flags: */
+ AutoUpdate = TRUE,
+ Cachable = Cachable,
+ FastCall = TRUE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = TRUE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_MATH;
+]
+
+//--------------------------------------------------------------------------
+SfxInt16Item Graphic SID_GAPHIC_SM
+
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ Readonly = FALSE,
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_MATH;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem InsertCommand SID_INSERTCOMMAND
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Asynchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_INSERT;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem InsertConfigName SID_INSERTSYMBOL
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Asynchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_INSERT;
+]
+
+//--------------------------------------------------------------------------
+SfxBoolItem ImportFormula SID_IMPORT_FORMULA
+(SfxStringItem Name SID_IMPORT_FORMULA,SfxStringItem Filter FN_PARAM_1)
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = TRUE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Asynchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_INSERT;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem LoadSymbols SID_LOADSYMBOLS
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Asynchron;
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_OPTIONS;
+]
+
+//--------------------------------------------------------------------------
+SfxStringItem ModifyStatus SID_MODIFYSTATUS
+
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ Readonly = FALSE,
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = TRUE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem NextError SID_NEXTERR
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_NAVIGATOR;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem NextMark SID_NEXTMARK
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_NAVIGATOR;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem PasteObject SID_PASTEOBJECT
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_EDIT;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem PrevError SID_PREVERR
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_NAVIGATOR;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem PrevMark SID_PREVMARK
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_NAVIGATOR;
+]
+
+//--------------------------------------------------------------------------
+SfxBoolItem RedrawAutomatic SID_AUTO_REDRAW
+
+[
+ /* flags: */
+ AutoUpdate = TRUE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ Readonly = FALSE,
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem SaveSymbols SID_SAVESYMBOLS
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_OPTIONS;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem SetPaperSize SID_GETEDITTEXT
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_MATH;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem SymbolCatalogue SID_SYMBOLS_CATALOGUE
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = TRUE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_OPTIONS;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem Symbols SID_SYMBOLS
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = TRUE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_OPTIONS;
+]
+
+//--------------------------------------------------------------------------
+SfxBoolItem Textmode SID_TEXTMODE
+
+[
+ /* flags: */
+ AutoUpdate = TRUE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ Readonly = FALSE,
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxStringItem TextStatus SID_TEXTSTATUS
+
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ Readonly = FALSE,
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = TRUE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem ToolBowWindow SID_TOOLBOXWINDOW
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxBoolItem ToolBox SID_TOOLBOX
+
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ Readonly = FALSE,
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem View100 SID_VIEW100
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem View200 SID_VIEW200
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem View50 SID_VIEW050
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem ZoomIn SID_ZOOMIN
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
+//--------------------------------------------------------------------------
+SfxVoidItem ZoomOut SID_ZOOMOUT
+()
+[
+ /* flags: */
+ AutoUpdate = FALSE,
+ Cachable = Cachable,
+ FastCall = FALSE,
+ HasCoreId = FALSE,
+ HasDialog = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Synchron;
+
+ /* config: */
+ AccelConfig = TRUE,
+ MenuConfig = TRUE,
+ StatusBarConfig = FALSE,
+ ToolBoxConfig = TRUE,
+ GroupId = GID_VIEW;
+]
+
diff --git a/starmath/sdi/smitems.sdi b/starmath/sdi/smitems.sdi
new file mode 100644
index 000000000000..019d2c5f5312
--- /dev/null
+++ b/starmath/sdi/smitems.sdi
@@ -0,0 +1,595 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+//-------------------------------------------------------------------------
+
+enum SvxAdjust
+{
+ SVX_ADJUST_LEFT,
+ SVX_ADJUST_RIGHT,
+ SVX_ADJUST_BLOCK,
+ SVX_ADJUST_CENTER,
+ SVX_ADJUST_BLOCKLINE,
+ SVX_ADJUST_END
+};
+item SvxAdjust SvxAdjustItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxCaseMap
+{
+ SVX_CASEMAP_NOT_MAPPED,
+ SVX_CASEMAP_VERSALIEN,
+ SVX_CASEMAP_GEMEINE,
+ SVX_CASEMAP_TITEL,
+ SVX_CASEMAP_KAPITAELCHEN,
+ SVX_CASEMAP_END
+};
+item SvxCaseMap SvxCaseMapItem;
+
+//-------------------------------------------------------------------------
+
+enum CharSet
+{
+ CHARSET_DONTKNOW,
+ CHARSET_ANSI,
+ CHARSET_MAC,
+ CHARSET_IBMPC_437,
+ CHARSET_IBMPC_850,
+ CHARSET_IBMPC_860,
+ CHARSET_IBMPC_861,
+ CHARSET_IBMPC_863,
+ CHARSET_IBMPC_865,
+ CHARSET_SYSTEM,
+ CHARSET_SYMBOL
+};
+item CharSet CharSetItem;
+
+//-------------------------------------------------------------------------
+
+enum FontFamily
+{
+ FAMILY_DONTKNOW,
+ FAMILY_DECORATIVE,
+ FAMILY_MODERN,
+ FAMILY_ROMAN,
+ FAMILY_SCRIPT,
+ FAMILY_SWISS,
+ FAMILY_SYSTEM
+};
+item FontFamily FontFamilyItem;
+
+//-------------------------------------------------------------------------
+
+enum FontPitch
+{
+ PITCH_DONTKNOW,
+ PITCH_FIXED,
+ PITCH_VARIABLE
+};
+item FontPitch FontPitchItem;
+
+//-------------------------------------------------------------------------
+
+enum FontAlign
+{
+ ALIGN_TOP,
+ ALIGN_BASELINE,
+ ALIGN_BOTTOM
+};
+item FontAlign FontAlignItem;
+
+//-------------------------------------------------------------------------
+
+enum FontWeight
+{
+ WEIGHT_DONTKNOW,
+ WEIGHT_THIN,
+ WEIGHT_ULTRALIGHT,
+ WEIGHT_LIGHT,
+ WEIGHT_SEMILIGHT,
+ WEIGHT_NORMAL,
+ WEIGHT_MEDIUM,
+ WEIGHT_SEMIBOLD,
+ WEIGHT_BOLD,
+ WEIGHT_ULTRABOLD,
+ WEIGHT_BLACK
+};
+item FontWeight FontWeightItem;
+
+//-------------------------------------------------------------------------
+
+enum FontUnderline
+{
+ UNDERLINE_NONE,
+ UNDERLINE_SINGLE,
+ UNDERLINE_DOUBLE,
+ UNDERLINE_DOTTED
+};
+item FontUnderline FontUnderlineItem;
+
+//-------------------------------------------------------------------------
+
+enum FontStrikeout
+{
+ STRIKEOUT_NONE,
+ STRIKEOUT_SINGLE,
+ STRIKEOUT_DOUBLE
+};
+item FontStrikeout FontStrikeoutItem;
+
+//-------------------------------------------------------------------------
+
+enum FontItalic
+{
+ ITALIC_NONE,
+ ITALIC_OBLIQUE,
+ ITALIC_NORMAL
+};
+item FontItalic FontItalicItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxDbType
+{
+ DBTYPE_STARBASE,
+ DBTYPE_ODBC,
+ DBTYPE_WATCOM
+};
+item SvxDbType SvxDbTypeItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxLineSpace
+{
+ SVX_LINE_SPACE_AUTO,
+ SVX_LINE_SPACE_MAX,
+ SVX_LINE_SPACE_MIN,
+ SVX_LINE_SPACE_END
+};
+item SvxLineSpace SvxLineSpaceItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxInterLineSpace
+{
+ SVX_INTER_LINE_SPACE_OFF,
+ SVX_INTER_LINE_SPACE_PROP,
+ SVX_INTER_LINE_SPACE_FIX,
+ SVX_INTER_LINE_SPACE_END
+};
+item SvxInterLineSpace SvxInterLineSpaceItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxBreak
+{
+ SVX_BREAK_NONE,
+ SVX_BREAK_COLUMN_BEFORE,
+ SVX_BREAK_COLUMN_AFTER,
+ SVX_BREAK_COLUMN_BOTH,
+ SVX_BREAK_PAGE_BEFORE,
+ SVX_BREAK_PAGE_AFTER,
+ SVX_BREAK_PAGE_BOTH,
+ SVX_BREAK_END
+};
+item SvxBreak SvxBreakItem;
+
+//-------------------------------------------------------------------------
+
+enum BrushStyle
+{
+ BRUSH_NULL,
+ BRUSH_SOLID,
+ BRUSH_HORZ,
+ BRUSH_VERT,
+ BRUSH_CROSS,
+ BRUSH_DIAGCROSS,
+ BRUSH_UPDIAG,
+ BRUSH_DOWNDIAG,
+ BRUSH_25,
+ BRUSH_50,
+ BRUSH_75,
+ BRUSH_BITMAP
+};
+item BrushStyle BrushStyleItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxNumType
+{
+ SVX_CHARS_UPPER_LETTER,
+ SVX_CHARS_LOWER_LETTER,
+ SVX_ROMAN_UPPER,
+ SVX_ROMAN_LOWER,
+ SVX_ARABIC,
+ SVX_NUMBER_NONE,
+ SVX_CHAR_SPECIAL,
+ SVX_PAGEDESC
+};
+item SvxNumType SvxNumTypeItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxShadowLocation
+{
+ SVX_SHADOW_NONE,
+ SVX_SHADOW_TOPLEFT,
+ SVX_SHADOW_TOPRIGHT,
+ SVX_SHADOW_BOTTOMLEFT,
+ SVX_SHADOW_BOTTOMRIGHT,
+ SVX_SHADOW_END
+};
+item SvxShadowLocation SvxShadowLocationItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxBrush
+{
+ BrushStyle Style MID_BRUSHSTYLE;
+ BOOL Transparent MID_TRANSPARENT;
+ UINT32 BackColor MID_BG_COLOR;
+ UINT32 FillColor MID_FG_COLOR;
+};
+item SvxBrush SvxBrushItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxCharSetColor
+{
+ CharSet CharSet MID_CHARSET;
+ UINT32 Color MID_FG_COLOR;
+};
+item SvxCharSetColor SvxCharSetColorItem;
+
+//-------------------------------------------------------------------------
+
+item BOOL SvxAutoKernItem;
+item UINT32 SvxColorItem;
+item BOOL SvxContourItem;
+item FontStrikeout SvxCrossedOutItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxEscapement
+{
+ INT16 Esc MID_ESCAPEMENT;
+ BYTE Prop MID_PROPORTIONAL;
+};
+item SvxEscapement SvxEscapementItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxFmtBreak
+{
+ BOOL Auto MID_AUTOBREAK;
+ UINT16 Break MID_BREAKxxx;
+}
+item SvxFmtBreak SvxFmtBreakItem;
+
+//-------------------------------------------------------------------------
+
+item BOOL SvxFmtKeepItem;
+item BOOL SvxFmtSplitItem;
+
+struct SvxFontHeight
+{
+ UINT32 Height MID_HEIGHT;
+ BYTE Prop MID_PROPORTIONAL;
+};
+item SvxFontHeight SvxFontHeightItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxFont
+{
+ String StyleName MID_FONTSTYLE;
+ FontPitch Pitch MID_FONTPICTH;
+ CharSet CharSet MID_CHARSET;
+ FontFamily Family MID_FONTFAMILY;
+ String FamilyName MID_FONTFAMILYNAME;
+};
+item SvxFont SvxFontItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxHyphenZone
+{
+ BOOL Hyphen MID_HYPHEN;
+ BOOL PageEnd MID_PAGEEND;
+ BYTE MinLead MID_MINLEAD;
+ BYTE MinTrail MID_MINTRAIL;
+ BYTE MaxHyphens MID_MAXHYPHENS;
+};
+item SvxHyphenZone SvxHyphenZoneItem;
+
+//-------------------------------------------------------------------------
+
+item INT16 SvxKerningItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxLine
+{
+ UINT32 Color MID_FG_COLOR;
+ UINT16 OutWidth MID_OUTER_WIDTH;
+ UINT16 InWidth MID_INNER_WIDTH;
+ UINT16 Distance MID_DISTANCE;
+};
+item SvxLine SvxLineItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxLRSpace
+{
+ INT16 FirstLineOffset MID_FIRSTLINE_OFFSET; // % or direct
+ UINT16 LeftMargin MID_LEFT_MARGIN; // % or direct
+ UINT16 RightMargin MID_RIGHT_MARGIN; // % or direct
+};
+item SvxLRSpace SvxLRSpaceItem;
+
+//-------------------------------------------------------------------------
+
+item UINT16 SvxLanguage;
+
+struct SvxLineSpacing
+{
+ SvxLineSpace LineSpace MID_LINESPACE;
+ UINT16 LineHeight MID_HEIGHT; // % or direct
+ SvxInterLineSpace InterLineSpace MID_INTER_LINESPACE;
+ INT16 InterSpace MID_INTER_SPACE;
+};
+item SvxLineSpacing SvxLineSpacingItem;
+
+//-------------------------------------------------------------------------
+
+item BOOL SvxNoHyphenItem;
+item BOOL SvxNoLinebreakItem;
+item BOOL SvxOpaqueItem;
+item BYTE SvxOrphansItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxPage
+{
+ String DescName MID_DESCNAMExxx;
+ BOOL Landscape MID_LANDSCAPE;
+ UINT16 Use MID_USExxx;
+ SvxNumType NumType MID_NUMTYPExxx;
+};
+item SvxPage SvxPageItem;
+
+//-------------------------------------------------------------------------
+
+item String SvxPageModelItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxPagePosSize
+{
+ INT32 XPos MID_X;
+ INT32 YPos MID_Y;
+ INT32 Width MID_WIDTH;
+ INT32 Height MID_HEIGHT;
+};
+item SvxPagePosSize SvxPagePosSizeItem;
+
+//-------------------------------------------------------------------------
+
+item BYTE SvxPaperBinItem;
+
+//-------------------------------------------------------------------------
+
+item String SvxPostItAuthorItem;
+item String SvxPostItDateItem;
+item String SvxPostItTextItem;
+item FontItalic SvxPostureItem;
+item BOOL SvxPrintItem;
+item UINT16 SvxPropSizeItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxProtect
+{
+ BOOL Content MID_CONTENT;
+ BOOL Pos MID_POS;
+ BOOL Size MID_SIZE;
+};
+item SvxProtect SvxProtectItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxSearch
+{
+ UINT16 Command MID_COMMAND;
+ String SearchString MID_SEARCH_STRING;
+ String ReplaceString MID_REPLACE_STRING;
+ // W)ord, E)xact, B)ack, S)election, R)egExpr, P)attern
+ String Flags MID_FLAGS;
+ UINT16 Family MID_FAMILY;
+ UINT16 CellType MID_CELLTYPE;
+ BOOL RowDirection MID_ROW_DIRECTION;
+ UINT16 AppFlag MID_APPFLAG;
+};
+item SvxSearch SvxSearchItem;
+
+//-------------------------------------------------------------------------
+
+item BOOL SvxShadowedItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxShadow
+{
+ SvxShadowLocation Location MID_LOCATION;
+ UINT16 Width MID_WIDTH;
+ BrushStyle Style MID_BRUSHSTYLE;
+ BOOL Transparent MID_TRANSPARENT;
+ UINT32 BackColor MID_BG_COLOR;
+ UINT32 FillColor MID_FG_COLOR;
+};
+item SvxShadow SvxShadowItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxSize
+{
+ UINT32 Width MID_WIDTH;
+ UINT32 Height MID_HEIGHT;
+};
+item SvxSize SvxSizeItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxULSpace
+{
+ UINT16 Upper MID_UPPER; // % or direct
+ UINT16 Lower MID_LOWER; // % or direct
+};
+item SvxULSpace SvxULSpaceItem
+
+//-------------------------------------------------------------------------
+
+enum SvxChooseControlEnum
+{
+ SVX_SNAP_PUSHBUTTON,
+ SVX_SNAP_CHECKBOX,
+ SVX_SNAP_RADIOBUTTON,
+ SVX_SNAP_SPINBUTTON,
+ SVX_SNAP_FIXEDTEXT,
+ SVX_SNAP_GROUPBOX,
+ SVX_SNAP_LISTBOX,
+ SVX_SNAP_COMBOBOX,
+ SVX_SNAP_EDIT,
+ SVX_SNAP_HSCROLLBAR,
+ SVX_SNAP_VSCROLLBAR,
+ SVX_SNAP_PREVIEW,
+ SVX_SNAP_SELECT,
+ SVX_SNAP_NOTHING
+}
+item SvxChooseControlEnum SvxChooseControlEnumItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxDrawToolEnum
+{
+ SVX_SNAP_DRAW_SELECT,
+ //
+ SVX_SNAP_DRAW_LINE,
+ SVX_SNAP_DRAW_RECT,
+ SVX_SNAP_DRAW_ELLIPSE,
+ SVX_SNAP_DRAW_POLYGON,
+ SVX_SNAP_DRAW_ARC,
+ SVX_SNAP_DRAW_PIE,
+ SVX_SNAP_DRAW_CIRCLECUT,
+ SVX_SNAP_DRAW_TEXT,
+ SVX_SNAP_DRAW_CAPTION,
+ SVX_SNAP_DRAW_NOTHING
+}
+item SvxDrawToolEnum SvxDrawToolEnumItem;
+
+//-------------------------------------------------------------------------
+
+item SvxChooseControlEnum SvxChooseControlItem;
+item SvxDrawToolEnum SvxDrawToolItem;
+item FontUnderline SvxUnderlineItem;
+item FontWeight SvxWeightItem;
+item BYTE SvxWidowsItem;
+item BOOL SvxWordLineModeItem;
+item String SvxBoxItem; //! Dummy
+
+//-------------------------------------------------------------------------
+
+enum SvxCellHorJustifyEnum
+{
+ SVX_HOR_JUSTIFY_STANDARD,
+ SVX_HOR_JUSTIFY_LEFT,
+ SVX_HOR_JUSTIFY_CENTER,
+ SVX_HOR_JUSTIFY_RIGHT,
+ SVX_HOR_JUSTIFY_BLOCK,
+ SVX_HOR_JUSTIFY_REPEAT
+};
+item SvxCellHorJustifyEnum SvxCellHorJustifyEnumItem;
+
+enum SvxCellVerJustifyEnum
+{
+ SVX_VER_JUSTIFY_STANDARD,
+ SVX_VER_JUSTIFY_TOP,
+ SVX_VER_JUSTIFY_CENTER,
+ SVX_VER_JUSTIFY_BOTTOM
+};
+item SvxCellVerJustifyEnum SvxCellVerJustifyEnumItem;
+
+//-------------------------------------------------------------------------
+
+enum SvxCellOrientationEnum
+{
+ SVX_ORIENTATION_STANDARD,
+ SVX_ORIENTATION_TOPBOTTOM,
+ SVX_ORIENTATION_BOTTOMTOP,
+ SVX_ORIENTATION_STACKED
+};
+item SvxCellOrientationEnum SvxCellOrientationEnumItem;
+
+//-------------------------------------------------------------------------
+
+item SvxCellHorJustifyEnum SvxHorJustifyItem;
+item SvxCellVerJustifyEnum SvxVerJustifyItem;
+item SvxCellOrientationEnum SvxOrientationItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxLongLRSpace
+{
+ INT32 Left MID_LEFT;
+ INT32 Right MID_RIGHT;
+};
+item SvxLongLRSpace SvxLongLRSpaceItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxLongULSpace
+{
+ INT32 Upper MID_UPPER;
+ INT32 Lower MID_LOWER;
+};
+item SvxLongULSpace SvxLongULSpaceItem;
+
+//-------------------------------------------------------------------------
+
+struct SvxZoom
+{
+ INT32 Type MID_TYPE;
+ UINT16 ValueSet MID_VALUESET;
+ INT32 Percent MID_PERCENT;
+};
+item SvxZoom SvxZoomItem;
+
+//-------------------------------------------------------------------------
+
+item SbxObject SvxTabStopItem;
+
+
diff --git a/starmath/sdi/smslots.sdi b/starmath/sdi/smslots.sdi
new file mode 100755
index 000000000000..cc259af5d117
--- /dev/null
+++ b/starmath/sdi/smslots.sdi
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+module
+"312C4240-35E7-101C-B12A-04021C007002"
+"58216740-35E7-101C-B12A-04021C007002"
+StarMath
+[
+ HelpText ( "StarMath Application" )
+ SlotIdFile ( "starmath.hrc" )
+ SlotIdFile ( "editeng/editids.hrc" )
+ SlotIdFile ( "sfx2/sfxsids.hrc" )
+ SlotIdFile ( "svx/svxids.hrc" )
+]
+{
+ include "sfx2/sfxitems.sdi"
+ include "sfx2/sfx.sdi"
+ include "svx/svxitems.sdi"
+ include "svx/xoitems.sdi"
+ include "svx/svx.sdi"
+ include "smath.sdi"
+ interface StarMath
+ [
+ uuid ( "92B0FD20-2FC1-11CF-89CA-008029E4B0B1" )
+ ]
+ {
+ SID_CONFIGEVENT //idlpp ole : no , status : no
+ [
+ StateMethod = GetState ;
+ ]
+}
+
+shell SmModule
+{
+ import StarMath[Automation];
+}
+
+interface FormulaDocument
+[
+ uuid ( "815CBB20-2FC3-11CF-89CA-008029E4B0B1" )
+]
+{
+ SID_DOCTEMPLATE //idlpp ole : no , status : no
+ [
+ StateMethod = GetState ;
+ ]
+ SID_AUTO_REDRAW //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menuepunkt , also keine Texte
+ SID_LOADSYMBOLS //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menuepunkt , also keine Texte
+ SID_SAVESYMBOLS //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_FONT //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_FONTSIZE //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_DISTANCE //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_ALIGN //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_TEXTMODE //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_MODIFYSTATUS //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_TEXT //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_GAPHIC_SM //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+
+ SID_UNDO //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_REDO //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_GETUNDOSTRINGS //idlpp ole : no , status : no
+ [
+ StateMethod = GetState ;
+ ]
+ SID_GETREDOSTRINGS //idlpp ole : no , status : no
+ [
+ StateMethod = GetState ;
+ ]
+}
+
+shell SmDocShell
+{
+ import FormulaDocument[Automation];
+}
+
+
+interface FormulaView
+[
+ uuid ( "CE1A6C00-2FC3-11CF-89CA-008029E4B0B1" )
+]
+{
+ SID_FORMULACURSOR
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_NEXTERR //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_PREVERR //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_NEXTMARK //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_PREVMARK //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_VIEW050 //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_VIEW100 //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_VIEW200 //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_ZOOMIN //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_ZOOMOUT //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_DRAW //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_ADJUST //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_FITINWINDOW //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_COPYOBJECT //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_PASTEOBJECT //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_CUT //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_COPY //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_PASTE //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_DELETE //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_SELECT //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_INSERTCOMMAND //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_INSERTSYMBOL //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_IMPORT_FORMULA //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ Export = FALSE ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_ATTR_ZOOM //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_TEXTSTATUS //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_GETEDITTEXT //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_CMDBOXWINDOW //idlpp ole : no , status : no
+ [
+ ExecMethod = NoExec ;
+ StateMethod = NoState ;
+ ]
+ //idlpp kein Menueeintrag , also keine Texte
+ SID_TOOLBOXWINDOW //idlpp ole : no , status : no
+ [
+ ExecMethod = NoExec ;
+ StateMethod = NoState ;
+ ]
+ SID_TOOLBOX //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+ SID_SYMBOLS_CATALOGUE //idlpp ole : no , status : no
+ [
+ ExecMethod = Execute ;
+ StateMethod = GetState ;
+ ]
+}
+
+shell SmViewShell
+{
+ import FormulaView[Automation];
+}
+
+}
+
diff --git a/starmath/source/accessibility.cxx b/starmath/source/accessibility.cxx
new file mode 100644
index 000000000000..426d0a61c294
--- /dev/null
+++ b/starmath/source/accessibility.cxx
@@ -0,0 +1,1986 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleTextType.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
+#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
+#include <com/sun/star/awt/FocusEvent.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <unotools/accessiblerelationsethelper.hxx>
+
+
+#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
+#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <unotools/accessiblestatesethelper.hxx>
+#include <comphelper/accessibleeventnotifier.hxx>
+#include <osl/diagnose.h>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/unohelp2.hxx>
+#include <tools/gen.hxx>
+#include <osl/mutex.hxx>
+#include <svl/itemset.hxx>
+
+#include <editeng/editobj.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/unoedhlp.hxx>
+
+
+#include "accessibility.hxx"
+#include <applicat.hxx>
+#include <unomodel.hxx>
+#include <document.hxx>
+#include <view.hxx>
+
+using rtl::OUString;
+using namespace com::sun::star;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+//////////////////////////////////////////////////////////////////////
+
+static awt::Rectangle lcl_GetBounds( Window *pWin )
+{
+ // !! see VCLXAccessibleComponent::implGetBounds()
+
+ //! the coordinates returned are relativ to the parent window !
+ //! Thus the top-left point may be different from (0, 0) !
+
+ awt::Rectangle aBounds;
+ if (pWin)
+ {
+ Rectangle aRect = pWin->GetWindowExtentsRelative( NULL );
+ aBounds.X = aRect.Left();
+ aBounds.Y = aRect.Top();
+ aBounds.Width = aRect.GetWidth();
+ aBounds.Height = aRect.GetHeight();
+ Window* pParent = pWin->GetAccessibleParentWindow();
+ if (pParent)
+ {
+ Rectangle aParentRect = pParent->GetWindowExtentsRelative( NULL );
+ awt::Point aParentScreenLoc( aParentRect.Left(), aParentRect.Top() );
+ aBounds.X -= aParentScreenLoc.X;
+ aBounds.Y -= aParentScreenLoc.Y;
+ }
+ }
+ return aBounds;
+}
+
+static awt::Point lcl_GetLocationOnScreen( Window *pWin )
+{
+ // !! see VCLXAccessibleComponent::getLocationOnScreen()
+
+ awt::Point aPos;
+ if (pWin)
+ {
+ Rectangle aRect = pWin->GetWindowExtentsRelative( NULL );
+ aPos.X = aRect.Left();
+ aPos.Y = aRect.Top();
+ }
+ return aPos;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+SmGraphicAccessible::SmGraphicAccessible( SmGraphicWindow *pGraphicWin ) :
+ aAccName ( String(SmResId(RID_DOCUMENTSTR)) ),
+ nClientId (0),
+ pWin (pGraphicWin)
+{
+ OSL_ENSURE( pWin, "SmGraphicAccessible: window missing" );
+}
+
+
+SmGraphicAccessible::SmGraphicAccessible( const SmGraphicAccessible &rSmAcc ) :
+ SmGraphicAccessibleBaseClass(),
+ aAccName ( String(SmResId(RID_DOCUMENTSTR)) ),
+ nClientId (0)
+{
+ pWin = rSmAcc.pWin;
+ OSL_ENSURE( pWin, "SmGraphicAccessible: window missing" );
+}
+
+
+SmGraphicAccessible::~SmGraphicAccessible()
+{
+}
+
+
+SmDocShell * SmGraphicAccessible::GetDoc_Impl()
+{
+ SmViewShell *pView = pWin ? pWin->GetView() : 0;
+ return pView ? pView->GetDoc() : 0;
+}
+
+String SmGraphicAccessible::GetAccessibleText_Impl()
+{
+ String aTxt;
+ SmDocShell *pDoc = GetDoc_Impl();
+ if (pDoc)
+ aTxt = pDoc->GetAccessibleText();
+ return aTxt;
+}
+
+void SmGraphicAccessible::ClearWin()
+{
+ pWin = 0; // implicitly results in AccessibleStateType::DEFUNC set
+
+ if ( nClientId )
+ {
+ comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
+ nClientId = 0;
+ }
+}
+
+void SmGraphicAccessible::LaunchEvent(
+ const sal_Int16 nAccesibleEventId,
+ const uno::Any &rOldVal,
+ const uno::Any &rNewVal)
+{
+ AccessibleEventObject aEvt;
+ aEvt.Source = (XAccessible *) this;
+ aEvt.EventId = nAccesibleEventId;
+ aEvt.OldValue = rOldVal;
+ aEvt.NewValue = rNewVal ;
+
+ // pass event on to event-listener's
+ if (nClientId)
+ comphelper::AccessibleEventNotifier::addEvent( nClientId, aEvt );
+}
+
+uno::Reference< XAccessibleContext > SAL_CALL SmGraphicAccessible::getAccessibleContext()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return this;
+}
+
+sal_Bool SAL_CALL SmGraphicAccessible::containsPoint( const awt::Point& aPoint )
+ throw (RuntimeException)
+{
+ //! the arguments coordinates are relativ to the current window !
+ //! Thus the top-left point is (0, 0)
+
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+
+ Size aSz( pWin->GetSizePixel() );
+ return aPoint.X >= 0 && aPoint.Y >= 0 &&
+ aPoint.X < aSz.Width() && aPoint.Y < aSz.Height();
+}
+
+uno::Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleAtPoint(
+ const awt::Point& aPoint )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ XAccessible *pRes = 0;
+ if (containsPoint( aPoint ))
+ pRes = this;
+ return pRes;
+}
+
+awt::Rectangle SAL_CALL SmGraphicAccessible::getBounds()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+ OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
+ "mismatch of window parent and accessible parent" );
+ return lcl_GetBounds( pWin );
+}
+
+awt::Point SAL_CALL SmGraphicAccessible::getLocation()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+ OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
+ "mismatch of window parent and accessible parent" );
+ awt::Rectangle aRect( lcl_GetBounds( pWin ) );
+ return awt::Point( aRect.X, aRect.Y );
+}
+
+awt::Point SAL_CALL SmGraphicAccessible::getLocationOnScreen()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+ OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
+ "mismatch of window parent and accessible parent" );
+ return lcl_GetLocationOnScreen( pWin );
+}
+
+awt::Size SAL_CALL SmGraphicAccessible::getSize()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+ OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
+ "mismatch of window parent and accessible parent" );
+
+ Size aSz( pWin->GetSizePixel() );
+#if OSL_DEBUG_LEVEL > 1
+ awt::Rectangle aRect( lcl_GetBounds( pWin ) );
+ Size aSz2( aRect.Width, aRect.Height );
+ OSL_ENSURE( aSz == aSz2, "mismatch in width" );
+#endif
+ return awt::Size( aSz.Width(), aSz.Height() );
+}
+
+void SAL_CALL SmGraphicAccessible::grabFocus()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+
+ pWin->GrabFocus();
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getForeground()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ if (!pWin)
+ throw RuntimeException();
+ return (sal_Int32) pWin->GetTextColor().GetColor();
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getBackground()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ if (!pWin)
+ throw RuntimeException();
+ Wallpaper aWall( pWin->GetDisplayBackground() );
+ ColorData nCol;
+ if (aWall.IsBitmap() || aWall.IsGradient())
+ nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
+ else
+ nCol = aWall.GetColor().GetColor();
+ return (sal_Int32) nCol;
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleChildCount()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return 0;
+}
+
+Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleChild(
+ sal_Int32 /*i*/ )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ throw IndexOutOfBoundsException(); // there is no child...
+}
+
+Reference< XAccessible > SAL_CALL SmGraphicAccessible::getAccessibleParent()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+
+ Window *pAccParent = pWin->GetAccessibleParentWindow();
+ OSL_ENSURE( pAccParent, "accessible parent missing" );
+ return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >();
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getAccessibleIndexInParent()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nIdx = -1;
+ Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : 0;
+ if (pAccParent)
+ {
+ sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount();
+ for (sal_uInt16 i = 0; i < nCnt && nIdx == -1; ++i)
+ if (pAccParent->GetAccessibleChildWindow( i ) == pWin)
+ nIdx = i;
+ }
+ return nIdx;
+}
+
+sal_Int16 SAL_CALL SmGraphicAccessible::getAccessibleRole()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return AccessibleRole::DOCUMENT;
+}
+
+OUString SAL_CALL SmGraphicAccessible::getAccessibleDescription()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ SmDocShell *pDoc = GetDoc_Impl();
+ return pDoc ? OUString(pDoc->GetText()) : OUString();
+}
+
+OUString SAL_CALL SmGraphicAccessible::getAccessibleName()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return aAccName;
+}
+
+Reference< XAccessibleRelationSet > SAL_CALL SmGraphicAccessible::getAccessibleRelationSet()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper();
+ return xRelSet; // empty relation set
+}
+
+Reference< XAccessibleStateSet > SAL_CALL SmGraphicAccessible::getAccessibleStateSet()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ ::utl::AccessibleStateSetHelper *pStateSet =
+ new ::utl::AccessibleStateSetHelper;
+
+ Reference<XAccessibleStateSet> xStateSet( pStateSet );
+
+ if (!pWin)
+ pStateSet->AddState( AccessibleStateType::DEFUNC );
+ else
+ {
+ pStateSet->AddState( AccessibleStateType::ENABLED );
+ pStateSet->AddState( AccessibleStateType::FOCUSABLE );
+ if (pWin->HasFocus())
+ pStateSet->AddState( AccessibleStateType::FOCUSED );
+ if (pWin->IsActive())
+ pStateSet->AddState( AccessibleStateType::ACTIVE );
+ if (pWin->IsVisible())
+ pStateSet->AddState( AccessibleStateType::SHOWING );
+ if (pWin->IsReallyVisible())
+ pStateSet->AddState( AccessibleStateType::VISIBLE );
+ if (COL_TRANSPARENT != pWin->GetBackground().GetColor().GetColor())
+ pStateSet->AddState( AccessibleStateType::OPAQUE );
+ }
+
+ return xStateSet;
+}
+
+Locale SAL_CALL SmGraphicAccessible::getLocale()
+ throw (IllegalAccessibleComponentStateException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ // should be the document language...
+ // We use the language of the localized symbol names here.
+ return Application::GetSettings().GetUILocale();
+}
+
+
+void SAL_CALL SmGraphicAccessible::addEventListener(
+ const Reference< XAccessibleEventListener >& xListener )
+ throw (RuntimeException)
+{
+ if (xListener.is())
+ {
+ SolarMutexGuard aGuard;
+ if (pWin)
+ {
+ if (!nClientId)
+ nClientId = comphelper::AccessibleEventNotifier::registerClient( );
+ comphelper::AccessibleEventNotifier::addEventListener( nClientId, xListener );
+ }
+ }
+}
+
+void SAL_CALL SmGraphicAccessible::removeEventListener(
+ const Reference< XAccessibleEventListener >& xListener )
+ throw (RuntimeException)
+{
+ if (xListener.is())
+ {
+ SolarMutexGuard aGuard;
+ sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( nClientId, xListener );
+ if ( !nListenerCount )
+ {
+ // no listeners anymore
+ // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
+ // and at least to us not firing any events anymore, in case somebody calls
+ // NotifyAccessibleEvent, again
+ comphelper::AccessibleEventNotifier::revokeClient( nClientId );
+ nClientId = 0;
+ }
+ }
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getCaretPosition()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return 0;
+}
+
+sal_Bool SAL_CALL SmGraphicAccessible::setCaretPosition( sal_Int32 nIndex )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ xub_StrLen nIdx = (xub_StrLen) nIndex;
+ String aTxt( GetAccessibleText_Impl() );
+ if (!(nIdx < aTxt.Len()))
+ throw IndexOutOfBoundsException();
+ return sal_False;
+}
+
+sal_Unicode SAL_CALL SmGraphicAccessible::getCharacter( sal_Int32 nIndex )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ xub_StrLen nIdx = (xub_StrLen) nIndex;
+ String aTxt( GetAccessibleText_Impl() );
+ if (!(nIdx < aTxt.Len()))
+ throw IndexOutOfBoundsException();
+ return aTxt.GetChar( nIdx );
+}
+
+Sequence< beans::PropertyValue > SAL_CALL SmGraphicAccessible::getCharacterAttributes(
+ sal_Int32 nIndex,
+ const uno::Sequence< ::rtl::OUString > & /*rRequestedAttributes*/ )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nLen = GetAccessibleText_Impl().Len();
+ if (!(0 <= nIndex && nIndex < nLen))
+ throw IndexOutOfBoundsException();
+ return Sequence< beans::PropertyValue >();
+}
+
+awt::Rectangle SAL_CALL SmGraphicAccessible::getCharacterBounds( sal_Int32 nIndex )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ awt::Rectangle aRes;
+
+ if (!pWin)
+ throw RuntimeException();
+ else
+ {
+ // get accessible text
+ SmViewShell *pView = pWin->GetView();
+ SmDocShell *pDoc = pView ? pView->GetDoc() : 0;
+ if (!pDoc)
+ throw RuntimeException();
+ String aTxt( GetAccessibleText_Impl() );
+ if (!(0 <= nIndex && nIndex <= aTxt.Len())) // aTxt.Len() is valid
+ throw IndexOutOfBoundsException();
+
+ // find a reasonable rectangle for position aTxt.Len().
+ bool bWasBehindText = (nIndex == aTxt.Len());
+ if (bWasBehindText && nIndex)
+ --nIndex;
+
+ const SmNode *pTree = pDoc->GetFormulaTree();
+ const SmNode *pNode = pTree->FindNodeWithAccessibleIndex( (xub_StrLen) nIndex );
+ //! pNode may be 0 if the index belongs to a char that was inserted
+ //! only for the accessible text!
+ if (pNode)
+ {
+ sal_Int32 nAccIndex = pNode->GetAccessibleIndex();
+ OSL_ENSURE( nAccIndex >= 0, "invalid accessible index" );
+ OSL_ENSURE( nIndex >= nAccIndex, "index out of range" );
+
+ String aNodeText;
+ pNode->GetAccessibleText( aNodeText );
+ sal_Int32 nNodeIndex = nIndex - nAccIndex;
+ if (0 <= nNodeIndex && nNodeIndex < aNodeText.Len())
+ {
+ // get appropriate rectangle
+ Point aOffset(pNode->GetTopLeft() - pTree->GetTopLeft());
+ Point aTLPos (pWin->GetFormulaDrawPos() + aOffset);
+ aTLPos.X() -= 0;
+ Size aSize (pNode->GetSize());
+
+ sal_Int32 *pXAry = new sal_Int32[ aNodeText.Len() ];
+ pWin->SetFont( pNode->GetFont() );
+ pWin->GetTextArray( aNodeText, pXAry, 0, aNodeText.Len() );
+ aTLPos.X() += nNodeIndex > 0 ? pXAry[nNodeIndex - 1] : 0;
+ aSize.Width() = nNodeIndex > 0 ? pXAry[nNodeIndex] - pXAry[nNodeIndex - 1] : pXAry[nNodeIndex];
+ delete[] pXAry;
+
+#if OSL_DEBUG_LEVEL > 1
+ Point aLP00( pWin->LogicToPixel( Point(0,0)) );
+ Point aPL00( pWin->PixelToLogic( Point(0,0)) );
+#endif
+ aTLPos = pWin->LogicToPixel( aTLPos );
+ aSize = pWin->LogicToPixel( aSize );
+ aRes.X = aTLPos.X();
+ aRes.Y = aTLPos.Y();
+ aRes.Width = aSize.Width();
+ aRes.Height = aSize.Height();
+ }
+ }
+
+ // take rectangle from last character and move it to the right
+ if (bWasBehindText)
+ aRes.X += aRes.Width;
+ }
+
+ return aRes;
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getCharacterCount()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return GetAccessibleText_Impl().Len();
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getIndexAtPoint( const awt::Point& aPoint )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ sal_Int32 nRes = -1;
+ if (pWin)
+ {
+ const SmNode *pTree = pWin->GetView()->GetDoc()->GetFormulaTree();
+ //! kann NULL sein! ZB wenn bereits beim laden des Dokuments (bevor der
+ //! Parser angeworfen wurde) ins Fenster geklickt wird.
+ if (!pTree)
+ return nRes;
+
+ // get position relativ to formula draw position
+ Point aPos( aPoint.X, aPoint.Y );
+ aPos = pWin->PixelToLogic( aPos );
+ aPos -= pWin->GetFormulaDrawPos();
+
+ // if it was inside the formula then get the appropriate node
+ const SmNode *pNode = 0;
+ if (pTree->OrientedDist(aPos) <= 0)
+ pNode = pTree->FindRectClosestTo(aPos);
+
+ if (pNode)
+ {
+ // get appropriate rectangle
+ Point aOffset( pNode->GetTopLeft() - pTree->GetTopLeft() );
+ Point aTLPos ( aOffset );
+ aTLPos.X() -= 0;
+ Size aSize( pNode->GetSize() );
+#if OSL_DEBUG_LEVEL > 1
+ Point aLP00( pWin->LogicToPixel( Point(0,0)) );
+ Point aPL00( pWin->PixelToLogic( Point(0,0)) );
+#endif
+
+ Rectangle aRect( aTLPos, aSize );
+ if (aRect.IsInside( aPos ))
+ {
+ OSL_ENSURE( pNode->IsVisible(), "node is not a leaf" );
+ String aTxt;
+ pNode->GetAccessibleText( aTxt );
+ OSL_ENSURE( aTxt.Len(), "no accessible text available" );
+
+ long nNodeX = pNode->GetLeft();
+
+ sal_Int32 *pXAry = new sal_Int32[ aTxt.Len() ];
+ pWin->SetFont( pNode->GetFont() );
+ pWin->GetTextArray( aTxt, pXAry, 0, aTxt.Len() );
+ for (sal_Int32 i = 0; i < aTxt.Len() && nRes == -1; ++i)
+ {
+ if (pXAry[i] + nNodeX > aPos.X())
+ nRes = i;
+ }
+ delete[] pXAry;
+ OSL_ENSURE( nRes >= 0 && nRes < aTxt.Len(), "index out of range" );
+ OSL_ENSURE( pNode->GetAccessibleIndex() >= 0,
+ "invalid accessible index" );
+
+ nRes = pNode->GetAccessibleIndex() + nRes;
+ }
+ }
+ }
+ return nRes;
+}
+
+OUString SAL_CALL SmGraphicAccessible::getSelectedText()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return OUString();
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionStart()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return -1;
+}
+
+sal_Int32 SAL_CALL SmGraphicAccessible::getSelectionEnd()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return -1;
+}
+
+sal_Bool SAL_CALL SmGraphicAccessible::setSelection(
+ sal_Int32 nStartIndex,
+ sal_Int32 nEndIndex )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nLen = GetAccessibleText_Impl().Len();
+ if (!(0 <= nStartIndex && nStartIndex < nLen) ||
+ !(0 <= nEndIndex && nEndIndex < nLen))
+ throw IndexOutOfBoundsException();
+ return sal_False;
+}
+
+OUString SAL_CALL SmGraphicAccessible::getText()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return GetAccessibleText_Impl();
+}
+
+OUString SAL_CALL SmGraphicAccessible::getTextRange(
+ sal_Int32 nStartIndex,
+ sal_Int32 nEndIndex )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ //!! nEndIndex may be the string length per definition of the interface !!
+ //!! text should be copied exclusive that end index though. And arguments
+ //!! may be switched.
+
+ SolarMutexGuard aGuard;
+ String aTxt( GetAccessibleText_Impl() );
+ xub_StrLen nStart = (xub_StrLen) Min(nStartIndex, nEndIndex);
+ xub_StrLen nEnd = (xub_StrLen) Max(nStartIndex, nEndIndex);
+ if (!(nStart <= aTxt.Len()) ||
+ !(nEnd <= aTxt.Len()))
+ throw IndexOutOfBoundsException();
+ return aTxt.Copy( nStart, nEnd - nStart );
+}
+
+::com::sun::star::accessibility::TextSegment SAL_CALL SmGraphicAccessible::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ String aTxt( GetAccessibleText_Impl() );
+ xub_StrLen nIdx = (xub_StrLen) nIndex;
+ //!! nIndex is allowed to be the string length
+ if (!(nIdx <= aTxt.Len()))
+ throw IndexOutOfBoundsException();
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+ if ( (AccessibleTextType::CHARACTER == aTextType) && (nIdx < aTxt.Len()) )
+ {
+ aResult.SegmentText = aTxt.Copy(nIdx, 1);
+ aResult.SegmentStart = nIdx;
+ aResult.SegmentEnd = nIdx+1;
+ }
+ return aResult;
+}
+
+::com::sun::star::accessibility::TextSegment SAL_CALL SmGraphicAccessible::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ String aTxt( GetAccessibleText_Impl() );
+ xub_StrLen nIdx = (xub_StrLen) nIndex;
+ //!! nIndex is allowed to be the string length
+ if (!(nIdx <= aTxt.Len()))
+ throw IndexOutOfBoundsException();
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ if ( (AccessibleTextType::CHARACTER == aTextType) && nIdx )
+ {
+ aResult.SegmentText = aTxt.Copy(nIdx-1, 1);
+ aResult.SegmentStart = nIdx-1;
+ aResult.SegmentEnd = nIdx;
+ }
+ return aResult;
+}
+
+::com::sun::star::accessibility::TextSegment SAL_CALL SmGraphicAccessible::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ String aTxt( GetAccessibleText_Impl() );
+ xub_StrLen nIdx = (xub_StrLen) nIndex;
+ //!! nIndex is allowed to be the string length
+ if (!(nIdx <= aTxt.Len()))
+ throw IndexOutOfBoundsException();
+
+ ::com::sun::star::accessibility::TextSegment aResult;
+ aResult.SegmentStart = -1;
+ aResult.SegmentEnd = -1;
+
+ nIdx++; // text *behind*
+ if ( (AccessibleTextType::CHARACTER == aTextType) && (nIdx < aTxt.Len()) )
+ {
+ aResult.SegmentText = aTxt.Copy(nIdx, 1);
+ aResult.SegmentStart = nIdx;
+ aResult.SegmentEnd = nIdx+1;
+ }
+ return aResult;
+}
+
+sal_Bool SAL_CALL SmGraphicAccessible::copyText(
+ sal_Int32 nStartIndex,
+ sal_Int32 nEndIndex )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ sal_Bool bReturn = sal_False;
+
+ if (!pWin)
+ throw RuntimeException();
+ else
+ {
+ Reference< datatransfer::clipboard::XClipboard > xClipboard = pWin->GetClipboard();
+ if ( xClipboard.is() )
+ {
+ ::rtl::OUString sText( getTextRange(nStartIndex, nEndIndex) );
+
+ ::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText );
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+ xClipboard->setContents( pDataObj, NULL );
+
+ Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
+ if( xFlushableClipboard.is() )
+ xFlushableClipboard->flushClipboard();
+
+ Application::AcquireSolarMutex( nRef );
+
+ bReturn = sal_True;
+ }
+ }
+
+ return bReturn;
+}
+
+OUString SAL_CALL SmGraphicAccessible::getImplementationName()
+ throw (RuntimeException)
+{
+ return A2OU("SmGraphicAccessible");
+}
+
+sal_Bool SAL_CALL SmGraphicAccessible::supportsService(
+ const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return rServiceName == A2OU( "com::sun::star::accessibility::Accessible" ) ||
+ rServiceName == A2OU( "com::sun::star::accessibility::AccessibleComponent" ) ||
+ rServiceName == A2OU( "com::sun::star::accessibility::AccessibleContext" ) ||
+ rServiceName == A2OU( "com::sun::star::accessibility::AccessibleText" );
+}
+
+Sequence< OUString > SAL_CALL SmGraphicAccessible::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ Sequence< OUString > aNames(4);
+ OUString *pNames = aNames.getArray();
+ pNames[0] = A2OU( "com::sun::star::accessibility::Accessible" );
+ pNames[1] = A2OU( "com::sun::star::accessibility::AccessibleComponent" );
+ pNames[2] = A2OU( "com::sun::star::accessibility::AccessibleContext" );
+ pNames[3] = A2OU( "com::sun::star::accessibility::AccessibleText" );
+ return aNames;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+//------------------------------------------------------------------------
+
+SmEditSource::SmEditSource( SmEditWindow * /*pWin*/, SmEditAccessible &rAcc ) :
+ aViewFwd (rAcc),
+ aTextFwd (rAcc, *this),
+ aEditViewFwd(rAcc),
+ rEditAcc (rAcc)
+{
+}
+
+SmEditSource::SmEditSource( const SmEditSource &rSrc ) :
+ SvxEditSource(),
+ aViewFwd (rSrc.rEditAcc),
+ aTextFwd (rSrc.rEditAcc, *this),
+ aEditViewFwd(rSrc.rEditAcc),
+ rEditAcc (rSrc.rEditAcc)
+{
+}
+
+SmEditSource::~SmEditSource()
+{
+}
+
+SvxEditSource* SmEditSource::Clone() const
+{
+ return new SmEditSource( *this );
+}
+
+SvxTextForwarder* SmEditSource::GetTextForwarder()
+{
+ return &aTextFwd;
+}
+
+SvxViewForwarder* SmEditSource::GetViewForwarder()
+{
+ return &aViewFwd;
+}
+
+SvxEditViewForwarder* SmEditSource::GetEditViewForwarder( sal_Bool /*bCreate*/ )
+{
+ return &aEditViewFwd;
+}
+
+void SmEditSource::UpdateData()
+{
+ // would possibly only by needed if the XText inteface is implemented
+ // and its text needs to be updated.
+}
+
+SfxBroadcaster & SmEditSource::GetBroadcaster() const
+{
+ return ((SmEditSource *) this)->aBroadCaster;
+}
+
+//------------------------------------------------------------------------
+
+SmViewForwarder::SmViewForwarder( SmEditAccessible &rAcc ) :
+ rEditAcc(rAcc)
+{
+}
+
+SmViewForwarder::~SmViewForwarder()
+{
+}
+
+sal_Bool SmViewForwarder::IsValid() const
+{
+ return rEditAcc.GetEditView() != 0;
+}
+
+Rectangle SmViewForwarder::GetVisArea() const
+{
+ EditView *pEditView = rEditAcc.GetEditView();
+ OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
+
+ if( pOutDev && pEditView)
+ {
+ Rectangle aVisArea = pEditView->GetVisArea();
+
+ // figure out map mode from edit engine
+ EditEngine* pEditEngine = pEditView->GetEditEngine();
+
+ if( pEditEngine )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ aVisArea = OutputDevice::LogicToLogic( aVisArea,
+ pEditEngine->GetRefMapMode(),
+ aMapMode.GetMapUnit() );
+ aMapMode.SetOrigin(Point());
+ return pOutDev->LogicToPixel( aVisArea, aMapMode );
+ }
+ }
+
+ return Rectangle();
+}
+
+Point SmViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ EditView *pEditView = rEditAcc.GetEditView();
+ OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
+
+ if( pOutDev )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
+ aMapMode.GetMapUnit() ) );
+ aMapMode.SetOrigin(Point());
+ return pOutDev->LogicToPixel( aPoint, aMapMode );
+ }
+
+ return Point();
+}
+
+Point SmViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ EditView *pEditView = rEditAcc.GetEditView();
+ OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
+
+ if( pOutDev )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
+ return OutputDevice::LogicToLogic( aPoint,
+ aMapMode.GetMapUnit(),
+ rMapMode );
+ }
+
+ return Point();
+}
+
+
+//------------------------------------------------------------------------
+
+SmTextForwarder::SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource) :
+ rEditAcc ( rAcc ),
+ rEditSource (rSource)
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl( LINK(this, SmTextForwarder, NotifyHdl) );
+}
+
+SmTextForwarder::~SmTextForwarder()
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl( Link() );
+}
+
+IMPL_LINK(SmTextForwarder, NotifyHdl, EENotify*, aNotify)
+{
+ if (aNotify)
+ {
+ ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify );
+ if (aHint.get())
+ rEditSource.GetBroadcaster().Broadcast( *aHint.get() );
+ }
+
+ return 0;
+}
+
+sal_uInt16 SmTextForwarder::GetParagraphCount() const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetParagraphCount() : 0;
+}
+
+sal_uInt16 SmTextForwarder::GetTextLen( sal_uInt16 nParagraph ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetTextLen( nParagraph ) : 0;
+}
+
+String SmTextForwarder::GetText( const ESelection& rSel ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ String aRet;
+ if (pEditEngine)
+ aRet = pEditEngine->GetText( rSel, LINEEND_LF );
+ aRet.ConvertLineEnd();
+ return aRet;
+}
+
+SfxItemSet SmTextForwarder::GetAttribs( const ESelection& rSel, sal_Bool bOnlyHardAttrib ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ OSL_ENSURE( pEditEngine, "EditEngine missing" );
+ if( rSel.nStartPara == rSel.nEndPara )
+ {
+ sal_uInt8 nFlags = 0;
+ switch( bOnlyHardAttrib )
+ {
+ case EditEngineAttribs_All:
+ nFlags = GETATTRIBS_ALL;
+ break;
+ case EditEngineAttribs_HardAndPara:
+ nFlags = GETATTRIBS_PARAATTRIBS|GETATTRIBS_CHARATTRIBS;
+ break;
+ case EditEngineAttribs_OnlyHard:
+ nFlags = GETATTRIBS_CHARATTRIBS;
+ break;
+ default:
+ OSL_FAIL("unknown flags for SmTextForwarder::GetAttribs");
+ }
+
+ return pEditEngine->GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
+ }
+ else
+ {
+ return pEditEngine->GetAttribs( rSel, bOnlyHardAttrib );
+ }
+}
+
+SfxItemSet SmTextForwarder::GetParaAttribs( sal_uInt16 nPara ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ OSL_ENSURE( pEditEngine, "EditEngine missing" );
+
+ SfxItemSet aSet( pEditEngine->GetParaAttribs( nPara ) );
+
+ sal_uInt16 nWhich = EE_PARA_START;
+ while( nWhich <= EE_PARA_END )
+ {
+ if( aSet.GetItemState( nWhich, sal_True ) != SFX_ITEM_ON )
+ {
+ if( pEditEngine->HasParaAttrib( nPara, nWhich ) )
+ aSet.Put( pEditEngine->GetParaAttrib( nPara, nWhich ) );
+ }
+ nWhich++;
+ }
+
+ return aSet;
+}
+
+void SmTextForwarder::SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rSet )
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->SetParaAttribs( nPara, rSet );
+}
+
+SfxItemPool* SmTextForwarder::GetPool() const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : 0;
+}
+
+void SmTextForwarder::RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich )
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich );
+}
+
+void SmTextForwarder::GetPortions( sal_uInt16 nPara, SvUShorts& rList ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->GetPortions( nPara, rList );
+}
+
+void SmTextForwarder::QuickInsertText( const String& rText, const ESelection& rSel )
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->QuickInsertText( rText, rSel );
+}
+
+void SmTextForwarder::QuickInsertLineBreak( const ESelection& rSel )
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->QuickInsertLineBreak( rSel );
+}
+
+void SmTextForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->QuickInsertField( rFld, rSel );
+}
+
+void SmTextForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->QuickSetAttribs( rSet, rSel );
+}
+
+sal_Bool SmTextForwarder::IsValid() const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ // cannot reliably query EditEngine state
+ // while in the middle of an update
+ return pEditEngine ? pEditEngine->GetUpdateMode() : sal_False;
+}
+
+XubString SmTextForwarder::CalcFieldValue( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos, Color*& rpTxtColor, Color*& rpFldColor )
+{
+ XubString aTxt;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ aTxt = pEditEngine->CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
+ return aTxt;
+}
+
+void SmTextForwarder::FieldClicked(const SvxFieldItem&, sal_uInt16, sal_uInt16)
+{
+}
+
+sal_uInt16 GetSvxEditEngineItemState( EditEngine& rEditEngine, const ESelection& rSel, sal_uInt16 nWhich )
+{
+ EECharAttribArray aAttribs;
+
+ const SfxPoolItem* pLastItem = NULL;
+
+ SfxItemState eState = SFX_ITEM_DEFAULT;
+
+ // check all paragraphs inside the selection
+ for( sal_uInt16 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ )
+ {
+ SfxItemState eParaState = SFX_ITEM_DEFAULT;
+
+ // calculate start and endpos for this paragraph
+ sal_uInt16 nPos = 0;
+ if( rSel.nStartPara == nPara )
+ nPos = rSel.nStartPos;
+
+ sal_uInt16 nEndPos = rSel.nEndPos;
+ if( rSel.nEndPara != nPara )
+ nEndPos = rEditEngine.GetTextLen( nPara );
+
+
+ // get list of char attribs
+ rEditEngine.GetCharAttribs( nPara, aAttribs );
+
+ bool bEmpty = true; // we found no item inside the selektion of this paragraph
+ bool bGaps = false; // we found items but theire gaps between them
+ sal_uInt16 nLastEnd = nPos;
+
+ const SfxPoolItem* pParaItem = NULL;
+
+ for( sal_uInt16 nAttrib = 0; nAttrib < aAttribs.Count(); nAttrib++ )
+ {
+ struct EECharAttrib aAttrib = aAttribs.GetObject( nAttrib );
+ OSL_ENSURE( aAttrib.pAttr, "GetCharAttribs gives corrupt data" );
+
+ const sal_Bool bEmptyPortion = aAttrib.nStart == aAttrib.nEnd;
+ if( (!bEmptyPortion && (aAttrib.nStart >= nEndPos)) || (bEmptyPortion && (aAttrib.nStart > nEndPos)) )
+ break; // break if we are already behind our selektion
+
+ if( (!bEmptyPortion && (aAttrib.nEnd <= nPos)) || (bEmptyPortion && (aAttrib.nEnd < nPos)) )
+ continue; // or if the attribute ends before our selektion
+
+ if( aAttrib.pAttr->Which() != nWhich )
+ continue; // skip if is not the searched item
+
+ // if we already found an item
+ if( pParaItem )
+ {
+ // ... and its different to this one than the state is dont care
+ if( *pParaItem != *aAttrib.pAttr )
+ return SFX_ITEM_DONTCARE;
+ }
+ else
+ {
+ pParaItem = aAttrib.pAttr;
+ }
+
+ if( bEmpty )
+ bEmpty = false;
+
+ if( !bGaps && aAttrib.nStart > nLastEnd )
+ bGaps = true;
+
+ nLastEnd = aAttrib.nEnd;
+ }
+
+ if( !bEmpty && !bGaps && nLastEnd < ( nEndPos - 1 ) )
+ bGaps = true;
+ if( bEmpty )
+ eParaState = SFX_ITEM_DEFAULT;
+ else if( bGaps )
+ eParaState = SFX_ITEM_DONTCARE;
+ else
+ eParaState = SFX_ITEM_SET;
+
+ // if we already found an item check if we found the same
+ if( pLastItem )
+ {
+ if( (pParaItem == NULL) || (*pLastItem != *pParaItem) )
+ return SFX_ITEM_DONTCARE;
+ }
+ else
+ {
+ pLastItem = pParaItem;
+ eState = eParaState;
+ }
+ }
+
+ return eState;
+}
+
+sal_uInt16 SmTextForwarder::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
+{
+ sal_uInt16 nState = SFX_ITEM_DISABLED;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ nState = GetSvxEditEngineItemState( *pEditEngine, rSel, nWhich );
+ return nState;
+}
+
+sal_uInt16 SmTextForwarder::GetItemState( sal_uInt16 nPara, sal_uInt16 nWhich ) const
+{
+ sal_uInt16 nState = SFX_ITEM_DISABLED;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ {
+ const SfxItemSet& rSet = pEditEngine->GetParaAttribs( nPara );
+ nState = rSet.GetItemState( nWhich );
+ }
+ return nState;
+}
+
+LanguageType SmTextForwarder::GetLanguage( sal_uInt16 nPara, sal_uInt16 nIndex ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
+}
+
+sal_uInt16 SmTextForwarder::GetFieldCount( sal_uInt16 nPara ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0;
+}
+
+EFieldInfo SmTextForwarder::GetFieldInfo( sal_uInt16 nPara, sal_uInt16 nField ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetFieldInfo( nPara, nField ) : EFieldInfo();
+}
+
+EBulletInfo SmTextForwarder::GetBulletInfo( sal_uInt16 /*nPara*/ ) const
+{
+ return EBulletInfo();
+}
+
+Rectangle SmTextForwarder::GetCharBounds( sal_uInt16 nPara, sal_uInt16 nIndex ) const
+{
+ Rectangle aRect(0,0,0,0);
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+
+ if (pEditEngine)
+ {
+ // Handle virtual position one-past-the end of the string
+ if( nIndex >= pEditEngine->GetTextLen(nPara) )
+ {
+ if( nIndex )
+ aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex-1) );
+
+ aRect.Move( aRect.Right() - aRect.Left(), 0 );
+ aRect.SetSize( Size(1, pEditEngine->GetTextHeight()) );
+ }
+ else
+ {
+ aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex) );
+ }
+ }
+ return aRect;
+}
+
+Rectangle SmTextForwarder::GetParaBounds( sal_uInt16 nPara ) const
+{
+ Rectangle aRect(0,0,0,0);
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+
+ if (pEditEngine)
+ {
+ const Point aPnt = pEditEngine->GetDocPosTopLeft( nPara );
+ const sal_uLong nWidth = pEditEngine->CalcTextWidth();
+ const sal_uLong nHeight = pEditEngine->GetTextHeight( nPara );
+ aRect = Rectangle( aPnt.X(), aPnt.Y(), aPnt.X() + nWidth, aPnt.Y() + nHeight );
+ }
+
+ return aRect;
+}
+
+MapMode SmTextForwarder::GetMapMode() const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode( MAP_100TH_MM );
+}
+
+OutputDevice* SmTextForwarder::GetRefDevice() const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetRefDevice() : 0;
+}
+
+sal_Bool SmTextForwarder::GetIndexAtPoint( const Point& rPos, sal_uInt16& nPara, sal_uInt16& nIndex ) const
+{
+ sal_Bool bRes = sal_False;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ {
+ EPosition aDocPos = pEditEngine->FindDocPosition( rPos );
+ nPara = aDocPos.nPara;
+ nIndex = aDocPos.nIndex;
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+sal_Bool SmTextForwarder::GetWordIndices( sal_uInt16 nPara, sal_uInt16 nIndex, sal_uInt16& nStart, sal_uInt16& nEnd ) const
+{
+ sal_Bool bRes = sal_False;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ {
+ ESelection aRes = pEditEngine->GetWord( ESelection(nPara, nIndex, nPara, nIndex), com::sun::star::i18n::WordType::DICTIONARY_WORD );
+
+ if( aRes.nStartPara == nPara &&
+ aRes.nStartPara == aRes.nEndPara )
+ {
+ nStart = aRes.nStartPos;
+ nEnd = aRes.nEndPos;
+
+ bRes = sal_True;
+ }
+ }
+
+ return bRes;
+}
+
+sal_Bool SmTextForwarder::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_uInt16 nPara, sal_uInt16 nIndex ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ?
+ SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, *pEditEngine, nPara, nIndex )
+ : sal_False;
+}
+
+sal_uInt16 SmTextForwarder::GetLineCount( sal_uInt16 nPara ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0;
+}
+
+sal_uInt16 SmTextForwarder::GetLineLen( sal_uInt16 nPara, sal_uInt16 nLine ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0;
+}
+
+void SmTextForwarder::GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_uInt16 nPara, sal_uInt16 nLine ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine);
+}
+
+sal_uInt16 SmTextForwarder::GetLineNumberAtIndex( sal_uInt16 nPara, sal_uInt16 nIndex ) const
+{
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0;
+}
+
+sal_Bool SmTextForwarder::QuickFormatDoc( sal_Bool /*bFull*/ )
+{
+ sal_Bool bRes = sal_False;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ {
+ pEditEngine->QuickFormatDoc();
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+sal_Int16 SmTextForwarder::GetDepth( sal_uInt16 /*nPara*/ ) const
+{
+ // math has no outliner...
+ return -1;
+}
+
+sal_Bool SmTextForwarder::SetDepth( sal_uInt16 /*nPara*/, sal_Int16 nNewDepth )
+{
+ // math has no outliner...
+ return -1 == nNewDepth; // is it the value from 'GetDepth' ?
+}
+
+sal_Bool SmTextForwarder::Delete( const ESelection& rSelection )
+{
+ sal_Bool bRes = sal_False;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ {
+ pEditEngine->QuickDelete( rSelection );
+ pEditEngine->QuickFormatDoc();
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+sal_Bool SmTextForwarder::InsertText( const String& rStr, const ESelection& rSelection )
+{
+ sal_Bool bRes = sal_False;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ {
+ pEditEngine->QuickInsertText( rStr, rSelection );
+ pEditEngine->QuickFormatDoc();
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+const SfxItemSet* SmTextForwarder::GetEmptyItemSetPtr()
+{
+ const SfxItemSet *pItemSet = 0;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ {
+ pItemSet = &pEditEngine->GetEmptyItemSet();
+ }
+ return pItemSet;
+}
+
+void SmTextForwarder::AppendParagraph()
+{
+ // append an empty paragraph
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine)
+ {
+ sal_uInt16 nParaCount = pEditEngine->GetParagraphCount();
+ pEditEngine->InsertParagraph( nParaCount, String() );
+ }
+}
+
+xub_StrLen SmTextForwarder::AppendTextPortion( sal_uInt16 nPara, const String &rText, const SfxItemSet &rSet )
+{
+ xub_StrLen nRes = 0;
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine && nPara < pEditEngine->GetParagraphCount())
+ {
+ // append text
+ ESelection aSel( nPara, pEditEngine->GetTextLen( nPara ) );
+ pEditEngine->QuickInsertText( rText, aSel );
+
+ // set attributes for new appended text
+ nRes = aSel.nEndPos = pEditEngine->GetTextLen( nPara );
+ pEditEngine->QuickSetAttribs( rSet, aSel );
+ }
+ return nRes;
+}
+
+void SmTextForwarder::CopyText(const SvxTextForwarder& rSource)
+{
+
+ const SmTextForwarder* pSourceForwarder = dynamic_cast< const SmTextForwarder* >( &rSource );
+ if( !pSourceForwarder )
+ return;
+ EditEngine* pSourceEditEngine = pSourceForwarder->rEditAcc.GetEditEngine();
+ EditEngine *pEditEngine = rEditAcc.GetEditEngine();
+ if (pEditEngine && pSourceEditEngine )
+ {
+ EditTextObject* pNewTextObject = pSourceEditEngine->CreateTextObject();
+ pEditEngine->SetText( *pNewTextObject );
+ delete pNewTextObject;
+ }
+}
+
+//------------------------------------------------------------------------
+
+SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible& rAcc ) :
+ rEditAcc( rAcc )
+{
+}
+
+SmEditViewForwarder::~SmEditViewForwarder()
+{
+}
+
+sal_Bool SmEditViewForwarder::IsValid() const
+{
+ return rEditAcc.GetEditView() != 0;
+}
+
+Rectangle SmEditViewForwarder::GetVisArea() const
+{
+ Rectangle aRect(0,0,0,0);
+
+ EditView *pEditView = rEditAcc.GetEditView();
+ OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
+
+ if( pOutDev && pEditView)
+ {
+ Rectangle aVisArea = pEditView->GetVisArea();
+
+ // figure out map mode from edit engine
+ EditEngine* pEditEngine = pEditView->GetEditEngine();
+
+ if( pEditEngine )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ aVisArea = OutputDevice::LogicToLogic( aVisArea,
+ pEditEngine->GetRefMapMode(),
+ aMapMode.GetMapUnit() );
+ aMapMode.SetOrigin(Point());
+ aRect = pOutDev->LogicToPixel( aVisArea, aMapMode );
+ }
+ }
+
+ return aRect;
+}
+
+Point SmEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ EditView *pEditView = rEditAcc.GetEditView();
+ OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
+
+ if( pOutDev )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
+ aMapMode.GetMapUnit() ) );
+ aMapMode.SetOrigin(Point());
+ return pOutDev->LogicToPixel( aPoint, aMapMode );
+ }
+
+ return Point();
+}
+
+Point SmEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
+{
+ EditView *pEditView = rEditAcc.GetEditView();
+ OutputDevice* pOutDev = pEditView ? pEditView->GetWindow() : 0;
+
+ if( pOutDev )
+ {
+ MapMode aMapMode(pOutDev->GetMapMode());
+ aMapMode.SetOrigin(Point());
+ Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
+ return OutputDevice::LogicToLogic( aPoint,
+ aMapMode.GetMapUnit(),
+ rMapMode );
+ }
+
+ return Point();
+}
+
+sal_Bool SmEditViewForwarder::GetSelection( ESelection& rSelection ) const
+{
+ sal_Bool bRes = sal_False;
+ EditView *pEditView = rEditAcc.GetEditView();
+ if (pEditView)
+ {
+ rSelection = pEditView->GetSelection();
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+sal_Bool SmEditViewForwarder::SetSelection( const ESelection& rSelection )
+{
+ sal_Bool bRes = sal_False;
+ EditView *pEditView = rEditAcc.GetEditView();
+ if (pEditView)
+ {
+ pEditView->SetSelection( rSelection );
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+sal_Bool SmEditViewForwarder::Copy()
+{
+ sal_Bool bRes = sal_False;
+ EditView *pEditView = rEditAcc.GetEditView();
+ if (pEditView)
+ {
+ pEditView->Copy();
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+sal_Bool SmEditViewForwarder::Cut()
+{
+ sal_Bool bRes = sal_False;
+ EditView *pEditView = rEditAcc.GetEditView();
+ if (pEditView)
+ {
+ pEditView->Cut();
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+sal_Bool SmEditViewForwarder::Paste()
+{
+ sal_Bool bRes = sal_False;
+ EditView *pEditView = rEditAcc.GetEditView();
+ if (pEditView)
+ {
+ pEditView->Paste();
+ bRes = sal_True;
+ }
+ return bRes;
+}
+
+//------------------------------------------------------------------------
+
+SmEditAccessible::SmEditAccessible( SmEditWindow *pEditWin ) :
+ aAccName ( String(SmResId(STR_CMDBOXWINDOW)) ),
+ pTextHelper (0),
+ pWin (pEditWin)
+{
+ OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
+}
+
+
+SmEditAccessible::SmEditAccessible( const SmEditAccessible &rSmAcc ) :
+ SmEditAccessibleBaseClass(),
+ aAccName ( String(SmResId(STR_CMDBOXWINDOW)) )
+{
+ pWin = rSmAcc.pWin;
+ OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
+}
+
+SmEditAccessible::~SmEditAccessible()
+{
+ delete pTextHelper;
+}
+
+void SmEditAccessible::Init()
+{
+ OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
+ if (pWin)
+ {
+ EditEngine *pEditEngine = pWin->GetEditEngine();
+ EditView *pEditView = pWin->GetEditView();
+ if (pEditEngine && pEditView)
+ {
+ ::std::auto_ptr< SvxEditSource > pEditSource(
+ new SmEditSource( pWin, *this ) );
+ pTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource );
+ pTextHelper->SetEventSource( this );
+ }
+ }
+}
+
+void SmEditAccessible::ClearWin()
+{
+ // remove handler before current object gets destroyed
+ // (avoid handler being called for already dead object)
+ EditEngine *pEditEngine = GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->SetNotifyHdl( Link() );
+
+ pWin = 0; // implicitly results in AccessibleStateType::DEFUNC set
+
+ //! make TextHelper implicitly release C++ references to some core objects
+ pTextHelper->SetEditSource( ::std::auto_ptr<SvxEditSource>(NULL) );
+ //! make TextHelper release references
+ //! (e.g. the one set by the 'SetEventSource' call)
+ pTextHelper->Dispose();
+ delete pTextHelper; pTextHelper = 0;
+}
+
+// XAccessible
+uno::Reference< XAccessibleContext > SAL_CALL SmEditAccessible::getAccessibleContext( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return this;
+}
+
+// XAccessibleComponent
+sal_Bool SAL_CALL SmEditAccessible::containsPoint( const awt::Point& aPoint )
+ throw (RuntimeException)
+{
+ //! the arguments coordinates are relativ to the current window !
+ //! Thus the top left-point is (0, 0)
+
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+
+ Size aSz( pWin->GetSizePixel() );
+ return aPoint.X >= 0 && aPoint.Y >= 0 &&
+ aPoint.X < aSz.Width() && aPoint.Y < aSz.Height();
+}
+
+uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleAtPoint( const awt::Point& aPoint )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pTextHelper)
+ throw RuntimeException();
+ return pTextHelper->GetAt( aPoint );
+}
+
+awt::Rectangle SAL_CALL SmEditAccessible::getBounds( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+ OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
+ "mismatch of window parent and accessible parent" );
+ return lcl_GetBounds( pWin );
+}
+
+awt::Point SAL_CALL SmEditAccessible::getLocation( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+ OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
+ "mismatch of window parent and accessible parent" );
+ awt::Rectangle aRect( lcl_GetBounds( pWin ) );
+ return awt::Point( aRect.X, aRect.Y );
+}
+
+awt::Point SAL_CALL SmEditAccessible::getLocationOnScreen( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+ OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
+ "mismatch of window parent and accessible parent" );
+ return lcl_GetLocationOnScreen( pWin );
+}
+
+awt::Size SAL_CALL SmEditAccessible::getSize( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+ OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
+ "mismatch of window parent and accessible parent" );
+
+ Size aSz( pWin->GetSizePixel() );
+#if OSL_DEBUG_LEVEL > 1
+ awt::Rectangle aRect( lcl_GetBounds( pWin ) );
+ Size aSz2( aRect.Width, aRect.Height );
+ OSL_ENSURE( aSz == aSz2, "mismatch in width" );
+#endif
+ return awt::Size( aSz.Width(), aSz.Height() );
+}
+
+void SAL_CALL SmEditAccessible::grabFocus( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+
+ pWin->GrabFocus();
+}
+
+sal_Int32 SAL_CALL SmEditAccessible::getForeground()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ if (!pWin)
+ throw RuntimeException();
+ return (sal_Int32) pWin->GetTextColor().GetColor();
+}
+
+sal_Int32 SAL_CALL SmEditAccessible::getBackground()
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ if (!pWin)
+ throw RuntimeException();
+ Wallpaper aWall( pWin->GetDisplayBackground() );
+ ColorData nCol;
+ if (aWall.IsBitmap() || aWall.IsGradient())
+ nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
+ else
+ nCol = aWall.GetColor().GetColor();
+ return (sal_Int32) nCol;
+}
+
+// XAccessibleContext
+sal_Int32 SAL_CALL SmEditAccessible::getAccessibleChildCount( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pTextHelper)
+ throw RuntimeException();
+ return pTextHelper->GetChildCount();
+}
+
+uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleChild( sal_Int32 i )
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pTextHelper)
+ throw RuntimeException();
+ return pTextHelper->GetChild( i );
+}
+
+uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleParent( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pWin)
+ throw RuntimeException();
+
+ Window *pAccParent = pWin->GetAccessibleParentWindow();
+ OSL_ENSURE( pAccParent, "accessible parent missing" );
+ return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >();
+}
+
+sal_Int32 SAL_CALL SmEditAccessible::getAccessibleIndexInParent( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ sal_Int32 nIdx = -1;
+ Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : 0;
+ if (pAccParent)
+ {
+ sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount();
+ for (sal_uInt16 i = 0; i < nCnt && nIdx == -1; ++i)
+ if (pAccParent->GetAccessibleChildWindow( i ) == pWin)
+ nIdx = i;
+ }
+ return nIdx;
+}
+
+sal_Int16 SAL_CALL SmEditAccessible::getAccessibleRole( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return AccessibleRole::PANEL /*TEXT ?*/;
+}
+
+rtl::OUString SAL_CALL SmEditAccessible::getAccessibleDescription( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return OUString(); // empty as agreed with product-management
+}
+
+rtl::OUString SAL_CALL SmEditAccessible::getAccessibleName( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ // same name as displayed by the window when not docked
+ return aAccName;
+}
+
+uno::Reference< XAccessibleRelationSet > SAL_CALL SmEditAccessible::getAccessibleRelationSet( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper();
+ return xRelSet; // empty relation set
+}
+
+uno::Reference< XAccessibleStateSet > SAL_CALL SmEditAccessible::getAccessibleStateSet( )
+ throw (RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ ::utl::AccessibleStateSetHelper *pStateSet =
+ new ::utl::AccessibleStateSetHelper;
+
+ Reference<XAccessibleStateSet> xStateSet( pStateSet );
+
+ if (!pWin || !pTextHelper)
+ pStateSet->AddState( AccessibleStateType::DEFUNC );
+ else
+ {
+ pStateSet->AddState( AccessibleStateType::MULTI_LINE );
+ pStateSet->AddState( AccessibleStateType::ENABLED );
+ pStateSet->AddState( AccessibleStateType::FOCUSABLE );
+ if (pWin->HasFocus())
+ pStateSet->AddState( AccessibleStateType::FOCUSED );
+ if (pWin->IsActive())
+ pStateSet->AddState( AccessibleStateType::ACTIVE );
+ if (pWin->IsVisible())
+ pStateSet->AddState( AccessibleStateType::SHOWING );
+ if (pWin->IsReallyVisible())
+ pStateSet->AddState( AccessibleStateType::VISIBLE );
+ if (COL_TRANSPARENT != pWin->GetBackground().GetColor().GetColor())
+ pStateSet->AddState( AccessibleStateType::OPAQUE );
+ }
+
+ return xStateSet;
+}
+
+Locale SAL_CALL SmEditAccessible::getLocale( )
+ throw (IllegalAccessibleComponentStateException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ // should be the document language...
+ // We use the language of the localized symbol names here.
+ return Application::GetSettings().GetUILocale();
+}
+
+
+// XAccessibleEventBroadcaster
+void SAL_CALL SmEditAccessible::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
+ throw (RuntimeException)
+{
+ if (pTextHelper) // not disposing (about to destroy view shell)
+ pTextHelper->AddEventListener( xListener );
+}
+
+void SAL_CALL SmEditAccessible::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
+ throw (RuntimeException)
+{
+ if (pTextHelper) // not disposing (about to destroy view shell)
+ pTextHelper->RemoveEventListener( xListener );
+}
+
+OUString SAL_CALL SmEditAccessible::getImplementationName()
+ throw (RuntimeException)
+{
+ return A2OU("SmEditAccessible");
+}
+
+sal_Bool SAL_CALL SmEditAccessible::supportsService(
+ const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return rServiceName == A2OU( "com::sun::star::accessibility::Accessible" ) ||
+ rServiceName == A2OU( "com::sun::star::accessibility::AccessibleComponent" ) ||
+ rServiceName == A2OU( "com::sun::star::accessibility::AccessibleContext" );
+}
+
+Sequence< OUString > SAL_CALL SmEditAccessible::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ Sequence< OUString > aNames(3);
+ OUString *pNames = aNames.getArray();
+ pNames[0] = A2OU( "com::sun::star::accessibility::Accessible" );
+ pNames[1] = A2OU( "com::sun::star::accessibility::AccessibleComponent" );
+ pNames[2] = A2OU( "com::sun::star::accessibility::AccessibleContext" );
+ return aNames;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/accessibility.hxx b/starmath/source/accessibility.hxx
new file mode 100644
index 000000000000..a6b682b706fb
--- /dev/null
+++ b/starmath/source/accessibility.hxx
@@ -0,0 +1,402 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#ifndef _ACCESSIBILITY_HXX_
+#define _ACCESSIBILITY_HXX_
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <osl/mutex.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <cppuhelper/implbase5.hxx>
+#include <cppuhelper/implbase6.hxx>
+#include <svl/brdcst.hxx>
+
+#include <editeng/editeng.hxx>
+#include <editeng/unoedsrc.hxx> // SvxEditSource, SvxTextForwarder, SvxViewForwarder, SvxEditViewForwarder
+#include <svx/AccessibleTextHelper.hxx>
+#include <edit.hxx>
+
+class Window;
+class SmGraphicWindow;
+class SmEditWindow;
+class SmDocShell;
+
+namespace com { namespace sun { namespace star { namespace accessibility {
+struct AccessibleEventObject;
+}}}}
+
+//////////////////////////////////////////////////////////////////////
+//
+// classes and helper-classes used for accessibility in the graphic-window
+//
+
+typedef
+cppu::WeakImplHelper6
+ <
+ com::sun::star::lang::XServiceInfo,
+ com::sun::star::accessibility::XAccessible,
+ com::sun::star::accessibility::XAccessibleComponent,
+ com::sun::star::accessibility::XAccessibleContext,
+ com::sun::star::accessibility::XAccessibleText,
+ com::sun::star::accessibility::XAccessibleEventBroadcaster
+ >
+SmGraphicAccessibleBaseClass;
+
+class SmGraphicAccessible :
+ public SmGraphicAccessibleBaseClass
+{
+ osl::Mutex aListenerMutex;
+ String aAccName;
+ /// client id in the AccessibleEventNotifier queue
+ sal_uInt32 nClientId;
+
+ SmGraphicWindow *pWin;
+
+ // disallow copy-ctor and assignment-operator for now
+ SmGraphicAccessible( const SmGraphicAccessible & );
+ SmGraphicAccessible & operator = ( const SmGraphicAccessible & );
+
+protected:
+ SmDocShell * GetDoc_Impl();
+ String GetAccessibleText_Impl();
+
+public:
+ SmGraphicAccessible( SmGraphicWindow *pGraphicWin );
+ virtual ~SmGraphicAccessible();
+
+ SmGraphicWindow * GetWin() { return pWin; }
+ void ClearWin(); // to be called when view is destroyed
+ void LaunchEvent(
+ const sal_Int16 nAccesibleEventId,
+ const ::com::sun::star::uno::Any &rOldVal,
+ const ::com::sun::star::uno::Any &rNewVal);
+
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleText
+ virtual sal_Int32 SAL_CALL getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getIndexAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getSelectedText( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getText( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+//////////////////////////////////////////////////////////////////////
+//
+// classes and helper-classes used for accessibility in the command-window
+//
+
+class SmEditAccessible;
+class SmEditSource;
+class EditEngine;
+class EditView;
+class SvxFieldItem;
+struct ESelection;
+
+
+class SmViewForwarder :
+ public SvxViewForwarder
+{
+ SmEditAccessible & rEditAcc;
+
+ // disallow copy-ctor and assignment-operator for now
+ SmViewForwarder( const SmViewForwarder & );
+ SmViewForwarder & operator = ( const SmViewForwarder & );
+
+public:
+ SmViewForwarder( SmEditAccessible &rAcc );
+ virtual ~SmViewForwarder();
+
+ virtual sal_Bool IsValid() const;
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+};
+
+
+class SmTextForwarder : /* analog to SvxEditEngineForwarder */
+ public SvxTextForwarder
+{
+ SmEditAccessible & rEditAcc;
+ SmEditSource & rEditSource;
+
+ DECL_LINK( NotifyHdl, EENotify * );
+
+ // disallow copy-ctor and assignment-operator for now
+ SmTextForwarder( const SmTextForwarder & );
+ SmTextForwarder & operator = ( const SmTextForwarder & );
+
+public:
+ SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource );
+ virtual ~SmTextForwarder();
+
+ virtual sal_uInt16 GetParagraphCount() const;
+ virtual sal_uInt16 GetTextLen( sal_uInt16 nParagraph ) const;
+ virtual String GetText( const ESelection& rSel ) const;
+ virtual SfxItemSet GetAttribs( const ESelection& rSel, sal_Bool bOnlyHardAttrib = EditEngineAttribs_All ) const;
+ virtual SfxItemSet GetParaAttribs( sal_uInt16 nPara ) const;
+ virtual void SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rSet );
+ virtual void RemoveAttribs( const ESelection& rSelection, sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich );
+ virtual void GetPortions( sal_uInt16 nPara, SvUShorts& rList ) const;
+
+ virtual sal_uInt16 GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const;
+ virtual sal_uInt16 GetItemState( sal_uInt16 nPara, sal_uInt16 nWhich ) const;
+
+ virtual void QuickInsertText( const String& rText, const ESelection& rSel );
+ virtual void QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel );
+ virtual void QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel );
+ virtual void QuickInsertLineBreak( const ESelection& rSel );
+
+ virtual SfxItemPool* GetPool() const;
+
+ virtual XubString CalcFieldValue( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos, Color*& rpTxtColor, Color*& rpFldColor );
+ virtual void FieldClicked(const SvxFieldItem&, sal_uInt16, sal_uInt16);
+ virtual sal_Bool IsValid() const;
+
+ virtual LanguageType GetLanguage( sal_uInt16, sal_uInt16 ) const;
+ virtual sal_uInt16 GetFieldCount( sal_uInt16 nPara ) const;
+ virtual EFieldInfo GetFieldInfo( sal_uInt16 nPara, sal_uInt16 nField ) const;
+ virtual EBulletInfo GetBulletInfo( sal_uInt16 nPara ) const;
+ virtual Rectangle GetCharBounds( sal_uInt16 nPara, sal_uInt16 nIndex ) const;
+ virtual Rectangle GetParaBounds( sal_uInt16 nPara ) const;
+ virtual MapMode GetMapMode() const;
+ virtual OutputDevice* GetRefDevice() const;
+ virtual sal_Bool GetIndexAtPoint( const Point&, sal_uInt16& nPara, sal_uInt16& nIndex ) const;
+ virtual sal_Bool GetWordIndices( sal_uInt16 nPara, sal_uInt16 nIndex, sal_uInt16& nStart, sal_uInt16& nEnd ) const;
+ virtual sal_Bool GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_uInt16 nPara, sal_uInt16 nIndex ) const;
+ virtual sal_uInt16 GetLineCount( sal_uInt16 nPara ) const;
+ virtual sal_uInt16 GetLineLen( sal_uInt16 nPara, sal_uInt16 nLine ) const;
+ virtual void GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_uInt16 nParagraph, sal_uInt16 nLine ) const;
+ virtual sal_uInt16 GetLineNumberAtIndex( sal_uInt16 nPara, sal_uInt16 nLine ) const;
+ virtual sal_Bool Delete( const ESelection& );
+ virtual sal_Bool InsertText( const String&, const ESelection& );
+ virtual sal_Bool QuickFormatDoc( sal_Bool bFull=sal_False );
+
+ virtual sal_Int16 GetDepth( sal_uInt16 nPara ) const;
+ virtual sal_Bool SetDepth( sal_uInt16 nPara, sal_Int16 nNewDepth );
+
+ virtual const SfxItemSet* GetEmptyItemSetPtr();
+ // implementation functions for XParagraphAppend and XTextPortionAppend
+ virtual void AppendParagraph();
+ virtual xub_StrLen AppendTextPortion( sal_uInt16 nPara, const String &rText, const SfxItemSet &rSet );
+
+ virtual void CopyText(const SvxTextForwarder& rSource);
+};
+
+
+class SmEditViewForwarder : /* analog to SvxEditEngineViewForwarder */
+ public SvxEditViewForwarder
+{
+ SmEditAccessible& rEditAcc;
+
+ // disallow copy-ctor and assignment-operator for now
+ SmEditViewForwarder( const SmEditViewForwarder & );
+ SmEditViewForwarder & operator = ( const SmEditViewForwarder & );
+
+public:
+ SmEditViewForwarder( SmEditAccessible& rAcc );
+ virtual ~SmEditViewForwarder();
+
+ virtual sal_Bool IsValid() const;
+
+ virtual Rectangle GetVisArea() const;
+ virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const;
+ virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const;
+
+ virtual sal_Bool GetSelection( ESelection& rSelection ) const;
+ virtual sal_Bool SetSelection( const ESelection& rSelection );
+ virtual sal_Bool Copy();
+ virtual sal_Bool Cut();
+ virtual sal_Bool Paste();
+};
+
+
+class SmEditSource :
+ public SvxEditSource
+{
+ SfxBroadcaster aBroadCaster;
+ SmViewForwarder aViewFwd;
+ SmTextForwarder aTextFwd;
+ SmEditViewForwarder aEditViewFwd;
+
+ SmEditAccessible& rEditAcc;
+
+ // disallow copy-ctor and assignment-operator for now
+ SmEditSource( const SmEditSource &rSrc );
+ SmEditSource & operator = ( const SmEditSource & );
+
+public:
+ SmEditSource( SmEditWindow *pWin, SmEditAccessible &rAcc );
+ virtual ~SmEditSource();
+
+ virtual SvxEditSource* Clone() const;
+ virtual SvxTextForwarder* GetTextForwarder();
+ virtual SvxViewForwarder* GetViewForwarder();
+ virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate = sal_False );
+ virtual void UpdateData();
+ virtual SfxBroadcaster& GetBroadcaster() const;
+};
+
+
+
+
+typedef
+cppu::WeakImplHelper5
+ <
+ com::sun::star::lang::XServiceInfo,
+ com::sun::star::accessibility::XAccessible,
+ com::sun::star::accessibility::XAccessibleComponent,
+ com::sun::star::accessibility::XAccessibleContext,
+ com::sun::star::accessibility::XAccessibleEventBroadcaster
+ >
+SmEditAccessibleBaseClass;
+
+class SmEditAccessible :
+ public SmEditAccessibleBaseClass
+{
+ osl::Mutex aListenerMutex;
+ String aAccName;
+ ::accessibility::AccessibleTextHelper *pTextHelper;
+ SmEditWindow *pWin;
+
+ // disallow copy-ctor and assignment-operator for now
+ SmEditAccessible( const SmEditAccessible & );
+ SmEditAccessible & operator = ( const SmEditAccessible & );
+
+public:
+ SmEditAccessible( SmEditWindow *pEditWin );
+ virtual ~SmEditAccessible();
+
+ ::accessibility::AccessibleTextHelper * GetTextHelper() { return pTextHelper; }
+
+ void Init();
+ SmEditWindow * GetWin() { return pWin; }
+ void ClearWin(); // to be called when view is destroyed
+
+ //! access EditEngine and EditView via the functions in the respective window
+ //! pointers may be 0 (e.g. during reload)
+ EditEngine * GetEditEngine() { return pWin ? pWin->GetEditEngine() : 0; }
+ EditView * GetEditView() { return pWin ? pWin->GetEditView() : 0; }
+
+ // XAccessible
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleComponent
+ virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+//////////////////////////////////////////////////////////////////////
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/action.cxx b/starmath/source/action.cxx
new file mode 100644
index 000000000000..a7fbbc2a33bf
--- /dev/null
+++ b/starmath/source/action.cxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include "action.hxx"
+#include "smdll.hxx"
+#include "document.hxx"
+#include "starmath.hrc"
+
+
+SmFormatAction::SmFormatAction(SmDocShell *pDocSh,
+ const SmFormat& rOldFormat,
+ const SmFormat& rNewFormat) :
+ pDoc( pDocSh ),
+ aOldFormat( rOldFormat ),
+ aNewFormat( rNewFormat )
+{
+}
+
+void SmFormatAction::Undo()
+{
+ pDoc->SetFormat(aOldFormat);
+}
+
+void SmFormatAction::Redo()
+{
+ pDoc->SetFormat(aNewFormat);
+}
+
+void SmFormatAction::Repeat(SfxRepeatTarget& rDocSh)
+{
+ dynamic_cast< SmDocShell & >(rDocSh).SetFormat(aNewFormat);
+}
+
+UniString SmFormatAction::GetComment() const
+{
+ return (SmResId(RID_UNDOFORMATNAME));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/caret.cxx b/starmath/source/caret.cxx
new file mode 100644
index 000000000000..0fd781eb44b7
--- /dev/null
+++ b/starmath/source/caret.cxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Jonas Finnemann Jensen <jopsen@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jonas Finnemann Jensen <jopsen@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include "caret.hxx"
+
+/////////////////////////////// SmCaretPosGraph ////////////////////////////////
+
+SmCaretPosGraphEntry* SmCaretPosGraphIterator::Next(){
+ if(nOffset >= pGraph->nOffset){
+ if(pGraph->pNext){
+ pGraph = pGraph->pNext;
+ nOffset = 0;
+ pEntry = Next();
+ }else
+ pEntry = NULL;
+ }else
+ pEntry = pGraph->Graph + nOffset++;
+ return pEntry;
+}
+
+SmCaretPosGraphEntry* SmCaretPosGraph::Add(SmCaretPosGraphEntry entry){
+ if(nOffset >= SmCaretPosGraphSize){
+ if(!pNext)
+ pNext = new SmCaretPosGraph();
+ return pNext->Add(entry);
+ }else{
+ //Set Left and Right to point to the entry itself if they are NULL
+ entry.Left = entry.Left ? entry.Left : Graph + nOffset;
+ entry.Right = entry.Right ? entry.Right : Graph + nOffset;
+ //Save the entry
+ Graph[nOffset] = entry;
+ return Graph + nOffset++;
+ }
+}
+
+SmCaretPosGraph::~SmCaretPosGraph(){
+ if(pNext)
+ delete pNext;
+ pNext = NULL;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/cfgitem.cxx b/starmath/source/cfgitem.cxx
new file mode 100644
index 000000000000..cbbfa6d64761
--- /dev/null
+++ b/starmath/source/cfgitem.cxx
@@ -0,0 +1,1302 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <vcl/svapp.hxx>
+#include <sal/macros.h>
+#include "cfgitem.hxx"
+
+#include "starmath.hrc"
+#include "smdll.hxx"
+#include "format.hxx"
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+
+using ::rtl::OUString;
+
+
+static const char* aRootName = "Office.Math";
+
+#define SYMBOL_LIST "SymbolList"
+#define FONT_FORMAT_LIST "FontFormatList"
+
+/////////////////////////////////////////////////////////////////
+
+
+static Sequence< OUString > lcl_GetFontPropertyNames()
+{
+ static const char * aPropNames[] =
+ {
+ "Name",
+ "CharSet",
+ "Family",
+ "Pitch",
+ "Weight",
+ "Italic",
+ 0
+ };
+
+ const char** ppPropName = aPropNames;
+
+ Sequence< OUString > aNames( 6 );
+ OUString *pNames = aNames.getArray();
+ for( sal_Int32 i = 0; *ppPropName; ++i, ++ppPropName )
+ {
+ pNames[i] = A2OU( *ppPropName );
+ }
+ return aNames;
+}
+
+/////////////////////////////////////////////////////////////////
+
+
+static Sequence< OUString > lcl_GetSymbolPropertyNames()
+{
+ static const char * aPropNames[] =
+ {
+ "Char",
+ "Set",
+ "Predefined",
+ "FontFormatId",
+ 0
+ };
+
+ const char** ppPropName = aPropNames;
+
+ Sequence< OUString > aNames( 4 );
+ OUString *pNames = aNames.getArray();
+ for( sal_Int32 i = 0; *ppPropName; ++i, ++ppPropName )
+ {
+ pNames[i] = A2OU( *ppPropName );
+ }
+ return aNames;
+}
+
+/////////////////////////////////////////////////////////////////
+
+static const char * aMathPropNames[] =
+{
+ "Print/Title",
+ "Print/FormulaText",
+ "Print/Frame",
+ "Print/Size",
+ "Print/ZoomFactor",
+ "LoadSave/IsSaveOnlyUsedSymbols",
+ //"Misc/NoSymbolsWarning", @deprecated
+ "Misc/IgnoreSpacesRight",
+ "View/ToolboxVisible",
+ "View/AutoRedraw",
+ "View/FormulaCursor"
+};
+
+
+//! Beware of order according to *_BEGIN *_END defines in format.hxx !
+//! see respective load/save routines here
+static const char * aFormatPropNames[] =
+{
+ "StandardFormat/Textmode",
+ "StandardFormat/GreekCharStyle",
+ "StandardFormat/ScaleNormalBracket",
+ "StandardFormat/HorizontalAlignment",
+ "StandardFormat/BaseSize",
+ "StandardFormat/TextSize",
+ "StandardFormat/IndexSize",
+ "StandardFormat/FunctionSize",
+ "StandardFormat/OperatorSize",
+ "StandardFormat/LimitsSize",
+ "StandardFormat/Distance/Horizontal",
+ "StandardFormat/Distance/Vertical",
+ "StandardFormat/Distance/Root",
+ "StandardFormat/Distance/SuperScript",
+ "StandardFormat/Distance/SubScript",
+ "StandardFormat/Distance/Numerator",
+ "StandardFormat/Distance/Denominator",
+ "StandardFormat/Distance/Fraction",
+ "StandardFormat/Distance/StrokeWidth",
+ "StandardFormat/Distance/UpperLimit",
+ "StandardFormat/Distance/LowerLimit",
+ "StandardFormat/Distance/BracketSize",
+ "StandardFormat/Distance/BracketSpace",
+ "StandardFormat/Distance/MatrixRow",
+ "StandardFormat/Distance/MatrixColumn",
+ "StandardFormat/Distance/OrnamentSize",
+ "StandardFormat/Distance/OrnamentSpace",
+ "StandardFormat/Distance/OperatorSize",
+ "StandardFormat/Distance/OperatorSpace",
+ "StandardFormat/Distance/LeftSpace",
+ "StandardFormat/Distance/RightSpace",
+ "StandardFormat/Distance/TopSpace",
+ "StandardFormat/Distance/BottomSpace",
+ "StandardFormat/Distance/NormalBracketSize",
+ "StandardFormat/VariableFont",
+ "StandardFormat/FunctionFont",
+ "StandardFormat/NumberFont",
+ "StandardFormat/TextFont",
+ "StandardFormat/SerifFont",
+ "StandardFormat/SansFont",
+ "StandardFormat/FixedFont"
+};
+
+
+static Sequence< OUString > lcl_GetPropertyNames(
+ const char * aPropNames[], sal_uInt16 nCount )
+{
+
+ const char** ppPropName = aPropNames;
+
+ Sequence< OUString > aNames( nCount );
+ OUString *pNames = aNames.getArray();
+ for (sal_Int32 i = 0; i < nCount; ++i, ++ppPropName)
+ {
+ pNames[i] = A2OU( *ppPropName );
+ }
+ return aNames;
+}
+
+
+static Sequence< OUString > GetFormatPropertyNames()
+{
+ sal_uInt16 nCnt = SAL_N_ELEMENTS(aFormatPropNames);
+ return lcl_GetPropertyNames( aFormatPropNames, nCnt );
+}
+
+
+static Sequence< OUString > GetOtherPropertyNames()
+{
+ sal_uInt16 nCnt = SAL_N_ELEMENTS(aMathPropNames);
+ return lcl_GetPropertyNames( aMathPropNames, nCnt );
+}
+
+/////////////////////////////////////////////////////////////////
+
+struct SmCfgOther
+{
+ SmPrintSize ePrintSize;
+ sal_uInt16 nPrintZoomFactor;
+ bool bPrintTitle;
+ bool bPrintFormulaText;
+ bool bPrintFrame;
+ bool bIsSaveOnlyUsedSymbols;
+ bool bIgnoreSpacesRight;
+ bool bToolboxVisible;
+ bool bAutoRedraw;
+ bool bFormulaCursor;
+ //sal_Bool bNoSymbolsWarning;
+
+ SmCfgOther();
+};
+
+
+SmCfgOther::SmCfgOther()
+{
+ ePrintSize = PRINT_SIZE_NORMAL;
+ nPrintZoomFactor = 100;
+ bPrintTitle = bPrintFormulaText =
+ bPrintFrame = bIgnoreSpacesRight =
+ bToolboxVisible = bAutoRedraw =
+ bFormulaCursor = bIsSaveOnlyUsedSymbols = true;
+}
+
+/////////////////////////////////////////////////////////////////
+
+
+SmFontFormat::SmFontFormat()
+{
+ aName.AssignAscii( FONTNAME_MATH );
+ nCharSet = RTL_TEXTENCODING_UNICODE;
+ nFamily = FAMILY_DONTKNOW;
+ nPitch = PITCH_DONTKNOW;
+ nWeight = WEIGHT_DONTKNOW;
+ nItalic = ITALIC_NONE;
+}
+
+
+SmFontFormat::SmFontFormat( const Font &rFont )
+{
+ aName = rFont.GetName();
+ nCharSet = (sal_Int16) rFont.GetCharSet();
+ nFamily = (sal_Int16) rFont.GetFamily();
+ nPitch = (sal_Int16) rFont.GetPitch();
+ nWeight = (sal_Int16) rFont.GetWeight();
+ nItalic = (sal_Int16) rFont.GetItalic();
+}
+
+
+const Font SmFontFormat::GetFont() const
+{
+ Font aRes;
+ aRes.SetName( aName );
+ aRes.SetCharSet( (rtl_TextEncoding) nCharSet );
+ aRes.SetFamily( (FontFamily) nFamily );
+ aRes.SetPitch( (FontPitch) nPitch );
+ aRes.SetWeight( (FontWeight) nWeight );
+ aRes.SetItalic( (FontItalic) nItalic );
+ return aRes;
+}
+
+
+bool SmFontFormat::operator == ( const SmFontFormat &rFntFmt ) const
+{
+ return aName == rFntFmt.aName &&
+ nCharSet == rFntFmt.nCharSet &&
+ nFamily == rFntFmt.nFamily &&
+ nPitch == rFntFmt.nPitch &&
+ nWeight == rFntFmt.nWeight &&
+ nItalic == rFntFmt.nItalic;
+}
+
+
+/////////////////////////////////////////////////////////////////
+
+SmFntFmtListEntry::SmFntFmtListEntry( const String &rId, const SmFontFormat &rFntFmt ) :
+ aId (rId),
+ aFntFmt (rFntFmt)
+{
+}
+
+
+SmFontFormatList::SmFontFormatList()
+{
+ bModified = false;
+}
+
+
+void SmFontFormatList::Clear()
+{
+ if (!aEntries.empty())
+ {
+ aEntries.clear();
+ SetModified( true );
+ }
+}
+
+
+void SmFontFormatList::AddFontFormat( const String &rFntFmtId,
+ const SmFontFormat &rFntFmt )
+{
+ const SmFontFormat *pFntFmt = GetFontFormat( rFntFmtId );
+ OSL_ENSURE( !pFntFmt, "FontFormatId already exists" );
+ if (!pFntFmt)
+ {
+ SmFntFmtListEntry aEntry( rFntFmtId, rFntFmt );
+ aEntries.push_back( aEntry );
+ SetModified( true );
+ }
+}
+
+
+void SmFontFormatList::RemoveFontFormat( const String &rFntFmtId )
+{
+
+ // search for entry
+ for (size_t i = 0; i < aEntries.size(); ++i)
+ {
+ if (aEntries[i].aId == rFntFmtId)
+ {
+ // remove entry if found
+ aEntries.erase( aEntries.begin() + i );
+ SetModified( true );
+ break;
+ }
+ }
+}
+
+
+const SmFontFormat * SmFontFormatList::GetFontFormat( const String &rFntFmtId ) const
+{
+ const SmFontFormat *pRes = 0;
+
+ for (size_t i = 0; i < aEntries.size(); ++i)
+ {
+ if (aEntries[i].aId == rFntFmtId)
+ {
+ pRes = &aEntries[i].aFntFmt;
+ break;
+ }
+ }
+
+ return pRes;
+}
+
+
+
+const SmFontFormat * SmFontFormatList::GetFontFormat( size_t nPos ) const
+{
+ const SmFontFormat *pRes = 0;
+ if (nPos < aEntries.size())
+ pRes = &aEntries[nPos].aFntFmt;
+ return pRes;
+}
+
+
+const String SmFontFormatList::GetFontFormatId( const SmFontFormat &rFntFmt ) const
+{
+ String aRes;
+
+ for (size_t i = 0; i < aEntries.size(); ++i)
+ {
+ if (aEntries[i].aFntFmt == rFntFmt)
+ {
+ aRes = aEntries[i].aId;
+ break;
+ }
+ }
+
+ return aRes;
+}
+
+
+const String SmFontFormatList::GetFontFormatId( const SmFontFormat &rFntFmt, bool bAdd )
+{
+ String aRes( GetFontFormatId( rFntFmt) );
+ if (0 == aRes.Len() && bAdd)
+ {
+ aRes = GetNewFontFormatId();
+ AddFontFormat( aRes, rFntFmt );
+ }
+ return aRes;
+}
+
+
+const String SmFontFormatList::GetFontFormatId( size_t nPos ) const
+{
+ String aRes;
+ if (nPos < aEntries.size())
+ aRes = aEntries[nPos].aId;
+ return aRes;
+}
+
+
+const String SmFontFormatList::GetNewFontFormatId() const
+{
+ // returns first unused FormatId
+
+ String aRes;
+
+ String aPrefix( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
+ sal_Int32 nCnt = GetCount();
+ for (sal_Int32 i = 1; i <= nCnt + 1; ++i)
+ {
+ String aTmpId( aPrefix );
+ aTmpId += String::CreateFromInt32( i );
+ if (!GetFontFormat( aTmpId ))
+ {
+ aRes = aTmpId;
+ break;
+ }
+ }
+ OSL_ENSURE( 0 != aRes.Len(), "failed to create new FontFormatId" );
+
+ return aRes;
+}
+
+/////////////////////////////////////////////////////////////////
+
+SmMathConfig::SmMathConfig() :
+ ConfigItem( String::CreateFromAscii( aRootName ))
+{
+ pFormat = 0;
+ pOther = 0;
+ pFontFormatList = 0;
+ pSymbolMgr = 0;
+
+ bIsOtherModified = bIsFormatModified = false;
+}
+
+
+SmMathConfig::~SmMathConfig()
+{
+ Save();
+ delete pFormat;
+ delete pOther;
+ delete pFontFormatList;
+ delete pSymbolMgr;
+}
+
+
+void SmMathConfig::SetOtherModified( bool bVal )
+{
+ bIsOtherModified = bVal;
+}
+
+
+void SmMathConfig::SetFormatModified( bool bVal )
+{
+ bIsFormatModified = bVal;
+}
+
+
+void SmMathConfig::SetFontFormatListModified( bool bVal )
+{
+ if (pFontFormatList)
+ pFontFormatList->SetModified( bVal );
+}
+
+
+void SmMathConfig::ReadSymbol( SmSym &rSymbol,
+ const rtl::OUString &rSymbolName,
+ const rtl::OUString &rBaseNode ) const
+{
+ Sequence< OUString > aNames = lcl_GetSymbolPropertyNames();
+ sal_Int32 nProps = aNames.getLength();
+
+ OUString aDelim( OUString::valueOf( (sal_Unicode) '/' ) );
+ OUString *pName = aNames.getArray();
+ for (sal_Int32 i = 0; i < nProps; ++i)
+ {
+ OUString &rName = pName[i];
+ OUString aTmp( rName );
+ rName = rBaseNode;
+ rName += aDelim;
+ rName += rSymbolName;
+ rName += aDelim;
+ rName += aTmp;
+ }
+
+ const Sequence< Any > aValues = ((SmMathConfig*) this)->GetProperties( aNames );
+
+ if (nProps && aValues.getLength() == nProps)
+ {
+ const Any * pValue = aValues.getConstArray();
+ Font aFont;
+ sal_UCS4 cChar = '\0';
+ String aSet;
+ bool bPredefined = false;
+
+ OUString aTmpStr;
+ sal_Int32 nTmp32 = 0;
+ bool bTmp = false;
+
+ bool bOK = true;
+ if (pValue->hasValue() && (*pValue >>= nTmp32))
+ cChar = static_cast< sal_UCS4 >( nTmp32 );
+ else
+ bOK = false;
+ ++pValue;
+ if (pValue->hasValue() && (*pValue >>= aTmpStr))
+ aSet = aTmpStr;
+ else
+ bOK = false;
+ ++pValue;
+ if (pValue->hasValue() && (*pValue >>= bTmp))
+ bPredefined = bTmp;
+ else
+ bOK = false;
+ ++pValue;
+ if (pValue->hasValue() && (*pValue >>= aTmpStr))
+ {
+ const SmFontFormat *pFntFmt = GetFontFormatList().GetFontFormat( aTmpStr );
+ OSL_ENSURE( pFntFmt, "unknown FontFormat" );
+ if (pFntFmt)
+ aFont = pFntFmt->GetFont();
+ }
+ else
+ bOK = false;
+ ++pValue;
+
+ if (bOK)
+ {
+ String aUiName( rSymbolName );
+ String aUiSetName( aSet );
+ if (bPredefined)
+ {
+ String aTmp;
+ aTmp = GetUiSymbolName( rSymbolName );
+ OSL_ENSURE( aTmp.Len(), "localized symbol-name not found" );
+ if (aTmp.Len())
+ aUiName = aTmp;
+ aTmp = GetUiSymbolSetName( aSet );
+ OSL_ENSURE( aTmp.Len(), "localized symbolset-name not found" );
+ if (aTmp.Len())
+ aUiSetName = aTmp;
+ }
+
+ rSymbol = SmSym( aUiName, aFont, cChar, aUiSetName, bPredefined );
+ if (aUiName != String(rSymbolName))
+ rSymbol.SetExportName( rSymbolName );
+ }
+ else
+ {
+ OSL_FAIL( "symbol read error" );
+ }
+ }
+}
+
+
+SmSymbolManager & SmMathConfig::GetSymbolManager()
+{
+ if (!pSymbolMgr)
+ {
+ pSymbolMgr = new SmSymbolManager;
+ pSymbolMgr->Load();
+ }
+ return *pSymbolMgr;
+}
+
+
+void SmMathConfig::Commit()
+{
+ Save();
+}
+
+
+void SmMathConfig::Save()
+{
+ SaveOther();
+ SaveFormat();
+ SaveFontFormatList();
+}
+
+
+void SmMathConfig::GetSymbols( std::vector< SmSym > &rSymbols ) const
+{
+ Sequence< OUString > aNodes( ((SmMathConfig*) this)->GetNodeNames( A2OU( SYMBOL_LIST ) ) );
+ const OUString *pNode = aNodes.getConstArray();
+ sal_Int32 nNodes = aNodes.getLength();
+
+ rSymbols.resize( nNodes );
+ std::vector< SmSym >::iterator aIt( rSymbols.begin() );
+ std::vector< SmSym >::iterator aEnd( rSymbols.end() );
+ while (aIt != aEnd)
+ {
+ ReadSymbol( *aIt++, *pNode++, A2OU( SYMBOL_LIST ) );
+ }
+}
+
+
+void SmMathConfig::SetSymbols( const std::vector< SmSym > &rNewSymbols )
+{
+ sal_uIntPtr nCount = rNewSymbols.size();
+
+ Sequence< OUString > aNames = lcl_GetSymbolPropertyNames();
+ const OUString *pNames = aNames.getConstArray();
+ sal_uIntPtr nSymbolProps = sal::static_int_cast< sal_uInt32 >(aNames.getLength());
+
+ Sequence< PropertyValue > aValues( nCount * nSymbolProps );
+ PropertyValue *pValues = aValues.getArray();
+
+ PropertyValue *pVal = pValues;
+ OUString aDelim( OUString::valueOf( (sal_Unicode) '/' ) );
+ std::vector< SmSym >::const_iterator aIt( rNewSymbols.begin() );
+ std::vector< SmSym >::const_iterator aEnd( rNewSymbols.end() );
+ while (aIt != aEnd)
+ {
+ const SmSym &rSymbol = *aIt++;
+ OUString aNodeNameDelim( A2OU( SYMBOL_LIST ) );
+ aNodeNameDelim += aDelim;
+ aNodeNameDelim += rSymbol.GetExportName();
+ aNodeNameDelim += aDelim;
+
+ const OUString *pName = pNames;
+
+ // Char
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= static_cast< sal_UCS4 >( rSymbol.GetCharacter() );
+ pVal++;
+ // Set
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ OUString aTmp( rSymbol.GetSymbolSetName() );
+ if (rSymbol.IsPredefined())
+ aTmp = GetExportSymbolSetName( aTmp );
+ pVal->Value <<= aTmp;
+ pVal++;
+ // Predefined
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= (sal_Bool) rSymbol.IsPredefined();
+ pVal++;
+ // FontFormatId
+ SmFontFormat aFntFmt( rSymbol.GetFace() );
+ String aFntFmtId( GetFontFormatList().GetFontFormatId( aFntFmt, true ) );
+ OSL_ENSURE( aFntFmtId.Len(), "FontFormatId not found" );
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= OUString( aFntFmtId );
+ pVal++;
+ }
+ OSL_ENSURE( pVal - pValues == sal::static_int_cast< ptrdiff_t >(nCount * nSymbolProps), "properties missing" );
+ ReplaceSetProperties( A2OU( SYMBOL_LIST ) , aValues );
+
+ StripFontFormatList( rNewSymbols );
+ SaveFontFormatList();
+}
+
+
+SmFontFormatList & SmMathConfig::GetFontFormatList()
+{
+ if (!pFontFormatList)
+ {
+ LoadFontFormatList();
+ }
+ return *pFontFormatList;
+}
+
+
+void SmMathConfig::LoadFontFormatList()
+{
+ if (!pFontFormatList)
+ pFontFormatList = new SmFontFormatList;
+ else
+ pFontFormatList->Clear();
+
+ Sequence< OUString > aNodes( GetNodeNames( A2OU( FONT_FORMAT_LIST ) ) );
+ const OUString *pNode = aNodes.getConstArray();
+ sal_Int32 nNodes = aNodes.getLength();
+
+ for (sal_Int32 i = 0; i < nNodes; ++i)
+ {
+ SmFontFormat aFntFmt;
+ ReadFontFormat( aFntFmt, pNode[i], A2OU( FONT_FORMAT_LIST ) );
+ if (!pFontFormatList->GetFontFormat( pNode[i] ))
+ {
+ OSL_ENSURE( 0 == pFontFormatList->GetFontFormat( pNode[i] ),
+ "FontFormat ID already exists" );
+ pFontFormatList->AddFontFormat( pNode[i], aFntFmt );
+ }
+ }
+ pFontFormatList->SetModified( false );
+}
+
+
+void SmMathConfig::ReadFontFormat( SmFontFormat &rFontFormat,
+ const OUString &rSymbolName, const OUString &rBaseNode ) const
+{
+ Sequence< OUString > aNames = lcl_GetFontPropertyNames();
+ sal_Int32 nProps = aNames.getLength();
+
+ OUString aDelim( OUString::valueOf( (sal_Unicode) '/' ) );
+ OUString *pName = aNames.getArray();
+ for (sal_Int32 i = 0; i < nProps; ++i)
+ {
+ OUString &rName = pName[i];
+ OUString aTmp( rName );
+ rName = rBaseNode;
+ rName += aDelim;
+ rName += rSymbolName;
+ rName += aDelim;
+ rName += aTmp;
+ }
+
+ const Sequence< Any > aValues = ((SmMathConfig*) this)->GetProperties( aNames );
+
+ if (nProps && aValues.getLength() == nProps)
+ {
+ const Any * pValue = aValues.getConstArray();
+
+ OUString aTmpStr;
+ sal_Int16 nTmp16 = 0;
+
+ bool bOK = true;
+ if (pValue->hasValue() && (*pValue >>= aTmpStr))
+ rFontFormat.aName = aTmpStr;
+ else
+ bOK = false;
+ ++pValue;
+ if (pValue->hasValue() && (*pValue >>= nTmp16))
+ rFontFormat.nCharSet = nTmp16; // 6.0 file-format GetSOLoadTextEncoding not needed
+ else
+ bOK = false;
+ ++pValue;
+ if (pValue->hasValue() && (*pValue >>= nTmp16))
+ rFontFormat.nFamily = nTmp16;
+ else
+ bOK = false;
+ ++pValue;
+ if (pValue->hasValue() && (*pValue >>= nTmp16))
+ rFontFormat.nPitch = nTmp16;
+ else
+ bOK = false;
+ ++pValue;
+ if (pValue->hasValue() && (*pValue >>= nTmp16))
+ rFontFormat.nWeight = nTmp16;
+ else
+ bOK = false;
+ ++pValue;
+ if (pValue->hasValue() && (*pValue >>= nTmp16))
+ rFontFormat.nItalic = nTmp16;
+ else
+ bOK = false;
+ ++pValue;
+
+ OSL_ENSURE( bOK, "read FontFormat failed" );
+ (void)bOK;
+ }
+}
+
+
+void SmMathConfig::SaveFontFormatList()
+{
+ SmFontFormatList &rFntFmtList = GetFontFormatList();
+
+ if (!rFntFmtList.IsModified())
+ return;
+
+ Sequence< OUString > aNames = lcl_GetFontPropertyNames();
+ sal_Int32 nSymbolProps = aNames.getLength();
+
+ size_t nCount = rFntFmtList.GetCount();
+
+ Sequence< PropertyValue > aValues( nCount * nSymbolProps );
+ PropertyValue *pValues = aValues.getArray();
+
+ PropertyValue *pVal = pValues;
+ OUString aDelim( OUString::valueOf( (sal_Unicode) '/' ) );
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ String aFntFmtId( rFntFmtList.GetFontFormatId( i ) );
+ const SmFontFormat aFntFmt( *rFntFmtList.GetFontFormat( aFntFmtId ) );
+
+ OUString aNodeNameDelim( A2OU( FONT_FORMAT_LIST ) );
+ aNodeNameDelim += aDelim;
+ aNodeNameDelim += aFntFmtId;
+ aNodeNameDelim += aDelim;
+
+ const OUString *pName = aNames.getConstArray();;
+
+ // Name
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= OUString( aFntFmt.aName );
+ pVal++;
+ // CharSet
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= (sal_Int16) aFntFmt.nCharSet; // 6.0 file-format GetSOStoreTextEncoding not needed
+ pVal++;
+ // Family
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= (sal_Int16) aFntFmt.nFamily;
+ pVal++;
+ // Pitch
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= (sal_Int16) aFntFmt.nPitch;
+ pVal++;
+ // Weight
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= (sal_Int16) aFntFmt.nWeight;
+ pVal++;
+ // Italic
+ pVal->Name = aNodeNameDelim;
+ pVal->Name += *pName++;
+ pVal->Value <<= (sal_Int16) aFntFmt.nItalic;
+ pVal++;
+ }
+ OSL_ENSURE( sal::static_int_cast<size_t>(pVal - pValues) == nCount * nSymbolProps, "properties missing" );
+ ReplaceSetProperties( A2OU( FONT_FORMAT_LIST ) , aValues );
+
+ rFntFmtList.SetModified( false );
+}
+
+
+void SmMathConfig::StripFontFormatList( const std::vector< SmSym > &rSymbols )
+{
+ size_t i;
+
+ // build list of used font-formats only
+ //!! font-format IDs may be different !!
+ SmFontFormatList aUsedList;
+ for (i = 0; i < rSymbols.size(); ++i)
+ {
+ OSL_ENSURE( rSymbols[i].GetName().Len() > 0, "non named symbol" );
+ aUsedList.GetFontFormatId( SmFontFormat( rSymbols[i].GetFace() ) , true );
+ }
+ const SmFormat & rStdFmt = GetStandardFormat();
+ for (i = FNT_BEGIN; i <= FNT_END; ++i)
+ {
+ aUsedList.GetFontFormatId( SmFontFormat( rStdFmt.GetFont( i ) ) , true );
+ }
+
+ // remove unused font-formats from list
+ SmFontFormatList &rFntFmtList = GetFontFormatList();
+ size_t nCnt = rFntFmtList.GetCount();
+ SmFontFormat *pTmpFormat = new SmFontFormat[ nCnt ];
+ String *pId = new String [ nCnt ];
+ size_t k;
+ for (k = 0; k < nCnt; ++k)
+ {
+ pTmpFormat[k] = *rFntFmtList.GetFontFormat( k );
+ pId[k] = rFntFmtList.GetFontFormatId( k );
+ }
+ for (k = 0; k < nCnt; ++k)
+ {
+ if (0 == aUsedList.GetFontFormatId( pTmpFormat[k] ).Len())
+ {
+ rFntFmtList.RemoveFontFormat( pId[k] );
+ }
+ }
+ delete [] pId;
+ delete [] pTmpFormat;
+}
+
+
+void SmMathConfig::LoadOther()
+{
+ if (!pOther)
+ pOther = new SmCfgOther;
+
+ Sequence< OUString > aNames( GetOtherPropertyNames() );
+ sal_Int32 nProps = aNames.getLength();
+
+ Sequence< Any > aValues( GetProperties( aNames ) );
+ if (nProps && aValues.getLength() == nProps)
+ {
+ const Any *pValues = aValues.getConstArray();
+ const Any *pVal = pValues;
+
+ sal_Int16 nTmp16 = 0;
+ bool bTmp = false;
+
+ // Print/Title
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pOther->bPrintTitle = bTmp;
+ ++pVal;
+ // Print/FormulaText
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pOther->bPrintFormulaText = bTmp;
+ ++pVal;
+ // Print/Frame
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pOther->bPrintFrame = bTmp;
+ ++pVal;
+ // Print/Size
+ if (pVal->hasValue() && (*pVal >>= nTmp16))
+ pOther->ePrintSize = (SmPrintSize) nTmp16;
+ ++pVal;
+ // Print/ZoomFactor
+ if (pVal->hasValue() && (*pVal >>= nTmp16))
+ pOther->nPrintZoomFactor = nTmp16;
+ ++pVal;
+ // LoadSave/IsSaveOnlyUsedSymbols
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pOther->bIsSaveOnlyUsedSymbols = bTmp;
+ ++pVal;
+ // Misc/IgnoreSpacesRight
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pOther->bIgnoreSpacesRight = bTmp;
+ ++pVal;
+ // View/ToolboxVisible
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pOther->bToolboxVisible = bTmp;
+ ++pVal;
+ // View/AutoRedraw
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pOther->bAutoRedraw = bTmp;
+ ++pVal;
+ // View/FormulaCursor
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pOther->bFormulaCursor = bTmp;
+ ++pVal;
+
+ OSL_ENSURE( pVal - pValues == nProps, "property mismatch" );
+ SetOtherModified( false );
+ }
+}
+
+
+void SmMathConfig::SaveOther()
+{
+ if (!pOther || !IsOtherModified())
+ return;
+
+ const Sequence< OUString > aNames( GetOtherPropertyNames() );
+ sal_Int32 nProps = aNames.getLength();
+
+ Sequence< Any > aValues( nProps );
+ Any *pValues = aValues.getArray();
+ Any *pValue = pValues;
+
+ // Print/Title
+ *pValue++ <<= (sal_Bool) pOther->bPrintTitle;
+ // Print/FormulaText
+ *pValue++ <<= (sal_Bool) pOther->bPrintFormulaText;
+ // Print/Frame
+ *pValue++ <<= (sal_Bool) pOther->bPrintFrame;
+ // Print/Size
+ *pValue++ <<= (sal_Int16) pOther->ePrintSize;
+ // Print/ZoomFactor
+ *pValue++ <<= (sal_Int16) pOther->nPrintZoomFactor;
+ // LoadSave/IsSaveOnlyUsedSymbols
+ *pValue++ <<= (sal_Bool) pOther->bIsSaveOnlyUsedSymbols;
+ // Misc/IgnoreSpacesRight
+ *pValue++ <<= (sal_Bool) pOther->bIgnoreSpacesRight;
+ // View/ToolboxVisible
+ *pValue++ <<= (sal_Bool) pOther->bToolboxVisible;
+ // View/AutoRedraw
+ *pValue++ <<= (sal_Bool) pOther->bAutoRedraw;
+ // View/FormulaCursor
+ *pValue++ <<= (sal_Bool) pOther->bFormulaCursor;
+
+ OSL_ENSURE( pValue - pValues == nProps, "property mismatch" );
+ PutProperties( aNames , aValues );
+
+ SetOtherModified( false );
+}
+
+void SmMathConfig::LoadFormat()
+{
+ if (!pFormat)
+ pFormat = new SmFormat;
+
+
+ Sequence< OUString > aNames( GetFormatPropertyNames() );
+ sal_Int32 nProps = aNames.getLength();
+
+ Sequence< Any > aValues( GetProperties( aNames ) );
+ if (nProps && aValues.getLength() == nProps)
+ {
+ const Any *pValues = aValues.getConstArray();
+ const Any *pVal = pValues;
+
+ OUString aTmpStr;
+ sal_Int16 nTmp16 = 0;
+ bool bTmp = false;
+
+ // StandardFormat/Textmode
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pFormat->SetTextmode( bTmp );
+ ++pVal;
+ // StandardFormat/GreekCharStyle
+ if (pVal->hasValue() && (*pVal >>= nTmp16))
+ pFormat->SetGreekCharStyle( nTmp16 );
+ ++pVal;
+ // StandardFormat/ScaleNormalBracket
+ if (pVal->hasValue() && (*pVal >>= bTmp))
+ pFormat->SetScaleNormalBrackets( bTmp );
+ ++pVal;
+ // StandardFormat/HorizontalAlignment
+ if (pVal->hasValue() && (*pVal >>= nTmp16))
+ pFormat->SetHorAlign( (SmHorAlign) nTmp16 );
+ ++pVal;
+ // StandardFormat/BaseSize
+ if (pVal->hasValue() && (*pVal >>= nTmp16))
+ pFormat->SetBaseSize( Size(0, SmPtsTo100th_mm( nTmp16 )) );
+ ++pVal;
+
+ sal_uInt16 i;
+ for (i = SIZ_BEGIN; i <= SIZ_END; ++i)
+ {
+ if (pVal->hasValue() && (*pVal >>= nTmp16))
+ pFormat->SetRelSize( i, nTmp16 );
+ ++pVal;
+ }
+
+ for (i = DIS_BEGIN; i <= DIS_END; ++i)
+ {
+ if (pVal->hasValue() && (*pVal >>= nTmp16))
+ pFormat->SetDistance( i, nTmp16 );
+ ++pVal;
+ }
+
+ LanguageType nLang = Application::GetSettings().GetUILanguage();
+ for (i = FNT_BEGIN; i < FNT_END; ++i)
+ {
+ Font aFnt;
+ bool bUseDefaultFont = true;
+ if (pVal->hasValue() && (*pVal >>= aTmpStr))
+ {
+ bUseDefaultFont = 0 == aTmpStr.getLength();
+ if (bUseDefaultFont)
+ {
+ aFnt = pFormat->GetFont( i );
+ aFnt.SetName( GetDefaultFontName( nLang, i ) );
+ }
+ else
+ {
+ const SmFontFormat *pFntFmt = GetFontFormatList().GetFontFormat( aTmpStr );
+ OSL_ENSURE( pFntFmt, "unknown FontFormat" );
+ if (pFntFmt)
+ aFnt = pFntFmt->GetFont();
+ }
+ }
+ ++pVal;
+
+ aFnt.SetSize( pFormat->GetBaseSize() );
+ pFormat->SetFont( i, aFnt, bUseDefaultFont );
+ }
+
+ OSL_ENSURE( pVal - pValues == nProps, "property mismatch" );
+ SetFormatModified( false );
+ }
+}
+
+
+void SmMathConfig::SaveFormat()
+{
+ if (!pFormat || !IsFormatModified())
+ return;
+
+ const Sequence< OUString > aNames( GetFormatPropertyNames() );
+ sal_Int32 nProps = aNames.getLength();
+
+ Sequence< Any > aValues( nProps );
+ Any *pValues = aValues.getArray();
+ Any *pValue = pValues;
+
+ // StandardFormat/Textmode
+ *pValue++ <<= (sal_Bool) pFormat->IsTextmode();
+ // StandardFormat/GreekCharStyle
+ *pValue++ <<= (sal_Int16) pFormat->GetGreekCharStyle();
+ // StandardFormat/ScaleNormalBracket
+ *pValue++ <<= (sal_Bool) pFormat->IsScaleNormalBrackets();
+ // StandardFormat/HorizontalAlignment
+ *pValue++ <<= (sal_Int16) pFormat->GetHorAlign();
+ // StandardFormat/BaseSize
+ *pValue++ <<= (sal_Int16) SmRoundFraction( Sm100th_mmToPts(
+ pFormat->GetBaseSize().Height() ) );
+
+ sal_uInt16 i;
+ for (i = SIZ_BEGIN; i <= SIZ_END; ++i)
+ *pValue++ <<= (sal_Int16) pFormat->GetRelSize( i );
+
+ for (i = DIS_BEGIN; i <= DIS_END; ++i)
+ *pValue++ <<= (sal_Int16) pFormat->GetDistance( i );
+
+ for (i = FNT_BEGIN; i < FNT_END; ++i)
+ {
+ OUString aFntFmtId;
+
+ if (!pFormat->IsDefaultFont( i ))
+ {
+ SmFontFormat aFntFmt( pFormat->GetFont( i ) );
+ aFntFmtId = GetFontFormatList().GetFontFormatId( aFntFmt, true );
+ OSL_ENSURE( aFntFmtId.getLength(), "FontFormatId not found" );
+ }
+
+ *pValue++ <<= aFntFmtId;
+ }
+
+ OSL_ENSURE( pValue - pValues == nProps, "property mismatch" );
+ PutProperties( aNames , aValues );
+
+ SetFormatModified( false );
+}
+
+
+const SmFormat & SmMathConfig::GetStandardFormat() const
+{
+ if (!pFormat)
+ ((SmMathConfig *) this)->LoadFormat();
+ return *pFormat;
+}
+
+
+void SmMathConfig::SetStandardFormat( const SmFormat &rFormat, bool bSaveFontFormatList )
+{
+ if (!pFormat)
+ LoadFormat();
+ if (rFormat != *pFormat)
+ {
+ *pFormat = rFormat;
+ SetFormatModified( true );
+ SaveFormat();
+
+ if (bSaveFontFormatList)
+ {
+ // needed for SmFontTypeDialog's DefaultButtonClickHdl
+ SetFontFormatListModified( true );
+ SaveFontFormatList();
+ }
+ }
+}
+
+
+SmPrintSize SmMathConfig::GetPrintSize() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->ePrintSize;
+}
+
+
+void SmMathConfig::SetPrintSize( SmPrintSize eSize )
+{
+ if (!pOther)
+ LoadOther();
+ if (eSize != pOther->ePrintSize)
+ {
+ pOther->ePrintSize = eSize;
+ SetOtherModified( true );
+ }
+}
+
+
+sal_uInt16 SmMathConfig::GetPrintZoomFactor() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->nPrintZoomFactor;
+}
+
+
+void SmMathConfig::SetPrintZoomFactor( sal_uInt16 nVal )
+{
+ if (!pOther)
+ LoadOther();
+ if (nVal != pOther->nPrintZoomFactor)
+ {
+ pOther->nPrintZoomFactor = nVal;
+ SetOtherModified( true );
+ }
+}
+
+
+void SmMathConfig::SetOtherIfNotEqual( bool &rbItem, bool bNewVal )
+{
+ if (bNewVal != rbItem)
+ {
+ rbItem = bNewVal;
+ SetOtherModified( true );
+ }
+}
+
+
+bool SmMathConfig::IsPrintTitle() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->bPrintTitle;
+}
+
+
+void SmMathConfig::SetPrintTitle( bool bVal )
+{
+ if (!pOther)
+ LoadOther();
+ SetOtherIfNotEqual( pOther->bPrintTitle, bVal );
+}
+
+
+bool SmMathConfig::IsPrintFormulaText() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->bPrintFormulaText;
+}
+
+
+void SmMathConfig::SetPrintFormulaText( bool bVal )
+{
+ if (!pOther)
+ LoadOther();
+ SetOtherIfNotEqual( pOther->bPrintFormulaText, bVal );
+}
+
+bool SmMathConfig::IsSaveOnlyUsedSymbols() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->bIsSaveOnlyUsedSymbols;
+}
+
+bool SmMathConfig::IsPrintFrame() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->bPrintFrame;
+}
+
+
+void SmMathConfig::SetPrintFrame( bool bVal )
+{
+ if (!pOther)
+ LoadOther();
+ SetOtherIfNotEqual( pOther->bPrintFrame, bVal );
+}
+
+
+void SmMathConfig::SetSaveOnlyUsedSymbols( bool bVal )
+{
+ if (!pOther)
+ LoadOther();
+ SetOtherIfNotEqual( pOther->bIsSaveOnlyUsedSymbols, bVal );
+}
+
+
+bool SmMathConfig::IsIgnoreSpacesRight() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->bIgnoreSpacesRight;
+}
+
+
+void SmMathConfig::SetIgnoreSpacesRight( bool bVal )
+{
+ if (!pOther)
+ LoadOther();
+ SetOtherIfNotEqual( pOther->bIgnoreSpacesRight, bVal );
+}
+
+
+bool SmMathConfig::IsAutoRedraw() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->bAutoRedraw;
+}
+
+
+void SmMathConfig::SetAutoRedraw( bool bVal )
+{
+ if (!pOther)
+ LoadOther();
+ SetOtherIfNotEqual( pOther->bAutoRedraw, bVal );
+}
+
+
+bool SmMathConfig::IsShowFormulaCursor() const
+{
+ if (!pOther)
+ ((SmMathConfig *) this)->LoadOther();
+ return pOther->bFormulaCursor;
+}
+
+
+void SmMathConfig::SetShowFormulaCursor( bool bVal )
+{
+ if (!pOther)
+ LoadOther();
+ SetOtherIfNotEqual( pOther->bFormulaCursor, bVal );
+}
+
+void SmMathConfig::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& )
+{}
+
+/////////////////////////////////////////////////////////////////
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/cfgitem.hxx b/starmath/source/cfgitem.hxx
new file mode 100644
index 000000000000..e3fb818d4c4c
--- /dev/null
+++ b/starmath/source/cfgitem.hxx
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#ifndef _MATH_CFGITEM_HXX_
+#define _MATH_CFGITEM_HXX_
+
+#include <deque>
+#include <vector>
+
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Any.h>
+
+#include <tools/solar.h>
+#include <rtl/ustring.hxx>
+#include <unotools/configitem.hxx>
+#include <vcl/timer.hxx>
+
+#include <symbol.hxx>
+#include <types.hxx>
+
+using namespace com::sun::star;
+
+class SmSym;
+class SmFormat;
+class Font;
+struct SmCfgOther;
+
+/////////////////////////////////////////////////////////////////
+
+
+struct SmFontFormat
+{
+ String aName;
+ sal_Int16 nCharSet;
+ sal_Int16 nFamily;
+ sal_Int16 nPitch;
+ sal_Int16 nWeight;
+ sal_Int16 nItalic;
+
+ SmFontFormat();
+ SmFontFormat( const Font &rFont );
+
+ const Font GetFont() const;
+ bool operator == ( const SmFontFormat &rFntFmt ) const;
+};
+
+
+struct SmFntFmtListEntry
+{
+ String aId;
+ SmFontFormat aFntFmt;
+
+ SmFntFmtListEntry( const String &rId, const SmFontFormat &rFntFmt );
+};
+
+class SmFontFormatList
+{
+ std::deque<SmFntFmtListEntry> aEntries;
+ bool bModified;
+
+ // disallow copy-constructor and assignment-operator for now
+ SmFontFormatList( const SmFontFormatList & );
+ SmFontFormatList & operator = ( const SmFontFormatList & );
+
+public:
+ SmFontFormatList();
+
+ void Clear();
+ void AddFontFormat( const String &rFntFmtId, const SmFontFormat &rFntFmt );
+ void RemoveFontFormat( const String &rFntFmtId );
+
+ const SmFontFormat * GetFontFormat( const String &rFntFmtId ) const;
+ const SmFontFormat * GetFontFormat( size_t nPos ) const;
+ const String GetFontFormatId( const SmFontFormat &rFntFmt ) const;
+ const String GetFontFormatId( const SmFontFormat &rFntFmt, bool bAdd );
+ const String GetFontFormatId( size_t nPos ) const;
+ const String GetNewFontFormatId() const;
+ size_t GetCount() const { return aEntries.size(); }
+
+ bool IsModified() const { return bModified; }
+ void SetModified( bool bVal ) { bModified = bVal; }
+};
+
+
+/////////////////////////////////////////////////////////////////
+
+class SmMathConfig : public utl::ConfigItem
+{
+ SmFormat * pFormat;
+ SmCfgOther * pOther;
+ SmFontFormatList * pFontFormatList;
+ SmSymbolManager * pSymbolMgr;
+ bool bIsOtherModified;
+ bool bIsFormatModified;
+
+ // disallow copy-constructor and assignment-operator for now
+ SmMathConfig( const SmMathConfig & );
+ SmMathConfig & operator = ( const SmMathConfig & );
+
+
+ void StripFontFormatList( const std::vector< SmSym > &rSymbols );
+
+
+ void Save();
+
+ void ReadSymbol( SmSym &rSymbol,
+ const rtl::OUString &rSymbolName,
+ const rtl::OUString &rBaseNode ) const;
+ void ReadFontFormat( SmFontFormat &rFontFormat,
+ const rtl::OUString &rSymbolName,
+ const rtl::OUString &rBaseNode ) const;
+
+ void SetOtherIfNotEqual( bool &rbItem, bool bNewVal );
+
+protected:
+ void LoadOther();
+ void SaveOther();
+ void LoadFormat();
+ void SaveFormat();
+ void LoadFontFormatList();
+ void SaveFontFormatList();
+
+ void SetOtherModified( bool bVal );
+ inline bool IsOtherModified() const { return bIsOtherModified; }
+ void SetFormatModified( bool bVal );
+ inline bool IsFormatModified() const { return bIsFormatModified; }
+ void SetFontFormatListModified( bool bVal );
+ inline bool IsFontFormatListModified() const { return pFontFormatList ? pFontFormatList->IsModified(): false; }
+
+ SmFontFormatList & GetFontFormatList();
+ const SmFontFormatList & GetFontFormatList() const
+ {
+ return ((SmMathConfig *) this)->GetFontFormatList();
+ }
+
+public:
+ SmMathConfig();
+ virtual ~SmMathConfig();
+
+ // utl::ConfigItem
+ virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString > &rPropertyNames );
+ virtual void Commit();
+
+ SmSymbolManager & GetSymbolManager();
+ void GetSymbols( std::vector< SmSym > &rSymbols ) const;
+ void SetSymbols( const std::vector< SmSym > &rNewSymbols );
+
+ const SmFormat & GetStandardFormat() const;
+ void SetStandardFormat( const SmFormat &rFormat, bool bSaveFontFormatList = false );
+
+ bool IsPrintTitle() const;
+ void SetPrintTitle( bool bVal );
+ bool IsPrintFormulaText() const;
+ void SetPrintFormulaText( bool bVal );
+ bool IsPrintFrame() const;
+ void SetPrintFrame( bool bVal );
+ SmPrintSize GetPrintSize() const;
+ void SetPrintSize( SmPrintSize eSize );
+ sal_uInt16 GetPrintZoomFactor() const;
+ void SetPrintZoomFactor( sal_uInt16 nVal );
+
+ bool IsSaveOnlyUsedSymbols() const;
+ void SetSaveOnlyUsedSymbols( bool bVal );
+ bool IsIgnoreSpacesRight() const;
+ void SetIgnoreSpacesRight( bool bVal );
+ bool IsAutoRedraw() const;
+ void SetAutoRedraw( bool bVal );
+ bool IsShowFormulaCursor() const;
+ void SetShowFormulaCursor( bool bVal );
+ void SetAutoRedraw( sal_Bool bVal );
+};
+
+/////////////////////////////////////////////////////////////////
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/commands.src b/starmath/source/commands.src
new file mode 100644
index 000000000000..9d618bbd0cf3
--- /dev/null
+++ b/starmath/source/commands.src
@@ -0,0 +1,1561 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include <sfx2/sfx.hrc>
+#include "starmath.hrc"
+
+
+////////////////////////////////////////////////////////////
+
+String RID_PLUSX { Text = "+<?> " ; };
+String RID_MINUSX { Text = "-<?> " ; };
+String RID_PLUSMINUSX { Text = "+-<?> " ; };
+String RID_MINUSPLUSX { Text = "-+<?> " ; };
+String RID_NEGX { Text = "neg <?> " ; };
+String RID_XPLUSY { Text = "<?> + <?> " ; };
+String RID_XMINUSY { Text = "<?> - <?> " ; };
+String RID_XCDOTY { Text = "<?> cdot <?> " ; };
+String RID_XTIMESY { Text = "<?> times <?> " ; };
+String RID_XSYMTIMESY { Text = "<?> * <?> " ; };
+String RID_XSYMDIVIDEY { Text = "<?> / <?> " ; };
+String RID_XDIVY { Text = "<?> div <?> " ; };
+String RID_XOVERY { Text = "{<?>} over {<?>} " ; };
+String RID_XODIVIDEY { Text = "<?> odivide <?> " ; };
+String RID_XODOTY { Text = "<?> odot <?> " ; };
+String RID_XOMINUSY { Text = "<?> ominus <?> " ; };
+String RID_XOPLUSY { Text = "<?> oplus <?> " ; };
+String RID_XOTIMESY { Text = "<?> otimes <?> " ; };
+String RID_XANDY { Text = "<?> and <?> " ; };
+String RID_XORY { Text = "<?> or <?> " ; };
+String RID_XEQY { Text = "<?> = <?> " ; };
+String RID_XNEQY { Text = "<?> <> <?> " ; };
+String RID_XLTY { Text = "<?> < <?> " ; };
+String RID_XGTY { Text = "<?> > <?> " ; };
+String RID_XLEY { Text = "<?> <= <?> " ; };
+String RID_XGEY { Text = "<?> >= <?> " ; };
+String RID_XLESLANTY { Text = "<?> leslant <?> " ; };
+String RID_XGESLANTY { Text = "<?> geslant <?> " ; };
+String RID_XLLY { Text = "<?> << <?> " ; };
+String RID_XGGY { Text = "<?> >> <?> " ; };
+String RID_XDEFY { Text = "<?> def <?> " ; };
+String RID_XEQUIVY { Text = "<?> equiv <?> " ; };
+String RID_XAPPROXY { Text = "<?> approx <?> " ; };
+String RID_XSIMY { Text = "<?> sim <?> " ; };
+String RID_XSIMEQY { Text = "<?> simeq <?> " ; };
+String RID_XPROPY { Text = "<?> prop <?> " ; };
+String RID_XORTHOY { Text = "<?> ortho <?> " ; };
+String RID_XPARALLELY { Text = "<?> parallel <?> " ; };
+String RID_XTOWARDY { Text = "<?> toward <?> " ; };
+String RID_XTRANSLY { Text = "<?> transl <?> " ; };
+String RID_XTRANSRY { Text = "<?> transr <?> " ; };
+String RID_XINY { Text = "<?> in <?> " ; };
+String RID_XNOTINY { Text = "<?> notin <?> " ; };
+String RID_XOWNSY { Text = "<?> owns <?> " ; };
+String RID_XUNIONY { Text = "<?> union <?> " ; };
+String RID_XINTERSECTIONY { Text = "<?> intersection <?> " ; };
+String RID_XSETMINUSY { Text = "<?> setminus <?> " ; };
+String RID_XSLASHY { Text = "<?> slash <?> " ; };
+String RID_XSUBSETY { Text = "<?> subset <?> " ; };
+String RID_XSUBSETEQY { Text = "<?> subseteq <?> " ; };
+String RID_XSUPSETY { Text = "<?> supset <?> " ; };
+String RID_XSUPSETEQY { Text = "<?> supseteq <?> " ; };
+String RID_XNSUBSETY { Text = "<?> nsubset <?> " ; };
+String RID_XNSUBSETEQY { Text = "<?> nsubseteq <?> " ; };
+String RID_XNSUPSETY { Text = "<?> nsupset <?> " ; };
+String RID_XNSUPSETEQY { Text = "<?> nsupseteq <?> " ; };
+String RID_ABSX { Text = "abs{<?>} " ; };
+String RID_FACTX { Text = "fact {<?>} " ; };
+String RID_SQRTX { Text = "sqrt{<?>} " ; };
+String RID_NROOTXY { Text = "nroot{<?>}{<?>} " ; };
+String RID_EX { Text = "func e^{<?>} " ; };
+String RID_EXPX { Text = "exp(<?>) " ; };
+String RID_LNX { Text = "ln(<?>) " ; };
+String RID_LOGX { Text = "log(<?>) " ; };
+String RID_SINX { Text = "sin(<?>) " ; };
+String RID_COSX { Text = "cos(<?>) " ; };
+String RID_TANX { Text = "tan(<?>) " ; };
+String RID_COTX { Text = "cot(<?>) " ; };
+String RID_ARCSINX { Text = "arcsin(<?>) " ; };
+String RID_ARCCOSX { Text = "arccos(<?>) " ; };
+String RID_ARCTANX { Text = "arctan(<?>) " ; };
+String RID_ARCCOTX { Text = "arccot(<?>) " ; };
+String RID_SINHX { Text = "sinh(<?>) " ; };
+String RID_COSHX { Text = "cosh(<?>) " ; };
+String RID_TANHX { Text = "tanh(<?>) " ; };
+String RID_COTHX { Text = "coth(<?>) " ; };
+String RID_ARSINHX { Text = "arsinh(<?>) " ; };
+String RID_ARCOSHX { Text = "arcosh(<?>) " ; };
+String RID_ARTANHX { Text = "artanh(<?>) " ; };
+String RID_ARCOTHX { Text = "arcoth(<?>) " ; };
+String RID_SUMX { Text = "sum <?> " ; };
+String RID_PRODX { Text = "prod <?> " ; };
+String RID_COPRODX { Text = "coprod <?> " ; };
+String RID_LIMX { Text = "lim <?> " ; };
+String RID_LIMINFX { Text = "liminf <?> " ; };
+String RID_LIMSUPX { Text = "limsup <?> " ; };
+String RID_EXISTS { Text = "exists " ; };
+String RID_FORALL { Text = "forall " ; };
+String RID_INTX { Text = "int <?> " ; };
+String RID_IINTX { Text = "iint <?> " ; };
+String RID_IIINTX { Text = "iiint <?> " ; };
+String RID_LINTX { Text = "lint <?> " ; };
+String RID_LLINTX { Text = "llint <?> " ; };
+String RID_LLLINTX { Text = "lllint <?> " ; };
+String RID_FROMX { Text = "from{<?>} <?> " ; };
+String RID_TOX { Text = "to{<?>} <?> " ; };
+String RID_FROMXTOY { Text = "from{<?>} to{<?>} <?> " ; };
+String RID_ACUTEX { Text = "acute <?> " ; };
+String RID_BARX { Text = "bar <?> " ; };
+String RID_BREVEX { Text = "breve <?> " ; };
+String RID_CHECKX { Text = "check <?> " ; };
+String RID_CIRCLEX { Text = "circle <?> " ; };
+String RID_DOTX { Text = "dot <?> " ; };
+String RID_DDOTX { Text = "ddot <?> " ; };
+String RID_DDDOTX { Text = "dddot <?> " ; };
+String RID_GRAVEX { Text = "grave <?> " ; };
+String RID_HATX { Text = "hat <?> " ; };
+String RID_TILDEX { Text = "tilde <?> " ; };
+String RID_VECX { Text = "vec <?> " ; };
+String RID_UNDERLINEX { Text = "underline {<?>} " ; };
+String RID_OVERLINEX { Text = "overline {<?>} " ; };
+String RID_OVERSTRIKEX { Text = "overstrike {<?>} " ; };
+String RID_PHANTOMX { Text = "phantom {<?>} " ; };
+String RID_BOLDX { Text = "bold <?> " ; };
+String RID_ITALX { Text = "ital <?> " ; };
+String RID_SIZEXY { Text = "size <?> {<?>} " ; };
+String RID_FONTXY { Text = "font <?> {<?>} " ; };
+String RID_COLORX { Text = "color <?> {<?>} " ; };
+String RID_LRGROUPX { Text = "{<?>} " ; };
+String RID_LRPARENTX { Text = "(<?>) " ; };
+String RID_LRBRACKETX { Text = "[<?>] " ; };
+String RID_LRDBRACKETX { Text = "ldbracket <?> rdbracket " ; };
+String RID_LRBRACEX { Text = "lbrace <?> rbrace " ; };
+String RID_LRANGLEX { Text = "langle <?> rangle " ; };
+String RID_LRCEILX { Text = "lceil <?> rceil " ; };
+String RID_LRFLOORX { Text = "lfloor <?> rfloor " ; };
+String RID_LRLINEX { Text = "lline <?> rline " ; };
+String RID_LRDLINEX { Text = "ldline <?> rdline " ; };
+String RID_LMRANGLEXY { Text = "langle <?> mline <?> rangle " ; };
+String RID_SLRPARENTX { Text = "left ( <?> right ) " ; };
+String RID_SLRBRACKETX { Text = "left [ <?> right ] " ; };
+String RID_SLRDBRACKETX { Text = "left ldbracket <?> right rdbracket " ; };
+String RID_SLRBRACEX { Text = "left lbrace <?> right rbrace " ; };
+String RID_SLRANGLEX { Text = "left langle <?> right rangle " ; };
+String RID_SLRCEILX { Text = "left lceil <?> right rceil " ; };
+String RID_SLRFLOORX { Text = "left lfloor <?> right rfloor " ; };
+String RID_SLRLINEX { Text = "left lline <?> right rline " ; };
+String RID_SLRDLINEX { Text = "left ldline <?> right rdline " ; };
+String RID_SLMRANGLEXY { Text = "left langle <?> mline <?> right rangle " ; };
+String RID_XOVERBRACEY { Text = "{<?>} overbrace {<?>} " ; };
+String RID_XUNDERBRACEY { Text = "{<?>} underbrace {<?>} " ; };
+String RID_RSUBX { Text = "<?>_{<?>}" ; };
+String RID_RSUPX { Text = "<?>^{<?>}" ; };
+String RID_LSUBX { Text = "<?> lsub{<?>} " ; };
+String RID_LSUPX { Text = "<?> lsup{<?>} " ; };
+String RID_CSUBX { Text = "<?> csub{<?>} " ; };
+String RID_CSUPX { Text = "<?> csup{<?>} " ; };
+String RID_SBLANK { Text = "`" ; };
+String RID_BLANK { Text = "~" ; };
+String RID_NEWLINE { Text = "newline " ; };
+String RID_BINOMXY { Text = "binom{<?>}{<?>} " ; };
+String RID_STACK { Text = "stack{<?> # <?> # <?>} " ; };
+String RID_MATRIX { Text = "matrix{<?> # <?> ## <?> # <?>} " ; };
+String RID_ALIGNLX { Text = "alignl <?> " ; };
+String RID_ALIGNCX { Text = "alignc <?> " ; };
+String RID_ALIGNRX { Text = "alignr <?> " ; };
+String RID_ALEPH { Text = "aleph " ; };
+String RID_EMPTYSET { Text = "emptyset " ; };
+String RID_RE { Text = "Re " ; };
+String RID_IM { Text = "Im " ; };
+String RID_INFINITY { Text = "infinity " ; };
+String RID_PARTIAL { Text = "partial " ; };
+String RID_NABLA { Text = "nabla " ; };
+String RID_WP { Text = "wp " ; };
+String RID_DOTSAXIS { Text = "dotsaxis " ; };
+String RID_DOTSUP { Text = "dotsup " ; };
+String RID_DOTSDOWN { Text = "dotsdown " ; };
+String RID_DOTSLOW { Text = "dotslow " ; };
+String RID_DOTSVERT { Text = "dotsvert " ; };
+String RID_XCIRCY { Text = "<?> circ <?> " ; };
+String RID_XWIDESLASHY { Text = "{<?>} wideslash {<?>} " ; };
+String RID_XWIDEBSLASHY { Text = "<?> widebslash <?> " ; };
+String RID_XDIVIDESY { Text = "<?> divides <?> " ; };
+String RID_XNDIVIDESY { Text = "<?> ndivides <?> " ; };
+String RID_DLARROW { Text = "<?> dlarrow <?> " ; };
+String RID_DLRARROW { Text = "<?> dlrarrow <?> " ; };
+String RID_DRARROW { Text = "<?> drarrow <?> " ; };
+String RID_SETN { Text = "setN " ; };
+String RID_SETZ { Text = "setZ " ; };
+String RID_SETQ { Text = "setQ " ; };
+String RID_SETR { Text = "setR " ; };
+String RID_SETC { Text = "setC " ; };
+String RID_WIDEHATX { Text = "widehat {<?>} " ; };
+String RID_WIDETILDEX { Text = "widetilde {<?>} " ; };
+String RID_WIDEVECX { Text = "widevec {<?>} " ; };
+String RID_HBAR { Text = "hbar " ; };
+String RID_LAMBDABAR { Text = "lambdabar " ; };
+String RID_LEFTARROW { Text = "leftarrow " ; };
+String RID_RIGHTARROW { Text = "rightarrow " ; };
+String RID_UPARROW { Text = "uparrow " ; };
+String RID_DOWNARROW { Text = "downarrow " ; };
+String RID_NOSPACE { Text = "nospace {<?>} " ; };
+
+
+//////////////////////////////////////////
+
+
+Menu RID_COMMANDMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_UNBINOPS_MENU ;
+ HelpId = HID_SMA_UNBINOPS_TBX ;
+ Text [ en-US ] = "~Unary/Binary Operators" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_PLUSX;
+ HelpId = HID_SMA_PLUSX;
+ Text = "+a";
+ };
+ MenuItem
+ {
+ Identifier = RID_MINUSX;
+ HelpId = HID_SMA_MINUSX;
+ Text = "-a";
+ };
+ MenuItem
+ {
+ Identifier = RID_PLUSMINUSX;
+ HelpId = HID_SMA_PLUSMINUSX;
+ Text = "+-a";
+ };
+ MenuItem
+ {
+ Identifier = RID_MINUSPLUSX;
+ HelpId = HID_SMA_MINUSPLUSX;
+ Text = "-+a";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_XPLUSY;
+ HelpId = HID_SMA_XPLUSY;
+ Text = "a + b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XMINUSY;
+ HelpId = HID_SMA_XMINUSY;
+ Text = "a - b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XCDOTY;
+ HelpId = HID_SMA_XCDOTY;
+ Text = "a cdot b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XTIMESY;
+ HelpId = HID_SMA_XTIMESY;
+ Text = "a times b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSYMTIMESY;
+ HelpId = HID_SMA_XSYMTIMESY;
+ Text = "a * b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XOVERY;
+ HelpId = HID_SMA_XOVERY;
+ Text = "a over b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XDIVY;
+ HelpId = HID_SMA_XDIVY;
+ Text = "a div b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSYMDIVIDEY;
+ HelpId = HID_SMA_XSYMDIVIDEY;
+ Text = "a / b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XCIRCY;
+ HelpId = HID_SMA_XCIRCY;
+ Text = "a circ b";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_XWIDESLASHY;
+ HelpId = HID_SMA_XWIDESLASHY;
+ Text = "a wideslash b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XWIDEBSLASHY;
+ HelpId = HID_SMA_XWIDEBSLASHY;
+ Text = "a widebslash b";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_NEGX;
+ HelpId = HID_SMA_NEGX;
+ Text = "neg a";
+ };
+ MenuItem
+ {
+ Identifier = RID_XANDY;
+ HelpId = HID_SMA_XANDY;
+ Text = "a and b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XORY;
+ HelpId = HID_SMA_XORY;
+ Text = "a or b";
+ };
+ };
+ };
+ };
+ MenuItem
+ {
+ Identifier = RID_RELATIONS_MENU ;
+ HelpId = HID_SMA_RELATIONS_TBX ;
+ Text [ en-US ] = "~Relations" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_XEQY;
+ HelpId = HID_SMA_XEQY;
+ Text = "a = b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XNEQY;
+ HelpId = HID_SMA_XNEQY;
+ Text = "a <> b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XLTY;
+ HelpId = HID_SMA_XLTY;
+ Text = "a < b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XLEY;
+ HelpId = HID_SMA_XLEY;
+ Text = "a <= b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XLESLANTY;
+ HelpId = HID_SMA_XLESLANTY;
+ Text = "a leslant b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XGTY;
+ HelpId = HID_SMA_XGTY;
+ Text = "a > b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XGEY;
+ HelpId = HID_SMA_XGEY;
+ Text = "a >= b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XGESLANTY;
+ HelpId = HID_SMA_XGESLANTY;
+ Text = "a geslant b";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_XAPPROXY;
+ HelpId = HID_SMA_XAPPROXY;
+ Text = "a approx b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSIMY;
+ HelpId = HID_SMA_XSIMY;
+ Text = "a sim b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSIMEQY;
+ HelpId = HID_SMA_XSIMEQY;
+ Text = "a simeq b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XEQUIVY;
+ HelpId = HID_SMA_XEQUIVY;
+ Text = "a equiv b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XPROPY;
+ HelpId = HID_SMA_XPROPY;
+ Text = "a prop b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XPARALLELY;
+ HelpId = HID_SMA_XPARALLELY;
+ Text = "a parallel b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XORTHOY;
+ HelpId = HID_SMA_XORTHOY;
+ Text = "a ortho b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XDIVIDESY;
+ HelpId = HID_SMA_XDIVIDESY;
+ Text = "a divides b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XNDIVIDESY;
+ HelpId = HID_SMA_XNDIVIDESY;
+ Text = "a ndivides b";
+ };
+ MenuItem
+ {
+ Identifier = RID_XTOWARDY;
+ HelpId = HID_SMA_XTOWARDY;
+ Text = "a toward b";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_DLARROW;
+ HelpId = HID_SMA_DLARROW;
+ Text = "a dlarrow b";
+ };
+ MenuItem
+ {
+ Identifier = RID_DLRARROW;
+ HelpId = HID_SMA_DLRARROW;
+ Text = "a dlrarrow b";
+ };
+ MenuItem
+ {
+ Identifier = RID_DRARROW;
+ HelpId = HID_SMA_DRARROW;
+ Text = "a drarrow b";
+ };
+ };
+ };
+ };
+ MenuItem
+ {
+ Identifier = RID_SETOPERATIONS_MENU ;
+ HelpId = HID_SMA_SETOPERATIONS_TBX ;
+ Text [ en-US ] = "~Set Operations" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_XINY;
+ HelpId = HID_SMA_XINY;
+ Text = "a in A";
+ };
+ MenuItem
+ {
+ Identifier = RID_XNOTINY;
+ HelpId = HID_SMA_XNOTINY;
+ Text = "a notin A";
+ };
+ MenuItem
+ {
+ Identifier = RID_XOWNSY;
+ HelpId = HID_SMA_XOWNSY;
+ Text = "A owns a";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_XINTERSECTIONY;
+ HelpId = HID_SMA_XINTERSECTIONY;
+ Text = "A intersection B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XUNIONY;
+ HelpId = HID_SMA_XUNIONY;
+ Text = "A union B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSETMINUSY;
+ HelpId = HID_SMA_XSETMINUSY;
+ Text = "A \\ B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSLASHY;
+ HelpId = HID_SMA_XSLASHY;
+ Text = "A / B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSUBSETY;
+ HelpId = HID_SMA_XSUBSETY;
+ Text = "A subset B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSUBSETEQY;
+ HelpId = HID_SMA_XSUBSETEQY;
+ Text = "A subseteq B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSUPSETY;
+ HelpId = HID_SMA_XSUPSETY;
+ Text = "A supset B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XSUPSETEQY;
+ HelpId = HID_SMA_XSUPSETEQY;
+ Text = "A supseteq B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XNSUBSETY;
+ HelpId = HID_SMA_XNSUBSETY;
+ Text = "A nsubset B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XNSUBSETEQY;
+ HelpId = HID_SMA_XNSUBSETEQY;
+ Text = "A nsubseteq B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XNSUPSETY;
+ HelpId = HID_SMA_XNSUPSETY;
+ Text = "A nsupset B";
+ };
+ MenuItem
+ {
+ Identifier = RID_XNSUPSETEQY;
+ HelpId = HID_SMA_XNSUPSETEQY;
+ Text = "A nsupseteq B";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_EMPTYSET;
+ HelpId = HID_SMA_EMPTYSET;
+ Text = "emptyset";
+ };
+ MenuItem
+ {
+ Identifier = RID_ALEPH;
+ HelpId = HID_SMA_ALEPH;
+ Text = "aleph";
+ };
+ MenuItem
+ {
+ Identifier = RID_SETN;
+ HelpId = HID_SMA_SETN;
+ Text = "setN";
+ };
+ MenuItem
+ {
+ Identifier = RID_SETZ;
+ HelpId = HID_SMA_SETZ;
+ Text = "setZ";
+ };
+ MenuItem
+ {
+ Identifier = RID_SETQ;
+ HelpId = HID_SMA_SETQ;
+ Text = "setQ";
+ };
+ MenuItem
+ {
+ Identifier = RID_SETR;
+ HelpId = HID_SMA_SETR;
+ Text = "setR";
+ };
+ MenuItem
+ {
+ Identifier = RID_SETC;
+ HelpId = HID_SMA_SETC;
+ Text = "setC";
+ };
+ };
+ };
+ };
+ MenuItem
+ {
+ Identifier = RID_FUNCTIONS_MENU ;
+ HelpId = HID_SMA_FUNCTIONS_TBX ;
+ Text [ en-US ] = "~Functions" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_ABSX;
+ HelpId = HID_SMA_ABSX;
+ Text = "|x|";
+ };
+ MenuItem
+ {
+ Identifier = RID_FACTX;
+ HelpId = HID_SMA_FACTX;
+ Text = "x!";
+ };
+ MenuItem
+ {
+ Identifier = RID_SQRTX;
+ HelpId = HID_SMA_SQRTX;
+ Text = "sqrt x";
+ };
+ MenuItem
+ {
+ Identifier = RID_NROOTXY;
+ HelpId = HID_SMA_NROOTXY;
+ Text = "nroot x y";
+ };
+ MenuItem
+ {
+ Identifier = RID_RSUPX;
+ HelpId = HID_SMA_RSUPX;
+ Text = "x^y";
+ };
+ MenuItem
+ {
+ Identifier = RID_EX;
+ HelpId = HID_SMA_EX;
+ Text = "e^x";
+ };
+ MenuItem
+ {
+ Identifier = RID_LNX;
+ HelpId = HID_SMA_LNX;
+ Text = "ln(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_EXPX;
+ HelpId = HID_SMA_EXPX;
+ Text = "exp(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_LOGX;
+ HelpId = HID_SMA_LOGX;
+ Text = "log(x)";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_SINX;
+ HelpId = HID_SMA_SINX;
+ Text = "sin(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_COSX;
+ HelpId = HID_SMA_COSX;
+ Text = "cos(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_TANX;
+ HelpId = HID_SMA_TANX;
+ Text = "tan(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_COTX;
+ HelpId = HID_SMA_COTX;
+ Text = "cot(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_SINHX;
+ HelpId = HID_SMA_SINHX;
+ Text = "sinh(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_COSHX;
+ HelpId = HID_SMA_COSHX;
+ Text = "cosh(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_TANHX;
+ HelpId = HID_SMA_TANHX;
+ Text = "tanh(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_COTHX;
+ HelpId = HID_SMA_COTHX;
+ Text = "coth(x)";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_FUNCTIONSOTHER1_MENU;
+ HelpId = HID_SMA_FUNCTIONSOTHER1_MENU;
+ Text [ en-US ] = "More";
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_ARCSINX;
+ HelpId = HID_SMA_ARCSINX;
+ Text = "arcsin(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_ARCCOSX;
+ HelpId = HID_SMA_ARCCOSX;
+ Text = "arccos(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_ARCTANX;
+ HelpId = HID_SMA_ARCTANX;
+ Text = "arctan(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_ARCCOTX;
+ HelpId = HID_SMA_ARCCOTX;
+ Text = "arcot(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_ARSINHX;
+ HelpId = HID_SMA_ARSINHX;
+ Text = "arsinh(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_ARCOSHX;
+ HelpId = HID_SMA_ARCOSHX;
+ Text = "arcosh(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_ARTANHX;
+ HelpId = HID_SMA_ARTANHX;
+ Text = "artanh(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_ARCOTHX;
+ HelpId = HID_SMA_ARCOTHX;
+ Text = "arcoth(x)";
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+ MenuItem
+ {
+ Identifier = RID_OPERATORS_MENU ;
+ HelpId = HID_SMA_OPERATORS_TBX ;
+ Text [ en-US ] = "O~perators" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_LIMX;
+ HelpId = HID_SMA_LIMX;
+ Text = "lim x";
+ };
+ MenuItem
+ {
+ Identifier = RID_SUMX;
+ HelpId = HID_SMA_SUMX;
+ Text = "sum x";
+ };
+ MenuItem
+ {
+ Identifier = RID_PRODX;
+ HelpId = HID_SMA_PRODX;
+ Text = "prod x";
+ };
+ MenuItem
+ {
+ Identifier = RID_COPRODX;
+ HelpId = HID_SMA_COPRODX;
+ Text = "coprod x";
+ };
+ MenuItem
+ {
+ Identifier = RID_INTX;
+ HelpId = HID_SMA_INTX;
+ Text = "int x";
+ };
+ MenuItem
+ {
+ Identifier = RID_IINTX;
+ HelpId = HID_SMA_IINTX;
+ Text = "iint x";
+ };
+ MenuItem
+ {
+ Identifier = RID_IIINTX;
+ HelpId = HID_SMA_IIINTX;
+ Text = "iiint x";
+ };
+ MenuItem
+ {
+ Identifier = RID_LINTX;
+ HelpId = HID_SMA_LINTX;
+ Text = "lint x";
+ };
+ MenuItem
+ {
+ Identifier = RID_LLINTX;
+ HelpId = HID_SMA_LLINTX;
+ Text = "llint x";
+ };
+ MenuItem
+ {
+ Identifier = RID_LLLINTX;
+ HelpId = HID_SMA_LLLINTX;
+ Text = "lllint x";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_FROMXTOY;
+ HelpId = HID_SMA_FROMXTOY;
+ Text = "... from a to b";
+ };
+ MenuItem
+ {
+ Identifier = RID_FROMX;
+ HelpId = HID_SMA_FROMX;
+ Text = "... from a";
+ };
+ MenuItem
+ {
+ Identifier = RID_TOX;
+ HelpId = HID_SMA_TOX;
+ Text = "... to b";
+ };
+ };
+ };
+ };
+ MenuItem
+ {
+ Identifier = RID_ATTRIBUTES_MENU ;
+ HelpId = HID_SMA_ATTRIBUTES_TBX ;
+ Text [ en-US ] = "~Attributes" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_ACUTEX;
+ HelpId = HID_SMA_ACUTEX;
+ Text = "acute a";
+ };
+ MenuItem
+ {
+ Identifier = RID_GRAVEX;
+ HelpId = HID_SMA_GRAVEX;
+ Text = "grave a";
+ };
+ MenuItem
+ {
+ Identifier = RID_CHECKX;
+ HelpId = HID_SMA_CHECKX;
+ Text = "check a";
+ };
+ MenuItem
+ {
+ Identifier = RID_BREVEX;
+ HelpId = HID_SMA_BREVEX;
+ Text = "breve a";
+ };
+ MenuItem
+ {
+ Identifier = RID_CIRCLEX;
+ HelpId = HID_SMA_CIRCLEX;
+ Text = "circle a";
+ };
+ MenuItem
+ {
+ Identifier = RID_DOTX;
+ HelpId = HID_SMA_DOTX;
+ Text = "dot a";
+ };
+ MenuItem
+ {
+ Identifier = RID_DDOTX;
+ HelpId = HID_SMA_DDOTX;
+ Text = "ddot a";
+ };
+ MenuItem
+ {
+ Identifier = RID_DDDOTX;
+ HelpId = HID_SMA_DDDOTX;
+ Text = "dddot a";
+ };
+ MenuItem
+ {
+ Identifier = RID_BARX;
+ HelpId = HID_SMA_BARX;
+ Text = "bar a";
+ };
+ MenuItem
+ {
+ Identifier = RID_VECX;
+ HelpId = HID_SMA_VECX;
+ Text = "vec a";
+ };
+ MenuItem
+ {
+ Identifier = RID_TILDEX;
+ HelpId = HID_SMA_TILDEX;
+ Text = "tilde a";
+ };
+ MenuItem
+ {
+ Identifier = RID_HATX;
+ HelpId = HID_SMA_HATX;
+ Text = "hat a";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_WIDEVECX;
+ HelpId = HID_SMA_WIDEVECX;
+ Text = "widevec abc";
+ };
+ MenuItem
+ {
+ Identifier = RID_WIDETILDEX;
+ HelpId = HID_SMA_WIDETILDEX;
+ Text = "widetilde abc";
+ };
+ MenuItem
+ {
+ Identifier = RID_WIDEHATX;
+ HelpId = HID_SMA_WIDEHATX;
+ Text = "widehat abc";
+ };
+ MenuItem
+ {
+ Identifier = RID_OVERLINEX;
+ HelpId = HID_SMA_OVERLINEX;
+ Text = "overline abc";
+ };
+ MenuItem
+ {
+ Identifier = RID_UNDERLINEX;
+ HelpId = HID_SMA_UNDERLINEX;
+ Text = "underline abc";
+ };
+ MenuItem
+ {
+ Identifier = RID_OVERSTRIKEX;
+ HelpId = HID_SMA_OVERSTRIKEX;
+ Text = "overstrike abc";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_PHANTOMX;
+ HelpId = HID_SMA_PHANTOMX;
+ Text = "phantom b";
+ };
+ MenuItem
+ {
+ Identifier = RID_BOLDX;
+ HelpId = HID_SMA_BOLDX;
+ Text = "bold b";
+ };
+ MenuItem
+ {
+ Identifier = RID_ITALX;
+ HelpId = HID_SMA_ITALX;
+ Text = "ital b";
+ };
+ MenuItem
+ {
+ Identifier = RID_SIZEXY;
+ HelpId = HID_SMA_SIZEXY;
+ Text = "size s b";
+ };
+ MenuItem
+ {
+ Identifier = RID_FONTXY;
+ HelpId = HID_SMA_FONTXY;
+ Text = "font f b";
+ };
+ };
+ };
+ };
+ MenuItem
+ {
+ Identifier = RID_BRACKETS_MENU ;
+ HelpId = HID_SMA_BRACKETS_TBX ;
+ Text [ en-US ] = "~Brackets" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_LRGROUPX;
+ HelpId = HID_SMA_LRGROUPX;
+ Text = "{...}";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_LRPARENTX;
+ HelpId = HID_SMA_LRPARENTX;
+ Text = "(x)";
+ };
+ MenuItem
+ {
+ Identifier = RID_LRBRACKETX;
+ HelpId = HID_SMA_LRBRACKETX;
+ Text = "[x]";
+ };
+ MenuItem
+ {
+ Identifier = RID_LRDBRACKETX;
+ HelpId = HID_SMA_LRDBRACKETX;
+ Text = "ldbracket x rdbracket ";
+ };
+ MenuItem
+ {
+ Identifier = RID_LRBRACEX;
+ HelpId = HID_SMA_LRBRACEX;
+ Text = "{x}";
+ };
+ MenuItem
+ {
+ Identifier = RID_LRANGLEX;
+ HelpId = HID_SMA_LRANGLEX;
+ Text = "langle x rangle";
+ };
+ MenuItem
+ {
+ Identifier = RID_LMRANGLEXY;
+ HelpId = HID_SMA_LMRANGLEXY;
+ Text = "langle x mline y rangle";
+ };
+ MenuItem
+ {
+ Identifier = RID_LRCEILX;
+ HelpId = HID_SMA_LRCEILX;
+ Text = "lceil x rceil";
+ };
+ MenuItem
+ {
+ Identifier = RID_LRFLOORX;
+ HelpId = HID_SMA_LRFLOORX;
+ Text = "lfloor x rfloor";
+ };
+ MenuItem
+ {
+ Identifier = RID_LRLINEX;
+ HelpId = HID_SMA_LRLINEX;
+ Text = "lline x rline";
+ };
+ MenuItem
+ {
+ Identifier = RID_LRDLINEX;
+ HelpId = HID_SMA_LRDLINEX;
+ Text = "ldline x rdline";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRPARENTX;
+ HelpId = HID_SMA_SLRPARENTX;
+ Text = "left ( x right )";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRBRACKETX;
+ HelpId = HID_SMA_SLRBRACKETX;
+ Text = "left [ x right ]";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRDBRACKETX;
+ HelpId = HID_SMA_SLRDBRACKETX;
+ Text = "left ldbracket x right rdbracket ";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRBRACEX;
+ HelpId = HID_SMA_SLRBRACEX;
+ Text = "left { x right }";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRANGLEX;
+ HelpId = HID_SMA_SLRANGLEX;
+ Text = "left langle x right rangle";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLMRANGLEXY;
+ HelpId = HID_SMA_SLMRANGLEXY;
+ Text = "left langle x mline y right rangle";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRCEILX;
+ HelpId = HID_SMA_SLRCEILX;
+ Text = "left lceil x right rceil";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRFLOORX;
+ HelpId = HID_SMA_SLRFLOORX;
+ Text = "left lfloor x right rfloor";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRLINEX;
+ HelpId = HID_SMA_SLRLINEX;
+ Text = "left lline x right rline";
+ };
+ MenuItem
+ {
+ Identifier = RID_SLRDLINEX;
+ HelpId = HID_SMA_SLRDLINEX;
+ Text = "left ldline x right rdline";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_XOVERBRACEY;
+ HelpId = HID_SMA_XOVERBRACEY;
+ Text = "x overbrace y";
+ };
+ MenuItem
+ {
+ Identifier = RID_XUNDERBRACEY;
+ HelpId = HID_SMA_XUNDERBRACEY;
+ Text = "x underbrace y";
+ };
+ };
+ };
+ };
+ MenuItem
+ {
+ Identifier = RID_FORMAT_MENU ;
+ HelpId = HID_SMA_FORMAT_TBX ;
+ Text [ en-US ] = "For~mats" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_RSUPX;
+ HelpId = HID_SMA_RSUPX;
+ Text = "^x";
+ };
+ MenuItem
+ {
+ Identifier = RID_RSUBX;
+ HelpId = HID_SMA_RSUBX;
+ Text = "_x";
+ };
+ MenuItem
+ {
+ Identifier = RID_LSUPX;
+ HelpId = HID_SMA_LSUPX;
+ Text = "lsup x";
+ };
+ MenuItem
+ {
+ Identifier = RID_LSUBX;
+ HelpId = HID_SMA_LSUBX;
+ Text = "lsub x";
+ };
+ MenuItem
+ {
+ Identifier = RID_CSUPX;
+ HelpId = HID_SMA_CSUPX;
+ Text = "csup x";
+ };
+ MenuItem
+ {
+ Identifier = RID_CSUBX;
+ HelpId = HID_SMA_CSUBX;
+ Text = "csub x";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_NEWLINE;
+ HelpId = HID_SMA_NEWLINE;
+ Text [ en-US ] = "New Line";
+ };
+ MenuItem
+ {
+ Identifier = RID_SBLANK;
+ HelpId = HID_SMA_SBLANK;
+ Text [ en-US ] = "Small Gap";
+ };
+ MenuItem
+ {
+ Identifier = RID_BLANK;
+ HelpId = HID_SMA_BLANK;
+ Text [ en-US ] = "Gap";
+ };
+ MenuItem
+ {
+ Identifier = RID_NOSPACE;
+ HelpId = HID_SMA_NOSPACE;
+ Text [ en-US ] = "nospace {...}";
+ };
+ MenuItem
+ {
+ Identifier = RID_BINOMXY;
+ HelpId = HID_SMA_BINOMXY;
+ Text = "binom x y";
+ };
+ MenuItem
+ {
+ Identifier = RID_STACK;
+ HelpId = HID_SMA_STACK;
+ Text = "stack {...}";
+ };
+ MenuItem
+ {
+ Identifier = RID_MATRIX;
+ HelpId = HID_SMA_MATRIX;
+ Text = "matrix {...}";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_ALIGNLX;
+ HelpId = HID_SMA_ALIGNLX;
+ Text = "alignl x";
+ };
+ MenuItem
+ {
+ Identifier = RID_ALIGNCX;
+ HelpId = HID_SMA_ALIGNCX;
+ Text = "alignc x";
+ };
+ MenuItem
+ {
+ Identifier = RID_ALIGNRX;
+ HelpId = HID_SMA_ALIGNRX;
+ Text = "alignr x";
+ };
+ };
+ };
+ };
+ MenuItem
+ {
+ Identifier = RID_MISC_MENU ;
+ HelpId = HID_SMA_MISC_MENU ;
+ Text [ en-US ] = "~Others" ;
+ SubMenu = Menu
+ {
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = RID_INFINITY;
+ HelpId = HID_SMA_INFINITY;
+ Text = "infinity";
+ };
+ MenuItem
+ {
+ Identifier = RID_PARTIAL;
+ HelpId = HID_SMA_PARTIAL;
+ Text = "partial";
+ };
+ MenuItem
+ {
+ Identifier = RID_NABLA;
+ HelpId = HID_SMA_NABLA;
+ Text = "nabla";
+ };
+ MenuItem
+ {
+ Identifier = RID_EXISTS;
+ HelpId = HID_SMA_EXISTS;
+ Text = "exists";
+ };
+ MenuItem
+ {
+ Identifier = RID_FORALL;
+ HelpId = HID_SMA_FORALL;
+ Text = "forall";
+ };
+ MenuItem
+ {
+ Identifier = RID_HBAR;
+ HelpId = HID_SMA_HBAR;
+ Text = "hbar";
+ };
+ MenuItem
+ {
+ Identifier = RID_LAMBDABAR;
+ HelpId = HID_SMA_LAMBDABAR;
+ Text = "lambdabar";
+ };
+ MenuItem
+ {
+ Identifier = RID_RE;
+ HelpId = HID_SMA_RE;
+ Text = "Re";
+ };
+ MenuItem
+ {
+ Identifier = RID_IM;
+ HelpId = HID_SMA_IM;
+ Text = "Im";
+ };
+ MenuItem
+ {
+ Identifier = RID_WP;
+ HelpId = HID_SMA_WP;
+ Text = "wp";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_LEFTARROW;
+ HelpId = HID_SMA_LEFTARROW;
+ Text = "leftarrow";
+ };
+ MenuItem
+ {
+ Identifier = RID_RIGHTARROW;
+ HelpId = HID_SMA_RIGHTARROW;
+ Text = "rightarrow";
+ };
+ MenuItem
+ {
+ Identifier = RID_UPARROW;
+ HelpId = HID_SMA_UPARROW;
+ Text = "uparrow";
+ };
+ MenuItem
+ {
+ Identifier = RID_DOWNARROW;
+ HelpId = HID_SMA_DOWNARROW;
+ Text = "downarrow";
+ };
+ MenuItem
+ {
+ Separator = TRUE;
+ };
+ MenuItem
+ {
+ Identifier = RID_DOTSLOW;
+ HelpId = HID_SMA_DOTSLOW;
+ Text = "dotslow";
+ };
+ MenuItem
+ {
+ Identifier = RID_DOTSAXIS;
+ HelpId = HID_SMA_DOTSAXIS;
+ Text = "dotsaxis";
+ };
+ MenuItem
+ {
+ Identifier = RID_DOTSVERT;
+ HelpId = HID_SMA_DOTSVERT;
+ Text = "dotsvert";
+ };
+ MenuItem
+ {
+ Identifier = RID_DOTSUP;
+ HelpId = HID_SMA_DOTSUP;
+ Text = "dotsup";
+ };
+ MenuItem
+ {
+ Identifier = RID_DOTSDOWN;
+ HelpId = HID_SMA_DOTSDOWN;
+ Text = "dotsdown";
+ };
+ };
+ };
+ };
+ };
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/starmath/source/config.cxx b/starmath/source/config.cxx
new file mode 100644
index 000000000000..2bcfb43a0d1f
--- /dev/null
+++ b/starmath/source/config.cxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <svl/itemset.hxx>
+#include <svl/hint.hxx>
+#include <svl/smplhint.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/eitem.hxx>
+#include <svl/itempool.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <tools/stream.hxx>
+
+
+#include "config.hxx"
+#include "format.hxx"
+#include "smmod.hxx"
+#include "starmath.hrc"
+
+/////////////////////////////////////////////////////////////////
+
+SmConfig::SmConfig()
+{
+}
+
+
+SmConfig::~SmConfig()
+{
+}
+
+
+void SmConfig::ItemSetToConfig(const SfxItemSet &rSet)
+{
+ const SfxPoolItem *pItem = NULL;
+
+ sal_uInt16 nU16;
+ bool bVal;
+ if (rSet.GetItemState(SID_PRINTSIZE, sal_True, &pItem) == SFX_ITEM_SET)
+ { nU16 = ((const SfxUInt16Item *) pItem)->GetValue();
+ SetPrintSize( (SmPrintSize) nU16 );
+ }
+ if (rSet.GetItemState(SID_PRINTZOOM, sal_True, &pItem) == SFX_ITEM_SET)
+ { nU16 = ((const SfxUInt16Item *) pItem)->GetValue();
+ SetPrintZoomFactor( nU16 );
+ }
+ if (rSet.GetItemState(SID_PRINTTITLE, sal_True, &pItem) == SFX_ITEM_SET)
+ { bVal = ((const SfxBoolItem *) pItem)->GetValue();
+ SetPrintTitle( bVal );
+ }
+ if (rSet.GetItemState(SID_PRINTTEXT, sal_True, &pItem) == SFX_ITEM_SET)
+ { bVal = ((const SfxBoolItem *) pItem)->GetValue();
+ SetPrintFormulaText( bVal );
+ }
+ if (rSet.GetItemState(SID_PRINTFRAME, sal_True, &pItem) == SFX_ITEM_SET)
+ { bVal = ((const SfxBoolItem *) pItem)->GetValue();
+ SetPrintFrame( bVal );
+ }
+ if (rSet.GetItemState(SID_AUTOREDRAW, sal_True, &pItem) == SFX_ITEM_SET)
+ { bVal = ((const SfxBoolItem *) pItem)->GetValue();
+ SetAutoRedraw( bVal );
+ }
+ if (rSet.GetItemState(SID_NO_RIGHT_SPACES, sal_True, &pItem) == SFX_ITEM_SET)
+ { bVal = ((const SfxBoolItem *) pItem)->GetValue();
+ if (IsIgnoreSpacesRight() != bVal)
+ {
+ SetIgnoreSpacesRight( bVal );
+
+ // (angezeigte) Formeln muessen entsprechen neu formatiert werden.
+ // Das erreichen wir mit:
+ Broadcast(SfxSimpleHint(HINT_FORMATCHANGED));
+ }
+ }
+ if (rSet.GetItemState(SID_SAVE_ONLY_USED_SYMBOLS, sal_True, &pItem) == SFX_ITEM_SET)
+ { bVal = ((const SfxBoolItem *) pItem)->GetValue();
+ SetSaveOnlyUsedSymbols( bVal );
+ }
+
+ SaveOther();
+}
+
+
+void SmConfig::ConfigToItemSet(SfxItemSet &rSet) const
+{
+ const SfxItemPool *pPool = rSet.GetPool();
+
+ rSet.Put(SfxUInt16Item(pPool->GetWhich(SID_PRINTSIZE),
+ (sal_uInt16) GetPrintSize()));
+ rSet.Put(SfxUInt16Item(pPool->GetWhich(SID_PRINTZOOM),
+ (sal_uInt16) GetPrintZoomFactor()));
+
+ rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTTITLE), IsPrintTitle()));
+ rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTTEXT), IsPrintFormulaText()));
+ rSet.Put(SfxBoolItem(pPool->GetWhich(SID_PRINTFRAME), IsPrintFrame()));
+ rSet.Put(SfxBoolItem(pPool->GetWhich(SID_AUTOREDRAW), IsAutoRedraw()));
+ rSet.Put(SfxBoolItem(pPool->GetWhich(SID_NO_RIGHT_SPACES), IsIgnoreSpacesRight()));
+ rSet.Put(SfxBoolItem(pPool->GetWhich(SID_SAVE_ONLY_USED_SYMBOLS), IsSaveOnlyUsedSymbols()));
+}
+
+
+/////////////////////////////////////////////////////////////////
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/cursor.cxx b/starmath/source/cursor.cxx
new file mode 100644
index 000000000000..9c164355d851
--- /dev/null
+++ b/starmath/source/cursor.cxx
@@ -0,0 +1,1646 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Jonas Finnemann Jensen <jopsen@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jonas Finnemann Jensen <jopsen@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include "cursor.hxx"
+#include "parse.hxx"
+#include "visitors.hxx"
+#include "document.hxx"
+#include "view.hxx"
+#include "accessibility.hxx"
+
+void SmCursor::Move(OutputDevice* pDev, SmMovementDirection direction, bool bMoveAnchor){
+ SmCaretPosGraphEntry* NewPos = NULL;
+ switch(direction){
+ case MoveLeft:
+ {
+ NewPos = position->Left;
+ OSL_ENSURE(NewPos, "NewPos shouldn't be NULL here!");
+ }break;
+ case MoveRight:
+ {
+ NewPos = position->Right;
+ OSL_ENSURE(NewPos, "NewPos shouldn't be NULL here!");
+ }break;
+ case MoveUp:
+ //Implementation is practically identical to MoveDown, except for a single if statement
+ //so I've implemented them together and added a direction == MoveDown to the if statements.
+ case MoveDown:
+ {
+ SmCaretLine from_line = SmCaretPos2LineVisitor(pDev, position->CaretPos).GetResult(),
+ best_line, //Best approximated line found so far
+ curr_line; //Current line
+ long dbp_sq = 0; //Distance squared to best line
+ SmCaretPosGraphIterator it = pGraph->GetIterator();
+ while(it.Next()){
+ //Reject it if it's the current position
+ if(it->CaretPos == position->CaretPos) continue;
+ //Compute caret line
+ curr_line = SmCaretPos2LineVisitor(pDev, it->CaretPos).GetResult();
+ //Reject anything above if we're moving down
+ if(curr_line.GetTop() <= from_line.GetTop() && direction == MoveDown) continue;
+ //Reject anything below if we're moving up
+ if(curr_line.GetTop() + curr_line.GetHeight() >= from_line.GetTop() + from_line.GetHeight()
+ && direction == MoveUp) continue;
+ //Compare if it to what we have, if we have anything yet
+ if(NewPos){
+ //Compute distance to current line squared, multiplied with a horizontial factor
+ long dp_sq = curr_line.SquaredDistanceX(from_line) * HORIZONTICAL_DISTANCE_FACTOR +
+ curr_line.SquaredDistanceY(from_line);
+ //Discard current line if best line is closer
+ if(dbp_sq <= dp_sq) continue;
+ }
+ //Take current line as the best
+ best_line = curr_line;
+ NewPos = it.Current();
+ //Update distance to best line
+ dbp_sq = best_line.SquaredDistanceX(from_line) * HORIZONTICAL_DISTANCE_FACTOR +
+ best_line.SquaredDistanceY(from_line);
+ }
+ }break;
+ default:
+ OSL_FAIL("Movement direction not supported!");
+ }
+ if(NewPos){
+ position = NewPos;
+ if(bMoveAnchor)
+ anchor = NewPos;
+ RequestRepaint();
+ }
+}
+
+void SmCursor::MoveTo(OutputDevice* pDev, Point pos, bool bMoveAnchor){
+ SmCaretLine best_line, //Best line found so far, when iterating
+ curr_line; //Current line, when iterating
+ SmCaretPosGraphEntry* NewPos = NULL;
+ long dp_sq = 0, //Distance to current line squared
+ dbp_sq = 1; //Distance to best line squared
+ SmCaretPosGraphIterator it = pGraph->GetIterator();
+ while(it.Next()){
+ OSL_ENSURE(it->CaretPos.IsValid(), "The caret position graph may not have invalid positions!");
+ //Compute current line
+ curr_line = SmCaretPos2LineVisitor(pDev, it->CaretPos).GetResult();
+ //If we have a position compare to it
+ if(NewPos){
+ //Compute squared distance to current line
+ dp_sq = curr_line.SquaredDistanceX(pos) + curr_line.SquaredDistanceY(pos);
+ //If best line is closer, reject current line
+ if(dbp_sq <= dp_sq) continue;
+ }
+ //Accept current position as the best
+ best_line = curr_line;
+ NewPos = it.Current();
+ //Update distance to best line
+ dbp_sq = best_line.SquaredDistanceX(pos) + best_line.SquaredDistanceY(pos);
+ }
+ if(NewPos){
+ position = NewPos;
+ if(bMoveAnchor)
+ anchor = NewPos;
+ RequestRepaint();
+ }
+}
+
+void SmCursor::BuildGraph(){
+ //Save the current anchor and position
+ SmCaretPos _anchor, _position;
+ //Release pGraph if allocated
+ if(pGraph){
+ if(anchor)
+ _anchor = anchor->CaretPos;
+ if(position)
+ _position = position->CaretPos;
+ delete pGraph;
+ //Reset anchor and position as they point into an old graph
+ anchor = NULL;
+ position = NULL;
+ }
+ pGraph = NULL;
+
+ //Build the new graph
+ pGraph = SmCaretPosGraphBuildingVisitor(pTree).Graph();
+
+ //Restore anchor and position pointers
+ if(_anchor.IsValid() || _position.IsValid()){
+ SmCaretPosGraphIterator it = pGraph->GetIterator();
+ while(it.Next()){
+ if(_anchor == it->CaretPos)
+ anchor = it.Current();
+ if(_position == it->CaretPos)
+ position = it.Current();
+ }
+ }
+ //Set position and anchor to first caret position
+ SmCaretPosGraphIterator it = pGraph->GetIterator();
+ if(!position)
+ position = it.Next();
+ if(!anchor)
+ anchor = position;
+
+ OSL_ENSURE(position->CaretPos.IsValid(), "Position must be valid");
+ OSL_ENSURE(anchor->CaretPos.IsValid(), "Anchor must be valid");
+}
+
+bool SmCursor::SetCaretPosition(SmCaretPos pos, bool moveAnchor){
+ SmCaretPosGraphIterator it = pGraph->GetIterator();
+ while(it.Next()){
+ if(it->CaretPos == pos){
+ position = it.Current();
+ if(moveAnchor)
+ anchor = it.Current();
+ return true;
+ }
+ }
+ return false;
+}
+
+void SmCursor::AnnotateSelection(){
+ //TODO: Manage a state, reset it upon modification and optimize this call
+ SmSetSelectionVisitor(anchor->CaretPos, position->CaretPos, pTree);
+}
+
+void SmCursor::Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible){
+ SmCaretDrawingVisitor(pDev, GetPosition(), Offset, isCaretVisible);
+}
+
+void SmCursor::DeletePrev(OutputDevice* pDev){
+ //Delete only a selection if there's a selection
+ if(HasSelection()){
+ Delete();
+ return;
+ }
+
+ SmNode* pLine = FindTopMostNodeInLine(position->CaretPos.pSelectedNode);
+ SmStructureNode* pLineParent = pLine->GetParent();
+ int nLineOffset = pLineParent->IndexOfSubNode(pLine);
+
+ //If we're in front of a node who's parent is a TABLE
+ if(pLineParent->GetType() == NTABLE && position->CaretPos.Index == 0 && nLineOffset > 0){
+ //Now we can merge with nLineOffset - 1
+ BeginEdit();
+ //Line to merge things into, so we can delete pLine
+ SmNode* pMergeLine = pLineParent->GetSubNode(nLineOffset-1);
+ OSL_ENSURE(pMergeLine, "pMergeLine cannot be NULL!");
+ //Convert first line to list
+ SmNodeList *pLineList = NodeToList(pMergeLine);
+ //Find iterator to patch
+ SmNodeList::iterator patchPoint = pLineList->end();
+ --patchPoint;
+ //Convert second line to list
+ NodeToList(pLine, pLineList);
+ //Patch the line list
+ ++patchPoint;
+ SmCaretPos PosAfterDelete = PatchLineList(pLineList, patchPoint);
+ //Parse the line
+ pLine = SmNodeListParser().Parse(pLineList);
+ delete pLineList;
+ pLineParent->SetSubNode(nLineOffset-1, pLine);
+ //Delete the removed line slot
+ SmNodeArray lines(pLineParent->GetNumSubNodes()-1);
+ for(int i = 0; i < pLineParent->GetNumSubNodes(); i++){
+ if(i < nLineOffset)
+ lines[i] = pLineParent->GetSubNode(i);
+ else if(i > nLineOffset)
+ lines[i-1] = pLineParent->GetSubNode(i);
+ }
+ pLineParent->SetSubNodes(lines);
+ //Rebuild graph
+ anchor = NULL;
+ position = NULL;
+ BuildGraph();
+ AnnotateSelection();
+ //Set caret position
+ if(!SetCaretPosition(PosAfterDelete, true))
+ SetCaretPosition(SmCaretPos(pLine, 0), true);
+ //Finish editing
+ EndEdit();
+
+ //TODO: If we're in an empty (sub/super/*) script
+ /*}else if(pLineParent->GetType() == NSUBSUP &&
+ nLineOffset != 0 &&
+ pLine->GetType() == NEXPRESSION &&
+ pLine->GetNumSubNodes() == 0){
+ //There's a (sub/super) script we can delete
+ //Consider selecting the entire script if GetNumSubNodes() != 0 or pLine->GetType() != NEXPRESSION
+ //TODO: Handle case where we delete a limit
+ */
+
+ //Else move select, and delete if not complex
+ }else{
+ this->Move(pDev, MoveLeft, false);
+ if(!this->HasComplexSelection())
+ Delete();
+ }
+}
+
+void SmCursor::Delete(){
+ //Return if we don't have a selection to delete
+ if(!HasSelection())
+ return;
+
+ //Enter edit setion
+ BeginEdit();
+
+ //Set selected on nodes
+ AnnotateSelection();
+
+ //Find an arbitrary selected node
+ SmNode* pSNode = FindSelectedNode(pTree);
+ OSL_ENSURE(pSNode != NULL, "There must be a selection when HasSelection is true!");
+
+ //Find the topmost node of the line that holds the selection
+ SmNode* pLine = FindTopMostNodeInLine(pSNode, true);
+ OSL_ENSURE(pLine != pTree, "Shouldn't be able to select the entire tree");
+
+ //Get the parent of the line
+ SmStructureNode* pLineParent = pLine->GetParent();
+ //Find line offset in parent
+ int nLineOffset = pLineParent->IndexOfSubNode(pLine);
+ OSL_ENSURE(nLineOffset != -1, "pLine must be a child of it's parent!");
+
+ //Position after delete
+ SmCaretPos PosAfterDelete;
+
+ SmNodeList* pLineList = NodeToList(pLine);
+
+ //Take the selected nodes and delete them...
+ SmNodeList::iterator patchIt = TakeSelectedNodesFromList(pLineList);
+
+ //Get teh position to set after delete
+ PosAfterDelete = PatchLineList(pLineList, patchIt);
+
+ //Finish editing
+ FinishEdit(pLineList, pLineParent, nLineOffset, PosAfterDelete);
+}
+
+void SmCursor::InsertNodes(SmNodeList* pNewNodes){
+ if(pNewNodes->size() == 0){
+ delete pNewNodes;
+ return;
+ }
+
+ //Begin edit section
+ BeginEdit();
+
+ //Position after insert should be after pNewNode
+ SmCaretPos PosAfterInsert = SmCaretPos(pNewNodes->back(), 1);
+
+ //Get the current position
+ const SmCaretPos pos = position->CaretPos;
+
+ //Find top most of line that holds position
+ SmNode* pLine = FindTopMostNodeInLine(pos.pSelectedNode, false);
+
+ //Find line parent and line index in parent
+ SmStructureNode* pLineParent = pLine->GetParent();
+ int nParentIndex = pLineParent->IndexOfSubNode(pLine);
+ OSL_ENSURE(nParentIndex != -1, "pLine must be a subnode of pLineParent!");
+
+ //Convert line to list
+ SmNodeList* pLineList = NodeToList(pLine);
+
+ //Find iterator for place to insert nodes
+ SmNodeList::iterator it = FindPositionInLineList(pLineList, pos);
+
+ //Insert all new nodes
+ SmNodeList::iterator newIt,
+ patchIt = it, // (pointless default value, fixes compiler warnings)
+ insIt;
+ for(newIt = pNewNodes->begin(); newIt != pNewNodes->end(); ++newIt){
+ insIt = pLineList->insert(it, *newIt);
+ if(newIt == pNewNodes->begin())
+ patchIt = insIt;
+ if((*newIt)->GetType() == NTEXT)
+ PosAfterInsert = SmCaretPos(*newIt, ((SmTextNode*)*newIt)->GetText().Len());
+ else
+ PosAfterInsert = SmCaretPos(*newIt, 1);
+ }
+ //Patch the places we've changed stuff
+ PatchLineList(pLineList, patchIt);
+ PosAfterInsert = PatchLineList(pLineList, it);
+ //Release list, we've taken the nodes
+ delete pNewNodes;
+ pNewNodes = NULL;
+
+ //Finish editing
+ FinishEdit(pLineList, pLineParent, nParentIndex, PosAfterInsert);
+}
+
+SmNodeList::iterator SmCursor::FindPositionInLineList(SmNodeList* pLineList, SmCaretPos aCaretPos) {
+ //Find iterator for position
+ SmNodeList::iterator it;
+ for(it = pLineList->begin(); it != pLineList->end(); ++it){
+ if(*it == aCaretPos.pSelectedNode){
+ if((*it)->GetType() == NTEXT){
+ //Split textnode if needed
+ if(aCaretPos.Index > 0){
+ SmTextNode* pText = (SmTextNode*)aCaretPos.pSelectedNode;
+ XubString str1 = pText->GetText().Copy(0, aCaretPos.Index);
+ XubString str2 = pText->GetText().Copy(aCaretPos.Index);
+ pText->ChangeText(str1);
+ ++it;
+ //Insert str2 as new text node
+ if(str2.Len() > 0){
+ SmTextNode* pNewText = new SmTextNode(pText->GetToken(), pText->GetFontDesc());
+ pNewText->ChangeText(str2);
+ it = pLineList->insert(it, pNewText);
+ }
+ }
+ }else
+ ++it;
+ //it now pointer to the node following pos, so pLineList->insert(it, ...) will insert correctly
+ return it;
+
+ }
+ }
+ //If we didn't find pSelectedNode, it must be because the caret is infront of the line
+ return pLineList->begin();
+}
+
+SmCaretPos SmCursor::PatchLineList(SmNodeList* pLineList, SmNodeList::iterator aIter) {
+ //The nodes we should consider merging
+ SmNode *prev = NULL,
+ *next = NULL;
+ if(aIter != pLineList->end())
+ next = *aIter;
+ if(aIter != pLineList->begin()) {
+ --aIter;
+ prev = *aIter;
+ ++aIter;
+ }
+
+ //Check if there's textnodes to merge
+ if( prev &&
+ next &&
+ prev->GetType() == NTEXT &&
+ next->GetType() == NTEXT &&
+ ( prev->GetToken().eType != TNUMBER ||
+ next->GetToken().eType == TNUMBER) ){
+ SmTextNode *pText = (SmTextNode*)prev,
+ *pOldN = (SmTextNode*)next;
+ SmCaretPos retval(pText, pText->GetText().Len());
+ String newText;
+ newText += pText->GetText();
+ newText += pOldN->GetText();
+ pText->ChangeText(newText);
+ delete pOldN;
+ pLineList->erase(aIter);
+ return retval;
+ }
+
+ //Check if there's a SmPlaceNode to remove:
+ if(prev && next && prev->GetType() == NPLACE && !SmNodeListParser::IsOperator(next->GetToken())){
+ --aIter;
+ aIter = pLineList->erase(aIter);
+ delete prev;
+ //Return caret pos infront of aIter
+ if(aIter != pLineList->begin())
+ --aIter; //Thus find node before aIter
+ if(aIter == pLineList->begin())
+ return SmCaretPos();
+ if((*aIter)->GetType() == NTEXT)
+ return SmCaretPos(*aIter, ((SmTextNode*)*aIter)->GetText().Len());
+ return SmCaretPos(*aIter, 1);
+ }
+ if(prev && next && next->GetType() == NPLACE && !SmNodeListParser::IsOperator(prev->GetToken())){
+ aIter = pLineList->erase(aIter);
+ delete next;
+ if(prev->GetType() == NTEXT)
+ return SmCaretPos(prev, ((SmTextNode*)prev)->GetText().Len());
+ return SmCaretPos(prev, 1);
+ }
+
+ //If we didn't do anything return
+ if(!prev) //return an invalid to indicate we're infront of line
+ return SmCaretPos();
+ if(prev->GetType() == NTEXT)
+ return SmCaretPos(prev, ((SmTextNode*)prev)->GetText().Len());
+ return SmCaretPos(prev, 1);
+}
+
+SmNodeList::iterator SmCursor::TakeSelectedNodesFromList(SmNodeList *pLineList,
+ SmNodeList *pSelectedNodes) {
+ SmNodeList::iterator retval;
+ SmNodeList::iterator it = pLineList->begin();
+ while(it != pLineList->end()){
+ if((*it)->IsSelected()){
+ //Split text nodes
+ if((*it)->GetType() == NTEXT) {
+ SmTextNode* pText = (SmTextNode*)*it;
+ String aText = pText->GetText();
+ //Start and lengths of the segments, 2 is the selected segment
+ int start2 = pText->GetSelectionStart(),
+ start3 = pText->GetSelectionEnd(),
+ len1 = start2 - 0,
+ len2 = start3 - start2,
+ len3 = aText.Len() - start3;
+ SmToken aToken = pText->GetToken();
+ sal_uInt16 eFontDesc = pText->GetFontDesc();
+ //If we need make segment 1
+ if(len1 > 0) {
+ int start1 = 0;
+ String str = aText.Copy(start1, len1);
+ pText->ChangeText(str);
+ ++it;
+ } else {//Remove it if not needed
+ it = pLineList->erase(it);
+ delete pText;
+ }
+ //Set retval to be right after the selection
+ retval = it;
+ //if we need make segment 3
+ if(len3 > 0) {
+ String str = aText.Copy(start3, len3);
+ SmTextNode* pSeg3 = new SmTextNode(aToken, eFontDesc);
+ pSeg3->ChangeText(str);
+ retval = pLineList->insert(it, pSeg3);
+ }
+ //If we need to save the selected text
+ if(pSelectedNodes && len2 > 0) {
+ String str = aText.Copy(start2, len2);
+ SmTextNode* pSeg2 = new SmTextNode(aToken, eFontDesc);
+ pSeg2->ChangeText(str);
+ pSelectedNodes->push_back(pSeg2);
+ }
+ } else { //if it's not textnode
+ SmNode* pNode = *it;
+ retval = it = pLineList->erase(it);
+ if(pSelectedNodes)
+ pSelectedNodes->push_back(pNode);
+ else
+ delete pNode;
+ }
+ } else
+ ++it;
+ }
+ return retval;
+}
+
+void SmCursor::InsertSubSup(SmSubSup eSubSup) {
+ AnnotateSelection();
+
+ //Find line
+ SmNode *pLine;
+ if(HasSelection()) {
+ SmNode *pSNode = FindSelectedNode(pTree);
+ OSL_ENSURE(pSNode != NULL, "There must be a selected node when HasSelection is true!");
+ pLine = FindTopMostNodeInLine(pSNode, sal_True);
+ } else
+ pLine = FindTopMostNodeInLine(position->CaretPos.pSelectedNode, sal_False);
+
+ //Find Parent and offset in parent
+ SmStructureNode *pLineParent = pLine->GetParent();
+ int nParentIndex = pLineParent->IndexOfSubNode(pLine);
+ OSL_ENSURE(nParentIndex != -1, "pLine must be a subnode of pLineParent!");
+
+ //TODO: Consider handling special cases where parent is an SmOperNode,
+ // Maybe this method should be able to add limits to an SmOperNode...
+
+ //We begin modifying the tree here
+ BeginEdit();
+
+ //Convert line to list
+ SmNodeList* pLineList = NodeToList(pLine);
+
+ //Take the selection, and/or find iterator for current position
+ SmNodeList* pSelectedNodesList = new SmNodeList();
+ SmNodeList::iterator it;
+ if(HasSelection())
+ it = TakeSelectedNodesFromList(pLineList, pSelectedNodesList);
+ else
+ it = FindPositionInLineList(pLineList, position->CaretPos);
+
+ //Find node that this should be applied to
+ SmNode* pSubject;
+ bool bPatchLine = pSelectedNodesList->size() > 0; //If the line should be patched later
+ if(it != pLineList->begin()) {
+ --it;
+ pSubject = *it;
+ ++it;
+ } else {
+ //Create a new place node
+ pSubject = new SmPlaceNode();
+ pSubject->Prepare(pDocShell->GetFormat(), *pDocShell);
+ it = pLineList->insert(it, pSubject);
+ ++it;
+ bPatchLine = true; //We've modified the line it should be patched later.
+ }
+
+ //Wrap the subject in a SmSubSupNode
+ SmSubSupNode* pSubSup;
+ if(pSubject->GetType() != NSUBSUP){
+ SmToken token;
+ token.nGroup = TGPOWER;
+ pSubSup = new SmSubSupNode(token);
+ pSubSup->SetBody(pSubject);
+ *(--it) = pSubSup;
+ ++it;
+ }else
+ pSubSup = (SmSubSupNode*)pSubject;
+ //pSubject shouldn't be referenced anymore, pSubSup is the SmSubSupNode in pLineList we wish to edit.
+ //and it pointer to the element following pSubSup in pLineList.
+ pSubject = NULL;
+
+ //Patch the line if we noted that was needed previously
+ if(bPatchLine)
+ PatchLineList(pLineList, it);
+
+ //Convert existing, if any, sub-/superscript line to list
+ SmNode *pScriptLine = pSubSup->GetSubSup(eSubSup);
+ SmNodeList* pScriptLineList = NodeToList(pScriptLine);
+
+ //Add selection to pScriptLineList
+ unsigned int nOldSize = pScriptLineList->size();
+ pScriptLineList->insert(pScriptLineList->end(), pSelectedNodesList->begin(), pSelectedNodesList->end());
+ delete pSelectedNodesList;
+ pSelectedNodesList = NULL;
+
+ //Patch pScriptLineList if needed
+ if(0 < nOldSize && nOldSize < pScriptLineList->size()) {
+ SmNodeList::iterator iPatchPoint = pScriptLineList->begin();
+ std::advance(iPatchPoint, nOldSize);
+ PatchLineList(pScriptLineList, iPatchPoint);
+ }
+
+ //Find caret pos, that should be used after sub-/superscription.
+ SmCaretPos PosAfterScript; //Leave invalid for first position
+ if(pScriptLineList->size() > 0)
+ PosAfterScript = SmCaretPos::GetPosAfter(pScriptLineList->back());
+
+ //Parse pScriptLineList
+ pScriptLine = SmNodeListParser().Parse(pScriptLineList);
+ delete pScriptLineList;
+ pScriptLineList = NULL;
+
+ //Insert pScriptLine back into the tree
+ pSubSup->SetSubSup(eSubSup, pScriptLine);
+
+ //Finish editing
+ FinishEdit(pLineList, pLineParent, nParentIndex, PosAfterScript, pScriptLine);
+}
+
+bool SmCursor::InsertLimit(SmSubSup eSubSup, bool bMoveCaret) {
+ //Find a subject to set limits on
+ SmOperNode *pSubject = NULL;
+ //Check if pSelectedNode might be a subject
+ if(position->CaretPos.pSelectedNode->GetType() == NOPER)
+ pSubject = (SmOperNode*)position->CaretPos.pSelectedNode;
+ else {
+ //If not, check if parent of the current line is a SmOperNode
+ SmNode *pLineNode = FindTopMostNodeInLine(position->CaretPos.pSelectedNode, sal_False);
+ if(pLineNode->GetParent() && pLineNode->GetParent()->GetType() == NOPER)
+ pSubject = (SmOperNode*)pLineNode->GetParent();
+ }
+
+ //Abort operation if we're not in the appropriate context
+ if(!pSubject)
+ return false;
+
+ BeginEdit();
+
+ //Find the sub sup node
+ SmSubSupNode *pSubSup = NULL;
+ //Check if there's already one there...
+ if(pSubject->GetSubNode(0)->GetType() == NSUBSUP)
+ pSubSup = (SmSubSupNode*)pSubject->GetSubNode(0);
+ else { //if not create a new SmSubSupNode
+ SmToken token;
+ token.nGroup = TGLIMIT;
+ pSubSup = new SmSubSupNode(token);
+ //Set it's body
+ pSubSup->SetBody(pSubject->GetSubNode(0));
+ //Replace the operation of the SmOperNode
+ pSubject->SetSubNode(0, pSubSup);
+ }
+
+ //Create the limit, if needed
+ SmCaretPos PosAfterLimit;
+ SmNode *pLine = NULL;
+ if(!pSubSup->GetSubSup(eSubSup)){
+ pLine = new SmPlaceNode();
+ pSubSup->SetSubSup(eSubSup, pLine);
+ PosAfterLimit = SmCaretPos(pLine, 1);
+ //If it's already there... let's move the caret
+ } else if(bMoveCaret){
+ pLine = pSubSup->GetSubSup(eSubSup);
+ SmNodeList* pLineList = NodeToList(pLine);
+ if(pLineList->size() > 0)
+ PosAfterLimit = SmCaretPos::GetPosAfter(pLineList->back());
+ pLine = SmNodeListParser().Parse(pLineList);
+ delete pLineList;
+ pSubSup->SetSubSup(eSubSup, pLine);
+ }
+
+ //Rebuild graph of caret positions
+ BuildGraph();
+ AnnotateSelection();
+
+ //Set caret position
+ if(bMoveCaret)
+ if(!SetCaretPosition(PosAfterLimit, true))
+ SetCaretPosition(SmCaretPos(pLine, 0), true);
+
+ EndEdit();
+
+ return true;
+}
+
+void SmCursor::InsertBrackets(SmBracketType eBracketType) {
+ BeginEdit();
+
+ AnnotateSelection();
+
+ //Find line
+ SmNode *pLine;
+ if(HasSelection()) {
+ SmNode *pSNode = FindSelectedNode(pTree);
+ OSL_ENSURE(pSNode != NULL, "There must be a selected node if HasSelection()");
+ pLine = FindTopMostNodeInLine(pSNode, sal_True);
+ } else
+ pLine = FindTopMostNodeInLine(position->CaretPos.pSelectedNode, sal_False);
+
+ //Find parent and offset in parent
+ SmStructureNode *pLineParent = pLine->GetParent();
+ int nParentIndex = pLineParent->IndexOfSubNode(pLine);
+ OSL_ENSURE( nParentIndex != -1, "pLine must be a subnode of pLineParent!");
+
+ //Convert line to list
+ SmNodeList *pLineList = NodeToList(pLine);
+
+ //Take the selection, and/or find iterator for current position
+ SmNodeList *pSelectedNodesList = new SmNodeList();
+ SmNodeList::iterator it;
+ if(HasSelection())
+ it = TakeSelectedNodesFromList(pLineList, pSelectedNodesList);
+ else
+ it = FindPositionInLineList(pLineList, position->CaretPos);
+
+ //If there's no selected nodes, create a place node
+ SmCaretPos PosAfterInsert;
+ if(pSelectedNodesList->size() == 0) {
+ SmNode* pPlace = new SmPlaceNode();
+ PosAfterInsert = SmCaretPos(pPlace, 1);
+ pSelectedNodesList->push_front(pPlace);
+ }
+
+ //Parse body nodes
+ SmNode *pBodyNode = SmNodeListParser().Parse(pSelectedNodesList);
+ delete pSelectedNodesList;
+
+ //Create SmBraceNode
+ SmToken aTok(TLEFT, '\0', "left", 0, 5);
+ SmBraceNode *pBrace = new SmBraceNode(aTok);
+ pBrace->SetScaleMode(SCALE_HEIGHT);
+ SmNode *pLeft = CreateBracket(eBracketType, true),
+ *pRight = CreateBracket(eBracketType, false);
+ SmBracebodyNode *pBody = new SmBracebodyNode(SmToken());
+ pBody->SetSubNodes(pBodyNode, NULL);
+ pBrace->SetSubNodes(pLeft, pBody, pRight);
+ pBrace->Prepare(pDocShell->GetFormat(), *pDocShell);
+
+ //Insert into line
+ pLineList->insert(it, pBrace);
+ //Patch line (I think this is good enough)
+ SmCaretPos pAfter = PatchLineList(pLineList, it);
+ if( !PosAfterInsert.IsValid() )
+ PosAfterInsert = pAfter;
+
+ //Finish editing
+ FinishEdit(pLineList, pLineParent, nParentIndex, PosAfterInsert);
+}
+
+SmNode *SmCursor::CreateBracket(SmBracketType eBracketType, bool bIsLeft) {
+ SmToken aTok;
+ if(bIsLeft){
+ switch(eBracketType){
+ case NoneBrackets:
+ aTok = SmToken(TNONE, '\0', "none", TGLBRACES | TGRBRACES, 0);
+ break;
+ case RoundBrackets:
+ aTok = SmToken(TLPARENT, MS_LPARENT, "(", TGLBRACES, 5);
+ break;
+ case SquareBrackets:
+ aTok = SmToken(TLBRACKET, MS_LBRACKET, "[", TGLBRACES, 5);
+ break;
+ case DoubleSquareBrackets:
+ aTok = SmToken(TLDBRACKET, MS_LDBRACKET, "ldbracket", TGLBRACES, 5);
+ break;
+ case LineBrackets:
+ aTok = SmToken(TLLINE, MS_LINE, "lline", TGLBRACES, 5);
+ break;
+ case DoubleLineBrackets:
+ aTok = SmToken(TLDLINE, MS_DLINE, "ldline", TGLBRACES, 5);
+ break;
+ case CurlyBrackets:
+ aTok = SmToken(TLBRACE, MS_LBRACE, "lbrace", TGLBRACES, 5);
+ break;
+ case AngleBrackets:
+ aTok = SmToken(TLANGLE, MS_LANGLE, "langle", TGLBRACES, 5);
+ break;
+ case CeilBrackets:
+ aTok = SmToken(TLCEIL, MS_LCEIL, "lceil", TGLBRACES, 5);
+ break;
+ case FloorBrackets:
+ aTok = SmToken(TLFLOOR, MS_LFLOOR, "lfloor", TGLBRACES, 5);
+ break;
+ }
+ } else {
+ switch(eBracketType) {
+ case NoneBrackets:
+ aTok = SmToken(TNONE, '\0', "none", TGLBRACES | TGRBRACES, 0);
+ break;
+ case RoundBrackets:
+ aTok = SmToken(TRPARENT, MS_RPARENT, ")", TGRBRACES, 5);
+ break;
+ case SquareBrackets:
+ aTok = SmToken(TRBRACKET, MS_RBRACKET, "]", TGRBRACES, 5);
+ break;
+ case DoubleSquareBrackets:
+ aTok = SmToken(TRDBRACKET, MS_RDBRACKET, "rdbracket", TGRBRACES, 5);
+ break;
+ case LineBrackets:
+ aTok = SmToken(TRLINE, MS_LINE, "rline", TGRBRACES, 5);
+ break;
+ case DoubleLineBrackets:
+ aTok = SmToken(TRDLINE, MS_DLINE, "rdline", TGRBRACES, 5);
+ break;
+ case CurlyBrackets:
+ aTok = SmToken(TRBRACE, MS_RBRACE, "rbrace", TGRBRACES, 5);
+ break;
+ case AngleBrackets:
+ aTok = SmToken(TRANGLE, MS_RANGLE, "rangle", TGRBRACES, 5);
+ break;
+ case CeilBrackets:
+ aTok = SmToken(TRCEIL, MS_RCEIL, "rceil", TGRBRACES, 5);
+ break;
+ case FloorBrackets:
+ aTok = SmToken(TRFLOOR, MS_RFLOOR, "rfloor", TGRBRACES, 5);
+ break;
+ }
+ }
+ SmNode* pRetVal = new SmMathSymbolNode(aTok);
+ pRetVal->SetScaleMode(SCALE_HEIGHT);
+ return pRetVal;
+}
+
+bool SmCursor::InsertRow() {
+ AnnotateSelection();
+
+ //Find line
+ SmNode *pLine;
+ if(HasSelection()) {
+ SmNode *pSNode = FindSelectedNode(pTree);
+ OSL_ENSURE(pSNode != NULL, "There must be a selected node if HasSelection()");
+ pLine = FindTopMostNodeInLine(pSNode, sal_True);
+ } else
+ pLine = FindTopMostNodeInLine(position->CaretPos.pSelectedNode, sal_False);
+
+ //Find parent and offset in parent
+ SmStructureNode *pLineParent = pLine->GetParent();
+ int nParentIndex = pLineParent->IndexOfSubNode(pLine);
+ OSL_ENSURE( nParentIndex != -1, "pLine must be a subnode of pLineParent!");
+
+ //Discover the context of this command
+ SmTableNode *pTable = NULL;
+ SmMatrixNode *pMatrix = NULL;
+ int nTableIndex = nParentIndex;
+ if(pLineParent->GetType() == NTABLE)
+ pTable = (SmTableNode*)pLineParent;
+ //If it's warped in a SmLineNode, we can still insert a newline
+ else if(pLineParent->GetType() == NLINE &&
+ pLineParent->GetParent() &&
+ pLineParent->GetParent()->GetType() == NTABLE) {
+ //NOTE: This hack might give problems if we stop ignoring SmAlignNode
+ pTable = (SmTableNode*)pLineParent->GetParent();
+ nTableIndex = pTable->IndexOfSubNode(pLineParent);
+ OSL_ENSURE(nTableIndex != -1, "pLineParent must be a child of its parent!");
+ }
+ if(pLineParent->GetType() == NMATRIX)
+ pMatrix = (SmMatrixNode*)pLineParent;
+
+ //If we're not in a context that supports InsertRow, return sal_False
+ if(!pTable && !pMatrix)
+ return false;
+
+ //Now we start editing
+ BeginEdit();
+
+ //Convert line to list
+ SmNodeList *pLineList = NodeToList(pLine);
+
+ //Find position in line
+ SmNodeList::iterator it;
+ if(HasSelection()) {
+ //Take the selected nodes and delete them...
+ it = TakeSelectedNodesFromList(pLineList);
+ } else
+ it = FindPositionInLineList(pLineList, position->CaretPos);
+
+ //New caret position after inserting the newline/row in whatever context
+ SmCaretPos PosAfterInsert;
+
+ //If we're in the context of a table
+ if(pTable) {
+ SmNodeList *pNewLineList = new SmNodeList();
+ //Move elements from pLineList to pNewLineList
+ pNewLineList->splice(pNewLineList->begin(), *pLineList, it, pLineList->end());
+ //Make sure it is valid again
+ it = pLineList->end();
+ if(it != pLineList->begin())
+ --it;
+ if(pNewLineList->size() == 0)
+ pNewLineList->push_front(new SmPlaceNode());
+ //Parse new line
+ SmNode *pNewLine = SmNodeListParser().Parse(pNewLineList);
+ delete pNewLineList;
+ //Wrap pNewLine in SmLineNode if needed
+ if(pLineParent->GetType() == NLINE) {
+ SmLineNode *pNewLineNode = new SmLineNode(SmToken(TNEWLINE, '\0', "newline"));
+ pNewLineNode->SetSubNodes(pNewLine, NULL);
+ pNewLine = pNewLineNode;
+ }
+ //Get position
+ PosAfterInsert = SmCaretPos(pNewLine, 0);
+ //Move other nodes if needed
+ for( int i = pTable->GetNumSubNodes(); i > nTableIndex + 1; i--)
+ pTable->SetSubNode(i, pTable->GetSubNode(i-1));
+
+ //Insert new line
+ pTable->SetSubNode(nTableIndex + 1, pNewLine);
+
+ //Check if we need to change token type:
+ if(pTable->GetNumSubNodes() > 2 && pTable->GetToken().eType == TBINOM) {
+ SmToken tok = pTable->GetToken();
+ tok.eType = TSTACK;
+ pTable->SetToken(tok);
+ }
+ }
+ //If we're in the context of a matrix
+ else if(pMatrix) {
+ //Find position after insert and patch the list
+ PosAfterInsert = PatchLineList(pLineList, it);
+ //Move other children
+ sal_uInt16 rows = pMatrix->GetNumRows();
+ sal_uInt16 cols = pMatrix->GetNumCols();
+ int nRowStart = (nParentIndex - nParentIndex % cols) + cols;
+ for( int i = pMatrix->GetNumSubNodes() + cols - 1; i >= nRowStart + cols; i--)
+ pMatrix->SetSubNode(i, pMatrix->GetSubNode(i - cols));
+ for( int i = nRowStart; i < nRowStart + cols; i++) {
+ SmPlaceNode *pNewLine = new SmPlaceNode();
+ if(i == nParentIndex + cols)
+ PosAfterInsert = SmCaretPos(pNewLine, 0);
+ pMatrix->SetSubNode(i, pNewLine);
+ }
+ pMatrix->SetRowCol(rows + 1, cols);
+ } else
+ OSL_FAIL("We must be either the context of a table or matrix!");
+
+ //Finish editing
+ FinishEdit(pLineList, pLineParent, nParentIndex, PosAfterInsert);
+ //FinishEdit is actually used to handle siturations where parent is an instance of
+ //SmSubSupNode. In this case parent should always be a table or matrix, however, for
+ //code reuse we just use FinishEdit() here too.
+ return true;
+}
+
+void SmCursor::InsertFraction() {
+ AnnotateSelection();
+
+ //Find line
+ SmNode *pLine;
+ if(HasSelection()) {
+ SmNode *pSNode = FindSelectedNode(pTree);
+ OSL_ENSURE(pSNode != NULL, "There must be a selected node when HasSelection is true!");
+ pLine = FindTopMostNodeInLine(pSNode, sal_True);
+ } else
+ pLine = FindTopMostNodeInLine(position->CaretPos.pSelectedNode, sal_False);
+
+ //Find Parent and offset in parent
+ SmStructureNode *pLineParent = pLine->GetParent();
+ int nParentIndex = pLineParent->IndexOfSubNode(pLine);
+ OSL_ENSURE(nParentIndex != -1, "pLine must be a subnode of pLineParent!");
+
+ //We begin modifying the tree here
+ BeginEdit();
+
+ //Convert line to list
+ SmNodeList* pLineList = NodeToList(pLine);
+
+ //Take the selection, and/or find iterator for current position
+ SmNodeList* pSelectedNodesList = new SmNodeList();
+ SmNodeList::iterator it;
+ if(HasSelection())
+ it = TakeSelectedNodesFromList(pLineList, pSelectedNodesList);
+ else
+ it = FindPositionInLineList(pLineList, position->CaretPos);
+
+ //Create pNum, and pDenom
+ if(pSelectedNodesList->size() == 0)
+ pSelectedNodesList->push_front(new SmPlaceNode());
+ SmNode *pNum = SmNodeListParser().Parse(pSelectedNodesList),
+ *pDenom = new SmPlaceNode();
+ delete pSelectedNodesList;
+ pSelectedNodesList = NULL;
+
+ //Create new fraction
+ SmBinVerNode *pFrac = new SmBinVerNode(SmToken(TOVER, '\0', "over", TGPRODUCT, 0));
+ SmNode *pRect = new SmRectangleNode(SmToken());
+ pFrac->SetSubNodes(pNum, pRect, pDenom);
+
+ //Insert in pLineList
+ SmNodeList::iterator patchIt = pLineList->insert(it, pFrac);
+ PatchLineList(pLineList, patchIt);
+ PatchLineList(pLineList, it);
+
+ //Finish editing
+ FinishEdit(pLineList, pLineParent, nParentIndex, SmCaretPos(pDenom, 1));
+}
+
+void SmCursor::InsertText(XubString aString){
+ BeginEdit();
+
+ Delete();
+
+ SmToken token;
+ token.eType = TIDENT;
+ token.cMathChar = '\0';
+ token.nGroup = 0;
+ token.nLevel = 5;
+ token.aText = aString;
+
+ SmTextNode* pText = new SmTextNode(token, FNT_VARIABLE);
+
+ //Prepare the new node
+ pText->Prepare(pDocShell->GetFormat(), *pDocShell);
+ pText->AdjustFontDesc();
+
+ SmNodeList* pList = new SmNodeList();
+ pList->push_front(pText);
+ InsertNodes(pList);
+
+ EndEdit();
+}
+
+void SmCursor::InsertElement(SmFormulaElement element){
+ BeginEdit();
+
+ Delete();
+
+ //Create new node
+ SmNode* pNewNode = NULL;
+ switch(element){
+ case BlankElement:
+ {
+ SmToken token;
+ token.nGroup = TGBLANK;
+ token.aText.AssignAscii("~");
+ pNewNode = new SmBlankNode(token);
+ }break;
+ case FactorialElement:
+ {
+ SmToken token(TFACT, MS_FACT, "fact", TGUNOPER, 5);
+ pNewNode = new SmMathSymbolNode(token);
+ }break;
+ case PlusElement:
+ {
+ SmToken token;
+ token.eType = TPLUS;
+ token.cMathChar = MS_PLUS;
+ token.nGroup = TGUNOPER | TGSUM;
+ token.nLevel = 5;
+ token.aText.AssignAscii("+");
+ pNewNode = new SmMathSymbolNode(token);
+ }break;
+ case MinusElement:
+ {
+ SmToken token;
+ token.eType = TMINUS;
+ token.cMathChar = MS_MINUS;
+ token.nGroup = MS_PLUS;
+ token.nLevel = 5;
+ token.aText.AssignAscii("-");
+ pNewNode = new SmMathSymbolNode(token);
+ }break;
+ case CDotElement:
+ {
+ SmToken token;
+ token.eType = TCDOT;
+ token.cMathChar = MS_CDOT;
+ token.nGroup = TGPRODUCT;
+ token.aText.AssignAscii("cdot");
+ pNewNode = new SmMathSymbolNode(token);
+ }break;
+ case EqualElement:
+ {
+ SmToken token;
+ token.eType = TASSIGN;
+ token.cMathChar = MS_ASSIGN;
+ token.nGroup = TGRELATION;
+ token.aText.AssignAscii("=");
+ pNewNode = new SmMathSymbolNode(token);
+ }break;
+ case LessThanElement:
+ {
+ SmToken token;
+ token.eType = TLT;
+ token.cMathChar = MS_LT;
+ token.nGroup = TGRELATION;
+ token.aText.AssignAscii("<");
+ pNewNode = new SmMathSymbolNode(token);
+ }break;
+ case GreaterThanElement:
+ {
+ SmToken token;
+ token.eType = TGT;
+ token.cMathChar = MS_GT;
+ token.nGroup = TGRELATION;
+ token.aText.AssignAscii(">");
+ pNewNode = new SmMathSymbolNode(token);
+ }break;
+ case PercentElement:
+ {
+ SmToken token;
+ token.eType = TTEXT;
+ token.cMathChar = MS_PERCENT;
+ token.nGroup = 0;
+ token.aText.AssignAscii("\"%\"");
+ pNewNode = new SmMathSymbolNode(token);
+ }break;
+ default:
+ OSL_FAIL("Element unknown!");
+ }
+ OSL_ENSURE(pNewNode != NULL, "No new node was created!");
+ if(!pNewNode)
+ return;
+
+ //Prepare the new node
+ pNewNode->Prepare(pDocShell->GetFormat(), *pDocShell);
+
+ //Insert new node
+ SmNodeList* pList = new SmNodeList();
+ pList->push_front(pNewNode);
+ InsertNodes(pList);
+
+ EndEdit();
+}
+
+void SmCursor::InsertSpecial(XubString aString) {
+ BeginEdit();
+ Delete();
+
+ aString.EraseLeadingAndTrailingChars();
+ aString.EraseLeadingChars('%');
+
+ //Create instance of special node
+ SmToken token;
+ token.eType = TSPECIAL;
+ token.cMathChar = '\0';
+ token.nGroup = 0;
+ token.nLevel = 5;
+ token.aText = aString; //Don't know if leading "%" should be removed
+ SmSpecialNode* pSpecial = new SmSpecialNode(token);
+
+ //Prepare the special node
+ pSpecial->Prepare(pDocShell->GetFormat(), *pDocShell);
+
+ //Insert the node
+ SmNodeList* pList = new SmNodeList();
+ pList->push_front(pSpecial);
+ InsertNodes(pList);
+
+ EndEdit();
+}
+
+void SmCursor::InsertCommand(sal_uInt16 nCommand) {
+ switch(nCommand){
+ case RID_NEWLINE:
+ InsertRow();
+ break;
+ case RID_FROMX:
+ InsertLimit(CSUB, true);
+ break;
+ case RID_TOX:
+ InsertLimit(CSUP, true);
+ break;
+ case RID_FROMXTOY:
+ if(InsertLimit(CSUB, true))
+ InsertLimit(CSUP, true);
+ break;
+ default:
+ InsertCommandText(SmResId(nCommand));
+ break;
+ }
+}
+
+void SmCursor::InsertCommandText(XubString aCommandText) {
+ //Parse the the sub expression
+ SmNode* pSubExpr = SmParser().ParseExpression(aCommandText);
+
+ //Prepare the subtree
+ pSubExpr->Prepare(pDocShell->GetFormat(), *pDocShell);
+
+ //Convert subtree to list
+ SmNodeList* pLineList = NodeToList(pSubExpr);
+
+ BeginEdit();
+
+ //Delete any selection
+ Delete();
+
+ //Insert it
+ InsertNodes(pLineList);
+
+ EndEdit();
+}
+
+void SmCursor::Copy(){
+ if(!HasSelection())
+ return;
+
+ //Find selected node
+ SmNode* pSNode = FindSelectedNode(pTree);
+ //Find visual line
+ SmNode* pLine = FindTopMostNodeInLine(pSNode, true);
+
+ //Clone selected nodes
+ SmNodeList* pList;
+ if(IsLineCompositionNode(pLine))
+ pList = CloneLineToList((SmStructureNode*)pLine, true);
+ else{
+ pList = new SmNodeList();
+ //Special care to only clone selected text
+ if(pLine->GetType() == NTEXT) {
+ SmTextNode *pText = (SmTextNode*)pLine;
+ SmTextNode *pClone = new SmTextNode( pText->GetToken(), pText->GetFontDesc() );
+ int start = pText->GetSelectionStart(),
+ length = pText->GetSelectionEnd() - pText->GetSelectionStart();
+ pClone->ChangeText(pText->GetText().Copy(start, length));
+ pClone->SetScaleMode(pText->GetScaleMode());
+ pList->push_front(pClone);
+ } else {
+ SmCloningVisitor aCloneFactory;
+ pList->push_front(aCloneFactory.Clone(pLine));
+ }
+ }
+
+ //Set clipboard
+ if(pList->size() > 0)
+ SetClipboard(pList);
+}
+
+void SmCursor::Paste() {
+ BeginEdit();
+ Delete();
+
+ if(pClipboard && pClipboard->size() > 0)
+ InsertNodes(CloneList(pClipboard));
+
+ EndEdit();
+}
+
+SmNodeList* SmCursor::CloneList(SmNodeList* pList){
+ SmCloningVisitor aCloneFactory;
+ SmNodeList* pClones = new SmNodeList();
+
+ SmNodeList::iterator it;
+ for(it = pList->begin(); it != pList->end(); ++it){
+ SmNode *pClone = aCloneFactory.Clone(*it);
+ pClones->push_back(pClone);
+ }
+
+ return pClones;
+}
+
+void SmCursor::SetClipboard(SmNodeList* pList){
+ if(pClipboard){
+ //Delete all nodes on the clipboard
+ SmNodeList::iterator it;
+ for(it = pClipboard->begin(); it != pClipboard->end(); ++it)
+ delete (*it);
+ delete pClipboard;
+ }
+ pClipboard = pList;
+}
+
+SmNode* SmCursor::FindTopMostNodeInLine(SmNode* pSNode, bool MoveUpIfSelected){
+ //If we haven't got a subnode
+ if(!pSNode)
+ return NULL;
+
+ //Move up parent untill we find a node who's
+ //parent is NULL or isn't selected and not a type of:
+ // SmExpressionNode
+ // SmLineNode
+ // SmBinHorNode
+ // SmUnHorNode
+ // SmAlignNode
+ // SmFontNode
+ while(pSNode->GetParent() &&
+ ((MoveUpIfSelected &&
+ pSNode->GetParent()->IsSelected()) ||
+ IsLineCompositionNode(pSNode->GetParent())))
+ pSNode = pSNode->GetParent();
+ //Now we have the selection line node
+ return pSNode;
+}
+
+SmNode* SmCursor::FindSelectedNode(SmNode* pNode){
+ SmNodeIterator it(pNode);
+ while(it.Next()){
+ if(it->IsSelected())
+ return it.Current();
+ SmNode* pRetVal = FindSelectedNode(it.Current());
+ if(pRetVal)
+ return pRetVal;
+ }
+ return NULL;
+}
+
+SmNodeList* SmCursor::LineToList(SmStructureNode* pLine, SmNodeList* list){
+ SmNodeIterator it(pLine);
+ while(it.Next()){
+ switch(it->GetType()){
+ case NLINE:
+ case NUNHOR:
+ case NEXPRESSION:
+ case NBINHOR:
+ case NALIGN:
+ case NFONT:
+ LineToList((SmStructureNode*)it.Current(), list);
+ break;
+ case NERROR:
+ delete it.Current();
+ break;
+ default:
+ list->push_back(it.Current());
+ }
+ }
+ SmNodeArray emptyArray(0);
+ pLine->SetSubNodes(emptyArray);
+ delete pLine;
+ return list;
+}
+
+SmNodeList* SmCursor::CloneLineToList(SmStructureNode* pLine, bool bOnlyIfSelected, SmNodeList* pList){
+ SmCloningVisitor aCloneFactory;
+ SmNodeIterator it(pLine);
+ while(it.Next()){
+ if( IsLineCompositionNode( it.Current() ) )
+ CloneLineToList( (SmStructureNode*)it.Current(), bOnlyIfSelected, pList );
+ else if( (!bOnlyIfSelected || it->IsSelected()) && it->GetType() != NERROR ) {
+ //Only clone selected text from SmTextNode
+ if(it->GetType() == NTEXT) {
+ SmTextNode *pText = (SmTextNode*)it.Current();
+ SmTextNode *pClone = new SmTextNode( it->GetToken(), pText->GetFontDesc() );
+ int start = pText->GetSelectionStart(),
+ length = pText->GetSelectionEnd() - pText->GetSelectionStart();
+ pClone->ChangeText(pText->GetText().Copy(start, length));
+ pClone->SetScaleMode(pText->GetScaleMode());
+ pList->push_back(pClone);
+ } else
+ pList->push_back(aCloneFactory.Clone(it.Current()));
+ }
+ }
+ return pList;
+}
+
+bool SmCursor::IsLineCompositionNode(SmNode* pNode){
+ switch(pNode->GetType()){
+ case NLINE:
+ case NUNHOR:
+ case NEXPRESSION:
+ case NBINHOR:
+ case NALIGN:
+ case NFONT:
+ return true;
+ default:
+ return false;
+ }
+ return false;
+}
+
+int SmCursor::CountSelectedNodes(SmNode* pNode){
+ int nCount = 0;
+ SmNodeIterator it(pNode);
+ while(it.Next()){
+ if(it->IsSelected() && !IsLineCompositionNode(it.Current()))
+ nCount++;
+ nCount += CountSelectedNodes(it.Current());
+ }
+ return nCount;
+}
+
+bool SmCursor::HasComplexSelection(){
+ if(!HasSelection())
+ return false;
+ AnnotateSelection();
+
+ return CountSelectedNodes(pTree) > 1;
+}
+
+void SmCursor::FinishEdit(SmNodeList* pLineList,
+ SmStructureNode* pParent,
+ int nParentIndex,
+ SmCaretPos PosAfterEdit,
+ SmNode* pStartLine) {
+ //Store number of nodes in line for later
+ int entries = pLineList->size();
+
+ //Parse list of nodes to a tree
+ SmNodeListParser parser;
+ SmNode* pLine = parser.Parse(pLineList);
+ delete pLineList;
+
+ //Check if we're making the body of a subsup node bigger than one
+ if(pParent->GetType() == NSUBSUP &&
+ nParentIndex == 0 &&
+ entries > 1) {
+ //Wrap pLine in scalable round brackets
+ SmToken aTok(TLEFT, '\0', "left", 0, 5);
+ SmBraceNode *pBrace = new SmBraceNode(aTok);
+ pBrace->SetScaleMode(SCALE_HEIGHT);
+ SmNode *pLeft = CreateBracket(RoundBrackets, true),
+ *pRight = CreateBracket(RoundBrackets, false);
+ SmBracebodyNode *pBody = new SmBracebodyNode(SmToken());
+ pBody->SetSubNodes(pLine, NULL);
+ pBrace->SetSubNodes(pLeft, pBody, pRight);
+ pBrace->Prepare(pDocShell->GetFormat(), *pDocShell);
+ pLine = pBrace;
+ //TODO: Consider the following alternative behavior:
+ //Consider the line: A + {B + C}^D lsub E
+ //Here pLineList is B, + and C and pParent is a subsup node with
+ //both RSUP and LSUB set. Imagine the user just inserted "B +" in
+ //the body of the subsup node...
+ //The most natural thing to do would be to make the line like this:
+ //A + B lsub E + C ^ D
+ //E.g. apply LSUB and LSUP to the first element in pLineList and RSUP
+ //and RSUB to the last eleent in pLineList. But how should this act
+ //for CSUP and CSUB ???
+ //For this reason and because brackets was faster to implement, this solution
+ //have been choosen. It might be worth working on the other solution later...
+ }
+
+ //Set pStartLine if NULL
+ if(!pStartLine)
+ pStartLine = pLine;
+
+ //Insert it back into the parent
+ pParent->SetSubNode(nParentIndex, pLine);
+
+ //Rebuild graph of caret position
+ anchor = NULL;
+ position = NULL;
+ BuildGraph();
+ AnnotateSelection(); //Update selection annotation!
+
+ //Set caret position
+ if(!SetCaretPosition(PosAfterEdit, true))
+ SetCaretPosition(SmCaretPos(pStartLine, 0), true);
+
+ //End edit section
+ EndEdit();
+}
+
+void SmCursor::BeginEdit(){
+ if(nEditSections++ > 0) return;
+
+ bIsEnabledSetModifiedSmDocShell = pDocShell->IsEnableSetModified();
+ if( bIsEnabledSetModifiedSmDocShell )
+ pDocShell->EnableSetModified( sal_False );
+}
+
+void SmCursor::EndEdit(){
+ if(--nEditSections > 0) return;
+
+ pDocShell->SetFormulaArranged(sal_False);
+ //Okay, I don't know what this does... :)
+ //It's used in SmDocShell::SetText and with places where everything is modified.
+ //I think it does some magic, with sfx, but everything is totally undocumented so
+ //it's kinda hard to tell...
+ if ( bIsEnabledSetModifiedSmDocShell )
+ pDocShell->EnableSetModified( bIsEnabledSetModifiedSmDocShell );
+ //I think this notifies people around us that we've modified this document...
+ pDocShell->SetModified(sal_True);
+ //I think SmDocShell uses this value when it sends an update graphics event
+ //Anyway comments elsewhere suggests it need to be updated...
+ pDocShell->nModifyCount++;
+
+ //TODO: Consider copying the update accessability code from SmDocShell::SetText in here...
+ //This somehow updates the size of SmGraphicView if it is running in embedded mode
+ if( pDocShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ pDocShell->OnDocumentPrinterChanged(0);
+
+ //Request a replaint...
+ RequestRepaint();
+
+ //Update the edit engine and text of the document
+ String formula;
+ SmNodeToTextVisitor(pTree, formula);
+ //pTree->CreateTextFromNode(formula);
+ pDocShell->aText = formula;
+ pDocShell->GetEditEngine().QuickInsertText( formula, ESelection( 0, 0, EE_PARA_ALL, EE_PARA_ALL ) );
+ pDocShell->GetEditEngine().QuickFormatDoc();
+}
+
+void SmCursor::RequestRepaint(){
+ SmViewShell *pViewSh = SmGetActiveView();
+ if( pViewSh ) {
+ if ( SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
+ pDocShell->Repaint();
+ else
+ pViewSh->GetGraphicWindow().Invalidate();
+ }
+}
+
+/////////////////////////////////////// SmNodeListParser ///////////////////////////////////////
+
+SmNode* SmNodeListParser::Parse(SmNodeList* list, bool bDeleteErrorNodes){
+ pList = list;
+ if(bDeleteErrorNodes){
+ //Delete error nodes
+ SmNodeList::iterator it = pList->begin();
+ while(it != pList->end()) {
+ if((*it)->GetType() == NERROR){
+ //Delete and erase
+ delete *it;
+ it = pList->erase(it);
+ }else
+ ++it;
+ }
+ }
+ SmNode* retval = Expression();
+ pList = NULL;
+ return retval;
+}
+
+SmNode* SmNodeListParser::Expression(){
+ SmNodeArray NodeArray;
+ //Accept as many relations as there is
+ while(Terminal())
+ NodeArray.push_back(Relation());
+
+ //Create SmExpressionNode, I hope SmToken() will do :)
+ SmStructureNode* pExpr = new SmExpressionNode(SmToken());
+ pExpr->SetSubNodes(NodeArray);
+ return pExpr;
+}
+
+SmNode* SmNodeListParser::Relation(){
+ //Read a sum
+ SmNode* pLeft = Sum();
+ //While we have tokens and the next is a relation
+ while(Terminal() && IsRelationOperator(Terminal()->GetToken())){
+ //Take the operator
+ SmNode* pOper = Take();
+ //Find the right side of the relation
+ SmNode* pRight = Sum();
+ //Create new SmBinHorNode
+ SmStructureNode* pNewNode = new SmBinHorNode(SmToken());
+ pNewNode->SetSubNodes(pLeft, pOper, pRight);
+ pLeft = pNewNode;
+ }
+ return pLeft;
+}
+
+SmNode* SmNodeListParser::Sum(){
+ //Read a product
+ SmNode* pLeft = Product();
+ //While we have tokens and the next is a sum
+ while(Terminal() && IsSumOperator(Terminal()->GetToken())){
+ //Take the operator
+ SmNode* pOper = Take();
+ //Find the right side of the sum
+ SmNode* pRight = Product();
+ //Create new SmBinHorNode
+ SmStructureNode* pNewNode = new SmBinHorNode(SmToken());
+ pNewNode->SetSubNodes(pLeft, pOper, pRight);
+ pLeft = pNewNode;
+ }
+ return pLeft;
+}
+
+SmNode* SmNodeListParser::Product(){
+ //Read a Factor
+ SmNode* pLeft = Factor();
+ //While we have tokens and the next is a product
+ while(Terminal() && IsProductOperator(Terminal()->GetToken())){
+ //Take the operator
+ SmNode* pOper = Take();
+ //Find the right side of the operation
+ SmNode* pRight = Factor();
+ //Create new SmBinHorNode
+ SmStructureNode* pNewNode = new SmBinHorNode(SmToken());
+ pNewNode->SetSubNodes(pLeft, pOper, pRight);
+ pLeft = pNewNode;
+ }
+ return pLeft;
+}
+
+SmNode* SmNodeListParser::Factor(){
+ //Read unary operations
+ if(!Terminal())
+ return Error();
+ //Take care of unary operators
+ else if(IsUnaryOperator(Terminal()->GetToken()))
+ {
+ SmStructureNode *pUnary = new SmUnHorNode(SmToken());
+ SmNode *pOper = Terminal(),
+ *pArg;
+
+ if(Next())
+ pArg = Factor();
+ else
+ pArg = Error();
+
+ pUnary->SetSubNodes(pOper, pArg);
+ return pUnary;
+ }
+ return Postfix();
+}
+
+SmNode* SmNodeListParser::Postfix(){
+ if(!Terminal())
+ return Error();
+ SmNode *pArg = NULL;
+ if(IsPostfixOperator(Terminal()->GetToken()))
+ pArg = Error();
+ else if(IsOperator(Terminal()->GetToken()))
+ return Error();
+ else
+ pArg = Take();
+ while(Terminal() && IsPostfixOperator(Terminal()->GetToken())) {
+ SmStructureNode *pUnary = new SmUnHorNode(SmToken());
+ SmNode *pOper = Take();
+ pUnary->SetSubNodes(pArg, pOper);
+ pArg = pUnary;
+ }
+ return pArg;
+}
+
+SmNode* SmNodeListParser::Error(){
+ return new SmErrorNode(PE_UNEXPECTED_TOKEN, SmToken());
+}
+
+bool SmNodeListParser::IsOperator(const SmToken &token) {
+ return IsRelationOperator(token) ||
+ IsSumOperator(token) ||
+ IsProductOperator(token) ||
+ IsUnaryOperator(token) ||
+ IsPostfixOperator(token);
+}
+
+bool SmNodeListParser::IsRelationOperator(const SmToken &token) {
+ return token.nGroup & TGRELATION;
+}
+
+bool SmNodeListParser::IsSumOperator(const SmToken &token) {
+ return token.nGroup & TGSUM;
+}
+
+bool SmNodeListParser::IsProductOperator(const SmToken &token) {
+ return token.nGroup & TGPRODUCT &&
+ token.eType != TWIDESLASH &&
+ token.eType != TWIDEBACKSLASH &&
+ token.eType != TUNDERBRACE &&
+ token.eType != TOVERBRACE &&
+ token.eType != TOVER;
+}
+
+bool SmNodeListParser::IsUnaryOperator(const SmToken &token) {
+ return token.nGroup & TGUNOPER &&
+ (token.eType == TPLUS ||
+ token.eType == TMINUS ||
+ token.eType == TPLUSMINUS ||
+ token.eType == TMINUSPLUS ||
+ token.eType == TNEG ||
+ token.eType == TUOPER);
+}
+
+bool SmNodeListParser::IsPostfixOperator(const SmToken &token) {
+ return token.eType == TFACT;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/detreg.cxx b/starmath/source/detreg.cxx
new file mode 100644
index 000000000000..45f539b0931d
--- /dev/null
+++ b/starmath/source/detreg.cxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/uno/Sequence.h>
+#include <rtl/ustring.hxx>
+
+#include "smdetect.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+extern "C" {
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char** ppEnvironmentTypeName,
+ uno_Environment** /*ppEnvironment*/ )
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplementationName,
+ void* pServiceManager,
+ void* /*pRegistryKey*/ )
+{
+ // Set default return value for this operation - if it failed.
+ void* pReturn = NULL ;
+
+ if (
+ ( pImplementationName != NULL ) &&
+ ( pServiceManager != NULL )
+ )
+ {
+ // Define variables which are used in following macros.
+ Reference< XSingleServiceFactory > xFactory ;
+ Reference< XMultiServiceFactory > xServiceManager( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+
+ if( SmFilterDetect::impl_getStaticImplementationName().equalsAscii( pImplementationName ) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmFilterDetect::impl_getStaticImplementationName(),
+ SmFilterDetect::impl_createInstance,
+ SmFilterDetect::impl_getStaticSupportedServiceNames() );
+ }
+
+ // Factory is valid - service was found.
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pReturn = xFactory.get();
+ }
+ }
+
+ // Return with result of this operation.
+ return pReturn ;
+}
+} // extern "C"
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/dialog.cxx b/starmath/source/dialog.cxx
new file mode 100644
index 000000000000..0daecc2054dd
--- /dev/null
+++ b/starmath/source/dialog.cxx
@@ -0,0 +1,2441 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#define SMDLL 1
+#include "tools/rcid.h"
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/app.hxx>
+#include <vcl/msgbox.hxx>
+#include <svtools/ctrltool.hxx>
+#include <sfx2/printer.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/sndstyle.hxx>
+#include <vcl/waitobj.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/wall.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/sfx.hrc>
+#include <tools/string.hxx>
+#include <osl/diagnose.h>
+#include <svx/ucsubset.hxx>
+
+
+#include "dialog.hxx"
+#include "starmath.hrc"
+#include "config.hxx"
+#include "dialog.hrc"
+#include "smmod.hxx"
+#include "symbol.hxx"
+#include "view.hxx"
+#include "document.hxx"
+#include "unomodel.hxx"
+
+
+using ::rtl::OUString;
+
+////////////////////////////////////////
+//
+// Da der FontStyle besser ueber die Attribute gesetzt/abgefragt wird als ueber
+// den StyleName bauen wir uns hier unsere eigene Uebersetzung
+// Attribute <-> StyleName
+//
+
+class SmFontStyles
+{
+ String aNormal;
+ String aBold;
+ String aItalic;
+ String aBoldItalic;
+ String aEmpty;
+
+public:
+ SmFontStyles();
+
+ sal_uInt16 GetCount() const { return 4; }
+ const String & GetStyleName( const Font &rFont ) const;
+ const String & GetStyleName( sal_uInt16 nIdx ) const;
+};
+
+
+SmFontStyles::SmFontStyles() :
+ aNormal ( ResId( RID_FONTREGULAR, *SM_MOD()->GetResMgr() ) ),
+ aBold ( ResId( RID_FONTBOLD, *SM_MOD()->GetResMgr() ) ),
+ aItalic ( ResId( RID_FONTITALIC, *SM_MOD()->GetResMgr() ) )
+{
+
+ aBoldItalic = aBold;
+ aBoldItalic.AppendAscii( ", " );
+ aBoldItalic += aItalic;
+}
+
+
+const String & SmFontStyles::GetStyleName( const Font &rFont ) const
+{
+ //! compare also SmSpecialNode::Prepare
+ bool bBold = IsBold( rFont ),
+ bItalic = IsItalic( rFont );
+
+ if (bBold && bItalic)
+ return aBoldItalic;
+ else if (bItalic)
+ return aItalic;
+ else if (bBold)
+ return aBold;
+ else
+ return aNormal;
+}
+
+
+const String & SmFontStyles::GetStyleName( sal_uInt16 nIdx ) const
+{
+ // 0 = "normal", 1 = "italic",
+ // 2 = "bold", 3 = "bold italic"
+
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE( nIdx < GetCount(), "index out of range" );
+#endif
+ switch (nIdx)
+ {
+ case 0 : return aNormal;
+ case 1 : return aItalic;
+ case 2 : return aBold;
+ case 3 : return aBoldItalic;
+ }
+ return aEmpty;
+}
+
+
+const SmFontStyles & GetFontStyles()
+{
+ static const SmFontStyles aImpl;
+ return aImpl;
+}
+
+/////////////////////////////////////////////////////////////////
+
+void SetFontStyle(const XubString &rStyleName, Font &rFont)
+{
+ // finden des Index passend zum StyleName fuer den leeren StyleName wird
+ // 0 (nicht bold nicht italic) angenommen.
+ sal_uInt16 nIndex = 0;
+ if (rStyleName.Len())
+ {
+ sal_uInt16 i;
+ const SmFontStyles &rStyles = GetFontStyles();
+ for (i = 0; i < rStyles.GetCount(); i++)
+ if (rStyleName.CompareTo( rStyles.GetStyleName(i) ) == COMPARE_EQUAL)
+ break;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(i < rStyles.GetCount(), "style-name unknown");
+#endif
+ nIndex = i;
+ }
+
+ rFont.SetItalic((nIndex & 0x1) ? ITALIC_NORMAL : ITALIC_NONE);
+ rFont.SetWeight((nIndex & 0x2) ? WEIGHT_BOLD : WEIGHT_NORMAL);
+}
+
+
+/**************************************************************************/
+
+IMPL_LINK_INLINE_START( SmPrintOptionsTabPage, SizeButtonClickHdl, Button *, EMPTYARG/*pButton*/ )
+{
+ aZoom.Enable(aSizeZoomed.IsChecked());
+ return 0;
+}
+IMPL_LINK_INLINE_END( SmPrintOptionsTabPage, SizeButtonClickHdl, Button *, pButton )
+
+
+SmPrintOptionsTabPage::SmPrintOptionsTabPage(Window *pParent, const SfxItemSet &rOptions)
+ : SfxTabPage(pParent, SmResId(RID_PRINTOPTIONPAGE), rOptions),
+ aFixedLine1 (this, SmResId( FL_PRINTOPTIONS )),
+ aTitle (this, SmResId( CB_TITLEROW )),
+ aText (this, SmResId( CB_EQUATION_TEXT )),
+ aFrame (this, SmResId( CB_FRAME )),
+ aFixedLine2 (this, SmResId( FL_PRINT_FORMAT )),
+ aSizeNormal (this, SmResId( RB_ORIGINAL_SIZE )),
+ aSizeScaled (this, SmResId( RB_FIT_TO_PAGE )),
+ aSizeZoomed (this, SmResId( RB_ZOOM )),
+ aZoom (this, SmResId( MF_ZOOM )),
+ aFixedLine3 (this, SmResId( FL_MISC_OPTIONS )),
+ aNoRightSpaces (this, SmResId( CB_IGNORE_SPACING )),
+ aSaveOnlyUsedSymbols (this, SmResId( CB_SAVE_ONLY_USED_SYMBOLS ))
+{
+ FreeResource();
+
+ aSizeNormal.SetClickHdl(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
+ aSizeScaled.SetClickHdl(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
+ aSizeZoomed.SetClickHdl(LINK(this, SmPrintOptionsTabPage, SizeButtonClickHdl));
+
+ Reset(rOptions);
+}
+
+
+sal_Bool SmPrintOptionsTabPage::FillItemSet(SfxItemSet& rSet)
+{
+ sal_uInt16 nPrintSize;
+ if (aSizeNormal.IsChecked())
+ nPrintSize = PRINT_SIZE_NORMAL;
+ else if (aSizeScaled.IsChecked())
+ nPrintSize = PRINT_SIZE_SCALED;
+ else
+ nPrintSize = PRINT_SIZE_ZOOMED;
+
+ rSet.Put(SfxUInt16Item(GetWhich(SID_PRINTSIZE), (sal_uInt16) nPrintSize));
+ rSet.Put(SfxUInt16Item(GetWhich(SID_PRINTZOOM), (sal_uInt16) aZoom.GetValue()));
+ rSet.Put(SfxBoolItem(GetWhich(SID_PRINTTITLE), aTitle.IsChecked()));
+ rSet.Put(SfxBoolItem(GetWhich(SID_PRINTTEXT), aText.IsChecked()));
+ rSet.Put(SfxBoolItem(GetWhich(SID_PRINTFRAME), aFrame.IsChecked()));
+ rSet.Put(SfxBoolItem(GetWhich(SID_NO_RIGHT_SPACES), aNoRightSpaces.IsChecked()));
+ rSet.Put(SfxBoolItem(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS), aSaveOnlyUsedSymbols.IsChecked()));
+
+ return true;
+}
+
+
+void SmPrintOptionsTabPage::Reset(const SfxItemSet& rSet)
+{
+ SmPrintSize ePrintSize = (SmPrintSize)((const SfxUInt16Item &)rSet.Get(GetWhich(SID_PRINTSIZE))).GetValue();
+
+ aSizeNormal.Check(ePrintSize == PRINT_SIZE_NORMAL);
+ aSizeScaled.Check(ePrintSize == PRINT_SIZE_SCALED);
+ aSizeZoomed.Check(ePrintSize == PRINT_SIZE_ZOOMED);
+
+ aZoom.Enable(aSizeZoomed.IsChecked());
+
+ aZoom.SetValue(((const SfxUInt16Item &)rSet.Get(GetWhich(SID_PRINTZOOM))).GetValue());
+
+ aTitle.Check(((const SfxBoolItem &)rSet.Get(GetWhich(SID_PRINTTITLE))).GetValue());
+ aText.Check(((const SfxBoolItem &)rSet.Get(GetWhich(SID_PRINTTEXT))).GetValue());
+ aFrame.Check(((const SfxBoolItem &)rSet.Get(GetWhich(SID_PRINTFRAME))).GetValue());
+ aNoRightSpaces.Check(((const SfxBoolItem &)rSet.Get(GetWhich(SID_NO_RIGHT_SPACES))).GetValue());
+ aSaveOnlyUsedSymbols.Check(((const SfxBoolItem &)rSet.Get(GetWhich(SID_SAVE_ONLY_USED_SYMBOLS))).GetValue());
+}
+
+
+SfxTabPage* SmPrintOptionsTabPage::Create(Window* pWindow, const SfxItemSet& rSet)
+{
+ return (new SmPrintOptionsTabPage(pWindow, rSet));
+}
+
+/**************************************************************************/
+
+
+void SmShowFont::Paint(const Rectangle& rRect )
+{
+ Control::Paint( rRect );
+
+ XubString Text (GetFont().GetName());
+ Size TextSize(GetTextWidth(Text), GetTextHeight());
+
+ DrawText(Point((GetOutputSize().Width() - TextSize.Width()) / 2,
+ (GetOutputSize().Height() - TextSize.Height()) / 2), Text);
+}
+
+
+void SmShowFont::SetFont(const Font& rFont)
+{
+ Color aTxtColor( GetTextColor() );
+ Font aFont (rFont);
+
+ Invalidate();
+ aFont.SetSize(Size(0, 24));
+ aFont.SetAlign(ALIGN_TOP);
+ Control::SetFont(aFont);
+
+ // keep old text color (new font may have different color)
+ SetTextColor( aTxtColor );
+}
+
+
+IMPL_LINK_INLINE_START( SmFontDialog, FontSelectHdl, ComboBox *, pComboBox )
+{
+ Face.SetName(pComboBox->GetText());
+ aShowFont.SetFont(Face);
+ return 0;
+}
+IMPL_LINK_INLINE_END( SmFontDialog, FontSelectHdl, ComboBox *, pComboBox )
+
+
+IMPL_LINK( SmFontDialog, FontModifyHdl, ComboBox *, pComboBox )
+{
+ // if font is available in list then use it
+ sal_uInt16 nPos = pComboBox->GetEntryPos( pComboBox->GetText() );
+ if (COMBOBOX_ENTRY_NOTFOUND != nPos)
+ {
+ FontSelectHdl( pComboBox );
+ }
+ return 0;
+}
+
+
+IMPL_LINK( SmFontDialog, AttrChangeHdl, CheckBox *, EMPTYARG /*pCheckBox*/ )
+{
+ if (aBoldCheckBox.IsChecked())
+ Face.SetWeight(FontWeight(WEIGHT_BOLD));
+ else
+ Face.SetWeight(FontWeight(WEIGHT_NORMAL));
+
+ if (aItalicCheckBox.IsChecked())
+ Face.SetItalic(ITALIC_NORMAL);
+ else
+ Face.SetItalic(ITALIC_NONE);
+
+ aShowFont.SetFont(Face);
+ return 0;
+}
+
+
+void SmFontDialog::SetFont(const Font &rFont)
+{
+ Face = rFont;
+
+ aFontBox.SetText( Face.GetName() );
+ aBoldCheckBox.Check( IsBold( Face ) );
+ aItalicCheckBox.Check( IsItalic( Face ) );
+
+ aShowFont.SetFont(Face);
+}
+
+
+SmFontDialog::SmFontDialog(Window * pParent,
+ OutputDevice *pFntListDevice, bool bHideCheckboxes, bool bFreeRes)
+ : ModalDialog(pParent,SmResId(RID_FONTDIALOG)),
+ aFixedText1 (this, SmResId(1)),
+ aFontBox (this, SmResId(1)),
+ aBoldCheckBox (this, SmResId(1)),
+ aItalicCheckBox (this, SmResId(2)),
+ aOKButton1 (this, SmResId(1)),
+ aCancelButton1 (this, SmResId(1)),
+ aShowFont (this, SmResId(1)),
+ aFixedText2 (this, SmResId(2))
+{
+ if (bFreeRes)
+ FreeResource();
+
+ {
+ WaitObject( this );
+
+ FontList aFontList( pFntListDevice );
+
+ sal_uInt16 nCount = aFontList.GetFontNameCount();
+ for (sal_uInt16 i = 0; i < nCount; i++)
+ aFontBox.InsertEntry( aFontList.GetFontName(i).GetName() );
+
+ Face.SetSize(Size(0, 24));
+ Face.SetWeight(WEIGHT_NORMAL);
+ Face.SetItalic(ITALIC_NONE);
+ Face.SetFamily(FAMILY_DONTKNOW);
+ Face.SetPitch(PITCH_DONTKNOW);
+ Face.SetCharSet(RTL_TEXTENCODING_DONTKNOW);
+ Face.SetTransparent(true);
+
+ InitColor_Impl();
+
+ // preview like controls should have a 2D look
+ aShowFont.SetBorderStyle( WINDOW_BORDER_MONO );
+ }
+
+ aFontBox.SetSelectHdl(LINK(this, SmFontDialog, FontSelectHdl));
+ aFontBox.SetModifyHdl(LINK(this, SmFontDialog, FontModifyHdl));
+ aBoldCheckBox.SetClickHdl(LINK(this, SmFontDialog, AttrChangeHdl));
+ aItalicCheckBox.SetClickHdl(LINK(this, SmFontDialog, AttrChangeHdl));
+
+ if (bHideCheckboxes)
+ {
+ aBoldCheckBox.Check( false );
+ aBoldCheckBox.Enable( false );
+ aBoldCheckBox.Show( false );
+ aItalicCheckBox.Check( false );
+ aItalicCheckBox.Enable( false );
+ aItalicCheckBox.Show( false );
+ aFixedText2.Show( false );
+
+ Size aSize( aFontBox.GetSizePixel() );
+ long nComboBoxBottom = aFontBox.GetPosPixel().Y() + aFontBox.GetSizePixel().Height();
+ long nCheckBoxBottom = aItalicCheckBox.GetPosPixel().Y() + aItalicCheckBox.GetSizePixel().Height();
+ aSize.Height() += nCheckBoxBottom - nComboBoxBottom;
+ aFontBox.SetSizePixel( aSize );
+ }
+}
+
+void SmFontDialog::InitColor_Impl()
+{
+#if OSL_DEBUG_LEVEL > 1
+ Color aBC( GetDisplayBackground().GetColor() );
+#endif
+ ColorData nBgCol = COL_WHITE,
+ nTxtCol = COL_BLACK;
+ const StyleSettings &rS = GetSettings().GetStyleSettings();
+ if (rS.GetHighContrastMode())
+ {
+ nBgCol = rS.GetFieldColor().GetColor();
+ nTxtCol = rS.GetFieldTextColor().GetColor();
+ }
+
+ Color aTmpColor( nBgCol );
+ Wallpaper aWall( aTmpColor );
+ Color aTxtColor( nTxtCol );
+ aShowFont.SetBackground( aWall );
+ aShowFont.SetTextColor( aTxtColor );
+}
+
+
+void SmFontDialog::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( rDCEvt.GetType() == DATACHANGED_SETTINGS &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ InitColor_Impl();
+
+ ModalDialog::DataChanged( rDCEvt );
+}
+
+/**************************************************************************/
+
+
+IMPL_LINK( SmFontSizeDialog, DefaultButtonClickHdl, Button *, EMPTYARG /*pButton*/ )
+{
+ QueryBox *pQueryBox = new QueryBox(this, SmResId(RID_DEFAULTSAVEQUERY));
+
+ if (pQueryBox->Execute() == RET_YES)
+ {
+ SmModule *pp = SM_MOD();
+ SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
+ WriteTo( aFmt );
+ pp->GetConfig()->SetStandardFormat( aFmt );
+ }
+
+ delete pQueryBox;
+ return 0;
+}
+
+
+SmFontSizeDialog::SmFontSizeDialog(Window * pParent, bool bFreeRes)
+ : ModalDialog(pParent, SmResId(RID_FONTSIZEDIALOG)),
+ aFixedText1(this, SmResId(1)),
+ aBaseSize(this, SmResId(1)),
+ aFixedText4(this, SmResId(4)),
+ aTextSize(this, SmResId(4)),
+ aFixedText5(this, SmResId(5)),
+ aIndexSize(this, SmResId(5)),
+ aFixedText6(this, SmResId(6)),
+ aFunctionSize(this, SmResId(6)),
+ aFixedText7(this, SmResId(7)),
+ aOperatorSize(this, SmResId(7)),
+ aFixedText8(this, SmResId(8)),
+ aBorderSize(this, SmResId(8)),
+ aFixedLine1(this, SmResId(1)),
+ aOKButton1(this, SmResId(1)),
+ aCancelButton1(this, SmResId(1)),
+ aDefaultButton(this, SmResId(1))
+{
+ if (bFreeRes)
+ FreeResource();
+
+ aDefaultButton.SetClickHdl(LINK(this, SmFontSizeDialog, DefaultButtonClickHdl));
+}
+
+
+void SmFontSizeDialog::ReadFrom(const SmFormat &rFormat)
+{
+ //! aufpassen: richtig runden!
+ aBaseSize.SetValue( SmRoundFraction(
+ Sm100th_mmToPts( rFormat.GetBaseSize().Height() ) ) );
+
+ aTextSize .SetValue( rFormat.GetRelSize(SIZ_TEXT) );
+ aIndexSize .SetValue( rFormat.GetRelSize(SIZ_INDEX) );
+ aFunctionSize.SetValue( rFormat.GetRelSize(SIZ_FUNCTION) );
+ aOperatorSize.SetValue( rFormat.GetRelSize(SIZ_OPERATOR) );
+ aBorderSize .SetValue( rFormat.GetRelSize(SIZ_LIMITS) );
+}
+
+
+void SmFontSizeDialog::WriteTo(SmFormat &rFormat) const
+{
+ rFormat.SetBaseSize( Size(0, SmPtsTo100th_mm( static_cast< long >(aBaseSize.GetValue()))) );
+
+ rFormat.SetRelSize(SIZ_TEXT, (sal_uInt16) aTextSize .GetValue());
+ rFormat.SetRelSize(SIZ_INDEX, (sal_uInt16) aIndexSize .GetValue());
+ rFormat.SetRelSize(SIZ_FUNCTION, (sal_uInt16) aFunctionSize.GetValue());
+ rFormat.SetRelSize(SIZ_OPERATOR, (sal_uInt16) aOperatorSize.GetValue());
+ rFormat.SetRelSize(SIZ_LIMITS, (sal_uInt16) aBorderSize .GetValue());
+
+ const Size aTmp (rFormat.GetBaseSize());
+ for (sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++)
+ rFormat.SetFontSize(i, aTmp);
+
+ rFormat.RequestApplyChanges();
+}
+
+
+/**************************************************************************/
+
+
+IMPL_LINK( SmFontTypeDialog, MenuSelectHdl, Menu *, pMenu )
+{
+ SmFontPickListBox *pActiveListBox;
+
+ bool bHideCheckboxes = false;
+ switch (pMenu->GetCurItemId())
+ {
+ case 1: pActiveListBox = &aVariableFont; break;
+ case 2: pActiveListBox = &aFunctionFont; break;
+ case 3: pActiveListBox = &aNumberFont; break;
+ case 4: pActiveListBox = &aTextFont; break;
+ case 5: pActiveListBox = &aSerifFont; bHideCheckboxes = true; break;
+ case 6: pActiveListBox = &aSansFont; bHideCheckboxes = true; break;
+ case 7: pActiveListBox = &aFixedFont; bHideCheckboxes = true; break;
+ default:pActiveListBox = NULL;
+ }
+
+ if (pActiveListBox)
+ {
+ SmFontDialog *pFontDialog = new SmFontDialog(this, pFontListDev, bHideCheckboxes);
+
+ pActiveListBox->WriteTo(*pFontDialog);
+ if (pFontDialog->Execute() == RET_OK)
+ pActiveListBox->ReadFrom(*pFontDialog);
+ delete pFontDialog;
+ }
+ return 0;
+}
+
+
+IMPL_LINK_INLINE_START( SmFontTypeDialog, DefaultButtonClickHdl, Button *, EMPTYARG /*pButton*/ )
+{
+ QueryBox *pQueryBox = new QueryBox(this, SmResId(RID_DEFAULTSAVEQUERY));
+ if (pQueryBox->Execute() == RET_YES)
+ {
+ SmModule *pp = SM_MOD();
+ SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
+ WriteTo( aFmt );
+ pp->GetConfig()->SetStandardFormat( aFmt, true );
+ }
+
+ delete pQueryBox;
+ return 0;
+}
+IMPL_LINK_INLINE_END( SmFontTypeDialog, DefaultButtonClickHdl, Button *, pButton )
+
+
+SmFontTypeDialog::SmFontTypeDialog(Window * pParent, OutputDevice *pFntListDevice, bool bFreeRes)
+ : ModalDialog(pParent, SmResId(RID_FONTTYPEDIALOG)),
+ aFixedText1 (this, SmResId(1)),
+ aVariableFont (this, SmResId(1)),
+ aFixedText2 (this, SmResId(2)),
+ aFunctionFont (this, SmResId(2)),
+ aFixedText3 (this, SmResId(3)),
+ aNumberFont (this, SmResId(3)),
+ aFixedText4 (this, SmResId(4)),
+ aTextFont (this, SmResId(4)),
+ aFixedText5 (this, SmResId(5)),
+ aSerifFont (this, SmResId(5)),
+ aFixedText6 (this, SmResId(6)),
+ aSansFont (this, SmResId(6)),
+ aFixedText7 (this, SmResId(7)),
+ aFixedFont (this, SmResId(7)),
+ aFixedLine1 (this, SmResId(1)),
+ aFixedLine2 (this, SmResId(2)),
+ aOKButton1 (this, SmResId(1)),
+ aCancelButton1 (this, SmResId(1)),
+ aMenuButton (this, SmResId(1)),
+ aDefaultButton (this, SmResId(2)),
+ pFontListDev (pFntListDevice)
+{
+ if (bFreeRes)
+ FreeResource();
+
+ aDefaultButton.SetClickHdl(LINK(this, SmFontTypeDialog, DefaultButtonClickHdl));
+
+ aMenuButton.GetPopupMenu()->SetSelectHdl(LINK(this, SmFontTypeDialog, MenuSelectHdl));
+}
+
+void SmFontTypeDialog::ReadFrom(const SmFormat &rFormat)
+{
+ SmModule *pp = SM_MOD();
+
+ aVariableFont = pp->GetConfig()->GetFontPickList(FNT_VARIABLE);
+ aFunctionFont = pp->GetConfig()->GetFontPickList(FNT_FUNCTION);
+ aNumberFont = pp->GetConfig()->GetFontPickList(FNT_NUMBER);
+ aTextFont = pp->GetConfig()->GetFontPickList(FNT_TEXT);
+ aSerifFont = pp->GetConfig()->GetFontPickList(FNT_SERIF);
+ aSansFont = pp->GetConfig()->GetFontPickList(FNT_SANS);
+ aFixedFont = pp->GetConfig()->GetFontPickList(FNT_FIXED);
+
+ aVariableFont.Insert( rFormat.GetFont(FNT_VARIABLE) );
+ aFunctionFont.Insert( rFormat.GetFont(FNT_FUNCTION) );
+ aNumberFont .Insert( rFormat.GetFont(FNT_NUMBER) );
+ aTextFont .Insert( rFormat.GetFont(FNT_TEXT) );
+ aSerifFont .Insert( rFormat.GetFont(FNT_SERIF) );
+ aSansFont .Insert( rFormat.GetFont(FNT_SANS) );
+ aFixedFont .Insert( rFormat.GetFont(FNT_FIXED) );
+}
+
+
+void SmFontTypeDialog::WriteTo(SmFormat &rFormat) const
+{
+ SmModule *pp = SM_MOD();
+
+ pp->GetConfig()->GetFontPickList(FNT_VARIABLE) = aVariableFont;
+ pp->GetConfig()->GetFontPickList(FNT_FUNCTION) = aFunctionFont;
+ pp->GetConfig()->GetFontPickList(FNT_NUMBER) = aNumberFont;
+ pp->GetConfig()->GetFontPickList(FNT_TEXT) = aTextFont;
+ pp->GetConfig()->GetFontPickList(FNT_SERIF) = aSerifFont;
+ pp->GetConfig()->GetFontPickList(FNT_SANS) = aSansFont;
+ pp->GetConfig()->GetFontPickList(FNT_FIXED) = aFixedFont;
+
+ rFormat.SetFont( FNT_VARIABLE, aVariableFont.Get(0) );
+ rFormat.SetFont( FNT_FUNCTION, aFunctionFont.Get(0) );
+ rFormat.SetFont( FNT_NUMBER, aNumberFont .Get(0) );
+ rFormat.SetFont( FNT_TEXT, aTextFont .Get(0) );
+ rFormat.SetFont( FNT_SERIF, aSerifFont .Get(0) );
+ rFormat.SetFont( FNT_SANS, aSansFont .Get(0) );
+ rFormat.SetFont( FNT_FIXED, aFixedFont .Get(0) );
+
+ rFormat.RequestApplyChanges();
+}
+
+/**************************************************************************/
+
+struct FieldMinMax
+{
+ sal_uInt16 nMin, nMax;
+};
+
+// Data for min and max values of the 4 metric fields
+// for each of the 10 categories
+static const FieldMinMax pMinMaxData[10][4] =
+{
+ // 0
+ {{ 0, 200 }, { 0, 200 }, { 0, 100 }, { 0, 0 }},
+ // 1
+ {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
+ // 2
+ {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
+ // 3
+ {{ 0, 100 }, { 1, 100 }, { 0, 0 }, { 0, 0 }},
+ // 4
+ {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
+ // 5
+ {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 100 }},
+ // 6
+ {{ 0, 300 }, { 0, 300 }, { 0, 0 }, { 0, 0 }},
+ // 7
+ {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
+ // 8
+ {{ 0, 100 }, { 0, 100 }, { 0, 0 }, { 0, 0 }},
+ // 9
+ {{ 0, 10000 }, { 0, 10000 }, { 0, 10000 }, { 0, 10000 }}
+};
+
+SmCategoryDesc::SmCategoryDesc(const ResId& rResId, sal_uInt16 nCategoryIdx) :
+ Resource(rResId)
+{
+ if (IsAvailableRes(ResId(1,*rResId.GetResMgr()).SetRT(RSC_STRING)))
+ {
+ Name = XubString(ResId(1,*rResId.GetResMgr()));
+
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ int nI2 = i + 2;
+
+ if (IsAvailableRes(ResId(nI2,*rResId.GetResMgr()).SetRT(RSC_STRING)))
+ {
+ Strings [i] = new XubString(ResId(nI2,*rResId.GetResMgr()));
+ Graphics [i] = new Bitmap(ResId(10*nI2,*rResId.GetResMgr()));
+ }
+ else
+ {
+ Strings [i] = 0;
+ Graphics [i] = 0;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ const FieldMinMax &rMinMax = pMinMaxData[ nCategoryIdx ][i];
+ Value[i] = Minimum[i] = rMinMax.nMin;
+ Maximum[i] = rMinMax.nMax;
+ }
+ }
+
+ FreeResource();
+}
+
+
+SmCategoryDesc::~SmCategoryDesc()
+{
+ for (int i = 0; i < 4; i++)
+ {
+ delete Strings [i];
+ delete Graphics [i];
+ }
+}
+
+/**************************************************************************/
+
+IMPL_LINK( SmDistanceDialog, GetFocusHdl, Control *, pControl )
+{
+ if (Categories[nActiveCategory])
+ {
+ sal_uInt16 i;
+
+ if (pControl == &aMetricField1)
+ i = 0;
+ else if (pControl == &aMetricField2)
+ i = 1;
+ else if (pControl == &aMetricField3)
+ i = 2;
+ else if (pControl == &aMetricField4)
+ i = 3;
+ else
+ return 0;
+ aBitmap.SetBitmap(*(Categories[nActiveCategory]->GetGraphic(i)));
+ }
+ return 0;
+}
+
+IMPL_LINK( SmDistanceDialog, MenuSelectHdl, Menu *, pMenu )
+{
+ SetCategory(pMenu->GetCurItemId() - 1);
+ return 0;
+}
+
+
+IMPL_LINK( SmDistanceDialog, DefaultButtonClickHdl, Button *, EMPTYARG /*pButton*/ )
+{
+ QueryBox *pQueryBox = new QueryBox(this, SmResId(RID_DEFAULTSAVEQUERY));
+
+ if (pQueryBox->Execute() == RET_YES)
+ {
+ SmModule *pp = SM_MOD();
+ SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
+ WriteTo( aFmt );
+ pp->GetConfig()->SetStandardFormat( aFmt );
+ }
+ delete pQueryBox;
+ return 0;
+}
+
+
+IMPL_LINK( SmDistanceDialog, CheckBoxClickHdl, CheckBox *, pCheckBox )
+{
+ if (pCheckBox == &aCheckBox1)
+ {
+ aCheckBox1.Toggle();
+
+ bool bChecked = aCheckBox1.IsChecked();
+ aFixedText4 .Enable( bChecked );
+ aMetricField4.Enable( bChecked );
+ }
+ return 0;
+}
+
+
+void SmDistanceDialog::SetHelpId(MetricField &rField, const rtl::OString& sHelpId)
+{
+ //! HelpID's die auf diese Weise explizit gesetzt werden, muessen im
+ //! util Verzeichnis im File "hidother.src" mit Hilfe von "hidspecial"
+ //! definiert werden!
+
+ const XubString aEmptyText;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(aEmptyText.Len() == 0, "Sm: Ooops...");
+#endif
+
+ rField.SetHelpId(sHelpId);
+ rField.SetHelpText(aEmptyText);
+
+ // since MetricField inherits from SpinField which has a sub Edit field
+ // (which is actually the one we modify) we have to set the help-id
+ // for it too.
+ Edit *pSubEdit = rField.GetSubEdit();
+ if (pSubEdit)
+ {
+ pSubEdit->SetHelpId(sHelpId);
+ pSubEdit->SetHelpText(aEmptyText);
+ }
+}
+
+
+void SmDistanceDialog::SetCategory(sal_uInt16 nCategory)
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(/*0 <= nCategory &&*/ nCategory < NOCATEGORIES,
+ "Sm: wrong category number in SmDistanceDialog");
+#endif
+
+ // array to convert category- and metricfield-number in help ids.
+ // 0 is used in case of unused combinations.
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(NOCATEGORIES == 10, "Sm : array doesn't fit into the number of categories");
+#endif
+ static const char * aCatMf2Hid[10][4] =
+ {
+ { HID_SMA_DEFAULT_DIST, HID_SMA_LINE_DIST, HID_SMA_ROOT_DIST, 0 },
+ { HID_SMA_SUP_DIST, HID_SMA_SUB_DIST , 0, 0 },
+ { HID_SMA_NUMERATOR_DIST, HID_SMA_DENOMINATOR_DIST, 0, 0 },
+ { HID_SMA_FRACLINE_EXCWIDTH, HID_SMA_FRACLINE_LINEWIDTH, 0, 0 },
+ { HID_SMA_UPPERLIMIT_DIST, HID_SMA_LOWERLIMIT_DIST, 0, 0 },
+ { HID_SMA_BRACKET_EXCHEIGHT, HID_SMA_BRACKET_DIST, 0, HID_SMA_BRACKET_EXCHEIGHT2 },
+ { HID_SMA_MATRIXROW_DIST, HID_SMA_MATRIXCOL_DIST, 0, 0 },
+ { HID_SMA_ATTRIBUT_DIST, HID_SMA_INTERATTRIBUT_DIST, 0, 0 },
+ { HID_SMA_OPERATOR_EXCHEIGHT, HID_SMA_OPERATOR_DIST, 0, 0 },
+ { HID_SMA_LEFTBORDER_DIST, HID_SMA_RIGHTBORDER_DIST, HID_SMA_UPPERBORDER_DIST, HID_SMA_LOWERBORDER_DIST }
+ };
+
+ // array to help iterate over the controls
+ Window * const aWin[4][2] =
+ {
+ { &aFixedText1, &aMetricField1 },
+ { &aFixedText2, &aMetricField2 },
+ { &aFixedText3, &aMetricField3 },
+ { &aFixedText4, &aMetricField4 }
+ };
+
+ SmCategoryDesc *pCat;
+
+ // merken der (evtl neuen) Einstellungen der aktiven SmCategoryDesc
+ // bevor zu der neuen gewechselt wird.
+ if (nActiveCategory != CATEGORY_NONE)
+ {
+ pCat = Categories[nActiveCategory];
+ pCat->SetValue(0, (sal_uInt16) aMetricField1.GetValue());
+ pCat->SetValue(1, (sal_uInt16) aMetricField2.GetValue());
+ pCat->SetValue(2, (sal_uInt16) aMetricField3.GetValue());
+ pCat->SetValue(3, (sal_uInt16) aMetricField4.GetValue());
+
+ if (nActiveCategory == 5)
+ bScaleAllBrackets = aCheckBox1.IsChecked();
+
+ aMenuButton.GetPopupMenu()->CheckItem(nActiveCategory + 1, false);
+ }
+
+ // aktivieren/deaktivieren der zugehoerigen Controls in Abhaengigkeit von der
+ // gewaehlten Kategorie.
+ bool bActive;
+ for (sal_uInt16 i = 0; i < 4; i++)
+ {
+ FixedText *pFT = (FixedText * const) aWin[i][0];
+ MetricField *pMF = (MetricField * const) aWin[i][1];
+
+ // Um feststellen welche Controls aktiv sein sollen wird das
+ // vorhandensein einer zugehoerigen HelpID ueberprueft.
+ bActive = aCatMf2Hid[nCategory][i] != 0;
+
+ pFT->Show(bActive);
+ pFT->Enable(bActive);
+ pMF->Show(bActive);
+ pMF->Enable(bActive);
+
+ // setzen von Masseinheit und Anzahl der Nachkommastellen
+ FieldUnit eUnit;
+ sal_uInt16 nDigits;
+ if (nCategory < 9)
+ {
+ eUnit = FUNIT_CUSTOM;
+ nDigits = 0;
+ pMF->SetCustomUnitText( '%' );
+ }
+ else
+ {
+ eUnit = FUNIT_100TH_MM;
+ nDigits = 2;
+ }
+ pMF->SetUnit(eUnit); //! veraendert den Wert
+ pMF->SetDecimalDigits(nDigits);
+
+ if (bActive)
+ {
+ pCat = Categories[nCategory];
+ pFT->SetText(*pCat->GetString(i));
+
+ pMF->SetMin(pCat->GetMinimum(i));
+ pMF->SetMax(pCat->GetMaximum(i));
+ pMF->SetValue(pCat->GetValue(i));
+
+ SetHelpId(*pMF, aCatMf2Hid[nCategory][i]);
+ }
+ }
+ // nun noch die CheckBox und das zugehoerige MetricField genau dann aktivieren,
+ // falls es sich um das Klammer Menu handelt.
+ bActive = nCategory == 5;
+ aCheckBox1.Show(bActive);
+ aCheckBox1.Enable(bActive);
+ if (bActive)
+ {
+ aCheckBox1.Check( bScaleAllBrackets );
+
+ bool bChecked = aCheckBox1.IsChecked();
+ aFixedText4 .Enable( bChecked );
+ aMetricField4.Enable( bChecked );
+ }
+
+ aMenuButton.GetPopupMenu()->CheckItem(nCategory + 1, true);
+ aFixedLine.SetText(Categories[nCategory]->GetName());
+
+ nActiveCategory = nCategory;
+
+ aMetricField1.GrabFocus();
+ Invalidate();
+ Update();
+}
+
+
+SmDistanceDialog::SmDistanceDialog(Window *pParent, bool bFreeRes)
+ : ModalDialog(pParent, SmResId(RID_DISTANCEDIALOG)),
+ aFixedText1 (this, SmResId(1)),
+ aMetricField1 (this, SmResId(1)),
+ aFixedText2 (this, SmResId(2)),
+ aMetricField2 (this, SmResId(2)),
+ aFixedText3 (this, SmResId(3)),
+ aMetricField3 (this, SmResId(3)),
+ aCheckBox1 (this, SmResId(1)),
+ aFixedText4 (this, SmResId(4)),
+ aMetricField4 (this, SmResId(4)),
+ aOKButton1 (this, SmResId(1)),
+ aCancelButton1 (this, SmResId(1)),
+ aMenuButton (this, SmResId(1)),
+ aDefaultButton (this, SmResId(1)),
+ aBitmap (this, SmResId(1)),
+ aFixedLine (this, SmResId(1))
+{
+ for (sal_uInt16 i = 0; i < NOCATEGORIES; i++)
+ Categories[i] = new SmCategoryDesc(SmResId(i + 1), i);
+ nActiveCategory = CATEGORY_NONE;
+ bScaleAllBrackets = false;
+
+ if (bFreeRes)
+ FreeResource();
+
+ // preview like controls should have a 2D look
+ aBitmap.SetBorderStyle( WINDOW_BORDER_MONO );
+
+ aMetricField1.SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
+ aMetricField2.SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
+ aMetricField3.SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
+ aMetricField4.SetGetFocusHdl(LINK(this, SmDistanceDialog, GetFocusHdl));
+ aCheckBox1.SetClickHdl(LINK(this, SmDistanceDialog, CheckBoxClickHdl));
+
+ aMenuButton.GetPopupMenu()->SetSelectHdl(LINK(this, SmDistanceDialog, MenuSelectHdl));
+
+ aDefaultButton.SetClickHdl(LINK(this, SmDistanceDialog, DefaultButtonClickHdl));
+}
+
+
+SmDistanceDialog::~SmDistanceDialog()
+{
+ for (int i = 0; i < NOCATEGORIES; i++)
+ DELETEZ(Categories[i]);
+}
+
+void SmDistanceDialog::DataChanged( const DataChangedEvent &rEvt )
+{
+ ModalDialog::DataChanged( rEvt );
+}
+
+void SmDistanceDialog::ReadFrom(const SmFormat &rFormat)
+{
+ Categories[0]->SetValue(0, rFormat.GetDistance(DIS_HORIZONTAL));
+ Categories[0]->SetValue(1, rFormat.GetDistance(DIS_VERTICAL));
+ Categories[0]->SetValue(2, rFormat.GetDistance(DIS_ROOT));
+ Categories[1]->SetValue(0, rFormat.GetDistance(DIS_SUPERSCRIPT));
+ Categories[1]->SetValue(1, rFormat.GetDistance(DIS_SUBSCRIPT));
+ Categories[2]->SetValue(0, rFormat.GetDistance(DIS_NUMERATOR));
+ Categories[2]->SetValue(1, rFormat.GetDistance(DIS_DENOMINATOR));
+ Categories[3]->SetValue(0, rFormat.GetDistance(DIS_FRACTION));
+ Categories[3]->SetValue(1, rFormat.GetDistance(DIS_STROKEWIDTH));
+ Categories[4]->SetValue(0, rFormat.GetDistance(DIS_UPPERLIMIT));
+ Categories[4]->SetValue(1, rFormat.GetDistance(DIS_LOWERLIMIT));
+ Categories[5]->SetValue(0, rFormat.GetDistance(DIS_BRACKETSIZE));
+ Categories[5]->SetValue(1, rFormat.GetDistance(DIS_BRACKETSPACE));
+ Categories[5]->SetValue(3, rFormat.GetDistance(DIS_NORMALBRACKETSIZE));
+ Categories[6]->SetValue(0, rFormat.GetDistance(DIS_MATRIXROW));
+ Categories[6]->SetValue(1, rFormat.GetDistance(DIS_MATRIXCOL));
+ Categories[7]->SetValue(0, rFormat.GetDistance(DIS_ORNAMENTSIZE));
+ Categories[7]->SetValue(1, rFormat.GetDistance(DIS_ORNAMENTSPACE));
+ Categories[8]->SetValue(0, rFormat.GetDistance(DIS_OPERATORSIZE));
+ Categories[8]->SetValue(1, rFormat.GetDistance(DIS_OPERATORSPACE));
+ Categories[9]->SetValue(0, rFormat.GetDistance(DIS_LEFTSPACE));
+ Categories[9]->SetValue(1, rFormat.GetDistance(DIS_RIGHTSPACE));
+ Categories[9]->SetValue(2, rFormat.GetDistance(DIS_TOPSPACE));
+ Categories[9]->SetValue(3, rFormat.GetDistance(DIS_BOTTOMSPACE));
+
+ bScaleAllBrackets = rFormat.IsScaleNormalBrackets();
+
+ // force update (even of category 0) by setting nActiveCategory to a
+ // non-existent category number
+ nActiveCategory = CATEGORY_NONE;
+ SetCategory(0);
+}
+
+
+void SmDistanceDialog::WriteTo(SmFormat &rFormat) /*const*/
+{
+ // hmm... koennen die tatsaechlich unterschiedlich sein?
+ // wenn nicht kann oben naemlich das const stehen!
+ SetCategory(nActiveCategory);
+
+ rFormat.SetDistance( DIS_HORIZONTAL, Categories[0]->GetValue(0) );
+ rFormat.SetDistance( DIS_VERTICAL, Categories[0]->GetValue(1) );
+ rFormat.SetDistance( DIS_ROOT, Categories[0]->GetValue(2) );
+ rFormat.SetDistance( DIS_SUPERSCRIPT, Categories[1]->GetValue(0) );
+ rFormat.SetDistance( DIS_SUBSCRIPT, Categories[1]->GetValue(1) );
+ rFormat.SetDistance( DIS_NUMERATOR, Categories[2]->GetValue(0) );
+ rFormat.SetDistance( DIS_DENOMINATOR, Categories[2]->GetValue(1) );
+ rFormat.SetDistance( DIS_FRACTION, Categories[3]->GetValue(0) );
+ rFormat.SetDistance( DIS_STROKEWIDTH, Categories[3]->GetValue(1) );
+ rFormat.SetDistance( DIS_UPPERLIMIT, Categories[4]->GetValue(0) );
+ rFormat.SetDistance( DIS_LOWERLIMIT, Categories[4]->GetValue(1) );
+ rFormat.SetDistance( DIS_BRACKETSIZE, Categories[5]->GetValue(0) );
+ rFormat.SetDistance( DIS_BRACKETSPACE, Categories[5]->GetValue(1) );
+ rFormat.SetDistance( DIS_MATRIXROW, Categories[6]->GetValue(0) );
+ rFormat.SetDistance( DIS_MATRIXCOL, Categories[6]->GetValue(1) );
+ rFormat.SetDistance( DIS_ORNAMENTSIZE, Categories[7]->GetValue(0) );
+ rFormat.SetDistance( DIS_ORNAMENTSPACE, Categories[7]->GetValue(1) );
+ rFormat.SetDistance( DIS_OPERATORSIZE, Categories[8]->GetValue(0) );
+ rFormat.SetDistance( DIS_OPERATORSPACE, Categories[8]->GetValue(1) );
+ rFormat.SetDistance( DIS_LEFTSPACE, Categories[9]->GetValue(0) );
+ rFormat.SetDistance( DIS_RIGHTSPACE, Categories[9]->GetValue(1) );
+ rFormat.SetDistance( DIS_TOPSPACE, Categories[9]->GetValue(2) );
+ rFormat.SetDistance( DIS_BOTTOMSPACE, Categories[9]->GetValue(3) );
+ rFormat.SetDistance( DIS_NORMALBRACKETSIZE, Categories[5]->GetValue(3) );
+
+ rFormat.SetScaleNormalBrackets( bScaleAllBrackets );
+
+ rFormat.RequestApplyChanges();
+}
+
+
+/**************************************************************************/
+
+
+IMPL_LINK( SmAlignDialog, DefaultButtonClickHdl, Button *, EMPTYARG /*pButton*/ )
+{
+ QueryBox *pQueryBox = new QueryBox(this, SmResId(RID_DEFAULTSAVEQUERY));
+
+ if (pQueryBox->Execute() == RET_YES)
+ {
+ SmModule *pp = SM_MOD();
+ SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
+ WriteTo( aFmt );
+ pp->GetConfig()->SetStandardFormat( aFmt );
+ }
+
+ delete pQueryBox;
+ return 0;
+}
+
+
+SmAlignDialog::SmAlignDialog(Window * pParent, bool bFreeRes)
+ : ModalDialog(pParent, SmResId(RID_ALIGNDIALOG)),
+ aLeft (this, SmResId(1)),
+ aCenter (this, SmResId(2)),
+ aRight (this, SmResId(3)),
+ aFixedLine1 (this, SmResId(1)),
+ aOKButton1 (this, SmResId(1)),
+ aCancelButton1 (this, SmResId(1)),
+ aDefaultButton (this, SmResId(1))
+{
+ if (bFreeRes)
+ FreeResource();
+
+ aDefaultButton.SetClickHdl(LINK(this, SmAlignDialog, DefaultButtonClickHdl));
+}
+
+
+void SmAlignDialog::ReadFrom(const SmFormat &rFormat)
+{
+ switch (rFormat.GetHorAlign())
+ {
+ case AlignLeft:
+ aLeft .Check(true);
+ aCenter.Check(false);
+ aRight .Check(false);
+ break;
+
+ case AlignCenter:
+ aLeft .Check(false);
+ aCenter.Check(true);
+ aRight .Check(false);
+ break;
+
+ case AlignRight:
+ aLeft .Check(false);
+ aCenter.Check(false);
+ aRight .Check(true);
+ break;
+ }
+}
+
+
+void SmAlignDialog::WriteTo(SmFormat &rFormat) const
+{
+ if (aLeft.IsChecked())
+ rFormat.SetHorAlign(AlignLeft);
+ else if (aRight.IsChecked())
+ rFormat.SetHorAlign(AlignRight);
+ else
+ rFormat.SetHorAlign(AlignCenter);
+
+ rFormat.RequestApplyChanges();
+}
+
+
+/**************************************************************************/
+
+
+void SmShowSymbolSet::Paint(const Rectangle&)
+{
+ Push(PUSH_MAPMODE);
+
+ // MapUnit einstellen fuer die 'nLen' berechnet wurde
+ SetMapMode(MapMode(MAP_PIXEL));
+
+ sal_uInt16 v = sal::static_int_cast< sal_uInt16 >((aVScrollBar.GetThumbPos() * nColumns));
+ size_t nSymbols = aSymbolSet.size();
+
+ Color aTxtColor( GetTextColor() );
+ for (sal_uInt16 i = v; i < nSymbols ; i++)
+ {
+ SmSym aSymbol (*aSymbolSet[i]);
+ Font aFont (aSymbol.GetFace());
+ aFont.SetAlign(ALIGN_TOP);
+
+ // etwas kleinere FontSize nehmen (als nLen) um etwas Luft zu haben
+ // (hoffentlich auch genug fuer links und rechts!)
+ aFont.SetSize(Size(0, nLen - (nLen / 3)));
+ SetFont(aFont);
+ // keep text color
+ SetTextColor( aTxtColor );
+
+ int nIV = i - v;
+ sal_UCS4 cChar = aSymbol.GetCharacter();
+ String aText( OUString( &cChar, 1 ) );
+ Size aSize( GetTextWidth( aText ), GetTextHeight());
+
+ DrawText(Point((nIV % nColumns) * nLen + (nLen - aSize.Width()) / 2,
+ (nIV / nColumns) * nLen + (nLen - aSize.Height()) / 2),
+ aText);
+ }
+
+ if (nSelectSymbol != SYMBOL_NONE)
+ {
+ Invert(Rectangle(Point(((nSelectSymbol - v) % nColumns) * nLen,
+ ((nSelectSymbol - v) / nColumns) * nLen),
+ Size(nLen, nLen)));
+ }
+
+ Pop();
+}
+
+
+void SmShowSymbolSet::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ GrabFocus();
+
+ if (rMEvt.IsLeft() && Rectangle(Point(0, 0), aOutputSize).IsInside(rMEvt.GetPosPixel()))
+ {
+ long nPos = (rMEvt.GetPosPixel().Y() / nLen) * nColumns + (rMEvt.GetPosPixel().X() / nLen) +
+ aVScrollBar.GetThumbPos() * nColumns;
+ SelectSymbol( sal::static_int_cast< sal_uInt16 >(nPos) );
+
+ aSelectHdlLink.Call(this);
+
+ if (rMEvt.GetClicks() > 1) aDblClickHdlLink.Call(this);
+ }
+ else Control::MouseButtonDown (rMEvt);
+}
+
+
+void SmShowSymbolSet::KeyInput(const KeyEvent& rKEvt)
+{
+ sal_uInt16 n = nSelectSymbol;
+
+ if (n != SYMBOL_NONE)
+ {
+ switch (rKEvt.GetKeyCode().GetCode())
+ {
+ case KEY_DOWN: n = n + nColumns; break;
+ case KEY_UP: n = n - nColumns; break;
+ case KEY_LEFT: n -= 1; break;
+ case KEY_RIGHT: n += 1; break;
+ case KEY_HOME: n = 0; break;
+ case KEY_END: n = static_cast< sal_uInt16 >(aSymbolSet.size() - 1); break;
+ case KEY_PAGEUP: n -= nColumns * nRows; break;
+ case KEY_PAGEDOWN: n += nColumns * nRows; break;
+
+ default:
+ Control::KeyInput(rKEvt);
+ return;
+ }
+ }
+ else
+ n = 0;
+
+ if (n >= aSymbolSet.size())
+ n = nSelectSymbol;
+
+ // adjust scrollbar
+ if ((n < (sal_uInt16) (aVScrollBar.GetThumbPos() * nColumns)) ||
+ (n >= (sal_uInt16) ((aVScrollBar.GetThumbPos() + nRows) * nColumns)))
+ {
+ aVScrollBar.SetThumbPos(n / nColumns);
+ Invalidate();
+ Update();
+ }
+
+ SelectSymbol(n);
+ aSelectHdlLink.Call(this);
+}
+
+
+SmShowSymbolSet::SmShowSymbolSet(Window *pParent, const ResId& rResId) :
+ Control(pParent, rResId),
+ aVScrollBar(this, WinBits(WB_VSCROLL))
+{
+ nSelectSymbol = SYMBOL_NONE;
+
+ aOutputSize = GetOutputSizePixel();
+ long nScrollBarWidth = aVScrollBar.GetSizePixel().Width(),
+ nUseableWidth = aOutputSize.Width() - nScrollBarWidth;
+
+ // Hoehe von 16pt in Pixeln (passend zu 'aOutputSize')
+ nLen = (sal_uInt16) LogicToPixel(Size(0, 16), MapMode(MAP_POINT)).Height();
+
+ nColumns = sal::static_int_cast< sal_uInt16 >(nUseableWidth / nLen);
+ if (nColumns > 2 && nColumns % 2 != 0)
+ nColumns--;
+ nRows = sal::static_int_cast< sal_uInt16 >(aOutputSize.Height() / nLen);
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(nColumns > 0, "Sm : no columns");
+ OSL_ENSURE(nRows > 0, "Sm : no rows");
+#endif
+
+ // genau passend machen
+ aOutputSize.Width() = nColumns * nLen;
+ aOutputSize.Height() = nRows * nLen;
+
+ aVScrollBar.SetPosSizePixel(Point(aOutputSize.Width() + 1, -1),
+ Size(nScrollBarWidth, aOutputSize.Height() + 2));
+ aVScrollBar.Enable(false);
+ aVScrollBar.Show();
+ aVScrollBar.SetScrollHdl(LINK(this, SmShowSymbolSet, ScrollHdl));
+
+ Size WindowSize (aOutputSize);
+ WindowSize.Width() += nScrollBarWidth;
+ SetOutputSizePixel(WindowSize);
+
+}
+
+
+void SmShowSymbolSet::SetSymbolSet(const SymbolPtrVec_t& rSymbolSet)
+{
+ aSymbolSet = rSymbolSet;
+
+ if (static_cast< sal_uInt16 >(aSymbolSet.size()) > (nColumns * nRows))
+ {
+ aVScrollBar.SetRange(Range(0, ((aSymbolSet.size() + (nColumns - 1)) / nColumns) - nRows));
+ aVScrollBar.Enable(true);
+ }
+ else
+ {
+ aVScrollBar.SetRange(Range(0,0));
+ aVScrollBar.Enable (false);
+ }
+
+ Invalidate();
+}
+
+
+void SmShowSymbolSet::SelectSymbol(sal_uInt16 nSymbol)
+{
+ int v = (int) (aVScrollBar.GetThumbPos() * nColumns);
+
+ if (nSelectSymbol != SYMBOL_NONE)
+ Invalidate(Rectangle(Point(((nSelectSymbol - v) % nColumns) * nLen,
+ ((nSelectSymbol - v) / nColumns) * nLen),
+ Size(nLen, nLen)));
+
+ if (nSymbol < aSymbolSet.size())
+ nSelectSymbol = nSymbol;
+
+ if (aSymbolSet.size() == 0)
+ nSelectSymbol = SYMBOL_NONE;
+
+ if (nSelectSymbol != SYMBOL_NONE)
+ Invalidate(Rectangle(Point(((nSelectSymbol - v) % nColumns) * nLen,
+ ((nSelectSymbol - v) / nColumns) * nLen),
+ Size(nLen, nLen)));
+
+ Update();
+}
+
+
+IMPL_LINK( SmShowSymbolSet, ScrollHdl, ScrollBar*, EMPTYARG /*pScrollBar*/)
+{
+ Invalidate();
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void SmShowSymbol::Paint(const Rectangle &rRect)
+{
+ Control::Paint( rRect );
+
+ const XubString &rText = GetText();
+ Size aTextSize(GetTextWidth(rText), GetTextHeight());
+
+ DrawText(Point((GetOutputSize().Width() - aTextSize.Width()) / 2,
+ (GetOutputSize().Height() * 7/10)), rText);
+}
+
+
+void SmShowSymbol::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ if (rMEvt.GetClicks() > 1)
+ aDblClickHdlLink.Call(this);
+ else
+ Control::MouseButtonDown (rMEvt);
+}
+
+
+void SmShowSymbol::SetSymbol(const SmSym *pSymbol)
+{
+ if (pSymbol)
+ {
+ Font aFont (pSymbol->GetFace());
+ aFont.SetSize(Size(0, GetOutputSize().Height() - GetOutputSize().Height() / 3));
+ aFont.SetAlign(ALIGN_BASELINE);
+ SetFont(aFont);
+
+ sal_UCS4 cChar = pSymbol->GetCharacter();
+ String aText( OUString( &cChar, 1 ) );
+ SetText( aText );
+ }
+
+ // 'Invalidate' fuellt den background mit der background-Farbe.
+ // Falls der NULL pointer uebergeben wurde reicht dies also zum loeschen
+ // der Anzeige
+ Invalidate();
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+void SmSymbolDialog::FillSymbolSets(bool bDeleteText)
+ // fuellt die Eintraege der moeglichen 'SymbolsSet's im Dialog mit den
+ // aktuellen Werten des SymbolSet Managers, selektiert aber keinen.
+{
+ aSymbolSets.Clear();
+ if (bDeleteText)
+ aSymbolSets.SetNoSelection();
+
+ std::set< String > aSybolSetNames( rSymbolMgr.GetSymbolSetNames() );
+ std::set< String >::const_iterator aIt( aSybolSetNames.begin() );
+ for ( ; aIt != aSybolSetNames.end(); ++aIt)
+ aSymbolSets.InsertEntry( *aIt );
+}
+
+
+IMPL_LINK( SmSymbolDialog, SymbolSetChangeHdl, ListBox *, EMPTYARG pListBox )
+{
+ (void) pListBox;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pListBox == &aSymbolSets, "Sm : wrong argument");
+#endif
+
+ SelectSymbolSet(aSymbolSets.GetSelectEntry());
+ return 0;
+}
+
+
+IMPL_LINK( SmSymbolDialog, SymbolChangeHdl, SmShowSymbolSet *, EMPTYARG pShowSymbolSet )
+{
+ (void) pShowSymbolSet;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pShowSymbolSet == &aSymbolSetDisplay, "Sm : wrong argument");
+#endif
+
+ SelectSymbol(aSymbolSetDisplay.GetSelectSymbol());
+ return 0;
+}
+
+IMPL_LINK( SmSymbolDialog, EditClickHdl, Button *, EMPTYARG pButton )
+{
+ (void) pButton;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pButton == &aEditBtn, "Sm : wrong argument");
+#endif
+
+ SmSymDefineDialog *pDialog = new SmSymDefineDialog(this, pFontListDev, rSymbolMgr);
+
+ // aktuelles Symbol und SymbolSet am neuen Dialog setzen
+ const XubString aSymSetName (aSymbolSets.GetSelectEntry()),
+ aSymName (aSymbolName.GetText());
+ pDialog->SelectOldSymbolSet(aSymSetName);
+ pDialog->SelectOldSymbol(aSymName);
+ pDialog->SelectSymbolSet(aSymSetName);
+ pDialog->SelectSymbol(aSymName);
+
+ // altes SymbolSet merken
+ XubString aOldSymbolSet (aSymbolSets.GetSelectEntry());
+
+ sal_uInt16 nSymPos = GetSelectedSymbol();
+
+ // Dialog an evtl geaenderte Daten des SymbolSet Manager anpassen
+ if (pDialog->Execute() == RET_OK && rSymbolMgr.IsModified())
+ {
+ rSymbolMgr.Save();
+ FillSymbolSets();
+ }
+
+ // wenn das alte SymbolSet nicht mehr existiert zum ersten gehen
+ // (soweit eines vorhanden ist)
+ if (!SelectSymbolSet(aOldSymbolSet) && aSymbolSets.GetEntryCount() > 0)
+ SelectSymbolSet(aSymbolSets.GetEntry(0));
+ else
+ {
+ // just update display of current symbol set
+ OSL_ENSURE( aSymSetName == aSymSetName, "unexpected change in symbol set name" );
+ aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
+ aSymbolSetDisplay.SetSymbolSet( aSymbolSet );
+ }
+
+ if (nSymPos >= aSymbolSet.size())
+ nSymPos = static_cast< sal_uInt16 >(aSymbolSet.size()) - 1;
+ SelectSymbol( nSymPos );
+
+ delete pDialog;
+ return 0;
+}
+
+
+IMPL_LINK( SmSymbolDialog, SymbolDblClickHdl, SmShowSymbolSet *, EMPTYARG pShowSymbolSet )
+{
+ (void) pShowSymbolSet;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pShowSymbolSet == &aSymbolSetDisplay, "Sm : wrong argument");
+#endif
+
+ GetClickHdl(&aGetBtn);
+ EndDialog(RET_OK);
+ return 0;
+}
+
+
+IMPL_LINK( SmSymbolDialog, GetClickHdl, Button *, EMPTYARG pButton )
+{
+ (void) pButton;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pButton == &aGetBtn, "Sm : wrong button");
+#endif
+
+ const SmSym *pSym = GetSymbol();
+ if (pSym)
+ {
+ String aText ('%');
+ aText += pSym->GetName();
+ aText += (sal_Unicode)' ';
+
+ rViewSh.GetViewFrame()->GetDispatcher()->Execute(
+ SID_INSERTSYMBOL, SFX_CALLMODE_STANDARD,
+ new SfxStringItem(SID_INSERTSYMBOL, aText), 0L);
+ }
+
+ return 0;
+}
+
+
+IMPL_LINK_INLINE_START( SmSymbolDialog, CloseClickHdl, Button *, EMPTYARG pButton )
+{
+ (void) pButton;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pButton == &aCloseBtn, "Sm : wrong button");
+#endif
+
+ EndDialog(true);
+ return 0;
+}
+IMPL_LINK_INLINE_END( SmSymbolDialog, CloseClickHdl, Button *, pButton )
+
+
+SmSymbolDialog::SmSymbolDialog(Window *pParent, OutputDevice *pFntListDevice,
+ SmSymbolManager &rMgr, SmViewShell &rViewShell, bool bFreeRes) :
+ ModalDialog (pParent, SmResId(RID_SYMBOLDIALOG)),
+ aSymbolSetText (this, SmResId(1)),
+ aSymbolSets (this, SmResId(1)),
+ aSymbolSetDisplay (this, SmResId(1)),
+ aSymbolName (this, SmResId(2)),
+ aSymbolDisplay (this, SmResId(2)),
+ aGetBtn (this, SmResId(2)),
+ aCloseBtn (this, SmResId(3)),
+ aEditBtn (this, SmResId(1)),
+ rViewSh (rViewShell),
+ rSymbolMgr (rMgr),
+ pFontListDev (pFntListDevice)
+{
+ if (bFreeRes)
+ FreeResource();
+
+ aSymbolSetName = String();
+ aSymbolSet.clear();
+ FillSymbolSets();
+ if (aSymbolSets.GetEntryCount() > 0)
+ SelectSymbolSet(aSymbolSets.GetEntry(0));
+
+ InitColor_Impl();
+
+ // preview like controls should have a 2D look
+ aSymbolDisplay.SetBorderStyle( WINDOW_BORDER_MONO );
+
+ aSymbolSets .SetSelectHdl (LINK(this, SmSymbolDialog, SymbolSetChangeHdl));
+ aSymbolSetDisplay.SetSelectHdl (LINK(this, SmSymbolDialog, SymbolChangeHdl));
+ aSymbolSetDisplay.SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl));
+ aSymbolDisplay .SetDblClickHdl(LINK(this, SmSymbolDialog, SymbolDblClickHdl));
+ aCloseBtn .SetClickHdl (LINK(this, SmSymbolDialog, CloseClickHdl));
+ aEditBtn .SetClickHdl (LINK(this, SmSymbolDialog, EditClickHdl));
+ aGetBtn .SetClickHdl (LINK(this, SmSymbolDialog, GetClickHdl));
+}
+
+
+SmSymbolDialog::~SmSymbolDialog()
+{
+}
+
+
+void SmSymbolDialog::InitColor_Impl()
+{
+#if OSL_DEBUG_LEVEL > 1
+ Color aBC( GetDisplayBackground().GetColor() );
+#endif
+ ColorData nBgCol = COL_WHITE,
+ nTxtCol = COL_BLACK;
+ const StyleSettings &rS = GetSettings().GetStyleSettings();
+ if (rS.GetHighContrastMode())
+ {
+ nBgCol = rS.GetFieldColor().GetColor();
+ nTxtCol = rS.GetFieldTextColor().GetColor();
+ }
+
+ Color aTmpColor( nBgCol );
+ Wallpaper aWall( aTmpColor );
+ Color aTxtColor( nTxtCol );
+ aSymbolDisplay .SetBackground( aWall );
+ aSymbolDisplay .SetTextColor( aTxtColor );
+ aSymbolSetDisplay.SetBackground( aWall );
+ aSymbolSetDisplay.SetTextColor( aTxtColor );
+}
+
+
+void SmSymbolDialog::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( rDCEvt.GetType() == DATACHANGED_SETTINGS &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ InitColor_Impl();
+
+ ModalDialog::DataChanged( rDCEvt );
+}
+
+
+bool SmSymbolDialog::SelectSymbolSet(const XubString &rSymbolSetName)
+{
+ bool bRet = false;
+ sal_uInt16 nPos = aSymbolSets.GetEntryPos(rSymbolSetName);
+
+ aSymbolSetName = String();
+ aSymbolSet.clear();
+ if (nPos != LISTBOX_ENTRY_NOTFOUND)
+ {
+ aSymbolSets.SelectEntryPos(nPos);
+
+ aSymbolSetName = rSymbolSetName;
+ aSymbolSet = rSymbolMgr.GetSymbolSet( aSymbolSetName );
+
+ // sort symbols by Unicode position (useful for displaying Greek characters alphabetically)
+ std::sort( aSymbolSet.begin(), aSymbolSet.end(), lt_SmSymPtr() );
+
+ aSymbolSetDisplay.SetSymbolSet( aSymbolSet );
+ if (aSymbolSet.size() > 0)
+ SelectSymbol(0);
+
+ bRet = true;
+ }
+ else
+ aSymbolSets.SetNoSelection();
+
+ return bRet;
+}
+
+
+void SmSymbolDialog::SelectSymbol(sal_uInt16 nSymbolNo)
+{
+ const SmSym *pSym = NULL;
+ if (aSymbolSetName.Len() > 0 && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size()))
+ pSym = aSymbolSet[ nSymbolNo ];
+
+ aSymbolSetDisplay.SelectSymbol(nSymbolNo);
+ aSymbolDisplay.SetSymbol(pSym);
+ aSymbolName.SetText(pSym ? pSym->GetName() : XubString());
+}
+
+
+const SmSym * SmSymbolDialog::GetSymbol() const
+{
+ sal_uInt16 nSymbolNo = aSymbolSetDisplay.GetSelectSymbol();
+ bool bValid = aSymbolSetName.Len() > 0 && nSymbolNo < static_cast< sal_uInt16 >(aSymbolSet.size());
+ return bValid ? aSymbolSet[ nSymbolNo ] : NULL;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+void SmShowChar::Paint(const Rectangle &rRect)
+{
+ Control::Paint( rRect );
+
+ OUString aText( GetText() );
+ if (aText.getLength() > 0)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ sal_Int32 nPos = 0;
+ sal_UCS4 cChar = aText.iterateCodePoints( &nPos );
+ (void) cChar;
+#endif
+ Size aTextSize(GetTextWidth(aText), GetTextHeight());
+
+ DrawText(Point((GetOutputSize().Width() - aTextSize.Width()) / 2,
+ (GetOutputSize().Height() * 7/10)), aText);
+ }
+}
+
+
+void SmShowChar::SetSymbol( const SmSym *pSym )
+{
+ if (pSym)
+ SetSymbol( pSym->GetCharacter(), pSym->GetFace() );
+}
+
+
+void SmShowChar::SetSymbol( sal_UCS4 cChar, const Font &rFont )
+{
+ Font aFont( rFont );
+ aFont.SetSize( Size(0, GetOutputSize().Height() - GetOutputSize().Height() / 3) );
+ aFont.SetAlign(ALIGN_BASELINE);
+ SetFont(aFont);
+ aFont.SetTransparent(true);
+
+ String aText( OUString( &cChar, 1) );
+ SetText( aText );
+
+ Invalidate();
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+void SmSymDefineDialog::FillSymbols(ComboBox &rComboBox, bool bDeleteText)
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(&rComboBox == &aOldSymbols || &rComboBox == &aSymbols,
+ "Sm : wrong ComboBox");
+#endif
+
+ rComboBox.Clear();
+ if (bDeleteText)
+ rComboBox.SetText(XubString());
+
+ ComboBox &rBox = &rComboBox == &aOldSymbols ? aOldSymbolSets : aSymbolSets;
+ SymbolPtrVec_t aSymSet( aSymbolMgrCopy.GetSymbolSet( rBox.GetText() ) );
+ for (size_t i = 0; i < aSymSet.size(); ++i)
+ rComboBox.InsertEntry( aSymSet[i]->GetName() );
+}
+
+
+void SmSymDefineDialog::FillSymbolSets(ComboBox &rComboBox, bool bDeleteText)
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(&rComboBox == &aOldSymbolSets || &rComboBox == &aSymbolSets,
+ "Sm : falsche ComboBox");
+#endif
+
+ rComboBox.Clear();
+ if (bDeleteText)
+ rComboBox.SetText(XubString());
+
+ const std::set< String > aSymbolSetNames( aSymbolMgrCopy.GetSymbolSetNames() );
+ std::set< String >::const_iterator aIt( aSymbolSetNames.begin() );
+ for ( ; aIt != aSymbolSetNames.end(); ++aIt)
+ rComboBox.InsertEntry( *aIt );
+}
+
+
+void SmSymDefineDialog::FillFonts(bool bDelete)
+{
+ aFonts.Clear();
+ if (bDelete)
+ aFonts.SetNoSelection();
+
+ // alle Fonts der 'FontList' in die Fontliste aufnehmen
+ // von denen mit gleichen Namen jedoch nur einen (denn der Style wird
+ // ueber die 'FontStyleBox' gewaehlt und nicht auch noch hier)
+ if (pFontList)
+ {
+ sal_uInt16 nCount = pFontList->GetFontNameCount();
+ for (sal_uInt16 i = 0; i < nCount; i++)
+ aFonts.InsertEntry( pFontList->GetFontName(i).GetName() );
+ }
+}
+
+
+void SmSymDefineDialog::FillStyles(bool bDeleteText)
+{
+ aStyles.Clear();
+ if (bDeleteText)
+ aStyles.SetText(XubString());
+
+ XubString aText (aFonts.GetSelectEntry());
+ if (aText.Len() != 0)
+ {
+ // eigene StyleName's verwenden
+ const SmFontStyles &rStyles = GetFontStyles();
+ for (sal_uInt16 i = 0; i < rStyles.GetCount(); i++)
+ aStyles.InsertEntry( rStyles.GetStyleName(i) );
+
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(aStyles.GetEntryCount() > 0, "Sm : no styles available");
+#endif
+ aStyles.SetText( aStyles.GetEntry(0) );
+ }
+}
+
+
+SmSym * SmSymDefineDialog::GetSymbol(const ComboBox &rComboBox)
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(&rComboBox == &aOldSymbols || &rComboBox == &aSymbols,
+ "Sm : wrong combobox");
+#endif
+ return aSymbolMgrCopy.GetSymbolByName(rComboBox.GetText());
+}
+
+
+IMPL_LINK( SmSymDefineDialog, OldSymbolChangeHdl, ComboBox *, EMPTYARG pComboBox )
+{
+ (void) pComboBox;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pComboBox == &aOldSymbols, "Sm : wrong argument");
+#endif
+ SelectSymbol(aOldSymbols, aOldSymbols.GetText(), false);
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, OldSymbolSetChangeHdl, ComboBox *, EMPTYARG pComboBox )
+{
+ (void) pComboBox;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pComboBox == &aOldSymbolSets, "Sm : wrong argument");
+#endif
+ SelectSymbolSet(aOldSymbolSets, aOldSymbolSets.GetText(), false);
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, ModifyHdl, ComboBox *, pComboBox )
+{
+ // merken der Cursorposition zum wiederherstellen derselben
+ Selection aSelection (pComboBox->GetSelection());
+
+ if (pComboBox == &aSymbols)
+ SelectSymbol(aSymbols, aSymbols.GetText(), false);
+ else if (pComboBox == &aSymbolSets)
+ SelectSymbolSet(aSymbolSets, aSymbolSets.GetText(), false);
+ else if (pComboBox == &aOldSymbols)
+ // nur Namen aus der Liste erlauben
+ SelectSymbol(aOldSymbols, aOldSymbols.GetText(), true);
+ else if (pComboBox == &aOldSymbolSets)
+ // nur Namen aus der Liste erlauben
+ SelectSymbolSet(aOldSymbolSets, aOldSymbolSets.GetText(), true);
+ else if (pComboBox == &aStyles)
+ // nur Namen aus der Liste erlauben (ist hier eh immer der Fall)
+ SelectStyle(aStyles.GetText(), true);
+ else
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OSL_FAIL("Sm : wrong combobox argument");
+#endif
+ }
+
+ pComboBox->SetSelection(aSelection);
+
+ UpdateButtons();
+
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, FontChangeHdl, ListBox *, EMPTYARG pListBox )
+{
+ (void) pListBox;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pListBox == &aFonts, "Sm : wrong argument");
+#endif
+
+ SelectFont(aFonts.GetSelectEntry());
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, SubsetChangeHdl, ListBox *, EMPTYARG pListBox )
+{
+ (void) pListBox;
+ sal_uInt16 nPos = aFontsSubsetLB.GetSelectEntryPos();
+ if (LISTBOX_ENTRY_NOTFOUND != nPos)
+ {
+ const Subset* pSubset = reinterpret_cast<const Subset*> (aFontsSubsetLB.GetEntryData( nPos ));
+ if (pSubset)
+ {
+ aCharsetDisplay.SelectCharacter( pSubset->GetRangeMin() );
+ }
+ }
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, StyleChangeHdl, ComboBox *, EMPTYARG pComboBox )
+{
+ (void) pComboBox;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pComboBox == &aStyles, "Sm : falsches Argument");
+#endif
+
+ SelectStyle(aStyles.GetText());
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, CharHighlightHdl, Control *, EMPTYARG )
+{
+ sal_UCS4 cChar = aCharsetDisplay.GetSelectCharacter();
+
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE( pSubsetMap, "SubsetMap missing" );
+#endif
+ if (pSubsetMap)
+ {
+ const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if (pSubset)
+ aFontsSubsetLB.SelectEntry( pSubset->GetName() );
+ else
+ aFontsSubsetLB.SetNoSelection();
+ }
+
+ aSymbolDisplay.SetSymbol( cChar, aCharsetDisplay.GetFont() );
+
+ UpdateButtons();
+
+ // display Unicode position as symbol name while iterating over characters
+ const String aHex( String::CreateFromInt64( cChar, 16 ).ToUpperAscii() );
+ const String aPattern( A2OU( aHex.Len() > 4 ? "Ux000000" : "Ux0000" ) );
+ String aUnicodePos( aPattern.Copy( 0, aPattern.Len() - aHex.Len() ) );
+ aUnicodePos += aHex;
+ aSymbols.SetText( aUnicodePos );
+ aSymbolName.SetText( aUnicodePos );
+
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, AddClickHdl, Button *, EMPTYARG pButton )
+{
+ (void) pButton;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pButton == &aAddBtn, "Sm : wrong argument");
+ OSL_ENSURE(aAddBtn.IsEnabled(), "Sm : requirements met ??");
+#endif
+
+ // add symbol
+ const SmSym aNewSymbol( aSymbols.GetText(), aCharsetDisplay.GetFont(),
+ aCharsetDisplay.GetSelectCharacter(), aSymbolSets.GetText() );
+ //OSL_ENSURE( aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == NULL, "symbol already exists" );
+ aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol );
+
+ // update display of new symbol
+ aSymbolDisplay.SetSymbol( &aNewSymbol );
+ aSymbolName.SetText( aNewSymbol.GetName() );
+ aSymbolSetName.SetText( aNewSymbol.GetSymbolSetName() );
+
+ // update list box entries
+ FillSymbolSets(aOldSymbolSets, false);
+ FillSymbolSets(aSymbolSets, false);
+ FillSymbols(aOldSymbols ,false);
+ FillSymbols(aSymbols ,false);
+
+ UpdateButtons();
+
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, ChangeClickHdl, Button *, EMPTYARG pButton )
+{
+ (void) pButton;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pButton == &aChangeBtn, "Sm : wrong argument");
+ OSL_ENSURE(aChangeBtn.IsEnabled(), "Sm : requirements met ??");
+#endif
+
+ // get new Sybol to use
+ //! get font from symbol-disp lay since charset-display does not keep
+ //! the bold attribut.
+ const SmSym aNewSymbol( aSymbols.GetText(), aCharsetDisplay.GetFont(),
+ aCharsetDisplay.GetSelectCharacter(), aSymbolSets.GetText() );
+
+ // remove old symbol if the name was changed then add new one
+ const bool bNameChanged = aOldSymbols.GetText() != aSymbols.GetText();
+ if (bNameChanged)
+ aSymbolMgrCopy.RemoveSymbol( aOldSymbols.GetText() );
+ aSymbolMgrCopy.AddOrReplaceSymbol( aNewSymbol, true );
+
+ // clear display for original symbol if necessary
+ if (bNameChanged)
+ SetOrigSymbol(NULL, XubString());
+
+ // update display of new symbol
+ aSymbolDisplay.SetSymbol( &aNewSymbol );
+ aSymbolName.SetText( aNewSymbol.GetName() );
+ aSymbolSetName.SetText( aNewSymbol.GetSymbolSetName() );
+
+ // update list box entries
+ FillSymbolSets(aOldSymbolSets, false);
+ FillSymbolSets(aSymbolSets, false);
+ FillSymbols(aOldSymbols ,false);
+ FillSymbols(aSymbols ,false);
+
+ UpdateButtons();
+
+ return 0;
+}
+
+
+IMPL_LINK( SmSymDefineDialog, DeleteClickHdl, Button *, EMPTYARG pButton )
+{
+ (void) pButton;
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(pButton == &aDeleteBtn, "Sm : wrong argument");
+ OSL_ENSURE(aDeleteBtn.IsEnabled(), "Sm : requirements met ??");
+#endif
+
+ if (pOrigSymbol)
+ {
+ aSymbolMgrCopy.RemoveSymbol( pOrigSymbol->GetName() );
+
+ // clear display for original symbol
+ SetOrigSymbol(NULL, XubString());
+
+ // update list box entries
+ FillSymbolSets(aOldSymbolSets, false);
+ FillSymbolSets(aSymbolSets, false);
+ FillSymbols(aOldSymbols ,false);
+ FillSymbols(aSymbols ,false);
+ }
+
+ UpdateButtons();
+
+ return 0;
+}
+
+
+void SmSymDefineDialog::UpdateButtons()
+{
+ bool bAdd = false,
+ bChange = false,
+ bDelete = false;
+ XubString aTmpSymbolName (aSymbols.GetText()),
+ aTmpSymbolSetName (aSymbolSets.GetText());
+
+ if (aTmpSymbolName.Len() > 0 && aTmpSymbolSetName.Len() > 0)
+ {
+ // alle Einstellungen gleich?
+ //! (Font-, Style- und SymbolSet Name werden nicht case sensitiv verglichen)
+ bool bEqual = pOrigSymbol
+ && aTmpSymbolSetName.EqualsIgnoreCaseAscii(aOldSymbolSetName.GetText())
+ && aTmpSymbolName.Equals(pOrigSymbol->GetName())
+ && aFonts.GetSelectEntry().EqualsIgnoreCaseAscii(
+ pOrigSymbol->GetFace().GetName())
+ && aStyles.GetText().EqualsIgnoreCaseAscii(
+ GetFontStyles().GetStyleName(pOrigSymbol->GetFace()))
+ && aCharsetDisplay.GetSelectCharacter() == pOrigSymbol->GetCharacter();
+
+ // hinzufuegen nur wenn es noch kein Symbol desgleichen Namens gibt
+ bAdd = aSymbolMgrCopy.GetSymbolByName(aTmpSymbolName) == NULL;
+
+ // loeschen nur wenn alle Einstellungen gleich sind
+ bDelete = pOrigSymbol != NULL;
+
+ // aendern nur falls altes Symbol vorhanden und am neuen etwas anders ist
+ bChange = pOrigSymbol && !bEqual;
+ }
+
+ aAddBtn .Enable(bAdd);
+ aChangeBtn.Enable(bChange);
+ aDeleteBtn.Enable(bDelete);
+}
+
+
+SmSymDefineDialog::SmSymDefineDialog(Window * pParent,
+ OutputDevice *pFntListDevice, SmSymbolManager &rMgr, bool bFreeRes) :
+ ModalDialog (pParent, SmResId(RID_SYMDEFINEDIALOG)),
+ aOldSymbolText (this, SmResId(1)),
+ aOldSymbols (this, SmResId(1)),
+ aOldSymbolSetText (this, SmResId(2)),
+ aOldSymbolSets (this, SmResId(2)),
+ aCharsetDisplay (this, SmResId(1)),
+ aSymbolText (this, SmResId(9)),
+ aSymbols (this, SmResId(4)),
+ aSymbolSetText (this, SmResId(10)),
+ aSymbolSets (this, SmResId(5)),
+ aFontText (this, SmResId(3)),
+ aFonts (this, SmResId(1)),
+ aFontsSubsetFT (this, SmResId( FT_FONTS_SUBSET )),
+ aFontsSubsetLB (this, SmResId( LB_FONTS_SUBSET )),
+ aStyleText (this, SmResId(4)),
+ aStyles (this, SmResId(3)),
+ aOldSymbolName (this, SmResId(7)),
+ aOldSymbolDisplay (this, SmResId(3)),
+ aOldSymbolSetName (this, SmResId(8)),
+ aSymbolName (this, SmResId(5)),
+ aSymbolDisplay (this, SmResId(2)),
+ aSymbolSetName (this, SmResId(6)),
+ aOkBtn (this, SmResId(1)),
+ aCancelBtn (this, SmResId(1)),
+ aAddBtn (this, SmResId(1)),
+ aChangeBtn (this, SmResId(2)),
+ aDeleteBtn (this, SmResId(3)),
+ aRightArrow (this, SmResId(1)),
+ aRigthArrow_Im (SmResId(1)),
+ rSymbolMgr (rMgr),
+ pSubsetMap (NULL),
+ pFontList (NULL)
+{
+ if (bFreeRes)
+ FreeResource();
+
+ pFontList = new FontList( pFntListDevice );
+
+ pOrigSymbol = 0;
+
+ // auto completion is troublesome since that symbols character also gets automatically selected in the
+ // display and if the user previously selected a character to define/redefine that one this is bad
+ aOldSymbols.EnableAutocomplete( false, true );
+ aSymbols .EnableAutocomplete( false, true );
+
+ FillFonts();
+ if (aFonts.GetEntryCount() > 0)
+ SelectFont(aFonts.GetEntry(0));
+
+ InitColor_Impl();
+
+ SetSymbolSetManager(rSymbolMgr);
+
+ aOldSymbols .SetSelectHdl(LINK(this, SmSymDefineDialog, OldSymbolChangeHdl));
+ aOldSymbolSets .SetSelectHdl(LINK(this, SmSymDefineDialog, OldSymbolSetChangeHdl));
+ aSymbolSets .SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
+ aOldSymbolSets .SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
+ aSymbols .SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
+ aOldSymbols .SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
+ aStyles .SetModifyHdl(LINK(this, SmSymDefineDialog, ModifyHdl));
+ aFonts .SetSelectHdl(LINK(this, SmSymDefineDialog, FontChangeHdl));
+ aFontsSubsetLB .SetSelectHdl(LINK(this, SmSymDefineDialog, SubsetChangeHdl));
+ aStyles .SetSelectHdl(LINK(this, SmSymDefineDialog, StyleChangeHdl));
+ aAddBtn .SetClickHdl (LINK(this, SmSymDefineDialog, AddClickHdl));
+ aChangeBtn .SetClickHdl (LINK(this, SmSymDefineDialog, ChangeClickHdl));
+ aDeleteBtn .SetClickHdl (LINK(this, SmSymDefineDialog, DeleteClickHdl));
+ aCharsetDisplay.SetHighlightHdl( LINK( this, SmSymDefineDialog, CharHighlightHdl ) );
+
+ // preview like controls should have a 2D look
+ aOldSymbolDisplay.SetBorderStyle( WINDOW_BORDER_MONO );
+ aSymbolDisplay .SetBorderStyle( WINDOW_BORDER_MONO );
+}
+
+
+SmSymDefineDialog::~SmSymDefineDialog()
+{
+ delete pSubsetMap;
+ delete pOrigSymbol;
+}
+
+void SmSymDefineDialog::InitColor_Impl()
+{
+#if OSL_DEBUG_LEVEL > 1
+ Color aBC( GetDisplayBackground().GetColor() );
+#endif
+ ColorData nBgCol = COL_WHITE,
+ nTxtCol = COL_BLACK;
+ bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
+ if (bHighContrast)
+ {
+ const StyleSettings &rS = GetSettings().GetStyleSettings();
+ nBgCol = rS.GetFieldColor().GetColor();
+ nTxtCol = rS.GetFieldTextColor().GetColor();
+ }
+
+ Color aTmpColor( nBgCol );
+ Wallpaper aWall( aTmpColor );
+ Color aTxtColor( nTxtCol );
+ aCharsetDisplay .SetBackground( aWall );
+ aCharsetDisplay .SetTextColor( aTxtColor );
+ aOldSymbolDisplay.SetBackground( aWall );
+ aOldSymbolDisplay.SetTextColor( aTxtColor );
+ aSymbolDisplay .SetBackground( aWall );
+ aSymbolDisplay .SetTextColor( aTxtColor );
+
+ const Image &rArrowRight = aRigthArrow_Im;
+ aRightArrow.SetImage( rArrowRight );
+}
+
+
+void SmSymDefineDialog::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( rDCEvt.GetType() == DATACHANGED_SETTINGS &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ InitColor_Impl();
+
+ ModalDialog::DataChanged( rDCEvt );
+}
+
+
+short SmSymDefineDialog::Execute()
+{
+ short nResult = ModalDialog::Execute();
+
+ // Aenderungen uebernehmen falls Dialog mit OK beendet wurde
+ if (aSymbolMgrCopy.IsModified() && nResult == RET_OK)
+ rSymbolMgr = aSymbolMgrCopy;
+
+ return nResult;
+}
+
+
+void SmSymDefineDialog::SetSymbolSetManager(const SmSymbolManager &rMgr)
+{
+ aSymbolMgrCopy = rMgr;
+
+ // Das modified Flag der Kopie auf false setzen, damit man spaeter damit
+ // testen kann ob sich was geaendert hat.
+ aSymbolMgrCopy.SetModified(false);
+
+ FillSymbolSets(aOldSymbolSets);
+ if (aOldSymbolSets.GetEntryCount() > 0)
+ SelectSymbolSet(aOldSymbolSets.GetEntry(0));
+ FillSymbolSets(aSymbolSets);
+ if (aSymbolSets.GetEntryCount() > 0)
+ SelectSymbolSet(aSymbolSets.GetEntry(0));
+ FillSymbols(aOldSymbols);
+ if (aOldSymbols.GetEntryCount() > 0)
+ SelectSymbol(aOldSymbols.GetEntry(0));
+ FillSymbols(aSymbols);
+ if (aSymbols.GetEntryCount() > 0)
+ SelectSymbol(aSymbols.GetEntry(0));
+
+ UpdateButtons();
+}
+
+
+bool SmSymDefineDialog::SelectSymbolSet(ComboBox &rComboBox,
+ const XubString &rSymbolSetName, bool bDeleteText)
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(&rComboBox == &aOldSymbolSets || &rComboBox == &aSymbolSets,
+ "Sm : wrong ComboBox");
+#endif
+
+ // 'Normalisieren' des SymbolNamens (ohne leading und trailing Leerzeichen)
+ XubString aNormName (rSymbolSetName);
+ aNormName.EraseLeadingChars(' ');
+ aNormName.EraseTrailingChars(' ');
+ // und evtl Abweichungen in der Eingabe beseitigen
+ rComboBox.SetText(aNormName);
+
+ bool bRet = false;
+ sal_uInt16 nPos = rComboBox.GetEntryPos(aNormName);
+
+ if (nPos != COMBOBOX_ENTRY_NOTFOUND)
+ {
+ rComboBox.SetText(rComboBox.GetEntry(nPos));
+ bRet = true;
+ }
+ else if (bDeleteText)
+ rComboBox.SetText(XubString());
+
+ bool bIsOld = &rComboBox == &aOldSymbolSets;
+
+ // setzen des SymbolSet Namens an der zugehoerigen Darstellung
+ FixedText &rFT = bIsOld ? aOldSymbolSetName : aSymbolSetName;
+ rFT.SetText(rComboBox.GetText());
+
+ // setzen der zum SymbolSet gehoerenden Symbol Namen an der zugehoerigen
+ // Auswahbox
+ ComboBox &rCB = bIsOld ? aOldSymbols : aSymbols;
+ FillSymbols(rCB, false);
+
+ // bei Wechsel des SymbolSets fuer das alte Zeichen ein gueltiges
+ // Symbol bzw keins zur Anzeige bringen
+ if (bIsOld)
+ {
+ XubString aTmpOldSymbolName;
+ if (aOldSymbols.GetEntryCount() > 0)
+ aTmpOldSymbolName = aOldSymbols.GetEntry(0);
+ SelectSymbol(aOldSymbols, aTmpOldSymbolName, true);
+ }
+
+ UpdateButtons();
+
+ return bRet;
+}
+
+
+void SmSymDefineDialog::SetOrigSymbol(const SmSym *pSymbol,
+ const XubString &rSymbolSetName)
+{
+ // clear old symbol
+ delete pOrigSymbol;
+ pOrigSymbol = 0;
+
+ XubString aSymName,
+ aSymSetName;
+ if (pSymbol)
+ {
+ // set new symbol
+ pOrigSymbol = new SmSym( *pSymbol );
+
+ aSymName = pSymbol->GetName();
+ aSymSetName = rSymbolSetName;
+ aOldSymbolDisplay.SetSymbol( pSymbol );
+ }
+ else
+ { // loeschen des angezeigten Symbols
+ aOldSymbolDisplay.SetText(XubString());
+ aOldSymbolDisplay.Invalidate();
+ }
+ aOldSymbolName .SetText(aSymName);
+ aOldSymbolSetName.SetText(aSymSetName);
+}
+
+
+bool SmSymDefineDialog::SelectSymbol(ComboBox &rComboBox,
+ const XubString &rSymbolName, bool bDeleteText)
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(&rComboBox == &aOldSymbols || &rComboBox == &aSymbols,
+ "Sm : wrong ComboBox");
+#endif
+
+ // 'Normalisieren' des SymbolNamens (ohne Leerzeichen)
+ XubString aNormName (rSymbolName);
+ aNormName.EraseAllChars(' ');
+ // und evtl Abweichungen in der Eingabe beseitigen
+ rComboBox.SetText(aNormName);
+
+ bool bRet = false;
+ sal_uInt16 nPos = rComboBox.GetEntryPos(aNormName);
+
+ bool bIsOld = &rComboBox == &aOldSymbols;
+
+ if (nPos != COMBOBOX_ENTRY_NOTFOUND)
+ {
+ rComboBox.SetText(rComboBox.GetEntry(nPos));
+
+ if (!bIsOld)
+ {
+ const SmSym *pSymbol = GetSymbol(aSymbols);
+ if (pSymbol)
+ {
+ // Font und Style entsprechend waehlen
+ const Font &rFont = pSymbol->GetFace();
+ SelectFont(rFont.GetName(), false);
+ SelectStyle(GetFontStyles().GetStyleName(rFont), false);
+
+ // da das setzen des Fonts ueber den Style Namen des SymbolsFonts nicht
+ // so gut klappt (er kann zB leer sein obwohl der Font selbst 'bold' und
+ // 'italic' ist!). Setzen wir hier den Font wie er zum Symbol gehoert
+ // zu Fuss.
+ aCharsetDisplay.SetFont(rFont);
+ aSymbolDisplay.SetFont(rFont);
+
+ // das zugehoerige Zeichen auswaehlen
+ SelectChar(pSymbol->GetCharacter());
+
+ // since SelectChar will also set the unicode point as text in the
+ // symbols box, we have to set the symbol name again to get that one displayed
+ aSymbols.SetText( pSymbol->GetName() );
+ }
+ }
+
+ bRet = true;
+ }
+ else if (bDeleteText)
+ rComboBox.SetText(XubString());
+
+ if (bIsOld)
+ {
+ // bei Wechsel des alten Symbols nur vorhandene anzeigen sonst keins
+ const SmSym *pOldSymbol = NULL;
+ XubString aTmpOldSymbolSetName;
+ if (nPos != COMBOBOX_ENTRY_NOTFOUND)
+ {
+ pOldSymbol = aSymbolMgrCopy.GetSymbolByName(aNormName);
+ aTmpOldSymbolSetName = aOldSymbolSets.GetText();
+ }
+ SetOrigSymbol(pOldSymbol, aTmpOldSymbolSetName);
+ }
+ else
+ aSymbolName.SetText(rComboBox.GetText());
+
+ UpdateButtons();
+
+ return bRet;
+}
+
+
+void SmSymDefineDialog::SetFont(const XubString &rFontName, const XubString &rStyleName)
+{
+ // Font (FontInfo) passend zu Namen und Style holen
+ FontInfo aFI;
+ if (pFontList)
+ aFI = pFontList->Get(rFontName, WEIGHT_NORMAL, ITALIC_NONE);
+ SetFontStyle(rStyleName, aFI);
+
+ aCharsetDisplay.SetFont(aFI);
+ aSymbolDisplay.SetFont(aFI);
+
+ // update subset listbox for new font's unicode subsets
+ FontCharMap aFontCharMap;
+ aCharsetDisplay.GetFontCharMap( aFontCharMap );
+ if (pSubsetMap)
+ delete pSubsetMap;
+ pSubsetMap = new SubsetMap( &aFontCharMap );
+
+ aFontsSubsetLB.Clear();
+ bool bFirst = true;
+ const Subset* pSubset;
+ while( NULL != (pSubset = pSubsetMap->GetNextSubset( bFirst )) )
+ {
+ sal_uInt16 nPos = aFontsSubsetLB.InsertEntry( pSubset->GetName());
+ aFontsSubsetLB.SetEntryData( nPos, (void *) pSubset );
+ // subset must live at least as long as the selected font !!!
+ if( bFirst )
+ aFontsSubsetLB.SelectEntryPos( nPos );
+ bFirst = false;
+ }
+ if( bFirst )
+ aFontsSubsetLB.SetNoSelection();
+ aFontsSubsetLB.Enable( !bFirst );
+}
+
+
+bool SmSymDefineDialog::SelectFont(const XubString &rFontName, bool bApplyFont)
+{
+ bool bRet = false;
+ sal_uInt16 nPos = aFonts.GetEntryPos(rFontName);
+
+ if (nPos != LISTBOX_ENTRY_NOTFOUND)
+ {
+ aFonts.SelectEntryPos(nPos);
+ if (aStyles.GetEntryCount() > 0)
+ SelectStyle(aStyles.GetEntry(0));
+ if (bApplyFont)
+ {
+ SetFont(aFonts.GetSelectEntry(), aStyles.GetText());
+ bRet = true;
+ aSymbolDisplay.SetSymbol( aCharsetDisplay.GetSelectCharacter(), aCharsetDisplay.GetFont() );
+ }
+ bRet = sal_True;
+ }
+ else
+ aFonts.SetNoSelection();
+ FillStyles();
+
+ UpdateButtons();
+
+ return bRet;
+}
+
+
+bool SmSymDefineDialog::SelectStyle(const XubString &rStyleName, bool bApplyFont)
+{
+ bool bRet = false;
+ sal_uInt16 nPos = aStyles.GetEntryPos(rStyleName);
+
+ // falls der Style nicht zur Auswahl steht nehmen wir den erst moeglichen
+ // (sofern vorhanden)
+ if (nPos == COMBOBOX_ENTRY_NOTFOUND && aStyles.GetEntryCount() > 0)
+ nPos = 0;
+
+ if (nPos != COMBOBOX_ENTRY_NOTFOUND)
+ {
+ aStyles.SetText(aStyles.GetEntry(nPos));
+ if (bApplyFont)
+ {
+ SetFont(aFonts.GetSelectEntry(), aStyles.GetText());
+ bRet = true;
+ aSymbolDisplay.SetSymbol( aCharsetDisplay.GetSelectCharacter(), aCharsetDisplay.GetFont() );
+ }
+ bRet = sal_True;
+ }
+ else
+ aStyles.SetText(XubString());
+
+ UpdateButtons();
+
+ return bRet;
+}
+
+
+void SmSymDefineDialog::SelectChar(xub_Unicode cChar)
+{
+ aCharsetDisplay.SelectCharacter( cChar );
+ aSymbolDisplay.SetSymbol( cChar, aCharsetDisplay.GetFont() );
+
+ UpdateButtons();
+}
+
+
+/**************************************************************************/
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/dialog.hrc b/starmath/source/dialog.hrc
new file mode 100755
index 000000000000..9e3e58493ab3
--- /dev/null
+++ b/starmath/source/dialog.hrc
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _DIALOG_HRC_
+#define _DIALOG_HRC_
+
+
+#define FL_PRINTOPTIONS 10
+#define CB_TITLEROW 11
+#define CB_EQUATION_TEXT 12
+#define CB_FRAME 13
+
+#define FL_PRINT_FORMAT 20
+#define RB_ORIGINAL_SIZE 21
+#define RB_FIT_TO_PAGE 22
+#define RB_ZOOM 23
+#define MF_ZOOM 24
+
+#define FL_MISC_OPTIONS 30
+#define CB_IGNORE_SPACING 31
+#define CB_SAVE_ONLY_USED_SYMBOLS 32
+
+#define FT_FONTS_SUBSET 110
+#define LB_FONTS_SUBSET 111
+
+
+#endif
+
diff --git a/starmath/source/document.cxx b/starmath/source/document.cxx
new file mode 100644
index 000000000000..337e038df69e
--- /dev/null
+++ b/starmath/source/document.cxx
@@ -0,0 +1,1439 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/uno/Any.h>
+
+#include <comphelper/accessibletexthelper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <rtl/logfile.hxx>
+#include <rtl/ustring.hxx>
+#include <unotools/eventcfg.hxx>
+#include <sfx2/event.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sot/clsids.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <sot/storage.hxx>
+#include <svl/eitem.hxx>
+#include <svl/fstathelper.hxx>
+#include <svl/intitem.hxx>
+#include <svl/itempool.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/ptitem.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/smplhint.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/transfer.hxx>
+#include <svl/undo.hxx>
+#include <svl/urihelper.hxx>
+#include <svl/whiter.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <ucbhelper/content.hxx>
+#include <vcl/mapmod.hxx>
+#include <tools/mapunit.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/sfx.hrc>
+#include <document.hxx>
+#include <action.hxx>
+#include <config.hxx>
+#include <dialog.hxx>
+#include <format.hxx>
+#include <smdll.hxx>
+#include <starmath.hrc>
+#include <symbol.hxx>
+#include <toolbox.hxx>
+#include <unomodel.hxx>
+#include <utility.hxx>
+#include <view.hxx>
+#include "mathtype.hxx"
+#include "mathmlimport.hxx"
+#include "mathmlexport.hxx"
+#include <sfx2/sfxsids.hrc>
+#include <svx/svxids.hrc>
+#include "cursor.hxx"
+#include <tools/diagnose_ex.h>
+#include "visitors.hxx"
+#include "accessibility.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+
+
+#define DOCUMENT_BUFFER_SIZE (sal_uInt16)32768
+
+static const char pStarMathDoc[] = "StarMathDocument";
+
+#define SmDocShell
+#include "smslots.hxx"
+
+////////////////////////////////////////////////////////////
+
+
+TYPEINIT1( SmDocShell, SfxObjectShell );
+
+SFX_IMPL_INTERFACE(SmDocShell, SfxObjectShell, SmResId(0))
+{
+ SFX_POPUPMENU_REGISTRATION(SmResId(RID_VIEWMENU));
+ SFX_POPUPMENU_REGISTRATION(SmResId(RID_COMMANDMENU));
+}
+
+SFX_IMPL_OBJECTFACTORY(SmDocShell, SvGlobalName(SO3_SM_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "smath" )
+
+void SmDocShell::SFX_NOTIFY(SfxBroadcaster&, const TypeId&,
+ const SfxHint& rHint, const TypeId&)
+{
+ switch (((SfxSimpleHint&)rHint).GetId())
+ {
+ case HINT_FORMATCHANGED:
+ SetFormulaArranged(false);
+
+ nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
+
+ Repaint();
+ break;
+ }
+}
+
+void SmDocShell::LoadSymbols()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::LoadSymbols" );
+
+ SmModule *pp = SM_MOD();
+ pp->GetSymbolManager().Load();
+}
+
+
+const String SmDocShell::GetComment() const
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetComment" );
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ const_cast<SmDocShell*>(this)->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps(
+ xDPS->getDocumentProperties());
+ return xDocProps->getDescription();
+}
+
+
+void SmDocShell::SetText(const String& rBuffer)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetText" );
+
+ if (rBuffer != aText)
+ {
+ bool bIsEnabled = IsEnableSetModified();
+ if( bIsEnabled )
+ EnableSetModified( false );
+
+ aText = rBuffer;
+ SetFormulaArranged( false );
+
+ Parse();
+
+ SmViewShell *pViewSh = SmGetActiveView();
+ if( pViewSh )
+ {
+ pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_TEXT);
+ if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
+ {
+ // have SwOleClient::FormatChanged() to align the modified formula properly
+ // even if the vis area does not change (e.g. when formula text changes from
+ // "{a over b + c} over d" to "d over {a over b + c}"
+ SFX_APP()->NotifyEvent(SfxEventHint( SFX_EVENT_VISAREACHANGED, GlobalEventConfig::GetEventName(STR_EVENT_VISAREACHANGED), this));
+
+ Repaint();
+ }
+ else
+ pViewSh->GetGraphicWindow().Invalidate();
+ }
+
+ if ( bIsEnabled )
+ EnableSetModified( bIsEnabled );
+ SetModified(true);
+
+ // launch accessible event if necessary
+ SmGraphicAccessible *pAcc = pViewSh ? pViewSh->GetGraphicWindow().GetAccessible_Impl() : 0;
+ if (pAcc)
+ {
+ Any aOldValue, aNewValue;
+ if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( aText, rBuffer, aOldValue, aNewValue ) )
+ {
+ pAcc->LaunchEvent( AccessibleEventId::TEXT_CHANGED,
+ aOldValue, aNewValue );
+ }
+ }
+
+ if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ OnDocumentPrinterChanged(0);
+ }
+}
+
+void SmDocShell::SetFormat(SmFormat& rFormat)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetFormat" );
+
+ aFormat = rFormat;
+ SetFormulaArranged( false );
+ SetModified( true );
+
+ nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
+
+ // don't use SmGetActiveView since the view shell might not be active (0 pointer)
+ // if for example the Basic Macro dialog currently has the focus. Thus:
+ SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
+ while (pFrm)
+ {
+ pFrm->GetBindings().Invalidate(SID_GAPHIC_SM);
+ pFrm = SfxViewFrame::GetNext( *pFrm, this );
+ }
+}
+
+String SmDocShell::GetAccessibleText()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetAccessibleText" );
+
+ if (!IsFormulaArranged())
+ ArrangeFormula();
+ if (0 == aAccText.Len())
+ {
+ OSL_ENSURE( pTree, "Tree missing" );
+ if (pTree)
+ pTree->GetAccessibleText( aAccText );
+ }
+ return aAccText;
+}
+
+void SmDocShell::Parse()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Parse" );
+
+ if (pTree)
+ delete pTree;
+ ReplaceBadChars();
+ pTree = aInterpreter.Parse(aText);
+ nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
+ SetFormulaArranged( false );
+ InvalidateCursor();
+ aUsedSymbols = aInterpreter.GetUsedSymbols();
+}
+
+
+void SmDocShell::ArrangeFormula()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ArrangeFormula" );
+
+ if (IsFormulaArranged())
+ return;
+
+ //! Nur f�r die Dauer der Existenz dieses Objekts sind am Drucker die
+ //! richtigen Einstellungen garantiert.
+ SmPrinterAccess aPrtAcc(*this);
+ OutputDevice* pOutDev = aPrtAcc.GetRefDev();
+
+ if (!pOutDev)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OSL_FAIL("!! SmDocShell::ArrangeFormula: reference device missing !!");
+#endif
+ }
+
+ // falls n�tig ein anderes OutputDevice holen f�r das formatiert wird
+ if (!pOutDev)
+ {
+ SmViewShell *pView = SmGetActiveView();
+ if (pView)
+ pOutDev = &pView->GetGraphicWindow();
+ else
+ {
+ pOutDev = &SM_MOD()->GetDefaultVirtualDev();
+ pOutDev->SetMapMode( MapMode(MAP_100TH_MM) );
+ }
+ }
+ OSL_ENSURE(pOutDev->GetMapMode().GetMapUnit() == MAP_100TH_MM,
+ "Sm : falscher MapMode");
+
+ const SmFormat &rFormat = GetFormat();
+ pTree->Prepare(rFormat, *this);
+
+ // format/draw formulas always from left to right,
+ // and numbers should not be converted
+ sal_uLong nLayoutMode = pOutDev->GetLayoutMode();
+ pOutDev->SetLayoutMode( TEXT_LAYOUT_BIDI_LTR );
+ sal_Int16 nDigitLang = pOutDev->GetDigitLanguage();
+ pOutDev->SetDigitLanguage( LANGUAGE_ENGLISH );
+ //
+ pTree->Arrange(*pOutDev, rFormat);
+ //
+ pOutDev->SetLayoutMode( nLayoutMode );
+ pOutDev->SetDigitLanguage( nDigitLang );
+
+ SetFormulaArranged(true);
+
+ // invalidate accessible text
+ aAccText = String();
+}
+
+
+void SetEditEngineDefaultFonts(
+ EditEngine &/*rEditEngine*/,
+ SfxItemPool &rEditEngineItemPool )
+{
+ //
+ // set fonts to be used
+ //
+ SvtLinguOptions aOpt;
+ SvtLinguConfig().GetOptions( aOpt );
+ //
+ struct FontDta {
+ sal_Int16 nFallbackLang;
+ sal_Int16 nLang;
+ sal_uInt16 nFontType;
+ sal_uInt16 nFontInfoId;
+ } aTable[3] =
+ {
+ // info to get western font to be used
+ { LANGUAGE_ENGLISH_US, LANGUAGE_NONE,
+ DEFAULTFONT_FIXED, EE_CHAR_FONTINFO },
+ // info to get CJK font to be used
+ { LANGUAGE_JAPANESE, LANGUAGE_NONE,
+ DEFAULTFONT_CJK_TEXT, EE_CHAR_FONTINFO_CJK },
+ // info to get CTL font to be used
+ { LANGUAGE_ARABIC_SAUDI_ARABIA, LANGUAGE_NONE,
+ DEFAULTFONT_CTL_TEXT, EE_CHAR_FONTINFO_CTL }
+ };
+ aTable[0].nLang = aOpt.nDefaultLanguage;
+ aTable[1].nLang = aOpt.nDefaultLanguage_CJK;
+ aTable[2].nLang = aOpt.nDefaultLanguage_CTL;
+ //
+ for (int i = 0; i < 3; ++i)
+ {
+ const FontDta &rFntDta = aTable[i];
+ LanguageType nLang = (LANGUAGE_NONE == rFntDta.nLang) ?
+ rFntDta.nFallbackLang : rFntDta.nLang;
+ Font aFont = Application::GetDefaultDevice()->GetDefaultFont(
+ rFntDta.nFontType, nLang, DEFAULTFONT_FLAGS_ONLYONE );
+ rEditEngineItemPool.SetPoolDefaultItem(
+ SvxFontItem( aFont.GetFamily(), aFont.GetName(),
+ aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(),
+ rFntDta.nFontInfoId ) );
+ }
+
+ // set font heights
+ SvxFontHeightItem aFontHeigt(
+ Application::GetDefaultDevice()->LogicToPixel(
+ Size( 0, 11 ), MapMode( MAP_POINT ) ).Height(), 100,
+ EE_CHAR_FONTHEIGHT );
+ rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt );
+ aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CJK );
+ rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt );
+ aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CTL );
+ rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt );
+}
+
+
+EditEngine& SmDocShell::GetEditEngine()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetEditEngine" );
+
+ if (!pEditEngine)
+ {
+ //!
+ //! see also SmEditWindow::DataChanged !
+ //!
+
+ pEditEngineItemPool = EditEngine::CreatePool();
+
+ SetEditEngineDefaultFonts( *pEditEngine, *pEditEngineItemPool );
+
+ pEditEngine = new EditEngine( pEditEngineItemPool );
+
+ pEditEngine->EnableUndo( true );
+ pEditEngine->SetDefTab( sal_uInt16(
+ Application::GetDefaultDevice()->GetTextWidth( C2S("XXXX") ) ) );
+
+ pEditEngine->SetControlWord(
+ (pEditEngine->GetControlWord() | EE_CNTRL_AUTOINDENTING) &
+ (~EE_CNTRL_UNDOATTRIBS) &
+ (~EE_CNTRL_PASTESPECIAL) );
+
+ pEditEngine->SetWordDelimiters( C2S(" .=+-*/(){}[];\"" ) );
+ pEditEngine->SetRefMapMode( MAP_PIXEL );
+
+ pEditEngine->SetPaperSize( Size( 800, 0 ) );
+
+ pEditEngine->EraseVirtualDevice();
+
+ // set initial text if the document already has some...
+ // (may be the case when reloading a doc)
+ String aTxt( GetText() );
+ if (aTxt.Len())
+ pEditEngine->SetText( aTxt );
+
+ pEditEngine->ClearModifyFlag();
+
+ }
+ return *pEditEngine;
+}
+
+
+SfxItemPool& SmDocShell::GetEditEngineItemPool()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetEditEngineItemPool" );
+
+ if (!pEditEngineItemPool)
+ GetEditEngine();
+ OSL_ENSURE( pEditEngineItemPool, "EditEngineItemPool missing" );
+ return *pEditEngineItemPool;
+}
+
+void SmDocShell::DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSelection)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Draw" );
+
+ if (!pTree)
+ Parse();
+ OSL_ENSURE(pTree, "Sm : NULL pointer");
+
+ if (!IsFormulaArranged())
+ ArrangeFormula();
+
+ //Problem: Was passiert mit dem WYSIWYG? Wir haben waehrend wir inplace aktiv
+ //sind kein Referenzdevice und sind auch nicht darauf ausgerichtet. Es kann
+ //also jetzt eine Differenz zwischen der VisArea (spricht die Groesse im Client)
+ //und der jetzt vorliegenden Groese geben.
+ //Idee: Die Differenz koennte, zumindest behelfsmaessig, mit SmNod::SetSize
+ //angepasst werden.
+
+ rPosition.X() += aFormat.GetDistance( DIS_LEFTSPACE );
+ rPosition.Y() += aFormat.GetDistance( DIS_TOPSPACE );
+
+ //! in case of high contrast-mode (accessibility option!)
+ //! the draw mode needs to be set to default, because when imbedding
+ //! Math for example in Calc in "a over b" the fraction bar may not
+ //! be visible else. More generally: the FillColor may have been changed.
+ sal_uLong nOldDrawMode = DRAWMODE_DEFAULT;
+ bool bRestoreDrawMode = false;
+ if (OUTDEV_WINDOW == rDev.GetOutDevType() &&
+ ((Window &) rDev).GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ nOldDrawMode = rDev.GetDrawMode();
+ rDev.SetDrawMode( DRAWMODE_DEFAULT );
+ bRestoreDrawMode = true;
+ }
+
+ // format/draw formulas always from left to right
+ // and numbers should not be converted
+ sal_uLong nLayoutMode = rDev.GetLayoutMode();
+ rDev.SetLayoutMode( TEXT_LAYOUT_BIDI_LTR );
+ sal_Int16 nDigitLang = rDev.GetDigitLanguage();
+ rDev.SetDigitLanguage( LANGUAGE_ENGLISH );
+
+ //Set selection if any
+ if(pCursor && bDrawSelection){
+ pCursor->AnnotateSelection();
+ SmSelectionDrawingVisitor(rDev, pTree, rPosition);
+ }
+
+ //Drawing using visitor
+ SmDrawingVisitor(rDev, rPosition, pTree);
+
+ //
+ rDev.SetLayoutMode( nLayoutMode );
+ rDev.SetDigitLanguage( nDigitLang );
+
+ if (bRestoreDrawMode)
+ rDev.SetDrawMode( nOldDrawMode );
+}
+
+
+
+Size SmDocShell::GetSize()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetSize" );
+
+ Size aRet;
+
+ if (!pTree)
+ Parse();
+
+ if (pTree)
+ {
+ if (!IsFormulaArranged())
+ ArrangeFormula();
+ aRet = pTree->GetSize();
+
+ if ( !aRet.Width() )
+ aRet.Width() = 2000;
+ else
+ aRet.Width() += aFormat.GetDistance( DIS_LEFTSPACE ) +
+ aFormat.GetDistance( DIS_RIGHTSPACE );
+ if ( !aRet.Height() )
+ aRet.Height() = 1000;
+ else
+ aRet.Height() += aFormat.GetDistance( DIS_TOPSPACE ) +
+ aFormat.GetDistance( DIS_BOTTOMSPACE );
+ }
+
+ return aRet;
+}
+
+void SmDocShell::InvalidateCursor(){
+ delete pCursor;
+ pCursor = NULL;
+}
+
+SmCursor& SmDocShell::GetCursor(){
+ if(!pCursor)
+ pCursor = new SmCursor(pTree, this);
+ return *pCursor;
+}
+
+////////////////////////////////////////
+
+SmPrinterAccess::SmPrinterAccess( SmDocShell &rDocShell )
+{
+ if ( 0 != (pPrinter = rDocShell.GetPrt()) )
+ {
+ pPrinter->Push( PUSH_MAPMODE );
+ if ( SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() )
+ {
+ // if it is an embedded object (without it's own printer)
+ // we change the MapMode temporarily.
+ //!If it is a document with it's own printer the MapMode should
+ //!be set correct (once) elsewhere(!), in order to avoid numerous
+ //!superfluous pushing and poping of the MapMode when using
+ //!this class.
+
+ const MapUnit eOld = pPrinter->GetMapMode().GetMapUnit();
+ if ( MAP_100TH_MM != eOld )
+ {
+ MapMode aMap( pPrinter->GetMapMode() );
+ aMap.SetMapUnit( MAP_100TH_MM );
+ Point aTmp( aMap.GetOrigin() );
+ aTmp.X() = OutputDevice::LogicToLogic( aTmp.X(), eOld, MAP_100TH_MM );
+ aTmp.Y() = OutputDevice::LogicToLogic( aTmp.Y(), eOld, MAP_100TH_MM );
+ aMap.SetOrigin( aTmp );
+ pPrinter->SetMapMode( aMap );
+ }
+ }
+ }
+ if ( 0 != (pRefDev = rDocShell.GetRefDev()) && pPrinter != pRefDev )
+ {
+ pRefDev->Push( PUSH_MAPMODE );
+ if ( SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() )
+ {
+ // if it is an embedded object (without it's own printer)
+ // we change the MapMode temporarily.
+ //!If it is a document with it's own printer the MapMode should
+ //!be set correct (once) elsewhere(!), in order to avoid numerous
+ //!superfluous pushing and poping of the MapMode when using
+ //!this class.
+
+ const MapUnit eOld = pRefDev->GetMapMode().GetMapUnit();
+ if ( MAP_100TH_MM != eOld )
+ {
+ MapMode aMap( pRefDev->GetMapMode() );
+ aMap.SetMapUnit( MAP_100TH_MM );
+ Point aTmp( aMap.GetOrigin() );
+ aTmp.X() = OutputDevice::LogicToLogic( aTmp.X(), eOld, MAP_100TH_MM );
+ aTmp.Y() = OutputDevice::LogicToLogic( aTmp.Y(), eOld, MAP_100TH_MM );
+ aMap.SetOrigin( aTmp );
+ pRefDev->SetMapMode( aMap );
+ }
+ }
+ }
+}
+
+SmPrinterAccess::~SmPrinterAccess()
+{
+ if ( pPrinter )
+ pPrinter->Pop();
+ if ( pRefDev && pRefDev != pPrinter )
+ pRefDev->Pop();
+}
+
+////////////////////////////////////////
+
+Printer* SmDocShell::GetPrt()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetPrt" );
+
+ if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
+ {
+ //Normalerweise wird der Printer vom Server besorgt. Wenn dieser aber
+ //keinen liefert (weil etwa noch keine connection da ist), kann es
+ //dennoch sein, dass wir den Printer kennen, denn dieser wird in
+ //OnDocumentPrinterChanged vom Server durchgereicht und dann temporaer
+ //festgehalten.
+ Printer *pPrt = GetDocumentPrinter();
+ if ( !pPrt && pTmpPrinter )
+ pPrt = pTmpPrinter;
+ return pPrt;
+ }
+ else if ( !pPrinter )
+ {
+ SfxItemSet *pOptions =
+ new SfxItemSet(GetPool(),
+ SID_PRINTSIZE, SID_PRINTSIZE,
+ SID_PRINTZOOM, SID_PRINTZOOM,
+ SID_PRINTTITLE, SID_PRINTTITLE,
+ SID_PRINTTEXT, SID_PRINTTEXT,
+ SID_PRINTFRAME, SID_PRINTFRAME,
+ SID_NO_RIGHT_SPACES, SID_NO_RIGHT_SPACES,
+ 0);
+
+ SmModule *pp = SM_MOD();
+ pp->GetConfig()->ConfigToItemSet(*pOptions);
+ pPrinter = new SfxPrinter(pOptions);
+ pPrinter->SetMapMode( MapMode(MAP_100TH_MM) );
+ }
+ return pPrinter;
+}
+
+OutputDevice* SmDocShell::GetRefDev()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetRefDev" );
+
+ if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
+ {
+ OutputDevice* pOutDev = GetDocumentRefDev();
+ if ( pOutDev )
+ return pOutDev;
+ }
+
+ return GetPrt();
+}
+
+
+void SmDocShell::SetPrinter( SfxPrinter *pNew )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetPrinter" );
+
+ delete pPrinter;
+ pPrinter = pNew; //Eigentumsuebergang!
+ pPrinter->SetMapMode( MapMode(MAP_100TH_MM) );
+ SetFormulaArranged(false);
+ Repaint();
+}
+
+void SmDocShell::OnDocumentPrinterChanged( Printer *pPrt )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::OnDocumentPrinterChanged" );
+
+ pTmpPrinter = pPrt;
+ SetFormulaArranged(false);
+ Size aOldSize = GetVisArea().GetSize();
+ Repaint();
+ if( aOldSize != GetVisArea().GetSize() && aText.Len() )
+ SetModified( true );
+ pTmpPrinter = 0;
+}
+
+void SmDocShell::Repaint()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Repaint" );
+
+ bool bIsEnabled = IsEnableSetModified();
+ if ( bIsEnabled )
+ EnableSetModified( false );
+
+ SetFormulaArranged( false );
+
+ Size aVisSize = GetSize();
+ SetVisAreaSize( aVisSize );
+ SmViewShell *pViewSh = SmGetActiveView();
+ if (pViewSh)
+ pViewSh->GetGraphicWindow().Invalidate();
+
+ if ( bIsEnabled )
+ EnableSetModified( bIsEnabled );
+}
+
+
+SmDocShell::SmDocShell( const sal_uInt64 i_nSfxCreationFlags ) :
+ SfxObjectShell( i_nSfxCreationFlags ),
+ pTree ( 0 ),
+ pEditEngineItemPool ( 0 ),
+ pEditEngine ( 0 ),
+ pPrinter ( 0 ),
+ pTmpPrinter ( 0 ),
+ nModifyCount ( 0 ),
+ bIsFormulaArranged ( false )
+{
+ pCursor = NULL;
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SmDocShell" );
+
+ SetPool(&SFX_APP()->GetPool());
+
+ SmModule *pp = SM_MOD();
+ aFormat = pp->GetConfig()->GetStandardFormat();
+
+ StartListening(aFormat);
+ StartListening(*pp->GetConfig());
+
+ SetBaseModel( new SmModel(this) );
+}
+
+
+
+SmDocShell::~SmDocShell()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::~SmDocShell" );
+
+ SmModule *pp = SM_MOD();
+
+ EndListening(aFormat);
+ EndListening(*pp->GetConfig());
+
+
+ if(pCursor)
+ delete pCursor;
+ pCursor = NULL;
+
+ delete pEditEngine;
+ SfxItemPool::Free(pEditEngineItemPool);
+ delete pTree;
+ delete pPrinter;
+}
+
+
+sal_Bool SmDocShell::SetData( const String& rData )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetData" );
+
+ SetText( rData );
+ return true;
+}
+
+
+sal_Bool SmDocShell::ConvertFrom(SfxMedium &rMedium)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ConvertFrom" );
+
+ bool bSuccess = false;
+ const String& rFltName = rMedium.GetFilter()->GetFilterName();
+
+ OSL_ENSURE( !rFltName.EqualsAscii( STAROFFICE_XML ), "Wrong filter!");
+
+ if ( rFltName.EqualsAscii( MATHML_XML ) )
+ {
+ if (pTree)
+ {
+ delete pTree;
+ pTree = 0;
+ InvalidateCursor();
+ }
+ Reference<com::sun::star::frame::XModel> xModel(GetModel());
+ SmXMLImportWrapper aEquation(xModel);
+ bSuccess = 0 == aEquation.Import(rMedium);
+ }
+ else
+ {
+ SvStream *pStream = rMedium.GetInStream();
+ if ( pStream )
+ {
+ if ( SotStorage::IsStorageFile( pStream ) )
+ {
+ SvStorageRef aStorage = new SotStorage( pStream, false );
+ if ( aStorage->IsStream( C2S( "Equation Native" ) ) )
+ {
+ // is this a MathType Storage?
+ MathType aEquation( aText );
+ if ( true == (bSuccess = (1 == aEquation.Parse( aStorage )) ))
+ Parse();
+ }
+ }
+ }
+ }
+
+ if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ SetFormulaArranged( false );
+ Repaint();
+ }
+
+ FinishedLoading( SFX_LOADED_ALL );
+ return bSuccess;
+}
+
+
+sal_Bool SmDocShell::InitNew( const uno::Reference < embed::XStorage >& xStorage )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::InitNew" );
+
+ bool bRet = false;
+ if ( SfxObjectShell::InitNew( xStorage ) )
+ {
+ bRet = true;
+ SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000)));
+ }
+ return bRet;
+}
+
+
+sal_Bool SmDocShell::Load( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Load" );
+
+ bool bRet = false;
+ if( SfxObjectShell::Load( rMedium ))
+ {
+ uno::Reference < embed::XStorage > xStorage = GetMedium()->GetStorage();
+ uno::Reference < container::XNameAccess > xAccess (xStorage, uno::UNO_QUERY);
+ if (
+ (
+ xAccess->hasByName( C2S( "content.xml" ) ) &&
+ xStorage->isStreamElement( C2S( "content.xml" ) )
+ ) ||
+ (
+ xAccess->hasByName( C2S( "Content.xml" ) ) &&
+ xStorage->isStreamElement( C2S( "Content.xml" ) )
+ )
+ )
+ {
+ // is this a fabulous math package ?
+ Reference<com::sun::star::frame::XModel> xModel(GetModel());
+ SmXMLImportWrapper aEquation(xModel);
+ sal_uLong nError = aEquation.Import(rMedium);
+ bRet = 0 == nError;
+ SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ }
+ }
+
+ if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ SetFormulaArranged( false );
+ Repaint();
+ }
+
+ FinishedLoading( SFX_LOADED_ALL );
+ return bRet;
+}
+
+//------------------------------------------------------------------
+
+sal_Bool SmDocShell::Save()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Save" );
+
+ //! apply latest changes if necessary
+ UpdateText();
+
+ if ( SfxObjectShell::Save() )
+ {
+ if (!pTree)
+ Parse();
+ if( pTree && !IsFormulaArranged() )
+ ArrangeFormula();
+
+ Reference<com::sun::star::frame::XModel> xModel(GetModel());
+ SmXMLExportWrapper aEquation(xModel);
+ aEquation.SetFlat(sal_False);
+ return aEquation.Export(*GetMedium());
+ }
+
+ return false;
+}
+
+/*
+ * replace bad characters that can not be saved. (#i74144)
+ * */
+sal_Bool SmDocShell::ReplaceBadChars()
+{
+ sal_Bool bReplace = sal_False;
+ if (pEditEngine)
+ {
+ String aEngTxt( pEditEngine->GetText( LINEEND_LF ) );
+ const sal_Unicode *pEngTxt = aEngTxt.GetBuffer();
+ xub_StrLen nLen = aEngTxt.Len();
+ for (xub_StrLen i = 0; i < nLen && !bReplace; ++i)
+ {
+ const sal_Unicode c = *pEngTxt++;
+ if (c < ' ' && c != '\r' && c != '\n' && c != '\t')
+ bReplace = sal_True;
+ }
+ if (bReplace)
+ {
+ sal_Unicode *pChgTxt = aEngTxt.GetBufferAccess();
+ for (xub_StrLen i = 0; i < nLen; ++i)
+ {
+ sal_Unicode &rc = *pChgTxt++;
+ if (rc < ' ' && rc != '\r' && rc != '\n' && rc != '\t')
+ rc = ' ';
+ }
+ aEngTxt.ReleaseBufferAccess( nLen );
+
+ aText = aEngTxt;
+ }
+ }
+ return bReplace;
+}
+
+
+void SmDocShell::UpdateText()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::UpdateText" );
+
+ if (pEditEngine && pEditEngine->IsModified())
+ {
+ String aEngTxt( pEditEngine->GetText( LINEEND_LF ) );
+ if (GetText() != aEngTxt)
+ SetText( aEngTxt );
+ }
+}
+
+
+sal_Bool SmDocShell::SaveAs( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveAs" );
+
+ bool bRet = false;
+
+ //! apply latest changes if necessary
+ UpdateText();
+
+ if ( SfxObjectShell::SaveAs( rMedium ) )
+ {
+ if (!pTree)
+ Parse();
+ if( pTree && !IsFormulaArranged() )
+ ArrangeFormula();
+
+ Reference<com::sun::star::frame::XModel> xModel(GetModel());
+ SmXMLExportWrapper aEquation(xModel);
+ aEquation.SetFlat(sal_False);
+ bRet = aEquation.Export(rMedium);
+ }
+ return bRet;
+}
+
+sal_Bool SmDocShell::ConvertTo( SfxMedium &rMedium )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ConvertTo" );
+
+ bool bRet = false;
+ const SfxFilter* pFlt = rMedium.GetFilter();
+ if( pFlt )
+ {
+ if( !pTree )
+ Parse();
+ if( pTree && !IsFormulaArranged() )
+ ArrangeFormula();
+
+ const String& rFltName = pFlt->GetFilterName();
+ if(rFltName.EqualsAscii( STAROFFICE_XML ))
+ {
+ Reference<com::sun::star::frame::XModel> xModel(GetModel());
+ SmXMLExportWrapper aEquation(xModel);
+ aEquation.SetFlat(sal_False);
+ bRet = aEquation.Export(rMedium);
+ }
+ else if(rFltName.EqualsAscii( MATHML_XML ))
+ {
+ Reference<com::sun::star::frame::XModel> xModel(GetModel());
+ SmXMLExportWrapper aEquation(xModel);
+ aEquation.SetFlat(sal_True);
+ bRet = aEquation.Export(rMedium);
+ }
+ else if( pFlt->GetFilterName().EqualsAscii("MathType 3.x"))
+ bRet = WriteAsMathType3( rMedium );
+ }
+ return bRet;
+}
+
+sal_Bool SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveCompleted" );
+
+ if( SfxObjectShell::SaveCompleted( xStorage ))
+ return true;
+
+ return false;
+}
+
+
+void SmDocShell::Execute(SfxRequest& rReq)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Execute" );
+
+ switch (rReq.GetSlot())
+ {
+ case SID_TEXTMODE:
+ {
+ SmFormat aOldFormat = GetFormat();
+ SmFormat aNewFormat( aOldFormat );
+ aNewFormat.SetTextmode(!aOldFormat.IsTextmode());
+
+ ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
+ if (pTmpUndoMgr)
+ pTmpUndoMgr->AddUndoAction(
+ new SmFormatAction(this, aOldFormat, aNewFormat));
+
+ SetFormat( aNewFormat );
+ Repaint();
+ }
+ break;
+
+ case SID_AUTO_REDRAW :
+ {
+ SmModule *pp = SM_MOD();
+ bool bRedraw = pp->GetConfig()->IsAutoRedraw();
+ pp->GetConfig()->SetAutoRedraw(!bRedraw);
+ }
+ break;
+
+ case SID_LOADSYMBOLS:
+ LoadSymbols();
+ break;
+
+ case SID_SAVESYMBOLS:
+ SaveSymbols();
+ break;
+
+ case SID_FONT:
+ {
+ // get device used to retrieve the FontList
+ OutputDevice *pDev = GetPrinter();
+ if (!pDev || pDev->GetDevFontCount() == 0)
+ pDev = &SM_MOD()->GetDefaultVirtualDev();
+ OSL_ENSURE (pDev, "device for font list missing" );
+
+ SmFontTypeDialog *pFontTypeDialog = new SmFontTypeDialog( NULL, pDev );
+
+ SmFormat aOldFormat = GetFormat();
+ pFontTypeDialog->ReadFrom( aOldFormat );
+ if (pFontTypeDialog->Execute() == RET_OK)
+ {
+ SmFormat aNewFormat( aOldFormat );
+
+ pFontTypeDialog->WriteTo(aNewFormat);
+ ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
+ if (pTmpUndoMgr)
+ pTmpUndoMgr->AddUndoAction(
+ new SmFormatAction(this, aOldFormat, aNewFormat));
+
+ SetFormat( aNewFormat );
+ Repaint();
+ }
+ delete pFontTypeDialog;
+ }
+ break;
+
+ case SID_FONTSIZE:
+ {
+ SmFontSizeDialog *pFontSizeDialog = new SmFontSizeDialog(NULL);
+
+ SmFormat aOldFormat = GetFormat();
+ pFontSizeDialog->ReadFrom( aOldFormat );
+ if (pFontSizeDialog->Execute() == RET_OK)
+ {
+ SmFormat aNewFormat( aOldFormat );
+
+ pFontSizeDialog->WriteTo(aNewFormat);
+
+ ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
+ if (pTmpUndoMgr)
+ pTmpUndoMgr->AddUndoAction(
+ new SmFormatAction(this, aOldFormat, aNewFormat));
+
+ SetFormat( aNewFormat );
+ Repaint();
+ }
+ delete pFontSizeDialog;
+ }
+ break;
+
+ case SID_DISTANCE:
+ {
+ SmDistanceDialog *pDistanceDialog = new SmDistanceDialog(NULL);
+
+ SmFormat aOldFormat = GetFormat();
+ pDistanceDialog->ReadFrom( aOldFormat );
+ if (pDistanceDialog->Execute() == RET_OK)
+ {
+ SmFormat aNewFormat( aOldFormat );
+
+ pDistanceDialog->WriteTo(aNewFormat);
+
+ ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
+ if (pTmpUndoMgr)
+ pTmpUndoMgr->AddUndoAction(
+ new SmFormatAction(this, aOldFormat, aNewFormat));
+
+ SetFormat( aNewFormat );
+ Repaint();
+ }
+ delete pDistanceDialog;
+ }
+ break;
+
+ case SID_ALIGN:
+ {
+ SmAlignDialog *pAlignDialog = new SmAlignDialog(NULL);
+
+ SmFormat aOldFormat = GetFormat();
+ pAlignDialog->ReadFrom( aOldFormat );
+ if (pAlignDialog->Execute() == RET_OK)
+ {
+ SmFormat aNewFormat( aOldFormat );
+
+ pAlignDialog->WriteTo(aNewFormat);
+
+ SmModule *pp = SM_MOD();
+ SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
+ pAlignDialog->WriteTo( aFmt );
+ pp->GetConfig()->SetStandardFormat( aFmt );
+
+ ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
+ if (pTmpUndoMgr)
+ pTmpUndoMgr->AddUndoAction(
+ new SmFormatAction(this, aOldFormat, aNewFormat));
+
+ SetFormat( aNewFormat );
+ Repaint();
+ }
+ delete pAlignDialog;
+ }
+ break;
+
+ case SID_TEXT:
+ {
+ const SfxStringItem& rItem = (const SfxStringItem&)rReq.GetArgs()->Get(SID_TEXT);
+ if (GetText() != rItem.GetValue())
+ SetText(rItem.GetValue());
+ }
+ break;
+
+ case SID_UNDO:
+ case SID_REDO:
+ {
+ ::svl::IUndoManager* pTmpUndoMgr = GetUndoManager();
+ if( pTmpUndoMgr )
+ {
+ sal_uInt16 nId = rReq.GetSlot(), nCnt = 1;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ if( pArgs && SFX_ITEM_SET == pArgs->GetItemState( nId, false, &pItem ))
+ nCnt = ((SfxUInt16Item*)pItem)->GetValue();
+
+ sal_Bool (::svl::IUndoManager:: *fnDo)();
+
+ sal_uInt16 nCount;
+ if( SID_UNDO == rReq.GetSlot() )
+ {
+ nCount = pTmpUndoMgr->GetUndoActionCount();
+ fnDo = &::svl::IUndoManager::Undo;
+ }
+ else
+ {
+ nCount = pTmpUndoMgr->GetRedoActionCount();
+ fnDo = &::svl::IUndoManager::Redo;
+ }
+
+ try
+ {
+ for( ; nCnt && nCount; --nCnt, --nCount )
+ (pTmpUndoMgr->*fnDo)();
+ }
+ catch( const Exception& e )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ Repaint();
+ UpdateText();
+ SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
+ while( pFrm )
+ {
+ SfxBindings& rBind = pFrm->GetBindings();
+ rBind.Invalidate(SID_UNDO);
+ rBind.Invalidate(SID_REDO);
+ rBind.Invalidate(SID_REPEAT);
+ rBind.Invalidate(SID_CLEARHISTORY);
+ pFrm = SfxViewFrame::GetNext( *pFrm, this );
+ }
+ }
+ break;
+ }
+
+ rReq.Done();
+}
+
+
+void SmDocShell::GetState(SfxItemSet &rSet)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetState" );
+
+ SfxWhichIter aIter(rSet);
+
+ for (sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich())
+ {
+ switch (nWh)
+ {
+ case SID_TEXTMODE:
+ rSet.Put(SfxBoolItem(SID_TEXTMODE, GetFormat().IsTextmode()));
+ break;
+
+ case SID_DOCTEMPLATE :
+ rSet.DisableItem(SID_DOCTEMPLATE);
+ break;
+
+ case SID_AUTO_REDRAW :
+ {
+ SmModule *pp = SM_MOD();
+ bool bRedraw = pp->GetConfig()->IsAutoRedraw();
+
+ rSet.Put(SfxBoolItem(SID_AUTO_REDRAW, bRedraw));
+ }
+ break;
+
+ case SID_MODIFYSTATUS:
+ {
+ sal_Unicode cMod = ' ';
+ if (IsModified())
+ cMod = '*';
+ rSet.Put(SfxStringItem(SID_MODIFYSTATUS, String(cMod)));
+ }
+ break;
+
+ case SID_TEXT:
+ rSet.Put(SfxStringItem(SID_TEXT, GetText()));
+ break;
+
+ case SID_GAPHIC_SM:
+ //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWindow.
+ //! If nModifyCount gets changed then the call below will implicitly notify
+ //! SmGraphicController::StateChanged and there the window gets invalidated.
+ //! Thus all the 'nModifyCount++' before invalidating this slot.
+ rSet.Put(SfxInt16Item(SID_GAPHIC_SM, nModifyCount));
+ break;
+
+ case SID_UNDO:
+ case SID_REDO:
+ {
+ SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
+ if( pFrm )
+ pFrm->GetSlotState( nWh, NULL, &rSet );
+ else
+ rSet.DisableItem( nWh );
+ }
+ break;
+
+ case SID_GETUNDOSTRINGS:
+ case SID_GETREDOSTRINGS:
+ {
+ ::svl::IUndoManager* pTmpUndoMgr = GetUndoManager();
+ if( pTmpUndoMgr )
+ {
+ UniString(::svl::IUndoManager:: *fnGetComment)( size_t, bool const ) const;
+
+ sal_uInt16 nCount;
+ if( SID_GETUNDOSTRINGS == nWh )
+ {
+ nCount = pTmpUndoMgr->GetUndoActionCount();
+ fnGetComment = &::svl::IUndoManager::GetUndoActionComment;
+ }
+ else
+ {
+ nCount = pTmpUndoMgr->GetRedoActionCount();
+ fnGetComment = &::svl::IUndoManager::GetRedoActionComment;
+ }
+ if( nCount )
+ {
+ String sList;
+ for( sal_uInt16 n = 0; n < nCount; ++n )
+ ( sList += (pTmpUndoMgr->*fnGetComment)( n, ::svl::IUndoManager::TopLevel ) )
+ += '\n';
+
+ SfxStringListItem aItem( nWh );
+ aItem.SetString( sList );
+ rSet.Put( aItem );
+ }
+ }
+ else
+ rSet.DisableItem( nWh );
+ }
+ break;
+ }
+ }
+}
+
+
+::svl::IUndoManager *SmDocShell::GetUndoManager()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetUndoManager" );
+
+ if (!pEditEngine)
+ GetEditEngine();
+ return &pEditEngine->GetUndoManager();
+}
+
+
+void SmDocShell::SaveSymbols()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveSymbols" );
+
+ SmModule *pp = SM_MOD();
+ pp->GetSymbolManager().Save();
+}
+
+
+void SmDocShell::Draw(OutputDevice *pDevice,
+ const JobSetup &,
+ sal_uInt16 /*nAspect*/)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Draw" );
+
+ pDevice->IntersectClipRegion(GetVisArea());
+ Point atmppoint;
+ DrawFormula(*pDevice, atmppoint);
+}
+
+SfxItemPool& SmDocShell::GetPool() const
+{
+ return SFX_APP()->GetPool();
+}
+
+void SmDocShell::SetVisArea(const Rectangle & rVisArea)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetVisArea" );
+
+ Rectangle aNewRect(rVisArea);
+
+ aNewRect.SetPos(Point());
+
+ if (! aNewRect.Right()) aNewRect.Right() = 2000;
+ if (! aNewRect.Bottom()) aNewRect.Bottom() = 1000;
+
+ bool bIsEnabled = IsEnableSetModified();
+ if ( bIsEnabled )
+ EnableSetModified( false );
+
+ //TODO/LATER: it's unclear how this interacts with the SFX code
+ // If outplace editing, then dont resize the OutplaceWindow. But the
+ // ObjectShell has to resize. Bug 56470
+ bool bUnLockFrame;
+ if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && !IsInPlaceActive() && GetFrame() )
+ {
+ GetFrame()->LockAdjustPosSizePixel();
+ bUnLockFrame = true;
+ }
+ else
+ bUnLockFrame = false;
+
+ SfxObjectShell::SetVisArea( aNewRect );
+
+ if( bUnLockFrame )
+ GetFrame()->UnlockAdjustPosSizePixel();
+
+ if ( bIsEnabled )
+ EnableSetModified( bIsEnabled );
+}
+
+
+void SmDocShell::FillClass(SvGlobalName* pClassName,
+ sal_uInt32* pFormat,
+ String* /*pAppName*/,
+ String* pFullTypeName,
+ String* pShortTypeName,
+ sal_Int32 nFileFormat,
+ sal_Bool bTemplate /* = sal_False */) const
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::FillClass" );
+
+ if (nFileFormat == SOFFICE_FILEFORMAT_60 )
+ {
+ *pClassName = SvGlobalName(SO3_SM_CLASSID_60);
+ *pFormat = SOT_FORMATSTR_ID_STARMATH_60;
+ *pFullTypeName = String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT));
+ *pShortTypeName = String(SmResId(RID_DOCUMENTSTR));
+ }
+ else if (nFileFormat == SOFFICE_FILEFORMAT_8 )
+ {
+ *pClassName = SvGlobalName(SO3_SM_CLASSID_60);
+ *pFormat = bTemplate ? SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE : SOT_FORMATSTR_ID_STARMATH_8;
+ *pFullTypeName = String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT));
+ *pShortTypeName = String(SmResId(RID_DOCUMENTSTR));
+ }
+}
+
+sal_uLong SmDocShell::GetMiscStatus() const
+{
+ return SfxObjectShell::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE
+ | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE;
+}
+
+void SmDocShell::SetModified(sal_Bool bModified)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetModified" );
+
+ if( IsEnableSetModified() )
+ {
+ SfxObjectShell::SetModified( bModified );
+ Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED));
+ }
+}
+
+bool SmDocShell::WriteAsMathType3( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::WriteAsMathType3" );
+
+ MathType aEquation( aText, pTree );
+
+ bool bRet = 0 != aEquation.ConvertFromStarMath( rMedium );
+ return bRet;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/edit.cxx b/starmath/source/edit.cxx
new file mode 100644
index 000000000000..bfc0309ebe71
--- /dev/null
+++ b/starmath/source/edit.cxx
@@ -0,0 +1,995 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+
+
+#include "starmath.hrc"
+#define ITEMID_FONT 1
+#define ITEMID_FONTHEIGHT 2
+#define ITEMID_LRSPACE 3
+#define ITEMID_WEIGHT 4
+
+
+#include <vcl/menu.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/eeitem.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/intitem.hxx>
+#include <svl/itempool.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/fontitem.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "edit.hxx"
+#include "view.hxx"
+#include "document.hxx"
+#include "config.hxx"
+#include "accessibility.hxx"
+
+#define SCROLL_LINE 24
+
+#define MINWIDTH 200
+#define MINHEIGHT 200
+#define MINSPLIT 40
+#define SPLITTERWIDTH 2
+
+
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+
+////////////////////////////////////////
+
+
+void SmGetLeftSelectionPart(const ESelection &rSel,
+ sal_uInt16 &nPara, sal_uInt16 &nPos)
+ // returns paragraph number and position of the selections left part
+{
+ // compare start and end of selection and use the one that comes first
+ if ( rSel.nStartPara < rSel.nEndPara
+ || (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos < rSel.nEndPos) )
+ { nPara = rSel.nStartPara;
+ nPos = rSel.nStartPos;
+ }
+ else
+ { nPara = rSel.nEndPara;
+ nPos = rSel.nEndPos;
+ }
+}
+
+bool SmEditWindow::IsInlineEditEnabled()
+{
+ SmViewShell *pView = GetView();
+ return pView ? pView->IsInlineEditEnabled() : false;
+}
+
+////////////////////////////////////////
+
+SmEditWindow::SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin ) :
+ Window (&rMyCmdBoxWin),
+ DropTargetHelper ( this ),
+ pAccessible (0),
+ rCmdBox (rMyCmdBoxWin),
+ pEditView (0),
+ pHScrollBar (0),
+ pVScrollBar (0),
+ pScrollBox (0)
+{
+ SetHelpId(HID_SMA_COMMAND_WIN_EDIT);
+ SetMapMode(MAP_PIXEL);
+
+ // Even RTL languages don't use RTL for math
+ rCmdBox.GetEditWindow()->EnableRTL( false );
+
+ ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
+
+ // compare DataChanged
+ SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
+
+ aModifyTimer.SetTimeoutHdl(LINK(this, SmEditWindow, ModifyTimerHdl));
+ aModifyTimer.SetTimeout(500);
+
+ if (!IsInlineEditEnabled())
+ {
+ aCursorMoveTimer.SetTimeoutHdl(LINK(this, SmEditWindow, CursorMoveTimerHdl));
+ aCursorMoveTimer.SetTimeout(500);
+ }
+
+ // if not called explicitly the this edit window within the
+ // command window will just show an empty gray panel.
+ Show();
+}
+
+
+SmEditWindow::~SmEditWindow()
+{
+ aModifyTimer.Stop();
+
+ StartCursorMove();
+
+ // clean up of classes used for accessibility
+ // must be done before EditView (and thus EditEngine) is no longer
+ // available for those classes.
+ if (pAccessible)
+ pAccessible->ClearWin(); // make Accessible defunctional
+ // Note: memory for pAccessible will be freed when the reference
+ // xAccessible is released.
+
+ if (pEditView)
+ {
+ EditEngine *pEditEngine = pEditView->GetEditEngine();
+ if (pEditEngine)
+ {
+ pEditEngine->SetStatusEventHdl( Link() );
+ pEditEngine->RemoveView( pEditView );
+ }
+ }
+ delete pEditView;
+ delete pHScrollBar;
+ delete pVScrollBar;
+ delete pScrollBox;
+}
+
+void SmEditWindow::StartCursorMove()
+{
+ if (!IsInlineEditEnabled())
+ aCursorMoveTimer.Stop();
+}
+
+void SmEditWindow::InvalidateSlots()
+{
+ SfxBindings& rBind = GetView()->GetViewFrame()->GetBindings();
+ rBind.Invalidate(SID_COPY);
+ rBind.Invalidate(SID_CUT);
+ rBind.Invalidate(SID_DELETE);
+}
+
+SmViewShell * SmEditWindow::GetView()
+{
+ return rCmdBox.GetView();
+}
+
+
+SmDocShell * SmEditWindow::GetDoc()
+{
+ SmViewShell *pView = rCmdBox.GetView();
+ return pView ? pView->GetDoc() : 0;
+}
+
+
+EditEngine * SmEditWindow::GetEditEngine()
+{
+ EditEngine *pEditEng = 0;
+ if (pEditView)
+ pEditEng = pEditView->GetEditEngine();
+ else
+ {
+ SmDocShell *pDoc = GetDoc();
+ if (pDoc)
+ pEditEng = &pDoc->GetEditEngine();
+ }
+ return pEditEng;
+}
+
+
+SfxItemPool * SmEditWindow::GetEditEngineItemPool()
+{
+ SmDocShell *pDoc = GetDoc();
+ return pDoc ? &pDoc->GetEditEngineItemPool() : 0;
+}
+
+void SmEditWindow::ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg )
+{
+ // Note: SetBackground still done in SmEditWindow::DataChanged
+#if OSL_DEBUG_LEVEL > 1
+// ColorData nVal = rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor;
+#endif
+ SetTextColor( rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor );
+ Invalidate();
+}
+
+void SmEditWindow::DataChanged( const DataChangedEvent& )
+{
+ const StyleSettings aSettings( GetSettings().GetStyleSettings() );
+
+ ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
+ SetBackground( aSettings.GetWindowColor() );
+
+ // edit fields in other Applications use this font instead of
+ // the application font thus we use this one too
+ SetPointFont( aSettings.GetFieldFont() /*aSettings.GetAppFont()*/ );
+
+ EditEngine *pEditEngine = GetEditEngine();
+ SfxItemPool *pEditEngineItemPool = GetEditEngineItemPool();
+
+ if (pEditEngine && pEditEngineItemPool)
+ {
+ //!
+ //! see also SmDocShell::GetEditEngine() !
+ //!
+
+ pEditEngine->SetDefTab( sal_uInt16( GetTextWidth( C2S("XXXX") ) ) );
+
+ SetEditEngineDefaultFonts( *pEditEngine, *pEditEngineItemPool );
+
+ // forces new settings to be used
+ // unfortunately this resets the whole edit engine
+ // thus we need to save at least the text
+ String aTxt( pEditEngine->GetText( LINEEND_LF ) );
+ pEditEngine->Clear(); //incorrect font size
+ pEditEngine->SetText( aTxt );
+ }
+
+ AdjustScrollBars();
+ Resize();
+}
+
+IMPL_LINK( SmEditWindow, ModifyTimerHdl, Timer *, EMPTYARG /*pTimer*/ )
+{
+ SmModule *pp = SM_MOD();
+ if (pp->GetConfig()->IsAutoRedraw())
+ Flush();
+ aModifyTimer.Stop();
+ return 0;
+}
+
+IMPL_LINK(SmEditWindow, CursorMoveTimerHdl, Timer *, EMPTYARG /*pTimer*/)
+ // every once in a while check cursor position (selection) of edit
+ // window and if it has changed (try to) set the formula-cursor
+ // according to that.
+{
+ if (IsInlineEditEnabled())
+ return 0;
+
+ ESelection aNewSelection(GetSelection());
+
+ if (!aNewSelection.IsEqual(aOldSelection))
+ {
+ SmViewShell *pView = rCmdBox.GetView();
+ if (pView)
+ {
+ // get row and column to look for
+ sal_uInt16 nRow, nCol;
+ SmGetLeftSelectionPart(aNewSelection, nRow, nCol);
+ nRow++;
+ nCol++;
+ pView->GetGraphicWindow().SetCursorPos(nRow, nCol);
+ aOldSelection = aNewSelection;
+ }
+ }
+ aCursorMoveTimer.Stop();
+
+ return 0;
+}
+
+void SmEditWindow::Resize()
+{
+ if (!pEditView)
+ CreateEditView();
+
+ if (pEditView)
+ {
+ pEditView->SetOutputArea(AdjustScrollBars());
+ pEditView->ShowCursor();
+
+ OSL_ENSURE( pEditView->GetEditEngine(), "EditEngine missing" );
+ const long nMaxVisAreaStart = pEditView->GetEditEngine()->GetTextHeight() -
+ pEditView->GetOutputArea().GetHeight();
+ if (pEditView->GetVisArea().Top() > nMaxVisAreaStart)
+ {
+ Rectangle aVisArea(pEditView->GetVisArea() );
+ aVisArea.Top() = (nMaxVisAreaStart > 0 ) ? nMaxVisAreaStart : 0;
+ aVisArea.SetSize(pEditView->GetOutputArea().GetSize());
+ pEditView->SetVisArea(aVisArea);
+ pEditView->ShowCursor();
+ }
+ InitScrollBars();
+ }
+ Invalidate();
+}
+
+void SmEditWindow::MouseButtonUp(const MouseEvent &rEvt)
+{
+ if (pEditView)
+ pEditView->MouseButtonUp(rEvt);
+ else
+ Window::MouseButtonUp (rEvt);
+
+ if (!IsInlineEditEnabled())
+ CursorMoveTimerHdl(&aCursorMoveTimer);
+ InvalidateSlots();
+}
+
+void SmEditWindow::MouseButtonDown(const MouseEvent &rEvt)
+{
+ if (pEditView)
+ pEditView->MouseButtonDown(rEvt);
+ else
+ Window::MouseButtonDown (rEvt);
+
+ GrabFocus();
+}
+
+void SmEditWindow::Command(const CommandEvent& rCEvt)
+{
+ bool bForwardEvt = true;
+ if (rCEvt.GetCommand() == COMMAND_CONTEXTMENU)
+ {
+ GetParent()->ToTop();
+
+ Point aPoint = rCEvt.GetMousePosPixel();
+ PopupMenu* pPopupMenu = new PopupMenu(SmResId(RID_COMMANDMENU));
+
+ // added for replaceability of context menus
+ Menu* pMenu = NULL;
+ ::com::sun::star::ui::ContextMenuExecuteEvent aEvent;
+ aEvent.SourceWindow = VCLUnoHelper::GetInterface( this );
+ aEvent.ExecutePosition.X = aPoint.X();
+ aEvent.ExecutePosition.Y = aPoint.Y();
+ ::rtl::OUString sDummy;
+ if ( GetView()->TryContextMenuInterception( *pPopupMenu, sDummy, pMenu, aEvent ) )
+ {
+ if ( pMenu )
+ {
+ delete pPopupMenu;
+ pPopupMenu = (PopupMenu*) pMenu;
+ }
+ }
+
+ pPopupMenu->SetSelectHdl(LINK(this, SmEditWindow, MenuSelectHdl));
+
+ pPopupMenu->Execute( this, aPoint );
+ delete pPopupMenu;
+ bForwardEvt = false;
+ }
+ else if (rCEvt.GetCommand() == COMMAND_WHEEL)
+ bForwardEvt = !HandleWheelCommands( rCEvt );
+
+ if (bForwardEvt)
+ {
+ if (pEditView)
+ pEditView->Command( rCEvt );
+ else
+ Window::Command (rCEvt);
+ }
+}
+
+
+bool SmEditWindow::HandleWheelCommands( const CommandEvent &rCEvt )
+{
+ bool bCommandHandled = false; // true if the CommandEvent needs not
+ // to be passed on (because it has fully
+ // been taken care of).
+
+ const CommandWheelData* pWData = rCEvt.GetWheelData();
+ if (pWData)
+ {
+ if (COMMAND_WHEEL_ZOOM == pWData->GetMode())
+ bCommandHandled = true; // no zooming in Command window
+ else
+ bCommandHandled = HandleScrollCommand( rCEvt, pHScrollBar, pVScrollBar);
+ }
+
+ return bCommandHandled;
+}
+
+
+IMPL_LINK_INLINE_START( SmEditWindow, MenuSelectHdl, Menu *, pMenu )
+{
+ SmViewShell *pViewSh = rCmdBox.GetView();
+ if (pViewSh)
+ pViewSh->GetViewFrame()->GetDispatcher()->Execute(
+ SID_INSERTCOMMAND, SFX_CALLMODE_STANDARD,
+ new SfxInt16Item(SID_INSERTCOMMAND, pMenu->GetCurItemId()), 0L);
+ return 0;
+}
+IMPL_LINK_INLINE_END( SmEditWindow, MenuSelectHdl, Menu *, pMenu )
+
+void SmEditWindow::KeyInput(const KeyEvent& rKEvt)
+{
+ if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
+ {
+ bool bCallBase = true;
+ SfxViewShell* pViewShell = GetView();
+ if ( pViewShell && pViewShell->ISA(SmViewShell) )
+ {
+ // Terminate possible InPlace mode
+ bCallBase = !pViewShell->Escape();
+ }
+ if ( bCallBase )
+ Window::KeyInput( rKEvt );
+ }
+ else
+ {
+ StartCursorMove();
+
+ if (!pEditView)
+ CreateEditView();
+ if ( !pEditView->PostKeyEvent(rKEvt) )
+ {
+ SmViewShell *pView = GetView();
+ if ( pView && !pView->KeyInput(rKEvt) )
+ {
+ /* fuert bei F1 (Hilfe) zum Zerstoeren von this! */
+ Flush();
+ if ( aModifyTimer.IsActive() )
+ aModifyTimer.Stop();
+ Window::KeyInput(rKEvt);
+ }
+ else
+ {
+ //SFX hat evtl. Slot an der View gecallt und dabei (wg. Hack
+ //im SFX) den Focus auf die View gesetzt
+ SfxViewShell* pVShell = GetView();
+ if ( pVShell && pVShell->ISA(SmViewShell) &&
+ ((SmViewShell*)pVShell)->GetGraphicWindow().HasFocus() )
+ {
+ GrabFocus();
+ }
+ }
+ }
+ else
+ {
+ // have doc-shell modified only for formula input/change and not
+ // cursor travelling and such things...
+ SmDocShell *pDocShell = GetDoc();
+ if (pDocShell)
+ pDocShell->SetModified( GetEditEngine()->IsModified() );
+
+ aModifyTimer.Start();
+ }
+
+ InvalidateSlots();
+ }
+}
+
+void SmEditWindow::Paint(const Rectangle& rRect)
+{
+ if (!pEditView)
+ CreateEditView();
+ pEditView->Paint(rRect);
+}
+
+void SmEditWindow::CreateEditView()
+{
+ EditEngine *pEditEngine = GetEditEngine();
+
+ //! pEditEngine and pEditView may be 0.
+ //! For example when the program is used by the document-converter
+ if (!pEditView && pEditEngine)
+ {
+ pEditView = new EditView( pEditEngine, this );
+ pEditEngine->InsertView( pEditView );
+
+ if (!pVScrollBar)
+ pVScrollBar = new ScrollBar(this, WinBits(WB_VSCROLL));
+ if (!pHScrollBar)
+ pHScrollBar = new ScrollBar(this, WinBits(WB_HSCROLL));
+ if (!pScrollBox)
+ pScrollBox = new ScrollBarBox(this);
+ pVScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl));
+ pHScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl));
+ pVScrollBar->EnableDrag( true );
+ pHScrollBar->EnableDrag( true );
+
+ pEditView->SetOutputArea(AdjustScrollBars());
+
+ ESelection eSelection;
+
+ pEditView->SetSelection(eSelection);
+ Update();
+ pEditView->ShowCursor(true, true);
+
+ pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) );
+ SetPointer(pEditView->GetPointer());
+
+ SetScrollBarRanges();
+ }
+}
+
+
+IMPL_LINK( SmEditWindow, EditStatusHdl, EditStatus *, EMPTYARG /*pStat*/ )
+{
+ if (!pEditView)
+ return 1;
+ else
+ {
+ Resize();
+ return 0;
+ }
+}
+
+IMPL_LINK_INLINE_START( SmEditWindow, ScrollHdl, ScrollBar *, EMPTYARG /*pScrollBar*/ )
+{
+ OSL_ENSURE(pEditView, "EditView missing");
+ if (pEditView)
+ {
+ pEditView->SetVisArea(Rectangle(Point(pHScrollBar->GetThumbPos(),
+ pVScrollBar->GetThumbPos()),
+ pEditView->GetVisArea().GetSize()));
+ pEditView->Invalidate();
+ }
+ return 0;
+}
+IMPL_LINK_INLINE_END( SmEditWindow, ScrollHdl, ScrollBar *, pScrollBar )
+
+Rectangle SmEditWindow::AdjustScrollBars()
+{
+ const Size aOut( GetOutputSizePixel() );
+ Point aPoint;
+ Rectangle aRect( aPoint, aOut );
+
+ if (pVScrollBar && pHScrollBar && pScrollBox)
+ {
+ const long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
+ Point aPt( aRect.TopRight() ); aPt.X() -= nTmp -1L;
+ pVScrollBar->SetPosSizePixel( aPt, Size(nTmp, aOut.Height() - nTmp));
+
+ aPt = aRect.BottomLeft(); aPt.Y() -= nTmp - 1L;
+ pHScrollBar->SetPosSizePixel( aPt, Size(aOut.Width() - nTmp, nTmp));
+
+ aPt.X() = pHScrollBar->GetSizePixel().Width();
+ aPt.Y() = pVScrollBar->GetSizePixel().Height();
+ pScrollBox->SetPosSizePixel(aPt, Size(nTmp, nTmp ));
+
+ aRect.Right() = aPt.X() - 2;
+ aRect.Bottom() = aPt.Y() - 2;
+ }
+ return aRect;
+}
+
+void SmEditWindow::SetScrollBarRanges()
+{
+ // Extra-Methode, nicht InitScrollBars, da auch fuer EditEngine-Events.
+ EditEngine *pEditEngine = GetEditEngine();
+ if (pVScrollBar && pHScrollBar && pEditEngine && pEditView)
+ {
+ long nTmp = pEditEngine->GetTextHeight();
+ pVScrollBar->SetRange(Range(0, nTmp));
+ pVScrollBar->SetThumbPos(pEditView->GetVisArea().Top());
+
+ nTmp = pEditEngine->GetPaperSize().Width();
+ pHScrollBar->SetRange(Range(0,nTmp));
+ pHScrollBar->SetThumbPos(pEditView->GetVisArea().Left());
+ }
+}
+
+void SmEditWindow::InitScrollBars()
+{
+ if (pVScrollBar && pHScrollBar && pScrollBox && pEditView)
+ {
+ const Size aOut( pEditView->GetOutputArea().GetSize() );
+ pVScrollBar->SetVisibleSize(aOut.Height());
+ pVScrollBar->SetPageSize(aOut.Height() * 8 / 10);
+ pVScrollBar->SetLineSize(aOut.Height() * 2 / 10);
+
+ pHScrollBar->SetVisibleSize(aOut.Width());
+ pHScrollBar->SetPageSize(aOut.Width() * 8 / 10);
+ pHScrollBar->SetLineSize(SCROLL_LINE );
+
+ SetScrollBarRanges();
+
+ pVScrollBar->Show();
+ pHScrollBar->Show();
+ pScrollBox->Show();
+ }
+}
+
+
+String SmEditWindow::GetText() const
+{
+ String aText;
+ EditEngine *pEditEngine = const_cast< SmEditWindow* >(this)->GetEditEngine();
+ OSL_ENSURE( pEditEngine, "EditEngine missing" );
+ if (pEditEngine)
+ aText = pEditEngine->GetText( LINEEND_LF );
+ return aText;
+}
+
+
+void SmEditWindow::SetText(const XubString& rText)
+{
+ EditEngine *pEditEngine = GetEditEngine();
+ OSL_ENSURE( pEditEngine, "EditEngine missing" );
+ if (pEditEngine && !pEditEngine->IsModified())
+ {
+ if (!pEditView)
+ CreateEditView();
+
+ ESelection eSelection = pEditView->GetSelection();
+
+ pEditEngine->SetText(rText);
+ pEditEngine->ClearModifyFlag();
+
+ //! Hier die Timer neu zu starten verhindert, dass die Handler fuer andere
+ //! (im Augenblick nicht mehr aktive) Math Tasks aufgerufen werden.
+ aModifyTimer.Start();
+
+ pEditView->SetSelection(eSelection);
+ }
+}
+
+
+void SmEditWindow::GetFocus()
+{
+ Window::GetFocus();
+
+ if (xAccessible.is())
+ {
+ // Note: will implicitly send the AccessibleStateType::FOCUSED event
+ ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper();
+ if (pHelper)
+ pHelper->SetFocus( sal_True );
+ }
+
+ if (!pEditView)
+ CreateEditView();
+ EditEngine *pEditEngine = GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) );
+
+ //Let SmViewShell know we got focus
+ if(GetView() && IsInlineEditEnabled())
+ GetView()->SetInsertIntoEditWindow(true);
+}
+
+
+void SmEditWindow::LoseFocus()
+{
+ EditEngine *pEditEngine = GetEditEngine();
+ if (pEditEngine)
+ pEditEngine->SetStatusEventHdl( Link() );
+
+ Window::LoseFocus();
+
+ if (xAccessible.is())
+ {
+ // Note: will implicitly send the AccessibleStateType::FOCUSED event
+ ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper();
+ if (pHelper)
+ pHelper->SetFocus( sal_False );
+ }
+}
+
+
+bool SmEditWindow::IsAllSelected() const
+{
+ bool bRes = false;
+ EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine();
+ OSL_ENSURE( pEditView, "NULL pointer" );
+ OSL_ENSURE( pEditEngine, "NULL pointer" );
+ if (pEditEngine && pEditView)
+ {
+ ESelection eSelection( pEditView->GetSelection() );
+ sal_Int32 nParaCnt = pEditEngine->GetParagraphCount();
+ if (!(nParaCnt - 1))
+ {
+ String Text( pEditEngine->GetText( LINEEND_LF ) );
+ bRes = !eSelection.nStartPos && (eSelection.nEndPos == Text.Len () - 1);
+ }
+ else
+ {
+ bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1);
+ }
+ }
+ return bRes;
+}
+
+void SmEditWindow::SelectAll()
+{
+ OSL_ENSURE( pEditView, "NULL pointer" );
+ if (pEditView)
+ {
+ // 0xFFFF as last two parameters refers to the end of the text
+ pEditView->SetSelection( ESelection( 0, 0, 0xFFFF, 0xFFFF ) );
+ }
+}
+
+void SmEditWindow::InsertCommand(sal_uInt16 nCommand)
+{
+ OSL_ENSURE( pEditView, "EditView missing" );
+ if (pEditView)
+ {
+ //Anfang der Selektion merken und hinterher den Cursor daraufsetzen. Nur so
+ //macht das SelNextMark() Sinn.
+ ESelection aSelection = pEditView->GetSelection();
+ aSelection.nEndPos = aSelection.nStartPos;
+ aSelection.nEndPara = aSelection.nStartPara;
+
+ OSL_ENSURE( pEditView, "NULL pointer" );
+ String aText = String(SmResId(nCommand));
+ pEditView->InsertText(aText);
+
+ if (HasMark(aText))
+ { // set selection to next mark
+ pEditView->SetSelection(aSelection);
+ SelNextMark();
+ }
+ else
+ { // set selection after inserted text
+ aSelection.nEndPos = aSelection.nEndPos + sal::static_int_cast< xub_StrLen >(aText.Len());
+ aSelection.nStartPos = aSelection.nEndPos;
+ pEditView->SetSelection(aSelection);
+ }
+
+ aModifyTimer.Start();
+ StartCursorMove();
+ GrabFocus();
+ }
+}
+
+void SmEditWindow::MarkError(const Point &rPos)
+{
+ OSL_ENSURE( pEditView, "EditView missing" );
+ if (pEditView)
+ {
+ const xub_StrLen nCol = sal::static_int_cast< xub_StrLen >(rPos.X());
+ const sal_uInt16 nRow = sal::static_int_cast< sal_uInt16 >(rPos.Y() - 1);
+
+ pEditView->SetSelection(ESelection(nRow, nCol - 1, nRow, nCol));
+ GrabFocus();
+ }
+}
+
+void SmEditWindow::SelNextMark()
+{
+ EditEngine *pEditEngine = GetEditEngine();
+ OSL_ENSURE( pEditView, "NULL pointer" );
+ OSL_ENSURE( pEditEngine, "NULL pointer" );
+ if (pEditEngine && pEditView)
+ {
+ ESelection eSelection = pEditView->GetSelection();
+ sal_uInt16 Pos = eSelection.nEndPos;
+ String aMark (C2S("<?>"));
+ String aText;
+ sal_uInt16 nCounts = pEditEngine->GetParagraphCount();
+
+ while (eSelection.nEndPara < nCounts)
+ {
+ aText = pEditEngine->GetText( eSelection.nEndPara );
+ Pos = aText.Search(aMark, Pos);
+
+ if (Pos != STRING_NOTFOUND)
+ {
+ pEditView->SetSelection(ESelection (eSelection.nEndPara, Pos, eSelection.nEndPara, Pos + 3));
+ break;
+ }
+
+ Pos = 0;
+ eSelection.nEndPara++;
+ }
+ }
+}
+
+void SmEditWindow::SelPrevMark()
+{
+ EditEngine *pEditEngine = GetEditEngine();
+ OSL_ENSURE( pEditEngine, "NULL pointer" );
+ OSL_ENSURE( pEditView, "NULL pointer" );
+ if (pEditEngine && pEditView)
+ {
+ ESelection eSelection = pEditView->GetSelection();
+ sal_uInt16 Pos = STRING_NOTFOUND;
+ xub_StrLen Max = eSelection.nStartPos;
+ String Text( pEditEngine->GetText( eSelection.nStartPara ) );
+ String aMark (C2S("<?>"));
+ sal_uInt16 nCounts = pEditEngine->GetParagraphCount();
+
+ do
+ {
+ sal_uInt16 Fnd = Text.Search(aMark, 0);
+
+ while ((Fnd < Max) && (Fnd != STRING_NOTFOUND))
+ {
+ Pos = Fnd;
+ Fnd = Text.Search(aMark, Fnd + 1);
+ }
+
+ if (Pos == STRING_NOTFOUND)
+ {
+ eSelection.nStartPara--;
+ Text = pEditEngine->GetText( eSelection.nStartPara );
+ Max = Text.Len();
+ }
+ }
+ while ((eSelection.nStartPara < nCounts) &&
+ (Pos == STRING_NOTFOUND));
+
+ if (Pos != STRING_NOTFOUND)
+ {
+ pEditView->SetSelection(ESelection (eSelection.nStartPara, Pos, eSelection.nStartPara, Pos + 3));
+ }
+ }
+}
+
+bool SmEditWindow::HasMark(const String& rText) const
+ // returns true iff 'rText' contains a mark
+{
+ return rText.SearchAscii("<?>", 0) != STRING_NOTFOUND;
+}
+
+void SmEditWindow::MouseMove(const MouseEvent &rEvt)
+{
+ if (pEditView)
+ pEditView->MouseMove(rEvt);
+}
+
+sal_Int8 SmEditWindow::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
+{
+ return pEditView ? /*pEditView->QueryDrop( rEvt )*/DND_ACTION_NONE: DND_ACTION_NONE;
+}
+
+sal_Int8 SmEditWindow::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )
+{
+ return pEditView ? /*pEditView->Drop( rEvt )*/DND_ACTION_NONE : DND_ACTION_NONE;
+}
+
+ESelection SmEditWindow::GetSelection() const
+{
+ // pointer may be 0 when reloading a document and the old view
+ // was already destroyed
+ //(OSL_ENSURE( pEditView, "NULL pointer" );
+ ESelection eSel;
+ if (pEditView)
+ eSel = pEditView->GetSelection();
+ return eSel;
+}
+
+void SmEditWindow::SetSelection(const ESelection &rSel)
+{
+ OSL_ENSURE( pEditView, "NULL pointer" );
+ if (pEditView)
+ pEditView->SetSelection(rSel);
+ InvalidateSlots();
+}
+
+bool SmEditWindow::IsEmpty() const
+{
+ EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine();
+ bool bEmpty = ( pEditEngine ? pEditEngine->GetTextLen() == 0 : false);
+ return bEmpty;
+}
+
+bool SmEditWindow::IsSelected() const
+{
+ return pEditView ? pEditView->HasSelection() : false;
+}
+
+void SmEditWindow::Cut()
+{
+ OSL_ENSURE( pEditView, "EditView missing" );
+ if (pEditView)
+ {
+ pEditView->Cut();
+ GetDoc()->SetModified( true );
+ }
+}
+
+void SmEditWindow::Copy()
+{
+ OSL_ENSURE( pEditView, "EditView missing" );
+ if (pEditView)
+ pEditView->Copy();
+}
+
+void SmEditWindow::Paste()
+{
+ OSL_ENSURE( pEditView, "EditView missing" );
+ if (pEditView)
+ {
+ pEditView->Paste();
+ GetDoc()->SetModified( true );
+ }
+}
+
+void SmEditWindow::Delete()
+{
+ OSL_ENSURE( pEditView, "EditView missing" );
+ if (pEditView)
+ {
+ pEditView->DeleteSelected();
+ GetDoc()->SetModified( true );
+ }
+}
+
+void SmEditWindow::InsertText(const String& Text)
+{
+ OSL_ENSURE( pEditView, "EditView missing" );
+ if (pEditView)
+ {
+ pEditView->InsertText(Text);
+ aModifyTimer.Start();
+ StartCursorMove();
+ }
+}
+
+void SmEditWindow::Flush()
+{
+ EditEngine *pEditEngine = GetEditEngine();
+ if (pEditEngine && pEditEngine->IsModified())
+ {
+ pEditEngine->ClearModifyFlag();
+ SmViewShell *pViewSh = rCmdBox.GetView();
+ if (pViewSh)
+ {
+ pViewSh->GetViewFrame()->GetDispatcher()->Execute(
+ SID_TEXT, SFX_CALLMODE_STANDARD,
+ new SfxStringItem(SID_TEXT, GetText()), 0L);
+ }
+ }
+ if (aCursorMoveTimer.IsActive())
+ {
+ aCursorMoveTimer.Stop();
+ CursorMoveTimerHdl(&aCursorMoveTimer);
+ }
+}
+
+
+void SmEditWindow::DeleteEditView( SmViewShell & /*rView*/ )
+{
+ if (pEditView)
+ {
+ EditEngine *pEditEngine = pEditView->GetEditEngine();
+ if (pEditEngine)
+ {
+ pEditEngine->SetStatusEventHdl( Link() );
+ pEditEngine->RemoveView( pEditView );
+ }
+ delete pEditView;
+ pEditView = 0;
+ }
+}
+
+
+uno::Reference< XAccessible > SmEditWindow::CreateAccessible()
+{
+ if (!pAccessible)
+ {
+ pAccessible = new SmEditAccessible( this );
+ xAccessible = pAccessible;
+ pAccessible->Init();
+ }
+ return xAccessible;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/eqnolefilehdr.cxx b/starmath/source/eqnolefilehdr.cxx
new file mode 100644
index 000000000000..2a553fb862e4
--- /dev/null
+++ b/starmath/source/eqnolefilehdr.cxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+#include "eqnolefilehdr.hxx"
+#include <sot/storage.hxx>
+
+//////////////////////////////////////////////////////////////////////
+
+void EQNOLEFILEHDR::Read(SvStorageStream *pS)
+{
+ *pS >> nCBHdr;
+ *pS >> nVersion;
+ *pS >> nCf;
+ *pS >> nCBObject;
+ *pS >> nReserved1;
+ *pS >> nReserved2;
+ *pS >> nReserved3;
+ *pS >> nReserved4;
+}
+
+
+void EQNOLEFILEHDR::Write(SvStorageStream *pS)
+{
+ *pS << nCBHdr;
+ *pS << nVersion;
+ *pS << nCf;
+ *pS << nCBObject;
+ *pS << nReserved1;
+ *pS << nReserved2;
+ *pS << nReserved3;
+ *pS << nReserved4;
+}
+
+
+sal_Bool GetMathTypeVersion( SotStorage* pStor, sal_uInt8 &nVersion )
+{
+ sal_uInt8 nVer = 0;
+ sal_Bool bSuccess = sal_False;
+
+ //
+ // code sniplet copied from MathType::Parse
+ //
+ SvStorageStreamRef xSrc = pStor->OpenSotStream(
+ String::CreateFromAscii("Equation Native"),
+ STREAM_STD_READ | STREAM_NOCREATE);
+ if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError()))
+ return bSuccess;
+ SvStorageStream *pS = &xSrc;
+ pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ //
+ EQNOLEFILEHDR aHdr;
+ aHdr.Read(pS);
+ *pS >> nVer;
+
+ if (!pS->GetError())
+ {
+ nVersion = nVer;
+ bSuccess = sal_True;
+ }
+ return bSuccess;
+}
+
+//////////////////////////////////////////////////////////////////////
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/eqnolefilehdr.hxx b/starmath/source/eqnolefilehdr.hxx
new file mode 100644
index 000000000000..cdc592d8ea0c
--- /dev/null
+++ b/starmath/source/eqnolefilehdr.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __EQNOLEFILEHDR_HXX__
+#define __EQNOLEFILEHDR_HXX__
+
+#include <sal/types.h>
+#include <sot/storage.hxx>
+
+class SvStorageStream;
+class SotStorage;
+
+#define EQNOLEFILEHDR_SIZE 28
+
+class EQNOLEFILEHDR
+{
+public:
+ EQNOLEFILEHDR() {}
+ EQNOLEFILEHDR(sal_uInt32 nLenMTEF) : nCBHdr(0x1c),nVersion(0x20000),
+ nCf(0xc1c6),nCBObject(nLenMTEF),nReserved1(0),nReserved2(0x0014F690),
+ nReserved3(0x0014EBB4), nReserved4(0) {}
+
+ sal_uInt16 nCBHdr; // length of header, sizeof(EQNOLEFILEHDR) = 28
+ sal_uInt32 nVersion; // hiword = 2, loword = 0
+ sal_uInt16 nCf; // clipboard format ("MathType EF")
+ sal_uInt32 nCBObject; // length of MTEF data following this header
+ sal_uInt32 nReserved1; // not used
+ sal_uInt32 nReserved2; // not used
+ sal_uInt32 nReserved3; // not used
+ sal_uInt32 nReserved4; // not used
+
+ void Read(SvStorageStream *pS);
+ void Write(SvStorageStream *pS);
+};
+
+sal_Bool GetMathTypeVersion( SotStorage* pStor, sal_uInt8 &nVersion );
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/format.cxx b/starmath/source/format.cxx
new file mode 100644
index 000000000000..0e612126b00f
--- /dev/null
+++ b/starmath/source/format.cxx
@@ -0,0 +1,244 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <tools/stream.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include "format.hxx"
+
+/////////////////////////////////////////////////////////////////
+
+// Latin default-fonts
+static const sal_uInt16 aLatinDefFnts[FNT_END] =
+{
+ DEFAULTFONT_SERIF, // FNT_VARIABLE
+ DEFAULTFONT_SERIF, // FNT_FUNCTION
+ DEFAULTFONT_SERIF, // FNT_NUMBER
+ DEFAULTFONT_SERIF, // FNT_TEXT
+ DEFAULTFONT_SERIF, // FNT_SERIF
+ DEFAULTFONT_SANS, // FNT_SANS
+ DEFAULTFONT_FIXED // FNT_FIXED
+ //OpenSymbol, // FNT_MATH
+};
+
+// CJK default-fonts
+//! we use non-asian fonts for variables, functions and numbers since they
+//! look better and even in asia only latin letters will be used for those.
+//! At least that's what I was told...
+static const sal_uInt16 aCJKDefFnts[FNT_END] =
+{
+ DEFAULTFONT_SERIF, // FNT_VARIABLE
+ DEFAULTFONT_SERIF, // FNT_FUNCTION
+ DEFAULTFONT_SERIF, // FNT_NUMBER
+ DEFAULTFONT_CJK_TEXT, // FNT_TEXT
+ DEFAULTFONT_CJK_TEXT, // FNT_SERIF
+ DEFAULTFONT_CJK_DISPLAY, // FNT_SANS
+ DEFAULTFONT_CJK_TEXT // FNT_FIXED
+ //OpenSymbol, // FNT_MATH
+};
+
+// CTL default-fonts
+static const sal_uInt16 aCTLDefFnts[FNT_END] =
+{
+ DEFAULTFONT_CTL_TEXT, // FNT_VARIABLE
+ DEFAULTFONT_CTL_TEXT, // FNT_FUNCTION
+ DEFAULTFONT_CTL_TEXT, // FNT_NUMBER
+ DEFAULTFONT_CTL_TEXT, // FNT_TEXT
+ DEFAULTFONT_CTL_TEXT, // FNT_SERIF
+ DEFAULTFONT_CTL_TEXT, // FNT_SANS
+ DEFAULTFONT_CTL_TEXT // FNT_FIXED
+ //OpenSymbol, // FNT_MATH
+};
+
+
+String GetDefaultFontName( LanguageType nLang, sal_uInt16 nIdent )
+{
+ OSL_ENSURE( /*FNT_BEGIN <= nIdent &&*/ nIdent <= FNT_END,
+ "index out opd range" );
+
+ if (FNT_MATH == nIdent)
+ return String::CreateFromAscii( FNTNAME_MATH );
+ else
+ {
+ const sal_uInt16 *pTable;
+ switch ( SvtLanguageOptions::GetScriptTypeOfLanguage( nLang ) )
+ {
+ case SCRIPTTYPE_LATIN : pTable = aLatinDefFnts; break;
+ case SCRIPTTYPE_ASIAN : pTable = aCJKDefFnts; break;
+ case SCRIPTTYPE_COMPLEX : pTable = aCTLDefFnts; break;
+ default :
+ pTable = aLatinDefFnts;
+ OSL_FAIL( "unknown script-type" );
+ }
+
+ return Application::GetDefaultDevice()->GetDefaultFont(
+ pTable[ nIdent ], nLang,
+ DEFAULTFONT_FLAGS_ONLYONE ).GetName();
+ }
+}
+
+/////////////////////////////////////////////////////////////////
+
+SmFormat::SmFormat()
+: aBaseSize(0, SmPtsTo100th_mm(12))
+{
+ nVersion = SM_FMT_VERSION_NOW;
+
+ eHorAlign = AlignCenter;
+ nGreekCharStyle = 0;
+ bIsTextmode = bScaleNormalBrackets = false;
+
+ vSize[SIZ_TEXT] = 100;
+ vSize[SIZ_INDEX] = 60;
+ vSize[SIZ_FUNCTION] =
+ vSize[SIZ_OPERATOR] = 100;
+ vSize[SIZ_LIMITS] = 60;
+
+ vDist[DIS_HORIZONTAL] = 10;
+ vDist[DIS_VERTICAL] = 5;
+ vDist[DIS_ROOT] = 0;
+ vDist[DIS_SUPERSCRIPT] =
+ vDist[DIS_SUBSCRIPT] = 20;
+ vDist[DIS_NUMERATOR] =
+ vDist[DIS_DENOMINATOR] = 0;
+ vDist[DIS_FRACTION] = 10;
+ vDist[DIS_STROKEWIDTH] = 5;
+ vDist[DIS_UPPERLIMIT] =
+ vDist[DIS_LOWERLIMIT] = 0;
+ vDist[DIS_BRACKETSIZE] =
+ vDist[DIS_BRACKETSPACE] = 5;
+ vDist[DIS_MATRIXROW] = 3;
+ vDist[DIS_MATRIXCOL] = 30;
+ vDist[DIS_ORNAMENTSIZE] =
+ vDist[DIS_ORNAMENTSPACE] = 0;
+ vDist[DIS_OPERATORSIZE] = 50;
+ vDist[DIS_OPERATORSPACE] = 20;
+ vDist[DIS_LEFTSPACE] =
+ vDist[DIS_RIGHTSPACE] = 100;
+ vDist[DIS_TOPSPACE] =
+ vDist[DIS_BOTTOMSPACE] =
+ vDist[DIS_NORMALBRACKETSIZE] = 0;
+
+ vFont[FNT_VARIABLE] =
+ vFont[FNT_FUNCTION] =
+ vFont[FNT_NUMBER] =
+ vFont[FNT_TEXT] =
+ vFont[FNT_SERIF] = SmFace(C2S(FNTNAME_TIMES), aBaseSize);
+ vFont[FNT_SANS] = SmFace(C2S(FNTNAME_HELV), aBaseSize);
+ vFont[FNT_FIXED] = SmFace(C2S(FNTNAME_COUR), aBaseSize);
+ vFont[FNT_MATH] = SmFace(C2S(FNTNAME_MATH), aBaseSize);
+
+ vFont[FNT_MATH].SetCharSet( RTL_TEXTENCODING_UNICODE );
+
+ vFont[FNT_VARIABLE].SetItalic(ITALIC_NORMAL);
+ vFont[FNT_FUNCTION].SetItalic(ITALIC_NONE);
+ vFont[FNT_NUMBER] .SetItalic(ITALIC_NONE);
+ vFont[FNT_TEXT] .SetItalic(ITALIC_NONE);
+ vFont[FNT_SERIF] .SetItalic(ITALIC_NONE);
+ vFont[FNT_SANS] .SetItalic(ITALIC_NONE);
+ vFont[FNT_FIXED] .SetItalic(ITALIC_NONE);
+
+ for ( sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++ )
+ {
+ SmFace &rFace = vFont[i];
+ rFace.SetTransparent( true );
+ rFace.SetAlign( ALIGN_BASELINE );
+ rFace.SetColor( COL_AUTO );
+ bDefaultFont[i] = false;
+ }
+}
+
+
+void SmFormat::SetFont(sal_uInt16 nIdent, const SmFace &rFont, bool bDefault )
+{
+ vFont[nIdent] = rFont;
+ vFont[nIdent].SetTransparent( true );
+ vFont[nIdent].SetAlign( ALIGN_BASELINE );
+
+ bDefaultFont[nIdent] = bDefault;
+}
+
+SmFormat & SmFormat::operator = (const SmFormat &rFormat)
+{
+ SetBaseSize(rFormat.GetBaseSize());
+ SetVersion (rFormat.GetVersion());
+ SetHorAlign(rFormat.GetHorAlign());
+ SetTextmode(rFormat.IsTextmode());
+ SetGreekCharStyle(rFormat.GetGreekCharStyle());
+ SetScaleNormalBrackets(rFormat.IsScaleNormalBrackets());
+
+ sal_uInt16 i;
+ for (i = FNT_BEGIN; i <= FNT_END; i++)
+ {
+ SetFont(i, rFormat.GetFont(i));
+ SetDefaultFont(i, rFormat.IsDefaultFont(i));
+ }
+ for (i = SIZ_BEGIN; i <= SIZ_END; i++)
+ SetRelSize(i, rFormat.GetRelSize(i));
+ for (i = DIS_BEGIN; i <= DIS_END; i++)
+ SetDistance(i, rFormat.GetDistance(i));
+
+ return *this;
+}
+
+
+bool SmFormat::operator == (const SmFormat &rFormat) const
+{
+ bool bRes = aBaseSize == rFormat.aBaseSize &&
+ eHorAlign == rFormat.eHorAlign &&
+ nGreekCharStyle == rFormat.nGreekCharStyle &&
+ bIsTextmode == rFormat.bIsTextmode &&
+ bScaleNormalBrackets == rFormat.bScaleNormalBrackets;
+
+ sal_uInt16 i;
+ for (i = 0; i <= SIZ_END && bRes; ++i)
+ {
+ if (vSize[i] != rFormat.vSize[i])
+ bRes = false;
+ }
+ for (i = 0; i <= DIS_END && bRes; ++i)
+ {
+ if (vDist[i] != rFormat.vDist[i])
+ bRes = false;
+ }
+ for (i = 0; i <= FNT_END && bRes; ++i)
+ {
+ if (vFont[i] != rFormat.vFont[i] ||
+ bDefaultFont[i] != rFormat.bDefaultFont[i])
+ bRes = false;
+ }
+
+ return bRes;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/makefile.mk b/starmath/source/makefile.mk
new file mode 100755
index 000000000000..520708b5552d
--- /dev/null
+++ b/starmath/source/makefile.mk
@@ -0,0 +1,113 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=starmath
+TARGET=starmath
+
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+SMDLL=TRUE
+
+SRS2NAME =smres
+SRC2FILES = smres.src \
+ symbol.src \
+ toolbox.src \
+ commands.src
+
+SLO1FILES = \
+ $(SLO)$/accessibility.obj \
+ $(SLO)$/caret.obj \
+ $(SLO)$/cursor.obj \
+ $(SLO)$/edit.obj \
+ $(SLO)$/eqnolefilehdr.obj \
+ $(SLO)$/mathmlexport.obj \
+ $(SLO)$/mathmlimport.obj \
+ $(SLO)$/symbol.obj \
+ $(SLO)$/types.obj \
+ $(SLO)$/unodoc.obj \
+ $(SLO)$/action.obj \
+ $(SLO)$/cfgitem.obj \
+ $(SLO)$/config.obj \
+ $(SLO)$/dialog.obj \
+ $(SLO)$/document.obj \
+ $(SLO)$/format.obj \
+ $(SLO)$/mathtype.obj \
+ $(SLO)$/node.obj \
+ $(SLO)$/parse.obj \
+ $(SLO)$/register.obj \
+ $(SLO)$/smdll.obj \
+ $(SLO)$/toolbox.obj \
+ $(SLO)$/typemap.obj \
+ $(SLO)$/smmod.obj \
+ $(SLO)$/utility.obj \
+ $(SLO)$/rect.obj \
+ $(SLO)$/unomodel.obj \
+ $(SLO)$/view.obj \
+ $(SLO)$/visitors.obj
+
+SLO2FILES = \
+ $(SLO)$/register.obj \
+ $(SLO)$/detreg.obj
+
+SLOFILES = \
+ $(SLO)$/smdetect.obj \
+ $(SLO1FILES) \
+ $(SLO2FILES)
+
+LIB1TARGET = \
+ $(SLB)$/$(TARGET).lib
+
+LIB1OBJFILES = \
+ $(SLO1FILES)
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(INCCOM)$/dllname.hxx: makefile.mk
+.IF "$(GUI)"=="UNX"
+ $(RM) $@
+ echo \#define DLL_NAME \"$(DLLPRE)sm$(DLLPOSTFIX)$(DLLPOST)\" >$@
+.ELSE
+ echo $(EMQ)#define DLL_NAME $(EMQ)"$(DLLPRE)sm$(DLLPOSTFIX)$(DLLPOST)$(EMQ)" >$@
+.ENDIF
+
+$(SRS)$/smres.srs: $(SOLARINCDIR)$/svx$/globlmn.hrc
+
+
+$(SRS)$/$(SRS2NAME).srs : $(LOCALIZE_ME_DEST)
+
diff --git a/starmath/source/math_pch.cxx b/starmath/source/math_pch.cxx
new file mode 100644
index 000000000000..e61a9c377291
--- /dev/null
+++ b/starmath/source/math_pch.cxx
@@ -0,0 +1,433 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+#define SMDLL 1
+
+#include "starmath.hrc"
+
+#define ITEMID_FONT 1
+#define ITEMID_FONTHEIGHT 2
+#define ITEMID_LRSPACE 3
+#define ITEMID_WEIGHT 4
+
+//--------- ab hier die "generierten"
+#include <tools/string.hxx>
+#include <tools/solar.h>
+#include <tools/contnr.hxx>
+#include <tools/rtti.hxx>
+#include <tools/ref.hxx>
+#include <tools/link.hxx>
+#include <svl/brdcst.hxx>
+#include <svl/svarray.hxx>
+#include <osl/diagnose.h>
+#include <svl/hint.hxx>
+#include <svl/smplhint.hxx>
+#include <sot/sotref.hxx>
+#include <tools/globname.hxx>
+#include <sot/factory.hxx>
+#include <vcl/sv.h>
+#include <basic/sbxdef.hxx>
+#include <tools/time.hxx>
+#include <tools/gen.hxx>
+#include <tools/stream.hxx>
+#include <tools/errinf.hxx>
+#include <tools/errcode.hxx>
+#include <sot/object.hxx>
+#include <sot/sotdata.hxx>
+#include <sfx2/shell.hxx>
+#include <sal/types.h>
+#include <sal/config.h>
+#include <tools/date.hxx>
+#include <tools/ownlist.hxx>
+#include <vcl/accel.hxx>
+#include <tools/resid.hxx>
+#include <tools/rc.hxx>
+#include <i18npool/lang.h>
+#include <tools/resmgr.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/keycodes.hxx>
+#include <vcl/vclenum.hxx>
+#include <vcl/cmdevt.hxx>
+#include <vcl/font.hxx>
+#include <tools/color.hxx>
+#include <vcl/region.hxx>
+#include <vcl/mapmod.hxx>
+#include <tools/fract.hxx>
+#include <vcl/wall.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/pointr.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <vcl/wintypes.hxx>
+#include <vcl/inputctx.hxx>
+#include <vcl/event.hxx>
+#include <format.hxx>
+#include <utility.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/ctrl.hxx>
+#include <vcl/window.hxx>
+#include <sfx2/minarray.hxx>
+#include <vcl/combobox.hxx>
+#include <vcl/combobox.h>
+#include <vcl/menu.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/lstbox.h>
+#include <usr/guid.hxx>
+#include <usr/sequ.hxx>
+#include <uno/types.h>
+#include <uno/macros.h>
+#include <osl/mutex.h>
+#include <tools/shl.hxx>
+#include <sfx2/module.hxx>
+#include <sfx2/imgdef.hxx>
+#include <usr/uno.hxx>
+#include <usr/xiface.hxx>
+#include <usr/ustring.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include <osl/types.h>
+#include <osl/interlck.h>
+#include <smdll.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <chaos/cntids.hrc>
+#include <svl/cntwids.hrc>
+#include <svl/solar.hrc>
+#include <svl/lstner.hxx>
+#include <starmath.hrc>
+#include <basic/sbx.hxx>
+#include <basic/sbxform.hxx>
+#include <basic/sbxobj.hxx>
+#include <basic/sbxvar.hxx>
+#include <basic/sbxcore.hxx>
+#include <basic/sbxprop.hxx>
+#include <basic/sbxmeth.hxx>
+#include <tools/unqid.hxx>
+#include <tools/unqidx.hxx>
+#include <svl/poolitem.hxx>
+#include <svtools/args.hxx>
+#include <smmod.hxx>
+#include <osl/thread.hxx>
+#include <osl/thread.h>
+#include <vcl/apptypes.hxx>
+#include <tools/dynary.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/timer.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/sfx.hrc>
+#include <svl/memberid.hrc>
+#include <vcl/syswin.hxx>
+#include <tools/datetime.hxx>
+#include <tools/wldcrd.hxx>
+#include <parse.hxx>
+#include <tools/stack.hxx>
+#include <types.hxx>
+#include <config.hxx>
+#include <svtools/confitem.hxx>
+#include <tools/poly.hxx>
+#include <svx/xpoly.hxx>
+#include <rect.hxx>
+#include <vcl/outdev.hxx>
+#include <smart/com/sun/star/frame/XDispatchProviderInterceptor.hxx>
+#include <smart/com/sun/star/frame/XDispatch.hxx>
+#include <smart/com/sun/star/frame/XDispatchProvider.hxx>
+#include <smart/com/sun/star/frame/XStatusListener.hxx>
+#include <smart/com/sun/star/frame/FrameSearchFlag.hxx>
+#include <smart/com/sun/star/frame/XDispatchProviderInterception.hxx>
+#include <smart/com/sun/star/frame/FeatureStateEvent.hxx>
+#include <smart/com/sun/star/frame/DispatchDescriptor.hxx>
+#include <smart/com/sun/star/frame/XFrameActionListener.hxx>
+#include <smart/com/sun/star/frame/XComponentLoader.hxx>
+#include <smart/com/sun/star/frame/XFrame.hxx>
+#include <smart/com/sun/star/frame/FrameActionEvent.hxx>
+#include <smart/com/sun/star/frame/FrameAction.hxx>
+#include <smart/com/sun/star/util/XURLTransformer.hxx>
+#include <smart/com/sun/star/task/XStatusIndicatorFactory.hxx>
+#include <smart/com/sun/star/task/XStatusIndicatorSupplier.hxx>
+#include <smart/com/sun/star/task/XStatusIndicator.hxx>
+#include <smart/com/sun/star/frame/XBrowseHistoryRegistry.hxx>
+#include <smart/com/sun/star/io/BufferSizeExceededException.hxx>
+#include <smart/com/sun/star/io/NotConnectedException.hxx>
+#include <smart/com/sun/star/io/IOException.hxx>
+#include <smart/com/sun/star/io/UnexpectedEOFException.hxx>
+#include <smart/com/sun/star/io/WrongFormatException.hxx>
+#include <smart/com/sun/star/lang/ServiceNotRegisteredException.hxx>
+#include <smart/com/sun/star/lang/NullPointerException.hxx>
+#include <smart/com/sun/star/lang/ClassNotFoundException.hxx>
+#include <smart/com/sun/star/lang/NoSuchMethodException.hxx>
+#include <smart/com/sun/star/lang/SecurityException.hxx>
+#include <smart/com/sun/star/lang/NoSuchFieldException.hxx>
+#include <smart/com/sun/star/lang/DisposedException.hxx>
+#include <smart/com/sun/star/lang/ArrayIndexOutOfBoundsException.hxx>
+#include <smart/com/sun/star/lang/IllegalAccessException.hxx>
+#include <smart/com/sun/star/lang/IndexOutOfBoundsException.hxx>
+#include <smart/com/sun/star/lang/IllegalArgumentException.hxx>
+#include <smart/com/sun/star/lang/NoSupportException.hxx>
+#include <smart/com/sun/star/lang/WrappedTargetException.hxx>
+#include <smart/com/sun/star/reflection/ParamInfo.hxx>
+#include <smart/com/sun/star/reflection/XIdlArray.hxx>
+#include <smart/com/sun/star/reflection/XIdlClassProvider.hxx>
+#include <smart/com/sun/star/reflection/FieldAccessMode.hxx>
+#include <smart/com/sun/star/reflection/XIdlClass.hxx>
+#include <smart/com/sun/star/reflection/XIdlField.hxx>
+#include <smart/com/sun/star/reflection/ParamMode.hxx>
+#include <smart/com/sun/star/reflection/MethodMode.hxx>
+#include <smart/com/sun/star/reflection/XIdlMember.hxx>
+#include <smart/com/sun/star/reflection/XIdlReflection.hxx>
+#include <smart/com/sun/star/reflection/XIdlMethod.hxx>
+#include <smart/com/sun/star/reflection/InvocationTargetException.hxx>
+#include <smart/com/sun/star/beans/PropertyValues.hxx>
+#include <smart/com/sun/star/beans/XPropertySet.hxx>
+#include <smart/com/sun/star/beans/PropertyValue.hxx>
+#include <smart/com/sun/star/beans/PropertyState.hxx>
+#include <smart/com/sun/star/beans/XPropertySetInfo.hxx>
+#include <smart/com/sun/star/beans/XMultiPropertySet.hxx>
+#include <smart/com/sun/star/beans/XFastPropertySet.hxx>
+#include <smart/com/sun/star/beans/XVetoableChangeListener.hxx>
+#include <smart/com/sun/star/beans/XPropertyState.hxx>
+#include <smart/com/sun/star/beans/XPropertyStateChangeListener.hxx>
+#include <smart/com/sun/star/beans/PropertyAttribute.hxx>
+#include <smart/com/sun/star/beans/XPropertiesChangeListener.hxx>
+#include <smart/com/sun/star/beans/XPropertyChangeListener.hxx>
+#include <smart/com/sun/star/beans/XPropertyAccess.hxx>
+#include <smart/com/sun/star/beans/XPropertyContainer.hxx>
+#include <smart/com/sun/star/beans/PropertyStateChangeEvent.hxx>
+#include <smart/com/sun/star/beans/PropertyChangeEvent.hxx>
+#include <smart/com/sun/star/beans/UnknownPropertyException.hxx>
+#include <smart/com/sun/star/beans/IntrospectionException.hxx>
+#include <smart/com/sun/star/beans/PropertyExistException.hxx>
+#include <smart/com/sun/star/beans/IllegalTypeException.hxx>
+#include <smart/com/sun/star/beans/PropertyVetoException.hxx>
+#include <smart/com/sun/star/container/XEnumerationAccess.hxx>
+#include <smart/com/sun/star/container/XHierarchicalNameAccess.hxx>
+#include <smart/com/sun/star/container/XNameAccess.hxx>
+#include <smart/com/sun/star/container/XContentEnumerationAccess.hxx>
+#include <smart/com/sun/star/container/XEnumeration.hxx>
+#include <smart/com/sun/star/container/XElementAccess.hxx>
+#include <smart/com/sun/star/container/XIndexAccess.hxx>
+#include <smart/com/sun/star/lang/XEventListener.hxx>
+#include <smart/com/sun/star/lang/EventObject.hxx>
+#include <smart/com/sun/star/script/XAllListenerAdapterService.hxx>
+#include <smart/com/sun/star/script/XAllListener.hxx>
+#include <smart/com/sun/star/script/AllEventObject.hxx>
+#include <smart/com/sun/star/container/XComponentEnumeration.hxx>
+#include <smart/com/sun/star/lang/XComponent.hxx>
+#include <smart/com/sun/star/container/XComponentEnumerationAccess.hxx>
+#include <smart/com/sun/star/lang/ListenerExistException.hxx>
+#include <smart/com/sun/star/container/ElementExistException.hxx>
+#include <smart/com/sun/star/lang/InvalidListenerException.hxx>
+#include <smart/com/sun/star/container/NoSuchElementException.hxx>
+#include <smart/com/sun/star/awt/XKeyListener.hxx>
+#include <smart/com/sun/star/awt/XPaintListener.hxx>
+#include <smart/com/sun/star/awt/KeyEvent.hxx>
+#include <smart/com/sun/star/awt/KeyModifier.hxx>
+#include <smart/com/sun/star/awt/XMouseMotionListener.hxx>
+#include <smart/com/sun/star/awt/FocusEvent.hxx>
+#include <smart/com/sun/star/awt/XWindowListener.hxx>
+#include <smart/com/sun/star/awt/XActivateListener.hxx>
+#include <smart/com/sun/star/awt/MouseEvent.hxx>
+#include <smart/com/sun/star/awt/XTopWindowListener.hxx>
+#include <smart/com/sun/star/awt/PaintEvent.hxx>
+#include <smart/com/sun/star/awt/InputEvent.hxx>
+#include <smart/com/sun/star/awt/KeyGroup.hxx>
+#include <smart/com/sun/star/awt/Key.hxx>
+#include <smart/com/sun/star/awt/WindowEvent.hxx>
+#include <smart/com/sun/star/awt/XMouseListener.hxx>
+#include <smart/com/sun/star/awt/KeyFunction.hxx>
+#include <smart/com/sun/star/awt/FocusChangeReason.hxx>
+#include <smart/com/sun/star/awt/MouseButton.hxx>
+#include <smart/com/sun/star/awt/XFocusListener.hxx>
+#include <smart/com/sun/star/awt/XAdjustmentListener.hxx>
+#include <smart/com/sun/star/awt/XActionListener.hxx>
+#include <smart/com/sun/star/awt/XTextListener.hxx>
+#include <smart/com/sun/star/awt/XSpinListener.hxx>
+#include <smart/com/sun/star/awt/XItemListener.hxx>
+#include <smart/com/sun/star/awt/XVclContainerListener.hxx>
+#include <smart/com/sun/star/awt/XFileDialog.hxx>
+#include <smart/com/sun/star/awt/XTextComponent.hxx>
+#include <smart/com/sun/star/awt/XListBox.hxx>
+#include <smart/com/sun/star/awt/XProgressMonitor.hxx>
+#include <smart/com/sun/star/awt/TextAlign.hxx>
+#include <smart/com/sun/star/awt/XScrollBar.hxx>
+#include <smart/com/sun/star/awt/XVclContainerPeer.hxx>
+#include <smart/com/sun/star/awt/XTabControllerModel.hxx>
+#include <smart/com/sun/star/awt/XMessageBox.hxx>
+#include <smart/com/sun/star/awt/XTextEditField.hxx>
+#include <smart/com/sun/star/awt/Style.hxx>
+#include <smart/com/sun/star/awt/XTimeField.hxx>
+#include <smart/com/sun/star/awt/XVclWindowPeer.hxx>
+#include <smart/com/sun/star/awt/XControlModel.hxx>
+#include <smart/com/sun/star/awt/XSpinField.hxx>
+#include <smart/com/sun/star/awt/XUnoControlContainer.hxx>
+#include <smart/com/sun/star/awt/XTextLayoutConstrains.hxx>
+#include <smart/com/sun/star/awt/XNumericField.hxx>
+#include <smart/com/sun/star/awt/XButton.hxx>
+#include <smart/com/sun/star/awt/XTextArea.hxx>
+#include <smart/com/sun/star/awt/XImageButton.hxx>
+#include <smart/com/sun/star/awt/XFixedText.hxx>
+#include <smart/com/sun/star/awt/XControlContainer.hxx>
+#include <smart/com/sun/star/awt/XDialog.hxx>
+#include <smart/com/sun/star/awt/ScrollBarOrientation.hxx>
+#include <smart/com/sun/star/awt/XRadioButton.hxx>
+#include <smart/com/sun/star/awt/XCurrencyField.hxx>
+#include <smart/com/sun/star/awt/XPatternField.hxx>
+#include <smart/com/sun/star/awt/VclWindowPeerAttribute.hxx>
+#include <smart/com/sun/star/awt/XTabController.hxx>
+#include <smart/com/sun/star/awt/XVclContainer.hxx>
+#include <smart/com/sun/star/awt/XDateField.hxx>
+#include <smart/com/sun/star/awt/XComboBox.hxx>
+#include <smart/com/sun/star/awt/XControl.hxx>
+#include <smart/com/sun/star/awt/XCheckBox.hxx>
+#include <smart/com/sun/star/awt/MessageBoxCommand.hxx>
+#include <smart/com/sun/star/awt/XLayoutConstrains.hxx>
+#include <smart/com/sun/star/awt/XProgressBar.hxx>
+#include <smart/com/sun/star/awt/SimpleFontMetric.hxx>
+#include <smart/com/sun/star/awt/FontWeight.hxx>
+#include <smart/com/sun/star/awt/FontSlant.hxx>
+#include <smart/com/sun/star/awt/CharSet.hxx>
+#include <smart/com/sun/star/awt/FontDescriptor.hxx>
+#include <smart/com/sun/star/awt/FontWidth.hxx>
+#include <smart/com/sun/star/awt/XFont.hxx>
+#include <smart/com/sun/star/awt/FontType.hxx>
+#include <smart/com/sun/star/awt/FontUnderline.hxx>
+#include <smart/com/sun/star/awt/FontStrikeout.hxx>
+#include <smart/com/sun/star/awt/FontFamily.hxx>
+#include <smart/com/sun/star/awt/FontPitch.hxx>
+#include <smart/com/sun/star/awt/XTopWindow.hxx>
+#include <smart/com/sun/star/awt/XWindow.hxx>
+#include <smart/com/sun/star/awt/PosSize.hxx>
+#include <smart/com/sun/star/awt/VclContainerEvent.hxx>
+#include <smart/com/sun/star/awt/ItemEvent.hxx>
+#include <smart/com/sun/star/awt/SpinEvent.hxx>
+#include <smart/com/sun/star/awt/TextEvent.hxx>
+#include <smart/com/sun/star/awt/AdjustmentType.hxx>
+#include <smart/com/sun/star/awt/ActionEvent.hxx>
+#include <smart/com/sun/star/awt/AdjustmentEvent.hxx>
+#include <smart/com/sun/star/awt/Rectangle.hxx>
+#include <smart/com/sun/star/awt/Selection.hxx>
+#include <smart/com/sun/star/awt/Size.hxx>
+#include <smart/com/sun/star/awt/WindowDescriptor.hxx>
+#include <smart/com/sun/star/awt/InvalidateStyle.hxx>
+#include <smart/com/sun/star/awt/XToolkit.hxx>
+#include <smart/com/sun/star/awt/XWindowPeer.hxx>
+#include <smart/com/sun/star/awt/WindowClass.hxx>
+#include <smart/com/sun/star/awt/XSystemDependentWindowPeer.hxx>
+#include <smart/com/sun/star/awt/WindowAttribute.hxx>
+#include <smart/com/sun/star/awt/XPointer.hxx>
+#include <smart/com/sun/star/awt/SystemPointer.hxx>
+#include <smart/com/sun/star/awt/XView.hxx>
+#include <usr/refl.hxx>
+#include <sfx2/msg.hxx>
+#include <svl/itemset.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/objface.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <symbol.hxx>
+#include <svl/itempool.hxx>
+#include <vcl/image.hxx>
+#include <vcl/metric.hxx>
+#include <sfx2/inimgr.hxx>
+#include <node.hxx>
+#include <tools/pstm.hxx>
+#include <tools/table.hxx>
+#include <sfx2/docfac.hxx>
+#include <svl/ownlist.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/stritem.hxx>
+#include <sfx2/ipfrm.hxx>
+#include <vcl/dialog.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/svstdarr.hxx>
+#include <sfx2/bindings.hxx>
+#include <dialog.hxx>
+#include <vcl/symbol.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <vcl/button.hxx>
+#include <vcl/tabdlg.hxx>
+#include <vcl/tabpage.hxx>
+#include <vcl/tabctrl.hxx>
+#include <svx/optgenrl.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/group.hxx>
+#include <document.hxx>
+#include <vcl/spinfld.hxx>
+#include <vcl/menubtn.hxx>
+#include <svtools/ctrlbox.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/field.hxx>
+#include <svtools/ctrltool.hxx>
+#include <sfx2/interno.hxx>
+#include <sfx2/sfxdefs.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/chalign.hxx>
+#include <vcl/floatwin.hxx>
+#include <sot/storage.hxx>
+#include <rsc/rscsfx.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/btndlg.hxx>
+#include <uno/uno.h>
+#include <uno/string.h>
+#include <uno/sequence.h>
+#include <uno/any.h>
+#include <uno/exceptn.h>
+#include <uno/intrface.h>
+#include <uno/factory.h>
+#include <uno/api.h>
+#include <svx/svxids.hrc>
+#include <view.hxx>
+#include <sfx2/dockwin.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/clientsh.hxx>
+#include <svtools/scrwin.hxx>
+#include <vcl/scrbar.hxx>
+#include <sfx2/ctrlitem.hxx>
+#include <sfx2/viewfac.hxx>
+#include <edit.hxx>
+#include <editeng/editdata.hxx>
+#include <toolbox.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/dockwin.hxx>
+#include <smslots.hxx>
+#include <svl/undo.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/prntypes.hxx>
+#include <vcl/jobset.hxx>
+#include <vcl/gdimtf.hxx>
+#include <sot/exchange.hxx>
+#include <vcl/wrkwin.hxx>
+#include <action.hxx>
+#include <sfx2/filedlg.hxx>
+#include <sfx2/iodlg.hxx>
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/mathmlexport.cxx b/starmath/source/mathmlexport.cxx
new file mode 100644
index 000000000000..d23fef88c7f0
--- /dev/null
+++ b/starmath/source/mathmlexport.cxx
@@ -0,0 +1,1508 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+/*
+ Warning: The SvXMLElementExport helper class creates the beginning and
+ closing tags of xml elements in its constructor and destructor, so theres
+ hidden stuff going on, on occasion the ordering of these classes declarations
+ may be significant
+*/
+
+
+#include <com/sun/star/xml/sax/XErrorHandler.hpp>
+#include <com/sun/star/xml/sax/XEntityResolver.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XDTDHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/uno/Any.h>
+
+#include <rtl/math.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/docfile.hxx>
+#include <osl/diagnose.h>
+#include <tools/urlobj.hxx>
+#include <svtools/sfxecode.hxx>
+#include <unotools/saveopt.hxx>
+#include <svl/stritem.hxx>
+#include <svl/itemprop.hxx>
+#include <unotools/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/attrlist.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlmetai.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/genericpropertyset.hxx>
+
+#include <memory>
+
+#include "mathmlexport.hxx"
+#include <starmath.hrc>
+#include <unomodel.hxx>
+#include <document.hxx>
+#include <utility.hxx>
+#include <config.hxx>
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+#define EXPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLExportFilter")
+
+#undef WANTEXCEPT
+
+
+////////////////////////////////////////////////////////////
+
+sal_Bool SmXMLExportWrapper::Export(SfxMedium &rMedium)
+{
+ sal_Bool bRet=sal_True;
+ uno::Reference<lang::XMultiServiceFactory>
+ xServiceFactory(utl::getProcessServiceFactory());
+ OSL_ENSURE(xServiceFactory.is(),"got no service manager");
+
+ //Get model
+ uno::Reference< lang::XComponent > xModelComp(xModel, uno::UNO_QUERY );
+
+ sal_Bool bEmbedded = sal_False;
+ uno::Reference <lang::XUnoTunnel> xTunnel;
+ xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
+ SmModel *pModel = reinterpret_cast<SmModel *>
+ (xTunnel->getSomething(SmModel::getUnoTunnelId()));
+
+ SmDocShell *pDocShell = pModel ?
+ static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
+ if ( pDocShell &&
+ SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
+ bEmbedded = sal_True;
+
+ uno::Reference<task::XStatusIndicator> xStatusIndicator;
+ if (!bEmbedded)
+ {
+ if (pDocShell /*&& pDocShell->GetMedium()*/)
+ {
+ OSL_ENSURE( pDocShell->GetMedium() == &rMedium,
+ "different SfxMedium found" );
+
+ SfxItemSet* pSet = rMedium.GetItemSet();
+ if (pSet)
+ {
+ const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
+ pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
+ if (pItem)
+ pItem->GetValue() >>= xStatusIndicator;
+ }
+ }
+
+ // set progress range and start status indicator
+ if (xStatusIndicator.is())
+ {
+ sal_Int32 nProgressRange = bFlat ? 1 : 3;
+ xStatusIndicator->start(String(SmResId(STR_STATSTR_WRITING)),
+ nProgressRange);
+ }
+ }
+
+
+ // create XPropertySet with three properties for status indicator
+ comphelper::PropertyMapEntry aInfoMap[] =
+ {
+ { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
+ &::getBooleanCppuType(),
+ beans::PropertyAttribute::MAYBEVOID, 0},
+ { "BaseURI", sizeof("BaseURI")-1, 0,
+ &::getCppuType( (OUString *)0 ),
+ beans::PropertyAttribute::MAYBEVOID, 0 },
+ { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
+ &::getCppuType( (OUString *)0 ),
+ beans::PropertyAttribute::MAYBEVOID, 0 },
+ { "StreamName", sizeof("StreamName")-1, 0,
+ &::getCppuType( (OUString *)0 ),
+ beans::PropertyAttribute::MAYBEVOID, 0 },
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ uno::Reference< beans::XPropertySet > xInfoSet(
+ comphelper::GenericPropertySet_CreateInstance(
+ new comphelper::PropertySetInfo( aInfoMap ) ) );
+
+ SvtSaveOptions aSaveOpt;
+ OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
+ sal_Bool bUsePrettyPrinting( bFlat || aSaveOpt.IsPrettyPrinting() );
+ Any aAny;
+ aAny.setValue( &bUsePrettyPrinting, ::getBooleanCppuType() );
+ xInfoSet->setPropertyValue( sUsePrettyPrinting, aAny );
+
+ // Set base URI
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
+ xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL( true ) ) );
+
+ sal_Int32 nSteps=0;
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+ if (!bFlat) //Storage (Package) of Stream
+ {
+ uno::Reference < embed::XStorage > xStg = rMedium.GetOutputStorage();
+ sal_Bool bOASIS = ( SotStorage::GetVersion( xStg ) > SOFFICE_FILEFORMAT_60 );
+
+ // TODO/LATER: handle the case of embedded links gracefully
+ if ( bEmbedded ) //&& !pStg->IsRoot() )
+ {
+ OUString aName;
+ if ( rMedium.GetItemSet() )
+ {
+ const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
+ rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
+ if ( pDocHierarchItem )
+ aName = pDocHierarchItem->GetValue();
+ }
+
+ if ( aName.getLength() )
+ {
+ sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
+ xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
+ }
+ }
+
+ if ( !bEmbedded )
+ {
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ bRet = WriteThroughComponent(
+ xStg, xModelComp, "meta.xml", xServiceFactory, xInfoSet,
+ (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaExporter"
+ : "com.sun.star.comp.Math.XMLMetaExporter"),
+ sal_False);
+ }
+ if ( bRet )
+ {
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ bRet = WriteThroughComponent(
+ xStg, xModelComp, "content.xml", xServiceFactory, xInfoSet,
+ "com.sun.star.comp.Math.XMLContentExporter");
+ }
+
+ if ( bRet )
+ {
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ bRet = WriteThroughComponent(
+ xStg, xModelComp, "settings.xml", xServiceFactory, xInfoSet,
+ (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsExporter"
+ : "com.sun.star.comp.Math.XMLSettingsExporter") );
+ }
+ }
+ else
+ {
+ SvStream *pStream = rMedium.GetOutStream();
+ uno::Reference<io::XOutputStream> xOut(
+ new utl::OOutputStreamWrapper(*pStream) );
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ bRet = WriteThroughComponent(
+ xOut, xModelComp, xServiceFactory, xInfoSet,
+ "com.sun.star.comp.Math.XMLContentExporter");
+ }
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->end();
+
+ return bRet;
+}
+
+
+/// export through an XML exporter component (output stream version)
+sal_Bool SmXMLExportWrapper::WriteThroughComponent(
+ Reference<io::XOutputStream> xOutputStream,
+ Reference<XComponent> xComponent,
+ Reference<lang::XMultiServiceFactory> & rFactory,
+ Reference<beans::XPropertySet> & rPropSet,
+ const sal_Char* pComponentName )
+{
+ OSL_ENSURE(xOutputStream.is(), "I really need an output stream!");
+ OSL_ENSURE(xComponent.is(), "Need component!");
+ OSL_ENSURE(NULL != pComponentName, "Need component name!");
+
+ // get component
+ Reference< io::XActiveDataSource > xSaxWriter(
+ rFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") )),
+ UNO_QUERY );
+ OSL_ENSURE( xSaxWriter.is(), "can't instantiate XML writer" );
+ if (!xSaxWriter.is())
+ return sal_False;
+
+ // connect XML writer to output stream
+ xSaxWriter->setOutputStream( xOutputStream );
+
+ // prepare arguments (prepend doc handler to given arguments)
+ Reference<xml::sax::XDocumentHandler> xDocHandler( xSaxWriter,UNO_QUERY);
+
+ Sequence<Any> aArgs( 2 );
+ aArgs[0] <<= xDocHandler;
+ aArgs[1] <<= rPropSet;
+
+ // get filter component
+ Reference< document::XExporter > xExporter(
+ rFactory->createInstanceWithArguments(
+ OUString::createFromAscii(pComponentName), aArgs), UNO_QUERY);
+ OSL_ENSURE( xExporter.is(),
+ "can't instantiate export filter component" );
+ if ( !xExporter.is() )
+ return sal_False;
+
+
+ // connect model and filter
+ xExporter->setSourceDocument( xComponent );
+
+ // filter!
+ Reference < XFilter > xFilter( xExporter, UNO_QUERY );
+ uno::Sequence< PropertyValue > aProps(0);
+ xFilter->filter( aProps );
+
+ uno::Reference<lang::XUnoTunnel> xFilterTunnel;
+ xFilterTunnel = uno::Reference<lang::XUnoTunnel>
+ ( xFilter, uno::UNO_QUERY );
+ SmXMLExport *pFilter = reinterpret_cast< SmXMLExport * >(
+ sal::static_int_cast< sal_uIntPtr >(
+ xFilterTunnel->getSomething( SmXMLExport::getUnoTunnelId() )));
+ return pFilter ? pFilter->GetSuccess() : sal_True;
+}
+
+
+/// export through an XML exporter component (storage version)
+sal_Bool SmXMLExportWrapper::WriteThroughComponent(
+ const Reference < embed::XStorage >& xStorage,
+ Reference<XComponent> xComponent,
+ const sal_Char* pStreamName,
+ Reference<lang::XMultiServiceFactory> & rFactory,
+ Reference<beans::XPropertySet> & rPropSet,
+ const sal_Char* pComponentName,
+ sal_Bool bCompress
+ )
+{
+ OSL_ENSURE(xStorage.is(), "Need storage!");
+ OSL_ENSURE(NULL != pStreamName, "Need stream name!");
+
+ // open stream
+ Reference < io::XStream > xStream;
+ OUString sStreamName = OUString::createFromAscii(pStreamName);
+ try
+ {
+ xStream = xStorage->openStreamElement( sStreamName,
+ embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL( "Can't create output stream in package!" );
+ return sal_False;
+ }
+
+ String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
+ OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
+ uno::Any aAny;
+ aAny <<= aMime;
+
+ uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
+ xSet->setPropertyValue( aPropName, aAny );
+
+ if ( !bCompress )
+ {
+ aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Compressed") );
+ sal_Bool bFalse = sal_False;
+ aAny.setValue( &bFalse, ::getBooleanCppuType() );
+ xSet->setPropertyValue( aPropName, aAny );
+ }
+
+ // even plain stream must be encrypted in encrypted document
+ OUString aTmpPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
+ sal_Bool bTrue = sal_True;
+ aAny.setValue( &bTrue, ::getBooleanCppuType() );
+ xSet->setPropertyValue( aTmpPropName, aAny );
+
+ // set Base URL
+ if ( rPropSet.is() )
+ {
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
+ rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
+ }
+
+ // write the stuff
+ sal_Bool bRet = WriteThroughComponent( xStream->getOutputStream(), xComponent, rFactory,
+ rPropSet, pComponentName );
+
+ return bRet;
+}
+
+////////////////////////////////////////////////////////////
+
+SmXMLExport::SmXMLExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ sal_uInt16 nExportFlags)
+: SvXMLExport( xServiceFactory, MAP_INCH, XML_MATH, nExportFlags ) ,
+ pTree(0) ,
+ bSuccess(sal_False)
+{
+}
+
+sal_Int64 SAL_CALL SmXMLExport::getSomething(
+ const uno::Sequence< sal_Int8 >& rId )
+throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
+
+ return SvXMLExport::getSomething( rId );
+}
+
+const uno::Sequence< sal_Int8 > & SmXMLExport::getUnoTunnelId() throw()
+{
+ static uno::Sequence< sal_Int8 > * pSeq = 0;
+ if ( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+OUString SAL_CALL SmXMLExport_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLExporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLExport_getSupportedServiceNames()
+ throw()
+{
+ const OUString aServiceName( EXPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLExport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+ throw( uno::Exception )
+{
+ // EXPORT_OASIS is required here allthough there is no differrence between
+ // OOo and OASIS, because without the flag, a transformation to OOo would
+ // be chained in.
+ return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_ALL );
+}
+
+////////////////////////////////////////////////////////////
+
+OUString SAL_CALL SmXMLExportMetaOOO_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLMetaExporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLExportMetaOOO_getSupportedServiceNames()
+ throw()
+{
+ const OUString aServiceName( EXPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMetaOOO_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_META );
+}
+
+////////////////////////////////////////////////////////////
+
+OUString SAL_CALL SmXMLExportMeta_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaExporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLExportMeta_getSupportedServiceNames()
+throw()
+{
+ const OUString aServiceName( EXPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMeta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_META );
+}
+
+////////////////////////////////////////////////////////////
+
+OUString SAL_CALL SmXMLExportSettingsOOO_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLSettingsExporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLExportSettingsOOO_getSupportedServiceNames()
+throw()
+{
+ const OUString aServiceName( EXPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettingsOOO_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_SETTINGS );
+}
+
+////////////////////////////////////////////////////////////
+
+OUString SAL_CALL SmXMLExportSettings_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsExporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLExportSettings_getSupportedServiceNames()
+throw()
+{
+ const OUString aServiceName( EXPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_SETTINGS );
+}
+
+////////////////////////////////////////////////////////////
+
+OUString SAL_CALL SmXMLExportContent_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLContentExporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLExportContent_getSupportedServiceNames()
+ throw()
+{
+ const OUString aServiceName( EXPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLExportContent_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+throw( uno::Exception )
+{
+ // The EXPORT_OASIS flag is only required to avoid that a transformer is
+ // chanied in
+ return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_CONTENT );
+}
+
+////////////////////////////////////////////////////////////
+
+// XServiceInfo
+// override empty method from parent class
+rtl::OUString SAL_CALL SmXMLExport::getImplementationName()
+throw(uno::RuntimeException)
+{
+ OUString aTxt;
+ switch( getExportFlags() )
+ {
+ case EXPORT_META:
+ aTxt = SmXMLExportMeta_getImplementationName();
+ break;
+ case EXPORT_SETTINGS:
+ aTxt = SmXMLExportSettings_getImplementationName();
+ break;
+ case EXPORT_CONTENT:
+ aTxt = SmXMLExportContent_getImplementationName();
+ break;
+ case EXPORT_ALL:
+ default:
+ aTxt = SmXMLExport_getImplementationName();
+ break;
+ }
+ return aTxt;
+}
+
+sal_uInt32 SmXMLExport::exportDoc(enum XMLTokenEnum eClass)
+{
+ if ( (getExportFlags() & EXPORT_CONTENT) == 0 )
+ {
+ SvXMLExport::exportDoc( eClass );
+ }
+ else
+ {
+ uno::Reference <frame::XModel> xModel = GetModel();
+ uno::Reference <lang::XUnoTunnel> xTunnel;
+ xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
+ SmModel *pModel = reinterpret_cast<SmModel *>
+ (xTunnel->getSomething(SmModel::getUnoTunnelId()));
+
+ if (pModel)
+ {
+ SmDocShell *pDocShell =
+ static_cast<SmDocShell*>(pModel->GetObjectShell());
+ pTree = pDocShell->GetFormulaTree();
+ aText = pDocShell->GetText();
+ }
+
+ GetDocHandler()->startDocument();
+
+ /*Add xmlns line*/
+ SvXMLAttributeList &rList = GetAttrList();
+
+ // make use of a default namespace
+ ResetNamespaceMap(); // Math doesn't need namespaces from xmloff, since it now uses default namespaces (because that is common with current MathML usage in the web)
+ _GetNamespaceMap().Add( OUString(), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
+
+ rList.AddAttribute(GetNamespaceMap().GetAttrNameByKey(XML_NAMESPACE_MATH_IDX),
+ GetNamespaceMap().GetNameByKey( XML_NAMESPACE_MATH_IDX));
+
+ //I think we need something like ImplExportEntities();
+ _ExportContent();
+ GetDocHandler()->endDocument();
+ }
+
+ bSuccess=sal_True;
+ return 0;
+}
+
+void SmXMLExport::_ExportContent()
+{
+ SvXMLElementExport aEquation(*this, XML_NAMESPACE_MATH, XML_MATH, sal_True, sal_True);
+ SvXMLElementExport *pSemantics=0;
+
+ if (aText.Len())
+ {
+ pSemantics = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_SEMANTICS, sal_True, sal_True);
+ }
+
+ ExportNodes(pTree, 0);
+
+ if (aText.Len())
+ {
+ // Convert symbol names
+ uno::Reference <frame::XModel> xModel = GetModel();
+ uno::Reference <lang::XUnoTunnel> xTunnel;
+ xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
+ SmModel *pModel = reinterpret_cast<SmModel *>
+ (xTunnel->getSomething(SmModel::getUnoTunnelId()));
+ SmDocShell *pDocShell = pModel ?
+ static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
+ OSL_ENSURE( pDocShell, "doc shell missing" );
+ if (pDocShell)
+ {
+ SmParser &rParser = pDocShell->GetParser();
+ bool bVal = rParser.IsExportSymbolNames();
+ rParser.SetExportSymbolNames( true );
+ SmNode *pTmpTree = rParser.Parse( aText );
+ aText = rParser.GetText();
+ delete pTmpTree;
+ rParser.SetExportSymbolNames( bVal );
+ }
+
+ AddAttribute(XML_NAMESPACE_MATH, XML_ENCODING,
+ OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
+ SvXMLElementExport aAnnotation(*this, XML_NAMESPACE_MATH,
+ XML_ANNOTATION, sal_True, sal_False);
+ GetDocHandler()->characters(OUString( aText ));
+ }
+ delete pSemantics;
+}
+
+void SmXMLExport::GetViewSettings( Sequence < PropertyValue >& aProps)
+{
+ uno::Reference <frame::XModel> xModel = GetModel();
+ if ( !xModel.is() )
+ return;
+
+ uno::Reference <lang::XUnoTunnel> xTunnel;
+ xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
+ SmModel *pModel = reinterpret_cast<SmModel *>
+ (xTunnel->getSomething(SmModel::getUnoTunnelId()));
+
+ if ( !pModel )
+ return;
+
+ SmDocShell *pDocShell =
+ static_cast<SmDocShell*>(pModel->GetObjectShell());
+ if ( !pDocShell )
+ return;
+
+ aProps.realloc( 4 );
+ PropertyValue *pValue = aProps.getArray();
+ sal_Int32 nIndex = 0;
+
+ Rectangle aRect( pDocShell->GetVisArea() );
+
+ pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaTop") );
+ pValue[nIndex++].Value <<= aRect.Top();
+
+ pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaLeft") );
+ pValue[nIndex++].Value <<= aRect.Left();
+
+ pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaWidth") );
+ pValue[nIndex++].Value <<= aRect.GetWidth();
+
+ pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaHeight") );
+ pValue[nIndex++].Value <<= aRect.GetHeight();
+}
+
+void SmXMLExport::GetConfigurationSettings( Sequence < PropertyValue > & rProps)
+{
+ Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
+ if ( xProps.is() )
+ {
+ Reference< XPropertySetInfo > xPropertySetInfo = xProps->getPropertySetInfo();
+ if (xPropertySetInfo.is())
+ {
+ Sequence< Property > aProps = xPropertySetInfo->getProperties();
+ sal_Int32 nCount(aProps.getLength());
+ if (nCount > 0)
+ {
+ rProps.realloc(nCount);
+ PropertyValue* pProps = rProps.getArray();
+ if (pProps)
+ {
+ SmConfig *pConfig = SM_MOD()->GetConfig();
+ const bool bUsedSymbolsOnly = pConfig ? pConfig->IsSaveOnlyUsedSymbols() : false;
+
+ const OUString sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
+ const OUString sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
+ const OUString sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
+ const OUString sRuntimeUID ( RTL_CONSTASCII_USTRINGPARAM ( "RuntimeUID" ) );
+ for (sal_Int32 i = 0; i < nCount; i++, pProps++)
+ {
+ const OUString &rPropName = aProps[i].Name;
+ if (rPropName != sFormula &&
+ rPropName != sBasicLibraries &&
+ rPropName != sDialogLibraries &&
+ rPropName != sRuntimeUID)
+ {
+ pProps->Name = rPropName;
+
+ rtl::OUString aActualName( rPropName );
+
+ // handle 'save used symbols only'
+ if (bUsedSymbolsOnly && rPropName.equalsAscii("Symbols"))
+ aActualName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "UserDefinedSymbolsInUse" ) );
+
+ pProps->Value = xProps->getPropertyValue( aActualName );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void SmXMLExport::ExportLine(const SmNode *pNode, int nLevel)
+{
+ ExportExpression(pNode, nLevel);
+}
+
+void SmXMLExport::ExportBinaryHorizontal(const SmNode *pNode, int nLevel)
+{
+ ExportExpression(pNode, nLevel);
+}
+
+void SmXMLExport::ExportUnaryHorizontal(const SmNode *pNode, int nLevel)
+{
+ ExportExpression(pNode, nLevel);
+}
+
+void SmXMLExport::ExportExpression(const SmNode *pNode, int nLevel)
+{
+ SvXMLElementExport *pRow=0;
+ sal_uLong nSize = pNode->GetNumSubNodes();
+
+ // #i115443: nodes of type expression always need to be grouped with mrow statement
+ if (nSize > 1 || (pNode && pNode->GetType() == NEXPRESSION))
+ pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW, sal_True, sal_True);
+
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (const SmNode *pTemp = pNode->GetSubNode(i))
+ ExportNodes(pTemp, nLevel+1);
+
+ delete pRow;
+}
+
+void SmXMLExport::ExportBinaryVertical(const SmNode *pNode, int nLevel)
+{
+ OSL_ENSURE(pNode->GetNumSubNodes()==3,"Bad Fraction");
+ SvXMLElementExport aFraction(*this, XML_NAMESPACE_MATH, XML_MFRAC, sal_True, sal_True);
+ ExportNodes(pNode->GetSubNode(0), nLevel);
+ ExportNodes(pNode->GetSubNode(2), nLevel);
+}
+
+void SmXMLExport::ExportTable(const SmNode *pNode, int nLevel)
+{
+ SvXMLElementExport *pTable=0;
+
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+
+ //If the list ends in newline then the last entry has
+ //no subnodes, the newline is superfulous so we just drop
+ //the last node, inclusion would create a bad MathML
+ //table
+ if (nSize >= 1 && pNode->GetSubNode(nSize-1)->GetNumSubNodes() == 0)
+ --nSize;
+
+ // try to avoid creating a mtable element when the formula consists only
+ // of a single output line
+ if (nLevel || (nSize >1))
+ pTable = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTABLE, sal_True, sal_True);
+
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (const SmNode *pTemp = pNode->GetSubNode(i))
+ {
+ SvXMLElementExport *pRow=0;
+ SvXMLElementExport *pCell=0;
+ if (pTable)
+ {
+ pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTR, sal_True, sal_True);
+ pCell = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTD, sal_True, sal_True);
+ }
+ ExportNodes(pTemp, nLevel+1);
+ delete pCell;
+ delete pRow;
+ }
+
+ delete pTable;
+}
+
+void SmXMLExport::ExportMath(const SmNode *pNode, int /*nLevel*/)
+{
+ const SmMathSymbolNode *pTemp = static_cast<const SmMathSymbolNode *>(pNode);
+ SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO, sal_True, sal_False);
+ sal_Unicode nArse[2];
+ nArse[0] = pTemp->GetText().GetChar(0);
+ sal_Unicode cTmp = ConvertMathToMathML( nArse[0] );
+ if (cTmp != 0)
+ nArse[0] = cTmp;
+ OSL_ENSURE(nArse[0] != 0xffff,"Non existant symbol");
+ nArse[1] = 0;
+ GetDocHandler()->characters(nArse);
+}
+
+void SmXMLExport::ExportText(const SmNode *pNode, int /*nLevel*/)
+{
+ SvXMLElementExport *pText;
+ const SmTextNode *pTemp = static_cast<const SmTextNode *>(pNode);
+ switch (pNode->GetToken().eType)
+ {
+ default:
+ case TIDENT:
+ {
+ //Note that we change the fontstyle to italic for strings that
+ //are italic and longer than a single character.
+ sal_Bool bIsItalic = IsItalic( pTemp->GetFont() );
+ if ((pTemp->GetText().Len() > 1) && bIsItalic)
+ AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, XML_ITALIC);
+ else if ((pTemp->GetText().Len() == 1) && !bIsItalic)
+ AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, XML_NORMAL);
+ pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MI,sal_True,sal_False);
+ break;
+ }
+ case TNUMBER:
+ pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MN,sal_True,sal_False);
+ break;
+ case TTEXT:
+ pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTEXT,sal_True,sal_False);
+ break;
+ }
+ GetDocHandler()->characters(OUString(pTemp->GetText().GetBuffer()));
+ delete pText;
+}
+
+void SmXMLExport::ExportBlank(const SmNode * /*pNode*/, int /*nLevel*/)
+{
+ //!! exports an empty <mi> tag since for example "~_~" is allowed in
+ //!! Math (so it has no sense at all) but must not result in an empty
+ //!! <msub> tag in MathML !!
+
+ SvXMLElementExport *pText;
+
+ pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MI, sal_True, sal_False);
+
+ GetDocHandler()->characters( OUString() );
+ delete pText;
+}
+
+void SmXMLExport::ExportSubSupScript(const SmNode *pNode, int nLevel)
+{
+ const SmNode *pSub = 0;
+ const SmNode *pSup = 0;
+ const SmNode *pCSub = 0;
+ const SmNode *pCSup = 0;
+ const SmNode *pLSub = 0;
+ const SmNode *pLSup = 0;
+ SvXMLElementExport *pThing = 0, *pThing2 = 0;
+
+ //if we have prescripts at all then we must use the tensor notation
+
+ //This is one of those excellent locations where scope is vital to
+ //arrange the construction and destruction of the element helper
+ //classes correctly
+ pLSub = pNode->GetSubNode(LSUB+1);
+ pLSup = pNode->GetSubNode(LSUP+1);
+ if (pLSub || pLSup)
+ {
+ SvXMLElementExport aMultiScripts(*this, XML_NAMESPACE_MATH,
+ XML_MMULTISCRIPTS, sal_True, sal_True);
+
+
+ if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
+ && NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
+ {
+ pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_MUNDEROVER, sal_True,sal_True);
+ }
+ else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
+ {
+ pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_MUNDER, sal_True,sal_True);
+ }
+ else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
+ {
+ pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_MOVER, sal_True,sal_True);
+ }
+
+ ExportNodes(pNode->GetSubNode(0), nLevel+1); //Main Term
+
+ if (pCSub)
+ ExportNodes(pCSub, nLevel+1);
+ if (pCSup)
+ ExportNodes(pCSup, nLevel+1);
+ delete pThing2;
+
+ pSub = pNode->GetSubNode(RSUB+1);
+ pSup = pNode->GetSubNode(RSUP+1);
+ if (pSub || pSup)
+ {
+ if (pSub)
+ ExportNodes(pSub, nLevel+1);
+ else
+ {
+ SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,sal_True,sal_True);
+ }
+ if (pSup)
+ ExportNodes(pSup, nLevel+1);
+ else
+ {
+ SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,sal_True,sal_True);
+ }
+ }
+
+ //Seperator element between suffix and prefix sub/sup pairs
+ {
+ SvXMLElementExport aPrescripts(*this, XML_NAMESPACE_MATH,
+ XML_MPRESCRIPTS, sal_True,sal_True);
+ }
+
+ if (pLSub)
+ ExportNodes(pLSub, nLevel+1);
+ else
+ {
+ SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,
+ sal_True,sal_True);
+
+ }
+ if (pLSup)
+ ExportNodes(pLSup, nLevel+1);
+ else
+ {
+ SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,
+ sal_True,sal_True);
+
+ }
+ }
+ else
+ {
+ if (NULL != (pSub = pNode->GetSubNode(RSUB+1)) &&
+ NULL != (pSup = pNode->GetSubNode(RSUP+1)))
+ {
+ pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_MSUBSUP, sal_True,sal_True);
+ }
+ else if (NULL != (pSub = pNode->GetSubNode(RSUB+1)))
+ {
+ pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MSUB,
+ sal_True,sal_True);
+ }
+ else if (NULL != (pSup = pNode->GetSubNode(RSUP+1)))
+ {
+ pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MSUP,
+ sal_True,sal_True);
+ }
+
+ if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
+ && NULL != (pCSup=pNode->GetSubNode(CSUP+1)))
+ {
+ pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_MUNDEROVER, sal_True,sal_True);
+ }
+ else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
+ {
+ pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_MUNDER, sal_True,sal_True);
+ }
+ else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
+ {
+ pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_MOVER, sal_True,sal_True);
+ }
+ ExportNodes(pNode->GetSubNode(0), nLevel+1); //Main Term
+
+ if (pCSub)
+ ExportNodes(pCSub, nLevel+1);
+ if (pCSup)
+ ExportNodes(pCSup, nLevel+1);
+ delete pThing2;
+
+ if (pSub)
+ ExportNodes(pSub, nLevel+1);
+ if (pSup)
+ ExportNodes(pSup, nLevel+1);
+ delete pThing;
+ }
+}
+
+void SmXMLExport::ExportBrace(const SmNode *pNode, int nLevel)
+{
+ const SmNode *pTemp;
+ const SmNode *pLeft=pNode->GetSubNode(0);
+ const SmNode *pRight=pNode->GetSubNode(2);
+ SvXMLElementExport *pFences=0,*pRow=0;
+ if ( ((pLeft) && (pLeft->GetToken().eType != TNONE)) &&
+ ((pRight) && (pRight->GetToken().eType != TNONE)) &&
+ (pNode->GetScaleMode() == SCALE_HEIGHT))
+ {
+ sal_Unicode nArse[2];
+ nArse[1] = 0;
+ nArse[0] = static_cast<
+ const SmMathSymbolNode* >(pLeft)->GetText().GetChar(0);
+ OSL_ENSURE(nArse[0] != 0xffff,"Non existant symbol");
+ AddAttribute(XML_NAMESPACE_MATH, XML_OPEN,nArse);
+ nArse[0] = static_cast<
+ const SmMathSymbolNode* >(pRight)->GetText().GetChar(0);
+ OSL_ENSURE(nArse[0] != 0xffff,"Non existant symbol");
+ AddAttribute(XML_NAMESPACE_MATH, XML_CLOSE,nArse);
+ pFences = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MFENCED,
+ sal_True,sal_True);
+ }
+ else if (pLeft && (pLeft->GetToken().eType != TNONE))
+ {
+ pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW,
+ sal_True, sal_True);
+ if (pNode->GetScaleMode() == SCALE_HEIGHT)
+ AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
+ else
+ AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
+ ExportNodes(pLeft, nLevel+1);
+ }
+ else
+ pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW,
+ sal_True, sal_True);
+
+ if (NULL != (pTemp = pNode->GetSubNode(1)))
+ ExportNodes(pTemp, nLevel+1);
+ if (pFences)
+ delete pFences;
+ else if (pRight && (pRight->GetToken().eType != TNONE))
+ {
+ if (pNode->GetScaleMode() == SCALE_HEIGHT)
+ AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
+ else
+ AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
+ ExportNodes(pRight, nLevel+1);
+ }
+ delete pRow;
+}
+
+void SmXMLExport::ExportRoot(const SmNode *pNode, int nLevel)
+{
+ if (pNode->GetSubNode(0))
+ {
+ SvXMLElementExport aRoot(*this, XML_NAMESPACE_MATH, XML_MROOT,sal_True,
+ sal_True);
+ ExportNodes(pNode->GetSubNode(2), nLevel+1);
+ ExportNodes(pNode->GetSubNode(0), nLevel+1);
+ }
+ else
+ {
+ SvXMLElementExport aSqrt(*this, XML_NAMESPACE_MATH, XML_MSQRT,sal_True,
+ sal_True);
+ ExportNodes(pNode->GetSubNode(2), nLevel+1);
+ }
+}
+
+void SmXMLExport::ExportOperator(const SmNode *pNode, int nLevel)
+{
+ /*we need to either use content or font and size attributes
+ *here*/
+ SvXMLElementExport aRow(*this, XML_NAMESPACE_MATH, XML_MROW,
+ sal_True, sal_True);
+ ExportNodes(pNode->GetSubNode(0), nLevel+1);
+ ExportNodes(pNode->GetSubNode(1), nLevel+1);
+}
+
+void SmXMLExport::ExportAttributes(const SmNode *pNode, int nLevel)
+{
+ SvXMLElementExport *pElement=0;
+
+ if (pNode->GetToken().eType == TUNDERLINE)
+ {
+ AddAttribute(XML_NAMESPACE_MATH, XML_ACCENTUNDER,
+ XML_TRUE);
+ pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MUNDER,
+ sal_True,sal_True);
+ }
+ else if (pNode->GetToken().eType != TOVERSTRIKE)
+ {
+ AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT,
+ XML_TRUE);
+ pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MOVER,
+ sal_True,sal_True);
+ }
+
+ ExportNodes(pNode->GetSubNode(1), nLevel+1);
+ switch (pNode->GetToken().eType)
+ {
+ case TOVERLINE:
+ {
+ //proper entity support required
+ SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
+ sal_True,sal_True);
+ sal_Unicode nArse[2] = {0xAF,0x00};
+ GetDocHandler()->characters(nArse);
+ }
+ break;
+ case TUNDERLINE:
+ {
+ //proper entity support required
+ SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
+ sal_True,sal_True);
+ sal_Unicode nArse[2] = {0x0332,0x00};
+ GetDocHandler()->characters(nArse);
+ }
+ break;
+ case TOVERSTRIKE:
+ break;
+ default:
+ ExportNodes(pNode->GetSubNode(0), nLevel+1);
+ break;
+ }
+ delete pElement;
+}
+
+static bool lcl_HasEffectOnMathvariant( const SmTokenType eType )
+{
+ return eType == TBOLD || eType == TNBOLD ||
+ eType == TITALIC || eType == TNBOLD ||
+ eType == TSANS || eType == TSERIF || eType == TFIXED;
+}
+
+void SmXMLExport::ExportFont(const SmNode *pNode, int nLevel)
+{
+ SvXMLElementExport *pElement = 0;
+
+ //
+ // gather the mathvariant attribut relevant data from all
+ // successively following SmFontNodes...
+ //
+ int nBold = -1; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
+ int nItalic = -1; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
+ int nSansSerifFixed = -1;
+ SmTokenType eNodeType = TUNKNOWN;
+ while (lcl_HasEffectOnMathvariant( (eNodeType = pNode->GetToken().eType) ))
+ {
+ switch (eNodeType)
+ {
+ case TBOLD : nBold = 1; break;
+ case TNBOLD : nBold = 0; break;
+ case TITALIC : nItalic = 1; break;
+ case TNITALIC : nItalic = 0; break;
+ case TSANS : nSansSerifFixed = 0; break;
+ case TSERIF : nSansSerifFixed = 1; break;
+ case TFIXED : nSansSerifFixed = 2; break;
+ default:
+ OSL_FAIL( "unexpected case" );
+ }
+ // According to the parser every node that is to be evaluated heres
+ // has a single non-zero subnode at index 1!! Thus we only need to check
+ // that single node for follow-up nodes that have an effect on the attribute.
+ if (pNode->GetNumSubNodes() > 1 && pNode->GetSubNode(1) &&
+ lcl_HasEffectOnMathvariant( pNode->GetSubNode(1)->GetToken().eType))
+ {
+ pNode = pNode->GetSubNode(1);
+ }
+ else
+ break;
+ }
+
+ switch (pNode->GetToken().eType)
+ {
+ //wrap a phantom element around everything*/
+ case TPHANTOM:
+ pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
+ XML_MPHANTOM, sal_True,sal_True);
+ break;
+ case TBLACK:
+ AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_BLACK);
+ break;
+ case TWHITE:
+ AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_WHITE);
+ break;
+ case TRED:
+ AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_RED);
+ break;
+ case TGREEN:
+ AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_GREEN);
+ break;
+ case TBLUE:
+ AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_BLUE);
+ break;
+ case TCYAN:
+ AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_AQUA);
+ break;
+ case TMAGENTA:
+ AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_FUCHSIA);
+ break;
+ case TYELLOW:
+ AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_YELLOW);
+ break;
+ case TSIZE:
+ {
+ const SmFontNode *pFontNode = static_cast<const SmFontNode *>(pNode);
+ const Fraction &aFrac = pFontNode->GetSizeParameter();
+
+ OUStringBuffer sStrBuf;
+ switch(pFontNode->GetSizeType())
+ {
+ case FNTSIZ_MULTIPLY:
+ SvXMLUnitConverter::convertDouble(sStrBuf,
+ static_cast<double>(aFrac*Fraction(100.00)));
+ sStrBuf.append(static_cast<sal_Unicode>('%'));
+ break;
+ case FNTSIZ_DIVIDE:
+ SvXMLUnitConverter::convertDouble(sStrBuf,
+ static_cast<double>(Fraction(100.00)/aFrac));
+ sStrBuf.append(static_cast<sal_Unicode>('%'));
+ break;
+ case FNTSIZ_ABSOLUT:
+ SvXMLUnitConverter::convertDouble(sStrBuf,
+ static_cast<double>(aFrac));
+ sStrBuf.append(
+ GetXMLToken(XML_UNIT_PT));
+ break;
+ default:
+ {
+ //The problem here is that the wheels fall off because
+ //font size is stored in 100th's of a mm not pts, and
+ //rounding errors take their toll on the original
+ //value specified in points.
+
+ //Must fix StarMath to retain the original pt values
+ Fraction aTemp = Sm100th_mmToPts(pFontNode->GetFont().
+ GetSize().Height());
+
+ if (pFontNode->GetSizeType() == FNTSIZ_MINUS)
+ aTemp-=aFrac;
+ else
+ aTemp+=aFrac;
+
+ double mytest = static_cast<double>(aTemp);
+
+ mytest = ::rtl::math::round(mytest,1);
+ SvXMLUnitConverter::convertDouble(sStrBuf,mytest);
+ sStrBuf.append(GetXMLToken(XML_UNIT_PT));
+ }
+ break;
+ }
+
+ OUString sStr(sStrBuf.makeStringAndClear());
+ AddAttribute(XML_NAMESPACE_MATH, XML_MATHSIZE, sStr);
+ }
+ break;
+ case TBOLD:
+ case TITALIC:
+ case TNBOLD:
+ case TNITALIC:
+ case TFIXED:
+ case TSANS:
+ case TSERIF:
+ {
+ // nBold: -1 = yet undefined; 0 = false; 1 = true;
+ // nItalic: -1 = yet undefined; 0 = false; 1 = true;
+ // nSansSerifFixed: -1 = undefined; 0 = sans; 1 = serif; 2 = fixed;
+ const sal_Char *pText = "normal";
+ if (nSansSerifFixed == -1 || nSansSerifFixed == 1)
+ {
+ pText = "normal";
+ if (nBold == 1 && nItalic != 1)
+ pText = "bold";
+ else if (nBold != 1 && nItalic == 1)
+ pText = "italic";
+ else if (nBold == 1 && nItalic == 1)
+ pText = "bold-italic";
+ }
+ else if (nSansSerifFixed == 0)
+ {
+ pText = "sans-serif";
+ if (nBold == 1 && nItalic != 1)
+ pText = "bold-sans-serif";
+ else if (nBold != 1 && nItalic == 1)
+ pText = "sans-serif-italic";
+ else if (nBold == 1 && nItalic == 1)
+ pText = "sans-serif-bold-italic";
+ }
+ else if (nSansSerifFixed == 2)
+ pText = "monospace"; // no modifiers allowed for monospace ...
+ else
+ {
+ OSL_FAIL( "unexpected case" );
+ }
+ AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, A2OU(pText));
+ }
+ break;
+ default:
+ break;
+
+ }
+ //for now we will just always export with a style and not worry about
+ //anyone else for the moment.
+ {
+ //wrap a style around it
+ SvXMLElementExport aStyle(*this, XML_NAMESPACE_MATH, XML_MSTYLE, sal_True,sal_True);
+ ExportExpression(pNode, nLevel);
+ }
+
+ delete pElement;
+}
+
+
+void SmXMLExport::ExportVerticalBrace(const SmNode *pNode, int nLevel)
+{
+ //Place the overbrace value OVER a vertical brace and then place that
+ //expression OVER the overbrace value, If someone can find a
+ //dedicated term in MathML to handle this overbrace/underbrace concept
+ //let me know. C.
+ XMLTokenEnum which;
+
+ switch (pNode->GetToken().eType)
+ {
+ case TOVERBRACE:
+ default:
+ which = XML_MOVER;
+ break;
+ case TUNDERBRACE:
+ which = XML_MUNDER;
+ break;
+ }
+
+ OSL_ENSURE(pNode->GetNumSubNodes()==3,"Bad Vertical Brace");
+ SvXMLElementExport aOver1(*this, XML_NAMESPACE_MATH,which, sal_True, sal_True);
+ {//Scoping
+ // using accents will draw the over-/underbraces too close to the base
+ // see http://www.w3.org/TR/MathML2/chapter3.html#id.3.4.5.2
+ // also XML_ACCENT is illegal with XML_MUNDER. Thus no XML_ACCENT attribut here!
+ SvXMLElementExport aOver2(*this, XML_NAMESPACE_MATH,which, sal_True, sal_True);
+ ExportNodes(pNode->GetSubNode(0), nLevel);
+ ExportNodes(pNode->GetSubNode(1), nLevel);
+ }
+ ExportNodes(pNode->GetSubNode(2), nLevel);
+}
+
+void SmXMLExport::ExportMatrix(const SmNode *pNode, int nLevel)
+{
+ SvXMLElementExport aTable(*this, XML_NAMESPACE_MATH, XML_MTABLE, sal_True, sal_True);
+ const SmMatrixNode *pMatrix = static_cast<const SmMatrixNode *>(pNode);
+ sal_uInt16 i=0;
+ for (sal_uLong y = 0; y < pMatrix->GetNumRows(); y++)
+ {
+ SvXMLElementExport aRow(*this, XML_NAMESPACE_MATH, XML_MTR, sal_True, sal_True);
+ for (sal_uLong x = 0; x < pMatrix->GetNumCols(); x++)
+ if (const SmNode *pTemp = pNode->GetSubNode(i++))
+ {
+ SvXMLElementExport aCell(*this, XML_NAMESPACE_MATH, XML_MTD, sal_True, sal_True);
+ ExportNodes(pTemp, nLevel+1);
+ }
+ }
+}
+
+void SmXMLExport::ExportNodes(const SmNode *pNode, int nLevel)
+{
+ if (!pNode)
+ return;
+ switch(pNode->GetType())
+ {
+ case NTABLE:
+ ExportTable(pNode, nLevel);
+ break;
+ case NALIGN:
+ case NBRACEBODY:
+ case NEXPRESSION:
+ ExportExpression(pNode, nLevel);
+ break;
+ case NLINE:
+ ExportLine(pNode, nLevel);
+ break;
+ case NTEXT:
+ ExportText(pNode, nLevel);
+ break;
+ case NSPECIAL: //NSPECIAL requires some sort of Entity preservation in the XML engine.
+ case NGLYPH_SPECIAL:
+ case NMATH:
+ {
+ sal_Unicode cTmp = 0;
+ const SmTextNode *pTemp = static_cast< const SmTextNode * >(pNode);
+ if (pTemp->GetText().Len() > 0)
+ cTmp = ConvertMathToMathML( pTemp->GetText().GetChar(0) );
+ if (cTmp == 0)
+ {
+ // no conversion to MathML implemented -> export it as text
+ // thus at least it will not vanish into nothing
+ ExportText(pNode, nLevel);
+ }
+ else
+ {
+ //To fully handle generic MathML we need to implement the full
+ //operator dictionary, we will generate MathML with explicit
+ //stretchiness for now.
+ sal_Int16 nLength = GetAttrList().getLength();
+ sal_Bool bAddStretch=sal_True;
+ for ( sal_Int16 i = 0; i < nLength; i++ )
+ {
+ OUString sLocalName;
+ sal_uInt16 nPrefix = GetNamespaceMap().GetKeyByAttrName(
+ GetAttrList().getNameByIndex(i), &sLocalName );
+
+ if ( ( XML_NAMESPACE_MATH == nPrefix ) &&
+ IsXMLToken(sLocalName, XML_STRETCHY) )
+ {
+ bAddStretch = sal_False;
+ break;
+ }
+ }
+ if (bAddStretch)
+ {
+ AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
+ }
+ ExportMath(pNode, nLevel);
+ }
+ }
+ break;
+ case NPLACE:
+ ExportMath(pNode, nLevel);
+ break;
+ case NBINHOR:
+ ExportBinaryHorizontal(pNode, nLevel);
+ break;
+ case NUNHOR:
+ ExportUnaryHorizontal(pNode, nLevel);
+ break;
+ case NBRACE:
+ ExportBrace(pNode, nLevel);
+ break;
+ case NBINVER:
+ ExportBinaryVertical(pNode, nLevel);
+ break;
+ case NSUBSUP:
+ ExportSubSupScript(pNode, nLevel);
+ break;
+ case NROOT:
+ ExportRoot(pNode, nLevel);
+ break;
+ case NOPER:
+ ExportOperator(pNode, nLevel);
+ break;
+ case NATTRIBUT:
+ ExportAttributes(pNode, nLevel);
+ break;
+ case NFONT:
+ ExportFont(pNode, nLevel);
+ break;
+ case NVERTICAL_BRACE:
+ ExportVerticalBrace(pNode, nLevel);
+ break;
+ case NMATRIX:
+ ExportMatrix(pNode, nLevel);
+ break;
+ case NBLANK:
+ ExportBlank(pNode, nLevel);
+ break;
+ default:
+ OSL_FAIL( "Warning: failed to export a node?" );
+ break;
+
+ }
+}
+
+////////////////////////////////////////////////////////////
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/mathmlexport.hxx b/starmath/source/mathmlexport.hxx
new file mode 100644
index 000000000000..4ab602bad8b3
--- /dev/null
+++ b/starmath/source/mathmlexport.hxx
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _MATHMLEXPORT_HXX_
+#define _MATHMLEXPORT_HXX_
+
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/DocumentSettingsContext.hxx>
+#include <xmloff/xmltoken.hxx>
+
+#include <node.hxx>
+
+class SfxMedium;
+namespace com { namespace sun { namespace star {
+ namespace io {
+ class XInputStream;
+ class XOutputStream; }
+ namespace beans {
+ class XPropertySet; }
+} } }
+
+
+////////////////////////////////////////////////////////////
+
+class SmXMLExportWrapper
+{
+ com::sun::star::uno::Reference<com::sun::star::frame::XModel> xModel;
+ sal_Bool bFlat; //set true for export to flat .mml, set false for
+ //export to a .sxm (or whatever) package
+public:
+ SmXMLExportWrapper(com::sun::star::uno::Reference<com::sun::star::frame::XModel> &rRef)
+ : xModel(rRef), bFlat(sal_True) {}
+
+ sal_Bool Export(SfxMedium &rMedium);
+ void SetFlat(sal_Bool bIn) {bFlat = bIn;}
+
+ sal_Bool WriteThroughComponent(
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
+ xOutputStream,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
+ xComponent,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory > & rFactory,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet,
+ const sal_Char* pComponentName );
+
+ sal_Bool WriteThroughComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
+ xComponent,
+ const sal_Char* pStreamName,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::lang::XMultiServiceFactory > & rFactory,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet,
+ const sal_Char* pComponentName,
+ sal_Bool bCompress=sal_True );
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLExport : public SvXMLExport
+{
+ const SmNode * pTree;
+ String aText;
+ sal_Bool bSuccess;
+
+protected:
+ void ExportNodes(const SmNode *pNode, int nLevel);
+ void ExportTable(const SmNode *pNode, int nLevel);
+ void ExportLine(const SmNode *pNode, int nLevel);
+ void ExportExpression(const SmNode *pNode, int nLevel);
+ void ExportText(const SmNode *pNode, int nLevel);
+ void ExportMath(const SmNode *pNode, int nLevel);
+ void ExportPolygon(const SmNode *pNode, int nLevel);
+ void ExportBinaryHorizontal(const SmNode *pNode, int nLevel);
+ void ExportUnaryHorizontal(const SmNode *pNode, int nLevel);
+ void ExportBrace(const SmNode *pNode, int nLevel);
+ void ExportBinaryVertical(const SmNode *pNode, int nLevel);
+ void ExportSubSupScript(const SmNode *pNode, int nLevel);
+ void ExportRoot(const SmNode *pNode, int nLevel);
+ void ExportOperator(const SmNode *pNode, int nLevel);
+ void ExportAttributes(const SmNode *pNode, int nLevel);
+ void ExportFont(const SmNode *pNode, int nLevel);
+ void ExportVerticalBrace(const SmNode *pNode, int nLevel);
+ void ExportMatrix(const SmNode *pNode, int nLevel);
+ void ExportBlank(const SmNode *pNode, int nLevel);
+
+public:
+ SmXMLExport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ sal_uInt16 nExportFlags=EXPORT_ALL);
+ virtual ~SmXMLExport() {};
+
+ // XServiceInfo (override parent method)
+ ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
+
+ // XUnoTunnel
+ sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException);
+ static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId() throw();
+
+ void _ExportAutoStyles() {}
+ void _ExportMasterStyles() {}
+ void _ExportContent();
+ sal_uInt32 exportDoc(enum ::xmloff::token::XMLTokenEnum eClass);
+
+ virtual void GetViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps);
+ virtual void GetConfigurationSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aProps);
+
+ sal_Bool GetSuccess() {return bSuccess;}
+};
+
+////////////////////////////////////////////////////////////
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/mathmlimport.cxx b/starmath/source/mathmlimport.cxx
new file mode 100644
index 000000000000..e3308e59cc62
--- /dev/null
+++ b/starmath/source/mathmlimport.cxx
@@ -0,0 +1,3042 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+/*todo: Change characters and tcharacters to accumulate the characters together
+into one string, xml parser hands them to us line by line rather than all in
+one go*/
+
+#include <com/sun/star/xml/sax/XErrorHandler.hpp>
+#include <com/sun/star/xml/sax/XEntityResolver.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XDTDHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/uno/Any.h>
+
+#include <rtl/math.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/docfile.hxx>
+#include <osl/diagnose.h>
+#include <tools/urlobj.hxx>
+#include <svtools/sfxecode.hxx>
+#include <unotools/saveopt.hxx>
+#include <svl/stritem.hxx>
+#include <svl/itemprop.hxx>
+#include <unotools/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <xmloff/attrlist.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/xmlmetai.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/genericpropertyset.hxx>
+
+#include <memory>
+
+#include "mathmlimport.hxx"
+#include <starmath.hrc>
+#include <unomodel.hxx>
+#include <document.hxx>
+#include <utility.hxx>
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace ::xmloff::token;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+#define IMPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLImportFilter")
+
+#undef WANTEXCEPT
+
+////////////////////////////////////////////////////////////
+
+sal_uLong SmXMLImportWrapper::Import(SfxMedium &rMedium)
+{
+ sal_uLong nError = ERRCODE_SFX_DOLOADFAILED;
+
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory(
+ utl::getProcessServiceFactory());
+ OSL_ENSURE(xServiceFactory.is(), "XMLReader::Read: got no service manager");
+ if ( !xServiceFactory.is() )
+ return nError;
+
+ //Make a model component from our SmModel
+ uno::Reference< lang::XComponent > xModelComp( xModel, uno::UNO_QUERY );
+ OSL_ENSURE( xModelComp.is(), "XMLReader::Read: got no model" );
+
+ // try to get an XStatusIndicator from the Medium
+ uno::Reference<task::XStatusIndicator> xStatusIndicator;
+
+ sal_Bool bEmbedded = sal_False;
+ uno::Reference <lang::XUnoTunnel> xTunnel;
+ xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
+ SmModel *pModel = reinterpret_cast<SmModel *>
+ (xTunnel->getSomething(SmModel::getUnoTunnelId()));
+
+ SmDocShell *pDocShell = pModel ?
+ static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
+ if (pDocShell)
+ {
+ OSL_ENSURE( pDocShell->GetMedium() == &rMedium,
+ "different SfxMedium found" );
+
+ SfxItemSet* pSet = rMedium.GetItemSet();
+ if (pSet)
+ {
+ const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
+ pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
+ if (pItem)
+ pItem->GetValue() >>= xStatusIndicator;
+ }
+
+ if ( SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
+ bEmbedded = sal_True;
+ }
+
+ comphelper::PropertyMapEntry aInfoMap[] =
+ {
+ { "PrivateData", sizeof("PrivateData")-1, 0,
+ &::getCppuType( (Reference<XInterface> *)0 ),
+ beans::PropertyAttribute::MAYBEVOID, 0 },
+ { "BaseURI", sizeof("BaseURI")-1, 0,
+ &::getCppuType( (OUString *)0 ),
+ beans::PropertyAttribute::MAYBEVOID, 0 },
+ { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
+ &::getCppuType( (OUString *)0 ),
+ beans::PropertyAttribute::MAYBEVOID, 0 },
+ { "StreamName", sizeof("StreamName")-1, 0,
+ &::getCppuType( (OUString *)0 ),
+ beans::PropertyAttribute::MAYBEVOID, 0 },
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ uno::Reference< beans::XPropertySet > xInfoSet(
+ comphelper::GenericPropertySet_CreateInstance(
+ new comphelper::PropertySetInfo( aInfoMap ) ) );
+
+ // Set base URI
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
+ xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL() ) );
+
+ sal_Int32 nSteps=3;
+ if ( !(rMedium.IsStorage()))
+ nSteps = 1;
+
+ sal_Int32 nProgressRange(nSteps);
+ if (xStatusIndicator.is())
+ {
+ xStatusIndicator->start(String(SmResId(STR_STATSTR_READING)),
+ nProgressRange);
+ }
+
+ nSteps=0;
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ if ( rMedium.IsStorage())
+ {
+ // TODO/LATER: handle the case of embedded links gracefully
+ if ( bEmbedded ) // && !rMedium.GetStorage()->IsRoot() )
+ {
+ OUString aName( RTL_CONSTASCII_USTRINGPARAM( "dummyObjName" ) );
+ if ( rMedium.GetItemSet() )
+ {
+ const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
+ rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
+ if ( pDocHierarchItem )
+ aName = pDocHierarchItem->GetValue();
+ }
+
+ if ( aName.getLength() )
+ {
+ sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
+ xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
+ }
+ }
+
+ sal_Bool bOASIS = ( SotStorage::GetVersion( rMedium.GetStorage() ) > SOFFICE_FILEFORMAT_60 );
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ sal_uLong nWarn = ReadThroughComponent(
+ rMedium.GetStorage(), xModelComp, "meta.xml", "Meta.xml",
+ xServiceFactory, xInfoSet,
+ (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaImporter"
+ : "com.sun.star.comp.Math.XMLMetaImporter") );
+
+ if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
+ {
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ nWarn = ReadThroughComponent(
+ rMedium.GetStorage(), xModelComp, "settings.xml", 0,
+ xServiceFactory, xInfoSet,
+ (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsImporter"
+ : "com.sun.star.comp.Math.XMLSettingsImporter" ) );
+
+ if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
+ {
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ nError = ReadThroughComponent(
+ rMedium.GetStorage(), xModelComp, "content.xml", "Content.xml",
+ xServiceFactory, xInfoSet, "com.sun.star.comp.Math.XMLImporter" );
+ }
+ else
+ nError = ERRCODE_IO_BROKENPACKAGE;
+ }
+ else
+ nError = ERRCODE_IO_BROKENPACKAGE;
+ }
+ else
+ {
+ Reference<io::XInputStream> xInputStream =
+ new utl::OInputStreamWrapper(rMedium.GetInStream());
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->setValue(nSteps++);
+
+ nError = ReadThroughComponent( xInputStream, xModelComp,
+ xServiceFactory, xInfoSet, "com.sun.star.comp.Math.XMLImporter", false );
+ }
+
+ if (xStatusIndicator.is())
+ xStatusIndicator->end();
+ return nError;
+}
+
+
+/// read a component (file + filter version)
+sal_uLong SmXMLImportWrapper::ReadThroughComponent(
+ Reference<io::XInputStream> xInputStream,
+ Reference<XComponent> xModelComponent,
+ Reference<lang::XMultiServiceFactory> & rFactory,
+ Reference<beans::XPropertySet> & rPropSet,
+ const sal_Char* pFilterName,
+ sal_Bool bEncrypted )
+{
+ sal_uLong nError = ERRCODE_SFX_DOLOADFAILED;
+ OSL_ENSURE(xInputStream.is(), "input stream missing");
+ OSL_ENSURE(xModelComponent.is(), "document missing");
+ OSL_ENSURE(rFactory.is(), "factory missing");
+ OSL_ENSURE(NULL != pFilterName,"I need a service name for the component!");
+
+ // prepare ParserInputSrouce
+ xml::sax::InputSource aParserInput;
+ aParserInput.aInputStream = xInputStream;
+
+ // get parser
+ Reference< xml::sax::XParser > xParser(
+ rFactory->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser")) ),
+ UNO_QUERY );
+ OSL_ENSURE( xParser.is(), "Can't create parser" );
+ if ( !xParser.is() )
+ return nError;
+
+ Sequence<Any> aArgs( 1 );
+ aArgs[0] <<= rPropSet;
+
+ // get filter
+ Reference< xml::sax::XDocumentHandler > xFilter(
+ rFactory->createInstanceWithArguments(
+ OUString::createFromAscii(pFilterName), aArgs ),
+ UNO_QUERY );
+ OSL_ENSURE( xFilter.is(), "Can't instantiate filter component." );
+ if ( !xFilter.is() )
+ return nError;
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ // connect model and filter
+ Reference < XImporter > xImporter( xFilter, UNO_QUERY );
+ xImporter->setTargetDocument( xModelComponent );
+
+ // finally, parser the stream
+ try
+ {
+ xParser->parseStream( aParserInput );
+
+ uno::Reference<lang::XUnoTunnel> xFilterTunnel;
+ xFilterTunnel = uno::Reference<lang::XUnoTunnel>
+ ( xFilter, uno::UNO_QUERY );
+ SmXMLImport *pFilter = reinterpret_cast< SmXMLImport * >(
+ sal::static_int_cast< sal_uIntPtr >(
+ xFilterTunnel->getSomething( SmXMLImport::getUnoTunnelId() )));
+ if ( pFilter && pFilter->GetSuccess() )
+ nError = 0;
+ }
+ catch( xml::sax::SAXParseException& r )
+ {
+ // sax parser sends wrapped exceptions,
+ // try to find the original one
+ xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r);
+ sal_Bool bTryChild = sal_True;
+
+ while( bTryChild )
+ {
+ xml::sax::SAXException aTmp;
+ if ( aSaxEx.WrappedException >>= aTmp )
+ aSaxEx = aTmp;
+ else
+ bTryChild = sal_False;
+ }
+
+ packages::zip::ZipIOException aBrokenPackage;
+ if ( aSaxEx.WrappedException >>= aBrokenPackage )
+ return ERRCODE_IO_BROKENPACKAGE;
+
+ if ( bEncrypted )
+ nError = ERRCODE_SFX_WRONGPASSWORD;
+ }
+ catch( xml::sax::SAXException& r )
+ {
+ packages::zip::ZipIOException aBrokenPackage;
+ if ( r.WrappedException >>= aBrokenPackage )
+ return ERRCODE_IO_BROKENPACKAGE;
+
+ if ( bEncrypted )
+ nError = ERRCODE_SFX_WRONGPASSWORD;
+ }
+ catch( packages::zip::ZipIOException& )
+ {
+ nError = ERRCODE_IO_BROKENPACKAGE;
+ }
+ catch( io::IOException& )
+ {
+ }
+
+ return nError;
+}
+
+
+sal_uLong SmXMLImportWrapper::ReadThroughComponent(
+ const uno::Reference< embed::XStorage >& xStorage,
+ Reference<XComponent> xModelComponent,
+ const sal_Char* pStreamName,
+ const sal_Char* pCompatibilityStreamName,
+ Reference<lang::XMultiServiceFactory> & rFactory,
+ Reference<beans::XPropertySet> & rPropSet,
+ const sal_Char* pFilterName )
+{
+ OSL_ENSURE(xStorage.is(), "Need storage!");
+ OSL_ENSURE(NULL != pStreamName, "Please, please, give me a name!");
+
+ // open stream (and set parser input)
+ OUString sStreamName = OUString::createFromAscii(pStreamName);
+ uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
+ if ( !xAccess->hasByName(sStreamName) || !xStorage->isStreamElement(sStreamName) )
+ {
+ // stream name not found! Then try the compatibility name.
+ // do we even have an alternative name?
+ if ( pCompatibilityStreamName )
+ sStreamName = OUString::createFromAscii(pCompatibilityStreamName);
+ }
+
+ // get input stream
+ try
+ {
+ uno::Reference < io::XStream > xEventsStream = xStorage->openStreamElement( sStreamName, embed::ElementModes::READ );
+
+ // determine if stream is encrypted or not
+ uno::Reference < beans::XPropertySet > xProps( xEventsStream, uno::UNO_QUERY );
+ Any aAny = xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) );
+ sal_Bool bEncrypted = sal_False;
+ if ( aAny.getValueType() == ::getBooleanCppuType() )
+ aAny >>= bEncrypted;
+
+ // set Base URL
+ if ( rPropSet.is() )
+ {
+ OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
+ rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
+ }
+
+
+ Reference < io::XInputStream > xStream = xEventsStream->getInputStream();
+ return ReadThroughComponent( xStream, xModelComponent, rFactory, rPropSet, pFilterName, bEncrypted );
+ }
+ catch ( packages::WrongPasswordException& )
+ {
+ return ERRCODE_SFX_WRONGPASSWORD;
+ }
+ catch( packages::zip::ZipIOException& )
+ {
+ return ERRCODE_IO_BROKENPACKAGE;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ return ERRCODE_SFX_DOLOADFAILED;
+}
+
+////////////////////////////////////////////////////////////
+
+SmXMLImport::SmXMLImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ sal_uInt16 nImportFlags)
+: SvXMLImport( xServiceFactory, nImportFlags ),
+ pPresLayoutElemTokenMap(0),
+ pPresLayoutAttrTokenMap(0),
+ pFencedAttrTokenMap(0),
+ pOperatorAttrTokenMap(0),
+ pAnnotationAttrTokenMap(0),
+ pPresElemTokenMap(0),
+ pPresScriptEmptyElemTokenMap(0),
+ pPresTableElemTokenMap(0),
+ pColorTokenMap(0),
+ bSuccess(sal_False)
+{
+}
+
+const uno::Sequence< sal_Int8 > & SmXMLImport::getUnoTunnelId() throw()
+{
+ static uno::Sequence< sal_Int8 > * pSeq = 0;
+ if ( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if ( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+OUString SAL_CALL SmXMLImport_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLImporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLImport_getSupportedServiceNames()
+ throw()
+{
+ const OUString aServiceName( IMPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLImport_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+ throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new SmXMLImport(rSMgr, IMPORT_ALL);
+}
+
+////////////////////////////////////////////////////////////
+
+OUString SAL_CALL SmXMLImportMeta_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaImporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLImportMeta_getSupportedServiceNames()
+throw()
+{
+ const OUString aServiceName( IMPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLImportMeta_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new SmXMLImport( rSMgr, IMPORT_META );
+}
+
+////////////////////////////////////////////////////////////
+
+OUString SAL_CALL SmXMLImportSettings_getImplementationName() throw()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsImporter" ) );
+}
+
+uno::Sequence< OUString > SAL_CALL SmXMLImportSettings_getSupportedServiceNames()
+ throw()
+{
+ const OUString aServiceName( IMPORT_SVC_NAME );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmXMLImportSettings_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
+ throw( uno::Exception )
+{
+ return (cppu::OWeakObject*)new SmXMLImport( rSMgr, IMPORT_SETTINGS );
+}
+
+////////////////////////////////////////////////////////////
+
+// XServiceInfo
+// override empty method from parent class
+rtl::OUString SAL_CALL SmXMLImport::getImplementationName()
+ throw(uno::RuntimeException)
+{
+ OUString aTxt;
+ switch( getImportFlags() )
+ {
+ case IMPORT_META:
+ aTxt = SmXMLImportMeta_getImplementationName();
+ break;
+ case IMPORT_SETTINGS:
+ aTxt = SmXMLImportSettings_getImplementationName();
+ break;
+ case IMPORT_ALL:
+ default:
+ aTxt = SmXMLImport_getImplementationName();
+ break;
+ }
+ return aTxt;
+}
+
+
+sal_Int64 SAL_CALL SmXMLImport::getSomething(
+ const uno::Sequence< sal_Int8 >&rId )
+throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
+
+ return SvXMLImport::getSomething( rId );
+}
+
+void SmXMLImport::endDocument(void)
+ throw(xml::sax::SAXException, uno::RuntimeException)
+{
+ //Set the resulted tree into the SmDocShell where it belongs
+ SmNode *pTree;
+ if (NULL != (pTree = GetTree()))
+ {
+ uno::Reference <frame::XModel> xModel = GetModel();
+ uno::Reference <lang::XUnoTunnel> xTunnel;
+ xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
+ SmModel *pModel = reinterpret_cast<SmModel *>
+ (xTunnel->getSomething(SmModel::getUnoTunnelId()));
+
+ if (pModel)
+ {
+ SmDocShell *pDocShell =
+ static_cast<SmDocShell*>(pModel->GetObjectShell());
+ pDocShell->SetFormulaTree(pTree);
+ if (0 == aText.Len()) //If we picked up no annotation text
+ {
+ //Make up some editable text
+ aText = pDocShell->GetText();
+ pTree->CreateTextFromNode(aText);
+ aText.EraseTrailingChars();
+ if ((aText.GetChar(0) == '{') &&
+ (aText.GetChar(aText.Len()-1) == '}'))
+ {
+ aText.Erase(0,1);
+ aText.Erase(aText.Len()-1,1);
+ }
+ }
+ pDocShell->SetText( String() );
+
+ // Convert symbol names
+ SmParser &rParser = pDocShell->GetParser();
+ bool bVal = rParser.IsImportSymbolNames();
+ rParser.SetImportSymbolNames( true );
+ SmNode *pTmpTree = rParser.Parse( aText );
+ aText = rParser.GetText();
+ delete pTmpTree;
+ rParser.SetImportSymbolNames( bVal );
+
+ pDocShell->SetText( aText );
+ }
+ OSL_ENSURE(pModel,"So there *was* a uno problem after all");
+
+ bSuccess = sal_True;
+ }
+
+ SvXMLImport::endDocument();
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLImportContext: public SvXMLImportContext
+{
+public:
+ SmXMLImportContext( SmXMLImport &rImport, sal_uInt16 nPrfx,
+ const OUString& rLName)
+ : SvXMLImportContext(rImport, nPrfx, rLName) {}
+
+ const SmXMLImport& GetSmImport() const
+ {
+ return (const SmXMLImport&)GetImport();
+ }
+
+ SmXMLImport& GetSmImport()
+ {
+ return (SmXMLImport&)GetImport();
+ }
+
+ virtual void TCharacters(const OUString & /*rChars*/);
+ virtual void Characters(const OUString &rChars);
+ virtual SvXMLImportContext *CreateChildContext(sal_uInt16 /*nPrefix*/, const OUString& /*rLocalName*/, const uno::Reference< xml::sax::XAttributeList > & /*xAttrList*/);
+};
+
+void SmXMLImportContext::TCharacters(const OUString & /*rChars*/)
+{
+}
+
+void SmXMLImportContext::Characters(const OUString &rChars)
+{
+ /*
+ Whitespace occurring within the content of token elements is "trimmed"
+ from the ends (i.e. all whitespace at the beginning and end of the
+ content is removed), and "collapsed" internally (i.e. each sequence of
+ 1 or more whitespace characters is replaced with one blank character).
+ */
+ //collapsing not done yet!
+ const OUString &rChars2 = rChars.trim();
+ if (rChars2.getLength())
+ TCharacters(rChars2/*.collapse()*/);
+}
+
+SvXMLImportContext * SmXMLImportContext::CreateChildContext(sal_uInt16 /*nPrefix*/,
+ const OUString& /*rLocalName*/,
+ const uno::Reference< xml::sax::XAttributeList > & /*xAttrList*/)
+{
+ return 0;
+}
+
+////////////////////////////////////////////////////////////
+
+struct SmXMLContext_Helper
+{
+ sal_Int8 nIsBold;
+ sal_Int8 nIsItalic;
+ double nFontSize;
+ sal_Bool bFontNodeNeeded;
+ OUString sFontFamily;
+ OUString sColor;
+
+ SmXMLImportContext rContext;
+
+ SmXMLContext_Helper(SmXMLImportContext &rImport) :
+ nIsBold(-1), nIsItalic(-1), nFontSize(0.0), rContext(rImport) {}
+
+ void RetrieveAttrs(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
+ void ApplyAttrs();
+};
+
+void SmXMLContext_Helper::RetrieveAttrs(const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList )
+{
+ sal_Int8 nOldIsBold=nIsBold;
+ sal_Int8 nOldIsItalic=nIsItalic;
+ double nOldFontSize=nFontSize;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ OUString sOldFontFamily = sFontFamily;
+ for (sal_Int16 i=0;i<nAttrCount;i++)
+ {
+ OUString sAttrName = xAttrList->getNameByIndex(i);
+ OUString aLocalName;
+ sal_uInt16 nPrefix = rContext.GetSmImport().GetNamespaceMap().
+ GetKeyByAttrName(sAttrName,&aLocalName);
+ OUString sValue = xAttrList->getValueByIndex(i);
+ const SvXMLTokenMap &rAttrTokenMap =
+ rContext.GetSmImport().GetPresLayoutAttrTokenMap();
+ switch(rAttrTokenMap.Get(nPrefix,aLocalName))
+ {
+ case XML_TOK_FONTWEIGHT:
+ nIsBold = sValue.equals(GetXMLToken(XML_BOLD));
+ break;
+ case XML_TOK_FONTSTYLE:
+ nIsItalic = sValue.equals(GetXMLToken(XML_ITALIC));
+ break;
+ case XML_TOK_FONTSIZE:
+ SvXMLUnitConverter::convertDouble(nFontSize,sValue);
+ rContext.GetSmImport().GetMM100UnitConverter().
+ setXMLMeasureUnit(MAP_POINT);
+ if (-1 == sValue.indexOf(GetXMLToken(XML_UNIT_PT)))
+ {
+ if (-1 == sValue.indexOf('%'))
+ nFontSize=0.0;
+ else
+ {
+ rContext.GetSmImport().GetMM100UnitConverter().
+ setXMLMeasureUnit(MAP_RELATIVE);
+ }
+ }
+ break;
+ case XML_TOK_FONTFAMILY:
+ sFontFamily = sValue;
+ break;
+ case XML_TOK_COLOR:
+ sColor = sValue;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((nOldIsBold!=nIsBold) || (nOldIsItalic!=nIsItalic) ||
+ (nOldFontSize!=nFontSize) || (sOldFontFamily!=sFontFamily)
+ || sColor.getLength())
+ bFontNodeNeeded=sal_True;
+ else
+ bFontNodeNeeded=sal_False;
+}
+
+void SmXMLContext_Helper::ApplyAttrs()
+{
+ SmNodeStack &rNodeStack = rContext.GetSmImport().GetNodeStack();
+
+ if (bFontNodeNeeded)
+ {
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 5;
+
+ if (nIsBold != -1)
+ {
+ if (nIsBold)
+ aToken.eType = TBOLD;
+ else
+ aToken.eType = TNBOLD;
+ SmStructureNode *pFontNode = static_cast<SmStructureNode *>
+ (new SmFontNode(aToken));
+ pFontNode->SetSubNodes(0,rNodeStack.Pop());
+ rNodeStack.Push(pFontNode);
+ }
+ if (nIsItalic != -1)
+ {
+ if (nIsItalic)
+ aToken.eType = TITALIC;
+ else
+ aToken.eType = TNITALIC;
+ SmStructureNode *pFontNode = static_cast<SmStructureNode *>
+ (new SmFontNode(aToken));
+ pFontNode->SetSubNodes(0,rNodeStack.Pop());
+ rNodeStack.Push(pFontNode);
+ }
+ if (nFontSize != 0.0)
+ {
+ aToken.eType = TSIZE;
+ SmFontNode *pFontNode = new SmFontNode(aToken);
+
+ if (MAP_RELATIVE == rContext.GetSmImport().GetMM100UnitConverter().
+ getXMLMeasureUnit())
+ {
+ if (nFontSize < 100.00)
+ pFontNode->SetSizeParameter(Fraction(100.00/nFontSize),
+ FNTSIZ_DIVIDE);
+ else
+ pFontNode->SetSizeParameter(Fraction(nFontSize/100.00),
+ FNTSIZ_MULTIPLY);
+ }
+ else
+ pFontNode->SetSizeParameter(Fraction(nFontSize),FNTSIZ_ABSOLUT);
+
+ pFontNode->SetSubNodes(0,rNodeStack.Pop());
+ rNodeStack.Push(pFontNode);
+ }
+ if (sFontFamily.getLength())
+ {
+ if (sFontFamily.equalsIgnoreAsciiCase(GetXMLToken(XML_FIXED)))
+ aToken.eType = TFIXED;
+ else if (sFontFamily.equalsIgnoreAsciiCase(OUString(
+ RTL_CONSTASCII_USTRINGPARAM("sans"))))
+ aToken.eType = TSANS;
+ else if (sFontFamily.equalsIgnoreAsciiCase(OUString(
+ RTL_CONSTASCII_USTRINGPARAM("serif"))))
+ aToken.eType = TSERIF;
+ else //Just give up, we need to extend our font mechanism to be
+ //more general
+ return;
+
+ aToken.aText = sFontFamily;
+ SmFontNode *pFontNode = new SmFontNode(aToken);
+ pFontNode->SetSubNodes(0,rNodeStack.Pop());
+ rNodeStack.Push(pFontNode);
+ }
+ if (sColor.getLength())
+ {
+ //Again we can only handle a small set of colours in
+ //StarMath for now.
+ const SvXMLTokenMap& rTokenMap =
+ rContext.GetSmImport().GetColorTokenMap();
+ aToken.eType = static_cast<SmTokenType>(rTokenMap.Get(
+ XML_NAMESPACE_MATH, sColor));
+ if (aToken.eType != -1)
+ {
+ SmFontNode *pFontNode = new SmFontNode(aToken);
+ pFontNode->SetSubNodes(0,rNodeStack.Pop());
+ rNodeStack.Push(pFontNode);
+ }
+ }
+
+ }
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLDocContext_Impl : public SmXMLImportContext
+{
+public:
+ SmXMLDocContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrfx,rLName) {}
+
+ virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList);
+
+ void EndElement();
+};
+
+////////////////////////////////////////////////////////////
+
+/*avert thy gaze from the proginator*/
+class SmXMLRowContext_Impl : public SmXMLDocContext_Impl
+{
+protected:
+ sal_uLong nElementCount;
+
+public:
+ SmXMLRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLDocContext_Impl(rImport,nPrefix,rLName)
+ { nElementCount = GetSmImport().GetNodeStack().Count(); }
+
+ virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList);
+
+ SvXMLImportContext *StrictCreateChildContext(sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > &xAttrList);
+
+ void EndElement();
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLFracContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ SmXMLFracContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement();
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLSqrtContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ SmXMLSqrtContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement();
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLRootContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ SmXMLRootContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement();
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLStyleContext_Impl : public SmXMLRowContext_Impl
+{
+protected:
+ SmXMLContext_Helper aStyleHelper;
+
+public:
+ /*Right now the style tag is completely ignored*/
+ SmXMLStyleContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName) : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
+ aStyleHelper(*this) {}
+
+ void EndElement();
+ void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
+};
+
+void SmXMLStyleContext_Impl::StartElement(const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList )
+{
+ aStyleHelper.RetrieveAttrs(xAttrList);
+}
+
+
+void SmXMLStyleContext_Impl::EndElement()
+{
+ /*
+ <mstyle> accepts any number of arguments; if this number is not 1, its
+ contents are treated as a single "inferred <mrow>" containing its
+ arguments
+ */
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ if (rNodeStack.Count() - nElementCount > 1)
+ SmXMLRowContext_Impl::EndElement();
+ aStyleHelper.ApplyAttrs();
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLPaddedContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ /*Right now the style tag is completely ignored*/
+ SmXMLPaddedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement();
+};
+
+void SmXMLPaddedContext_Impl::EndElement()
+{
+ /*
+ <mpadded> accepts any number of arguments; if this number is not 1, its
+ contents are treated as a single "inferred <mrow>" containing its
+ arguments
+ */
+ if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
+ SmXMLRowContext_Impl::EndElement();
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLPhantomContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ /*Right now the style tag is completely ignored*/
+ SmXMLPhantomContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement();
+};
+
+void SmXMLPhantomContext_Impl::EndElement()
+{
+ /*
+ <mphantom> accepts any number of arguments; if this number is not 1, its
+ contents are treated as a single "inferred <mrow>" containing its
+ arguments
+ */
+ if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
+ SmXMLRowContext_Impl::EndElement();
+
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 5;
+ aToken.eType = TPHANTOM;
+
+ SmStructureNode *pPhantom = static_cast<SmStructureNode *>
+ (new SmFontNode(aToken));
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ pPhantom->SetSubNodes(0,rNodeStack.Pop());
+ rNodeStack.Push(pPhantom);
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLFencedContext_Impl : public SmXMLRowContext_Impl
+{
+protected:
+ sal_Unicode cBegin;
+ sal_Unicode cEnd;
+
+public:
+ SmXMLFencedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
+ cBegin('('), cEnd(')') {}
+
+ void StartElement(const uno::Reference< xml::sax::XAttributeList > & xAttrList );
+ void EndElement();
+};
+
+
+void SmXMLFencedContext_Impl::StartElement(const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for (sal_Int16 i=0;i<nAttrCount;i++)
+ {
+ OUString sAttrName = xAttrList->getNameByIndex(i);
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
+ GetKeyByAttrName(sAttrName,&aLocalName);
+ OUString sValue = xAttrList->getValueByIndex(i);
+ const SvXMLTokenMap &rAttrTokenMap =
+ GetSmImport().GetFencedAttrTokenMap();
+ switch(rAttrTokenMap.Get(nPrefix,aLocalName))
+ {
+ //temp, starmath cannot handle multichar brackets (I think)
+ case XML_TOK_OPEN:
+ cBegin = sValue[0];
+ break;
+ case XML_TOK_CLOSE:
+ cEnd = sValue[0];
+ break;
+ default:
+ /*Go to superclass*/
+ break;
+ }
+ }
+}
+
+
+void SmXMLFencedContext_Impl::EndElement()
+{
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.aText = ',';
+ aToken.eType = TLEFT;
+ aToken.nLevel = 5;
+
+ aToken.eType = TLPARENT;
+ aToken.cMathChar = cBegin;
+ SmStructureNode *pSNode = new SmBraceNode(aToken);
+ SmNode *pLeft = new SmMathSymbolNode(aToken);
+
+ aToken.cMathChar = cEnd;
+ aToken.eType = TRPARENT;
+ SmNode *pRight = new SmMathSymbolNode(aToken);
+
+ SmNodeArray aRelationArray;
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+
+ aToken.cMathChar = '\0';
+ aToken.aText = ',';
+ aToken.eType = TIDENT;
+
+ sal_uLong i = rNodeStack.Count() - nElementCount;
+ if (rNodeStack.Count() - nElementCount > 1)
+ i += rNodeStack.Count() - 1 - nElementCount;
+ aRelationArray.resize(i);
+ while (rNodeStack.Count() > nElementCount)
+ {
+ aRelationArray[--i] = rNodeStack.Pop();
+ if (i > 1 && rNodeStack.Count() > 1)
+ aRelationArray[--i] = new SmGlyphSpecialNode(aToken);
+ }
+
+ SmToken aDummy;
+ SmStructureNode *pBody = new SmExpressionNode(aDummy);
+ pBody->SetSubNodes(aRelationArray);
+
+
+ pSNode->SetSubNodes(pLeft,pBody,pRight);
+ pSNode->SetScaleMode(SCALE_HEIGHT);
+ GetSmImport().GetNodeStack().Push(pSNode);
+}
+
+
+////////////////////////////////////////////////////////////
+
+class SmXMLErrorContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ SmXMLErrorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement();
+};
+
+void SmXMLErrorContext_Impl::EndElement()
+{
+ /*Right now the error tag is completely ignored, what
+ can I do with it in starmath, ?, maybe we need a
+ report window ourselves, do a test for validity of
+ the xml input, use merrors, and then generate
+ the markup inside the merror with a big red colour
+ of something. For now just throw them all away.
+ */
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ while (rNodeStack.Count() > nElementCount)
+ {
+ SmNode *pNode = rNodeStack.Pop();
+ delete pNode;
+ }
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLNumberContext_Impl : public SmXMLImportContext
+{
+protected:
+ SmToken aToken;
+
+public:
+ SmXMLNumberContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName)
+ {
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 5;
+ aToken.eType = TNUMBER;
+ }
+
+ virtual void TCharacters(const OUString &rChars);
+
+ void EndElement();
+};
+
+void SmXMLNumberContext_Impl::TCharacters(const OUString &rChars)
+{
+ aToken.aText = rChars;
+}
+
+void SmXMLNumberContext_Impl::EndElement()
+{
+ GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_NUMBER));
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLAnnotationContext_Impl : public SmXMLImportContext
+{
+ sal_Bool bIsStarMath;
+
+public:
+ SmXMLAnnotationContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName), bIsStarMath(sal_False) {}
+
+ virtual void Characters(const OUString &rChars);
+
+ void StartElement(const uno::Reference<xml::sax::XAttributeList > & xAttrList );
+};
+
+void SmXMLAnnotationContext_Impl::StartElement(const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for (sal_Int16 i=0;i<nAttrCount;i++)
+ {
+ OUString sAttrName = xAttrList->getNameByIndex(i);
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
+ GetKeyByAttrName(sAttrName,&aLocalName);
+
+ OUString sValue = xAttrList->getValueByIndex(i);
+ const SvXMLTokenMap &rAttrTokenMap =
+ GetSmImport().GetAnnotationAttrTokenMap();
+ switch(rAttrTokenMap.Get(nPrefix,aLocalName))
+ {
+ case XML_TOK_ENCODING:
+ bIsStarMath= sValue.equals(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void SmXMLAnnotationContext_Impl::Characters(const OUString &rChars)
+{
+ if (bIsStarMath)
+ GetSmImport().GetText().Append(String(rChars));
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLTextContext_Impl : public SmXMLImportContext
+{
+protected:
+ SmToken aToken;
+
+public:
+ SmXMLTextContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName)
+ {
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 5;
+ aToken.eType = TTEXT;
+ }
+
+ virtual void TCharacters(const OUString &rChars);
+
+ void EndElement();
+};
+
+void SmXMLTextContext_Impl::TCharacters(const OUString &rChars)
+{
+ aToken.aText = rChars;
+}
+
+void SmXMLTextContext_Impl::EndElement()
+{
+ GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_TEXT));
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLStringContext_Impl : public SmXMLImportContext
+{
+protected:
+ SmToken aToken;
+
+public:
+ SmXMLStringContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName)
+ {
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 5;
+ aToken.eType = TTEXT;
+ }
+
+ virtual void TCharacters(const OUString &rChars);
+
+ void EndElement();
+};
+
+void SmXMLStringContext_Impl::TCharacters(const OUString &rChars)
+{
+ /*
+ The content of <ms> elements should be rendered with visible "escaping" of
+ certain characters in the content, including at least "double quote"
+ itself, and preferably whitespace other than individual blanks. The intent
+ is for the viewer to see that the expression is a string literal, and to
+ see exactly which characters form its content. For example, <ms>double
+ quote is "</ms> might be rendered as "double quote is \"".
+
+ Obviously this isn't fully done here.
+ */
+ aToken.aText.Erase();
+ aToken.aText += '\"';
+ aToken.aText += String(rChars);
+ aToken.aText += '\"';
+}
+
+void SmXMLStringContext_Impl::EndElement()
+{
+ GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_FIXED));
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLIdentifierContext_Impl : public SmXMLImportContext
+{
+protected:
+ SmXMLContext_Helper aStyleHelper;
+ SmToken aToken;
+
+public:
+ SmXMLIdentifierContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName),aStyleHelper(*this)
+ {
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 5;
+ aToken.eType = TIDENT;
+ }
+
+ void TCharacters(const OUString &rChars);
+ void StartElement(const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+ {
+ aStyleHelper.RetrieveAttrs(xAttrList);
+ };
+ void EndElement();
+};
+
+void SmXMLIdentifierContext_Impl::EndElement()
+{
+ SmTextNode *pNode = 0;
+ //we will handle identifier italic/normal here instead of with a standalone
+ //font node
+ if (((aStyleHelper.nIsItalic == -1) && (aToken.aText.Len() > 1))
+ || ((aStyleHelper.nIsItalic == 0) && (aToken.aText.Len() == 1)))
+ {
+ pNode = new SmTextNode(aToken,FNT_FUNCTION);
+ pNode->GetFont().SetItalic(ITALIC_NONE);
+ aStyleHelper.nIsItalic = -1;
+ }
+ else
+ pNode = new SmTextNode(aToken,FNT_VARIABLE);
+ if (aStyleHelper.bFontNodeNeeded && aStyleHelper.nIsItalic != -1)
+ {
+ if (aStyleHelper.nIsItalic)
+ pNode->GetFont().SetItalic(ITALIC_NORMAL);
+ else
+ pNode->GetFont().SetItalic(ITALIC_NONE);
+ }
+
+ if ((-1!=aStyleHelper.nIsBold) || (0.0!=aStyleHelper.nFontSize) ||
+ (aStyleHelper.sFontFamily.getLength()) ||
+ aStyleHelper.sColor.getLength())
+ aStyleHelper.bFontNodeNeeded=sal_True;
+ else
+ aStyleHelper.bFontNodeNeeded=sal_False;
+ if (aStyleHelper.bFontNodeNeeded)
+ aStyleHelper.ApplyAttrs();
+ GetSmImport().GetNodeStack().Push(pNode);
+}
+
+void SmXMLIdentifierContext_Impl::TCharacters(const OUString &rChars)
+{
+ aToken.aText = rChars;
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLOperatorContext_Impl : public SmXMLImportContext
+{
+ sal_Bool bIsStretchy;
+
+protected:
+ SmToken aToken;
+
+public:
+ SmXMLOperatorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName), bIsStretchy(sal_False)
+ {
+ aToken.nGroup = 0;
+ aToken.eType = TSPECIAL;
+ aToken.nLevel = 5;
+ }
+
+ void TCharacters(const OUString &rChars);
+ void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
+ void EndElement();
+};
+
+void SmXMLOperatorContext_Impl::TCharacters(const OUString &rChars)
+{
+ aToken.cMathChar = rChars[0];
+}
+
+void SmXMLOperatorContext_Impl::EndElement()
+{
+ SmMathSymbolNode *pNode = new SmMathSymbolNode(aToken);
+ //For stretchy scaling the scaling must be retrieved from this node
+ //and applied to the expression itself so as to get the expression
+ //to scale the operator to the height of the expression itself
+ if (bIsStretchy)
+ pNode->SetScaleMode(SCALE_HEIGHT);
+ GetSmImport().GetNodeStack().Push(pNode);
+}
+
+
+
+void SmXMLOperatorContext_Impl::StartElement(const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList )
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for (sal_Int16 i=0;i<nAttrCount;i++)
+ {
+ OUString sAttrName = xAttrList->getNameByIndex(i);
+ OUString aLocalName;
+ sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
+ GetKeyByAttrName(sAttrName,&aLocalName);
+
+ OUString sValue = xAttrList->getValueByIndex(i);
+ const SvXMLTokenMap &rAttrTokenMap =
+ GetSmImport().GetOperatorAttrTokenMap();
+ switch(rAttrTokenMap.Get(nPrefix,aLocalName))
+ {
+ case XML_TOK_STRETCHY:
+ bIsStretchy = sValue.equals(
+ GetXMLToken(XML_TRUE));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+
+class SmXMLSpaceContext_Impl : public SmXMLImportContext
+{
+public:
+ SmXMLSpaceContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName) {}
+
+ void StartElement(const uno::Reference< xml::sax::XAttributeList >& xAttrList );
+};
+
+void SmXMLSpaceContext_Impl::StartElement(
+ const uno::Reference<xml::sax::XAttributeList > & /*xAttrList*/ )
+{
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.eType = TBLANK;
+ aToken.nLevel = 5;
+ SmBlankNode *pBlank = new SmBlankNode(aToken);
+ pBlank->IncreaseBy(aToken);
+ GetSmImport().GetNodeStack().Push(pBlank);
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLSubContext_Impl : public SmXMLRowContext_Impl
+{
+protected:
+ void GenericEndElement(SmTokenType eType,SmSubSup aSubSup);
+
+public:
+ SmXMLSubContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement()
+ {
+ GenericEndElement(TRSUB,RSUB);
+ }
+};
+
+
+void SmXMLSubContext_Impl::GenericEndElement(SmTokenType eType, SmSubSup eSubSup)
+{
+ /*The <msub> element requires exactly 2 arguments.*/
+ const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 2;
+ OSL_ENSURE( bNodeCheck, "Sub has not two arguments" );
+ if (!bNodeCheck)
+ return;
+
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = eType;
+ SmSubSupNode *pNode = new SmSubSupNode(aToken);
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+
+ // initialize subnodes array
+ SmNodeArray aSubNodes;
+ aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
+ for (sal_uLong i = 1; i < aSubNodes.size(); i++)
+ aSubNodes[i] = NULL;
+
+ aSubNodes[eSubSup+1] = rNodeStack.Pop();
+ aSubNodes[0] = rNodeStack.Pop();
+ pNode->SetSubNodes(aSubNodes);
+ rNodeStack.Push(pNode);
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLSupContext_Impl : public SmXMLSubContext_Impl
+{
+public:
+ SmXMLSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLSubContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement()
+ {
+ GenericEndElement(TRSUP,RSUP);
+ }
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLSubSupContext_Impl : public SmXMLRowContext_Impl
+{
+protected:
+ void GenericEndElement(SmTokenType eType, SmSubSup aSub,SmSubSup aSup);
+
+public:
+ SmXMLSubSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement()
+ {
+ GenericEndElement(TRSUB,RSUB,RSUP);
+ }
+};
+
+void SmXMLSubSupContext_Impl::GenericEndElement(SmTokenType eType,
+ SmSubSup aSub,SmSubSup aSup)
+{
+ /*The <msub> element requires exactly 3 arguments.*/
+ const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 3;
+ OSL_ENSURE( bNodeCheck, "SubSup has not three arguments" );
+ if (!bNodeCheck)
+ return;
+
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = eType;
+ SmSubSupNode *pNode = new SmSubSupNode(aToken);
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+
+ // initialize subnodes array
+ SmNodeArray aSubNodes;
+ aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
+ for (sal_uLong i = 1; i < aSubNodes.size(); i++)
+ aSubNodes[i] = NULL;
+
+ aSubNodes[aSup+1] = rNodeStack.Pop();
+ aSubNodes[aSub+1] = rNodeStack.Pop();
+ aSubNodes[0] = rNodeStack.Pop();
+ pNode->SetSubNodes(aSubNodes);
+ rNodeStack.Push(pNode);
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLUnderContext_Impl : public SmXMLSubContext_Impl
+{
+protected:
+ sal_Int16 nAttrCount;
+
+public:
+ SmXMLUnderContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLSubContext_Impl(rImport,nPrefix,rLName) {}
+
+ void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
+ void EndElement();
+ void HandleAccent();
+};
+
+void SmXMLUnderContext_Impl::StartElement(const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList )
+{
+ nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+}
+
+void SmXMLUnderContext_Impl::HandleAccent()
+{
+ const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 2;
+ OSL_ENSURE( bNodeCheck, "Sub has not two arguments" );
+ if (!bNodeCheck)
+ return;
+
+ /*Just one special case for the underline thing*/
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ SmNode *pTest = rNodeStack.Pop();
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = TUNDERLINE;
+
+
+ SmNodeArray aSubNodes;
+ aSubNodes.resize(2);
+
+ SmStructureNode *pNode = new SmAttributNode(aToken);
+ if ((pTest->GetToken().cMathChar & 0x0FFF) == 0x0332)
+ {
+ aSubNodes[0] = new SmRectangleNode(aToken);
+ delete pTest;
+ }
+ else
+ aSubNodes[0] = pTest;
+
+ aSubNodes[1] = rNodeStack.Pop();
+ pNode->SetSubNodes(aSubNodes);
+ pNode->SetScaleMode(SCALE_WIDTH);
+ rNodeStack.Push(pNode);
+}
+
+
+void SmXMLUnderContext_Impl::EndElement()
+{
+ if (!nAttrCount)
+ GenericEndElement(TCSUB,CSUB);
+ else
+ HandleAccent();
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLOverContext_Impl : public SmXMLSubContext_Impl
+{
+protected:
+ sal_Int16 nAttrCount;
+
+public:
+ SmXMLOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLSubContext_Impl(rImport,nPrefix,rLName), nAttrCount(0) {}
+
+ void EndElement();
+ void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
+ void HandleAccent();
+};
+
+
+void SmXMLOverContext_Impl::StartElement(const uno::Reference<
+ xml::sax::XAttributeList > & xAttrList )
+{
+ nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+}
+
+
+void SmXMLOverContext_Impl::EndElement()
+{
+ if (!nAttrCount)
+ GenericEndElement(TCSUP,CSUP);
+ else
+ HandleAccent();
+}
+
+
+void SmXMLOverContext_Impl::HandleAccent()
+{
+ const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 2;
+ OSL_ENSURE (bNodeCheck, "Sub has not two arguments");
+ if (!bNodeCheck)
+ return;
+
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = TACUTE;
+
+ SmAttributNode *pNode = new SmAttributNode(aToken);
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+
+ SmNodeArray aSubNodes;
+ aSubNodes.resize(2);
+ aSubNodes[0] = rNodeStack.Pop();
+ aSubNodes[1] = rNodeStack.Pop();
+ pNode->SetSubNodes(aSubNodes);
+ pNode->SetScaleMode(SCALE_WIDTH);
+ rNodeStack.Push(pNode);
+
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLUnderOverContext_Impl : public SmXMLSubSupContext_Impl
+{
+public:
+ SmXMLUnderOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLSubSupContext_Impl(rImport,nPrefix,rLName) {}
+
+ void EndElement()
+ {
+ GenericEndElement(TCSUB,CSUB,CSUP);
+ }
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLMultiScriptsContext_Impl : public SmXMLSubSupContext_Impl
+{
+ bool bHasPrescripts;
+
+public:
+ SmXMLMultiScriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName) :
+ SmXMLSubSupContext_Impl(rImport,nPrefix,rLName),
+ bHasPrescripts(false) {}
+
+ void EndElement();
+ void MiddleElement();
+ SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > &xAttrList);
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLNoneContext_Impl : public SmXMLImportContext
+{
+public:
+ SmXMLNoneContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName) {}
+
+ void EndElement();
+};
+
+
+void SmXMLNoneContext_Impl::EndElement(void)
+{
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.aText.Erase();
+ aToken.nLevel = 5;
+ aToken.eType = TIDENT;
+ GetSmImport().GetNodeStack().Push(
+ new SmTextNode(aToken,FNT_VARIABLE));
+}
+
+////////////////////////////////////////////////////////////
+
+class SmXMLPrescriptsContext_Impl : public SmXMLImportContext
+{
+public:
+ SmXMLPrescriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName)
+ : SmXMLImportContext(rImport,nPrefix,rLName) {}
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLTableRowContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ SmXMLTableRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName) :
+ SmXMLRowContext_Impl(rImport,nPrefix,rLName)
+ {}
+
+ SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > &xAttrList);
+};
+
+
+////////////////////////////////////////////////////////////
+
+class SmXMLTableContext_Impl : public SmXMLTableRowContext_Impl
+{
+public:
+ SmXMLTableContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName) :
+ SmXMLTableRowContext_Impl(rImport,nPrefix,rLName)
+ {}
+
+ void EndElement();
+ SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > &xAttrList);
+};
+
+
+////////////////////////////////////////////////////////////
+
+class SmXMLTableCellContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ SmXMLTableCellContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName) :
+ SmXMLRowContext_Impl(rImport,nPrefix,rLName)
+ {}
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLAlignGroupContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ SmXMLAlignGroupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName) :
+ SmXMLRowContext_Impl(rImport,nPrefix,rLName)
+ {}
+
+ /*Don't do anything with alignment for now*/
+ void EndElement()
+ {
+ }
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLActionContext_Impl : public SmXMLRowContext_Impl
+{
+public:
+ SmXMLActionContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
+ const OUString& rLName) :
+ SmXMLRowContext_Impl(rImport,nPrefix,rLName)
+ {}
+
+ void EndElement();
+};
+
+////////////////////////////////////////////////////////////
+
+// NB: virtually inherit so we can multiply inherit properly
+// in SmXMLFlatDocContext_Impl
+class SmXMLOfficeContext_Impl : public virtual SvXMLImportContext
+{
+public:
+ SmXMLOfficeContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
+ const OUString& rLName)
+ : SvXMLImportContext(rImport,nPrfx,rLName) {}
+
+ virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList);
+};
+
+SvXMLImportContext *SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference< xml::sax::XAttributeList > &xAttrList)
+{
+ SvXMLImportContext *pContext = 0;
+ if ( XML_NAMESPACE_OFFICE == nPrefix &&
+ rLocalName == GetXMLToken(XML_META) )
+ {
+ DBG_WARNING("XML_TOK_DOC_META: should not have come here, maybe document is invalid?");
+ }
+ else if ( XML_NAMESPACE_OFFICE == nPrefix &&
+ rLocalName == GetXMLToken(XML_SETTINGS) )
+ {
+ pContext = new XMLDocumentSettingsContext( GetImport(),
+ XML_NAMESPACE_OFFICE, rLocalName,
+ xAttrList );
+ }
+ else
+ pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
+
+ return pContext;
+}
+
+////////////////////////////////////////////////////////////
+
+// context for flat file xml format
+class SmXMLFlatDocContext_Impl
+ : public SmXMLOfficeContext_Impl, public SvXMLMetaDocumentContext
+{
+public:
+ SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport,
+ sal_uInt16 i_nPrefix, const OUString & i_rLName,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps,
+ const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder);
+
+ virtual ~SmXMLFlatDocContext_Impl();
+
+ virtual SvXMLImportContext *CreateChildContext(sal_uInt16 i_nPrefix, const OUString& i_rLocalName, const uno::Reference<xml::sax::XAttributeList>& i_xAttrList);
+};
+
+SmXMLFlatDocContext_Impl::SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport,
+ sal_uInt16 i_nPrefix, const OUString & i_rLName,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps,
+ const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder) :
+ SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
+ SmXMLOfficeContext_Impl(i_rImport, i_nPrefix, i_rLName),
+ SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
+ i_xDocProps, i_xDocBuilder)
+{
+}
+
+SmXMLFlatDocContext_Impl::~SmXMLFlatDocContext_Impl()
+{
+}
+
+SvXMLImportContext *SmXMLFlatDocContext_Impl::CreateChildContext(
+ sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
+{
+ // behave like meta base class iff we encounter office:meta
+ if ( XML_NAMESPACE_OFFICE == i_nPrefix &&
+ i_rLocalName == GetXMLToken(XML_META) )
+ {
+ return SvXMLMetaDocumentContext::CreateChildContext(
+ i_nPrefix, i_rLocalName, i_xAttrList );
+ }
+ else
+ {
+ return SmXMLOfficeContext_Impl::CreateChildContext(
+ i_nPrefix, i_rLocalName, i_xAttrList );
+ }
+}
+
+////////////////////////////////////////////////////////////
+
+static SvXMLTokenMapEntry aPresLayoutElemTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_SEMANTICS, XML_TOK_SEMANTICS },
+ { XML_NAMESPACE_MATH, XML_MATH, XML_TOK_MATH },
+ { XML_NAMESPACE_MATH, XML_MSTYLE, XML_TOK_MSTYLE },
+ { XML_NAMESPACE_MATH, XML_MERROR, XML_TOK_MERROR },
+ { XML_NAMESPACE_MATH, XML_MPHANTOM, XML_TOK_MPHANTOM },
+ { XML_NAMESPACE_MATH, XML_MROW, XML_TOK_MROW },
+ { XML_NAMESPACE_MATH, XML_MFRAC, XML_TOK_MFRAC },
+ { XML_NAMESPACE_MATH, XML_MSQRT, XML_TOK_MSQRT },
+ { XML_NAMESPACE_MATH, XML_MROOT, XML_TOK_MROOT },
+ { XML_NAMESPACE_MATH, XML_MSUB, XML_TOK_MSUB },
+ { XML_NAMESPACE_MATH, XML_MSUP, XML_TOK_MSUP },
+ { XML_NAMESPACE_MATH, XML_MSUBSUP, XML_TOK_MSUBSUP },
+ { XML_NAMESPACE_MATH, XML_MUNDER, XML_TOK_MUNDER },
+ { XML_NAMESPACE_MATH, XML_MOVER, XML_TOK_MOVER },
+ { XML_NAMESPACE_MATH, XML_MUNDEROVER, XML_TOK_MUNDEROVER },
+ { XML_NAMESPACE_MATH, XML_MMULTISCRIPTS, XML_TOK_MMULTISCRIPTS },
+ { XML_NAMESPACE_MATH, XML_MTABLE, XML_TOK_MTABLE },
+ { XML_NAMESPACE_MATH, XML_MACTION, XML_TOK_MACTION },
+ { XML_NAMESPACE_MATH, XML_MFENCED, XML_TOK_MFENCED },
+ { XML_NAMESPACE_MATH, XML_MPADDED, XML_TOK_MPADDED },
+ XML_TOKEN_MAP_END
+};
+
+static SvXMLTokenMapEntry aPresLayoutAttrTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_FONTWEIGHT, XML_TOK_FONTWEIGHT },
+ { XML_NAMESPACE_MATH, XML_FONTSTYLE, XML_TOK_FONTSTYLE },
+ { XML_NAMESPACE_MATH, XML_FONTSIZE, XML_TOK_FONTSIZE },
+ { XML_NAMESPACE_MATH, XML_FONTFAMILY, XML_TOK_FONTFAMILY },
+ { XML_NAMESPACE_MATH, XML_COLOR, XML_TOK_COLOR },
+ XML_TOKEN_MAP_END
+};
+
+static SvXMLTokenMapEntry aFencedAttrTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_OPEN, XML_TOK_OPEN },
+ { XML_NAMESPACE_MATH, XML_CLOSE, XML_TOK_CLOSE },
+ XML_TOKEN_MAP_END
+};
+
+static SvXMLTokenMapEntry aOperatorAttrTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_STRETCHY, XML_TOK_STRETCHY },
+ XML_TOKEN_MAP_END
+};
+
+static SvXMLTokenMapEntry aAnnotationAttrTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_ENCODING, XML_TOK_ENCODING },
+ XML_TOKEN_MAP_END
+};
+
+
+static SvXMLTokenMapEntry aPresElemTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_ANNOTATION, XML_TOK_ANNOTATION },
+ { XML_NAMESPACE_MATH, XML_MI, XML_TOK_MI },
+ { XML_NAMESPACE_MATH, XML_MN, XML_TOK_MN },
+ { XML_NAMESPACE_MATH, XML_MO, XML_TOK_MO },
+ { XML_NAMESPACE_MATH, XML_MTEXT, XML_TOK_MTEXT },
+ { XML_NAMESPACE_MATH, XML_MSPACE,XML_TOK_MSPACE },
+ { XML_NAMESPACE_MATH, XML_MS, XML_TOK_MS },
+ { XML_NAMESPACE_MATH, XML_MALIGNGROUP, XML_TOK_MALIGNGROUP },
+ XML_TOKEN_MAP_END
+};
+
+static SvXMLTokenMapEntry aPresScriptEmptyElemTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_MPRESCRIPTS, XML_TOK_MPRESCRIPTS },
+ { XML_NAMESPACE_MATH, XML_NONE, XML_TOK_NONE },
+ XML_TOKEN_MAP_END
+};
+
+static SvXMLTokenMapEntry aPresTableElemTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_MTR, XML_TOK_MTR },
+ { XML_NAMESPACE_MATH, XML_MTD, XML_TOK_MTD },
+ XML_TOKEN_MAP_END
+};
+
+static SvXMLTokenMapEntry aColorTokenMap[] =
+{
+ { XML_NAMESPACE_MATH, XML_BLACK, TBLACK},
+ { XML_NAMESPACE_MATH, XML_WHITE, TWHITE},
+ { XML_NAMESPACE_MATH, XML_RED, TRED},
+ { XML_NAMESPACE_MATH, XML_GREEN, TGREEN},
+ { XML_NAMESPACE_MATH, XML_BLUE, TBLUE},
+ { XML_NAMESPACE_MATH, XML_AQUA, TCYAN},
+ { XML_NAMESPACE_MATH, XML_FUCHSIA, TMAGENTA},
+ { XML_NAMESPACE_MATH, XML_YELLOW, TYELLOW},
+ XML_TOKEN_MAP_END
+};
+
+
+////////////////////////////////////////////////////////////
+
+const SvXMLTokenMap& SmXMLImport::GetPresLayoutElemTokenMap()
+{
+ if (!pPresLayoutElemTokenMap)
+ pPresLayoutElemTokenMap = new SvXMLTokenMap(aPresLayoutElemTokenMap);
+ return *pPresLayoutElemTokenMap;
+}
+
+const SvXMLTokenMap& SmXMLImport::GetPresLayoutAttrTokenMap()
+{
+ if (!pPresLayoutAttrTokenMap)
+ pPresLayoutAttrTokenMap = new SvXMLTokenMap(aPresLayoutAttrTokenMap);
+ return *pPresLayoutAttrTokenMap;
+}
+
+
+const SvXMLTokenMap& SmXMLImport::GetFencedAttrTokenMap()
+{
+ if (!pFencedAttrTokenMap)
+ pFencedAttrTokenMap = new SvXMLTokenMap(aFencedAttrTokenMap);
+ return *pFencedAttrTokenMap;
+}
+
+const SvXMLTokenMap& SmXMLImport::GetOperatorAttrTokenMap()
+{
+ if (!pOperatorAttrTokenMap)
+ pOperatorAttrTokenMap = new SvXMLTokenMap(aOperatorAttrTokenMap);
+ return *pOperatorAttrTokenMap;
+}
+
+const SvXMLTokenMap& SmXMLImport::GetAnnotationAttrTokenMap()
+{
+ if (!pAnnotationAttrTokenMap)
+ pAnnotationAttrTokenMap = new SvXMLTokenMap(aAnnotationAttrTokenMap);
+ return *pAnnotationAttrTokenMap;
+}
+
+const SvXMLTokenMap& SmXMLImport::GetPresElemTokenMap()
+{
+ if (!pPresElemTokenMap)
+ pPresElemTokenMap = new SvXMLTokenMap(aPresElemTokenMap);
+ return *pPresElemTokenMap;
+}
+
+const SvXMLTokenMap& SmXMLImport::GetPresScriptEmptyElemTokenMap()
+{
+ if (!pPresScriptEmptyElemTokenMap)
+ pPresScriptEmptyElemTokenMap = new
+ SvXMLTokenMap(aPresScriptEmptyElemTokenMap);
+ return *pPresScriptEmptyElemTokenMap;
+}
+
+const SvXMLTokenMap& SmXMLImport::GetPresTableElemTokenMap()
+{
+ if (!pPresTableElemTokenMap)
+ pPresTableElemTokenMap = new SvXMLTokenMap(aPresTableElemTokenMap);
+ return *pPresTableElemTokenMap;
+}
+
+const SvXMLTokenMap& SmXMLImport::GetColorTokenMap()
+{
+ if (!pColorTokenMap)
+ pColorTokenMap = new SvXMLTokenMap(aColorTokenMap);
+ return *pColorTokenMap;
+}
+
+////////////////////////////////////////////////////////////
+
+SvXMLImportContext *SmXMLDocContext_Impl::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ SvXMLImportContext* pContext = 0L;
+
+ const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresLayoutElemTokenMap();
+
+ switch(rTokenMap.Get(nPrefix, rLocalName))
+ {
+ //Consider semantics a dummy except for any starmath annotations
+ case XML_TOK_SEMANTICS:
+ pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ /*General Layout Schemata*/
+ case XML_TOK_MROW:
+ pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MFRAC:
+ pContext = GetSmImport().CreateFracContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MSQRT:
+ pContext = GetSmImport().CreateSqrtContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MROOT:
+ pContext = GetSmImport().CreateRootContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MSTYLE:
+ pContext = GetSmImport().CreateStyleContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MERROR:
+ pContext = GetSmImport().CreateErrorContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MPADDED:
+ pContext = GetSmImport().CreatePaddedContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MPHANTOM:
+ pContext = GetSmImport().CreatePhantomContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MFENCED:
+ pContext = GetSmImport().CreateFencedContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ /*Script and Limit Schemata*/
+ case XML_TOK_MSUB:
+ pContext = GetSmImport().CreateSubContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MSUP:
+ pContext = GetSmImport().CreateSupContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MSUBSUP:
+ pContext = GetSmImport().CreateSubSupContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MUNDER:
+ pContext = GetSmImport().CreateUnderContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MOVER:
+ pContext = GetSmImport().CreateOverContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MUNDEROVER:
+ pContext = GetSmImport().CreateUnderOverContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MMULTISCRIPTS:
+ pContext = GetSmImport().CreateMultiScriptsContext(nPrefix,
+ rLocalName, xAttrList);
+ break;
+ case XML_TOK_MTABLE:
+ pContext = GetSmImport().CreateTableContext(nPrefix,
+ rLocalName, xAttrList);
+ break;
+ case XML_TOK_MACTION:
+ pContext = GetSmImport().CreateActionContext(nPrefix,
+ rLocalName, xAttrList);
+ break;
+ default:
+ /*Basically theres an implicit mrow around certain bare
+ *elements, use a RowContext to see if this is one of
+ *those ones*/
+ SmXMLRowContext_Impl aTempContext(GetSmImport(),nPrefix,
+ GetXMLToken(XML_MROW));
+
+ pContext = aTempContext.StrictCreateChildContext(nPrefix,
+ rLocalName, xAttrList);
+ break;
+ }
+ return pContext;
+}
+
+void SmXMLDocContext_Impl::EndElement()
+{
+ SmNodeArray ContextArray;
+ ContextArray.resize(1);
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+
+ for (sal_uLong i=0;i< 1;i++)
+ ContextArray[i] = rNodeStack.Pop();
+
+ SmToken aDummy;
+ SmStructureNode *pSNode = new SmLineNode(aDummy);
+ pSNode->SetSubNodes(ContextArray);
+ rNodeStack.Push(pSNode);
+
+ SmNodeArray LineArray;
+ sal_uLong n = rNodeStack.Count();
+ LineArray.resize(n);
+ for (sal_uLong j = 0; j < n; j++)
+ LineArray[n - (j + 1)] = rNodeStack.Pop();
+ SmStructureNode *pSNode2 = new SmTableNode(aDummy);
+ pSNode2->SetSubNodes(LineArray);
+ rNodeStack.Push(pSNode2);
+}
+
+void SmXMLFracContext_Impl::EndElement()
+{
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ const bool bNodeCheck = rNodeStack.Count() - nElementCount == 2;
+ OSL_ENSURE( bNodeCheck, "Fraction (mfrac) tag is missing component" );
+ if (!bNodeCheck)
+ return;
+
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = TOVER;
+ SmStructureNode *pSNode = new SmBinVerNode(aToken);
+ SmNode *pOper = new SmRectangleNode(aToken);
+ SmNode *pSecond = rNodeStack.Pop();
+ SmNode *pFirst = rNodeStack.Pop();
+ pSNode->SetSubNodes(pFirst,pOper,pSecond);
+ rNodeStack.Push(pSNode);
+}
+
+void SmXMLRootContext_Impl::EndElement()
+{
+ /*The <mroot> element requires exactly 2 arguments.*/
+ const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 2;
+ OSL_ENSURE( bNodeCheck, "Root tag is missing component");
+ if (!bNodeCheck)
+ return;
+
+ SmToken aToken;
+ aToken.cMathChar = MS_SQRT; //Temporary: alert, based on StarSymbol font
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = TNROOT;
+ SmStructureNode *pSNode = new SmRootNode(aToken);
+ SmNode *pOper = new SmRootSymbolNode(aToken);
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ SmNode *pIndex = rNodeStack.Pop();
+ SmNode *pBase = rNodeStack.Pop();
+ pSNode->SetSubNodes(pIndex,pOper,pBase);
+ rNodeStack.Push(pSNode);
+}
+
+void SmXMLSqrtContext_Impl::EndElement()
+{
+ /*
+ <msqrt> accepts any number of arguments; if this number is not 1, its
+ contents are treated as a single "inferred <mrow>" containing its
+ arguments
+ */
+ if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
+ SmXMLRowContext_Impl::EndElement();
+
+ SmToken aToken;
+ aToken.cMathChar = MS_SQRT; //Temporary: alert, based on StarSymbol font
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = TSQRT;
+ SmStructureNode *pSNode = new SmRootNode(aToken);
+ SmNode *pOper = new SmRootSymbolNode(aToken);
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ pSNode->SetSubNodes(0,pOper,rNodeStack.Pop());
+ rNodeStack.Push(pSNode);
+}
+
+void SmXMLRowContext_Impl::EndElement()
+{
+ SmNodeArray aRelationArray;
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ sal_uLong nSize = rNodeStack.Count()-nElementCount;
+
+ if (nSize > 0)
+ {
+ aRelationArray.resize(nSize);
+ for (sal_uLong j=rNodeStack.Count()-nElementCount;j > 0;j--)
+ aRelationArray[j-1] = rNodeStack.Pop();
+
+
+ //If the first or last element is an operator with stretchyness
+ //set then we must create a brace node here from those elements,
+ //removing the stretchness from the operators and applying it to
+ //ourselves, and creating the appropiate dummy StarMath none bracket
+ //to balance the arrangement
+ if (((aRelationArray[0]->GetScaleMode() == SCALE_HEIGHT)
+ && (aRelationArray[0]->GetType() == NMATH))
+ || ((aRelationArray[nSize-1]->GetScaleMode() == SCALE_HEIGHT)
+ && (aRelationArray[nSize-1]->GetType() == NMATH)))
+ {
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 5;
+
+ int nLeft=0,nRight=0;
+ if ((aRelationArray[0]->GetScaleMode() == SCALE_HEIGHT)
+ && (aRelationArray[0]->GetType() == NMATH))
+ {
+ aToken = aRelationArray[0]->GetToken();
+ nLeft=1;
+ }
+ else
+ aToken.cMathChar = '\0';
+
+ aToken.eType = TLPARENT;
+ SmNode *pLeft = new SmMathSymbolNode(aToken);
+
+ if ((aRelationArray[nSize-1]->GetScaleMode() == SCALE_HEIGHT)
+ && (aRelationArray[nSize-1]->GetType() == NMATH))
+ {
+ aToken = aRelationArray[nSize-1]->GetToken();
+ nRight=1;
+ }
+ else
+ aToken.cMathChar = '\0';
+
+ aToken.eType = TRPARENT;
+ SmNode *pRight = new SmMathSymbolNode(aToken);
+
+ SmNodeArray aRelationArray2;
+
+ //!! nSize-nLeft-nRight may be < 0 !!
+ int nRelArrSize = nSize-nLeft-nRight;
+ if (nRelArrSize > 0)
+ {
+ aRelationArray2.resize(nRelArrSize);
+ for (int i=0;i < nRelArrSize;i++)
+ aRelationArray2[i] = aRelationArray[i+nLeft];
+ }
+
+ SmToken aDummy;
+ SmStructureNode *pSNode = new SmBraceNode(aToken);
+ SmStructureNode *pBody = new SmExpressionNode(aDummy);
+ pBody->SetSubNodes(aRelationArray2);
+
+ pSNode->SetSubNodes(pLeft,pBody,pRight);
+ pSNode->SetScaleMode(SCALE_HEIGHT);
+ rNodeStack.Push(pSNode);
+ return;
+ }
+ }
+ else //Multiple newlines result in empty row elements
+ {
+ aRelationArray.resize(1);
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 5;
+ aToken.eType = TNEWLINE;
+ aRelationArray[0] = new SmLineNode(aToken);
+ }
+
+ SmToken aDummy;
+ SmStructureNode *pSNode = new SmExpressionNode(aDummy);
+ pSNode->SetSubNodes(aRelationArray);
+ rNodeStack.Push(pSNode);
+}
+
+
+SvXMLImportContext *SmXMLRowContext_Impl::StrictCreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ SvXMLImportContext* pContext = 0L;
+
+ const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresElemTokenMap();
+ switch(rTokenMap.Get(nPrefix, rLocalName))
+ {
+ /*Note that these should accept malignmark subelements, but do not*/
+ case XML_TOK_MN:
+ pContext = GetSmImport().CreateNumberContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MI:
+ pContext = GetSmImport().CreateIdentifierContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MO:
+ pContext = GetSmImport().CreateOperatorContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MTEXT:
+ pContext = GetSmImport().CreateTextContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MSPACE:
+ pContext = GetSmImport().CreateSpaceContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ case XML_TOK_MS:
+ pContext = GetSmImport().CreateStringContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+
+ /*Note: The maligngroup should only be seen when the row
+ * (or decendants) are in a table*/
+ case XML_TOK_MALIGNGROUP:
+ pContext = GetSmImport().CreateAlignGroupContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+
+ case XML_TOK_ANNOTATION:
+ pContext = GetSmImport().CreateAnnotationContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+
+ default:
+ break;
+ }
+ return pContext;
+}
+
+
+SvXMLImportContext *SmXMLRowContext_Impl::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ SvXMLImportContext* pContext = StrictCreateChildContext(nPrefix,
+ rLocalName, xAttrList);
+
+ if (!pContext)
+ {
+ //Hmm, unrecognized for this level, check to see if its
+ //an element that can have an implicit schema around it
+ pContext = SmXMLDocContext_Impl::CreateChildContext(nPrefix,
+ rLocalName,xAttrList);
+ }
+ return pContext;
+}
+
+
+SvXMLImportContext *SmXMLMultiScriptsContext_Impl::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ SvXMLImportContext* pContext = 0L;
+
+ const SvXMLTokenMap& rTokenMap = GetSmImport().
+ GetPresScriptEmptyElemTokenMap();
+ switch(rTokenMap.Get(nPrefix, rLocalName))
+ {
+ case XML_TOK_MPRESCRIPTS:
+ MiddleElement();
+ pContext = GetSmImport().CreatePrescriptsContext(nPrefix,
+ rLocalName, xAttrList);
+ break;
+ case XML_TOK_NONE:
+ pContext = GetSmImport().CreateNoneContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ default:
+ pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
+ rLocalName,xAttrList);
+ break;
+ }
+ return pContext;
+}
+
+void SmXMLMultiScriptsContext_Impl::MiddleElement()
+{
+ bHasPrescripts=true;
+
+ OSL_ENSURE( GetSmImport().GetNodeStack().Count() - nElementCount > 0,
+ "Sub has no arguments");
+
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ if (rNodeStack.Count()-nElementCount > 1)
+ {
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = TRSUB;
+ sal_uLong nFinalCount = rNodeStack.Count()-nElementCount-1;
+
+ SmNodeStack aReverseStack;
+ while (rNodeStack.Count()-nElementCount)
+ {
+ SmNode *pThing = rNodeStack.Pop();
+ aReverseStack.Push(pThing);
+ }
+
+ for (sal_uLong nCount=0;nCount < nFinalCount;nCount+=2)
+ {
+ SmSubSupNode *pNode = new SmSubSupNode(aToken);
+
+ // initialize subnodes array
+ SmNodeArray aSubNodes;
+ aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
+ for (sal_uLong i = 1; i < aSubNodes.size(); i++)
+ aSubNodes[i] = NULL;
+
+ /*On each loop the base and its sub sup pair becomes the
+ base for the next loop to which the next sub sup pair is
+ attached, i.e. wheels within wheels*/
+ aSubNodes[0] = aReverseStack.Pop();
+
+ SmNode *pScriptNode = aReverseStack.Pop();
+
+ if (pScriptNode && ((pScriptNode->GetToken().eType != TIDENT) ||
+ (pScriptNode->GetToken().aText.Len())))
+ aSubNodes[RSUB+1] = pScriptNode;
+ pScriptNode = aReverseStack.Pop();
+ if (pScriptNode && ((pScriptNode->GetToken().eType != TIDENT) ||
+ (pScriptNode->GetToken().aText.Len())))
+ aSubNodes[RSUP+1] = pScriptNode;
+
+ pNode->SetSubNodes(aSubNodes);
+ aReverseStack.Push(pNode);
+ }
+ rNodeStack.Push(aReverseStack.Pop());
+ }
+}
+
+
+void SmXMLTableContext_Impl::EndElement()
+{
+ SmNodeArray aExpressionArray;
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ SmNodeStack aReverseStack;
+ aExpressionArray.resize(rNodeStack.Count()-nElementCount);
+
+ sal_uLong nRows = rNodeStack.Count()-nElementCount;
+ sal_uInt16 nCols = 0;
+
+ SmStructureNode *pArray;
+ for (sal_uLong i=rNodeStack.Count()-nElementCount;i > 0;i--)
+ {
+ pArray = (SmStructureNode *)rNodeStack.Pop();
+ if (pArray->GetNumSubNodes() == 0)
+ {
+ //This is a little tricky, it is possible that there was
+ //be elements that were not inside a <mtd> pair, in which
+ //case they will not be in a row, i.e. they will not have
+ //SubNodes, so we have to wait until here before we can
+ //resolve the situation. Implicitsurrounding tags are
+ //surprisingly difficult to get right within this
+ //architecture
+
+ SmNodeArray aRelationArray;
+ aRelationArray.resize(1);
+ aRelationArray[0] = pArray;
+ SmToken aDummy;
+ pArray = new SmExpressionNode(aDummy);
+ pArray->SetSubNodes(aRelationArray);
+ }
+
+ if (pArray->GetNumSubNodes() > nCols)
+ nCols = pArray->GetNumSubNodes();
+ aReverseStack.Push(pArray);
+ }
+ aExpressionArray.resize(nCols*nRows);
+ sal_uLong j=0;
+ while (aReverseStack.Count())
+ {
+ pArray = (SmStructureNode *)aReverseStack.Pop();
+ for (sal_uInt16 i=0;i<pArray->GetNumSubNodes();i++)
+ aExpressionArray[j++] = pArray->GetSubNode(i);
+ }
+
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = TRGROUP;
+ aToken.nLevel = 0;
+ aToken.eType = TMATRIX;
+ SmMatrixNode *pSNode = new SmMatrixNode(aToken);
+ pSNode->SetSubNodes(aExpressionArray);
+ pSNode->SetRowCol(static_cast<sal_uInt16>(nRows),nCols);
+ rNodeStack.Push(pSNode);
+}
+
+SvXMLImportContext *SmXMLTableRowContext_Impl::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ SvXMLImportContext* pContext = 0L;
+
+ const SvXMLTokenMap& rTokenMap = GetSmImport().
+ GetPresTableElemTokenMap();
+ switch(rTokenMap.Get(nPrefix, rLocalName))
+ {
+ case XML_TOK_MTD:
+ pContext = GetSmImport().CreateTableCellContext(nPrefix,
+ rLocalName, xAttrList);
+ break;
+ default:
+ pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
+ rLocalName,xAttrList);
+ break;
+ }
+ return pContext;
+}
+
+SvXMLImportContext *SmXMLTableContext_Impl::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+{
+ SvXMLImportContext* pContext = 0L;
+
+ const SvXMLTokenMap& rTokenMap = GetSmImport().
+ GetPresTableElemTokenMap();
+ switch(rTokenMap.Get(nPrefix, rLocalName))
+ {
+ case XML_TOK_MTR:
+ pContext = GetSmImport().CreateTableRowContext(nPrefix,rLocalName,
+ xAttrList);
+ break;
+ default:
+ pContext = SmXMLTableRowContext_Impl::CreateChildContext(nPrefix,
+ rLocalName,xAttrList);
+ break;
+ }
+ return pContext;
+}
+
+void SmXMLMultiScriptsContext_Impl::EndElement()
+{
+ if (!bHasPrescripts)
+ MiddleElement();
+
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ if (rNodeStack.Count()-nElementCount > 1)
+ {
+ SmToken aToken;
+ aToken.cMathChar = '\0';
+ aToken.nGroup = 0;
+ aToken.nLevel = 0;
+ aToken.eType = TLSUB;
+ sal_uLong nFinalCount = rNodeStack.Count()-nElementCount-1;
+
+ SmNodeStack aReverseStack;
+ while (rNodeStack.Count()-nElementCount)
+ aReverseStack.Push(rNodeStack.Pop());
+ for (sal_uLong nCount=0;nCount < nFinalCount;nCount+=2)
+ {
+ SmSubSupNode *pNode = new SmSubSupNode(aToken);
+
+ // initialize subnodes array
+ SmNodeArray aSubNodes;
+ aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
+ for (sal_uLong i = 1; i < aSubNodes.size(); i++)
+ aSubNodes[i] = NULL;
+
+ /*On each loop the base and its sub sup pair becomes the
+ base for the next loop to which the next sub sup pair is
+ attached, i.e. wheels within wheels*/
+ aSubNodes[0] = aReverseStack.Pop();
+
+ SmNode *pScriptNode = aReverseStack.Pop();
+ if (pScriptNode->GetToken().aText.Len())
+ aSubNodes[LSUB+1] = pScriptNode;
+ pScriptNode = aReverseStack.Pop();
+ if (pScriptNode->GetToken().aText.Len())
+ aSubNodes[LSUP+1] = pScriptNode;
+
+ pNode->SetSubNodes(aSubNodes);
+ aReverseStack.Push(pNode);
+ }
+ rNodeStack.Push(aReverseStack.Pop());
+ }
+
+}
+void SmXMLActionContext_Impl::EndElement()
+{
+ /*For now we will just assume that the
+ selected attribute is one, and then just display
+ that expression alone, i.e. remove all expect the
+ first pushed one*/
+
+ SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
+ for (sal_uLong i=rNodeStack.Count()-nElementCount;i > 1;i--)
+ {
+ delete rNodeStack.Pop();
+ }
+}
+
+SvXMLImportContext *SmXMLImport::CreateContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ if ( XML_NAMESPACE_OFFICE == nPrefix )
+ {
+ if ( (IsXMLToken(rLocalName, XML_DOCUMENT) ||
+ IsXMLToken(rLocalName, XML_DOCUMENT_META)))
+ {
+ uno::Reference<xml::sax::XDocumentHandler> xDocBuilder(
+ mxServiceFactory->createInstance(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.dom.SAXDocumentBuilder"))),
+ uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ return IsXMLToken(rLocalName, XML_DOCUMENT_META)
+ ? new SvXMLMetaDocumentContext(*this,
+ XML_NAMESPACE_OFFICE, rLocalName,
+ xDPS->getDocumentProperties(), xDocBuilder)
+ // flat OpenDocument file format -- this has not been tested...
+ : new SmXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
+ xDPS->getDocumentProperties(), xDocBuilder);
+ }
+ else
+ {
+ return new SmXMLOfficeContext_Impl( *this,nPrefix,rLocalName);
+ }
+ }
+ else
+ return new SmXMLDocContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateRowContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLRowContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateTextContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLTextContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateAnnotationContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLAnnotationContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateStringContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLStringContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateNumberContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLNumberContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateIdentifierContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLIdentifierContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateOperatorContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLOperatorContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateSpaceContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLSpaceContext_Impl(*this,nPrefix,rLocalName);
+}
+
+
+SvXMLImportContext *SmXMLImport::CreateFracContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLFracContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateSqrtContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLSqrtContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateRootContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLRootContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateStyleContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLStyleContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreatePaddedContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLPaddedContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreatePhantomContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLPhantomContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateFencedContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLFencedContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateErrorContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLErrorContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateSubContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLSubContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateSubSupContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLSubSupContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateSupContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLSupContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateUnderContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLUnderContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateOverContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLOverContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateUnderOverContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLUnderOverContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateMultiScriptsContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLMultiScriptsContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateTableContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLTableContext_Impl(*this,nPrefix,rLocalName);
+}
+SvXMLImportContext *SmXMLImport::CreateTableRowContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLTableRowContext_Impl(*this,nPrefix,rLocalName);
+}
+SvXMLImportContext *SmXMLImport::CreateTableCellContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLTableCellContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateNoneContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLNoneContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreatePrescriptsContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLPrescriptsContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateAlignGroupContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLAlignGroupContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SvXMLImportContext *SmXMLImport::CreateActionContext(sal_uInt16 nPrefix,
+ const OUString &rLocalName,
+ const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
+{
+ return new SmXMLActionContext_Impl(*this,nPrefix,rLocalName);
+}
+
+SmXMLImport::~SmXMLImport() throw ()
+{
+ delete pPresLayoutElemTokenMap;
+ delete pPresElemTokenMap;
+ delete pPresScriptEmptyElemTokenMap;
+ delete pPresTableElemTokenMap;
+ delete pPresLayoutAttrTokenMap;
+ delete pFencedAttrTokenMap;
+ delete pColorTokenMap;
+ delete pOperatorAttrTokenMap;
+ delete pAnnotationAttrTokenMap;
+}
+
+void SmXMLImport::SetViewSettings(const Sequence<PropertyValue>& aViewProps)
+{
+ uno::Reference <frame::XModel> xModel = GetModel();
+ if ( !xModel.is() )
+ return;
+
+ uno::Reference <lang::XUnoTunnel> xTunnel;
+ xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
+ SmModel *pModel = reinterpret_cast<SmModel *>
+ (xTunnel->getSomething(SmModel::getUnoTunnelId()));
+
+ if ( !pModel )
+ return;
+
+ SmDocShell *pDocShell =
+ static_cast<SmDocShell*>(pModel->GetObjectShell());
+ if ( !pDocShell )
+ return;
+
+ Rectangle aRect( pDocShell->GetVisArea() );
+
+ sal_Int32 nCount = aViewProps.getLength();
+ const PropertyValue *pValue = aViewProps.getConstArray();
+
+ long nTmp = 0;
+
+ for (sal_Int32 i = 0; i < nCount ; i++)
+ {
+ if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaTop" ) ) )
+ {
+ pValue->Value >>= nTmp;
+ aRect.setY( nTmp );
+ }
+ else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaLeft" ) ) )
+ {
+ pValue->Value >>= nTmp;
+ aRect.setX( nTmp );
+ }
+ else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaWidth" ) ) )
+ {
+ pValue->Value >>= nTmp;
+ Size aSize( aRect.GetSize() );
+ aSize.Width() = nTmp;
+ aRect.SetSize( aSize );
+ }
+ else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaHeight" ) ) )
+ {
+ pValue->Value >>= nTmp;
+ Size aSize( aRect.GetSize() );
+ aSize.Height() = nTmp;
+ aRect.SetSize( aSize );
+ }
+ pValue++;
+ }
+
+ pDocShell->SetVisArea ( aRect );
+}
+
+void SmXMLImport::SetConfigurationSettings(const Sequence<PropertyValue>& aConfProps)
+{
+ uno::Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
+ if ( xProps.is() )
+ {
+ Reference < XPropertySetInfo > xInfo ( xProps->getPropertySetInfo() );
+ if (xInfo.is() )
+ {
+ sal_Int32 nCount = aConfProps.getLength();
+ const PropertyValue* pValues = aConfProps.getConstArray();
+
+ const OUString sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
+ const OUString sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
+ const OUString sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
+ while ( nCount-- )
+ {
+ if (pValues->Name != sFormula &&
+ pValues->Name != sBasicLibraries &&
+ pValues->Name != sDialogLibraries)
+ {
+ try
+ {
+ if ( xInfo->hasPropertyByName( pValues->Name ) )
+ xProps->setPropertyValue( pValues->Name, pValues->Value );
+ }
+ catch (beans::PropertyVetoException &e)
+ {
+ (void) e;
+ // dealing with read-only properties here. Nothing to do...
+ }
+ catch( Exception& e)
+ {
+ OSL_FAIL( "SmXMLImport::SetConfigurationSettings: Exception!" );
+ }
+ }
+
+ pValues++;
+ }
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/mathmlimport.hxx b/starmath/source/mathmlimport.hxx
new file mode 100644
index 000000000000..db44e4a336ea
--- /dev/null
+++ b/starmath/source/mathmlimport.hxx
@@ -0,0 +1,348 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _MATHMLIMPORT_HXX_
+#define _MATHMLIMPORT_HXX_
+
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/DocumentSettingsContext.hxx>
+#include <xmloff/xmltoken.hxx>
+
+#include <node.hxx>
+
+class SfxMedium;
+namespace com { namespace sun { namespace star {
+ namespace io {
+ class XInputStream;
+ class XOutputStream; }
+ namespace beans {
+ class XPropertySet; }
+} } }
+
+////////////////////////////////////////////////////////////
+
+class SmXMLImportWrapper
+{
+ com::sun::star::uno::Reference<com::sun::star::frame::XModel> xModel;
+
+public:
+ SmXMLImportWrapper(com::sun::star::uno::Reference<com::sun::star::frame::XModel> &rRef)
+ : xModel(rRef) {}
+
+ sal_uLong Import(SfxMedium &rMedium);
+
+ sal_uLong ReadThroughComponent(
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInputStream,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xModelComponent,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rFactory,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet,
+ const sal_Char* pFilterName,
+ sal_Bool bEncrypted );
+
+ sal_uLong ReadThroughComponent(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xModelComponent,
+ const sal_Char* pStreamName,
+ const sal_Char* pCompatibilityStreamName,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rFactory,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet,
+ const sal_Char* pFilterName );
+};
+
+////////////////////////////////////////////////////////////
+
+class SmXMLImport : public SvXMLImport
+{
+ SvXMLTokenMap *pPresLayoutElemTokenMap;
+ SvXMLTokenMap *pPresLayoutAttrTokenMap;
+ SvXMLTokenMap *pFencedAttrTokenMap;
+ SvXMLTokenMap *pOperatorAttrTokenMap;
+ SvXMLTokenMap *pAnnotationAttrTokenMap;
+ SvXMLTokenMap *pPresElemTokenMap;
+ SvXMLTokenMap *pPresScriptEmptyElemTokenMap;
+ SvXMLTokenMap *pPresTableElemTokenMap;
+ SvXMLTokenMap *pColorTokenMap;
+
+ SmNodeStack aNodeStack;
+ sal_Bool bSuccess;
+ String aText;
+
+public:
+ SmXMLImport(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
+ sal_uInt16 nImportFlags=IMPORT_ALL);
+ virtual ~SmXMLImport() throw ();
+
+ // XServiceInfo (override parent method)
+ ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
+
+ // XUnoTunnel
+ sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException);
+ static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId() throw();
+
+ void SAL_CALL endDocument(void)
+ throw( ::com::sun::star::xml::sax::SAXException,
+ ::com::sun::star::uno::RuntimeException );
+
+ SvXMLImportContext *CreateContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateMathContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateRowContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateFracContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateNumberContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateTextContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateAnnotationContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateStringContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateIdentifierContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateOperatorContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateSpaceContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateSqrtContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateRootContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateStyleContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreatePaddedContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreatePhantomContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateFencedContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateErrorContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateSubContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateSupContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateSubSupContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateUnderContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateOverContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateUnderOverContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateMultiScriptsContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateNoneContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreatePrescriptsContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateTableContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateTableRowContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateTableCellContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateAlignGroupContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+ SvXMLImportContext *CreateActionContext(sal_uInt16 nPrefix,
+ const rtl::OUString &rLocalName,
+ const com::sun::star::uno::Reference <
+ com::sun::star::xml::sax::XAttributeList> &xAttrList);
+
+ const SvXMLTokenMap &GetPresLayoutElemTokenMap();
+ const SvXMLTokenMap &GetPresLayoutAttrTokenMap();
+ const SvXMLTokenMap &GetFencedAttrTokenMap();
+ const SvXMLTokenMap &GetOperatorAttrTokenMap();
+ const SvXMLTokenMap &GetAnnotationAttrTokenMap();
+ const SvXMLTokenMap &GetPresElemTokenMap();
+ const SvXMLTokenMap &GetPresScriptEmptyElemTokenMap();
+ const SvXMLTokenMap &GetPresTableElemTokenMap();
+ const SvXMLTokenMap &GetColorTokenMap();
+
+ SmNodeStack & GetNodeStack() { return aNodeStack; }
+ SmNode *GetTree() { return aNodeStack.Pop(); }
+ sal_Bool GetSuccess() { return bSuccess; }
+ String &GetText() { return aText; }
+
+ virtual void SetViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aViewProps);
+ virtual void SetConfigurationSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aViewProps);
+};
+
+////////////////////////////////////////////////////////////
+
+enum SmXMLMathElemTokenMap
+{
+ XML_TOK_MATH
+};
+
+enum SmXMLPresLayoutElemTokenMap
+{
+ XML_TOK_SEMANTICS,
+ XML_TOK_MSTYLE,
+ XML_TOK_MERROR,
+ XML_TOK_MPHANTOM,
+ XML_TOK_MROW,
+ XML_TOK_MFRAC,
+ XML_TOK_MSQRT,
+ XML_TOK_MROOT,
+ XML_TOK_MSUB,
+ XML_TOK_MSUP,
+ XML_TOK_MSUBSUP,
+ XML_TOK_MMULTISCRIPTS,
+ XML_TOK_MUNDER,
+ XML_TOK_MOVER,
+ XML_TOK_MUNDEROVER,
+ XML_TOK_MTABLE,
+ XML_TOK_MACTION,
+ XML_TOK_MFENCED,
+ XML_TOK_MPADDED
+};
+
+enum SmXMLPresLayoutAttrTokenMap
+{
+ XML_TOK_FONTWEIGHT,
+ XML_TOK_FONTSTYLE,
+ XML_TOK_FONTSIZE,
+ XML_TOK_FONTFAMILY,
+ XML_TOK_COLOR
+};
+
+
+enum SmXMLFencedAttrTokenMap
+{
+ XML_TOK_OPEN,
+ XML_TOK_CLOSE
+};
+
+
+enum SmXMLPresTableElemTokenMap
+{
+ XML_TOK_MTR,
+ XML_TOK_MTD
+};
+
+enum SmXMLPresElemTokenMap
+{
+ XML_TOK_ANNOTATION,
+ XML_TOK_MI,
+ XML_TOK_MN,
+ XML_TOK_MO,
+ XML_TOK_MTEXT,
+ XML_TOK_MSPACE,
+ XML_TOK_MS,
+ XML_TOK_MALIGNGROUP
+};
+
+enum SmXMLPresScriptEmptyElemTokenMap
+{
+ XML_TOK_MPRESCRIPTS,
+ XML_TOK_NONE
+};
+
+enum SmXMLOperatorAttrTokenMap
+{
+ XML_TOK_STRETCHY
+};
+
+enum SmXMLAnnotationAttrTokenMap
+{
+ XML_TOK_ENCODING
+};
+
+////////////////////////////////////////////////////////////
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/mathtype.cxx b/starmath/source/mathtype.cxx
new file mode 100644
index 000000000000..c30f95e369db
--- /dev/null
+++ b/starmath/source/mathtype.cxx
@@ -0,0 +1,3372 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+#include <mathtype.hxx>
+#include <osl/diagnose.h>
+#include <sfx2/docfile.hxx>
+
+#define APPEND(str,ascii) str.AppendAscii(RTL_CONSTASCII_STRINGPARAM(ascii))
+
+static sal_Unicode Convert(sal_Unicode nIn)
+{
+ //Find the best match in accepted unicode for our private area symbols
+ static sal_Unicode aStarMathPrivateToUnicode[] =
+ {
+ 0x2030, 0xF613, 0xF612, 0x002B, 0x003C, 0x003E, 0xE425, 0xE421, 0xE088, 0x2208,
+ 0x0192, 0x2026, 0x2192, 0x221A, 0x221A, 0x221A, 0xE090, 0x005E, 0x02C7, 0x02D8,
+ 0x00B4, 0x0060, 0x02DC, 0x00AF, 0x0362, 0xE099, 0xE09A, 0x20DB, 0xE09C, 0xE09D,
+ 0x0028, 0x0029, 0x2220, 0x22AF, 0xE0A2, 0xE0A3, 0xE0A4, 0xE0A5, 0xE0A6, 0xE0A7,
+ 0x002F, 0x005C, 0x274F, 0xE0AB, 0x0393, 0x0394, 0x0398, 0x039b, 0x039e, 0x03A0,
+ 0x03a3, 0x03a5, 0x03a6, 0x03a8, 0x03A9, 0x03B1, 0x03B2, 0x03b3, 0x03b4, 0x03b5,
+ 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03b5,
+ 0x03d1, 0x03d6, 0xE0D2, 0x03db, 0x2118, 0x2202, 0x2129, 0xE0D7, 0xE0D8, 0x22A4,
+ 0xE0DA, 0x2190, 0x2191, 0x2193
+ };
+ if ((nIn >= 0xE080) && (nIn <= 0xE0DD))
+ nIn = aStarMathPrivateToUnicode[nIn-0xE080];
+
+ //For whatever unicode glyph that equation editor doesn't ship with that
+ //we have a possible match we can munge it to.
+ switch (nIn)
+ {
+ case 0x2223:
+ nIn = '|';
+ break;
+ default:
+ break;
+ }
+
+ return nIn;
+}
+
+void MathType::Init()
+{
+ //These are the default MathType sizes
+ aSizeTable[0]=12;
+ aSizeTable[1]=8;
+ aSizeTable[2]=6;
+ aSizeTable[3]=24;
+ aSizeTable[4]=10;
+ aSizeTable[5]=12;
+ aSizeTable[6]=12;
+
+ /*
+ These are the default MathType italic/bold settings If mathtype is changed
+ from its defaults, there is nothing we can do, as this information is not
+ stored in the document
+ */
+ MathTypeFont aFont;
+ for(sal_uInt8 i=1;i<=11;i++)
+ {
+ aFont.nTface = i+128;
+ switch (i)
+ {
+ default:
+ aFont.nStyle=0;
+ break;
+ case 3:
+ case 4:
+ aFont.nStyle=1;
+ break;
+ case 7:
+ aFont.nStyle=2;
+ break;
+ }
+ aUserStyles.insert(aFont);
+ }
+}
+
+
+/*ToDo replace with table rather than switch, returns
+ sal_True in the case that the char is just a char, and
+ sal_False if the character is an operator which must not be
+ placed inside the quote sequence designed to protect
+ against being parsed as a keyword
+
+ General solution required to force starmath to handle
+ unicode math chars the way it handles its own math
+ chars rathar than handle them as text as it will do
+ for the default case below, i.e. incorrect spacing
+ between math symbols and ordinary text e.g. 1=2 rather
+ than 1 = 2
+ */
+sal_Bool MathType::LookupChar(sal_Unicode nChar,String &rRet,sal_uInt8 nVersion,
+ sal_uInt8 nTypeFace)
+{
+ bool bRet=false;
+ const char *pC = NULL;
+ switch(nChar)
+ {
+ case 0x0000:
+ pC = " none ";
+ break;
+ case 0x00ac:
+ pC = " neg ";
+ break;
+ case 0x00b1:
+ pC = " +- ";
+ break;
+ case '(':
+ pC = " \\( ";
+ break;
+ case ')':
+ pC = " \\) ";
+ break;
+ case '[':
+ pC = " \\[ ";
+ break;
+ case ']':
+ pC = " \\] ";
+ break;
+ case '.':
+ pC = " \".\" ";
+ break;
+ case 0xae:
+ if ((nVersion < 3) && (nTypeFace == 0x86))
+ pC = " rightarrow ";
+ else
+ {
+ rRet.Append(nChar);
+ bRet=true;
+ }
+ break;
+ case 0x00fb:
+ if ((nVersion < 3) && (nTypeFace == 0x81))
+ nChar = 0xDF;
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ case 'a':
+ if ((nVersion < 3) && (nTypeFace == 0x84))
+ nChar = 0x3b1;
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ case 'b':
+ if ((nVersion < 3) && (nTypeFace == 0x84))
+ nChar = 0x3b2;
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ case 'l':
+ if ((nVersion < 3) && (nTypeFace == 0x84))
+ nChar = 0x3bb;
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ case 'n':
+ if ((nVersion < 3) && (nTypeFace == 0x84))
+ nChar = 0x3bd;
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ case 'r':
+ if ((nVersion < 3) && (nTypeFace == 0x84))
+ nChar = 0x3c1;
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ case 'D':
+ if ((nVersion < 3) && (nTypeFace == 0x84))
+ nChar = 0x394;
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ case 0xa9:
+ if ((nVersion < 3) && (nTypeFace == 0x82))
+ nChar = '\'';
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ case 0x00f1:
+ if ((nVersion < 3) && (nTypeFace == 0x86))
+ pC = " \\rangle ";
+ else
+ {
+ rRet.Append(nChar);
+ bRet=true;
+ }
+ break;
+ case 0x00a3:
+ if ((nVersion < 3) && (nTypeFace == 0x86))
+ pC = " <= ";
+ else
+ {
+ rRet.Append(nChar);
+ bRet=true;
+ }
+ break;
+ case 0x00de:
+ if ((nVersion < 3) && (nTypeFace == 0x86))
+ pC = " drarrow ";
+ else
+ {
+ rRet.Append(nChar);
+ bRet=true;
+ }
+ break;
+ case 0x0057:
+ if ((nVersion < 3) && (nTypeFace == 0x85))
+ pC = " %OMEGA ";
+ else
+ {
+ rRet.Append(nChar);
+ bRet=true;
+ }
+ break;
+ case 0x007b:
+ pC = " lbrace ";
+ break;
+ case 0x007c:
+ pC = " \\lline ";
+ break;
+ case 0x007d:
+ pC = " rbrace ";
+ break;
+ case 0x007e:
+ pC = " \"~\" ";
+ break;
+ case 0x2224:
+ pC = " ndivides ";
+ break;
+ case 0x2225:
+ pC = " parallel ";
+ break;
+ case 0x00d7:
+ if (nVersion < 3)
+ pC = " cdot ";
+ else
+ pC = " times ";
+ break;
+ case 0x00f7:
+ pC = " div ";
+ break;
+ case 0x019b:
+ pC = " lambdabar ";
+ break;
+ case 0x2026:
+ pC = " dotslow ";
+ break;
+ case 0x2022:
+ pC = " cdot ";
+ break;
+ case 0x2102:
+ pC = " setC ";
+ break;
+ case 0x210f:
+ pC = " hbar ";
+ break;
+ case 0x2111:
+ pC = " Im ";
+ break;
+ case 0x2115:
+ pC = " setN ";
+ break;
+ case 0x2118:
+ pC = " wp ";
+ break;
+ case 0x211a:
+ pC = " setQ ";
+ break;
+ case 0x211c:
+ pC = " Re ";
+ break;
+ case 0x211d:
+ pC = " setR ";
+ break;
+ case 0x2124:
+ pC = " setZ ";
+ break;
+ case 0x2135:
+ pC = " aleph ";
+ break;
+ case 0x2190:
+ pC = " leftarrow ";
+ break;
+ case 0x2191:
+ pC = " uparrow ";
+ break;
+ case 0x2192:
+ pC = " rightarrow ";
+ break;
+ case 0x0362:
+ pC = " widevec ";
+ break;
+ case 0x2193:
+ pC = " downarrow ";
+ break;
+ case 0x21d0:
+ pC = " dlarrow ";
+ break;
+ case 0x21d2:
+ pC = " drarrow ";
+ break;
+ case 0x21d4:
+ pC = " dlrarrow ";
+ break;
+ case 0x2200:
+ pC = " forall ";
+ break;
+ case 0x2202:
+ pC = " partial ";
+ break;
+ case 0x2203:
+ pC = " exists ";
+ break;
+ case 0x2205:
+ pC = " emptyset ";
+ break;
+ case 0x2207:
+ pC = " nabla ";
+ break;
+ case 0x2208:
+ pC = " in ";
+ break;
+ case 0x2209:
+ pC = " notin ";
+ break;
+ case 0x220d:
+ pC = " owns ";
+ break;
+ case 0x220f:
+ pC = " prod ";
+ break;
+ case 0x2210:
+ pC = " coprod ";
+ break;
+ case 0x2211:
+ pC = " sum ";
+ break;
+ case 0x2212:
+ pC = " - ";
+ break;
+ case 0x2213:
+ pC = " -+ ";
+ break;
+ case 0x2217:
+ pC = " * ";
+ break;
+ case 0x2218:
+ pC = " circ ";
+ break;
+ case 0x221d:
+ pC = " prop ";
+ break;
+ case 0x221e:
+ pC = " infinity ";
+ break;
+ case 0x2227:
+ pC = " and ";
+ break;
+ case 0x2228:
+ pC = " or ";
+ break;
+ case 0x2229:
+ pC = " intersection ";
+ break;
+ case 0x222a:
+ pC = " union ";
+ break;
+ case 0x222b:
+ pC = " int ";
+ break;
+ case 0x222c:
+ pC = " iint ";
+ break;
+ case 0x222d:
+ pC = " iiint ";
+ break;
+ case 0x222e:
+ pC = " lint ";
+ break;
+ case 0x222f:
+ pC = " llint ";
+ break;
+ case 0x2230:
+ pC = " lllint ";
+ break;
+ case 0x2245:
+ pC = " simeq ";
+ break;
+ case 0x2248:
+ pC = " approx ";
+ break;
+ case 0x2260:
+ pC = " <> ";
+ break;
+ case 0x2261:
+ pC = " equiv ";
+ break;
+ case 0x2264:
+ pC = " <= ";
+ break;
+ case 0x2265:
+ pC = " >= ";
+ break;
+ case 0x2282:
+ pC = " subset ";
+ break;
+ case 0x2283:
+ pC = " supset ";
+ break;
+ case 0x2284:
+ pC = " nsubset ";
+ break;
+ case 0x2285:
+ pC = " nsupset ";
+ break;
+ case 0x2286:
+ pC = " subseteq ";
+ break;
+ case 0x2287:
+ pC = " supseteq ";
+ break;
+ case 0x2288:
+ pC = " nsubseteq ";
+ break;
+ case 0x2289:
+ pC = " nsupseteq ";
+ break;
+ case 0x227a:
+ case 0x227b:
+ case 0x22b2:
+ case 0x22b3:
+ rRet += ' ';
+ rRet.Append(nChar);
+ rRet += ' ';
+ break;
+ case 0x22a5:
+ pC = " ortho ";
+ break;
+ case 0x22c5:
+ pC = " cdot ";
+ break;
+ case 0x22ee:
+ pC = " dotsvert ";
+ break;
+ case 0x22ef:
+ pC = " dotsaxis ";
+ break;
+ case 0x22f0:
+ pC = " dotsup ";
+ break;
+ case 0x22f1:
+ pC = " dotsdown ";
+ break;
+ case 0x2329:
+ pC = " langle ";
+ break;
+ case 0x232a:
+ pC = " rangle ";
+ break;
+ case 0x301a:
+ pC = " ldbracket ";
+ break;
+ case 0x301b:
+ pC = " rdbracket ";
+ break;
+ case 0xe083:
+ rRet.Append('+');
+ bRet=true;
+ break;
+ case '^':
+ case 0xe091:
+ pC = " widehat ";
+ break;
+ case 0xe096:
+ pC = " widetilde ";
+ break;
+ case 0xe098:
+ pC = " widevec ";
+ break;
+ case 0xE421:
+ pC = " geslant ";
+ break;
+ case 0xE425:
+ pC = " leslant ";
+ break;
+ case 0xeb01: //no space
+ case 0xeb08: //normal space
+ bRet=true;
+ break;
+ case 0xef04: //tiny space
+ case 0xef05: //tiny space
+ case 0xeb02: //small space
+ case 0xeb04: //medium space
+ rRet.Append('`');
+ break;
+ case 0xeb05: //large space
+ rRet.Append('~');
+ break;
+ case 0x3a9:
+ pC = " %OMEGA ";
+ break;
+ default:
+ rRet.Append(nChar);
+ bRet=true;
+ break;
+ }
+ if (pC)
+ rRet.AppendAscii(pC);
+ return bRet;
+}
+
+void MathTypeFont::AppendStyleToText(String &rRet)
+{
+ const char *pC = NULL;
+ switch (nStyle)
+ {
+ default:
+ case 0:
+ break;
+ case 1:
+ pC = " ital ";
+ break;
+ case 2:
+ pC = " bold ";
+ break;
+ case 3:
+ pC = " bold italic";
+ break;
+ }
+ if (pC)
+ rRet.AppendAscii(pC);
+}
+
+void MathType::TypeFaceToString(String &rTxt,sal_uInt8 nFace)
+{
+ MathTypeFont aFont(nFace);
+ MathTypeFontSet::iterator aItr = aUserStyles.find(aFont);
+ if (aItr != aUserStyles.end())
+ aFont.nStyle = aItr->nStyle;
+ aFont.AppendStyleToText(rTxt);
+}
+
+int MathType::Parse(SotStorage *pStor)
+{
+ SvStorageStreamRef xSrc = pStor->OpenSotStream(
+ String::CreateFromAscii("Equation Native"),
+ STREAM_STD_READ | STREAM_NOCREATE);
+ if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError()))
+ return 0;
+ pS = &xSrc;
+ pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ EQNOLEFILEHDR aHdr;
+ aHdr.Read(pS);
+ *pS >> nVersion;
+ *pS >> nPlatform;
+ *pS >> nProduct;
+ *pS >> nProdVersion;
+ *pS >> nProdSubVersion;
+
+ if (nVersion > 3) // allow only supported versions of MathType to be parsed
+ return 0;
+
+#ifdef STANDALONE
+ *pOut << "Format Version is " << int(nVersion) << endl;
+ *pOut << "Generating Platform is " << (nPlatform ? "Windows"
+ : "Mac") << endl;
+ *pOut << "Generating Product is " << (nPlatform ? "Equation Editor"
+ : "Equation Editor") << endl;
+ *pOut << "Prod Version is " << int(nProdVersion) << "." <<
+ int(nProdSubVersion) << endl << endl;
+#endif
+
+ int nRet = HandleRecords();
+ //little crude hack to close ocassionally open expressions
+ //a sophisticated system to determine what expressions are
+ //opened is required, but this is as much work as rewriting
+ //starmaths internals.
+ APPEND(rRet,"{}");
+
+#if OSL_DEBUG_LEVEL > 1
+# ifdef CAOLAN
+ //sanity check
+
+ //sigh, theres no point! MathType (in some bizarre subvarient) pads
+ //the end of the formula with ENDs (0)'s
+ sal_uLong nEnd = pS->Tell();
+ OSL_ENSURE(nEnd == pS->Seek(STREAM_SEEK_TO_END),
+ "Possibly unfully parsed formula");
+# endif
+#endif
+ return nRet;
+}
+
+static void lcl_PrependDummyTerm(String &rRet, xub_StrLen &rTextStart)
+{
+ if ((rRet.GetChar(rTextStart) == '=') &&
+ ((rTextStart == 0) ||
+ (rRet.GetChar(rTextStart-1) == '{'))
+ )
+ {
+ rRet.InsertAscii(" {}",rTextStart);
+ rTextStart+=3;
+ }
+}
+
+static void lcl_AppendDummyTerm(String &rRet)
+{
+ bool bOk=false;
+ for(int nI=rRet.Len()-1;nI >= 0; nI--)
+ {
+ xub_StrLen nIdx = sal::static_int_cast< xub_StrLen >(nI);
+ sal_Unicode nChar = rRet.GetChar(nIdx);
+ if (nChar == ' ')
+ continue;
+ if (rRet.GetChar(nIdx) != '{')
+ bOk=true;
+ break;
+ }
+ if (!bOk) //No term, use dummy
+ APPEND(rRet," {}");
+}
+
+void MathType::HandleNudge()
+{
+ sal_uInt8 nXNudge;
+ *pS >> nXNudge;
+ sal_uInt8 nYNudge;
+ *pS >> nYNudge;
+ if (nXNudge == 128 && nYNudge == 128)
+ {
+ sal_uInt16 nXLongNudge;
+ sal_uInt16 nYLongNudge;
+ *pS >> nXLongNudge;
+ *pS >> nYLongNudge;
+ }
+}
+/*Fabously complicated as many tokens have to be reordered and generally
+ *moved around from mathtypes paradigm to starmaths.*/
+int MathType::HandleRecords(int nLevel,sal_uInt8 nSelector,
+ sal_uInt8 nVariation, int nMatrixRows,int nMatrixCols)
+{
+ sal_uInt8 nTag,nRecord;
+ sal_uInt8 nTabType,nTabStops;
+ sal_uInt16 nTabOffset;
+ sal_Char nChar8;
+ String sFontName;
+ int i,nRet=1,newline=0;
+ bool bSilent=false;
+ int nPart=0;
+ String sPush,sMainTerm;
+ int nSetSize=0,nSetAlign=0;
+ int nCurRow=0,nCurCol=0;
+ bool bOpenString=false;
+ xub_StrLen nTextStart = 0;
+ xub_StrLen nSubSupStartPos = 0;
+ xub_StrLen nLastTemplateBracket=STRING_NOTFOUND;
+
+ do
+ {
+ *pS >> nTag;
+ nRecord = nTag&0x0F;
+
+ /*MathType strings can of course include words which
+ *are StarMath keywords, the simplest solution is
+ to escape strings of greater than len 1 with double
+ quotes to avoid scanning the TokenTable for matches
+
+ Unfortunately it may turn out that the string gets
+ split during the handling of a character emblishment
+ so this special case must be handled in the
+ character handler case 2:
+ */
+ if ((nRecord == CHAR) && (!bIsSilent) && (!bOpenString))
+ {
+ bOpenString=true;
+ nTextStart = rRet.Len();
+ }
+ else if ((nRecord != CHAR) && (bOpenString))
+ {
+ bOpenString=false;
+ if ((rRet.Len() - nTextStart) > 1)
+ {
+ String aStr;
+ TypeFaceToString(aStr,nTypeFace);
+ aStr += '\"';
+ rRet.Insert(aStr,nTextStart);
+ rRet += '\"';
+ }
+ else
+ {
+ if (nRecord == END)
+ {
+ sal_Unicode cChar = 0;
+ xub_StrLen nI = rRet.Len()-1;
+ while (nI && ((cChar = rRet.GetChar(nI)) == ' '))
+ --nI;
+ if ((cChar == '=') || (cChar == '+') || (cChar == '-'))
+ APPEND(rRet,"{}");
+ }
+ }
+ }
+
+ switch(nRecord)
+ {
+ case LINE:
+ {
+ if (xfLMOVE(nTag))
+ HandleNudge();
+
+ if (newline>0)
+ APPEND(rRet,"\nnewline\n");
+ if (!(xfNULL(nTag)))
+ {
+ switch (nSelector)
+ {
+ case 0x0:
+ if (nVariation==0)
+ APPEND(rRet," langle ");
+ else if (nVariation==1)
+ APPEND(rRet," \\langle ");
+ break;
+ case 0x1:
+ if (nVariation==0)
+ APPEND(rRet," left (");
+ else if (nVariation==1)
+ APPEND(rRet,"\\(");
+ break;
+ case 0x2:
+ if ((nVariation==0) || (nVariation==1))
+ APPEND(rRet," left lbrace ");
+ else
+ APPEND(rRet," left none ");
+ break;
+ case 0x3:
+ if (nVariation==0)
+ APPEND(rRet," left [");
+ else if (nVariation==1)
+ APPEND(rRet,"\\[");
+ break;
+ case 0x8:
+ case 0xb:
+ APPEND(rRet," \\[");
+ break;
+ case 0x4:
+ if (nVariation==0)
+ APPEND(rRet," lline ");
+ else if (nVariation==1)
+ APPEND(rRet," \\lline ");
+ break;
+ case 0x5:
+ if (nVariation==0)
+ APPEND(rRet," ldline ");
+ else if (nVariation==1)
+ APPEND(rRet," \\ldline ");
+ break;
+ case 0x6:
+ if (nVariation == 0 || nVariation == 1)
+ APPEND(rRet," left lfloor ");
+ else if (nVariation==1)
+ APPEND(rRet," left none ");
+ break;
+ case 0x7:
+ if (nVariation==0)
+ APPEND(rRet," lceil ");
+ else if (nVariation==1)
+ APPEND(rRet," \\lceil ");
+ break;
+ case 0x9:
+ case 0xa:
+ APPEND(rRet," \\]");
+ break;
+ case 0xc:
+ APPEND(rRet," \\(");
+ break;
+ case 0xd:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," sqrt");
+ else
+ {
+ APPEND(rRet," nroot");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ APPEND(rRet," {");
+ break;
+ case 0xe:
+ if (nPart == 0)
+ APPEND(rRet," { ");
+
+
+ if (nPart == 1)
+ APPEND(rRet," over ");
+ APPEND(rRet," {");
+ break;
+ case 0xf:
+ nSubSupStartPos = rRet.Len();
+ if ((nVariation == 0) ||
+ ((nVariation == 2) && (nPart==1)))
+ {
+ lcl_AppendDummyTerm(rRet);
+ APPEND(rRet," rSup");
+ }
+ else if ((nVariation == 1) ||
+ ((nVariation == 2) && (nPart==0)))
+ {
+ lcl_AppendDummyTerm(rRet);
+ APPEND(rRet," rSub");
+ }
+ APPEND(rRet," {");
+ break;
+ case 0x10:
+ if (nVariation == 0)
+ APPEND(rRet," {underline ");
+ else if (nVariation == 1)
+ APPEND(rRet," {underline underline ");
+ APPEND(rRet," {");
+ break;
+ case 0x11:
+ if (nVariation == 0)
+ APPEND(rRet," {overline ");
+ else if (nVariation == 1)
+ APPEND(rRet," {overline overline ");
+ APPEND(rRet," {");
+ break;
+ case 0x12:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//left arrow above
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//left arrow below
+ APPEND(rRet," {");
+ }
+ break;
+ case 0x13:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//right arrow above
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//right arrow below
+ APPEND(rRet," {");
+ }
+ break;
+ case 0x14:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//double arrow above
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//double arrow below
+ APPEND(rRet," {");
+ }
+ break;
+ case 0x15:
+ if (nPart == 0)
+ {
+ if ((nVariation == 3) || (nVariation == 4))
+ APPEND(rRet," lInt");
+ else
+ APPEND(rRet," Int");
+ if ( (nVariation != 0) && (nVariation != 3))
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if (((nVariation == 1) ||
+ (nVariation == 4)) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 2) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 2) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x16:
+ if (nPart == 0)
+ {
+ if ((nVariation == 2) || (nVariation == 3))
+ APPEND(rRet," llInt");
+ else
+ APPEND(rRet," iInt");
+ if ( (nVariation != 0) && (nVariation != 2))
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if (((nVariation == 1) ||
+ (nVariation == 3)) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x17:
+ if (nPart == 0)
+ {
+ if ((nVariation == 2) || (nVariation == 3))
+ APPEND(rRet," lllInt");
+ else
+ APPEND(rRet," iiInt");
+ if ( (nVariation != 0) && (nVariation != 2))
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if (((nVariation == 1) ||
+ (nVariation == 3)) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x18:
+ if (nPart == 0)
+ {
+ if (nVariation == 2)
+ APPEND(rRet," lInt");
+ else
+ APPEND(rRet," Int");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if (((nVariation == 1) ||
+ (nVariation == 2)) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 0) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x19:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," llInt");
+ else
+ APPEND(rRet," iInt");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if (nPart==1)
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x1a:
+ if (nPart == 0)
+ {
+ if (nVariation == 0)
+ APPEND(rRet," lllInt");
+ else
+ APPEND(rRet," iiInt");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if (nPart==1)
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x1b:
+ case 0x1c:
+ APPEND(rRet," {");
+ break;
+ case 0x1d:
+ if (nPart == 0)
+ {
+ APPEND(rRet," Sum");
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x1e:
+ if (nPart == 0)
+ {
+ APPEND(rRet," Sum");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x1f:
+ if (nPart == 0)
+ {
+ APPEND(rRet," Prod");
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x20:
+ if (nPart == 0)
+ {
+ APPEND(rRet," Prod");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x21:
+ if (nPart == 0)
+ {
+ APPEND(rRet," coProd");
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x22:
+ if (nPart == 0)
+ {
+ APPEND(rRet," coProd");
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x23:
+ if (nPart == 0)
+ {
+ APPEND(rRet," union"); //union
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x24:
+ if (nPart == 0)
+ {
+ APPEND(rRet," union"); //union
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x25:
+ if (nPart == 0)
+ {
+ APPEND(rRet," intersect"); //intersect
+ if (nVariation != 2)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x26:
+ if (nPart == 0)
+ {
+ APPEND(rRet," intersect"); //intersect
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 1) && (nPart==2))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x27:
+ if ((nVariation == 0) && (nPart==1))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 2) && (nPart==1))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 2) && (nPart==2))
+ APPEND(rRet," cSup");
+ APPEND(rRet," {");
+ break;
+ case 0x28:
+ if (nVariation == 0)
+ {
+ if (nPart == 0)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ }
+ APPEND(rRet," {");
+ if (nVariation == 0)
+ {
+ if (nPart == 1)
+ APPEND(rRet,"alignr ");
+ }
+ if (nPart == 0)
+ APPEND(rRet,"\\lline ");
+ if (nVariation == 1)
+ APPEND(rRet,"overline ");
+ break;
+ case 0x29:
+ APPEND(rRet," {");
+ break;
+ case 0x2a:
+ if (nPart == 0)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==0))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 2) && (nPart==1))
+ APPEND(rRet," rSup");
+ else if ((nVariation == 1) && (nPart==0))
+ APPEND(rRet," rSub");
+ else if ((nVariation == 2) && (nPart==0))
+ APPEND(rRet," rSub");
+ APPEND(rRet," {");
+ break;
+ case 0x2b:
+ if (nPart == 0)
+ {
+ sPush = rRet;
+ rRet.Erase();
+ }
+ if ((nVariation == 0) && (nPart==0))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 2) && (nPart==1))
+ APPEND(rRet," cSup");
+ else if ((nVariation == 1) && (nPart==0))
+ APPEND(rRet," cSub");
+ else if ((nVariation == 2) && (nPart==0))
+ APPEND(rRet," cSub");
+ APPEND(rRet," {");
+ break;
+ case 0x2c:
+ if (nPart == 0)
+ APPEND(rRet,"\"\"");
+ if ((nVariation == 0)
+ || ((nVariation == 2) && (nPart==1)))
+ APPEND(rRet," lSup");
+ else if ((nVariation == 1)
+ || ((nVariation == 2) && (nPart==0)))
+ APPEND(rRet," lSub");
+ APPEND(rRet," {");
+ break;
+ case 0x2d:
+ if (nVariation==0)
+ {
+ if (nPart == 0)
+ APPEND(rRet," langle ");
+ }
+ else if (nVariation==1)
+ {
+ APPEND(rRet," \\langle ");
+ newline--;
+ }
+ else if (nVariation==2)
+ {
+ APPEND(rRet," \\lline ");
+ newline--;
+ }
+ break;
+ case 0x2e:
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//left below
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//right below
+ else if (nVariation == 2)
+ APPEND(rRet," widevec ");//double headed below
+ APPEND(rRet," {");
+ break;
+ case 0x2f:
+ if (nVariation == 0)
+ APPEND(rRet," widevec ");//left above
+ else if (nVariation == 1)
+ APPEND(rRet," widevec ");//right above
+ else if (nVariation == 2)
+ APPEND(rRet," widevec ");//double headed above
+ APPEND(rRet," {");
+ break;
+ default:
+ break;
+ }
+ sal_Int16 nOldCurSize=nCurSize;
+ xub_StrLen nSizeStartPos = rRet.Len();
+ HandleSize(nLSize,nDSize,nSetSize);
+ nRet = HandleRecords(nLevel+1);
+ while (nSetSize)
+ {
+ bool bOk=false;
+ xub_StrLen nI = rRet.SearchBackward('{');
+ if (nI != STRING_NOTFOUND)
+ {
+ for(nI=nI+1;nI<rRet.Len();nI++)
+ if (rRet.GetChar(nI) != ' ')
+ {
+ bOk=true;
+ break;
+ }
+ }
+ else
+ bOk=true;
+
+ if (bOk)
+ APPEND(rRet,"} ");
+ else
+ rRet.Erase(nSizeStartPos);
+ nSetSize--;
+ nCurSize=nOldCurSize;
+ }
+
+
+ HandleMatrixSeperator(nMatrixRows,nMatrixCols,
+ nCurCol,nCurRow);
+
+ switch (nSelector)
+ {
+ case 0x0:
+ if (nVariation==0)
+ APPEND(rRet," rangle ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rangle ");
+ break;
+ case 0x1:
+ if (nVariation==0)
+ APPEND(rRet," right )");
+ else if (nVariation==2)
+ APPEND(rRet,"\\)");
+ break;
+ case 0x2:
+ if ((nVariation==0) || (nVariation==2))
+ APPEND(rRet," right rbrace ");
+ else
+ APPEND(rRet," right none ");
+ break;
+ case 0x3:
+ if (nVariation==0)
+ APPEND(rRet," right ]");
+ else if (nVariation==2)
+ APPEND(rRet,"\\]");
+ break;
+ case 0x4:
+ if (nVariation==0)
+ APPEND(rRet," rline ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rline ");
+ break;
+ case 0x5:
+ if (nVariation==0)
+ APPEND(rRet," rdline ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rdline ");
+ break;
+ case 0x6:
+ if (nVariation == 0 || nVariation == 2)
+ APPEND(rRet," right rfloor ");
+ else if (nVariation==2)
+ APPEND(rRet," right none ");
+ break;
+ case 0x7:
+ if (nVariation==0)
+ APPEND(rRet," rceil ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rceil ");
+ break;
+ case 0x8:
+ case 0xa:
+ APPEND(rRet,"\\[");
+ break;
+ case 0x9:
+ case 0xc:
+ APPEND(rRet,"\\]");
+ break;
+ case 0xd:
+ APPEND(rRet,"} ");
+ if (nVariation == 1)
+ {
+ if (nPart == 0)
+ {
+ newline--;
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ else
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ }
+ }
+ else
+ {
+ if (nPart == 0)
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0xb:
+ APPEND(rRet,"\\)");
+ break;
+ case 0xe:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ newline--;
+ else
+ APPEND(rRet,"} ");
+ nPart++;
+ break;
+ case 0xf:
+ {
+ if ((nPart == 0) &&
+ ((nVariation == 2) || (nVariation == 1)))
+ newline--;
+
+ bool bOk=false;
+ xub_StrLen nI = rRet.SearchBackward('{');
+ if (nI != STRING_NOTFOUND)
+ {
+ for(nI=nI+1;nI<rRet.Len();nI++)
+ if (rRet.GetChar(nI) != ' ')
+ {
+ bOk=true;
+ break;
+ }
+ }
+ else
+ bOk=true;
+
+ if (bOk)
+ APPEND(rRet,"} ");
+ else
+ rRet.Erase(nSubSupStartPos);
+ nPart++;
+ }
+ break;
+ case 0x2c:
+ if ((nPart == 0) &&
+ ((nVariation == 2) || (nVariation == 1)))
+ newline--;
+ APPEND(rRet,"} ");
+ nPart++;
+ break;
+ case 0x2e:
+ case 0x2f:
+ APPEND(rRet,"} ");
+ break;
+ case 0x10:
+ case 0x11:
+ APPEND(rRet,"}} ");
+ break;
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ if (nPart == 0)
+ {
+ newline--;
+ APPEND(rRet,"} ");
+ }
+ nPart++;
+ break;
+ case 0x1b:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ newline--;
+ APPEND(rRet,"overbrace");
+ }
+ nPart++;
+ break;
+ case 0x1c:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ newline--;
+ APPEND(rRet,"underbrace");
+ }
+ nPart++;
+ break;
+ case 0x27:
+ if (nPart==0)
+ newline--;
+ else if ((nPart==1) &&
+ ((nVariation == 2) || (nVariation == 1)))
+ newline--;
+ APPEND(rRet,"} ");
+ nPart++;
+ break;
+ case 0x28:
+ APPEND(rRet,"} ");
+ if (nVariation == 0)
+ {
+ if (nPart == 0)
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ else
+ {
+ sPush += rRet;
+ rRet = sPush;
+ APPEND(rRet," over ");
+ rRet += sMainTerm;
+ }
+ }
+ if (nPart == 0)
+ newline--;
+ nPart++;
+ break;
+ case 0x29:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ newline--;
+ switch (nVariation)
+ {
+ case 1:
+ APPEND(rRet,"slash");
+ break;
+ default:
+ APPEND(rRet,"wideslash");
+ break;
+ }
+ }
+ nPart++;
+ break;
+ case 0x1d:
+ case 0x1e:
+ case 0x1f:
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x26:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ if (nVariation != 2)
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ newline--;
+ }
+ else if ((nPart == 1) && (nVariation == 0))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ else if ((nPart == 1) && (nVariation == 1))
+ newline--;
+ else if ((nPart == 2) && (nVariation == 1))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x15:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ if ((nVariation != 0) && (nVariation != 3))
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ newline--;
+ }
+ else if ((nPart == 1) &&
+ ((nVariation == 1) || (nVariation==4)))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ else if ((nPart == 1) && (nVariation == 2))
+ newline--;
+ else if ((nPart == 2) && (nVariation == 2))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x16:
+ case 0x17:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ if ((nVariation != 0) && (nVariation != 2))
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ }
+ newline--;
+ }
+ else if ((nPart == 1) &&
+ ((nVariation == 1) || (nVariation==3)))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x18:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ newline--;
+ }
+ else if ((nPart == 1) &&
+ ((nVariation == 1) || (nVariation==2)))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ else if ((nPart == 1) && (nVariation == 0))
+ newline--;
+ else if ((nPart == 2) && (nVariation == 0))
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x19:
+ case 0x1a:
+ APPEND(rRet,"} ");
+ if (nPart == 0)
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ newline--;
+ }
+ else if (nPart == 1)
+ {
+ sPush += rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ newline--;
+ }
+ nPart++;
+ break;
+ case 0x2a:
+ case 0x2b:
+ APPEND(rRet,"} ");
+
+ if ((nPart == 0) &&
+ ((nVariation == 0) || (nVariation == 1)))
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ newline--;
+ }
+ else if ((nPart == 0) && (nVariation == 2))
+ newline--;
+ else if ((nPart == 1) && (nVariation == 2))
+ {
+ sMainTerm = rRet;
+ rRet.Erase();
+ newline--;
+ }
+ else if ((nPart == 2) || ((((nPart == 1) &&
+ (nVariation == 0)) || (nVariation == 1))))
+ {
+ sPush+=rRet;
+ rRet = sPush;
+ rRet += sMainTerm;
+ }
+ nPart++;
+ break;
+ case 0x2d:
+ if (nVariation==0)
+ {
+ if (nPart == 0)
+ {
+ newline--; //there is another term to arrive
+ APPEND(rRet," mline ");
+ }
+ else
+ APPEND(rRet," rangle ");
+ }
+ else if (nVariation==1)
+ APPEND(rRet," \\lline ");
+ else if (nVariation==2)
+ APPEND(rRet," \\rangle ");
+ nPart++;
+ break;
+ default:
+ break;
+ }
+ bSilent = true; //Skip the optional brackets and/or
+ //symbols that follow some of these
+ //records. Foo Data.
+
+ /*In matrices and piles we cannot seperate equation
+ *lines with the newline keyword*/
+ if (nMatrixCols==0)
+ newline++;
+ }
+ }
+ break;
+ case CHAR:
+ if (xfLMOVE(nTag))
+ HandleNudge();
+ nRet = HandleChar(nTextStart,nSetSize,nLevel,nTag,nSelector,
+ nVariation,bSilent);
+ break;
+ case TMPL:
+ if (xfLMOVE(nTag))
+ HandleNudge();
+ nRet = HandleTemplate(nLevel,nSelector,nVariation,
+ nLastTemplateBracket);
+ break;
+ case PILE:
+ if (xfLMOVE(nTag))
+ HandleNudge();
+ nRet = HandlePile(nSetAlign,nLevel,nSelector,nVariation);
+ HandleMatrixSeperator(nMatrixRows,nMatrixCols,nCurCol,nCurRow);
+ break;
+ case MATRIX:
+ if (xfLMOVE(nTag))
+ HandleNudge();
+ nRet = HandleMatrix(nLevel,nSelector,nVariation);
+ HandleMatrixSeperator(nMatrixRows,nMatrixCols,nCurCol,nCurRow);
+ break;
+ case EMBEL:
+ if (xfLMOVE(nTag))
+ HandleNudge();
+ HandleEmblishments();
+ break;
+ case RULER:
+ *pS >> nTabStops;
+ for (i=0;i<nTabStops;i++)
+ {
+ *pS >> nTabType;
+ *pS >> nTabOffset;
+ }
+ OSL_FAIL("Not seen in the wild Equation Ruler Field");
+ break;
+ case FONT:
+ {
+ MathTypeFont aFont;
+ *pS >> aFont.nTface;
+ /*
+ The typeface number is the negative (which makes it
+ positive) of the typeface value (unbiased) that appears in
+ CHAR records that might follow a given FONT record
+ */
+ aFont.nTface = 128-aFont.nTface;
+ *pS >> aFont.nStyle;
+ aUserStyles.insert(aFont);
+ sFontName.Erase();
+ do
+ {
+ *pS >> nChar8;
+ sFontName.Append(ByteString::ConvertToUnicode(
+ nChar8,RTL_TEXTENCODING_MS_1252));
+ }
+ while(nChar8);
+ }
+ break;
+ case SIZE:
+ HandleSetSize();
+ break;
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ nLSize=nRecord-10;
+ break;
+ case END:
+ default:
+ break;
+ }
+ }
+ while (nRecord != END && !pS->IsEof());
+ while (nSetSize)
+ {
+ rRet += '}';
+ nSetSize--;
+ }
+ return nRet;
+}
+
+/*Simply determine if we are at the end of a record or the end of a line,
+ *with fiddley logic to see if we are in a matrix or a pile or neither
+
+ Note we cannot tell until after the event that this is the last entry
+ of a pile, so we must strip the last seperator of a pile after this
+ is detected in the PILE handler
+ */
+void MathType::HandleMatrixSeperator(int nMatrixRows,int nMatrixCols,
+ int &rCurCol,int &rCurRow)
+{
+ if (nMatrixRows!=0)
+ {
+ if (rCurCol == nMatrixCols-1)
+ {
+ if (rCurRow != nMatrixRows-1)
+ APPEND(rRet," {} ##\n");
+ if (nMatrixRows!=-1)
+ {
+ rCurCol=0;
+ rCurRow++;
+ }
+ }
+ else
+ {
+ APPEND(rRet," {} # ");
+ if (nMatrixRows!=-1)
+ rCurCol++;
+ else
+ rRet += '\n';
+ }
+ }
+}
+
+/* set the alignment of the following term, but starmath currently
+ * cannot handle vertical alignment */
+void MathType::HandleAlign(sal_uInt8 nHorAlign, sal_uInt8 /*nVAlign*/, int &rSetAlign)
+{
+ switch(nHorAlign)
+ {
+ case 1:
+ default:
+ APPEND(rRet,"alignl {");
+ break;
+ case 2:
+ APPEND(rRet,"alignc {");
+ break;
+ case 3:
+ APPEND(rRet,"alignr {");
+ break;
+ }
+ rSetAlign++;
+}
+
+/* set size of text, complexity due to overuse of signedness as a flag
+ * indicator by mathtype file format*/
+sal_Bool MathType::HandleSize(sal_Int16 nLstSize,sal_Int16 nDefSize, int &rSetSize)
+{
+ bool bRet=false;
+ if (nLstSize < 0)
+ {
+ if ((-nLstSize/32 != nDefaultSize) && (-nLstSize/32 != nCurSize))
+ {
+ if (rSetSize)
+ {
+ rSetSize--;
+ rRet += '}';
+ bRet=true;
+ }
+ if (-nLstSize/32 != nLastSize)
+ {
+ nLastSize = nCurSize;
+ APPEND(rRet," size ");
+ rRet += String::CreateFromInt32(-nLstSize/32);
+ rRet += '{';
+ bRet=true;
+ rSetSize++;
+ }
+ nCurSize = -nLstSize/32;
+ }
+ }
+ else
+ {
+ /*sizetable should theoreticaly be filled with the default sizes
+ *of the various font groupings matching starmaths equivalents
+ in aTypeFaces, and a test would be done to see if the new font
+ size would be the same as what starmath would have chosen for
+ itself anyway in which case the size setting could be ignored*/
+ nLstSize = aSizeTable[nLstSize];
+ nLstSize = nLstSize + nDefSize;
+ if (nLstSize != nCurSize)
+ {
+ if (rSetSize)
+ {
+ rSetSize--;
+ rRet += '}';
+ bRet=true;
+ }
+ if (nLstSize != nLastSize)
+ {
+ nLastSize = nCurSize;
+ APPEND(rRet," size ");
+ rRet += String::CreateFromInt32(nLstSize);
+ rRet += '{';
+ bRet=true;
+ rSetSize++;
+ }
+ nCurSize = nLstSize;
+ }
+ }
+ return bRet;
+}
+
+int MathType::ConvertFromStarMath( SfxMedium& rMedium )
+{
+ if (!pTree)
+ return 0;
+
+ SvStream *pStream = rMedium.GetOutStream();
+ if ( pStream )
+ {
+ SvStorageRef pStor = new SotStorage( pStream, false );
+
+ SvGlobalName aGName(0x0002ce02L, 0x0000, 0x0000,0xc0,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x46 );
+ pStor->SetClass( aGName, 0, C2S("Microsoft Equation 3.0"));
+
+ static sal_uInt8 const aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0xCE, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x17, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x45, 0x71, 0x75, 0x61, 0x74, 0x69,
+ 0x6F, 0x6E, 0x20, 0x33, 0x2E, 0x30, 0x00, 0x0C,
+ 0x00, 0x00, 0x00, 0x44, 0x53, 0x20, 0x45, 0x71,
+ 0x75, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x0B,
+ 0x00, 0x00, 0x00, 0x45, 0x71, 0x75, 0x61, 0x74,
+ 0x69, 0x6F, 0x6E, 0x2E, 0x33, 0x00, 0xF4, 0x39,
+ 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ SvStorageStreamRef xStor( pStor->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+
+ static sal_uInt8 const aOle[] = {
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+ SvStorageStreamRef xStor2( pStor->OpenSotStream( C2S("\1Ole")));
+ xStor2->Write(aOle,sizeof(aOle));
+ xStor.Clear();
+ xStor2.Clear();
+
+ SvStorageStreamRef xSrc = pStor->OpenSotStream(C2S("Equation Native"));
+ if ( (!xSrc.Is()) || (SVSTREAM_OK != xSrc->GetError()))
+ return 0;
+
+ pS = &xSrc;
+ pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ pS->SeekRel(EQNOLEFILEHDR_SIZE); //Skip 28byte Header and fill it in later
+ *pS << sal_uInt8(0x03);
+ *pS << sal_uInt8(0x01);
+ *pS << sal_uInt8(0x01);
+ *pS << sal_uInt8(0x03);
+ *pS << sal_uInt8(0x00);
+ sal_uInt32 nSize = pS->Tell();
+ nPendingAttributes=0;
+
+ HandleNodes(pTree);
+ *pS << sal_uInt8(END);
+
+ nSize = pS->Tell()-nSize;
+ pS->Seek(0);
+ EQNOLEFILEHDR aHdr(nSize+4+1);
+ aHdr.Write(pS);
+
+ pStor->Commit();
+ }
+
+ return 1;
+}
+
+
+sal_uInt8 MathType::HandleNodes(SmNode *pNode,int nLevel)
+{
+ bool bRet=false;
+ switch(pNode->GetType())
+ {
+ case NATTRIBUT:
+ HandleAttributes(pNode,nLevel);
+ break;
+ case NTEXT:
+ HandleText(pNode,nLevel);
+ break;
+ case NVERTICAL_BRACE:
+ HandleVerticalBrace(pNode,nLevel);
+ break;
+ case NBRACE:
+ HandleBrace(pNode,nLevel);
+ break;
+ case NOPER:
+ HandleOperator(pNode,nLevel);
+ break;
+ case NBINVER:
+ HandleFractions(pNode,nLevel);
+ break;
+ case NROOT:
+ HandleRoot(pNode,nLevel);
+ break;
+ case NSPECIAL:
+ {
+ SmTextNode *pText=(SmTextNode *)pNode;
+ //if the token str and the result text are the same then this
+ //is to be seen as text, else assume its a mathchar
+ if (pText->GetText() == pText->GetToken().aText)
+ HandleText(pText,nLevel);
+ else
+ HandleMath(pText,nLevel);
+ }
+ break;
+ case NMATH:
+ HandleMath(pNode,nLevel);
+ break;
+ case NSUBSUP:
+ HandleSubSupScript(pNode,nLevel);
+ break;
+ case NEXPRESSION:
+ {
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ }
+ break;
+ case NTABLE:
+ //Root Node, PILE equivalent, i.e. vertical stack
+ HandleTable(pNode,nLevel);
+ break;
+ case NMATRIX:
+ HandleSmMatrix((SmMatrixNode *)pNode,nLevel);
+ break;
+ case NLINE:
+ {
+ *pS << sal_uInt8(0x0a);
+ *pS << sal_uInt8(LINE);
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END);
+ }
+ break;
+ case NALIGN:
+ HandleMAlign(pNode,nLevel);
+ break;
+ case NBLANK:
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x98);
+ if (pNode->GetToken().eType == TSBLANK)
+ *pS << sal_uInt16(0xEB04);
+ else
+ *pS << sal_uInt16(0xEB05);
+ break;
+ default:
+ {
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ }
+ break;
+ }
+ return bRet;
+}
+
+
+int MathType::StartTemplate(sal_uInt16 nSelector,sal_uInt16 nVariation)
+{
+ int nOldPending=nPendingAttributes;
+ *pS << sal_uInt8(TMPL); //Template
+ *pS << sal_uInt8(nSelector); //selector
+ *pS << sal_uInt8(nVariation); //variation
+ *pS << sal_uInt8(0x00); //options
+ *pS << sal_uInt8(LINE);
+ //theres just no way we can now handle any character
+ //attributes (from mathtypes perspective) centered
+ //over an expression but above template attribute
+ //such as widevec and similiar constructs
+ //we have to drop them
+ nPendingAttributes=0;
+ return nOldPending;
+}
+
+void MathType::EndTemplate(int nOldPendingAttributes)
+{
+ *pS << sal_uInt8(END); //end line
+ *pS << sal_uInt8(END); //end template
+ nPendingAttributes=nOldPendingAttributes;
+}
+
+
+void MathType::HandleSmMatrix(SmMatrixNode *pMatrix,int nLevel)
+{
+ *pS << sal_uInt8(MATRIX);
+ *pS << sal_uInt8(0x00); //vAlign ?
+ *pS << sal_uInt8(0x00); //h_just
+ *pS << sal_uInt8(0x00); //v_just
+ *pS << sal_uInt8(pMatrix->GetNumRows()); //v_just
+ *pS << sal_uInt8(pMatrix->GetNumCols()); //v_just
+ int nBytes=(pMatrix->GetNumRows()+1)*2/8;
+ if (((pMatrix->GetNumRows()+1)*2)%8)
+ nBytes++;
+ for (sal_uInt16 j = 0; j < nBytes; j++)
+ *pS << sal_uInt8(0x00); //row_parts
+ nBytes=(pMatrix->GetNumCols()+1)*2/8;
+ if (((pMatrix->GetNumCols()+1)*2)%8)
+ nBytes++;
+ for (sal_uInt16 k = 0; k < nBytes; k++)
+ *pS << sal_uInt8(0x00); //col_parts
+ sal_uInt16 nSize = pMatrix->GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pMatrix->GetSubNode(i))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //end line
+ }
+ *pS << sal_uInt8(END);
+}
+
+
+//Root Node, PILE equivalent, i.e. vertical stack
+void MathType::HandleTable(SmNode *pNode,int nLevel)
+{
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ //The root of the starmath is a table, if
+ //we convert this them each iteration of
+ //conversion from starmath to mathtype will
+ //add an extra unnecessary level to the
+ //mathtype output stack which would grow
+ //without bound in a multi step conversion
+
+ if (nLevel == 0)
+ *pS << sal_uInt8(0x0A); //initial size
+
+ if ( nLevel || (nSize >1))
+ {
+ *pS << sal_uInt8(PILE);
+ *pS << sal_uInt8(nHAlign); //vAlign ?
+ *pS << sal_uInt8(0x01); //hAlign
+ }
+
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ {
+ *pS << sal_uInt8(LINE);
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END);
+ }
+ if (nLevel || (nSize>1))
+ *pS << sal_uInt8(END);
+}
+
+
+void MathType::HandleRoot(SmNode *pNode,int nLevel)
+{
+ SmNode *pTemp;
+ *pS << sal_uInt8(TMPL); //Template
+ *pS << sal_uInt8(0x0D); //selector
+ if (pNode->GetSubNode(0))
+ *pS << sal_uInt8(0x01); //variation
+ else
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+
+ if (NULL != (pTemp = pNode->GetSubNode(2)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END);
+ }
+
+ if (NULL != (pTemp = pNode->GetSubNode(0)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END);
+ }
+ else
+ *pS << sal_uInt8(LINE|0x10); //dummy line
+
+
+
+ *pS << sal_uInt8(END);
+}
+
+sal_uInt8 MathType::HandleCScript(SmNode *pNode,SmNode *pContent,int nLevel,
+ sal_uLong *pPos,sal_Bool bTest)
+{
+ sal_uInt8 nVariation2=0xff;
+
+ if (bTest && pNode->GetSubNode(CSUP+1))
+ {
+ nVariation2=0;
+ if (pNode->GetSubNode(CSUB+1))
+ nVariation2=2;
+ }
+ else if (pNode->GetSubNode(CSUB+1))
+ nVariation2=1;
+
+ if (nVariation2!=0xff)
+ {
+ if (pPos)
+ *pPos = pS->Tell();
+ *pS << sal_uInt8(TMPL); //Template
+ *pS << sal_uInt8(0x2B); //selector
+ *pS << nVariation2;
+ *pS << sal_uInt8(0x00); //options
+
+ if (pContent)
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pContent,nLevel+1);
+ *pS << sal_uInt8(END); //line
+ }
+ else
+ *pS << sal_uInt8(LINE|0x10);
+
+ *pS << sal_uInt8(0x0B);
+
+ SmNode *pTemp;
+ if (NULL != (pTemp = pNode->GetSubNode(CSUB+1)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //line
+ }
+ else
+ *pS << sal_uInt8(LINE|0x10);
+ if (bTest && NULL != (pTemp = pNode->GetSubNode(CSUP+1)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //line
+ }
+ else
+ *pS << sal_uInt8(LINE|0x10);
+ }
+ return nVariation2;
+}
+
+
+
+/*
+ Sub and Sup scripts and another problem area, StarMath
+ can have all possible options used at the same time, whereas
+ Mathtype cannot. The ordering of the nodes for each system
+ is quite different as well leading to some complexity
+ */
+void MathType::HandleSubSupScript(SmNode *pNode,int nLevel)
+{
+ SmNode *pTemp;
+
+ sal_uInt8 nVariation=0xff;
+ if (pNode->GetSubNode(LSUP+1))
+ {
+ nVariation=0;
+ if (pNode->GetSubNode(LSUB+1))
+ nVariation=2;
+ }
+ else if (NULL != (pTemp = pNode->GetSubNode(LSUB+1)))
+ nVariation=1;
+
+ if (nVariation!=0xff)
+ {
+ *pS << sal_uInt8(TMPL); //Template
+ *pS << sal_uInt8(0x2c); //selector
+ *pS << nVariation;
+ *pS << sal_uInt8(0x00); //options
+ *pS << sal_uInt8(0x0B);
+
+ if (NULL != (pTemp = pNode->GetSubNode(LSUB+1)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //line
+ }
+ else
+ *pS << sal_uInt8(LINE|0x10);
+ if (NULL != (pTemp = pNode->GetSubNode(LSUP+1)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //line
+ }
+ else
+ *pS << sal_uInt8(LINE|0x10);
+ *pS << sal_uInt8(END);
+ nVariation=0xff;
+ }
+
+
+ sal_uInt8 nVariation2=HandleCScript(pNode,NULL,nLevel);
+
+ if (NULL != (pTemp = pNode->GetSubNode(0)))
+ {
+ HandleNodes(pTemp,nLevel+1);
+ }
+
+ if (nVariation2 != 0xff)
+ *pS << sal_uInt8(END);
+
+ if (NULL != (pNode->GetSubNode(RSUP+1)))
+ {
+ nVariation=0;
+ if (pNode->GetSubNode(RSUB+1))
+ nVariation=2;
+ }
+ else if (NULL != (pTemp = pNode->GetSubNode(RSUB+1)))
+ nVariation=1;
+
+ if (nVariation!=0xff)
+ {
+ *pS << sal_uInt8(TMPL); //Template
+ *pS << sal_uInt8(0x0F); //selector
+ *pS << nVariation;
+ *pS << sal_uInt8(0x00); //options
+ *pS << sal_uInt8(0x0B);
+
+ if (NULL != (pTemp = pNode->GetSubNode(RSUB+1)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //line
+ }
+ else
+ *pS << sal_uInt8(LINE|0x10);
+ if (NULL != (pTemp = pNode->GetSubNode(RSUP+1)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //line
+ }
+ else
+ *pS << sal_uInt8(LINE|0x10);
+ *pS << sal_uInt8(END); //line
+ }
+
+ //After subscript mathtype will keep the size of
+ //normal text at the subscript size, sigh.
+ *pS << sal_uInt8(0x0A);
+}
+
+
+void MathType::HandleFractions(SmNode *pNode,int nLevel)
+{
+ SmNode *pTemp;
+ *pS << sal_uInt8(TMPL); //Template
+ *pS << sal_uInt8(0x0E); //selector
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(LINE); //line
+ if (NULL != (pTemp = pNode->GetSubNode(0)))
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END);
+
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(LINE); //line
+ if (NULL != (pTemp = pNode->GetSubNode(2)))
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END);
+
+ *pS << sal_uInt8(END);
+}
+
+
+void MathType::HandleBrace(SmNode *pNode,int nLevel)
+{
+ SmNode *pTemp;
+ SmNode *pLeft=pNode->GetSubNode(0);
+ SmNode *pRight=pNode->GetSubNode(2);
+
+ *pS << sal_uInt8(TMPL); //Template
+ bIsReInterpBrace=0;
+ sal_uInt8 nBSpec=0x10;
+ sal_uLong nLoc = pS->Tell();
+ if (pLeft)
+ {
+ switch (pLeft->GetToken().eType)
+ {
+ case TLANGLE:
+ *pS << sal_uInt8(tmANGLE); //selector
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+ break;
+ case TLBRACE:
+ *pS << sal_uInt8(tmBRACE); //selector
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+ nBSpec+=3;
+ break;
+ case TLBRACKET:
+ *pS << sal_uInt8(tmBRACK); //selector
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+ nBSpec+=3;
+ break;
+ case TLFLOOR:
+ *pS << sal_uInt8(tmFLOOR); //selector
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+ break;
+ case TLLINE:
+ *pS << sal_uInt8(tmBAR); //selector
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+ nBSpec+=3;
+ break;
+ case TLDLINE:
+ *pS << sal_uInt8(tmDBAR); //selector
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+ break;
+ default:
+ *pS << sal_uInt8(tmPAREN); //selector
+ *pS << sal_uInt8(0x00); //variation
+ *pS << sal_uInt8(0x00); //options
+ nBSpec+=3;
+ break;
+ }
+ }
+
+ if (NULL != (pTemp = pNode->GetSubNode(1)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //options
+ }
+ nSpec=nBSpec;
+ if (pLeft)
+ HandleNodes(pLeft,nLevel+1);
+ if (bIsReInterpBrace)
+ {
+ sal_uLong nLoc2 = pS->Tell();
+ pS->Seek(nLoc);
+ *pS << sal_uInt8(0x2D);
+ pS->Seek(nLoc2);
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x96);
+ *pS << sal_uInt16(0xEC07);
+ bIsReInterpBrace=0;
+ }
+ if (pRight)
+ HandleNodes(pRight,nLevel+1);
+ nSpec=0x0;
+ *pS << sal_uInt8(END);
+}
+
+
+void MathType::HandleVerticalBrace(SmNode *pNode,int nLevel)
+{
+ SmNode *pTemp;
+ *pS << sal_uInt8(TMPL); //Template
+ if (pNode->GetToken().eType == TUNDERBRACE)
+ *pS << sal_uInt8(tmLHBRACE); //selector
+ else
+ *pS << sal_uInt8(tmUHBRACE); //selector
+ *pS << sal_uInt8(0x01); //variation
+ *pS << sal_uInt8(0x00); //options
+
+ if (NULL != (pTemp = pNode->GetSubNode(0)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //options
+ }
+
+ if (NULL != (pTemp = pNode->GetSubNode(2)))
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pTemp,nLevel+1);
+ *pS << sal_uInt8(END); //options
+ }
+ *pS << sal_uInt8(END);
+}
+
+void MathType::HandleOperator(SmNode *pNode,int nLevel)
+{
+ if (HandleLim(pNode,nLevel))
+ return;
+
+ sal_uLong nPos;
+ sal_uInt8 nVariation;
+
+ switch (pNode->GetToken().eType)
+ {
+ case TIINT:
+ case TIIINT:
+ case TLINT:
+ case TLLINT:
+ case TLLLINT:
+ nVariation=HandleCScript(pNode->GetSubNode(0),
+ pNode->GetSubNode(1),nLevel,&nPos,0);
+ break;
+ default:
+ nVariation=HandleCScript(pNode->GetSubNode(0),
+ pNode->GetSubNode(1),nLevel,&nPos);
+ break;
+ }
+
+ sal_uInt8 nOldVariation=nVariation;
+ sal_uInt8 nIntVariation=nVariation;
+
+ sal_uLong nPos2=0;
+ if (nVariation != 0xff)
+ {
+ nPos2 = pS->Tell();
+ pS->Seek(nPos);
+ if (nVariation == 2)
+ {
+ nIntVariation=0;
+ nVariation = 1;
+ }
+ else if (nVariation == 0)
+ nVariation = 1;
+ else if (nVariation == 1)
+ nVariation = 0;
+ }
+ else
+ {
+ nVariation = 2;
+ nIntVariation=0;
+ }
+ *pS << sal_uInt8(TMPL);
+ switch(pNode->GetToken().eType)
+ {
+ case TINT:
+ if (nOldVariation != 0xff)
+ *pS << sal_uInt8(0x18); //selector
+ else
+ *pS << sal_uInt8(0x15); //selector
+ *pS << nIntVariation; //variation
+ break;
+ case TIINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << sal_uInt8(0x19);
+ *pS << sal_uInt8(0x01);
+ }
+ else
+ {
+ *pS << sal_uInt8(0x16);
+ *pS << sal_uInt8(0x00);
+ }
+ break;
+ case TIIINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << sal_uInt8(0x1a);
+ *pS << sal_uInt8(0x01);
+ }
+ else
+ {
+ *pS << sal_uInt8(0x17);
+ *pS << sal_uInt8(0x00);
+ }
+ break;
+ case TLINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << sal_uInt8(0x18);
+ *pS << sal_uInt8(0x02);
+ }
+ else
+ {
+ *pS << sal_uInt8(0x15);
+ *pS << sal_uInt8(0x03);
+ }
+ break;
+ case TLLINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << sal_uInt8(0x19);
+ *pS << sal_uInt8(0x00);
+ }
+ else
+ {
+ *pS << sal_uInt8(0x16);
+ *pS << sal_uInt8(0x02);
+ }
+ break;
+ case TLLLINT:
+ if (nOldVariation != 0xff)
+ {
+ *pS << sal_uInt8(0x1a);
+ *pS << sal_uInt8(0x00);
+ }
+ else
+ {
+ *pS << sal_uInt8(0x17);
+ *pS << sal_uInt8(0x02);
+ }
+ break;
+ case TSUM:
+ default:
+ *pS << sal_uInt8(0x1d);
+ *pS << nVariation;
+ break;
+ case TPROD:
+ *pS << sal_uInt8(0x1f);
+ *pS << nVariation;
+ break;
+ case TCOPROD:
+ *pS << sal_uInt8(0x21);
+ *pS << nVariation;
+ break;
+ }
+ *pS << sal_uInt8(0x00); //options
+
+ if (nPos2)
+ pS->Seek(nPos2);
+ else
+ {
+ *pS << sal_uInt8(LINE); //line
+ HandleNodes(pNode->GetSubNode(1),nLevel+1);
+ *pS << sal_uInt8(END); //line
+ *pS << sal_uInt8(LINE|0x10);
+ *pS << sal_uInt8(LINE|0x10);
+ }
+
+
+ *pS << sal_uInt8(0x0D);
+ switch(pNode->GetToken().eType)
+ {
+ case TSUM:
+ default:
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x86);
+ *pS << sal_uInt16(0x2211);
+ break;
+ case TPROD:
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x86);
+ *pS << sal_uInt16(0x220F);
+ break;
+ case TCOPROD:
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x8B);
+ *pS << sal_uInt16(0x2210);
+ break;
+ case TIIINT:
+ case TLLLINT:
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x86);
+ *pS << sal_uInt16(0x222B);
+ case TIINT:
+ case TLLINT:
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x86);
+ *pS << sal_uInt16(0x222B);
+ case TINT:
+ case TLINT:
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x86);
+ *pS << sal_uInt16(0x222B);
+ break;
+ }
+ *pS << sal_uInt8(END);
+ *pS << sal_uInt8(0x0A);
+}
+
+
+int MathType::HandlePile(int &rSetAlign,int nLevel,sal_uInt8 nSelector,
+ sal_uInt8 nVariation)
+{
+ *pS >> nHAlign;
+ *pS >> nVAlign;
+
+ HandleAlign(nHAlign,nVAlign,rSetAlign);
+
+ APPEND(rRet," stack {\n");
+ int nRet = HandleRecords(nLevel+1,nSelector,nVariation,-1,-1);
+ rRet.Erase(rRet.Len()-3,2);
+ APPEND(rRet,"} ");
+
+ while (rSetAlign)
+ {
+ APPEND(rRet,"} ");
+ rSetAlign--;
+ }
+ return nRet;
+}
+
+int MathType::HandleMatrix(int nLevel,sal_uInt8 nSelector,
+ sal_uInt8 nVariation)
+{
+ sal_uInt8 nH_just,nV_just,nRows,nCols;
+ *pS >> nVAlign;
+ *pS >> nH_just;
+ *pS >> nV_just;
+ *pS >> nRows;
+ *pS >> nCols;
+ int nBytes = ((nRows+1)*2)/8;
+ if (((nRows+1)*2)%8)
+ nBytes++;
+ pS->SeekRel(nBytes);
+ nBytes = ((nCols+1)*2)/8;
+ if (((nCols+1)*2)%8)
+ nBytes++;
+ pS->SeekRel(nBytes);
+ APPEND(rRet," matrix {\n");
+ int nRet = HandleRecords(nLevel+1,nSelector,nVariation,nRows,nCols);
+
+ xub_StrLen nI = rRet.SearchBackward('#');
+ if ((nI != STRING_NOTFOUND) && (nI > 0))
+ if (rRet.GetChar(nI-1) != '#') //missing column
+ APPEND(rRet,"{}");
+
+ APPEND(rRet,"\n} ");
+ return nRet;
+}
+
+int MathType::HandleTemplate(int nLevel,sal_uInt8 &rSelector,
+ sal_uInt8 &rVariation, xub_StrLen &rLastTemplateBracket)
+{
+ sal_uInt8 nOption; //This appears utterly unused
+ *pS >> rSelector;
+ *pS >> rVariation;
+ *pS >> nOption;
+ OSL_ENSURE(rSelector < 48,"Selector out of range");
+ if ((rSelector >= 21) && (rSelector <=26))
+ {
+ OSL_ENSURE(nOption < 2,"Option out of range");
+ }
+ else if (/*(rSelector >= 0) &&*/ (rSelector <=12))
+ {
+ OSL_ENSURE(nOption < 3,"Option out of range");
+ }
+
+ //For the (broken) case where one subscript template ends, and there is
+ //another one after it, mathtype handles it as if the second one was
+ //inside the first one and renders it as sub of sub
+ bool bRemove=false;
+ if ( (rSelector == 0xf) && (rLastTemplateBracket != STRING_NOTFOUND) )
+ {
+ bRemove=true;
+ for (xub_StrLen nI = rLastTemplateBracket+1; nI < rRet.Len(); nI++ )
+ if (rRet.GetChar(nI) != ' ')
+ {
+ bRemove=false;
+ break;
+ }
+ }
+
+ //suborderlist
+ int nRet = HandleRecords(nLevel+1,rSelector,rVariation);
+
+ if (bRemove)
+ {
+ rRet.Erase(rLastTemplateBracket,1);
+ APPEND(rRet,"} ");
+ rLastTemplateBracket = STRING_NOTFOUND;
+ }
+ if (rSelector == 0xf)
+ rLastTemplateBracket = rRet.SearchBackward('}');
+ else
+ rLastTemplateBracket = STRING_NOTFOUND;
+
+ rSelector = sal::static_int_cast< sal_uInt8 >(-1);
+ return nRet;
+}
+
+void MathType::HandleEmblishments()
+{
+ sal_uInt8 nEmbel;
+ do
+ {
+ *pS >> nEmbel;
+ switch (nEmbel)
+ {
+ case 0x02:
+ APPEND(rRet," dot ");
+ break;
+ case 0x03:
+ APPEND(rRet," ddot ");
+ break;
+ case 0x04:
+ APPEND(rRet," dddot ");
+ break;
+ case 0x05:
+ if (nPostSup == 0)
+ {
+ APPEND(sPost," sup {}");
+ nPostSup = sPost.Len();
+ }
+ sPost.InsertAscii(" ' ",nPostSup-1);
+ nPostSup += 3;
+ break;
+ case 0x06:
+ if (nPostSup == 0)
+ {
+ APPEND(sPost," sup {}");
+ nPostSup = sPost.Len();
+ }
+ sPost.InsertAscii(" '' ",nPostSup-1);
+ nPostSup += 4;
+ break;
+ case 0x07:
+ if (nPostlSup == 0)
+ {
+ APPEND(sPost," lsup {}");
+ nPostlSup = sPost.Len();
+ }
+ sPost.InsertAscii(" ' ",nPostlSup-1);
+ nPostlSup += 3;
+ break;
+ case 0x08:
+ APPEND(rRet," tilde ");
+ break;
+ case 0x09:
+ APPEND(rRet," hat ");
+ break;
+ case 0x0b:
+ APPEND(rRet," vec ");
+ break;
+ case 0x10:
+ APPEND(rRet," overstrike ");
+ break;
+ case 0x11:
+ APPEND(rRet," bar ");
+ break;
+ case 0x12:
+ if (nPostSup == 0)
+ {
+ APPEND(sPost," sup {}");
+ nPostSup = sPost.Len();
+ }
+ sPost.InsertAscii(" ''' ",nPostSup-1);
+ nPostSup += 5;
+ break;
+ case 0x14:
+ APPEND(rRet," breve ");
+ break;
+ default:
+ OSL_ENSURE(nEmbel < 21,"Embel out of range");
+ break;
+ }
+ if (nVersion < 3)
+ break;
+ }while (nEmbel);
+}
+
+void MathType::HandleSetSize()
+{
+ sal_uInt8 nTemp;
+ *pS >> nTemp;
+ switch (nTemp)
+ {
+ case 101:
+ *pS >> nLSize;
+ nLSize = -nLSize;
+ break;
+ case 100:
+ *pS >> nTemp;
+ nLSize = nTemp;
+ *pS >> nDSize;
+ break;
+ default:
+ nLSize = nTemp;
+ *pS >> nTemp;
+ nDSize = nTemp-128;
+ break;
+ }
+}
+
+int MathType::HandleChar(xub_StrLen &rTextStart,int &rSetSize,int nLevel,
+ sal_uInt8 nTag,sal_uInt8 nSelector,sal_uInt8 nVariation, sal_Bool bSilent)
+{
+ sal_Unicode nChar;
+ int nRet=1;
+
+ if (xfAUTO(nTag))
+ {
+ //This is a candidate for function recognition, whatever
+ //that is!
+ }
+
+ sal_uInt8 nOldTypeFace = nTypeFace;
+ *pS >> nTypeFace;
+ if (nVersion < 3)
+ {
+ sal_uInt8 nChar8;
+ *pS >> nChar8;
+ nChar = nChar8;
+ }
+ else
+ *pS >> nChar;
+
+ /*
+ bad character, old mathtype < 3 has these
+ */
+ if (nChar < 0x20)
+ return nRet;
+
+ if (xfEMBELL(nTag))
+ {
+ //A bit tricky, the character emblishments for
+ //mathtype can all be listed after eachother, in
+ //starmath some must go before the character and some
+ //must go after. In addition some of the emblishments
+ //may repeated and in starmath some of these groups
+ //must be gathered together. sPost is the portion that
+ //follows the char and nPostSup and nPostlSup are the
+ //indexes at which this class of emblishment is
+ //collated together
+ sPost.Erase();
+ nPostSup = nPostlSup = 0;
+ int nOriglen=rRet.Len()-rTextStart;
+ APPEND(rRet," {"); // #i24340# make what would be "vec {A}_n" become "{vec {A}}_n"
+ if ((!bSilent) && ((nOriglen) > 1))
+ rRet += '\"';
+ nRet = HandleRecords(nLevel+1,nSelector,nVariation);
+ if (!bSilent)
+ {
+ if (nOriglen > 1)
+ {
+ String aStr;
+ TypeFaceToString(aStr,nOldTypeFace);
+ aStr += '\"';
+ rRet.Insert(aStr,rTextStart);
+
+ aStr.Erase();
+ TypeFaceToString(aStr,nTypeFace);
+ rRet.Append(aStr);
+ rRet += '{';
+ }
+ else
+ APPEND(rRet," {");
+ rTextStart = rRet.Len();
+ }
+ }
+
+ if (!bSilent)
+ {
+ xub_StrLen nOldLen = rRet.Len();
+ if (
+ HandleSize(nLSize,nDSize,rSetSize) ||
+ (nOldTypeFace != nTypeFace)
+ )
+ {
+ if ((nOldLen - rTextStart) > 1)
+ {
+ rRet.InsertAscii("\"",nOldLen);
+ String aStr;
+ TypeFaceToString(aStr,nOldTypeFace);
+ aStr += '\"';
+ rRet.Insert(aStr,rTextStart);
+ }
+ rTextStart = rRet.Len();
+ }
+ nOldLen = rRet.Len();
+ if (!LookupChar(nChar,rRet,nVersion,nTypeFace))
+ {
+ if (nOldLen - rTextStart > 1)
+ {
+ rRet.InsertAscii("\"",nOldLen);
+ String aStr;
+ TypeFaceToString(aStr,nOldTypeFace);
+ aStr += '\"';
+ rRet.Insert(aStr,rTextStart);
+ }
+ rTextStart = rRet.Len();
+ }
+ lcl_PrependDummyTerm(rRet, rTextStart);
+ }
+
+ if ((xfEMBELL(nTag)) && (!bSilent))
+ {
+ rRet += '}'; // #i24340# make what would be "vec {A}_n" become "{vec {A}}_n"
+ rRet += '}';
+ rRet += sPost;
+ rTextStart = rRet.Len();
+ }
+ return nRet;
+}
+
+sal_Bool MathType::HandleLim(SmNode *pNode,int nLevel)
+{
+ bool bRet=false;
+ //Special case for the "lim" option in StarMath
+ if ((pNode->GetToken().eType == TLIM)
+ || (pNode->GetToken().eType == TLIMSUP)
+ || (pNode->GetToken().eType == TLIMINF)
+ )
+ {
+ if (pNode->GetSubNode(1))
+ {
+ sal_uInt8 nVariation2=HandleCScript(pNode->GetSubNode(0),NULL,
+ nLevel);
+
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(LINE); //line
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('l');
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('i');
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('m');
+
+ if (pNode->GetToken().eType == TLIMSUP)
+ {
+ *pS << sal_uInt8(CHAR); //some space
+ *pS << sal_uInt8(0x98);
+ *pS << sal_uInt16(0xEB04);
+
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('s');
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('u');
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('p');
+ }
+ else if (pNode->GetToken().eType == TLIMINF)
+ {
+ *pS << sal_uInt8(CHAR); //some space
+ *pS << sal_uInt8(0x98);
+ *pS << sal_uInt16(0xEB04);
+
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('i');
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('n');
+ *pS << sal_uInt8(CHAR|0x10);
+ *pS << sal_uInt8(0x82);
+ *pS << sal_uInt16('f');
+ }
+
+
+ *pS << sal_uInt8(CHAR); //some space
+ *pS << sal_uInt8(0x98);
+ *pS << sal_uInt16(0xEB04);
+
+ if (nVariation2 != 0xff)
+ {
+ *pS << sal_uInt8(END);
+ *pS << sal_uInt8(END);
+ }
+ HandleNodes(pNode->GetSubNode(1),nLevel+1);
+ //*pS << sal_uInt8(END); //options
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+void MathType::HandleMAlign(SmNode *pNode,int nLevel)
+{
+ sal_uInt8 nPushedHAlign=nHAlign;
+ switch(pNode->GetToken().eType)
+ {
+ case TALIGNC:
+ nHAlign=2;
+ break;
+ case TALIGNR:
+ nHAlign=3;
+ break;
+ default:
+ nHAlign=1;
+ break;
+ }
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ nHAlign=nPushedHAlign;
+}
+
+void MathType::HandleMath(SmNode *pNode, int /*nLevel*/)
+{
+ if (pNode->GetToken().eType == TMLINE)
+ {
+ *pS << sal_uInt8(END);
+ *pS << sal_uInt8(LINE);
+ bIsReInterpBrace=1;
+ return;
+ }
+ SmMathSymbolNode *pTemp=(SmMathSymbolNode *)pNode;
+ for(xub_StrLen i=0;i<pTemp->GetText().Len();i++)
+ {
+ sal_Unicode nArse = Convert(pTemp->GetText().GetChar(i));
+ if ((nArse == 0x2224) || (nArse == 0x2288) || (nArse == 0x2285) ||
+ (nArse == 0x2289))
+ {
+ *pS << sal_uInt8(CHAR|0x20);
+ }
+ else if ((nPendingAttributes) &&
+ (i == ((pTemp->GetText().Len()+1)/2)-1))
+ {
+ *pS << sal_uInt8(0x22);
+ }
+ else
+ *pS << sal_uInt8(CHAR); //char without formula recognition
+ //The typeface seems to be MTEXTRA for unicode characters,
+ //though how to determine when mathtype chooses one over
+ //the other is unknown. This should do the trick
+ //nevertheless.
+ sal_uInt8 nBias;
+ if ( (nArse == 0x2213) || (nArse == 0x2218) ||
+ (nArse == 0x210F) || (
+ (nArse >= 0x22EE) && (nArse <= 0x22FF)
+ ))
+ {
+ nBias = 0xB; //typeface
+ }
+ else if ((nArse > 0x2000) || (nArse == 0x00D7))
+ nBias = 0x6; //typeface
+ else if (nArse == 0x3d1)
+ nBias = 0x4;
+ else if ((nArse > 0xFF) && ((nArse < 0x393) || (nArse > 0x3c9)))
+ nBias = 0xB; //typeface
+ else if ((nArse == 0x2F) || (nArse == 0x2225))
+ nBias = 0x2; //typeface
+ else
+ nBias = 0x3; //typeface
+
+ *pS << sal_uInt8(nSpec+nBias+128); //typeface
+
+ if (nArse == 0x2224)
+ {
+ *pS << sal_uInt16(0x7C);
+ *pS << sal_uInt8(EMBEL);
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ else if (nArse == 0x2225)
+ *pS << sal_uInt16(0xEC09);
+ else if (nArse == 0xE421)
+ *pS << sal_uInt16(0x2265);
+ else if (nArse == 0x230A)
+ *pS << sal_uInt16(0xF8F0);
+ else if (nArse == 0x230B)
+ *pS << sal_uInt16(0xF8FB);
+ else if (nArse == 0xE425)
+ *pS << sal_uInt16(0x2264);
+ else if (nArse == 0x226A)
+ {
+ *pS << sal_uInt16(0x3C);
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x98);
+ *pS << sal_uInt16(0xEB01);
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x86);
+ *pS << sal_uInt16(0x3c);
+ }
+ else if (nArse == 0x2288)
+ {
+ *pS << sal_uInt16(0x2286);
+ *pS << sal_uInt8(EMBEL);
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ else if (nArse == 0x2289)
+ {
+ *pS << sal_uInt16(0x2287);
+ *pS << sal_uInt8(EMBEL);
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ else if (nArse == 0x2285)
+ {
+ *pS << sal_uInt16(0x2283);
+ *pS << sal_uInt8(EMBEL);
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ else
+ *pS << nArse;
+ }
+ nPendingAttributes = 0;
+}
+
+void MathType::HandleAttributes(SmNode *pNode,int nLevel)
+{
+ int nOldPending = 0;
+ SmNode *pTemp = 0;
+ SmTextNode *pIsText = 0;
+
+ if (NULL != (pTemp = pNode->GetSubNode(0)))
+ {
+ pIsText = (SmTextNode *)pNode->GetSubNode(1);
+
+ switch (pTemp->GetToken().eType)
+ {
+ case TWIDEVEC:
+ //theres just no way we can now handle any character
+ //attributes (from mathtypes perspective) centered
+ //over an expression but above template attributes
+ //such as widevec and similiar constructs
+ //we have to drop them
+ nOldPending = StartTemplate(0x2f,0x01);
+ break;
+ case TCHECK: //Not Exportable
+ case TACUTE: //Not Exportable
+ case TGRAVE: //Not Exportable
+ case TCIRCLE: //Not Exportable
+ case TWIDETILDE: //Not Exportable
+ case TWIDEHAT: //Not Exportable
+ break;
+ case TUNDERLINE:
+ nOldPending = StartTemplate(0x10);
+ break;
+ case TOVERLINE: //If the next node is not text
+ //or text with more than one char
+ if ((pIsText->GetToken().eType != TTEXT) ||
+ (pIsText->GetText().Len() > 1))
+ nOldPending = StartTemplate(0x11);
+ break;
+ default:
+ nPendingAttributes++;
+ break;
+ }
+ }
+
+ if (pIsText)
+ HandleNodes(pIsText,nLevel+1);
+
+ switch (pTemp->GetToken().eType)
+ {
+ case TWIDEVEC:
+ case TUNDERLINE:
+ EndTemplate(nOldPending);
+ break;
+ case TOVERLINE:
+ if ((pIsText->GetToken().eType != TTEXT) ||
+ (pIsText->GetText().Len() > 1))
+ EndTemplate(nOldPending);
+ break;
+ default:
+ break;
+ }
+
+ //if there was no suitable place to put the attribute,
+ //then we have to just give up on it
+ if (nPendingAttributes)
+ nPendingAttributes--;
+ else
+ {
+ if ((nInsertion != 0) && NULL != (pTemp = pNode->GetSubNode(0)))
+ {
+ sal_uLong nPos = pS->Tell();
+ nInsertion--;
+ pS->Seek(nInsertion);
+ switch(pTemp->GetToken().eType)
+ {
+ case TACUTE: //Not Exportable
+ case TGRAVE: //Not Exportable
+ case TCIRCLE: //Not Exportable
+ break;
+ case TCDOT:
+ *pS << sal_uInt8(2);
+ break;
+ case TDDOT:
+ *pS << sal_uInt8(3);
+ break;
+ case TDDDOT:
+ *pS << sal_uInt8(4);
+ break;
+ case TTILDE:
+ *pS << sal_uInt8(8);
+ break;
+ case THAT:
+ *pS << sal_uInt8(9);
+ break;
+ case TVEC:
+ *pS << sal_uInt8(11);
+ break;
+ case TOVERSTRIKE:
+ *pS << sal_uInt8(16);
+ break;
+ case TOVERLINE:
+ if ((pIsText->GetToken().eType == TTEXT) &&
+ (pIsText->GetText().Len() == 1))
+ *pS << sal_uInt8(17);
+ break;
+ case TBREVE:
+ *pS << sal_uInt8(20);
+ break;
+ case TWIDEVEC:
+ case TUNDERLINE:
+ case TWIDETILDE:
+ case TWIDEHAT:
+ break;
+ case TBAR:
+ *pS << sal_uInt8(17);
+ break;
+ default:
+ *pS << sal_uInt8(0x2);
+ break;
+ }
+ pS->Seek(nPos);
+ }
+ }
+}
+
+void MathType::HandleText(SmNode *pNode, int /*nLevel*/)
+{
+ SmTextNode *pTemp=(SmTextNode *)pNode;
+ for(xub_StrLen i=0;i<pTemp->GetText().Len();i++)
+ {
+ if ((nPendingAttributes) &&
+ (i == ((pTemp->GetText().Len()+1)/2)-1))
+ {
+ *pS << sal_uInt8(0x22); //char, with attributes right
+ //after the character
+ }
+ else
+ *pS << sal_uInt8(CHAR);
+
+ sal_uInt8 nFace = 0x1;
+ if (pNode->GetFont().GetItalic() == ITALIC_NORMAL)
+ nFace = 0x3;
+ else if (pNode->GetFont().GetWeight() == WEIGHT_BOLD)
+ nFace = 0x7;
+ *pS << sal_uInt8(nFace+128); //typeface
+ sal_uInt16 nChar = pTemp->GetText().GetChar(i);
+ *pS << Convert(nChar);
+
+ //Mathtype can only have these sort of character
+ //attributes on a single character, starmath can put them
+ //anywhere, when the entity involved is a text run this is
+ //a large effort to place the character attribute on the
+ //central mathtype character so that it does pretty much
+ //what the user probably has in mind. The attributes
+ //filled in here are dummy ones which are replaced in the
+ //ATTRIBUT handler if a suitable location for the
+ //attributes was found here. Unfortunately it is
+ //possible for starmath to place character attributes on
+ //entities which cannot occur in mathtype e.g. a Summation
+ //symbol so these attributes may be lost
+ if ((nPendingAttributes) &&
+ (i == ((pTemp->GetText().Len()+1)/2)-1))
+ {
+ *pS << sal_uInt8(EMBEL);
+ while (nPendingAttributes)
+ {
+ *pS << sal_uInt8(2);
+ //wedge the attributes in here and clear
+ //the pending stack
+ nPendingAttributes--;
+ }
+ nInsertion=pS->Tell();
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/mathtype.hxx b/starmath/source/mathtype.hxx
new file mode 100644
index 000000000000..e37d388f8e8a
--- /dev/null
+++ b/starmath/source/mathtype.hxx
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+ #ifndef MATHTYPE_HXX
+#define MATHTYPE_HXX
+
+#include "node.hxx"
+#include "eqnolefilehdr.hxx"
+
+#include <sot/storage.hxx>
+
+#include <set>
+
+class SfxMedium;
+
+class MathTypeFont
+{
+public:
+ sal_uInt8 nTface;
+ sal_uInt8 nStyle;
+ MathTypeFont() : nTface(0),nStyle(0) {}
+ MathTypeFont(sal_uInt8 nFace) : nTface(nFace),nStyle(0) {}
+ void AppendStyleToText(String &rS);
+};
+
+struct LessMathTypeFont
+{
+ sal_Bool operator() (const MathTypeFont &rValue1,
+ const MathTypeFont &rValue2) const
+ {
+ return rValue1.nTface < rValue2.nTface;
+ }
+};
+
+typedef ::std::set< MathTypeFont, LessMathTypeFont > MathTypeFontSet;
+
+class MathType
+{
+public:
+ MathType(String &rIn) :
+ rRet(rIn), nHAlign(0), nVAlign(0), nDefaultSize(12),
+ nLSize(0), nDSize(0), nCurSize(0), nLastSize(0), bIsSilent(sal_False),
+ nTypeFace(0)
+ {
+ Init();
+ }
+
+ MathType(String &rIn,SmNode *pIn) :
+ rRet(rIn), pTree(pIn), nHAlign(2), nVAlign(0), nInsertion(0), nDefaultSize(12),
+ nLSize(0), nDSize(0), nCurSize(0), nLastSize(0), nSpec(0), bIsSilent(sal_False),
+ nTypeFace(0)
+ {
+ Init();
+ }
+
+ int Parse( SotStorage* pStor );
+ int ConvertFromStarMath( SfxMedium& rMedium );
+
+private:
+/*Ver 2 Header*/
+ sal_uInt8 nVersion;
+ sal_uInt8 nPlatform;
+ sal_uInt8 nProduct;
+ sal_uInt8 nProdVersion;
+ sal_uInt8 nProdSubVersion;
+
+ SvStorageStream *pS;
+
+ void Init();
+
+ int HandleRecords(int nLevel=0,sal_uInt8 nSelector=0xFF,
+ sal_uInt8 nVariation=0xFF,int nRows=0,int nCols=0);
+ sal_Bool HandleSize(sal_Int16 nLSize,sal_Int16 nDSize, int &rSetSize);
+ void HandleAlign(sal_uInt8 nHAlign,sal_uInt8 nVAlign, int &rSetAlign);
+ int HandlePile(int &rSetAlign,int nLevel,sal_uInt8 nSelector,
+ sal_uInt8 nVariation);
+ int HandleMatrix(int nLevel,sal_uInt8 nSelector,sal_uInt8 nVariarion);
+ void HandleMatrixSeperator(int nMatrixRows,int nMatrixCols,int &rCurCol,
+ int &rCurRow);
+ int HandleTemplate(int nLevel,sal_uInt8 &rSelector,sal_uInt8 &rVariation,
+ xub_StrLen &rLastTemplateBracket);
+ void HandleEmblishments();
+ void HandleSetSize();
+ int HandleChar(xub_StrLen &rTextStart,int &rSetSize,int nLevel,
+ sal_uInt8 nTag,sal_uInt8 nSelector,sal_uInt8 nVariation,
+ sal_Bool bSilent);
+ void HandleNudge();
+ int xfLMOVE(sal_uInt8 nTest) const {return nTest&0x80;}
+ int xfAUTO(sal_uInt8 nTest) const {return nTest&0x10;}
+ int xfEMBELL(sal_uInt8 nTest) const {return nTest&0x20;}
+ int xfNULL(sal_uInt8 nTest) const {return nTest&0x10;}
+ int xfLSPACE(sal_uInt8 nTest) const {return nTest&0x40;}
+ int xfRULER(sal_uInt8 nTest) const {return nTest&0x20;}
+
+ sal_uInt8 HandleNodes(SmNode *pNode,int nLevel=0);
+ int StartTemplate(sal_uInt16 nSelector,sal_uInt16 nVariation=0);
+ void EndTemplate(int nOldPendingAttributes);
+ void HandleSmMatrix(SmMatrixNode *pMatrix,int nLevel);
+ void HandleTable(SmNode *pNode,int nLevel);
+ void HandleRoot(SmNode *pNode,int nLevel);
+ void HandleSubSupScript(SmNode *pNode,int nLevel);
+ sal_uInt8 HandleCScript(SmNode *pNode,SmNode *pContent,int nLevel,
+ sal_uLong *pPos=NULL,sal_Bool bTest=sal_True);
+ void HandleFractions(SmNode *pNode,int nLevel);
+ void HandleBrace(SmNode *pNode,int nLevel);
+ void HandleVerticalBrace(SmNode *pNode,int nLevel);
+ void HandleOperator(SmNode *pNode,int nLevel);
+ sal_Bool HandleLim(SmNode *pNode,int nLevel);
+ void HandleMAlign(SmNode *pNode,int nLevel);
+ void HandleMath(SmNode *pNode,int nLevel);
+ void HandleText(SmNode *pNode,int nLevel);
+ void HandleAttributes(SmNode *pNode,int nLevel);
+ void TypeFaceToString(String &rRet,sal_uInt8 nFace);
+
+ String &rRet;
+ SmNode *pTree;
+
+ sal_uInt8 nHAlign;
+ sal_uInt8 nVAlign;
+
+ int nPendingAttributes;
+ sal_uLong nInsertion;
+
+ sal_Int16 aSizeTable[7];
+ sal_Int16 nDefaultSize;
+ sal_Int16 nLSize;
+ sal_Int16 nDSize;
+ sal_Int16 nCurSize;
+ sal_Int16 nLastSize;
+ sal_uInt8 nSpec;
+ sal_Bool bIsSilent, bIsReInterpBrace;
+ String sPost;
+ xub_StrLen nPostSup;
+ xub_StrLen nPostlSup;
+ sal_uInt8 nTypeFace;
+ MathTypeFontSet aUserStyles;
+
+ enum MTOKENS {END,LINE,CHAR,TMPL,PILE,MATRIX,EMBEL,RULER,FONT,SIZE};
+ enum MTEMPLATES
+ {
+ tmANGLE,tmPAREN,tmBRACE,tmBRACK,tmBAR,tmDBAR,tmFLOOR,tmCEILING,
+ tmLBLB,tmRBRB,tmRBLB,tmLBRP,tmLPRB,tmROOT,tmFRACT,tmSCRIPT,tmUBAR,
+ tmOBAR,tmLARROW,tmRARROW,tmBARROW,tmSINT,tmDINT,tmTINT,tmSSINT,
+ tmDSINT,tmTSINT,tmUHBRACE,tmLHBRACE,tmSUM
+ };
+public:
+ static sal_Bool LookupChar(sal_Unicode nChar,String &rRet,
+ sal_uInt8 nVersion=3,sal_uInt8 nTypeFace=0);
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx
new file mode 100644
index 000000000000..0f1c44b38307
--- /dev/null
+++ b/starmath/source/node.cxx
@@ -0,0 +1,3152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+#include "node.hxx"
+#include "rect.hxx"
+#include "symbol.hxx"
+#include "smmod.hxx"
+#include "document.hxx"
+#include "view.hxx"
+#include "mathtype.hxx"
+#include "visitors.hxx"
+
+#include <tools/gen.hxx>
+#include <tools/fract.hxx>
+#include <rtl/math.hxx>
+#include <tools/color.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/outdev.hxx>
+#include <sfx2/module.hxx>
+
+#include <math.h>
+#include <float.h>
+
+
+#define APPEND(str,ascii) str.AppendAscii(RTL_CONSTASCII_STRINGPARAM(ascii))
+
+
+using ::rtl::OUString;
+
+
+////////////////////////////////////////
+// SmTmpDevice
+// Allows for font and color changes. The original settings will be restored
+// in the destructor.
+// It's main purpose is to allow for the "const" in the 'OutputDevice'
+// argument in the 'Arrange' functions and restore changes made in the 'Draw'
+// functions.
+// Usually a MapMode of 1/100th mm will be used.
+//
+
+class SmTmpDevice
+{
+ OutputDevice &rOutDev;
+
+ // disallow use of copy-constructor and assignment-operator
+ SmTmpDevice(const SmTmpDevice &rTmpDev);
+ SmTmpDevice & operator = (const SmTmpDevice &rTmpDev);
+
+ Color Impl_GetColor( const Color& rColor );
+
+public:
+ SmTmpDevice(OutputDevice &rTheDev, bool bUseMap100th_mm);
+ ~SmTmpDevice() { rOutDev.Pop(); }
+
+ void SetFont(const Font &rNewFont);
+
+ void SetLineColor( const Color& rColor ) { rOutDev.SetLineColor( Impl_GetColor(rColor) ); }
+ void SetFillColor( const Color& rColor ) { rOutDev.SetFillColor( Impl_GetColor(rColor) ); }
+ void SetTextColor( const Color& rColor ) { rOutDev.SetTextColor( Impl_GetColor(rColor) ); }
+
+ operator OutputDevice & () { return rOutDev; }
+};
+
+
+SmTmpDevice::SmTmpDevice(OutputDevice &rTheDev, bool bUseMap100th_mm) :
+ rOutDev(rTheDev)
+{
+ rOutDev.Push( PUSH_FONT | PUSH_MAPMODE |
+ PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
+ if (bUseMap100th_mm && MAP_100TH_MM != rOutDev.GetMapMode().GetMapUnit())
+ {
+ OSL_FAIL( "incorrect MapMode?" );
+ rOutDev.SetMapMode( MAP_100TH_MM ); //Immer fuer 100% fomatieren
+ }
+}
+
+
+Color SmTmpDevice::Impl_GetColor( const Color& rColor )
+{
+ ColorData nNewCol = rColor.GetColor();
+ if (COL_AUTO == nNewCol)
+ {
+ if (OUTDEV_PRINTER == rOutDev.GetOutDevType())
+ nNewCol = COL_BLACK;
+ else
+ {
+ Color aBgCol( rOutDev.GetBackground().GetColor() );
+ if (OUTDEV_WINDOW == rOutDev.GetOutDevType())
+ aBgCol = ((Window &) rOutDev).GetDisplayBackground().GetColor();
+
+ nNewCol = SM_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
+
+ Color aTmpColor( nNewCol );
+ if (aBgCol.IsDark() && aTmpColor.IsDark())
+ nNewCol = COL_WHITE;
+ else if (aBgCol.IsBright() && aTmpColor.IsBright())
+ nNewCol = COL_BLACK;
+ }
+ }
+ return Color( nNewCol );
+}
+
+
+void SmTmpDevice::SetFont(const Font &rNewFont)
+{
+ rOutDev.SetFont( rNewFont );
+ rOutDev.SetTextColor( Impl_GetColor( rNewFont.GetColor() ) );
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+
+SmNode::SmNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+{
+ eType = eNodeType;
+ eScaleMode = SCALE_NONE;
+ aNodeToken = rNodeToken;
+ nAccIndex = -1;
+ SetSelected(false);
+ aParentNode = NULL;
+}
+
+
+SmNode::~SmNode()
+{
+}
+
+
+bool SmNode::IsVisible() const
+{
+ return false;
+}
+
+
+sal_uInt16 SmNode::GetNumSubNodes() const
+{
+ return 0;
+}
+
+
+SmNode * SmNode::GetSubNode(sal_uInt16 /*nIndex*/)
+{
+ return NULL;
+}
+
+
+SmNode * SmNode::GetLeftMost()
+ // returns leftmost node of current subtree.
+ //! (this assumes the one with index 0 is always the leftmost subnode
+ //! for the current node).
+{
+ SmNode *pNode = GetNumSubNodes() > 0 ?
+ GetSubNode(0) : NULL;
+
+ return pNode ? pNode->GetLeftMost() : this;
+}
+
+
+void SmNode::SetPhantom(bool bIsPhantomP)
+{
+ if (! (Flags() & FLG_VISIBLE))
+ bIsPhantom = bIsPhantomP;
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->SetPhantom(bIsPhantom);
+}
+
+
+void SmNode::SetColor(const Color& rColor)
+{
+ if (! (Flags() & FLG_COLOR))
+ GetFont().SetColor(rColor);
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->SetColor(rColor);
+}
+
+
+void SmNode::SetAttribut(sal_uInt16 nAttrib)
+{
+ if (
+ (nAttrib == ATTR_BOLD && !(Flags() & FLG_BOLD)) ||
+ (nAttrib == ATTR_ITALIC && !(Flags() & FLG_ITALIC))
+ )
+ {
+ nAttributes |= nAttrib;
+ }
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->SetAttribut(nAttrib);
+}
+
+
+void SmNode::ClearAttribut(sal_uInt16 nAttrib)
+{
+ if (
+ (nAttrib == ATTR_BOLD && !(Flags() & FLG_BOLD)) ||
+ (nAttrib == ATTR_ITALIC && !(Flags() & FLG_ITALIC))
+ )
+ {
+ nAttributes &= ~nAttrib;
+ }
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->ClearAttribut(nAttrib);
+}
+
+
+void SmNode::SetFont(const SmFace &rFace)
+{
+ if (!(Flags() & FLG_FONT))
+ GetFont() = rFace;
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->SetFont(rFace);
+}
+
+
+void SmNode::SetFontSize(const Fraction &rSize, sal_uInt16 nType)
+ //! 'rSize' is in units of pts
+{
+ Size aFntSize;
+
+ if (!(Flags() & FLG_SIZE))
+ {
+ Fraction aVal (SmPtsTo100th_mm(rSize.GetNumerator()),
+ rSize.GetDenominator());
+ long nHeight = (long)aVal;
+
+ aFntSize = GetFont().GetSize();
+ aFntSize.Width() = 0;
+ switch(nType)
+ {
+ case FNTSIZ_ABSOLUT:
+ aFntSize.Height() = nHeight;
+ break;
+
+ case FNTSIZ_PLUS:
+ aFntSize.Height() += nHeight;
+ break;
+
+ case FNTSIZ_MINUS:
+ aFntSize.Height() -= nHeight;
+ break;
+
+ case FNTSIZ_MULTIPLY:
+ aFntSize.Height() = (long) (Fraction(aFntSize.Height()) * rSize);
+ break;
+
+ case FNTSIZ_DIVIDE:
+ if (rSize != Fraction(0L))
+ aFntSize.Height() = (long) (Fraction(aFntSize.Height()) / rSize);
+ break;
+ default:
+ break;
+ }
+
+ // check the requested size against maximum value
+ static int const nMaxVal = SmPtsTo100th_mm(128);
+ if (aFntSize.Height() > nMaxVal)
+ aFntSize.Height() = nMaxVal;
+
+ GetFont().SetSize(aFntSize);
+ }
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->SetFontSize(rSize, nType);
+}
+
+
+void SmNode::SetSize(const Fraction &rSize)
+{
+ GetFont() *= rSize;
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->SetSize(rSize);
+}
+
+
+void SmNode::SetRectHorAlign(RectHorAlign eHorAlign, bool bApplyToSubTree )
+{
+ if (!(Flags() & FLG_HORALIGN))
+ eRectHorAlign = eHorAlign;
+
+ if (bApplyToSubTree)
+ {
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->SetRectHorAlign(eHorAlign);
+ }
+}
+
+
+void SmNode::PrepareAttributes()
+{
+ GetFont().SetWeight((Attributes() & ATTR_BOLD) ? WEIGHT_BOLD : WEIGHT_NORMAL);
+ GetFont().SetItalic((Attributes() & ATTR_ITALIC) ? ITALIC_NORMAL : ITALIC_NONE);
+}
+
+
+void SmNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+#if OSL_DEBUG_LEVEL > 1
+ bIsDebug = true;
+#else
+ bIsDebug = false;
+#endif
+ bIsPhantom = false;
+ nFlags = 0;
+ nAttributes = 0;
+
+ switch (rFormat.GetHorAlign())
+ { case AlignLeft: eRectHorAlign = RHA_LEFT; break;
+ case AlignCenter: eRectHorAlign = RHA_CENTER; break;
+ case AlignRight: eRectHorAlign = RHA_RIGHT; break;
+ }
+
+ GetFont() = rFormat.GetFont(FNT_MATH);
+ OSL_ENSURE( GetFont().GetCharSet() == RTL_TEXTENCODING_UNICODE,
+ "unexpected CharSet" );
+ GetFont().SetWeight(WEIGHT_NORMAL);
+ GetFont().SetItalic(ITALIC_NONE);
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->Prepare(rFormat, rDocShell);
+}
+
+
+#if OSL_DEBUG_LEVEL > 1
+void SmNode::ToggleDebug() const
+ // toggle 'bIsDebug' in current subtree
+{
+ SmNode *pThis = (SmNode *) this;
+
+ pThis->bIsDebug = bIsDebug ? false : true;
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = pThis->GetSubNode(i)))
+ pNode->ToggleDebug();
+}
+#endif
+
+
+void SmNode::Move(const Point& rPosition)
+{
+ if (rPosition.X() == 0 && rPosition.Y() == 0)
+ return;
+
+ SmRect::Move(rPosition);
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->Move(rPosition);
+}
+
+
+void SmNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->Arrange(rDev, rFormat);
+}
+
+void SmNode::CreateTextFromNode(String &rText)
+{
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ if (nSize > 1)
+ rText.Append('{');
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->CreateTextFromNode(rText);
+ if (nSize > 1)
+ {
+ rText.EraseTrailingChars();
+ APPEND(rText,"} ");
+ }
+}
+
+
+void SmNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong /*nWidth*/)
+{
+}
+
+
+void SmNode::AdaptToY(const OutputDevice &/*rDev*/, sal_uLong /*nHeight*/)
+{
+}
+
+
+const SmNode * SmNode::FindTokenAt(sal_uInt16 nRow, sal_uInt16 nCol) const
+ // returns (first) ** visible ** (sub)node with the tokens text at
+ // position 'nRow', 'nCol'.
+ //! (there should be exactly one such node if any)
+{
+ if ( IsVisible()
+ && nRow == GetToken().nRow
+ && nCol >= GetToken().nCol && nCol < GetToken().nCol + GetToken().aText.Len())
+ return this;
+ else
+ {
+ sal_uInt16 nNumSubNodes = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nNumSubNodes; i++)
+ { const SmNode *pNode = GetSubNode(i);
+
+ if (!pNode)
+ continue;
+
+ const SmNode *pResult = pNode->FindTokenAt(nRow, nCol);
+ if (pResult)
+ return pResult;
+ }
+ }
+
+ return 0;
+}
+
+
+const SmNode * SmNode::FindRectClosestTo(const Point &rPoint) const
+{
+ long nDist = LONG_MAX;
+ const SmNode *pResult = 0;
+
+ if (IsVisible())
+ pResult = this;
+ else
+ {
+ sal_uInt16 nNumSubNodes = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nNumSubNodes; i++)
+ { const SmNode *pNode = GetSubNode(i);
+
+ if (!pNode)
+ continue;
+
+ long nTmp;
+ const SmNode *pFound = pNode->FindRectClosestTo(rPoint);
+ if (pFound && (nTmp = pFound->OrientedDist(rPoint)) < nDist)
+ { nDist = nTmp;
+ pResult = pFound;
+
+ // quit immediately if 'rPoint' is inside the *should not
+ // overlap with other rectangles* part.
+ // This (partly) serves for getting the attributes in eg
+ // "bar overstrike a".
+ // ('nDist < 0' is used as *quick shot* to avoid evaluation of
+ // the following expression, where the result is already determined)
+ if (nDist < 0 && pFound->IsInsideRect(rPoint))
+ break;
+ }
+ }
+ }
+
+ return pResult;
+}
+
+void SmNode::GetAccessibleText( String &/*rText*/ ) const
+{
+ OSL_FAIL( "SmNode: GetAccessibleText not overloaded" );
+}
+
+const SmNode * SmNode::FindNodeWithAccessibleIndex(xub_StrLen nAccIdx) const
+{
+ const SmNode *pResult = 0;
+
+ sal_Int32 nIdx = GetAccessibleIndex();
+ String aTxt;
+ if (nIdx >= 0)
+ GetAccessibleText( aTxt ); // get text if used in following 'if' statement
+
+ if (nIdx >= 0
+ && nIdx <= nAccIdx && nAccIdx < nIdx + aTxt.Len())
+ pResult = this;
+ else
+ {
+ sal_uInt16 nNumSubNodes = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nNumSubNodes; i++)
+ {
+ const SmNode *pNode = GetSubNode(i);
+ if (!pNode)
+ continue;
+
+ pResult = pNode->FindNodeWithAccessibleIndex(nAccIdx);
+ if (pResult)
+ return pResult;
+ }
+ }
+
+ return pResult;
+}
+
+#ifdef DEBUG_ENABLE_DUMPASDOT
+void SmNode::DumpAsDot(std::ostream &out, String* label, int number, int& id, int parent) const
+{
+ //If this is the root start the file
+ if(number == -1){
+ out<<"digraph {"<<std::endl;
+ if(label){
+ out<<"labelloc = \"t\";"<<std::endl;
+ String eq(*label);
+ //CreateTextFromNode(eq);
+ eq.SearchAndReplaceAll(String::CreateFromAscii("\n"), String::CreateFromAscii(" "));
+ eq.SearchAndReplaceAll(String::CreateFromAscii("\\"), String::CreateFromAscii("\\\\"));
+ eq.SearchAndReplaceAll(String::CreateFromAscii("\""), String::CreateFromAscii("\\\""));
+ out<<"label= \"Equation: \\\"";
+ out<<ByteString( eq, RTL_TEXTENCODING_UTF8).GetBuffer();
+ out<<"\\\"\";"<<std::endl;
+ }
+ }
+
+ //Some how out<<(int)this; doesn't work... So we do this nasty workaround...
+ char strid[100];
+ sprintf(strid, "%i", id);
+
+ char strnr[100];
+ sprintf(strnr, "%i", number);
+
+ //Dump connection to this node
+ if( parent != -1 ){
+ char pid[100];
+ sprintf(pid, "%i", parent);
+ out<<"n"<<pid<<" -> n"<<strid<<" [label=\""<<strnr<<"\"];"<<std::endl;
+ //If doesn't have parent and isn't a rootnode:
+ } else if(number != -1) {
+ out<<"orphaned -> n"<<strid<<" [label=\""<<strnr<<"\"];"<<std::endl;
+ }
+
+ //Dump this node
+ out<<"n"<< strid<<" [label=\"";
+ switch( GetType() ) {
+ case NTABLE: out<<"SmTableNode"; break;
+ case NBRACE: out<<"SmBraceNode"; break;
+ case NBRACEBODY: out<<"SmBracebodyNode"; break;
+ case NOPER: out<<"SmOperNode"; break;
+ case NALIGN: out<<"SmAlignNode"; break;
+ case NATTRIBUT: out<<"SmAttributNode"; break;
+ case NFONT: out<<"SmFontNode"; break;
+ case NUNHOR: out<<"SmUnHorNode"; break;
+ case NBINHOR: out<<"SmBinHorNode"; break;
+ case NBINVER: out<<"SmBinVerNode"; break;
+ case NBINDIAGONAL: out<<"SmBinDiagonalNode"; break;
+ case NSUBSUP: out<<"SmSubSupNode"; break;
+ case NMATRIX: out<<"SmMatrixNode"; break;
+ case NPLACE: out<<"SmPlaceNode"; break;
+ case NTEXT:
+ out<<"SmTextNode: ";
+ out<< ByteString( ((SmTextNode*)this)->GetText(), RTL_TEXTENCODING_UTF8).GetBuffer();
+ break;
+ case NSPECIAL: out<<"SmSpecialNode"; break;
+ case NGLYPH_SPECIAL: out<<"SmGlyphSpecialNode"; break;
+ case NMATH:
+ out<<"SmMathSymbolNode: ";
+ out<< ByteString( ((SmMathSymbolNode*)this)->GetText(), RTL_TEXTENCODING_UTF8).GetBuffer();
+ break;
+ case NBLANK: out<<"SmBlankNode"; break;
+ case NERROR: out<<"SmErrorNode"; break;
+ case NLINE: out<<"SmLineNode"; break;
+ case NEXPRESSION: out<<"SmExpressionNode"; break;
+ case NPOLYLINE: out<<"SmPolyLineNode"; break;
+ case NROOT: out<<"SmRootNode"; break;
+ case NROOTSYMBOL: out<<"SmRootSymbolNode"; break;
+ case NRECTANGLE: out<<"SmRectangleNode"; break;
+ case NVERTICAL_BRACE: out<<"SmVerticalBraceNode"; break;
+ default:
+ out<<"Unknown Node";
+ }
+ out<<"\"";
+ if(IsSelected())
+ out<<", style=dashed";
+ out<<"];"<<std::endl;
+
+ //Dump subnodes
+ int myid = id;
+ const SmNode *pNode;
+ USHORT nSize = GetNumSubNodes();
+ for (USHORT i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->DumpAsDot(out, NULL, i, ++id, myid);
+
+ //If this is the root end the file
+ if( number == -1 )
+ out<<"}"<<std::endl;
+}
+#endif /* DEBUG_ENABLE_DUMPASDOT */
+
+long SmNode::GetFormulaBaseline() const
+{
+ DBG_ASSERT( 0, "This dummy implementation should not have been called." );
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+SmStructureNode::SmStructureNode( const SmStructureNode &rNode ) :
+ SmNode( rNode.GetType(), rNode.GetToken() )
+{
+ sal_uLong i;
+ for (i = 0; i < aSubNodes.size(); i++)
+ delete aSubNodes[i];
+ aSubNodes.resize(0);
+
+ sal_uLong nSize = rNode.aSubNodes.size();
+ aSubNodes.resize( nSize );
+ for (i = 0; i < nSize; ++i)
+ {
+ SmNode *pNode = rNode.aSubNodes[i];
+ aSubNodes[i] = pNode ? new SmNode( *pNode ) : 0;
+ }
+ ClaimPaternity();
+}
+
+
+SmStructureNode::~SmStructureNode()
+{
+ SmNode *pNode;
+
+ for (sal_uInt16 i = 0; i < GetNumSubNodes(); i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ delete pNode;
+}
+
+
+SmStructureNode & SmStructureNode::operator = ( const SmStructureNode &rNode )
+{
+ SmNode::operator = ( rNode );
+
+ sal_uLong i;
+ for (i = 0; i < aSubNodes.size(); i++)
+ delete aSubNodes[i];
+ aSubNodes.resize(0);
+
+ sal_uLong nSize = rNode.aSubNodes.size();
+ aSubNodes.resize( nSize );
+ for (i = 0; i < nSize; ++i)
+ {
+ SmNode *pNode = rNode.aSubNodes[i];
+ aSubNodes[i] = pNode ? new SmNode( *pNode ) : 0;
+ }
+
+ ClaimPaternity();
+
+ return *this;
+}
+
+
+void SmStructureNode::SetSubNodes(SmNode *pFirst, SmNode *pSecond, SmNode *pThird)
+{
+ size_t nSize = pThird ? 3 : (pSecond ? 2 : (pFirst ? 1 : 0));
+ aSubNodes.resize( nSize );
+ if (pFirst)
+ aSubNodes[0] = pFirst;
+ if (pSecond)
+ aSubNodes[1] = pSecond;
+ if (pThird)
+ aSubNodes[2] = pThird;
+
+ ClaimPaternity();
+}
+
+
+void SmStructureNode::SetSubNodes(const SmNodeArray &rNodeArray)
+{
+ aSubNodes = rNodeArray;
+ ClaimPaternity();
+}
+
+
+bool SmStructureNode::IsVisible() const
+{
+ return false;
+}
+
+
+sal_uInt16 SmStructureNode::GetNumSubNodes() const
+{
+ return (sal_uInt16) aSubNodes.size();
+}
+
+
+SmNode * SmStructureNode::GetSubNode(sal_uInt16 nIndex)
+{
+ return aSubNodes[nIndex];
+}
+
+
+void SmStructureNode::GetAccessibleText( String &rText ) const
+{
+ sal_uInt16 nNodes = GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nNodes; ++i)
+ {
+ const SmNode *pNode = ((SmStructureNode *) this)->GetSubNode(i);
+ if (pNode)
+ {
+ if (pNode->IsVisible())
+ ((SmStructureNode *) pNode)->nAccIndex = rText.Len();
+ pNode->GetAccessibleText( rText );
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+
+bool SmVisibleNode::IsVisible() const
+{
+ return true;
+}
+
+
+sal_uInt16 SmVisibleNode::GetNumSubNodes() const
+{
+ return 0;
+}
+
+
+SmNode * SmVisibleNode::GetSubNode(sal_uInt16 /*nIndex*/)
+{
+ return NULL;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+void SmGraphicNode::GetAccessibleText( String &rText ) const
+{
+ rText += GetToken().aText;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+
+void SmExpressionNode::CreateTextFromNode(String &rText)
+{
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ if (nSize > 1)
+ rText.Append('{');
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ {
+ pNode->CreateTextFromNode(rText);
+ //Just a bit of foo to make unary +asd -asd +-asd -+asd look nice
+ if (pNode->GetType() == NMATH)
+ if ((nSize != 2) || ((rText.GetChar(rText.Len()-1) != '+') &&
+ (rText.GetChar(rText.Len()-1) != '-')))
+ rText.Append(' ');
+ }
+
+ if (nSize > 1)
+ {
+ rText.EraseTrailingChars();
+ APPEND(rText,"} ");
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+void SmTableNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+ // arranges all subnodes in one column
+{
+ Point rPosition;
+
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+
+ // make distance depend on font size
+ long nDist = +(rFormat.GetDistance(DIS_VERTICAL)
+ * GetFont().GetSize().Height()) / 100L;
+
+ if (nSize < 1)
+ return;
+
+ // arrange subnodes and get maximum width of them
+ long nMaxWidth = 0,
+ nTmp;
+ sal_uInt16 i;
+ for (i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ { pNode->Arrange(rDev, rFormat);
+ if ((nTmp = pNode->GetItalicWidth()) > nMaxWidth)
+ nMaxWidth = nTmp;
+ }
+
+ Point aPos;
+ SmRect::operator = (SmRect(nMaxWidth, 1));
+ for (i = 0; i < nSize; i++)
+ { if (NULL != (pNode = GetSubNode(i)))
+ { const SmRect &rNodeRect = pNode->GetRect();
+ const SmNode *pCoNode = pNode->GetLeftMost();
+ RectHorAlign eHorAlign = pCoNode->GetRectHorAlign();
+
+ aPos = rNodeRect.AlignTo(*this, RP_BOTTOM,
+ eHorAlign, RVA_BASELINE);
+ if (i)
+ aPos.Y() += nDist;
+ pNode->MoveTo(aPos);
+ ExtendBy(rNodeRect, nSize > 1 ? RCP_NONE : RCP_ARG);
+ }
+ }
+ // --> 4.7.2010 #i972#
+ if (HasBaseline())
+ nFormulaBaseline = GetBaseline();
+ else
+ {
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, sal_True);
+ aTmpDev.SetFont(GetFont());
+
+ SmRect aRect = (SmRect(aTmpDev, &rFormat, C2S("a"),
+ GetFont().GetBorderWidth()));
+ nFormulaBaseline = GetAlignM();
+ // move from middle position by constant - distance
+ // between middle and baseline for single letter
+ nFormulaBaseline += aRect.GetBaseline() - aRect.GetAlignM();
+ }
+ // <--
+}
+
+
+SmNode * SmTableNode::GetLeftMost()
+{
+ return this;
+}
+
+
+long SmTableNode::GetFormulaBaseline() const
+{
+ return nFormulaBaseline;
+}
+
+
+/**************************************************************************/
+
+
+void SmLineNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+ SmNode::Prepare(rFormat, rDocShell);
+
+ //! wir verwenden hier den 'FNT_VARIABLE' Font, da er vom Ascent und Descent
+ //! ia besser zum Rest der Formel passt als der 'FNT_MATH' Font.
+ GetFont() = rFormat.GetFont(FNT_VARIABLE);
+ Flags() |= FLG_FONT;
+}
+
+
+/**************************************************************************/
+
+
+void SmLineNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+ // arranges all subnodes in one row with some extra space between
+{
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ sal_uInt16 i;
+ for (i = 0; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ pNode->Arrange(rDev, rFormat);
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ if (nSize < 1)
+ {
+ // provide an empty rectangle with alignment parameters for the "current"
+ // font (in order to make "a^1 {}_2^3 a_4" work correct, that is, have the
+ // same sub-/supscript positions.)
+ //! be sure to use a character that has explicitly defined HiAttribut
+ //! line in rect.cxx such as 'a' in order to make 'vec a' look same to
+ //! 'vec {a}'.
+ SmRect::operator = (SmRect(aTmpDev, &rFormat, C2S("a"),
+ GetFont().GetBorderWidth()));
+ // make sure that the rectangle occupies (almost) no space
+ SetWidth(1);
+ SetItalicSpaces(0, 0);
+ return;
+ }
+
+ // make distance depend on font size
+ long nDist = (rFormat.GetDistance(DIS_HORIZONTAL) * GetFont().GetSize().Height()) / 100L;
+ if (!IsUseExtraSpaces())
+ nDist = 0;
+
+ Point aPos;
+ // copy the first node into LineNode and extend by the others
+ if (NULL != (pNode = GetSubNode(0)))
+ SmRect::operator = (pNode->GetRect());
+
+ for (i = 1; i < nSize; i++)
+ if (NULL != (pNode = GetSubNode(i)))
+ {
+ aPos = pNode->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
+
+ // add horizontal space to the left for each but the first sub node
+ aPos.X() += nDist;
+
+ pNode->MoveTo(aPos);
+ ExtendBy( *pNode, RCP_XOR );
+ }
+}
+
+
+/**************************************************************************/
+
+
+void SmExpressionNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+ // as 'SmLineNode::Arrange' but keeps alignment of leftmost subnode
+{
+ SmLineNode::Arrange(rDev, rFormat);
+
+ // copy alignment of leftmost subnode if any
+ SmNode *pNode = GetLeftMost();
+ if (pNode)
+ SetRectHorAlign(pNode->GetRectHorAlign(), false);
+}
+
+
+/**************************************************************************/
+
+
+void SmUnHorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ bool bIsPostfix = GetToken().eType == TFACT;
+
+ SmNode *pOper = GetSubNode(bIsPostfix ? 1 : 0),
+ *pBody = GetSubNode(bIsPostfix ? 0 : 1);
+ OSL_ENSURE(pOper, "Sm: NULL pointer");
+ OSL_ENSURE(pBody, "Sm: NULL pointer");
+
+ pOper->SetSize(Fraction (rFormat.GetRelSize(SIZ_OPERATOR), 100));
+ pOper->Arrange(rDev, rFormat);
+ pBody->Arrange(rDev, rFormat);
+
+ Point aPos = pOper->AlignTo(*pBody, bIsPostfix ? RP_RIGHT : RP_LEFT,
+ RHA_CENTER, RVA_BASELINE);
+ // add a bit space between operator and argument
+ // (worst case -{1 over 2} where - and over have almost no space inbetween)
+ long nDelta = pOper->GetFont().GetSize().Height() / 20;
+ if (bIsPostfix)
+ aPos.X() += nDelta;
+ else
+ aPos.X() -= nDelta;
+ pOper->MoveTo(aPos);
+
+ SmRect::operator = (*pBody);
+ long nOldBot = GetBottom();
+
+ ExtendBy(*pOper, RCP_XOR);
+
+ // workaround for Bug 50865: "a^2 a^+2" have different baselines
+ // for exponents (if size of exponent is large enough)
+ SetBottom(nOldBot);
+}
+
+
+/**************************************************************************/
+
+
+void SmRootNode::GetHeightVerOffset(const SmRect &rRect,
+ long &rHeight, long &rVerOffset) const
+ // calculate height and vertical offset of root sign suitable for 'rRect'
+{
+ rVerOffset = (rRect.GetBottom() - rRect.GetAlignB()) / 2;
+ rHeight = rRect.GetHeight() - rVerOffset;
+
+ OSL_ENSURE(rHeight >= 0, "Sm : Ooops...");
+ OSL_ENSURE(rVerOffset >= 0, "Sm : Ooops...");
+}
+
+
+Point SmRootNode::GetExtraPos(const SmRect &rRootSymbol,
+ const SmRect &rExtra) const
+{
+ const Size &rSymSize = rRootSymbol.GetSize();
+
+ Point aPos = rRootSymbol.GetTopLeft()
+ + Point((rSymSize.Width() * 70) / 100,
+ (rSymSize.Height() * 52) / 100);
+
+ // from this calculate topleft edge of 'rExtra'
+ aPos.X() -= rExtra.GetWidth() + rExtra.GetItalicRightSpace();
+ aPos.Y() -= rExtra.GetHeight();
+ // if there's enough space move a bit less to the right
+ // examples: "nroot i a", "nroot j a"
+ // (it looks better if we don't use italic-spaces here)
+ long nX = rRootSymbol.GetLeft() + (rSymSize.Width() * 30) / 100;
+ if (aPos.X() > nX)
+ aPos.X() = nX;
+
+ return aPos;
+}
+
+
+void SmRootNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ //! pExtra needs to have the smaller index than pRootSym in order to
+ //! not to get the root symbol but the pExtra when clicking on it in the
+ //! GraphicWindow. (That is because of the simplicity of the algorithm
+ //! that finds the node corresponding to a mouseclick in the window.)
+ SmNode *pExtra = GetSubNode(0),
+ *pRootSym = GetSubNode(1),
+ *pBody = GetSubNode(2);
+ OSL_ENSURE(pRootSym, "Sm: NULL pointer");
+ OSL_ENSURE(pBody, "Sm: NULL pointer");
+
+ pBody->Arrange(rDev, rFormat);
+
+ long nHeight,
+ nVerOffset;
+ GetHeightVerOffset(*pBody, nHeight, nVerOffset);
+ nHeight += rFormat.GetDistance(DIS_ROOT)
+ * GetFont().GetSize().Height() / 100L;
+
+ // font specialist advised to change the width first
+ pRootSym->AdaptToY(rDev, nHeight);
+ pRootSym->AdaptToX(rDev, pBody->GetItalicWidth());
+
+ pRootSym->Arrange(rDev, rFormat);
+
+ Point aPos = pRootSym->AlignTo(*pBody, RP_LEFT, RHA_CENTER, RVA_BASELINE);
+ //! overrride calulated vertical position
+ aPos.Y() = pRootSym->GetTop() + pBody->GetBottom() - pRootSym->GetBottom();
+ aPos.Y() -= nVerOffset;
+ pRootSym->MoveTo(aPos);
+
+ if (pExtra)
+ { pExtra->SetSize(Fraction(rFormat.GetRelSize(SIZ_INDEX), 100));
+ pExtra->Arrange(rDev, rFormat);
+
+ aPos = GetExtraPos(*pRootSym, *pExtra);
+ pExtra->MoveTo(aPos);
+ }
+
+ SmRect::operator = (*pBody);
+ ExtendBy(*pRootSym, RCP_THIS);
+ if (pExtra)
+ ExtendBy(*pExtra, RCP_THIS, true);
+}
+
+
+void SmRootNode::CreateTextFromNode(String &rText)
+{
+ SmNode *pExtra = GetSubNode(0);
+ if (pExtra)
+ {
+ APPEND(rText,"nroot ");
+ pExtra->CreateTextFromNode(rText);
+ }
+ else
+ APPEND(rText,"sqrt ");
+ GetSubNode(2)->CreateTextFromNode(rText);
+}
+
+
+/**************************************************************************/
+
+
+void SmBinHorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmNode *pLeft = GetSubNode(0),
+ *pOper = GetSubNode(1),
+ *pRight = GetSubNode(2);
+ OSL_ENSURE(pLeft != NULL, "Sm: NULL pointer");
+ OSL_ENSURE(pOper != NULL, "Sm: NULL pointer");
+ OSL_ENSURE(pRight != NULL, "Sm: NULL pointer");
+
+ pOper->SetSize(Fraction (rFormat.GetRelSize(SIZ_OPERATOR), 100));
+
+ pLeft ->Arrange(rDev, rFormat);
+ pOper ->Arrange(rDev, rFormat);
+ pRight->Arrange(rDev, rFormat);
+
+ const SmRect &rOpRect = pOper->GetRect();
+
+ long nDist = (rOpRect.GetWidth() *
+ rFormat.GetDistance(DIS_HORIZONTAL)) / 100L;
+
+ SmRect::operator = (*pLeft);
+
+ Point aPos;
+ aPos = pOper->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
+ aPos.X() += nDist;
+ pOper->MoveTo(aPos);
+ ExtendBy(*pOper, RCP_XOR);
+
+ aPos = pRight->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
+ aPos.X() += nDist;
+
+ pRight->MoveTo(aPos);
+ ExtendBy(*pRight, RCP_XOR);
+}
+
+
+/**************************************************************************/
+
+
+void SmBinVerNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmNode *pNum = GetSubNode(0),
+ *pLine = GetSubNode(1),
+ *pDenom = GetSubNode(2);
+ OSL_ENSURE(pNum, "Sm : NULL pointer");
+ OSL_ENSURE(pLine, "Sm : NULL pointer");
+ OSL_ENSURE(pDenom, "Sm : NULL pointer");
+
+ bool bIsTextmode = rFormat.IsTextmode();
+ if (bIsTextmode)
+ {
+ Fraction aFraction(rFormat.GetRelSize(SIZ_INDEX), 100);
+ pNum ->SetSize(aFraction);
+ pLine ->SetSize(aFraction);
+ pDenom->SetSize(aFraction);
+ }
+
+ pNum ->Arrange(rDev, rFormat);
+ pDenom->Arrange(rDev, rFormat);
+
+ long nFontHeight = GetFont().GetSize().Height(),
+ nExtLen = nFontHeight * rFormat.GetDistance(DIS_FRACTION) / 100L,
+ nThick = nFontHeight * rFormat.GetDistance(DIS_STROKEWIDTH) / 100L,
+ nWidth = Max(pNum->GetItalicWidth(), pDenom->GetItalicWidth()),
+ nNumDist = bIsTextmode ? 0 :
+ nFontHeight * rFormat.GetDistance(DIS_NUMERATOR) / 100L,
+ nDenomDist = bIsTextmode ? 0 :
+ nFontHeight * rFormat.GetDistance(DIS_DENOMINATOR) / 100L;
+
+ // font specialist advised to change the width first
+ pLine->AdaptToY(rDev, nThick);
+ pLine->AdaptToX(rDev, nWidth + 2 * nExtLen);
+ pLine->Arrange(rDev, rFormat);
+
+ // get horizontal alignment for numerator
+ const SmNode *pLM = pNum->GetLeftMost();
+ RectHorAlign eHorAlign = pLM->GetRectHorAlign();
+
+ // move numerator to its position
+ Point aPos = pNum->AlignTo(*pLine, RP_TOP, eHorAlign, RVA_BASELINE);
+ aPos.Y() -= nNumDist;
+ pNum->MoveTo(aPos);
+
+ // get horizontal alignment for denominator
+ pLM = pDenom->GetLeftMost();
+ eHorAlign = pLM->GetRectHorAlign();
+
+ // move denominator to its position
+ aPos = pDenom->AlignTo(*pLine, RP_BOTTOM, eHorAlign, RVA_BASELINE);
+ aPos.Y() += nDenomDist;
+ pDenom->MoveTo(aPos);
+
+ SmRect::operator = (*pNum);
+ ExtendBy(*pDenom, RCP_NONE).ExtendBy(*pLine, RCP_NONE, pLine->GetCenterY());
+}
+
+void SmBinVerNode::CreateTextFromNode(String &rText)
+{
+ SmNode *pNum = GetSubNode(0),
+ *pDenom = GetSubNode(2);
+ pNum->CreateTextFromNode(rText);
+ APPEND(rText,"over ");
+ pDenom->CreateTextFromNode(rText);
+}
+
+
+SmNode * SmBinVerNode::GetLeftMost()
+{
+ return this;
+}
+
+
+/**************************************************************************/
+
+
+double Det(const Point &rHeading1, const Point &rHeading2)
+ // gibt den Wert der durch die beiden Punkte gebildeten Determinante
+ // zurueck
+{
+ return rHeading1.X() * rHeading2.Y() - rHeading1.Y() * rHeading2.X();
+}
+
+
+bool IsPointInLine(const Point &rPoint1,
+ const Point &rPoint2, const Point &rHeading2)
+ // ergibt true genau dann, wenn der Punkt 'rPoint1' zu der Gerade gehoert die
+ // durch den Punkt 'rPoint2' geht und den Richtungsvektor 'rHeading2' hat
+{
+ OSL_ENSURE(rHeading2 != Point(), "Sm : 0 vector");
+
+ bool bRes = false;
+ const double eps = 5.0 * DBL_EPSILON;
+
+ double fLambda;
+ if (labs(rHeading2.X()) > labs(rHeading2.Y()))
+ {
+ fLambda = (rPoint1.X() - rPoint2.X()) / (double) rHeading2.X();
+ bRes = fabs(rPoint1.Y() - (rPoint2.Y() + fLambda * rHeading2.Y())) < eps;
+ }
+ else
+ {
+ fLambda = (rPoint1.Y() - rPoint2.Y()) / (double) rHeading2.Y();
+ bRes = fabs(rPoint1.X() - (rPoint2.X() + fLambda * rHeading2.X())) < eps;
+ }
+
+ return bRes;
+}
+
+
+sal_uInt16 GetLineIntersectionPoint(Point &rResult,
+ const Point& rPoint1, const Point &rHeading1,
+ const Point& rPoint2, const Point &rHeading2)
+{
+ OSL_ENSURE(rHeading1 != Point(), "Sm : 0 vector");
+ OSL_ENSURE(rHeading2 != Point(), "Sm : 0 vector");
+
+ sal_uInt16 nRes = 1;
+ const double eps = 5.0 * DBL_EPSILON;
+
+ // sind die Richtumgsvektoren linear abhaengig ?
+ double fDet = Det(rHeading1, rHeading2);
+ if (fabs(fDet) < eps)
+ {
+ nRes = IsPointInLine(rPoint1, rPoint2, rHeading2) ? USHRT_MAX : 0;
+ rResult = nRes ? rPoint1 : Point();
+ }
+ else
+ {
+ // hier achten wir nicht auf Rechengenauigkeit
+ // (das wuerde aufwendiger und lohnt sich hier kaum)
+ double fLambda = ( (rPoint1.Y() - rPoint2.Y()) * rHeading2.X()
+ - (rPoint1.X() - rPoint2.X()) * rHeading2.Y())
+ / fDet;
+ rResult = Point(rPoint1.X() + (long) (fLambda * rHeading1.X()),
+ rPoint1.Y() + (long) (fLambda * rHeading1.Y()));
+ }
+
+ return nRes;
+}
+
+
+
+SmBinDiagonalNode::SmBinDiagonalNode(const SmToken &rNodeToken)
+: SmStructureNode(NBINDIAGONAL, rNodeToken)
+{
+ bAscending = false;
+ SetNumSubNodes(3);
+}
+
+
+void SmBinDiagonalNode::GetOperPosSize(Point &rPos, Size &rSize,
+ const Point &rDiagPoint, double fAngleDeg) const
+ // gibt die Position und Groesse fuer den Diagonalstrich zurueck.
+ // Vor.: das SmRect des Nodes gibt die Begrenzung vor(!), muss also selbst
+ // bereits bekannt sein.
+
+{
+ const double fPi = 3.1415926535897932384626433;
+ double fAngleRad = fAngleDeg / 180.0 * fPi;
+ long nRectLeft = GetItalicLeft(),
+ nRectRight = GetItalicRight(),
+ nRectTop = GetTop(),
+ nRectBottom = GetBottom();
+ Point aRightHdg (100, 0),
+ aDownHdg (0, 100),
+ aDiagHdg ( (long)(100.0 * cos(fAngleRad)),
+ (long)(-100.0 * sin(fAngleRad)) );
+
+ long nLeft, nRight, nTop, nBottom; // Raender des Rechtecks fuer die
+ // Diagonale
+ Point aPoint;
+ if (IsAscending())
+ {
+ //
+ // obere rechte Ecke bestimmen
+ //
+ GetLineIntersectionPoint(aPoint,
+ Point(nRectLeft, nRectTop), aRightHdg,
+ rDiagPoint, aDiagHdg);
+ //
+ // gibt es einen Schnittpunkt mit dem oberen Rand ?
+ if (aPoint.X() <= nRectRight)
+ {
+ nRight = aPoint.X();
+ nTop = nRectTop;
+ }
+ else
+ {
+ // es muss einen Schnittpunkt mit dem rechten Rand geben!
+ GetLineIntersectionPoint(aPoint,
+ Point(nRectRight, nRectTop), aDownHdg,
+ rDiagPoint, aDiagHdg);
+
+ nRight = nRectRight;
+ nTop = aPoint.Y();
+ }
+
+ //
+ // untere linke Ecke bestimmen
+ //
+ GetLineIntersectionPoint(aPoint,
+ Point(nRectLeft, nRectBottom), aRightHdg,
+ rDiagPoint, aDiagHdg);
+ //
+ // gibt es einen Schnittpunkt mit dem unteren Rand ?
+ if (aPoint.X() >= nRectLeft)
+ {
+ nLeft = aPoint.X();
+ nBottom = nRectBottom;
+ }
+ else
+ {
+ // es muss einen Schnittpunkt mit dem linken Rand geben!
+ GetLineIntersectionPoint(aPoint,
+ Point(nRectLeft, nRectTop), aDownHdg,
+ rDiagPoint, aDiagHdg);
+
+ nLeft = nRectLeft;
+ nBottom = aPoint.Y();
+ }
+ }
+ else
+ {
+ //
+ // obere linke Ecke bestimmen
+ //
+ GetLineIntersectionPoint(aPoint,
+ Point(nRectLeft, nRectTop), aRightHdg,
+ rDiagPoint, aDiagHdg);
+ //
+ // gibt es einen Schnittpunkt mit dem oberen Rand ?
+ if (aPoint.X() >= nRectLeft)
+ {
+ nLeft = aPoint.X();
+ nTop = nRectTop;
+ }
+ else
+ {
+ // es muss einen Schnittpunkt mit dem linken Rand geben!
+ GetLineIntersectionPoint(aPoint,
+ Point(nRectLeft, nRectTop), aDownHdg,
+ rDiagPoint, aDiagHdg);
+
+ nLeft = nRectLeft;
+ nTop = aPoint.Y();
+ }
+
+ //
+ // untere rechte Ecke bestimmen
+ //
+ GetLineIntersectionPoint(aPoint,
+ Point(nRectLeft, nRectBottom), aRightHdg,
+ rDiagPoint, aDiagHdg);
+ //
+ // gibt es einen Schnittpunkt mit dem unteren Rand ?
+ if (aPoint.X() <= nRectRight)
+ {
+ nRight = aPoint.X();
+ nBottom = nRectBottom;
+ }
+ else
+ {
+ // es muss einen Schnittpunkt mit dem rechten Rand geben!
+ GetLineIntersectionPoint(aPoint,
+ Point(nRectRight, nRectTop), aDownHdg,
+ rDiagPoint, aDiagHdg);
+
+ nRight = nRectRight;
+ nBottom = aPoint.Y();
+ }
+ }
+
+ rSize = Size(nRight - nLeft + 1, nBottom - nTop + 1);
+ rPos.X() = nLeft;
+ rPos.Y() = nTop;
+}
+
+
+void SmBinDiagonalNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ //! die beiden Argumente muessen in den Subnodes vor dem Operator kommen,
+ //! damit das anklicken im GraphicWindow den FormulaCursor richtig setzt
+ //! (vgl SmRootNode)
+ SmNode *pLeft = GetSubNode(0),
+ *pRight = GetSubNode(1);
+ OSL_ENSURE(pLeft, "Sm : NULL pointer");
+ OSL_ENSURE(pRight, "Sm : NULL pointer");
+
+ OSL_ENSURE(GetSubNode(2)->GetType() == NPOLYLINE, "Sm : wrong node type");
+ SmPolyLineNode *pOper = (SmPolyLineNode *) GetSubNode(2);
+ OSL_ENSURE(pOper, "Sm : NULL pointer");
+
+ //! some routines being called extract some info from the OutputDevice's
+ //! font (eg the space to be used for borders OR the font name(!!)).
+ //! Thus the font should reflect the needs and has to be set!
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ pLeft->Arrange(aTmpDev, rFormat);
+ pRight->Arrange(aTmpDev, rFormat);
+
+ // implizit die Weite (incl Rand) des Diagonalstrichs ermitteln
+ pOper->Arrange(aTmpDev, rFormat);
+
+ long nDelta = pOper->GetWidth() * 8 / 10;
+
+ // TopLeft Position vom rechten Argument ermitteln
+ Point aPos;
+ aPos.X() = pLeft->GetItalicRight() + nDelta + pRight->GetItalicLeftSpace();
+ if (IsAscending())
+ aPos.Y() = pLeft->GetBottom() + nDelta;
+ else
+ aPos.Y() = pLeft->GetTop() - nDelta - pRight->GetHeight();
+
+ pRight->MoveTo(aPos);
+
+ // neue Baseline bestimmen
+ long nTmpBaseline = IsAscending() ? (pLeft->GetBottom() + pRight->GetTop()) / 2
+ : (pLeft->GetTop() + pRight->GetBottom()) / 2;
+ Point aLogCenter ((pLeft->GetItalicRight() + pRight->GetItalicLeft()) / 2,
+ nTmpBaseline);
+
+ SmRect::operator = (*pLeft);
+ ExtendBy(*pRight, RCP_NONE);
+
+
+ // Position und Groesse des Diagonalstrich ermitteln
+ Size aTmpSize;
+ GetOperPosSize(aPos, aTmpSize, aLogCenter, IsAscending() ? 60.0 : -60.0);
+
+ // font specialist advised to change the width first
+ pOper->AdaptToY(aTmpDev, aTmpSize.Height());
+ pOper->AdaptToX(aTmpDev, aTmpSize.Width());
+ // und diese wirksam machen
+ pOper->Arrange(aTmpDev, rFormat);
+
+ pOper->MoveTo(aPos);
+
+ ExtendBy(*pOper, RCP_NONE, nTmpBaseline);
+}
+
+
+/**************************************************************************/
+
+
+void SmSubSupNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ OSL_ENSURE(GetNumSubNodes() == 1 + SUBSUP_NUM_ENTRIES,
+ "Sm: wrong number of subnodes");
+
+ SmNode *pBody = GetBody();
+ OSL_ENSURE(pBody, "Sm: NULL pointer");
+
+ long nOrigHeight = pBody->GetFont().GetSize().Height();
+
+ pBody->Arrange(rDev, rFormat);
+
+ const SmRect &rBodyRect = pBody->GetRect();
+ SmRect::operator = (rBodyRect);
+
+ // line that separates sub- and supscript rectangles
+ long nDelimLine = SmFromTo(GetAlignB(), GetAlignT(), 0.4);
+
+ Point aPos;
+ long nDelta, nDist;
+
+ // iterate over all possible sub-/supscripts
+ SmRect aTmpRect (rBodyRect);
+ for (int i = 0; i < SUBSUP_NUM_ENTRIES; i++)
+ { SmSubSup eSubSup = (SmSubSup) i; // cast
+ SmNode *pSubSup = GetSubSup(eSubSup);
+
+ if (!pSubSup)
+ continue;
+
+ // switch position of limits if we are in textmode
+ if (rFormat.IsTextmode() && (GetToken().nGroup & TGLIMIT))
+ switch (eSubSup)
+ { case CSUB: eSubSup = RSUB; break;
+ case CSUP: eSubSup = RSUP; break;
+ default:
+ break;
+ }
+
+ // prevent sub-/supscripts from diminishing in size
+ // (as would be in "a_{1_{2_{3_4}}}")
+ if (GetFont().GetSize().Height() > rFormat.GetBaseSize().Height() / 3)
+ {
+ sal_uInt16 nIndex = (eSubSup == CSUB || eSubSup == CSUP) ?
+ SIZ_LIMITS : SIZ_INDEX;
+ Fraction aFraction ( rFormat.GetRelSize(nIndex), 100 );
+ pSubSup->SetSize(aFraction);
+ }
+
+ pSubSup->Arrange(rDev, rFormat);
+
+ bool bIsTextmode = rFormat.IsTextmode();
+ nDist = 0;
+
+ //! be sure that CSUB, CSUP are handled before the other cases!
+ switch (eSubSup)
+ { case RSUB :
+ case LSUB :
+ if (!bIsTextmode)
+ nDist = nOrigHeight
+ * rFormat.GetDistance(DIS_SUBSCRIPT) / 100L;
+ aPos = pSubSup->GetRect().AlignTo(aTmpRect,
+ eSubSup == LSUB ? RP_LEFT : RP_RIGHT,
+ RHA_CENTER, RVA_BOTTOM);
+ aPos.Y() += nDist;
+ nDelta = nDelimLine - aPos.Y();
+ if (nDelta > 0)
+ aPos.Y() += nDelta;
+ break;
+ case RSUP :
+ case LSUP :
+ if (!bIsTextmode)
+ nDist = nOrigHeight
+ * rFormat.GetDistance(DIS_SUPERSCRIPT) / 100L;
+ aPos = pSubSup->GetRect().AlignTo(aTmpRect,
+ eSubSup == LSUP ? RP_LEFT : RP_RIGHT,
+ RHA_CENTER, RVA_TOP);
+ aPos.Y() -= nDist;
+ nDelta = aPos.Y() + pSubSup->GetHeight() - nDelimLine;
+ if (nDelta > 0)
+ aPos.Y() -= nDelta;
+ break;
+ case CSUB :
+ if (!bIsTextmode)
+ nDist = nOrigHeight
+ * rFormat.GetDistance(DIS_LOWERLIMIT) / 100L;
+ aPos = pSubSup->GetRect().AlignTo(rBodyRect, RP_BOTTOM,
+ RHA_CENTER, RVA_BASELINE);
+ aPos.Y() += nDist;
+ break;
+ case CSUP :
+ if (!bIsTextmode)
+ nDist = nOrigHeight
+ * rFormat.GetDistance(DIS_UPPERLIMIT) / 100L;
+ aPos = pSubSup->GetRect().AlignTo(rBodyRect, RP_TOP,
+ RHA_CENTER, RVA_BASELINE);
+ aPos.Y() -= nDist;
+ break;
+ default :
+ OSL_FAIL("Sm: unknown case");
+ break;
+ }
+
+ pSubSup->MoveTo(aPos);
+ ExtendBy(*pSubSup, RCP_THIS, true);
+
+ // update rectangle to which RSUB, RSUP, LSUB, LSUP
+ // will be aligned to
+ if (eSubSup == CSUB || eSubSup == CSUP)
+ aTmpRect = *this;
+ }
+}
+
+void SmSubSupNode::CreateTextFromNode(String &rText)
+{
+ SmNode *pNode;
+ GetSubNode(0)->CreateTextFromNode(rText);
+
+ if (NULL != (pNode = GetSubNode(LSUB+1)))
+ {
+ APPEND(rText,"lsub ");
+ pNode->CreateTextFromNode(rText);
+ }
+ if (NULL != (pNode = GetSubNode(LSUP+1)))
+ {
+ APPEND(rText,"lsup ");
+ pNode->CreateTextFromNode(rText);
+ }
+ if (NULL != (pNode = GetSubNode(CSUB+1)))
+ {
+ APPEND(rText,"csub ");
+ pNode->CreateTextFromNode(rText);
+ }
+ if (NULL != (pNode = GetSubNode(CSUP+1)))
+ {
+ APPEND(rText,"csup ");
+ pNode->CreateTextFromNode(rText);
+ }
+ if (NULL != (pNode = GetSubNode(RSUB+1)))
+ {
+ rText.EraseTrailingChars();
+ rText.Append('_');
+ pNode->CreateTextFromNode(rText);
+ }
+ if (NULL != (pNode = GetSubNode(RSUP+1)))
+ {
+ rText.EraseTrailingChars();
+ rText.Append('^');
+ pNode->CreateTextFromNode(rText);
+ }
+}
+
+
+/**************************************************************************/
+
+void SmBraceNode::CreateTextFromNode(String &rText)
+{
+ if (GetScaleMode() == SCALE_HEIGHT)
+ APPEND(rText,"left ");
+ {
+ String aStr;
+ GetSubNode(0)->CreateTextFromNode(aStr);
+ aStr.EraseLeadingAndTrailingChars();
+ aStr.EraseLeadingChars('\\');
+ if (aStr.Len())
+ {
+ if (aStr.EqualsAscii("divides"))
+ APPEND(rText,"lline");
+ else if (aStr.EqualsAscii("parallel"))
+ APPEND(rText,"ldline");
+ else if (aStr.EqualsAscii("<"))
+ APPEND(rText,"langle");
+ else
+ rText.Append(aStr);
+ rText.Append(' ');
+ }
+ else
+ APPEND(rText,"none ");
+ }
+ GetSubNode(1)->CreateTextFromNode(rText);
+ if (GetScaleMode() == SCALE_HEIGHT)
+ APPEND(rText,"right ");
+ {
+ String aStr;
+ GetSubNode(2)->CreateTextFromNode(aStr);
+ aStr.EraseLeadingAndTrailingChars();
+ aStr.EraseLeadingChars('\\');
+ if (aStr.Len())
+ {
+ if (aStr.EqualsAscii("divides"))
+ APPEND(rText,"rline");
+ else if (aStr.EqualsAscii("parallel"))
+ APPEND(rText,"rdline");
+ else if (aStr.EqualsAscii(">"))
+ APPEND(rText,"rangle");
+ else
+ rText.Append(aStr);
+ rText.Append(' ');
+ }
+ else
+ APPEND(rText,"none ");
+ }
+ rText.Append(' ');
+
+}
+
+void SmBraceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmNode *pLeft = GetSubNode(0),
+ *pBody = GetSubNode(1),
+ *pRight = GetSubNode(2);
+ OSL_ENSURE(pLeft, "Sm: NULL pointer");
+ OSL_ENSURE(pBody, "Sm: NULL pointer");
+ OSL_ENSURE(pRight, "Sm: NULL pointer");
+
+ pBody->Arrange(rDev, rFormat);
+
+ bool bIsScaleNormal = rFormat.IsScaleNormalBrackets(),
+ bScale = pBody->GetHeight() > 0 &&
+ (GetScaleMode() == SCALE_HEIGHT || bIsScaleNormal),
+ bIsABS = GetToken().eType == TABS;
+
+ long nFaceHeight = GetFont().GetSize().Height();
+
+ // Uebergroesse in % ermitteln
+ sal_uInt16 nPerc = 0;
+ if (!bIsABS && bScale)
+ { // im Fall von Klammern mit Uebergroesse...
+ sal_uInt16 nIndex = GetScaleMode() == SCALE_HEIGHT ?
+ DIS_BRACKETSIZE : DIS_NORMALBRACKETSIZE;
+ nPerc = rFormat.GetDistance(nIndex);
+ }
+
+ // ermitteln der Hoehe fuer die Klammern
+ long nBraceHeight;
+ if (bScale)
+ {
+ nBraceHeight = pBody->GetType() == NBRACEBODY ?
+ ((SmBracebodyNode *) pBody)->GetBodyHeight()
+ : pBody->GetHeight();
+ nBraceHeight += 2 * (nBraceHeight * nPerc / 100L);
+ }
+ else
+ nBraceHeight = nFaceHeight;
+
+ // Abstand zum Argument
+ nPerc = bIsABS ? 0 : rFormat.GetDistance(DIS_BRACKETSPACE);
+ long nDist = nFaceHeight * nPerc / 100L;
+
+ // sofern erwuenscht skalieren der Klammern auf die gewuenschte Groesse
+ if (bScale)
+ {
+ Size aTmpSize (pLeft->GetFont().GetSize());
+ OSL_ENSURE(pRight->GetFont().GetSize() == aTmpSize,
+ "Sm : different font sizes");
+ aTmpSize.Width() = Min((long) nBraceHeight * 60L / 100L,
+ rFormat.GetBaseSize().Height() * 3L / 2L);
+ // correction factor since change from StarMath to OpenSymbol font
+ // because of the different font width in the FontMetric
+ aTmpSize.Width() *= 182;
+ aTmpSize.Width() /= 267;
+
+ xub_Unicode cChar = pLeft->GetToken().cMathChar;
+ if (cChar != MS_LINE && cChar != MS_DLINE)
+ pLeft ->GetFont().SetSize(aTmpSize);
+
+ cChar = pRight->GetToken().cMathChar;
+ if (cChar != MS_LINE && cChar != MS_DLINE)
+ pRight->GetFont().SetSize(aTmpSize);
+
+ pLeft ->AdaptToY(rDev, nBraceHeight);
+ pRight->AdaptToY(rDev, nBraceHeight);
+ }
+
+ pLeft ->Arrange(rDev, rFormat);
+ pRight->Arrange(rDev, rFormat);
+
+ // damit auch "\(a\) - (a) - left ( a right )" vernuenftig aussieht
+ RectVerAlign eVerAlign = bScale ? RVA_CENTERY : RVA_BASELINE;
+
+ Point aPos;
+ aPos = pLeft->AlignTo(*pBody, RP_LEFT, RHA_CENTER, eVerAlign);
+ aPos.X() -= nDist;
+ pLeft->MoveTo(aPos);
+
+ aPos = pRight->AlignTo(*pBody, RP_RIGHT, RHA_CENTER, eVerAlign);
+ aPos.X() += nDist;
+ pRight->MoveTo(aPos);
+
+ SmRect::operator = (*pBody);
+ ExtendBy(*pLeft, RCP_THIS).ExtendBy(*pRight, RCP_THIS);
+}
+
+
+/**************************************************************************/
+
+
+void SmBracebodyNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ sal_uInt16 nNumSubNodes = GetNumSubNodes();
+ if (nNumSubNodes == 0)
+ return;
+
+ // arrange arguments
+ sal_uInt16 i;
+ for (i = 0; i < nNumSubNodes; i += 2)
+ GetSubNode(i)->Arrange(rDev, rFormat);
+
+ // build reference rectangle with necessary info for vertical alignment
+ SmRect aRefRect (*GetSubNode(0));
+ for (i = 0; i < nNumSubNodes; i += 2)
+ {
+ SmRect aTmpRect (*GetSubNode(i));
+ Point aPos = aTmpRect.AlignTo(aRefRect, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
+ aTmpRect.MoveTo(aPos);
+ aRefRect.ExtendBy(aTmpRect, RCP_XOR);
+ }
+
+ nBodyHeight = aRefRect.GetHeight();
+
+ // scale separators to required height and arrange them
+ bool bScale = GetScaleMode() == SCALE_HEIGHT || rFormat.IsScaleNormalBrackets();
+ long nHeight = bScale ? aRefRect.GetHeight() : GetFont().GetSize().Height();
+ sal_uInt16 nIndex = GetScaleMode() == SCALE_HEIGHT ?
+ DIS_BRACKETSIZE : DIS_NORMALBRACKETSIZE;
+ sal_uInt16 nPerc = rFormat.GetDistance(nIndex);
+ if (bScale)
+ nHeight += 2 * (nHeight * nPerc / 100L);
+ for (i = 1; i < nNumSubNodes; i += 2)
+ {
+ SmNode *pNode = GetSubNode(i);
+ pNode->AdaptToY(rDev, nHeight);
+ pNode->Arrange(rDev, rFormat);
+ }
+
+ // horizontal distance between argument and brackets or separators
+ long nDist = GetFont().GetSize().Height()
+ * rFormat.GetDistance(DIS_BRACKETSPACE) / 100L;
+
+ SmNode *pLeft = GetSubNode(0);
+ SmRect::operator = (*pLeft);
+ for (i = 1; i < nNumSubNodes; i++)
+ {
+ bool bIsSeparator = i % 2 != 0;
+ RectVerAlign eVerAlign = bIsSeparator ? RVA_CENTERY : RVA_BASELINE;
+
+ SmNode *pRight = GetSubNode(i);
+ Point aPosX = pRight->AlignTo(*pLeft, RP_RIGHT, RHA_CENTER, eVerAlign),
+ aPosY = pRight->AlignTo(aRefRect, RP_RIGHT, RHA_CENTER, eVerAlign);
+ aPosX.X() += nDist;
+
+ pRight->MoveTo(Point(aPosX.X(), aPosY.Y()));
+ ExtendBy(*pRight, bIsSeparator ? RCP_THIS : RCP_XOR);
+
+ pLeft = pRight;
+ }
+}
+
+
+/**************************************************************************/
+
+
+void SmVerticalBraceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmNode *pBody = GetSubNode(0),
+ *pBrace = GetSubNode(1),
+ *pScript = GetSubNode(2);
+ OSL_ENSURE(pBody, "Sm: NULL pointer!");
+ OSL_ENSURE(pBrace, "Sm: NULL pointer!");
+ OSL_ENSURE(pScript, "Sm: NULL pointer!");
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ pBody->Arrange(aTmpDev, rFormat);
+
+ // Groesse wie bei Grenzen fuer diesen Teil
+ pScript->SetSize( Fraction( rFormat.GetRelSize(SIZ_LIMITS), 100 ) );
+ // etwas hoehere Klammern als normal
+ pBrace ->SetSize( Fraction(3, 2) );
+
+ long nItalicWidth = pBody->GetItalicWidth();
+ if (nItalicWidth > 0)
+ pBrace->AdaptToX(aTmpDev, nItalicWidth);
+
+ pBrace ->Arrange(aTmpDev, rFormat);
+ pScript->Arrange(aTmpDev, rFormat);
+
+ // die relativen Position und die Abstaende zueinander bestimmen
+ RectPos eRectPos;
+ long nFontHeight = pBody->GetFont().GetSize().Height();
+ long nDistBody = nFontHeight * rFormat.GetDistance(DIS_ORNAMENTSIZE),
+ nDistScript = nFontHeight;
+ if (GetToken().eType == TOVERBRACE)
+ {
+ eRectPos = RP_TOP;
+ nDistBody = - nDistBody;
+ nDistScript *= - rFormat.GetDistance(DIS_UPPERLIMIT);
+ }
+ else // TUNDERBRACE
+ {
+ eRectPos = RP_BOTTOM;
+ nDistScript *= + rFormat.GetDistance(DIS_LOWERLIMIT);
+ }
+ nDistBody /= 100L;
+ nDistScript /= 100L;
+
+ Point aPos = pBrace->AlignTo(*pBody, eRectPos, RHA_CENTER, RVA_BASELINE);
+ aPos.Y() += nDistBody;
+ pBrace->MoveTo(aPos);
+
+ aPos = pScript->AlignTo(*pBrace, eRectPos, RHA_CENTER, RVA_BASELINE);
+ aPos.Y() += nDistScript;
+ pScript->MoveTo(aPos);
+
+ SmRect::operator = (*pBody);
+ ExtendBy(*pBrace, RCP_THIS).ExtendBy(*pScript, RCP_THIS);
+}
+
+
+/**************************************************************************/
+
+
+SmNode * SmOperNode::GetSymbol()
+{
+ SmNode *pNode = GetSubNode(0);
+ OSL_ENSURE(pNode, "Sm: NULL pointer!");
+
+ if (pNode->GetType() == NSUBSUP)
+ pNode = ((SmSubSupNode *) pNode)->GetBody();
+
+ OSL_ENSURE(pNode, "Sm: NULL pointer!");
+ return pNode;
+}
+
+
+long SmOperNode::CalcSymbolHeight(const SmNode &rSymbol,
+ const SmFormat &rFormat) const
+ // returns the font height to be used for operator-symbol
+{
+ long nHeight = GetFont().GetSize().Height();
+
+ SmTokenType eTmpType = GetToken().eType;
+ if (eTmpType == TLIM || eTmpType == TLIMINF || eTmpType == TLIMSUP)
+ return nHeight;
+
+ if (!rFormat.IsTextmode())
+ {
+ // set minimum size ()
+ nHeight += (nHeight * 20L) / 100L;
+
+ nHeight += nHeight
+ * rFormat.GetDistance(DIS_OPERATORSIZE) / 100L;
+ nHeight = nHeight * 686L / 845L;
+ }
+
+ // correct user-defined symbols to match height of sum from used font
+ if (rSymbol.GetToken().eType == TSPECIAL)
+ nHeight = nHeight * 845L / 686L;
+
+ return nHeight;
+}
+
+
+void SmOperNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmNode *pOper = GetSubNode(0);
+ SmNode *pBody = GetSubNode(1);
+
+ OSL_ENSURE(pOper, "Sm: missing subnode");
+ OSL_ENSURE(pBody, "Sm: missing subnode");
+
+ SmNode *pSymbol = GetSymbol();
+ pSymbol->SetSize(Fraction(CalcSymbolHeight(*pSymbol, rFormat),
+ pSymbol->GetFont().GetSize().Height()));
+
+ pBody->Arrange(rDev, rFormat);
+ pOper->Arrange(rDev, rFormat);
+
+ long nOrigHeight = GetFont().GetSize().Height(),
+ nDist = nOrigHeight
+ * rFormat.GetDistance(DIS_OPERATORSPACE) / 100L;
+
+ Point aPos = pOper->AlignTo(*pBody, RP_LEFT, RHA_CENTER, /*RVA_CENTERY*/RVA_MID);
+ aPos.X() -= nDist;
+ pOper->MoveTo(aPos);
+
+ SmRect::operator = (*pBody);
+ ExtendBy(*pOper, RCP_THIS);
+}
+
+
+/**************************************************************************/
+
+
+void SmAlignNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+ // setzt im ganzen subtree (incl aktuellem node) das alignment
+{
+ OSL_ENSURE(GetNumSubNodes() > 0, "Sm: missing subnode");
+
+ SmNode *pNode = GetSubNode(0);
+
+ RectHorAlign eHorAlign = RHA_CENTER;
+ switch (GetToken().eType)
+ {
+ case TALIGNL: eHorAlign = RHA_LEFT; break;
+ case TALIGNC: eHorAlign = RHA_CENTER; break;
+ case TALIGNR: eHorAlign = RHA_RIGHT; break;
+ default:
+ break;
+ }
+ SetRectHorAlign(eHorAlign);
+
+ pNode->Arrange(rDev, rFormat);
+
+ SmRect::operator = (pNode->GetRect());
+}
+
+
+/**************************************************************************/
+
+
+void SmAttributNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmNode *pAttr = GetSubNode(0),
+ *pBody = GetSubNode(1);
+ OSL_ENSURE(pBody, "Sm: body missing");
+ OSL_ENSURE(pAttr, "Sm: attribute missing");
+
+ pBody->Arrange(rDev, rFormat);
+
+ if (GetScaleMode() == SCALE_WIDTH)
+ pAttr->AdaptToX(rDev, pBody->GetItalicWidth());
+ pAttr->Arrange(rDev, rFormat);
+
+ // get relative position of attribut
+ RectVerAlign eVerAlign;
+ long nDist = 0;
+ switch (GetToken().eType)
+ { case TUNDERLINE :
+ eVerAlign = RVA_ATTRIBUT_LO;
+ break;
+ case TOVERSTRIKE :
+ eVerAlign = RVA_ATTRIBUT_MID;
+ break;
+ default :
+ eVerAlign = RVA_ATTRIBUT_HI;
+ if (pBody->GetType() == NATTRIBUT)
+ nDist = GetFont().GetSize().Height()
+ * rFormat.GetDistance(DIS_ORNAMENTSPACE) / 100L;
+ }
+ Point aPos = pAttr->AlignTo(*pBody, RP_ATTRIBUT, RHA_CENTER, eVerAlign);
+ aPos.Y() -= nDist;
+ pAttr->MoveTo(aPos);
+
+ SmRect::operator = (*pBody);
+ ExtendBy(*pAttr, RCP_THIS, true);
+}
+
+
+/**************************************************************************/
+
+
+
+
+void SmFontNode::CreateTextFromNode(String &rText)
+{
+ switch (GetToken().eType)
+ {
+ case TBOLD:
+ APPEND(rText,"bold ");
+ break;
+ case TNBOLD:
+ APPEND(rText,"nbold ");
+ break;
+ case TITALIC:
+ APPEND(rText,"italic ");
+ break;
+ case TNITALIC:
+ APPEND(rText,"nitalic ");
+ break;
+ case TPHANTOM:
+ APPEND(rText,"phantom ");
+ break;
+ case TSIZE:
+ {
+ APPEND(rText,"size ");
+ switch (nSizeType)
+ {
+ case FNTSIZ_PLUS:
+ rText.Append('+');
+ break;
+ case FNTSIZ_MINUS:
+ rText.Append('-');
+ break;
+ case FNTSIZ_MULTIPLY:
+ rText.Append('*');
+ break;
+ case FNTSIZ_DIVIDE:
+ rText.Append('/');
+ break;
+ case FNTSIZ_ABSOLUT:
+ default:
+ break;
+ }
+ rText += String( ::rtl::math::doubleToUString(
+ static_cast<double>(aFontSize),
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', sal_True));
+ rText.Append(' ');
+ }
+ break;
+ case TBLACK:
+ APPEND(rText,"color black ");
+ break;
+ case TWHITE:
+ APPEND(rText,"color white ");
+ break;
+ case TRED:
+ APPEND(rText,"color red ");
+ break;
+ case TGREEN:
+ APPEND(rText,"color green ");
+ break;
+ case TBLUE:
+ APPEND(rText,"color blue ");
+ break;
+ case TCYAN:
+ APPEND(rText,"color cyan ");
+ break;
+ case TMAGENTA:
+ APPEND(rText,"color magenta ");
+ break;
+ case TYELLOW:
+ APPEND(rText,"color yellow ");
+ break;
+ case TSANS:
+ APPEND(rText,"font sans ");
+ break;
+ case TSERIF:
+ APPEND(rText,"font serif ");
+ break;
+ case TFIXED:
+ APPEND(rText,"font fixed ");
+ break;
+ default:
+ break;
+ }
+ GetSubNode(1)->CreateTextFromNode(rText);
+}
+
+
+void SmFontNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+ //! prepare subnodes first
+ SmNode::Prepare(rFormat, rDocShell);
+
+ int nFnt = -1;
+ switch (GetToken().eType)
+ {
+ case TFIXED: nFnt = FNT_FIXED; break;
+ case TSANS: nFnt = FNT_SANS; break;
+ case TSERIF: nFnt = FNT_SERIF; break;
+ default:
+ break;
+ }
+ if (nFnt != -1)
+ { GetFont() = rFormat.GetFont( sal::static_int_cast< sal_uInt16 >(nFnt) );
+ SetFont(GetFont());
+ }
+
+ //! prevent overwrites of this font by 'Arrange' or 'SetFont' calls of
+ //! other font nodes (those with lower depth in the tree)
+ Flags() |= FLG_FONT;
+}
+
+
+void SmFontNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmNode *pNode = GetSubNode(1);
+ OSL_ENSURE(pNode, "Sm: missing subnode");
+
+ switch (GetToken().eType)
+ { case TSIZE :
+ pNode->SetFontSize(aFontSize, nSizeType);
+ break;
+ case TSANS :
+ case TSERIF :
+ case TFIXED :
+ pNode->SetFont(GetFont());
+ break;
+ case TUNKNOWN : break; // no assertion on "font <?> <?>"
+
+ case TPHANTOM : SetPhantom(true); break;
+ case TBOLD : SetAttribut(ATTR_BOLD); break;
+ case TITALIC : SetAttribut(ATTR_ITALIC); break;
+ case TNBOLD : ClearAttribut(ATTR_BOLD); break;
+ case TNITALIC : ClearAttribut(ATTR_ITALIC); break;
+
+ case TBLACK : SetColor(Color(COL_BLACK)); break;
+ case TWHITE : SetColor(Color(COL_WHITE)); break;
+ case TRED : SetColor(Color(COL_RED)); break;
+ case TGREEN : SetColor(Color(COL_GREEN)); break;
+ case TBLUE : SetColor(Color(COL_BLUE)); break;
+ case TCYAN : SetColor(Color(COL_CYAN)); break;
+ case TMAGENTA : SetColor(Color(COL_MAGENTA)); break;
+ case TYELLOW : SetColor(Color(COL_YELLOW)); break;
+
+ default:
+ OSL_FAIL("Sm: unknown case");
+ }
+
+ pNode->Arrange(rDev, rFormat);
+
+ SmRect::operator = (pNode->GetRect());
+}
+
+
+void SmFontNode::SetSizeParameter(const Fraction& rValue, sal_uInt16 Type)
+{
+ nSizeType = Type;
+ aFontSize = rValue;
+}
+
+
+/**************************************************************************/
+
+
+SmPolyLineNode::SmPolyLineNode(const SmToken &rNodeToken)
+: SmGraphicNode(NPOLYLINE, rNodeToken)
+{
+ aPoly.SetSize(2);
+ nWidth = 0;
+}
+
+
+void SmPolyLineNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nNewWidth)
+{
+ aToSize.Width() = nNewWidth;
+}
+
+
+void SmPolyLineNode::AdaptToY(const OutputDevice &/*rDev*/, sal_uLong nNewHeight)
+{
+ GetFont().FreezeBorderWidth();
+ aToSize.Height() = nNewHeight;
+}
+
+
+void SmPolyLineNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ //! some routines being called extract some info from the OutputDevice's
+ //! font (eg the space to be used for borders OR the font name(!!)).
+ //! Thus the font should reflect the needs and has to be set!
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ long nBorderwidth = GetFont().GetBorderWidth();
+
+ //
+ // Das Polygon mit den beiden Endpunkten bilden
+ //
+ OSL_ENSURE(aPoly.GetSize() == 2, "Sm : wrong number of points");
+ Point aPointA, aPointB;
+ if (GetToken().eType == TWIDESLASH)
+ {
+ aPointA.X() = nBorderwidth;
+ aPointA.Y() = aToSize.Height() - nBorderwidth;
+ aPointB.X() = aToSize.Width() - nBorderwidth;
+ aPointB.Y() = nBorderwidth;
+ }
+ else
+ {
+ OSL_ENSURE(GetToken().eType == TWIDEBACKSLASH, "Sm : unexpected token");
+ aPointA.X() =
+ aPointA.Y() = nBorderwidth;
+ aPointB.X() = aToSize.Width() - nBorderwidth;
+ aPointB.Y() = aToSize.Height() - nBorderwidth;
+ }
+ aPoly.SetPoint(aPointA, 0);
+ aPoly.SetPoint(aPointB, 1);
+
+ long nThick = GetFont().GetSize().Height()
+ * rFormat.GetDistance(DIS_STROKEWIDTH) / 100L;
+ nWidth = nThick + 2 * nBorderwidth;
+
+ SmRect::operator = (SmRect(aToSize.Width(), aToSize.Height()));
+}
+
+
+/**************************************************************************/
+
+void SmRootSymbolNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nWidth)
+{
+ nBodyWidth = nWidth;
+}
+
+
+void SmRootSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
+{
+ // etwas extra Laenge damit der horizontale Balken spaeter ueber dem
+ // Argument positioniert ist
+ SmMathSymbolNode::AdaptToY(rDev, nHeight + nHeight / 10L);
+}
+
+
+/**************************************************************************/
+
+
+void SmRectangleNode::AdaptToX(const OutputDevice &/*rDev*/, sal_uLong nWidth)
+{
+ aToSize.Width() = nWidth;
+}
+
+
+void SmRectangleNode::AdaptToY(const OutputDevice &/*rDev*/, sal_uLong nHeight)
+{
+ GetFont().FreezeBorderWidth();
+ aToSize.Height() = nHeight;
+}
+
+
+void SmRectangleNode::Arrange(const OutputDevice &rDev, const SmFormat &/*rFormat*/)
+{
+ long nFontHeight = GetFont().GetSize().Height();
+ long nWidth = aToSize.Width(),
+ nHeight = aToSize.Height();
+ if (nHeight == 0)
+ nHeight = nFontHeight / 30;
+ if (nWidth == 0)
+ nWidth = nFontHeight / 3;
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ // add some borderspace
+ sal_uLong nTmpBorderWidth = GetFont().GetBorderWidth();
+ nHeight += 2 * nTmpBorderWidth;
+
+ //! use this method in order to have 'SmRect::HasAlignInfo() == true'
+ //! and thus having the attribut-fences updated in 'SmRect::ExtendBy'
+ SmRect::operator = (SmRect(nWidth, nHeight));
+}
+
+
+/**************************************************************************/
+
+
+SmTextNode::SmTextNode( SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 nFontDescP ) :
+ SmVisibleNode(eNodeType, rNodeToken)
+{
+ nFontDesc = nFontDescP;
+}
+
+
+SmTextNode::SmTextNode( const SmToken &rNodeToken, sal_uInt16 nFontDescP ) :
+ SmVisibleNode(NTEXT, rNodeToken)
+{
+ nFontDesc = nFontDescP;
+}
+
+
+void SmTextNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+ SmNode::Prepare(rFormat, rDocShell);
+
+ // default setting for horizontal alignment of nodes with TTEXT
+ // content is as alignl (cannot be done in Arrange since it would
+ // override the settings made by an SmAlignNode before)
+ if (TTEXT == GetToken().eType)
+ SetRectHorAlign( RHA_LEFT );
+
+ aText = GetToken().aText;
+ GetFont() = rFormat.GetFont(GetFontDesc());
+
+ if (IsItalic( GetFont() ))
+ Attributes() |= ATTR_ITALIC;
+ if (IsBold( GetFont() ))
+ Attributes() |= ATTR_BOLD;
+
+ // special handling for ':' where it is a token on it's own and is likely
+ // to be used for mathematical notations. (E.g. a:b = 2:3)
+ // In that case it should not be displayed in italic.
+ if (GetToken().aText.Len() == 1 && GetToken().aText.GetChar(0) == ':')
+ Attributes() &= ~ATTR_ITALIC;
+};
+
+
+void SmTextNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ PrepareAttributes();
+
+ sal_uInt16 nSizeDesc = GetFontDesc() == FNT_FUNCTION ?
+ SIZ_FUNCTION : SIZ_TEXT;
+ GetFont() *= Fraction (rFormat.GetRelSize(nSizeDesc), 100);
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ SmRect::operator = (SmRect(aTmpDev, &rFormat, aText, GetFont().GetBorderWidth()));
+}
+
+void SmTextNode::CreateTextFromNode(String &rText)
+{
+ bool bQuoted=false;
+ if (GetToken().eType == TTEXT)
+ {
+ rText.Append('\"');
+ bQuoted=true;
+ }
+ else
+ {
+ SmParser aParseTest;
+ SmNode *pTable = aParseTest.Parse(GetToken().aText);
+ bQuoted=true;
+ if ( (pTable->GetType() == NTABLE) && (pTable->GetNumSubNodes() == 1) )
+ {
+ SmNode *pResult = pTable->GetSubNode(0);
+ if ( (pResult->GetType() == NLINE) &&
+ (pResult->GetNumSubNodes() == 1) )
+ {
+ pResult = pResult->GetSubNode(0);
+ if ( (pResult->GetType() == NEXPRESSION) &&
+ (pResult->GetNumSubNodes() == 1) )
+ {
+ pResult = pResult->GetSubNode(0);
+ if (pResult->GetType() == NTEXT)
+ bQuoted=false;
+ }
+ }
+ }
+ delete pTable;
+
+ if ((GetToken().eType == TIDENT) && (GetFontDesc() == FNT_FUNCTION))
+ {
+ //Search for existing functions and remove extraenous keyword
+ APPEND(rText,"func ");
+ }
+ else if (bQuoted)
+ APPEND(rText,"italic ");
+
+ if (bQuoted)
+ rText.Append('\"');
+
+ }
+
+ rText.Append(GetToken().aText);
+
+ if (bQuoted)
+ rText.Append('\"');
+ rText.Append(' ');
+}
+
+
+void SmTextNode::GetAccessibleText( String &rText ) const
+{
+ rText += aText;
+}
+
+void SmTextNode::AdjustFontDesc()
+{
+ if (GetToken().eType == TTEXT)
+ nFontDesc = FNT_TEXT;
+ else if(GetToken().eType == TFUNC)
+ nFontDesc = FNT_FUNCTION;
+ else {
+ SmTokenType nTok;
+ const SmTokenTableEntry *pEntry = SmParser::GetTokenTableEntry( aText );
+ if (pEntry && pEntry->nGroup == TGFUNCTION) {
+ nTok = pEntry->eType;
+ nFontDesc = FNT_FUNCTION;
+ } else {
+ sal_Unicode firstChar = aText.GetChar(0);
+ if( ('0' <= firstChar && firstChar <= '9') || firstChar == '.' || firstChar == ',') {
+ nFontDesc = FNT_NUMBER;
+ nTok = TNUMBER;
+ } else if (aText.Len() > 1) {
+ nFontDesc = FNT_VARIABLE;
+ nTok = TIDENT;
+ } else {
+ nFontDesc = FNT_VARIABLE;
+ nTok = TCHARACTER;
+ }
+ }
+ SmToken tok = GetToken();
+ tok.eType = nTok;
+ SetToken(tok);
+ }
+}
+
+/**************************************************************************/
+
+void SmMatrixNode::CreateTextFromNode(String &rText)
+{
+ APPEND(rText,"matrix {");
+ for (sal_uInt16 i = 0; i < nNumRows; i++)
+ {
+ for (sal_uInt16 j = 0; j < nNumCols; j++)
+ {
+ SmNode *pNode = GetSubNode(i * nNumCols + j);
+ pNode->CreateTextFromNode(rText);
+ if (j != nNumCols-1)
+ APPEND(rText,"# ");
+ }
+ if (i != nNumRows-1)
+ APPEND(rText,"## ");
+ }
+ rText.EraseTrailingChars();
+ APPEND(rText,"} ");
+}
+
+
+void SmMatrixNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ Point aPosition,
+ aOffset;
+ SmNode *pNode;
+ sal_uInt16 i, j;
+
+ // initialize array that is to hold the maximum widhts of all
+ // elements (subnodes) in that column.
+ long *pColWidth = new long[nNumCols];
+ for (j = 0; j < nNumCols; j++)
+ pColWidth[j] = 0;
+
+ // arrange subnodes and calculate the aboves arrays contents
+ sal_uInt16 nNodes = GetNumSubNodes();
+ for (i = 0; i < nNodes; i++)
+ {
+ sal_uInt16 nIdx = nNodes - 1 - i;
+ if (NULL != (pNode = GetSubNode(nIdx)))
+ {
+ pNode->Arrange(rDev, rFormat);
+ int nCol = nIdx % nNumCols;
+ pColWidth[nCol] = Max(pColWidth[nCol], pNode->GetItalicWidth());
+ }
+ }
+
+ // norm distance from which the following two are calcutated
+ const int nNormDist = 3 * GetFont().GetSize().Height();
+
+ // define horizontal and vertical minimal distances that seperate
+ // the elements
+ long nHorDist = nNormDist * rFormat.GetDistance(DIS_MATRIXCOL) / 100L,
+ nVerDist = nNormDist * rFormat.GetDistance(DIS_MATRIXROW) / 100L;
+
+ // build array that holds the leftmost position for each column
+ long *pColLeft = new long[nNumCols];
+ long nX = 0;
+ for (j = 0; j < nNumCols; j++)
+ { pColLeft[j] = nX;
+ nX += pColWidth[j] + nHorDist;
+ }
+
+ Point aPos, aDelta;
+ SmRect aLineRect;
+ SmRect::operator = (SmRect());
+ for (i = 0; i < nNumRows; i++)
+ { aLineRect = SmRect();
+ for (j = 0; j < nNumCols; j++)
+ { SmNode *pTmpNode = GetSubNode(i * nNumCols + j);
+ OSL_ENSURE(pTmpNode, "Sm: NULL pointer");
+
+ const SmRect &rNodeRect = pTmpNode->GetRect();
+
+ // align all baselines in that row if possible
+ aPos = rNodeRect.AlignTo(aLineRect, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
+ aPos.X() += nHorDist;
+
+ // get horizontal alignment
+ const SmNode *pCoNode = pTmpNode->GetLeftMost();
+ RectHorAlign eHorAlign = pCoNode->GetRectHorAlign();
+
+ // caculate horizontal position of element depending on column
+ // and horizontal alignment
+ switch (eHorAlign)
+ { case RHA_LEFT:
+ aPos.X() = rNodeRect.GetLeft() + pColLeft[j];
+ break;
+ case RHA_CENTER:
+ aPos.X() = rNodeRect.GetLeft() + pColLeft[j]
+ + pColWidth[j] / 2
+ - rNodeRect.GetItalicCenterX();
+ break;
+ case RHA_RIGHT:
+ aPos.X() = rNodeRect.GetLeft() + pColLeft[j]
+ + pColWidth[j] - rNodeRect.GetItalicWidth();
+ break;
+ }
+
+ pTmpNode->MoveTo(aPos);
+ aLineRect.ExtendBy(rNodeRect, RCP_XOR);
+ }
+
+ aPos = aLineRect.AlignTo(*this, RP_BOTTOM, RHA_CENTER, RVA_BASELINE);
+ aPos.Y() += nVerDist;
+
+ // move 'aLineRect' and rectangles in that line to final position
+ aDelta.X() = 0; // since horizontal alignment is already done
+ aDelta.Y() = aPos.Y() - aLineRect.GetTop();
+ aLineRect.Move(aDelta);
+ for (j = 0; j < nNumCols; j++)
+ if (NULL != (pNode = GetSubNode(i * nNumCols + j)))
+ pNode->Move(aDelta);
+
+ ExtendBy(aLineRect, RCP_NONE);
+ }
+
+ delete [] pColLeft;
+ delete [] pColWidth;
+}
+
+
+void SmMatrixNode::SetRowCol(sal_uInt16 nMatrixRows, sal_uInt16 nMatrixCols)
+{
+ nNumRows = nMatrixRows;
+ nNumCols = nMatrixCols;
+}
+
+
+SmNode * SmMatrixNode::GetLeftMost()
+{
+ return this;
+}
+
+
+/**************************************************************************/
+
+
+SmMathSymbolNode::SmMathSymbolNode(const SmToken &rNodeToken)
+: SmSpecialNode(NMATH, rNodeToken, FNT_MATH)
+{
+ xub_Unicode cChar = GetToken().cMathChar;
+ if ((xub_Unicode) '\0' != cChar)
+ SetText( cChar );
+}
+
+void SmMathSymbolNode::AdaptToX(const OutputDevice &rDev, sal_uLong nWidth)
+{
+ // Since there is no function to do this, we try to approximate it:
+ Size aFntSize (GetFont().GetSize());
+
+ //! however the result is a bit better with 'nWidth' as initial font width
+ aFntSize.Width() = nWidth;
+ GetFont().SetSize(aFntSize);
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ // get denominator of error factor for width
+ long nTmpBorderWidth = GetFont().GetBorderWidth();
+ long nDenom = SmRect(aTmpDev, NULL, GetText(), nTmpBorderWidth).GetItalicWidth();
+
+ // scale fontwidth with this error factor
+ aFntSize.Width() *= nWidth;
+ aFntSize.Width() /= nDenom ? nDenom : 1;
+
+ GetFont().SetSize(aFntSize);
+}
+
+void SmMathSymbolNode::AdaptToY(const OutputDevice &rDev, sal_uLong nHeight)
+{
+ GetFont().FreezeBorderWidth();
+ Size aFntSize (GetFont().GetSize());
+
+ // da wir nur die Hoehe skalieren wollen muesen wir hier ggf die Fontweite
+ // ermitteln um diese beizubehalten.
+ if (aFntSize.Width() == 0)
+ {
+ OutputDevice &rDevNC = (OutputDevice &) rDev;
+ rDevNC.Push(PUSH_FONT | PUSH_MAPMODE);
+ rDevNC.SetFont(GetFont());
+ aFntSize.Width() = rDev.GetFontMetric().GetSize().Width();
+ rDevNC.Pop();
+ }
+ OSL_ENSURE(aFntSize.Width() != 0, "Sm: ");
+
+ //! however the result is a bit better with 'nHeight' as initial
+ //! font height
+ aFntSize.Height() = nHeight;
+ GetFont().SetSize(aFntSize);
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ // get denominator of error factor for height
+ long nTmpBorderWidth = GetFont().GetBorderWidth();
+ long nDenom = SmRect(aTmpDev, NULL, GetText(), nTmpBorderWidth).GetHeight();
+
+ // scale fontwidth with this error factor
+ aFntSize.Height() *= nHeight;
+ aFntSize.Height() /= nDenom ? nDenom : 1;
+
+ GetFont().SetSize(aFntSize);
+}
+
+
+void SmMathSymbolNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+ SmNode::Prepare(rFormat, rDocShell);
+
+ GetFont() = rFormat.GetFont(GetFontDesc());
+ // use same font size as is used for variables
+ GetFont().SetSize( rFormat.GetFont( FNT_VARIABLE ).GetSize() );
+
+ OSL_ENSURE(GetFont().GetCharSet() == RTL_TEXTENCODING_SYMBOL ||
+ GetFont().GetCharSet() == RTL_TEXTENCODING_UNICODE,
+ "wrong charset for character from StarMath/OpenSymbol font");
+
+ Flags() |= FLG_FONT | FLG_ITALIC;
+};
+
+
+void SmMathSymbolNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ const XubString &rText = GetText();
+
+ if (rText.Len() == 0 || rText.GetChar(0) == xub_Unicode('\0'))
+ { SmRect::operator = (SmRect());
+ return;
+ }
+
+ PrepareAttributes();
+
+ GetFont() *= Fraction (rFormat.GetRelSize(SIZ_TEXT), 100);
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ SmRect::operator = (SmRect(aTmpDev, &rFormat, rText, GetFont().GetBorderWidth()));
+}
+
+void SmMathSymbolNode::CreateTextFromNode(String &rText)
+{
+ String sStr;
+ MathType::LookupChar(GetToken().cMathChar, sStr);
+ rText.Append(sStr);
+}
+
+void SmRectangleNode::CreateTextFromNode(String &rText)
+{
+ switch (GetToken().eType)
+ {
+ case TUNDERLINE:
+ APPEND(rText,"underline ");
+ break;
+ case TOVERLINE:
+ APPEND(rText,"overline ");
+ break;
+ case TOVERSTRIKE:
+ APPEND(rText,"overstrike ");
+ break;
+ default:
+ break;
+ }
+}
+
+void SmAttributNode::CreateTextFromNode(String &rText)
+{
+ SmNode *pNode;
+ sal_uInt16 nSize = GetNumSubNodes();
+ OSL_ENSURE(nSize == 2, "Node missing members");
+ rText.Append('{');
+ sal_Unicode nLast=0;
+ if (NULL != (pNode = GetSubNode(0)))
+ {
+ String aStr;
+ pNode->CreateTextFromNode(aStr);
+ if (aStr.Len() > 1)
+ rText.Append(aStr);
+ else
+ {
+ nLast = aStr.GetChar(0);
+ switch (nLast)
+ {
+ case 0xAF:
+ APPEND(rText,"overline ");
+ break;
+ case 0x2d9:
+ APPEND(rText,"dot ");
+ break;
+ case 0x2dc:
+ APPEND(rText,"widetilde ");
+ break;
+ case 0xA8:
+ APPEND(rText,"ddot ");
+ break;
+ case 0xE082:
+ break;
+ case 0xE09B:
+ APPEND(rText,"dddot ");
+ break;
+ default:
+ rText.Append(nLast);
+ break;
+ }
+ }
+ }
+
+ if (nSize == 2)
+ if (NULL != (pNode = GetSubNode(1)))
+ pNode->CreateTextFromNode(rText);
+
+ rText.EraseTrailingChars();
+
+ if (nLast == 0xE082)
+ APPEND(rText," overbrace {}");
+
+ APPEND(rText,"} ");
+}
+
+/**************************************************************************/
+
+bool lcl_IsFromGreekSymbolSet( const String &rTokenText )
+{
+ bool bRes = false;
+
+ // valid symbol name needs to have a '%' at pos 0 and at least an additonal char
+ if (rTokenText.Len() > 2 && rTokenText.GetBuffer()[0] == (sal_Unicode)'%')
+ {
+ String aName( rTokenText.Copy(1) );
+ SmSym *pSymbol = SM_MOD()->GetSymbolManager().GetSymbolByName( aName );
+ if (pSymbol && GetExportSymbolSetName( pSymbol->GetSymbolSetName() ).EqualsAscii( "Greek" ) )
+ bRes = true;
+ }
+
+ return bRes;
+}
+
+
+SmSpecialNode::SmSpecialNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 _nFontDesc) :
+ SmTextNode(eNodeType, rNodeToken, _nFontDesc)
+{
+ bIsFromGreekSymbolSet = lcl_IsFromGreekSymbolSet( rNodeToken.aText );
+}
+
+
+SmSpecialNode::SmSpecialNode(const SmToken &rNodeToken) :
+ SmTextNode(NSPECIAL, rNodeToken, FNT_MATH) //! default Font nicht immer richtig
+{
+ bIsFromGreekSymbolSet = lcl_IsFromGreekSymbolSet( rNodeToken.aText );
+}
+
+
+void SmSpecialNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+ SmNode::Prepare(rFormat, rDocShell);
+
+ const SmSym *pSym;
+ SmModule *pp = SM_MOD();
+
+ String aName( GetToken().aText.Copy(1) );
+ if (NULL != (pSym = pp->GetSymbolManager().GetSymbolByName( aName )))
+ {
+ sal_UCS4 cChar = pSym->GetCharacter();
+ String aTmp( OUString( &cChar, 1 ) );
+ SetText( aTmp );
+ GetFont() = pSym->GetFace();
+ }
+ else
+ {
+ SetText( GetToken().aText );
+ GetFont() = rFormat.GetFont(FNT_VARIABLE);
+ }
+ // use same font size as is used for variables
+ GetFont().SetSize( rFormat.GetFont( FNT_VARIABLE ).GetSize() );
+
+ //! eigentlich sollten nur WEIGHT_NORMAL und WEIGHT_BOLD vorkommen...
+ //! In der sms-Datei gibt es jedoch zB auch 'WEIGHT_ULTRALIGHT'
+ //! daher vergleichen wir hier mit > statt mit != .
+ //! (Langfristig sollte die Notwendigkeit fuer 'PrepareAttribut', und damit
+ //! fuer dieses hier, mal entfallen.)
+ //
+ //! see also SmFontStyles::GetStyleName
+ if (IsItalic( GetFont() ))
+ SetAttribut(ATTR_ITALIC);
+ if (IsBold( GetFont() ))
+ SetAttribut(ATTR_BOLD);
+
+ Flags() |= FLG_FONT;
+
+ if (bIsFromGreekSymbolSet)
+ {
+ OSL_ENSURE( GetText().Len() == 1, "a symbol should only consist of 1 char!" );
+ bool bItalic = false;
+ sal_Int16 nStyle = rFormat.GetGreekCharStyle();
+ OSL_ENSURE( nStyle >= 0 && nStyle <= 2, "unexpected value for GreekCharStyle" );
+ if (nStyle == 1)
+ bItalic = true;
+ else if (nStyle == 2)
+ {
+ String aTmp( GetText() );
+ if (aTmp.Len() > 0)
+ {
+ const sal_Unicode cUppercaseAlpha = 0x0391;
+ const sal_Unicode cUppercaseOmega = 0x03A9;
+ sal_Unicode cChar = aTmp.GetBuffer()[0];
+ // uppercase letters should be straight and lowercase letters italic
+ bItalic = !(cUppercaseAlpha <= cChar && cChar <= cUppercaseOmega);
+ }
+ }
+
+ if (bItalic)
+ Attributes() |= ATTR_ITALIC;
+ else
+ Attributes() &= ~ATTR_ITALIC;;
+ }
+};
+
+
+void SmSpecialNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ PrepareAttributes();
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(), GetFont().GetBorderWidth()));
+}
+
+/**************************************************************************/
+
+
+void SmGlyphSpecialNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ PrepareAttributes();
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(),
+ GetFont().GetBorderWidth()).AsGlyphRect());
+}
+
+
+/**************************************************************************/
+
+
+void SmPlaceNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+ SmNode::Prepare(rFormat, rDocShell);
+
+ GetFont().SetColor(COL_GRAY);
+ Flags() |= FLG_COLOR | FLG_FONT | FLG_ITALIC;
+};
+
+
+void SmPlaceNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ PrepareAttributes();
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ SmRect::operator = (SmRect(aTmpDev, &rFormat, GetText(), GetFont().GetBorderWidth()));
+}
+
+
+/**************************************************************************/
+
+
+void SmErrorNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+ SmNode::Prepare(rFormat, rDocShell);
+
+ GetFont().SetColor(COL_RED);
+ Flags() |= FLG_VISIBLE | FLG_BOLD | FLG_ITALIC
+ | FLG_COLOR | FLG_FONT | FLG_SIZE;
+}
+
+
+void SmErrorNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ PrepareAttributes();
+
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ const XubString &rText = GetText();
+ SmRect::operator = (SmRect(aTmpDev, &rFormat, rText, GetFont().GetBorderWidth()));
+}
+
+
+/**************************************************************************/
+
+
+void SmBlankNode::IncreaseBy(const SmToken &rToken)
+{
+ switch(rToken.eType)
+ {
+ case TBLANK: nNum += 4; break;
+ case TSBLANK: nNum += 1; break;
+ default:
+ break;
+ }
+}
+
+
+void SmBlankNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell)
+{
+ SmNode::Prepare(rFormat, rDocShell);
+
+ //! hier muss/sollte es lediglich nicht der StarMath Font sein,
+ //! damit fuer das in Arrange verwendete Zeichen ein "normales"
+ //! (ungecliptes) Rechteck erzeugt wird.
+ GetFont() = rFormat.GetFont(FNT_VARIABLE);
+
+ Flags() |= FLG_FONT | FLG_BOLD | FLG_ITALIC;
+}
+
+
+void SmBlankNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
+{
+ SmTmpDevice aTmpDev ((OutputDevice &) rDev, true);
+ aTmpDev.SetFont(GetFont());
+
+ // Abstand von der Fonthoehe abhaengig machen
+ // (damit er beim skalieren (zB size *2 {a ~ b}) mitwaechst)
+ long nDist = GetFont().GetSize().Height() / 10L,
+ nSpace = nNum * nDist;
+
+ // ein SmRect mit Baseline und allem drum und dran besorgen
+ SmRect::operator = (SmRect(aTmpDev, &rFormat, XubString(xub_Unicode(' ')),
+ GetFont().GetBorderWidth()));
+
+ // und dieses auf die gewuenschte Breite bringen
+ SetItalicSpaces(0, 0);
+ SetWidth(nSpace);
+}
+
+/**************************************************************************/
+//Implementation of all accept methods for SmVisitor
+
+void SmNode::Accept(SmVisitor*){
+ //This method is only implemented to avoid making SmNode abstract because an
+ //obscure copy constructor is used... I can't find it's implementation, and
+ //don't want to figure out how to fix it... If you want to, just delete this
+ //method, making SmNode abstract, and see where you can an problem with that.
+ OSL_FAIL("SmNode should not be visitable!");
+}
+
+void SmTableNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmBraceNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmBracebodyNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmOperNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmAlignNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmAttributNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmFontNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmUnHorNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmBinHorNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmBinVerNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmBinDiagonalNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmSubSupNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmMatrixNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmPlaceNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmTextNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmSpecialNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmGlyphSpecialNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmMathSymbolNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmBlankNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmErrorNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmLineNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmExpressionNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmPolyLineNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmRootNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmRootSymbolNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmRectangleNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+void SmVerticalBraceNode::Accept(SmVisitor* pVisitor) {
+ pVisitor->Visit(this);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/parse.cxx b/starmath/source/parse.cxx
new file mode 100644
index 000000000000..1aa56358693d
--- /dev/null
+++ b/starmath/source/parse.cxx
@@ -0,0 +1,2527 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <stdio.h>
+
+#define SMDLL 1
+
+#include <com/sun/star/i18n/UnicodeType.hpp>
+#include <i18npool/lang.h>
+#include <unotools/charclass.hxx>
+#include <editeng/unolingu.hxx>
+#include <unotools/syslocale.hxx>
+#include <sal/macros.h>
+#include "parse.hxx"
+#include "starmath.hrc"
+#include "smdll.hxx"
+#include "smmod.hxx"
+#include "config.hxx"
+
+#include "node.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::i18n;
+
+///////////////////////////////////////////////////////////////////////////
+
+static inline bool strnccmp(const String &u1, xub_StrLen nIdx,
+ const sal_Char *s2, xub_StrLen nLen)
+{
+ return u1.EqualsIgnoreCaseAscii( s2, nIdx, nLen );
+}
+
+static const sal_Unicode aDelimiterTable[] =
+{
+ ' ', '\t', '\n', '\r', '+', '-', '*', '/', '=', '#',
+ '%', '\\', '"', '~', '`', '>', '<', '&', '|', '(',
+ ')', '{', '}', '[', ']', '^', '_',
+ '\0' // end of list symbol
+};
+
+
+static inline bool IsDigit( sal_Unicode cChar )
+{
+ return '0' <= cChar && cChar <= '9';
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+SmToken::SmToken() :
+ eType (TUNKNOWN),
+ cMathChar ('\0')
+{
+ nGroup = nCol = nRow = nLevel = 0;
+}
+
+SmToken::SmToken(SmTokenType eTokenType,
+ sal_Unicode cMath,
+ const sal_Char* pText,
+ sal_uLong nTokenGroup,
+ sal_uInt16 nTokenLevel) {
+ eType = eTokenType;
+ cMathChar = cMath;
+ aText.AssignAscii(pText);
+ nGroup = nTokenGroup;
+ nLevel = nTokenLevel;
+ nCol = nRow = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+
+static const SmTokenTableEntry aTokenTable[] =
+{
+ { "Im" , TIM, MS_IM, TGSTANDALONE, 5 },
+ { "MZ23", TDEBUG, '\0', TGATTRIBUT, 0 },
+ { "Re" , TRE, MS_RE, TGSTANDALONE, 5 },
+ { "abs", TABS, '\0', TGUNOPER, 13 },
+ { "arcosh", TACOSH, '\0', TGFUNCTION, 5 },
+ { "arcoth", TACOTH, '\0', TGFUNCTION, 5 },
+ { "acute", TACUTE, MS_ACUTE, TGATTRIBUT, 5 },
+ { "aleph" , TALEPH, MS_ALEPH, TGSTANDALONE, 5 },
+ { "alignb", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
+ { "alignc", TALIGNC, '\0', TGALIGN, 0},
+ { "alignl", TALIGNL, '\0', TGALIGN, 0},
+ { "alignm", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
+ { "alignr", TALIGNR, '\0', TGALIGN, 0},
+ { "alignt", TALIGNC, '\0', TGALIGN | TGDISCARDED, 0},
+ { "and", TAND, MS_AND, TGPRODUCT, 0},
+ { "approx", TAPPROX, MS_APPROX, TGRELATION, 0},
+ { "arccos", TACOS, '\0', TGFUNCTION, 5},
+ { "arccot", TACOT, '\0', TGFUNCTION, 5},
+ { "arcsin", TASIN, '\0', TGFUNCTION, 5},
+ { "arctan", TATAN, '\0', TGFUNCTION, 5},
+ { "arsinh", TASINH, '\0', TGFUNCTION, 5},
+ { "artanh", TATANH, '\0', TGFUNCTION, 5},
+ { "backepsilon" , TBACKEPSILON, MS_BACKEPSILON, TGSTANDALONE, 5},
+ { "bar", TBAR, MS_BAR, TGATTRIBUT, 5},
+ { "binom", TBINOM, '\0', 0, 5 },
+ { "black", TBLACK, '\0', TGCOLOR, 0},
+ { "blue", TBLUE, '\0', TGCOLOR, 0},
+ { "bold", TBOLD, '\0', TGFONTATTR, 5},
+ { "boper", TBOPER, '\0', TGPRODUCT, 0},
+ { "breve", TBREVE, MS_BREVE, TGATTRIBUT, 5},
+ { "bslash", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
+ { "cdot", TCDOT, MS_CDOT, TGPRODUCT, 0},
+ { "check", TCHECK, MS_CHECK, TGATTRIBUT, 5},
+ { "circ" , TCIRC, MS_CIRC, TGSTANDALONE, 5},
+ { "circle", TCIRCLE, MS_CIRCLE, TGATTRIBUT, 5},
+ { "color", TCOLOR, '\0', TGFONTATTR, 5},
+ { "coprod", TCOPROD, MS_COPROD, TGOPER, 5},
+ { "cos", TCOS, '\0', TGFUNCTION, 5},
+ { "cosh", TCOSH, '\0', TGFUNCTION, 5},
+ { "cot", TCOT, '\0', TGFUNCTION, 5},
+ { "coth", TCOTH, '\0', TGFUNCTION, 5},
+ { "csub", TCSUB, '\0', TGPOWER, 0},
+ { "csup", TCSUP, '\0', TGPOWER, 0},
+ { "cyan", TCYAN, '\0', TGCOLOR, 0},
+ { "dddot", TDDDOT, MS_DDDOT, TGATTRIBUT, 5},
+ { "ddot", TDDOT, MS_DDOT, TGATTRIBUT, 5},
+ { "def", TDEF, MS_DEF, TGRELATION, 0},
+ { "div", TDIV, MS_DIV, TGPRODUCT, 0},
+ { "divides", TDIVIDES, MS_LINE, TGRELATION, 0},
+ { "dlarrow" , TDLARROW, MS_DLARROW, TGSTANDALONE, 5},
+ { "dlrarrow" , TDLRARROW, MS_DLRARROW, TGSTANDALONE, 5},
+ { "dot", TDOT, MS_DOT, TGATTRIBUT, 5},
+ { "dotsaxis", TDOTSAXIS, MS_DOTSAXIS, TGSTANDALONE, 5}, // 5 to continue expression
+ { "dotsdiag", TDOTSDIAG, MS_DOTSUP, TGSTANDALONE, 5}, //
+ { "dotsdown", TDOTSDOWN, MS_DOTSDOWN, TGSTANDALONE, 5}, //
+ { "dotslow", TDOTSLOW, MS_DOTSLOW, TGSTANDALONE, 5}, //
+ { "dotsup", TDOTSUP, MS_DOTSUP, TGSTANDALONE, 5}, //
+ { "dotsvert", TDOTSVERT, MS_DOTSVERT, TGSTANDALONE, 5}, //
+ { "downarrow" , TDOWNARROW, MS_DOWNARROW, TGSTANDALONE, 5},
+ { "drarrow" , TDRARROW, MS_DRARROW, TGSTANDALONE, 5},
+ { "emptyset" , TEMPTYSET, MS_EMPTYSET, TGSTANDALONE, 5},
+ { "equiv", TEQUIV, MS_EQUIV, TGRELATION, 0},
+ { "exists", TEXISTS, MS_EXISTS, TGSTANDALONE, 5},
+ { "exp", TEXP, '\0', TGFUNCTION, 5},
+ { "fact", TFACT, MS_FACT, TGUNOPER, 5},
+ { "fixed", TFIXED, '\0', TGFONT, 0},
+ { "font", TFONT, '\0', TGFONTATTR, 5},
+ { "forall", TFORALL, MS_FORALL, TGSTANDALONE, 5},
+ { "from", TFROM, '\0', TGLIMIT, 0},
+ { "func", TFUNC, '\0', TGFUNCTION, 5},
+ { "ge", TGE, MS_GE, TGRELATION, 0},
+ { "geslant", TGESLANT, MS_GESLANT, TGRELATION, 0 },
+ { "gg", TGG, MS_GG, TGRELATION, 0},
+ { "grave", TGRAVE, MS_GRAVE, TGATTRIBUT, 5},
+ { "green", TGREEN, '\0', TGCOLOR, 0},
+ { "gt", TGT, MS_GT, TGRELATION, 0},
+ { "hat", THAT, MS_HAT, TGATTRIBUT, 5},
+ { "hbar" , THBAR, MS_HBAR, TGSTANDALONE, 5},
+ { "iiint", TIIINT, MS_IIINT, TGOPER, 5},
+ { "iint", TIINT, MS_IINT, TGOPER, 5},
+ { "in", TIN, MS_IN, TGRELATION, 0},
+ { "infinity" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5},
+ { "infty" , TINFINITY, MS_INFINITY, TGSTANDALONE, 5},
+ { "int", TINT, MS_INT, TGOPER, 5},
+ { "intersection", TINTERSECT, MS_INTERSECT, TGPRODUCT, 0},
+ { "ital", TITALIC, '\0', TGFONTATTR, 5},
+ { "italic", TITALIC, '\0', TGFONTATTR, 5},
+ { "lambdabar" , TLAMBDABAR, MS_LAMBDABAR, TGSTANDALONE, 5},
+ { "langle", TLANGLE, MS_LANGLE, TGLBRACES, 5},
+ { "lbrace", TLBRACE, MS_LBRACE, TGLBRACES, 5},
+ { "lceil", TLCEIL, MS_LCEIL, TGLBRACES, 5},
+ { "ldbracket", TLDBRACKET, MS_LDBRACKET, TGLBRACES, 5},
+ { "ldline", TLDLINE, MS_DLINE, TGLBRACES, 5},
+ { "le", TLE, MS_LE, TGRELATION, 0},
+ { "left", TLEFT, '\0', 0, 5},
+ { "leftarrow" , TLEFTARROW, MS_LEFTARROW, TGSTANDALONE, 5},
+ { "leslant", TLESLANT, MS_LESLANT, TGRELATION, 0 },
+ { "lfloor", TLFLOOR, MS_LFLOOR, TGLBRACES, 5},
+ { "lim", TLIM, '\0', TGOPER, 5},
+ { "liminf", TLIMINF, '\0', TGOPER, 5},
+ { "limsup", TLIMSUP, '\0', TGOPER, 5},
+ { "lint", TLINT, MS_LINT, TGOPER, 5},
+ { "ll", TLL, MS_LL, TGRELATION, 0},
+ { "lline", TLLINE, MS_LINE, TGLBRACES, 5},
+ { "llint", TLLINT, MS_LLINT, TGOPER, 5},
+ { "lllint", TLLLINT, MS_LLLINT, TGOPER, 5},
+ { "ln", TLN, '\0', TGFUNCTION, 5},
+ { "log", TLOG, '\0', TGFUNCTION, 5},
+ { "lsub", TLSUB, '\0', TGPOWER, 0},
+ { "lsup", TLSUP, '\0', TGPOWER, 0},
+ { "lt", TLT, MS_LT, TGRELATION, 0},
+ { "magenta", TMAGENTA, '\0', TGCOLOR, 0},
+ { "matrix", TMATRIX, '\0', 0, 5},
+ { "minusplus", TMINUSPLUS, MS_MINUSPLUS, TGUNOPER | TGSUM, 5},
+ { "mline", TMLINE, MS_LINE, 0, 0}, //! nicht in TGRBRACES, Level 0
+ { "nabla", TNABLA, MS_NABLA, TGSTANDALONE, 5},
+ { "nbold", TNBOLD, '\0', TGFONTATTR, 5},
+ { "ndivides", TNDIVIDES, MS_NDIVIDES, TGRELATION, 0},
+ { "neg", TNEG, MS_NEG, TGUNOPER, 5 },
+ { "neq", TNEQ, MS_NEQ, TGRELATION, 0},
+ { "newline", TNEWLINE, '\0', 0, 0},
+ { "ni", TNI, MS_NI, TGRELATION, 0},
+ { "nitalic", TNITALIC, '\0', TGFONTATTR, 5},
+ { "none", TNONE, '\0', TGLBRACES | TGRBRACES, 0},
+ { "nospace", TNOSPACE, '\0', TGSTANDALONE, 5},
+ { "notin", TNOTIN, MS_NOTIN, TGRELATION, 0},
+ { "nroot", TNROOT, MS_SQRT, TGUNOPER, 5},
+ { "nsubset", TNSUBSET, MS_NSUBSET, TGRELATION, 0 },
+ { "nsupset", TNSUPSET, MS_NSUPSET, TGRELATION, 0 },
+ { "nsubseteq", TNSUBSETEQ, MS_NSUBSETEQ, TGRELATION, 0 },
+ { "nsupseteq", TNSUPSETEQ, MS_NSUPSETEQ, TGRELATION, 0 },
+ { "odivide", TODIVIDE, MS_ODIVIDE, TGPRODUCT, 0},
+ { "odot", TODOT, MS_ODOT, TGPRODUCT, 0},
+ { "ominus", TOMINUS, MS_OMINUS, TGSUM, 0},
+ { "oper", TOPER, '\0', TGOPER, 5},
+ { "oplus", TOPLUS, MS_OPLUS, TGSUM, 0},
+ { "or", TOR, MS_OR, TGSUM, 0},
+ { "ortho", TORTHO, MS_ORTHO, TGRELATION, 0},
+ { "otimes", TOTIMES, MS_OTIMES, TGPRODUCT, 0},
+ { "over", TOVER, '\0', TGPRODUCT, 0},
+ { "overbrace", TOVERBRACE, MS_OVERBRACE, TGPRODUCT, 5},
+ { "overline", TOVERLINE, '\0', TGATTRIBUT, 5},
+ { "overstrike", TOVERSTRIKE, '\0', TGATTRIBUT, 5},
+ { "owns", TNI, MS_NI, TGRELATION, 0},
+ { "parallel", TPARALLEL, MS_DLINE, TGRELATION, 0},
+ { "partial", TPARTIAL, MS_PARTIAL, TGSTANDALONE, 5 },
+ { "phantom", TPHANTOM, '\0', TGFONTATTR, 5},
+ { "plusminus", TPLUSMINUS, MS_PLUSMINUS, TGUNOPER | TGSUM, 5},
+ { "prod", TPROD, MS_PROD, TGOPER, 5},
+ { "prop", TPROP, MS_PROP, TGRELATION, 0},
+ { "rangle", TRANGLE, MS_RANGLE, TGRBRACES, 0}, //! 0 to terminate expression
+ { "rbrace", TRBRACE, MS_RBRACE, TGRBRACES, 0}, //
+ { "rceil", TRCEIL, MS_RCEIL, TGRBRACES, 0}, //
+ { "rdbracket", TRDBRACKET, MS_RDBRACKET, TGRBRACES, 0}, //
+ { "rdline", TRDLINE, MS_DLINE, TGRBRACES, 0}, //
+ { "red", TRED, '\0', TGCOLOR, 0},
+ { "rfloor", TRFLOOR, MS_RFLOOR, TGRBRACES, 0}, //! 0 to terminate expression
+ { "right", TRIGHT, '\0', 0, 0},
+ { "rightarrow" , TRIGHTARROW, MS_RIGHTARROW, TGSTANDALONE, 5},
+ { "rline", TRLINE, MS_LINE, TGRBRACES, 0}, //! 0 to terminate expression
+ { "rsub", TRSUB, '\0', TGPOWER, 0},
+ { "rsup", TRSUP, '\0', TGPOWER, 0},
+ { "sans", TSANS, '\0', TGFONT, 0},
+ { "serif", TSERIF, '\0', TGFONT, 0},
+ { "setC" , TSETC, MS_SETC, TGSTANDALONE, 5},
+ { "setN" , TSETN, MS_SETN, TGSTANDALONE, 5},
+ { "setQ" , TSETQ, MS_SETQ, TGSTANDALONE, 5},
+ { "setR" , TSETR, MS_SETR, TGSTANDALONE, 5},
+ { "setZ" , TSETZ, MS_SETZ, TGSTANDALONE, 5},
+ { "setminus", TBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
+ { "sim", TSIM, MS_SIM, TGRELATION, 0},
+ { "simeq", TSIMEQ, MS_SIMEQ, TGRELATION, 0},
+ { "sin", TSIN, '\0', TGFUNCTION, 5},
+ { "sinh", TSINH, '\0', TGFUNCTION, 5},
+ { "size", TSIZE, '\0', TGFONTATTR, 5},
+ { "slash", TSLASH, MS_SLASH, TGPRODUCT, 0 },
+ { "sqrt", TSQRT, MS_SQRT, TGUNOPER, 5},
+ { "stack", TSTACK, '\0', 0, 5},
+ { "sub", TRSUB, '\0', TGPOWER, 0},
+ { "subset", TSUBSET, MS_SUBSET, TGRELATION, 0},
+ { "subseteq", TSUBSETEQ, MS_SUBSETEQ, TGRELATION, 0},
+ { "sum", TSUM, MS_SUM, TGOPER, 5},
+ { "sup", TRSUP, '\0', TGPOWER, 0},
+ { "supset", TSUPSET, MS_SUPSET, TGRELATION, 0},
+ { "supseteq", TSUPSETEQ, MS_SUPSETEQ, TGRELATION, 0},
+ { "tan", TTAN, '\0', TGFUNCTION, 5},
+ { "tanh", TTANH, '\0', TGFUNCTION, 5},
+ { "tilde", TTILDE, MS_TILDE, TGATTRIBUT, 5},
+ { "times", TTIMES, MS_TIMES, TGPRODUCT, 0},
+ { "to", TTO, '\0', TGLIMIT, 0},
+ { "toward", TTOWARD, MS_RIGHTARROW, TGRELATION, 0},
+ { "transl", TTRANSL, MS_TRANSL, TGRELATION, 0},
+ { "transr", TTRANSR, MS_TRANSR, TGRELATION, 0},
+ { "underbrace", TUNDERBRACE, MS_UNDERBRACE, TGPRODUCT, 5},
+ { "underline", TUNDERLINE, '\0', TGATTRIBUT, 5},
+ { "union", TUNION, MS_UNION, TGSUM, 0},
+ { "uoper", TUOPER, '\0', TGUNOPER, 5},
+ { "uparrow" , TUPARROW, MS_UPARROW, TGSTANDALONE, 5},
+ { "vec", TVEC, MS_VEC, TGATTRIBUT, 5},
+ { "white", TWHITE, '\0', TGCOLOR, 0},
+ { "widebslash", TWIDEBACKSLASH, MS_BACKSLASH, TGPRODUCT, 0 },
+ { "widehat", TWIDEHAT, MS_HAT, TGATTRIBUT, 5},
+ { "widetilde", TWIDETILDE, MS_TILDE, TGATTRIBUT, 5},
+ { "wideslash", TWIDESLASH, MS_SLASH, TGPRODUCT, 0 },
+ { "widevec", TWIDEVEC, MS_VEC, TGATTRIBUT, 5},
+ { "wp" , TWP, MS_WP, TGSTANDALONE, 5},
+ { "yellow", TYELLOW, '\0', TGCOLOR, 0},
+ { "", TEND, '\0', 0, 0}
+};
+
+const SmTokenTableEntry * SmParser::GetTokenTableEntry( const String &rName )
+{
+ const SmTokenTableEntry * pRes = 0;
+ if (rName.Len())
+ {
+ sal_Int32 nEntries = SAL_N_ELEMENTS(aTokenTable);
+ for (sal_Int32 i = 0; i < nEntries; ++i)
+ {
+ if (rName.EqualsIgnoreCaseAscii( aTokenTable[i].pIdent ))
+ {
+ pRes = &aTokenTable[i];
+ break;
+ }
+ }
+
+ }
+
+ return pRes;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+
+#if OSL_DEBUG_LEVEL
+
+bool SmParser::IsDelimiter( const String &rTxt, xub_StrLen nPos )
+ // returns 'true' iff cChar is '\0' or a delimeter
+{
+ OSL_ENSURE( nPos <= rTxt.Len(), "index out of range" );
+
+ sal_Unicode cChar = rTxt.GetChar( nPos );
+ if(!cChar)
+ return true;
+
+ // check if 'cChar' is in the delimeter table
+ const sal_Unicode *pDelim = &aDelimiterTable[0];
+ for ( ; *pDelim != 0; pDelim++)
+ if (*pDelim == cChar)
+ break;
+
+
+ sal_Int16 nTypJp = SM_MOD()->GetSysLocale().GetCharClass().getType( rTxt, nPos );
+ bool bIsDelim = (*pDelim != 0 ||
+ nTypJp == com::sun::star::i18n::UnicodeType::SPACE_SEPARATOR ||
+ nTypJp == com::sun::star::i18n::UnicodeType::CONTROL);
+
+ return bIsDelim;
+}
+
+#endif
+
+void SmParser::Insert(const String &rText, sal_uInt16 nPos)
+{
+ m_aBufferString.Insert(rText, nPos);
+
+ xub_StrLen nLen = rText.Len();
+ m_nBufferIndex = m_nBufferIndex + nLen;
+ m_nTokenIndex = m_nTokenIndex + nLen;
+}
+
+
+void SmParser::Replace( sal_uInt16 nPos, sal_uInt16 nLen, const String &rText )
+{
+ OSL_ENSURE( nPos + nLen <= m_aBufferString.Len(), "argument mismatch" );
+
+ m_aBufferString.Replace( nPos, nLen, rText );
+ sal_Int16 nChg = rText.Len() - nLen;
+ m_nBufferIndex = m_nBufferIndex + nChg;
+ m_nTokenIndex = m_nTokenIndex + nChg;
+}
+
+
+// First character may be any alphabetic
+const sal_Int32 coStartFlags =
+ KParseTokens::ANY_LETTER_OR_NUMBER |
+ KParseTokens::IGNORE_LEADING_WS;
+
+// Continuing characters may be any alphanumeric or dot.
+const sal_Int32 coContFlags =
+ ((coStartFlags | KParseTokens::ASC_DOT) & ~KParseTokens::IGNORE_LEADING_WS)
+ | KParseTokens::TWO_DOUBLE_QUOTES_BREAK_STRING;
+
+// First character for numbers, may be any numeric or dot
+const sal_Int32 coNumStartFlags =
+ KParseTokens::ASC_DIGIT |
+ KParseTokens::ASC_DOT |
+ KParseTokens::IGNORE_LEADING_WS;
+// Continuing characters for numbers, may be any numeric or dot.
+const sal_Int32 coNumContFlags =
+ (coNumStartFlags | KParseTokens::ASC_DOT) & ~KParseTokens::IGNORE_LEADING_WS;
+
+void SmParser::NextToken()
+{
+ static const String aEmptyStr;
+
+ xub_StrLen nBufLen = m_aBufferString.Len();
+ ParseResult aRes;
+ xub_StrLen nRealStart;
+ bool bCont;
+ bool bNumStart = false;
+ CharClass aCC(SM_MOD()->GetSysLocale().GetCharClass().getLocale());
+ do
+ {
+ // skip white spaces
+ while (UnicodeType::SPACE_SEPARATOR ==
+ aCC.getType( m_aBufferString, m_nBufferIndex ))
+ ++m_nBufferIndex;
+
+ sal_Int32 nStartFlags = coStartFlags;
+ sal_Int32 nContFlags = coContFlags;
+ sal_Unicode cFirstChar = m_aBufferString.GetChar( m_nBufferIndex );
+ aRes = aCC.parseAnyToken( m_aBufferString, m_nBufferIndex,
+ nStartFlags, aEmptyStr,
+ nContFlags, aEmptyStr );
+
+ // #i45779# parse numbers correctly
+ // i.e. independent from the locale setting.
+ // (note that #i11752# remains fixed)
+ if ((aRes.TokenType & KParseType::IDENTNAME) && IsDigit( cFirstChar ))
+ {
+ //! locale where '.' is decimal seperator!
+ static lang::Locale aDotLoc( SvxCreateLocale( LANGUAGE_ENGLISH_US ) );
+
+ ParseResult aTmpRes;
+ lang::Locale aOldLoc( aCC.getLocale() );
+ aCC.setLocale( aDotLoc );
+ aTmpRes = aCC.parsePredefinedToken(
+ KParseType::ASC_NUMBER,
+ m_aBufferString, m_nBufferIndex,
+ KParseTokens::ASC_DIGIT, aEmptyStr,
+ KParseTokens::ASC_DIGIT | KParseTokens::ASC_DOT, aEmptyStr );
+ aCC.setLocale( aOldLoc );
+ if (aTmpRes.TokenType & KParseType::ASC_NUMBER)
+ aRes.TokenType = aTmpRes.TokenType;
+ }
+
+ nRealStart = m_nBufferIndex + sal::static_int_cast< xub_StrLen >(aRes.LeadingWhiteSpace);
+ m_nBufferIndex = nRealStart;
+
+ bCont = false;
+ if ( aRes.TokenType == 0 &&
+ nRealStart < nBufLen &&
+ '\n' == m_aBufferString.GetChar( nRealStart ) )
+ {
+ // keep data needed for tokens row and col entry up to date
+ ++m_Row;
+ m_nBufferIndex = m_nColOff = nRealStart + 1;
+ bCont = true;
+ }
+ else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR)
+ {
+ String aName( m_aBufferString.Copy( nRealStart, 2 ));
+ if ( aName.EqualsAscii( "%%" ))
+ {
+ //SkipComment
+ m_nBufferIndex = nRealStart + 2;
+ while (m_nBufferIndex < nBufLen &&
+ '\n' != m_aBufferString.GetChar( m_nBufferIndex ))
+ ++m_nBufferIndex;
+ bCont = true;
+ }
+ }
+
+ } while (bCont);
+
+ // set index of current token
+ m_nTokenIndex = m_nBufferIndex;
+
+ m_aCurToken.nRow = m_Row;
+ m_aCurToken.nCol = nRealStart - m_nColOff + 1;
+
+ bool bHandled = true;
+ if (nRealStart >= nBufLen)
+ {
+ m_aCurToken.eType = TEND;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.Erase();
+ }
+ else if ((aRes.TokenType & (KParseType::ASC_NUMBER | KParseType::UNI_NUMBER))
+ || (bNumStart && (aRes.TokenType & KParseType::IDENTNAME)))
+ {
+ sal_Int32 n = aRes.EndPos - nRealStart;
+ OSL_ENSURE( n >= 0, "length < 0" );
+ m_aCurToken.eType = TNUMBER;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText = m_aBufferString.Copy( nRealStart, sal::static_int_cast< xub_StrLen >(n) );
+
+#if OSL_DEBUG_LEVEL > 1
+ if (!IsDelimiter( m_aBufferString, static_cast< xub_StrLen >(aRes.EndPos) ))
+ {
+ DBG_WARNING( "identifier really finished? (compatibility!)" );
+ }
+#endif
+ }
+ else if (aRes.TokenType & KParseType::DOUBLE_QUOTE_STRING)
+ {
+ m_aCurToken.eType = TTEXT;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText = aRes.DequotedNameOrString;
+ m_aCurToken.nRow = m_Row;
+ m_aCurToken.nCol = nRealStart - m_nColOff + 2;
+ }
+ else if (aRes.TokenType & KParseType::IDENTNAME)
+ {
+ sal_Int32 n = aRes.EndPos - nRealStart;
+ OSL_ENSURE( n >= 0, "length < 0" );
+ String aName( m_aBufferString.Copy( nRealStart, sal::static_int_cast< xub_StrLen >(n) ) );
+ const SmTokenTableEntry *pEntry = GetTokenTableEntry( aName );
+
+ if (pEntry)
+ {
+ m_aCurToken.eType = pEntry->eType;
+ m_aCurToken.cMathChar = pEntry->cMathChar;
+ m_aCurToken.nGroup = pEntry->nGroup;
+ m_aCurToken.nLevel = pEntry->nLevel;
+ m_aCurToken.aText.AssignAscii( pEntry->pIdent );
+ }
+ else
+ {
+ m_aCurToken.eType = TIDENT;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText = aName;
+
+#if OSL_DEBUG_LEVEL > 1
+ if (!IsDelimiter( m_aBufferString, static_cast< xub_StrLen >(aRes.EndPos) ))
+ {
+ DBG_WARNING( "identifier really finished? (compatibility!)" );
+ }
+#endif
+ }
+ }
+ else if (aRes.TokenType == 0 && '_' == m_aBufferString.GetChar( nRealStart ))
+ {
+ m_aCurToken.eType = TRSUB;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = TGPOWER;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "_" );
+
+ aRes.EndPos = nRealStart + 1;
+ }
+ else if (aRes.TokenType & KParseType::BOOLEAN)
+ {
+ sal_Int32 &rnEndPos = aRes.EndPos;
+ String aName( m_aBufferString.Copy( nRealStart,
+ sal::static_int_cast< xub_StrLen >(rnEndPos - nRealStart) ));
+ if (2 >= aName.Len())
+ {
+ sal_Unicode ch = aName.GetChar( 0 );
+ switch (ch)
+ {
+ case '<':
+ {
+ if (m_aBufferString.Copy( nRealStart, 2 ).
+ EqualsAscii( "<<" ))
+ {
+ m_aCurToken.eType = TLL;
+ m_aCurToken.cMathChar = MS_LL;
+ m_aCurToken.nGroup = TGRELATION;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "<<" );
+
+ rnEndPos = nRealStart + 2;
+ }
+ else if (m_aBufferString.Copy( nRealStart, 2 ).
+ EqualsAscii( "<=" ))
+ {
+ m_aCurToken.eType = TLE;
+ m_aCurToken.cMathChar = MS_LE;
+ m_aCurToken.nGroup = TGRELATION;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "<=" );
+
+ rnEndPos = nRealStart + 2;
+ }
+ else if (m_aBufferString.Copy( nRealStart, 2 ).
+ EqualsAscii( "<>" ))
+ {
+ m_aCurToken.eType = TNEQ;
+ m_aCurToken.cMathChar = MS_NEQ;
+ m_aCurToken.nGroup = TGRELATION;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "<>" );
+
+ rnEndPos = nRealStart + 2;
+ }
+ else if (m_aBufferString.Copy( nRealStart, 3 ).
+ EqualsAscii( "<?>" ))
+ {
+ m_aCurToken.eType = TPLACE;
+ m_aCurToken.cMathChar = MS_PLACE;
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "<?>" );
+
+ rnEndPos = nRealStart + 3;
+ }
+ else
+ {
+ m_aCurToken.eType = TLT;
+ m_aCurToken.cMathChar = MS_LT;
+ m_aCurToken.nGroup = TGRELATION;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "<" );
+ }
+ }
+ break;
+ case '>':
+ {
+ if (m_aBufferString.Copy( nRealStart, 2 ).
+ EqualsAscii( ">=" ))
+ {
+ m_aCurToken.eType = TGE;
+ m_aCurToken.cMathChar = MS_GE;
+ m_aCurToken.nGroup = TGRELATION;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( ">=" );
+
+ rnEndPos = nRealStart + 2;
+ }
+ else if (m_aBufferString.Copy( nRealStart, 2 ).
+ EqualsAscii( ">>" ))
+ {
+ m_aCurToken.eType = TGG;
+ m_aCurToken.cMathChar = MS_GG;
+ m_aCurToken.nGroup = TGRELATION;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( ">>" );
+
+ rnEndPos = nRealStart + 2;
+ }
+ else
+ {
+ m_aCurToken.eType = TGT;
+ m_aCurToken.cMathChar = MS_GT;
+ m_aCurToken.nGroup = TGRELATION;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( ">" );
+ }
+ }
+ break;
+ default:
+ bHandled = false;
+ }
+ }
+ }
+ else if (aRes.TokenType & KParseType::ONE_SINGLE_CHAR)
+ {
+ sal_Int32 &rnEndPos = aRes.EndPos;
+ String aName( m_aBufferString.Copy( nRealStart,
+ sal::static_int_cast< xub_StrLen >(rnEndPos - nRealStart) ) );
+
+ if (1 == aName.Len())
+ {
+ sal_Unicode ch = aName.GetChar( 0 );
+ switch (ch)
+ {
+ case '%':
+ {
+ //! modifies aRes.EndPos
+
+ OSL_ENSURE( rnEndPos >= nBufLen ||
+ '%' != m_aBufferString.GetChar( sal::static_int_cast< xub_StrLen >(rnEndPos) ),
+ "unexpected comment start" );
+
+ // get identifier of user-defined character
+ ParseResult aTmpRes = aCC.parseAnyToken(
+ m_aBufferString, rnEndPos,
+ KParseTokens::ANY_LETTER,
+ aEmptyStr,
+ coContFlags,
+ aEmptyStr );
+
+ xub_StrLen nTmpStart = sal::static_int_cast< xub_StrLen >(rnEndPos +
+ aTmpRes.LeadingWhiteSpace);
+
+ // default setting for the case that no identifier
+ // i.e. a valid symbol-name is following the '%'
+ // character
+ m_aCurToken.eType = TTEXT;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText = String();
+ m_aCurToken.nRow = sal::static_int_cast< xub_StrLen >(m_Row);
+ m_aCurToken.nCol = nTmpStart - m_nColOff;
+
+ if (aTmpRes.TokenType & KParseType::IDENTNAME)
+ {
+
+ xub_StrLen n = sal::static_int_cast< xub_StrLen >(aTmpRes.EndPos - nTmpStart);
+ m_aCurToken.eType = TSPECIAL;
+ m_aCurToken.aText = m_aBufferString.Copy( sal::static_int_cast< xub_StrLen >(nTmpStart-1), n+1 );
+
+ OSL_ENSURE( aTmpRes.EndPos > rnEndPos,
+ "empty identifier" );
+ if (aTmpRes.EndPos > rnEndPos)
+ rnEndPos = aTmpRes.EndPos;
+ else
+ ++rnEndPos;
+ }
+
+ // if no symbol-name was found we start-over with
+ // finding the next token right afer the '%' sign.
+ // I.e. we leave rnEndPos unmodified.
+ }
+ break;
+ case '[':
+ {
+ m_aCurToken.eType = TLBRACKET;
+ m_aCurToken.cMathChar = MS_LBRACKET;
+ m_aCurToken.nGroup = TGLBRACES;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "[" );
+ }
+ break;
+ case '\\':
+ {
+ m_aCurToken.eType = TESCAPE;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "\\" );
+ }
+ break;
+ case ']':
+ {
+ m_aCurToken.eType = TRBRACKET;
+ m_aCurToken.cMathChar = MS_RBRACKET;
+ m_aCurToken.nGroup = TGRBRACES;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "]" );
+ }
+ break;
+ case '^':
+ {
+ m_aCurToken.eType = TRSUP;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = TGPOWER;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "^" );
+ }
+ break;
+ case '`':
+ {
+ m_aCurToken.eType = TSBLANK;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = TGBLANK;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "`" );
+ }
+ break;
+ case '{':
+ {
+ m_aCurToken.eType = TLGROUP;
+ m_aCurToken.cMathChar = MS_LBRACE;
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "{" );
+ }
+ break;
+ case '|':
+ {
+ m_aCurToken.eType = TOR;
+ m_aCurToken.cMathChar = MS_OR;
+ m_aCurToken.nGroup = TGSUM;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "|" );
+ }
+ break;
+ case '}':
+ {
+ m_aCurToken.eType = TRGROUP;
+ m_aCurToken.cMathChar = MS_RBRACE;
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "}" );
+ }
+ break;
+ case '~':
+ {
+ m_aCurToken.eType = TBLANK;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = TGBLANK;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "~" );
+ }
+ break;
+ case '#':
+ {
+ if (m_aBufferString.Copy( nRealStart, 2 ).
+ EqualsAscii( "##" ))
+ {
+ m_aCurToken.eType = TDPOUND;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "##" );
+
+ rnEndPos = nRealStart + 2;
+ }
+ else
+ {
+ m_aCurToken.eType = TPOUND;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "#" );
+ }
+ }
+ break;
+ case '&':
+ {
+ m_aCurToken.eType = TAND;
+ m_aCurToken.cMathChar = MS_AND;
+ m_aCurToken.nGroup = TGPRODUCT;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "&" );
+ }
+ break;
+ case '(':
+ {
+ m_aCurToken.eType = TLPARENT;
+ m_aCurToken.cMathChar = MS_LPARENT;
+ m_aCurToken.nGroup = TGLBRACES;
+ m_aCurToken.nLevel = 5; //! 0 to continue expression
+ m_aCurToken.aText.AssignAscii( "(" );
+ }
+ break;
+ case ')':
+ {
+ m_aCurToken.eType = TRPARENT;
+ m_aCurToken.cMathChar = MS_RPARENT;
+ m_aCurToken.nGroup = TGRBRACES;
+ m_aCurToken.nLevel = 0; //! 0 to terminate expression
+ m_aCurToken.aText.AssignAscii( ")" );
+ }
+ break;
+ case '*':
+ {
+ m_aCurToken.eType = TMULTIPLY;
+ m_aCurToken.cMathChar = MS_MULTIPLY;
+ m_aCurToken.nGroup = TGPRODUCT;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "*" );
+ }
+ break;
+ case '+':
+ {
+ if (m_aBufferString.Copy( nRealStart, 2 ).
+ EqualsAscii( "+-" ))
+ {
+ m_aCurToken.eType = TPLUSMINUS;
+ m_aCurToken.cMathChar = MS_PLUSMINUS;
+ m_aCurToken.nGroup = TGUNOPER | TGSUM;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "+-" );
+
+ rnEndPos = nRealStart + 2;
+ }
+ else
+ {
+ m_aCurToken.eType = TPLUS;
+ m_aCurToken.cMathChar = MS_PLUS;
+ m_aCurToken.nGroup = TGUNOPER | TGSUM;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "+" );
+ }
+ }
+ break;
+ case '-':
+ {
+ if (m_aBufferString.Copy( nRealStart, 2 ).
+ EqualsAscii( "-+" ))
+ {
+ m_aCurToken.eType = TMINUSPLUS;
+ m_aCurToken.cMathChar = MS_MINUSPLUS;
+ m_aCurToken.nGroup = TGUNOPER | TGSUM;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "-+" );
+
+ rnEndPos = nRealStart + 2;
+ }
+ else
+ {
+ m_aCurToken.eType = TMINUS;
+ m_aCurToken.cMathChar = MS_MINUS;
+ m_aCurToken.nGroup = TGUNOPER | TGSUM;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText.AssignAscii( "-" );
+ }
+ }
+ break;
+ case '.':
+ {
+ // for compatibility with SO5.2
+ // texts like .34 ...56 ... h ...78..90
+ // will be treated as numbers
+ m_aCurToken.eType = TNUMBER;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+
+ xub_StrLen nTxtStart = m_nBufferIndex;
+ sal_Unicode cChar;
+ do
+ {
+ cChar = m_aBufferString.GetChar( ++m_nBufferIndex );
+ }
+ while ( cChar == '.' || IsDigit( cChar ) );
+
+ m_aCurToken.aText = m_aBufferString.Copy( sal::static_int_cast< xub_StrLen >(nTxtStart),
+ sal::static_int_cast< xub_StrLen >(m_nBufferIndex - nTxtStart) );
+ aRes.EndPos = m_nBufferIndex;
+ }
+ break;
+ case '/':
+ {
+ m_aCurToken.eType = TDIVIDEBY;
+ m_aCurToken.cMathChar = MS_SLASH;
+ m_aCurToken.nGroup = TGPRODUCT;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "/" );
+ }
+ break;
+ case '=':
+ {
+ m_aCurToken.eType = TASSIGN;
+ m_aCurToken.cMathChar = MS_ASSIGN;
+ m_aCurToken.nGroup = TGRELATION;
+ m_aCurToken.nLevel = 0;
+ m_aCurToken.aText.AssignAscii( "=" );
+ }
+ break;
+ default:
+ bHandled = false;
+ }
+ }
+ }
+ else
+ bHandled = false;
+
+ if (!bHandled)
+ {
+ m_aCurToken.eType = TCHARACTER;
+ m_aCurToken.cMathChar = '\0';
+ m_aCurToken.nGroup = 0;
+ m_aCurToken.nLevel = 5;
+ m_aCurToken.aText = m_aBufferString.Copy( nRealStart, 1 );
+
+ aRes.EndPos = nRealStart + 1;
+ }
+
+ if (TEND != m_aCurToken.eType)
+ m_nBufferIndex = sal::static_int_cast< xub_StrLen >(aRes.EndPos);
+}
+
+
+////////////////////////////////////////
+// grammar
+//
+
+
+void SmParser::Table()
+{
+ SmNodeArray LineArray;
+
+ Line();
+ while (m_aCurToken.eType == TNEWLINE)
+ {
+ NextToken();
+ Line();
+ }
+
+ if (m_aCurToken.eType != TEND)
+ Error(PE_UNEXPECTED_CHAR);
+
+ sal_uLong n = m_aNodeStack.Count();
+
+ LineArray.resize(n);
+
+ for (sal_uLong i = 0; i < n; i++)
+ LineArray[n - (i + 1)] = m_aNodeStack.Pop();
+
+ SmStructureNode *pSNode = new SmTableNode(m_aCurToken);
+ pSNode->SetSubNodes(LineArray);
+ m_aNodeStack.Push(pSNode);
+}
+
+
+void SmParser::Align()
+ // parse alignment info (if any), then go on with rest of expression
+{
+ SmStructureNode *pSNode = 0;
+ bool bNeedGroupClose = false;
+
+ if (TokenInGroup(TGALIGN))
+ {
+ if (CONVERT_40_TO_50 == GetConversion())
+ // encapsulate expression to be aligned in group braces
+ // (here group-open brace)
+ { Insert('{', GetTokenIndex());
+ bNeedGroupClose = true;
+
+ // get first valid align statement in sequence
+ // (the dominant one in 4.0) and erase all others (especially old
+ // discarded tokens) from command string.
+ while (TokenInGroup(TGALIGN))
+ {
+ if (TokenInGroup(TGDISCARDED) || pSNode)
+ {
+ m_nBufferIndex = GetTokenIndex();
+ m_aBufferString.Erase(m_nBufferIndex, m_aCurToken.aText.Len());
+ }
+ else
+ pSNode = new SmAlignNode(m_aCurToken);
+
+ NextToken();
+ }
+ }
+ else
+ {
+ pSNode = new SmAlignNode(m_aCurToken);
+
+ NextToken();
+
+ // allow for just one align statement in 5.0
+ if (CONVERT_40_TO_50 != GetConversion() && TokenInGroup(TGALIGN))
+ { Error(PE_DOUBLE_ALIGN);
+ return;
+ }
+ }
+ }
+
+ Expression();
+
+ if (bNeedGroupClose)
+ Insert('}', GetTokenIndex());
+
+ if (pSNode)
+ { pSNode->SetSubNodes(m_aNodeStack.Pop(), 0);
+ m_aNodeStack.Push(pSNode);
+ }
+}
+
+
+void SmParser::Line()
+{
+ sal_uInt16 n = 0;
+ SmNodeArray ExpressionArray;
+
+ ExpressionArray.resize(n);
+
+ // start with single expression that may have an alignment statement
+ // (and go on with expressions that must not have alignment
+ // statements in 'while' loop below. See also 'Expression()'.)
+ if (m_aCurToken.eType != TEND && m_aCurToken.eType != TNEWLINE)
+ { Align();
+ ExpressionArray.resize(++n);
+ ExpressionArray[n - 1] = m_aNodeStack.Pop();
+ }
+
+ while (m_aCurToken.eType != TEND && m_aCurToken.eType != TNEWLINE)
+ { if (CONVERT_40_TO_50 != GetConversion())
+ Expression();
+ else
+ Align();
+ ExpressionArray.resize(++n);
+ ExpressionArray[n - 1] = m_aNodeStack.Pop();
+ }
+
+ //If there's no expression, add an empty one.
+ //this is to avoid a formula tree without any caret
+ //positions, in visual formula editor.
+ if(ExpressionArray.size() == 0)
+ ExpressionArray.push_back(new SmExpressionNode(SmToken()));
+
+ SmStructureNode *pSNode = new SmLineNode(m_aCurToken);
+ pSNode->SetSubNodes(ExpressionArray);
+ m_aNodeStack.Push(pSNode);
+}
+
+
+void SmParser::Expression()
+{
+ bool bUseExtraSpaces = true;
+ SmNode *pNode = m_aNodeStack.Pop();
+ if (pNode)
+ {
+ if (pNode->GetToken().eType == TNOSPACE)
+ bUseExtraSpaces = false;
+ else
+ m_aNodeStack.Push(pNode); // push the node from above again (now to be used as argument to this current 'nospace' node)
+ }
+
+ sal_uInt16 n = 0;
+ SmNodeArray RelationArray;
+
+ RelationArray.resize(n);
+
+ Relation();
+ RelationArray.resize(++n);
+ RelationArray[n - 1] = m_aNodeStack.Pop();
+
+ while (m_aCurToken.nLevel >= 4)
+ { Relation();
+ RelationArray.resize(++n);
+ RelationArray[n - 1] = m_aNodeStack.Pop();
+ }
+
+ SmExpressionNode *pSNode = new SmExpressionNode(m_aCurToken);
+ pSNode->SetSubNodes(RelationArray);
+ pSNode->SetUseExtraSpaces(bUseExtraSpaces);
+ m_aNodeStack.Push(pSNode);
+}
+
+
+void SmParser::Relation()
+{
+ Sum();
+ while (TokenInGroup(TGRELATION))
+ {
+ SmStructureNode *pSNode = new SmBinHorNode(m_aCurToken);
+ SmNode *pFirst = m_aNodeStack.Pop();
+
+ OpSubSup();
+ SmNode *pSecond = m_aNodeStack.Pop();
+
+ Sum();
+
+ pSNode->SetSubNodes(pFirst, pSecond, m_aNodeStack.Pop());
+ m_aNodeStack.Push(pSNode);
+ }
+}
+
+
+void SmParser::Sum()
+{
+ Product();
+ while (TokenInGroup(TGSUM))
+ {
+ SmStructureNode *pSNode = new SmBinHorNode(m_aCurToken);
+ SmNode *pFirst = m_aNodeStack.Pop();
+
+ OpSubSup();
+ SmNode *pSecond = m_aNodeStack.Pop();
+
+ Product();
+
+ pSNode->SetSubNodes(pFirst, pSecond, m_aNodeStack.Pop());
+ m_aNodeStack.Push(pSNode);
+ }
+}
+
+
+void SmParser::Product()
+{
+ Power();
+
+ while (TokenInGroup(TGPRODUCT))
+ { SmStructureNode *pSNode;
+ SmNode *pFirst = m_aNodeStack.Pop(),
+ *pOper;
+ bool bSwitchArgs = false;
+
+ SmTokenType eType = m_aCurToken.eType;
+ switch (eType)
+ {
+ case TOVER:
+ pSNode = new SmBinVerNode(m_aCurToken);
+ pOper = new SmRectangleNode(m_aCurToken);
+ NextToken();
+ break;
+
+ case TBOPER:
+ pSNode = new SmBinHorNode(m_aCurToken);
+
+ NextToken();
+
+ //Let the glyph node know it's a binary operation
+ m_aCurToken.eType = TBOPER;
+ m_aCurToken.nGroup = TGPRODUCT;
+
+ GlyphSpecial();
+ pOper = m_aNodeStack.Pop();
+ break;
+
+ case TOVERBRACE :
+ case TUNDERBRACE :
+ pSNode = new SmVerticalBraceNode(m_aCurToken);
+ pOper = new SmMathSymbolNode(m_aCurToken);
+
+ NextToken();
+ break;
+
+ case TWIDEBACKSLASH:
+ case TWIDESLASH:
+ {
+ SmBinDiagonalNode *pSTmp = new SmBinDiagonalNode(m_aCurToken);
+ pSTmp->SetAscending(eType == TWIDESLASH);
+ pSNode = pSTmp;
+
+ pOper = new SmPolyLineNode(m_aCurToken);
+ NextToken();
+
+ bSwitchArgs = true;
+ break;
+ }
+
+ default:
+ pSNode = new SmBinHorNode(m_aCurToken);
+
+ OpSubSup();
+ pOper = m_aNodeStack.Pop();
+ }
+
+ Power();
+
+ if (bSwitchArgs)
+ //! vgl siehe SmBinDiagonalNode::Arrange
+ pSNode->SetSubNodes(pFirst, m_aNodeStack.Pop(), pOper);
+ else
+ pSNode->SetSubNodes(pFirst, pOper, m_aNodeStack.Pop());
+ m_aNodeStack.Push(pSNode);
+ }
+}
+
+
+void SmParser::SubSup(sal_uLong nActiveGroup)
+{
+ OSL_ENSURE(nActiveGroup == TGPOWER || nActiveGroup == TGLIMIT,
+ "Sm: wrong token group");
+
+ if (!TokenInGroup(nActiveGroup))
+ // already finish
+ return;
+
+ SmSubSupNode *pNode = new SmSubSupNode(m_aCurToken);
+ //! Of course 'm_aCurToken' is just the first sub-/supscript token.
+ //! It should be of no further interest. The positions of the
+ //! sub-/supscripts will be identified by the corresponding subnodes
+ //! index in the 'aSubNodes' array (enum value from 'SmSubSup').
+
+ pNode->SetUseLimits(nActiveGroup == TGLIMIT);
+
+ // initialize subnodes array
+ SmNodeArray aSubNodes;
+ aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
+ aSubNodes[0] = m_aNodeStack.Pop();
+ for (sal_uInt16 i = 1; i < aSubNodes.size(); i++)
+ aSubNodes[i] = NULL;
+
+ // process all sub-/supscripts
+ int nIndex = 0;
+ while (TokenInGroup(nActiveGroup))
+ { SmTokenType eType (m_aCurToken.eType);
+
+ // skip sub-/supscript token
+ NextToken();
+
+ // get sub-/supscript node on top of stack
+ if (eType == TFROM || eType == TTO)
+ {
+ // parse limits in old 4.0 and 5.0 style
+ Relation();
+ }
+ else
+ Term();
+
+ switch (eType)
+ { case TRSUB : nIndex = (int) RSUB; break;
+ case TRSUP : nIndex = (int) RSUP; break;
+ case TFROM :
+ case TCSUB : nIndex = (int) CSUB; break;
+ case TTO :
+ case TCSUP : nIndex = (int) CSUP; break;
+ case TLSUB : nIndex = (int) LSUB; break;
+ case TLSUP : nIndex = (int) LSUP; break;
+ default :
+ OSL_FAIL("Sm: unknown case");
+ }
+ nIndex++;
+ OSL_ENSURE(1 <= nIndex && nIndex <= 1 + SUBSUP_NUM_ENTRIES,
+ "SmParser::Power() : sub-/supscript index falsch");
+
+ // set sub-/supscript if not already done
+ if (aSubNodes[nIndex] != NULL)
+ Error(PE_DOUBLE_SUBSUPSCRIPT);
+ aSubNodes[nIndex] = m_aNodeStack.Pop();
+ }
+
+ pNode->SetSubNodes(aSubNodes);
+ m_aNodeStack.Push(pNode);
+}
+
+
+void SmParser::OpSubSup()
+{
+ // push operator symbol
+ m_aNodeStack.Push(new SmMathSymbolNode(m_aCurToken));
+ // skip operator token
+ NextToken();
+ // get sub- supscripts if any
+ if (TokenInGroup(TGPOWER))
+ SubSup(TGPOWER);
+}
+
+
+void SmParser::Power()
+{
+ // get body for sub- supscripts on top of stack
+ Term();
+
+ SubSup(TGPOWER);
+}
+
+
+void SmParser::Blank()
+{
+ OSL_ENSURE(TokenInGroup(TGBLANK), "Sm : wrong token");
+ SmBlankNode *pBlankNode = new SmBlankNode(m_aCurToken);
+
+ while (TokenInGroup(TGBLANK))
+ {
+ pBlankNode->IncreaseBy(m_aCurToken);
+ NextToken();
+ }
+
+ // Blanks am Zeilenende ignorieren wenn die entsprechende Option gesetzt ist
+ if ( m_aCurToken.eType == TNEWLINE ||
+ (m_aCurToken.eType == TEND && SM_MOD()->GetConfig()->IsIgnoreSpacesRight()) )
+ {
+ pBlankNode->Clear();
+ }
+
+ m_aNodeStack.Push(pBlankNode);
+}
+
+
+void SmParser::Term()
+{
+ switch (m_aCurToken.eType)
+ {
+ case TESCAPE :
+ Escape();
+ break;
+
+ case TNOSPACE :
+ case TLGROUP :
+ {
+ bool bNoSpace = m_aCurToken.eType == TNOSPACE;
+ if (bNoSpace) // push 'no space' node and continue to parse expression
+ {
+ m_aNodeStack.Push(new SmExpressionNode(m_aCurToken));
+ NextToken();
+ }
+ if (m_aCurToken.eType != TLGROUP)
+ {
+ m_aNodeStack.Pop(); // get rid of the 'no space' node pushed above
+ Term();
+ }
+ else
+ {
+ NextToken();
+
+ // allow for empty group
+ if (m_aCurToken.eType == TRGROUP)
+ {
+ if (bNoSpace) // get rid of the 'no space' node pushed above
+ m_aNodeStack.Pop();
+ SmStructureNode *pSNode = new SmExpressionNode(m_aCurToken);
+ pSNode->SetSubNodes(NULL, NULL);
+ m_aNodeStack.Push(pSNode);
+
+ NextToken();
+ }
+ else // go as usual
+ {
+ Align();
+ if (m_aCurToken.eType != TRGROUP)
+ Error(PE_RGROUP_EXPECTED);
+ else
+ NextToken();
+ }
+ }
+ }
+ break;
+
+ case TLEFT :
+ Brace();
+ break;
+
+ case TBLANK :
+ case TSBLANK :
+ Blank();
+ break;
+
+ case TTEXT :
+ m_aNodeStack.Push(new SmTextNode(m_aCurToken, FNT_TEXT));
+ NextToken();
+ break;
+ case TIDENT :
+ case TCHARACTER :
+ m_aNodeStack.Push(new SmTextNode(m_aCurToken, FNT_VARIABLE));
+ NextToken();
+ break;
+ case TNUMBER :
+ m_aNodeStack.Push(new SmTextNode(m_aCurToken, FNT_NUMBER));
+ NextToken();
+ break;
+
+ case TLEFTARROW :
+ case TRIGHTARROW :
+ case TUPARROW :
+ case TDOWNARROW :
+ case TSETN :
+ case TSETZ :
+ case TSETQ :
+ case TSETR :
+ case TSETC :
+ case THBAR :
+ case TLAMBDABAR :
+ case TCIRC :
+ case TDRARROW :
+ case TDLARROW :
+ case TDLRARROW :
+ case TBACKEPSILON :
+ case TALEPH :
+ case TIM :
+ case TRE :
+ case TWP :
+ case TEMPTYSET :
+ case TINFINITY :
+ case TEXISTS :
+ case TFORALL :
+ case TPARTIAL :
+ case TNABLA :
+ case TTOWARD :
+ case TDOTSAXIS :
+ case TDOTSDIAG :
+ case TDOTSDOWN :
+ case TDOTSLOW :
+ case TDOTSUP :
+ case TDOTSVERT :
+ m_aNodeStack.Push(new SmMathSymbolNode(m_aCurToken));
+ NextToken();
+ break;
+
+ case TPLACE:
+ m_aNodeStack.Push(new SmPlaceNode(m_aCurToken));
+ NextToken();
+ break;
+
+ case TSPECIAL:
+ Special();
+ break;
+
+ case TBINOM:
+ Binom();
+ break;
+
+ case TSTACK:
+ Stack();
+ break;
+
+ case TMATRIX:
+ Matrix();
+ break;
+
+ default:
+ if (TokenInGroup(TGLBRACES))
+ { Brace();
+ }
+ else if (TokenInGroup(TGOPER))
+ { Operator();
+ }
+ else if (TokenInGroup(TGUNOPER))
+ { UnOper();
+ }
+ else if ( TokenInGroup(TGATTRIBUT)
+ || TokenInGroup(TGFONTATTR))
+ { SmStructureNodeArray aArray;
+
+ bool bIsAttr;
+ sal_uInt16 n = 0;
+ while (true == (bIsAttr = TokenInGroup(TGATTRIBUT))
+ || TokenInGroup(TGFONTATTR))
+ { aArray.resize(n + 1);
+
+ if (bIsAttr)
+ Attribut();
+ else
+ FontAttribut();
+
+ // check if casting in following line is ok
+ OSL_ENSURE(!m_aNodeStack.Top()->IsVisible(), "Sm : Ooops...");
+
+ aArray[n] = (SmStructureNode *) m_aNodeStack.Pop();
+ n++;
+ }
+
+ Power();
+
+ SmNode *pFirstNode = m_aNodeStack.Pop();
+ while (n > 0)
+ { aArray[n - 1]->SetSubNodes(0, pFirstNode);
+ pFirstNode = aArray[n - 1];
+ n--;
+ }
+ m_aNodeStack.Push(pFirstNode);
+ }
+ else if (TokenInGroup(TGFUNCTION))
+ { if (CONVERT_40_TO_50 != GetConversion())
+ { Function();
+ }
+ else // encapsulate old 4.0 style parsing in braces
+ {
+ // insert opening brace
+ Insert('{', GetTokenIndex());
+
+ //
+ // parse in 4.0 style
+ //
+ Function();
+
+ SmNode *pFunc = m_aNodeStack.Pop();
+
+ if (m_aCurToken.eType == TLPARENT)
+ { Term();
+ }
+ else
+ { Align();
+ }
+
+ // insert closing brace
+ Insert('}', GetTokenIndex());
+
+ SmStructureNode *pSNode = new SmExpressionNode(pFunc->GetToken());
+ pSNode->SetSubNodes(pFunc, m_aNodeStack.Pop());
+ m_aNodeStack.Push(pSNode);
+ }
+ }
+ else
+ Error(PE_UNEXPECTED_CHAR);
+ }
+}
+
+
+void SmParser::Escape()
+{
+ NextToken();
+
+ switch (m_aCurToken.eType)
+ {
+ case TLPARENT :
+ case TRPARENT :
+ case TLBRACKET :
+ case TRBRACKET :
+ case TLDBRACKET :
+ case TRDBRACKET :
+ case TLBRACE :
+ case TLGROUP :
+ case TRBRACE :
+ case TRGROUP :
+ case TLANGLE :
+ case TRANGLE :
+ case TLCEIL :
+ case TRCEIL :
+ case TLFLOOR :
+ case TRFLOOR :
+ case TLLINE :
+ case TRLINE :
+ case TLDLINE :
+ case TRDLINE :
+ break;
+ default:
+ Error(PE_UNEXPECTED_TOKEN);
+ }
+
+ SmNode *pNode = new SmMathSymbolNode(m_aCurToken);
+ m_aNodeStack.Push(pNode);
+
+ NextToken();
+}
+
+
+void SmParser::Operator()
+{
+ if (TokenInGroup(TGOPER))
+ { SmStructureNode *pSNode = new SmOperNode(m_aCurToken);
+
+ // put operator on top of stack
+ Oper();
+
+ if (TokenInGroup(TGLIMIT) || TokenInGroup(TGPOWER))
+ SubSup(m_aCurToken.nGroup);
+ SmNode *pOperator = m_aNodeStack.Pop();
+
+ // get argument
+ Power();
+
+ pSNode->SetSubNodes(pOperator, m_aNodeStack.Pop());
+ m_aNodeStack.Push(pSNode);
+ }
+}
+
+
+void SmParser::Oper()
+{
+ SmTokenType eType (m_aCurToken.eType);
+ SmNode *pNode = NULL;
+
+ switch (eType)
+ {
+ case TSUM :
+ case TPROD :
+ case TCOPROD :
+ case TINT :
+ case TIINT :
+ case TIIINT :
+ case TLINT :
+ case TLLINT :
+ case TLLLINT :
+ pNode = new SmMathSymbolNode(m_aCurToken);
+ break;
+
+ case TLIM :
+ case TLIMSUP :
+ case TLIMINF :
+ {
+ const sal_Char* pLim = 0;
+ switch (eType)
+ {
+ case TLIM : pLim = "lim"; break;
+ case TLIMSUP : pLim = "lim sup"; break;
+ case TLIMINF : pLim = "lim inf"; break;
+ default:
+ break;
+ }
+ if( pLim )
+ m_aCurToken.aText.AssignAscii( pLim );
+ pNode = new SmTextNode(m_aCurToken, FNT_TEXT);
+ }
+ break;
+
+ case TOVERBRACE :
+ case TUNDERBRACE :
+ pNode = new SmMathSymbolNode(m_aCurToken);
+ break;
+
+ case TOPER :
+ NextToken();
+
+ OSL_ENSURE(m_aCurToken.eType == TSPECIAL, "Sm: wrong token");
+ pNode = new SmGlyphSpecialNode(m_aCurToken);
+ break;
+
+ default :
+ OSL_FAIL("Sm: unknown case");
+ }
+ m_aNodeStack.Push(pNode);
+
+ NextToken();
+}
+
+
+void SmParser::UnOper()
+{
+ OSL_ENSURE(TokenInGroup(TGUNOPER), "Sm: wrong token");
+
+ SmToken aNodeToken = m_aCurToken;
+ SmTokenType eType = m_aCurToken.eType;
+ bool bIsPostfix = eType == TFACT;
+
+ SmStructureNode *pSNode;
+ SmNode *pOper = 0,
+ *pExtra = 0,
+ *pArg;
+
+ switch (eType)
+ {
+ case TABS :
+ case TSQRT :
+ NextToken();
+ break;
+
+ case TNROOT :
+ NextToken();
+ Power();
+ pExtra = m_aNodeStack.Pop();
+ break;
+
+ case TUOPER :
+ NextToken();
+ //Let the glyph know what it is...
+ m_aCurToken.eType = TUOPER;
+ m_aCurToken.nGroup = TGUNOPER;
+ GlyphSpecial();
+ pOper = m_aNodeStack.Pop();
+ break;
+
+ case TPLUS :
+ case TMINUS :
+ case TPLUSMINUS :
+ case TMINUSPLUS :
+ case TNEG :
+ case TFACT :
+ OpSubSup();
+ pOper = m_aNodeStack.Pop();
+ break;
+
+ default :
+ Error(PE_UNOPER_EXPECTED);
+ }
+
+ // get argument
+ Power();
+ pArg = m_aNodeStack.Pop();
+
+ if (eType == TABS)
+ { pSNode = new SmBraceNode(aNodeToken);
+ pSNode->SetScaleMode(SCALE_HEIGHT);
+
+ // build nodes for left & right lines
+ // (text, group, level of the used token are of no interrest here)
+ // we'll use row & column of the keyword for abs
+ aNodeToken.eType = TABS;
+ //
+ aNodeToken.cMathChar = MS_LINE;
+ SmNode* pLeft = new SmMathSymbolNode(aNodeToken);
+ //
+ aNodeToken.cMathChar = MS_LINE;
+ SmNode* pRight = new SmMathSymbolNode(aNodeToken);
+
+ pSNode->SetSubNodes(pLeft, pArg, pRight);
+ }
+ else if (eType == TSQRT || eType == TNROOT)
+ { pSNode = new SmRootNode(aNodeToken);
+ pOper = new SmRootSymbolNode(aNodeToken);
+ pSNode->SetSubNodes(pExtra, pOper, pArg);
+ }
+ else
+ { pSNode = new SmUnHorNode(aNodeToken);
+
+ if (bIsPostfix)
+ pSNode->SetSubNodes(pArg, pOper);
+ else
+ // prefix operator
+ pSNode->SetSubNodes(pOper, pArg);
+ }
+
+ m_aNodeStack.Push(pSNode);
+}
+
+
+void SmParser::Attribut()
+{
+ OSL_ENSURE(TokenInGroup(TGATTRIBUT), "Sm: wrong token group");
+
+ SmStructureNode *pSNode = new SmAttributNode(m_aCurToken);
+ SmNode *pAttr;
+ SmScaleMode eScaleMode = SCALE_NONE;
+
+ // get appropriate node for the attribut itself
+ switch (m_aCurToken.eType)
+ { case TUNDERLINE :
+ case TOVERLINE :
+ case TOVERSTRIKE :
+ pAttr = new SmRectangleNode(m_aCurToken);
+ eScaleMode = SCALE_WIDTH;
+ break;
+
+ case TWIDEVEC :
+ case TWIDEHAT :
+ case TWIDETILDE :
+ pAttr = new SmMathSymbolNode(m_aCurToken);
+ eScaleMode = SCALE_WIDTH;
+ break;
+
+ default :
+ pAttr = new SmMathSymbolNode(m_aCurToken);
+ }
+
+ NextToken();
+
+ pSNode->SetSubNodes(pAttr, 0);
+ pSNode->SetScaleMode(eScaleMode);
+ m_aNodeStack.Push(pSNode);
+}
+
+
+void SmParser::FontAttribut()
+{
+ OSL_ENSURE(TokenInGroup(TGFONTATTR), "Sm: wrong token group");
+
+ switch (m_aCurToken.eType)
+ {
+ case TITALIC :
+ case TNITALIC :
+ case TBOLD :
+ case TNBOLD :
+ case TPHANTOM :
+ m_aNodeStack.Push(new SmFontNode(m_aCurToken));
+ NextToken();
+ break;
+
+ case TSIZE :
+ FontSize();
+ break;
+
+ case TFONT :
+ Font();
+ break;
+
+ case TCOLOR :
+ Color();
+ break;
+
+ default :
+ OSL_FAIL("Sm: unknown case");
+ }
+}
+
+
+void SmParser::Color()
+{
+ OSL_ENSURE(m_aCurToken.eType == TCOLOR, "Sm : Ooops...");
+
+ // last color rules, get that one
+ SmToken aToken;
+ do
+ { NextToken();
+
+ if (TokenInGroup(TGCOLOR))
+ { aToken = m_aCurToken;
+ NextToken();
+ }
+ else
+ Error(PE_COLOR_EXPECTED);
+ } while (m_aCurToken.eType == TCOLOR);
+
+ m_aNodeStack.Push(new SmFontNode(aToken));
+}
+
+
+void SmParser::Font()
+{
+ OSL_ENSURE(m_aCurToken.eType == TFONT, "Sm : Ooops...");
+
+ // last font rules, get that one
+ SmToken aToken;
+ do
+ { NextToken();
+
+ if (TokenInGroup(TGFONT))
+ { aToken = m_aCurToken;
+ NextToken();
+ }
+ else
+ Error(PE_FONT_EXPECTED);
+ } while (m_aCurToken.eType == TFONT);
+
+ m_aNodeStack.Push(new SmFontNode(aToken));
+}
+
+
+// gets number used as arguments in Math formulas (e.g. 'size' command)
+// Format: no negative numbers, must start with a digit, no exponent notation, ...
+bool lcl_IsNumber(const UniString& rText)
+{
+ bool bPoint = false;
+ const sal_Unicode* pBuffer = rText.GetBuffer();
+ for(xub_StrLen nPos = 0; nPos < rText.Len(); nPos++, pBuffer++)
+ {
+ const sal_Unicode cChar = *pBuffer;
+ if(cChar == '.')
+ {
+ if(bPoint)
+ return false;
+ else
+ bPoint = true;
+ }
+ else if ( !IsDigit( cChar ) )
+ return false;
+ }
+ return true;
+}
+
+void SmParser::FontSize()
+{
+ OSL_ENSURE(m_aCurToken.eType == TSIZE, "Sm : Ooops...");
+
+ sal_uInt16 Type;
+ SmFontNode *pFontNode = new SmFontNode(m_aCurToken);
+
+ NextToken();
+
+ switch (m_aCurToken.eType)
+ {
+ case TNUMBER: Type = FNTSIZ_ABSOLUT; break;
+ case TPLUS: Type = FNTSIZ_PLUS; break;
+ case TMINUS: Type = FNTSIZ_MINUS; break;
+ case TMULTIPLY: Type = FNTSIZ_MULTIPLY; break;
+ case TDIVIDEBY: Type = FNTSIZ_DIVIDE; break;
+
+ default:
+ delete pFontNode;
+ Error(PE_SIZE_EXPECTED);
+ return;
+ }
+
+ if (Type != FNTSIZ_ABSOLUT)
+ {
+ NextToken();
+ if (m_aCurToken.eType != TNUMBER)
+ {
+ delete pFontNode;
+ Error(PE_SIZE_EXPECTED);
+ return;
+ }
+ }
+
+ // get number argument
+ Fraction aValue( 1L );
+ if (lcl_IsNumber( m_aCurToken.aText ))
+ {
+ double fTmp;
+ if ((fTmp = m_aCurToken.aText.ToDouble()) != 0.0)
+ {
+ aValue = fTmp;
+
+ //!! keep the numerator and denominator from being to large
+ //!! otherwise ongoing multiplications may result in overflows
+ //!! (for example in SmNode::SetFontSize the font size calculated
+ //!! may become 0 because of this!!! Happens e.g. for ftmp = 2.9 with Linux
+ //!! or ftmp = 1.11111111111111111... (11/9) on every platform.)
+ if (aValue.GetDenominator() > 1000)
+ {
+ long nNum = aValue.GetNumerator();
+ long nDenom = aValue.GetDenominator();
+ while (nDenom > 1000)
+ {
+ nNum /= 10;
+ nDenom /= 10;
+ }
+ aValue = Fraction( nNum, nDenom );
+ }
+ }
+ }
+
+ NextToken();
+
+ pFontNode->SetSizeParameter(aValue, Type);
+ m_aNodeStack.Push(pFontNode);
+}
+
+
+void SmParser::Brace()
+{
+ OSL_ENSURE(m_aCurToken.eType == TLEFT || TokenInGroup(TGLBRACES),
+ "Sm: kein Klammer Ausdruck");
+
+ SmStructureNode *pSNode = new SmBraceNode(m_aCurToken);
+ SmNode *pBody = 0,
+ *pLeft = 0,
+ *pRight = 0;
+ SmScaleMode eScaleMode = SCALE_NONE;
+ SmParseError eError = PE_NONE;
+
+ if (m_aCurToken.eType == TLEFT)
+ { NextToken();
+
+ eScaleMode = SCALE_HEIGHT;
+
+ // check for left bracket
+ if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES))
+ {
+ pLeft = new SmMathSymbolNode(m_aCurToken);
+
+ NextToken();
+ Bracebody(true);
+ pBody = m_aNodeStack.Pop();
+
+ if (m_aCurToken.eType == TRIGHT)
+ { NextToken();
+
+ // check for right bracket
+ if (TokenInGroup(TGLBRACES) || TokenInGroup(TGRBRACES))
+ {
+ pRight = new SmMathSymbolNode(m_aCurToken);
+ NextToken();
+ }
+ else
+ eError = PE_RBRACE_EXPECTED;
+ }
+ else
+ eError = PE_RIGHT_EXPECTED;
+ }
+ else
+ eError = PE_LBRACE_EXPECTED;
+ }
+ else
+ {
+ if (TokenInGroup(TGLBRACES))
+ {
+ pLeft = new SmMathSymbolNode(m_aCurToken);
+
+ NextToken();
+ Bracebody(false);
+ pBody = m_aNodeStack.Pop();
+
+ SmTokenType eExpectedType = TUNKNOWN;
+ switch (pLeft->GetToken().eType)
+ { case TLPARENT : eExpectedType = TRPARENT; break;
+ case TLBRACKET : eExpectedType = TRBRACKET; break;
+ case TLBRACE : eExpectedType = TRBRACE; break;
+ case TLDBRACKET : eExpectedType = TRDBRACKET; break;
+ case TLLINE : eExpectedType = TRLINE; break;
+ case TLDLINE : eExpectedType = TRDLINE; break;
+ case TLANGLE : eExpectedType = TRANGLE; break;
+ case TLFLOOR : eExpectedType = TRFLOOR; break;
+ case TLCEIL : eExpectedType = TRCEIL; break;
+ default :
+ OSL_FAIL("Sm: unknown case");
+ }
+
+ if (m_aCurToken.eType == eExpectedType)
+ {
+ pRight = new SmMathSymbolNode(m_aCurToken);
+ NextToken();
+ }
+ else
+ eError = PE_PARENT_MISMATCH;
+ }
+ else
+ eError = PE_LBRACE_EXPECTED;
+ }
+
+ if (eError == PE_NONE)
+ { OSL_ENSURE(pLeft, "Sm: NULL pointer");
+ OSL_ENSURE(pRight, "Sm: NULL pointer");
+ pSNode->SetSubNodes(pLeft, pBody, pRight);
+ pSNode->SetScaleMode(eScaleMode);
+ m_aNodeStack.Push(pSNode);
+ }
+ else
+ { delete pSNode;
+ delete pBody;
+ delete pLeft;
+ delete pRight;
+
+ Error(eError);
+ }
+}
+
+
+void SmParser::Bracebody(bool bIsLeftRight)
+{
+ SmStructureNode *pBody = new SmBracebodyNode(m_aCurToken);
+ SmNodeArray aNodes;
+ sal_uInt16 nNum = 0;
+
+ // get body if any
+ if (bIsLeftRight)
+ {
+ do
+ {
+ if (m_aCurToken.eType == TMLINE)
+ {
+ m_aNodeStack.Push(new SmMathSymbolNode(m_aCurToken));
+ NextToken();
+ nNum++;
+ }
+ else if (m_aCurToken.eType != TRIGHT)
+ { Align();
+ nNum++;
+
+ if (m_aCurToken.eType != TMLINE && m_aCurToken.eType != TRIGHT)
+ Error(PE_RIGHT_EXPECTED);
+ }
+ } while (m_aCurToken.eType != TEND && m_aCurToken.eType != TRIGHT);
+ }
+ else
+ {
+ do
+ {
+ if (m_aCurToken.eType == TMLINE)
+ {
+ m_aNodeStack.Push(new SmMathSymbolNode(m_aCurToken));
+ NextToken();
+ nNum++;
+ }
+ else if (!TokenInGroup(TGRBRACES))
+ { Align();
+ nNum++;
+
+ if (m_aCurToken.eType != TMLINE && !TokenInGroup(TGRBRACES))
+ Error(PE_RBRACE_EXPECTED);
+ }
+ } while (m_aCurToken.eType != TEND && !TokenInGroup(TGRBRACES));
+ }
+
+ // build argument vector in parsing order
+ aNodes.resize(nNum);
+ for (sal_uInt16 i = 0; i < nNum; i++)
+ aNodes[nNum - 1 - i] = m_aNodeStack.Pop();
+
+ pBody->SetSubNodes(aNodes);
+ pBody->SetScaleMode(bIsLeftRight ? SCALE_HEIGHT : SCALE_NONE);
+ m_aNodeStack.Push(pBody);
+}
+
+
+void SmParser::Function()
+{
+ switch (m_aCurToken.eType)
+ {
+ case TFUNC:
+ NextToken(); // skip "FUNC"-statement
+ // fall through
+
+ case TSIN :
+ case TCOS :
+ case TTAN :
+ case TCOT :
+ case TASIN :
+ case TACOS :
+ case TATAN :
+ case TACOT :
+ case TSINH :
+ case TCOSH :
+ case TTANH :
+ case TCOTH :
+ case TASINH :
+ case TACOSH :
+ case TATANH :
+ case TACOTH :
+ case TLN :
+ case TLOG :
+ case TEXP :
+ m_aNodeStack.Push(new SmTextNode(m_aCurToken, FNT_FUNCTION));
+ NextToken();
+ break;
+
+ default:
+ Error(PE_FUNC_EXPECTED);
+ }
+}
+
+
+void SmParser::Binom()
+{
+ SmNodeArray ExpressionArray;
+ SmStructureNode *pSNode = new SmTableNode(m_aCurToken);
+
+ NextToken();
+
+ Sum();
+ Sum();
+
+ ExpressionArray.resize(2);
+
+ for (int i = 0; i < 2; i++)
+ ExpressionArray[2 - (i + 1)] = m_aNodeStack.Pop();
+
+ pSNode->SetSubNodes(ExpressionArray);
+ m_aNodeStack.Push(pSNode);
+}
+
+
+void SmParser::Stack()
+{
+ SmNodeArray ExpressionArray;
+ NextToken();
+ if (m_aCurToken.eType == TLGROUP)
+ {
+ sal_uInt16 n = 0;
+
+ do
+ {
+ NextToken();
+ Align();
+ n++;
+ }
+ while (m_aCurToken.eType == TPOUND);
+
+ ExpressionArray.resize(n);
+
+ for (sal_uInt16 i = 0; i < n; i++)
+ ExpressionArray[n - (i + 1)] = m_aNodeStack.Pop();
+
+ if (m_aCurToken.eType != TRGROUP)
+ Error(PE_RGROUP_EXPECTED);
+
+ NextToken();
+
+ //We need to let the table node know it context
+ //it's used in SmNodeToTextVisitor
+ SmToken aTok = m_aCurToken;
+ aTok.eType = TSTACK;
+ SmStructureNode *pSNode = new SmTableNode(aTok);
+ pSNode->SetSubNodes(ExpressionArray);
+ m_aNodeStack.Push(pSNode);
+ }
+ else
+ Error(PE_LGROUP_EXPECTED);
+}
+
+
+void SmParser::Matrix()
+{
+ SmNodeArray ExpressionArray;
+
+ NextToken();
+ if (m_aCurToken.eType == TLGROUP)
+ {
+ sal_uInt16 c = 0;
+
+ do
+ {
+ NextToken();
+ Align();
+ c++;
+ }
+ while (m_aCurToken.eType == TPOUND);
+
+ sal_uInt16 r = 1;
+
+ while (m_aCurToken.eType == TDPOUND)
+ {
+ NextToken();
+ for (sal_uInt16 i = 0; i < c; i++)
+ {
+ Align();
+ if (i < (c - 1))
+ {
+ if (m_aCurToken.eType == TPOUND)
+ {
+ NextToken();
+ }
+ else
+ Error(PE_POUND_EXPECTED);
+ }
+ }
+
+ r++;
+ }
+
+ long nRC = r * c;
+
+ ExpressionArray.resize(nRC);
+
+ for (sal_uInt16 i = 0; i < (nRC); i++)
+ ExpressionArray[(nRC) - (i + 1)] = m_aNodeStack.Pop();
+
+ if (m_aCurToken.eType != TRGROUP)
+ Error(PE_RGROUP_EXPECTED);
+
+ NextToken();
+
+ SmMatrixNode *pMNode = new SmMatrixNode(m_aCurToken);
+ pMNode->SetSubNodes(ExpressionArray);
+ pMNode->SetRowCol(r, c);
+ m_aNodeStack.Push(pMNode);
+ }
+ else
+ Error(PE_LGROUP_EXPECTED);
+}
+
+
+void SmParser::Special()
+{
+ bool bReplace = false;
+ String &rName = m_aCurToken.aText;
+ String aNewName;
+
+ if (CONVERT_NONE == GetConversion())
+ {
+ // conversion of symbol names for 6.0 (XML) file format
+ // (name change on import / export.
+ // UI uses localized names XML file format does not.)
+ if( rName.Len() && rName.GetChar( 0 ) == sal_Unicode( '%' ) )
+ {
+ if (IsImportSymbolNames())
+ {
+ const SmLocalizedSymbolData &rLSD = SM_MOD()->GetLocSymbolData();
+ aNewName = rLSD.GetUiSymbolName( rName.Copy( 1 ) );
+ bReplace = true;
+ }
+ else if (IsExportSymbolNames())
+ {
+ const SmLocalizedSymbolData &rLSD = SM_MOD()->GetLocSymbolData();
+ aNewName = rLSD.GetExportSymbolName( rName.Copy( 1 ) );
+ bReplace = true;
+ }
+ }
+ if( aNewName.Len() )
+ aNewName.Insert( '%', 0 );
+ }
+ else // 5.0 <-> 6.0 formula text (symbol name) conversion
+ {
+ LanguageType nLanguage = GetLanguage();
+ SmLocalizedSymbolData &rData = SM_MOD()->GetLocSymbolData();
+ const ResStringArray *pFrom = 0;
+ const ResStringArray *pTo = 0;
+ if (CONVERT_50_TO_60 == GetConversion())
+ {
+ pFrom = rData.Get50NamesArray( nLanguage );
+ pTo = rData.Get60NamesArray( nLanguage );
+ }
+ else if (CONVERT_60_TO_50 == GetConversion())
+ {
+ pFrom = rData.Get60NamesArray( nLanguage );
+ pTo = rData.Get50NamesArray( nLanguage );
+ }
+ if (pFrom && pTo)
+ {
+ OSL_ENSURE( pFrom->Count() == pTo->Count(),
+ "array length mismatch" );
+ sal_uInt16 nCount = sal::static_int_cast< sal_uInt16 >(pFrom->Count());
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ if (pFrom->GetString(i) == rName)
+ {
+ aNewName = pTo->GetString(i);
+ bReplace = true;
+ }
+ }
+ }
+ // else:
+ // conversion arrays not found or (usually)
+ // conversion not necessary
+ }
+
+ if (bReplace && aNewName.Len() && rName != aNewName)
+ {
+ Replace( GetTokenIndex(), rName.Len(), aNewName );
+ rName = aNewName;
+ }
+
+ // add symbol name to list of used symbols
+ const String aSymbolName( m_aCurToken.aText.Copy( 1 ) );
+ if (aSymbolName.Len() > 0 )
+ AddToUsedSymbols( aSymbolName );
+
+ m_aNodeStack.Push(new SmSpecialNode(m_aCurToken));
+ NextToken();
+}
+
+
+void SmParser::GlyphSpecial()
+{
+ m_aNodeStack.Push(new SmGlyphSpecialNode(m_aCurToken));
+ NextToken();
+}
+
+
+void SmParser::Error(SmParseError eError)
+{
+ SmStructureNode *pSNode = new SmExpressionNode(m_aCurToken);
+ SmErrorNode *pErr = new SmErrorNode(eError, m_aCurToken);
+ pSNode->SetSubNodes(pErr, 0);
+
+ //! put a structure node on the stack (instead of the error node itself)
+ //! because sometimes such a node is expected in order to attach some
+ //! subnodes
+ m_aNodeStack.Push(pSNode);
+
+ AddError(eError, pSNode);
+
+ NextToken();
+}
+
+
+// end gramar
+
+
+SmParser::SmParser()
+{
+ m_eConversion = CONVERT_NONE;
+ bImportSymNames = m_bExportSymNames = false;
+ m_nLang = Application::GetSettings().GetUILanguage();
+}
+
+SmNode *SmParser::Parse(const String &rBuffer)
+{
+ ClearUsedSymbols();
+
+ m_aBufferString = rBuffer;
+ m_aBufferString.ConvertLineEnd( LINEEND_LF );
+ m_nBufferIndex = 0;
+ m_nTokenIndex = 0;
+ m_Row = 1;
+ m_nColOff = 0;
+ m_nCurError = -1;
+
+ for ( size_t i = 0, n = m_aErrDescList.size(); i < n; ++i )
+ delete m_aErrDescList[ i ];
+ m_aErrDescList.clear();
+
+ m_aNodeStack.Clear();
+
+ SetLanguage( Application::GetSettings().GetUILanguage() );
+ NextToken();
+ Table();
+
+ return m_aNodeStack.Pop();
+}
+
+SmNode *SmParser::ParseExpression(const String &rBuffer)
+{
+ m_aBufferString = rBuffer;
+ m_aBufferString.ConvertLineEnd( LINEEND_LF );
+ m_nBufferIndex = 0;
+ m_nTokenIndex = 0;
+ m_Row = 1;
+ m_nColOff = 0;
+ m_nCurError = -1;
+
+ for ( size_t i = 0, n = m_aErrDescList.size(); i < n; ++i )
+ delete m_aErrDescList[ i ];
+ m_aErrDescList.clear();
+
+ m_aNodeStack.Clear();
+
+ SetLanguage( Application::GetSettings().GetUILanguage() );
+ NextToken();
+ Expression();
+
+ return m_aNodeStack.Pop();
+}
+
+
+size_t SmParser::AddError(SmParseError Type, SmNode *pNode)
+{
+ SmErrorDesc *pErrDesc = new SmErrorDesc;
+
+ pErrDesc->Type = Type;
+ pErrDesc->pNode = pNode;
+ pErrDesc->Text = String(SmResId(RID_ERR_IDENT));
+
+ sal_uInt16 nRID;
+ switch (Type)
+ {
+ case PE_UNEXPECTED_CHAR: nRID = RID_ERR_UNEXPECTEDCHARACTER; break;
+ case PE_LGROUP_EXPECTED: nRID = RID_ERR_LGROUPEXPECTED; break;
+ case PE_RGROUP_EXPECTED: nRID = RID_ERR_RGROUPEXPECTED; break;
+ case PE_LBRACE_EXPECTED: nRID = RID_ERR_LBRACEEXPECTED; break;
+ case PE_RBRACE_EXPECTED: nRID = RID_ERR_RBRACEEXPECTED; break;
+ case PE_FUNC_EXPECTED: nRID = RID_ERR_FUNCEXPECTED; break;
+ case PE_UNOPER_EXPECTED: nRID = RID_ERR_UNOPEREXPECTED; break;
+ case PE_BINOPER_EXPECTED: nRID = RID_ERR_BINOPEREXPECTED; break;
+ case PE_SYMBOL_EXPECTED: nRID = RID_ERR_SYMBOLEXPECTED; break;
+ case PE_IDENTIFIER_EXPECTED: nRID = RID_ERR_IDENTEXPECTED; break;
+ case PE_POUND_EXPECTED: nRID = RID_ERR_POUNDEXPECTED; break;
+ case PE_COLOR_EXPECTED: nRID = RID_ERR_COLOREXPECTED; break;
+ case PE_RIGHT_EXPECTED: nRID = RID_ERR_RIGHTEXPECTED; break;
+
+ default:
+ nRID = RID_ERR_UNKOWN;
+ }
+ pErrDesc->Text += SmResId(nRID);
+
+ m_aErrDescList.push_back( pErrDesc );
+
+ return m_aErrDescList.size()-1;
+}
+
+
+const SmErrorDesc *SmParser::NextError()
+{
+ if ( !m_aErrDescList.empty() )
+ if (m_nCurError > 0) return m_aErrDescList[ --m_nCurError ];
+ else
+ {
+ m_nCurError = 0;
+ return m_aErrDescList[ m_nCurError ];
+ }
+ else return NULL;
+}
+
+
+const SmErrorDesc *SmParser::PrevError()
+{
+ if ( !m_aErrDescList.empty() )
+ if (m_nCurError < (int) (m_aErrDescList.size() - 1)) return m_aErrDescList[ ++m_nCurError ];
+ else
+ {
+ m_nCurError = (int) (m_aErrDescList.size() - 1);
+ return m_aErrDescList[ m_nCurError ];
+ }
+ else return NULL;
+}
+
+
+const SmErrorDesc *SmParser::GetError(size_t i)
+{
+ if ( i < m_aErrDescList.size() )
+ return m_aErrDescList[ i ];
+
+ if ( (size_t)m_nCurError < m_aErrDescList.size() )
+ return m_aErrDescList[ m_nCurError ];
+
+ return NULL;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/rect.cxx b/starmath/source/rect.cxx
new file mode 100644
index 000000000000..b69abbd455c6
--- /dev/null
+++ b/starmath/source/rect.cxx
@@ -0,0 +1,696 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <tools/string.hxx>
+#include <osl/diagnose.h>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/virdev.hxx>
+
+
+#include "rect.hxx"
+#include "types.hxx"
+#include "utility.hxx"
+#include "smmod.hxx"
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+// '\0' terminated Array with symbol, which should be treat as letters in
+// StarMath Font, (to get a normal (non-clipped) SmRect in contrast to the
+// other operators and symbols).
+static xub_Unicode const aMathAlpha[] =
+{
+ MS_ALEPH, MS_IM, MS_RE,
+ MS_WP, xub_Unicode(0xE070), MS_EMPTYSET,
+ xub_Unicode(0x2113), xub_Unicode(0xE0D6), xub_Unicode(0x2107),
+ xub_Unicode(0x2127), xub_Unicode(0x210A), MS_HBAR,
+ MS_LAMBDABAR, MS_SETN, MS_SETZ,
+ MS_SETQ, MS_SETR, MS_SETC,
+ xub_Unicode(0x2373), xub_Unicode(0xE0A5), xub_Unicode(0x2112),
+ xub_Unicode(0x2130), xub_Unicode(0x2131),
+ xub_Unicode('\0')
+};
+
+bool SmIsMathAlpha(const XubString &rText)
+ // true iff symbol (from StarMath Font) should be treated as letter
+{
+ if (rText.Len() == 0)
+ return false;
+
+ OSL_ENSURE(rText.Len() == 1, "Sm : string must be exactly one character long");
+ xub_Unicode cChar = rText.GetChar(0);
+
+ // is it a greek symbol?
+ if (xub_Unicode(0xE0AC) <= cChar && cChar <= xub_Unicode(0xE0D4))
+ return true;
+ else
+ {
+ // appears it in 'aMathAlpha'?
+ const xub_Unicode *pChar = aMathAlpha;
+ while (*pChar && *pChar != cChar)
+ pChar++;
+ return *pChar != xub_Unicode('\0');
+ }
+}
+
+
+////////////////////////////////////////
+//
+// SmRect members
+//
+
+
+SmRect::SmRect()
+ // constructs empty rectangle at (0, 0) with width and height 0.
+{
+ OSL_ENSURE(aTopLeft == Point(0, 0), "Sm: ooops...");
+ OSL_ENSURE(aSize == Size(0, 0), "Sm: ooops...");
+
+ bHasBaseline = bHasAlignInfo = false;
+ nBaseline = nAlignT = nAlignM = nAlignB =
+ nGlyphTop = nGlyphBottom =
+ nItalicLeftSpace = nItalicRightSpace =
+ nLoAttrFence = nHiAttrFence = 0;
+ nBorderWidth = 0;
+}
+
+
+SmRect::SmRect(const SmRect &rRect)
+: aTopLeft(rRect.aTopLeft),
+ aSize(rRect.aSize)
+{
+ bHasBaseline = rRect.bHasBaseline;
+ nBaseline = rRect.nBaseline;
+ nAlignT = rRect.nAlignT;
+ nAlignM = rRect.nAlignM;
+ nAlignB = rRect.nAlignB;
+ nGlyphTop = rRect.nGlyphTop;
+ nGlyphBottom = rRect.nGlyphBottom;
+ nHiAttrFence = rRect.nHiAttrFence;
+ nLoAttrFence = rRect.nLoAttrFence;
+ bHasAlignInfo = rRect.bHasAlignInfo;
+ nItalicLeftSpace = rRect.nItalicLeftSpace;
+ nItalicRightSpace = rRect.nItalicRightSpace;
+ nBorderWidth = rRect.nBorderWidth;
+}
+
+
+void SmRect::CopyAlignInfo(const SmRect &rRect)
+{
+ nBaseline = rRect.nBaseline;
+ bHasBaseline = rRect.bHasBaseline;
+ nAlignT = rRect.nAlignT;
+ nAlignM = rRect.nAlignM;
+ nAlignB = rRect.nAlignB;
+ bHasAlignInfo = rRect.bHasAlignInfo;
+ nLoAttrFence = rRect.nLoAttrFence;
+ nHiAttrFence = rRect.nHiAttrFence;
+}
+
+
+void SmRect::BuildRect(const OutputDevice &rDev, const SmFormat *pFormat,
+ const XubString &rText, sal_uInt16 nBorder)
+{
+ OSL_ENSURE(aTopLeft == Point(0, 0), "Sm: Ooops...");
+
+ aSize = Size(rDev.GetTextWidth(rText), rDev.GetTextHeight());
+
+ const FontMetric aFM (rDev.GetFontMetric());
+ bool bIsMath = aFM.GetName().EqualsIgnoreCaseAscii( FONTNAME_MATH );
+ bool bAllowSmaller = bIsMath && !SmIsMathAlpha(rText);
+ const long nFontHeight = rDev.GetFont().GetSize().Height();
+
+ nBorderWidth = nBorder;
+ bHasAlignInfo = true;
+ bHasBaseline = true;
+ nBaseline = aFM.GetAscent();
+ nAlignT = nBaseline - nFontHeight * 750L / 1000L;
+ nAlignM = nBaseline - nFontHeight * 121L / 422L;
+ // that's where the horizontal bars of '+', '-', ... are
+ // (1/3 of ascent over baseline)
+ // (121 = 1/3 of 12pt ascent, 422 = 12pt fontheight)
+ nAlignB = nBaseline;
+
+ // workaround for printer fonts with very small (possible 0 or even
+ // negative(!)) leading
+ if (aFM.GetIntLeading() < 5 && rDev.GetOutDevType() == OUTDEV_PRINTER)
+ {
+ OutputDevice *pWindow = Application::GetDefaultDevice();
+
+ pWindow->Push(PUSH_MAPMODE | PUSH_FONT);
+
+ pWindow->SetMapMode(rDev.GetMapMode());
+ pWindow->SetFont(rDev.GetFontMetric());
+
+ long nDelta = pWindow->GetFontMetric().GetIntLeading();
+ if (nDelta == 0)
+ { // this value approx. fits a Leading of 80 at a
+ // Fontheight of 422 (12pt)
+ nDelta = nFontHeight * 8L / 43;
+ }
+ SetTop(GetTop() - nDelta);
+
+ pWindow->Pop();
+ }
+
+ // get GlyphBoundRect
+ Rectangle aGlyphRect;
+#if OSL_DEBUG_LEVEL > 1
+ bool bSuccess =
+#endif
+ SmGetGlyphBoundRect(rDev, rText, aGlyphRect);
+#if OSL_DEBUG_LEVEL > 1
+ if (!bSuccess)
+ {
+ OSL_FAIL( "Sm : Ooops... (fehlt evtl. der Font?)");
+ }
+#endif
+
+ nItalicLeftSpace = GetLeft() - aGlyphRect.Left() + nBorderWidth;
+ nItalicRightSpace = aGlyphRect.Right() - GetRight() + nBorderWidth;
+ if (nItalicLeftSpace < 0 && !bAllowSmaller)
+ nItalicLeftSpace = 0;
+ if (nItalicRightSpace < 0 && !bAllowSmaller)
+ nItalicRightSpace = 0;
+
+ long nDist = 0;
+ if (pFormat)
+ nDist = (rDev.GetFont().GetSize().Height()
+ * pFormat->GetDistance(DIS_ORNAMENTSIZE)) / 100L;
+
+ nHiAttrFence = aGlyphRect.TopLeft().Y() - 1 - nBorderWidth - nDist;
+ nLoAttrFence = SmFromTo(GetAlignB(), GetBottom(), 0.0);
+
+ nGlyphTop = aGlyphRect.Top() - nBorderWidth;
+ nGlyphBottom = aGlyphRect.Bottom() + nBorderWidth;
+
+ if (bAllowSmaller)
+ {
+ // for symbols and operators from the StarMath Font
+ // we adjust upper and lower margin of the symbol
+ SetTop(nGlyphTop);
+ SetBottom(nGlyphBottom);
+ }
+
+ if (nHiAttrFence < GetTop())
+ nHiAttrFence = GetTop();
+
+ if (nLoAttrFence > GetBottom())
+ nLoAttrFence = GetBottom();
+
+ OSL_ENSURE(rText.Len() == 0 || !IsEmpty(),
+ "Sm: empty rectangle created");
+}
+
+
+void SmRect::Init(const OutputDevice &rDev, const SmFormat *pFormat,
+ const XubString &rText, sal_uInt16 nEBorderWidth)
+ // get rectangle fitting for drawing 'rText' on OutputDevice 'rDev'
+{
+ BuildRect(rDev, pFormat, rText, nEBorderWidth);
+}
+
+
+SmRect::SmRect(const OutputDevice &rDev, const SmFormat *pFormat,
+ const XubString &rText, long nEBorderWidth)
+{
+ OSL_ENSURE( nEBorderWidth >= 0, "BorderWidth is negative" );
+ if (nEBorderWidth < 0)
+ nEBorderWidth = 0;
+ Init(rDev, pFormat, rText, (sal_uInt16) nEBorderWidth);
+}
+
+
+SmRect::SmRect(long nWidth, long nHeight)
+ // this constructor should never be used for anything textlike because
+ // it will not provide useful values for baseline, AlignT and AlignB!
+ // It's purpose is to get a 'SmRect' for the horizontal line in fractions
+ // as used in 'SmBinVerNode'.
+: aSize(nWidth, nHeight)
+{
+ OSL_ENSURE(aTopLeft == Point(0, 0), "Sm: ooops...");
+
+ bHasBaseline = false;
+ bHasAlignInfo = true;
+ nBaseline = 0;
+ nAlignT = GetTop();
+ nAlignB = GetBottom();
+ nAlignM = (nAlignT + nAlignB) / 2; // this is the default
+ nItalicLeftSpace = nItalicRightSpace = 0;
+ nGlyphTop = nHiAttrFence = GetTop();
+ nGlyphBottom = nLoAttrFence = GetBottom();
+ nBorderWidth = 0;
+}
+
+
+void SmRect::SetLeft(long nLeft)
+{
+ if (nLeft <= GetRight())
+ { aSize.Width() = GetRight() - nLeft + 1;
+ aTopLeft.X() = nLeft;
+ }
+}
+
+
+void SmRect::SetRight(long nRight)
+{
+ if (nRight >= GetLeft())
+ aSize.Width() = nRight - GetLeft() + 1;
+}
+
+
+void SmRect::SetBottom(long nBottom)
+{
+ if (nBottom >= GetTop())
+ aSize.Height() = nBottom - GetTop() + 1;
+}
+
+
+void SmRect::SetTop(long nTop)
+{
+ if (nTop <= GetBottom())
+ { aSize.Height() = GetBottom() - nTop + 1;
+ aTopLeft.Y() = nTop;
+ }
+}
+
+
+void SmRect::Move(const Point &rPosition)
+ // move rectangle by position 'rPosition'.
+{
+ aTopLeft += rPosition;
+
+ long nDelta = rPosition.Y();
+ nBaseline += nDelta;
+ nAlignT += nDelta;
+ nAlignM += nDelta;
+ nAlignB += nDelta;
+ nGlyphTop += nDelta;
+ nGlyphBottom += nDelta;
+ nHiAttrFence += nDelta;
+ nLoAttrFence += nDelta;
+}
+
+
+const Point SmRect::AlignTo(const SmRect &rRect, RectPos ePos,
+ RectHorAlign eHor, RectVerAlign eVer) const
+{ Point aPos (GetTopLeft());
+ // will become the topleft point of the new rectangle position
+
+ // set horizontal or vertical new rectangle position depending on
+ // 'ePos' is one of 'RP_LEFT', 'RP_RIGHT' or 'RP_TOP', 'RP_BOTTOM'
+ switch (ePos)
+ { case RP_LEFT :
+ aPos.X() = rRect.GetItalicLeft() - GetItalicRightSpace()
+ - GetWidth();
+ break;
+ case RP_RIGHT :
+ aPos.X() = rRect.GetItalicRight() + 1 + GetItalicLeftSpace();
+ break;
+ case RP_TOP :
+ aPos.Y() = rRect.GetTop() - GetHeight();
+ break;
+ case RP_BOTTOM :
+ aPos.Y() = rRect.GetBottom() + 1;
+ break;
+ case RP_ATTRIBUT :
+ aPos.X() = rRect.GetItalicCenterX() - GetItalicWidth() / 2
+ + GetItalicLeftSpace();
+ break;
+ default :
+ OSL_FAIL("Sm: unknown case");
+ }
+
+ // check if horizontal position is already set
+ if (ePos == RP_LEFT || ePos == RP_RIGHT || ePos == RP_ATTRIBUT)
+ // correct error in current vertical position
+ switch (eVer)
+ { case RVA_TOP :
+ aPos.Y() += rRect.GetAlignT() - GetAlignT();
+ break;
+ case RVA_MID :
+ aPos.Y() += rRect.GetAlignM() - GetAlignM();
+ break;
+ case RVA_BASELINE :
+ // align baselines if possible else align mid's
+ if (HasBaseline() && rRect.HasBaseline())
+ aPos.Y() += rRect.GetBaseline() - GetBaseline();
+ else
+ aPos.Y() += rRect.GetAlignM() - GetAlignM();
+ break;
+ case RVA_BOTTOM :
+ aPos.Y() += rRect.GetAlignB() - GetAlignB();
+ break;
+ case RVA_CENTERY :
+ aPos.Y() += rRect.GetCenterY() - GetCenterY();
+ break;
+ case RVA_ATTRIBUT_HI:
+ aPos.Y() += rRect.GetHiAttrFence() - GetBottom();
+ break;
+ case RVA_ATTRIBUT_MID :
+ aPos.Y() += SmFromTo(rRect.GetAlignB(), rRect.GetAlignT(), 0.4)
+ - GetCenterY();
+ break;
+ case RVA_ATTRIBUT_LO :
+ aPos.Y() += rRect.GetLoAttrFence() - GetTop();
+ break;
+ default :
+ OSL_FAIL("Sm: unknown case");
+ }
+
+ // check if vertical position is already set
+ if (ePos == RP_TOP || ePos == RP_BOTTOM)
+ // correct error in current horizontal position
+ switch (eHor)
+ { case RHA_LEFT :
+ aPos.X() += rRect.GetItalicLeft() - GetItalicLeft();
+ break;
+ case RHA_CENTER :
+ aPos.X() += rRect.GetItalicCenterX() - GetItalicCenterX();
+ break;
+ case RHA_RIGHT :
+ aPos.X() += rRect.GetItalicRight() - GetItalicRight();
+ break;
+ default :
+ OSL_FAIL("Sm: unknown case");
+ }
+
+ return aPos;
+}
+
+
+SmRect & SmRect::Union(const SmRect &rRect)
+ // rectangle union of current one with 'rRect'. The result is to be the
+ // smallest rectangles that covers the space of both rectangles.
+ // (empty rectangles cover no space)
+ //! Italic correction is NOT taken into account here!
+{
+ if (rRect.IsEmpty())
+ return *this;
+
+ long nL = rRect.GetLeft(),
+ nR = rRect.GetRight(),
+ nT = rRect.GetTop(),
+ nB = rRect.GetBottom(),
+ nGT = rRect.nGlyphTop,
+ nGB = rRect.nGlyphBottom;
+ if (!IsEmpty())
+ { long nTmp;
+
+ if ((nTmp = GetLeft()) < nL)
+ nL = nTmp;
+ if ((nTmp = GetRight()) > nR)
+ nR = nTmp;
+ if ((nTmp = GetTop()) < nT)
+ nT = nTmp;
+ if ((nTmp = GetBottom()) > nB)
+ nB = nTmp;
+ if ((nTmp = nGlyphTop) < nGT)
+ nGT = nTmp;
+ if ((nTmp = nGlyphBottom) > nGB)
+ nGB = nTmp;
+ }
+
+ SetLeft(nL);
+ SetRight(nR);
+ SetTop(nT);
+ SetBottom(nB);
+ nGlyphTop = nGT;
+ nGlyphBottom = nGB;
+
+ return *this;
+}
+
+
+SmRect & SmRect::ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode)
+ // let current rectangle be the union of itself and 'rRect'
+ // (the smallest rectangle surrounding both). Also adapt values for
+ // 'AlignT', 'AlignM', 'AlignB', baseline and italic-spaces.
+ // The baseline is set according to 'eCopyMode'.
+ // If one of the rectangles has no relevant info the other one is copied.
+{
+ // get some values used for (italic) spaces adaption
+ // ! (need to be done before changing current SmRect) !
+ long nL = Min(GetItalicLeft(), rRect.GetItalicLeft()),
+ nR = Max(GetItalicRight(), rRect.GetItalicRight());
+
+ Union(rRect);
+
+ SetItalicSpaces(GetLeft() - nL, nR - GetRight());
+
+ if (!HasAlignInfo())
+ CopyAlignInfo(rRect);
+ else if (rRect.HasAlignInfo())
+ { nAlignT = Min(GetAlignT(), rRect.GetAlignT());
+ nAlignB = Max(GetAlignB(), rRect.GetAlignB());
+ nHiAttrFence = Min(GetHiAttrFence(), rRect.GetHiAttrFence());
+ nLoAttrFence = Max(GetLoAttrFence(), rRect.GetLoAttrFence());
+ OSL_ENSURE(HasAlignInfo(), "Sm: ooops...");
+
+ switch (eCopyMode)
+ { case RCP_THIS:
+ // already done
+ break;
+ case RCP_ARG:
+ CopyMBL(rRect);
+ break;
+ case RCP_NONE:
+ ClearBaseline();
+ nAlignM = (nAlignT + nAlignB) / 2;
+ break;
+ case RCP_XOR:
+ if (!HasBaseline())
+ CopyMBL(rRect);
+ break;
+ default :
+ OSL_FAIL("Sm: unknown case");
+ }
+ }
+
+ return *this;
+}
+
+
+SmRect & SmRect::ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode,
+ long nNewAlignM)
+ // as 'ExtendBy' but sets AlignM value to 'nNewAlignM'.
+ // (this version will be used in 'SmBinVerNode' to provide means to
+ // align eg "{a over b} over c" correctly where AlignM should not
+ // be (AlignT + AlignB) / 2)
+{
+ OSL_ENSURE(HasAlignInfo(), "Sm: no align info");
+
+ ExtendBy(rRect, eCopyMode);
+ nAlignM = nNewAlignM;
+
+ return *this;
+}
+
+
+SmRect & SmRect::ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode,
+ bool bKeepVerAlignParams)
+ // as 'ExtendBy' but keeps original values for AlignT, -M and -B and
+ // baseline.
+ // (this is used in 'SmSupSubNode' where the sub-/supscripts shouldn't
+ // be allowed to modify these values.)
+{
+ long nOldAlignT = GetAlignT(),
+ nOldAlignM = GetAlignM(),
+ nOldAlignB = GetAlignB(),
+ nOldBaseline = nBaseline; //! depends not on 'HasBaseline'
+ bool bOldHasAlignInfo = HasAlignInfo();
+
+ ExtendBy(rRect, eCopyMode);
+
+ if (bKeepVerAlignParams)
+ { nAlignT = nOldAlignT;
+ nAlignM = nOldAlignM;
+ nAlignB = nOldAlignB;
+ nBaseline = nOldBaseline;
+ bHasAlignInfo = bOldHasAlignInfo;
+ }
+
+ return *this;
+}
+
+
+long SmRect::OrientedDist(const Point &rPoint) const
+ // return oriented distance of rPoint to the current rectangle,
+ // especially the return value is <= 0 iff the point is inside the
+ // rectangle.
+ // For simplicity the maximum-norm is used.
+{
+ bool bIsInside = IsInsideItalicRect(rPoint);
+
+ // build reference point to define the distance
+ Point aRef;
+ if (bIsInside)
+ { Point aIC (GetItalicCenterX(), GetCenterY());
+
+ aRef.X() = rPoint.X() >= aIC.X() ? GetItalicRight() : GetItalicLeft();
+ aRef.Y() = rPoint.Y() >= aIC.Y() ? GetBottom() : GetTop();
+ }
+ else
+ {
+ // x-coordinate
+ if (rPoint.X() > GetItalicRight())
+ aRef.X() = GetItalicRight();
+ else if (rPoint.X() < GetItalicLeft())
+ aRef.X() = GetItalicLeft();
+ else
+ aRef.X() = rPoint.X();
+ // y-coordinate
+ if (rPoint.Y() > GetBottom())
+ aRef.Y() = GetBottom();
+ else if (rPoint.Y() < GetTop())
+ aRef.Y() = GetTop();
+ else
+ aRef.Y() = rPoint.Y();
+ }
+
+ // build distance vector
+ Point aDist (aRef - rPoint);
+
+ long nAbsX = labs(aDist.X()),
+ nAbsY = labs(aDist.Y());
+
+ return bIsInside ? - Min(nAbsX, nAbsY) : Max (nAbsX, nAbsY);
+}
+
+
+bool SmRect::IsInsideRect(const Point &rPoint) const
+{
+ return rPoint.Y() >= GetTop()
+ && rPoint.Y() <= GetBottom()
+ && rPoint.X() >= GetLeft()
+ && rPoint.X() <= GetRight();
+}
+
+
+bool SmRect::IsInsideItalicRect(const Point &rPoint) const
+{
+ return rPoint.Y() >= GetTop()
+ && rPoint.Y() <= GetBottom()
+ && rPoint.X() >= GetItalicLeft()
+ && rPoint.X() <= GetItalicRight();
+}
+
+SmRect SmRect::AsGlyphRect() const
+{
+ SmRect aRect (*this);
+ aRect.SetTop(nGlyphTop);
+ aRect.SetBottom(nGlyphBottom);
+ return aRect;
+}
+
+bool SmGetGlyphBoundRect(const OutputDevice &rDev,
+ const XubString &rText, Rectangle &rRect)
+ // basically the same as 'GetTextBoundRect' (in class 'OutputDevice')
+ // but with a string as argument.
+{
+ // handle special case first
+ xub_StrLen nLen = rText.Len();
+ if (nLen == 0)
+ { rRect.SetEmpty();
+ return true;
+ }
+
+ // get a device where 'OutputDevice::GetTextBoundRect' will be successful
+ OutputDevice *pGlyphDev;
+ if (rDev.GetOutDevType() != OUTDEV_PRINTER)
+ pGlyphDev = (OutputDevice *) &rDev;
+ else
+ {
+ // since we format for the printer (where GetTextBoundRect will fail)
+ // we need a virtual device here.
+ pGlyphDev = &SM_MOD()->GetDefaultVirtualDev();
+ }
+
+ const FontMetric aDevFM (rDev.GetFontMetric());
+
+ pGlyphDev->Push(PUSH_FONT | PUSH_MAPMODE);
+ Font aFnt(rDev.GetFont());
+ aFnt.SetAlign(ALIGN_TOP);
+
+ // use scale factor when calling GetTextBoundRect to counter
+ // negative effects from antialiasing which may otherwise result
+ // in significant incorrect bounding rectangles for some charcters.
+ Size aFntSize = aFnt.GetSize();
+
+ // Workaround to avoid HUGE font sizes and resulting problems
+ long nScaleFactor = 1;
+ while( aFntSize.Height() > 2000 * nScaleFactor )
+ nScaleFactor *= 2;
+
+ aFnt.SetSize( Size( aFntSize.Width() / nScaleFactor, aFntSize.Height() / nScaleFactor ) );
+ pGlyphDev->SetFont(aFnt);
+
+ long nTextWidth = rDev.GetTextWidth(rText);
+ Point aPoint;
+ Rectangle aResult (aPoint, Size(nTextWidth, rDev.GetTextHeight())),
+ aTmp;
+
+ bool bSuccess = pGlyphDev->GetTextBoundRect(aTmp, rText, 0, 0);
+ OSL_ENSURE( bSuccess, "GetTextBoundRect failed" );
+
+
+ if (!aTmp.IsEmpty())
+ {
+ aResult = Rectangle(aTmp.Left() * nScaleFactor, aTmp.Top() * nScaleFactor,
+ aTmp.Right() * nScaleFactor, aTmp.Bottom() * nScaleFactor);
+ if (&rDev != pGlyphDev) /* only when rDev is a printer... */
+ {
+ long nGDTextWidth = pGlyphDev->GetTextWidth(rText);
+ if (nGDTextWidth != 0 &&
+ nTextWidth != nGDTextWidth)
+ {
+ aResult.Right() *= nTextWidth;
+ aResult.Right() /= nGDTextWidth * nScaleFactor;
+ }
+ }
+ }
+
+ // move rectangle to match possibly different baselines
+ // (because of different devices)
+ long nDelta = aDevFM.GetAscent() - pGlyphDev->GetFontMetric().GetAscent() * nScaleFactor;
+ aResult.Move(0, nDelta);
+
+ pGlyphDev->Pop();
+
+ rRect = aResult;
+ return bSuccess;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/register.cxx b/starmath/source/register.cxx
new file mode 100644
index 000000000000..0851ef040fbe
--- /dev/null
+++ b/starmath/source/register.cxx
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/uno/Sequence.h>
+#include <rtl/ustring.hxx>
+
+#include <sfx2/sfxmodelfactory.hxx>
+
+#include "smdll.hxx"
+#include "document.hxx"
+#include "unomodel.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+//Math document
+extern Sequence< OUString > SAL_CALL
+ SmDocument_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmDocument_getImplementationName() throw();
+extern Reference< XInterface >SAL_CALL
+ SmDocument_createInstance(const Reference< XMultiServiceFactory > & rSMgr, const sal_uInt64 _nCreationFlags) throw( Exception );
+
+//MathML import
+extern Sequence< OUString > SAL_CALL
+ SmXMLImport_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmXMLImport_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLImport_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+extern Sequence< OUString > SAL_CALL
+ SmXMLImportMeta_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmXMLImportMeta_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLImportMeta_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+extern Sequence< OUString > SAL_CALL
+ SmXMLImportSettings_getSupportedServiceNames() throw();
+extern OUString SAL_CALL SmXMLImportSettings_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLImportSettings_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+
+//MathML export
+extern Sequence< OUString > SAL_CALL
+ SmXMLExport_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmXMLExport_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLExport_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+extern Sequence< OUString > SAL_CALL
+ SmXMLExportMetaOOO_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmXMLExportMetaOOO_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLExportMetaOOO_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+extern Sequence< OUString > SAL_CALL
+ SmXMLExportMeta_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmXMLExportMeta_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLExportMeta_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+extern Sequence< OUString > SAL_CALL
+ SmXMLExportSettingsOOO_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmXMLExportSettingsOOO_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLExportSettingsOOO_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+extern Sequence< OUString > SAL_CALL
+ SmXMLExportSettings_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmXMLExportSettings_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLExportSettings_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+extern Sequence< OUString > SAL_CALL
+ SmXMLExportContent_getSupportedServiceNames() throw();
+extern OUString SAL_CALL
+ SmXMLExportContent_getImplementationName() throw();
+extern Reference< XInterface > SAL_CALL
+ SmXMLExportContent_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception );
+
+
+extern "C" {
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char** ppEnvironmentTypeName,
+ uno_Environment** /*ppEnvironment*/ )
+{
+ *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplementationName,
+ void* pServiceManager,
+ void* /*pRegistryKey*/ )
+{
+ // Set default return value for this operation - if it failed.
+ void* pReturn = NULL ;
+
+ if (
+ ( pImplementationName != NULL ) &&
+ ( pServiceManager != NULL )
+ )
+ {
+ // Define variables which are used in following macros.
+ Reference< XSingleServiceFactory > xFactory ;
+ Reference< XMultiServiceFactory > xServiceManager( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+
+ if( SmXMLImport_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLImport_getImplementationName(),
+ SmXMLImport_createInstance,
+ SmXMLImport_getSupportedServiceNames() );
+ }
+ else if( SmXMLExport_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLExport_getImplementationName(),
+ SmXMLExport_createInstance,
+ SmXMLExport_getSupportedServiceNames() );
+ }
+ else if( SmXMLImportMeta_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLImportMeta_getImplementationName(),
+ SmXMLImportMeta_createInstance,
+ SmXMLImportMeta_getSupportedServiceNames() );
+ }
+ else if( SmXMLExportMetaOOO_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLExportMetaOOO_getImplementationName(),
+ SmXMLExportMetaOOO_createInstance,
+ SmXMLExportMetaOOO_getSupportedServiceNames() );
+ }
+ else if( SmXMLExportMeta_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLExportMeta_getImplementationName(),
+ SmXMLExportMeta_createInstance,
+ SmXMLExportMeta_getSupportedServiceNames() );
+ }
+ else if( SmXMLImportSettings_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLImportSettings_getImplementationName(),
+ SmXMLImportSettings_createInstance,
+ SmXMLImportSettings_getSupportedServiceNames() );
+ }
+ else if( SmXMLExportSettingsOOO_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLExportSettingsOOO_getImplementationName(),
+ SmXMLExportSettingsOOO_createInstance,
+ SmXMLExportSettingsOOO_getSupportedServiceNames() );
+ }
+ else if( SmXMLExportSettings_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLExportSettings_getImplementationName(),
+ SmXMLExportSettings_createInstance,
+ SmXMLExportSettings_getSupportedServiceNames() );
+ }
+ else if( SmXMLExportContent_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::cppu::createSingleFactory( xServiceManager,
+ SmXMLExportContent_getImplementationName(),
+ SmXMLExportContent_createInstance,
+ SmXMLExportContent_getSupportedServiceNames() );
+ }
+ else if( SmDocument_getImplementationName().equalsAsciiL(
+ pImplementationName, strlen(pImplementationName)) )
+ {
+ xFactory = ::sfx2::createSfxModelFactory( xServiceManager,
+ SmDocument_getImplementationName(),
+ SmDocument_createInstance,
+ SmDocument_getSupportedServiceNames() );
+ }
+
+
+ // Factory is valid - service was found.
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pReturn = xFactory.get();
+ }
+ }
+
+ // Return with result of this operation.
+ return pReturn ;
+}
+} // extern "C"
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/smdetect.cxx b/starmath/source/smdetect.cxx
new file mode 100644
index 000000000000..4c8e0075a4ef
--- /dev/null
+++ b/starmath/source/smdetect.cxx
@@ -0,0 +1,476 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+#include "smdetect.hxx"
+
+//#include <framework/interaction.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/InteractiveAppException.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/packages/zip/ZipIOException.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <ucbhelper/simpleinteractionrequest.hxx>
+
+#include <rtl/ustring.h>
+#include <rtl/logfile.hxx>
+#include <svl/itemset.hxx>
+#include <vcl/window.hxx>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <tools/urlobj.hxx>
+#include <osl/mutex.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <sot/storinfo.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/request.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/brokenpackageint.hxx>
+
+#include "document.hxx"
+#include "eqnolefilehdr.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::rtl;
+
+SmFilterDetect::SmFilterDetect( const REFERENCE < ::com::sun::star::lang::XMultiServiceFactory >& /*xFactory*/ )
+{
+}
+
+SmFilterDetect::~SmFilterDetect()
+{
+}
+
+::rtl::OUString SAL_CALL SmFilterDetect::detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lDescriptor ) throw( ::com::sun::star::uno::RuntimeException )
+{
+ REFERENCE< XInputStream > xStream;
+ REFERENCE< XContent > xContent;
+ REFERENCE< XInteractionHandler > xInteraction;
+ String aURL;
+ ::rtl::OUString sTemp;
+ String aTypeName; // a name describing the type (from MediaDescriptor, usually from flat detection)
+ String aPreselectedFilterName; // a name describing the filter to use (from MediaDescriptor, usually from UI action)
+
+ ::rtl::OUString aDocumentTitle; // interesting only if set in this method
+
+ // opening as template is done when a parameter tells to do so and a template filter can be detected
+ // (otherwise no valid filter would be found) or if the detected filter is a template filter and
+ // there is no parameter that forbids to open as template
+ sal_Bool bOpenAsTemplate = sal_False;
+ sal_Bool bWasReadOnly = sal_False, bReadOnly = sal_False;
+
+ sal_Bool bRepairPackage = sal_False;
+ sal_Bool bRepairAllowed = sal_False;
+
+ // now some parameters that can already be in the array, but may be overwritten or new inserted here
+ // remember their indices in the case new values must be added to the array
+ sal_Int32 nPropertyCount = lDescriptor.getLength();
+ sal_Int32 nIndexOfInputStream = -1;
+ sal_Int32 nIndexOfContent = -1;
+ sal_Int32 nIndexOfReadOnlyFlag = -1;
+ sal_Int32 nIndexOfTemplateFlag = -1;
+ sal_Int32 nIndexOfDocumentTitle = -1;
+
+ for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
+ {
+ // extract properties
+ if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) )
+ {
+ lDescriptor[nProperty].Value >>= sTemp;
+ aURL = sTemp;
+ }
+ else if( !aURL.Len() && lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FileName")) )
+ {
+ lDescriptor[nProperty].Value >>= sTemp;
+ aURL = sTemp;
+ }
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
+ {
+ lDescriptor[nProperty].Value >>= sTemp;
+ aTypeName = sTemp;
+ }
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("FilterName")) )
+ {
+ lDescriptor[nProperty].Value >>= sTemp;
+ aPreselectedFilterName = sTemp;
+ }
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream")) )
+ nIndexOfInputStream = nProperty;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly")) )
+ nIndexOfReadOnlyFlag = nProperty;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent")) )
+ nIndexOfContent = nProperty;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) )
+ {
+ lDescriptor[nProperty].Value >>= bOpenAsTemplate;
+ nIndexOfTemplateFlag = nProperty;
+ }
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) )
+ lDescriptor[nProperty].Value >>= xInteraction;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")) )
+ lDescriptor[nProperty].Value >>= bRepairPackage;
+ else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) )
+ nIndexOfDocumentTitle = nProperty;
+ }
+
+ // can't check the type for external filters, so set the "dont" flag accordingly
+ SolarMutexGuard aGuard;
+
+ SfxApplication* pApp = SFX_APP();
+ SfxAllItemSet *pSet = new SfxAllItemSet( pApp->GetPool() );
+ TransformParameters( SID_OPENDOC, lDescriptor, *pSet );
+ SFX_ITEMSET_ARG( pSet, pItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
+
+ bWasReadOnly = pItem && pItem->GetValue();
+
+ String aFilterName;
+ String aPrefix = String::CreateFromAscii( "private:factory/" );
+ if( aURL.Match( aPrefix ) == aPrefix.Len() )
+ {
+ const SfxFilter* pFilter = 0;
+ String aPattern( aPrefix );
+ aPattern += String::CreateFromAscii("smath");
+ if ( aURL.Match( aPattern ) >= aPattern.Len() )
+ {
+ pFilter = SfxFilter::GetDefaultFilterFromFactory( aURL );
+ aTypeName = pFilter->GetTypeName();
+ aFilterName = pFilter->GetName();
+ }
+ }
+ else
+ {
+ // ctor of SfxMedium uses owner transition of ItemSet
+ SfxMedium aMedium( aURL, bWasReadOnly ? STREAM_STD_READ : STREAM_STD_READWRITE, sal_False, NULL, pSet );
+ aMedium.UseInteractionHandler( true );
+
+ bool bIsStorage = aMedium.IsStorage();
+ if ( aMedium.GetErrorCode() == ERRCODE_NONE )
+ {
+ // remember input stream and content and put them into the descriptor later
+ // should be done here since later the medium can switch to a version
+ xStream = aMedium.GetInputStream();
+ xContent = aMedium.GetContent();
+ bReadOnly = aMedium.IsReadOnly();
+
+ if ( bIsStorage )
+ {
+ //TODO/LATER: factor this out!
+ uno::Reference < embed::XStorage > xStorage = aMedium.GetStorage( sal_False );
+ if ( aMedium.GetLastStorageCreationState() != ERRCODE_NONE )
+ {
+ // error during storage creation means _here_ that the medium
+ // is broken, but we can not handle it in medium since unpossibility
+ // to create a storage does not _always_ means that the medium is broken
+ aMedium.SetError( aMedium.GetLastStorageCreationState(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
+ if ( xInteraction.is() )
+ {
+ OUString empty;
+ try
+ {
+ InteractiveAppException xException( empty,
+ REFERENCE< XInterface >(),
+ InteractionClassification_ERROR,
+ aMedium.GetError() );
+
+ REFERENCE< XInteractionRequest > xRequest(
+ new ucbhelper::SimpleInteractionRequest( makeAny( xException ),
+ ucbhelper::CONTINUATION_APPROVE ) );
+ xInteraction->handle( xRequest );
+ }
+ catch ( Exception & ) {};
+ }
+ }
+ else
+ {
+ aFilterName.Erase();
+
+ try
+ {
+ const SfxFilter* pFilter = aPreselectedFilterName.Len() ?
+ SfxFilterMatcher().GetFilter4FilterName( aPreselectedFilterName ) : aTypeName.Len() ?
+ SfxFilterMatcher(String::CreateFromAscii("smath")).GetFilter4EA( aTypeName ) : 0;
+ String aTmpFilterName;
+ if ( pFilter )
+ aTmpFilterName = pFilter->GetName();
+ aTypeName = SfxFilter::GetTypeFromStorage( xStorage, pFilter ? pFilter->IsAllowedAsTemplate() : sal_False, &aTmpFilterName );
+ }
+ catch( lang::WrappedTargetException& aWrap )
+ {
+ packages::zip::ZipIOException aZipException;
+
+ // repairing is done only if this type is requested from outside
+ if ( ( aWrap.TargetException >>= aZipException ) && aTypeName.Len() )
+ {
+ if ( xInteraction.is() )
+ {
+ // the package is broken one
+ aDocumentTitle = aMedium.GetURLObject().getName(
+ INetURLObject::LAST_SEGMENT,
+ true,
+ INetURLObject::DECODE_WITH_CHARSET );
+
+ if ( !bRepairPackage )
+ {
+ // ask the user whether he wants to try to repair
+ RequestPackageReparation aRequest( aDocumentTitle );
+ xInteraction->handle( aRequest.GetRequest() );
+ bRepairAllowed = aRequest.isApproved();
+ }
+
+ if ( !bRepairAllowed )
+ {
+ // repair either not allowed or not successful
+ NotifyBrokenPackage aNotifyRequest( aDocumentTitle );
+ xInteraction->handle( aNotifyRequest.GetRequest() );
+ }
+ }
+
+ if ( !bRepairAllowed )
+ aTypeName.Erase();
+ }
+ }
+ catch( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch( uno::Exception& )
+ {
+ aTypeName.Erase();
+ }
+
+ if ( aTypeName.Len() )
+ {
+ const SfxFilter* pFilter =
+ SfxFilterMatcher( String::CreateFromAscii("smath") ).GetFilter4EA( aTypeName );
+ if ( pFilter )
+ aFilterName = pFilter->GetName();
+ }
+ }
+ }
+ else
+ {
+ //Test to see if this begins with xml and if so run it through
+ //the MathML filter. There are all sorts of things wrong with
+ //this approach, to be fixed at a better level than here
+ SvStream *pStrm = aMedium.GetInStream();
+ aTypeName.Erase();
+ if (pStrm && !pStrm->GetError())
+ {
+ SotStorageRef aStorage = new SotStorage ( pStrm, sal_False );
+ if ( !aStorage->GetError() )
+ {
+ if ( aStorage->IsStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Equation Native" ) ) ) )
+ {
+ sal_uInt8 nVersion;
+ if (GetMathTypeVersion( aStorage, nVersion ) && nVersion <=3)
+ aTypeName.AssignAscii( "math_MathType_3x" );
+ }
+ }
+ else
+ {
+ const sal_uInt16 nSize = 5;
+ sal_Char aBuffer[nSize+1];
+ aBuffer[nSize] = 0;
+ pStrm->Seek( STREAM_SEEK_TO_BEGIN );
+ sal_uLong nBytesRead = pStrm->Read( aBuffer, nSize );
+ if (nBytesRead == nSize)
+ {
+ if (0 == strncmp( "<?xml",aBuffer,nSize))
+ {
+ static const sal_Char sFltrNm_2[] = MATHML_XML;
+ static const sal_Char sTypeNm_2[] = "math_MathML_XML_Math";
+ aFilterName.AssignAscii( sFltrNm_2 );
+ aTypeName.AssignAscii( sTypeNm_2 );
+ }
+ }
+ }
+
+ if ( aTypeName.Len() )
+ {
+ const SfxFilter* pFilt = SfxFilterMatcher( String::CreateFromAscii("smath") ).GetFilter4EA( aTypeName );
+ if ( pFilt )
+ aFilterName = pFilt->GetName();
+ }
+ }
+ }
+ }
+ }
+
+ if ( nIndexOfInputStream == -1 && xStream.is() )
+ {
+ // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("InputStream"));
+ lDescriptor[nPropertyCount].Value <<= xStream;
+ nPropertyCount++;
+ }
+
+ if ( nIndexOfContent == -1 && xContent.is() )
+ {
+ // if input stream wasn't part of the descriptor, now it should be, otherwise the content would be opend twice
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UCBContent"));
+ lDescriptor[nPropertyCount].Value <<= xContent;
+ nPropertyCount++;
+ }
+
+ if ( bReadOnly != bWasReadOnly )
+ {
+ if ( nIndexOfReadOnlyFlag == -1 )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
+ lDescriptor[nPropertyCount].Value <<= bReadOnly;
+ nPropertyCount++;
+ }
+ else
+ lDescriptor[nIndexOfReadOnlyFlag].Value <<= bReadOnly;
+ }
+
+ if ( !bRepairPackage && bRepairAllowed )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage"));
+ lDescriptor[nPropertyCount].Value <<= bRepairAllowed;
+ nPropertyCount++;
+
+ bOpenAsTemplate = sal_True;
+
+ // TODO/LATER: set progress bar that should be used
+ }
+
+ if ( bOpenAsTemplate )
+ {
+ if ( nIndexOfTemplateFlag == -1 )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate"));
+ lDescriptor[nPropertyCount].Value <<= bOpenAsTemplate;
+ nPropertyCount++;
+ }
+ else
+ lDescriptor[nIndexOfTemplateFlag].Value <<= bOpenAsTemplate;
+ }
+
+ if ( aDocumentTitle.getLength() )
+ {
+ // the title was set here
+ if ( nIndexOfDocumentTitle == -1 )
+ {
+ lDescriptor.realloc( nPropertyCount + 1 );
+ lDescriptor[nPropertyCount].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle"));
+ lDescriptor[nPropertyCount].Value <<= aDocumentTitle;
+ nPropertyCount++;
+ }
+ else
+ lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle;
+ }
+
+ if ( !aFilterName.Len() )
+ aTypeName.Erase();
+
+ return aTypeName;
+}
+
+SFX_IMPL_SINGLEFACTORY( SmFilterDetect )
+
+/* XServiceInfo */
+UNOOUSTRING SAL_CALL SmFilterDetect::getImplementationName() throw( UNORUNTIMEEXCEPTION )
+{
+ return impl_getStaticImplementationName();
+}
+ \
+/* XServiceInfo */
+sal_Bool SAL_CALL SmFilterDetect::supportsService( const UNOOUSTRING& sServiceName ) throw( UNORUNTIMEEXCEPTION )
+{
+ UNOSEQUENCE< UNOOUSTRING > seqServiceNames = getSupportedServiceNames();
+ const UNOOUSTRING* pArray = seqServiceNames.getConstArray();
+ for ( sal_Int32 nCounter=0; nCounter<seqServiceNames.getLength(); nCounter++ )
+ {
+ if ( pArray[nCounter] == sServiceName )
+ {
+ return sal_True ;
+ }
+ }
+ return sal_False ;
+}
+
+/* XServiceInfo */
+UNOSEQUENCE< UNOOUSTRING > SAL_CALL SmFilterDetect::getSupportedServiceNames() throw( UNORUNTIMEEXCEPTION )
+{
+ return impl_getStaticSupportedServiceNames();
+}
+
+/* Helper for XServiceInfo */
+UNOSEQUENCE< UNOOUSTRING > SmFilterDetect::impl_getStaticSupportedServiceNames()
+{
+ UNOMUTEXGUARD aGuard( UNOMUTEX::getGlobalMutex() );
+ UNOSEQUENCE< UNOOUSTRING > seqServiceNames( 1 );
+ seqServiceNames.getArray() [0] = UNOOUSTRING(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ExtendedTypeDetection" ));
+ return seqServiceNames ;
+}
+
+/* Helper for XServiceInfo */
+UNOOUSTRING SmFilterDetect::impl_getStaticImplementationName()
+{
+ return UNOOUSTRING(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.math.FormatDetector" ));
+}
+
+/* Helper for registry */
+UNOREFERENCE< UNOXINTERFACE > SAL_CALL SmFilterDetect::impl_createInstance( const UNOREFERENCE< UNOXMULTISERVICEFACTORY >& xServiceManager ) throw( UNOEXCEPTION )
+{
+ return UNOREFERENCE< UNOXINTERFACE >( *new SmFilterDetect( xServiceManager ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/smdetect.hxx b/starmath/source/smdetect.hxx
new file mode 100644
index 000000000000..ae5fc38852ce
--- /dev/null
+++ b/starmath/source/smdetect.hxx
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SM_TYPEDETECT_HXX
+#define _SM_TYPEDETECT_HXX
+
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <cppuhelper/implbase2.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <cppuhelper/factory.hxx>
+#include <tools/link.hxx>
+#include <tools/string.hxx>
+
+class SfxObjectFactory;
+class SfxFilterMatcher;
+class LoadEnvironment_Impl;
+class SfxMedium;
+
+namespace com
+{
+ namespace sun
+ {
+ namespace star
+ {
+ namespace uno
+ {
+ class Any;
+ }
+ namespace lang
+ {
+ class XMultiServiceFactory;
+ }
+ namespace frame
+ {
+ class XFrame;
+ }
+ namespace beans
+ {
+ struct PropertyValue;
+ }
+ }
+ }
+}
+
+#include <sfx2/sfxuno.hxx>
+
+#define REFERENCE ::com::sun::star::uno::Reference
+#define SEQUENCE ::com::sun::star::uno::Sequence
+#define RUNTIME_EXCEPTION ::com::sun::star::uno::RuntimeException
+
+class SmFilterDetect : public ::cppu::WeakImplHelper2< ::com::sun::star::document::XExtendedFilterDetection, ::com::sun::star::lang::XServiceInfo >
+{
+public:
+ SmFilterDetect( const REFERENCE < ::com::sun::star::lang::XMultiServiceFactory >& xFactory );
+ virtual ~SmFilterDetect();
+
+ SFX_DECL_XSERVICEINFO
+
+ //----------------------------------------------------------------------------------
+ // XExtendedFilterDetect
+ //----------------------------------------------------------------------------------
+ virtual ::rtl::OUString SAL_CALL detect( SEQUENCE< ::com::sun::star::beans::PropertyValue >& lDescriptor ) throw( RUNTIME_EXCEPTION );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/smdll.cxx b/starmath/source/smdll.cxx
new file mode 100644
index 000000000000..00ea0f5d49b2
--- /dev/null
+++ b/starmath/source/smdll.cxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <sot/factory.hxx>
+#include <svx/svxids.hrc>
+#include <svx/modctrl.hxx>
+#include <svx/zoomctrl.hxx>
+#include <sfx2/docfac.hxx>
+#include <svx/lboxctrl.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/taskpane.hxx>
+
+#include <smdll.hxx>
+#include <document.hxx>
+#include <toolbox.hxx>
+#include <view.hxx>
+
+#include <starmath.hrc>
+
+#include <svx/xmlsecctrl.hxx>
+
+
+
+bool SmDLL::bInitialized = false;
+
+
+// Initialization
+
+void SmDLL::Init()
+{
+ if ( bInitialized )
+ return;
+
+ bInitialized = true;
+
+ SfxObjectFactory& rFactory = SmDocShell::Factory();
+
+ SmModule** ppShlPtr = (SmModule**) GetAppData(SHL_SM);
+ *ppShlPtr = new SmModule( &rFactory );
+
+ SfxModule *p = SM_MOD();
+ SmModule *pp = (SmModule *) p;
+
+ rFactory.SetDocumentServiceName( String::CreateFromAscii("com.sun.star.formula.FormulaProperties") );
+
+ SmModule::RegisterInterface(pp);
+ SmDocShell::RegisterInterface(pp);
+ SmViewShell::RegisterInterface(pp);
+
+ SmViewShell::RegisterFactory(1);
+
+ SvxZoomStatusBarControl::RegisterControl( SID_ATTR_ZOOM, pp );
+ SvxModifyControl::RegisterControl( SID_TEXTSTATUS, pp );
+ SvxUndoRedoControl::RegisterControl( SID_UNDO, pp );
+ SvxUndoRedoControl::RegisterControl( SID_REDO, pp );
+ XmlSecStatusBarControl::RegisterControl( SID_SIGNATURE, pp );
+
+ SmToolBoxWrapper::RegisterChildWindow(true);
+ SmCmdBoxWrapper::RegisterChildWindow(true);
+
+ ::sfx2::TaskPaneWrapper::RegisterChildWindow( false, pp );
+}
+
+
+// Deinitialization
+
+void SmDLL::Exit()
+{
+ // the SdModule must be destroyed
+ SmModule** ppShlPtr = (SmModule**) GetAppData(SHL_SM);
+ delete (*ppShlPtr);
+ (*ppShlPtr) = NULL;
+
+ *GetAppData(SHL_SM) = 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/smmod.cxx b/starmath/source/smmod.cxx
new file mode 100644
index 000000000000..669a26ab39ef
--- /dev/null
+++ b/starmath/source/smmod.cxx
@@ -0,0 +1,375 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <tools/globname.hxx>
+#include <vcl/status.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/sfx.hrc>
+#include <sfx2/viewsh.hxx>
+#include <vcl/wrkwin.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/msgbox.hxx>
+#include <vcl/virdev.hxx>
+#include <unotools/syslocale.hxx>
+#include <tools/rtti.hxx>
+#include "smmod.hxx"
+#include "symbol.hxx"
+#include "config.hxx"
+#include "dialog.hxx"
+#include "edit.hxx"
+#include "view.hxx"
+#include "starmath.hrc"
+#include "svx/modctrl.hxx"
+
+TYPEINIT1( SmModule, SfxModule );
+
+#define SmModule
+#include "smslots.hxx"
+
+#include <svx/xmlsecctrl.hxx>
+
+
+
+SmResId::SmResId( sal_uInt16 nId )
+ : ResId(nId, *SM_MOD()->GetResMgr())
+{
+}
+
+/////////////////////////////////////////////////////////////////
+
+SmLocalizedSymbolData::SmLocalizedSymbolData() :
+ Resource( SmResId(RID_LOCALIZED_NAMES) ),
+ aUiSymbolNamesAry ( SmResId(RID_UI_SYMBOL_NAMES) ),
+ aExportSymbolNamesAry ( SmResId(RID_EXPORT_SYMBOL_NAMES) ),
+ aUiSymbolSetNamesAry ( SmResId(RID_UI_SYMBOLSET_NAMES) ),
+ aExportSymbolSetNamesAry( SmResId(RID_EXPORT_SYMBOLSET_NAMES) ),
+ p50NamesAry ( 0 ),
+ p60NamesAry ( 0 ),
+ n50NamesLang ( LANGUAGE_NONE ),
+ n60NamesLang ( LANGUAGE_NONE )
+{
+ FreeResource();
+}
+
+
+SmLocalizedSymbolData::~SmLocalizedSymbolData()
+{
+ delete p50NamesAry;
+ delete p60NamesAry;
+}
+
+
+const String SmLocalizedSymbolData::GetUiSymbolName( const String &rExportName ) const
+{
+ String aRes;
+
+ const SmLocalizedSymbolData &rData = SM_MOD()->GetLocSymbolData();
+ const ResStringArray &rUiNames = rData.GetUiSymbolNamesArray();
+ const ResStringArray &rExportNames = rData.GetExportSymbolNamesArray();
+ sal_uInt16 nCount = sal::static_int_cast< xub_StrLen >(rExportNames.Count());
+ for (sal_uInt16 i = 0; i < nCount && !aRes.Len(); ++i)
+ {
+ if (rExportName == rExportNames.GetString(i))
+ {
+ aRes = rUiNames.GetString(i);
+ break;
+ }
+ }
+
+ return aRes;
+}
+
+
+const String SmLocalizedSymbolData::GetExportSymbolName( const String &rUiName ) const
+{
+ String aRes;
+
+ const SmLocalizedSymbolData &rData = SM_MOD()->GetLocSymbolData();
+ const ResStringArray &rUiNames = rData.GetUiSymbolNamesArray();
+ const ResStringArray &rExportNames = rData.GetExportSymbolNamesArray();
+ sal_uInt16 nCount = sal::static_int_cast< xub_StrLen >(rUiNames.Count());
+ for (sal_uInt16 i = 0; i < nCount && !aRes.Len(); ++i)
+ {
+ if (rUiName == rUiNames.GetString(i))
+ {
+ aRes = rExportNames.GetString(i);
+ break;
+ }
+ }
+
+ return aRes;
+}
+
+
+const String SmLocalizedSymbolData::GetUiSymbolSetName( const String &rExportName ) const
+{
+ String aRes;
+
+ const SmLocalizedSymbolData &rData = SM_MOD()->GetLocSymbolData();
+ const ResStringArray &rUiNames = rData.GetUiSymbolSetNamesArray();
+ const ResStringArray &rExportNames = rData.GetExportSymbolSetNamesArray();
+ sal_uInt16 nCount = sal::static_int_cast< xub_StrLen >(rExportNames.Count());
+ for (sal_uInt16 i = 0; i < nCount && !aRes.Len(); ++i)
+ {
+ if (rExportName == rExportNames.GetString(i))
+ {
+ aRes = rUiNames.GetString(i);
+ break;
+ }
+ }
+
+ return aRes;
+}
+
+
+const String SmLocalizedSymbolData::GetExportSymbolSetName( const String &rUiName ) const
+{
+ String aRes;
+
+ const SmLocalizedSymbolData &rData = SM_MOD()->GetLocSymbolData();
+ const ResStringArray &rUiNames = rData.GetUiSymbolSetNamesArray();
+ const ResStringArray &rExportNames = rData.GetExportSymbolSetNamesArray();
+ sal_uInt16 nCount = sal::static_int_cast< xub_StrLen >(rUiNames.Count());
+ for (sal_uInt16 i = 0; i < nCount && !aRes.Len(); ++i)
+ {
+ if (rUiName == rUiNames.GetString(i))
+ {
+ aRes = rExportNames.GetString(i);
+ break;
+ }
+ }
+
+ return aRes;
+}
+
+
+const ResStringArray* SmLocalizedSymbolData::Get50NamesArray( LanguageType nLang )
+{
+ if (nLang != n50NamesLang)
+ {
+ int nRID;
+ switch (nLang)
+ {
+ case LANGUAGE_FRENCH : nRID = RID_FRENCH_50_NAMES; break;
+ case LANGUAGE_ITALIAN : nRID = RID_ITALIAN_50_NAMES; break;
+ case LANGUAGE_SWEDISH : nRID = RID_SWEDISH_50_NAMES; break;
+ case LANGUAGE_SPANISH : nRID = RID_SPANISH_50_NAMES; break;
+ default : nRID = -1; break;
+ }
+ delete p50NamesAry;
+ p50NamesAry = 0;
+ n50NamesLang = nLang;
+ if (-1 != nRID)
+ p50NamesAry = new SmNamesArray( n50NamesLang, nRID );
+ }
+
+ return p50NamesAry ? &p50NamesAry->GetNamesArray() : 0;
+}
+
+
+const ResStringArray* SmLocalizedSymbolData::Get60NamesArray( LanguageType nLang )
+{
+ if (nLang != n60NamesLang)
+ {
+ int nRID;
+ switch (nLang)
+ {
+ case LANGUAGE_FRENCH : nRID = RID_FRENCH_60_NAMES; break;
+ case LANGUAGE_ITALIAN : nRID = RID_ITALIAN_60_NAMES; break;
+ case LANGUAGE_SWEDISH : nRID = RID_SWEDISH_60_NAMES; break;
+ case LANGUAGE_SPANISH : nRID = RID_SPANISH_60_NAMES; break;
+ default : nRID = -1; break;
+ }
+ delete p60NamesAry;
+ p60NamesAry = 0;
+ n60NamesLang = nLang;
+ if (-1 != nRID)
+ p60NamesAry = new SmNamesArray( n60NamesLang, nRID );
+ }
+
+ return p60NamesAry ? &p60NamesAry->GetNamesArray() : 0;
+}
+
+/////////////////////////////////////////////////////////////////
+
+SFX_IMPL_INTERFACE(SmModule, SfxModule, SmResId(RID_APPLICATION))
+{
+ SFX_STATUSBAR_REGISTRATION(SmResId(RID_STATUSBAR));
+}
+
+
+SmModule::SmModule(SfxObjectFactory* pObjFact) :
+ SfxModule(SfxApplication::CreateResManager("sm"), sal_False, pObjFact, NULL),
+ pColorConfig( 0 ),
+ pConfig( 0 ),
+ pLocSymbolData( 0 ),
+ pSysLocale( 0 ),
+ pVirtualDev( 0 )
+{
+ SetName( C2S("StarMath" ));
+
+ SvxModifyControl::RegisterControl(SID_DOC_MODIFIED, this);
+}
+
+
+SmModule::~SmModule()
+{
+ delete pConfig;
+ if (pColorConfig)
+ pColorConfig->RemoveListener(this);
+ delete pColorConfig;
+ delete pLocSymbolData;
+ delete pSysLocale;
+ delete pVirtualDev;
+}
+
+void SmModule::_CreateSysLocale() const
+{
+ SmModule* pThis = (SmModule*)this;
+ pThis->pSysLocale = new SvtSysLocale;
+}
+
+void SmModule::_CreateVirtualDev() const
+{
+ SmModule* pThis = (SmModule*)this;
+ pThis->pVirtualDev = new VirtualDevice;
+ pThis->pVirtualDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_MSO1 );
+}
+
+void SmModule::ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg )
+{
+ //invalidate all graphic and edit windows
+ const TypeId aSmViewTypeId = TYPE(SmViewShell);
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+ while (pViewShell)
+ {
+ if ((pViewShell->IsA(aSmViewTypeId)))
+ {
+ SmViewShell *pSmView = (SmViewShell *) pViewShell;
+ pSmView->GetGraphicWindow().ApplyColorConfigValues( rColorCfg );
+ SmEditWindow *pEditWin = pSmView->GetEditWindow();
+ if (pEditWin)
+ pEditWin->ApplyColorConfigValues( rColorCfg );
+ }
+ pViewShell = SfxViewShell::GetNext( *pViewShell );
+ }
+}
+
+svtools::ColorConfig & SmModule::GetColorConfig()
+{
+ if(!pColorConfig)
+ {
+ pColorConfig = new svtools::ColorConfig;
+ ApplyColorConfigValues( *pColorConfig );
+ pColorConfig->AddListener(this);
+ }
+ return *pColorConfig;
+}
+
+void SmModule::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 )
+{
+ ApplyColorConfigValues(*pColorConfig);
+}
+
+SmConfig * SmModule::GetConfig()
+{
+ if(!pConfig)
+ pConfig = new SmConfig;
+ return pConfig;
+}
+
+SmSymbolManager & SmModule::GetSymbolManager()
+{
+ return GetConfig()->GetSymbolManager();
+}
+
+SmLocalizedSymbolData & SmModule::GetLocSymbolData() const
+{
+ if (!pLocSymbolData)
+ ((SmModule *) this)->pLocSymbolData = new SmLocalizedSymbolData;
+ return *pLocSymbolData;
+}
+
+void SmModule::GetState(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter(rSet);
+
+ for (sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich())
+ switch (nWh)
+ {
+ case SID_CONFIGEVENT :
+ rSet.DisableItem(SID_CONFIGEVENT);
+ break;
+ }
+}
+
+SfxItemSet* SmModule::CreateItemSet( sal_uInt16 nId )
+{
+ SfxItemSet* pRet = 0;
+ if(nId == SID_SM_EDITOPTIONS)
+ {
+ pRet = new SfxItemSet(GetPool(),
+ //TP_SMPRINT
+ SID_PRINTSIZE, SID_PRINTSIZE,
+ SID_PRINTZOOM, SID_PRINTZOOM,
+ SID_PRINTTITLE, SID_PRINTTITLE,
+ SID_PRINTTEXT, SID_PRINTTEXT,
+ SID_PRINTFRAME, SID_PRINTFRAME,
+ SID_NO_RIGHT_SPACES, SID_NO_RIGHT_SPACES,
+ SID_SAVE_ONLY_USED_SYMBOLS, SID_SAVE_ONLY_USED_SYMBOLS,
+ 0 );
+
+ GetConfig()->ConfigToItemSet(*pRet);
+ }
+ return pRet;
+}
+void SmModule::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet )
+{
+ if(nId == SID_SM_EDITOPTIONS)
+ {
+ GetConfig()->ItemSetToConfig(rSet);
+ }
+}
+SfxTabPage* SmModule::CreateTabPage( sal_uInt16 nId, Window* pParent, const SfxItemSet& rSet )
+{
+ SfxTabPage* pRet = 0;
+ if(nId == SID_SM_TP_PRINTOPTIONS)
+ pRet = SmPrintOptionsTabPage::Create( pParent, rSet );
+ return pRet;
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/smres.src b/starmath/source/smres.src
new file mode 100644
index 000000000000..dd616848f277
--- /dev/null
+++ b/starmath/source/smres.src
@@ -0,0 +1,1670 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include <sfx2/sfx.hrc>
+#include <svx/globlmn.hrc>
+#include "starmath.hrc"
+#include "dialog.hrc"
+#include "toolbox.hrc"
+#include "smcommands.h"
+
+#define IMAGE_STDBTN_COLOR Color { Red = 0xff00; Green = 0x0000; Blue = 0xff00; }
+#define MN_SUB_TOOLBAR 32
+#define WORKARROUND_1 1
+#define WORKARROUND_3 3
+#define WORKARROUND_10 10
+
+ModalDialog RID_FONTDIALOG
+{
+ HelpID = "starmath:ModalDialog:RID_FONTDIALOG";
+ Moveable = TRUE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 183 , 150 ) ;
+ Text [ en-US ] = "Fonts" ;
+ FixedText 1
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 40 , 8 ) ;
+ Text [ en-US ] = "~Font";
+ };
+ ComboBox 1
+ {
+ HelpID = "starmath:ComboBox:RID_FONTDIALOG:1";
+ Pos = MAP_APPFONT ( 6 , 17 ) ;
+ Size = MAP_APPFONT ( 111 , 60 ) ;
+ TabStop = TRUE ;
+ Sort = TRUE ;
+ VScroll = TRUE ;
+ };
+ CheckBox 1
+ {
+ HelpID = "starmath:CheckBox:RID_FONTDIALOG:1";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 60 , 84 ) ;
+ Size = MAP_APPFONT ( 33 , 10 ) ;
+ Text [ en-US ] = "~Bold" ;
+ };
+ CheckBox 2
+ {
+ HelpID = "starmath:CheckBox:RID_FONTDIALOG:2";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 60 , 97 ) ;
+ Size = MAP_APPFONT ( 33 , 10 ) ;
+ Text [ en-US ] = "~Italic" ;
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 126 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 126 , 24 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ Control 1
+ {
+ Disable = TRUE ;
+ Border = TRUE;
+ Pos = MAP_APPFONT ( 6 , 113 ) ;
+ Size = MAP_APPFONT ( 111 , 31 ) ;
+ };
+ FixedText 2
+ {
+ Pos = MAP_APPFONT ( 6 , 85 ) ;
+ Size = MAP_APPFONT ( 42 , 8 ) ;
+ Text [ en-US ] = "Attributes" ;
+ };
+};
+
+ModalDialog RID_FONTSIZEDIALOG
+{
+ Moveable = TRUE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ HelpId = CMD_SID_FONTSIZE ;
+ Size = MAP_APPFONT ( 171 , 120 ) ;
+ Text [ en-US ] = "Font Sizes" ;
+ FixedText 1
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 7 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "Base ~size";
+ };
+ MetricField 1
+ {
+ HelpID = "starmath:MetricField:RID_FONTSIZEDIALOG:1";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 57 , 6 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 4 ;
+ Maximum = 127 ;
+ Unit = FUNIT_POINT ;
+ };
+ FixedText 4
+ {
+ Pos = MAP_APPFONT ( 12 , 37 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "~Text";
+ };
+ MetricField 4
+ {
+ HelpID = "starmath:MetricField:RID_FONTSIZEDIALOG:4";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 57 , 36 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 5 ;
+ Maximum = 200 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = "%" ;
+ };
+ FixedText 5
+ {
+ Pos = MAP_APPFONT ( 12 , 52 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "~Indexes";
+ };
+ MetricField 5
+ {
+ HelpID = "starmath:MetricField:RID_FONTSIZEDIALOG:5";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 57 , 51 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 5 ;
+ Maximum = 200 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = "%" ;
+ };
+ FixedText 6
+ {
+ Pos = MAP_APPFONT ( 12 , 67 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "~Functions";
+ };
+ MetricField 6
+ {
+ HelpID = "starmath:MetricField:RID_FONTSIZEDIALOG:6";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 57 , 66 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 5 ;
+ Maximum = 200 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = "%" ;
+ };
+ FixedText 7
+ {
+ Pos = MAP_APPFONT ( 12 , 82 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "~Operators";
+ };
+ MetricField 7
+ {
+ HelpID = "starmath:MetricField:RID_FONTSIZEDIALOG:7";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 57 , 81 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 5 ;
+ Maximum = 200 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = "%" ;
+ };
+ FixedText 8
+ {
+ Pos = MAP_APPFONT ( 12 , 97 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "~Limits";
+ };
+ MetricField 8
+ {
+ HelpID = "starmath:MetricField:RID_FONTSIZEDIALOG:8";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 57 , 96 ) ;
+ Size = MAP_APPFONT ( 40 , 12 ) ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 5 ;
+ Maximum = 200 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = "%" ;
+ };
+ FixedLine 1
+ {
+ Pos = MAP_APPFONT ( 6 , 24 ) ;
+ Size = MAP_APPFONT ( 99 , 8 ) ;
+ Text [ en-US ] = "Relative sizes" ;
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 114 , 3 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 114 , 21 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton 1
+ {
+ HelpID = "starmath:PushButton:RID_FONTSIZEDIALOG:1";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 114 , 45 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Default" ;
+ };
+};
+
+ModalDialog RID_FONTTYPEDIALOG
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ HelpId = CMD_SID_FONT ;
+ Size = MAP_APPFONT ( 282 , 153 ) ;
+ Text [ en-US ] = "Fonts" ;
+ Moveable = TRUE ;
+ FixedLine 1
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 207 , 8 ) ;
+ Text [ en-US ] = "Formula fonts" ;
+ };
+ FixedLine 2
+ {
+ Pos = MAP_APPFONT ( 6 , 84 ) ;
+ Size = MAP_APPFONT ( 207 , 8 ) ;
+ Text [ en-US ] = "Custom fonts" ;
+ };
+ FixedText 1
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 18 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "~Variables";
+ };
+ ListBox 1
+ {
+ HelpID = "starmath:ListBox:RID_FONTTYPEDIALOG:1";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 54 , 18 ) ;
+ Size = MAP_APPFONT ( 150 , 69 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText 2
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 33 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "~Functions";
+ };
+ ListBox 2
+ {
+ HelpID = "starmath:ListBox:RID_FONTTYPEDIALOG:2";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 54 , 33 ) ;
+ Size = MAP_APPFONT ( 150 , 69 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText 3
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 51 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "~Numbers";
+ };
+ ListBox 3
+ {
+ HelpID = "starmath:ListBox:RID_FONTTYPEDIALOG:3";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 54 , 48 ) ;
+ Size = MAP_APPFONT ( 150 , 69 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText 4
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 66 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "~Text";
+ };
+ ListBox 4
+ {
+ HelpID = "starmath:ListBox:RID_FONTTYPEDIALOG:4";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 54 , 63 ) ;
+ Size = MAP_APPFONT ( 150 , 69 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText 5
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 97 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "~Serif";
+ };
+ ListBox 5
+ {
+ HelpID = "starmath:ListBox:RID_FONTTYPEDIALOG:5";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 54 , 96 ) ;
+ Size = MAP_APPFONT ( 150 , 69 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText 6
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 112 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "S~ans";
+ };
+ ListBox 6
+ {
+ HelpID = "starmath:ListBox:RID_FONTTYPEDIALOG:6";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 54 , 111 ) ;
+ Size = MAP_APPFONT ( 150 , 69 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText 7
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 127 ) ;
+ Size = MAP_APPFONT ( 40 , 10 ) ;
+ Text [ en-US ] = "F~ixed";
+ };
+ ListBox 7
+ {
+ HelpID = "starmath:ListBox:RID_FONTTYPEDIALOG:7";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 54 , 126 ) ;
+ Size = MAP_APPFONT ( 150 , 69 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 225 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 225 , 24 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ MenuButton 1
+ {
+ HelpID = "starmath:MenuButton:RID_FONTTYPEDIALOG:1";
+ TabStop = TRUE ;
+ ButtonMenu = Menu , RID_FONTMENU ;
+ Pos = MAP_APPFONT ( 225 , 48 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Modify" ;
+ };
+ PushButton 2
+ {
+ HelpID = "starmath:PushButton:RID_FONTTYPEDIALOG:2";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 225 , 66 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Default" ;
+ };
+};
+
+ModalDialog RID_DISTANCEDIALOG
+{
+ Moveable = TRUE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ HelpId = CMD_SID_DISTANCE ;
+ Size = MAP_APPFONT ( 240 , 90 ) ;
+ Text [ en-US ] = "Spacing" ;
+ FixedText 1
+ {
+ Pos = MAP_APPFONT ( 12 , 19 ) ;
+ Size = MAP_APPFONT ( 65 , 10 ) ;
+ Left = TRUE ;
+ };
+ MetricField 1
+ {
+ HelpID = "starmath:MetricField:RID_DISTANCEDIALOG:1";
+ Border = TRUE ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Spin = TRUE ;
+ SpinSize = 1 ;
+ Repeat = TRUE;
+ Pos = MAP_APPFONT ( 78 , 18 ) ;
+ Size = MAP_APPFONT ( 38 , 12 ) ;
+ CustomUnitText [ en-US ] = "%" ;
+ };
+ FixedText 2
+ {
+ Disable = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 35 ) ;
+ Size = MAP_APPFONT ( 65 , 10 ) ;
+ Left = TRUE ;
+ };
+ MetricField 2
+ {
+ HelpID = "starmath:MetricField:RID_DISTANCEDIALOG:2";
+ Border = TRUE ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Spin = TRUE ;
+ SpinSize = 1 ;
+ Repeat = TRUE;
+ Pos = MAP_APPFONT ( 78 , 34 ) ;
+ Size = MAP_APPFONT ( 38 , 12 ) ;
+ CustomUnitText [ en-US ] = "%" ;
+ };
+ CheckBox 1
+ {
+ HelpID = "starmath:CheckBox:RID_DISTANCEDIALOG:1";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 55 ) ;
+ Size = MAP_APPFONT ( 110 , 12 ) ;
+ Text [ en-US ] = "Scale all brackets";
+ };
+ FixedText 3
+ {
+ Disable = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 51 ) ;
+ Size = MAP_APPFONT ( 65 , 10 ) ;
+ Left = TRUE ;
+ };
+ MetricField 3
+ {
+ HelpID = "starmath:MetricField:RID_DISTANCEDIALOG:3";
+ Border = TRUE ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Spin = TRUE ;
+ SpinSize = 1 ;
+ Repeat = TRUE;
+ Pos = MAP_APPFONT ( 78 , 50 ) ;
+ Size = MAP_APPFONT ( 38 , 12 ) ;
+ CustomUnitText [ en-US ] = "%" ;
+ };
+ FixedText 4
+ {
+ Disable = TRUE ;
+ Hide = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 67 ) ;
+ Size = MAP_APPFONT ( 65 , 10 ) ;
+ Left = TRUE ;
+ };
+ MetricField 4
+ {
+ HelpID = "starmath:MetricField:RID_DISTANCEDIALOG:4";
+ Border = TRUE ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Spin = TRUE ;
+ SpinSize = 1 ;
+ Repeat = TRUE;
+ Pos = MAP_APPFONT ( 78 , 66 ) ;
+ Size = MAP_APPFONT ( 38 , 12 ) ;
+ TabStop = TRUE ;
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 184 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 184 , 24 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton 1
+ {
+ HelpID = "starmath:PushButton:RID_DISTANCEDIALOG:1";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 184 , 69 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Default" ;
+ };
+ MenuButton 1
+ {
+ HelpID = "starmath:MenuButton:RID_DISTANCEDIALOG:1";
+ TabStop = TRUE ;
+ ButtonMenu = Menu , RID_DISTANCEMENU ;
+ Pos = MAP_APPFONT ( 184 , 51 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Category" ;
+ };
+ FixedBitmap 1
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 122 , 18 ) ;
+ Size = MAP_APPFONT ( 49 , 53 ) ;
+ };
+ FixedLine 1
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 171 , 8 ) ;
+ Text [ en-US ] = "Category" ;
+ };
+ Resource 1
+ {
+ String 1
+ {
+ Text [ en-US ] = "Spacing" ;
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Spacing";
+ };
+ Bitmap 20
+ {
+ File = "dist11.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Line spacing";
+ };
+ Bitmap 30
+ {
+ File = "dist12.bmp" ;
+ };
+ String 4
+ {
+ Text [ en-US ] = "~Root spacing";
+ };
+ Bitmap 40
+ {
+ File = "dist13.bmp" ;
+ };
+ };
+ Resource 2
+ {
+ String 1
+ {
+ Text [ en-US ] = "Indexes";
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Superscript";
+ };
+ Bitmap 20
+ {
+ File = "dist21.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "S~ubscript";
+ };
+ Bitmap 30
+ {
+ File = "dist22.bmp" ;
+ };
+ };
+ Resource 3
+ {
+ String 1
+ {
+ Text [ en-US ] = "Fractions" ;
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Numerator";
+ };
+ Bitmap 20
+ {
+ File = "dist31.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Denominator";
+ };
+ Bitmap 30
+ {
+ File = "dist32.bmp" ;
+ };
+ };
+ Resource 4
+ {
+ String 1
+ {
+ Text [ en-US ] = "Fraction bar" ;
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Excess length";
+ };
+ Bitmap 20
+ {
+ File = "dist41.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Weight";
+ };
+ Bitmap 30
+ {
+ File = "dist42.bmp" ;
+ };
+ };
+ Resource 5
+ {
+ String 1
+ {
+ Text [ en-US ] = "Limits" ;
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Upper limit";
+ };
+ Bitmap 20
+ {
+ File = "dist51.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Lower limit";
+ };
+ Bitmap 30
+ {
+ File = "dist52.bmp" ;
+ };
+ };
+ Resource 6
+ {
+ String 1
+ {
+ Text [ en-US ] = "Brackets" ;
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Excess size (left/right)";
+ };
+ Bitmap 20
+ {
+ File = "dist61.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Spacing";
+ };
+ Bitmap 30
+ {
+ File = "dist62.bmp" ;
+ };
+ String 5
+ {
+ Text [ en-US ] = "~Excess size";
+ };
+ Bitmap 50
+ {
+ File = "dist61.bmp" ;
+ };
+ };
+ Resource 7
+ {
+ String 1
+ {
+ Text [ en-US ] = "Matrix" ;
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Line spacing";
+ };
+ Bitmap 20
+ {
+ File = "dist71.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Column spacing";
+ };
+ Bitmap 30
+ {
+ File = "dist72.bmp" ;
+ };
+ };
+ Resource 8
+ {
+ String 1
+ {
+ Text [ en-US ] = "Symbols" ;
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Primary height";
+ };
+ Bitmap 20
+ {
+ File = "dist81.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Minimum spacing";
+ };
+ Bitmap 30
+ {
+ File = "dist82.bmp" ;
+ };
+ };
+ Resource 9
+ {
+ String 1
+ {
+ Text [ en-US ] = "Operators" ;
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Excess size";
+ };
+ Bitmap 20
+ {
+ File = "dist91.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Spacing";
+ };
+ Bitmap 30
+ {
+ File = "dist92.bmp" ;
+ };
+ };
+ Resource 10
+ {
+ String 1
+ {
+ Text [ en-US ] = "Borders";
+ };
+ String 2
+ {
+ Text [ en-US ] = "~Left";
+ };
+ Bitmap 20
+ {
+ File = "dist101.bmp" ;
+ };
+ String 3
+ {
+ Text [ en-US ] = "~Right";
+ };
+ Bitmap 30
+ {
+ File = "dist102.bmp" ;
+ };
+ String 4
+ {
+ Text [ en-US ] = "~Top";
+ };
+ Bitmap 40
+ {
+ File = "dist103.bmp" ;
+ };
+ String 5
+ {
+ Text [ en-US ] = "~Bottom";
+ };
+ Bitmap 50
+ {
+ File = "dist104.bmp" ;
+ };
+ };
+};
+
+
+ModalDialog RID_ALIGNDIALOG
+{
+ Moveable = TRUE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ HelpId = CMD_SID_ALIGN ;
+ Size = MAP_APPFONT ( 139 , 66 ) ;
+ Text [ en-US ] = "Alignment" ;
+ RadioButton 1
+ {
+ HelpID = "starmath:RadioButton:RID_ALIGNDIALOG:1";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 17 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "~Left" ;
+ };
+ RadioButton 2
+ {
+ HelpID = "starmath:RadioButton:RID_ALIGNDIALOG:2";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 31 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "~Centered" ;
+ };
+ RadioButton 3
+ {
+ HelpID = "starmath:RadioButton:RID_ALIGNDIALOG:3";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 44 ) ;
+ Size = MAP_APPFONT ( 60 , 10 ) ;
+ Text [ en-US ] = "~Right" ;
+ };
+ FixedLine 1
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 71 , 8 ) ;
+ Text [ en-US ] = "Horizontal" ;
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 83 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 83 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+ PushButton 1
+ {
+ HelpID = "starmath:PushButton:RID_ALIGNDIALOG:1";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 83 , 46 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Default" ;
+ };
+};
+
+TabPage RID_PRINTOPTIONPAGE
+{
+ HelpID = "starmath:TabPage:RID_PRINTOPTIONPAGE";
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 260 , 185 ) ;
+ Text [ en-US ] = "Formula Options:Settings";
+ FixedLine FL_PRINTOPTIONS
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Print options";
+ };
+ CheckBox CB_TITLEROW
+ {
+ HelpID = "starmath:CheckBox:RID_PRINTOPTIONPAGE:CB_TITLEROW";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 14 ) ;
+ Size = MAP_APPFONT ( 68 , 10 ) ;
+ Text [ en-US ] = "~Title row" ;
+ };
+ CheckBox CB_EQUATION_TEXT
+ {
+ HelpID = "starmath:CheckBox:RID_PRINTOPTIONPAGE:CB_EQUATION_TEXT";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 28 ) ;
+ Size = MAP_APPFONT ( 68 , 10 ) ;
+ Text [ en-US ] = "~Formula text" ;
+ };
+ CheckBox CB_FRAME
+ {
+ HelpID = "starmath:CheckBox:RID_PRINTOPTIONPAGE:CB_FRAME";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 42 ) ;
+ Size = MAP_APPFONT ( 68 , 10 ) ;
+ Text [ en-US ] = "B~order" ;
+ };
+ FixedLine FL_PRINT_FORMAT
+ {
+ Pos = MAP_APPFONT ( 6 , 58 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Print format" ;
+ };
+ RadioButton RB_ORIGINAL_SIZE
+ {
+ HelpID = "starmath:RadioButton:RID_PRINTOPTIONPAGE:RB_ORIGINAL_SIZE";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 69 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+ Text [ en-US ] = "O~riginal size" ;
+ };
+ RadioButton RB_FIT_TO_PAGE
+ {
+ HelpID = "starmath:RadioButton:RID_PRINTOPTIONPAGE:RB_FIT_TO_PAGE";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 83 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+ Text [ en-US ] = "Fit to ~page" ;
+ };
+ RadioButton RB_ZOOM
+ {
+ HelpID = "starmath:RadioButton:RID_PRINTOPTIONPAGE:RB_ZOOM";
+ Pos = MAP_APPFONT ( 12 , 97 ) ;
+ Size = MAP_APPFONT ( 90 , 10 ) ;
+ Text [ en-US ] = "~Scaling" ;
+ TabStop = TRUE ;
+ };
+ MetricField MF_ZOOM
+ {
+ HelpID = "starmath:MetricField:RID_PRINTOPTIONPAGE:MF_ZOOM";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 18 , 111 ) ;
+ Size = MAP_APPFONT ( 30 , 12 ) ;
+ TabStop = TRUE ;
+ Left = TRUE ;
+ Repeat = TRUE ;
+ Spin = TRUE ;
+ Minimum = 10 ;
+ Maximum = 400 ;
+ Unit = FUNIT_CUSTOM ;
+ CustomUnitText = "%" ;
+ };
+ FixedLine FL_MISC_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 6 , 129 ) ;
+ Size = MAP_APPFONT ( 248 , 8 ) ;
+ Text [ en-US ] = "Miscellaneous options";
+ };
+ CheckBox CB_IGNORE_SPACING
+ {
+ HelpID = "starmath:CheckBox:RID_PRINTOPTIONPAGE:CB_IGNORE_SPACING";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 140 ) ;
+ Size = MAP_APPFONT ( 236 , 10 ) ;
+ Text [ en-US ] = "Ig~nore ~~ and ` at the end of the line";
+ };
+ CheckBox CB_SAVE_ONLY_USED_SYMBOLS
+ {
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 12 , 154 ) ;
+ Size = MAP_APPFONT ( 236 , 10 ) ;
+ Text [ en-US ] = "Embed only used symbols (smaller file size)";
+ };
+};
+
+ModalDialog RID_SYMBOLDIALOG
+{
+ HelpID = "starmath:ModalDialog:RID_SYMBOLDIALOG";
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Closeable = TRUE; // Close Button in Window Leiste explizit einbauen
+ Size = MAP_APPFONT ( 239 , 123 ) ;
+ Text [ en-US ] = "Symbols" ;
+ Moveable = TRUE ;
+ FixedText 1
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 92 , 8 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "~Symbol set";
+ };
+ ListBox 1
+ {
+ HelpID = "starmath:ListBox:RID_SYMBOLDIALOG:1";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 17 ) ;
+ Size = MAP_APPFONT ( 92, 57 ) ;
+ TabStop = TRUE ;
+ Sort = TRUE ;
+ DropDown = TRUE ;
+ VScroll = TRUE ;
+ };
+ Control 1
+ {
+ HelpID = HID_SMA_CONTROL_SYMBOLSET_VIEW ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 35 ) ;
+ Size = MAP_APPFONT ( 96 , 72 ) ;
+ TabStop = TRUE ;
+ };
+ Control 2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 108 , 35 ) ;
+ Size = MAP_APPFONT ( 63 , 72 ) ;
+ };
+ FixedText 2
+ {
+ Center = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 108 ) ;
+ Size = MAP_APPFONT ( 92 , 8 ) ;
+ Text [ en-US ] = "Unknown" ;
+ };
+ PushButton 2
+ {
+ HelpID = "starmath:PushButton:RID_SYMBOLDIALOG:2";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 177 , 6 ) ;
+ Size = MAP_APPFONT ( 56 , 14 ) ;
+ DefButton = TRUE ;
+ Text [ en-US ] = "~Insert" ;
+ };
+ PushButton 3
+ {
+ HelpID = "starmath:PushButton:RID_SYMBOLDIALOG:3";
+ Pos = MAP_APPFONT ( 177 , 24 ) ;
+ Size = MAP_APPFONT ( 56 , 14 ) ;
+ TabStop = TRUE ;
+ Text [ en-US ] = "~Close";
+ };
+ PushButton 1
+ {
+ HelpID = "starmath:PushButton:RID_SYMBOLDIALOG:1";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 177 , 42 ) ;
+ Size = MAP_APPFONT ( 56 , 14 ) ;
+ Text [ en-US ] = "~Edit..." ;
+ };
+};
+
+ModalDialog RID_SYMDEFINEDIALOG
+{
+ HelpID = "starmath:ModalDialog:RID_SYMDEFINEDIALOG";
+ Moveable = TRUE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 365 , 215 ) ;
+ Text [ en-US ] = "Edit Symbols" ;
+ FixedText 1
+ {
+ Pos = MAP_APPFONT ( 6 , 8 ) ;
+ Size = MAP_APPFONT ( 50 , 8 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "~Old symbol";
+ };
+ ComboBox 1
+ {
+ HelpID = "starmath:ComboBox:RID_SYMDEFINEDIALOG:1";
+ Pos = MAP_APPFONT ( 59 , 6 ) ;
+ Size = MAP_APPFONT ( 80 , 100 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ FixedText 2
+ {
+ Pos = MAP_APPFONT ( 145 , 8 ) ;
+ Size = MAP_APPFONT ( 60 , 8 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "O~ld symbol set";
+ };
+ ComboBox 2
+ {
+ HelpID = "starmath:ComboBox:RID_SYMDEFINEDIALOG:2";
+ Pos = MAP_APPFONT ( 210 , 6 ) ;
+ Size = MAP_APPFONT ( 80 , 100 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ Control 1
+ {
+ HelpID = HID_SMA_CONTROL_FONTCHAR_VIEW ;
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 24 ) ;
+ Size = MAP_APPFONT ( 295 , 87 ) ;
+ TabStop = TRUE ;
+ Group = TRUE ;
+ };
+ FixedText 9
+ {
+ Pos = MAP_APPFONT ( 6 , 118 ) ;
+ Size = MAP_APPFONT ( 71 , 8 ) ;
+ Left = TRUE ;
+ Text [ en-US ] = "~Symbol";
+ };
+ ComboBox 4
+ {
+ HelpID = "starmath:ComboBox:RID_SYMDEFINEDIALOG:4";
+ Pos = MAP_APPFONT ( 80 , 115 ) ;
+ Size = MAP_APPFONT ( 100 , 100 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ FixedText 10
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 133 ) ;
+ Size = MAP_APPFONT ( 71 , 8 ) ;
+ Text [ en-US ] = "Symbol s~et";
+ };
+ ComboBox 5
+ {
+ HelpID = "starmath:ComboBox:RID_SYMDEFINEDIALOG:5";
+ Pos = MAP_APPFONT ( 80 , 130 ) ;
+ Size = MAP_APPFONT ( 100 , 100 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = TRUE ;
+ };
+ FixedText 3
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 148 ) ;
+ Size = MAP_APPFONT ( 71 , 8 ) ;
+ Text [ en-US ] = "~Font";
+ };
+ ListBox 1
+ {
+ HelpID = "starmath:ListBox:RID_SYMDEFINEDIALOG:1";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 80 , 145 ) ;
+ Size = MAP_APPFONT ( 100 , 100 ) ;
+ TabStop = TRUE ;
+ Sort = TRUE ;
+ DropDown = TRUE ;
+ };
+ FixedText FT_FONTS_SUBSET
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 163 ) ;
+ Size = MAP_APPFONT ( 71 , 8 ) ;
+ Text [ en-US ] = "~Subset";
+ };
+ ListBox LB_FONTS_SUBSET
+ {
+ HelpID = "starmath:ListBox:RID_SYMDEFINEDIALOG:LB_FONTS_SUBSET";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 80 , 160 ) ;
+ Size = MAP_APPFONT ( 100 , 100 ) ;
+ TabStop = TRUE ;
+ Sort = FALSE ;
+ DropDown = TRUE ;
+ };
+ FixedText 4
+ {
+ Left = TRUE ;
+ Pos = MAP_APPFONT ( 6 , 178 ) ;
+ Size = MAP_APPFONT ( 71 , 8 ) ;
+ Text [ en-US ] = "~Typeface";
+ };
+ ComboBox 3
+ {
+ HelpID = "starmath:ComboBox:RID_SYMDEFINEDIALOG:3";
+ Border = TRUE;
+ Pos = MAP_APPFONT ( 80 , 175 ) ;
+ Size = MAP_APPFONT ( 100 , 100 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+ Sort = FALSE ;
+ };
+ FixedText 5
+ {
+ Center = TRUE ;
+ Pos = MAP_APPFONT ( 303 , 130 ) ;
+ Size = MAP_APPFONT ( 54 , 8 ) ;
+ };
+ Control 2
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 310 , 140 ) ;
+ Size = MAP_APPFONT ( 40 , 40 ) ;
+ };
+ FixedText 6
+ {
+ Center = TRUE ;
+ Pos = MAP_APPFONT ( 303 , 182 ) ;
+ Size = MAP_APPFONT ( 54 , 8 ) ;
+ };
+ Image 1
+ {
+ ImageBitmap = Bitmap { File = "ar_right.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ };
+ FixedImage BMP_ARROW_RIGHT
+ {
+ Pos = MAP_APPFONT ( 252 , 142 ) ;
+ Size = MAP_APPFONT ( 36 , 36 ) ;
+
+ Fixed = Image
+ {
+ ImageBitmap = Bitmap { File = "ar_right.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ };
+ };
+ FixedText 7
+ {
+ Center = TRUE ;
+ Pos = MAP_APPFONT ( 183 , 130 ) ;
+ Size = MAP_APPFONT ( 54 , 9 ) ;
+ };
+ Control 3
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 190 , 140 ) ;
+ Size = MAP_APPFONT ( 40 , 40 ) ;
+ };
+ FixedText 8
+ {
+ Center = TRUE ;
+ Pos = MAP_APPFONT ( 183 , 182 ) ;
+ Size = MAP_APPFONT ( 54 , 8 ) ;
+ };
+ PushButton 1
+ {
+ HelpID = "starmath:PushButton:RID_SYMDEFINEDIALOG:1";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 305 , 195 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Add" ;
+ };
+ PushButton 2
+ {
+ HelpID = "starmath:PushButton:RID_SYMDEFINEDIALOG:2";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 245 , 195 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Modify" ;
+ };
+ PushButton 3
+ {
+ HelpID = "starmath:PushButton:RID_SYMDEFINEDIALOG:3";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( 185 , 195 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ Text [ en-US ] = "~Delete" ;
+ };
+ OKButton 1
+ {
+ Pos = MAP_APPFONT ( 310 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton 1
+ {
+ Pos = MAP_APPFONT ( 310 , 24 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ };
+};
+
+WarningBox RID_NOMATHTYPEFACEWARNING
+{
+ Message [ en-US ] = "The 'StarMath' font has not been installed.\nWithout this font %PRODUCTNAME Math cannot function correctly.\nPlease install this font and restart %PRODUCTNAME Math." ;
+};
+
+QueryBox RID_DEFAULTSAVEQUERY
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_YES ;
+ Message [ en-US ] = "Should the changes be saved as defaults?\n\nThese changes will apply for all new formulas." ;
+};
+
+String RID_FONTREGULAR
+{
+ Text [ en-US ] = "Standard" ;
+};
+String RID_FONTITALIC
+{
+ Text [ en-US ] = "Italic" ;
+};
+String RID_FONTBOLD
+{
+ Text [ en-US ] = "Bold" ;
+};
+String RID_APPLICATION
+{
+ Text = "StarMath" ;
+};
+String RID_OBJECTNAME
+{
+ Text = "SMath3" ;
+};
+String RID_UNDOEDITNAME
+{
+ Text = "Edit" ;
+};
+String RID_UNDOFORMATNAME
+{
+ Text = "Format" ;
+};
+String GID_FORMEL
+{
+ Text = "StarMath" ;
+};
+Menu RID_VIEWMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = SID_VIEW050 ;
+ HelpId = CMD_SID_VIEW050 ;
+ Text [ en-US ] = "~View 50%" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_VIEW100 ;
+ HelpId = CMD_SID_VIEW100 ;
+ Text [ en-US ] = "View ~100%" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_VIEW200 ;
+ HelpId = CMD_SID_VIEW200 ;
+ Text [ en-US ] = "View ~200%" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_ZOOMIN ;
+ HelpId = CMD_SID_ZOOMIN ;
+ Text [ en-US ] = "~Zoom In" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_ZOOMOUT ;
+ HelpId = CMD_SID_ZOOMOUT ;
+ Text [ en-US ] = "Zoom ~Out" ;
+ };
+ MenuItem
+ {
+ Identifier = SID_ADJUST ;
+ HelpId = CMD_SID_ADJUST ;
+ Text [ en-US ] = "~Display All" ;
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = SID_DRAW ;
+ HelpId = CMD_SID_DRAW ;
+ Text [ en-US ] = "U~pdate" ;
+ };
+ };
+};
+Menu RID_DISTANCEMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = WORKARROUND_1 ;
+ Text [ en-US ] = "Spacing" ;
+ };
+ MenuItem
+ {
+ Identifier = 2 ;
+ Text [ en-US ] = "Indexes" ;
+ };
+ MenuItem
+ {
+ Identifier = WORKARROUND_3 ;
+ Text [ en-US ] = "Fractions" ;
+ };
+ MenuItem
+ {
+ Identifier = 4 ;
+ Text [ en-US ] = "Fraction Bars" ;
+ };
+ MenuItem
+ {
+ Identifier = 5 ;
+ Text [ en-US ] = "Limits" ;
+ };
+ MenuItem
+ {
+ Identifier = 6 ;
+ Text [ en-US ] = "Brackets" ;
+ };
+ MenuItem
+ {
+ Identifier = 7 ;
+ Text [ en-US ] = "Matrices" ;
+ };
+ MenuItem
+ {
+ Identifier = 8 ;
+ Text [ en-US ] = "Symbols" ;
+ };
+ MenuItem
+ {
+ Identifier = 9 ;
+ Text [ en-US ] = "Operators" ;
+ };
+ MenuItem
+ {
+ Identifier = WORKARROUND_10 ;
+ Text [ en-US ] = "Borders";
+ };
+ };
+};
+
+Menu RID_FONTMENU
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = 1 ;
+ Text [ en-US ] = "Variables" ;
+ };
+ MenuItem
+ {
+ Identifier = 2 ;
+ Text [ en-US ] = "Functions" ;
+ };
+ MenuItem
+ {
+ Identifier = 3 ;
+ Text [ en-US ] = "Numbers" ;
+ };
+ MenuItem
+ {
+ Identifier = 4 ;
+ Text [ en-US ] = "Text" ;
+ };
+ MenuItem
+ {
+ Identifier = 5 ;
+ Text [ en-US ] = "Serif" ;
+ };
+ MenuItem
+ {
+ Identifier = 6 ;
+ Text [ en-US ] = "Sans" ;
+ };
+ MenuItem
+ {
+ Identifier = 7 ;
+ Text [ en-US ] = "Fixed" ;
+ };
+ };
+};
+
+#define CMDBOXWINDOW_TEXT \
+ Text [ en-US ] = "Commands" ; \
+
+DockingWindow RID_CMDBOXWINDOW\
+{
+ HelpId = HID_SMA_COMMAND_WIN ;
+ Moveable = TRUE ;
+ Closeable = FALSE ;
+ Sizeable = TRUE ;
+ OutputSize = TRUE ;
+ HideWhenDeactivate = FALSE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 292 , 94 ) ;
+ Dockable = TRUE ;
+ CMDBOXWINDOW_TEXT
+};
+
+
+String STR_CMDBOXWINDOW
+{
+ CMDBOXWINDOW_TEXT
+};
+
+String RID_DOCUMENTSTR
+{
+ Text [ en-US ] = "Formula" ;
+};
+
+String STR_STATSTR_READING
+{
+ Text [ en-US ] = "Loading document..." ;
+};
+
+String STR_STATSTR_WRITING
+{
+ Text [ en-US ] = "Saving document..." ;
+};
+
+
+String STR_MATH_DOCUMENT_FULLTYPE_CURRENT
+{
+ Text [ en-US ] = "%PRODUCTNAME %PRODUCTVERSION Formula";
+};
+
+String RID_SYMBOLFILESSTR
+{
+ Text [ en-US ] = "Symbol files (*.sms)" ;
+};
+
+String RID_ALLFILESSTR
+{
+ Text [ en-US ] = "All Files (*.*)" ;
+};
+
+String RID_ERR_IDENT
+{
+ Text [ en-US ] = "ERROR : " ;
+};
+
+String RID_ERR_UNKOWN
+{
+ Text [ en-US ] = "Unknown error occurred" ;
+};
+
+String RID_ERR_UNEXPECTEDCHARACTER
+{
+ Text [ en-US ] = "Unexpected character" ;
+};
+
+String RID_ERR_OVERFLOW
+{
+ Text [ en-US ] = "Formula entry too complex" ;
+};
+
+String RID_ERR_LGROUPEXPECTED
+{
+ Text [ en-US ] = "'{' expected" ;
+};
+
+String RID_ERR_RGROUPEXPECTED
+{
+ Text [ en-US ] = "'}' expected" ;
+};
+
+String RID_ERR_LBRACEEXPECTED
+{
+ Text [ en-US ] = "'(' expected" ;
+};
+
+String RID_ERR_RBRACEEXPECTED
+{
+ Text [ en-US ] = "')' expected" ;
+};
+
+String RID_ERR_FUNCEXPECTED
+{
+ Text [ en-US ] = "Function expected" ;
+};
+
+String RID_ERR_UNOPEREXPECTED
+{
+ Text [ en-US ] = "Unary operator expected" ;
+};
+
+String RID_ERR_BINOPEREXPECTED
+{
+ Text [ en-US ] = "Binary operator expected" ;
+};
+
+String RID_ERR_SYMBOLEXPECTED
+{
+ Text [ en-US ] = "Symbol expected" ;
+};
+
+String RID_ERR_IDENTEXPECTED
+{
+ Text [ en-US ] = "Identifier expected" ;
+};
+
+String RID_ERR_POUNDEXPECTED
+{
+ Text [ en-US ] = "'#' expected" ;
+};
+
+String RID_ERR_COLOREXPECTED
+{
+ Text [ en-US ] = "Color required" ;
+};
+
+String RID_ERR_LPARENTEXPECTED
+{
+ Text [ en-US ] = "Left limit expected" ;
+};
+
+String RID_ERR_RPARENTEXPECTED
+{
+ Text [ en-US ] = "Right limit expected" ;
+};
+
+String RID_ERR_RIGHTEXPECTED
+{
+ Text [ en-US ] = "'RIGHT' expected" ;
+};
+
+String RID_MATH_TOOLBOX
+{
+ Text [ en-US ] = "Main Toolbar" ;
+};
+
+StringArray RID_PRINTUIOPTIONS
+{
+ ItemList [en-US] =
+ {
+ < "%PRODUCTNAME %s"; >;
+ < "Contents"; >;
+ < "~Title"; >;
+ < "~Formula text"; >;
+ < "B~orders"; >;
+ < "Size"; >;
+ < "O~riginal size"; >;
+ < "Fit to ~page"; >;
+ < "~Scaling"; >;
+ };
+};
+
diff --git a/starmath/source/symbol.cxx b/starmath/source/symbol.cxx
new file mode 100644
index 000000000000..b0deeb4d93fe
--- /dev/null
+++ b/starmath/source/symbol.cxx
@@ -0,0 +1,338 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <osl/mutex.hxx>
+#include <ucbhelper/content.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+
+#include <map>
+#include <vector>
+#include <iterator>
+
+#include "symbol.hxx"
+#include "view.hxx"
+#include "utility.hxx"
+#include "dialog.hxx"
+#include "config.hxx"
+#include "cfgitem.hxx"
+#include "smmod.hxx"
+#include "starmath.hrc"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+
+
+/**************************************************************************/
+
+SmSym::SmSym() :
+ m_aName(C2S("unknown")),
+ m_aSetName(C2S("unknown")),
+ m_cChar('\0'),
+ m_bPredefined(false),
+ m_bDocSymbol(false)
+{
+ m_aExportName = m_aName;
+ m_aFace.SetTransparent(true);
+ m_aFace.SetAlign(ALIGN_BASELINE);
+}
+
+
+SmSym::SmSym(const SmSym& rSymbol)
+{
+ *this = rSymbol;
+}
+
+
+SmSym::SmSym(const String& rName, const Font& rFont, sal_UCS4 cChar,
+ const String& rSet, bool bIsPredefined)
+{
+ m_aName = m_aExportName = rName;
+
+ m_aFace = rFont;
+ m_aFace.SetTransparent(true);
+ m_aFace.SetAlign(ALIGN_BASELINE);
+
+ m_cChar = cChar;
+ m_aSetName = rSet;
+ m_bPredefined = bIsPredefined;
+ m_bDocSymbol = false;
+}
+
+
+SmSym& SmSym::operator = (const SmSym& rSymbol)
+{
+ m_aName = rSymbol.m_aName;
+ m_aExportName = rSymbol.m_aExportName;
+ m_cChar = rSymbol.m_cChar;
+ m_aFace = rSymbol.m_aFace;
+ m_aSetName = rSymbol.m_aSetName;
+ m_bPredefined = rSymbol.m_bPredefined;
+ m_bDocSymbol = rSymbol.m_bDocSymbol;
+
+ SmSymbolManager * pSymSetManager = &SM_MOD()->GetSymbolManager();
+ if (pSymSetManager)
+ pSymSetManager->SetModified(true);
+
+ return *this;
+}
+
+
+bool SmSym::IsEqualInUI( const SmSym& rSymbol ) const
+{
+ return m_aName == rSymbol.m_aName &&
+ m_aFace == rSymbol.m_aFace &&
+ m_cChar == rSymbol.m_cChar;
+}
+
+/**************************************************************************/
+
+void SmSymbolManager::SFX_NOTIFY(SfxBroadcaster& /*rBC*/, const TypeId& rBCType,
+ const SfxHint& /*rHint*/, const TypeId& rHintType)
+{
+}
+
+
+void SmSymbolManager::Init()
+{
+ SmModule *pp = SM_MOD();
+ StartListening(*pp->GetConfig());
+}
+
+
+void SmSymbolManager::Exit()
+{
+ SmModule *pp = SM_MOD();
+ EndListening(*pp->GetConfig());
+}
+
+
+SmSymbolManager::SmSymbolManager()
+{
+ m_bModified = false;
+}
+
+
+SmSymbolManager::SmSymbolManager(const SmSymbolManager& rSymbolSetManager) :
+ SfxListener()
+{
+ m_aSymbols = rSymbolSetManager.m_aSymbols;
+ m_bModified = true;
+}
+
+
+SmSymbolManager::~SmSymbolManager()
+{
+}
+
+
+SmSymbolManager& SmSymbolManager::operator = (const SmSymbolManager& rSymbolSetManager)
+{
+ m_aSymbols = rSymbolSetManager.m_aSymbols;
+ m_bModified = true;
+ return *this;
+}
+
+
+SmSym *SmSymbolManager::GetSymbolByName(const String& rSymbolName)
+{
+ SmSym *pRes = NULL;
+ SymbolMap_t::iterator aIt( m_aSymbols.find( rSymbolName ) );
+ if (aIt != m_aSymbols.end())
+ pRes = &aIt->second;
+ return pRes;
+}
+
+
+const SymbolPtrVec_t SmSymbolManager::GetSymbols() const
+{
+ SymbolPtrVec_t aRes;
+ SymbolMap_t::const_iterator aIt( m_aSymbols.begin() );
+ for ( ; aIt != m_aSymbols.end(); ++aIt)
+ aRes.push_back( &aIt->second );
+// OSL_ENSURE( sSymbols.size() == m_aSymbols.size(), "number of symbols mismatch " );
+ return aRes;
+}
+
+
+bool SmSymbolManager::AddOrReplaceSymbol( const SmSym &rSymbol, bool bForceChange )
+{
+ bool bAdded = false;
+
+ const String aSymbolName( rSymbol.GetName() );
+ if (aSymbolName.Len() > 0 && rSymbol.GetSymbolSetName().Len() > 0)
+ {
+ const SmSym *pFound = GetSymbolByName( aSymbolName );
+ const bool bSymbolConflict = pFound && !pFound->IsEqualInUI( rSymbol );
+
+ // avoid having the same symbol name twice but with different symbols in use
+ if (!pFound || bForceChange)
+ {
+ m_aSymbols[ aSymbolName ] = rSymbol;
+ bAdded = true;
+ }
+ else if (pFound && !bForceChange && bSymbolConflict)
+ {
+ // TODO: to solve this a document owned symbol manager would be required ...
+ OSL_FAIL( "symbol conflict, different symbol with same name found!" );
+ // symbols in all formulas. A copy of the global one would be needed here
+ // and then the new symbol has to be forcefully applied. This would keep
+ // the current formula intact but will leave the set of symbols in the
+ // global symbol manager somewhat to chance.
+ }
+
+ OSL_ENSURE( bAdded, "failed to add symbol" );
+ if (bAdded)
+ m_bModified = true;
+ DBG_ASSERT( bAdded || (pFound && !bSymbolConflict), "AddOrReplaceSymbol: unresolved symbol conflict" );
+ }
+
+ return bAdded;
+}
+
+
+void SmSymbolManager::RemoveSymbol( const String & rSymbolName )
+{
+ if (rSymbolName.Len() > 0)
+ {
+ size_t nOldSize = m_aSymbols.size();
+ m_aSymbols.erase( rSymbolName );
+ m_bModified = nOldSize != m_aSymbols.size();
+ }
+}
+
+
+std::set< String > SmSymbolManager::GetSymbolSetNames() const
+{
+ std::set< String > aRes;
+ SymbolMap_t::const_iterator aIt( m_aSymbols.begin() );
+ for ( ; aIt != m_aSymbols.end(); ++aIt )
+ aRes.insert( aIt->second.GetSymbolSetName() );
+ return aRes;
+}
+
+
+const SymbolPtrVec_t SmSymbolManager::GetSymbolSet( const String& rSymbolSetName )
+{
+ SymbolPtrVec_t aRes;
+ if (rSymbolSetName.Len() > 0)
+ {
+ SymbolMap_t::const_iterator aIt( m_aSymbols.begin() );
+ for ( ; aIt != m_aSymbols.end(); ++aIt )
+ {
+ if (aIt->second.GetSymbolSetName() == rSymbolSetName)
+ aRes.push_back( &aIt->second );
+ }
+ }
+ return aRes;
+}
+
+
+void SmSymbolManager::Load()
+{
+ std::vector< SmSym > aSymbols;
+ SmMathConfig &rCfg = *SM_MOD()->GetConfig();
+ rCfg.GetSymbols( aSymbols );
+ size_t nSymbolCount = aSymbols.size();
+
+ m_aSymbols.clear();
+ for (size_t i = 0; i < nSymbolCount; ++i)
+ {
+ const SmSym &rSym = aSymbols[i];
+ OSL_ENSURE( rSym.GetName().Len() > 0, "symbol without name!" );
+ if (rSym.GetName().Len() > 0)
+ AddOrReplaceSymbol( rSym );
+ }
+ m_bModified = true;
+
+ if (0 == nSymbolCount)
+ {
+ OSL_FAIL( "no symbol set found" );
+ m_bModified = false;
+ }
+
+ // now add a %i... symbol to the 'iGreek' set for every symbol found in the 'Greek' set.
+ SmLocalizedSymbolData aLocalizedData;
+ const String aGreekSymbolSetName( aLocalizedData.GetUiSymbolSetName( A2OU("Greek") ) );
+ const SymbolPtrVec_t aGreekSymbols( GetSymbolSet( aGreekSymbolSetName ) );
+ String aSymbolSetName( (sal_Unicode) 'i' );
+ aSymbolSetName += aGreekSymbolSetName;
+ size_t nSymbols = aGreekSymbols.size();
+ for (size_t i = 0; i < nSymbols; ++i)
+ {
+ // make the new symbol a copy but with ITALIC_NORMAL, and add it to iGreek
+ const SmSym &rSym = *aGreekSymbols[i];
+ Font aFont( rSym.GetFace() );
+ OSL_ENSURE( aFont.GetItalic() == ITALIC_NONE, "expected Font with ITALIC_NONE, failed." );
+ aFont.SetItalic( ITALIC_NORMAL );
+ String aSymbolName( (sal_Unicode)'i' );
+ aSymbolName += rSym.GetName();
+ SmSym aSymbol( aSymbolName, aFont, rSym.GetCharacter(),
+ aSymbolSetName, true /*bIsPredefined*/ );
+
+ AddOrReplaceSymbol( aSymbol );
+ }
+}
+
+void SmSymbolManager::Save()
+{
+ if (m_bModified)
+ {
+ SmMathConfig &rCfg = *SM_MOD()->GetConfig();
+
+ // prepare to skip symbols from iGreek on saving
+ SmLocalizedSymbolData aLocalizedData;
+ String aSymbolSetName( (sal_Unicode) 'i' );
+ aSymbolSetName += aLocalizedData.GetUiSymbolSetName( A2OU("Greek") );
+
+ SymbolPtrVec_t aTmp( GetSymbols() );
+ std::vector< SmSym > aSymbols;
+ for (size_t i = 0; i < aTmp.size(); ++i)
+ {
+ // skip symbols from iGreek set since those symbols always get added
+ // by computational means in SmSymbolManager::Load
+ if (aTmp[i]->GetSymbolSetName() != aSymbolSetName)
+ aSymbols.push_back( *aTmp[i] );
+ }
+ rCfg.SetSymbols( aSymbols );
+
+ m_bModified = false;
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/symbol.src b/starmath/source/symbol.src
new file mode 100644
index 000000000000..7f8e15a15817
--- /dev/null
+++ b/starmath/source/symbol.src
@@ -0,0 +1,344 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <starmath.hrc>
+
+
+/////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////
+
+Resource RID_LOCALIZED_NAMES
+{
+ StringArray RID_FRENCH_50_NAMES
+ {
+ ItemList =
+ {
+ < "BETA" ; > ;
+ < "beta" ; > ;
+ < "ETA" ; > ;
+ < "eta" ; > ;
+ < "JOTA" ; > ;
+ < "jota" ; > ;
+ < "CHI" ; > ;
+ < "chi" ; > ;
+ < "MY" ; > ;
+ < "my" ; > ;
+ < "NY" ; > ;
+ < "ny" ; > ;
+ < "OMIKRON" ; > ;
+ < "omikron" ; > ;
+ < "OMEGA" ; > ;
+ < "omega" ; > ;
+ < "RHO" ; > ;
+ < "rho" ; > ;
+ < "THETA" ; > ;
+ < "theta" ; > ;
+ < "YPSILON" ; > ;
+ < "ypsilon" ; > ;
+ < "ZETA" ; > ;
+ < "zeta" ; > ;
+ < "varrho" ; > ;
+ < "vartheta" ; > ;
+ };
+ };
+ StringArray RID_FRENCH_60_NAMES
+ {
+ ItemList =
+ {
+ < "BÊTA" ; > ;
+ < "bêta" ; > ;
+ < "ÊTA" ; > ;
+ < "êta" ; > ;
+ < "IOTA" ; > ;
+ < "iota" ; > ;
+ < "KHI" ; > ;
+ < "khi" ; > ;
+ < "MU" ; > ;
+ < "mu" ; > ;
+ < "NU" ; > ;
+ < "nu" ; > ;
+ < "OMICRON" ; > ;
+ < "omicron" ; > ;
+ < "OMÉGA" ; > ;
+ < "oméga" ; > ;
+ < "RHÔ" ; > ;
+ < "rhô" ; > ;
+ < "THÊTA" ; > ;
+ < "thêta" ; > ;
+ < "UPSILON" ; > ;
+ < "upsilon" ; > ;
+ < "ZÊTA" ; > ;
+ < "zêta" ; > ;
+ < "varrhô" ; > ;
+ < "varthêta" ; > ;
+ };
+ };
+ StringArray RID_ITALIAN_50_NAMES
+ {
+ ItemList =
+ {
+ < "nu" ; > ;
+ < "Nu" ; > ;
+ < "varrho" ; > ;
+ < "moltomaggioredi" ; > ;
+ < "indentico" ; > ;
+ < "nonelemento" ; > ;
+ < "moltoinferioredi" ; > ;
+ < "o" ; > ;
+ < "permille" ; > ;
+ < "tendentea" ; > ;
+ < "nonuguale" ; > ;
+ < "infinite" ; > ;
+ };
+ };
+ StringArray RID_ITALIAN_60_NAMES
+ {
+ ItemList =
+ {
+ < "ni" ; > ;
+ < "Ni" ; > ;
+ < "varro" ; > ;
+ < "molto.maggiore.di" ; > ;
+ < "identico" ; > ;
+ < "non.elemento" ; > ;
+ < "molto.minore.di" ; > ;
+ < "oppure" ; > ;
+ < "per.mille" ; > ;
+ < "tendente.a" ; > ;
+ < "non.uguale" ; > ;
+ < "infinito" ; > ;
+ };
+ };
+ StringArray RID_SWEDISH_50_NAMES
+ {
+ ItemList =
+ {
+ < "iota" ; > ;
+ < "IOTA" ; > ;
+ < "xi" ; > ;
+ < "XI" ; > ;
+ < "rho" ; > ;
+ < "RHO" ; > ;
+ < "element" ; > ;
+ };
+ };
+ StringArray RID_SWEDISH_60_NAMES
+ {
+ ItemList =
+ {
+ < "jota" ; > ;
+ < "JOTA" ; > ;
+ < "ksi" ; > ;
+ < "KSI" ; > ;
+ < "ro" ; > ;
+ < "RO" ; > ;
+ < "tillhör" ; > ;
+ };
+ };
+ StringArray RID_SPANISH_50_NAMES
+ {
+ ItemList =
+ {
+ < "distino" ; > ;
+ < "muchomenos" ; > ;
+ < "pertenece" ; > ;
+ < "nopertenece" ; > ;
+ };
+ };
+ StringArray RID_SPANISH_60_NAMES
+ {
+ ItemList =
+ {
+ < "diferente" ; > ;
+ < "muchomenor" ; > ;
+ < "elemento" ; > ;
+ < "sinelemento" ; > ;
+ };
+ };
+ StringArray RID_EXPORT_SYMBOLSET_NAMES
+ {
+ ItemList =
+ {
+ < "Greek" ; > ;
+ < "Special" ; > ;
+ };
+ };
+ StringArray RID_UI_SYMBOLSET_NAMES
+ {
+ ItemList [ en-US ] =
+ {
+ < "Greek" ; > ;
+ < "Special" ; > ;
+ };
+ };
+ StringArray RID_EXPORT_SYMBOL_NAMES
+ {
+ ItemList =
+ {
+ < "alpha" ; > ;
+ < "ALPHA" ; > ;
+ < "beta" ; > ;
+ < "BETA" ; > ;
+ < "gamma" ; > ;
+ < "GAMMA" ; > ;
+ < "delta" ; > ;
+ < "DELTA" ; > ;
+ < "epsilon" ; > ;
+ < "EPSILON" ; > ;
+ < "zeta" ; > ;
+ < "ZETA" ; > ;
+ < "eta" ; > ;
+ < "ETA" ; > ;
+ < "theta" ; > ;
+ < "THETA" ; > ;
+ < "iota" ; > ;
+ < "IOTA" ; > ;
+ < "kappa" ; > ;
+ < "KAPPA" ; > ;
+ < "lambda" ; > ;
+ < "LAMBDA" ; > ;
+ < "mu" ; > ;
+ < "MU" ; > ;
+ < "nu" ; > ;
+ < "NU" ; > ;
+ < "xi" ; > ;
+ < "XI" ; > ;
+ < "omicron" ; > ;
+ < "OMICRON" ; > ;
+ < "pi" ; > ;
+ < "PI" ; > ;
+ < "rho" ; > ;
+ < "RHO" ; > ;
+ < "sigma" ; > ;
+ < "SIGMA" ; > ;
+ < "tau" ; > ;
+ < "TAU" ; > ;
+ < "upsilon" ; > ;
+ < "UPSILON" ; > ;
+ < "phi" ; > ;
+ < "PHI" ; > ;
+ < "chi" ; > ;
+ < "CHI" ; > ;
+ < "psi" ; > ;
+ < "PSI" ; > ;
+ < "omega" ; > ;
+ < "OMEGA" ; > ;
+ < "varepsilon" ; > ;
+ < "vartheta" ; > ;
+ < "varpi" ; > ;
+ < "varrho" ; > ;
+ < "varsigma" ; > ;
+ < "varphi" ; > ;
+ < "element" ; > ;
+ < "noelement" ; > ;
+ < "strictlylessthan" ; > ;
+ < "strictlygreaterthan" ; > ;
+ < "notequal" ; > ;
+ < "identical" ; > ;
+ < "tendto" ; > ;
+ < "infinite" ; > ;
+ < "angle" ; > ;
+ < "perthousand" ; > ;
+ < "and" ; > ;
+ < "or" ; > ;
+ };
+ };
+ StringArray RID_UI_SYMBOL_NAMES
+ {
+ ItemList [ en-US ] =
+ {
+ < "alpha" ; > ;
+ < "ALPHA" ; > ;
+ < "beta" ; > ;
+ < "BETA" ; > ;
+ < "gamma" ; > ;
+ < "GAMMA" ; > ;
+ < "delta" ; > ;
+ < "DELTA" ; > ;
+ < "epsilon" ; > ;
+ < "EPSILON" ; > ;
+ < "zeta" ; > ;
+ < "ZETA" ; > ;
+ < "eta" ; > ;
+ < "ETA" ; > ;
+ < "theta" ; > ;
+ < "THETA" ; > ;
+ < "iota" ; > ;
+ < "IOTA" ; > ;
+ < "kappa" ; > ;
+ < "KAPPA" ; > ;
+ < "lambda" ; > ;
+ < "LAMBDA" ; > ;
+ < "mu" ; > ;
+ < "MU" ; > ;
+ < "nu" ; > ;
+ < "NU" ; > ;
+ < "xi" ; > ;
+ < "XI" ; > ;
+ < "omicron" ; > ;
+ < "OMICRON" ; > ;
+ < "pi" ; > ;
+ < "PI" ; > ;
+ < "rho" ; > ;
+ < "RHO" ; > ;
+ < "sigma" ; > ;
+ < "SIGMA" ; > ;
+ < "tau" ; > ;
+ < "TAU" ; > ;
+ < "upsilon" ; > ;
+ < "UPSILON" ; > ;
+ < "phi" ; > ;
+ < "PHI" ; > ;
+ < "chi" ; > ;
+ < "CHI" ; > ;
+ < "psi" ; > ;
+ < "PSI" ; > ;
+ < "omega" ; > ;
+ < "OMEGA" ; > ;
+ < "varepsilon" ; > ;
+ < "vartheta" ; > ;
+ < "varpi" ; > ;
+ < "varrho" ; > ;
+ < "varsigma" ; > ;
+ < "varphi" ; > ;
+ < "element" ; > ;
+ < "noelement" ; > ;
+ < "strictlylessthan" ; > ;
+ < "strictlygreaterthan" ; > ;
+ < "notequal" ; > ;
+ < "identical" ; > ;
+ < "tendto" ; > ;
+ < "infinite" ; > ;
+ < "angle" ; > ;
+ < "perthousand" ; > ;
+ < "and" ; > ;
+ < "or" ; > ;
+ };
+ };
+};
diff --git a/starmath/source/toolbox.cxx b/starmath/source/toolbox.cxx
new file mode 100644
index 000000000000..68e15f6079d0
--- /dev/null
+++ b/starmath/source/toolbox.cxx
@@ -0,0 +1,383 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <rtl/logfile.hxx>
+#include <svl/eitem.hxx>
+#include <sfx2/app.hxx>
+#include <svl/intitem.hxx>
+#include <svtools/imgdef.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/imgmgr.hxx>
+#include <vcl/wrkwin.hxx>
+#include "toolbox.hxx"
+#include "starmath.hrc"
+#include "toolbox.hrc"
+#include "view.hxx"
+
+
+////////////////////////////////////////////////////////////
+
+static sal_uInt16 GetImageListRID( sal_uInt16 nCategoryRID )
+{
+ sal_uInt16 nRes = 0xFFFF;
+ switch (nCategoryRID)
+ {
+ case RID_UNBINOPS_CAT : nRes = RID_IL_UNBINOPS; break;
+ case RID_RELATIONS_CAT : nRes = RID_IL_RELATIONS; break;
+ case RID_SETOPERATIONS_CAT : nRes = RID_IL_SETOPERATIONS; break;
+ case RID_FUNCTIONS_CAT : nRes = RID_IL_FUNCTIONS; break;
+ case RID_OPERATORS_CAT : nRes = RID_IL_OPERATORS; break;
+ case RID_ATTRIBUTES_CAT : nRes = RID_IL_ATTRIBUTES; break;
+ case RID_BRACKETS_CAT : nRes = RID_IL_BRACKETS; break;
+ case RID_FORMAT_CAT : nRes = RID_IL_FORMAT; break;
+ case RID_MISC_CAT : nRes = RID_IL_MISC; break;
+ default :
+ OSL_FAIL( "unkown category" );
+ }
+ return nRes;
+}
+
+
+static sal_Int16 GetToolBoxCategoriesIndex( sal_uInt16 nCategoryRID )
+{
+ sal_Int16 nIdx = -1;
+ switch (nCategoryRID)
+ {
+ case RID_UNBINOPS_CAT : nIdx = 0; break;
+ case RID_RELATIONS_CAT : nIdx = 1; break;
+ case RID_SETOPERATIONS_CAT : nIdx = 2; break;
+ case RID_FUNCTIONS_CAT : nIdx = 3; break;
+ case RID_OPERATORS_CAT : nIdx = 4; break;
+ case RID_ATTRIBUTES_CAT : nIdx = 5; break;
+ case RID_BRACKETS_CAT : nIdx = 6; break;
+ case RID_FORMAT_CAT : nIdx = 7; break;
+ case RID_MISC_CAT : nIdx = 8; break;
+ default:
+ ;
+ }
+ return nIdx;
+}
+
+
+static sal_uInt16 GetCategoryRID( sal_uInt16 nResId )
+{
+ sal_uInt16 nRes = 0xFFFF;
+ switch (nResId)
+ {
+ case RID_IL_UNBINOPS : nRes = RID_UNBINOPS_CAT; break;
+ case RID_IL_RELATIONS : nRes = RID_RELATIONS_CAT; break;
+ case RID_IL_SETOPERATIONS : nRes = RID_SETOPERATIONS_CAT; break;
+ case RID_IL_FUNCTIONS : nRes = RID_FUNCTIONS_CAT; break;
+ case RID_IL_OPERATORS : nRes = RID_OPERATORS_CAT; break;
+ case RID_IL_ATTRIBUTES : nRes = RID_ATTRIBUTES_CAT; break;
+ case RID_IL_BRACKETS : nRes = RID_BRACKETS_CAT; break;
+ case RID_IL_FORMAT : nRes = RID_FORMAT_CAT; break;
+ case RID_IL_MISC : nRes = RID_MISC_CAT; break;
+ default :
+ if (nResId != RID_IL_CATALOG)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OSL_FAIL( "unkown category" );
+#endif
+ }
+ }
+ return nRes;
+}
+
+
+////////////////////////////////////////////////////////////
+
+
+SmToolBoxWindow::SmToolBoxWindow(SfxBindings *pTmpBindings,
+ SfxChildWindow *pChildWindow,
+ Window *pParent) :
+ SfxFloatingWindow(pTmpBindings, pChildWindow, pParent, SmResId(RID_TOOLBOXWINDOW)),
+ aToolBoxCat(this, SmResId(TOOLBOX_CATALOG)),
+ aToolBoxCat_Delim(this, SmResId( FL_TOOLBOX_CAT_DELIM ))
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmToolBoxWindow::SmToolBoxWindow" );
+
+ // allow for cursor travelling between toolbox and sub-categories
+ SetStyle( GetStyle() | WB_DIALOGCONTROL );
+
+ nActiveCategoryRID = USHRT_MAX;
+
+ aToolBoxCat.SetClickHdl(LINK(this, SmToolBoxWindow, CategoryClickHdl));
+
+ sal_uInt16 i;
+ for (i = 0; i < NUM_TBX_CATEGORIES; ++i)
+ {
+ ToolBox *pBox = new ToolBox(this, SmResId( TOOLBOX_CAT_A + i ));
+ vToolBoxCategories[i] = pBox;
+ pBox->SetSelectHdl(LINK(this, SmToolBoxWindow, CmdSelectHdl));
+ }
+ pToolBoxCmd = vToolBoxCategories[0];
+
+ for (i = 0; i <= NUM_TBX_CATEGORIES; ++i)
+ aImageLists [i] = 0;
+
+ FreeResource();
+}
+
+SmToolBoxWindow::~SmToolBoxWindow()
+{
+ int i;
+ for (i = 0; i < NUM_TBX_CATEGORIES; ++i)
+ {
+ ToolBox *pBox = vToolBoxCategories[i];
+ delete pBox;
+ }
+ for (i = 0; i < NUM_TBX_CATEGORIES + 1; ++i)
+ delete aImageLists[i];
+}
+
+
+SmViewShell * SmToolBoxWindow::GetView()
+{
+ SfxViewShell *pView = GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
+ return PTR_CAST(SmViewShell, pView);
+}
+
+
+const ImageList * SmToolBoxWindow::GetImageList( sal_uInt16 nResId )
+{
+ // creates the image list via its resource id and stores that
+ // list for later use in the respective array.
+
+ const ImageList *pIL = 0;
+
+ // get index to use
+ sal_uInt16 nCategoryRID = GetCategoryRID( nResId );
+ sal_Int16 nIndex = GetToolBoxCategoriesIndex( nCategoryRID );
+ if (nIndex == -1 && (nResId == RID_IL_CATALOG))
+ nIndex = NUM_TBX_CATEGORIES;
+
+ if (nIndex >= 0)
+ {
+ ImageList **pImgList = aImageLists;
+ if (!pImgList[ nIndex ])
+ pImgList[ nIndex ] = new ImageList( SmResId(nResId) );
+ pIL = pImgList[ nIndex ];
+ }
+
+ OSL_ENSURE( pIL, "image list not found!" );
+ return pIL;
+}
+
+
+void SmToolBoxWindow::ApplyImageLists( sal_uInt16 nCategoryRID )
+{
+ // set image list for toolbox 'catalog'
+ const ImageList *pImageList = GetImageList( RID_IL_CATALOG );
+ OSL_ENSURE( pImageList, "image list missing" );
+ if (pImageList)
+ aToolBoxCat.SetImageList( *pImageList );
+
+ // set image list for active (visible) category of 'catalog'
+ sal_Int16 nIdx = GetToolBoxCategoriesIndex( nCategoryRID );
+ sal_uInt16 nResId = GetImageListRID( nCategoryRID );
+ pImageList = GetImageList( nResId );
+ OSL_ENSURE( pImageList && nIdx >= 0, "image list or index missing" );
+ if (pImageList && nIdx >= 0)
+ vToolBoxCategories[ nIdx ]->SetImageList( *pImageList );
+}
+
+void SmToolBoxWindow::DataChanged( const DataChangedEvent &rEvt )
+{
+ if ( (rEvt.GetType() == DATACHANGED_SETTINGS) && (rEvt.GetFlags() & SETTINGS_STYLE) )
+ ApplyImageLists( nActiveCategoryRID );
+
+ SfxFloatingWindow::DataChanged( rEvt );
+}
+
+void SmToolBoxWindow::StateChanged( StateChangedType nStateChange )
+{
+ static bool bSetPosition = true;
+ if (STATE_CHANGE_INITSHOW == nStateChange)
+ {
+ SetCategory( nActiveCategoryRID == USHRT_MAX ? RID_UNBINOPS_CAT : nActiveCategoryRID );
+
+ // calculate initial position to be used after creation of the window...
+ AdjustPosSize( bSetPosition );
+ bSetPosition = false;
+ }
+ //... otherwise the base class will remember the last position of the window
+ SfxFloatingWindow::StateChanged( nStateChange );
+}
+
+
+void SmToolBoxWindow::AdjustPosSize( bool bSetPos )
+{
+ Size aCatSize( aToolBoxCat.CalcWindowSizePixel( 2 ) );
+ Size aCmdSize( pToolBoxCmd->CalcWindowSizePixel( 5 /* see nLines in SetCategory*/ ) );
+ OSL_ENSURE( aCatSize.Width() == aCmdSize.Width(), "width mismatch" );
+
+ // catalog settings
+ aToolBoxCat.SetPosPixel( Point(0, 3) );
+ aToolBoxCat.SetSizePixel( aCatSize );
+ // settings for catalog / category delimiter
+ Point aP( aToolBoxCat_Delim.GetPosPixel() );
+ aP.X() = 0;
+ aToolBoxCat_Delim.SetPosPixel( aP );
+ aToolBoxCat_Delim.SetSizePixel( Size( aCatSize.Width(), aToolBoxCat_Delim.GetSizePixel().Height() ) );
+ // category settings
+ aP.Y() += aToolBoxCat_Delim.GetSizePixel().Height();
+ for (int i = 0; i < NUM_TBX_CATEGORIES; ++i)
+ {
+ vToolBoxCategories[i]->SetPosPixel( aP );
+ vToolBoxCategories[i]->SetSizePixel( aCmdSize );
+ }
+ // main window settings
+ Size aWndSize ( aCatSize.Width(), pToolBoxCmd->GetPosPixel().Y() + pToolBoxCmd->GetSizePixel().Height() + 3);
+ SetOutputSizePixel( aWndSize );
+
+ if (bSetPos)
+ {
+ SmViewShell *pView = GetView();
+ OSL_ENSURE( pView, "view shell missing" );
+ Point aPos( 50, 75 );
+ if (pView)
+ {
+ SmGraphicWindow &rWin = pView->GetGraphicWindow();
+ aPos = Point( rWin.OutputToScreenPixel(
+ Point( rWin.GetSizePixel().Width() - aWndSize.Width(), 0) ) );
+ }
+ if (aPos.X() < 0)
+ aPos.X() = 0;
+ if (aPos.Y() < 0)
+ aPos.Y() = 0;
+ SetPosPixel( aPos );
+ }
+}
+
+
+sal_Bool SmToolBoxWindow::Close()
+{
+ SmViewShell *pViewSh = GetView();
+ if (pViewSh)
+ pViewSh->GetViewFrame()->GetDispatcher()->Execute(
+ SID_TOOLBOX, SFX_CALLMODE_STANDARD,
+ new SfxBoolItem(SID_TOOLBOX, false), 0L);
+ return true;
+}
+
+void SmToolBoxWindow::GetFocus()
+{
+ // give focus to category toolbox
+ // (allow for cursor travelling when a category is selected with the mouse)
+ aToolBoxCat.GrabFocus();
+}
+
+void SmToolBoxWindow::SetCategory(sal_uInt16 nCategoryRID)
+{
+ if (nCategoryRID != nActiveCategoryRID)
+ ApplyImageLists( nCategoryRID );
+
+ sal_uInt16 nLines;
+ // check for valid resource id
+ switch (nCategoryRID)
+ {
+ case RID_UNBINOPS_CAT : nLines = 4; break;
+ case RID_RELATIONS_CAT: nLines = 5; break;
+ case RID_SETOPERATIONS_CAT: nLines = 5; break;
+ case RID_FUNCTIONS_CAT: nLines = 5; break;
+ case RID_OPERATORS_CAT: nLines = 3; break;
+ case RID_ATTRIBUTES_CAT: nLines = 5; break;
+ case RID_MISC_CAT: nLines = 4; break;
+ case RID_BRACKETS_CAT: nLines = 5; break;
+ case RID_FORMAT_CAT: nLines = 3; break;
+ default:
+ // nothing to be done
+ return;
+ }
+
+ pToolBoxCmd->Hide();
+
+ sal_Int16 nIdx = GetToolBoxCategoriesIndex( nCategoryRID );
+ OSL_ENSURE( nIdx >= 0, "unkown category" );
+ if (nIdx >= 0)
+ pToolBoxCmd = vToolBoxCategories[nIdx];
+
+ // calculate actual size of window to use
+ Size aCatSize( aToolBoxCat.CalcWindowSizePixel( 2 ) );
+ Size aCmdSize( pToolBoxCmd->CalcWindowSizePixel( nLines ) );
+ OSL_ENSURE( aCatSize.Width() == aCmdSize.Width(), "width mismatch" );
+ // main window settings
+ Size aWndSize ( aCatSize.Width(), pToolBoxCmd->GetPosPixel().Y() + aCmdSize.Height() + 3);
+ SetOutputSizePixel( aWndSize );
+
+ if (nActiveCategoryRID)
+ aToolBoxCat.CheckItem(nActiveCategoryRID, false);
+ nActiveCategoryRID = nCategoryRID;
+ aToolBoxCat.CheckItem(nActiveCategoryRID, true);
+
+ pToolBoxCmd->Show();
+}
+
+
+IMPL_LINK( SmToolBoxWindow, CategoryClickHdl, ToolBox*, pToolBox)
+{
+ int nItemId = pToolBox->GetCurItemId();
+ if (nItemId != 0)
+ SetCategory( sal::static_int_cast< sal_uInt16 >(nItemId) );
+ return 0;
+}
+
+
+IMPL_LINK( SmToolBoxWindow, CmdSelectHdl, ToolBox*, pToolBox)
+{
+ SmViewShell *pViewSh = GetView();
+ if (pViewSh)
+ pViewSh->GetViewFrame()->GetDispatcher()->Execute(
+ SID_INSERTCOMMAND, SFX_CALLMODE_STANDARD,
+ new SfxInt16Item(SID_INSERTCOMMAND, pToolBox->GetCurItemId()), 0L);
+ return 0;
+}
+
+
+/**************************************************************************/
+
+SFX_IMPL_FLOATINGWINDOW(SmToolBoxWrapper, SID_TOOLBOXWINDOW);
+
+SmToolBoxWrapper::SmToolBoxWrapper(Window *pParentWindow,
+ sal_uInt16 nId, SfxBindings* pBindings,
+ SfxChildWinInfo *pInfo) :
+ SfxChildWindow(pParentWindow, nId)
+{
+ eChildAlignment = SFX_ALIGN_NOALIGNMENT;
+
+ pWindow = new SmToolBoxWindow(pBindings, this, pParentWindow);
+ ((SfxFloatingWindow *)pWindow)->Initialize(pInfo);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/toolbox.hrc b/starmath/source/toolbox.hrc
new file mode 100755
index 000000000000..29adff303a3e
--- /dev/null
+++ b/starmath/source/toolbox.hrc
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _TOOLBOX_HRC_
+#define _TOOLBOX_HRC_
+
+#define FL_TOOLBOX_CAT_DELIM 1
+#define TOOLBOX_CATALOG 10
+#define TOOLBOX_CAT_A 11
+#define TOOLBOX_CAT_B 12
+#define TOOLBOX_CAT_C 13
+#define TOOLBOX_CAT_D 14
+#define TOOLBOX_CAT_E 15
+#define TOOLBOX_CAT_F 16
+#define TOOLBOX_CAT_G 17
+#define TOOLBOX_CAT_H 18
+#define TOOLBOX_CAT_I 19
+
+#define NUM_TBX_CATEGORIES (TOOLBOX_CAT_I - TOOLBOX_CAT_A + 1)
+
+#endif
+
diff --git a/starmath/source/toolbox.src b/starmath/source/toolbox.src
new file mode 100644
index 000000000000..07e728f1e6cb
--- /dev/null
+++ b/starmath/source/toolbox.src
@@ -0,0 +1,1777 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#include <sfx2/sfx.hrc>
+#include <svx/globlmn.hrc>
+#include "starmath.hrc"
+#include "toolbox.hrc"
+
+#define IMAGE_STDBTN_COLOR Color { Red = 0xff00; Green = 0x0000; Blue = 0xff00; }
+#define IMAGE_STDBTN_COLOR_HC IMAGE_STDBTN_COLOR
+
+
+FloatingWindow RID_TOOLBOXWINDOW
+{
+ HelpId = HID_SMA_OPERATOR_WIN ;
+ Border = TRUE ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ Hide = TRUE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 0 , 0 ) ; // to be calculated programmatically
+ Text [ en-US ] = "Elements" ;
+
+ ToolBox TOOLBOX_CATALOG
+ {
+ // main menu of selection-window
+ HelpId = HID_SMA_SELECTION_TBX ;
+ Pos = MAP_APPFONT ( 0 , 0 ) ;
+ Size = MAP_APPFONT ( 65 , 38 ) ;
+ SVLook = TRUE ;
+ LineCount = 2 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_UNBINOPS_CAT ;
+ HelpId = HID_SMA_UNBINOPS_CAT ;
+ Text [ en-US ] = "Unary/Binary Operators" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_RELATIONS_CAT ;
+ HelpId = HID_SMA_RELATIONS_CAT ;
+ Text [ en-US ] = "Relations" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SETOPERATIONS_CAT ;
+ HelpId = HID_SMA_SETOPERATIONS_CAT ;
+ Text [ en-US ] = "Set Operations" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_FUNCTIONS_CAT ;
+ HelpId = HID_SMA_FUNCTIONS_CAT ;
+ Text [ en-US ] = "Functions" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_OPERATORS_CAT ;
+ HelpId = HID_SMA_OPERATORS_CAT ;
+ Text [ en-US ] = "Operators" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ATTRIBUTES_CAT ;
+ HelpId = HID_SMA_ATTRIBUTES_CAT ;
+ Text [ en-US ] = "Attributes" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_MISC_CAT ;
+ HelpId = HID_SMA_MISC_CAT ;
+ Text [ en-US ] = "Others";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_BRACKETS_CAT ;
+ HelpId = HID_SMA_BRACKETS_CAT ;
+ Text [ en-US ] = "Brackets" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_FORMAT_CAT ;
+ HelpId = HID_SMA_FORMAT_CAT ;
+ Text [ en-US ] = "Formats" ;
+ };
+ };
+ };
+
+ FixedLine FL_TOOLBOX_CAT_DELIM
+ {
+ Pos = MAP_APPFONT ( 0 , 44 ) ;
+ Size = MAP_APPFONT ( 65 , 8 ) ;
+ };
+
+ ToolBox TOOLBOX_CAT_A
+ {
+ // unary/binary operators
+ HelpId = HID_SMA_UNBINOPS_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 4 ;
+
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_PLUSX ;
+ HelpId = HID_SMA_PLUSX ;
+ Text [ en-US ] = "+ Sign" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_MINUSX ;
+ HelpId = HID_SMA_MINUSX ;
+ Text [ en-US ] = "- Sign" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_PLUSMINUSX ;
+ HelpId = HID_SMA_PLUSMINUSX ;
+ Text [ en-US ] = "+- Sign" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_MINUSPLUSX ;
+ HelpId = HID_SMA_MINUSPLUSX ;
+ Text [ en-US ] = "-+ Sign" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_NEGX ;
+ HelpId = HID_SMA_NEGX ;
+ Text [ en-US ] = "Boolean NOT" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XPLUSY ;
+ HelpId = HID_SMA_XPLUSY ;
+ Text [ en-US ] = "Addition +" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XCDOTY ;
+ HelpId = HID_SMA_XCDOTY ;
+ Text [ en-US ] = "Multiplication (Dot )" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XTIMESY ;
+ HelpId = HID_SMA_XTIMESY ;
+ Text [ en-US ] = "Multiplication (x)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSYMTIMESY ;
+ HelpId = HID_SMA_XSYMTIMESY ;
+ Text [ en-US ] = "Multiplication (*)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XANDY ;
+ HelpId = HID_SMA_XANDY ;
+ Text [ en-US ] = "Boolean AND" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XMINUSY ;
+ HelpId = HID_SMA_XMINUSY ;
+ Text [ en-US ] = "Subtraction -" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XOVERY ;
+ HelpId = HID_SMA_XOVERY ;
+ Text [ en-US ] = "Division (Fraction)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XDIVY ;
+ HelpId = HID_SMA_XDIVY ;
+ Text [ en-US ] = "Division (÷)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSYMDIVIDEY ;
+ HelpId = HID_SMA_XSYMDIVIDEY ;
+ Text [ en-US ] = "Division (Slash)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XORY ;
+ HelpId = HID_SMA_XORY ;
+ Text [ en-US ] = "Boolean OR" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XCIRCY ;
+ HelpId = HID_SMA_XCIRCY ;
+ Text [ en-US ] = "Concatenate";
+ };
+ };
+ };
+
+ ToolBox TOOLBOX_CAT_B
+ {
+ // relations
+ HelpId = HID_SMA_RELATIONS_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 5 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_XEQY ;
+ HelpId = HID_SMA_XEQY ;
+ Text [ en-US ] = "Is Equal" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XNEQY ;
+ HelpId = HID_SMA_XNEQY ;
+ Text [ en-US ] = "Is Not Equal" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XAPPROXY ;
+ HelpId = HID_SMA_XAPPROXY ;
+ Text [ en-US ] = "Is Approximately Equal" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XDIVIDESY ;
+ HelpId = HID_SMA_XDIVIDESY ;
+ Text [ en-US ] = "Divides";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XNDIVIDESY ;
+ HelpId = HID_SMA_XNDIVIDESY ;
+ Text [ en-US ] = "Does Not Divide";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XLTY ;
+ HelpId = HID_SMA_XLTY ;
+ Text [ en-US ] = "Is Less Than" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XGTY ;
+ HelpId = HID_SMA_XGTY ;
+ Text [ en-US ] = "Is Greater Than" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSIMEQY ;
+ HelpId = HID_SMA_XSIMEQY ;
+ /* ### ACHTUNG: Neuer Text in Resource? ist �hnlich oder gleich : ist �hnlich oder glech */
+ Text [ en-US ] = "Is Similar Or Equal" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XPARALLELY ;
+ HelpId = HID_SMA_XPARALLELY ;
+ Text [ en-US ] = "Is Parallel To" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XORTHOY ;
+ HelpId = HID_SMA_XORTHOY ;
+ Text [ en-US ] = "Is Orthogonal To" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XLESLANTY ;
+ HelpId = HID_SMA_XLESLANTY ;
+ Text [ en-US ] = "Is Less Than Or Equal To" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XGESLANTY ;
+ HelpId = HID_SMA_XGESLANTY ;
+ Text [ en-US ] = "Is Greater Than Or Equal To" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSIMY ;
+ HelpId = HID_SMA_XSIMY ;
+ Text [ en-US ] = "Is Similar To" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XEQUIVY ;
+ HelpId = HID_SMA_XEQUIVY ;
+ Text [ en-US ] = "Is Congruent To" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XLEY ;
+ HelpId = HID_SMA_XLEY ;
+ Text [ en-US ] = "Is Less Than Or Equal To" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XGEY ;
+ HelpId = HID_SMA_XGEY ;
+ Text [ en-US ] = "Is Greater Than Or Equal To" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XPROPY ;
+ HelpId = HID_SMA_XPROPY ;
+ Text [ en-US ] = "Is Proportional To" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XTOWARDY ;
+ HelpId = HID_SMA_XTOWARDY ;
+ Text [ en-US ] = "Toward" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DLARROW ;
+ HelpId = HID_SMA_DLARROW ;
+ Text [ en-US ] = "Double Arrow Left";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DLRARROW ;
+ HelpId = HID_SMA_DLRARROW ;
+ Text [ en-US ] = "Double Arrow Left And Right";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DRARROW ;
+ HelpId = HID_SMA_DRARROW ;
+ Text [ en-US ] = "Double Arrow Right";
+ };
+ };
+ };
+
+ ToolBox TOOLBOX_CAT_C
+ {
+ // set operations
+ HelpId = HID_SMA_SETOPERATIONS_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 5 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_XINY ;
+ HelpId = HID_SMA_XINY ;
+ Text [ en-US ] = "Is In" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XNOTINY ;
+ HelpId = HID_SMA_XNOTINY ;
+ Text [ en-US ] = "Is Not In" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XOWNSY ;
+ HelpId = HID_SMA_XOWNSY ;
+ Text [ en-US ] = "Owns" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_EMPTYSET ;
+ HelpId = HID_SMA_EMPTYSET ;
+ Text [ en-US ] = "Empty Set";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XINTERSECTIONY ;
+ HelpId = HID_SMA_XINTERSECTIONY ;
+ Text [ en-US ] = "Intersection" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XUNIONY ;
+ HelpId = HID_SMA_XUNIONY ;
+ Text [ en-US ] = "Union" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSETMINUSY ;
+ HelpId = HID_SMA_XSETMINUSY ;
+ Text [ en-US ] = "Difference" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSLASHY ;
+ HelpId = HID_SMA_XSLASHY ;
+ Text [ en-US ] = "Quotient Set" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ALEPH ;
+ HelpId = HID_SMA_ALEPH ;
+ Text [ en-US ] = "Aleph";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSUBSETY ;
+ HelpId = HID_SMA_XSUBSETY ;
+ Text [ en-US ] = "Subset" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSUBSETEQY ;
+ HelpId = HID_SMA_XSUBSETEQY ;
+ Text [ en-US ] = "Subset Or Equal To" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSUPSETY ;
+ HelpId = HID_SMA_XSUPSETY ;
+ Text [ en-US ] = "Superset" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XSUPSETEQY ;
+ HelpId = HID_SMA_XSUPSETEQY ;
+ Text [ en-US ] = "Superset Or Equal To" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XNSUBSETY ;
+ HelpId = HID_SMA_XNSUBSETY ;
+ Text [ en-US ] = "Not Subset" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XNSUBSETEQY ;
+ HelpId = HID_SMA_XNSUBSETEQY ;
+ Text [ en-US ] = "Not Subset Or Equal" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XNSUPSETY ;
+ HelpId = HID_SMA_XNSUPSETY ;
+ Text [ en-US ] = "Not Superset" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XNSUPSETEQY ;
+ HelpId = HID_SMA_XNSUPSETEQY ;
+ Text [ en-US ] = "Not Superset Or Equal" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SETN ;
+ HelpId = HID_SMA_SETN ;
+ Text [ en-US ] = "Natural Numbers Set";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SETZ ;
+ HelpId = HID_SMA_SETZ ;
+ Text [ en-US ] = "Integers Set";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SETQ ;
+ HelpId = HID_SMA_SETQ ;
+ Text [ en-US ] = "Set of Rational Numbers";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SETR ;
+ HelpId = HID_SMA_SETR ;
+ Text [ en-US ] = "Real Numbers Set";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SETC ;
+ HelpId = HID_SMA_SETC ;
+ Text [ en-US ] = "Complex Numbers Set";
+ };
+ };
+ };
+
+ ToolBox TOOLBOX_CAT_D
+ {
+ // functions
+ HelpId = HID_SMA_FUNCTIONS_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 5 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_EX ;
+ HelpId = HID_SMA_EX ;
+ Text [ en-US ] = "Exponential Function" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LNX ;
+ HelpId = HID_SMA_LNX ;
+ Text [ en-US ] = "Natural Logarithm" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_EXPX ;
+ HelpId = HID_SMA_EXPX ;
+ Text [ en-US ] = "Exponential Function" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LOGX ;
+ HelpId = HID_SMA_LOGX ;
+ Text [ en-US ] = "Logarithm" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_RSUPX ;
+ HelpId = HID_SMA_RSUPX ;
+ Text [ en-US ] = "Power";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SINX ;
+ HelpId = HID_SMA_SINX ;
+ Text [ en-US ] = "Sine" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_COSX ;
+ HelpId = HID_SMA_COSX ;
+ Text [ en-US ] = "Cosine" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_TANX ;
+ HelpId = HID_SMA_TANX ;
+ Text [ en-US ] = "Tangent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_COTX ;
+ HelpId = HID_SMA_COTX ;
+ Text [ en-US ] = "Cotangent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SQRTX ;
+ HelpId = HID_SMA_SQRTX ;
+ Text [ en-US ] = "Square Root" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ARCSINX ;
+ HelpId = HID_SMA_ARCSINX ;
+ Text [ en-US ] = "Arcsine" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ARCCOSX ;
+ HelpId = HID_SMA_ARCCOSX ;
+ Text [ en-US ] = "Arccosine" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ARCTANX ;
+ HelpId = HID_SMA_ARCTANX ;
+ Text [ en-US ] = "Arctangent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ARCCOTX ;
+ HelpId = HID_SMA_ARCCOTX ;
+ Text [ en-US ] = "Arccotangent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_NROOTXY ;
+ HelpId = HID_SMA_NROOTXY ;
+ Text [ en-US ] = "N-th Root" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SINHX ;
+ HelpId = HID_SMA_SINHX ;
+ Text [ en-US ] = "Hyperbolic Sine" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_COSHX ;
+ HelpId = HID_SMA_COSHX ;
+ Text [ en-US ] = "Hyperbolic Cosine" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_TANHX ;
+ HelpId = HID_SMA_TANHX ;
+ Text [ en-US ] = "Hyperbolic Tangent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_COTHX ;
+ HelpId = HID_SMA_COTHX ;
+ Text [ en-US ] = "Hyperbolic Cotangent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ABSX ;
+ HelpId = HID_SMA_ABSX ;
+ Text [ en-US ] = "Absolute Value" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ARSINHX ;
+ HelpId = HID_SMA_ARSINHX ;
+ Text [ en-US ] = "Area Hyperbolic Sine" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ARCOSHX ;
+ HelpId = HID_SMA_ARCOSHX ;
+ Text [ en-US ] = "Area Hyperbolic Cosine" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ARTANHX ;
+ HelpId = HID_SMA_ARTANHX ;
+ Text [ en-US ] = "Area Hyperbolic Tangent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ARCOTHX ;
+ HelpId = HID_SMA_ARCOTHX ;
+ Text [ en-US ] = "Area Hyperbolic Cotangent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_FACTX ;
+ HelpId = HID_SMA_FACTX ;
+ Text [ en-US ] = "Factorial" ;
+ };
+ };
+ };
+
+ ToolBox TOOLBOX_CAT_E
+ {
+ // operators
+ HelpId = HID_SMA_OPERATORS_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 3 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_LIMX ;
+ HelpId = HID_SMA_LIMX ;
+ Text [ en-US ] = "Limes" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SUMX ;
+ HelpId = HID_SMA_SUMX ;
+ Text [ en-US ] = "Sum" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_PRODX ;
+ HelpId = HID_SMA_PRODX ;
+ Text [ en-US ] = "Product" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_COPRODX ;
+ HelpId = HID_SMA_COPRODX ;
+ Text [ en-US ] = "Coproduct" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_FROMXTOY ;
+ HelpId = HID_SMA_FROMXTOY ;
+ Text [ en-US ] = "Upper And Lower Limit" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_INTX ;
+ HelpId = HID_SMA_INTX ;
+ Text [ en-US ] = "Integral" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_IINTX ;
+ HelpId = HID_SMA_IINTX ;
+ Text [ en-US ] = "Double Integral" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_IIINTX ;
+ HelpId = HID_SMA_IIINTX ;
+ Text [ en-US ] = "Triple Integral" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_FROMX ;
+ HelpId = HID_SMA_FROMX ;
+ Text [ en-US ] = "Lower Limit" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LINTX ;
+ HelpId = HID_SMA_LINTX ;
+ Text [ en-US ] = "Curve Integral" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LLINTX ;
+ HelpId = HID_SMA_LLINTX ;
+ Text [ en-US ] = "Double Curve Integral" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LLLINTX ;
+ HelpId = HID_SMA_LLLINTX ;
+ Text [ en-US ] = "Triple Curve Integral" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_TOX ;
+ HelpId = HID_SMA_TOX ;
+ Text [ en-US ] = "Upper Limit" ;
+ };
+ };
+ };
+
+ ToolBox TOOLBOX_CAT_F
+ {
+ // attributs
+ HelpId = HID_SMA_ATTRIBUTES_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 5 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_ACUTEX ;
+ HelpId = HID_SMA_ACUTEX ;
+ Text [ en-US ] = "Acute Accent";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_GRAVEX ;
+ HelpId = HID_SMA_GRAVEX ;
+ Text [ en-US ] = "Grave Accent";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_CHECKX ;
+ HelpId = HID_SMA_CHECKX ;
+ Text [ en-US ] = "Reverse Circumflex" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_BREVEX ;
+ HelpId = HID_SMA_BREVEX ;
+ Text [ en-US ] = "Breve" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_CIRCLEX ;
+ HelpId = HID_SMA_CIRCLEX ;
+ Text [ en-US ] = "Circle" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_VECX ;
+ HelpId = HID_SMA_VECX ;
+ Text [ en-US ] = "Vector Arrow" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_TILDEX ;
+ HelpId = HID_SMA_TILDEX ;
+ Text [ en-US ] = "Tilde" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_HATX ;
+ HelpId = HID_SMA_HATX ;
+ Text [ en-US ] = "Circumflex" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_BARX ;
+ HelpId = HID_SMA_BARX ;
+ Text [ en-US ] = "Line Above" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DOTX ;
+ HelpId = HID_SMA_DOTX ;
+ Text [ en-US ] = "Dot" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_WIDEVECX ;
+ HelpId = HID_SMA_WIDEVECX ;
+ Text [ en-US ] = "Large Vector Arrow";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_WIDETILDEX ;
+ HelpId = HID_SMA_WIDETILDEX ;
+ Text [ en-US ] = "Large Tilde";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_WIDEHATX ;
+ HelpId = HID_SMA_WIDEHATX ;
+ Text [ en-US ] = "Large Circumflex";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DDOTX ;
+ HelpId = HID_SMA_DDOTX ;
+ Text [ en-US ] = "Double Dot" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_OVERLINEX ;
+ HelpId = HID_SMA_OVERLINEX ;
+ Text [ en-US ] = "Line Over" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_UNDERLINEX ;
+ HelpId = HID_SMA_UNDERLINEX ;
+ Text [ en-US ] = "Line Below" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_OVERSTRIKEX ;
+ HelpId = HID_SMA_OVERSTRIKEX ;
+ Text [ en-US ] = "Line Through" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DDDOTX ;
+ HelpId = HID_SMA_DDDOTX ;
+ Text [ en-US ] = "Triple Dot" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_PHANTOMX ;
+ HelpId = HID_SMA_PHANTOMX ;
+ Text [ en-US ] = "Transparent" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_BOLDX ;
+ HelpId = HID_SMA_BOLDX ;
+ Text [ en-US ] = "Bold Font" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ITALX ;
+ HelpId = HID_SMA_ITALX ;
+ Text [ en-US ] = "Italic Font" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SIZEXY ;
+ HelpId = HID_SMA_SIZEXY ;
+ Text [ en-US ] = "Resize" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_FONTXY ;
+ HelpId = HID_SMA_FONTXY ;
+ Text [ en-US ] = "Change Font" ;
+ };
+ };
+ };
+
+ ToolBox TOOLBOX_CAT_G
+ {
+ // parentheses
+ HelpId = HID_SMA_BRACKETS_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 5 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_LRPARENTX ;
+ HelpId = HID_SMA_LRPARENTX ;
+ Text [ en-US ] = "Round Brackets" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LRBRACKETX ;
+ HelpId = HID_SMA_LRBRACKETX ;
+ Text [ en-US ] = "Square Brackets" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LRDBRACKETX ;
+ HelpId = HID_SMA_LRDBRACKETX ;
+ Text [ en-US ] = "Double Square Brackets";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LRLINEX ;
+ HelpId = HID_SMA_LRLINEX ;
+ Text [ en-US ] = "Single Lines" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LRDLINEX ;
+ HelpId = HID_SMA_LRDLINEX ;
+ Text [ en-US ] = "Double Lines" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LRBRACEX ;
+ HelpId = HID_SMA_LRBRACEX ;
+ Text [ en-US ] = "Braces" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LRANGLEX ;
+ HelpId = HID_SMA_LRANGLEX ;
+ Text [ en-US ] = "Angle Brackets" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LMRANGLEXY ;
+ HelpId = HID_SMA_LMRANGLEXY ;
+ Text [ en-US ] = "Operator Brackets";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LRGROUPX ;
+ HelpId = HID_SMA_LRGROUPX ;
+ Text [ en-US ] = "Group Brackets" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SLRPARENTX ;
+ HelpId = HID_SMA_SLRPARENTX ;
+ Text [ en-US ] = "Round Brackets (Scalable)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SLRBRACKETX ;
+ HelpId = HID_SMA_SLRBRACKETX ;
+ Text [ en-US ] = "Square Brackets (Scalable)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SLRDBRACKETX ;
+ HelpId = HID_SMA_SLRDBRACKETX ;
+ Text [ en-US ] = "Double Square Brackets (Scalable)";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SLRLINEX ;
+ HelpId = HID_SMA_SLRLINEX ;
+ Text [ en-US ] = "Single Lines (Scalable)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SLRDLINEX ;
+ HelpId = HID_SMA_SLRDLINEX ;
+ Text [ en-US ] = "Double Lines (Scalable)" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SLRBRACEX ;
+ HelpId = HID_SMA_SLRBRACEX ;
+ Text [ en-US ] = "Braces (Scalable)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SLRANGLEX ;
+ HelpId = HID_SMA_SLRANGLEX ;
+ Text [ en-US ] = "Angle Brackets (Scalable)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SLMRANGLEXY ;
+ HelpId = HID_SMA_SLMRANGLEXY ;
+ Text [ en-US ] = "Operator Brackets (Scalable)";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XOVERBRACEY ;
+ HelpId = HID_SMA_XOVERBRACEY ;
+ Text [ en-US ] = "Braces Top (Scalable)";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_XUNDERBRACEY ;
+ HelpId = HID_SMA_XUNDERBRACEY ;
+ Text [ en-US ] = "Braces Bottom (Scalable)";
+ };
+ };
+ };
+
+ ToolBox TOOLBOX_CAT_H
+ {
+ // format
+ HelpId = HID_SMA_FORMAT_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 3 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_LSUPX ;
+ HelpId = HID_SMA_LSUPX ;
+ Text [ en-US ] = "Superscript Left" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_CSUPX ;
+ HelpId = HID_SMA_CSUPX ;
+ Text [ en-US ] = "Superscript Top";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_RSUPX ;
+ HelpId = HID_SMA_RSUPX ;
+ Text [ en-US ] = "Superscript Right" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_BINOMXY ;
+ HelpId = HID_SMA_BINOMXY ;
+ Text [ en-US ] = "Vertical Stack (2 Elements)" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_NEWLINE ;
+ HelpId = HID_SMA_NEWLINE ;
+ Text [ en-US ] = "New Line" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LSUBX ;
+ HelpId = HID_SMA_LSUBX ;
+ Text [ en-US ] = "Subscript Left" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_CSUBX ;
+ HelpId = HID_SMA_CSUBX ;
+ Text [ en-US ] = "Subscript Bottom";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_RSUBX ;
+ HelpId = HID_SMA_RSUBX ;
+ Text [ en-US ] = "Subscript Right" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_STACK ;
+ HelpId = HID_SMA_STACK ;
+ Text [ en-US ] = "Vertical Stack" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_SBLANK ;
+ HelpId = HID_SMA_SBLANK ;
+ Text [ en-US ] = "Small Gap" ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ALIGNLX ;
+ HelpId = HID_SMA_ALIGNLX ;
+ Text [ en-US ] = "Align Left" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ALIGNCX ;
+ HelpId = HID_SMA_ALIGNCX ;
+ Text [ en-US ] = "Align Center" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_ALIGNRX ;
+ HelpId = HID_SMA_ALIGNRX ;
+ Text [ en-US ] = "Align Right" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_MATRIX ;
+ HelpId = HID_SMA_MATRIX ;
+ Text [ en-US ] = "Matrix Stack" ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_BLANK ;
+ HelpId = HID_SMA_BLANK ;
+ Text [ en-US ] = "Gap" ;
+ };
+ };
+ };
+
+ ToolBox TOOLBOX_CAT_I
+ {
+ // misc
+ HelpId = HID_SMA_FORMAT_TBX ;
+ Pos = MAP_APPFONT ( 0 , 45 ) ;
+ Size = MAP_APPFONT ( 65 , 95 ) ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ LineCount = 4 ;
+ ItemList =
+ {
+ ToolBoxItem
+ {
+ Identifier = RID_INFINITY ;
+ HelpId = HID_SMA_INFINITY ;
+ Text [ en-US ] = "infinite";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_PARTIAL ;
+ HelpId = HID_SMA_PARTIAL ;
+ Text [ en-US ] = "Partial";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_NABLA ;
+ HelpId = HID_SMA_NABLA ;
+ Text [ en-US ] = "Nabla";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_EXISTS ;
+ HelpId = HID_SMA_EXISTS ;
+ Text [ en-US ] = "There Exists";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_FORALL ;
+ HelpId = HID_SMA_FORALL ;
+ Text [ en-US ] = "For All";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_HBAR ;
+ HelpId = HID_SMA_HBAR ;
+ Text [ en-US ] = "h Bar";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LAMBDABAR ;
+ HelpId = HID_SMA_LAMBDABAR ;
+ Text [ en-US ] = "Lambda Bar";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_RE ;
+ HelpId = HID_SMA_RE ;
+ Text [ en-US ] = "Real Part";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_IM ;
+ HelpId = HID_SMA_IM ;
+ Text [ en-US ] = "Imaginary Part";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_WP ;
+ HelpId = HID_SMA_WP ;
+ Text [ en-US ] = "Weierstrass p";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_LEFTARROW ;
+ HelpId = HID_SMA_LEFTARROW ;
+ Text [ en-US ] = "Left Arrow";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_RIGHTARROW ;
+ HelpId = HID_SMA_RIGHTARROW ;
+ Text [ en-US ] = "Right Arrow";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_UPARROW ;
+ HelpId = HID_SMA_UPARROW ;
+ Text [ en-US ] = "Up Arrow";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DOWNARROW ;
+ HelpId = HID_SMA_DOWNARROW ;
+ Text [ en-US ] = "Down Arrow";
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_SPACE ;
+ };
+ ToolBoxItem
+ {
+ Type = TOOLBOXITEM_BREAK ;
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DOTSLOW ;
+ HelpId = HID_SMA_DOTSLOW ;
+ Text [ en-US ] = "Dots At Bottom";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DOTSAXIS ;
+ HelpId = HID_SMA_DOTSAXIS ;
+ Text [ en-US ] = "Dots In Middle";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DOTSVERT ;
+ HelpId = HID_SMA_DOTSVERT ;
+ Text [ en-US ] = "Dots Vertically";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DOTSUP ;
+ HelpId = HID_SMA_DOTSUP ;
+ Text [ en-US ] = "Dots To Top";
+ };
+ ToolBoxItem
+ {
+ Identifier = RID_DOTSDOWN ;
+ HelpId = HID_SMA_DOTSDOWN ;
+ Text [ en-US ] = "Dots to Bottom";
+ };
+ };
+ };
+};
+
+
+
+#define UNBINOPS_IDLIST \
+ IdList = \
+ { \
+ RID_PLUSX ; \
+ RID_MINUSX ; \
+ RID_PLUSMINUSX ; \
+ RID_MINUSPLUSX ; \
+ RID_XPLUSY ; \
+ RID_XCDOTY ; \
+ RID_XTIMESY ; \
+ RID_XSYMTIMESY ; \
+ RID_XMINUSY ; \
+ RID_XOVERY ; \
+ RID_XDIVY ; \
+ RID_XSYMDIVIDEY ; \
+ RID_NEGX ; \
+ RID_XANDY ; \
+ RID_XORY ; \
+ RID_XCIRCY ; \
+ }; \
+ IdCount = { 16 ; };
+
+ ImageList RID_IL_UNBINOPS
+ {
+ Prefix = "un";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ UNBINOPS_IDLIST
+ };
+
+#define RELATIONS_IDLIST \
+ IdList = \
+ { \
+ RID_XEQY ; \
+ RID_XNEQY ; \
+ RID_XEQUIVY ; \
+ RID_XORTHOY ; \
+ RID_XLTY ; \
+ RID_XGTY ; \
+ RID_XAPPROXY ; \
+ RID_XPARALLELY ; \
+ RID_XLESLANTY ; \
+ RID_XGESLANTY ; \
+ RID_XSIMEQY ; \
+ RID_XPROPY ; \
+ RID_XLEY ; \
+ RID_XGEY ; \
+ RID_XSIMY ; \
+ RID_XTOWARDY ; \
+ RID_XDIVIDESY ; \
+ RID_XNDIVIDESY; \
+ RID_DLARROW ; \
+ RID_DLRARROW ; \
+ RID_DRARROW ; \
+ }; \
+ IdCount ={ 21 ; };
+
+ ImageList RID_IL_RELATIONS
+ {
+ Prefix = "bi";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ RELATIONS_IDLIST
+ };
+
+#define SETOPERATIONS_IDLIST \
+ IdList = \
+ { \
+ RID_XINY ; \
+ RID_XNOTINY ; \
+ RID_XOWNSY ; \
+ RID_XINTERSECTIONY ; \
+ RID_XUNIONY ; \
+ RID_XSETMINUSY ; \
+ RID_XSLASHY ; \
+ RID_XSUBSETY ; \
+ RID_XSUBSETEQY ; \
+ RID_XSUPSETY ; \
+ RID_XSUPSETEQY ; \
+ RID_XNSUBSETY ; \
+ RID_XNSUBSETEQY ; \
+ RID_XNSUPSETY ; \
+ RID_XNSUPSETEQY ; \
+ RID_EMPTYSET ; \
+ RID_ALEPH ; \
+ RID_SETN ; \
+ RID_SETZ ; \
+ RID_SETQ ; \
+ RID_SETR ; \
+ RID_SETC ; \
+ }; \
+ IdCount = { 22 ; };
+
+ ImageList RID_IL_SETOPERATIONS
+ {
+ Prefix = "op";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ SETOPERATIONS_IDLIST
+ };
+
+#define FUNCTIONS_IDLIST \
+ IdList = \
+ { \
+ RID_ABSX ; \
+ RID_FACTX ; \
+ RID_SQRTX ; \
+ RID_NROOTXY ; \
+ RID_EX ; \
+ RID_LNX ; \
+ RID_EXPX ; \
+ RID_LOGX ; \
+ RID_SINX ; \
+ RID_COSX ; \
+ RID_TANX ; \
+ RID_COTX ; \
+ RID_SINHX ; \
+ RID_COSHX ; \
+ RID_TANHX ; \
+ RID_COTHX ; \
+ RID_ARCSINX ; \
+ RID_ARCCOSX ; \
+ RID_ARCTANX ; \
+ RID_ARCCOTX ; \
+ RID_ARSINHX ; \
+ RID_ARCOSHX ; \
+ RID_ARTANHX ; \
+ RID_ARCOTHX ; \
+ RID_RSUPX ; \
+ }; \
+ IdCount = { 25 ; };
+
+ ImageList RID_IL_FUNCTIONS
+ {
+ Prefix = "fu";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ FUNCTIONS_IDLIST
+ };
+
+#define OPERATORS_IDLIST \
+ IdList = \
+ { \
+ RID_LIMX ; \
+ RID_SUMX ; \
+ RID_PRODX ; \
+ RID_COPRODX ; \
+ RID_INTX ; \
+ RID_IINTX ; \
+ RID_IIINTX ; \
+ RID_LINTX ; \
+ RID_LLINTX ; \
+ RID_LLLINTX ; \
+ RID_FROMXTOY ; \
+ RID_FROMX ; \
+ RID_TOX ; \
+ }; \
+ IdCount = { 13 ; };
+
+ ImageList RID_IL_OPERATORS
+ {
+ Prefix = "fo";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ OPERATORS_IDLIST
+ };
+
+#define ATTRIBUTES_IDLIST \
+ IdList = \
+ { \
+ RID_ACUTEX ; \
+ RID_GRAVEX ; \
+ RID_CHECKX ; \
+ RID_BREVEX ; \
+ RID_BARX ; \
+ RID_VECX ; \
+ RID_HATX ; \
+ RID_TILDEX ; \
+ RID_CIRCLEX ; \
+ RID_DOTX ; \
+ RID_DDOTX ; \
+ RID_DDDOTX ; \
+ RID_OVERLINEX ; \
+ RID_UNDERLINEX ; \
+ RID_OVERSTRIKEX ; \
+ RID_PHANTOMX ; \
+ RID_BOLDX ; \
+ RID_ITALX ; \
+ RID_SIZEXY ; \
+ RID_FONTXY ; \
+ RID_WIDEHATX ; \
+ RID_WIDETILDEX ; \
+ RID_WIDEVECX ; \
+ }; \
+ IdCount = { 23 ; };
+
+ ImageList RID_IL_ATTRIBUTES
+ {
+ Prefix = "at";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ ATTRIBUTES_IDLIST
+ };
+
+#define BRACKETS_IDLIST \
+ IdList = \
+ { \
+ RID_LRPARENTX ; \
+ RID_LRBRACKETX ; \
+ RID_LRANGLEX ; \
+ RID_LRBRACEX ; \
+ RID_LRLINEX ; \
+ RID_LRDLINEX ; \
+ RID_LMRANGLEXY ; \
+ RID_LRGROUPX ; \
+ RID_SLRPARENTX ; \
+ RID_SLRBRACKETX ; \
+ RID_SLRANGLEX ; \
+ RID_SLRBRACEX ; \
+ RID_SLRLINEX ; \
+ RID_SLRDLINEX ; \
+ RID_SLMRANGLEXY ; \
+ RID_LRDBRACKETX ; \
+ RID_SLRDBRACKETX ; \
+ RID_XOVERBRACEY ; \
+ RID_XUNDERBRACEY ; \
+ }; \
+ IdCount = { 19 ; };
+
+ ImageList RID_IL_BRACKETS
+ {
+ Prefix = "al";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ BRACKETS_IDLIST
+ };
+
+#define FORMAT_IDLIST \
+ IdList = \
+ { \
+ RID_NEWLINE ; \
+ RID_SBLANK ; \
+ RID_BLANK ; \
+ RID_BINOMXY ; \
+ RID_STACK ; \
+ RID_MATRIX ; \
+ RID_ALIGNLX ; \
+ RID_ALIGNCX ; \
+ RID_ALIGNRX ; \
+ RID_RSUBX ; \
+ RID_RSUPX ; \
+ RID_LSUBX ; \
+ RID_LSUPX ; \
+ RID_CSUBX ; \
+ RID_CSUPX ; \
+ }; \
+ IdCount = { 15 ; };
+
+ ImageList RID_IL_FORMAT
+ {
+ Prefix = "co";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ FORMAT_IDLIST
+ };
+
+#define MISC_IDLIST \
+ IdList = \
+ { \
+ RID_INFINITY ; \
+ RID_PARTIAL ; \
+ RID_NABLA ; \
+ RID_EXISTS ; \
+ RID_FORALL ; \
+ RID_HBAR; \
+ RID_LAMBDABAR ; \
+ RID_RE ; \
+ RID_IM ; \
+ RID_WP ; \
+ RID_LEFTARROW ; \
+ RID_RIGHTARROW ; \
+ RID_UPARROW ; \
+ RID_DOWNARROW ; \
+ RID_DOTSLOW ; \
+ RID_DOTSAXIS ; \
+ RID_DOTSVERT ; \
+ RID_DOTSUP ; \
+ RID_DOTSDOWN ; \
+ }; \
+ IdCount = { 19 ; };
+
+ ImageList RID_IL_MISC
+ {
+ Prefix = "mi";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ MISC_IDLIST
+ };
+
+#define CATALOG_IDLIST \
+ IdList = \
+ { \
+ RID_UNBINOPS_CAT ; \
+ RID_RELATIONS_CAT ; \
+ RID_SETOPERATIONS_CAT ; \
+ RID_FUNCTIONS_CAT ; \
+ RID_OPERATORS_CAT ; \
+ RID_ATTRIBUTES_CAT ; \
+ RID_MISC_CAT ; \
+ RID_BRACKETS_CAT ; \
+ RID_FORMAT_CAT ; \
+ }; \
+ IdCount = { 9 ; };
+
+ ImageList RID_IL_CATALOG
+ {
+ Prefix = "im";
+ MaskColor = IMAGE_STDBTN_COLOR ;
+ CATALOG_IDLIST
+ };
+
+
+
diff --git a/starmath/source/typemap.cxx b/starmath/source/typemap.cxx
new file mode 100644
index 000000000000..767e29dcad34
--- /dev/null
+++ b/starmath/source/typemap.cxx
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#define ITEMID_PTR 0
+#define ITEMID_SHADOW 0
+#define ITEMID_PAGE 0
+#define ITEMID_SETITEM 0
+#define ITEMID_HORJUSTIFY 0
+#define ITEMID_VERJUSTIFY 0
+#define ITEMID_ORIENTATION 0
+#define ITEMID_MARGIN 0
+#define ITEMID_AUTHOR 0
+#define ITEMID_DATE 0
+#define ITEMID_TEXT 0
+#define ITEMID_SPELLCHECK 0
+#define ITEMID_HYPHENREGION 0
+#define ITEMID_FONT 0
+#define ITEMID_FONTHEIGHT 0
+#define ITEMID_BRUSH 0
+#define ITEMID_BOX 0
+#define ITEMID_LINE 0
+#define ITEMID_LINESPACING 0
+#define ITEMID_ADJUST 0
+#define ITEMID_WIDOWS 0
+#define ITEMID_ORPHANS 0
+#define ITEMID_HYPHENZONE 0
+#define ITEMID_TABSTOP 0
+#define ITEMID_FMTSPLIT 0
+#define ITEMID_PAGEMODEL 0
+#define ITEMID_FONTLIST 0
+#define ITEMID_POSTURE 0
+#define ITEMID_WEIGHT 0
+#define ITEMID_FONTWIDTH 0
+#define ITEMID_UNDERLINE 0
+#define ITEMID_CROSSEDOUT 0
+#define ITEMID_SHADOWED 0
+#define ITEMID_AUTOKERN 0
+#define ITEMID_WORDLINEMODE 0
+#define ITEMID_CONTOUR 0
+#define ITEMID_PROPSIZE 0
+#define ITEMID_COLOR 0
+#define ITEMID_CHARSETCOLOR 0
+#define ITEMID_KERNING 0
+#define ITEMID_CASEMAP 0
+#define ITEMID_ESCAPEMENT 0
+#define ITEMID_LANGUAGE 0
+#define ITEMID_NOLINEBREAK 0
+#define ITEMID_NOHYPHENHERE 0
+#define ITEMID_SEARCH 0
+#define ITEMID_COLOR_TABLE 0
+#define ITEMID_GRADIENT_LIST 0
+#define ITEMID_HATCH_LIST 0
+#define ITEMID_BITMAP_LIST 0
+#define ITEMID_DASH_LIST 0
+#define ITEMID_LINEEND_LIST 0
+#define ITEMID_NUMBERINFO 0
+#define ITEMID_CHARTSTYLE 0
+#define ITEMID_CHARTDATADESCR 0
+#define ITEMID_CHARTLEGENDPOS 0
+#define ITEMID_CHARTTEXTORDER 0
+#define ITEMID_CHARTTEXTORIENT 0
+#define ITEMID_DOUBLE 0
+#define ITEMID_PAPERBIN 0
+#define ITEMID_SIZE 0
+#define ITEMID_LRSPACE 0
+#define ITEMID_ULSPACE 0
+#define ITEMID_PRINT 0
+#define ITEMID_OPAQUE 0
+#define ITEMID_PROTECT 0
+#define ITEMID_MACRO 0
+#define ITEMID_BOXINFO 0
+#define ITEMID_FMTBREAK 0
+#define ITEMID_FMTKEEP 0
+
+#define CharSetItem SfxVoidItem
+#define FontFamilyItem SfxVoidItem
+#define FontPitchItem SfxVoidItem
+#define FontAlignItem SfxVoidItem
+#define FontWeightItem SfxVoidItem
+#define FontUnderlineItem SfxVoidItem
+#define FontStrikeoutItem SfxVoidItem
+#define FontItalicItem SfxVoidItem
+#define SvxDbTypeItem SfxVoidItem
+#define SvxLineSpaceItem SfxVoidItem
+#define SvxInterLineSpaceItem SfxVoidItem
+#define SvxBreakItem SfxVoidItem
+#define BrushStyleItem SfxVoidItem
+#define SvxNumTypeItem SfxVoidItem
+#define SvxShadowLocationItem SfxVoidItem
+#define SvxLanguage SfxVoidItem
+#define SvxChooseControlEnumItem SfxVoidItem
+#define SvxDrawToolEnumItem SfxVoidItem
+#define SvxChooseControlItem SfxVoidItem
+#define SvxDrawToolItem SfxVoidItem
+#define SvxCellHorJustifyEnumItem SfxVoidItem
+#define SvxCellVerJustifyEnumItem SfxVoidItem
+#define SvxCellOrientationEnumItem SfxVoidItem
+#include <sfx2/msg.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+#include <svx/zoomitem.hxx>
+#include <svl/slstitm.hxx>
+
+#define SFX_TYPEMAP
+#include "smslots.hxx"
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/types.cxx b/starmath/source/types.cxx
new file mode 100644
index 000000000000..185ec069b797
--- /dev/null
+++ b/starmath/source/types.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <types.hxx>
+#include <osl/diagnose.h>
+
+
+sal_Unicode ConvertMathPrivateUseAreaToUnicode( sal_Unicode cChar )
+{
+ sal_Unicode cRes = cChar;
+ if (IsInPrivateUseArea( cChar ))
+ {
+ OSL_FAIL( "Error: private use area characters should no longer be in use!" );
+ cRes = (sal_Unicode) '@'; // just some character that should easily be notice as odd in the context
+ }
+ return cRes;
+}
+
+
+sal_Unicode ConvertMathToMathML( sal_Unicode cChar )
+{
+ sal_Unicode cRes = ConvertMathPrivateUseAreaToUnicode( cChar );
+ return cRes;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/unodoc.cxx b/starmath/source/unodoc.cxx
new file mode 100644
index 000000000000..4f0205f5cd38
--- /dev/null
+++ b/starmath/source/unodoc.cxx
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+// System - Includes -----------------------------------------------------
+
+#include <tools/string.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/sfxmodelfactory.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include "smdll.hxx"
+#include "document.hxx"
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star;
+
+::rtl::OUString SAL_CALL SmDocument_getImplementationName() throw()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.FormulaDocument" ) );
+}
+
+uno::Sequence< rtl::OUString > SAL_CALL SmDocument_getSupportedServiceNames() throw()
+{
+ uno::Sequence< rtl::OUString > aSeq( 1 );
+ aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.formula.FormulaProperties" ));
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL SmDocument_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & /*rSMgr*/, const sal_uInt64 _nCreationFlags ) throw( uno::Exception )
+{
+ SolarMutexGuard aGuard;
+ if ( !SM_MOD() )
+ SmDLL::Init();
+
+ SfxObjectShell* pShell = new SmDocShell( _nCreationFlags );
+ if( pShell )
+ return uno::Reference< uno::XInterface >( pShell->GetModel() );
+
+ return uno::Reference< uno::XInterface >();
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/unomodel.cxx b/starmath/source/unomodel.cxx
new file mode 100644
index 000000000000..d3d41c36ee40
--- /dev/null
+++ b/starmath/source/unomodel.cxx
@@ -0,0 +1,1143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <osl/mutex.hxx>
+#include <sfx2/printer.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svl/itemprop.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/processfactory.hxx>
+#include <editeng/paperinf.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/print.hxx>
+#include <toolkit/awt/vclxdevice.hxx>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/formula/SymbolDescriptor.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <xmloff/xmluconv.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/propertysetinfo.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#include <unomodel.hxx>
+#include <document.hxx>
+#include <view.hxx>
+#include <symbol.hxx>
+#include <starmath.hrc>
+#include <config.hxx>
+#include <smdll.hxx>
+
+using namespace ::cppu;
+using namespace ::std;
+using namespace ::comphelper;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::formula;
+using namespace ::com::sun::star::view;
+using namespace ::com::sun::star::script;
+
+
+using rtl::OUString;
+
+#define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
+#define MM100_TO_TWIP(MM100) ((MM100) >= 0 ? (((MM100)*72L+63L)/127L) : (((MM100)*72L-63L)/127L))
+
+////////////////////////////////////////////////////////////
+
+SmPrintUIOptions::SmPrintUIOptions()
+{
+ ResStringArray aLocalizedStrings( SmResId( RID_PRINTUIOPTIONS ) );
+ OSL_ENSURE( aLocalizedStrings.Count() >= 18, "resource incomplete" );
+ if( aLocalizedStrings.Count() < 9 ) // bad resource ?
+ return;
+
+ SmModule *pp = SM_MOD();
+ SmConfig *pConfig = pp->GetConfig();
+ OSL_ENSURE( pConfig, "SmConfig not found" );
+ if (!pConfig)
+ return;
+
+ // create sequence of print UI options
+ // (Actually IsIgnoreSpacesRight is a parser option. Without it we need only 8 properties here.)
+ m_aUIProperties.realloc( 9 );
+
+ // create Section for formula (results in an extra tab page in dialog)
+ SvtModuleOptions aOpt;
+ String aAppGroupname( aLocalizedStrings.GetString( 0 ) );
+ aAppGroupname.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ),
+ aOpt.GetModuleName( SvtModuleOptions::E_SMATH ) );
+ m_aUIProperties[0].Value = getGroupControlOpt( aAppGroupname, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:TabPage:AppPage" ) ) );
+
+ // create subgroup for print options
+ m_aUIProperties[1].Value = getSubgroupControlOpt( aLocalizedStrings.GetString( 1 ), rtl::OUString() );
+
+ // create a bool option for title row (matches to SID_PRINTTITLE)
+ m_aUIProperties[2].Value = getBoolControlOpt( aLocalizedStrings.GetString( 2 ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:TitleRow:CheckBox" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PRTUIOPT_TITLE_ROW ) ),
+ pConfig->IsPrintTitle() );
+ // create a bool option for formula text (matches to SID_PRINTTEXT)
+ m_aUIProperties[3].Value = getBoolControlOpt( aLocalizedStrings.GetString( 3 ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:FormulaText:CheckBox" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PRTUIOPT_FORMULA_TEXT ) ),
+ pConfig->IsPrintFormulaText() );
+ // create a bool option for border (matches to SID_PRINTFRAME)
+ m_aUIProperties[4].Value = getBoolControlOpt( aLocalizedStrings.GetString( 4 ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:Border:CheckBox" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PRTUIOPT_BORDER ) ),
+ pConfig->IsPrintFrame() );
+
+ // create subgroup for print format
+ m_aUIProperties[5].Value = getSubgroupControlOpt( aLocalizedStrings.GetString( 5 ), rtl::OUString() );
+
+ // create a radio button group for print format (matches to SID_PRINTSIZE)
+ Sequence< rtl::OUString > aChoices( 3 );
+ aChoices[0] = aLocalizedStrings.GetString( 6 );
+ aChoices[1] = aLocalizedStrings.GetString( 7 );
+ aChoices[2] = aLocalizedStrings.GetString( 8 );
+ Sequence< rtl::OUString > aHelpIds( 3 );
+ aHelpIds[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintFormat:RadioButton:0" ) );
+ aHelpIds[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintFormat:RadioButton:1" ) );
+ aHelpIds[2] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintFormat:RadioButton:2" ) );
+ OUString aPrintFormatProp( RTL_CONSTASCII_USTRINGPARAM( PRTUIOPT_PRINT_FORMAT ) );
+ m_aUIProperties[6].Value = getChoiceControlOpt( rtl::OUString(),
+ aHelpIds,
+ aPrintFormatProp,
+ aChoices, static_cast< sal_Int32 >(pConfig->GetPrintSize())
+ );
+
+ // create a numeric box for scale dependent on PrintFormat = "Scaling" (matches to SID_PRINTZOOM)
+ vcl::PrinterOptionsHelper::UIControlOptions aRangeOpt( aPrintFormatProp, 2, sal_True );
+ m_aUIProperties[ 7 ].Value = getRangeControlOpt( rtl::OUString(),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:PrintScale:NumericField" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PRTUIOPT_PRINT_SCALE ) ),
+ pConfig->GetPrintZoomFactor(), // initial value
+ 10, // min value
+ 1000, // max value
+ aRangeOpt );
+
+ Sequence< PropertyValue > aHintNoLayoutPage( 1 );
+ aHintNoLayoutPage[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HintNoLayoutPage" ) );
+ aHintNoLayoutPage[0].Value = makeAny( sal_True );
+ m_aUIProperties[8].Value <<= aHintNoLayoutPage;
+
+}
+
+
+////////////////////////////////////////////////////////////
+//
+// class SmModel
+//
+
+// values from com/sun/star/beans/PropertyAttribute
+#define PROPERTY_NONE 0
+#define PROPERTY_READONLY 16
+
+enum SmModelPropertyHandles
+{
+ HANDLE_FORMULA,
+ HANDLE_FONT_NAME_VARIABLES,
+ HANDLE_FONT_NAME_FUNCTIONS,
+ HANDLE_FONT_NAME_NUMBERS,
+ HANDLE_FONT_NAME_TEXT,
+ HANDLE_CUSTOM_FONT_NAME_SERIF,
+ HANDLE_CUSTOM_FONT_NAME_SANS,
+ HANDLE_CUSTOM_FONT_NAME_FIXED,
+ HANDLE_CUSTOM_FONT_FIXED_POSTURE,
+ HANDLE_CUSTOM_FONT_FIXED_WEIGHT,
+ HANDLE_CUSTOM_FONT_SANS_POSTURE,
+ HANDLE_CUSTOM_FONT_SANS_WEIGHT,
+ HANDLE_CUSTOM_FONT_SERIF_POSTURE,
+ HANDLE_CUSTOM_FONT_SERIF_WEIGHT,
+ HANDLE_FONT_VARIABLES_POSTURE,
+ HANDLE_FONT_VARIABLES_WEIGHT,
+ HANDLE_FONT_FUNCTIONS_POSTURE,
+ HANDLE_FONT_FUNCTIONS_WEIGHT,
+ HANDLE_FONT_NUMBERS_POSTURE,
+ HANDLE_FONT_NUMBERS_WEIGHT,
+ HANDLE_FONT_TEXT_POSTURE,
+ HANDLE_FONT_TEXT_WEIGHT,
+ HANDLE_BASE_FONT_HEIGHT,
+ HANDLE_RELATIVE_FONT_HEIGHT_TEXT,
+ HANDLE_RELATIVE_FONT_HEIGHT_INDICES,
+ HANDLE_RELATIVE_FONT_HEIGHT_FUNCTIONS,
+ HANDLE_RELATIVE_FONT_HEIGHT_OPERATORS,
+ HANDLE_RELATIVE_FONT_HEIGHT_LIMITS,
+ HANDLE_IS_TEXT_MODE,
+ HANDLE_GREEK_CHAR_STYLE,
+ HANDLE_ALIGNMENT,
+ HANDLE_RELATIVE_SPACING,
+ HANDLE_RELATIVE_LINE_SPACING,
+ HANDLE_RELATIVE_ROOT_SPACING,
+ HANDLE_RELATIVE_INDEX_SUPERSCRIPT,
+ HANDLE_RELATIVE_INDEX_SUBSCRIPT,
+ HANDLE_RELATIVE_FRACTION_NUMERATOR_HEIGHT,
+ HANDLE_RELATIVE_FRACTION_DENOMINATOR_DEPTH,
+ HANDLE_RELATIVE_FRACTION_BAR_EXCESS_LENGTH,
+ HANDLE_RELATIVE_FRACTION_BAR_LINE_WEIGHT,
+ HANDLE_RELATIVE_UPPER_LIMIT_DISTANCE,
+ HANDLE_RELATIVE_LOWER_LIMIT_DISTANCE,
+ HANDLE_RELATIVE_BRACKET_EXCESS_SIZE,
+ HANDLE_RELATIVE_BRACKET_DISTANCE,
+ HANDLE_IS_SCALE_ALL_BRACKETS,
+ HANDLE_RELATIVE_SCALE_BRACKET_EXCESS_SIZE,
+ HANDLE_RELATIVE_MATRIX_LINE_SPACING,
+ HANDLE_RELATIVE_MATRIX_COLUMN_SPACING,
+ HANDLE_RELATIVE_SYMBOL_PRIMARY_HEIGHT,
+ HANDLE_RELATIVE_SYMBOL_MINIMUM_HEIGHT,
+ HANDLE_RELATIVE_OPERATOR_EXCESS_SIZE,
+ HANDLE_RELATIVE_OPERATOR_SPACING,
+ HANDLE_LEFT_MARGIN,
+ HANDLE_RIGHT_MARGIN,
+ HANDLE_TOP_MARGIN,
+ HANDLE_BOTTOM_MARGIN,
+ HANDLE_PRINTER_NAME,
+ HANDLE_PRINTER_SETUP,
+ HANDLE_SYMBOLS,
+ HANDLE_USED_SYMBOLS,
+ HANDLE_BASIC_LIBRARIES,
+ HANDLE_RUNTIME_UID,
+ HANDLE_LOAD_READONLY, // Security Options
+ HANDLE_DIALOG_LIBRARIES, // #i73329#
+ HANDLE_BASELINE
+};
+
+PropertySetInfo * lcl_createModelPropertyInfo ()
+{
+ static PropertyMapEntry aModelPropertyInfoMap[] =
+ {
+ { RTL_CONSTASCII_STRINGPARAM( "Alignment" ), HANDLE_ALIGNMENT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+ { RTL_CONSTASCII_STRINGPARAM( "BaseFontHeight" ), HANDLE_BASE_FONT_HEIGHT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+ { RTL_CONSTASCII_STRINGPARAM( "BasicLibraries" ), HANDLE_BASIC_LIBRARIES , &::getCppuType((const uno::Reference< script::XLibraryContainer > *)0), PropertyAttribute::READONLY, 0},
+ { RTL_CONSTASCII_STRINGPARAM( "BottomMargin" ), HANDLE_BOTTOM_MARGIN , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_BOTTOMSPACE },
+ { RTL_CONSTASCII_STRINGPARAM( "CustomFontNameFixed" ), HANDLE_CUSTOM_FONT_NAME_FIXED , &::getCppuType((const OUString*)0), PROPERTY_NONE, FNT_FIXED },
+ { RTL_CONSTASCII_STRINGPARAM( "CustomFontNameSans" ), HANDLE_CUSTOM_FONT_NAME_SANS , &::getCppuType((const OUString*)0), PROPERTY_NONE, FNT_SANS },
+ { RTL_CONSTASCII_STRINGPARAM( "CustomFontNameSerif" ), HANDLE_CUSTOM_FONT_NAME_SERIF , &::getCppuType((const OUString*)0), PROPERTY_NONE, FNT_SERIF },
+ { RTL_CONSTASCII_STRINGPARAM( "DialogLibraries" ), HANDLE_DIALOG_LIBRARIES , &::getCppuType((const uno::Reference< script::XLibraryContainer > *)0), PropertyAttribute::READONLY, 0},
+ { RTL_CONSTASCII_STRINGPARAM( "FontFixedIsBold"), HANDLE_CUSTOM_FONT_FIXED_WEIGHT , &::getBooleanCppuType(), PROPERTY_NONE, FNT_FIXED},
+ { RTL_CONSTASCII_STRINGPARAM( "FontFixedIsItalic"), HANDLE_CUSTOM_FONT_FIXED_POSTURE , &::getBooleanCppuType(), PROPERTY_NONE, FNT_FIXED},
+ { RTL_CONSTASCII_STRINGPARAM( "FontFunctionsIsBold"), HANDLE_FONT_FUNCTIONS_WEIGHT , &::getBooleanCppuType(), PROPERTY_NONE, FNT_FUNCTION},
+ { RTL_CONSTASCII_STRINGPARAM( "FontFunctionsIsItalic"), HANDLE_FONT_FUNCTIONS_POSTURE , &::getBooleanCppuType(), PROPERTY_NONE, FNT_FUNCTION},
+ { RTL_CONSTASCII_STRINGPARAM( "FontNameFunctions" ), HANDLE_FONT_NAME_FUNCTIONS , &::getCppuType((const OUString*)0), PROPERTY_NONE, FNT_FUNCTION },
+ { RTL_CONSTASCII_STRINGPARAM( "FontNameNumbers" ), HANDLE_FONT_NAME_NUMBERS , &::getCppuType((const OUString*)0), PROPERTY_NONE, FNT_NUMBER },
+ { RTL_CONSTASCII_STRINGPARAM( "FontNameText" ), HANDLE_FONT_NAME_TEXT , &::getCppuType((const OUString*)0), PROPERTY_NONE, FNT_TEXT },
+ { RTL_CONSTASCII_STRINGPARAM( "FontNameVariables" ), HANDLE_FONT_NAME_VARIABLES , &::getCppuType((const OUString*)0), PROPERTY_NONE, FNT_VARIABLE },
+ { RTL_CONSTASCII_STRINGPARAM( "FontNumbersIsBold"), HANDLE_FONT_NUMBERS_WEIGHT , &::getBooleanCppuType(), PROPERTY_NONE, FNT_NUMBER},
+ { RTL_CONSTASCII_STRINGPARAM( "FontNumbersIsItalic"), HANDLE_FONT_NUMBERS_POSTURE , &::getBooleanCppuType(), PROPERTY_NONE, FNT_NUMBER},
+ { RTL_CONSTASCII_STRINGPARAM( "FontSansIsBold"), HANDLE_CUSTOM_FONT_SANS_WEIGHT , &::getBooleanCppuType(), PROPERTY_NONE, FNT_SANS},
+ { RTL_CONSTASCII_STRINGPARAM( "FontSansIsItalic"), HANDLE_CUSTOM_FONT_SANS_POSTURE , &::getBooleanCppuType(), PROPERTY_NONE, FNT_SANS},
+ { RTL_CONSTASCII_STRINGPARAM( "FontSerifIsBold"), HANDLE_CUSTOM_FONT_SERIF_WEIGHT , &::getBooleanCppuType(), PROPERTY_NONE, FNT_SERIF},
+ { RTL_CONSTASCII_STRINGPARAM( "FontSerifIsItalic"), HANDLE_CUSTOM_FONT_SERIF_POSTURE , &::getBooleanCppuType(), PROPERTY_NONE, FNT_SERIF},
+ { RTL_CONSTASCII_STRINGPARAM( "FontTextIsBold"), HANDLE_FONT_TEXT_WEIGHT , &::getBooleanCppuType(), PROPERTY_NONE, FNT_TEXT},
+ { RTL_CONSTASCII_STRINGPARAM( "FontTextIsItalic"), HANDLE_FONT_TEXT_POSTURE , &::getBooleanCppuType(), PROPERTY_NONE, FNT_TEXT},
+ { RTL_CONSTASCII_STRINGPARAM( "FontVariablesIsBold"), HANDLE_FONT_VARIABLES_WEIGHT , &::getBooleanCppuType(), PROPERTY_NONE, FNT_VARIABLE},
+ { RTL_CONSTASCII_STRINGPARAM( "FontVariablesIsItalic"), HANDLE_FONT_VARIABLES_POSTURE, &::getBooleanCppuType(), PROPERTY_NONE, FNT_VARIABLE},
+ { RTL_CONSTASCII_STRINGPARAM( "Formula" ), HANDLE_FORMULA , &::getCppuType((const OUString*)0), PROPERTY_NONE, 0},
+ { RTL_CONSTASCII_STRINGPARAM( "IsScaleAllBrackets" ), HANDLE_IS_SCALE_ALL_BRACKETS , &::getBooleanCppuType(), PROPERTY_NONE, 0},
+ { RTL_CONSTASCII_STRINGPARAM( "IsTextMode" ), HANDLE_IS_TEXT_MODE , &::getBooleanCppuType(), PROPERTY_NONE, 0},
+ { RTL_CONSTASCII_STRINGPARAM( "GreekCharStyle" ), HANDLE_GREEK_CHAR_STYLE, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+ { RTL_CONSTASCII_STRINGPARAM( "LeftMargin" ), HANDLE_LEFT_MARGIN , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_LEFTSPACE },
+ { RTL_CONSTASCII_STRINGPARAM( "PrinterName" ), HANDLE_PRINTER_NAME , &::getCppuType((const OUString*)0), PROPERTY_NONE, 0 },
+ { RTL_CONSTASCII_STRINGPARAM( "PrinterSetup" ), HANDLE_PRINTER_SETUP , &::getCppuType((const Sequence < sal_Int8 >*)0), PROPERTY_NONE, 0 },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeBracketDistance" ), HANDLE_RELATIVE_BRACKET_DISTANCE , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_BRACKETSPACE },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeBracketExcessSize" ), HANDLE_RELATIVE_BRACKET_EXCESS_SIZE , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_BRACKETSIZE },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFontHeightFunctions" ), HANDLE_RELATIVE_FONT_HEIGHT_FUNCTIONS , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, SIZ_FUNCTION},
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFontHeightIndices" ), HANDLE_RELATIVE_FONT_HEIGHT_INDICES , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, SIZ_INDEX },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFontHeightLimits" ), HANDLE_RELATIVE_FONT_HEIGHT_LIMITS , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, SIZ_LIMITS },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFontHeightOperators" ), HANDLE_RELATIVE_FONT_HEIGHT_OPERATORS , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, SIZ_OPERATOR},
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFontHeightText" ), HANDLE_RELATIVE_FONT_HEIGHT_TEXT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, SIZ_TEXT },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFractionBarExcessLength"), HANDLE_RELATIVE_FRACTION_BAR_EXCESS_LENGTH, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_FRACTION },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFractionBarLineWeight" ), HANDLE_RELATIVE_FRACTION_BAR_LINE_WEIGHT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_STROKEWIDTH },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFractionDenominatorDepth"), HANDLE_RELATIVE_FRACTION_DENOMINATOR_DEPTH, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_DENOMINATOR },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeFractionNumeratorHeight" ), HANDLE_RELATIVE_FRACTION_NUMERATOR_HEIGHT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_NUMERATOR },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeIndexSubscript" ), HANDLE_RELATIVE_INDEX_SUBSCRIPT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_SUBSCRIPT },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeIndexSuperscript" ), HANDLE_RELATIVE_INDEX_SUPERSCRIPT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_SUPERSCRIPT },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeLineSpacing" ), HANDLE_RELATIVE_LINE_SPACING , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_VERTICAL },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeLowerLimitDistance" ), HANDLE_RELATIVE_LOWER_LIMIT_DISTANCE , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_LOWERLIMIT },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeMatrixColumnSpacing" ), HANDLE_RELATIVE_MATRIX_COLUMN_SPACING , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_MATRIXCOL},
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeMatrixLineSpacing" ), HANDLE_RELATIVE_MATRIX_LINE_SPACING , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_MATRIXROW},
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeOperatorExcessSize" ), HANDLE_RELATIVE_OPERATOR_EXCESS_SIZE , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_OPERATORSIZE },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeOperatorSpacing" ), HANDLE_RELATIVE_OPERATOR_SPACING , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_OPERATORSPACE},
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeRootSpacing" ), HANDLE_RELATIVE_ROOT_SPACING , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_ROOT },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeScaleBracketExcessSize" ), HANDLE_RELATIVE_SCALE_BRACKET_EXCESS_SIZE , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_NORMALBRACKETSIZE},
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeSpacing" ), HANDLE_RELATIVE_SPACING , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_HORIZONTAL },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeSymbolMinimumHeight" ), HANDLE_RELATIVE_SYMBOL_MINIMUM_HEIGHT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_ORNAMENTSPACE },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeSymbolPrimaryHeight" ), HANDLE_RELATIVE_SYMBOL_PRIMARY_HEIGHT , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_ORNAMENTSIZE },
+ { RTL_CONSTASCII_STRINGPARAM( "RelativeUpperLimitDistance" ), HANDLE_RELATIVE_UPPER_LIMIT_DISTANCE , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_UPPERLIMIT },
+ { RTL_CONSTASCII_STRINGPARAM( "RightMargin" ), HANDLE_RIGHT_MARGIN , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_RIGHTSPACE },
+ { RTL_CONSTASCII_STRINGPARAM( "RuntimeUID" ), HANDLE_RUNTIME_UID , &::getCppuType(static_cast< const rtl::OUString * >(0)), PropertyAttribute::READONLY, 0 },
+ { RTL_CONSTASCII_STRINGPARAM( "Symbols" ), HANDLE_SYMBOLS , &::getCppuType((const Sequence < SymbolDescriptor > *)0), PROPERTY_NONE, 0 },
+ { RTL_CONSTASCII_STRINGPARAM( "UserDefinedSymbolsInUse" ), HANDLE_USED_SYMBOLS , &::getCppuType((const Sequence < SymbolDescriptor > *)0), PropertyAttribute::READONLY, 0 },
+ { RTL_CONSTASCII_STRINGPARAM( "TopMargin" ), HANDLE_TOP_MARGIN , &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, DIS_TOPSPACE },
+ // --> PB 2004-08-25 #i33095# Security Options
+ { RTL_CONSTASCII_STRINGPARAM( "LoadReadonly" ), HANDLE_LOAD_READONLY, &::getBooleanCppuType(), PROPERTY_NONE, 0 },
+ // <--
+ // --> 3.7.2010 #i972#
+ { RTL_CONSTASCII_STRINGPARAM( "BaseLine"), HANDLE_BASELINE, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+ // <--
+ { NULL, 0, 0, NULL, 0, 0 }
+ };
+ PropertySetInfo *pInfo = new PropertySetInfo ( aModelPropertyInfoMap );
+ return pInfo;
+}
+
+SmModel::SmModel( SfxObjectShell *pObjSh )
+: SfxBaseModel(pObjSh)
+, PropertySetHelper ( lcl_createModelPropertyInfo () )
+, m_pPrintUIOptions( NULL )
+
+{
+}
+
+SmModel::~SmModel() throw ()
+{
+ delete m_pPrintUIOptions;
+}
+
+uno::Any SAL_CALL SmModel::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
+{
+ uno::Any aRet = ::cppu::queryInterface ( rType,
+ // OWeakObject interfaces
+ dynamic_cast< XInterface* > ( static_cast< XUnoTunnel* > ( this )),
+ static_cast< XWeak* > ( this ),
+ // PropertySetHelper interfaces
+ static_cast< XPropertySet* > ( this ),
+ static_cast< XMultiPropertySet* > ( this ),
+ //static_cast< XPropertyState* > ( this ),
+ // my own interfaces
+ static_cast< XServiceInfo* > ( this ),
+ static_cast< XRenderable* > ( this ) );
+ if (!aRet.hasValue())
+ aRet = SfxBaseModel::queryInterface ( rType );
+ return aRet;
+}
+
+void SAL_CALL SmModel::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL SmModel::release() throw()
+{
+ OWeakObject::release();
+}
+
+uno::Sequence< uno::Type > SAL_CALL SmModel::getTypes( ) throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ uno::Sequence< uno::Type > aTypes = SfxBaseModel::getTypes();
+ sal_Int32 nLen = aTypes.getLength();
+ aTypes.realloc(nLen + 4);
+ uno::Type* pTypes = aTypes.getArray();
+ pTypes[nLen++] = ::getCppuType((Reference<XServiceInfo>*)0);
+ pTypes[nLen++] = ::getCppuType((Reference<XPropertySet>*)0);
+ pTypes[nLen++] = ::getCppuType((Reference<XMultiPropertySet>*)0);
+ pTypes[nLen++] = ::getCppuType((Reference<XRenderable>*)0);
+
+ return aTypes;
+}
+
+const uno::Sequence< sal_Int8 > & SmModel::getUnoTunnelId()
+{
+ static osl::Mutex aCreateMutex;
+ osl::Guard<osl::Mutex> aGuard( aCreateMutex );
+
+ static uno::Sequence< sal_Int8 > aSeq;
+ if(!aSeq.getLength())
+ {
+ aSeq.realloc( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ }
+ return aSeq;
+}
+
+sal_Int64 SAL_CALL SmModel::getSomething( const uno::Sequence< sal_Int8 >& rId )
+ throw(uno::RuntimeException)
+{
+ if( rId.getLength() == 16
+ && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
+ }
+
+ return SfxBaseModel::getSomething( rId );
+}
+
+sal_Int16 lcl_AnyToINT16(const uno::Any& rAny)
+{
+ uno::TypeClass eType = rAny.getValueType().getTypeClass();
+
+ sal_Int16 nRet = 0;
+ if( eType == uno::TypeClass_DOUBLE )
+ nRet = (sal_Int16)*(double*)rAny.getValue();
+ else if( eType == uno::TypeClass_FLOAT )
+ nRet = (sal_Int16)*(float*)rAny.getValue();
+ else
+ rAny >>= nRet;
+ return nRet;
+}
+
+OUString SmModel::getImplementationName(void) throw( uno::RuntimeException )
+{
+ return getImplementationName_Static();
+}
+
+
+::rtl::OUString SmModel::getImplementationName_Static()
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.math.FormulaDocument"));
+}
+
+sal_Bool SmModel::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
+{
+ return (
+ rServiceName == A2OU("com.sun.star.document.OfficeDocument" ) ||
+ rServiceName == A2OU("com.sun.star.formula.FormulaProperties")
+ );
+}
+
+uno::Sequence< OUString > SmModel::getSupportedServiceNames(void) throw( uno::RuntimeException )
+{
+ return getSupportedServiceNames_Static();
+}
+
+uno::Sequence< OUString > SmModel::getSupportedServiceNames_Static(void)
+{
+ SolarMutexGuard aGuard;
+
+ uno::Sequence< OUString > aRet(2);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = A2OU("com.sun.star.document.OfficeDocument");
+ pArray[1] = A2OU("com.sun.star.formula.FormulaProperties");
+ return aRet;
+}
+
+void SmModel::_setPropertyValues(const PropertyMapEntry** ppEntries, const Any* pValues)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException)
+{
+ SolarMutexGuard aGuard;
+
+ SmDocShell *pDocSh = static_cast < SmDocShell * > (GetObjectShell());
+
+ if ( NULL == pDocSh )
+ throw UnknownPropertyException();
+
+ SmFormat aFormat = pDocSh->GetFormat();
+
+ for (; *ppEntries; ppEntries++, pValues++ )
+ {
+ if ((*ppEntries)->mnAttributes & PropertyAttribute::READONLY)
+ throw PropertyVetoException();
+
+ switch ( (*ppEntries)->mnHandle )
+ {
+ case HANDLE_FORMULA:
+ {
+ OUString aText;
+ *pValues >>= aText;
+ pDocSh->SetText(aText);
+ }
+ break;
+ case HANDLE_FONT_NAME_VARIABLES :
+ case HANDLE_FONT_NAME_FUNCTIONS :
+ case HANDLE_FONT_NAME_NUMBERS :
+ case HANDLE_FONT_NAME_TEXT :
+ case HANDLE_CUSTOM_FONT_NAME_SERIF :
+ case HANDLE_CUSTOM_FONT_NAME_SANS :
+ case HANDLE_CUSTOM_FONT_NAME_FIXED :
+ {
+ OUString aText;
+ *pValues >>= aText;
+ String sFontName = aText;
+ if(!sFontName.Len())
+ throw IllegalArgumentException();
+
+ if(aFormat.GetFont((*ppEntries)->mnMemberId).GetName() != sFontName)
+ {
+ const SmFace rOld = aFormat.GetFont((*ppEntries)->mnMemberId);
+
+ SmFace aSet( sFontName, rOld.GetSize() );
+ aSet.SetBorderWidth( rOld.GetBorderWidth() );
+ aSet.SetAlign( ALIGN_BASELINE );
+ aFormat.SetFont( (*ppEntries)->mnMemberId, aSet );
+ }
+ }
+ break;
+ case HANDLE_CUSTOM_FONT_FIXED_POSTURE:
+ case HANDLE_CUSTOM_FONT_SANS_POSTURE :
+ case HANDLE_CUSTOM_FONT_SERIF_POSTURE:
+ case HANDLE_FONT_VARIABLES_POSTURE :
+ case HANDLE_FONT_FUNCTIONS_POSTURE :
+ case HANDLE_FONT_NUMBERS_POSTURE :
+ case HANDLE_FONT_TEXT_POSTURE :
+ {
+ if((*pValues).getValueType() != ::getBooleanCppuType())
+ throw IllegalArgumentException();
+ bool bVal = *(sal_Bool*)(*pValues).getValue();
+ Font aNewFont(aFormat.GetFont((*ppEntries)->mnMemberId));
+ aNewFont.SetItalic((bVal) ? ITALIC_NORMAL : ITALIC_NONE);
+ aFormat.SetFont((*ppEntries)->mnMemberId, aNewFont);
+ }
+ break;
+ case HANDLE_CUSTOM_FONT_FIXED_WEIGHT :
+ case HANDLE_CUSTOM_FONT_SANS_WEIGHT :
+ case HANDLE_CUSTOM_FONT_SERIF_WEIGHT :
+ case HANDLE_FONT_VARIABLES_WEIGHT :
+ case HANDLE_FONT_FUNCTIONS_WEIGHT :
+ case HANDLE_FONT_NUMBERS_WEIGHT :
+ case HANDLE_FONT_TEXT_WEIGHT :
+ {
+ if((*pValues).getValueType() != ::getBooleanCppuType())
+ throw IllegalArgumentException();
+ bool bVal = *(sal_Bool*)(*pValues).getValue();
+ Font aNewFont(aFormat.GetFont((*ppEntries)->mnMemberId));
+ aNewFont.SetWeight((bVal) ? WEIGHT_BOLD : WEIGHT_NORMAL);
+ aFormat.SetFont((*ppEntries)->mnMemberId, aNewFont);
+ }
+ break;
+ case HANDLE_BASE_FONT_HEIGHT :
+ {
+ // Point!
+ sal_Int16 nVal = lcl_AnyToINT16(*pValues);
+ if(nVal < 1)
+ throw IllegalArgumentException();
+ Size aSize = aFormat.GetBaseSize();
+ nVal *= 20;
+ nVal = static_cast < sal_Int16 > ( TWIP_TO_MM100(nVal) );
+ aSize.Height() = nVal;
+ aFormat.SetBaseSize(aSize);
+
+ // apply base size to fonts
+ const Size aTmp( aFormat.GetBaseSize() );
+ for (sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++)
+ aFormat.SetFontSize(i, aTmp);
+ }
+ break;
+ case HANDLE_RELATIVE_FONT_HEIGHT_TEXT :
+ case HANDLE_RELATIVE_FONT_HEIGHT_INDICES :
+ case HANDLE_RELATIVE_FONT_HEIGHT_FUNCTIONS :
+ case HANDLE_RELATIVE_FONT_HEIGHT_OPERATORS :
+ case HANDLE_RELATIVE_FONT_HEIGHT_LIMITS :
+ {
+ sal_Int16 nVal = 0;
+ *pValues >>= nVal;
+ if(nVal < 1)
+ throw IllegalArgumentException();
+ aFormat.SetRelSize((*ppEntries)->mnMemberId, nVal);
+ }
+ break;
+
+ case HANDLE_IS_TEXT_MODE :
+ {
+ aFormat.SetTextmode(*(sal_Bool*)(*pValues).getValue());
+ }
+ break;
+
+ case HANDLE_GREEK_CHAR_STYLE :
+ {
+ sal_Int16 nVal = 0;
+ *pValues >>= nVal;
+ if (nVal < 0 || nVal > 2)
+ throw IllegalArgumentException();
+ aFormat.SetGreekCharStyle( nVal );
+ }
+ break;
+
+ case HANDLE_ALIGNMENT :
+ {
+ // SmHorAlign uses the same values as HorizontalAlignment
+ sal_Int16 nVal = 0;
+ *pValues >>= nVal;
+ if(nVal < 0 || nVal > 2)
+ throw IllegalArgumentException();
+ aFormat.SetHorAlign((SmHorAlign)nVal);
+ }
+ break;
+
+ case HANDLE_RELATIVE_SPACING :
+ case HANDLE_RELATIVE_LINE_SPACING :
+ case HANDLE_RELATIVE_ROOT_SPACING :
+ case HANDLE_RELATIVE_INDEX_SUPERSCRIPT :
+ case HANDLE_RELATIVE_INDEX_SUBSCRIPT :
+ case HANDLE_RELATIVE_FRACTION_NUMERATOR_HEIGHT :
+ case HANDLE_RELATIVE_FRACTION_DENOMINATOR_DEPTH:
+ case HANDLE_RELATIVE_FRACTION_BAR_EXCESS_LENGTH:
+ case HANDLE_RELATIVE_FRACTION_BAR_LINE_WEIGHT :
+ case HANDLE_RELATIVE_UPPER_LIMIT_DISTANCE :
+ case HANDLE_RELATIVE_LOWER_LIMIT_DISTANCE :
+ case HANDLE_RELATIVE_BRACKET_EXCESS_SIZE :
+ case HANDLE_RELATIVE_BRACKET_DISTANCE :
+ case HANDLE_RELATIVE_SCALE_BRACKET_EXCESS_SIZE :
+ case HANDLE_RELATIVE_MATRIX_LINE_SPACING :
+ case HANDLE_RELATIVE_MATRIX_COLUMN_SPACING :
+ case HANDLE_RELATIVE_SYMBOL_PRIMARY_HEIGHT :
+ case HANDLE_RELATIVE_SYMBOL_MINIMUM_HEIGHT :
+ case HANDLE_RELATIVE_OPERATOR_EXCESS_SIZE :
+ case HANDLE_RELATIVE_OPERATOR_SPACING :
+ case HANDLE_LEFT_MARGIN :
+ case HANDLE_RIGHT_MARGIN :
+ case HANDLE_TOP_MARGIN :
+ case HANDLE_BOTTOM_MARGIN :
+ {
+ sal_Int16 nVal = 0;
+ *pValues >>= nVal;
+ if(nVal < 0)
+ throw IllegalArgumentException();
+ aFormat.SetDistance((*ppEntries)->mnMemberId, nVal);
+ }
+ break;
+ case HANDLE_IS_SCALE_ALL_BRACKETS :
+ aFormat.SetScaleNormalBrackets(*(sal_Bool*)(*pValues).getValue());
+ break;
+ case HANDLE_PRINTER_NAME:
+ {
+ // embedded documents just ignore this property for now
+ if ( pDocSh->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
+ {
+ SfxPrinter *pPrinter = pDocSh->GetPrinter ( );
+ if (pPrinter)
+ {
+ OUString sPrinterName;
+ if (*pValues >>= sPrinterName )
+ {
+ if ( sPrinterName.getLength() )
+ {
+ SfxPrinter *pNewPrinter = new SfxPrinter ( pPrinter->GetOptions().Clone(), sPrinterName );
+ if (pNewPrinter->IsKnown())
+ pDocSh->SetPrinter ( pNewPrinter );
+ else
+ delete pNewPrinter;
+ }
+ }
+ else
+ throw IllegalArgumentException();
+ }
+ }
+ }
+ break;
+ case HANDLE_PRINTER_SETUP:
+ {
+ Sequence < sal_Int8 > aSequence;
+ if ( *pValues >>= aSequence )
+ {
+ sal_uInt32 nSize = aSequence.getLength();
+ SvMemoryStream aStream ( aSequence.getArray(), nSize, STREAM_READ );
+ aStream.Seek ( STREAM_SEEK_TO_BEGIN );
+ static sal_uInt16 const nRange[] =
+ {
+ SID_PRINTSIZE, SID_PRINTSIZE,
+ SID_PRINTZOOM, SID_PRINTZOOM,
+ SID_PRINTTITLE, SID_PRINTTITLE,
+ SID_PRINTTEXT, SID_PRINTTEXT,
+ SID_PRINTFRAME, SID_PRINTFRAME,
+ SID_NO_RIGHT_SPACES, SID_NO_RIGHT_SPACES,
+ 0
+ };
+ SfxItemSet *pItemSet = new SfxItemSet( pDocSh->GetPool(), nRange );
+ SmModule *pp = SM_MOD();
+ pp->GetConfig()->ConfigToItemSet(*pItemSet);
+ SfxPrinter *pPrinter = SfxPrinter::Create ( aStream, pItemSet );
+
+ pDocSh->SetPrinter( pPrinter );
+ }
+ else
+ throw IllegalArgumentException();
+ }
+ break;
+ case HANDLE_SYMBOLS:
+ {
+ // this is set
+ Sequence < SymbolDescriptor > aSequence;
+ if ( *pValues >>= aSequence )
+ {
+ sal_uInt32 nSize = aSequence.getLength();
+ SmModule *pp = SM_MOD();
+ SmSymbolManager &rManager = pp->GetSymbolManager();
+ SymbolDescriptor *pDescriptor = aSequence.getArray();
+ for (sal_uInt32 i = 0; i < nSize ; i++, pDescriptor++)
+ {
+ Font aFont;
+ aFont.SetName ( pDescriptor->sFontName );
+ aFont.SetCharSet ( static_cast < rtl_TextEncoding > (pDescriptor->nCharSet) );
+ aFont.SetFamily ( static_cast < FontFamily > (pDescriptor->nFamily ) );
+ aFont.SetPitch ( static_cast < FontPitch > (pDescriptor->nPitch ) );
+ aFont.SetWeight ( static_cast < FontWeight > (pDescriptor->nWeight ) );
+ aFont.SetItalic ( static_cast < FontItalic > (pDescriptor->nItalic ) );
+ SmSym aSymbol ( pDescriptor->sName, aFont, static_cast < sal_Unicode > (pDescriptor->nCharacter),
+ pDescriptor->sSymbolSet );
+ aSymbol.SetExportName ( pDescriptor->sExportName );
+ aSymbol.SetDocSymbol( sal_True );
+ rManager.AddOrReplaceSymbol ( aSymbol );
+ }
+ }
+ else
+ throw IllegalArgumentException();
+ }
+ break;
+ // --> PB 2004-08-25 #i33095# Security Options
+ case HANDLE_LOAD_READONLY :
+ {
+ if ( (*pValues).getValueType() != ::getBooleanCppuType() )
+ throw IllegalArgumentException();
+ sal_Bool bReadonly = sal_False;
+ if ( *pValues >>= bReadonly )
+ pDocSh->SetLoadReadonly( bReadonly );
+ break;
+ }
+ // <--
+ }
+ }
+
+ pDocSh->SetFormat( aFormat );
+
+ // #i67283# since about all of the above changes are likely to change
+ // the formula size we have to recalculate the vis-area now
+ pDocSh->SetVisArea( Rectangle( Point(0, 0), pDocSh->GetSize() ) );
+}
+
+void SmModel::_getPropertyValues( const PropertyMapEntry **ppEntries, Any *pValue )
+ throw( UnknownPropertyException, WrappedTargetException )
+{
+ SmDocShell *pDocSh = static_cast < SmDocShell * > (GetObjectShell());
+
+ if ( NULL == pDocSh )
+ throw UnknownPropertyException();
+
+ const SmFormat & aFormat = pDocSh->GetFormat();
+
+ for (; *ppEntries; ppEntries++, pValue++ )
+ {
+ switch ( (*ppEntries)->mnHandle )
+ {
+ case HANDLE_FORMULA:
+ *pValue <<= OUString(pDocSh->GetText());
+ break;
+ case HANDLE_FONT_NAME_VARIABLES :
+ case HANDLE_FONT_NAME_FUNCTIONS :
+ case HANDLE_FONT_NAME_NUMBERS :
+ case HANDLE_FONT_NAME_TEXT :
+ case HANDLE_CUSTOM_FONT_NAME_SERIF :
+ case HANDLE_CUSTOM_FONT_NAME_SANS :
+ case HANDLE_CUSTOM_FONT_NAME_FIXED :
+ {
+ const SmFace & rFace = aFormat.GetFont((*ppEntries)->mnMemberId);
+ *pValue <<= OUString(rFace.GetName());
+ }
+ break;
+ case HANDLE_CUSTOM_FONT_FIXED_POSTURE:
+ case HANDLE_CUSTOM_FONT_SANS_POSTURE :
+ case HANDLE_CUSTOM_FONT_SERIF_POSTURE:
+ case HANDLE_FONT_VARIABLES_POSTURE :
+ case HANDLE_FONT_FUNCTIONS_POSTURE :
+ case HANDLE_FONT_NUMBERS_POSTURE :
+ case HANDLE_FONT_TEXT_POSTURE :
+ {
+ const SmFace & rFace = aFormat.GetFont((*ppEntries)->mnMemberId);
+ bool bVal = IsItalic( rFace );
+ (*pValue).setValue(&bVal, *(*ppEntries)->mpType);
+ }
+ break;
+ case HANDLE_CUSTOM_FONT_FIXED_WEIGHT :
+ case HANDLE_CUSTOM_FONT_SANS_WEIGHT :
+ case HANDLE_CUSTOM_FONT_SERIF_WEIGHT :
+ case HANDLE_FONT_VARIABLES_WEIGHT :
+ case HANDLE_FONT_FUNCTIONS_WEIGHT :
+ case HANDLE_FONT_NUMBERS_WEIGHT :
+ case HANDLE_FONT_TEXT_WEIGHT :
+ {
+ const SmFace & rFace = aFormat.GetFont((*ppEntries)->mnMemberId);
+ bool bVal = IsBold( rFace ); // bold?
+ (*pValue).setValue(&bVal, *(*ppEntries)->mpType);
+ }
+ break;
+ case HANDLE_BASE_FONT_HEIGHT :
+ {
+ // Point!
+ sal_Int16 nVal = static_cast < sal_Int16 > (aFormat.GetBaseSize().Height());
+ nVal = static_cast < sal_Int16 > (MM100_TO_TWIP(nVal));
+ nVal = (nVal + 10) / 20;
+ *pValue <<= nVal;
+ }
+ break;
+ case HANDLE_RELATIVE_FONT_HEIGHT_TEXT :
+ case HANDLE_RELATIVE_FONT_HEIGHT_INDICES :
+ case HANDLE_RELATIVE_FONT_HEIGHT_FUNCTIONS :
+ case HANDLE_RELATIVE_FONT_HEIGHT_OPERATORS :
+ case HANDLE_RELATIVE_FONT_HEIGHT_LIMITS :
+ *pValue <<= (sal_Int16) aFormat.GetRelSize((*ppEntries)->mnMemberId);
+ break;
+
+ case HANDLE_IS_TEXT_MODE :
+ {
+ sal_Bool bVal = aFormat.IsTextmode();
+ (*pValue).setValue(&bVal, ::getBooleanCppuType());
+ }
+ break;
+
+ case HANDLE_GREEK_CHAR_STYLE :
+ *pValue <<= (sal_Int16)aFormat.GetGreekCharStyle();
+ break;
+
+ case HANDLE_ALIGNMENT :
+ // SmHorAlign uses the same values as HorizontalAlignment
+ *pValue <<= (sal_Int16)aFormat.GetHorAlign();
+ break;
+
+ case HANDLE_RELATIVE_SPACING :
+ case HANDLE_RELATIVE_LINE_SPACING :
+ case HANDLE_RELATIVE_ROOT_SPACING :
+ case HANDLE_RELATIVE_INDEX_SUPERSCRIPT :
+ case HANDLE_RELATIVE_INDEX_SUBSCRIPT :
+ case HANDLE_RELATIVE_FRACTION_NUMERATOR_HEIGHT :
+ case HANDLE_RELATIVE_FRACTION_DENOMINATOR_DEPTH:
+ case HANDLE_RELATIVE_FRACTION_BAR_EXCESS_LENGTH:
+ case HANDLE_RELATIVE_FRACTION_BAR_LINE_WEIGHT :
+ case HANDLE_RELATIVE_UPPER_LIMIT_DISTANCE :
+ case HANDLE_RELATIVE_LOWER_LIMIT_DISTANCE :
+ case HANDLE_RELATIVE_BRACKET_EXCESS_SIZE :
+ case HANDLE_RELATIVE_BRACKET_DISTANCE :
+ case HANDLE_RELATIVE_SCALE_BRACKET_EXCESS_SIZE :
+ case HANDLE_RELATIVE_MATRIX_LINE_SPACING :
+ case HANDLE_RELATIVE_MATRIX_COLUMN_SPACING :
+ case HANDLE_RELATIVE_SYMBOL_PRIMARY_HEIGHT :
+ case HANDLE_RELATIVE_SYMBOL_MINIMUM_HEIGHT :
+ case HANDLE_RELATIVE_OPERATOR_EXCESS_SIZE :
+ case HANDLE_RELATIVE_OPERATOR_SPACING :
+ case HANDLE_LEFT_MARGIN :
+ case HANDLE_RIGHT_MARGIN :
+ case HANDLE_TOP_MARGIN :
+ case HANDLE_BOTTOM_MARGIN :
+ *pValue <<= (sal_Int16)aFormat.GetDistance((*ppEntries)->mnMemberId);
+ break;
+ case HANDLE_IS_SCALE_ALL_BRACKETS :
+ {
+ sal_Bool bVal = aFormat.IsScaleNormalBrackets();
+ (*pValue).setValue(&bVal, ::getBooleanCppuType());
+ }
+ break;
+ case HANDLE_PRINTER_NAME:
+ {
+ SfxPrinter *pPrinter = pDocSh->GetPrinter ( );
+ *pValue <<= pPrinter ? OUString ( pPrinter->GetName()) : OUString();
+ }
+ break;
+ case HANDLE_PRINTER_SETUP:
+ {
+ SfxPrinter *pPrinter = pDocSh->GetPrinter ();
+ if (pPrinter)
+ {
+ SvMemoryStream aStream;
+ pPrinter->Store( aStream );
+ aStream.Seek ( STREAM_SEEK_TO_END );
+ sal_uInt32 nSize = aStream.Tell();
+ aStream.Seek ( STREAM_SEEK_TO_BEGIN );
+ Sequence < sal_Int8 > aSequence ( nSize );
+ aStream.Read ( aSequence.getArray(), nSize );
+ *pValue <<= aSequence;
+ }
+ }
+ break;
+ case HANDLE_SYMBOLS:
+ case HANDLE_USED_SYMBOLS:
+ {
+ const bool bUsedSymbolsOnly = (*ppEntries)->mnHandle == HANDLE_USED_SYMBOLS;
+ const std::set< rtl::OUString > &rUsedSymbols = pDocSh->GetUsedSymbols();
+
+ // this is get
+ SmModule *pp = SM_MOD();
+ const SmSymbolManager &rManager = pp->GetSymbolManager();
+ vector < const SmSym * > aVector;
+
+ const SymbolPtrVec_t aSymbols( rManager.GetSymbols() );
+ size_t nCount = 0;
+ for (size_t i = 0; i < aSymbols.size(); ++i)
+ {
+ const SmSym * pSymbol = aSymbols[ i ];
+ const bool bIsUsedSymbol = rUsedSymbols.find( pSymbol->GetName() ) != rUsedSymbols.end();
+ if (pSymbol && !pSymbol->IsPredefined() &&
+ (!bUsedSymbolsOnly || bIsUsedSymbol))
+ {
+ aVector.push_back ( pSymbol );
+ nCount++;
+ }
+ }
+ Sequence < SymbolDescriptor > aSequence ( nCount );
+ SymbolDescriptor * pDescriptor = aSequence.getArray();
+
+ vector < const SmSym * >::const_iterator aIter = aVector.begin(), aEnd = aVector.end();
+ for(; aIter != aEnd; pDescriptor++, aIter++)
+ {
+ pDescriptor->sName = (*aIter)->GetName();
+ pDescriptor->sExportName = (*aIter)->GetExportName();
+ pDescriptor->sSymbolSet = (*aIter)->GetSymbolSetName();
+ pDescriptor->nCharacter = static_cast < sal_Int32 > ((*aIter)->GetCharacter());
+
+ Font rFont = (*aIter)->GetFace();
+ pDescriptor->sFontName = rFont.GetName();
+ pDescriptor->nCharSet = sal::static_int_cast< sal_Int16 >(rFont.GetCharSet());
+ pDescriptor->nFamily = sal::static_int_cast< sal_Int16 >(rFont.GetFamily());
+ pDescriptor->nPitch = sal::static_int_cast< sal_Int16 >(rFont.GetPitch());
+ pDescriptor->nWeight = sal::static_int_cast< sal_Int16 >(rFont.GetWeight());
+ pDescriptor->nItalic = sal::static_int_cast< sal_Int16 >(rFont.GetItalic());
+ }
+ *pValue <<= aSequence;
+ }
+ break;
+ case HANDLE_BASIC_LIBRARIES:
+ *pValue <<= pDocSh->GetBasicContainer();
+ break;
+ case HANDLE_DIALOG_LIBRARIES:
+ *pValue <<= pDocSh->GetDialogContainer();
+ break;
+ case HANDLE_RUNTIME_UID:
+ *pValue <<= getRuntimeUID();
+ break;
+ // --> PB 2004-08-25 #i33095# Security Options
+ case HANDLE_LOAD_READONLY :
+ {
+ *pValue <<= pDocSh->IsLoadReadonly();
+ break;
+ }
+ // <--
+ // --> 3.7.2010 #i972#
+ case HANDLE_BASELINE:
+ {
+ if ( !pDocSh->pTree )
+ pDocSh->Parse();
+ if ( pDocSh->pTree )
+ {
+ if ( !pDocSh->IsFormulaArranged() )
+ pDocSh->ArrangeFormula();
+
+ *pValue <<= static_cast<sal_Int32>( pDocSh->pTree->GetFormulaBaseline() );
+ }
+ }
+ break;
+ // <--
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+
+sal_Int32 SAL_CALL SmModel::getRendererCount(
+ const uno::Any& /*rSelection*/,
+ const uno::Sequence< beans::PropertyValue >& /*xOptions*/ )
+ throw (IllegalArgumentException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return 1;
+}
+
+
+static Size lcl_GuessPaperSize()
+{
+ Size aRes;
+ Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() );
+ LocaleDataWrapper aLocWrp( xMgr, AllSettings().GetLocale() );
+ if( MEASURE_METRIC == aLocWrp.getMeasurementSystemEnum() )
+ {
+ // in 100th mm
+ PaperInfo aInfo( PAPER_A4 );
+ aRes.Width() = aInfo.getWidth();
+ aRes.Height() = aInfo.getHeight();
+ }
+ else
+ {
+ // in 100th mm
+ PaperInfo aInfo( PAPER_LETTER );
+ aRes.Width() = aInfo.getWidth();
+ aRes.Height() = aInfo.getHeight();
+ }
+ return aRes;
+}
+
+uno::Sequence< beans::PropertyValue > SAL_CALL SmModel::getRenderer(
+ sal_Int32 nRenderer,
+ const uno::Any& /*rSelection*/,
+ const uno::Sequence< beans::PropertyValue >& /*rxOptions*/ )
+ throw (IllegalArgumentException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ if (0 != nRenderer)
+ throw IllegalArgumentException();
+
+ SmDocShell *pDocSh = static_cast < SmDocShell * >( GetObjectShell() );
+ if (!pDocSh)
+ throw RuntimeException();
+
+ SmPrinterAccess aPrinterAccess( *pDocSh );
+ Printer *pPrinter = aPrinterAccess.GetPrinter();
+ Size aPrtPaperSize ( pPrinter->GetPaperSize() );
+
+ // if paper size is 0 (usually if no 'real' printer is found),
+ // guess the paper size
+ if (aPrtPaperSize.Height() == 0 || aPrtPaperSize.Width() == 0)
+ aPrtPaperSize = lcl_GuessPaperSize();
+ awt::Size aPageSize( aPrtPaperSize.Width(), aPrtPaperSize.Height() );
+
+ uno::Sequence< beans::PropertyValue > aRenderer(1);
+ PropertyValue &rValue = aRenderer.getArray()[0];
+ rValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) );
+ rValue.Value <<= aPageSize;
+
+ if (!m_pPrintUIOptions)
+ m_pPrintUIOptions = new SmPrintUIOptions();
+ m_pPrintUIOptions->appendPrintUIOptions( aRenderer );
+
+ return aRenderer;
+}
+
+void SAL_CALL SmModel::render(
+ sal_Int32 nRenderer,
+ const uno::Any& rSelection,
+ const uno::Sequence< beans::PropertyValue >& rxOptions )
+ throw (IllegalArgumentException, RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ if (0 != nRenderer)
+ throw IllegalArgumentException();
+
+ SmDocShell *pDocSh = static_cast < SmDocShell * >( GetObjectShell() );
+ if (!pDocSh)
+ throw RuntimeException();
+
+ // get device to be rendered in
+ uno::Reference< awt::XDevice > xRenderDevice;
+ for (sal_Int32 i = 0, nCount = rxOptions.getLength(); i < nCount; ++i)
+ {
+ if( rxOptions[i].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) ) )
+ rxOptions[i].Value >>= xRenderDevice;
+ }
+
+ if (xRenderDevice.is())
+ {
+ VCLXDevice* pDevice = VCLXDevice::GetImplementation( xRenderDevice );
+ OutputDevice* pOut = pDevice ? pDevice->GetOutputDevice() : NULL;
+
+ if (!pOut)
+ throw RuntimeException();
+
+ pOut->SetMapMode( MAP_100TH_MM );
+
+ uno::Reference< frame::XModel > xModel;
+ rSelection >>= xModel;
+ if (xModel == pDocSh->GetModel())
+ {
+ //!! when called via API we may not have an active view
+ //!! thus we go and look for a view that can be used.
+ const TypeId aTypeId = TYPE( SmViewShell );
+ SfxViewShell* pViewSh = SfxViewShell::GetFirst( &aTypeId, sal_False /* search non-visible views as well*/ );
+ while (pViewSh && pViewSh->GetObjectShell() != pDocSh)
+ pViewSh = SfxViewShell::GetNext( *pViewSh, &aTypeId, sal_False /* search non-visible views as well*/ );
+ SmViewShell *pView = PTR_CAST( SmViewShell, pViewSh );
+ OSL_ENSURE( pView, "SmModel::render : no SmViewShell found" );
+
+ if (pView)
+ {
+ SmPrinterAccess aPrinterAccess( *pDocSh );
+ Printer *pPrinter = aPrinterAccess.GetPrinter();
+
+ Size aPrtPaperSize ( pPrinter->GetPaperSize() );
+ Size aOutputSize ( pPrinter->GetOutputSize() );
+ Point aPrtPageOffset( pPrinter->GetPageOffset() );
+
+ // no real printer ??
+ if (aPrtPaperSize.Height() == 0 || aPrtPaperSize.Width() == 0)
+ {
+ aPrtPaperSize = lcl_GuessPaperSize();
+ // factors from Windows DIN A4
+ aOutputSize = Size( (long)(aPrtPaperSize.Width() * 0.941),
+ (long)(aPrtPaperSize.Height() * 0.961));
+ aPrtPageOffset = Point( (long)(aPrtPaperSize.Width() * 0.0250),
+ (long)(aPrtPaperSize.Height() * 0.0214));
+ }
+ Point aZeroPoint;
+ Rectangle OutputRect( aZeroPoint, aOutputSize );
+
+
+ // set minimum top and bottom border
+ if (aPrtPageOffset.Y() < 2000)
+ OutputRect.Top() += 2000 - aPrtPageOffset.Y();
+ if ((aPrtPaperSize.Height() - (aPrtPageOffset.Y() + OutputRect.Bottom())) < 2000)
+ OutputRect.Bottom() -= 2000 - (aPrtPaperSize.Height() -
+ (aPrtPageOffset.Y() + OutputRect.Bottom()));
+
+ // set minimum left and right border
+ if (aPrtPageOffset.X() < 2500)
+ OutputRect.Left() += 2500 - aPrtPageOffset.X();
+ if ((aPrtPaperSize.Width() - (aPrtPageOffset.X() + OutputRect.Right())) < 1500)
+ OutputRect.Right() -= 1500 - (aPrtPaperSize.Width() -
+ (aPrtPageOffset.X() + OutputRect.Right()));
+
+ if (!m_pPrintUIOptions)
+ m_pPrintUIOptions = new SmPrintUIOptions();
+ m_pPrintUIOptions->processProperties( rxOptions );
+
+ pView->Impl_Print( *pOut, *m_pPrintUIOptions, Rectangle( OutputRect ), Point() );
+
+ // release SmPrintUIOptions when everything is done.
+ // That way, when SmPrintUIOptions is needed again it will read the latest configuration settings in its c-tor.
+ if (m_pPrintUIOptions->getBoolValue( "IsLastPage", sal_False ))
+ {
+ delete m_pPrintUIOptions; m_pPrintUIOptions = 0;
+ }
+ }
+ }
+ }
+}
+
+void SAL_CALL SmModel::setParent( const uno::Reference< uno::XInterface >& xParent)
+ throw( lang::NoSupportException, uno::RuntimeException )
+{
+ SolarMutexGuard aGuard;
+ SfxBaseModel::setParent( xParent );
+ uno::Reference< lang::XUnoTunnel > xParentTunnel( xParent, uno::UNO_QUERY );
+ if ( xParentTunnel.is() )
+ {
+ SvGlobalName aSfxIdent( SFX_GLOBAL_CLASSID );
+ SfxObjectShell* pDoc = reinterpret_cast<SfxObjectShell *>(xParentTunnel->getSomething(
+ uno::Sequence< sal_Int8 >( aSfxIdent.GetByteSequence() ) ) );
+ if ( pDoc )
+ GetObjectShell()->OnDocumentPrinterChanged( pDoc->GetDocumentPrinter() );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/utility.cxx b/starmath/source/utility.cxx
new file mode 100644
index 000000000000..a5e4cc3d6ccd
--- /dev/null
+++ b/starmath/source/utility.cxx
@@ -0,0 +1,378 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <sfx2/app.hxx>
+#include <vcl/virdev.hxx>
+#include <tools/string.hxx>
+#include <tools/tenccvt.hxx>
+#include <osl/thread.h>
+
+#include <tools/stream.hxx>
+
+#include "starmath.hrc"
+
+#include "utility.hxx"
+#include "dialog.hxx"
+#include "view.hxx"
+#include "smdll.hxx"
+
+
+////////////////////////////////////////////////////////////
+
+// return pointer to active SmViewShell, if this is not possible
+// return 0 instead.
+//!! Since this method is based on the current focus it is somewhat
+//!! unreliable and may return unexpected 0 pointers!
+SmViewShell * SmGetActiveView()
+{
+ SfxViewShell *pView = SfxViewShell::Current();
+ return PTR_CAST(SmViewShell, pView);
+}
+
+
+////////////////////////////////////////////////////////////
+
+
+/**************************************************************************/
+
+SmPickList::SmPickList(sal_uInt16 nInitSize, sal_uInt16 nMaxSize) :
+ SfxPtrArr((sal_uInt8) nInitSize, 1)
+{
+ nSize = nMaxSize;
+}
+
+
+SmPickList::~SmPickList()
+{
+ Clear();
+}
+
+
+SmPickList& SmPickList::operator=(const SmPickList& rList)
+{
+ sal_uInt16 nPos;
+
+ Clear();
+ nSize = rList.nSize;
+ for (nPos = 0; nPos < rList.Count(); nPos++)
+ InsertPtr(nPos, CreateItem(rList.Get(nPos)));
+
+ return *this;
+}
+
+
+void SmPickList::Insert(const void *pItem)
+{
+ Remove(pItem);
+ InsertPtr(0, CreateItem(pItem));
+
+ if (Count() > nSize)
+ {
+ DestroyItem(GetPtr(nSize));
+ RemovePtr(nSize, 1);
+ }
+}
+
+
+void SmPickList::Update(const void *pItem, const void *pNewItem)
+{
+ sal_uInt16 nPos;
+
+ for (nPos = 0; nPos < Count(); nPos++)
+ if (CompareItem(GetPtr(nPos), pItem))
+ {
+ DestroyItem(GetPtr(nPos));
+ GetPtr(nPos) = CreateItem(pNewItem);
+ break;
+ }
+}
+
+void SmPickList::Remove(const void *pItem)
+{
+ sal_uInt16 nPos;
+
+ for (nPos = 0; nPos < Count(); nPos++)
+ if (CompareItem(GetPtr(nPos), pItem))
+ {
+ DestroyItem(GetPtr(nPos));
+ RemovePtr(nPos, 1);
+ break;
+ }
+}
+
+void SmPickList::Clear()
+{
+ sal_uInt16 nPos;
+
+ for (nPos = 0; nPos < Count(); nPos++)
+ DestroyItem(GetPtr(nPos));
+
+ RemovePtr(0, Count());
+}
+
+
+/**************************************************************************/
+
+void * SmFontPickList::CreateItem(const String& /*rString*/)
+{
+ return new Font();
+}
+
+void * SmFontPickList::CreateItem(const void *pItem)
+{
+ return new Font(*((Font *) pItem));
+}
+
+void SmFontPickList::DestroyItem(void *pItem)
+{
+ delete (Font *)pItem;
+}
+
+bool SmFontPickList::CompareItem(const void *pFirstItem, const void *pSecondItem) const
+{
+ Font *pFirstFont, *pSecondFont;
+
+ pFirstFont = (Font *)pFirstItem;
+ pSecondFont = (Font *)pSecondItem;
+
+ if (pFirstFont->GetName() == pSecondFont->GetName())
+ if ((pFirstFont->GetFamily() == pSecondFont->GetFamily()) &&
+ (pFirstFont->GetCharSet() == pSecondFont->GetCharSet()) &&
+ (pFirstFont->GetWeight() == pSecondFont->GetWeight()) &&
+ (pFirstFont->GetItalic() == pSecondFont->GetItalic()))
+ return (true);
+
+ return false;
+}
+
+String SmFontPickList::GetStringItem(void *pItem)
+{
+ Font *pFont;
+ String aString;
+ const sal_Char *pDelim = ", ";
+
+ pFont = (Font *)pItem;
+
+ aString = pFont->GetName();
+
+ if (IsItalic( *pFont ))
+ {
+ aString.AppendAscii( pDelim );
+ aString += String(SmResId(RID_FONTITALIC));
+ }
+ if (IsBold( *pFont ))
+ {
+ aString.AppendAscii( pDelim );
+ aString += String(SmResId(RID_FONTBOLD));
+ }
+
+ return (aString);
+}
+
+void SmFontPickList::Insert(const Font &rFont)
+{
+ SmPickList::Insert((void *)&rFont);
+}
+
+void SmFontPickList::Update(const Font &rFont, const Font &rNewFont)
+{
+ SmPickList::Update((void *)&rFont, (void *)&rNewFont);
+}
+
+void SmFontPickList::Remove(const Font &rFont)
+{
+ SmPickList::Remove((void *)&rFont);
+}
+
+
+void SmFontPickList::ReadFrom(const SmFontDialog& rDialog)
+{
+ Insert(rDialog.GetFont());
+}
+
+void SmFontPickList::WriteTo(SmFontDialog& rDialog) const
+{
+ rDialog.SetFont(Get());
+}
+
+
+/**************************************************************************/
+
+
+IMPL_LINK( SmFontPickListBox, SelectHdl, ListBox *, /*pListBox*/ )
+{
+ sal_uInt16 nPos;
+ String aString;
+
+ nPos = GetSelectEntryPos();
+
+ if (nPos != 0)
+ {
+ SmFontPickList::Insert(Get(nPos));
+ aString = GetEntry(nPos);
+ RemoveEntry(nPos);
+ InsertEntry(aString, 0);
+ }
+
+ SelectEntryPos(0);
+
+ return 0;
+}
+
+
+SmFontPickListBox::SmFontPickListBox(Window* pParent, const ResId& rResId, sal_uInt16 nMax) :
+ SmFontPickList(nMax, nMax),
+ ListBox(pParent, rResId)
+{
+ SetSelectHdl(LINK(this, SmFontPickListBox, SelectHdl));
+}
+
+
+SmFontPickListBox& SmFontPickListBox::operator=(const SmFontPickList& rList)
+{
+ sal_uInt16 nPos;
+
+ *(SmFontPickList *)this = rList;
+
+ for (nPos = 0; nPos < Count(); nPos++)
+ InsertEntry(GetStringItem(GetPtr(nPos)), nPos);
+
+ if (Count() > 0)
+ SelectEntry(GetStringItem(GetPtr(0)));
+
+ return *this;
+}
+
+void SmFontPickListBox::Insert(const Font &rFont)
+{
+ SmFontPickList::Insert(rFont);
+
+ RemoveEntry(GetStringItem(GetPtr(0)));
+ InsertEntry(GetStringItem(GetPtr(0)), 0);
+ SelectEntry(GetStringItem(GetPtr(0)));
+
+ while (GetEntryCount() > nSize)
+ RemoveEntry(GetEntryCount() - 1);
+
+ return;
+}
+
+
+void SmFontPickListBox::Update(const Font &rFont, const Font &rNewFont)
+{
+ SmFontPickList::Update(rFont, rNewFont);
+
+ return;
+}
+
+
+void SmFontPickListBox::Remove(const Font &rFont)
+{
+ SmFontPickList::Remove(rFont);
+
+ return;
+}
+
+////////////////////////////////////////
+
+bool IsItalic( const Font &rFont )
+{
+ FontItalic eItalic = rFont.GetItalic();
+ // the code below leaves only _NONE and _DONTKNOW as not italic
+ return eItalic == ITALIC_OBLIQUE || eItalic == ITALIC_NORMAL;
+}
+
+
+bool IsBold( const Font &rFont )
+{
+ FontWeight eWeight = rFont.GetWeight();
+ return eWeight != WEIGHT_DONTKNOW && eWeight > WEIGHT_NORMAL;
+}
+
+
+void SmFace::Impl_Init()
+{
+ SetSize( GetSize() );
+ SetTransparent( true );
+ SetAlign( ALIGN_BASELINE );
+ SetColor( COL_AUTO );
+}
+
+void SmFace::SetSize(const Size& rSize)
+{
+ Size aSize (rSize);
+
+ // check the requested size against minimum value
+ static int const nMinVal = SmPtsTo100th_mm(2);
+
+ if (aSize.Height() < nMinVal)
+ aSize.Height() = nMinVal;
+
+ //! we don't force a maximum value here because this may prevent eg the
+ //! parentheses in "left ( ... right )" from matching up with large
+ //! bodies (eg stack{...} with many entries).
+ //! Of course this is holds only if characters are used and not polygons.
+
+ Font::SetSize(aSize);
+}
+
+
+long SmFace::GetBorderWidth() const
+{
+ if (nBorderWidth < 0)
+ return GetDefaultBorderWidth();
+ else
+ return nBorderWidth;
+}
+
+SmFace & SmFace::operator = (const SmFace &rFace)
+{
+ Font::operator = (rFace);
+ nBorderWidth = -1;
+ return *this;
+}
+
+
+SmFace & operator *= (SmFace &rFace, const Fraction &rFrac)
+ // scales the width and height of 'rFace' by 'rFrac' and returns a
+ // reference to 'rFace'.
+ // It's main use is to make scaling fonts look easier.
+{ const Size &rFaceSize = rFace.GetSize();
+
+ rFace.SetSize(Size(Fraction(rFaceSize.Width()) *= rFrac,
+ Fraction(rFaceSize.Height()) *= rFrac));
+ return rFace;
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/view.cxx b/starmath/source/view.cxx
new file mode 100644
index 000000000000..641a8f6bcfaf
--- /dev/null
+++ b/starmath/source/view.cxx
@@ -0,0 +1,2124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/container/XChild.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <rtl/logfile.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docinsert.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/request.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/itemset.hxx>
+#include <svl/poolitem.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/transfer.hxx>
+#include <svtools/miscopt.hxx>
+#include <svl/undo.hxx>
+#include <svl/whiter.hxx>
+#include <svx/dialogs.hrc>
+#include <editeng/editeng.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/zoomitem.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/wrkwin.hxx>
+#include <fstream>
+
+#include "unomodel.hxx"
+#include "view.hxx"
+#include "config.hxx"
+#include "dialog.hxx"
+#include "document.hxx"
+#include "starmath.hrc"
+#include "toolbox.hxx"
+#include "mathmlimport.hxx"
+#include "cursor.hxx"
+#include "accessibility.hxx"
+
+#define MINWIDTH 200
+#define MINHEIGHT 200
+#define MINSPLIT 40
+#define SPLITTERWIDTH 2
+
+#define MINZOOM 25
+#define MAXZOOM 800
+
+#define SmViewShell
+#include "smslots.hxx"
+
+using namespace com::sun::star;
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+//////////////////////////////////////////////////////////////////////
+
+SmGraphicWindow::SmGraphicWindow(SmViewShell* pShell):
+ ScrollableWindow(&pShell->GetViewFrame()->GetWindow(), 0),
+ pAccessible(0),
+ pViewShell(pShell),
+ nZoom(100)
+{
+ // docking windows are usually hidden (often already done in the
+ // resource) and will be shown by the sfx framework.
+ Hide();
+
+ const Fraction aFraction (1,1);
+ SetMapMode( MapMode(MAP_100TH_MM, Point(), aFraction, aFraction));
+
+ ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
+
+ SetTotalSize();
+
+ SetHelpId(HID_SMA_WIN_DOCUMENT);
+ SetUniqueId(HID_SMA_WIN_DOCUMENT);
+
+ ShowLine(false);
+ CaretBlinkInit();
+}
+
+SmGraphicWindow::~SmGraphicWindow()
+{
+ if (pAccessible)
+ pAccessible->ClearWin(); // make Accessible defunctional
+ // Note: memory for pAccessible will be freed when the reference
+ // xAccessible is released.
+ CaretBlinkStop();
+}
+
+void SmGraphicWindow::StateChanged( StateChangedType eType )
+{
+ if ( eType == STATE_CHANGE_INITSHOW )
+ Show();
+ ScrollableWindow::StateChanged( eType );
+}
+
+
+void SmGraphicWindow::ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg )
+{
+ // Note: SetTextColor not necessary since the nodes that
+ // get painted have the color information.
+#if OSL_DEBUG_LEVEL > 1
+// ColorData nVal = rColorCfg.GetColorValue(svtools::DOCCOLOR).nColor;
+#endif
+ SetBackground( Color( (ColorData) rColorCfg.GetColorValue(svtools::DOCCOLOR).nColor ) );
+ Invalidate();
+}
+
+
+void SmGraphicWindow::DataChanged( const DataChangedEvent& rEvt )
+{
+ ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
+
+ ScrollableWindow::DataChanged( rEvt );
+}
+
+
+void SmGraphicWindow::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ ScrollableWindow::MouseButtonDown(rMEvt);
+
+ GrabFocus();
+
+ //
+ // set formula-cursor and selection of edit window according to the
+ // position clicked at
+ //
+ DBG_ASSERT(rMEvt.GetClicks() > 0, "Sm : 0 clicks");
+ if ( rMEvt.IsLeft() )
+ {
+ // get click position relativ to formula
+ Point aPos (PixelToLogic(rMEvt.GetPosPixel())
+ - GetFormulaDrawPos());
+
+ const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree();
+ if (!pTree)
+ return;
+
+ if (IsInlineEditEnabled()) {
+ // if it was clicked inside the formula then get the appropriate node
+ if (pTree->OrientedDist(aPos) <= 0)
+ pViewShell->GetDoc()->GetCursor().MoveTo(this, aPos, !rMEvt.IsShift());
+ return;
+ }
+ const SmNode *pNode = 0;
+ // if it was clicked inside the formula then get the appropriate node
+ if (pTree->OrientedDist(aPos) <= 0)
+ pNode = pTree->FindRectClosestTo(aPos);
+
+ if (pNode)
+ { SmEditWindow *pEdit = pViewShell->GetEditWindow();
+ if (!pEdit)
+ return;
+ const SmToken aToken (pNode->GetToken());
+
+ // set selection to the beginning of the token
+ ESelection aSel (aToken.nRow - 1, aToken.nCol - 1);
+
+ if (rMEvt.GetClicks() != 1 || aToken.eType == TPLACE)
+ aSel.nEndPos = aSel.nEndPos + sal::static_int_cast< sal_uInt16 >(aToken.aText.Len());
+
+ pEdit->SetSelection(aSel);
+ SetCursor(pNode);
+
+ // allow for immediate editing and
+ //! implicitly synchronize the cursor position mark in this window
+ pEdit->GrabFocus();
+ }
+ }
+}
+
+bool SmGraphicWindow::IsInlineEditEnabled() const
+{
+ return pViewShell->IsInlineEditEnabled();
+}
+
+void SmGraphicWindow::GetFocus()
+{
+ if (!IsInlineEditEnabled())
+ return;
+ if (pViewShell->GetEditWindow())
+ pViewShell->GetEditWindow()->Flush();
+ //Let view shell know what insertions should be done in visual editor
+ pViewShell->SetInsertIntoEditWindow(false);
+ SetIsCursorVisible(true);
+ ShowLine(true);
+ CaretBlinkStart();
+ RepaintViewShellDoc();
+}
+
+void SmGraphicWindow::LoseFocus()
+{
+ ScrollableWindow::LoseFocus();
+ if (xAccessible.is())
+ {
+ uno::Any aOldValue, aNewValue;
+ aOldValue <<= AccessibleStateType::FOCUSED;
+ // aNewValue remains empty
+ pAccessible->LaunchEvent( AccessibleEventId::STATE_CHANGED,
+ aOldValue, aNewValue );
+ }
+ if (!IsInlineEditEnabled())
+ return;
+ SetIsCursorVisible(false);
+ ShowLine(false);
+ CaretBlinkStop();
+ RepaintViewShellDoc();
+}
+
+void SmGraphicWindow::RepaintViewShellDoc()
+{
+ SmDocShell &rDoc = *pViewShell->GetDoc();
+ rDoc.Repaint();
+}
+
+IMPL_LINK( SmGraphicWindow, CaretBlinkTimerHdl, AutoTimer *, EMPTYARG )
+{
+ if (IsCursorVisible())
+ SetIsCursorVisible(false);
+ else
+ SetIsCursorVisible(true);
+
+ RepaintViewShellDoc();
+
+ return 0;
+}
+
+void SmGraphicWindow::CaretBlinkInit()
+{
+ aCaretBlinkTimer.SetTimeoutHdl(LINK(this, SmGraphicWindow, CaretBlinkTimerHdl));
+ aCaretBlinkTimer.SetTimeout( ScrollableWindow::GetSettings().GetStyleSettings().GetCursorBlinkTime() );
+}
+
+void SmGraphicWindow::CaretBlinkStart()
+{
+ if (!IsInlineEditEnabled())
+ return;
+ if ( aCaretBlinkTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME )
+ aCaretBlinkTimer.Start();
+}
+
+void SmGraphicWindow::CaretBlinkStop()
+{
+ if (!IsInlineEditEnabled())
+ return;
+ aCaretBlinkTimer.Stop();
+}
+
+void SmGraphicWindow::ShowCursor(bool bShow)
+ // shows or hides the formula-cursor depending on 'bShow' is true or not
+{
+ if (IsInlineEditEnabled())
+ return;
+
+ bool bInvert = bShow != IsCursorVisible();
+
+ if (bInvert)
+ InvertTracking(aCursorRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW);
+
+ SetIsCursorVisible(bShow);
+}
+
+void SmGraphicWindow::ShowLine(bool bShow)
+{
+ if (!IsInlineEditEnabled())
+ return;
+
+ bIsLineVisible = bShow;
+}
+
+void SmGraphicWindow::SetCursor(const SmNode *pNode)
+{
+ if (IsInlineEditEnabled())
+ return;
+
+ const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree();
+
+ // get appropriate rectangle
+ Point aOffset (pNode->GetTopLeft() - pTree->GetTopLeft()),
+ aTLPos (GetFormulaDrawPos() + aOffset);
+ aTLPos.X() -= pNode->GetItalicLeftSpace();
+ Size aSize (pNode->GetItalicSize());
+ Point aBRPos (aTLPos.X() + aSize.Width(), aTLPos.Y() + aSize.Height());
+
+ SetCursor(Rectangle(aTLPos, aSize));
+}
+
+void SmGraphicWindow::SetCursor(const Rectangle &rRect)
+ // sets cursor to new position (rectangle) 'rRect'.
+ // The old cursor will be removed, and the new one will be shown if
+ // that is activated in the ConfigItem
+{
+ if (IsInlineEditEnabled())
+ return;
+
+ SmModule *pp = SM_MOD();
+
+ if (IsCursorVisible())
+ ShowCursor(false); // clean up remainings of old cursor
+ aCursorRect = rRect;
+ if (pp->GetConfig()->IsShowFormulaCursor())
+ ShowCursor(true); // draw new cursor
+}
+
+const SmNode * SmGraphicWindow::SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol)
+ // looks for a VISIBLE node in the formula tree with it's token at
+ // (or around) the position 'nRow', 'nCol' in the edit window
+ // (row and column numbering starts with 1 there!).
+ // If there is such a node the formula-cursor is set to cover that nodes
+ // rectangle. If not the formula-cursor will be hidden.
+ // In any case the search result is being returned.
+{
+ if (IsInlineEditEnabled())
+ return NULL;
+
+ // find visible node with token at nRow, nCol
+ const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(),
+ *pNode = 0;
+ if (pTree)
+ pNode = pTree->FindTokenAt(nRow, nCol);
+
+ if (pNode)
+ SetCursor(pNode);
+ else
+ ShowCursor(false);
+
+ return pNode;
+}
+
+void SmGraphicWindow::Paint(const Rectangle&)
+{
+ OSL_ENSURE(pViewShell, "Sm : NULL pointer");
+
+ SmDocShell &rDoc = *pViewShell->GetDoc();
+ Point aPoint;
+
+ rDoc.DrawFormula(*this, aPoint, true); //! modifies aPoint to be the topleft
+ //! corner of the formula
+ SetFormulaDrawPos(aPoint);
+ if(IsInlineEditEnabled()) {
+ //Draw cursor if any...
+ if(pViewShell->GetDoc()->HasCursor() && IsLineVisible())
+ pViewShell->GetDoc()->GetCursor().Draw(*this, aPoint, IsCursorVisible());
+ } else {
+ SetIsCursorVisible(false); // (old) cursor must be drawn again
+
+ const SmEditWindow *pEdit = pViewShell->GetEditWindow();
+ if (pEdit)
+ { // get new position for formula-cursor (for possible altered formula)
+ sal_uInt16 nRow, nCol;
+ SmGetLeftSelectionPart(pEdit->GetSelection(), nRow, nCol);
+ nRow++;
+ nCol++;
+ const SmNode *pFound = SetCursorPos(nRow, nCol);
+
+ SmModule *pp = SM_MOD();
+ if (pFound && pp->GetConfig()->IsShowFormulaCursor())
+ ShowCursor(true);
+ }
+ }
+}
+
+
+void SmGraphicWindow::SetTotalSize ()
+{
+ SmDocShell &rDoc = *pViewShell->GetDoc();
+ const Size aTmp( PixelToLogic( LogicToPixel( rDoc.GetSize() )));
+ if ( aTmp != ScrollableWindow::GetTotalSize() )
+ ScrollableWindow::SetTotalSize( aTmp );
+}
+
+void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt)
+{
+ if (!IsInlineEditEnabled()) {
+ if (! (GetView() && GetView()->KeyInput(rKEvt)) )
+ ScrollableWindow::KeyInput(rKEvt);
+ return;
+ }
+ sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
+ SmCursor& rCursor = pViewShell->GetDoc()->GetCursor();
+ switch(nCode)
+ {
+ case KEY_LEFT:
+ {
+ rCursor.Move(this, MoveLeft, !rKEvt.GetKeyCode().IsShift());
+ }break;
+ case KEY_RIGHT:
+ {
+ rCursor.Move(this, MoveRight, !rKEvt.GetKeyCode().IsShift());
+ }break;
+ case KEY_UP:
+ {
+ rCursor.Move(this, MoveUp, !rKEvt.GetKeyCode().IsShift());
+ }break;
+ case KEY_DOWN:
+ {
+ rCursor.Move(this, MoveDown, !rKEvt.GetKeyCode().IsShift());
+ }break;
+ case KEY_RETURN:
+ {
+ if(!rKEvt.GetKeyCode().IsShift())
+ rCursor.InsertRow();
+#ifdef DEBUG_ENABLE_DUMPASDOT
+ else {
+ SmNode *pTree = (SmNode*)pViewShell->GetDoc()->GetFormulaTree();
+ std::fstream file("/tmp/smath-dump.gv", std::fstream::out);
+ String label(pViewShell->GetDoc()->GetText());
+ pTree->DumpAsDot(file, &label);
+ file.close();
+ }
+#endif /* DEBUG_ENABLE_DUMPASDOT */
+ }break;
+ case KEY_DELETE:
+ {
+ if(!rCursor.HasSelection()){
+ rCursor.Move(this, nCode == KEY_DELETE ? MoveRight : MoveLeft, false);
+ if(rCursor.HasComplexSelection()) break;
+ }
+ rCursor.Delete();
+ }break;
+ case KEY_BACKSPACE:
+ {
+ rCursor.DeletePrev(this);
+ }break;
+ case KEY_ADD:
+ rCursor.InsertElement(PlusElement);
+ break;
+ case KEY_SUBTRACT:
+ if(rKEvt.GetKeyCode().IsShift())
+ rCursor.InsertSubSup(RSUB);
+ else
+ rCursor.InsertElement(MinusElement);
+ break;
+ case KEY_MULTIPLY:
+ rCursor.InsertElement(CDotElement);
+ break;
+ case KEY_DIVIDE:
+ rCursor.InsertFraction();
+ break;
+ case KEY_LESS:
+ rCursor.InsertElement(LessThanElement);
+ break;
+ case KEY_GREATER:
+ rCursor.InsertElement(GreaterThanElement);
+ break;
+ case KEY_EQUAL:
+ rCursor.InsertElement(EqualElement);
+ break;
+ case KEY_COPY:
+ rCursor.Copy();
+ break;
+ case KEY_CUT:
+ rCursor.Cut();
+ break;
+ case KEY_PASTE:
+ rCursor.Paste();
+ break;
+ default:
+ {
+ sal_Unicode code = rKEvt.GetCharCode();
+ if(code == ' ') {
+ rCursor.InsertElement(BlankElement);
+ }else if(code == 'c' && rKEvt.GetKeyCode().IsMod1()) {
+ rCursor.Copy();
+ }else if(code == 'x' && rKEvt.GetKeyCode().IsMod1()) {
+ rCursor.Cut();
+ }else if(code == 'v' && rKEvt.GetKeyCode().IsMod1()) {
+ rCursor.Paste();
+ }else if(code == '^') {
+ rCursor.InsertSubSup(RSUP);
+ }else if(code == '(') {
+ rCursor.InsertBrackets(RoundBrackets);
+ }else if(code == '[') {
+ rCursor.InsertBrackets(SquareBrackets);
+ }else if(code == '{') {
+ rCursor.InsertBrackets(CurlyBrackets);
+ }else if(code == '!') {
+ rCursor.InsertElement(FactorialElement);
+ }else if(code == '%') {
+ rCursor.InsertElement(PercentElement);
+ }else{
+ if(code != 0){
+ rCursor.InsertText(code);
+ }else if (! (GetView() && GetView()->KeyInput(rKEvt)) )
+ ScrollableWindow::KeyInput(rKEvt);
+ }
+ }
+ }
+ CaretBlinkStop();
+ CaretBlinkStart();
+ SetIsCursorVisible(true);
+ RepaintViewShellDoc();
+}
+
+
+void SmGraphicWindow::Command(const CommandEvent& rCEvt)
+{
+ bool bCallBase = true;
+ if ( !pViewShell->GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ switch ( rCEvt.GetCommand() )
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ GetParent()->ToTop();
+ SmResId aResId( RID_VIEWMENU );
+ PopupMenu* pPopupMenu = new PopupMenu(aResId);
+ pPopupMenu->SetSelectHdl(LINK(this, SmGraphicWindow, MenuSelectHdl));
+ Point aPos(5, 5);
+ if (rCEvt.IsMouseEvent())
+ aPos = rCEvt.GetMousePosPixel();
+ OSL_ENSURE( pViewShell, "view shell missing" );
+
+ // added for replaceability of context menus
+ pViewShell->GetViewFrame()->GetBindings().GetDispatcher()
+ ->ExecutePopup( aResId, this, &aPos );
+
+ delete pPopupMenu;
+ bCallBase = false;
+ }
+ break;
+
+ case COMMAND_WHEEL:
+ {
+ const CommandWheelData* pWData = rCEvt.GetWheelData();
+ if ( pWData && COMMAND_WHEEL_ZOOM == pWData->GetMode() )
+ {
+ sal_uInt16 nTmpZoom = GetZoom();
+ if( 0L > pWData->GetDelta() )
+ nTmpZoom -= 10;
+ else
+ nTmpZoom += 10;
+ SetZoom( nTmpZoom );
+ bCallBase = false;
+ }
+ }
+ break;
+ }
+ }
+ if ( bCallBase )
+ ScrollableWindow::Command (rCEvt);
+}
+
+
+IMPL_LINK_INLINE_START( SmGraphicWindow, MenuSelectHdl, Menu *, pMenu )
+{
+ SmViewShell *pViewSh = GetView();
+ if (pViewSh)
+ pViewSh->GetViewFrame()->GetDispatcher()->Execute( pMenu->GetCurItemId() );
+ return 0;
+}
+IMPL_LINK_INLINE_END( SmGraphicWindow, MenuSelectHdl, Menu *, pMenu )
+
+
+void SmGraphicWindow::SetZoom(sal_uInt16 Factor)
+{
+ nZoom = Min(Max((sal_uInt16) Factor, (sal_uInt16) MINZOOM), (sal_uInt16) MAXZOOM);
+ Fraction aFraction (nZoom, 100);
+ SetMapMode( MapMode(MAP_100TH_MM, Point(), aFraction, aFraction) );
+ SetTotalSize();
+ SmViewShell *pViewSh = GetView();
+ if (pViewSh)
+ pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOM);
+ Invalidate();
+}
+
+
+void SmGraphicWindow::ZoomToFitInWindow()
+{
+ SmDocShell &rDoc = *pViewShell->GetDoc();
+
+ // set defined mapmode before calling 'LogicToPixel' below
+ SetMapMode(MapMode(MAP_100TH_MM));
+
+ Size aSize (LogicToPixel(rDoc.GetSize()));
+ Size aWindowSize (GetSizePixel());
+
+ if (aSize.Width() > 0 && aSize.Height() > 0)
+ {
+ long nVal = Min ((85 * aWindowSize.Width()) / aSize.Width(),
+ (85 * aWindowSize.Height()) / aSize.Height());
+ SetZoom ( sal::static_int_cast< sal_uInt16 >(nVal) );
+ }
+}
+
+uno::Reference< XAccessible > SmGraphicWindow::CreateAccessible()
+{
+ if (!pAccessible)
+ {
+ pAccessible = new SmGraphicAccessible( this );
+ xAccessible = pAccessible;
+ }
+ return xAccessible;
+}
+
+/**************************************************************************/
+
+
+SmGraphicController::SmGraphicController(SmGraphicWindow &rSmGraphic,
+ sal_uInt16 nId_,
+ SfxBindings &rBindings) :
+ SfxControllerItem(nId_, rBindings),
+ rGraphic(rSmGraphic)
+{
+}
+
+
+void SmGraphicController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
+{
+ rGraphic.SetTotalSize();
+ rGraphic.Invalidate();
+ SfxControllerItem::StateChanged (nSID, eState, pState);
+}
+
+
+/**************************************************************************/
+
+
+SmEditController::SmEditController(SmEditWindow &rSmEdit,
+ sal_uInt16 nId_,
+ SfxBindings &rBindings) :
+ SfxControllerItem(nId_, rBindings),
+ rEdit(rSmEdit)
+{
+}
+
+
+#if OSL_DEBUG_LEVEL > 1
+SmEditController::~SmEditController()
+{
+}
+#endif
+
+
+void SmEditController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
+{
+ const SfxStringItem *pItem = PTR_CAST(SfxStringItem, pState);
+
+ if ((pItem != NULL) && (rEdit.GetText() != pItem->GetValue()))
+ rEdit.SetText(pItem->GetValue());
+ SfxControllerItem::StateChanged (nSID, eState, pState);
+}
+
+
+/**************************************************************************/
+
+SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings *pBindings_, SfxChildWindow *pChildWindow,
+ Window *pParent) :
+ SfxDockingWindow(pBindings_, pChildWindow, pParent, SmResId(RID_CMDBOXWINDOW)),
+ aEdit (*this),
+ aController (aEdit, SID_TEXT, *pBindings_),
+ bExiting (false)
+{
+ Hide ();
+
+ aInitialFocusTimer.SetTimeoutHdl(LINK(this, SmCmdBoxWindow, InitialFocusTimerHdl));
+ aInitialFocusTimer.SetTimeout(100);
+}
+
+
+SmCmdBoxWindow::~SmCmdBoxWindow ()
+{
+ aInitialFocusTimer.Stop();
+ bExiting = true;
+}
+
+
+SmViewShell * SmCmdBoxWindow::GetView()
+{
+ SfxDispatcher *pDispatcher = GetBindings().GetDispatcher();
+ SfxViewShell *pView = pDispatcher ? pDispatcher->GetFrame()->GetViewShell() : NULL;
+ return PTR_CAST(SmViewShell, pView);
+}
+
+void SmCmdBoxWindow::Resize()
+{
+ Rectangle aRect = Rectangle(Point(0, 0), GetOutputSizePixel());
+
+ if (! IsFloatingMode())
+ {
+ switch (GetAlignment())
+ {
+ case SFX_ALIGN_TOP: aRect.Bottom()--; break;
+ case SFX_ALIGN_BOTTOM: aRect.Top()++; break;
+ case SFX_ALIGN_LEFT: aRect.Right()--; break;
+ case SFX_ALIGN_RIGHT: aRect.Left()++; break;
+ default:
+ break;
+ }
+ }
+
+ DecorationView aView(this);
+ aRect.Left() += 8; aRect.Top() += 8;
+ aRect.Right()-= 8; aRect.Bottom()-= 8;
+ aRect = aView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+
+ aEdit.SetPosSizePixel(aRect.TopLeft(), aRect.GetSize());
+ SfxDockingWindow::Resize();
+ Invalidate();
+}
+
+
+void SmCmdBoxWindow::Paint(const Rectangle& /*rRect*/)
+{
+ Rectangle aRect = Rectangle(Point(0, 0), GetOutputSizePixel());
+ DecorationView aView(this);
+
+ if (! IsFloatingMode())
+ {
+ Point aFrom, aTo;
+ switch (GetAlignment())
+ {
+ case SFX_ALIGN_TOP:
+ aFrom = aRect.BottomLeft(); aTo = aRect.BottomRight();
+ aRect.Bottom()--;
+ break;
+
+ case SFX_ALIGN_BOTTOM:
+ aFrom = aRect.TopLeft(); aTo = aRect.TopRight();
+ aRect.Top()++;
+ break;
+
+ case SFX_ALIGN_LEFT:
+ aFrom = aRect.TopRight(); aTo = aRect.BottomRight();
+ aRect.Right()--;
+ break;
+
+ case SFX_ALIGN_RIGHT:
+ aFrom = aRect.TopLeft(); aTo = aRect.BottomLeft();
+ aRect.Left()++;
+ break;
+
+ default:
+ break;
+ }
+ DrawLine( aFrom, aTo );
+ aView.DrawFrame(aRect, FRAME_DRAW_OUT);
+ }
+ aRect.Left() += 8; aRect.Top() += 8;
+ aRect.Right()-= 8; aRect.Bottom()-= 8;
+ aRect = aView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
+}
+
+
+Size SmCmdBoxWindow::CalcDockingSize(SfxChildAlignment eAlign)
+{
+ switch (eAlign)
+ {
+ case SFX_ALIGN_LEFT:
+ case SFX_ALIGN_RIGHT:
+ return Size();
+ default:
+ break;
+ }
+ return SfxDockingWindow::CalcDockingSize(eAlign);
+}
+
+
+SfxChildAlignment SmCmdBoxWindow::CheckAlignment(SfxChildAlignment eActual,
+ SfxChildAlignment eWish)
+{
+ switch (eWish)
+ {
+ case SFX_ALIGN_TOP:
+ case SFX_ALIGN_BOTTOM:
+ case SFX_ALIGN_NOALIGNMENT:
+ return eWish;
+ default:
+ break;
+ }
+
+ return eActual;
+}
+
+
+void SmCmdBoxWindow::StateChanged( StateChangedType nStateChange )
+{
+ if (STATE_CHANGE_INITSHOW == nStateChange)
+ {
+ Resize(); // avoid SmEditWindow not being painted correctly
+
+ // set initial position of window in floating mode
+ if (true == IsFloatingMode())
+ AdjustPosition(); //! don't change pos in docking-mode !
+
+ aInitialFocusTimer.Start();
+ }
+
+ SfxDockingWindow::StateChanged( nStateChange );
+}
+
+
+IMPL_LINK( SmCmdBoxWindow, InitialFocusTimerHdl, Timer *, EMPTYARG /*pTimer*/ )
+{
+ // We want to have the focus in the edit window once Math has been opened
+ // to allow for immediate typing.
+ // Problem: There is no proper way to do this
+ // Thus: this timer based soultion has been implemented (see GrabFocus below)
+ //
+ // Follow-up problem (#i114910): grabing the focus may bust the help system since
+ // it relies on getting the current frame which conflicts with grabbing the focus.
+ // Thus aside from the 'GrabFocus' call everything else is to get the
+ // help reliably working despite using 'GrabFocus'.
+
+ try
+ {
+ uno::Reference< frame::XDesktop > xDesktop;
+ uno::Reference< lang::XMultiServiceFactory > xSMGR( comphelper::getProcessServiceFactory() );
+ if (xSMGR.is())
+ {
+ xDesktop = uno::Reference< frame::XDesktop >(
+ xSMGR->createInstance( rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" )), uno::UNO_QUERY_THROW );
+ }
+
+ aEdit.GrabFocus();
+
+ if (xDesktop.is())
+ {
+ bool bInPlace = GetView()->GetViewFrame()->GetFrame().IsInPlace();
+ uno::Reference< frame::XFrame > xFrame( GetBindings().GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface());
+ if ( bInPlace )
+ {
+ uno::Reference< container::XChild > xModel( GetView()->GetDoc()->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XModel > xParent( xModel->getParent(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XController > xParentCtrler( xParent->getCurrentController() );
+ uno::Reference< frame::XFramesSupplier > xParentFrame( xParentCtrler->getFrame(), uno::UNO_QUERY_THROW );
+ xParentFrame->setActiveFrame( xFrame );
+ }
+ else
+ {
+ uno::Reference< frame::XFramesSupplier > xFramesSupplier( xDesktop, uno::UNO_QUERY );
+ xFramesSupplier->setActiveFrame( xFrame );
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ DBG_ASSERT( 0, "failed to properly set initial focus to edit window" );
+ }
+ return 0;
+}
+
+
+void SmCmdBoxWindow::AdjustPosition()
+{
+ Point aPt;
+ const Rectangle aRect( aPt, GetParent()->GetOutputSizePixel() );
+ Point aTopLeft( Point( aRect.Left(),
+ aRect.Bottom() - GetSizePixel().Height() ) );
+ Point aPos( GetParent()->OutputToScreenPixel( aTopLeft ) );
+ if (aPos.X() < 0)
+ aPos.X() = 0;
+ if (aPos.Y() < 0)
+ aPos.Y() = 0;
+ SetPosPixel( aPos );
+}
+
+
+void SmCmdBoxWindow::ToggleFloatingMode()
+{
+ SfxDockingWindow::ToggleFloatingMode();
+
+ if (GetFloatingWindow())
+ GetFloatingWindow()->SetMinOutputSizePixel(Size (200, 50));
+}
+
+
+void SmCmdBoxWindow::GetFocus()
+{
+ if (!bExiting)
+ aEdit.GrabFocus();
+}
+
+/**************************************************************************/
+
+
+SFX_IMPL_DOCKINGWINDOW(SmCmdBoxWrapper, SID_CMDBOXWINDOW);
+
+SmCmdBoxWrapper::SmCmdBoxWrapper(Window *pParentWindow, sal_uInt16 nId,
+ SfxBindings *pBindings,
+ SfxChildWinInfo *pInfo) :
+ SfxChildWindow(pParentWindow, nId)
+{
+ pWindow = new SmCmdBoxWindow(pBindings, this, pParentWindow);
+
+ // make window docked to the bottom initially (after first start)
+ eChildAlignment = SFX_ALIGN_BOTTOM;
+ ((SfxDockingWindow *)pWindow)->Initialize(pInfo);
+}
+
+
+#if OSL_DEBUG_LEVEL > 1
+SmCmdBoxWrapper::~SmCmdBoxWrapper()
+{
+}
+#endif
+
+
+/**************************************************************************/
+
+struct SmViewShell_Impl
+{
+ sfx2::DocumentInserter* pDocInserter;
+ SfxRequest* pRequest;
+ SvtMiscOptions aOpts;
+
+ SmViewShell_Impl() :
+ pDocInserter( NULL )
+ , pRequest( NULL )
+ {}
+
+ ~SmViewShell_Impl()
+ {
+ delete pDocInserter;
+ delete pRequest;
+ }
+};
+
+TYPEINIT1( SmViewShell, SfxViewShell );
+
+SFX_IMPL_INTERFACE(SmViewShell, SfxViewShell, SmResId(0))
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS | SFX_VISIBILITY_STANDARD |
+ SFX_VISIBILITY_FULLSCREEN | SFX_VISIBILITY_SERVER,
+ SmResId(RID_MATH_TOOLBOX ));
+ //Dummy-Objectbar, to avoid quiver while activating
+
+ SFX_CHILDWINDOW_REGISTRATION(SID_TASKPANE);
+ SFX_CHILDWINDOW_REGISTRATION(SmToolBoxWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(SmCmdBoxWrapper::GetChildWindowId());
+}
+
+
+SFX_IMPL_NAMED_VIEWFACTORY(SmViewShell, "Default")
+{
+ SFX_VIEW_REGISTRATION(SmDocShell);
+}
+
+
+Size SmViewShell::GetOptimalSizePixel() const
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetOptimalSizePixel" );
+
+ return aGraphic.LogicToPixel( ((SmViewShell*)this)->GetDoc()->GetSize() );
+}
+
+
+void SmViewShell::AdjustPosSizePixel(const Point &rPos, const Size &rSize)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::AdjustPosSizePixel" );
+
+ aGraphic.SetPosSizePixel(rPos, rSize);
+}
+
+
+void SmViewShell::InnerResizePixel(const Point &rOfs, const Size &rSize)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::InnerResizePixel" );
+
+ Size aObjSize = GetObjectShell()->GetVisArea().GetSize();
+ if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 )
+ {
+ Size aProvidedSize = GetWindow()->PixelToLogic( rSize, MAP_100TH_MM );
+ SfxViewShell::SetZoomFactor( Fraction( aProvidedSize.Width(), aObjSize.Width() ),
+ Fraction( aProvidedSize.Height(), aObjSize.Height() ) );
+ }
+
+ SetBorderPixel( SvBorder() );
+ GetGraphicWindow().SetPosSizePixel(rOfs, rSize);
+ GetGraphicWindow().SetTotalSize();
+}
+
+
+void SmViewShell::OuterResizePixel(const Point &rOfs, const Size &rSize)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::OuterResizePixel" );
+
+ SmGraphicWindow &rWin = GetGraphicWindow();
+ rWin.SetPosSizePixel(rOfs, rSize);
+ if (GetDoc()->IsPreview())
+ rWin.ZoomToFitInWindow();
+ rWin.Update();
+}
+
+
+void SmViewShell::QueryObjAreaPixel( Rectangle& rRect ) const
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::QueryObjAreaPixel" );
+
+ rRect.SetSize( GetGraphicWindow().GetSizePixel() );
+}
+
+
+void SmViewShell::SetZoomFactor( const Fraction &rX, const Fraction &rY )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetZoomFactor" );
+
+ const Fraction &rFrac = rX < rY ? rX : rY;
+ GetGraphicWindow().SetZoom( (sal_uInt16) long(rFrac * Fraction( 100, 1 )) );
+
+ //To avoid rounding errors base class regulates crooked values too
+ //if necessary
+ SfxViewShell::SetZoomFactor( rX, rY );
+}
+
+
+Size SmViewShell::GetTextLineSize(OutputDevice& rDevice, const String& rLine)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetTextLineSize" );
+
+ String aText;
+ Size aSize(rDevice.GetTextWidth(rLine), rDevice.GetTextHeight());
+ sal_uInt16 nTabs = rLine.GetTokenCount('\t');
+
+ if (nTabs > 0)
+ {
+ long TabPos = rDevice.GetTextWidth('n') * 8;
+
+ aSize.Width() = 0;
+
+ for (sal_uInt16 i = 0; i < nTabs; i++)
+ {
+ if (i > 0)
+ aSize.Width() = ((aSize.Width() / TabPos) + 1) * TabPos;
+
+ aText = rLine.GetToken(i, '\t');
+ aText.EraseLeadingChars('\t');
+ aText.EraseTrailingChars('\t');
+ aSize.Width() += rDevice.GetTextWidth(aText);
+ }
+ }
+
+ return aSize;
+}
+
+
+Size SmViewShell::GetTextSize(OutputDevice& rDevice, const String& rText, long MaxWidth)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetTextSize" );
+
+ Size aSize;
+ String aLine;
+ Size TextSize;
+ String aText;
+ sal_uInt16 nLines = rText.GetTokenCount('\n');
+
+ for (sal_uInt16 i = 0; i < nLines; i++)
+ {
+ aLine = rText.GetToken(i, '\n');
+ aLine.EraseAllChars('\r');
+ aLine.EraseLeadingChars('\n');
+ aLine.EraseTrailingChars('\n');
+
+ aSize = GetTextLineSize(rDevice, aLine);
+
+ if (aSize.Width() > MaxWidth)
+ {
+ do
+ {
+ xub_StrLen m = aLine.Len();
+ xub_StrLen nLen = m;
+
+ for (xub_StrLen n = 0; n < nLen; n++)
+ {
+ sal_Unicode cLineChar = aLine.GetChar(n);
+ if ((cLineChar == ' ') || (cLineChar == '\t'))
+ {
+ aText = aLine.Copy(0, n);
+ if (GetTextLineSize(rDevice, aText).Width() < MaxWidth)
+ m = n;
+ else
+ break;
+ }
+ }
+
+ aText = aLine.Copy(0, m);
+ aLine.Erase(0, m);
+ aSize = GetTextLineSize(rDevice, aText);
+ TextSize.Height() += aSize.Height();
+ TextSize.Width() = Max(TextSize.Width(), Min(aSize.Width(), MaxWidth));
+
+ aLine.EraseLeadingChars(' ');
+ aLine.EraseLeadingChars('\t');
+ aLine.EraseLeadingChars(' ');
+ }
+ while (aLine.Len() > 0);
+ }
+ else
+ {
+ TextSize.Height() += aSize.Height();
+ TextSize.Width() = Max(TextSize.Width(), aSize.Width());
+ }
+ }
+
+ return TextSize;
+}
+
+
+void SmViewShell::DrawTextLine(OutputDevice& rDevice, const Point& rPosition, const String& rLine)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::DrawTextLine" );
+
+ String aText;
+ Point aPoint (rPosition);
+ sal_uInt16 nTabs = rLine.GetTokenCount('\t');
+
+ if (nTabs > 0)
+ {
+ long TabPos = rDevice.GetTextWidth('n') * 8;
+
+ for (sal_uInt16 i = 0; i < nTabs; i++)
+ {
+ if (i > 0)
+ aPoint.X() = ((aPoint.X() / TabPos) + 1) * TabPos;
+
+ aText = rLine.GetToken(i, '\t');
+ aText.EraseLeadingChars('\t');
+ aText.EraseTrailingChars('\t');
+ rDevice.DrawText(aPoint, aText);
+ aPoint.X() += rDevice.GetTextWidth(aText);
+ }
+ }
+ else
+ rDevice.DrawText(aPoint, rLine);
+}
+
+
+void SmViewShell::DrawText(OutputDevice& rDevice, const Point& rPosition, const String& rText, sal_uInt16 MaxWidth)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::DrawText" );
+
+ sal_uInt16 nLines = rText.GetTokenCount('\n');
+ Point aPoint (rPosition);
+ Size aSize;
+ String aLine;
+ String aText;
+
+ for (sal_uInt16 i = 0; i < nLines; i++)
+ {
+ aLine = rText.GetToken(i, '\n');
+ aLine.EraseAllChars('\r');
+ aLine.EraseLeadingChars('\n');
+ aLine.EraseTrailingChars('\n');
+ aSize = GetTextLineSize(rDevice, aLine);
+ if (aSize.Width() > MaxWidth)
+ {
+ do
+ {
+ xub_StrLen m = aLine.Len();
+ xub_StrLen nLen = m;
+
+ for (xub_StrLen n = 0; n < nLen; n++)
+ {
+ sal_Unicode cLineChar = aLine.GetChar(n);
+ if ((cLineChar == ' ') || (cLineChar == '\t'))
+ {
+ aText = aLine.Copy(0, n);
+ if (GetTextLineSize(rDevice, aText).Width() < MaxWidth)
+ m = n;
+ else
+ break;
+ }
+ }
+ aText = aLine.Copy(0, m);
+ aLine.Erase(0, m);
+
+ DrawTextLine(rDevice, aPoint, aText);
+ aPoint.Y() += aSize.Height();
+
+ aLine.EraseLeadingChars(' ');
+ aLine.EraseLeadingChars('\t');
+ aLine.EraseLeadingChars(' ');
+ }
+ while (GetTextLineSize(rDevice, aLine).Width() > MaxWidth);
+
+ // print the remaining text
+ if (aLine.Len() > 0)
+ {
+ DrawTextLine(rDevice, aPoint, aLine);
+ aPoint.Y() += aSize.Height();
+ }
+ }
+ else
+ {
+ DrawTextLine(rDevice, aPoint, aLine);
+ aPoint.Y() += aSize.Height();
+ }
+ }
+}
+
+void SmViewShell::Impl_Print(
+ OutputDevice &rOutDev,
+ const SmPrintUIOptions &rPrintUIOptions,
+ Rectangle aOutRect, Point aZeroPoint )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Impl_Print" );
+
+ const bool bIsPrintTitle = rPrintUIOptions.getBoolValue( PRTUIOPT_TITLE_ROW, sal_True );
+ const bool bIsPrintFrame = rPrintUIOptions.getBoolValue( PRTUIOPT_BORDER, sal_True );
+ const bool bIsPrintFormulaText = rPrintUIOptions.getBoolValue( PRTUIOPT_FORMULA_TEXT, sal_True );
+ SmPrintSize ePrintSize( static_cast< SmPrintSize >( rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_FORMAT, PRINT_SIZE_NORMAL ) ));
+ const sal_uInt16 nZoomFactor = static_cast< sal_uInt16 >(rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_SCALE, 100 ));
+
+ rOutDev.Push();
+ rOutDev.SetLineColor( Color(COL_BLACK) );
+
+ // output text on top
+ if (bIsPrintTitle)
+ {
+ Size aSize600 (0, 600);
+ Size aSize650 (0, 650);
+ Font aFont(FAMILY_DONTKNOW, aSize600);
+
+ aFont.SetAlign(ALIGN_TOP);
+ aFont.SetWeight(WEIGHT_BOLD);
+ aFont.SetSize(aSize650);
+ aFont.SetColor( Color(COL_BLACK) );
+ rOutDev.SetFont(aFont);
+
+ Size aTitleSize (GetTextSize(rOutDev, GetDoc()->GetTitle(), aOutRect.GetWidth() - 200));
+
+ aFont.SetWeight(WEIGHT_NORMAL);
+ aFont.SetSize(aSize600);
+ rOutDev.SetFont(aFont);
+
+ Size aDescSize (GetTextSize(rOutDev, GetDoc()->GetComment(), aOutRect.GetWidth() - 200));
+
+ if (bIsPrintFrame)
+ rOutDev.DrawRect(Rectangle(aOutRect.TopLeft(),
+ Size(aOutRect.GetWidth(), 100 + aTitleSize.Height() + 200 + aDescSize.Height() + 100)));
+ aOutRect.Top() += 200;
+
+ // output title
+ aFont.SetWeight(WEIGHT_BOLD);
+ aFont.SetSize(aSize650);
+ rOutDev.SetFont(aFont);
+ Point aPoint(aOutRect.Left() + (aOutRect.GetWidth() - aTitleSize.Width()) / 2,
+ aOutRect.Top());
+ DrawText(rOutDev, aPoint, GetDoc()->GetTitle(),
+ sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
+ aOutRect.Top() += aTitleSize.Height() + 200;
+
+ // output description
+ aFont.SetWeight(WEIGHT_NORMAL);
+ aFont.SetSize(aSize600);
+ rOutDev.SetFont(aFont);
+ aPoint.X() = aOutRect.Left() + (aOutRect.GetWidth() - aDescSize.Width()) / 2;
+ aPoint.Y() = aOutRect.Top();
+ DrawText(rOutDev, aPoint, GetDoc()->GetComment(),
+ sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
+ aOutRect.Top() += aDescSize.Height() + 300;
+ }
+
+ // output text on bottom
+ if (bIsPrintFormulaText)
+ {
+ Font aFont(FAMILY_DONTKNOW, Size(0, 600));
+ aFont.SetAlign(ALIGN_TOP);
+ aFont.SetColor( Color(COL_BLACK) );
+
+ // get size
+ rOutDev.SetFont(aFont);
+
+ Size aSize (GetTextSize(rOutDev, GetDoc()->GetText(), aOutRect.GetWidth() - 200));
+
+ aOutRect.Bottom() -= aSize.Height() + 600;
+
+ if (bIsPrintFrame)
+ rOutDev.DrawRect(Rectangle(aOutRect.BottomLeft(),
+ Size(aOutRect.GetWidth(), 200 + aSize.Height() + 200)));
+
+ Point aPoint (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2,
+ aOutRect.Bottom() + 300);
+ DrawText(rOutDev, aPoint, GetDoc()->GetText(),
+ sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
+ aOutRect.Bottom() -= 200;
+ }
+
+ if (bIsPrintFrame)
+ rOutDev.DrawRect(aOutRect);
+
+ aOutRect.Top() += 100;
+ aOutRect.Left() += 100;
+ aOutRect.Bottom() -= 100;
+ aOutRect.Right() -= 100;
+
+ Size aSize (GetDoc()->GetSize());
+
+ MapMode OutputMapMode;
+ // PDF export should always use PRINT_SIZE_NORMAL ...
+ if (!rPrintUIOptions.getBoolValue( "IsPrinter", sal_False ) )
+ ePrintSize = PRINT_SIZE_NORMAL;
+ switch (ePrintSize)
+ {
+ case PRINT_SIZE_NORMAL:
+ OutputMapMode = MapMode(MAP_100TH_MM);
+ break;
+
+ case PRINT_SIZE_SCALED:
+ if ((aSize.Width() > 0) && (aSize.Height() > 0))
+ {
+ Size OutputSize (rOutDev.LogicToPixel(Size(aOutRect.GetWidth(),
+ aOutRect.GetHeight()), MapMode(MAP_100TH_MM)));
+ Size GraphicSize (rOutDev.LogicToPixel(aSize, MapMode(MAP_100TH_MM)));
+ sal_uInt16 nZ = (sal_uInt16) Min((long)Fraction(OutputSize.Width() * 100L, GraphicSize.Width()),
+ (long)Fraction(OutputSize.Height() * 100L, GraphicSize.Height()));
+ Fraction aFraction ((sal_uInt16) Max ((sal_uInt16) MINZOOM, Min((sal_uInt16) MAXZOOM, (sal_uInt16) (nZ - 10))), (sal_uInt16) 100);
+
+ OutputMapMode = MapMode(MAP_100TH_MM, aZeroPoint, aFraction, aFraction);
+ }
+ else
+ OutputMapMode = MapMode(MAP_100TH_MM);
+ break;
+
+ case PRINT_SIZE_ZOOMED:
+ {
+ Fraction aFraction( nZoomFactor, 100 );
+
+ OutputMapMode = MapMode(MAP_100TH_MM, aZeroPoint, aFraction, aFraction);
+ break;
+ }
+ }
+
+ aSize = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aSize, OutputMapMode),
+ MapMode(MAP_100TH_MM));
+
+ Point aPos (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2,
+ aOutRect.Top() + (aOutRect.GetHeight() - aSize.Height()) / 2);
+
+ aPos = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aPos, MapMode(MAP_100TH_MM)),
+ OutputMapMode);
+ aOutRect = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aOutRect, MapMode(MAP_100TH_MM)),
+ OutputMapMode);
+
+ rOutDev.SetMapMode(OutputMapMode);
+ rOutDev.SetClipRegion(Region(aOutRect));
+ GetDoc()->DrawFormula(rOutDev, aPos, false);
+ rOutDev.SetClipRegion();
+
+ rOutDev.Pop();
+}
+
+sal_uInt16 SmViewShell::Print(SfxProgress & /*rProgress*/, sal_Bool /*bIsAPI*/)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Print" );
+ OSL_FAIL( "SmViewShell::Print: no longer used with new UI print dialog. Should be removed!!" );
+ return 0;
+}
+
+
+SfxPrinter* SmViewShell::GetPrinter(sal_Bool bCreate)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetPrinter" );
+
+ SmDocShell *pDoc = GetDoc();
+ if ( pDoc->HasPrinter() || bCreate )
+ return pDoc->GetPrinter();
+ return 0;
+}
+
+
+sal_uInt16 SmViewShell::SetPrinter(SfxPrinter *pNewPrinter, sal_uInt16 nDiffFlags, bool )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetPrinter" );
+ SfxPrinter *pOld = GetDoc()->GetPrinter();
+ if ( pOld && pOld->IsPrinting() )
+ return SFX_PRINTERROR_BUSY;
+
+ if ((nDiffFlags & SFX_PRINTER_PRINTER) == SFX_PRINTER_PRINTER)
+ GetDoc()->SetPrinter( pNewPrinter );
+
+ if ((nDiffFlags & SFX_PRINTER_OPTIONS) == SFX_PRINTER_OPTIONS)
+ {
+ SmModule *pp = SM_MOD();
+ pp->GetConfig()->ItemSetToConfig(pNewPrinter->GetOptions());
+ }
+ return 0;
+}
+
+
+SfxTabPage* SmViewShell::CreatePrintOptionsPage(Window *pParent,
+ const SfxItemSet &rOptions)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::CreatePrintOptionsPage" );
+
+ return SmPrintOptionsTabPage::Create(pParent, rOptions);
+}
+
+
+SmEditWindow *SmViewShell::GetEditWindow()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetEditWindow" );
+
+ SmCmdBoxWrapper *pWrapper = (SmCmdBoxWrapper *) GetViewFrame()->
+ GetChildWindow( SmCmdBoxWrapper::GetChildWindowId() );
+
+ if (pWrapper != NULL)
+ {
+ SmEditWindow *pEditWin = pWrapper->GetEditWindow();
+ OSL_ENSURE( pEditWin, "SmEditWindow missing" );
+ return pEditWin;
+ }
+
+ return NULL;
+}
+
+
+void SmViewShell::SetStatusText(const String& Text)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetStatusText" );
+
+ StatusText = Text;
+ GetViewFrame()->GetBindings().Invalidate(SID_TEXTSTATUS);
+}
+
+
+void SmViewShell::ShowError( const SmErrorDesc *pErrorDesc )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::ShowError" );
+
+ OSL_ENSURE(GetDoc(), "Sm : Document missing");
+ if (pErrorDesc || 0 != (pErrorDesc = GetDoc()->GetParser().GetError(0)) )
+ {
+ SetStatusText( pErrorDesc->Text );
+ GetEditWindow()->MarkError( Point( pErrorDesc->pNode->GetColumn(),
+ pErrorDesc->pNode->GetRow()));
+ }
+}
+
+
+void SmViewShell::NextError()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::NextError" );
+
+ OSL_ENSURE(GetDoc(), "Sm : Document missing");
+ const SmErrorDesc *pErrorDesc = GetDoc()->GetParser().NextError();
+
+ if (pErrorDesc)
+ ShowError( pErrorDesc );
+}
+
+
+void SmViewShell::PrevError()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::PrevError" );
+
+ OSL_ENSURE(GetDoc(), "Sm : Document missing");
+ const SmErrorDesc *pErrorDesc = GetDoc()->GetParser().PrevError();
+
+ if (pErrorDesc)
+ ShowError( pErrorDesc );
+}
+
+
+bool SmViewShell::Insert( SfxMedium& rMedium )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Insert" );
+
+ SmDocShell *pDoc = GetDoc();
+ String aText( pDoc->GetText() );
+ String aTemp = aText;
+ bool bRet = false;
+
+ uno::Reference < embed::XStorage > xStorage = rMedium.GetStorage();
+ uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
+ if ( xNameAccess.is() && xNameAccess->getElementNames().getLength() )
+ {
+ if ( xNameAccess->hasByName( C2S( "content.xml" ) ) || xNameAccess->hasByName( C2S( "Content.xml" ) ))
+ {
+ // is this a fabulous math package ?
+ Reference<com::sun::star::frame::XModel> xModel(pDoc->GetModel());
+ SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !!
+ bRet = 0 == aEquation.Import(rMedium);
+ }
+ }
+
+ if( bRet )
+ {
+ aText = pDoc->GetText();
+ SmEditWindow *pEditWin = GetEditWindow();
+ if (pEditWin)
+ pEditWin->InsertText( aText );
+ else
+ {
+ OSL_FAIL( "EditWindow missing" );
+ aTemp += aText;
+ aText = aTemp;
+ }
+
+ pDoc->Parse();
+ pDoc->SetModified(true);
+
+ SfxBindings &rBnd = GetViewFrame()->GetBindings();
+ rBnd.Invalidate(SID_GAPHIC_SM);
+ rBnd.Invalidate(SID_TEXT);
+ }
+ return bRet;
+}
+
+
+bool SmViewShell::InsertFrom(SfxMedium &rMedium)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::InsertFrom" );
+
+ bool bSuccess = false;
+ SmDocShell *pDoc = GetDoc();
+ SvStream *pStream = rMedium.GetInStream();
+ String aText( pDoc->GetText() );
+ String aTemp = aText;
+
+ if (pStream)
+ {
+ const String& rFltName = rMedium.GetFilter()->GetFilterName();
+ if ( rFltName.EqualsAscii(MATHML_XML) )
+ {
+ Reference<com::sun::star::frame::XModel> xModel( pDoc->GetModel() );
+ SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !!
+ bSuccess = 0 == aEquation.Import(rMedium);
+ }
+ }
+
+ if( bSuccess )
+ {
+ aText = pDoc->GetText();
+ SmEditWindow *pEditWin = GetEditWindow();
+ if (pEditWin)
+ pEditWin->InsertText( aText );
+ else
+ {
+ OSL_FAIL( "EditWindow missing" );
+ aTemp += aText;
+ aText = aTemp;
+ }
+
+ pDoc->Parse();
+ pDoc->SetModified(true);
+
+ SfxBindings &rBnd = GetViewFrame()->GetBindings();
+ rBnd.Invalidate(SID_GAPHIC_SM);
+ rBnd.Invalidate(SID_TEXT);
+ }
+
+ return bSuccess;
+}
+
+
+void SmViewShell::Execute(SfxRequest& rReq)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Execute" );
+
+ SmEditWindow *pWin = GetEditWindow();
+
+ switch (rReq.GetSlot())
+ {
+ case SID_FORMULACURSOR:
+ {
+ SmModule *pp = SM_MOD();
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem *pItem;
+
+ bool bVal;
+ if ( pArgs &&
+ SFX_ITEM_SET == pArgs->GetItemState( SID_FORMULACURSOR, false, &pItem))
+ bVal = ((SfxBoolItem *) pItem)->GetValue();
+ else
+ bVal = !pp->GetConfig()->IsShowFormulaCursor();
+
+ pp->GetConfig()->SetShowFormulaCursor(bVal);
+ if (!IsInlineEditEnabled())
+ GetGraphicWindow().ShowCursor(bVal);
+ break;
+ }
+ case SID_DRAW:
+ if (pWin)
+ {
+ GetDoc()->SetText( pWin->GetText() );
+ SetStatusText(String());
+ ShowError( 0 );
+ GetDoc()->Repaint();
+ }
+ break;
+
+ case SID_ADJUST:
+ case SID_FITINWINDOW:
+ aGraphic.ZoomToFitInWindow();
+ break;
+
+ case SID_VIEW050:
+ aGraphic.SetZoom(50);
+ break;
+
+ case SID_VIEW100:
+ aGraphic.SetZoom(100);
+ break;
+
+ case SID_VIEW200:
+ aGraphic.SetZoom(200);
+ break;
+
+ case SID_ZOOMIN:
+ aGraphic.SetZoom(aGraphic.GetZoom() + 25);
+ break;
+
+ case SID_ZOOMOUT:
+ OSL_ENSURE(aGraphic.GetZoom() >= 25, "Sm: incorrect sal_uInt16 argument");
+ aGraphic.SetZoom(aGraphic.GetZoom() - 25);
+ break;
+
+ case SID_COPYOBJECT:
+ {
+ //TODO/LATER: does not work because of UNO Tunneling - will be fixed later
+ Reference< datatransfer::XTransferable > xTrans( GetDoc()->GetModel(), uno::UNO_QUERY );
+ if( xTrans.is() )
+ {
+ Reference< lang::XUnoTunnel> xTnnl( xTrans, uno::UNO_QUERY);
+ if( xTnnl.is() )
+ {
+ TransferableHelper* pTrans = reinterpret_cast< TransferableHelper * >(
+ sal::static_int_cast< sal_uIntPtr >(
+ xTnnl->getSomething( TransferableHelper::getUnoTunnelId() )));
+ if( pTrans )
+ pTrans->CopyToClipboard( this ? GetEditWindow() : 0 );
+ }
+ }
+ }
+ break;
+
+ case SID_PASTEOBJECT:
+ {
+ TransferableDataHelper aData( TransferableDataHelper::CreateFromSystemClipboard(this ? GetEditWindow(): 0) );
+ uno::Reference < io::XInputStream > xStrm;
+ SotFormatStringId nId;
+ if( aData.GetTransferable().is() &&
+ ( aData.HasFormat( nId = SOT_FORMATSTR_ID_EMBEDDED_OBJ ) ||
+ (aData.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) &&
+ aData.HasFormat( nId = SOT_FORMATSTR_ID_EMBED_SOURCE ))) &&
+ aData.GetInputStream( nId, xStrm ) && xStrm.is() )
+ {
+ try
+ {
+ uno::Reference < embed::XStorage > xStorage =
+ ::comphelper::OStorageHelper::GetStorageFromInputStream( xStrm, ::comphelper::getProcessServiceFactory() );
+ uno::Reference < beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
+ SfxMedium aMedium( xStorage, String() );
+ Insert( aMedium );
+ GetDoc()->UpdateText();
+ }
+ catch (uno::Exception &)
+ {
+ OSL_FAIL( "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" );
+ }
+ }
+ }
+ break;
+
+
+ case SID_CUT:
+ if (pWin)
+ pWin->Cut();
+ break;
+
+ case SID_COPY:
+ if (pWin)
+ {
+ if (pWin->IsAllSelected())
+ {
+ GetViewFrame()->GetDispatcher()->Execute(
+ SID_COPYOBJECT, SFX_CALLMODE_STANDARD,
+ new SfxVoidItem(SID_COPYOBJECT), 0L);
+ }
+ else
+ pWin->Copy();
+ }
+ break;
+
+ case SID_PASTE:
+ {
+ bool bCallExec = 0 == pWin;
+ if( !bCallExec )
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard(
+ GetEditWindow()) );
+
+ if( aDataHelper.GetTransferable().is() &&
+ aDataHelper.HasFormat( FORMAT_STRING ))
+ pWin->Paste();
+ else
+ bCallExec = true;
+ }
+ if( bCallExec )
+ {
+ GetViewFrame()->GetDispatcher()->Execute(
+ SID_PASTEOBJECT, SFX_CALLMODE_STANDARD,
+ new SfxVoidItem(SID_PASTEOBJECT), 0L);
+ }
+ }
+ break;
+
+ case SID_DELETE:
+ if (pWin)
+ pWin->Delete();
+ break;
+
+ case SID_SELECT:
+ if (pWin)
+ pWin->SelectAll();
+ break;
+
+ case SID_INSERTCOMMAND:
+ {
+ const SfxInt16Item& rItem =
+ (const SfxInt16Item&)rReq.GetArgs()->Get(SID_INSERTCOMMAND);
+
+ if (pWin && (bInsertIntoEditWindow || !IsInlineEditEnabled()))
+ pWin->InsertCommand(rItem.GetValue());
+ if (IsInlineEditEnabled() && (GetDoc() && !bInsertIntoEditWindow)) {
+ GetDoc()->GetCursor().InsertCommand(rItem.GetValue());
+ GetGraphicWindow().GrabFocus();
+ }
+ break;
+ }
+
+ case SID_INSERTSYMBOL:
+ {
+ const SfxStringItem& rItem =
+ (const SfxStringItem&)rReq.GetArgs()->Get(SID_INSERTSYMBOL);
+
+ if (pWin && (bInsertIntoEditWindow || !IsInlineEditEnabled()))
+ pWin->InsertText(rItem.GetValue());
+ if (IsInlineEditEnabled() && (GetDoc() && !bInsertIntoEditWindow))
+ GetDoc()->GetCursor().InsertSpecial(rItem.GetValue());
+ break;
+ }
+
+ case SID_IMPORT_FORMULA:
+ {
+ delete pImpl->pRequest;
+ pImpl->pRequest = new SfxRequest( rReq );
+ delete pImpl->pDocInserter;
+ pImpl->pDocInserter =
+ new ::sfx2::DocumentInserter( 0, GetDoc()->GetFactory().GetFactoryName(), 0 );
+ pImpl->pDocInserter->StartExecuteModal( LINK( this, SmViewShell, DialogClosedHdl ) );
+ break;
+ }
+
+ case SID_NEXTERR:
+ NextError();
+ if (pWin)
+ pWin->GrabFocus();
+ break;
+
+ case SID_PREVERR:
+ PrevError();
+ if (pWin)
+ pWin->GrabFocus();
+ break;
+
+ case SID_NEXTMARK:
+ if (pWin)
+ {
+ pWin->SelNextMark();
+ pWin->GrabFocus();
+ }
+ break;
+
+ case SID_PREVMARK:
+ if (pWin)
+ {
+ pWin->SelPrevMark();
+ pWin->GrabFocus();
+ }
+ break;
+
+ case SID_TEXTSTATUS:
+ {
+ if (rReq.GetArgs() != NULL)
+ {
+ const SfxStringItem& rItem =
+ (const SfxStringItem&)rReq.GetArgs()->Get(SID_TEXTSTATUS);
+
+ SetStatusText(rItem.GetValue());
+ }
+
+ break;
+ }
+
+ case SID_GETEDITTEXT:
+ if (pWin)
+ if (pWin->GetText ().Len ()) GetDoc()->SetText( pWin->GetText() );
+ break;
+
+ case SID_ATTR_ZOOM:
+ {
+ if ( !GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ AbstractSvxZoomDialog *pDlg = 0;
+ const SfxItemSet *pSet = rReq.GetArgs();
+ if ( !pSet )
+ {
+ SfxItemSet aSet( GetDoc()->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
+ aSet.Put( SvxZoomItem( SVX_ZOOM_PERCENT, aGraphic.GetZoom()));
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ pDlg = pFact->CreateSvxZoomDialog(&GetViewFrame()->GetWindow(), aSet);
+ OSL_ENSURE(pDlg, "Dialogdiet fail!");
+ pDlg->SetLimits( MINZOOM, MAXZOOM );
+ if( pDlg->Execute() != RET_CANCEL )
+ pSet = pDlg->GetOutputItemSet();
+ }
+ }
+ if ( pSet )
+ {
+ const SvxZoomItem &rZoom = (const SvxZoomItem &)pSet->Get(SID_ATTR_ZOOM);
+ switch( rZoom.GetType() )
+ {
+ case SVX_ZOOM_PERCENT:
+ aGraphic.SetZoom((sal_uInt16)rZoom.GetValue ());
+ break;
+
+ case SVX_ZOOM_OPTIMAL:
+ aGraphic.ZoomToFitInWindow();
+ break;
+
+ case SVX_ZOOM_PAGEWIDTH:
+ case SVX_ZOOM_WHOLEPAGE:
+ {
+ const MapMode aMap( MAP_100TH_MM );
+ SfxPrinter *pPrinter = GetPrinter( true );
+ Point aPoint;
+ Rectangle OutputRect(aPoint, pPrinter->GetOutputSize());
+ Size OutputSize(pPrinter->LogicToPixel(Size(OutputRect.GetWidth(),
+ OutputRect.GetHeight()), aMap));
+ Size GraphicSize(pPrinter->LogicToPixel(GetDoc()->GetSize(), aMap));
+ sal_uInt16 nZ = (sal_uInt16) Min((long)Fraction(OutputSize.Width() * 100L, GraphicSize.Width()),
+ (long)Fraction(OutputSize.Height() * 100L, GraphicSize.Height()));
+ aGraphic.SetZoom (nZ);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case SID_TOOLBOX:
+ {
+ GetViewFrame()->ToggleChildWindow( SmToolBoxWrapper::GetChildWindowId() );
+ }
+ break;
+
+ case SID_SYMBOLS_CATALOGUE:
+ {
+
+ // get device used to retrieve the FontList
+ SmDocShell *pDoc = GetDoc();
+ OutputDevice *pDev = pDoc->GetPrinter();
+ if (!pDev || pDev->GetDevFontCount() == 0)
+ pDev = &SM_MOD()->GetDefaultVirtualDev();
+ OSL_ENSURE (pDev, "device for font list missing" );
+
+ SmModule *pp = SM_MOD();
+ SmSymbolDialog( NULL, pDev, pp->GetSymbolManager(), *this ).Execute();
+ }
+ break;
+ }
+ rReq.Done();
+}
+
+
+void SmViewShell::GetState(SfxItemSet &rSet)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetState" );
+
+ SfxWhichIter aIter(rSet);
+
+ SmEditWindow *pEditWin = GetEditWindow();
+ for (sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich())
+ {
+ switch (nWh)
+ {
+ case SID_CUT:
+ case SID_COPY:
+ case SID_DELETE:
+ if (! pEditWin || ! pEditWin->IsSelected())
+ rSet.DisableItem(nWh);
+ break;
+
+ case SID_PASTE:
+ if( !xClipEvtLstnr.is() && pEditWin)
+ {
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard(
+ pEditWin) );
+
+ bPasteState = aDataHelper.GetTransferable().is() &&
+ ( aDataHelper.HasFormat( FORMAT_STRING ) ||
+ aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ ) ||
+ (aDataHelper.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
+ && aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE )));
+ }
+ if( !bPasteState )
+ rSet.DisableItem( nWh );
+ break;
+
+ case SID_ATTR_ZOOM:
+ rSet.Put(SvxZoomItem( SVX_ZOOM_PERCENT, aGraphic.GetZoom()));
+ /* no break here */
+ case SID_VIEW050:
+ case SID_VIEW100:
+ case SID_VIEW200:
+ case SID_ADJUST:
+ case SID_ZOOMIN:
+ case SID_ZOOMOUT:
+ case SID_FITINWINDOW:
+ if ( GetViewFrame()->GetFrame().IsInPlace() )
+ rSet.DisableItem( nWh );
+ break;
+
+ case SID_NEXTERR:
+ case SID_PREVERR:
+ case SID_NEXTMARK:
+ case SID_PREVMARK:
+ case SID_DRAW:
+ case SID_SELECT:
+ if (! pEditWin || pEditWin->IsEmpty())
+ rSet.DisableItem(nWh);
+ break;
+
+ case SID_TEXTSTATUS:
+ {
+ rSet.Put(SfxStringItem(nWh, StatusText));
+ }
+ break;
+
+ case SID_FORMULACURSOR:
+ {
+ SmModule *pp = SM_MOD();
+ rSet.Put(SfxBoolItem(nWh, pp->GetConfig()->IsShowFormulaCursor()));
+ }
+ break;
+
+ case SID_TOOLBOX:
+ {
+ bool bState = false;
+ SfxChildWindow *pChildWnd = GetViewFrame()->
+ GetChildWindow( SmToolBoxWrapper::GetChildWindowId() );
+ if (pChildWnd && pChildWnd->GetWindow()->IsVisible())
+ bState = true;
+ rSet.Put(SfxBoolItem(SID_TOOLBOX, bState));
+ }
+ break;
+
+ }
+ }
+}
+
+
+SmViewShell::SmViewShell(SfxViewFrame *pFrame_, SfxViewShell *):
+ SfxViewShell(pFrame_, SFX_VIEW_HAS_PRINTOPTIONS | SFX_VIEW_CAN_PRINT),
+ pImpl( new SmViewShell_Impl ),
+ aGraphic(this),
+ aGraphicController(aGraphic, SID_GAPHIC_SM, pFrame_->GetBindings())
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SmViewShell" );
+
+ SetStatusText(String());
+ SetWindow(&aGraphic);
+ SfxShell::SetName(C2S("SmView"));
+ SfxShell::SetUndoManager( &GetDoc()->GetEditEngine().GetUndoManager() );
+ SetHelpId( HID_SMA_VIEWSHELL_DOCUMENT );
+}
+
+
+SmViewShell::~SmViewShell()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::~SmViewShell" );
+
+ //!! this view shell is not active anymore !!
+ // Thus 'SmGetActiveView' will give a 0 pointer.
+ // Thus we need to supply this view as argument
+ SmEditWindow *pEditWin = GetEditWindow();
+ if (pEditWin)
+ pEditWin->DeleteEditView( *this );
+ delete pImpl;
+}
+
+void SmViewShell::Deactivate( sal_Bool bIsMDIActivate )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Deactivate" );
+
+ SmEditWindow *pEdit = GetEditWindow();
+ if ( pEdit )
+ pEdit->Flush();
+
+ SfxViewShell::Deactivate( bIsMDIActivate );
+}
+
+
+void SmViewShell::Activate( sal_Bool bIsMDIActivate )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Activate" );
+
+ SfxViewShell::Activate( bIsMDIActivate );
+
+ SmEditWindow *pEdit = GetEditWindow();
+ if ( pEdit )
+ {
+ //! Since there is no way to be informed if a "drag and drop"
+ //! event has taken place, we call SetText here in order to
+ //! syncronize the GraphicWindow display with the text in the
+ //! EditEngine.
+ SmDocShell *pDoc = GetDoc();
+ pDoc->SetText( pDoc->GetEditEngine().GetText( LINEEND_LF ) );
+
+ if ( bIsMDIActivate )
+ pEdit->GrabFocus();
+ }
+}
+
+IMPL_LINK( SmViewShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
+{
+ OSL_ENSURE( _pFileDlg, "SmViewShell::DialogClosedHdl(): no file dialog" );
+ OSL_ENSURE( pImpl->pDocInserter, "ScDocShell::DialogClosedHdl(): no document inserter" );
+
+ if ( ERRCODE_NONE == _pFileDlg->GetError() )
+ {
+ SfxMedium* pMedium = pImpl->pDocInserter->CreateMedium();
+
+ if ( pMedium != NULL )
+ {
+ if ( pMedium->IsStorage() )
+ Insert( *pMedium );
+ else
+ InsertFrom( *pMedium );
+ delete pMedium;
+
+ SmDocShell* pDoc = GetDoc();
+ pDoc->UpdateText();
+ pDoc->ArrangeFormula();
+ pDoc->Repaint();
+ // adjust window, repaint, increment ModifyCount,...
+ GetViewFrame()->GetBindings().Invalidate(SID_GAPHIC_SM);
+ }
+ }
+
+ pImpl->pRequest->SetReturnValue( SfxBoolItem( pImpl->pRequest->GetSlot(), true ) );
+ pImpl->pRequest->Done();
+ return 0;
+}
+
+void SmViewShell::Notify( SfxBroadcaster& , const SfxHint& rHint )
+{
+ if ( rHint.IsA(TYPE(SfxSimpleHint)) )
+ {
+ switch( ( (SfxSimpleHint&) rHint ).GetId() )
+ {
+ case SFX_HINT_MODECHANGED:
+ case SFX_HINT_DOCCHANGED:
+ GetViewFrame()->GetBindings().InvalidateAll(false);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+bool SmViewShell::IsInlineEditEnabled() const
+{
+ return pImpl->aOpts.IsExperimentalMode();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/visitors.cxx b/starmath/source/visitors.cxx
new file mode 100644
index 000000000000..78e5adcbeddf
--- /dev/null
+++ b/starmath/source/visitors.cxx
@@ -0,0 +1,2541 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Jonas Finnemann Jensen <jopsen@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Jonas Finnemann Jensen <jopsen@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+#include "visitors.hxx"
+#include "cursor.hxx"
+
+///////////////////////////////////// SmVisitorTest /////////////////////////////////////
+
+void SmVisitorTest::Visit( SmTableNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NTABLE, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmBraceNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NBRACE, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmBracebodyNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NBRACEBODY, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmOperNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NOPER, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmAlignNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NALIGN, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmAttributNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NATTRIBUT, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmFontNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NFONT, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmUnHorNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NUNHOR, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmBinHorNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NBINHOR, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmBinVerNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NBINVER, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmBinDiagonalNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NBINDIAGONAL, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmSubSupNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NSUBSUP, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmMatrixNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NMATRIX, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmPlaceNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NPLACE, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmTextNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NTEXT, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmSpecialNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NSPECIAL, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmGlyphSpecialNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NGLYPH_SPECIAL, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmMathSymbolNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NMATH, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmBlankNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NBLANK, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmErrorNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NERROR, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmLineNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NLINE, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmExpressionNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NEXPRESSION, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmPolyLineNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NPOLYLINE, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmRootNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NROOT, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmRootSymbolNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NROOTSYMBOL, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmRectangleNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NRECTANGLE, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::Visit( SmVerticalBraceNode* pNode )
+{
+ OSL_ENSURE( pNode->GetType( ) == NVERTICAL_BRACE, "the visitor-patterns isn't implemented correctly" );
+ VisitChildren( pNode );
+}
+
+void SmVisitorTest::VisitChildren( SmNode* pNode )
+{
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ it->Accept( this );
+}
+
+/////////////////////////////// SmDefaultingVisitor ////////////////////////////////
+
+void SmDefaultingVisitor::Visit( SmTableNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmBraceNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmBracebodyNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmOperNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmAlignNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmAttributNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmFontNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmUnHorNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmBinHorNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmBinVerNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmBinDiagonalNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmSubSupNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmMatrixNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmPlaceNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmTextNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmSpecialNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmGlyphSpecialNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmMathSymbolNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmBlankNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmErrorNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmLineNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmExpressionNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmPolyLineNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmRootNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmRootSymbolNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmRectangleNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+void SmDefaultingVisitor::Visit( SmVerticalBraceNode* pNode )
+{
+ DefaultVisit( pNode );
+}
+
+/////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
+
+SmCaretDrawingVisitor::SmCaretDrawingVisitor( OutputDevice& rDevice,
+ SmCaretPos position,
+ Point offset,
+ bool caretVisible )
+ : rDev( rDevice )
+{
+ pos = position;
+ Offset = offset;
+ isCaretVisible = caretVisible;
+ OSL_ENSURE( position.IsValid( ), "Cannot draw invalid position!" );
+ if( !position.IsValid( ) )
+ return;
+
+ //Save device state
+ rDev.Push( PUSH_FONT | PUSH_MAPMODE | PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
+
+ pos.pSelectedNode->Accept( this );
+ //Restore device state
+ rDev.Pop( );
+}
+
+void SmCaretDrawingVisitor::Visit( SmTextNode* pNode )
+{
+ long i = pos.Index;
+
+ rDev.SetFont( pNode->GetFont( ) );
+
+ //Find the line
+ SmNode* pLine = SmCursor::FindTopMostNodeInLine( pNode );
+
+ //Find coordinates
+ long left = pNode->GetLeft( ) + rDev.GetTextWidth( pNode->GetText( ), 0, i ) + Offset.X( );
+ long top = pLine->GetTop( ) + Offset.Y( );
+ long height = pLine->GetHeight( );
+ long left_line = pLine->GetLeft( ) + Offset.X( );
+ long right_line = pLine->GetRight( ) + Offset.X( );
+
+ //Set color
+ rDev.SetLineColor( Color( COL_BLACK ) );
+
+ if ( isCaretVisible ) {
+ //Draw vertical line
+ Point p1( left, top );
+ Point p2( left, top + height );
+ rDev.DrawLine( p1, p2 );
+ }
+
+ //Underline the line
+ Point pLeft( left_line, top + height );
+ Point pRight( right_line, top + height );
+ rDev.DrawLine( pLeft, pRight );
+}
+
+void SmCaretDrawingVisitor::DefaultVisit( SmNode* pNode )
+{
+ rDev.SetLineColor( Color( COL_BLACK ) );
+
+ //Find the line
+ SmNode* pLine = SmCursor::FindTopMostNodeInLine( pNode );
+
+ //Find coordinates
+ long left = pNode->GetLeft( ) + Offset.X( ) + ( pos.Index == 1 ? pNode->GetWidth( ) : 0 );
+ long top = pLine->GetTop( ) + Offset.Y( );
+ long height = pLine->GetHeight( );
+ long left_line = pLine->GetLeft( ) + Offset.X( );
+ long right_line = pLine->GetRight( ) + Offset.X( );
+
+ //Set color
+ rDev.SetLineColor( Color( COL_BLACK ) );
+
+ if ( isCaretVisible ) {
+ //Draw vertical line
+ Point p1( left, top );
+ Point p2( left, top + height );
+ rDev.DrawLine( p1, p2 );
+ }
+
+ //Underline the line
+ Point pLeft( left_line, top + height );
+ Point pRight( right_line, top + height );
+ rDev.DrawLine( pLeft, pRight );
+}
+
+/////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
+
+void SmCaretPos2LineVisitor::Visit( SmTextNode* pNode )
+{
+ //Save device state
+ pDev->Push( PUSH_FONT | PUSH_TEXTCOLOR );
+
+ long i = pos.Index;
+
+ pDev->SetFont( pNode->GetFont( ) );
+
+ //Find coordinates
+ long left = pNode->GetLeft( ) + pDev->GetTextWidth( pNode->GetText( ), 0, i );
+ long top = pNode->GetTop( );
+ long height = pNode->GetHeight( );
+
+ line = SmCaretLine( left, top, height );
+
+ //Restore device state
+ pDev->Pop( );
+}
+
+void SmCaretPos2LineVisitor::DefaultVisit( SmNode* pNode )
+{
+ //Vertical line ( code from SmCaretDrawingVisitor )
+ Point p1 = pNode->GetTopLeft( );
+ if( pos.Index == 1 )
+ p1.Move( pNode->GetWidth( ), 0 );
+
+ line = SmCaretLine( p1.X( ), p1.Y( ), pNode->GetHeight( ) );
+}
+
+/////////////////////////////// Nasty temporary device!!! ////////////////////////////////
+
+#include <tools/gen.hxx>
+#include <tools/fract.hxx>
+#include <rtl/math.hxx>
+#include <tools/color.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/outdev.hxx>
+#include <sfx2/module.hxx>
+#include "symbol.hxx"
+#include "smmod.hxx"
+
+class SmTmpDevice2
+{
+ OutputDevice &rOutDev;
+
+ // disallow use of copy-constructor and assignment-operator
+ SmTmpDevice2( const SmTmpDevice2 &rTmpDev );
+ SmTmpDevice2 & operator = ( const SmTmpDevice2 &rTmpDev );
+
+ Color Impl_GetColor( const Color& rColor );
+
+public:
+ SmTmpDevice2( OutputDevice &rTheDev, bool bUseMap100th_mm );
+ ~SmTmpDevice2( ) { rOutDev.Pop( ); }
+
+ void SetFont( const Font &rNewFont );
+
+ void SetLineColor( const Color& rColor ) { rOutDev.SetLineColor( Impl_GetColor( rColor ) ); }
+ void SetFillColor( const Color& rColor ) { rOutDev.SetFillColor( Impl_GetColor( rColor ) ); }
+ void SetTextColor( const Color& rColor ) { rOutDev.SetTextColor( Impl_GetColor( rColor ) ); }
+
+ operator OutputDevice & ( ) { return rOutDev; }
+};
+
+SmTmpDevice2::SmTmpDevice2( OutputDevice &rTheDev, bool bUseMap100th_mm ) :
+ rOutDev( rTheDev )
+{
+ rOutDev.Push( PUSH_FONT | PUSH_MAPMODE |
+ PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
+ if ( bUseMap100th_mm && MAP_100TH_MM != rOutDev.GetMapMode( ).GetMapUnit( ) )
+ {
+ OSL_FAIL( "incorrect MapMode?" );
+ rOutDev.SetMapMode( MAP_100TH_MM ); //format for 100% always
+ }
+}
+
+Color SmTmpDevice2::Impl_GetColor( const Color& rColor )
+{
+ ColorData nNewCol = rColor.GetColor( );
+ if ( COL_AUTO == nNewCol )
+ {
+ if ( OUTDEV_PRINTER == rOutDev.GetOutDevType( ) )
+ nNewCol = COL_BLACK;
+ else
+ {
+ Color aBgCol( rOutDev.GetBackground( ).GetColor( ) );
+ if ( OUTDEV_WINDOW == rOutDev.GetOutDevType( ) )
+ aBgCol = ( ( Window & ) rOutDev ).GetDisplayBackground( ).GetColor( );
+
+ nNewCol = SM_MOD( )->GetColorConfig( ).GetColorValue( svtools::FONTCOLOR ).nColor;
+
+ Color aTmpColor( nNewCol );
+ if ( aBgCol.IsDark( ) && aTmpColor.IsDark( ) )
+ nNewCol = COL_WHITE;
+ else if ( aBgCol.IsBright( ) && aTmpColor.IsBright( ) )
+ nNewCol = COL_BLACK;
+ }
+ }
+ return Color( nNewCol );
+}
+
+void SmTmpDevice2::SetFont( const Font &rNewFont )
+{
+ rOutDev.SetFont( rNewFont );
+ rOutDev.SetTextColor( Impl_GetColor( rNewFont.GetColor( ) ) );
+}
+
+/////////////////////////////// SmDrawingVisitor ////////////////////////////////
+
+void SmDrawingVisitor::Visit( SmTableNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmBraceNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmBracebodyNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmOperNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmAlignNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmAttributNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmFontNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmUnHorNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmBinHorNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmBinVerNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmBinDiagonalNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmSubSupNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmMatrixNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmPlaceNode* pNode )
+{
+ DrawSpecialNode( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmTextNode* pNode )
+{
+ DrawTextNode( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmSpecialNode* pNode )
+{
+ DrawSpecialNode( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmGlyphSpecialNode* pNode )
+{
+ DrawSpecialNode( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmMathSymbolNode* pNode )
+{
+ DrawSpecialNode( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmBlankNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmErrorNode* pNode )
+{
+ DrawSpecialNode( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmLineNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmExpressionNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmRootNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmVerticalBraceNode* pNode )
+{
+ DrawChildren( pNode );
+}
+
+void SmDrawingVisitor::Visit( SmRootSymbolNode* pNode )
+{
+ if ( pNode->IsPhantom( ) )
+ return;
+
+ // draw root-sign itself
+ DrawSpecialNode( pNode );
+
+ SmTmpDevice2 aTmpDev( ( OutputDevice & ) rDev, true );
+ aTmpDev.SetFillColor( pNode->GetFont( ).GetColor( ) );
+ rDev.SetLineColor( );
+ aTmpDev.SetFont( pNode->GetFont( ) );
+
+ // since the width is always unscaled it corresponds ot the _original_
+ // _unscaled_ font height to be used, we use that to calculate the
+ // bar height. Thus it is independent of the arguments height.
+ // ( see display of sqrt QQQ versus sqrt stack{Q#Q#Q#Q} )
+ long nBarHeight = pNode->GetWidth( ) * 7L / 100L;
+ long nBarWidth = pNode->GetBodyWidth( ) + pNode->GetBorderWidth( );
+ Point aBarOffset( pNode->GetWidth( ), +pNode->GetBorderWidth( ) );
+ Point aBarPos( Position + aBarOffset );
+
+ Rectangle aBar( aBarPos, Size( nBarWidth, nBarHeight ) );
+ //! avoid GROWING AND SHRINKING of drawn rectangle when constantly
+ //! increasing zoomfactor.
+ // This is done by shifting it's output-position to a point that
+ // corresponds exactly to a pixel on the output device.
+ Point aDrawPos( rDev.PixelToLogic( rDev.LogicToPixel( aBar.TopLeft( ) ) ) );
+ aBar.SetPos( aDrawPos );
+
+ rDev.DrawRect( aBar );
+}
+
+void SmDrawingVisitor::Visit( SmPolyLineNode* pNode )
+{
+ if ( pNode->IsPhantom( ) )
+ return;
+
+ long nBorderwidth = pNode->GetFont( ).GetBorderWidth( );
+
+ LineInfo aInfo;
+ aInfo.SetWidth( pNode->GetWidth( ) - 2 * nBorderwidth );
+
+ Point aOffset ( Point( ) - pNode->GetPolygon( ).GetBoundRect( ).TopLeft( )
+ + Point( nBorderwidth, nBorderwidth ) ),
+ aPos ( Position + aOffset );
+ pNode->GetPolygon( ).Move( aPos.X( ), aPos.Y( ) ); //Works because Polygon wraps a pointer
+
+ SmTmpDevice2 aTmpDev ( ( OutputDevice & ) rDev, false );
+ aTmpDev.SetLineColor( pNode->GetFont( ).GetColor( ) );
+
+ rDev.DrawPolyLine( pNode->GetPolygon( ), aInfo );
+}
+
+void SmDrawingVisitor::Visit( SmRectangleNode* pNode )
+{
+ if ( pNode->IsPhantom( ) )
+ return;
+
+ SmTmpDevice2 aTmpDev ( ( OutputDevice & ) rDev, false );
+ aTmpDev.SetFillColor( pNode->GetFont( ).GetColor( ) );
+ rDev.SetLineColor( );
+ aTmpDev.SetFont( pNode->GetFont( ) );
+
+ sal_uLong nTmpBorderWidth = pNode->GetFont( ).GetBorderWidth( );
+
+ // get rectangle and remove borderspace
+ Rectangle aTmp ( pNode->AsRectangle( ) + Position - pNode->GetTopLeft( ) );
+ aTmp.Left( ) += nTmpBorderWidth;
+ aTmp.Right( ) -= nTmpBorderWidth;
+ aTmp.Top( ) += nTmpBorderWidth;
+ aTmp.Bottom( ) -= nTmpBorderWidth;
+
+ DBG_ASSERT( aTmp.GetHeight( ) > 0 && aTmp.GetWidth( ) > 0,
+ "Sm: leeres Rechteck" );
+
+ //! avoid GROWING AND SHRINKING of drawn rectangle when constantly
+ //! increasing zoomfactor.
+ // This is done by shifting it's output-position to a point that
+ // corresponds exactly to a pixel on the output device.
+ Point aPos ( rDev.PixelToLogic( rDev.LogicToPixel( aTmp.TopLeft( ) ) ) );
+ aTmp.SetPos( aPos );
+
+ rDev.DrawRect( aTmp );
+}
+
+void SmDrawingVisitor::DrawTextNode( SmTextNode* pNode )
+{
+ if ( pNode->IsPhantom( ) || pNode->GetText( ).Len( ) == 0 || pNode->GetText( ).GetChar( 0 ) == xub_Unicode( '\0' ) )
+ return;
+
+ SmTmpDevice2 aTmpDev ( ( OutputDevice & ) rDev, false );
+ aTmpDev.SetFont( pNode->GetFont( ) );
+
+ Point aPos ( Position );
+ aPos.Y( ) += pNode->GetBaselineOffset( );
+ // auf Pixelkoordinaten runden
+ aPos = rDev.PixelToLogic( rDev.LogicToPixel( aPos ) );
+
+ rDev.DrawStretchText( aPos, pNode->GetWidth( ), pNode->GetText( ) );
+}
+
+void SmDrawingVisitor::DrawSpecialNode( SmSpecialNode* pNode )
+{
+ //! since this chars might come from any font, that we may not have
+ //! set to ALIGN_BASELINE yet, we do it now.
+ pNode->GetFont( ).SetAlign( ALIGN_BASELINE );
+
+ DrawTextNode( pNode );
+}
+
+void SmDrawingVisitor::DrawChildren( SmNode* pNode )
+{
+ if ( pNode->IsPhantom( ) )
+ return;
+
+ Point rPosition = Position;
+
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ {
+ Point aOffset ( it->GetTopLeft( ) - pNode->GetTopLeft( ) );
+ Position = rPosition + aOffset;
+ it->Accept( this );
+ }
+}
+
+/////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
+
+SmSetSelectionVisitor::SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pTree) {
+ StartPos = startPos;
+ EndPos = endPos;
+ IsSelecting = false;
+
+ //Assume that pTree is a SmTableNode
+ OSL_ENSURE(pTree->GetType() == NTABLE, "pTree should be a SmTableNode!");
+ //Visit root node, this is special as this node cannot be selected, but it's children can!
+ if(pTree->GetType() == NTABLE){
+ //Change state if StartPos is infront of this node
+ if( StartPos.pSelectedNode == pTree && StartPos.Index == 0 )
+ IsSelecting = !IsSelecting;
+ //Change state if EndPos is infront of this node
+ if( EndPos.pSelectedNode == pTree && EndPos.Index == 0 )
+ IsSelecting = !IsSelecting;
+ OSL_ENSURE(!IsSelecting, "Caret positions needed to set IsSelecting about, shouldn't be possible!");
+
+ //Visit lines
+ SmNodeIterator it( pTree );
+ while( it.Next( ) ) {
+ it->Accept( this );
+ //If we started a selection in this line and it haven't ended, we do that now!
+ if(IsSelecting) {
+ IsSelecting = false;
+ SetSelectedOnAll(it.Current(), true);
+ //Set StartPos and EndPos to invalid positions, this ensures that an unused
+ //start or end (because we forced end above), doesn't start a new selection.
+ StartPos = EndPos = SmCaretPos();
+ }
+ }
+ //Check if pTree isn't selected
+ OSL_ENSURE(!pTree->IsSelected(), "pTree should never be selected!");
+ //Discard the selection if there's a bug (it's better than crashing)
+ if(pTree->IsSelected())
+ SetSelectedOnAll(pTree, false);
+ }else //This shouldn't happen, but I don't see any reason to die if it does
+ pTree->Accept(this);
+}
+
+void SmSetSelectionVisitor::SetSelectedOnAll( SmNode* pSubTree, bool IsSelected ) {
+ pSubTree->SetSelected( IsSelected );
+
+ //Quick BFS to set all selections
+ SmNodeIterator it( pSubTree );
+ while( it.Next( ) )
+ SetSelectedOnAll( it.Current( ), IsSelected );
+}
+
+void SmSetSelectionVisitor::DefaultVisit( SmNode* pNode ) {
+ //Change state if StartPos is infront of this node
+ if( StartPos.pSelectedNode == pNode && StartPos.Index == 0 )
+ IsSelecting = !IsSelecting;
+ //Change state if EndPos is infront of this node
+ if( EndPos.pSelectedNode == pNode && EndPos.Index == 0 )
+ IsSelecting = !IsSelecting;
+
+ //Cache current state
+ bool WasSelecting = IsSelecting;
+ bool ChangedState = false;
+
+ //Set selected
+ pNode->SetSelected( IsSelecting );
+
+ //Visit children
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ {
+ it->Accept( this );
+ ChangedState = ( WasSelecting != IsSelecting ) || ChangedState;
+ }
+
+ //If state changed
+ if( ChangedState )
+ {
+ //Select this node and all of it's children
+ //(Make exception for SmBracebodyNode)
+ if( pNode->GetType() != NBRACEBODY ||
+ !pNode->GetParent() ||
+ pNode->GetParent()->GetType() != NBRACE )
+ SetSelectedOnAll( pNode, true );
+ else
+ SetSelectedOnAll( pNode->GetParent(), true );
+ /* If the equation is: sqrt{2 + 4} + 5
+ * And the selection is: sqrt{2 + [4} +] 5
+ * Where [ denotes StartPos and ] denotes EndPos
+ * Then the sqrt node should be selected, so that the
+ * effective selection is: [sqrt{2 + 4} +] 5
+ * The same is the case if we swap StartPos and EndPos.
+ */
+ }
+
+ //Change state if StartPos is after this node
+ if( StartPos.pSelectedNode == pNode && StartPos.Index == 1 )
+ {
+ IsSelecting = !IsSelecting;
+ }
+ //Change state if EndPos is after of this node
+ if( EndPos.pSelectedNode == pNode && EndPos.Index == 1 )
+ {
+ IsSelecting = !IsSelecting;
+ }
+}
+
+void SmSetSelectionVisitor::VisitCompositionNode( SmNode* pNode ) {
+ //Change state if StartPos is infront of this node
+ if( StartPos.pSelectedNode == pNode && StartPos.Index == 0 )
+ IsSelecting = !IsSelecting;
+ //Change state if EndPos is infront of this node
+ if( EndPos.pSelectedNode == pNode && EndPos.Index == 0 )
+ IsSelecting = !IsSelecting;
+
+ //Cache current state
+ bool WasSelecting = IsSelecting;
+
+ //Visit children
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ it->Accept( this );
+
+ //Set selected, if everything was selected
+ pNode->SetSelected( WasSelecting && IsSelecting );
+
+ //Change state if StartPos is after this node
+ if( StartPos.pSelectedNode == pNode && StartPos.Index == 1 )
+ IsSelecting = !IsSelecting;
+ //Change state if EndPos is after of this node
+ if( EndPos.pSelectedNode == pNode && EndPos.Index == 1 )
+ IsSelecting = !IsSelecting;
+}
+
+void SmSetSelectionVisitor::Visit( SmTextNode* pNode ) {
+ long i1 = -1,
+ i2 = -1;
+ if( StartPos.pSelectedNode == pNode )
+ i1 = StartPos.Index;
+ if( EndPos.pSelectedNode == pNode )
+ i2 = EndPos.Index;
+
+ long start, end;
+ pNode->SetSelected( true );
+ if( i1 != -1 && i2 != -1 ) {
+ start = i1 < i2 ? i1 : i2; //MIN
+ end = i1 > i2 ? i1 : i2; //MAX
+ } else if( IsSelecting && i1 != -1 ) {
+ start = 0;
+ end = i1;
+ IsSelecting = false;
+ } else if( IsSelecting && i2 != -1 ) {
+ start = 0;
+ end = i2;
+ IsSelecting = false;
+ } else if( !IsSelecting && i1 != -1 ) {
+ start = i1;
+ end = pNode->GetText( ).Len( );
+ IsSelecting = true;
+ } else if( !IsSelecting && i2 != -1 ) {
+ start = i2;
+ end = pNode->GetText( ).Len( );
+ IsSelecting = true;
+ } else if( IsSelecting ) {
+ start = 0;
+ end = pNode->GetText( ).Len( );
+ } else {
+ pNode->SetSelected( false );
+ start = 0;
+ end = 0;
+ }
+ pNode->SetSelected( start != end );
+ pNode->SetSelectionStart( start );
+ pNode->SetSelectionEnd( end );
+}
+
+void SmSetSelectionVisitor::Visit( SmExpressionNode* pNode ) {
+ VisitCompositionNode( pNode );
+}
+
+void SmSetSelectionVisitor::Visit( SmLineNode* pNode ) {
+ VisitCompositionNode( pNode );
+}
+
+void SmSetSelectionVisitor::Visit( SmAlignNode* pNode ) {
+ VisitCompositionNode( pNode );
+}
+
+void SmSetSelectionVisitor::Visit( SmBinHorNode* pNode ) {
+ VisitCompositionNode( pNode );
+}
+
+void SmSetSelectionVisitor::Visit( SmUnHorNode* pNode ) {
+ VisitCompositionNode( pNode );
+}
+
+void SmSetSelectionVisitor::Visit( SmFontNode* pNode ) {
+ VisitCompositionNode( pNode );
+}
+
+/////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
+
+SmCaretPosGraphBuildingVisitor::SmCaretPosGraphBuildingVisitor( SmNode* pRootNode ) {
+ pRightMost = NULL;
+ pGraph = new SmCaretPosGraph( );
+ //pRootNode should always be a table
+ OSL_ENSURE( pRootNode->GetType( ) == NTABLE, "pRootNode must be a table node");
+ //Handle the special case where NTABLE is used a rootnode
+ if( pRootNode->GetType( ) == NTABLE ){
+ //Children are SmLineNodes
+ //Or so I thought... Aparently, the children can be instances of SmExpression
+ //especially if there's a error in the formula... So he we go, a simple work around.
+ SmNodeIterator it( pRootNode );
+ while( it.Next( ) ){
+ //There's a special invariant between this method and the Visit( SmLineNode* )
+ //Usually pRightMost may not be NULL, to avoid this pRightMost should here be
+ //set to a new SmCaretPos infront of it.Current( ), however, if it.Current( ) is
+ //an instance of SmLineNode we let SmLineNode create this position infront of
+ //the visual line.
+ //The argument for doing this is that we now don't have to worry about SmLineNode
+ //being a visual line composition node. Thus, no need for yet another special case
+ //in SmCursor::IsLineCompositionNode and everywhere this method is used.
+ //if( it->GetType( ) != NLINE )
+ pRightMost = pGraph->Add( SmCaretPos( it.Current( ), 0 ) );
+ it->Accept( this );
+ }
+ }else
+ pRootNode->Accept(this);
+}
+
+void SmCaretPosGraphBuildingVisitor::Visit( SmLineNode* pNode ){
+ SmNodeIterator it( pNode );
+ while( it.Next( ) ){
+ it->Accept( this );
+ }
+}
+
+/** Build SmCaretPosGraph for SmTableNode
+ * This method covers cases where SmTableNode is used in a binom or stack,
+ * the special case where it is used as root node for the entire formula is
+ * handled in the constructor.
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmTableNode* pNode ){
+ SmCaretPosGraphEntry *left = pRightMost,
+ *right = pGraph->Add( SmCaretPos( pNode, 1) );
+ bool bIsFirst = true;
+ SmNodeIterator it( pNode );
+ while( it.Next() ){
+ pRightMost = pGraph->Add( SmCaretPos( it.Current(), 0 ), left);
+ if(bIsFirst)
+ left->SetRight(pRightMost);
+ it->Accept( this );
+ pRightMost->SetRight(right);
+ if(bIsFirst)
+ right->SetLeft(pRightMost);
+ bIsFirst = false;
+ }
+ pRightMost = right;
+}
+
+/** Build SmCaretPosGraph for SmSubSupNode
+ *
+ * The child positions in a SubSupNode, where H is the body:
+ * \code
+ * CSUP
+ *
+ * LSUP H H RSUP
+ * H H
+ * HHHH
+ * H H
+ * LSUB H H RSUB
+ *
+ * CSUB
+ * \endcode
+ *
+ * Graph over these, where "left" is before the SmSubSupNode and "right" is after:
+ * \dot
+ * digraph Graph{
+ * left -> H;
+ * H -> right;
+ * LSUP -> H;
+ * LSUB -> H;
+ * CSUP -> right;
+ * CSUB -> right;
+ * RSUP -> right;
+ * RSUB -> right;
+ * };
+ * \enddot
+ *
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmSubSupNode* pNode )
+{
+ SmCaretPosGraphEntry *left,
+ *right,
+ *bodyLeft,
+ *bodyRight;
+
+ left = pRightMost;
+ OSL_ENSURE( pRightMost, "pRightMost shouldn't be NULL here!" );
+
+ //Create bodyLeft
+ OSL_ENSURE( pNode->GetBody( ), "SmSubSupNode Doesn't have a body!" );
+ bodyLeft = pGraph->Add( SmCaretPos( pNode->GetBody( ), 0 ), left );
+ left->SetRight( bodyLeft ); //TODO: Don't make this if LSUP or LSUB are NULL ( not sure??? )
+
+ //Create right
+ right = pGraph->Add( SmCaretPos( pNode, 1 ) );
+
+ //Visit the body, to get bodyRight
+ pRightMost = bodyLeft;
+ pNode->GetBody( )->Accept( this );
+ bodyRight = pRightMost;
+ bodyRight->SetRight( right );
+ right->SetLeft( bodyRight );
+
+ SmNode* pChild;
+ //If there's an LSUP
+ if( ( pChild = pNode->GetSubSup( LSUP ) ) ){
+ SmCaretPosGraphEntry *cLeft; //Child left
+ cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+
+ pRightMost = cLeft;
+ pChild->Accept( this );
+
+ pRightMost->SetRight( bodyLeft );
+ }
+ //If there's an LSUB
+ if( ( pChild = pNode->GetSubSup( LSUB ) ) ){
+ SmCaretPosGraphEntry *cLeft; //Child left
+ cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+
+ pRightMost = cLeft;
+ pChild->Accept( this );
+
+ pRightMost->SetRight( bodyLeft );
+ }
+ //If there's an CSUP
+ if( ( pChild = pNode->GetSubSup( CSUP ) ) ){
+ SmCaretPosGraphEntry *cLeft; //Child left
+ cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+
+ pRightMost = cLeft;
+ pChild->Accept( this );
+
+ pRightMost->SetRight( right );
+ }
+ //If there's an CSUB
+ if( ( pChild = pNode->GetSubSup( CSUB ) ) ){
+ SmCaretPosGraphEntry *cLeft; //Child left
+ cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+
+ pRightMost = cLeft;
+ pChild->Accept( this );
+
+ pRightMost->SetRight( right );
+ }
+ //If there's an RSUP
+ if( ( pChild = pNode->GetSubSup( RSUP ) ) ){
+ SmCaretPosGraphEntry *cLeft; //Child left
+ cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), bodyRight );
+
+ pRightMost = cLeft;
+ pChild->Accept( this );
+
+ pRightMost->SetRight( right );
+ }
+ //If there's an RSUB
+ if( ( pChild = pNode->GetSubSup( RSUB ) ) ){
+ SmCaretPosGraphEntry *cLeft; //Child left
+ cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), bodyRight );
+
+ pRightMost = cLeft;
+ pChild->Accept( this );
+
+ pRightMost->SetRight( right );
+ }
+
+ //Set return parameters
+ pRightMost = right;
+}
+
+/** Build caret position for SmOperNode
+ *
+ * If first child is an SmSubSupNode we will ignore it's
+ * body, as this body is a SmMathSymbol, for SUM, INT or similar
+ * that shouldn't be subject to modification.
+ * If first child is not a SmSubSupNode, ignore it completely
+ * as it is a SmMathSymbol.
+ *
+ * The child positions in a SmOperNode, where H is symbol, e.g. int, sum or similar:
+ * \code
+ * TO
+ *
+ * LSUP H H RSUP BBB BB BBB B B
+ * H H B B B B B B B B
+ * HHHH BBB B B B B B
+ * H H B B B B B B B
+ * LSUB H H RSUB BBB BB BBB B
+ *
+ * FROM
+ * \endcode
+ * Notice, CSUP, etc. are actually granchildren, but inorder to ignore H, these are visited
+ * from here. If they are present, that is if pOper is an instance of SmSubSupNode.
+ *
+ * Graph over these, where "left" is before the SmOperNode and "right" is after:
+ * \dot
+ * digraph Graph{
+ * left -> BODY;
+ * BODY -> right;
+ * LSUP -> BODY;
+ * LSUB -> BODY;
+ * TO -> BODY;
+ * FROM -> BODY;
+ * RSUP -> BODY;
+ * RSUB -> BODY;
+ * };
+ * \enddot
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmOperNode* pNode )
+{
+ SmNode *pOper = pNode->GetSubNode( 0 ),
+ *pBody = pNode->GetSubNode( 1 );
+
+ SmCaretPosGraphEntry *left = pRightMost,
+ *bodyLeft,
+ *bodyRight,
+ *right;
+ //Create body left
+ bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
+ left->SetRight( bodyLeft );
+
+ //Visit body, get bodyRight
+ pRightMost = bodyLeft;
+ pBody->Accept( this );
+ bodyRight = pRightMost;
+
+ //Create right
+ right = pGraph->Add( SmCaretPos( pNode, 1 ), bodyRight );
+ bodyRight->SetRight( right );
+
+ //Get subsup pNode if any
+ SmSubSupNode* pSubSup = pOper->GetType( ) == NSUBSUP ? ( SmSubSupNode* )pOper : NULL;
+
+ SmNode* pChild;
+ SmCaretPosGraphEntry *childLeft;
+ if( pSubSup && ( pChild = pSubSup->GetSubSup( LSUP ) ) ) {
+ //Create position infront of pChild
+ childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+ //Visit pChild
+ pRightMost = childLeft;
+ pChild->Accept( this );
+ //Set right on pRightMost from pChild
+ pRightMost->SetRight( bodyLeft );
+ }
+ if( pSubSup && ( pChild = pSubSup->GetSubSup( LSUB ) ) ) {
+ //Create position infront of pChild
+ childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+ //Visit pChild
+ pRightMost = childLeft;
+ pChild->Accept( this );
+ //Set right on pRightMost from pChild
+ pRightMost->SetRight( bodyLeft );
+ }
+ if( pSubSup && ( pChild = pSubSup->GetSubSup( CSUP ) ) ) {//TO
+ //Create position infront of pChild
+ childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+ //Visit pChild
+ pRightMost = childLeft;
+ pChild->Accept( this );
+ //Set right on pRightMost from pChild
+ pRightMost->SetRight( bodyLeft );
+ }
+ if( pSubSup && ( pChild = pSubSup->GetSubSup( CSUB ) ) ) { //FROM
+ //Create position infront of pChild
+ childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+ //Visit pChild
+ pRightMost = childLeft;
+ pChild->Accept( this );
+ //Set right on pRightMost from pChild
+ pRightMost->SetRight( bodyLeft );
+ }
+ if( pSubSup && ( pChild = pSubSup->GetSubSup( RSUP ) ) ) {
+ //Create position infront of pChild
+ childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+ //Visit pChild
+ pRightMost = childLeft;
+ pChild->Accept( this );
+ //Set right on pRightMost from pChild
+ pRightMost->SetRight( bodyLeft );
+ }
+ if( pSubSup && ( pChild = pSubSup->GetSubSup( RSUB ) ) ) {
+ //Create position infront of pChild
+ childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
+ //Visit pChild
+ pRightMost = childLeft;
+ pChild->Accept( this );
+ //Set right on pRightMost from pChild
+ pRightMost->SetRight( bodyLeft );
+ }
+
+ //Return right
+ pRightMost = right;
+}
+
+void SmCaretPosGraphBuildingVisitor::Visit( SmMatrixNode* pNode )
+{
+ SmCaretPosGraphEntry *left = pRightMost,
+ *right = pGraph->Add( SmCaretPos( pNode, 1 ) );
+
+ for ( sal_uInt16 i = 0; i < pNode->GetNumRows( ); i++ ) {
+ SmCaretPosGraphEntry* r = left;
+ for ( sal_uInt16 j = 0; j < pNode->GetNumCols( ); j++ ){
+ SmNode* pSubNode = pNode->GetSubNode( i * pNode->GetNumCols( ) + j );
+
+ pRightMost = pGraph->Add( SmCaretPos( pSubNode, 0 ), r );
+ if( j != 0 || ( pNode->GetNumRows( ) - 1 ) / 2 == i )
+ r->SetRight( pRightMost );
+
+ pSubNode->Accept( this );
+
+ r = pRightMost;
+ }
+ pRightMost->SetRight( right );
+ if( ( pNode->GetNumRows( ) - 1 ) / 2 == i )
+ right->SetLeft( pRightMost );
+ }
+
+ pRightMost = right;
+}
+
+/** Build SmCaretPosGraph for SmTextNode
+ *
+ * Lines in an SmTextNode:
+ * \code
+ * A B C
+ * \endcode
+ * Where A B and C are characters in the text.
+ *
+ * Graph over these, where "left" is before the SmTextNode and "right" is after:
+ * \dot
+ * digraph Graph{
+ * left -> A;
+ * A -> B
+ * B -> right;
+ * };
+ * \enddot
+ * Notice that C and right is the same position here.
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmTextNode* pNode )
+{
+ OSL_ENSURE( pNode->GetText( ).Len( ) > 0, "Empty SmTextNode is bad" );
+
+ int size = pNode->GetText( ).Len( );
+ for( int i = 1; i <= size; i++ ){
+ SmCaretPosGraphEntry* pRight = pRightMost;
+ pRightMost = pGraph->Add( SmCaretPos( pNode, i ), pRight );
+ pRight->SetRight( pRightMost );
+ }
+}
+
+/** Build SmCaretPosGraph for SmBinVerNode
+ *
+ * Lines in an SmBinVerNode:
+ * \code
+ * A
+ * -----
+ * B
+ * \endcode
+ *
+ * Graph over these, where "left" is before the SmBinVerNode and "right" is after:
+ * \dot
+ * digraph Graph{
+ * left -> A;
+ * A -> right;
+ * B -> right;
+ * };
+ * \enddot
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmBinVerNode* pNode )
+{
+ //None if these children can be NULL, see SmBinVerNode::Arrange
+ SmNode *pNum = pNode->GetSubNode( 0 ),
+ *pDenom = pNode->GetSubNode( 2 );
+
+ SmCaretPosGraphEntry *left,
+ *right,
+ *numLeft,
+ *denomLeft;
+
+ //Set left
+ left = pRightMost;
+ OSL_ENSURE( pRightMost, "There must be a position infront of this" );
+
+ //Create right
+ right = pGraph->Add( SmCaretPos( pNode, 1 ) );
+
+ //Create numLeft
+ numLeft = pGraph->Add( SmCaretPos( pNum, 0 ), left );
+ left->SetRight( numLeft );
+
+ //Visit pNum
+ pRightMost = numLeft;
+ pNum->Accept( this );
+ pRightMost->SetRight( right );
+ right->SetLeft( pRightMost );
+
+ //Create denomLeft
+ denomLeft = pGraph->Add( SmCaretPos( pDenom, 0 ), left );
+
+ //Visit pDenom
+ pRightMost = denomLeft;
+ pDenom->Accept( this );
+ pRightMost->SetRight( right );
+
+ //Set return parameter
+ pRightMost = right;
+}
+
+/** Build SmCaretPosGraph for SmVerticalBraceNode
+ *
+ * Lines in an SmVerticalBraceNode:
+ * \code
+ * pScript
+ * ________
+ * / \
+ * pBody
+ * \endcode
+ *
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmVerticalBraceNode* pNode )
+{
+ SmNode *pBody = pNode->GetSubNode( 0 ),
+ *pScript = pNode->GetSubNode( 2 );
+ //None of these children can be NULL
+
+ SmCaretPosGraphEntry *left,
+ *bodyLeft,
+ *scriptLeft,
+ *right;
+
+ left = pRightMost;
+
+ //Create right
+ right = pGraph->Add( SmCaretPos( pNode, 1 ) );
+
+ //Create bodyLeft
+ bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
+ left->SetRight( bodyLeft );
+ pRightMost = bodyLeft;
+ pBody->Accept( this );
+ pRightMost->SetRight( right );
+ right->SetLeft( pRightMost );
+
+ //Create script
+ scriptLeft = pGraph->Add( SmCaretPos( pScript, 0 ), left );
+ pRightMost = scriptLeft;
+ pScript->Accept( this );
+ pRightMost->SetRight( right );
+
+ //Set return value
+ pRightMost = right;
+}
+
+/** Build SmCaretPosGraph for SmBinDiagonalNode
+ *
+ * Lines in an SmBinDiagonalNode:
+ * \code
+ * A /
+ * /
+ * / B
+ * \endcode
+ * Where A and B are lines.
+ *
+ * Used in formulas such as "A wideslash B"
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmBinDiagonalNode* pNode )
+{
+ SmNode *A = pNode->GetSubNode( 0 ),
+ *B = pNode->GetSubNode( 1 );
+
+ SmCaretPosGraphEntry *left,
+ *leftA,
+ *rightA,
+ *leftB,
+ *right;
+ left = pRightMost;
+
+ //Create right
+ right = pGraph->Add( SmCaretPos( pNode, 1 ) );
+
+ //Create left A
+ leftA = pGraph->Add( SmCaretPos( A, 0 ), left );
+ left->SetRight( leftA );
+
+ //Visit A
+ pRightMost = leftA;
+ A->Accept( this );
+ rightA = pRightMost;
+
+ //Create left B
+ leftB = pGraph->Add( SmCaretPos( B, 0 ), rightA );
+ rightA->SetRight( leftB );
+
+ //Visit B
+ pRightMost = leftB;
+ B->Accept( this );
+ pRightMost->SetRight( right );
+ right->SetLeft( pRightMost );
+
+ //Set return value
+ pRightMost = right;
+}
+
+//Straigt forward ( I think )
+void SmCaretPosGraphBuildingVisitor::Visit( SmBinHorNode* pNode )
+{
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ it->Accept( this );
+}
+void SmCaretPosGraphBuildingVisitor::Visit( SmUnHorNode* pNode )
+{
+ // Unary operator node
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ it->Accept( this );
+
+}
+
+void SmCaretPosGraphBuildingVisitor::Visit( SmExpressionNode* pNode )
+{
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ it->Accept( this );
+}
+
+void SmCaretPosGraphBuildingVisitor::Visit( SmFontNode* pNode )
+{
+ //Has only got one child, should act as an expression if possible
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ it->Accept( this );
+}
+
+/** Build SmCaretPosGraph for SmBracebodyNode
+ * Acts as an SmExpressionNode
+ *
+ * Below is an example of a formula tree that has multiple children for SmBracebodyNode
+ * \dot
+ * digraph {
+ * labelloc = "t";
+ * label= "Equation: \"lbrace i mline i in setZ rbrace\"";
+ * n0 [label="SmTableNode"];
+ * n0 -> n1 [label="0"];
+ * n1 [label="SmLineNode"];
+ * n1 -> n2 [label="0"];
+ * n2 [label="SmExpressionNode"];
+ * n2 -> n3 [label="0"];
+ * n3 [label="SmBraceNode"];
+ * n3 -> n4 [label="0"];
+ * n4 [label="SmMathSymbolNode: {"];
+ * n3 -> n5 [label="1"];
+ * n5 [label="SmBracebodyNode"];
+ * n5 -> n6 [label="0"];
+ * n6 [label="SmExpressionNode"];
+ * n6 -> n7 [label="0"];
+ * n7 [label="SmTextNode: i"];
+ * n5 -> n8 [label="1"];
+ * n8 [label="SmMathSymbolNode: ∣"];
+ * n5 -> n9 [label="2"];
+ * n9 [label="SmExpressionNode"];
+ * n9 -> n10 [label="0"];
+ * n10 [label="SmBinHorNode"];
+ * n10 -> n11 [label="0"];
+ * n11 [label="SmTextNode: i"];
+ * n10 -> n12 [label="1"];
+ * n12 [label="SmMathSymbolNode: ∈"];
+ * n10 -> n13 [label="2"];
+ * n13 [label="SmMathSymbolNode: ℤ"];
+ * n3 -> n14 [label="2"];
+ * n14 [label="SmMathSymbolNode: }"];
+ * }
+ * \enddot
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmBracebodyNode* pNode )
+{
+ SmNodeIterator it( pNode );
+ while( it.Next( ) ) {
+ SmCaretPosGraphEntry* pStart = pGraph->Add( SmCaretPos( it.Current(), 0), pRightMost );
+ pRightMost->SetRight( pStart );
+ pRightMost = pStart;
+ it->Accept( this );
+ }
+}
+
+/** Build SmCaretPosGraph for SmAlignNode
+ * Acts as an SmExpressionNode, as it only has one child this okay
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmAlignNode* pNode )
+{
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ it->Accept( this );
+}
+
+/** Build SmCaretPosGraph for SmRootNode
+ *
+ * Lines in an SmRootNode:
+ * \code
+ * _________
+ * A/
+ * \/ B
+ *
+ * \endcode
+ * A: pExtra ( optional, can be NULL ),
+ * B: pBody
+ *
+ * Graph over these, where "left" is before the SmRootNode and "right" is after:
+ * \dot
+ * digraph Graph{
+ * left -> B;
+ * B -> right;
+ * A -> B;
+ * }
+ * \enddot
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmRootNode* pNode )
+{
+ SmNode *pExtra = pNode->GetSubNode( 0 ), //Argument, NULL for sqrt, and SmTextNode if cubicroot
+ *pBody = pNode->GetSubNode( 2 ); //Body of the root
+ OSL_ENSURE( pBody, "pBody cannot be NULL" );
+
+ SmCaretPosGraphEntry *left,
+ *right,
+ *bodyLeft,
+ *bodyRight;
+
+ //Get left and save it
+ OSL_ENSURE( pRightMost, "There must be a position infront of this" );
+ left = pRightMost;
+
+ //Create body left
+ bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
+ left->SetRight( bodyLeft );
+
+ //Create right
+ right = pGraph->Add( SmCaretPos( pNode, 1 ) );
+
+ //Visit body
+ pRightMost = bodyLeft;
+ pBody->Accept( this );
+ bodyRight = pRightMost;
+ bodyRight->SetRight( right );
+ right->SetLeft( bodyRight );
+
+ //Visit pExtra
+ if( pExtra ){
+ pRightMost = pGraph->Add( SmCaretPos( pExtra, 0 ), left );
+ pExtra->Accept( this );
+ pRightMost->SetRight( bodyLeft );
+ }
+
+ pRightMost = right;
+}
+
+/** Build SmCaretPosGraph for SmPlaceNode
+ * Consider this a single character.
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmPlaceNode* pNode )
+{
+ SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
+ pRightMost->SetRight( right );
+ pRightMost = right;
+}
+
+/** SmErrorNode is context dependent metadata, it can't be selected
+ *
+ * @remarks There's no point in deleting, copying and/or moving an instance
+ * of SmErrorNode as it may not exist in an other context! Thus there are no
+ * positions to select an SmErrorNode.
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmErrorNode* )
+{
+}
+
+/** Build SmCaretPosGraph for SmBlankNode
+ * Consider this a single character, as it is only a blank space
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmBlankNode* pNode )
+{
+ SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
+ pRightMost->SetRight( right );
+ pRightMost = right;
+}
+
+/** Build SmCaretPosGraph for SmBraceNode
+ *
+ * Lines in an SmBraceNode:
+ * \code
+ * | |
+ * | B |
+ * | |
+ * \endcode
+ * B: Body
+ *
+ * Graph over these, where "left" is before the SmBraceNode and "right" is after:
+ * \dot
+ * digraph Graph{
+ * left -> B;
+ * B -> right;
+ * }
+ * \enddot
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmBraceNode* pNode )
+{
+ SmNode* pBody = pNode->GetSubNode( 1 );
+
+ SmCaretPosGraphEntry *left = pRightMost,
+ *right = pGraph->Add( SmCaretPos( pNode, 1 ) );
+
+ if( pBody->GetType() != NBRACEBODY ) {
+ pRightMost = pGraph->Add( SmCaretPos( pBody, 0 ), left );
+ left->SetRight( pRightMost );
+ }else
+ pRightMost = left;
+
+ pBody->Accept( this );
+ pRightMost->SetRight( right );
+ right->SetLeft( pRightMost );
+
+ pRightMost = right;
+}
+
+/** Build SmCaretPosGraph for SmAttributNode
+ *
+ * Lines in an SmAttributNode:
+ * \code
+ * Attr
+ * Body
+ * \endcode
+ *
+ * There's a body and an attribute, the construction is used for "widehat A", where "A" is the body
+ * and "^" is the attribute ( note GetScaleMode( ) on SmAttributNode tells how the attribute should be
+ * scaled ).
+ */
+void SmCaretPosGraphBuildingVisitor::Visit( SmAttributNode* pNode )
+{
+ SmNode *pAttr = pNode->GetSubNode( 0 ),
+ *pBody = pNode->GetSubNode( 1 );
+ //None of the children can be NULL
+
+ SmCaretPosGraphEntry *left = pRightMost,
+ *attrLeft,
+ *bodyLeft,
+ *bodyRight,
+ *right;
+
+ //Creating bodyleft
+ bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
+ left->SetRight( bodyLeft );
+
+ //Creating right
+ right = pGraph->Add( SmCaretPos( pNode, 1 ) );
+
+ //Visit the body
+ pRightMost = bodyLeft;
+ pBody->Accept( this );
+ bodyRight = pRightMost;
+ bodyRight->SetRight( right );
+ right->SetLeft( bodyRight );
+
+ //Create attrLeft
+ attrLeft = pGraph->Add( SmCaretPos( pAttr, 0 ), left );
+
+ //Visit attribute
+ pRightMost = attrLeft;
+ pAttr->Accept( this );
+ pRightMost->SetRight( right );
+
+ //Set return value
+ pRightMost = right;
+}
+
+//Consider these single symboles
+void SmCaretPosGraphBuildingVisitor::Visit( SmSpecialNode* pNode )
+{
+ SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
+ pRightMost->SetRight( right );
+ pRightMost = right;
+}
+void SmCaretPosGraphBuildingVisitor::Visit( SmGlyphSpecialNode* pNode )
+{
+ SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
+ pRightMost->SetRight( right );
+ pRightMost = right;
+}
+void SmCaretPosGraphBuildingVisitor::Visit( SmMathSymbolNode* pNode )
+{
+ SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
+ pRightMost->SetRight( right );
+ pRightMost = right;
+}
+
+void SmCaretPosGraphBuildingVisitor::Visit( SmRootSymbolNode* )
+{
+ //Do nothing
+}
+void SmCaretPosGraphBuildingVisitor::Visit( SmRectangleNode* )
+{
+ //Do nothing
+}
+void SmCaretPosGraphBuildingVisitor::Visit( SmPolyLineNode* )
+{
+ //Do nothing
+}
+
+/////////////////////////////// SmCloningVisitor ///////////////////////////////
+
+SmNode* SmCloningVisitor::Clone( SmNode* pNode )
+{
+ SmNode* pCurrResult = pResult;
+ pNode->Accept( this );
+ SmNode* pClone = pResult;
+ pResult = pCurrResult;
+ return pClone;
+}
+
+void SmCloningVisitor::CloneNodeAttr( SmNode* pSource, SmNode* pTarget )
+{
+ pTarget->SetScaleMode( pSource->GetScaleMode( ) );
+ //Other attributes are set when prepare or arrange is executed
+ //and may depend on stuff not being cloned here.
+}
+
+void SmCloningVisitor::CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget )
+{
+ //Cache current result
+ SmNode* pCurrResult = pResult;
+
+ //Create array for holding clones
+ sal_uInt16 nSize = pSource->GetNumSubNodes( );
+ SmNodeArray aNodes( nSize );
+
+ //Clone children
+ SmNode* pKid;
+ for( sal_uInt16 i = 0; i < nSize; i++ ){
+ if( NULL != ( pKid = pSource->GetSubNode( i ) ) )
+ pKid->Accept( this );
+ else
+ pResult = NULL;
+ aNodes[i] = pResult;
+ }
+
+ //Set subnodes of pTarget
+ pTarget->SetSubNodes( aNodes );
+
+ //Restore result as where prior to call
+ pResult = pCurrResult;
+}
+
+void SmCloningVisitor::Visit( SmTableNode* pNode )
+{
+ SmTableNode* pClone = new SmTableNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmBraceNode* pNode )
+{
+ SmBraceNode* pClone = new SmBraceNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmBracebodyNode* pNode )
+{
+ SmBracebodyNode* pClone = new SmBracebodyNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmOperNode* pNode )
+{
+ SmOperNode* pClone = new SmOperNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmAlignNode* pNode )
+{
+ SmAlignNode* pClone = new SmAlignNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmAttributNode* pNode )
+{
+ SmAttributNode* pClone = new SmAttributNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmFontNode* pNode )
+{
+ SmFontNode* pClone = new SmFontNode( pNode->GetToken( ) );
+ pClone->SetSizeParameter( pNode->GetSizeParameter( ), pNode->GetSizeType( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmUnHorNode* pNode )
+{
+ SmUnHorNode* pClone = new SmUnHorNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmBinHorNode* pNode )
+{
+ SmBinHorNode* pClone = new SmBinHorNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmBinVerNode* pNode )
+{
+ SmBinVerNode* pClone = new SmBinVerNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmBinDiagonalNode* pNode )
+{
+ SmBinDiagonalNode *pClone = new SmBinDiagonalNode( pNode->GetToken( ) );
+ pClone->SetAscending( pNode->IsAscending( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmSubSupNode* pNode )
+{
+ SmSubSupNode *pClone = new SmSubSupNode( pNode->GetToken( ) );
+ pClone->SetUseLimits( pNode->IsUseLimits( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmMatrixNode* pNode )
+{
+ SmMatrixNode *pClone = new SmMatrixNode( pNode->GetToken( ) );
+ pClone->SetRowCol( pNode->GetNumRows( ), pNode->GetNumCols( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmPlaceNode* pNode )
+{
+ pResult = new SmPlaceNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmTextNode* pNode )
+{
+ SmTextNode* pClone = new SmTextNode( pNode->GetToken( ), pNode->GetFontDesc( ) );
+ pClone->ChangeText( pNode->GetText( ) );
+ CloneNodeAttr( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmSpecialNode* pNode )
+{
+ pResult = new SmSpecialNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmGlyphSpecialNode* pNode )
+{
+ pResult = new SmGlyphSpecialNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmMathSymbolNode* pNode )
+{
+ pResult = new SmMathSymbolNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmBlankNode* pNode )
+{
+ SmBlankNode* pClone = new SmBlankNode( pNode->GetToken( ) );
+ pClone->SetBlankNum( pNode->GetBlankNum( ) );
+ pResult = pClone;
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmErrorNode* pNode )
+{
+ //PE_NONE is used the information have been discarded and isn't used
+ pResult = new SmErrorNode( PE_NONE, pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmLineNode* pNode )
+{
+ SmLineNode* pClone = new SmLineNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmExpressionNode* pNode )
+{
+ SmExpressionNode* pClone = new SmExpressionNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmPolyLineNode* pNode )
+{
+ pResult = new SmPolyLineNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmRootNode* pNode )
+{
+ SmRootNode* pClone = new SmRootNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+void SmCloningVisitor::Visit( SmRootSymbolNode* pNode )
+{
+ pResult = new SmRootSymbolNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmRectangleNode* pNode )
+{
+ pResult = new SmRectangleNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pResult );
+}
+
+void SmCloningVisitor::Visit( SmVerticalBraceNode* pNode )
+{
+ SmVerticalBraceNode* pClone = new SmVerticalBraceNode( pNode->GetToken( ) );
+ CloneNodeAttr( pNode, pClone );
+ CloneKids( pNode, pClone );
+ pResult = pClone;
+}
+
+/////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
+
+SmSelectionDrawingVisitor::SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, Point Offset )
+ : rDev( rDevice ) {
+ bHasSelectionArea = false;
+
+ //Visit everything
+ OSL_ENSURE( pTree, "pTree can't be null!" );
+ if( pTree )
+ pTree->Accept( this );
+
+ //Draw selection if there's any
+ if( bHasSelectionArea ){
+ aSelectionArea.Move( Offset.X( ), Offset.Y( ) );
+
+ //Save device state
+ rDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ //Change colors
+ rDev.SetLineColor( );
+ rDev.SetFillColor( Color( COL_LIGHTGRAY ) );
+
+ //Draw rectangle
+ rDev.DrawRect( aSelectionArea );
+
+ //Restore device state
+ rDev.Pop( );
+ }
+}
+
+void SmSelectionDrawingVisitor::ExtendSelectionArea( Rectangle aArea )
+{
+ if ( ! bHasSelectionArea ) {
+ aSelectionArea = aArea;
+ bHasSelectionArea = true;
+ } else
+ aSelectionArea.Union( aArea );
+}
+
+void SmSelectionDrawingVisitor::DefaultVisit( SmNode* pNode )
+{
+ if( pNode->IsSelected( ) )
+ ExtendSelectionArea( pNode->AsRectangle( ) );
+ VisitChildren( pNode );
+}
+
+void SmSelectionDrawingVisitor::VisitChildren( SmNode* pNode )
+{
+ SmNodeIterator it( pNode );
+ while( it.Next( ) )
+ it->Accept( this );
+}
+
+void SmSelectionDrawingVisitor::Visit( SmTextNode* pNode )
+{
+ if( pNode->IsSelected( ) ){
+ rDev.Push( PUSH_TEXTCOLOR | PUSH_FONT );
+
+ rDev.SetFont( pNode->GetFont( ) );
+ Point Position = pNode->GetTopLeft( );
+ long left = Position.getX( ) + rDev.GetTextWidth( pNode->GetText( ), 0, pNode->GetSelectionStart( ) );
+ long right = Position.getX( ) + rDev.GetTextWidth( pNode->GetText( ), 0, pNode->GetSelectionEnd( ) );
+ long top = Position.getY( );
+ long bottom = top + pNode->GetHeight( );
+ Rectangle rect( left, top, right, bottom );
+
+ ExtendSelectionArea( rect );
+
+ rDev.Pop( );
+ }
+}
+
+/////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
+
+void SmNodeToTextVisitor::Visit( SmTableNode* pNode )
+{
+ if( pNode->GetToken( ).eType == TBINOM ) {
+ Append( "{ binom" );
+ LineToText( pNode->GetSubNode( 0 ) );
+ LineToText( pNode->GetSubNode( 1 ) );
+ Append("} ");
+ } else if( pNode->GetToken( ).eType == TSTACK ) {
+ Append( "stack{ " );
+ SmNodeIterator it( pNode );
+ it.Next( );
+ while( true ) {
+ LineToText( it.Current( ) );
+ if( it.Next( ) ) {
+ Separate( );
+ Append( "# " );
+ }else
+ break;
+ }
+ Separate( );
+ Append( "}" );
+ } else { //Assume it's a toplevel table, containing lines
+ SmNodeIterator it( pNode );
+ it.Next( );
+ while( true ) {
+ Separate( );
+ it->Accept( this );
+ if( it.Next( ) ) {
+ Separate( );
+ Append( "newline" );
+ }else
+ break;
+ }
+ }
+}
+
+void SmNodeToTextVisitor::Visit( SmBraceNode* pNode )
+{
+ SmNode *pLeftBrace = pNode->GetSubNode( 0 ),
+ *pBody = pNode->GetSubNode( 1 ),
+ *pRightBrace = pNode->GetSubNode( 2 );
+ //Handle special case where it's absolute function
+ if( pNode->GetToken( ).eType == TABS ) {
+ Append( "abs" );
+ LineToText( pBody );
+ } else {
+ if( pNode->GetScaleMode( ) == SCALE_HEIGHT )
+ Append( "left " );
+ pLeftBrace->Accept( this );
+ Separate( );
+ pBody->Accept( this );
+ Separate( );
+ if( pNode->GetScaleMode( ) == SCALE_HEIGHT )
+ Append( "right " );
+ pRightBrace->Accept( this );
+ }
+}
+
+void SmNodeToTextVisitor::Visit( SmBracebodyNode* pNode )
+{
+ SmNodeIterator it( pNode );
+ while( it.Next( ) ){
+ Separate( );
+ it->Accept( this );
+ }
+}
+
+void SmNodeToTextVisitor::Visit( SmOperNode* pNode )
+{
+ Append( pNode->GetToken( ).aText );
+ Separate( );
+ if( pNode->GetToken( ).eType == TOPER ){
+ //There's an SmGlyphSpecialNode if eType == TOPER
+ if( pNode->GetSubNode( 0 )->GetType( ) == NSUBSUP )
+ Append( pNode->GetSubNode( 0 )->GetSubNode( 0 )->GetToken( ).aText );
+ else
+ Append( pNode->GetSubNode( 0 )->GetToken( ).aText );
+ }
+ if( pNode->GetSubNode( 0 )->GetType( ) == NSUBSUP ) {
+ SmSubSupNode *pSubSup = ( SmSubSupNode* )pNode->GetSubNode( 0 );
+ SmNode* pChild;
+ if( ( pChild = pSubSup->GetSubSup( LSUP ) ) ) {
+ Separate( );
+ Append( "lsup { " );
+ LineToText( pChild );
+ Append( "} " );
+ }
+ if( ( pChild = pSubSup->GetSubSup( LSUB ) ) ) {
+ Separate( );
+ Append( "lsub { " );
+ LineToText( pChild );
+ Append( "} " );
+ }
+ if( ( pChild = pSubSup->GetSubSup( RSUP ) ) ) {
+ Separate( );
+ Append( "rsup { " );
+ LineToText( pChild );
+ Append( "} " );
+ }
+ if( ( pChild = pSubSup->GetSubSup( RSUB ) ) ) {
+ Separate( );
+ Append( "rsub { " );
+ LineToText( pChild );
+ Append( "} " );
+ }
+ if( ( pChild = pSubSup->GetSubSup( CSUP ) ) ) {
+ Separate( );
+ Append( "csup { " );
+ LineToText( pChild );
+ Append( "} " );
+ }
+ if( ( pChild = pSubSup->GetSubSup( CSUB ) ) ) {
+ Separate( );
+ Append( "csub { " );
+ LineToText( pChild );
+ Append( "} " );
+ }
+ }
+ LineToText( pNode->GetSubNode( 1 ) );
+}
+
+void SmNodeToTextVisitor::Visit( SmAlignNode* pNode )
+{
+ Append( pNode->GetToken( ).aText );
+ LineToText( pNode->GetSubNode( 0 ) );
+}
+
+void SmNodeToTextVisitor::Visit( SmAttributNode* pNode )
+{
+ Append( pNode->GetToken( ).aText );
+ LineToText( pNode->GetSubNode( 1 ) );
+}
+
+void SmNodeToTextVisitor::Visit( SmFontNode* pNode )
+{
+ switch ( pNode->GetToken( ).eType )
+ {
+ case TBOLD:
+ Append( "bold " );
+ break;
+ case TNBOLD:
+ Append( "nbold " );
+ break;
+ case TITALIC:
+ Append( "italic " );
+ break;
+ case TNITALIC:
+ Append( "nitalic " );
+ break;
+ case TPHANTOM:
+ Append( "phantom " );
+ break;
+ case TSIZE:
+ {
+ Append( "size " );
+ switch ( pNode->GetSizeType( ) )
+ {
+ case FNTSIZ_PLUS:
+ Append( "+" );
+ break;
+ case FNTSIZ_MINUS:
+ Append( "-" );
+ break;
+ case FNTSIZ_MULTIPLY:
+ Append( "*" );
+ break;
+ case FNTSIZ_DIVIDE:
+ Append( "/" );
+ break;
+ case FNTSIZ_ABSOLUT:
+ default:
+ break;
+ }
+ Append( String( ::rtl::math::doubleToUString(
+ static_cast<double>( pNode->GetSizeParameter( ) ),
+ rtl_math_StringFormat_Automatic,
+ rtl_math_DecimalPlaces_Max, '.', sal_True ) ) );
+ Append( " " );
+ }
+ break;
+ case TBLACK:
+ Append( "color black " );
+ break;
+ case TWHITE:
+ Append( "color white " );
+ break;
+ case TRED:
+ Append( "color red " );
+ break;
+ case TGREEN:
+ Append( "color green " );
+ break;
+ case TBLUE:
+ Append( "color blue " );
+ break;
+ case TCYAN:
+ Append( "color cyan " );
+ break;
+ case TMAGENTA:
+ Append( "color magenta " );
+ break;
+ case TYELLOW:
+ Append( "color yellow " );
+ break;
+ case TSANS:
+ Append( "font sans " );
+ break;
+ case TSERIF:
+ Append( "font serif " );
+ break;
+ case TFIXED:
+ Append( "font fixed " );
+ break;
+ default:
+ break;
+ }
+ LineToText( pNode->GetSubNode( 1 ) );
+}
+
+void SmNodeToTextVisitor::Visit( SmUnHorNode* pNode )
+{
+ SmNodeIterator it( pNode, pNode->GetSubNode( 1 )->GetToken( ).eType == TFACT );
+ while( it.Next( ) ) {
+ Separate( );
+ it->Accept( this );
+ }
+}
+
+void SmNodeToTextVisitor::Visit( SmBinHorNode* pNode )
+{
+ SmNode *pLeft = pNode->GetSubNode( 0 ),
+ *pOper = pNode->GetSubNode( 1 ),
+ *pRight = pNode->GetSubNode( 2 );
+ Separate( );
+ pLeft->Accept( this );
+ Separate( );
+ pOper->Accept( this );
+ Separate( );
+ pRight->Accept( this );
+ Separate( );
+}
+
+void SmNodeToTextVisitor::Visit( SmBinVerNode* pNode )
+{
+ SmNode *pNum = pNode->GetSubNode( 0 ),
+ *pDenom = pNode->GetSubNode( 2 );
+ Append( "{ " );
+ LineToText( pNum );
+ Append( "over" );
+ LineToText( pDenom );
+ Append( "} " );
+}
+
+void SmNodeToTextVisitor::Visit( SmBinDiagonalNode* pNode )
+{
+ SmNode *pLeftOperand = pNode->GetSubNode( 0 ),
+ *pRightOperand = pNode->GetSubNode( 1 );
+ Append( "{ " );
+ LineToText( pLeftOperand );
+ Separate( );
+ Append( "wideslash " );
+ LineToText( pRightOperand );
+ Append( "} " );
+}
+
+void SmNodeToTextVisitor::Visit( SmSubSupNode* pNode )
+{
+ LineToText( pNode->GetBody( ) );
+ SmNode *pChild;
+ if( ( pChild = pNode->GetSubSup( LSUP ) ) ) {
+ Separate( );
+ Append( "lsup " );
+ LineToText( pChild );
+ }
+ if( ( pChild = pNode->GetSubSup( LSUB ) ) ) {
+ Separate( );
+ Append( "lsub " );
+ LineToText( pChild );
+ }
+ if( ( pChild = pNode->GetSubSup( RSUP ) ) ) {
+ Separate( );
+ Append( "rsup " );
+ LineToText( pChild );
+ }
+ if( ( pChild = pNode->GetSubSup( RSUB ) ) ) {
+ Separate( );
+ Append( "rsub " );
+ LineToText( pChild );
+ }
+ if( ( pChild = pNode->GetSubSup( CSUP ) ) ) {
+ Separate( );
+ Append( "csup " );
+ LineToText( pChild );
+ }
+ if( ( pChild = pNode->GetSubSup( CSUB ) ) ) {
+ Separate( );
+ Append( "csub " );
+ LineToText( pChild );
+ }
+}
+
+void SmNodeToTextVisitor::Visit( SmMatrixNode* pNode )
+{
+ Append( "matrix{" );
+ for ( sal_uInt16 i = 0; i < pNode->GetNumRows( ); i++ ) {
+ for ( sal_uInt16 j = 0; j < pNode->GetNumCols( ); j++ ) {
+ SmNode* pSubNode = pNode->GetSubNode( i * pNode->GetNumCols( ) + j );
+ Separate( );
+ pSubNode->Accept( this );
+ Separate( );
+ if( j != pNode->GetNumCols( ) - 1 )
+ Append( "#" );
+ }
+ Separate( );
+ if( i != pNode->GetNumRows( ) - 1 )
+ Append( "##" );
+ }
+ Append( "} " );
+}
+
+void SmNodeToTextVisitor::Visit( SmPlaceNode* )
+{
+ Append( "<?>" );
+}
+
+void SmNodeToTextVisitor::Visit( SmTextNode* pNode )
+{
+ //TODO: This method might need improvements, see SmTextNode::CreateTextFromNode
+ if( pNode->GetToken( ).eType == TTEXT )
+ Append( "\"" );
+ Append( pNode->GetText( ) );
+ if( pNode->GetToken( ).eType == TTEXT )
+ Append( "\"" );
+}
+
+void SmNodeToTextVisitor::Visit( SmSpecialNode* pNode )
+{
+ Append( pNode->GetToken( ).aText );
+}
+
+void SmNodeToTextVisitor::Visit( SmGlyphSpecialNode* pNode )
+{
+ if( pNode->GetToken( ).eType == TBOPER )
+ Append( "boper " );
+ else
+ Append( "uoper " );
+ Append( pNode->GetToken( ).aText );
+}
+
+void SmNodeToTextVisitor::Visit( SmMathSymbolNode* pNode )
+{
+ Append( pNode->GetToken( ).aText );
+}
+
+void SmNodeToTextVisitor::Visit( SmBlankNode* pNode )
+{
+ Append( pNode->GetToken( ).aText );
+}
+
+void SmNodeToTextVisitor::Visit( SmErrorNode* )
+{
+}
+
+void SmNodeToTextVisitor::Visit( SmLineNode* pNode )
+{
+ SmNodeIterator it( pNode );
+ while( it.Next( ) ){
+ Separate( );
+ it->Accept( this );
+ }
+}
+
+void SmNodeToTextVisitor::Visit( SmExpressionNode* pNode )
+{
+ bool bracketsNeeded = pNode->GetNumSubNodes() != 1 || pNode->GetSubNode(0)->GetType() == NBINHOR;
+ if (bracketsNeeded) {
+ Append( "{ " );
+ }
+ SmNodeIterator it( pNode );
+ while( it.Next( ) ) {
+ it->Accept( this );
+ Separate( );
+ }
+ if (bracketsNeeded) {
+ Append( "} " );
+ }
+}
+
+void SmNodeToTextVisitor::Visit( SmPolyLineNode* )
+{
+}
+
+void SmNodeToTextVisitor::Visit( SmRootNode* pNode )
+{
+ SmNode *pExtra = pNode->GetSubNode( 0 ),
+ *pBody = pNode->GetSubNode( 2 );
+ if( pExtra ) {
+ Append( "nroot" );
+ LineToText( pExtra );
+ } else
+ Append( "sqrt" );
+ LineToText( pBody );
+}
+
+void SmNodeToTextVisitor::Visit( SmRootSymbolNode* )
+{
+}
+
+void SmNodeToTextVisitor::Visit( SmRectangleNode* )
+{
+}
+
+void SmNodeToTextVisitor::Visit( SmVerticalBraceNode* pNode )
+{
+ SmNode *pBody = pNode->GetSubNode( 0 ),
+ *pScript = pNode->GetSubNode( 2 );
+ LineToText( pBody );
+ Append( pNode->GetToken( ).aText );
+ LineToText( pScript );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/uiconfig/smath/menubar/menubar.xml b/starmath/uiconfig/smath/menubar/menubar.xml
new file mode 100755
index 000000000000..dcb68e740718
--- /dev/null
+++ b/starmath/uiconfig/smath/menubar/menubar.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<menu:menubar xmlns:menu="http://openoffice.org/2001/menu" menu:id="menubar">
+ <menu:menu menu:id=".uno:PickList">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:AddDirect"/>
+ <menu:menuitem menu:id=".uno:Open"/>
+ <menu:menuitem menu:id=".uno:RecentFileList"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:AutoPilotMenu"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:CloseDoc"/>
+ <menu:menuitem menu:id=".uno:Save"/>
+ <menu:menuitem menu:id=".uno:SaveAs"/>
+ <menu:menuitem menu:id=".uno:SaveAll"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:Reload"/>
+ <menu:menuitem menu:id=".uno:VersionDialog"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:ExportTo"/>
+ <menu:menu menu:id=".uno:SendToMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:SendMail"/>
+ <menu:menuitem menu:id=".uno:SendMailDocAsPDF"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:SetDocumentProperties"/>
+ <menu:menuitem menu:id=".uno:Signature"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:Print"/>
+ <menu:menuitem menu:id=".uno:PrinterSetup"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:Quit"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:EditMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:Undo"/>
+ <menu:menuitem menu:id=".uno:Redo"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:Cut"/>
+ <menu:menuitem menu:id=".uno:Copy"/>
+ <menu:menuitem menu:id=".uno:Paste"/>
+ <menu:menuitem menu:id=".uno:Select"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:NextMark"/>
+ <menu:menuitem menu:id=".uno:PrevMark"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:NextError"/>
+ <menu:menuitem menu:id=".uno:PrevError"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:ViewMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:Draw"/>
+ <menu:menuitem menu:id=".uno:RedrawAutomatic"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:AvailableToolbars"/>
+ <menu:menuitem menu:id=".uno:StatusBarVisible"/>
+ <menu:menuitem menu:id=".uno:ShowImeStatusWindow"/>
+ <menu:menuitem menu:id=".uno:ToolBox"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:TaskPane"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:FullScreen"/>
+ <menu:menuitem menu:id=".uno:ZoomIn"/>
+ <menu:menuitem menu:id=".uno:ZoomOut"/>
+ <menu:menuitem menu:id=".uno:Adjust"/>
+ <menu:menuitem menu:id=".uno:Zoom"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:FormatMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:ChangeFont"/>
+ <menu:menuitem menu:id=".uno:ChangeFontSize"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:ChangeDistance"/>
+ <menu:menuitem menu:id=".uno:ChangeAlignment"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:Textmode"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:ToolsMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:SymbolCatalogue"/>
+ <menu:menuitem menu:id=".uno:ImportFormula"/>
+ <menu:menuseparator/>
+ <menu:menu menu:id=".uno:MacrosMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:MacroRecorder"/>
+ <menu:menuitem menu:id=".uno:RunMacro"/>
+ <menu:menu menu:id=".uno:ScriptOrganizer"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:MacroOrganizer?TabId:short=1"/>
+ </menu:menupopup>
+ </menu:menu>
+
+ <menu:menuitem menu:id="service:com.sun.star.deployment.ui.PackageManagerDialog"/>
+ <menu:menuitem menu:id=".uno:ConfigureDialog"/>
+ <menu:menuitem menu:id=".uno:OptionsTreeDialog"/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:WindowList">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:NewWindow"/>
+ <menu:menuitem menu:id=".uno:CloseWin"/>
+ <menu:menuseparator/>
+ </menu:menupopup>
+ </menu:menu>
+ <menu:menu menu:id=".uno:HelpMenu">
+ <menu:menupopup>
+ <menu:menuitem menu:id=".uno:HelpIndex"/>
+ <menu:menuitem menu:id=".uno:ExtendedHelp"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:ShowLicense"/>
+ <menu:menuseparator/>
+ <menu:menuitem menu:id=".uno:ShowCredits"/>
+ <menu:menuitem menu:id=".uno:About"/>
+ </menu:menupopup>
+ </menu:menu>
+</menu:menubar>
diff --git a/starmath/uiconfig/smath/statusbar/statusbar.xml b/starmath/uiconfig/smath/statusbar/statusbar.xml
new file mode 100644
index 000000000000..33e4e4888f2a
--- /dev/null
+++ b/starmath/uiconfig/smath/statusbar/statusbar.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE statusbar:statusbar PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "statusbar.dtd">
+<statusbar:statusbar xmlns:statusbar="http://openoffice.org/2001/statusbar" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <statusbar:statusbaritem xlink:href=".uno:TextStatus" statusbar:align="left" statusbar:width="300" statusbar:helpid="helpid:30367"/>
+ <statusbar:statusbaritem xlink:href=".uno:Zoom" statusbar:align="center" statusbar:width="54" statusbar:helpid="helpid:10000"/>
+ <statusbar:statusbaritem xlink:href=".uno:ModifiedStatus" statusbar:align="center" statusbar:ownerdraw="true" statusbar:width="14" statusbar:helpid="helpid:5584"/>
+ <statusbar:statusbaritem xlink:href=".uno:Signature" statusbar:align="center" statusbar:ownerdraw="true" statusbar:width="16" statusbar:helpid="helpid:5699"/>
+</statusbar:statusbar> \ No newline at end of file
diff --git a/starmath/uiconfig/smath/toolbar/fullscreenbar.xml b/starmath/uiconfig/smath/toolbar/fullscreenbar.xml
new file mode 100644
index 000000000000..ce9cf7d93013
--- /dev/null
+++ b/starmath/uiconfig/smath/toolbar/fullscreenbar.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE toolbar:toolbar PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "toolbar.dtd">
+<toolbar:toolbar xmlns:toolbar="http://openoffice.org/2001/toolbar" xmlns:xlink="http://www.w3.org/1999/xlink" toolbar:id="toolbar">
+ <toolbar:toolbaritem xlink:href=".uno:FullScreen" toolbar:helpid="helpid:5627" toolbar:text="" />
+</toolbar:toolbar> \ No newline at end of file
diff --git a/starmath/uiconfig/smath/toolbar/standardbar.xml b/starmath/uiconfig/smath/toolbar/standardbar.xml
new file mode 100644
index 000000000000..1a00b34b0128
--- /dev/null
+++ b/starmath/uiconfig/smath/toolbar/standardbar.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE toolbar:toolbar PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "toolbar.dtd">
+<toolbar:toolbar xmlns:toolbar="http://openoffice.org/2001/toolbar" xmlns:xlink="http://www.w3.org/1999/xlink" toolbar:id="toolbar">
+ <toolbar:toolbaritem xlink:href=".uno:OpenUrl" toolbar:visible="false"/>
+ <toolbar:toolbaritem xlink:href=".uno:AddDirect" toolbar:helpid="helpid:5537" toolbar:text="" toolbar:style="dropdown" />
+ <toolbar:toolbaritem xlink:href=".uno:NewDoc" toolbar:helpid="helpid:5500" toolbar:text="" toolbar:visible="false" />
+ <toolbar:toolbaritem xlink:href=".uno:Open" toolbar:helpid="helpid:5501" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:Save" toolbar:helpid="helpid:5505" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:SaveAs" toolbar:helpid="helpid:5502" toolbar:text="" toolbar:visible="false" />
+ <toolbar:toolbaritem xlink:href=".uno:SendMail" toolbar:helpid="5331"/>
+ <toolbar:toolbarseparator/>
+ <toolbar:toolbaritem xlink:href=".uno:ExportDirectToPDF" toolbar:helpid="helpid:6674" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:PrintDefault" toolbar:helpid="helpid:5509" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:SendFax" toolbar:helpid="helpid:20028" toolbar:text="" toolbar:visible="false" />
+ <toolbar:toolbarseparator/>
+ <toolbar:toolbaritem xlink:href=".uno:Cut" toolbar:helpid="helpid:5710" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:Copy" toolbar:helpid="helpid:5711" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:Paste" toolbar:helpid="helpid:5712" toolbar:text="" />
+ <toolbar:toolbarseparator/>
+ <toolbar:toolbaritem xlink:href=".uno:Undo" toolbar:helpid="helpid:5701" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:Redo" toolbar:helpid="helpid:5700" toolbar:text="" />
+ <toolbar:toolbarseparator/>
+ <toolbar:toolbaritem xlink:href=".uno:HelpIndex" toolbar:helpid="helpid:5401" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:ExtendedHelp" toolbar:text="" toolbar:visible="false" toolbar:helpid="5402"/>
+
+</toolbar:toolbar>
diff --git a/starmath/uiconfig/smath/toolbar/toolbar.xml b/starmath/uiconfig/smath/toolbar/toolbar.xml
new file mode 100644
index 000000000000..1d3eeb2dd0c8
--- /dev/null
+++ b/starmath/uiconfig/smath/toolbar/toolbar.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE toolbar:toolbar PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "toolbar.dtd">
+<toolbar:toolbar xmlns:toolbar="http://openoffice.org/2001/toolbar" xmlns:xlink="http://www.w3.org/1999/xlink" toolbar:id="toolbar">
+ <toolbar:toolbaritem xlink:href=".uno:ZoomIn" toolbar:helpid="helpid:30266" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:ZoomOut" toolbar:helpid="helpid:30267" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:View100" toolbar:helpid="helpid:30264" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:Adjust" toolbar:helpid="helpid:30269" toolbar:text="" />
+ <toolbar:toolbarseparator/>
+ <toolbar:toolbaritem xlink:href=".uno:Draw" toolbar:helpid="helpid:30268" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:FormelCursor" toolbar:helpid="helpid:30271" toolbar:text="" />
+ <toolbar:toolbaritem xlink:href=".uno:SymbolCatalogue" toolbar:helpid="helpid:30261" toolbar:text="" />
+</toolbar:toolbar> \ No newline at end of file
diff --git a/starmath/util/hidother.src b/starmath/util/hidother.src
new file mode 100644
index 000000000000..23a4aab1eb76
--- /dev/null
+++ b/starmath/util/hidother.src
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "../inc/helpids.h"
+
+hidspecial HID_SMA_OPTIONSDIALOG { HelpId = HID_SMA_OPTIONSDIALOG; };
+hidspecial HID_SMA_FONTDIALOG { HelpId = HID_SMA_FONTDIALOG; };
+hidspecial HID_SMA_FONTSIZEDIALOG { HelpId = HID_SMA_FONTSIZEDIALOG; };
+hidspecial HID_SMA_FONTTYPEDIALOG { HelpId = HID_SMA_FONTTYPEDIALOG; };
+hidspecial HID_SMA_DISTANCEDIALOG { HelpId = HID_SMA_DISTANCEDIALOG; };
+hidspecial HID_SMA_ALIGNDIALOG { HelpId = HID_SMA_ALIGNDIALOG; };
+hidspecial HID_SMA_PRINTOPTIONPAGE { HelpId = HID_SMA_PRINTOPTIONPAGE; };
+hidspecial HID_SMA_SYMBOLDIALOG { HelpId = HID_SMA_SYMBOLDIALOG; };
+hidspecial HID_SMA_SYMDEFINEDIALOG { HelpId = HID_SMA_SYMDEFINEDIALOG; };
+hidspecial HID_SMA_EXTRAOPTIONPAGE { HelpId = HID_SMA_EXTRAOPTIONPAGE; };
+hidspecial HID_SMA_DOCSAVEQUERY { HelpId = HID_SMA_DOCSAVEQUERY; };
+hidspecial HID_SMA_OBJECTSAVEQUERY { HelpId = HID_SMA_OBJECTSAVEQUERY; };
+hidspecial HID_SMA_DEFAULTSAVEQUERY { HelpId = HID_SMA_DEFAULTSAVEQUERY; };
+hidspecial HID_SMA_ILLEGALOBJECTERROR { HelpId = HID_SMA_ILLEGALOBJECTERROR; };
+hidspecial HID_SMA_ILLEGALFILEERROR { HelpId = HID_SMA_ILLEGALFILEERROR; };
+hidspecial HID_SMA_WRITESYMBOLERROR { HelpId = HID_SMA_WRITESYMBOLERROR; };
+hidspecial HID_SMA_READSYMBOLERROR { HelpId = HID_SMA_READSYMBOLERROR; };
+hidspecial HID_SMA_NOMATHTYPEFACEWARNING { HelpId = HID_SMA_NOMATHTYPEFACEWARNING; };
+hidspecial HID_SMA_OBJECTNAME { HelpId = HID_SMA_OBJECTNAME; };
+hidspecial HID_SMA_VIEWNAME { HelpId = HID_SMA_VIEWNAME; };
+hidspecial HID_SMA_UNDOEDITNAME { HelpId = HID_SMA_UNDOEDITNAME; };
+hidspecial HID_SMA_UNDOFORMATNAME { HelpId = HID_SMA_UNDOFORMATNAME; };
+hidspecial HID_SMA_APPICO { HelpId = HID_SMA_APPICO; };
+hidspecial HID_SMA_DOCICO { HelpId = HID_SMA_DOCICO; };
+hidspecial HID_SMA_TMPICO { HelpId = HID_SMA_TMPICO; };
+hidspecial HID_SMA_COMMANDMENU { HelpId = HID_SMA_COMMANDMENU; };
+hidspecial HID_SMA_VIEWMENU { HelpId = HID_SMA_VIEWMENU; };
+hidspecial HID_SMA_DISTANCEMENU { HelpId = HID_SMA_DISTANCEMENU; };
+hidspecial HID_SMA_FONTMENU { HelpId = HID_SMA_FONTMENU; };
+hidspecial HID_SMA_STARTUPWINDOW { HelpId = HID_SMA_STARTUPWINDOW; };
+hidspecial HID_SMA_TOOLBOXWINDOW { HelpId = HID_SMA_TOOLBOXWINDOW; };
+hidspecial HID_SMA_CMDBOXWINDOW { HelpId = HID_SMA_CMDBOXWINDOW; };
+hidspecial HID_SMA_UPDATEOBJECT { HelpId = HID_SMA_UPDATEOBJECT; };
+hidspecial HID_SMA_FONTREGULAR { HelpId = HID_SMA_FONTREGULAR; };
+hidspecial HID_SMA_FONTITALIC { HelpId = HID_SMA_FONTITALIC; };
+hidspecial HID_SMA_FONTBOLD { HelpId = HID_SMA_FONTBOLD; };
+hidspecial HID_SMA_PRINTOPTION { HelpId = HID_SMA_PRINTOPTION; };
+hidspecial HID_SMA_DOCUMENTSTR { HelpId = HID_SMA_DOCUMENTSTR; };
+hidspecial HID_SMA_SYMBOLFILESSTR { HelpId = HID_SMA_SYMBOLFILESSTR; };
+hidspecial HID_SMA_ALLFILESSTR { HelpId = HID_SMA_ALLFILESSTR; };
+hidspecial HID_SMA_CREATORSTR { HelpId = HID_SMA_CREATORSTR; };
+hidspecial HID_SMA_FILESMFTYP { HelpId = HID_SMA_FILESMFTYP; };
+hidspecial HID_SMA_FILESYMTYP { HelpId = HID_SMA_FILESYMTYP; };
+hidspecial HID_SMA_WIN_DOCUMENT { HelpId = HID_SMA_WIN_DOCUMENT; };
+hidspecial HID_SMA_COMMAND_WIN_EDIT { HelpId = HID_SMA_COMMAND_WIN_EDIT; };
+
+hidspecial HID_SMA_DEFAULT_DIST { HelpId = HID_SMA_DEFAULT_DIST; };
+hidspecial HID_SMA_LINE_DIST { HelpId = HID_SMA_LINE_DIST; };
+hidspecial HID_SMA_ROOT_DIST { HelpId = HID_SMA_ROOT_DIST; };
+hidspecial HID_SMA_SUP_DIST { HelpId = HID_SMA_SUP_DIST; };
+hidspecial HID_SMA_SUB_DIST { HelpId = HID_SMA_SUB_DIST; };
+hidspecial HID_SMA_NUMERATOR_DIST { HelpId = HID_SMA_NUMERATOR_DIST; };
+hidspecial HID_SMA_DENOMINATOR_DIST { HelpId = HID_SMA_DENOMINATOR_DIST; };
+hidspecial HID_SMA_FRACLINE_EXCWIDTH { HelpId = HID_SMA_FRACLINE_EXCWIDTH; };
+hidspecial HID_SMA_FRACLINE_LINEWIDTH { HelpId = HID_SMA_FRACLINE_LINEWIDTH; };
+hidspecial HID_SMA_UPPERLIMIT_DIST { HelpId = HID_SMA_UPPERLIMIT_DIST; };
+hidspecial HID_SMA_LOWERLIMIT_DIST { HelpId = HID_SMA_LOWERLIMIT_DIST; };
+hidspecial HID_SMA_BRACKET_EXCHEIGHT { HelpId = HID_SMA_BRACKET_EXCHEIGHT; };
+hidspecial HID_SMA_BRACKET_DIST { HelpId = HID_SMA_BRACKET_DIST; };
+hidspecial HID_SMA_BRACKET_EXCHEIGHT2 { HelpId = HID_SMA_BRACKET_EXCHEIGHT2; };
+hidspecial HID_SMA_MATRIXROW_DIST { HelpId = HID_SMA_MATRIXROW_DIST; };
+hidspecial HID_SMA_MATRIXCOL_DIST { HelpId = HID_SMA_MATRIXCOL_DIST; };
+hidspecial HID_SMA_ATTRIBUT_DIST { HelpId = HID_SMA_ATTRIBUT_DIST; };
+hidspecial HID_SMA_INTERATTRIBUT_DIST { HelpId = HID_SMA_INTERATTRIBUT_DIST; };
+hidspecial HID_SMA_OPERATOR_EXCHEIGHT { HelpId = HID_SMA_OPERATOR_EXCHEIGHT; };
+hidspecial HID_SMA_OPERATOR_DIST { HelpId = HID_SMA_OPERATOR_DIST; };
+hidspecial HID_SMA_LEFTBORDER_DIST { HelpId = HID_SMA_LEFTBORDER_DIST; };
+hidspecial HID_SMA_RIGHTBORDER_DIST { HelpId = HID_SMA_RIGHTBORDER_DIST; };
+hidspecial HID_SMA_UPPERBORDER_DIST { HelpId = HID_SMA_UPPERBORDER_DIST; };
+hidspecial HID_SMA_LOWERBORDER_DIST { HelpId = HID_SMA_LOWERBORDER_DIST; };
+
+//! this shouldn't have been necessary!
+hidspecial HID_SMA_ALEPH { HelpId = HID_SMA_ALEPH; };
+hidspecial HID_SMA_EMPTYSET { HelpId = HID_SMA_EMPTYSET; };
+hidspecial HID_SMA_RE { HelpId = HID_SMA_RE; };
+hidspecial HID_SMA_IM { HelpId = HID_SMA_IM; };
+hidspecial HID_SMA_INFINITY { HelpId = HID_SMA_INFINITY; };
+hidspecial HID_SMA_PARTIAL { HelpId = HID_SMA_PARTIAL; };
+hidspecial HID_SMA_WP { HelpId = HID_SMA_WP; };
+hidspecial HID_SMA_DOTSAXIS { HelpId = HID_SMA_DOTSAXIS; };
+hidspecial HID_SMA_DOTSUP { HelpId = HID_SMA_DOTSUP; };
+hidspecial HID_SMA_DOTSDOWN { HelpId = HID_SMA_DOTSDOWN; };
+hidspecial HID_SMA_DOTSLOW { HelpId = HID_SMA_DOTSLOW; };
+hidspecial HID_SMA_DOTSVERT { HelpId = HID_SMA_DOTSVERT; };
+hidspecial HID_SMA_NABLA { HelpId = HID_SMA_NABLA; };
+hidspecial HID_SMA_EXISTS { HelpId = HID_SMA_EXISTS; };
+hidspecial HID_SMA_FORALL { HelpId = HID_SMA_FORALL; };
+
diff --git a/starmath/util/makefile.mk b/starmath/util/makefile.mk
new file mode 100644
index 000000000000..09fedb57fb2c
--- /dev/null
+++ b/starmath/util/makefile.mk
@@ -0,0 +1,127 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=starmath
+TARGET=smath3
+LIBTARGET=NO
+GEN_HID=TRUE
+GEN_HID_OTHER=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+RESLIB1NAME=sm
+RESLIB1IMAGES=$(PRJ)$/res
+RESLIB1SRSFILES=\
+ $(SRS)$/smres.srs
+
+SHL1TARGET= sm$(DLLPOSTFIX)
+SHL1IMPLIB= smimp
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME= $(SHL1TARGET)
+
+SHL1STDLIBS= \
+ $(EDITENGLIB) \
+ $(SVXCORELIB) \
+ $(SVXLIB) \
+ $(SFX2LIB) \
+ $(XMLOFFLIB) \
+ $(SVTOOLLIB) \
+ $(TKLIB) \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(I18NPAPERLIB) \
+ $(SOTLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL2TARGET= smd$(DLLPOSTFIX)
+SHL2IMPLIB= smdimp
+SHL2VERSIONMAP=$(SOLARENV)/src/component.map
+SHL2DEF=$(MISC)$/$(SHL2TARGET).def
+DEF2NAME= $(SHL2TARGET)
+
+SHL2STDLIBS= \
+ $(SFX2LIB) \
+ $(SVTOOLLIB) \
+ $(SVLLIB) \
+ $(VCLLIB) \
+ $(SOTLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL2DEPN= makefile.mk
+SHL2VERSIONMAP=$(SOLARENV)/src/component.map
+SHL2OBJS= $(SLO)$/smdetect.obj \
+ $(SLO)$/detreg.obj \
+ $(SLO)$/eqnolefilehdr.obj
+
+SHL1DEPN= makefile.mk
+SHL1LIBS= $(SLB)$/starmath.lib
+
+.IF "$(GUI)" != "UNX"
+.IF "$(GUI)$(COM)" != "WNTGCC"
+SHL1OBJS= $(SLO)$/smdll.obj
+.ENDIF
+.ENDIF # ! UNX
+
+.IF "$(GUI)" == "WNT"
+SHL1RES= $(RCTARGET)
+.ENDIF # WNT
+
+# --- Targets -------------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
+ALLTAR : $(MISC)/sm.component $(MISC)/smd.component
+
+$(MISC)/sm.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ sm.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt sm.component
+
+$(MISC)/smd.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ smd.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL2TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt smd.component
diff --git a/starmath/util/sm.component b/starmath/util/sm.component
new file mode 100644
index 000000000000..8047662e2915
--- /dev/null
+++ b/starmath/util/sm.component
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.Math.FormulaDocument">
+ <service name="com.sun.star.formula.FormulaProperties"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLContentExporter">
+ <service name="com.sun.star.xml.XMLExportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLExporter">
+ <service name="com.sun.star.xml.XMLExportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLImporter">
+ <service name="com.sun.star.xml.XMLImportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLMetaExporter">
+ <service name="com.sun.star.xml.XMLExportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLOasisMetaExporter">
+ <service name="com.sun.star.xml.XMLExportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLOasisMetaImporter">
+ <service name="com.sun.star.xml.XMLImportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLOasisSettingsExporter">
+ <service name="com.sun.star.xml.XMLExportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLOasisSettingsImporter">
+ <service name="com.sun.star.xml.XMLImportFilter"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.Math.XMLSettingsExporter">
+ <service name="com.sun.star.xml.XMLExportFilter"/>
+ </implementation>
+</component>
diff --git a/starmath/util/smd.component b/starmath/util/smd.component
new file mode 100644
index 000000000000..9f566864482e
--- /dev/null
+++ b/starmath/util/smd.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.math.FormatDetector">
+ <service name="com.sun.star.frame.ExtendedTypeDetection"/>
+ </implementation>
+</component>
diff --git a/starmath/visual-editor-todo b/starmath/visual-editor-todo
new file mode 100644
index 000000000000..f378d2db6940
--- /dev/null
+++ b/starmath/visual-editor-todo
@@ -0,0 +1,43 @@
+Visual Formula Editor for LibreOffice Math
+==========================================
+
+This file contains a list of things to do for the visual formula editor.
+The visual formula editor hack was started by Jonas during GSoC...
+He is, as of writing this, still working on this features, but do by all
+means feel free to help out.
+
+Here is the list of things to be done. They are organized by complexity and necessity, note that
+some of the items are wishful thinking... If you have questions please feel free to ping me (Jonas)
+on IRC (jopsen) or e-mail me at jopsen@gmail.com.
+
+Easy
+----
+1. SmGraphicWindow::KeyInput relies on comparison of sal_Char, a better way must be available for CTRL+c
+2. Code style (missing spaces, linebreaks and a few renames)
+3. More documentation
+4. Remove the CreateTextFromNode methods and replace calls to it with NodeToTextVisitor
+5. Extend NodeToTextVisitor to update token offsets so SmNode::GetRow and SmNode::GetColumn will work.
+ (These methods can be used to enable synchronization of caret positions between visual and non-visual editor).
+
+Medium
+------
+1. SmCursor::InsertCol() method for added columns to matrices should be implemented.
+2. SmCursor` should support deletion of lines, rows, cols and sub-/superscripts.
+3. SmCursor::InsertSubSup() should wrap the body in a SmBraceNode if the body is an SmOperNode, SmBinVerNode, etc.
+4. When OpenOffice Math runs in standalone mode it centers the current formula, this is not nice for visual editing.
+
+Complex
+-------
+1. SmAlignNode and SmFontNode are ignored by visual editor, figure out how these should work.
+2. Solve the flickering issue when drawing formulas (See dev@gsl.OpenOffice.org)
+3. Make " a shortcut for creating an SmTextNode with FNT_TEXT, also check that SmNodeToTextVisitor supports this.
+4. parse.cxx merges multiple blanks into one SmBlankNode, the visual editor doesn't...
+
+Complex and non-essential
+-------------------------
+* Global clipboard integration
+* Consider improving GUI for "Formula Elements"-dialog, most buttons work with visual editor
+* Consider allowing users to enter commands in visual editor, by prefixing the command...
+* Optimize things, for instance SmCursor::AnnotateSelection() is called way too many places...
+* Improve handling of MoveUp and MoveDown in SmCursor::Move, SmCaretPos2LineVisitor might need improvement.
+* Synchronized command text caret and visual editor caret.
diff --git a/starmath/workben/smath-dump-watch.sh b/starmath/workben/smath-dump-watch.sh
new file mode 100755
index 000000000000..21ec5f14ad35
--- /dev/null
+++ b/starmath/workben/smath-dump-watch.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+
+# Watches for formula dumps by starmath and renders them
+# If starmath is compiled with the macro DEBUG_ENABLE_DUMPASDOT defined.
+# shift+enter, in the visual formula editor will make starmath dump a
+# graphviz graph of the formula tree structure. This is very useful when
+# debugging. The formula is dumped to /tmp/smath-dump.gv-
+# This script monitors this file and renders the graph when written,
+# after which the formula is displayed using feh.
+#
+# Usage: Let this script run in the background, e.g. start it in a terminal
+# (and don't close the terminal). Then compile starmath with DEBUG_ENABLE_DUMPASDOT
+# defined, use the visual formula editor to write something and hit shift+enter.
+#
+# Note: This won't work on Windows as the /tmp/ folder will be missing.
+#
+# Author: "Jonas Finnemann Jensen" <jopsen@gmail.com>
+
+touch /tmp/smath-dump.gv;
+while inotifywait -q -e close_write /tmp/smath-dump.gv;
+do
+ dot -Tpng < /tmp/smath-dump.gv > /tmp/smath-dump.png; > /dev/null
+ kill `pidof -s feh`; > /dev/null
+ feh /tmp/smath-dump.png & > /dev/null
+done
diff --git a/starmath/xml/math.xml b/starmath/xml/math.xml
new file mode 100644
index 000000000000..99f2576c0d80
--- /dev/null
+++ b/starmath/xml/math.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name>sm</module-name>
+ <component-description>
+ <author>Oliver Specht</author>
+ <name>math.SmModel</name>
+ <description>This component provides access to various settings of a formula.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.formula.FormulaProperties</supported-service>
+ </component-description>
+ <!-- XML-based filter: Math import components
+ (full, styles, content, meta, settings)
+ -->
+ <component-description>
+ <author>xmloff development team</author>
+ <name>com.sun.star.comp.Math.XMLMetaImporter</name>
+ <description>This component imports the meta.xml stream into a math document.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.xml.XMLImportFilter</supported-service>
+ </component-description>
+ <component-description>
+ <author>xmloff development team</author>
+ <name>com.sun.star.comp.Math.XMLImporter</name>
+ <description>This component imports a single XML document stream into a math document.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.xml.XMLImportFilter</supported-service>
+ </component-description>
+ <component-description>
+ <author>xmloff development team</author>
+ <name>com.sun.star.comp.Math.XMLSettingsImporter</name>
+ <description>This component imports the settings.xml stream into a math document.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.xml.XMLImportFilter</supported-service>
+ </component-description>
+ <!-- XML-based filter: Math export components
+ (full, styles, content, meta, settings)
+ -->
+ <component-description>
+ <author>xmloff development team</author>
+ <name>com.sun.star.comp.Math.XMLMetaExporter</name>
+ <description>This component exports the meta of a math document.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.xml.XMLExportFilter</supported-service>
+ </component-description>
+ <component-description>
+ <author>xmloff development team</author>
+ <name>com.sun.star.comp.Math.XMLExporter</name>
+ <description>This component exports a math document into a single XML document stream.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.xml.XMLExportFilter</supported-service>
+ </component-description>
+ <component-description>
+ <author>xmloff development team</author>
+ <name>com.sun.star.comp.Math.XMLSettingsExporter</name>
+ <description>This component exports a the settings of a math document.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.xml.XMLExportFilter</supported-service>
+ </component-description>
+ <component-description>
+ <author>TL</author>
+ <name>SmGraphicAccessible</name>
+ <description>The accessible view of a formula documents visual representation.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.formula.AccessibleFormulaView</supported-service>
+ </component-description>
+ <component-description>
+ <author>TL</author>
+ <name>SmEditAccessible</name>
+ <description>The accessible view of a formula documents command text.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.formula.AccessibleFormulaText</supported-service>
+ </component-description>
+</module-description>