summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorMathias Bauer <mba@openoffice.org>2009-10-31 00:29:04 +0100
committerMathias Bauer <mba@openoffice.org>2009-10-31 00:29:04 +0100
commitd2000efb31f864e912c6cf52760eea0e602b6893 (patch)
tree11bbbde7f8c6e7762efb819c00df9751d7e150e8 /filter
parentf972fce0a2df22b37cbd3ede207ce285b69eda9b (diff)
#i106421#: move msfilter to filter
Diffstat (limited to 'filter')
-rw-r--r--filter/inc/filter/msfilter/countryid.hxx321
-rw-r--r--filter/inc/filter/msfilter/escherex.hxx1513
-rw-r--r--filter/inc/filter/msfilter/mscodec.hxx343
-rw-r--r--filter/inc/filter/msfilter/msdffimp.hxx864
-rw-r--r--filter/inc/filter/msfilter/msfilterdllapi.h44
-rw-r--r--filter/inc/filter/msfilter/msfiltertracer.hxx99
-rw-r--r--filter/inc/filter/msfilter/msocximex.hxx1423
-rw-r--r--filter/inc/filter/msfilter/msoleexp.hxx63
-rw-r--r--filter/inc/filter/msfilter/svdfppt.hxx1443
-rw-r--r--filter/inc/filter/msfilter/svxmsbas.hxx97
-rw-r--r--filter/prj/d.lst6
-rw-r--r--filter/source/msfilter/countryid.cxx345
-rw-r--r--filter/source/msfilter/escherex.cxx4848
-rw-r--r--filter/source/msfilter/eschesdo.cxx1241
-rw-r--r--filter/source/msfilter/eschesdo.hxx208
-rw-r--r--filter/source/msfilter/makefile.mk89
-rw-r--r--filter/source/msfilter/makefile.pmk34
-rw-r--r--filter/source/msfilter/mscodec.cxx537
-rw-r--r--filter/source/msfilter/msdffimp.cxx8142
-rw-r--r--filter/source/msfilter/msfiltertracer.cxx254
-rw-r--r--filter/source/msfilter/msocximex.cxx5960
-rw-r--r--filter/source/msfilter/msoleexp.cxx367
-rw-r--r--filter/source/msfilter/msvbasic.cxx677
-rw-r--r--filter/source/msfilter/msvbasic.hxx129
-rw-r--r--filter/source/msfilter/svdfppt.cxx7802
-rw-r--r--filter/source/msfilter/svxmsbas.cxx406
-rw-r--r--filter/source/msfilter/svxmsbas2.cxx88
-rw-r--r--filter/source/msfilter/viscache.hxx85
28 files changed, 37428 insertions, 0 deletions
diff --git a/filter/inc/filter/msfilter/countryid.hxx b/filter/inc/filter/msfilter/countryid.hxx
new file mode 100644
index 000000000000..0c66f1bf546c
--- /dev/null
+++ b/filter/inc/filter/msfilter/countryid.hxx
@@ -0,0 +1,321 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: countryid.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * 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 INCLUDED_SVX_COUNTRYID_HXX
+#define INCLUDED_SVX_COUNTRYID_HXX
+
+#include <sal/types.h>
+#include <i18npool/lang.h>
+#include "filter/msfilter/msfilterdllapi.h"
+
+// ----------------------------------------------------------------------------
+
+namespace msfilter {
+
+// Windows Country IDs ========================================================
+
+/** Represents a Windows country ID.
+
+ The country IDs used in Windows are equal to the international calling
+ code of each country, i.e. the code 353 represents Ireland (+353).
+
+ ATTENTION: These country codes are not supposed to be used anywhere in core
+ structures! They shall ONLY be used in the import/export filters for
+ Microsoft Office documents!
+ */
+typedef sal_uInt16 CountryId;
+
+const CountryId COUNTRY_DONTKNOW = 0;
+const CountryId COUNTRY_USA = 1;
+const CountryId COUNTRY_DOMINICAN_REPUBLIC = 1; // NANP
+const CountryId COUNTRY_GUAM = 1; // NANP
+const CountryId COUNTRY_JAMAICA = 1; // NANP
+const CountryId COUNTRY_PUERTO_RICO = 1; // NANP
+const CountryId COUNTRY_TRINIDAD_Y_TOBAGO = 1; // NANP
+const CountryId COUNTRY_CANADA = 2;
+const CountryId COUNTRY_RUSSIA = 7;
+const CountryId COUNTRY_KAZAKHSTAN = 7; // no own ID
+const CountryId COUNTRY_TATARSTAN = 7; // no own ID
+const CountryId COUNTRY_EGYPT = 20;
+const CountryId COUNTRY_SOUTH_AFRICA = 27;
+const CountryId COUNTRY_GREECE = 30;
+const CountryId COUNTRY_NETHERLANDS = 31;
+const CountryId COUNTRY_BELGIUM = 32;
+const CountryId COUNTRY_FRANCE = 33;
+const CountryId COUNTRY_SPAIN = 34;
+const CountryId COUNTRY_HUNGARY = 36;
+const CountryId COUNTRY_ITALY = 39;
+const CountryId COUNTRY_ROMANIA = 40;
+const CountryId COUNTRY_SWITZERLAND = 41;
+const CountryId COUNTRY_AUSTRIA = 43;
+const CountryId COUNTRY_UNITED_KINGDOM = 44;
+const CountryId COUNTRY_DENMARK = 45;
+const CountryId COUNTRY_SWEDEN = 46;
+const CountryId COUNTRY_NORWAY = 47;
+const CountryId COUNTRY_POLAND = 48;
+const CountryId COUNTRY_GERMANY = 49;
+const CountryId COUNTRY_PERU = 51;
+const CountryId COUNTRY_MEXICO = 52;
+const CountryId COUNTRY_CUBA = 53;
+const CountryId COUNTRY_ARGENTINIA = 54;
+const CountryId COUNTRY_BRAZIL = 55;
+const CountryId COUNTRY_CHILE = 56;
+const CountryId COUNTRY_COLOMBIA = 57;
+const CountryId COUNTRY_VENEZUELA = 58;
+const CountryId COUNTRY_MALAYSIA = 60;
+const CountryId COUNTRY_AUSTRALIA = 61;
+const CountryId COUNTRY_INDONESIA = 62;
+const CountryId COUNTRY_PHILIPPINES = 63;
+const CountryId COUNTRY_NEW_ZEALAND = 64;
+const CountryId COUNTRY_SINGAPORE = 65;
+const CountryId COUNTRY_THAILAND = 66;
+const CountryId COUNTRY_JAPAN = 81;
+const CountryId COUNTRY_SOUTH_KOREA = 82;
+const CountryId COUNTRY_VIET_NAM = 84;
+const CountryId COUNTRY_PR_CHINA = 86;
+const CountryId COUNTRY_TIBET = 86; // no own ID
+const CountryId COUNTRY_TURKEY = 90;
+const CountryId COUNTRY_INDIA = 91;
+const CountryId COUNTRY_PAKISTAN = 92;
+const CountryId COUNTRY_AFGHANISTAN = 93;
+const CountryId COUNTRY_SRI_LANKA = 94;
+const CountryId COUNTRY_MYANMAR = 95;
+const CountryId COUNTRY_MOROCCO = 212;
+const CountryId COUNTRY_ALGERIA = 213;
+const CountryId COUNTRY_TUNISIA = 216;
+const CountryId COUNTRY_LIBYA = 218;
+const CountryId COUNTRY_GAMBIA = 220;
+const CountryId COUNTRY_SENEGAL = 221;
+const CountryId COUNTRY_MAURITANIA = 222;
+const CountryId COUNTRY_MALI = 223;
+const CountryId COUNTRY_GUINEA = 224;
+const CountryId COUNTRY_COTE_D_IVOIRE = 225;
+const CountryId COUNTRY_BURKINA_FARSO = 226;
+const CountryId COUNTRY_NIGER = 227;
+const CountryId COUNTRY_TOGO = 228;
+const CountryId COUNTRY_BENIN = 229;
+const CountryId COUNTRY_MAURITIUS = 230;
+const CountryId COUNTRY_LIBERIA = 231;
+const CountryId COUNTRY_SIERRA_LEONE = 232;
+const CountryId COUNTRY_GHANA = 233;
+const CountryId COUNTRY_NIGERIA = 234;
+const CountryId COUNTRY_CHAD = 235;
+const CountryId COUNTRY_CENTRAL_AFR_REP = 236;
+const CountryId COUNTRY_CAMEROON = 237;
+const CountryId COUNTRY_CAPE_VERDE = 238;
+const CountryId COUNTRY_SAO_TOME = 239;
+const CountryId COUNTRY_EQUATORIAL_GUINEA = 240;
+const CountryId COUNTRY_GABON = 241;
+const CountryId COUNTRY_CONGO = 242;
+const CountryId COUNTRY_ZAIRE = 243;
+const CountryId COUNTRY_ANGOLA = 244;
+const CountryId COUNTRY_GUINEA_BISSAU = 245;
+const CountryId COUNTRY_DIEGO_GARCIA = 246;
+const CountryId COUNTRY_ASCENSION_ISLAND = 247;
+const CountryId COUNTRY_SEYCHELLES = 248;
+const CountryId COUNTRY_SUDAN = 249;
+const CountryId COUNTRY_RWANDA = 250;
+const CountryId COUNTRY_ETHIOPIA = 251;
+const CountryId COUNTRY_SOMALIA = 252;
+const CountryId COUNTRY_DJIBOUTI = 253;
+const CountryId COUNTRY_KENYA = 254;
+const CountryId COUNTRY_TANZANIA = 255;
+const CountryId COUNTRY_UGANDA = 256;
+const CountryId COUNTRY_BURUNDI = 257;
+const CountryId COUNTRY_MOZAMBIQUE = 258;
+const CountryId COUNTRY_ZANZIBAR = 259;
+const CountryId COUNTRY_ZAMBIA = 260;
+const CountryId COUNTRY_MADAGASKAR = 261;
+const CountryId COUNTRY_REUNION = 262;
+const CountryId COUNTRY_ZIMBABWE = 263;
+const CountryId COUNTRY_NAMIBIA = 264;
+const CountryId COUNTRY_MALAWI = 265;
+const CountryId COUNTRY_LESOTHO = 266;
+const CountryId COUNTRY_BOTSWANA = 267;
+const CountryId COUNTRY_SWAZILAND = 268;
+const CountryId COUNTRY_COMOROS_MAYOTTE = 269;
+const CountryId COUNTRY_ST_HELENA = 290;
+const CountryId COUNTRY_ERITREA = 291;
+const CountryId COUNTRY_ARUBA = 297;
+const CountryId COUNTRY_FAEROE_ISLANDS = 298;
+const CountryId COUNTRY_GREEN_ISLAND = 299;
+const CountryId COUNTRY_GIBRALTAR = 350;
+const CountryId COUNTRY_PORTUGAL = 351;
+const CountryId COUNTRY_LUXEMBOURG = 352;
+const CountryId COUNTRY_IRELAND = 353;
+const CountryId COUNTRY_ICELAND = 354;
+const CountryId COUNTRY_ALBANIA = 355;
+const CountryId COUNTRY_MALTA = 356;
+const CountryId COUNTRY_CYPRUS = 357;
+const CountryId COUNTRY_FINLAND = 358;
+const CountryId COUNTRY_BULGARIA = 359;
+const CountryId COUNTRY_LITHUANIA = 370;
+const CountryId COUNTRY_LATVIA = 371;
+const CountryId COUNTRY_ESTONIA = 372;
+const CountryId COUNTRY_MOLDOVA = 373;
+const CountryId COUNTRY_ARMENIA = 374;
+const CountryId COUNTRY_BELARUS = 375;
+const CountryId COUNTRY_ANDORRA = 376;
+const CountryId COUNTRY_MONACO = 377;
+const CountryId COUNTRY_SAN_MARINO = 378;
+const CountryId COUNTRY_VATICAN_CITY = 379;
+const CountryId COUNTRY_UKRAINE = 380;
+const CountryId COUNTRY_SERBIA = 381;
+const CountryId COUNTRY_CROATIA = 385;
+const CountryId COUNTRY_SLOVENIA = 386;
+const CountryId COUNTRY_BOSNIA = 387;
+const CountryId COUNTRY_MACEDONIA = 389;
+const CountryId COUNTRY_CZECH = 420;
+const CountryId COUNTRY_SLOVAK = 421;
+const CountryId COUNTRY_LIECHTENSTEIN = 423;
+const CountryId COUNTRY_FALKLAND_ISLANDS = 500;
+const CountryId COUNTRY_BELIZE = 501;
+const CountryId COUNTRY_GUATEMALA = 502;
+const CountryId COUNTRY_EL_SALVADOR = 503;
+const CountryId COUNTRY_HONDURAS = 504;
+const CountryId COUNTRY_NICARAGUA = 505;
+const CountryId COUNTRY_COSTA_RICA = 506;
+const CountryId COUNTRY_PANAMA = 507;
+const CountryId COUNTRY_ST_PIERRE = 508;
+const CountryId COUNTRY_HAITI = 509;
+const CountryId COUNTRY_GUADELOUPE = 590;
+const CountryId COUNTRY_BOLIVIA = 591;
+const CountryId COUNTRY_GUYANA = 592;
+const CountryId COUNTRY_ECUADOR = 593;
+const CountryId COUNTRY_FRENCH_GUIANA = 594;
+const CountryId COUNTRY_PARAGUAY = 595;
+const CountryId COUNTRY_MARTINIQUE = 596;
+const CountryId COUNTRY_SURINAME = 597;
+const CountryId COUNTRY_URUGUAY = 598;
+const CountryId COUNTRY_NETHERL_ANTILLES = 599;
+const CountryId COUNTRY_EAST_TIMOR = 670;
+const CountryId COUNTRY_ANTARCTICA = 672;
+const CountryId COUNTRY_BRUNEI_DARUSSALAM = 673;
+const CountryId COUNTRY_NARUPU = 674;
+const CountryId COUNTRY_PAPUA_NEW_GUINEA = 675;
+const CountryId COUNTRY_TONGA = 676;
+const CountryId COUNTRY_SOLOMON_ISLANDS = 677;
+const CountryId COUNTRY_VANUATU = 678;
+const CountryId COUNTRY_FIJI = 679;
+const CountryId COUNTRY_PALAU = 680;
+const CountryId COUNTRY_WALLIS_AND_FUTUNA = 681;
+const CountryId COUNTRY_COOK_ISLANDS = 682;
+const CountryId COUNTRY_NIUE_ISLAND = 683;
+const CountryId COUNTRY_AMERICAN_SAMOA = 684;
+const CountryId COUNTRY_WESTERN_SAMOA = 685;
+const CountryId COUNTRY_KIRIBATI = 686;
+const CountryId COUNTRY_NEW_CALEDONIA = 687;
+const CountryId COUNTRY_TUVALU = 688;
+const CountryId COUNTRY_FRENCH_POLYNESIA = 689;
+const CountryId COUNTRY_TOKELAU = 690;
+const CountryId COUNTRY_MICRONESIA = 691;
+const CountryId COUNTRY_MARSHALL_ISLANDS = 692;
+const CountryId COUNTRY_NORTH_KOREA = 850;
+const CountryId COUNTRY_HONG_KONG = 852;
+const CountryId COUNTRY_MACAU = 853;
+const CountryId COUNTRY_CAMBODIA = 855;
+const CountryId COUNTRY_LAOS = 856;
+const CountryId COUNTRY_BANGLADESH = 880;
+const CountryId COUNTRY_TAIWAN = 886;
+const CountryId COUNTRY_MALDIVES = 960;
+const CountryId COUNTRY_LEBANON = 961;
+const CountryId COUNTRY_JORDAN = 962;
+const CountryId COUNTRY_SYRIA = 963;
+const CountryId COUNTRY_IRAQ = 964;
+const CountryId COUNTRY_KUWAIT = 965;
+const CountryId COUNTRY_SAUDI_ARABIA = 966;
+const CountryId COUNTRY_YEMEN = 967;
+const CountryId COUNTRY_OMAN = 968;
+const CountryId COUNTRY_PALESTINE = 970;
+const CountryId COUNTRY_UAE = 971;
+const CountryId COUNTRY_ISRAEL = 972;
+const CountryId COUNTRY_BAHRAIN = 973;
+const CountryId COUNTRY_QATAR = 974;
+const CountryId COUNTRY_BHUTAN = 975;
+const CountryId COUNTRY_MONGOLIA = 976;
+const CountryId COUNTRY_NEPAL = 977;
+const CountryId COUNTRY_IRAN = 981;
+const CountryId COUNTRY_TAJIKISTAN = 992;
+const CountryId COUNTRY_TURKMENISTAN = 993;
+const CountryId COUNTRY_AZERBAIJAN = 994;
+const CountryId COUNTRY_GEORGIA = 995;
+const CountryId COUNTRY_KYRGYZSTAN = 996;
+const CountryId COUNTRY_UZBEKISTAN = 998;
+
+// Country ID <-> Language type conversion ====================================
+
+/** Converts a language type to a Windows country ID.
+
+ The function regards the sub type of the passed language, and tries to
+ return the appropriate country, i.e. COUNTRY_IRELAND for
+ LANGUAGE_ENGLISH_EIRE.
+
+ A few countries do not have an own associated country ID. Most of these
+ countries are mapped to another related country, i.e. Kazakhstan is
+ mapped to Russia.
+
+ If no country can be found, the value COUNTRY_DONTKNOW will be returned.
+
+ @param eLanguage
+ A language type, defined in tools/lang.hxx.
+
+ @return
+ The best Windows country ID for the passed language type, or
+ COUNTRY_DONTKNOW on error.
+ */
+MSFILTER_DLLPUBLIC CountryId ConvertLanguageToCountry( LanguageType eLanguage );
+
+/** Converts a Windows country ID to a language type.
+
+ The function returns the most used language for the passed country
+ (hopefully), i.e. LANGUAGE_ENGLISH_EIRE for COUNTRY_IRELAND.
+
+ If the passed country ID is not valid, the value LANGUAGE_DONTKNOW will be
+ returned.
+
+ @param eCountry
+ A Windows country ID, defined above.
+
+ @return
+ The most used language type in the passed country, or LANGUAGE_DONTKNOW
+ on error.
+ */
+MSFILTER_DLLPUBLIC LanguageType ConvertCountryToLanguage( CountryId eCountry );
+
+// ============================================================================
+
+} // namespace svx
+
+// ============================================================================
+
+#endif
+
diff --git a/filter/inc/filter/msfilter/escherex.hxx b/filter/inc/filter/msfilter/escherex.hxx
new file mode 100644
index 000000000000..fc36208d1207
--- /dev/null
+++ b/filter/inc/filter/msfilter/escherex.hxx
@@ -0,0 +1,1513 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: escherex.hxx,v $
+ * $Revision: 1.6.146.1 $
+ *
+ * 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 _SVX_ESCHEREX_HXX
+#define _SVX_ESCHEREX_HXX
+
+#include <vector>
+#include <tools/solar.h>
+#include <tools/gen.hxx>
+#include <tools/list.hxx>
+#include <tools/stream.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <goodies/grfmgr.hxx>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/Hatch.hpp>
+#include <svx/msdffdef.hxx>
+#include "filter/msfilter/msfilterdllapi.h"
+
+ /*Record Name FBT-Value Instance Contents Wrd Exl PPt Ver*/
+// In der Mickysoft-Doku heissen die msofbt... statt ESCHER_...
+#define ESCHER_DggContainer 0xF000 /* per-document data X X X */
+#define ESCHER_Dgg 0xF006 /* an FDGG and several FIDCLs X X X 0 */
+#define ESCHER_CLSID 0xF016 /* the CLSID of the application that put the data on the clipboard C C C 0 */
+#define ESCHER_OPT 0xF00B /* count of properties the document-wide default shape properties X X X 3 */
+#define ESCHER_ColorMRU 0xF11A /* count of colors the colors in the MRU swatch X X X 0 */
+#define ESCHER_SplitMenuColors 0xF11E /* count of colors the colors in the top-level split menus X X X 0 */
+#define ESCHER_BstoreContainer 0xF001 /* count of BLIPs all images in the document (JPEGs, metafiles, etc.) X X X */
+#define ESCHER_BSE 0xF007 /* BLIP type an FBSE (one per BLIP) X X X 2 */
+#define ESCHER_BlipFirst 0xF018 /* range of fbts reserved for various kinds of BLIPs X X X */
+#define ESCHER_BlipLast 0xF117 /* range of fbts reserved for various kinds of BLIPs X X X */
+
+#define ESCHER_DgContainer 0xF002 /* per-sheet/page/slide data X X X */
+#define ESCHER_Dg 0xF008 /* drawing ID an FDG X X X 0 */
+#define ESCHER_RegroupItems 0xF118 /* count of regroup entries several FRITs X X X 0 */
+#define ESCHER_ColorScheme 0xF120 /* count of colors the colors of the source host's color scheme C C 0 */
+#define ESCHER_SpgrContainer 0xF003 /* several SpContainers, the first of which is the group shape itself X X X */
+#define ESCHER_SpContainer 0xF004 /* a shape X X X */
+#define ESCHER_Spgr 0xF009 /* an FSPGR; only present if the shape is a group shape X X X 1 */
+#define ESCHER_Sp 0xF00A /* shape type an FSP X X X 2 */
+//#define ESCHER_OPT 0xF00B /* count of properties a shape property table X X X 3 */
+#define ESCHER_Textbox 0xF00C /* RTF text C C C 0 */
+#define ESCHER_ClientTextbox 0xF00D /* host-defined the text in the textbox, in host-defined format X X X */
+#define ESCHER_Anchor 0xF00E /* a RECT, in 100000ths of an inch C C C 0 */
+#define ESCHER_ChildAnchor 0xF00F /* a RECT, in units relative to the parent group X X X 0 */
+#define ESCHER_ClientAnchor 0xF010 /* host-defined the location of the shape, in a host-defined format X X X */
+#define ESCHER_ClientData 0xF011 /* host-defined host-specific data X X X */
+#define ESCHER_OleObject 0xF11F /* a serialized IStorage for an OLE object C C C 0 */
+#define ESCHER_DeletedPspl 0xF11D /* an FPSPL; only present in top-level deleted shapes X 0 */
+#define ESCHER_SolverContainer 0xF005 /* count of rules the rules governing shapes X X X */
+#define ESCHER_ConnectorRule 0xF012 /* an FConnectorRule X X 1 */
+#define ESCHER_AlignRule 0xF013 /* an FAlignRule X X X 0 */
+#define ESCHER_ArcRule 0xF014 /* an FARCRU X X X 0 */
+#define ESCHER_ClientRule 0xF015 /* host-defined host-defined */
+#define ESCHER_CalloutRule 0xF017 /* an FCORU X X X 0 */
+#define ESCHER_Selection 0xF119 /* an FDGSL followed by the SPIDs of the shapes in the selection X 0 */
+#define ESCHER_UDefProp 0xF122
+
+#define SHAPEFLAG_GROUP 0x001 // This shape is a group shape
+#define SHAPEFLAG_CHILD 0x002 // Not a top-level shape
+#define SHAPEFLAG_PATRIARCH 0x004 // This is the topmost group shape. Exactly one of these per drawing.
+#define SHAPEFLAG_DELETED 0x008 // The shape has been deleted
+#define SHAPEFLAG_OLESHAPE 0x010 // The shape is an OLE object
+#define SHAPEFLAG_HAVEMASTER 0x020 // Shape has a hspMaster property
+#define SHAPEFLAG_FLIPH 0x040 // Shape is flipped horizontally
+#define SHAPEFLAG_FLIPV 0x080 // Shape is flipped vertically
+#define SHAPEFLAG_CONNECTOR 0x100 // Connector type of shape
+#define SHAPEFLAG_HAVEANCHOR 0x200 // Shape has an anchor of some kind
+#define SHAPEFLAG_BACKGROUND 0x400 // Background shape
+#define SHAPEFLAG_HAVESPT 0x800 // Shape has a shape type property
+
+#define ESCHER_ShpInst_Min 0
+#define ESCHER_ShpInst_NotPrimitive ESCHER_ShpInst_Min
+#define ESCHER_ShpInst_Rectangle 1
+#define ESCHER_ShpInst_RoundRectangle 2
+#define ESCHER_ShpInst_Ellipse 3
+#define ESCHER_ShpInst_Diamond 4
+#define ESCHER_ShpInst_IsocelesTriangle 5
+#define ESCHER_ShpInst_RightTriangle 6
+#define ESCHER_ShpInst_Parallelogram 7
+#define ESCHER_ShpInst_Trapezoid 8
+#define ESCHER_ShpInst_Hexagon 9
+#define ESCHER_ShpInst_Octagon 10
+#define ESCHER_ShpInst_Plus 11
+#define ESCHER_ShpInst_Star 12
+#define ESCHER_ShpInst_Arrow 13
+#define ESCHER_ShpInst_ThickArrow 14
+#define ESCHER_ShpInst_HomePlate 15
+#define ESCHER_ShpInst_Cube 16
+#define ESCHER_ShpInst_Balloon 17
+#define ESCHER_ShpInst_Seal 18
+#define ESCHER_ShpInst_Arc 19
+#define ESCHER_ShpInst_Line 20
+#define ESCHER_ShpInst_Plaque 21
+#define ESCHER_ShpInst_Can 22
+#define ESCHER_ShpInst_Donut 23
+#define ESCHER_ShpInst_TextSimple 24
+#define ESCHER_ShpInst_TextOctagon 25
+#define ESCHER_ShpInst_TextHexagon 26
+#define ESCHER_ShpInst_TextCurve 27
+#define ESCHER_ShpInst_TextWave 28
+#define ESCHER_ShpInst_TextRing 29
+#define ESCHER_ShpInst_TextOnCurve 30
+#define ESCHER_ShpInst_TextOnRing 31
+#define ESCHER_ShpInst_StraightConnector1 32
+#define ESCHER_ShpInst_BentConnector2 33
+#define ESCHER_ShpInst_BentConnector3 34
+#define ESCHER_ShpInst_BentConnector4 35
+#define ESCHER_ShpInst_BentConnector5 36
+#define ESCHER_ShpInst_CurvedConnector2 37
+#define ESCHER_ShpInst_CurvedConnector3 38
+#define ESCHER_ShpInst_CurvedConnector4 39
+#define ESCHER_ShpInst_CurvedConnector5 40
+#define ESCHER_ShpInst_Callout1 41
+#define ESCHER_ShpInst_Callout2 42
+#define ESCHER_ShpInst_Callout3 43
+#define ESCHER_ShpInst_AccentCallout1 44
+#define ESCHER_ShpInst_AccentCallout2 45
+#define ESCHER_ShpInst_AccentCallout3 46
+#define ESCHER_ShpInst_BorderCallout1 47
+#define ESCHER_ShpInst_BorderCallout2 48
+#define ESCHER_ShpInst_BorderCallout3 49
+#define ESCHER_ShpInst_AccentBorderCallout1 50
+#define ESCHER_ShpInst_AccentBorderCallout2 51
+#define ESCHER_ShpInst_AccentBorderCallout3 52
+#define ESCHER_ShpInst_Ribbon 53
+#define ESCHER_ShpInst_Ribbon2 54
+#define ESCHER_ShpInst_Chevron 55
+#define ESCHER_ShpInst_Pentagon 56
+#define ESCHER_ShpInst_NoSmoking 57
+#define ESCHER_ShpInst_Seal8 58
+#define ESCHER_ShpInst_Seal16 59
+#define ESCHER_ShpInst_Seal32 60
+#define ESCHER_ShpInst_WedgeRectCallout 61
+#define ESCHER_ShpInst_WedgeRRectCallout 62
+#define ESCHER_ShpInst_WedgeEllipseCallout 63
+#define ESCHER_ShpInst_Wave 64
+#define ESCHER_ShpInst_FoldedCorner 65
+#define ESCHER_ShpInst_LeftArrow 66
+#define ESCHER_ShpInst_DownArrow 67
+#define ESCHER_ShpInst_UpArrow 68
+#define ESCHER_ShpInst_LeftRightArrow 69
+#define ESCHER_ShpInst_UpDownArrow 70
+#define ESCHER_ShpInst_IrregularSeal1 71
+#define ESCHER_ShpInst_IrregularSeal2 72
+#define ESCHER_ShpInst_LightningBolt 73
+#define ESCHER_ShpInst_Heart 74
+#define ESCHER_ShpInst_PictureFrame 75
+#define ESCHER_ShpInst_QuadArrow 76
+#define ESCHER_ShpInst_LeftArrowCallout 77
+#define ESCHER_ShpInst_RightArrowCallout 78
+#define ESCHER_ShpInst_UpArrowCallout 79
+#define ESCHER_ShpInst_DownArrowCallout 80
+#define ESCHER_ShpInst_LeftRightArrowCallout 81
+#define ESCHER_ShpInst_UpDownArrowCallout 82
+#define ESCHER_ShpInst_QuadArrowCallout 83
+#define ESCHER_ShpInst_Bevel 84
+#define ESCHER_ShpInst_LeftBracket 85
+#define ESCHER_ShpInst_RightBracket 86
+#define ESCHER_ShpInst_LeftBrace 87
+#define ESCHER_ShpInst_RightBrace 88
+#define ESCHER_ShpInst_LeftUpArrow 89
+#define ESCHER_ShpInst_BentUpArrow 90
+#define ESCHER_ShpInst_BentArrow 91
+#define ESCHER_ShpInst_Seal24 92
+#define ESCHER_ShpInst_StripedRightArrow 93
+#define ESCHER_ShpInst_NotchedRightArrow 94
+#define ESCHER_ShpInst_BlockArc 95
+#define ESCHER_ShpInst_SmileyFace 96
+#define ESCHER_ShpInst_VerticalScroll 97
+#define ESCHER_ShpInst_HorizontalScroll 98
+#define ESCHER_ShpInst_CircularArrow 99
+#define ESCHER_ShpInst_NotchedCircularArrow 100
+#define ESCHER_ShpInst_UturnArrow 101
+#define ESCHER_ShpInst_CurvedRightArrow 102
+#define ESCHER_ShpInst_CurvedLeftArrow 103
+#define ESCHER_ShpInst_CurvedUpArrow 104
+#define ESCHER_ShpInst_CurvedDownArrow 105
+#define ESCHER_ShpInst_CloudCallout 106
+#define ESCHER_ShpInst_EllipseRibbon 107
+#define ESCHER_ShpInst_EllipseRibbon2 108
+#define ESCHER_ShpInst_FlowChartProcess 109
+#define ESCHER_ShpInst_FlowChartDecision 110
+#define ESCHER_ShpInst_FlowChartInputOutput 111
+#define ESCHER_ShpInst_FlowChartPredefinedProcess 112
+#define ESCHER_ShpInst_FlowChartInternalStorage 113
+#define ESCHER_ShpInst_FlowChartDocument 114
+#define ESCHER_ShpInst_FlowChartMultidocument 115
+#define ESCHER_ShpInst_FlowChartTerminator 116
+#define ESCHER_ShpInst_FlowChartPreparation 117
+#define ESCHER_ShpInst_FlowChartManualInput 118
+#define ESCHER_ShpInst_FlowChartManualOperation 119
+#define ESCHER_ShpInst_FlowChartConnector 120
+#define ESCHER_ShpInst_FlowChartPunchedCard 121
+#define ESCHER_ShpInst_FlowChartPunchedTape 122
+#define ESCHER_ShpInst_FlowChartSummingJunction 123
+#define ESCHER_ShpInst_FlowChartOr 124
+#define ESCHER_ShpInst_FlowChartCollate 125
+#define ESCHER_ShpInst_FlowChartSort 126
+#define ESCHER_ShpInst_FlowChartExtract 127
+#define ESCHER_ShpInst_FlowChartMerge 128
+#define ESCHER_ShpInst_FlowChartOfflineStorage 129
+#define ESCHER_ShpInst_FlowChartOnlineStorage 130
+#define ESCHER_ShpInst_FlowChartMagneticTape 131
+#define ESCHER_ShpInst_FlowChartMagneticDisk 132
+#define ESCHER_ShpInst_FlowChartMagneticDrum 133
+#define ESCHER_ShpInst_FlowChartDisplay 134
+#define ESCHER_ShpInst_FlowChartDelay 135
+#define ESCHER_ShpInst_TextPlainText 136
+#define ESCHER_ShpInst_TextStop 137
+#define ESCHER_ShpInst_TextTriangle 138
+#define ESCHER_ShpInst_TextTriangleInverted 139
+#define ESCHER_ShpInst_TextChevron 140
+#define ESCHER_ShpInst_TextChevronInverted 141
+#define ESCHER_ShpInst_TextRingInside 142
+#define ESCHER_ShpInst_TextRingOutside 143
+#define ESCHER_ShpInst_TextArchUpCurve 144
+#define ESCHER_ShpInst_TextArchDownCurve 145
+#define ESCHER_ShpInst_TextCircleCurve 146
+#define ESCHER_ShpInst_TextButtonCurve 147
+#define ESCHER_ShpInst_TextArchUpPour 148
+#define ESCHER_ShpInst_TextArchDownPour 149
+#define ESCHER_ShpInst_TextCirclePour 150
+#define ESCHER_ShpInst_TextButtonPour 151
+#define ESCHER_ShpInst_TextCurveUp 152
+#define ESCHER_ShpInst_TextCurveDown 153
+#define ESCHER_ShpInst_TextCascadeUp 154
+#define ESCHER_ShpInst_TextCascadeDown 155
+#define ESCHER_ShpInst_TextWave1 156
+#define ESCHER_ShpInst_TextWave2 157
+#define ESCHER_ShpInst_TextWave3 158
+#define ESCHER_ShpInst_TextWave4 159
+#define ESCHER_ShpInst_TextInflate 160
+#define ESCHER_ShpInst_TextDeflate 161
+#define ESCHER_ShpInst_TextInflateBottom 162
+#define ESCHER_ShpInst_TextDeflateBottom 163
+#define ESCHER_ShpInst_TextInflateTop 164
+#define ESCHER_ShpInst_TextDeflateTop 165
+#define ESCHER_ShpInst_TextDeflateInflate 166
+#define ESCHER_ShpInst_TextDeflateInflateDeflate 167
+#define ESCHER_ShpInst_TextFadeRight 168
+#define ESCHER_ShpInst_TextFadeLeft 169
+#define ESCHER_ShpInst_TextFadeUp 170
+#define ESCHER_ShpInst_TextFadeDown 171
+#define ESCHER_ShpInst_TextSlantUp 172
+#define ESCHER_ShpInst_TextSlantDown 173
+#define ESCHER_ShpInst_TextCanUp 174
+#define ESCHER_ShpInst_TextCanDown 175
+#define ESCHER_ShpInst_FlowChartAlternateProcess 176
+#define ESCHER_ShpInst_FlowChartOffpageConnector 177
+#define ESCHER_ShpInst_Callout90 178
+#define ESCHER_ShpInst_AccentCallout90 179
+#define ESCHER_ShpInst_BorderCallout90 180
+#define ESCHER_ShpInst_AccentBorderCallout90 181
+#define ESCHER_ShpInst_LeftRightUpArrow 182
+#define ESCHER_ShpInst_Sun 183
+#define ESCHER_ShpInst_Moon 184
+#define ESCHER_ShpInst_BracketPair 185
+#define ESCHER_ShpInst_BracePair 186
+#define ESCHER_ShpInst_Seal4 187
+#define ESCHER_ShpInst_DoubleWave 188
+#define ESCHER_ShpInst_ActionButtonBlank 189
+#define ESCHER_ShpInst_ActionButtonHome 190
+#define ESCHER_ShpInst_ActionButtonHelp 191
+#define ESCHER_ShpInst_ActionButtonInformation 192
+#define ESCHER_ShpInst_ActionButtonForwardNext 193
+#define ESCHER_ShpInst_ActionButtonBackPrevious 194
+#define ESCHER_ShpInst_ActionButtonEnd 195
+#define ESCHER_ShpInst_ActionButtonBeginning 196
+#define ESCHER_ShpInst_ActionButtonReturn 197
+#define ESCHER_ShpInst_ActionButtonDocument 198
+#define ESCHER_ShpInst_ActionButtonSound 199
+#define ESCHER_ShpInst_ActionButtonMovie 200
+#define ESCHER_ShpInst_HostControl 201
+#define ESCHER_ShpInst_TextBox 202
+
+#define ESCHER_ShpInst_COUNT 203
+#define ESCHER_ShpInst_Max 0x0FFF
+#define ESCHER_ShpInst_Nil ESCHER_ShpInst_Max
+
+enum ESCHER_BlibType
+{ // GEL provided types...
+ ERROR = 0, // An error occured during loading
+ UNKNOWN, // An unknown blip type
+ EMF, // Windows Enhanced Metafile
+ WMF, // Windows Metafile
+ PICT, // Macintosh PICT
+ PEG, // JFIF
+ PNG, // PNG
+ DIB, // Windows DIB
+ FirstClient = 32, // First client defined blip type
+ LastClient = 255 // Last client defined blip type
+};
+
+enum ESCHER_FillStyle
+{
+ ESCHER_FillSolid, // Fill with a solid color
+ ESCHER_FillPattern, // Fill with a pattern (bitmap)
+ ESCHER_FillTexture, // A texture (pattern with its own color map)
+ ESCHER_FillPicture, // Center a picture in the shape
+ ESCHER_FillShade, // Shade from start to end points
+ ESCHER_FillShadeCenter, // Shade from bounding rectangle to end point
+ ESCHER_FillShadeShape, // Shade from shape outline to end point
+ ESCHER_FillShadeScale,
+ ESCHER_FillShadeTitle,
+ ESCHER_FillBackground
+};
+
+enum ESCHER_wMode
+{
+ ESCHER_wColor, // only used for predefined shades
+ ESCHER_wAutomatic, // depends on object type
+ ESCHER_wGrayScale, // shades of gray only
+ ESCHER_wLightGrayScale, // shades of light gray only
+ ESCHER_wInverseGray, // dark gray mapped to light gray, etc.
+ ESCHER_wGrayOutline, // pure gray and white
+ ESCHER_wBlackTextLine, // black text and lines, all else grayscale
+ ESCHER_wHighContrast, // pure black and white mode (no grays)
+ ESCHER_wBlack, // solid black msobwWhite, // solid white
+ ESCHER_wDontShow, // object not drawn
+ ESCHER_wNumModes // number of Black and white modes
+};
+
+
+//
+enum ESCHER_ShapePath
+{
+ ESCHER_ShapeLines, // A line of straight segments
+ ESCHER_ShapeLinesClosed, // A closed polygonal object
+ ESCHER_ShapeCurves, // A line of Bezier curve segments
+ ESCHER_ShapeCurvesClosed, // A closed shape with curved edges
+ ESCHER_ShapeComplex // pSegmentInfo must be non-empty
+};
+
+
+enum ESCHER_WrapMode
+{
+ ESCHER_WrapSquare,
+ ESCHER_WrapByPoints,
+ ESCHER_WrapNone,
+ ESCHER_WrapTopBottom,
+ ESCHER_WrapThrough
+};
+
+//
+enum ESCHER_bwMode
+{
+ ESCHER_bwColor, // only used for predefined shades
+ ESCHER_bwAutomatic, // depends on object type
+ ESCHER_bwGrayScale, // shades of gray only
+ ESCHER_bwLightGrayScale, // shades of light gray only
+ ESCHER_bwInverseGray, // dark gray mapped to light gray, etc.
+ ESCHER_bwGrayOutline, // pure gray and white
+ ESCHER_bwBlackTextLine, // black text and lines, all else grayscale
+ ESCHER_bwHighContrast, // pure black and white mode (no grays)
+ ESCHER_bwBlack, // solid black
+ ESCHER_bwWhite, // solid white
+ ESCHER_bwDontShow, // object not drawn
+ ESCHER_bwNumModes // number of Black and white modes
+};
+
+
+enum ESCHER_AnchorText
+{
+ ESCHER_AnchorTop,
+ ESCHER_AnchorMiddle,
+ ESCHER_AnchorBottom,
+ ESCHER_AnchorTopCentered,
+ ESCHER_AnchorMiddleCentered,
+ ESCHER_AnchorBottomCentered,
+ ESCHER_AnchorTopBaseline,
+ ESCHER_AnchorBottomBaseline,
+ ESCHER_AnchorTopCenteredBaseline,
+ ESCHER_AnchorBottomCenteredBaseline
+};
+
+enum ESCHER_cDir
+{
+ ESCHER_cDir0, // Right
+ ESCHER_cDir90, // Down
+ ESCHER_cDir180, // Left
+ ESCHER_cDir270 // Up
+};
+
+// connector style
+enum ESCHER_cxSTYLE
+{
+ ESCHER_cxstyleStraight = 0,
+ ESCHER_cxstyleBent,
+ ESCHER_cxstyleCurved,
+ ESCHER_cxstyleNone
+};
+
+// text flow
+enum ESCHER_txfl
+{
+ ESCHER_txflHorzN, // Horizontal non-@
+ ESCHER_txflTtoBA, // Top to Bottom @-font
+ ESCHER_txflBtoT, // Bottom to Top non-@
+ ESCHER_txflTtoBN, // Top to Bottom non-@
+ ESCHER_txflHorzA, // Horizontal @-font
+ ESCHER_txflVertN // Vertical, non-@
+};
+
+// text direction (needed for Bi-Di support)
+enum ESCHER_txDir
+{
+ ESCHER_txdirLTR, // left-to-right text direction
+ ESCHER_txdirRTL, // right-to-left text direction
+ ESCHER_txdirContext // context text direction
+};
+
+// Callout Type
+enum ESCHER_spcot
+{
+ ESCHER_spcotRightAngle = 1,
+ ESCHER_spcotOneSegment = 2,
+ ESCHER_spcotTwoSegment = 3,
+ ESCHER_spcotThreeSegment = 4
+};
+
+// Callout Angle
+enum ESCHER_spcoa
+{
+ ESCHER_spcoaAny,
+ ESCHER_spcoa30,
+ ESCHER_spcoa45,
+ ESCHER_spcoa60,
+ ESCHER_spcoa90,
+ ESCHER_spcoa0
+};
+
+// Callout Drop
+enum ESCHER_spcod
+{
+ ESCHER_spcodTop,
+ ESCHER_spcodCenter,
+ ESCHER_spcodBottom,
+ ESCHER_spcodSpecified
+};
+
+// FontWork alignment
+enum ESCHER_GeoTextAlign
+{
+ ESCHER_AlignTextStretch, /* Stretch each line of text to fit width. */
+ ESCHER_AlignTextCenter, /* Center text on width. */
+ ESCHER_AlignTextLeft, /* Left justify. */
+ ESCHER_AlignTextRight, /* Right justify. */
+ ESCHER_AlignTextLetterJust, /* Spread letters out to fit width. */
+ ESCHER_AlignTextWordJust, /* Spread words out to fit width. */
+ ESCHER_AlignTextInvalid /* Invalid */
+};
+
+// flags for pictures
+enum ESCHER_BlipFlags
+{
+ ESCHER_BlipFlagDefault = 0,
+ ESCHER_BlipFlagComment = 0, // Blip name is a comment
+ ESCHER_BlipFlagFile, // Blip name is a file name
+ ESCHER_BlipFlagURL, // Blip name is a full URL
+ ESCHER_BlipFlagType = 3, // Mask to extract type
+ /* Or the following flags with any of the above. */
+ ESCHER_BlipFlagDontSave = 4, // A "dont" is the depression in the metal
+ // body work of an automobile caused when a
+ // cyclist violently thrusts his or her nose
+ // at it, thus a DontSave is another name for
+ // a cycle lane.
+ ESCHER_BlipFlagDoNotSave = 4, // For those who prefer English
+ ESCHER_BlipFlagLinkToFile = 8
+};
+
+//
+enum ESCHER_3DRenderMode
+{
+ ESCHER_FullRender, // Generate a full rendering
+ ESCHER_Wireframe, // Generate a wireframe
+ ESCHER_BoundingCube // Generate a bounding cube
+};
+
+//
+enum ESCHER_xFormType
+{
+ ESCHER_xFormAbsolute, // Apply transform in absolute space centered on shape
+ ESCHER_xFormShape, // Apply transform to shape geometry
+ ESCHER_xFormDrawing // Apply transform in drawing space
+};
+
+//
+enum ESCHER_ShadowType
+{
+ ESCHER_ShadowOffset, // N pixel offset shadow
+ ESCHER_ShadowDouble, // Use second offset too
+ ESCHER_ShadowRich, // Rich perspective shadow (cast relative to shape)
+ ESCHER_ShadowShape, // Rich perspective shadow (cast in shape space)
+ ESCHER_ShadowDrawing, // Perspective shadow cast in drawing space
+ ESCHER_ShadowEmbossOrEngrave
+};
+
+// - the type of a (length) measurement
+enum ESCHER_dzType
+ {
+ ESCHER_dzTypeMin = 0,
+ ESCHER_dzTypeDefault = 0, // Default size, ignore the values
+ ESCHER_dzTypeA = 1, // Values are in EMUs
+ ESCHER_dzTypeV = 2, // Values are in pixels
+ ESCHER_dzTypeShape = 3, // Values are 16.16 fractions of shape size
+ ESCHER_dzTypeFixedAspect = 4, // Aspect ratio is fixed
+ ESCHER_dzTypeAFixed = 5, // EMUs, fixed aspect ratio
+ ESCHER_dzTypeVFixed = 6, // Pixels, fixed aspect ratio
+ ESCHER_dzTypeShapeFixed = 7, // Proportion of shape, fixed aspect ratio
+ ESCHER_dzTypeFixedAspectEnlarge= 8, // Aspect ratio is fixed, favor larger size
+ ESCHER_dzTypeAFixedBig = 9, // EMUs, fixed aspect ratio
+ ESCHER_dzTypeVFixedBig = 10, // Pixels, fixed aspect ratio
+ ESCHER_dzTypeShapeFixedBig= 11, // Proportion of shape, fixed aspect ratio
+ ESCHER_dzTypeMax = 11
+};
+
+// how to interpret the colors in a shaded fill.
+enum ESCHER_ShadeType
+{
+ ESCHER_ShadeNone = 0, // Interpolate without correction between RGBs
+ ESCHER_ShadeGamma = 1, // Apply gamma correction to colors
+ ESCHER_ShadeSigma = 2, // Apply a sigma transfer function to position
+ ESCHER_ShadeBand = 4, // Add a flat band at the start of the shade
+ ESCHER_ShadeOneColor = 8, // This is a one color shade
+
+ /* A parameter for the band or sigma function can be stored in the top
+ 16 bits of the value - this is a proportion of *each* band of the
+ shade to make flat (or the approximate equal value for a sigma
+ function). NOTE: the parameter is not used for the sigma function,
+ instead a built in value is used. This value should not be changed
+ from the default! */
+ ESCHER_ShadeParameterShift = 16,
+ ESCHER_ShadeParameterMask = 0xffff0000,
+
+ ESCHER_ShadeDefault = (ESCHER_ShadeGamma|ESCHER_ShadeSigma|
+ (16384<<ESCHER_ShadeParameterShift))
+};
+
+// compound line style
+enum ESCHER_LineStyle
+{
+ ESCHER_LineSimple, // Single line (of width lineWidth)
+ ESCHER_LineDouble, // Double lines of equal width
+ ESCHER_LineThickThin, // Double lines, one thick, one thin
+ ESCHER_LineThinThick, // Double lines, reverse order
+ ESCHER_LineTriple // Three lines, thin, thick, thin
+};
+
+// how to "fill" the line contour
+enum ESCHER_LineType
+{
+ ESCHER_lineSolidType, // Fill with a solid color
+ ESCHER_linePattern, // Fill with a pattern (bitmap)
+ ESCHER_lineTexture, // A texture (pattern with its own color map)
+ ESCHER_linePicture // Center a picture in the shape
+};
+
+// dashed line style
+enum ESCHER_LineDashing
+{
+ ESCHER_LineSolid, // Solid (continuous) pen
+ ESCHER_LineDashSys, // PS_DASH system dash style
+ ESCHER_LineDotSys, // PS_DOT system dash style
+ ESCHER_LineDashDotSys, // PS_DASHDOT system dash style
+ ESCHER_LineDashDotDotSys, // PS_DASHDOTDOT system dash style
+ ESCHER_LineDotGEL, // square dot style
+ ESCHER_LineDashGEL, // dash style
+ ESCHER_LineLongDashGEL, // long dash style
+ ESCHER_LineDashDotGEL, // dash short dash
+ ESCHER_LineLongDashDotGEL, // long dash short dash
+ ESCHER_LineLongDashDotDotGEL // long dash short dash short dash
+};
+
+// line end effect
+enum ESCHER_LineEnd
+{
+ ESCHER_LineNoEnd,
+ ESCHER_LineArrowEnd,
+ ESCHER_LineArrowStealthEnd,
+ ESCHER_LineArrowDiamondEnd,
+ ESCHER_LineArrowOvalEnd,
+ ESCHER_LineArrowOpenEnd
+};
+
+// size of arrowhead
+enum ESCHER_LineWidth
+{
+ ESCHER_LineNarrowArrow,
+ ESCHER_LineMediumWidthArrow,
+ ESCHER_LineWideArrow
+};
+
+// size of arrowhead
+enum ESCHER_LineEndLenght
+{
+ ESCHER_LineShortArrow,
+ ESCHER_LineMediumLenArrow,
+ ESCHER_LineLongArrow
+};
+
+// line join style.
+enum ESCHER_LineJoin
+{
+ ESCHER_LineJoinBevel, // Join edges by a straight line
+ ESCHER_LineJoinMiter, // Extend edges until they join
+ ESCHER_LineJoinRound // Draw an arc between the two edges
+};
+
+// line cap style (applies to ends of dash segments too).
+enum ESCHER_LineCap
+{
+ ESCHER_LineEndCapRound, // Rounded ends - the default
+ ESCHER_LineEndCapSquare, // Square protrudes by half line width
+ ESCHER_LineEndCapFlat // Line ends at end point
+};
+// Shape Properties
+// 1pt = 12700 EMU (English Metric Units)
+// 1pt = 20 Twip = 20/1440" = 1/72"
+// 1twip=635 EMU
+// 1" = 12700*72 = 914400 EMU
+// 1" = 25.4mm
+// 1mm = 36000 EMU
+// Transform
+#define ESCHER_Prop_Rotation 4 /* Fixed Point 16.16 degrees */
+// Protection
+#define ESCHER_Prop_LockRotation 119 /* BOOL No rotation */
+#define ESCHER_Prop_LockAspectRatio 120 /* BOOL Don't allow changes in aspect ratio */
+#define ESCHER_Prop_LockPosition 121 /* BOOL Don't allow the shape to be moved */
+#define ESCHER_Prop_LockAgainstSelect 122 /* BOOL Shape may not be selected */
+#define ESCHER_Prop_LockCropping 123 /* BOOL No cropping this shape */
+#define ESCHER_Prop_LockVertices 124 /* BOOL Edit Points not allowed */
+#define ESCHER_Prop_LockText 125 /* BOOL Do not edit text */
+#define ESCHER_Prop_LockAdjustHandles 126 /* BOOL Do not adjust */
+#define ESCHER_Prop_LockAgainstGrouping 127 /* BOOL Do not group this shape */
+// Text
+#define ESCHER_Prop_lTxid 128 /* LONG id for the text, value determined by the host */
+#define ESCHER_Prop_dxTextLeft 129 /* LONG margins relative to shape's inscribed */
+#define ESCHER_Prop_dyTextTop 130 /* LONG text rectangle (in EMUs) */
+#define ESCHER_Prop_dxTextRight 131 /* LONG */
+#define ESCHER_Prop_dyTextBottom 132 /* LONG */
+#define ESCHER_Prop_WrapText 133 /* MSOWRAPMODE Wrap text at shape margins */
+#define ESCHER_Prop_scaleText 134 /* LONG Text zoom/scale (used if fFitTextToShape) */
+#define ESCHER_Prop_AnchorText 135 /* ESCHER_AnchorText How to anchor the text */
+#define ESCHER_Prop_txflTextFlow 136 /* MSOTXFL Text flow */
+#define ESCHER_Prop_cdirFont 137 /* MSOCDIR Font rotation */
+#define ESCHER_Prop_hspNext 138 /* MSOHSP ID of the next shape (used by Word for linked textboxes) */
+#define ESCHER_Prop_txdir 139 /* MSOTXDIR Bi-Di Text direction */
+#define ESCHER_Prop_SelectText 187 /* BOOL TRUE if single click selects text, FALSE if two clicks */
+#define ESCHER_Prop_AutoTextMargin 188 /* BOOL use host's margin calculations */
+#define ESCHER_Prop_RotateText 189 /* BOOL Rotate text with shape */
+#define ESCHER_Prop_FitShapeToText 190 /* BOOL Size shape to fit text size */
+#define ESCHER_Prop_FitTextToShape 191 /* BOOL Size text to fit shape size */
+// GeoText
+#define ESCHER_Prop_gtextUNICODE 192 /* WCHAR* UNICODE text string */
+#define ESCHER_Prop_gtextRTF 193 /* char* RTF text string */
+#define ESCHER_Prop_gtextAlign 194 /* MSOGEOTEXTALIGN alignment on curve */
+#define ESCHER_Prop_gtextSize 195 /* LONG default point size */
+#define ESCHER_Prop_gtextSpacing 196 /* LONG fixed point 16.16 */
+#define ESCHER_Prop_gtextFont 197 /* WCHAR* font family name */
+#define ESCHER_Prop_gtextFReverseRows 240 /* BOOL Reverse row order */
+#define ESCHER_Prop_fGtext 241 /* BOOL Has text effect */
+#define ESCHER_Prop_gtextFVertical 242 /* BOOL Rotate characters */
+#define ESCHER_Prop_gtextFKern 243 /* BOOL Kern characters */
+#define ESCHER_Prop_gtextFTight 244 /* BOOL Tightening or tracking */
+#define ESCHER_Prop_gtextFStretch 245 /* BOOL Stretch to fit shape */
+#define ESCHER_Prop_gtextFShrinkFit 246 /* BOOL Char bounding box */
+#define ESCHER_Prop_gtextFBestFit 247 /* BOOL Scale text-on-path */
+#define ESCHER_Prop_gtextFNormalize 248 /* BOOL Stretch char height */
+#define ESCHER_Prop_gtextFDxMeasure 249 /* BOOL Do not measure along path */
+#define ESCHER_Prop_gtextFBold 250 /* BOOL Bold font */
+#define ESCHER_Prop_gtextFItalic 251 /* BOOL Italic font */
+#define ESCHER_Prop_gtextFUnderline 252 /* BOOL Underline font */
+#define ESCHER_Prop_gtextFShadow 253 /* BOOL Shadow font */
+#define ESCHER_Prop_gtextFSmallcaps 254 /* BOOL Small caps font */
+#define ESCHER_Prop_gtextFStrikethrough 255 /* BOOL Strike through font */
+// Blip
+#define ESCHER_Prop_cropFromTop 256 /* LONG 16.16 fraction times total */
+#define ESCHER_Prop_cropFromBottom 257 /* LONG image width or height, */
+#define ESCHER_Prop_cropFromLeft 258 /* LONG as appropriate. */
+#define ESCHER_Prop_cropFromRight 259 /* LONG */
+#define ESCHER_Prop_pib 260 /* IMsoBlip* Blip to display */
+#define ESCHER_Prop_pibName 261 /* WCHAR* Blip file name */
+#define ESCHER_Prop_pibFlags 262 /* MSOBLIPFLAGS Blip flags */
+#define ESCHER_Prop_pictureTransparent 263 /* LONG transparent color (none if ~0UL) */
+#define ESCHER_Prop_pictureContrast 264 /* LONG contrast setting */
+#define ESCHER_Prop_pictureBrightness 265 /* LONG brightness setting */
+#define ESCHER_Prop_pictureGamma 266 /* LONG 16.16 gamma */
+#define ESCHER_Prop_pictureId 267 /* LONG Host-defined ID for OLE objects (usually a pointer) */
+#define ESCHER_Prop_pictureDblCrMod 268 /* MSOCLR Modification used if shape has double shadow */
+#define ESCHER_Prop_pictureFillCrMod 269 /* MSOCLR */
+#define ESCHER_Prop_pictureLineCrMod 270 /* MSOCLR */
+#define ESCHER_Prop_pibPrint 271 /* IMsoBlip* Blip to display when printing */
+#define ESCHER_Prop_pibPrintName 272 /* WCHAR* Blip file name */
+#define ESCHER_Prop_pibPrintFlags 273 /* MSOBLIPFLAGS Blip flags */
+#define ESCHER_Prop_fNoHitTestPicture 316 /* BOOL Do not hit test the picture */
+#define ESCHER_Prop_pictureGray 317 /* BOOL grayscale display */
+#define ESCHER_Prop_pictureBiLevel 318 /* BOOL bi-level display */
+#define ESCHER_Prop_pictureActive 319 /* BOOL Server is active (OLE objects only) */
+// Geometry
+#define ESCHER_Prop_geoLeft 320 /* LONG Defines the G (geometry) coordinate space. */
+#define ESCHER_Prop_geoTop 321 /* LONG */
+#define ESCHER_Prop_geoRight 322 /* LONG */
+#define ESCHER_Prop_geoBottom 323 /* LONG */
+#define ESCHER_Prop_shapePath 324 /* MSOSHAPEPATH */
+#define ESCHER_Prop_pVertices 325 /* IMsoArray An array of points, in G units. */
+#define ESCHER_Prop_pSegmentInfo 326 /* IMsoArray */
+#define ESCHER_Prop_adjustValue 327 /* LONG Adjustment values corresponding to */
+#define ESCHER_Prop_adjust2Value 328 /* LONG the positions of the adjust handles */
+#define ESCHER_Prop_adjust3Value 329 /* LONG of the shape. The number of values */
+#define ESCHER_Prop_adjust4Value 330 /* LONG used and their allowable ranges vary */
+#define ESCHER_Prop_adjust5Value 331 /* LONG from shape type to shape type. */
+#define ESCHER_Prop_adjust6Value 332 /* LONG */
+#define ESCHER_Prop_adjust7Value 333 /* LONG */
+#define ESCHER_Prop_adjust8Value 334 /* LONG */
+#define ESCHER_Prop_adjust9Value 335 /* LONG */
+#define ESCHER_Prop_adjust10Value 336 /* LONG */
+#define ESCHER_Prop_fShadowOK 378 /* BOOL Shadow may be set */
+#define ESCHER_Prop_f3DOK 379 /* BOOL 3D may be set */
+#define ESCHER_Prop_fLineOK 380 /* BOOL Line style may be set */
+#define ESCHER_Prop_fGtextOK 381 /* BOOL Text effect (FontWork) supported */
+#define ESCHER_Prop_fFillShadeShapeOK 382 /* BOOL */
+#define ESCHER_Prop_fFillOK 383 /* BOOL OK to fill the shape through the UI or VBA? */
+// FillStyle
+#define ESCHER_Prop_fillType 384 /* ESCHER_FillStyle Type of fill */
+#define ESCHER_Prop_fillColor 385 /* MSOCLR Foreground color */
+#define ESCHER_Prop_fillOpacity 386 /* LONG Fixed 16.16 */
+#define ESCHER_Prop_fillBackColor 387 /* MSOCLR Background color */
+#define ESCHER_Prop_fillBackOpacity 388 /* LONG Shades only */
+#define ESCHER_Prop_fillCrMod 389 /* MSOCLR Modification for BW views */
+#define ESCHER_Prop_fillBlip 390 /* IMsoBlip* Pattern/texture */
+#define ESCHER_Prop_fillBlipName 391 /* WCHAR* Blip file name */
+#define ESCHER_Prop_fillBlipFlags 392 /* MSOBLIPFLAGS Blip flags */
+#define ESCHER_Prop_fillWidth 393 /* LONG How big (A units) to make a metafile texture. */
+#define ESCHER_Prop_fillHeight 394 /* LONG */
+#define ESCHER_Prop_fillAngle 395 /* LONG Fade angle - degrees in 16.16 */
+#define ESCHER_Prop_fillFocus 396 /* LONG Linear shaded fill focus percent */
+#define ESCHER_Prop_fillToLeft 397 /* LONG Fraction 16.16 */
+#define ESCHER_Prop_fillToTop 398 /* LONG Fraction 16.16 */
+#define ESCHER_Prop_fillToRight 399 /* LONG Fraction 16.16 */
+#define ESCHER_Prop_fillToBottom 400 /* LONG Fraction 16.16 */
+#define ESCHER_Prop_fillRectLeft 401 /* LONG For shaded fills, use the specified rectangle */
+#define ESCHER_Prop_fillRectTop 402 /* LONG instead of the shape's bounding rect to */
+#define ESCHER_Prop_fillRectRight 403 /* LONG define how large the fade is going to be. */
+#define ESCHER_Prop_fillRectBottom 404 /* LONG */
+#define ESCHER_Prop_fillDztype 405 /* MSODZTYPE */
+#define ESCHER_Prop_fillShadePreset 406 /* LONG Special shades */
+#define ESCHER_Prop_fillShadeColors 407 /* IMsoArray a preset array of colors */
+#define ESCHER_Prop_fillOriginX 408 /* LONG */
+#define ESCHER_Prop_fillOriginY 409 /* LONG */
+#define ESCHER_Prop_fillShapeOriginX 410 /* LONG */
+#define ESCHER_Prop_fillShapeOriginY 411 /* LONG */
+#define ESCHER_Prop_fillShadeType 412 /* MSOSHADETYPE Type of shading, if a shaded (gradient) fill. */
+#define ESCHER_Prop_fFilled 443 /* BOOL Is shape filled? */
+#define ESCHER_Prop_fHitTestFill 444 /* BOOL Should we hit test fill? */
+#define ESCHER_Prop_fillShape 445 /* BOOL Register pattern on shape */
+#define ESCHER_Prop_fillUseRect 446 /* BOOL Use the large rect? */
+#define ESCHER_Prop_fNoFillHitTest 447 /* BOOL Hit test a shape as though filled */
+// LineStyle
+#define ESCHER_Prop_lineColor 448 /* MSOCLR Color of line */
+#define ESCHER_Prop_lineOpacity 449 /* LONG Not implemented */
+#define ESCHER_Prop_lineBackColor 450 /* MSOCLR Background color */
+#define ESCHER_Prop_lineCrMod 451 /* MSOCLR Modification for BW views */
+#define ESCHER_Prop_lineType 452 /* MSOLINETYPE Type of line */
+#define ESCHER_Prop_lineFillBlip 453 /* IMsoBlip* Pattern/texture */
+#define ESCHER_Prop_lineFillBlipName 454 /* WCHAR* Blip file name */
+#define ESCHER_Prop_lineFillBlipFlags 455 /* MSOBLIPFLAGS Blip flags */
+#define ESCHER_Prop_lineFillWidth 456 /* LONG How big (A units) to make */
+#define ESCHER_Prop_lineFillHeight 457 /* LONG a metafile texture. */
+#define ESCHER_Prop_lineFillDztype 458 /* MSODZTYPE How to interpret fillWidth/Height numbers. */
+#define ESCHER_Prop_lineWidth 459 /* LONG A units; 1pt == 12700 EMUs */
+#define ESCHER_Prop_lineMiterLimit 460 /* LONG ratio (16.16) of width */
+#define ESCHER_Prop_lineStyle 461 /* MSOLINESTYLE Draw parallel lines? */
+#define ESCHER_Prop_lineDashing 462 /* MSOLINEDASHING Can be overridden by: */
+#define ESCHER_Prop_lineDashStyle 463 /* IMsoArray As Win32 ExtCreatePen */
+#define ESCHER_Prop_lineStartArrowhead 464 /* MSOLINEEND Arrow at start */
+#define ESCHER_Prop_lineEndArrowhead 465 /* MSOLINEEND Arrow at end */
+#define ESCHER_Prop_lineStartArrowWidth 466 /* MSOLINEENDWIDTH Arrow at start */
+#define ESCHER_Prop_lineStartArrowLength 467 /* MSOLINEENDLENGTH Arrow at end */
+#define ESCHER_Prop_lineEndArrowWidth 468 /* MSOLINEENDWIDTH Arrow at start */
+#define ESCHER_Prop_lineEndArrowLength 469 /* MSOLINEENDLENGTH Arrow at end */
+#define ESCHER_Prop_lineJoinStyle 470 /* MSOLINEJOIN How to join lines */
+#define ESCHER_Prop_lineEndCapStyle 471 /* MSOLINECAP How to end lines */
+#define ESCHER_Prop_fArrowheadsOK 507 /* BOOL Allow arrowheads if prop. is set */
+#define ESCHER_Prop_fLine 508 /* BOOL Any line? */
+#define ESCHER_Prop_fHitTestLine 509 /* BOOL Should we hit test lines? */
+#define ESCHER_Prop_lineFillShape 510 /* BOOL Register pattern on shape */
+#define ESCHER_Prop_fNoLineDrawDash 511 /* BOOL Draw a dashed line if no line */
+// ShadowStyle
+#define ESCHER_Prop_shadowType 512 /* MSOSHADOWTYPE Type of effect */
+#define ESCHER_Prop_shadowColor 513 /* MSOCLR Foreground color */
+#define ESCHER_Prop_shadowHighlight 514 /* MSOCLR Embossed color */
+#define ESCHER_Prop_shadowCrMod 515 /* MSOCLR Modification for BW views */
+#define ESCHER_Prop_shadowOpacity 516 /* LONG Fixed 16.16 */
+#define ESCHER_Prop_shadowOffsetX 517 /* LONG Offset shadow */
+#define ESCHER_Prop_shadowOffsetY 518 /* LONG Offset shadow */
+#define ESCHER_Prop_shadowSecondOffsetX 519 /* LONG Double offset shadow */
+#define ESCHER_Prop_shadowSecondOffsetY 520 /* LONG Double offset shadow */
+#define ESCHER_Prop_shadowScaleXToX 521 /* LONG 16.16 */
+#define ESCHER_Prop_shadowScaleYToX 522 /* LONG 16.16 */
+#define ESCHER_Prop_shadowScaleXToY 523 /* LONG 16.16 */
+#define ESCHER_Prop_shadowScaleYToY 524 /* LONG 16.16 */
+#define ESCHER_Prop_shadowPerspectiveX 525 /* LONG 16.16 / weight */
+#define ESCHER_Prop_shadowPerspectiveY 526 /* LONG 16.16 / weight */
+#define ESCHER_Prop_shadowWeight 527 /* LONG scaling factor */
+#define ESCHER_Prop_shadowOriginX 528 /* LONG */
+#define ESCHER_Prop_shadowOriginY 529 /* LONG */
+#define ESCHER_Prop_fShadow 574 /* BOOL Any shadow? */
+#define ESCHER_Prop_fshadowObscured 575 /* BOOL Excel5-style shadow */
+// PerspectiveStyle
+#define ESCHER_Prop_perspectiveType 576 /* MSOXFORMTYPE Where transform applies */
+#define ESCHER_Prop_perspectiveOffsetX 577 /* LONG The LONG values define a */
+#define ESCHER_Prop_perspectiveOffsetY 578 /* LONG transformation matrix, */
+#define ESCHER_Prop_perspectiveScaleXToX 579 /* LONG effectively, each value */
+#define ESCHER_Prop_perspectiveScaleYToX 580 /* LONG is scaled by the */
+#define ESCHER_Prop_perspectiveScaleXToY 581 /* LONG perspectiveWeight parameter. */
+#define ESCHER_Prop_perspectiveScaleYToY 582 /* LONG */
+#define ESCHER_Prop_perspectivePerspectiveX 583 /* LONG */
+#define ESCHER_Prop_perspectivePerspectiveY 584 /* LONG */
+#define ESCHER_Prop_perspectiveWeight 585 /* LONG Scaling factor */
+#define ESCHER_Prop_perspectiveOriginX 586 /* LONG */
+#define ESCHER_Prop_perspectiveOriginY 587 /* LONG */
+#define ESCHER_Prop_fPerspective 639 /* BOOL On/off */
+// 3D Object
+#define ESCHER_Prop_c3DSpecularAmt 640 /* LONG Fixed-point 16.16 */
+#define ESCHER_Prop_c3DDiffuseAmt 641 /* LONG Fixed-point 16.16 */
+#define ESCHER_Prop_c3DShininess 642 /* LONG Default gives OK results */
+#define ESCHER_Prop_c3DEdgeThickness 643 /* LONG Specular edge thickness */
+#define ESCHER_Prop_c3DExtrudeForward 644 /* LONG Distance of extrusion in EMUs */
+#define ESCHER_Prop_c3DExtrudeBackward 645 /* LONG */
+#define ESCHER_Prop_c3DExtrudePlane 646 /* LONG Extrusion direction */
+#define ESCHER_Prop_c3DExtrusionColor 647 /* MSOCLR Basic color of extruded part of shape; the lighting model used will determine the exact shades used when rendering. */
+#define ESCHER_Prop_c3DCrMod 648 /* MSOCLR Modification for BW views */
+#define ESCHER_Prop_f3D 700 /* BOOL Does this shape have a 3D effect? */
+#define ESCHER_Prop_fc3DMetallic 701 /* BOOL Use metallic specularity? */
+#define ESCHER_Prop_fc3DUseExtrusionColor 702 /* BOOL */
+#define ESCHER_Prop_fc3DLightFace 703 /* BOOL */
+// 3D Style
+#define ESCHER_Prop_c3DYRotationAngle 704 /* LONG degrees (16.16) about y axis */
+#define ESCHER_Prop_c3DXRotationAngle 705 /* LONG degrees (16.16) about x axis */
+#define ESCHER_Prop_c3DRotationAxisX 706 /* LONG These specify the rotation axis; */
+#define ESCHER_Prop_c3DRotationAxisY 707 /* LONG only their relative magnitudes */
+#define ESCHER_Prop_c3DRotationAxisZ 708 /* LONG matter. */
+#define ESCHER_Prop_c3DRotationAngle 709 /* LONG degrees (16.16) about axis */
+#define ESCHER_Prop_c3DRotationCenterX 710 /* LONG rotation center x (16.16 or g-units) */
+#define ESCHER_Prop_c3DRotationCenterY 711 /* LONG rotation center y (16.16 or g-units) */
+#define ESCHER_Prop_c3DRotationCenterZ 712 /* LONG rotation center z (absolute (emus)) */
+#define ESCHER_Prop_c3DRenderMode 713 /* MSO3DRENDERMODE Full,wireframe, or bcube */
+#define ESCHER_Prop_c3DTolerance 714 /* LONG pixels (16.16) */
+#define ESCHER_Prop_c3DXViewpoint 715 /* LONG X view point (emus) */
+#define ESCHER_Prop_c3DYViewpoint 716 /* LONG Y view point (emus) */
+#define ESCHER_Prop_c3DZViewpoint 717 /* LONG Z view distance (emus) */
+#define ESCHER_Prop_c3DOriginX 718 /* LONG */
+#define ESCHER_Prop_c3DOriginY 719 /* LONG */
+#define ESCHER_Prop_c3DSkewAngle 720 /* LONG degree (16.16) skew angle */
+#define ESCHER_Prop_c3DSkewAmount 721 /* LONG Percentage skew amount */
+#define ESCHER_Prop_c3DAmbientIntensity 722 /* LONG Fixed point intensity */
+#define ESCHER_Prop_c3DKeyX 723 /* LONG Key light source direc- */
+#define ESCHER_Prop_c3DKeyY 724 /* LONG tion; only their relative */
+#define ESCHER_Prop_c3DKeyZ 725 /* LONG magnitudes matter */
+#define ESCHER_Prop_c3DKeyIntensity 726 /* LONG Fixed point intensity */
+#define ESCHER_Prop_c3DFillX 727 /* LONG Fill light source direc- */
+#define ESCHER_Prop_c3DFillY 728 /* LONG tion; only their relative */
+#define ESCHER_Prop_c3DFillZ 729 /* LONG magnitudes matter */
+#define ESCHER_Prop_c3DFillIntensity 730 /* LONG Fixed point intensity */
+#define ESCHER_Prop_fc3DConstrainRotation 763 /* BOOL */
+#define ESCHER_Prop_fc3DRotationCenterAuto 764 /* BOOL */
+#define ESCHER_Prop_fc3DParallel 765 /* BOOL Parallel projection? */
+#define ESCHER_Prop_fc3DKeyHarsh 766 /* BOOL Is key lighting harsh? */
+#define ESCHER_Prop_fc3DFillHarsh 767 /* BOOL Is fill lighting harsh? */
+// Shape
+#define ESCHER_Prop_hspMaster 769 /* MSOHSP master shape */
+#define ESCHER_Prop_cxstyle 771 /* MSOCXSTYLE Type of connector */
+#define ESCHER_Prop_bWMode 772 /* ESCHERwMode Settings for modifications to */
+#define ESCHER_Prop_bWModePureBW 773 /* ESCHERwMode be made when in different */
+#define ESCHER_Prop_bWModeBW 774 /* ESCHERwMode forms of black-and-white mode. */
+#define ESCHER_Prop_fOleIcon 826 /* BOOL For OLE objects, whether the object is in icon form */
+#define ESCHER_Prop_fPreferRelativeResize 827 /* BOOL For UI only. Prefer relative resizing. */
+#define ESCHER_Prop_fLockShapeType 828 /* BOOL Lock the shape type (don't allow Change Shape) */
+#define ESCHER_Prop_fDeleteAttachedObject 830 /* BOOL */
+#define ESCHER_Prop_fBackground 831 /* BOOL If TRUE, this is the background shape. */
+// Callout
+#define ESCHER_Prop_spcot 832 /* MSOSPCOT Callout type */
+#define ESCHER_Prop_dxyCalloutGap 833 /* LONG Distance from box to first point.(EMUs) */
+#define ESCHER_Prop_spcoa 834 /* MSOSPCOA Callout angle */
+#define ESCHER_Prop_spcod 835 /* MSOSPCOD Callout drop type */
+#define ESCHER_Prop_dxyCalloutDropSpecified 836 /* LONG if msospcodSpecified, the actual drop distance */
+#define ESCHER_Prop_dxyCalloutLengthSpecified 837 /* LONG if fCalloutLengthSpecified, the actual distance */
+#define ESCHER_Prop_fCallout 889 /* BOOL Is the shape a callout? */
+#define ESCHER_Prop_fCalloutAccentBar 890 /* BOOL does callout have accent bar */
+#define ESCHER_Prop_fCalloutTextBorder 891 /* BOOL does callout have a text border */
+#define ESCHER_Prop_fCalloutMinusX 892 /* BOOL */
+#define ESCHER_Prop_fCalloutMinusY 893 /* BOOL */
+#define ESCHER_Prop_fCalloutDropAuto 894 /* BOOL If true, then we occasionally invert the drop distance */
+#define ESCHER_Prop_fCalloutLengthSpecified 895 /* BOOL if true, we look at dxyCalloutLengthSpecified */
+// GroupShape
+#define ESCHER_Prop_wzName 896 /* WCHAR* Shape Name (present only if explicitly set) */
+#define ESCHER_Prop_wzDescription 897 /* WCHAR* alternate text */
+#define ESCHER_Prop_pihlShape 898 /* IHlink* The hyperlink in the shape. */
+#define ESCHER_Prop_pWrapPolygonVertices 899 /* IMsoArray The polygon that text will be wrapped around (Word) */
+#define ESCHER_Prop_dxWrapDistLeft 900 /* LONG Left wrapping distance from text (Word) */
+#define ESCHER_Prop_dyWrapDistTop 901 /* LONG Top wrapping distance from text (Word) */
+#define ESCHER_Prop_dxWrapDistRight 902 /* LONG Right wrapping distance from text (Word) */
+#define ESCHER_Prop_dyWrapDistBottom 903 /* LONG Bottom wrapping distance from text (Word) */
+#define ESCHER_Prop_lidRegroup 904 /* LONG Regroup ID */
+#define ESCHER_Prop_tableProperties 927
+#define ESCHER_Prop_tableRowProperties 928
+#define ESCHER_Prop_fEditedWrap 953 /* BOOL Has the wrap polygon been edited? */
+#define ESCHER_Prop_fBehindDocument 954 /* BOOL Word-only (shape is behind text) */
+#define ESCHER_Prop_fOnDblClickNotify 955 /* BOOL Notify client on a double click */
+#define ESCHER_Prop_fIsButton 956 /* BOOL A button shape (i.e., clicking performs an action). Set for shapes with attached hyperlinks or macros. */
+#define ESCHER_Prop_fOneD 957 /* BOOL 1D adjustment */
+#define ESCHER_Prop_fHidden 958 /* BOOL Do not display */
+#define ESCHER_Prop_fPrint 959 /* BOOL Print this shape */
+
+#define ESCHER_PERSISTENTRY_PREALLOCATE 64
+
+#define ESCHER_Persist_PrivateEntry 0x80000000
+#define ESCHER_Persist_Dgg 0x00010000
+#define ESCHER_Persist_Dgg_FIDCL 0x00010001
+#define ESCHER_Persist_Dg 0x00020000
+#define ESCHER_Persist_BlibStoreContainer 0x00030000
+#define ESCHER_Persist_CurrentPosition 0x00040000
+#define ESCHER_Persist_Grouping_Snap 0x00050000
+#define ESCHER_Persist_Grouping_Logic 0x00060000
+
+// ---------------------------------------------------------------------------------------------
+
+namespace com { namespace sun { namespace star {
+ namespace awt {
+ struct Gradient;
+ }
+ namespace drawing {
+ struct EnhancedCustomShapeAdjustmentValue;
+ class XShape;
+ }
+}}}
+
+struct MSFILTER_DLLPUBLIC EscherConnectorListEntry
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mXConnector;
+ ::com::sun::star::awt::Point maPointA;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mXConnectToA;
+ ::com::sun::star::awt::Point maPointB;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mXConnectToB;
+
+ sal_uInt32 GetConnectorRule( sal_Bool bFirst );
+
+ EscherConnectorListEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rC,
+ const ::com::sun::star::awt::Point& rPA,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rSA ,
+ const ::com::sun::star::awt::Point& rPB,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rSB ) :
+ mXConnector ( rC ),
+ maPointA ( rPA ),
+ mXConnectToA( rSA ),
+ maPointB ( rPB ),
+ mXConnectToB( rSB ) {}
+
+ sal_uInt32 GetClosestPoint( const Polygon& rPoly, const ::com::sun::star::awt::Point& rP );
+};
+
+struct MSFILTER_DLLPUBLIC EscherExContainer
+{
+ sal_uInt32 nContPos;
+ SvStream& rStrm;
+
+ EscherExContainer( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance = 0 );
+ ~EscherExContainer();
+};
+struct MSFILTER_DLLPUBLIC EscherExAtom
+{
+ sal_uInt32 nContPos;
+ SvStream& rStrm;
+
+ EscherExAtom( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance = 0, const sal_uInt8 nVersion = 0 );
+ ~EscherExAtom();
+};
+
+struct EscherPropertyValueHelper
+{
+ static sal_Bool GetPropertyValue(
+ ::com::sun::star::uno::Any& rAny,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &,
+ const String& rPropertyName,
+ sal_Bool bTestPropertyAvailability = sal_False );
+
+ static ::com::sun::star::beans::PropertyState GetPropertyState(
+ const ::com::sun::star::uno::Reference < ::com::sun::star::beans::XPropertySet > &,
+ const String& rPropertyName );
+};
+
+// ---------------------------------------------------------------------------------------------
+
+struct EscherPersistEntry
+{
+ UINT32 mnID;
+ UINT32 mnOffset;
+ EscherPersistEntry( UINT32 nId, UINT32 nOffset ) { mnID = nId; mnOffset = nOffset; };
+
+};
+
+// ---------------------------------------------------------------------------------------------
+
+class SvMemoryStream;
+class EscherBlibEntry
+{
+
+ friend class EscherGraphicProvider;
+ friend class EscherEx;
+ friend class _EscherEx;
+
+ protected:
+
+ UINT32 mnIdentifier[ 4 ];
+ UINT32 mnPictureOffset; // offset auf die grafik im PictureStreams
+ UINT32 mnSize; // size of real graphic
+
+ UINT32 mnRefCount; // !! reference count
+ UINT32 mnSizeExtra; // !! size of preceding header
+
+ ESCHER_BlibType meBlibType;
+
+ Size maPrefSize;
+ MapMode maPrefMapMode;
+
+ sal_Bool mbIsEmpty;
+ sal_Bool mbIsNativeGraphicPossible;
+
+ public:
+
+ EscherBlibEntry( sal_uInt32 nPictureOffset, const GraphicObject& rObj,
+ const ByteString& rId, const GraphicAttr* pAttr = NULL );
+
+ ~EscherBlibEntry();
+
+ void WriteBlibEntry( SvStream& rSt, sal_Bool bWritePictureOffset, sal_uInt32 nResize = 0 );
+ sal_Bool IsEmpty() const { return mbIsEmpty; };
+
+ BOOL operator==( const EscherBlibEntry& ) const;
+};
+
+// ---------------------------------------------------------------------------------------------
+
+#define _E_GRAPH_PROV_USE_INSTANCES 1
+#define _E_GRAPH_PROV_DO_NOT_ROTATE_METAFILES 2
+
+class MSFILTER_DLLPUBLIC EscherGraphicProvider
+{
+ sal_uInt32 mnFlags;
+
+ EscherBlibEntry** mpBlibEntrys;
+ sal_uInt32 mnBlibBufSize;
+ sal_uInt32 mnBlibEntrys;
+
+ protected :
+
+ UINT32 ImplInsertBlib( EscherBlibEntry* p_EscherBlibEntry );
+
+ public :
+
+ sal_uInt32 GetBlibStoreContainerSize( SvStream* pMergePicStreamBSE = NULL ) const;
+ void WriteBlibStoreContainer( SvStream& rStrm, SvStream* pMergePicStreamBSE = NULL );
+ sal_Bool WriteBlibStoreEntry(SvStream& rStrm, sal_uInt32 nBlipId,
+ sal_Bool bWritePictureOffset, sal_uInt32 nResize = 0);
+ sal_uInt32 GetBlibID( SvStream& rPicOutStream, const ByteString& rGraphicId, const Rectangle& rBoundRect,
+ const com::sun::star::awt::Rectangle* pVisArea = NULL, const GraphicAttr* pGrafikAttr = NULL );
+ sal_Bool HasGraphics() const { return mnBlibEntrys != 0; };
+
+ void SetNewBlipStreamOffset( sal_Int32 nOffset );
+
+ sal_Bool GetPrefSize( const sal_uInt32 nBlibId, Size& rSize, MapMode& rMapMode );
+
+ EscherGraphicProvider( sal_uInt32 nFlags = _E_GRAPH_PROV_DO_NOT_ROTATE_METAFILES );
+ ~EscherGraphicProvider();
+
+};
+
+class MSFILTER_DLLPUBLIC EscherSolverContainer
+{
+ List maShapeList;
+ List maConnectorList;
+
+public:
+
+ sal_uInt32 GetShapeId( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rShape ) const;
+
+ void AddShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > &, sal_uInt32 nId );
+ void AddConnector( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > &,
+ const ::com::sun::star::awt::Point& rA,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > &,
+ const ::com::sun::star::awt::Point& rB,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConB );
+
+ void WriteSolver( SvStream& );
+
+ EscherSolverContainer(){};
+ ~EscherSolverContainer();
+};
+
+// ---------------------------------------------------------------------------------------------
+
+#define ESCHER_CREATEPOLYGON_LINE 1
+#define ESCHER_CREATEPOLYGON_POLYLINE 2
+#define ESCHER_CREATEPOLYGON_POLYPOLYGON 4
+
+class GraphicAttr;
+class SdrObjCustomShape;
+
+struct EscherPropSortStruct
+{
+ sal_uInt8* pBuf;
+ sal_uInt32 nPropSize;
+ sal_uInt32 nPropValue;
+ sal_uInt16 nPropId;
+};
+
+typedef std::vector< EscherPropSortStruct > EscherProperties;
+
+class MSFILTER_DLLPUBLIC EscherPropertyContainer
+{
+ EscherGraphicProvider* pGraphicProvider;
+ SvStream* pPicOutStrm;
+ Rectangle* pShapeBoundRect;
+
+ EscherPropSortStruct* pSortStruct;
+
+ sal_uInt32 nSortCount;
+ sal_uInt32 nSortBufSize;
+ sal_uInt32 nCountCount;
+ sal_uInt32 nCountSize;
+
+ sal_Bool bHasComplexData;
+ sal_Bool bSuppressRotation;
+
+
+ sal_uInt32 ImplGetColor( const sal_uInt32 rColor, sal_Bool bSwap = sal_True );
+ void ImplCreateGraphicAttributes( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ sal_uInt32 nBlibId, sal_Bool bCreateCroppingAttributes );
+ sal_Bool ImplCreateEmbeddedBmp( const ByteString& rUniqueId );
+ void ImplInit();
+
+ public :
+
+ EscherPropertyContainer();
+ EscherPropertyContainer(
+ EscherGraphicProvider& rGraphicProvider, // the PropertyContainer needs to know
+ SvStream* pPicOutStrm, // the GraphicProvider to be able to write
+ Rectangle& rShapeBoundRect ); // FillBitmaps or GraphicObjects.
+ // under some cirumstances the ShapeBoundRect is adjusted
+ // this will happen when rotated GraphicObjects
+ // are saved to PowerPoint
+ ~EscherPropertyContainer();
+
+ void AddOpt( sal_uInt16 nPropertyID, const rtl::OUString& rString );
+
+ void AddOpt( sal_uInt16 nPropertyID, sal_uInt32 nPropValue,
+ sal_Bool bBlib = sal_False );
+
+ void AddOpt( sal_uInt16 nPropertyID, sal_Bool bBlib, sal_uInt32 nPropValue,
+ sal_uInt8* pProp, sal_uInt32 nPropSize );
+
+ sal_Bool GetOpt( sal_uInt16 nPropertyID, sal_uInt32& rPropValue ) const;
+
+ sal_Bool GetOpt( sal_uInt16 nPropertyID, EscherPropSortStruct& rPropValue ) const;
+
+ EscherProperties GetOpts() const;
+
+ void Commit( SvStream& rSt, sal_uInt16 nVersion = 3, sal_uInt16 nRecType = ESCHER_OPT );
+
+ sal_Bool CreateOLEGraphicProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXOleObject );
+
+ /** Creates a complex ESCHER_Prop_fillBlip containing the BLIP directly (for Excel charts). */
+ sal_Bool CreateEmbeddedBitmapProperties( const ::rtl::OUString& rBitmapUrl,
+ ::com::sun::star::drawing::BitmapMode eBitmapMode );
+ /** Creates a complex ESCHER_Prop_fillBlip containing a hatch style (for Excel charts). */
+ sal_Bool CreateEmbeddedHatchProperties( const ::com::sun::star::drawing::Hatch& rHatch,
+ const Color& rBackColor, bool bFillBackground );
+
+ // the GraphicProperties will only be created if a GraphicProvider and PicOutStrm is known
+ // DR: #99897# if no GraphicProvider is present, a complex ESCHER_Prop_fillBlip
+ // will be created, containing the BLIP directly (e.g. for Excel charts).
+ sal_Bool CreateGraphicProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ const String& rSource, const sal_Bool bCreateFillBitmap, const sal_Bool bCreateCroppingAttributes = sal_False,
+ const sal_Bool bFillBitmapModeAllowed = sal_True );
+
+ sal_Bool CreatePolygonProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ sal_uInt32 nFlags, sal_Bool bBezier, ::com::sun::star::awt::Rectangle& rGeoRect, Polygon* pPolygon = NULL );
+
+ static sal_uInt32 GetGradientColor( const ::com::sun::star::awt::Gradient* pGradient, sal_uInt32 nStartColor );
+
+ void CreateGradientProperties( const ::com::sun::star::awt::Gradient & rGradient );
+ void CreateGradientProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & );
+ void CreateLineProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &, sal_Bool bEdge );
+ void CreateFillProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &, sal_Bool bEdge );
+ void CreateTextProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > &, sal_uInt32 nText,
+ const sal_Bool bIsCustomShape = sal_False, const sal_Bool bIsTextFrame = sal_True );
+
+ sal_Bool CreateConnectorProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape,
+ EscherSolverContainer& rSolver, ::com::sun::star::awt::Rectangle& rGeoRect,
+ sal_uInt16& rShapeType, sal_uInt16& rShapeFlags );
+
+ // Because shadow properties depends to the line and fillstyle, the CreateShadowProperties method should be called at last.
+ // It activ only when at least a FillStyle or LineStyle is set.
+ sal_Bool CreateShadowProperties( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & );
+
+ // creates all necessary CustomShape properties, this includes also Text-, Shadow-, Fill-, and LineProperties
+ void CreateCustomShapeProperties( const MSO_SPT eShapeType, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & );
+ sal_Bool IsFontWork() const;
+
+ // helper functions which are also used by the escher import
+ static PolyPolygon GetPolyPolygon( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape );
+ static PolyPolygon GetPolyPolygon( const ::com::sun::star::uno::Any& rSource );
+ static MSO_SPT GetCustomShapeType( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape, sal_uInt32& nMirrorFlags );
+ static MSO_SPT GetCustomShapeType( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape, sal_uInt32& nMirrorFlags, rtl::OUString& rShapeType );
+
+ // helper functions which are also used in ooxml export
+ static sal_Bool GetLineArrow( const sal_Bool bLineStart,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ ESCHER_LineEnd& reLineEnd, sal_Int32& rnArrowLength, sal_Int32& rnArrowWidth );
+ static sal_Bool IsDefaultObject( SdrObjCustomShape* pCustoShape );
+ static void LookForPolarHandles( const MSO_SPT eShapeType, sal_Int32& nAdjustmentsWhichNeedsToBeConverted );
+ static sal_Bool GetAdjustmentValue( const com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue & rkProp, sal_Int32 nIndex, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, sal_Int32& nValue );
+};
+
+// ---------------------------------------------------------------------------------------------
+
+class MSFILTER_DLLPUBLIC EscherPersistTable
+{
+
+ public:
+ List maPersistTable;
+
+ BOOL PtIsID( UINT32 nID );
+ void PtInsert( UINT32 nID, UINT32 nOfs );
+ UINT32 PtDelete( UINT32 nID );
+ UINT32 PtGetOffsetByID( UINT32 nID );
+ UINT32 PtReplace( UINT32 nID, UINT32 nOfs );
+ UINT32 PtReplaceOrInsert( UINT32 nID, UINT32 nOfs );
+ UINT32 PtGetCount() const { return maPersistTable.Count(); };
+
+ EscherPersistTable();
+ virtual ~EscherPersistTable();
+};
+
+// ---------------------------------------------------------------------------------------------
+
+class EscherEx;
+
+/// abstract base class for ESCHER_ClientTextbox, ESCHER_ClientData
+class MSFILTER_DLLPUBLIC EscherExClientRecord_Base
+{
+public:
+ EscherExClientRecord_Base() {}
+ virtual ~EscherExClientRecord_Base();
+
+ /// Application writes the record header
+ /// using rEx.AddAtom(...) followed by
+ /// record data written to rEx.GetStream()
+ virtual void WriteData( EscherEx& rEx ) const = 0;
+};
+
+
+/// abstract base class for ESCHER_ClientAnchor
+class MSFILTER_DLLPUBLIC EscherExClientAnchor_Base
+{
+public:
+ EscherExClientAnchor_Base() {}
+ virtual ~EscherExClientAnchor_Base();
+
+ /// Application writes the record header
+ /// using rEx.AddAtom(...) followed by
+ /// record data written to rEx.GetStream()
+ virtual void WriteData( EscherEx& rEx,
+ const Rectangle& rRect ) = 0;
+};
+
+
+class EscherExHostAppData
+{
+private:
+ EscherExClientAnchor_Base* pClientAnchor;
+ EscherExClientRecord_Base* pClientData;
+ EscherExClientRecord_Base* pClientTextbox;
+ // ignore single shape if entire pages are written
+ BOOL bDontWriteShape;
+
+public:
+ EscherExHostAppData() : pClientAnchor(0), pClientData(0),
+ pClientTextbox(0), bDontWriteShape(FALSE)
+ {}
+
+ void SetClientAnchor( EscherExClientAnchor_Base* p )
+ { pClientAnchor = p; }
+ void SetClientData( EscherExClientRecord_Base* p )
+ { pClientData = p; }
+ void SetClientTextbox( EscherExClientRecord_Base* p )
+ { pClientTextbox = p; }
+ void SetDontWriteShape( BOOL b )
+ { bDontWriteShape = b; }
+ EscherExClientAnchor_Base* GetClientAnchor() const
+ { return pClientAnchor; }
+ EscherExClientRecord_Base* GetClientData() const
+ { return pClientData; }
+ EscherExClientRecord_Base* GetClientTextbox() const
+ { return pClientTextbox; }
+
+ void WriteClientAnchor( EscherEx& rEx, const Rectangle& rRect )
+ { if( pClientAnchor ) pClientAnchor->WriteData( rEx, rRect ); }
+ void WriteClientData( EscherEx& rEx )
+ { if( pClientData ) pClientData->WriteData( rEx ); }
+ void WriteClientTextbox( EscherEx& rEx )
+ { if( pClientTextbox ) pClientTextbox->WriteData( rEx ); }
+
+ BOOL DontWriteShape() const { return bDontWriteShape; }
+};
+
+
+// ---------------------------------------------------------------------------------------------
+
+class SdrObject;
+class SdrPage;
+class ImplEscherExSdr;
+class Color;
+
+class Graphic;
+class SvMemoryStream;
+class SvStream;
+
+class MSFILTER_DLLPUBLIC EscherEx : public EscherPersistTable, public EscherGraphicProvider
+{
+ protected :
+
+ SvStream* mpOutStrm;
+ ImplEscherExSdr* mpImplEscherExSdr;
+ UINT32 mnStrmStartOfs;
+ std::vector< sal_uInt32 > mOffsets;
+ std::vector< sal_uInt16 > mRecTypes;
+
+ UINT32 mnDrawings;
+ UINT32 mnFIDCLs; // anzahl der cluster ID's
+
+ UINT32 mnCurrentDg;
+ UINT32 mnCurrentShapeID; // die naechste freie ID
+ UINT32 mnCurrentShapeMaximumID; // die hoechste und auch benutzte ID
+ UINT32 mnTotalShapesDg; // anzahl der shapes im Dg
+ UINT32 mnTotalShapeIdUsedDg; // anzahl der benutzten shape Id's im Dg
+ UINT32 mnTotalShapesDgg; // anzahl der shapes im Dgg
+ UINT32 mnCountOfs;
+
+ UINT32 mnGroupLevel;
+ UINT16 mnHellLayerId;
+
+ BOOL mbEscherSpgr;
+ BOOL mbEscherDgg;
+ BOOL mbEscherDg;
+ BOOL mbOleEmf; // OLE is EMF instead of WMF
+
+
+ virtual BOOL DoSeek( UINT32 nKey );
+
+ public:
+
+ EscherEx( SvStream& rOut, UINT32 nDrawings );
+
+ /// Fuegt in den EscherStream interne Daten ein, dieser Vorgang
+ /// darf und muss nur einmal ausgefuehrt werden.
+ /// Wenn pPicStreamMergeBSE angegeben ist, werden die BLIPs
+ /// aus diesem Stream in die MsofbtBSE Records des EscherStream
+ /// gemerged, wie es fuer Excel (und Word?) benoetigt wird.
+ virtual void Flush( SvStream* pPicStreamMergeBSE = NULL );
+
+ virtual ~EscherEx();
+
+ // Application may overload this function to maintain an offset
+ // table for specific regions but MUST call this function too.
+ virtual void InsertAtCurrentPos( UINT32 nBytes, BOOL bCont = FALSE );// es werden nBytes an der aktuellen Stream Position eingefuegt,
+ // die PersistantTable und interne Zeiger angepasst
+
+ void InsertPersistOffset( UINT32 nKey, UINT32 nOffset ); // Es wird nicht geprueft, ob sich jener schluessel schon in der PersistantTable befindet
+ BOOL SeekToPersistOffset( UINT32 nKey );
+ virtual BOOL InsertAtPersistOffset( UINT32 nKey, UINT32 nValue );// nValue wird im Stream an entrsprechender Stelle eingefuegt(overwrite modus), ohne dass sich die
+ // aktuelle StreamPosition aendert
+
+ SvStream& GetStream() const { return *mpOutStrm; }
+ ULONG GetStreamPos() const { return mpOutStrm->Tell(); }
+
+ virtual BOOL SeekBehindRecHeader( UINT16 nRecType ); // der stream muss vor einem gueltigen Record Header oder Atom stehen
+
+ // features beim erzeugen folgender Container:
+ //
+ // ESCHER_DggContainer: ein EscherDgg Atom wird automatisch erzeugt und verwaltet
+ // ESCHER_DgContainer: ein EscherDg Atom wird automatisch erzeugt und verwaltet
+ // ESCHER_SpgrContainer:
+ // ESCHER_SpContainer:
+
+ virtual void OpenContainer( UINT16 nEscherContainer, int nRecInstance = 0 );
+ virtual void CloseContainer();
+
+ virtual void BeginAtom();
+ virtual void EndAtom( UINT16 nRecType, int nRecVersion = 0, int nRecInstance = 0 );
+ virtual void AddAtom( UINT32 nAtomSitze, UINT16 nRecType, int nRecVersion = 0, int nRecInstance = 0 );
+ virtual void AddChildAnchor( const Rectangle& rRectangle );
+ virtual void AddClientAnchor( const Rectangle& rRectangle );
+
+ virtual UINT32 EnterGroup( const String& rShapeName, const Rectangle* pBoundRect = 0 );
+ UINT32 EnterGroup( const Rectangle* pBoundRect = NULL );
+ UINT32 GetGroupLevel() const { return mnGroupLevel; };
+ virtual BOOL SetGroupSnapRect( UINT32 nGroupLevel, const Rectangle& rRect );
+ virtual BOOL SetGroupLogicRect( UINT32 nGroupLevel, const Rectangle& rRect );
+ virtual void LeaveGroup();
+
+ // ein ESCHER_Sp wird geschrieben ( Ein ESCHER_DgContainer muss dazu geoeffnet sein !!)
+ virtual void AddShape( UINT32 nShpInstance, UINT32 nFlagIds, UINT32 nShapeID = 0 );
+ // reserviert eine ShapeId
+ UINT32 GetShapeID();
+
+ virtual void Commit( EscherPropertyContainer& rProps, const Rectangle& rRect );
+
+ UINT32 GetColor( const UINT32 nColor, BOOL bSwap = TRUE );
+ UINT32 GetColor( const Color& rColor, BOOL bSwap = TRUE );
+
+ // OLE is written as EMF instead of WMF (default WMF)
+ void SetOleEmf( BOOL bVal ) { mbOleEmf = bVal; }
+ BOOL IsOleEmf() const { return mbOleEmf; }
+
+ // ...Sdr... implemented in eschesdo.cxx
+
+ void AddSdrPage( const SdrPage& rPage );
+
+ /// returns the ShapeID
+ UINT32 AddSdrObject( const SdrObject& rObj );
+
+ /// If objects are written through AddSdrObject the
+ /// SolverContainer has to be written, and maybe some
+ /// maintenance to be done.
+ void EndSdrObjectPage();
+
+ /// Called before a shape is written, application supplies
+ /// ClientRecords. May set AppData::bDontWriteShape so the
+ /// shape is ignored.
+ virtual EscherExHostAppData* StartShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rShape );
+
+ /// Called after a shape is written to inform the application
+ /// of the resulted shape type and ID.
+ virtual void EndShape( UINT16 nShapeType, UINT32 nShapeID );
+
+ /// Called before an AdditionalText EnterGroup occurs.
+ /// The current shape will be written in three parts:
+ /// a group shape, the shape itself, and an extra textbox shape.
+ /// The complete flow is:
+ /// StartShape sets HostData1.
+ /// EnterAdditionalTextGroup sets HostData2, App may modify
+ /// HostData1 and keep track of the change.
+ /// The group shape is written with HostData2.
+ /// Another StartShape with the same (!) object sets HostData3.
+ /// The current shape is written with HostData3.
+ /// EndShape is called for the current shape.
+ /// Another StartShape with the same (!) object sets HostData4.
+ /// The textbox shape is written with HostData4.
+ /// EndShape is called for the textbox shape.
+ /// EndShape is called for the group shape, this provides
+ /// the same functionality as an ordinary recursive group.
+ virtual EscherExHostAppData* EnterAdditionalTextGroup();
+
+ /// Called if a picture shall be written and no PicStream is
+ /// set at ImplEscherExSdr
+ virtual SvStream* QueryPicStream();
+
+ /// Called if an ESCHER_Prop_lTxid shall be written
+ virtual UINT32 QueryTextID( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >&, UINT32 nShapeId );
+ // add an dummy rectangle shape into the escher stream
+ UINT32 AddDummyShape();
+
+ static const SdrObject* GetSdrObject( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rXShape );
+
+ void SetHellLayerId( UINT16 nId ) { mnHellLayerId = nId; }
+ UINT16 GetHellLayerId() const { return mnHellLayerId; }
+};
+
+
+#endif
diff --git a/filter/inc/filter/msfilter/mscodec.hxx b/filter/inc/filter/msfilter/mscodec.hxx
new file mode 100644
index 000000000000..a42e360d0f96
--- /dev/null
+++ b/filter/inc/filter/msfilter/mscodec.hxx
@@ -0,0 +1,343 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mscodec.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * 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 SVX_MSCODEC_HXX
+#define SVX_MSCODEC_HXX
+
+#include "rtl/cipher.h"
+#include "rtl/digest.h"
+#include "filter/msfilter/msfilterdllapi.h"
+
+namespace msfilter {
+
+// ============================================================================
+
+/** Encodes and decodes data from protected MSO 95- documents.
+ */
+class MSFILTER_DLLPUBLIC MSCodec_Xor95
+{
+public:
+ explicit MSCodec_Xor95(int nRotateDistance);
+ virtual ~MSCodec_Xor95();
+
+ /** Initializes the algorithm with the specified password.
+
+ @param pPassData
+ Character array containing the password. Must be zero terminated,
+ which results in a maximum length of 15 characters.
+ */
+ void InitKey( const sal_uInt8 pnPassData[ 16 ] );
+
+ /** Verifies the validity of the password using the passed key and hash.
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param nKey
+ Password key value read from the file.
+ @param nHash
+ Password hash value read from the file.
+
+ @return
+ true = Test was successful.
+ */
+ bool VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const;
+
+ /** Reinitializes the codec to start a new memory block.
+
+ Resets the internal key offset to 0.
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+ */
+ void InitCipher();
+
+ /** Decodes a block of memory inplace.
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param pnData
+ Encrypted data block. Will contain the decrypted data afterwards.
+ @param nBytes
+ Size of the passed data block.
+ */
+ virtual void Decode( sal_uInt8* pnData, sal_Size nBytes )=0;
+
+ /** Lets the cipher skip a specific amount of bytes.
+
+ This function sets the cipher to the same state as if the specified
+ amount of data has been decoded with one or more calls of Decode().
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param nBytes
+ Number of bytes to be skipped (cipher "seeks" forward).
+ */
+ void Skip( sal_Size nBytes );
+
+ // static -----------------------------------------------------------------
+
+ /** Calculates the 16-bit hash value for the given password.
+
+ The password data may be longer than 16 bytes. The array does not need
+ to be terminated with a NULL byte (but it can without invalidating the
+ result).
+ */
+ static sal_uInt16 GetHash( const sal_uInt8* pnPassData, sal_Size nSize );
+
+protected:
+ sal_uInt8 mpnKey[ 16 ]; /// Encryption key.
+ sal_Size mnOffset; /// Key offset.
+
+private:
+ MSFILTER_DLLPRIVATE MSCodec_Xor95( const MSCodec_Xor95& );
+ MSFILTER_DLLPRIVATE MSCodec_Xor95& operator=( const MSCodec_Xor95& );
+
+ sal_uInt16 mnKey; /// Base key from password.
+ sal_uInt16 mnHash; /// Hash value from password.
+ int mnRotateDistance;
+};
+
+/** Encodes and decodes data from protected MSO XLS 95- documents.
+ */
+class MSFILTER_DLLPUBLIC MSCodec_XorXLS95 : public MSCodec_Xor95
+{
+public:
+ explicit MSCodec_XorXLS95() : MSCodec_Xor95(2) {}
+
+ /** Decodes a block of memory inplace.
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param pnData
+ Encrypted data block. Will contain the decrypted data afterwards.
+ @param nBytes
+ Size of the passed data block.
+ */
+ virtual void Decode( sal_uInt8* pnData, sal_Size nBytes );
+};
+
+/** Encodes and decodes data from protected MSO Word 95- documents.
+ */
+class MSFILTER_DLLPUBLIC MSCodec_XorWord95 : public MSCodec_Xor95
+{
+public:
+ explicit MSCodec_XorWord95() : MSCodec_Xor95(7) {}
+
+ /** Decodes a block of memory inplace.
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param pnData
+ Encrypted data block. Will contain the decrypted data afterwards.
+ @param nBytes
+ Size of the passed data block.
+ */
+ virtual void Decode( sal_uInt8* pnData, sal_Size nBytes );
+};
+
+
+// ============================================================================
+
+/** Encodes and decodes data from protected MSO 97+ documents.
+
+ This is a wrapper class around low level cryptographic functions from RTL.
+ Implementation is based on the wvDecrypt package by Caolan McNamara:
+ http://www.csn.ul.ie/~caolan/docs/wvDecrypt.html
+ */
+class MSFILTER_DLLPUBLIC MSCodec_Std97
+{
+public:
+ explicit MSCodec_Std97();
+ ~MSCodec_Std97();
+
+ /** Initializes the algorithm with the specified password and document ID.
+
+ @param pPassData
+ Wide character array containing the password. Must be zero
+ terminated, which results in a maximum length of 15 characters.
+ @param pUnique
+ Unique document identifier read from or written to the file.
+ */
+ void InitKey(
+ const sal_uInt16 pPassData[ 16 ],
+ const sal_uInt8 pUnique[ 16 ] );
+
+ /** Verifies the validity of the password using the passed salt data.
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param pSaltData
+ Salt data block read from the file.
+ @param pSaltDigest
+ Salt digest read from the file.
+
+ @return
+ true = Test was successful.
+ */
+ bool VerifyKey(
+ const sal_uInt8 pSaltData[ 16 ],
+ const sal_uInt8 pSaltDigest[ 16 ] );
+
+ /** Rekeys the codec using the specified counter.
+
+ After reading a specific amount of data the cipher algorithm needs to
+ be rekeyed using a counter that counts the data blocks.
+
+ The block size is for example 512 Bytes for Word files and 1024 Bytes
+ for Excel files.
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param nCounter
+ Block counter used to rekey the cipher.
+ */
+ bool InitCipher( sal_uInt32 nCounter );
+
+ /** Creates an MD5 digest of salt digest. */
+ bool CreateSaltDigest(
+ const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] );
+
+ /** Encodes a block of memory.
+
+ @see rtl_cipher_encode()
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used. The destination buffer must be able to take all
+ unencoded data from the source buffer (usually this means it must be
+ as long as or longer than the source buffer).
+
+ @param pData
+ Unencrypted source data block.
+ @param nDatLen
+ Size of the passed source data block.
+ @param pBuffer
+ Destination buffer for the encrypted data.
+ @param nBufLen
+ Size of the destination buffer.
+
+ @return
+ true = Encoding was successful (no error occured).
+ */
+ bool Encode(
+ const void* pData, sal_Size nDatLen,
+ sal_uInt8* pBuffer, sal_Size nBufLen );
+
+ /** Decodes a block of memory.
+
+ @see rtl_cipher_decode()
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used. The destination buffer must be able to take all
+ encoded data from the source buffer (usually this means it must be
+ as long as or longer than the source buffer).
+
+ @param pData
+ Encrypted source data block.
+ @param nDatLen
+ Size of the passed source data block.
+ @param pBuffer
+ Destination buffer for the decrypted data.
+ @param nBufLen
+ Size of the destination buffer.
+
+ @return
+ true = Decoding was successful (no error occured).
+ */
+ bool Decode(
+ const void* pData, sal_Size nDatLen,
+ sal_uInt8* pBuffer, sal_Size nBufLen );
+
+ /** Lets the cipher skip a specific amount of bytes.
+
+ This function sets the cipher to the same state as if the specified
+ amount of data has been decoded with one or more calls of Decode().
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param nDatLen
+ Number of bytes to be skipped (cipher "seeks" forward).
+ */
+ bool Skip( sal_Size nDatLen );
+
+ /** Gets salt data and salt digest.
+
+ @precond
+ The codec must be initialized with InitKey() before this function
+ can be used.
+
+ @param pSalt
+ Salt, a random number.
+ @param pSaltData
+ Salt data block generated from the salt.
+ @param pSaltDigest
+ Salt digest generated from the salt.
+ */
+ void GetEncryptKey (
+ const sal_uInt8 pSalt[16],
+ sal_uInt8 pSaltData[16],
+ sal_uInt8 pSaltDigest[16]);
+
+private:
+ void GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] );
+
+private:
+ MSFILTER_DLLPRIVATE MSCodec_Std97( const MSCodec_Std97& );
+ MSFILTER_DLLPRIVATE MSCodec_Std97& operator=( const MSCodec_Std97& );
+
+ rtlCipher m_hCipher;
+ rtlDigest m_hDigest;
+ sal_uInt8 m_pDigestValue[ RTL_DIGEST_LENGTH_MD5 ];
+};
+
+// ============================================================================
+
+} // namespace msfilter
+
+#endif
+
diff --git a/filter/inc/filter/msfilter/msdffimp.hxx b/filter/inc/filter/msfilter/msdffimp.hxx
new file mode 100644
index 000000000000..eadb6328b1de
--- /dev/null
+++ b/filter/inc/filter/msfilter/msdffimp.hxx
@@ -0,0 +1,864 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msdffimp.hxx,v $
+ * $Revision: 1.4.214.1 $
+ *
+ * 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 _MSDFFIMP_HXX
+#define _MSDFFIMP_HXX
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <tools/solar.h> // UINTXX
+#include <svl/svarray.hxx>
+#include <tools/color.hxx>
+#include <tools/gen.hxx>
+#include <tools/table.hxx>
+#include <svx/msdffdef.hxx>
+#include <filter/msfilter/msfiltertracer.hxx>
+#include <vcl/graph.hxx>
+#include <string.h>
+#include <map>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <filter/msfilter/msfilterdllapi.h>
+#include <sot/storage.hxx>
+
+class Graphic;
+class SvStream;
+class SdrObject;
+class SdrOle2Obj;
+class SotStorageRef;
+class Polygon;
+class PolyPolygon;
+class FmFormModel;
+class SdrModel;
+class DffRecordHeader;
+
+class SwFlyFrmFmt;
+
+struct SvxMSDffBLIPInfo;
+struct SvxMSDffShapeInfo;
+struct SvxMSDffShapeOrder;
+
+class MSFILTER_DLLPUBLIC DffRecordHeader
+{
+
+public:
+ BYTE nRecVer; // may be DFF_PSFLAG_CONTAINER
+ UINT16 nRecInstance;
+ UINT16 nImpVerInst;
+ UINT16 nRecType;
+ UINT32 nRecLen;
+ ULONG nFilePos;
+public:
+ DffRecordHeader() : nRecVer(0), nRecInstance(0), nImpVerInst(0), nRecType(0), nRecLen(0), nFilePos(0) {}
+ FASTBOOL IsContainer() const { return nRecVer == DFF_PSFLAG_CONTAINER; }
+ ULONG GetRecBegFilePos() const { return nFilePos; }
+ ULONG GetRecEndFilePos() const { return nFilePos + DFF_COMMON_RECORD_HEADER_SIZE + nRecLen; }
+ void SeekToEndOfRecord(SvStream& rIn) const { rIn.Seek(nFilePos + DFF_COMMON_RECORD_HEADER_SIZE + nRecLen ); }
+ void SeekToContent( SvStream& rIn) const { rIn.Seek(nFilePos + DFF_COMMON_RECORD_HEADER_SIZE ); }
+ void SeekToBegOfRecord(SvStream& rIn) const { rIn.Seek( nFilePos ); }
+
+ MSFILTER_DLLPUBLIC friend SvStream& operator>>(SvStream& rIn, DffRecordHeader& rRec);
+
+};
+
+struct DffPropFlags
+{
+ BYTE bSet : 1;
+ BYTE bComplex : 1;
+ BYTE bBlip : 1;
+ BYTE bSoftAttr : 1;
+};
+
+class SvxMSDffManager;
+
+class MSFILTER_DLLPUBLIC DffPropSet : public Table
+{
+ protected :
+
+ UINT32 mpContents[ 1024 ];
+ DffPropFlags mpFlags[ 1024 ];
+
+ public :
+
+ DffPropSet( BOOL bInitialize = FALSE ){ if ( bInitialize )
+ memset( mpFlags, 0, 0x400 * sizeof( DffPropFlags ) ); };
+
+ inline BOOL IsProperty( UINT32 nRecType ) const { return ( mpFlags[ nRecType & 0x3ff ].bSet ); };
+ BOOL IsHardAttribute( UINT32 nId ) const;
+ UINT32 GetPropertyValue( UINT32 nId, UINT32 nDefault = 0 ) const;
+ /** Returns a boolean property by its real identifier. */
+ bool GetPropertyBool( UINT32 nId, bool bDefault = false ) const;
+ /** Returns a string property. */
+ ::rtl::OUString GetPropertyString( UINT32 nId, SvStream& rStrm ) const;
+ void SetPropertyValue( UINT32 nId, UINT32 nValue ) const;
+ BOOL SeekToContent( UINT32 nRecType, SvStream& rSt ) const;
+ void Merge( DffPropSet& rMasterPropSet ) const;
+ void InitializePropSet() const;
+ friend SvStream& operator>>( SvStream& rIn, DffPropSet& rPropSet );
+};
+
+class SfxItemSet;
+class SdrObject;
+struct DffObjData;
+
+class MSFILTER_DLLPUBLIC DffPropertyReader : public DffPropSet
+{
+ const SvxMSDffManager& rManager;
+ DffPropSet* pDefaultPropSet;
+
+ void ApplyCustomShapeTextAttributes( SfxItemSet& rSet ) const;
+ void ApplyCustomShapeAdjustmentAttributes( SfxItemSet& rSet ) const;
+ void ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const;
+ void ApplyLineAttributes( SfxItemSet& rSet, const MSO_SPT eShapeType ) const; // #i28269#
+ void ApplyFillAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const;
+
+public:
+
+ INT32 mnFix16Angle;
+
+ DffPropertyReader( const SvxMSDffManager& rManager );
+ ~DffPropertyReader();
+ INT32 Fix16ToAngle( INT32 nAngle ) const;
+
+#ifdef DBG_CUSTOMSHAPE
+ void ReadPropSet( SvStream& rIn, void* pClientData, UINT32 nShapeType = 0 ) const;
+#else
+ void ReadPropSet( SvStream& rIn, void* pClientData ) const;
+#endif
+
+ void SetDefaultPropSet( SvStream& rIn, UINT32 nOffDgg ) const;
+ void ApplyAttributes( SvStream& rIn, SfxItemSet& rSet ) const;
+ void ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const;
+};
+
+
+#define COL_DEFAULT RGB_COLORDATA( 0xFA, 0xFB, 0xFC )
+
+typedef SvxMSDffBLIPInfo* SvxMSDffBLIPInfo_Ptr;
+
+typedef SvxMSDffShapeInfo* SvxMSDffShapeInfo_Ptr;
+
+typedef SvxMSDffShapeOrder* SvxMSDffShapeOrder_Ptr;
+
+typedef ::std::map< sal_Int32, SdrObject* > SvxMSDffShapeIdContainer;
+
+#define SVEXT_PERSIST_STREAM "\002OlePres000"
+
+// nach der Reihenfolge des Auftretens sortiert werden:
+//
+SV_DECL_PTRARR_DEL(SvxMSDffBLIPInfos, SvxMSDffBLIPInfo_Ptr, 16,16)
+
+SV_DECL_PTRARR_DEL(SvxMSDffShapeOrders, SvxMSDffShapeOrder_Ptr, 16,16)
+
+// explizit sortiert werden:
+//
+SV_DECL_PTRARR_SORT_DEL_VISIBILITY(SvxMSDffShapeInfos, SvxMSDffShapeInfo_Ptr, 16,16, MSFILTER_DLLPUBLIC)
+
+SV_DECL_PTRARR_SORT_VISIBILITY(SvxMSDffShapeTxBxSort, SvxMSDffShapeOrder_Ptr, 16,16, MSFILTER_DLLPUBLIC)
+
+#define SVXMSDFF_SETTINGS_CROP_BITMAPS 1
+#define SVXMSDFF_SETTINGS_IMPORT_PPT 2
+#define SVXMSDFF_SETTINGS_IMPORT_EXCEL 4
+
+#define SP_FGROUP 0x001 // This shape is a group shape
+#define SP_FCHILD 0x002 // Not a top-level shape
+#define SP_FPATRIARCH 0x004 // This is the topmost group shape.
+ // Exactly one of these per drawing.
+#define SP_FDELETED 0x008 // The shape has been deleted
+#define SP_FOLESHAPE 0x010 // The shape is an OLE object
+#define SP_FHAVEMASTER 0x020 // Shape has a hspMaster property
+#define SP_FFLIPH 0x040 // Shape is flipped horizontally
+#define SP_FFLIPV 0x080 // Shape is flipped vertically
+#define SP_FCONNECTOR 0x100 // Connector type of shape
+#define SP_FHAVEANCHOR 0x200 // Shape has an anchor of some kind
+#define SP_FBACKGROUND 0x400 // Background shape
+#define SP_FHAVESPT 0x800 // Shape has a shape type property
+
+// for the CreateSdrOLEFromStorage we need the information, how we handle
+// convert able OLE-Objects - this ist stored in
+#define OLE_MATHTYPE_2_STARMATH 0x0001
+#define OLE_WINWORD_2_STARWRITER 0x0002
+#define OLE_EXCEL_2_STARCALC 0x0004
+#define OLE_POWERPOINT_2_STARIMPRESS 0x0008
+
+struct SvxMSDffConnectorRule
+{
+ sal_uInt32 nRuleId;
+ sal_uInt32 nShapeA; // SPID of shape A
+
+ sal_uInt32 nShapeB; // SPID of shape B
+ sal_uInt32 nShapeC; // SPID of connector shape
+ sal_uInt32 ncptiA; // Connection site Index of shape A
+ sal_uInt32 ncptiB; // Connection site Index of shape B
+ sal_uInt32 nSpFlagsA; // SpFlags of shape A ( the original mirror flags must be known when solving the Solver Container )
+ sal_uInt32 nSpFlagsB; // SpFlags of shape A
+
+ SdrObject* pAObj; // pPtr of object ( corresponding to shape A )
+ SdrObject* pBObj; // "
+ SdrObject* pCObj; // " of connector object
+
+ SvxMSDffConnectorRule() : nSpFlagsA( 0 ), nSpFlagsB( 0 ), pAObj( NULL ), pBObj( NULL ), pCObj( NULL ) {};
+
+ friend SvStream& operator>>( SvStream& rIn, SvxMSDffConnectorRule& rAtom );
+};
+struct MSFILTER_DLLPUBLIC SvxMSDffSolverContainer
+{
+ List aCList;
+
+ SvxMSDffSolverContainer();
+ ~SvxMSDffSolverContainer();
+
+ MSFILTER_DLLPUBLIC friend SvStream& operator>>( SvStream& rIn, SvxMSDffSolverContainer& rAtom );
+};
+
+struct FIDCL
+{
+ UINT32 dgid; // DG owning the SPIDs in this cluster
+ UINT32 cspidCur; // number of SPIDs used so far
+};
+
+//---------------------------------------------------------------------------
+// von SvxMSDffManager fuer jedes in der Gruppe enthaltene Shape geliefert
+//---------------------------------------------------------------------------
+struct MSDffTxId
+{
+ USHORT nTxBxS;
+ USHORT nSequence;
+ MSDffTxId(USHORT nTxBxS_, USHORT nSequence_ )
+ : nTxBxS( nTxBxS_ ),
+ nSequence( nSequence_ ){}
+ MSDffTxId(const MSDffTxId& rCopy)
+ : nTxBxS( rCopy.nTxBxS ),
+ nSequence( rCopy.nSequence ){}
+};
+
+struct MSFILTER_DLLPUBLIC SvxMSDffImportRec
+{
+ SdrObject* pObj;
+ Polygon* pWrapPolygon;
+ char* pClientAnchorBuffer;
+ UINT32 nClientAnchorLen;
+ char* pClientDataBuffer;
+ UINT32 nClientDataLen;
+ UINT32 nXAlign;
+ UINT32 nXRelTo;
+ UINT32 nYAlign;
+ UINT32 nYRelTo;
+ UINT32 nLayoutInTableCell;
+ UINT32 nFlags;
+ long nTextRotationAngle;
+ long nDxTextLeft; // Abstand der Textbox vom umgebenden Shape
+ long nDyTextTop;
+ long nDxTextRight;
+ long nDyTextBottom;
+ long nDxWrapDistLeft;
+ long nDyWrapDistTop;
+ long nDxWrapDistRight;
+ long nDyWrapDistBottom;
+ long nCropFromTop;
+ long nCropFromBottom;
+ long nCropFromLeft;
+ long nCropFromRight;
+ MSDffTxId aTextId; // Kennungen fuer Textboxen
+ ULONG nNextShapeId; // fuer verlinkte Textboxen
+ ULONG nShapeId;
+ MSO_SPT eShapeType;
+ MSO_LineStyle eLineStyle; // Umrandungs-Arten
+ BOOL bDrawHell :1;
+ BOOL bHidden :1;
+ BOOL bReplaceByFly :1;
+ BOOL bLastBoxInChain :1;
+ BOOL bHasUDefProp :1;
+ BOOL bVFlip :1;
+ BOOL bHFlip :1;
+ BOOL bAutoWidth :1;
+
+ SvxMSDffImportRec();
+ SvxMSDffImportRec(const SvxMSDffImportRec& rCopy);
+ ~SvxMSDffImportRec();
+ BOOL operator==( const SvxMSDffImportRec& rEntry ) const
+ { return nShapeId == rEntry.nShapeId; }
+ BOOL operator<( const SvxMSDffImportRec& rEntry ) const
+ { return nShapeId < rEntry.nShapeId; }
+};
+typedef SvxMSDffImportRec* MSDffImportRec_Ptr;
+
+// Liste aller SvxMSDffImportRec fuer eine Gruppe
+SV_DECL_PTRARR_SORT_DEL_VISIBILITY(MSDffImportRecords, MSDffImportRec_Ptr, 16,16, MSFILTER_DLLPUBLIC)
+
+//---------------------------------------------------------------------------
+// Import-/Export-Parameterblock fuer 1 x ImportObjAtCurrentStreamPos()
+//---------------------------------------------------------------------------
+struct SvxMSDffImportData
+{
+ MSDffImportRecords aRecords; // Shape-Pointer, -Ids und private Daten
+ Rectangle aParentRect;// Rectangle der umgebenden Gruppe
+ // bzw. von aussen reingegebenes Rect
+ Rectangle aNewRect; // mit diesem Shape definiertes Rectangle
+
+ SvxMSDffImportData()
+ {}
+ SvxMSDffImportData(const Rectangle& rParentRect)
+ :aParentRect( rParentRect )
+ {}
+ void SetNewRect(INT32 l, INT32 o,
+ INT32 r, INT32 u ){ aNewRect = Rectangle(l,o, r,u); }
+ BOOL HasParRect() const { return aParentRect.IsEmpty(); }
+ BOOL HasNewRect() const { return aNewRect.IsEmpty() ; }
+ BOOL HasRecords() const { return 0 != aRecords.Count(); }
+ USHORT GetRecCount() const { return aRecords.Count(); }
+ SvxMSDffImportRec* GetRecord(USHORT iRecord) const
+ { return aRecords.GetObject( iRecord ); }
+};
+
+struct DffObjData
+{
+ const DffRecordHeader& rSpHd;
+
+ Rectangle aBoundRect;
+ Rectangle aChildAnchor;
+
+ UINT32 nShapeId;
+ UINT32 nSpFlags;
+ MSO_SPT eShapeType;
+
+ BOOL bShapeType : 1;
+ BOOL bClientAnchor : 1;
+ BOOL bClientData : 1;
+ BOOL bChildAnchor : 1;
+ BOOL bOpt : 1;
+ BOOL bIsAutoText : 1;
+
+ int nCalledByGroup;
+
+ DffObjData( const DffRecordHeader& rObjHd,
+ const Rectangle& rBoundRect,
+ int nClByGroup ) :
+ rSpHd( rObjHd ),
+ aBoundRect( rBoundRect ),
+ nShapeId( 0 ),
+ nSpFlags( 0 ),
+ eShapeType( mso_sptNil ),
+ bShapeType( FALSE ),
+ bClientAnchor( FALSE ),
+ bClientData( FALSE ),
+ bChildAnchor( FALSE ),
+ bOpt( FALSE ),
+ bIsAutoText( FALSE ),
+ nCalledByGroup( nClByGroup ){}
+};
+
+#define DFF_RECORD_MANAGER_BUF_SIZE 64
+
+struct DffRecordList
+{
+ UINT32 nCount;
+ UINT32 nCurrent;
+ DffRecordList* pPrev;
+ DffRecordList* pNext;
+
+ DffRecordHeader mHd[ DFF_RECORD_MANAGER_BUF_SIZE ];
+
+ DffRecordList( DffRecordList* pList );
+ ~DffRecordList();
+};
+
+enum DffSeekToContentMode
+{
+ SEEK_FROM_BEGINNING,
+ SEEK_FROM_CURRENT,
+ SEEK_FROM_CURRENT_AND_RESTART
+};
+
+class MSFILTER_DLLPUBLIC DffRecordManager : public DffRecordList
+{
+ public :
+
+ DffRecordList* pCList;
+
+ void Clear();
+ void Consume( SvStream& rIn, BOOL bAppend = FALSE, UINT32 nStOfs = 0 );
+
+ BOOL SeekToContent( SvStream& rIn, UINT16 nRecType, DffSeekToContentMode eMode = SEEK_FROM_BEGINNING );
+ DffRecordHeader* GetRecordHeader( UINT16 nRecType, DffSeekToContentMode eMode = SEEK_FROM_BEGINNING );
+
+ DffRecordManager();
+ DffRecordManager( SvStream& rIn );
+ ~DffRecordManager();
+
+ DffRecordHeader* Current();
+ DffRecordHeader* First();
+ DffRecordHeader* Next();
+ DffRecordHeader* Prev();
+ DffRecordHeader* Last();
+};
+
+/*
+ SvxMSDffManager - abstrakte Basis-Klasse fuer Escher-Import
+ ===============
+ Zweck: Zugriff auf Objekte im Drawing File Format
+ Stand: Zugriff nur auf BLIPs (wird spaeter erweitert)
+
+ Beachte: in der zwecks PowerPoint-, ODER Word- ODER Excel-Import
+ ======== abgeleiteten Klasse
+ MUSS jeweils die Methode ProcessUserDefinedRecord()
+ implementiert werden!
+*/
+class MSFILTER_DLLPUBLIC SvxMSDffManager : public DffPropertyReader
+{
+ FmFormModel* pFormModel;
+ SvxMSDffBLIPInfos* pBLIPInfos;
+ SvxMSDffShapeInfos* pShapeInfos;
+ SvxMSDffShapeOrders* pShapeOrders;
+ ULONG nDefaultFontHeight;
+ long nOffsDgg;
+ USHORT nBLIPCount;
+ USHORT nShapeCount;
+ sal_uInt32 nGroupShapeFlags;
+
+ void CheckTxBxStoryChain();
+ void GetFidclData( long nOffsDgg );
+
+protected :
+
+ String maBaseURL;
+ UINT32 mnCurMaxShapeId; // we need this information to
+ UINT32 mnDrawingsSaved; // access the right drawing
+ UINT32 mnIdClusters; // while only knowing the shapeid
+ FIDCL* mpFidcls;
+ Table maDgOffsetTable; // array of fileoffsets
+
+ friend class DffPropertyReader;
+
+ SvStream& rStCtrl;
+ SvStream* pStData;
+ SvStream* pStData2;
+ SdrModel* pSdrModel;
+
+ long nMapMul;
+ long nMapDiv;
+ long nMapXOfs;
+ long nMapYOfs;
+ long nEmuMul;
+ long nEmuDiv;
+ long nPntMul;
+ long nPntDiv;
+ FASTBOOL bNeedMap;
+ UINT32 nSvxMSDffSettings;
+ UINT32 nSvxMSDffOLEConvFlags;
+
+ /** stores a reference to an imported SdrObject with its shape id if
+ it has one
+ */
+ SvxMSDffShapeIdContainer maShapeIdContainer;
+
+ void GetCtrlData( long nOffsDgg );
+ void GetDrawingGroupContainerData( SvStream& rSt,
+ ULONG nLenDgg );
+ // --> OD 2008-08-01 #156763#
+ // Add internal drawing container id as parameter to the sub methods of
+ // reading the control information about the drawing objects.
+ // The drawing container id is used to distinguish the text ids of drawing
+ // objects in different drawing containers.
+ void GetDrawingContainerData( SvStream& rSt,
+ ULONG nLenDg,
+ const unsigned long nDrawingContainerId );
+ BOOL GetShapeGroupContainerData( SvStream& rSt,
+ ULONG nLenShapeGroupCont,
+ BOOL bPatriarch,
+ const unsigned long nDrawingContainerId );
+ BOOL GetShapeContainerData( SvStream& rSt,
+ ULONG nLenShapeCont,
+ ULONG nPosGroup,
+ const unsigned long nDrawingContainerId );
+ // <--
+
+ FASTBOOL ReadGraphic( SvStream& rSt, ULONG nIndex, Graphic& rGraphic ) const;
+ SdrObject* ImportFontWork( SvStream&, SfxItemSet&, Rectangle& rBoundRect ) const;
+ SdrObject* ImportGraphic( SvStream&, SfxItemSet&, const DffObjData& ) const;
+ // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method
+ // Needed in the Writer Microsoft Word import to avoid import of OLE objects
+ // inside groups. Instead a graphic object is created.
+ virtual SdrObject* ImportOLE( long nOLEId,
+ const Graphic& rGraf,
+ const Rectangle& rBoundRect,
+ const Rectangle& rVisArea,
+ const int _nCalledByGroup,
+ sal_Int64 nAspect ) const;
+ // <--
+ SdrObject* GetAutoForm( MSO_SPT eTyp ) const;
+ static const GDIMetaFile* lcl_GetMetaFileFromGrf_Impl( const Graphic& rGrf, GDIMetaFile& rMtf );
+#ifndef SVX_LIGHT
+ static com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > CheckForConvertToSOObj(
+ UINT32 nConvertFlags, SotStorage& rSrcStg,
+ const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xDestStg,
+ const Graphic& rGrf,
+ const Rectangle& rVisArea );
+#endif
+
+/*
+ folgende Methoden sind zum Excel-Import zu ueberschreiben:
+*/
+ virtual BOOL ProcessClientAnchor(SvStream& rStData, ULONG nDatLen, char*& rpBuff, UINT32& rBuffLen ) const;
+ virtual void ProcessClientAnchor2( SvStream& rStData, DffRecordHeader& rHd, void* pData, DffObjData& );
+ virtual BOOL ProcessClientData( SvStream& rStData, ULONG nDatLen, char*& rpBuff, UINT32& rBuffLen ) const;
+ virtual SdrObject* ProcessObj( SvStream& rSt, DffObjData& rData, void* pData, Rectangle& rTextRect, SdrObject* pObj = NULL);
+ virtual ULONG Calc_nBLIPPos( ULONG nOrgVal, ULONG nStreamPos ) const;
+ virtual FASTBOOL GetColorFromPalette(USHORT nNum, Color& rColor) const;
+
+ // -----------------------------------------------------------------------
+
+ FASTBOOL ReadDffString(SvStream& rSt, String& rTxt) const;
+ FASTBOOL ReadObjText(SvStream& rSt, SdrObject* pObj) const;
+
+ // SJ: New implementation of ReadObjText is used by Fontwork objects, because
+ // the old one does not properly import multiple paragraphs
+ void ReadObjText( const String& rText, SdrObject* pObj ) const;
+ // -----------------------------------------------------------------------
+
+ /*
+ folgende Methode ist von allen zu ueberschreiben, die OLE-Objecte
+ importieren moechten:
+ */
+ virtual BOOL GetOLEStorageName( long nOLEId, String& rStorageName,
+ SotStorageRef& rSrcStorage,
+ com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xDestStg
+ ) const;
+
+ /*
+ folgende Methode ist von allen zu ueberschreiben, die verhindern
+ moechten, dass (abgerundete) Rechtecke mit umgebrochenem Text
+ immer in SdrRectObj( OBJ_TEXT ) umgewandelt werden:
+ TRUE bedeutet umwandeln.
+ */
+ virtual BOOL ShapeHasText(ULONG nShapeId, ULONG nFilePos) const;
+
+public:
+
+ void* pSvxMSDffDummy1;
+ void* pSvxMSDffDummy2;
+ void* pSvxMSDffDummy3;
+ List* pEscherBlipCache;
+
+ DffRecordManager maShapeRecords;
+ ColorData mnDefaultColor;
+
+ MSFilterTracer* mpTracer;
+ sal_Bool mbTracing;
+
+ Color MSO_TEXT_CLR_ToColor( sal_uInt32 nColorCode ) const;
+ Color MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContextProperty = DFF_Prop_lineColor ) const;
+ virtual BOOL SeekToShape( SvStream& rSt, void* pClientData, UINT32 nId ) const;
+ FASTBOOL SeekToRec( SvStream& rSt, USHORT nRecId, ULONG nMaxFilePos, DffRecordHeader* pRecHd = NULL, ULONG nSkipCount = 0 ) const;
+ FASTBOOL SeekToRec2( USHORT nRecId1, USHORT nRecId2, ULONG nMaxFilePos, DffRecordHeader* pRecHd = NULL, ULONG nSkipCount = 0 ) const;
+
+ // -----------------------------------------------------------------------
+ static void MSDFFReadZString( SvStream& rIn, String& rStr, ULONG nMaxLen, FASTBOOL bUniCode = FALSE );
+
+ static BOOL ReadCommonRecordHeader( DffRecordHeader& rRec, SvStream& rIn );
+ static BOOL ReadCommonRecordHeader( SvStream& rSt,
+ BYTE& rVer,
+ USHORT& rInst,
+ USHORT& rFbt,
+ UINT32& rLength );
+/*
+ Konstruktor
+ ===========
+ Input: rStCtrl - Verwaltungsstream mit Containern,
+ FBSE Objekten und Shapes
+ ( muss immer uebergeben werden;
+ Stream muss bereits offen sein )
+
+ nOffsDgg - Offset im rStCtrl: Beginn des Drawing Group Containers
+
+ pStData - Datenstream, in dem die BLIPs gespeichert sind
+ ( falls Null, wird angenommen, dass die
+ BLIPs ebenfalls im rStCtrl gespeichert sind;
+ dieser Stream muss ebenfalls bereits offen sein )
+ pSdrModel_ kann beim Ctor-Aufruf leer bleiben, muss dann aber
+ spaeter ueber SetModel() gesetzt werden!
+
+ setzt nBLIPCount
+*/
+ SvxMSDffManager( SvStream& rStCtrl,
+ const String& rBaseURL,
+ long nOffsDgg,
+ SvStream* pStData,
+ SdrModel* pSdrModel_ = 0,
+ long nApplicationScale = 0,
+ ColorData mnDefaultColor_ = COL_DEFAULT,
+ ULONG nDefaultFontHeight_ = 24,
+ SvStream* pStData2_ = 0,
+ MSFilterTracer* pTracer = NULL );
+
+ // in PPT werden die Parameter DGGContainerOffset und PicStream
+ // mit Hilfe einer Init Routine Uebergeben.
+ SvxMSDffManager( SvStream& rStCtrl, const String& rBaseURL, MSFilterTracer* pTracer );
+ void InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nSvxMSDffOLEConvFlags );
+ void SetDgContainer( SvStream& rSt );
+
+ virtual ~SvxMSDffManager();
+
+ UINT32 GetSvxMSDffSettings() const { return nSvxMSDffSettings; };
+ void SetSvxMSDffSettings( UINT32 nSettings ) { nSvxMSDffSettings = nSettings; };
+
+ static BOOL MakeContentStream( SotStorage * pStor, const GDIMetaFile & );
+ static BOOL ConvertToOle2( SvStream& rStm, UINT32 nLen, const GDIMetaFile*,
+ const SotStorageRef & rDest );
+
+ void SetModel(SdrModel* pModel, long nApplicationScale);
+ SdrModel* GetModel() const { return pSdrModel; }
+ void Scale(sal_Int32& rVal) const;
+ void Scale(Point& rPos) const;
+ void Scale(Size& rSiz) const;
+ void Scale(Rectangle& rRect) const;
+ void Scale(Polygon& rPoly) const;
+ void Scale(PolyPolygon& rPoly) const;
+ void ScaleEmu(sal_Int32& rVal) const;
+ UINT32 ScalePt( UINT32 nPt ) const;
+ INT32 ScalePoint( INT32 nVal ) const;
+
+/*
+ GetBLIP() - Anforderung eines bestimmten BLIP
+ =========
+ Input: nIdx - Nummer des angeforderten BLIP
+ ( muss immer uebergeben werden )
+
+ Output: rData - bereits fertig konvertierte Daten
+ ( direkt als Grafik in unsere Dokumente einzusetzen )
+
+ Rueckgabewert: TRUE, im Erfolgsfalls, FALSE bei Fehler
+*/
+ BOOL GetBLIP( ULONG nIdx, Graphic& rData, Rectangle* pVisArea = NULL ) const;
+
+/*
+ GetBLIPDirect() -Einlesen eines BLIP aus schon positioniertem Stream
+ ===============
+ Input: rBLIPStream -bereits korrekt positionierter Stream
+ ( muss immer uebergeben werden )
+
+ Output: rData -bereits fertig konvertierte Daten
+ ( direkt als Grafik in unsere Dokumente einzusetzen )
+
+ Rueckgabewert: TRUE, im Erfolgsfalls, FALSE bei Fehler
+*/
+ BOOL GetBLIPDirect(SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea = NULL ) const;
+
+ BOOL GetShape(ULONG nId,
+ SdrObject*& rpData, SvxMSDffImportData& rData);
+
+/*
+ GetBLIPCount() - Abfrage der verwalteten BLIP Anzahl
+ ==============
+ Input: ./.
+ Output: ./.
+ Rueckgabewert: nBLIPCount - Anzahl der im pStData (bzw. rStCtrl) enthaltenen BLIPs
+ ( sprich: Anzahl der FBSEs im Drawing Group Container )
+
+ Werte: 0 - Struktur Ok, jedoch keine BLIPs vorhanden
+ 1.. - Anzahl der BLIPs
+ USHRT_MAX - Fehler: kein korrektes Drawing File Format
+*/
+ USHORT GetBLIPCount() const{ return nBLIPCount; }
+
+/*
+ ZCodecDecompressed() - Dekomprimierung eines komp. WMF oder Enhanced WMF
+ ====================
+ Input: rIn -bereits korrekt positionierter Stream,
+ der das komprimierte Bild enthaelt
+ rOut -bereits korrekt positionierter Ausgabe-Stream,
+
+ bLookForEnd -Flag, ob das komp. Bild bis zum Stream-Ende reicht.
+ Falls TRUE, wird jeweils geprueft, ob das gelesene noch
+ zum Bild gehoert.
+ Falls FALSE, wird bis zum Stream-Ende gelesen.
+
+ Output: rIn -Der Stream steht hinter dem Ende des komp. Bildes.
+ (es kann aber noch eine Ende-Kennung und CRC-Sum folgen)
+ rOut -Der Stream enthaelt das dekomprimierte Bild.
+ Der Stream wird auf den Anfang des Bildes positioniert.
+ (also dorthin, wo der Stream vor der Verarbeitung stand)
+
+ Rueckgabewert: TRUE, im Erfolgsfall
+ FALSE bei Fehler oder Null Bytes geschrieben
+*/
+// static BOOL ZCodecDecompressed( SvStream& rIn,
+// SvStream& rOut,
+// BOOL bLookForEnd );
+//
+ SdrObject* ImportObj(SvStream& rSt, void* pData,
+ Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup = 0, sal_Int32* pShapeId = NULL);
+
+ SdrObject* ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pData,
+ Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup = 0, sal_Int32* pShapeId = NULL );
+
+ SdrObject* ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pData,
+ Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup = 0, sal_Int32* pShapeId = NULL);
+
+ Rectangle GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect );
+ void GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt,
+ Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor,
+ const Rectangle& rClientRect, const Rectangle& rGlobalChildRect );
+
+ inline const SvxMSDffShapeInfos* GetShapeInfos( void ) const
+ {
+ return pShapeInfos;
+ }
+
+ inline const SvxMSDffShapeOrders* GetShapeOrders( void ) const
+ {
+ return pShapeOrders;
+ }
+
+ void StoreShapeOrder(ULONG nId,
+ ULONG nTxBx,
+ SdrObject* pObject,
+ SwFlyFrmFmt* pFly = 0,
+ short nHdFtSection = 0) const;
+
+ void ExchangeInShapeOrder(SdrObject* pOldObject,
+ ULONG nTxBx,
+ SwFlyFrmFmt* pFly,
+ SdrObject* pObject) const;
+
+ void RemoveFromShapeOrder( SdrObject* pObject ) const;
+
+ UINT32 GetConvertFlags() const { return nSvxMSDffOLEConvFlags; }
+
+ static SdrOle2Obj* CreateSdrOLEFromStorage( const String& rStorageName,
+ SotStorageRef& rSrcStorage,
+ const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xDestStg,
+ const Graphic& rGraf,
+ const Rectangle& rBoundRect,
+ const Rectangle& rVisArea,
+ SvStream* pDataStrrm,
+ ErrCode& rError,
+ UINT32 nConvertFlags,
+ sal_Int64 nAspect );
+
+ /* the method SolveSolver will create connections between shapes, it should be called after a page is imported.
+ The SvxMSDffSolverContainer is containing necessary data data that is collected during the import of each shape
+ */
+ void SolveSolver( const SvxMSDffSolverContainer& rSolver );
+
+ static sal_Bool SetPropValue(
+ const ::com::sun::star::uno::Any& rAny,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ const String& rPropertyName,
+ sal_Bool bTestPropertyAvailability = sal_False );
+
+ void insertShapeId( sal_Int32 nShapeId, SdrObject* pShape );
+ void removeShapeId( SdrObject* pShape );
+ SdrObject* getShapeForId( sal_Int32 nShapeId );
+};
+
+struct SvxMSDffBLIPInfo
+{
+ USHORT nBLIPType; // Art des BLIP: z.B. 6 fuer PNG
+ ULONG nFilePos; // Offset des BLIP im Daten-Stream
+ ULONG nBLIPSize; // Anzahl Bytes, die der BLIP im Stream einnimmt
+ SvxMSDffBLIPInfo(USHORT nBType, ULONG nFPos, ULONG nBSize):
+ nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){}
+};
+
+struct SvxMSDffShapeInfo
+{
+ sal_uInt32 nShapeId; // Shape Id, verwendet im PLCF SPA und im mso_fbtSp (FSP)
+ ULONG nFilePos; // Offset des Shape im Kontroll-Stream fuer eventuelle
+ // erneute Zugriffe auf dieses Shape
+ sal_uInt32 nTxBxComp;
+
+ BOOL bReplaceByFly :1; // Shape darf im Writer durch Rahmen ersetzt werden.
+ BOOL bSortByShapeId :1;
+ BOOL bLastBoxInChain:1;
+
+ SvxMSDffShapeInfo(ULONG nFPos, sal_uInt32 nId=0, // ULONG nBIdx=0,
+ USHORT nSeqId=0, USHORT nBoxId=0):
+ nShapeId( nId ),
+ nFilePos( nFPos ),
+ nTxBxComp( (nSeqId << 16) + nBoxId )
+ {
+ bReplaceByFly = FALSE;
+ bSortByShapeId = FALSE;
+ bLastBoxInChain = TRUE;
+ }
+ SvxMSDffShapeInfo(SvxMSDffShapeInfo& rInfo):
+ nShapeId( rInfo.nShapeId ),
+ nFilePos( rInfo.nFilePos ),
+ nTxBxComp( rInfo.nTxBxComp )
+ {
+ bReplaceByFly = rInfo.bReplaceByFly;
+ bSortByShapeId = rInfo.bSortByShapeId;
+ bLastBoxInChain = rInfo.bLastBoxInChain;
+ }
+ BOOL operator==( const SvxMSDffShapeInfo& rEntry ) const
+ {
+ return bSortByShapeId ? (nShapeId == rEntry.nShapeId)
+ : (nTxBxComp == rEntry.nTxBxComp && this == &rEntry);
+ }
+ BOOL operator<( const SvxMSDffShapeInfo& rEntry ) const
+ {
+ return bSortByShapeId ? (nShapeId < rEntry.nShapeId)
+ : (nTxBxComp < rEntry.nTxBxComp);
+ }
+};
+
+struct SvxMSDffShapeOrder
+{
+ ULONG nShapeId; // Shape Id, verwendet im PLCF SPA und im mso_fbtSp (FSP)
+
+ ULONG nTxBxComp; // Ketten- und Boxnummer in der Text-Box-Story (bzw. Null)
+
+ SwFlyFrmFmt* pFly; // Frame-Format eines statt des Sdr-Text-Objektes im
+ // Writer eingefuegten Rahmens: zur Verkettung benoetigt!
+
+ short nHdFtSection; // used by Writer to find out if linked frames are in the
+ // same header or footer of the same section
+
+ SdrObject* pObj; // Zeiger auf das Draw-Objekt (bzw. Null, falls nicht verwendet)
+
+ // Vorgehensweise: im Ctor des SvxMSDffManager werden im der Shape-Order-Array
+ // nur die Shape-Ids vermerkt,
+ // Text-Box-Nummer und der Objekt-Pointer werden nur dann
+ // gespeichert, wenn das Shape tatsaechlich importiert wird!
+ SvxMSDffShapeOrder( ULONG nId ):
+ nShapeId( nId ), nTxBxComp( 0 ), pFly( 0 ), nHdFtSection( 0 ), pObj( 0 ){}
+
+ BOOL operator==( const SvxMSDffShapeOrder& rEntry ) const
+ {
+ return (nTxBxComp == rEntry.nTxBxComp);
+ }
+ BOOL operator<( const SvxMSDffShapeOrder& rEntry ) const
+ {
+ return (nTxBxComp < rEntry.nTxBxComp);
+ }
+};
+
+#endif
+
diff --git a/filter/inc/filter/msfilter/msfilterdllapi.h b/filter/inc/filter/msfilter/msfilterdllapi.h
new file mode 100644
index 000000000000..ada4c8e853a9
--- /dev/null
+++ b/filter/inc/filter/msfilter/msfilterdllapi.h
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dllapi.h,v $
+ * $Revision: 1.3 $
+ *
+ * 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 INCLUDED_MSFILTER_DLLAPI_H
+#define INCLUDED_MSFILTER_DLLAPI_H
+
+#include "sal/types.h"
+
+#if defined MSFILTER_DLLIMPLEMENTATION
+#define MSFILTER_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define MSFILTER_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
+#define MSFILTER_DLLPRIVATE SAL_DLLPRIVATE
+
+#endif
diff --git a/filter/inc/filter/msfilter/msfiltertracer.hxx b/filter/inc/filter/msfilter/msfiltertracer.hxx
new file mode 100644
index 000000000000..13417175dc52
--- /dev/null
+++ b/filter/inc/filter/msfilter/msfiltertracer.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msfiltertracer.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * 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 _MS_FILTERTRACER_HXX
+#define _MS_FILTERTRACER_HXX
+
+#include <rtl/ustring.hxx>
+#include <tools/stream.hxx>
+#include <xmloff/attrlist.hxx>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/util/XTextSearch.hpp>
+#include <com/sun/star/util/SearchResult.hpp>
+#include <com/sun/star/util/logging/XLogger.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include "filter/msfilter/msfilterdllapi.h"
+
+class FilterConfigItem;
+class MSFILTER_DLLPUBLIC MSFilterTracer
+{
+ FilterConfigItem* mpCfgItem;
+ SvXMLAttributeList* mpAttributeList;
+ SvStream* mpStream;
+ sal_Bool mbEnabled;
+
+ ::com::sun::star::util::SearchOptions maSearchOptions;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > mxFilterTracer;
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XTextSearch > mxTextSearch;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::logging::XLogger > mxLogger;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > mxHandler;
+
+ public :
+
+ /* The first parameter is expecting the path of the configuration file.
+ The second parameter can be used to override properties of the configuration
+ file. A "DocumentURL" property can be set in the property
+ sequence to provide the current url of the document.
+ If the "Path" property is not set in the configuration file, then the path
+ of the "DocumentURL" property is used instead. If both are not set, the
+ application path is used instead.
+ If the "Name" property is not set in the configuration file, then the name
+ of the "DocumentURL" property is used instead. If both are not set, the
+ name "tracer* is used.
+ The file extension will always be "log" */
+
+ MSFilterTracer( const ::rtl::OUString& rConfigurationPath,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pConfigData = NULL );
+ ~MSFilterTracer();
+
+ void StartTracing();
+ void EndTracing();
+
+ inline sal_Bool IsEnabled() const { return mbEnabled; }
+
+ void StartElement( const ::rtl::OUString& rName, ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > xAttribs );
+ void EndElement( const ::rtl::OUString& rName );
+
+ void Trace( const ::rtl::OUString& rElementID, const ::rtl::OUString& rMessage );
+ void AddAttribute( const ::rtl::OUString &sName , const ::rtl::OUString &sValue );
+ void RemoveAttribute( const ::rtl::OUString& sName );
+ void ClearAttributes();
+
+ /* initially all properties of the configuration file and the
+ properties which are given to the c'tor can be retrieved */
+ ::com::sun::star::uno::Any GetProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any* pDefault = NULL ) const;
+ void SetProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any& rProperty );
+};
+
+#endif
diff --git a/filter/inc/filter/msfilter/msocximex.hxx b/filter/inc/filter/msfilter/msocximex.hxx
new file mode 100644
index 000000000000..cf06e8378541
--- /dev/null
+++ b/filter/inc/filter/msfilter/msocximex.hxx
@@ -0,0 +1,1423 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msocximex.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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 _MSOCXIMEX_HXX
+#define _MSOCXIMEX_HXX
+
+#include <sot/storage.hxx>
+#include <tools/debug.hxx>
+
+//!! no such defines in global namespaces - it will break other existing code that uses the same define!!
+//#ifndef C2U
+//#define C2U(cChar) rtl::OUString::createFromAscii(cChar)
+//#endif
+#include "filter/msfilter/msfilterdllapi.h"
+#include <vector>
+#include <hash_map>
+
+namespace com{namespace sun{namespace star{
+ namespace drawing{
+ class XDrawPage;
+ class XShape;
+ class XShapes;
+ }
+ namespace form{
+ class XFormComponent;
+ }
+ namespace lang{
+ class XMultiServiceFactory;
+ }
+ namespace container{
+ class XIndexContainer;
+ class XNameContainer;
+ }
+ namespace beans{
+ class XPropertySet;
+ }
+ namespace text{
+ class XText;
+ }
+ namespace awt{
+ struct Size;
+ class XControlModel;
+ }
+ namespace uno{
+ class XComponentContext;
+ }
+
+}}}
+
+class OCX_Control;
+class SfxObjectShell;
+class SwPaM;
+
+class TypeName
+{
+public:
+ String msName;
+ sal_uInt16 mnType;
+ sal_Int32 mnLeft;
+ sal_Int32 mnTop;
+ sal_Int32 mnStoreId;
+ TypeName(sal_Char *pName, sal_uInt32 nStoreId, sal_uInt32 nLen, sal_uInt16 nType,
+ sal_Int32 nLeft, sal_Int32 nTop);
+};
+
+
+class MSFILTER_DLLPUBLIC SvxMSConvertOCXControls
+{
+public:
+ SvxMSConvertOCXControls( SfxObjectShell *pDSh,SwPaM *pP );
+ virtual ~SvxMSConvertOCXControls();
+
+ //Reads a control from the given storage, constructed shape in pShapeRef
+ sal_Bool ReadOCXStream( SotStorageRef& rSrc1,
+ com::sun::star::uno::Reference<
+ com::sun::star::drawing::XShape > *pShapeRef=0,
+ BOOL bFloatingCtrl=FALSE );
+
+
+ //Excel has a nasty kludged mechanism for this, read
+ //the comments in the source to follow it
+ sal_Bool ReadOCXExcelKludgeStream(SotStorageStreamRef& rSrc1,
+ com::sun::star::uno::Reference <
+ com::sun::star::drawing::XShape > *pShapeRef,BOOL bFloatingCtrl);
+
+
+ //Writes the given Uno Control into the given storage
+
+ static sal_Bool WriteOCXStream(SotStorageRef &rSrc1,
+ const com::sun::star::uno::Reference<
+ com::sun::star::awt::XControlModel > &rControlModel,
+ const com::sun::star::awt::Size& rSize,String &rName);
+
+ //Excel has a nasty kludged mechanism for this, read
+ //the comments in the source to follow it
+ static sal_Bool WriteOCXExcelKludgeStream(SotStorageStreamRef& rContents,
+ const com::sun::star::uno::Reference<
+ com::sun::star::awt::XControlModel > &rControlModel,
+ const com::sun::star::awt::Size &rSize, String &rName);
+
+ //Generate an OCX converter based on the OLE2 name
+ static OCX_Control *OCX_Factory(const String &rId);
+
+ //Generate an OCX converter based on the StarOffice UNO id
+ static OCX_Control *OCX_Factory( const com::sun::star::uno::Reference<
+ com::sun::star::awt::XControlModel > &rControlModel,
+ String &rId,String &rName);
+
+ virtual sal_Bool InsertControl(
+ const com::sun::star::uno::Reference<
+ com::sun::star::form::XFormComponent >& /*rFComp*/,
+ const com::sun::star::awt::Size& /*rSize*/,
+ com::sun::star::uno::Reference<
+ com::sun::star::drawing::XShape >* /*pShape*/,
+ BOOL /*bFloatingCtrl*/ ) {return sal_False;}
+
+ /*begin: Backwards compatability with office 95 import, modify later*/
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > & GetServiceFactory();
+
+ sal_uInt16 GetEditNum() { return ++nEdit; }
+ sal_uInt16 GetCheckboxNum() { return ++nCheckbox; }
+ /*end: Backwards compatability*/
+protected:
+ const com::sun::star::uno::Reference< com::sun::star::drawing::XShapes > &
+ GetShapes();
+
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XIndexContainer > & GetFormComps();
+
+ SfxObjectShell *pDocSh;
+ SwPaM *pPaM;
+
+ // gecachte Interfaces
+ com::sun::star::uno::Reference< com::sun::star::drawing::XDrawPage >
+ xDrawPage;
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >
+ xShapes;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xServiceFactory;
+
+ // das einzige Formular
+ com::sun::star::uno::Reference< com::sun::star::container::XIndexContainer >
+ xFormComps;
+
+ sal_uInt16 nEdit;
+ sal_uInt16 nCheckbox;
+
+ virtual const com::sun::star::uno::Reference<
+ com::sun::star::drawing::XDrawPage > & GetDrawPage();
+};
+
+class OCX_FontData
+{
+public:
+ OCX_FontData() : nFontNameLen(0), fBold(0), fItalic(0), fUnderline(0),
+ fStrike(0), nFontSize(12), nJustification(1), pFontName(0),
+ bHasAlign(FALSE), bHasFont(TRUE) {}
+ ~OCX_FontData() {
+ if (pFontName)
+ delete [] pFontName;
+ }
+ sal_Bool Read(SotStorageStream *pS);
+ void Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet > &rPropSet);
+
+ sal_Bool Export(SotStorageStreamRef &rContent,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+
+ sal_uInt32 nFontNameLen;
+
+ sal_uInt8 fBold:1;
+ sal_uInt8 fItalic:1;
+ sal_uInt8 fUnderline:1;
+ sal_uInt8 fStrike:1;
+ sal_uInt8 fUnknown1:4;
+
+ sal_uInt8 nUnknown2;
+ sal_uInt8 nUnknown3;
+ sal_uInt8 nUnknown4;
+
+ sal_uInt32 nFontSize;
+ sal_uInt16 nLanguageID;
+ sal_uInt8 nJustification;
+ sal_uInt16 nFontWeight;
+
+ char *pFontName;
+ void SetHasAlign(sal_Bool bIn) {bHasAlign=bIn;}
+ void SetHasFont(sal_Bool bIn) {bHasFont=bIn;}
+protected:
+ static sal_uInt16 nStandardId;
+ sal_uInt8 ExportAlign(sal_Int16 nAlign) const;
+ sal_Int16 ImportAlign(sal_uInt8 nJustification) const;
+private:
+ sal_Bool bHasAlign;
+ sal_Bool bHasFont;
+};
+
+class MSFILTER_DLLPUBLIC OCX_Control
+{
+public:
+ OCX_Control(UniString sN, OCX_Control* parent = NULL ) : nWidth( 0 ), nHeight( 0 ), mnLeft(0), mnTop(0),
+ mnStep(0), mnBackColor(0x8000000FL), mnForeColor(0), mnTabPos(0), mbVisible(true), sName(sN), pDocSh(0),
+ bSetInDialog(FALSE), mpParent( parent ) {}
+ sal_Bool FullRead(SotStorageStream *pS)
+ {
+ return Read(pS) && ReadFontData(pS);
+ };
+ virtual sal_Bool Read(SotStorageStream *pS);
+ virtual sal_Bool ReadFontData(SotStorageStream *pS);
+ virtual sal_Bool Import(const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > &rServiceFactory,
+ com::sun::star::uno::Reference<
+ com::sun::star::form::XFormComponent > &rFComp,
+ com::sun::star::awt::Size &rSz);
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer>
+ &rDialog);
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet>& /*rPropSet*/)
+ {return sal_False;}
+ //Export exports a control as an OLE style storage stream tree
+ virtual sal_Bool Export(SotStorageRef& /*rObj*/,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet>& /*rPropSet*/,
+ const com::sun::star::awt::Size& /*rSize*/) {return sal_False;}
+
+ //WriteContents writes the contents of a contents stream, for
+ //the Excel export you cannot use Export, only WriteContents instead
+ virtual sal_Bool WriteContents(SotStorageStreamRef& /*rObj*/,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet>& /*rPropSet*/,
+ const com::sun::star::awt::Size& /*rSize*/) {return sal_False;}
+ void SetInDialog(bool bState) { bSetInDialog = bState; }
+ bool GetInDialog() { return bSetInDialog; }
+
+ sal_Bool ReadAndImport(SotStorageStream *pS,
+ com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > &rSF,
+ com::sun::star::uno::Reference<
+ com::sun::star::form::XFormComponent > &rFComp,
+ com::sun::star::awt::Size &rSz)
+ {
+ if (Read(pS))
+ return Import(rSF,rFComp,rSz);
+ return sal_False;
+ }
+ virtual ~OCX_Control() {}
+
+ static void FillSystemColors();
+
+ sal_uInt32 nWidth;
+ sal_uInt32 nHeight;
+ sal_Int32 mnLeft;
+ sal_Int32 mnTop;
+ sal_Int32 mnStep;
+ sal_Int32 mnBackColor;
+ sal_Int32 mnForeColor;
+ sal_uInt16 mnTabPos;
+ bool mbVisible;
+ UniString sName;
+ UniString msToolTip;
+ OCX_FontData aFontData;
+ SfxObjectShell *pDocSh;
+protected:
+
+ sal_uInt32 ImportColor(sal_uInt32 nColorCode) const;
+ sal_uInt32 ExportColor(sal_uInt32 nColorCode) const;
+ sal_uInt32 SwapColor(sal_uInt32 nColorCode) const;
+ sal_Int16 ImportBorder(sal_uInt16 nSpecialEffect,sal_uInt16 nBorderStyle)
+ const;
+ sal_uInt8 ExportBorder(sal_uInt16 nBorder,sal_uInt8 &rBorderStyle) const;
+ bool bSetInDialog;
+ sal_Int16 ImportSpecEffect( sal_uInt8 nSpecialEffect ) const;
+ sal_uInt8 ExportSpecEffect( sal_Int16 nApiEffect ) const;
+ static sal_uInt16 nStandardId;
+ static sal_uInt8 __READONLY_DATA aObjInfo[4];
+ rtl::OUString msFormType;
+ rtl::OUString msDialogType;
+ OCX_Control* mpParent;
+private:
+ static sal_uInt32 pColor[25];
+};
+
+class OCX_ModernControl : public OCX_Control
+{
+public:
+ OCX_ModernControl(UniString sN) : OCX_Control(sN),
+ fEnabled(1), fLocked(0), fBackStyle(1), fColumnHeads(0), fIntegralHeight(1),
+ fMatchRequired(0), fAlignment(1), fDragBehaviour(0), fEnterKeyBehaviour(0),
+ fEnterFieldBehaviour(0), fTabKeyBehaviour(0), fWordWrap(1),
+ fSelectionMargin(1), fAutoWordSelect(1), fAutoSize(0), fHideSelection(1),
+ fAutoTab(0), fMultiLine(1), nMaxLength(0), nBorderStyle(0), nScrollBars(0),
+ nStyle(0), nMousePointer(0), nPasswordChar(0), nListWidth(0),
+ nBoundColumn(1), nTextColumn(-1), nColumnCount(1), nListRows(8),
+ nMatchEntry(2), nListStyle(0), nShowDropButtonWhen(0), nDropButtonStyle(1),
+ nMultiState(0), nValueLen(0), nCaptionLen(0), nVertPos(1), nHorzPos(7),
+ nSpecialEffect(2), nIcon(0), nPicture(0), nAccelerator(0), nGroupNameLen(0),
+ pValue(0), pCaption(0), pGroupName(0), nIconLen(0), pIcon(0),
+ nPictureLen(0), pPicture(0) {}
+
+ ~OCX_ModernControl() {
+ if (pValue) delete[] pValue;
+ if (pCaption) delete[] pCaption;
+ if (pGroupName) delete[] pGroupName;
+ if (pIcon) delete[] pIcon;
+ if (pPicture) delete[] pPicture;
+ }
+ sal_Bool Read(SotStorageStream *pS);
+
+
+ /*sal_uInt8 for sal_uInt8 Word Struct*/
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[8];
+
+ sal_uInt8 fUnknown1:1;
+ sal_uInt8 fEnabled:1;
+ sal_uInt8 fLocked:1;
+ sal_uInt8 fBackStyle:1;
+ sal_uInt8 fUnknown2:4;
+
+ sal_uInt8 fUnknown3:2;
+ sal_uInt8 fColumnHeads:1;
+ sal_uInt8 fIntegralHeight:1;
+ sal_uInt8 fMatchRequired:1;
+ sal_uInt8 fAlignment:1;
+ sal_uInt8 fUnknown4:2;
+
+ sal_uInt8 fUnknown5:3;
+ sal_uInt8 fDragBehaviour:1;
+ sal_uInt8 fEnterKeyBehaviour:1;
+ sal_uInt8 fEnterFieldBehaviour:1;
+ sal_uInt8 fTabKeyBehaviour:1;
+ sal_uInt8 fWordWrap:1;
+
+ sal_uInt8 fUnknown6:2;
+ sal_uInt8 fSelectionMargin:1;
+ sal_uInt8 fAutoWordSelect:1;
+ sal_uInt8 fAutoSize:1;
+ sal_uInt8 fHideSelection:1;
+ sal_uInt8 fAutoTab:1;
+ sal_uInt8 fMultiLine:1;
+
+ sal_uInt32 nMaxLength;
+ sal_uInt8 nBorderStyle;
+ sal_uInt8 nScrollBars;
+ sal_uInt8 nStyle;
+ sal_uInt8 nMousePointer;
+ sal_uInt8 nUnknown7;
+ sal_uInt8 nPasswordChar;
+ sal_uInt32 nListWidth;
+ sal_uInt16 nBoundColumn;
+ sal_Int16 nTextColumn;
+ sal_uInt16 nColumnCount;
+ sal_uInt16 nListRows;
+ sal_uInt16 nUnknown8;
+ sal_uInt8 nMatchEntry;
+ sal_uInt8 nListStyle;
+ sal_uInt8 nShowDropButtonWhen;
+ sal_uInt8 nDropButtonStyle;
+ sal_uInt8 nMultiState;
+ sal_uInt32 nValueLen;
+ sal_uInt32 nCaptionLen;
+
+ sal_uInt16 nVertPos;
+ sal_uInt16 nHorzPos;
+
+ sal_uInt32 nBorderColor;
+ sal_uInt8 nSpecialEffect;
+ sal_uInt16 nIcon;
+ sal_uInt16 nPicture;
+ sal_uInt8 nAccelerator;
+ sal_uInt8 nUnknown9;
+ sal_uInt32 nGroupNameLen;
+ sal_uInt32 nUnknown10;
+
+ char *pValue;
+ char *pCaption;
+ char *pGroupName;
+
+ sal_uInt8 pIconHeader[20];
+ sal_uInt32 nIconLen;
+ sal_uInt8 *pIcon;
+
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen;
+ sal_uInt8 *pPicture;
+
+};
+
+class OCX_TabStrip : public OCX_Control
+{
+public:
+ OCX_TabStrip() : OCX_Control( rtl::OUString::createFromAscii("TabStrip")) {}
+ virtual sal_Bool ReadFontData(SotStorageStream *pS);
+ virtual sal_Bool Read(SotStorageStream *pS);
+
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+ sal_uInt16 nNumTabs;
+};
+
+class OCX_Image : public OCX_Control
+{
+public:
+ OCX_Image() : OCX_Control(rtl::OUString::createFromAscii("Image")), fEnabled(1), fBackStyle(0), bPictureTiling(false), bAutoSize(false) {
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.DatabaseImageControl");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlImageControlModel");
+ }
+
+ ~OCX_Image() { }
+ /*sal_uInt8 for sal_uInt8 Word Struct*/
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+
+ sal_uInt32 nBorderColor;
+ sal_uInt8 nBorderStyle;
+ sal_uInt8 nMousePointer;
+ sal_uInt8 nPictureSizeMode;
+
+
+ sal_uInt8 fUnknown1:1;
+ sal_uInt8 fEnabled:1;
+ sal_uInt8 fUnknown2:2;
+ sal_uInt8 fBackStyle:1;
+ sal_uInt8 fUnknown3:3;
+
+ sal_uInt8 nPictureAlignment;
+ bool bPictureTiling;
+ sal_uInt8 nSpecialEffect;
+
+ bool bAutoSize;
+ ::rtl::OUString sImageUrl;
+ sal_Bool Read(SotStorageStream *pS);
+
+ using OCX_Control::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet>& rPropSet);
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ // No Font record
+ virtual sal_Bool ReadFontData(SvStorageStream* /*pS*/) { return sal_True; }
+
+ static OCX_Control *Create() { return new OCX_Image;}
+};
+struct ContainerRecord
+{
+ ContainerRecord():nTop(0), nLeft(0), nSubStorageId(0), nSubStreamLen(0), nTabPos(0), nTypeIdent(0), bVisible( true ) {}
+
+ ::rtl::OUString cName;
+ ::rtl::OUString controlTip;
+
+ sal_uInt32 nTop;
+ sal_uInt32 nLeft;
+ sal_uInt32 nSubStorageId;
+ sal_uInt32 nSubStreamLen;
+ sal_uInt16 nTabPos;
+ sal_uInt16 nTypeIdent;
+ bool bVisible;
+};
+
+typedef std::vector<OCX_Control*>::iterator CtrlIterator;
+typedef std::vector<OCX_Control*>::const_iterator CtrlIteratorConst;
+typedef std::vector<OCX_Control*> CtrlList;
+
+
+
+class RBGroup
+{
+ public:
+ RBGroup():mRBGroupPos(0){}
+ RBGroup(sal_uInt16& groupPos ):mRBGroupPos(groupPos){}
+ sal_Int16 tabPos() const { return mRBGroupPos; }
+ std::vector<OCX_Control*>::size_type numControls()
+ { return mpControls.size(); }
+ std::vector<OCX_Control*>& controls() { return mpControls; }
+
+ void add(OCX_Control* pRB);
+ private:
+ sal_uInt16 mRBGroupPos;
+ std::vector<OCX_Control*> mpControls;
+};
+
+typedef ::std::hash_map < ::rtl::OUString, RBGroup*, ::rtl::OUStringHash,
+ ::std::equal_to< ::rtl::OUString > > RBGroupHash;
+typedef std::vector<RBGroup*>::iterator GroupIterator;
+
+class OCX_OptionButton;
+
+class RBGroupManager
+{
+public:
+ RBGroupManager( String& defaultName );
+ ~RBGroupManager();
+
+ CtrlList insertGroupsIntoControlList( const CtrlList& sourceList );
+ void addRadioButton( OCX_OptionButton* pRButton );
+private:
+
+ void addSeperator( std::vector< OCX_Control* >& dest );
+ void copyList( std::vector< OCX_Control* >& src,
+ std::vector< OCX_Control* >& dest,
+ bool addGroupSeperator );
+
+ RBGroupHash rbGroups;
+ String mSDefaultName;
+ std::vector< RBGroup* > groupList;
+ sal_uInt16 numRadioButtons;
+};
+
+
+
+
+class OCX_ContainerControl : public OCX_Control
+{
+public:
+ virtual ~OCX_ContainerControl();
+ // sub class will process the control specific information
+ // e.g frame or userform ( maybe tab, mulipage in the future )
+ // Base (this) class will process the container specific information
+ // e.g. the controls contained by this container
+ // will
+ // a) create the controls
+ // b) read the controls
+ // c) store these controls in a list for post processing
+ // e.g. import
+ //
+ virtual sal_Bool Read(SvStorageStream *pS);
+ // No Font record
+ virtual sal_Bool ReadFontData(SvStorageStream* /*pS*/) { return sal_True; }
+
+ using OCX_Control::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+
+ SotStorageStreamRef getContainerStream() { return mContainerStream; }
+
+ virtual void ProcessControl( OCX_Control* pControl, SvStorageStream* pS, ContainerRecord& rec );
+ bool createFromContainerRecord( const ContainerRecord& record,
+ OCX_Control*& );
+protected:
+ // This class not meant to be instantiated
+ // needs to be subclassed
+ OCX_ContainerControl( SotStorageRef& parent,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > &rParent,
+ OCX_Control* pParent = NULL );
+ rtl::OUString createSubStreamName( const sal_uInt32& subStorageID );
+
+ RBGroupManager rbGroupMgr;
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > mxParent;
+ std::vector<OCX_Control*> mpControls;
+ SotStorageRef mContainerStorage;
+ SotStorageStreamRef mContainerStream;
+ SotStorageStreamRef mContainedControlsStream;
+ sal_uInt32 nNoRecords;
+ sal_uInt32 nTotalLen;
+ sal_uInt32 containerType;
+
+private:
+ OCX_ContainerControl(); // not implemented
+ OCX_ContainerControl(const OCX_ContainerControl&); // not implemented
+};
+
+
+class OCX_MultiPage : public OCX_ContainerControl
+{
+public:
+ OCX_MultiPage( SotStorageRef& parent,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > &rDialog, OCX_Control* pParent = NULL);
+ virtual ~OCX_MultiPage()
+ {
+ delete[] pCaption;
+ delete[] pIcon;
+ delete[] pPicture;
+ }
+ virtual sal_Bool Read(SvStorageStream *pS);
+
+ using OCX_ContainerControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer>
+ &rDialog);
+ virtual void ProcessControl( OCX_Control* pControl, SvStorageStream* pS, ContainerRecord& rec );
+ /*sal_uInt8 for sal_uInt8 Word Struct*/
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+
+ sal_uInt32 fUnknown1;
+
+ sal_uInt8 fUnknown2:1;
+ sal_uInt8 fEnabled:1;
+ sal_uInt8 fLocked:1;
+ sal_uInt8 fBackStyle:1;
+ sal_uInt8 fUnknown3:4;
+
+ sal_uInt8 fUnknown4:8;
+
+ sal_uInt8 fUnknown5:7;
+ sal_uInt8 fWordWrap:1;
+
+ sal_uInt8 fUnknown6:4;
+ sal_uInt8 fAutoSize:1;
+ sal_uInt8 fUnknown7:3;
+
+ sal_uInt32 nCaptionLen;
+ sal_uInt16 nVertPos;
+ sal_uInt16 nHorzPos;
+ sal_uInt8 nMousePointer;
+ sal_uInt32 nBorderColor;
+ sal_uInt32 fUnknown8;
+ sal_uInt32 fUnknown9;
+ sal_uInt8 nKeepScrollBarsVisible;
+ sal_uInt8 nCycle;
+ sal_uInt16 nBorderStyle;
+ sal_uInt16 nSpecialEffect;
+ sal_uInt16 nPicture;
+ sal_uInt8 nPictureAlignment;
+ sal_uInt8 nPictureSizeMode;
+ bool bPictureTiling;
+ sal_uInt16 nAccelerator;
+ sal_uInt16 nIcon;
+
+ char *pCaption;
+
+ sal_uInt32 nScrollWidth;
+ sal_uInt32 nScrollHeight;
+
+
+ sal_uInt8 pIconHeader[20];
+ sal_uInt32 nIconLen;
+ sal_uInt8 *pIcon;
+
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen;
+ sal_uInt8 *pPicture;
+private:
+ sal_Int32 mnCurrentPageStep;
+};
+
+
+
+class OCX_Page : public OCX_ContainerControl
+{
+public:
+ OCX_Page( SotStorageRef& parentStorage,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > &rDialog, OCX_Control* parent = NULL);
+ virtual ~OCX_Page()
+ {
+ delete[] pCaption;
+ delete[] pIcon;
+ delete[] pPicture;
+ }
+ virtual sal_Bool Read(SvStorageStream *pS);
+
+ using OCX_ContainerControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer>
+ &rDialog);
+/* virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+*/
+ /*sal_uInt8 for sal_uInt8 Word Struct*/
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+
+ sal_uInt32 fUnknown1;
+
+ sal_uInt8 fUnknown2:1;
+ sal_uInt8 fEnabled:1;
+ sal_uInt8 fLocked:1;
+ sal_uInt8 fBackStyle:1;
+ sal_uInt8 fUnknown3:4;
+
+ sal_uInt8 fUnknown4:8;
+
+ sal_uInt8 fUnknown5:7;
+ sal_uInt8 fWordWrap:1;
+
+ sal_uInt8 fUnknown6:4;
+ sal_uInt8 fAutoSize:1;
+ sal_uInt8 fUnknown7:3;
+
+ sal_uInt32 nCaptionLen;
+ sal_uInt16 nVertPos;
+ sal_uInt16 nHorzPos;
+ sal_uInt8 nMousePointer;
+ sal_uInt32 nBorderColor;
+ sal_uInt32 fUnknown8;
+ sal_uInt32 fUnknown9;
+ sal_uInt8 nKeepScrollBarsVisible;
+ sal_uInt8 nCycle;
+ sal_uInt16 nBorderStyle;
+ sal_uInt16 nSpecialEffect;
+ sal_uInt16 nPicture;
+ sal_uInt8 nPictureAlignment;
+ sal_uInt8 nPictureSizeMode;
+ bool bPictureTiling;
+ sal_uInt16 nAccelerator;
+ sal_uInt16 nIcon;
+
+ char *pCaption;
+
+ sal_uInt32 nScrollWidth;
+ sal_uInt32 nScrollHeight;
+
+
+ sal_uInt8 pIconHeader[20];
+ sal_uInt32 nIconLen;
+ sal_uInt8 *pIcon;
+
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen;
+ sal_uInt8 *pPicture;
+private:
+};
+
+
+class OCX_Frame : public OCX_ContainerControl
+{
+public:
+ OCX_Frame( SotStorageRef& parent,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > &rDialog, OCX_Control* pParent = NULL);
+ virtual ~OCX_Frame()
+ {
+ delete[] pCaption;
+ delete[] pIcon;
+ delete[] pPicture;
+ }
+ virtual sal_Bool Read(SvStorageStream *pS);
+
+ using OCX_ContainerControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+
+ /*sal_uInt8 for sal_uInt8 Word Struct*/
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+
+ sal_uInt32 fUnknown1;
+
+ sal_uInt8 fUnknown2:1;
+ sal_uInt8 fEnabled:1;
+ sal_uInt8 fLocked:1;
+ sal_uInt8 fBackStyle:1;
+ sal_uInt8 fUnknown3:4;
+
+ sal_uInt8 fUnknown4:8;
+
+ sal_uInt8 fUnknown5:7;
+ sal_uInt8 fWordWrap:1;
+
+ sal_uInt8 fUnknown6:4;
+ sal_uInt8 fAutoSize:1;
+ sal_uInt8 fUnknown7:3;
+
+ sal_uInt32 nCaptionLen;
+ sal_uInt16 nVertPos;
+ sal_uInt16 nHorzPos;
+ sal_uInt8 nMousePointer;
+ sal_uInt32 nBorderColor;
+ sal_uInt32 fUnknown8;
+ sal_uInt32 fUnknown9;
+ sal_uInt8 nKeepScrollBarsVisible;
+ sal_uInt8 nCycle;
+ sal_uInt16 nBorderStyle;
+ sal_uInt16 nSpecialEffect;
+ sal_uInt16 nPicture;
+ sal_uInt8 nPictureAlignment;
+ sal_uInt8 nPictureSizeMode;
+ bool bPictureTiling;
+ sal_uInt16 nAccelerator;
+ sal_uInt16 nIcon;
+
+ char *pCaption;
+
+ sal_uInt32 nScrollWidth;
+ sal_uInt32 nScrollHeight;
+ sal_uInt32 nScrollLeft;
+ sal_uInt32 nScrollTop;
+
+
+ sal_uInt8 pIconHeader[20];
+ sal_uInt32 nIconLen;
+ sal_uInt8 *pIcon;
+
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen;
+ sal_uInt8 *pPicture;
+private:
+};
+
+class OCX_UserForm : public OCX_ContainerControl
+{
+public:
+ OCX_UserForm( SotStorageRef& parent,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > &rDialog,
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rMsf);
+ ~OCX_UserForm()
+ {
+ delete[] pCaption;
+ delete[] pIcon;
+ delete[] pPicture;
+ }
+
+ virtual sal_Bool Read(SvStorageStream *pS);
+
+ using OCX_ContainerControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import( com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer>
+ &rDialog);
+
+ /*sal_uInt8 for sal_uInt8 Word Struct*/
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+
+ sal_uInt32 nChildrenA;
+
+ sal_uInt8 fUnknown1:1;
+ sal_uInt8 fEnabled:1;
+ sal_uInt8 fLocked:1;
+ sal_uInt8 fBackStyle:1;
+ sal_uInt8 fUnknown2:4;
+
+ sal_uInt8 fUnknown3:8;
+
+ sal_uInt8 fUnknown4:7;
+ sal_uInt8 fWordWrap:1;
+
+ sal_uInt8 fUnknown5:4;
+ sal_uInt8 fAutoSize:1;
+ sal_uInt8 fUnknown6:3;
+
+ sal_uInt32 nCaptionLen;
+ sal_uInt16 nVertPos;
+ sal_uInt16 nHorzPos;
+ sal_uInt8 nMousePointer;
+ sal_uInt32 nBorderColor;
+ sal_uInt32 nDrawBuffer;
+ sal_uInt32 nChildrenB;
+ sal_uInt8 nKeepScrollBarsVisible;
+ sal_uInt8 nCycle;
+ sal_uInt16 nBorderStyle;
+ sal_uInt8 nSpecialEffect;
+ sal_uInt16 nPicture;
+ sal_uInt8 nPictureAlignment;
+ sal_uInt8 nPictureSizeMode;
+ bool bPictureTiling;
+ sal_uInt16 nAccelerator;
+ sal_uInt16 nIcon;
+ sal_uInt16 fUnknown7;
+
+ char *pCaption;
+
+ sal_uInt32 nScrollWidth;
+ sal_uInt32 nScrollHeight;
+ sal_uInt32 nScrollLeft;
+ sal_uInt32 nScrollTop;
+
+ sal_uInt8 pIconHeader[20];
+ sal_uInt32 nIconLen;
+ sal_uInt8 *pIcon;
+
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen;
+ sal_uInt8 *pPicture;
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XComponentContext> mxCtx;
+};
+
+
+
+class OCX_CheckBox : public OCX_ModernControl
+{
+public:
+ OCX_CheckBox() : OCX_ModernControl(rtl::OUString::createFromAscii("CheckBox")){
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.CheckBox");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlCheckBoxModel");
+ mnBackColor = 0x80000005L;
+ mnForeColor = 0x80000008L;
+ aFontData.SetHasAlign(TRUE);
+ }
+
+ using OCX_ModernControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ static OCX_Control *Create() { return new OCX_CheckBox;}
+};
+
+class OCX_OptionButton : public OCX_ModernControl
+{
+public:
+ OCX_OptionButton() : OCX_ModernControl(rtl::OUString::createFromAscii("OptionButton"))
+ {
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.RadioButton");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlRadioButtonModel");
+ mnBackColor = 0x80000005L;
+ mnForeColor = 0x80000008L;
+ aFontData.SetHasAlign(TRUE);
+ }
+
+ using OCX_ModernControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+
+
+ static OCX_Control *Create() { return new OCX_OptionButton;}
+};
+
+class OCX_TextBox : public OCX_ModernControl
+{
+public:
+ OCX_TextBox() : OCX_ModernControl(rtl::OUString::createFromAscii("TextBox")) {
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.TextField");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlEditModel");
+ mnBackColor = 0x80000005L;
+ mnForeColor = 0x80000008L;
+ nBorderColor = 0x80000006L;
+ aFontData.SetHasAlign(TRUE);
+ }
+
+ using OCX_ModernControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ static OCX_Control *Create() { return new OCX_TextBox;}
+};
+
+class OCX_FieldControl: public OCX_ModernControl
+{
+public:
+ OCX_FieldControl() : OCX_ModernControl(rtl::OUString::createFromAscii("TextBox")) {
+ mnBackColor = 0x80000005L;
+ mnForeColor = 0x80000008L;
+ nBorderColor = 0x80000006L;
+ }
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ static OCX_Control *Create() { return new OCX_FieldControl;}
+};
+
+
+class OCX_ToggleButton : public OCX_ModernControl
+{
+public:
+ OCX_ToggleButton() : OCX_ModernControl(rtl::OUString::createFromAscii("ToggleButton")) {
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.CommandButton");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel");
+
+ mnBackColor = 0x8000000F;
+ mnForeColor = 0x80000012;
+ aFontData.SetHasAlign(TRUE);
+ aFontData.nJustification = 3; // centered by default
+ }
+ static OCX_Control *Create() { return new OCX_ToggleButton;}
+
+ using OCX_ModernControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ sal_Bool Export(SvStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SvStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+};
+
+class OCX_ComboBox : public OCX_ModernControl
+{
+public:
+ OCX_ComboBox() : OCX_ModernControl(rtl::OUString::createFromAscii("ComboBox")){
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.ComboBox");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlComboBoxModel");
+ mnBackColor = 0x80000005;
+ mnForeColor = 0x80000008;
+ nBorderColor = 0x80000006;
+ aFontData.SetHasAlign(TRUE);
+ }
+ static OCX_Control *Create() { return new OCX_ComboBox;}
+ using OCX_ModernControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+};
+
+class OCX_ListBox : public OCX_ModernControl
+{
+public:
+ OCX_ListBox() : OCX_ModernControl(rtl::OUString::createFromAscii("ListBox")){
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.ListBox");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlListBoxModel");
+ mnBackColor = 0x80000005;
+ mnForeColor = 0x80000008;
+ nBorderColor = 0x80000006;
+ aFontData.SetHasAlign(TRUE);
+ }
+ static OCX_Control *Create() { return new OCX_ListBox;}
+ using OCX_ModernControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+
+};
+
+class OCX_CommandButton : public OCX_Control
+{
+public:
+ OCX_CommandButton() : OCX_Control(String::CreateFromAscii("CommandButton")),
+ fEnabled(1), fLocked(0), fBackStyle(1), fWordWrap(0), fAutoSize(0),
+ nCaptionLen(0), nVertPos(1), nHorzPos(7), nMousePointer(0), nPicture(0),
+ nAccelerator(0), nIcon(0), pCaption(0), nIconLen(0), pIcon(0), nPictureLen(0),
+ pPicture(0), mbTakeFocus( true )
+ {
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.CommandButton");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel");
+ mnForeColor = 0x80000012L;
+ mnBackColor = 0x8000000FL;
+ }
+
+ ~OCX_CommandButton() {
+ if (pCaption) delete[] pCaption;
+ if (pIcon) delete[] pIcon;
+ if (pPicture) delete[] pPicture;
+ }
+ sal_Bool Read(SotStorageStream *pS);
+
+ /*sal_uInt8 for sal_uInt8 Word Struct*/
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+
+
+ sal_uInt8 fUnknown1:1;
+ sal_uInt8 fEnabled:1;
+ sal_uInt8 fLocked:1;
+ sal_uInt8 fBackStyle:1;
+ sal_uInt8 fUnknown2:4;
+
+ sal_uInt8 fUnknown3:8;
+
+ sal_uInt8 fUnknown4:7;
+ sal_uInt8 fWordWrap:1;
+
+ sal_uInt8 fUnknown5:4;
+ sal_uInt8 fAutoSize:1;
+ sal_uInt8 fUnknown6:3;
+
+ sal_uInt32 nCaptionLen;
+
+ sal_uInt16 nVertPos;
+ sal_uInt16 nHorzPos;
+
+ sal_uInt16 nMousePointer;
+ sal_uInt16 nPicture;
+ sal_uInt16 nAccelerator;
+ sal_uInt16 nIcon;
+
+ char *pCaption;
+
+ sal_uInt8 pIconHeader[20];
+ sal_uInt32 nIconLen;
+ sal_uInt8 *pIcon;
+
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen;
+ sal_uInt8 *pPicture;
+
+ bool mbTakeFocus;
+
+ static OCX_Control *Create() { return new OCX_CommandButton;}
+ using OCX_Control::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+
+};
+
+class OCX_ImageButton: public OCX_CommandButton
+{
+public:
+ OCX_ImageButton() {
+ aFontData.SetHasAlign(FALSE);
+ aFontData.SetHasFont(FALSE);
+ }
+ static OCX_Control *Create() { return new OCX_ImageButton;}
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+
+};
+
+class OCX_GroupBox: public OCX_Control
+{
+public:
+ OCX_GroupBox() : OCX_Control(String::CreateFromAscii("GroupBox")) {}
+ static OCX_Control *Create() { return new OCX_GroupBox;}
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+
+};
+
+class OCX_Label : public OCX_Control
+{
+public:
+ OCX_Label(OCX_Control* pParent = NULL ) : OCX_Control(rtl::OUString::createFromAscii("Label"), pParent ), fEnabled(1),
+ fLocked(0),fBackStyle(1),fWordWrap(1),
+ fAutoSize(0),nCaptionLen(0),nVertPos(1),nHorzPos(7),nMousePointer(0),
+ nBorderColor(0x80000006),nBorderStyle(0),nSpecialEffect(0),
+ nPicture(0),nAccelerator(0),nIcon(0),pCaption(0),nIconLen(0),pIcon(0),
+ nPictureLen(0),pPicture(0)
+ {
+ msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.FixedText");
+ msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlFixedTextModel");
+ mnForeColor = 0x80000008;
+ mnBackColor = 0x80000005;
+ aFontData.SetHasAlign(TRUE);
+ }
+
+ ~OCX_Label() {
+ if (pCaption) delete[] pCaption;
+ if (pIcon) delete[] pIcon;
+ if (pPicture) delete[] pPicture;
+ }
+ sal_Bool Read(SotStorageStream *pS);
+
+ /*sal_uInt8 for sal_uInt8 Word Struct*/
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt8 pBlockFlags[4];
+
+
+ sal_uInt8 fUnknown1:1;
+ sal_uInt8 fEnabled:1;
+ sal_uInt8 fLocked:1;
+ sal_uInt8 fBackStyle:1;
+ sal_uInt8 fUnknown2:4;
+
+ sal_uInt8 fUnknown3:8;
+
+ sal_uInt8 fUnknown4:7;
+ sal_uInt8 fWordWrap:1;
+
+ sal_uInt8 fUnknown5:4;
+ sal_uInt8 fAutoSize:1;
+ sal_uInt8 fUnknown6:3;
+
+ sal_uInt32 nCaptionLen;
+ sal_uInt16 nVertPos;
+ sal_uInt16 nHorzPos;
+ sal_uInt8 nMousePointer;
+ sal_uInt32 nBorderColor;
+ sal_uInt16 nBorderStyle;
+ sal_uInt16 nSpecialEffect;
+ sal_uInt16 nPicture;
+ sal_uInt16 nAccelerator;
+ sal_uInt16 nIcon;
+
+ char *pCaption;
+
+ sal_uInt8 pIconHeader[20];
+ sal_uInt32 nIconLen;
+ sal_uInt8 *pIcon;
+
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen;
+ sal_uInt8 *pPicture;
+
+ static OCX_Control *Create() { return new OCX_Label;}
+
+ using OCX_Control::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+
+ sal_Bool Export(SotStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+ sal_Bool WriteContents(SotStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize);
+
+};
+
+
+class OCX_ProgressBar : public OCX_Control
+{
+public:
+ explicit OCX_ProgressBar();
+
+ static OCX_Control* Create();
+
+ virtual sal_Bool Read( SvStorageStream *pS );
+ using OCX_Control::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ // No Font record
+ virtual sal_Bool ReadFontData(SvStorageStream* /*pS*/) { return sal_True; }
+private:
+ sal_Int32 nMin;
+ sal_Int32 nMax;
+ bool bFixedSingle;
+ bool bEnabled;
+ bool b3d;
+};
+
+class OCX_SpinButton : public OCX_Control
+{
+public:
+ explicit OCX_SpinButton();
+
+ static OCX_Control* Create();
+
+ virtual sal_Bool Read( SvStorageStream *pS );
+
+ virtual sal_Bool ReadFontData( SvStorageStream *pS );
+
+ using OCX_Control::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ //Export exports a control as an OLE style storage stream tree
+ virtual sal_Bool Export( SvStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize );
+
+ //WriteContents writes the contents of a contents stream, for
+ //the Excel export you cannot use Export, only WriteContents instead
+ virtual sal_Bool WriteContents( SvStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize );
+
+protected:
+ void UpdateInt32Property(
+ sal_Int32& rnCoreValue, sal_Int32 nNewValue,
+ sal_Int32 nBlockFlag );
+
+ void GetInt32Property(
+ sal_Int32& rnCoreValue,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet >& rxPropSet,
+ const rtl::OUString& rPropName,
+ sal_Int32 nBlockFlag );
+
+ void UpdateBoolProperty(
+ bool& rbCoreValue, bool bNewValue,
+ sal_Int32 nBlockFlag );
+
+ void GetBoolProperty(
+ bool& rbCoreValue,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet >& rxPropSet,
+ const rtl::OUString& rPropName,
+ sal_Int32 nBlockFlag );
+
+ /** Writes the data from own members to stream. */
+ sal_Bool WriteData( SvStream& rStrm ) const;
+
+ sal_Int32 mnBlockFlags;
+ sal_Int32 mnValue;
+ sal_Int32 mnMin;
+ sal_Int32 mnMax;
+ sal_Int32 mnSmallStep;
+ sal_Int32 mnPageStep;
+ sal_Int32 mnOrient;
+ sal_Int32 mnDelay;
+ bool mbEnabled;
+ bool mbLocked;
+ bool mbPropThumb;
+};
+
+class OCX_ScrollBar : public OCX_SpinButton
+{
+public:
+ explicit OCX_ScrollBar();
+
+ static OCX_Control* Create();
+
+ using OCX_Control::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+
+ //Export exports a control as an OLE style storage stream tree
+ virtual sal_Bool Export( SvStorageRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize );
+
+ //WriteContents writes the contents of a contents stream, for
+ //the Excel export you cannot use Export, only WriteContents instead
+ virtual sal_Bool WriteContents( SvStorageStreamRef &rObj,
+ const com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet,
+ const com::sun::star::awt::Size& rSize );
+};
+
+#endif
diff --git a/filter/inc/filter/msfilter/msoleexp.hxx b/filter/inc/filter/msfilter/msoleexp.hxx
new file mode 100644
index 000000000000..8053928780f4
--- /dev/null
+++ b/filter/inc/filter/msfilter/msoleexp.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msoleexp.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * 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 _MSOLEEXP_HXX
+#define _MSOLEEXP_HXX
+
+#include <com/sun/star/uno/Reference.h>
+#include "filter/msfilter/msfilterdllapi.h"
+
+// for the CreateSdrOLEFromStorage we need the information, how we handle
+// convert able OLE-Objects - this ist stored in
+#define OLE_STARMATH_2_MATHTYPE 0x0001
+#define OLE_STARWRITER_2_WINWORD 0x0002
+#define OLE_STARCALC_2_EXCEL 0x0004
+#define OLE_STARIMPRESS_2_POWERPOINT 0x0008
+
+class SotStorage;
+
+#include <svtools/embedhlp.hxx>
+
+class MSFILTER_DLLPUBLIC SvxMSExportOLEObjects
+{
+ UINT32 nConvertFlags;
+public:
+ SvxMSExportOLEObjects( UINT32 nCnvrtFlgs ) : nConvertFlags(nCnvrtFlgs) {}
+
+ void SetFlags( UINT32 n ) { nConvertFlags = n; }
+ UINT32 GetFlags() const { return nConvertFlags; }
+
+ void ExportOLEObject( svt::EmbeddedObjectRef& rObj, SotStorage& rDestStg );
+ void ExportOLEObject( const com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject>& rObj, SotStorage& rDestStg );
+};
+
+
+
+#endif
+
diff --git a/filter/inc/filter/msfilter/svdfppt.hxx b/filter/inc/filter/msfilter/svdfppt.hxx
new file mode 100644
index 000000000000..e8c02d5da7d9
--- /dev/null
+++ b/filter/inc/filter/msfilter/svdfppt.hxx
@@ -0,0 +1,1443 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svdfppt.hxx,v $
+ * $Revision: 1.7.6.1 $
+ *
+ * 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 _SVDFPPT_HXX
+#define _SVDFPPT_HXX
+
+#ifndef SVX_LIGHT
+
+#include <tools/solar.h>
+#include <svl/svarray.hxx>
+#include <tools/string.hxx>
+#include <tools/gen.hxx>
+#include <tools/color.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/numitem.hxx>
+#include <svx/editdata.hxx>
+#include <filter/msfilter/msdffimp.hxx> // Escher-Grafikimport
+#include <filter/msfilter/msocximex.hxx>
+#include <filter/msfilter/msfiltertracer.hxx>
+#include <svx/eeitem.hxx>
+#define ITEMID_FIELD EE_FEATURE_FIELD
+#include <svx/flditem.hxx>
+#undef ITEMID_FIELD
+#include "filter/msfilter/msfilterdllapi.h"
+#include <vcl/font.hxx>
+#include <vector>
+#include <boost/optional.hpp>
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SdrModel;
+class SdPage;
+class SdrPage;
+class SdrObject;
+class SvStream;
+class Polygon;
+class PolyPolygon;
+class SfxItemSet;
+class Outliner;
+class Graphic;
+class SvxMSDffManager;
+class PptTextMetaCharList;
+class PPTTextObj;
+class DffRecordHeader;
+struct PptCharAttrSet;
+class SvxBulletItem;
+
+#define PPT_IMPORTFLAGS_NO_TEXT_ASSERT 1
+
+struct MSFILTER_DLLPUBLIC PptCurrentUserAtom
+{
+ sal_uInt32 nMagic;
+ sal_uInt32 nCurrentUserEdit;
+ sal_uInt16 nDocFileVersion;
+ sal_uInt8 nMajorVersion;
+ sal_uInt8 nMinorVersion;
+ String aCurrentUser;
+
+public:
+
+ PptCurrentUserAtom() : nMagic ( 0 ),
+ nCurrentUserEdit ( 0 ),
+ nDocFileVersion ( 0 ),
+ nMajorVersion ( 0 ),
+ nMinorVersion ( 0 ) {}
+
+ MSFILTER_DLLPUBLIC friend SvStream& operator>>( SvStream& rIn, PptCurrentUserAtom& rAtom );
+};
+
+struct MSFILTER_DLLPUBLIC PowerPointImportParam
+{
+ SvStream& rDocStream;
+ sal_uInt32 nImportFlags;
+ MSFilterTracer* pTracer;
+ PptCurrentUserAtom aCurrentUserAtom;
+
+ PowerPointImportParam( SvStream& rDocStream, sal_uInt32 nImportFlags, MSFilterTracer* pTracer );
+};
+
+struct SdHyperlinkEntry
+{
+ sal_uInt32 nIndex;
+ sal_Int32 nPrivate1;
+ sal_Int32 nPrivate2;
+ sal_Int32 nPrivate3;
+ sal_Int32 nInfo;
+ String aTarget;
+ String aSubAdress;
+
+ sal_Int32 nStartPos;
+ sal_Int32 nEndPos;
+
+ String aConvSubString;
+ ESelection aESelection;
+ sal_Bool bSelection;
+};
+
+// Hilfsklasse zum Einlesen der PPT InteractiveInfoAtom
+struct MSFILTER_DLLPUBLIC PptInteractiveInfoAtom
+{
+ UINT32 nSoundRef;
+ UINT32 nExHyperlinkId;
+ UINT8 nAction;
+ UINT8 nOleVerb;
+ UINT8 nJump;
+ UINT8 nFlags;
+ UINT8 nHyperlinkType;
+
+ // unknown, da Gesamtgroesse 16 ist
+ UINT8 nUnknown1;
+ UINT8 nUnknown2;
+ UINT8 nUnknown3;
+
+public:
+
+ MSFILTER_DLLPUBLIC friend SvStream& operator>>( SvStream& rIn, PptInteractiveInfoAtom& rAtom );
+};
+
+enum PptPageKind { PPT_MASTERPAGE, PPT_SLIDEPAGE, PPT_NOTEPAGE };
+
+enum PptPageFormat
+{ PPTPF_SCREEN, //
+ PPTPF_USLETTER, // 8.5x11"
+ PPTPF_A4, // 210x297mm
+ PPTPF_35MMDIA, // DIA
+ PPTPF_OVERHEAD, //
+ PPTPF_CUSTOM
+};
+
+// Werte fuer den ULONG im PPT_PST_TextHeaderAtom
+enum PPT_TextHeader
+{
+ PPTTH_TITLE,
+ PPTTH_BODY,
+ PPTTH_NOTES,
+ PPTTH_NOTUSED,
+ PPTTH_OTHER, // Text in a Shape
+ PPTTH_CENTERBODY, // Subtitle in Title-Slide
+ PPTTH_CENTERTITLE, // Title in Title-Slide
+ PPTTH_HALFBODY, // Body in two-column slide
+ PPTTH_QUARTERBODY // Body in four-body slide
+};
+
+#define TSS_TYPE_PAGETITLE (0)
+#define TSS_TYPE_BODY (1)
+#define TSS_TYPE_NOTES (2)
+#define TSS_TYPE_UNUSED (3)
+#define TSS_TYPE_TEXT_IN_SHAPE (4)
+#define TSS_TYPE_SUBTITLE (5)
+#define TSS_TYPE_TITLE (6)
+#define TSS_TYPE_HALFBODY (7)
+#define TSS_TYPE_QUARTERBODY (8)
+
+// Inventor-Id fuer PPT UserData
+const UINT32 PPTInventor =UINT32('P')*0x00000001+
+ UINT32('P')*0x00000100+
+ UINT32('T')*0x00010000+
+ UINT32('0')*0x01000000;
+
+// Object-Ids fuer StarDraw UserData
+#define PPT_OBJECTINFO_ID (1)
+
+struct MSFILTER_DLLPUBLIC PptDocumentAtom
+{
+ Size aSlidesPageSize; // Seitengroesse der Slides in 576DPI
+ Size aNotesPageSize; // Seitengroesse der Notes in 576DPI
+ // RatioAtom erstmal weggelassen
+ UINT32 nNotesMasterPersist; // 0=nicht vorhanden
+ UINT32 nHandoutMasterPersist; // 0=nicht vorhanden
+ UINT16 n1stPageNumber; // Seitennummer des ersten Slides
+ PptPageFormat eSlidesPageFormat; // Seitenformat der Slides
+ sal_Bool bEmbeddedTrueType : 1; // TrueType direkt im File?
+ sal_Bool bTitlePlaceholdersOmitted : 1;
+ sal_Bool bRightToLeft : 1;
+ sal_Bool bShowComments : 1;
+
+public:
+
+ Size GetPageSize( const Size& rSiz ) const;
+ Size GetSlidesPageSize() const { return GetPageSize( aSlidesPageSize ); }
+ Size GetNotesPageSize() const { return GetPageSize( aNotesPageSize ); }
+
+ friend SvStream& operator>>( SvStream& rIn, PptDocumentAtom& rAtom );
+};
+
+struct PptSlideLayoutAtom
+{
+ INT32 eLayout; // 0..18
+ BYTE aPlaceholderId[ 8 ];
+ ULONG aPlacementId[ 8 ];
+
+public:
+
+ PptSlideLayoutAtom() { Clear(); }
+ void Clear();
+
+ // Das SlideLayoutAtom wird ohne Header eingelesen!
+ friend SvStream& operator>>( SvStream& rIn, PptSlideLayoutAtom& rAtom );
+};
+
+struct PptSlideAtom
+{
+ PptSlideLayoutAtom aLayout;
+ UINT32 nMasterId;
+ UINT32 nNotesId;
+ UINT16 nFlags;
+
+public:
+
+ PptSlideAtom() { Clear(); }
+ void Clear();
+
+ friend SvStream& operator>>(SvStream& rIn, PptSlideAtom& rAtom);
+};
+
+struct PptSlidePersistAtom
+{
+ UINT32 nPsrReference;
+ UINT32 nFlags;
+ UINT32 nNumberTexts;
+ UINT32 nSlideId;
+ UINT32 nReserved; // we will use nReserved temporarly to set the offset to SSSlideInfoAtom ( if possible )
+
+public:
+
+ PptSlidePersistAtom() { Clear(); }
+ void Clear();
+
+ friend SvStream& operator>>(SvStream& rIn, PptSlidePersistAtom& rAtom);
+};
+
+struct PptNotesAtom
+{
+ UINT32 nSlideId;
+ UINT16 nFlags;
+
+public:
+
+ PptNotesAtom() { Clear(); }
+ void Clear();
+
+ friend SvStream& operator>>(SvStream& rIn, PptNotesAtom& rAtom);
+};
+
+struct PptColorSchemeAtom
+{
+ BYTE aData[32];
+
+public:
+ PptColorSchemeAtom () { Clear(); }
+ void Clear();
+ Color GetColor( USHORT nNum ) const;
+
+ friend SvStream& operator>>(SvStream& rIn, PptColorSchemeAtom& rAtom);
+};
+
+struct PptFontEntityAtom
+{
+ String aName;
+ double fScaling;
+ sal_uInt8 lfClipPrecision;
+ sal_uInt8 lfQuality;
+
+ sal_uInt32 nUniqueFontId; // not used anymore
+ CharSet eCharSet;
+ FontFamily eFamily;
+ FontPitch ePitch;
+ sal_Bool bAvailable;
+
+ friend SvStream& operator>>(SvStream& rIn, PptFontEntityAtom& rAtom);
+};
+
+class PptFontCollection;
+struct PptUserEditAtom
+{
+ DffRecordHeader aHd;
+ INT32 nLastSlideID; // ID of last visible slide
+ UINT32 nVersion; // This is major/minor/build which did the edit
+ UINT32 nOffsetLastEdit; // File offset of prev PptUserEditAtom
+ UINT32 nOffsetPersistDirectory; // Offset to PersistPtrs for this file version.
+ UINT32 nDocumentRef;
+ UINT32 nMaxPersistWritten; // Gesamtanzahl der Persisteintraege bis hierher.
+ INT16 eLastViewType; // enum view type
+
+public:
+
+ PptUserEditAtom() : nOffsetPersistDirectory( 0 ) {}
+
+ friend SvStream& operator>>( SvStream& rIn, PptUserEditAtom& rAtom );
+};
+
+struct PptOEPlaceholderAtom
+{
+ UINT32 nPlacementId;
+ BYTE nPlaceholderId;
+ BYTE nPlaceholderSize; // 0=Full size, 1=Half size, 2=Quarter of Slide
+
+public:
+
+ PptOEPlaceholderAtom() { Clear(); }
+ void Clear();
+
+ friend SvStream& operator>>( SvStream& rIn, PptOEPlaceholderAtom& rAtom );
+};
+
+struct ProcessData;
+struct PPTStyleSheet;
+struct HeaderFooterEntry;
+struct PptSlidePersistEntry
+{
+ PptSlidePersistAtom aPersistAtom;
+ PptSlideAtom aSlideAtom;
+ PptNotesAtom aNotesAtom;
+ PptColorSchemeAtom aColorScheme; // each slide includes this colorscheme atom
+ PPTStyleSheet* pStyleSheet; // stylesheet of this page ( only in masterpages ), since XP supports more than one masterpage
+
+ sal_uInt32 HeaderFooterOfs[ 4 ]; // containing the ofs to the placeholder (only masterpage)
+ HeaderFooterEntry* pHeaderFooterEntry;
+ SvxMSDffSolverContainer* pSolverContainer;
+ sal_uInt32 nSlidePersistStartOffset;// is an array to the end of the SlidePersistAtom of this page, TextHeaderAtom is following
+ sal_uInt32 nSlidePersistEndOffset;
+ sal_uInt32 nBackgroundOffset; // fileoffset
+ sal_uInt32 nDrawingDgId; // valid, if not -1
+ sal_uInt32* pPresentationObjects; // if valid, this is a pointer to an array that includes the offsets to the presentation objects
+ // on this masterpage for each instance ( 0 - 8 );
+ SdrObject* pBObj;
+ sal_Bool bBObjIsTemporary;
+
+ void* pDummy2;
+ PptPageKind ePageKind; //
+
+ sal_Bool bNotesMaster : 1; // fuer NotesMaster
+ sal_Bool bHandoutMaster : 1; // fuer HandoutMaster
+ sal_Bool bStarDrawFiller : 1; // speziell fuer StarDraw
+public:
+ PptSlidePersistEntry();
+ ~PptSlidePersistEntry();
+ UINT32 GetSlideId() const { return aPersistAtom.nSlideId; }
+};
+
+SV_DECL_PTRARR_DEL(_PptSlidePersistList,PptSlidePersistEntry*,16,16)
+
+#define PPTSLIDEPERSIST_ENTRY_NOTFOUND 0xFFFF
+
+class MSFILTER_DLLPUBLIC PptSlidePersistList: public _PptSlidePersistList
+{
+
+ public:
+
+ USHORT FindPage( UINT32 nId ) const;
+};
+
+class SfxObjectShell;
+struct PPTOleEntry
+{
+ sal_uInt32 nId; // OleId
+ sal_uInt32 nPersistPtr; // PersistPtr
+ sal_uInt32 nRecHdOfs; // points to the record header: ExObjListHd
+ SfxObjectShell* pShell;
+ sal_uInt16 nType; // maybe PPT_PST_ExEmbed or PPT_PST_ExControl
+ sal_uInt32 nAspect; // the aspect of the OLE object
+
+ PPTOleEntry( sal_uInt32 nid, sal_uInt32 nOfs, SfxObjectShell* pSh, sal_uInt16 nT, sal_uInt32 nAsp ) :
+ nId ( nid ),
+ nRecHdOfs ( nOfs ),
+ pShell ( pSh ),
+ nType ( nT ),
+ nAspect ( nAsp ) {}
+};
+
+struct PptExOleObjAtom
+{
+ UINT32 nAspect;
+ UINT32 nDummy1;
+ UINT32 nId;
+ UINT32 nDummy2;
+ UINT32 nPersistPtr;
+ UINT32 nDummy4;
+
+public:
+
+ friend SvStream& operator>>( SvStream& rIn, PptExOleObjAtom& rAtom );
+};
+
+class PPTExtParaProv;
+class MSFILTER_DLLPUBLIC SdrEscherImport : public SvxMSDffManager
+{
+
+protected:
+
+ friend class PPTTextObj;
+ friend class PPTPortionObj;
+ friend struct PPTStyleTextPropReader;
+ friend class ImplSdPPTImport;
+
+ PptDocumentAtom aDocAtom;
+ DffRecordManager aDocRecManager; // contains all first level container and atoms of the document container
+
+ List aHFMasterList;
+ List aOleObjectList; // contains PPTOleEntrys
+
+ PptFontCollection* pFonts;
+
+ sal_uInt32 nStreamLen;
+ sal_uInt16 nTextStylesIndex;
+
+ CharSet eCharSetSystem;
+
+ sal_Bool bWingdingsChecked : 1;
+ sal_Bool bWingdingsAvailable : 1;
+ sal_Bool bMonotypeSortsChecked : 1;
+ sal_Bool bMonotypeSortsAvailable : 1;
+ sal_Bool bTimesNewRomanChecked : 1;
+ sal_Bool bTimesNewRomanAvailable : 1;
+
+ sal_Bool ReadString( String& rStr ) const;
+ // nur fuer PowerPoint-Filter:
+ virtual const PptSlideLayoutAtom* GetSlideLayoutAtom() const;
+ void CheckWingdings() const;
+ void CheckMonotypeSorts() const;
+ void CheckTimesNewRoman() const;
+
+public:
+
+ PowerPointImportParam& rImportParam;
+
+ void* pSdrEscherDummy1;
+ void* pSdrEscherDummy2;
+ void* pSdrEscherDummy3;
+ void* pSdrEscherDummy4;
+
+ SdrEscherImport( PowerPointImportParam&, const String& rBaseURL );
+ virtual ~SdrEscherImport();
+ virtual FASTBOOL GetColorFromPalette( USHORT nNum, Color& rColor ) const;
+ virtual BOOL SeekToShape( SvStream& rSt, void* pClientData, UINT32 nId ) const;
+ PptFontEntityAtom* GetFontEnityAtom( UINT32 nNum ) const;
+ CharSet GetCharSet( UINT32 nNum ) const;
+ BOOL IsFontAvailable( UINT32 nNum ) const;
+ void RecolorGraphic( SvStream& rSt, sal_uInt32 nRecLen, Graphic& rGraph );
+ using SvxMSDffManager::ReadObjText;
+ virtual SdrObject* ReadObjText( PPTTextObj* pTextObj, SdrObject* pObj, SdPage* pPage ) const;
+ virtual SdrObject* ProcessObj( SvStream& rSt, DffObjData& rData, void* pData, Rectangle& rTextRect, SdrObject* pObj );
+ virtual void ProcessClientAnchor2( SvStream& rSt, DffRecordHeader& rHd, void* pData, DffObjData& rObj );
+ void ImportHeaderFooterContainer( DffRecordHeader& rHeader, HeaderFooterEntry& rEntry );
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define SD_HEADERFOOTER_DATE 1
+#define SD_HEADERFOOTER_TODAYDATE 2
+#define SD_HEADERFOOTER_USERDATE 4
+#define SD_HEADERFOOTER_SLIDENUMBER 8
+#define SD_HEADERFOOTER_HEADER 16
+#define SD_HEADERFOOTER_FOOTER 32
+
+class SvxFieldItem;
+struct MSFILTER_DLLPUBLIC PPTFieldEntry
+{
+ UINT16 nPos;
+ UINT16 nTextRangeEnd;
+ SvxFieldItem* pField1;
+ SvxFieldItem* pField2;
+ String* pString;
+
+ PPTFieldEntry() : nPos( 0 ), nTextRangeEnd( 0 ), pField1( NULL ), pField2( NULL ), pString( NULL ) {};
+ ~PPTFieldEntry();
+
+ void SetDateTime( UINT32 nType );
+
+ // converting PPT date time format:
+ static void GetDateTime( const sal_uInt32 nVal, SvxDateFormat& eDateFormat, SvxTimeFormat& eTimeFormat );
+};
+
+struct MSFILTER_DLLPUBLIC HeaderFooterEntry
+{
+ const PptSlidePersistEntry* pMasterPersist;
+ String pPlaceholder[ 4 ];
+ sal_uInt32 nAtom;
+
+ sal_uInt32 GetMaskForInstance( UINT32 nInstance );
+ sal_uInt32 IsToDisplay( UINT32 nInstance );
+ sal_uInt32 NeedToImportInstance( const sal_uInt32 nInstance, const PptSlidePersistEntry& rSlidePersist );
+
+ HeaderFooterEntry( const PptSlidePersistEntry* pMaster = NULL );
+ ~HeaderFooterEntry();
+};
+
+struct ProcessData
+{
+ PptSlidePersistEntry& rPersistEntry;
+ SdPage* pPage;
+ List* pBackgroundColoredObjects;
+ sal_uInt32* pTableRowProperties;
+
+ ProcessData( PptSlidePersistEntry& rP, SdPage* pP ) :
+ rPersistEntry ( rP ),
+ pPage ( pP ),
+ pBackgroundColoredObjects ( NULL ),
+ pTableRowProperties ( NULL ) {};
+ ~ProcessData() { delete pBackgroundColoredObjects; delete[] pTableRowProperties; };
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SdrTextObj;
+class SfxObjectShell;
+class MSFILTER_DLLPUBLIC SdrPowerPointImport : public SdrEscherImport
+{
+
+protected:
+
+ friend class PPTTextObj;
+ friend class PPTExtParaProv;
+ friend struct PPTStyleSheet;
+ friend class PPTNumberFormatCreator;
+
+ BOOL bOk;
+ PptUserEditAtom aUserEditAtom;
+ PptColorSchemeAtom aPageColors;
+ List aHyperList;
+ UINT32* pPersistPtr;
+ ULONG nPersistPtrAnz;
+
+ const PPTStyleSheet* pPPTStyleSheet; // this is the current stylesheet;
+ const PPTStyleSheet* pDefaultSheet; // this is a sheet we are using if no masterpage can be found, but that should
+ // never happen just preventing a crash
+ PptSlidePersistList* pMasterPages;
+ PptSlidePersistList* pSlidePages;
+ PptSlidePersistList* pNotePages;
+ USHORT nAktPageNum;
+ ULONG nDocStreamPos;
+ USHORT nPageColorsNum;
+ PptPageKind ePageColorsKind;
+ PptPageKind eAktPageKind;
+
+protected:
+
+ sal_Bool SeekToAktPage(DffRecordHeader* pRecHd=NULL) const;
+ sal_Bool SeekToDocument(DffRecordHeader* pRecHd=NULL) const;
+ sal_Bool SeekToContentOfProgTag( sal_Int32 nVersion, SvStream& rSt, const DffRecordHeader& rProgTagBinaryDataHd,
+ DffRecordHeader& rContentHd );
+ virtual SdrObject* ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pText, SdPage* pPage, SfxStyleSheet*, SfxStyleSheet** ) const;
+ using SdrEscherImport::ReadObjText;
+ virtual SdrObject* ReadObjText( PPTTextObj* pTextObj, SdrObject* pObj, SdPage* pPage ) const;
+ // --> OD 2004-12-14 #i32596# - new parameter <_nCalledByGroup>, which
+ // indicates, if the OLE object is imported inside a group object.
+ virtual SdrObject* ImportOLE( long nOLEId,
+ const Graphic& rGraf,
+ const Rectangle& rBoundRect,
+ const Rectangle& rVisArea,
+ const int _nCalledByGroup,
+ sal_Int64 nAspect ) const;
+ // <--
+ SvMemoryStream* ImportExOleObjStg( UINT32 nPersistPtr, UINT32& nOleId ) const;
+ SdrPage* MakeBlancPage(sal_Bool bMaster) const;
+ sal_Bool ReadFontCollection();
+ sal_Bool ForceFontCollection() const { return pFonts!=NULL?TRUE:((SdrPowerPointImport*)this)->ReadFontCollection(); }
+ PptSlidePersistList* GetPageList(PptPageKind ePageKind) const;
+ UINT32 GetAktPageId();
+ UINT32 GetMasterPageId(USHORT nPageNum, PptPageKind ePageKind) const;
+ UINT32 GetNotesPageId(USHORT nPageNum ) const;
+ SdrOutliner* GetDrawOutliner( SdrTextObj* pSdrText ) const;
+ void SeekOle( SfxObjectShell* pShell, sal_uInt32 nFilterOptions );
+
+public:
+ SdrPowerPointImport( PowerPointImportParam&, const String& rBaseURL );
+ virtual ~SdrPowerPointImport();
+ USHORT GetPageCount( PptPageKind eKind = PPT_SLIDEPAGE ) const;
+ void SetPageNum( USHORT nPageNum, PptPageKind = PPT_SLIDEPAGE );
+ USHORT GetPageNum() const { return nAktPageNum; }
+ PptPageKind GetPageKind() const { return eAktPageKind; }
+ Size GetPageSize() const;
+ SdrObject* ImportPageBackgroundObject( const SdrPage& rPage, sal_uInt32& nBgFileOffset, sal_Bool bForce );
+ sal_Bool IsNoteOrHandout( USHORT nPageNum, PptPageKind ePageKind ) const;
+ sal_Bool HasMasterPage( USHORT nPageNum, PptPageKind ePageKind = PPT_SLIDEPAGE ) const;
+ USHORT GetMasterPageIndex( USHORT nPageNum, PptPageKind ePageKind = PPT_SLIDEPAGE ) const;
+
+ void ImportPage( SdrPage* pPage, const PptSlidePersistEntry* pMasterPersist = NULL );
+ virtual FASTBOOL GetColorFromPalette(USHORT nNum, Color& rColor) const;
+ virtual BOOL SeekToShape( SvStream& rSt, void* pClientData, UINT32 nId ) const;
+ sal_Unicode PPTSubstitute( UINT16 nFont, sal_Unicode nChar,
+ UINT32& nMappedFontId, Font& rFont, char nDefault ) const;
+ const PptDocumentAtom& GetDocumentAtom() const { return aDocAtom; }
+ virtual const PptSlideLayoutAtom* GetSlideLayoutAtom() const;
+ SdrObject* CreateTable( SdrObject* pGroupObject, sal_uInt32* pTableArry, SvxMSDffSolverContainer* ) const;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+struct PPTTextCharacterStyleAtomInterpreter
+{
+ sal_uInt16 nFlags1;
+ sal_uInt16 nFlags2;
+ sal_uInt16 nFlags3;
+ sal_Int32 n1;
+ sal_uInt16 nFontHeight;
+ sal_Int32 nFontColor;
+
+ PPTTextCharacterStyleAtomInterpreter();
+ ~PPTTextCharacterStyleAtomInterpreter();
+
+ sal_Bool Read( SvStream& rIn, const DffRecordHeader& rRecHd );
+
+ sal_uInt32 GetColor( sal_uInt32 nDefault );
+};
+
+struct PPTTextParagraphStyleAtomInterpreter
+{
+ sal_Bool bValid;
+ sal_Bool bForbiddenRules;
+ sal_Bool bHangingPunctuation;
+ sal_Bool bLatinTextWrap;
+
+ PPTTextParagraphStyleAtomInterpreter();
+ ~PPTTextParagraphStyleAtomInterpreter();
+
+ sal_Bool Read( SvStream& rIn, const DffRecordHeader& rRecHd );
+};
+
+struct PPTTextSpecInfo
+{
+ sal_uInt32 nCharIdx;
+ sal_uInt16 nLanguage[ 3 ];
+ sal_uInt16 nDontKnow;
+
+ PPTTextSpecInfo( sal_uInt32 nCharIdx );
+ ~PPTTextSpecInfo();
+};
+
+struct PPTTextSpecInfoAtomInterpreter
+{
+ sal_Bool bValid;
+ List aList;
+
+ PPTTextSpecInfoAtomInterpreter();
+ ~PPTTextSpecInfoAtomInterpreter();
+
+ sal_Bool Read( SvStream& rIn, const DffRecordHeader& rRecHd,
+ sal_uInt16 nRecordType, const PPTTextSpecInfo* pTextSpecDefault = NULL );
+
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define PPT_STYLESHEETENTRYS 9
+
+struct PPTExtParaLevel
+{
+ sal_uInt32 mnExtParagraphMask;
+ sal_uInt16 mnBuBlip;
+ sal_uInt16 mnHasAnm;
+ sal_uInt32 mnAnmScheme;
+ sal_uInt32 mpfPP10Ext;
+ sal_uInt32 mnExtCharacterMask;
+ sal_uInt32 mcfPP10Ext;
+ sal_Bool mbSet;
+
+ PPTExtParaLevel();
+ friend SvStream& operator>>( SvStream& rIn, PPTExtParaLevel& rL );
+};
+
+struct PPTExtParaSheet
+{
+ PPTExtParaLevel aExtParaLevel[ 5 ];
+};
+
+struct PPTBuGraEntry
+{
+ UINT32 nInstance;
+ Graphic aBuGra;
+
+ PPTBuGraEntry( Graphic& rGraphic, UINT32 nInstance );
+};
+
+class PPTExtParaProv
+{
+ List aBuGraList;
+
+ public :
+ BOOL bStyles;
+ BOOL bGraphics;
+ DffRecordManager aExtendedPresRules;
+
+ PPTExtParaSheet aExtParaSheet[ PPT_STYLESHEETENTRYS ];
+
+ BOOL GetGraphic( UINT32 nInstance, Graphic& rGraphic ) const;
+
+ PPTExtParaProv( SdrPowerPointImport& rManager, SvStream& rSt,
+ const DffRecordHeader* pMainMasterHd );
+ ~PPTExtParaProv();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+struct PPTCharLevel
+{
+ Color mnFontColorInStyleSheet;
+ sal_uInt32 mnFontColor;
+ sal_uInt16 mnFlags;
+ sal_uInt16 mnFont;
+ sal_uInt16 mnAsianOrComplexFont;
+ sal_uInt16 mnFontHeight;
+ sal_uInt16 mnEscapement;
+};
+
+struct PPTCharSheet
+{
+ PPTCharLevel maCharLevel[ 5 ];
+
+ PPTCharSheet( sal_uInt32 nInstance );
+ PPTCharSheet( const PPTCharSheet& rCharSheet );
+
+ void Read( SvStream& rIn, sal_Bool bMasterStyle, sal_uInt32 nLevel, sal_Bool bFirst );
+};
+
+struct PPTParaLevel
+{
+ sal_uInt16 mnBuFlags;
+ sal_uInt16 mnBulletChar;
+ sal_uInt16 mnBulletFont;
+ sal_uInt16 mnBulletHeight;
+ sal_uInt32 mnBulletColor;
+
+ sal_uInt16 mnAdjust;
+ sal_uInt16 mnLineFeed;
+ sal_uInt16 mnUpperDist;
+ sal_uInt16 mnLowerDist;
+ sal_uInt16 mnTextOfs;
+ sal_uInt16 mnBulletOfs;
+ sal_uInt16 mnDefaultTab;
+ sal_uInt16 mnAsianLineBreak; // bit0: use asian rules for first and last character
+ // 1: do not wrap latin text in the middle of the word
+ // 2: allow hanging punctuation
+ sal_uInt16 mnBiDi;
+};
+
+struct PPTParaSheet
+{
+ public:
+
+ PPTParaLevel maParaLevel[ 5 ];
+
+ PPTParaSheet( sal_uInt32 nInstance );
+ PPTParaSheet( const PPTParaSheet& rParaSheet );
+
+ void Read( SdrPowerPointImport& rMan, SvStream& rIn, sal_Bool bMasterStyle,
+ sal_uInt32 nLevel, sal_Bool bFirst );
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class PPTParagraphObj;
+class PPTNumberFormatCreator
+{
+ UINT32 nIsBullet;
+ UINT32 nBulletChar;
+ UINT32 nBulletFont;
+ UINT32 nBulletHeight;
+ UINT32 nBulletColor;
+ UINT32 nTextOfs;
+ UINT32 nBulletOfs;
+
+ void ImplGetNumberFormat( SdrPowerPointImport& rMan, SvxNumberFormat& rNumberFormat, UINT32 nLevel );
+ BOOL ImplGetExtNumberFormat( SdrPowerPointImport& rMan, SvxNumberFormat& rNumberFormat, UINT32 nLevel,
+ UINT32 nInstance, UINT32 nInstanceInSheet, boost::optional< sal_Int16 >& rStartNumbering,
+ UINT32 nFontHeight, PPTParagraphObj* pPara );
+
+ protected :
+
+ PPTNumberFormatCreator( PPTExtParaProv* );
+ ~PPTNumberFormatCreator();
+
+ public :
+
+ PPTExtParaProv* pExtParaProv;
+
+ void GetNumberFormat( SdrPowerPointImport& rMan, SvxNumberFormat& rNumberFormat, UINT32 nLevel,
+ const PPTParaLevel& rParaLevel, const PPTCharLevel& rCharLevel, UINT32 nInstance );
+
+ BOOL GetNumberFormat( SdrPowerPointImport& rMan, SvxNumberFormat& rNumberFormat,
+ PPTParagraphObj* pPara, UINT32 nInstanceInSheet, boost::optional< sal_Int16 >& rStartNumbering );
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SvxNumBulletItem;
+struct PPTStyleSheet : public PPTNumberFormatCreator
+{
+ PPTTextSpecInfo maTxSI;
+ PPTCharSheet* mpCharSheet[ PPT_STYLESHEETENTRYS ];
+ PPTParaSheet* mpParaSheet[ PPT_STYLESHEETENTRYS ];
+ SvxNumBulletItem* mpNumBulletItem[ PPT_STYLESHEETENTRYS ];
+ void* mpDummy;
+
+ PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rSt, SdrPowerPointImport&,
+ const PPTTextCharacterStyleAtomInterpreter&, const PPTTextParagraphStyleAtomInterpreter&, const PPTTextSpecInfo& );
+ ~PPTStyleSheet();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+struct ImplPPTParaPropSet
+{
+ sal_uInt32 mnRefCount;
+
+ sal_uInt16 mnDepth;
+ sal_uInt32 mnAttrSet;
+ sal_uInt32 mnBulletColor;
+ sal_uInt16 mpArry[ 22 ];
+
+ sal_uInt32 mnExtParagraphMask;
+ sal_uInt32 mnAnmScheme;
+ sal_uInt16 mnHasAnm;
+ sal_uInt16 mnBuBlip;
+
+ sal_uInt32 nDontKnow1;
+ sal_uInt32 nDontKnow2;
+ sal_uInt16 nDontKnow2bit06;
+
+ ImplPPTParaPropSet(){ mnRefCount = 1; mnAttrSet = 0; mnExtParagraphMask = 0; mnDepth = 0; };
+};
+
+struct PPTParaPropSet
+{
+ sal_uInt32 mnOriginalTextPos;
+ ImplPPTParaPropSet* pParaSet;
+
+ PPTParaPropSet();
+ PPTParaPropSet( PPTParaPropSet& rParaPropSet );
+ ~PPTParaPropSet();
+
+ PPTParaPropSet& operator=( PPTParaPropSet& rParaPropSet );
+};
+
+struct ImplPPTCharPropSet
+{
+ sal_uInt32 mnRefCount;
+
+ sal_uInt32 mnAttrSet;
+ sal_uInt16 mnFlags;
+ sal_uInt32 mnColor;
+ sal_uInt16 mnFont;
+ sal_uInt16 mnAsianOrComplexFont;
+ sal_uInt16 mnANSITypeface;
+ sal_uInt16 mnFontHeight;
+ sal_uInt16 mnEscapement;
+ sal_uInt16 mnSymbolFont;
+
+ ImplPPTCharPropSet(){ mnRefCount = 1; mnAttrSet = 0; };
+};
+
+struct PPTCharPropSet
+{
+
+ sal_uInt32 mnOriginalTextPos;
+ sal_uInt32 mnParagraph;
+ String maString;
+ SvxFieldItem* mpFieldItem;
+ sal_uInt16 mnLanguage[ 3 ];
+
+ ImplPPTCharPropSet* pCharSet;
+
+ void SetFont( UINT16 nFont );
+ void SetColor( sal_uInt32 nColor );
+
+ PPTCharPropSet( sal_uInt32 nParagraph );
+ PPTCharPropSet( PPTCharPropSet& rCharPropSet );
+ PPTCharPropSet( PPTCharPropSet& rCharPropSet, sal_uInt32 nParagraph );
+ ~PPTCharPropSet();
+
+ PPTCharPropSet& operator=( PPTCharPropSet& rCharPropSet );
+
+ private :
+
+ void ImplMakeUnique();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+struct PPTTabEntry
+{
+ sal_uInt16 nOffset;
+ sal_uInt16 nStyle;
+};
+
+struct PPTRuler
+{
+ UINT32 nRefCount;
+
+ INT32 nFlags;
+ UINT16 nDefaultTab;
+ UINT16 nTextOfs[ 5 ];
+ UINT16 nBulletOfs[ 5 ];
+ PPTTabEntry* pTab;
+ UINT16 nTabCount;
+
+ PPTRuler();
+ ~PPTRuler();
+};
+
+struct PPTTextRulerInterpreter
+{
+ PPTRuler *mpImplRuler;
+
+ PPTTextRulerInterpreter();
+ PPTTextRulerInterpreter( PPTTextRulerInterpreter& rRuler );
+ PPTTextRulerInterpreter( UINT32 nFileOfs, SdrPowerPointImport&, DffRecordHeader& rHd, SvStream& rIn );
+ ~PPTTextRulerInterpreter();
+
+ sal_uInt16 GetTabOffsetByIndex( sal_uInt16 nIndex ) const { return mpImplRuler->pTab[ nIndex ].nOffset; };
+ sal_uInt16 GetTabStyleByIndex( sal_uInt16 nIndex ) const { return mpImplRuler->pTab[ nIndex ].nStyle; };
+ UINT16 GetTabCount() const { return mpImplRuler->nTabCount; };
+ BOOL GetDefaultTab( UINT32 nLevel, UINT16& nValue ) const;
+ BOOL GetTextOfs( UINT32 nLevel, UINT16& nValue ) const;
+ BOOL GetBulletOfs( UINT32 nLevel, UINT16& nValue ) const;
+
+ PPTTextRulerInterpreter& operator=( PPTTextRulerInterpreter& rRuler );
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define PPT_SPEC_NEWLINE 0x10000
+#define PPT_SPEC_SYMBOL 0x20000
+#define PPT_SPEC_USE_STARBATS 0x40000
+
+struct StyleTextProp9
+{
+ sal_uInt32 mnExtParagraphMask;
+ sal_uInt16 mnBuBlip;
+ sal_uInt16 mnHasAnm;
+ sal_uInt32 mnAnmScheme;
+ sal_uInt32 mpfPP10Ext;
+ sal_uInt32 mnExtCharacterMask;
+ sal_uInt32 mncfPP10Ext;
+ sal_uInt32 mnSpecialInfoMask;
+ sal_uInt32 mnPP10Ext;
+ sal_uInt16 mfBidi;
+
+ StyleTextProp9()
+ : mnExtParagraphMask( 0 )
+ , mnBuBlip( 0 )
+ , mnHasAnm( 0 )
+ , mnAnmScheme( 0 )
+ , mpfPP10Ext( 0 )
+ , mnExtCharacterMask( 0 )
+ , mncfPP10Ext( 0 )
+ , mnSpecialInfoMask( 0 )
+ , mnPP10Ext( 0 )
+ , mfBidi( 0 )
+ {
+ }
+ void Read( SvStream& rSt );
+};
+
+struct PPTStyleTextPropReader
+{
+ List aSpecMarkerList; // hiword -> Flags, loword -> Position
+ List aParaPropList;
+ List aCharPropList;
+
+ PPTStyleTextPropReader( SvStream& rIn, SdrPowerPointImport&, const DffRecordHeader& rClientTextBoxHd,
+ PPTTextRulerInterpreter& rInterpreter, const DffRecordHeader& rExtParaHd, sal_uInt32 nTextInstance );
+
+ void Init( SvStream& rIn, SdrPowerPointImport&, const DffRecordHeader& rClientTextBoxHd,
+ PPTTextRulerInterpreter& rInterpreter, const DffRecordHeader& rExtParaHd, sal_uInt32 nTextInstance );
+ void ReadParaProps( SvStream& rIn, SdrPowerPointImport& rMan, const DffRecordHeader& rTextHeader,
+ const String& aString, PPTTextRulerInterpreter& rRuler,
+ sal_uInt32& nCharCount, sal_Bool& bTextPropAtom );
+ void ReadCharProps( SvStream& rIn, PPTCharPropSet& aCharPropSet, const String& aString,
+ sal_uInt32& nCharCount, sal_uInt32 nCharAnzRead,
+ sal_Bool& bTextPropAtom, sal_uInt32 nExtParaPos,
+ const std::vector< StyleTextProp9 >& aStyleTextProp9,
+ sal_uInt32& nExtParaFlags, sal_uInt16& nBuBlip,
+ sal_uInt16& nHasAnm, sal_uInt32& nAnmScheme );
+
+ ~PPTStyleTextPropReader();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SvxFieldItem;
+class MSFILTER_DLLPUBLIC PPTPortionObj : public PPTCharPropSet
+{
+
+ friend class PPTParagraphObj;
+
+ const PPTStyleSheet& mrStyleSheet;
+ UINT32 mnInstance;
+ UINT32 mnDepth;
+
+ public :
+
+ BOOL GetAttrib( UINT32 nAttr, UINT32& nVal, UINT32 nInstanceInSheet );
+ SvxFieldItem* GetTextField();
+
+ PPTPortionObj( const PPTStyleSheet&, UINT32 nInstance, UINT32 nDepth );
+ PPTPortionObj( PPTCharPropSet&, const PPTStyleSheet&, UINT32 nInstance, UINT32 nDepth );
+ PPTPortionObj( PPTPortionObj& );
+ ~PPTPortionObj();
+
+ // the following function should be removed during next full update
+ void ApplyTo( SfxItemSet& rSet, SdrPowerPointImport& rManager, UINT32 nInstanceInSheet );
+ void ApplyTo( SfxItemSet& rSet, SdrPowerPointImport& rManager, UINT32 nInstanceInSheet, const PPTTextObj* pTextObj );
+ UINT32 Count() const { return ( mpFieldItem ) ? 1 : maString.Len(); };
+ BOOL HasTabulator();
+};
+
+class MSFILTER_DLLPUBLIC PPTParagraphObj : public PPTParaPropSet, public PPTNumberFormatCreator, public PPTTextRulerInterpreter
+{
+ friend class PPTTextObj;
+ friend class PPTNumberFormatCreator;
+
+ const PPTStyleSheet& mrStyleSheet;
+ UINT32 mnInstance;
+
+ protected :
+
+ void ImplClear();
+
+ public :
+
+ BOOL mbTab; // if true, this paragraph has tabulators in text
+
+ UINT32 mnCurrentObject;
+ UINT32 mnPortionCount;
+ PPTPortionObj** mpPortionList;
+
+ void UpdateBulletRelSize( sal_uInt32& nBulletRelSize ) const;
+ BOOL GetAttrib( UINT32 nAttr, UINT32& nVal, UINT32 nInstanceInSheet );
+
+ PPTParagraphObj( const PPTStyleSheet&, UINT32 nInstance, UINT16 nDepth );
+ PPTParagraphObj( PPTStyleTextPropReader&, const PPTStyleSheet&, UINT32 nInstance, PPTTextRulerInterpreter& rRuler );
+ ~PPTParagraphObj();
+
+ UINT32 GetTextSize();
+ PPTPortionObj* First();
+ PPTPortionObj* Next();
+
+ void AppendPortion( PPTPortionObj& rPortion );
+ void ApplyTo( SfxItemSet& rSet, boost::optional< sal_Int16 >& rStartNumbering, SdrPowerPointImport& rManager, UINT32 nInstanceInSheet, const PPTParagraphObj* pPrev );
+};
+
+#define PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT 1
+#define PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER 2
+#define PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT 4
+#define PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK 8
+#define PPT_TEXTOBJ_FLAGS_VERTICAL 16
+
+struct ImplPPTTextObj
+{
+ UINT32 mnRefCount;
+ UINT32 mnShapeId;
+ UINT32 mnShapeMaster;
+ PptOEPlaceholderAtom* mpPlaceHolderAtom;
+ UINT16 mnInstance;
+ UINT16 mnDestinationInstance;
+ MSO_SPT meShapeType;
+
+ UINT32 mnCurrentObject;
+ UINT32 mnParagraphCount;
+ PPTParagraphObj** mpParagraphList;
+ PptSlidePersistEntry& mrPersistEntry;
+
+ sal_uInt32 mnTextFlags;
+
+ ImplPPTTextObj( PptSlidePersistEntry& rPersistEntry ) : mrPersistEntry ( rPersistEntry ) {};
+};
+
+class PPTTextObj
+{
+ ImplPPTTextObj* mpImplTextObj;
+ void ImplClear();
+
+ PPTTextObj(){};
+ public :
+ PPTTextObj( SvStream& rSt, SdrPowerPointImport&, PptSlidePersistEntry&, DffObjData* );
+ PPTTextObj( PPTTextObj& rTextObj );
+ ~PPTTextObj();
+
+ UINT32 GetCurrentIndex() const { return mpImplTextObj->mnCurrentObject; };
+ UINT32 Count() const { return mpImplTextObj->mnParagraphCount; };
+ PPTParagraphObj* First();
+ PPTParagraphObj* Next();
+ MSO_SPT GetShapeType() const { return mpImplTextObj->meShapeType; };
+ UINT32 GetInstance() const { return mpImplTextObj->mnInstance; };
+ void SetInstance( UINT16 nInstance ) { mpImplTextObj->mnInstance = nInstance; };
+ UINT32 GetDestinationInstance() const { return mpImplTextObj->mnDestinationInstance; };
+ void SetDestinationInstance( UINT16 nInstance ) { mpImplTextObj->mnDestinationInstance = nInstance; };
+ PptOEPlaceholderAtom* GetOEPlaceHolderAtom() const { return mpImplTextObj->mpPlaceHolderAtom; };
+ sal_uInt32 GetTextFlags() const { return mpImplTextObj->mnTextFlags; };
+ void SetVertical( sal_Bool bVertical )
+ {
+ if ( bVertical )
+ mpImplTextObj->mnTextFlags |= PPT_TEXTOBJ_FLAGS_VERTICAL;
+ else
+ mpImplTextObj->mnTextFlags &= ~PPT_TEXTOBJ_FLAGS_VERTICAL;
+ }
+ sal_Bool GetVertical() const { return ( mpImplTextObj->mnTextFlags & PPT_TEXTOBJ_FLAGS_VERTICAL ) != 0; };
+ const SfxItemSet* GetBackground() const;
+
+ PPTTextObj& operator=( PPTTextObj& rTextObj );
+};
+
+class PPTConvertOCXControls : public SvxMSConvertOCXControls
+{
+ virtual const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > & GetDrawPage();
+ PptPageKind ePageKind;
+ public :
+
+ PPTConvertOCXControls( SfxObjectShell* pDSh, PptPageKind ePKind ) :
+ SvxMSConvertOCXControls ( pDSh, NULL ),
+ ePageKind ( ePKind ){};
+
+ virtual sal_Bool InsertControl(
+ const com::sun::star::uno::Reference<
+ com::sun::star::form::XFormComponent > &rFComp,
+ const com::sun::star::awt::Size& rSize,
+ com::sun::star::uno::Reference< com::sun::star::drawing::XShape > *pShape,
+ BOOL bFloatingCtrl );
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Powerpoint Recordtypen
+#define PPT_PST_Unknown 0
+#define PPT_PST_SubContainerCompleted 1
+#define PPT_PST_IRRAtom 2
+#define PPT_PST_PSS 3
+#define PPT_PST_SubContainerException 4
+#define PPT_PST_ClientSignal1 6
+#define PPT_PST_ClientSignal2 7
+#define PPT_PST_PowerPointStateInfoAtom 10
+#define PPT_PST_Document 1000
+#define PPT_PST_DocumentAtom 1001
+#define PPT_PST_EndDocument 1002
+#define PPT_PST_SlidePersist 1003
+#define PPT_PST_SlideBase 1004
+#define PPT_PST_SlideBaseAtom 1005
+#define PPT_PST_Slide 1006
+#define PPT_PST_SlideAtom 1007
+#define PPT_PST_Notes 1008
+#define PPT_PST_NotesAtom 1009
+#define PPT_PST_Environment 1010
+#define PPT_PST_SlidePersistAtom 1011
+#define PPT_PST_Scheme 1012
+#define PPT_PST_SchemeAtom 1013
+#define PPT_PST_DocViewInfo 1014
+#define PPT_PST_SslideLayoutAtom 1015
+#define PPT_PST_MainMaster 1016
+#define PPT_PST_SSSlideInfoAtom 1017
+#define PPT_PST_SlideViewInfo 1018
+#define PPT_PST_GuideAtom 1019
+#define PPT_PST_ViewInfo 1020
+#define PPT_PST_ViewInfoAtom 1021
+#define PPT_PST_SlideViewInfoAtom 1022
+#define PPT_PST_VBAInfo 1023
+#define PPT_PST_VBAInfoAtom 1024
+#define PPT_PST_SSDocInfoAtom 1025
+#define PPT_PST_Summary 1026
+#define PPT_PST_Texture 1027
+#define PPT_PST_VBASlideInfo 1028
+#define PPT_PST_VBASlideInfoAtom 1029
+#define PPT_PST_DocRoutingSlip 1030
+#define PPT_PST_OutlineViewInfo 1031
+#define PPT_PST_SorterViewInfo 1032
+#define PPT_PST_ExObjList 1033
+#define PPT_PST_ExObjListAtom 1034
+#define PPT_PST_PPDrawingGroup 1035
+#define PPT_PST_PPDrawing 1036
+#define PPT_PST_NewlyAddedAtomByXP1037 1037
+#define PPT_PST_NamedShows 1040
+#define PPT_PST_NamedShow 1041
+#define PPT_PST_NamedShowSlides 1042
+#define PPT_PST_List 2000
+#define PPT_PST_FontCollection 2005
+#define PPT_PST_ListPlaceholder 2017
+#define PPT_PST_BookmarkCollection 2019
+#define PPT_PST_SoundCollection 2020
+#define PPT_PST_SoundCollAtom 2021
+#define PPT_PST_Sound 2022
+#define PPT_PST_SoundData 2023
+#define PPT_PST_BookmarkSeedAtom 2025
+#define PPT_PST_GuideList 2026
+#define PPT_PST_RunArray 2028
+#define PPT_PST_RunArrayAtom 2029
+#define PPT_PST_ArrayElementAtom 2030
+#define PPT_PST_Int4ArrayAtom 2031
+#define PPT_PST_ColorSchemeAtom 2032
+
+// these atoms first was seen in ppt2000 in a private Tag atom
+#define PPT_PST_ExtendedBuGraContainer 2040 // consist of 4041
+#define PPT_PST_ExtendedBuGraAtom 2041 // the instance of this atom indices the current graphic
+
+#define PPT_PST_OEShape 3008
+#define PPT_PST_ExObjRefAtom 3009
+#define PPT_PST_OEPlaceholderAtom 3011
+#define PPT_PST_GrColor 3020
+#define PPT_PST_GrectAtom 3025
+#define PPT_PST_GratioAtom 3031
+#define PPT_PST_Gscaling 3032
+#define PPT_PST_GpointAtom 3034
+#define PPT_PST_OEShapeAtom 3035
+#define PPT_PST_OutlineTextRefAtom 3998
+#define PPT_PST_TextHeaderAtom 3999
+#define PPT_PST_TextCharsAtom 4000
+#define PPT_PST_StyleTextPropAtom 4001
+#define PPT_PST_BaseTextPropAtom 4002
+#define PPT_PST_TxMasterStyleAtom 4003
+#define PPT_PST_TxCFStyleAtom 4004
+#define PPT_PST_TxPFStyleAtom 4005
+#define PPT_PST_TextRulerAtom 4006
+#define PPT_PST_TextBookmarkAtom 4007
+#define PPT_PST_TextBytesAtom 4008
+#define PPT_PST_TxSIStyleAtom 4009
+#define PPT_PST_TextSpecInfoAtom 4010
+#define PPT_PST_DefaultRulerAtom 4011
+
+// these atoms first was seen in ppt2000 in a private Tag atom
+#define PPT_PST_ExtendedParagraphAtom 4012
+#define PPT_PST_ExtendedParagraphMasterAtom 4013
+#define PPT_PST_ExtendedPresRuleContainer 4014 // consist of 4012, 4015,
+#define PPT_PST_ExtendedParagraphHeaderAtom 4015 // the instance of this atom indices the current presobj
+ // the first UINT32 in this atom indices the current slideId
+#define PPT_PST_NewlyAddedAtom4016 4016
+
+#define PPT_PST_FontEntityAtom 4023
+#define PPT_PST_FontEmbedData 4024
+#define PPT_PST_TypeFace 4025
+#define PPT_PST_CString 4026
+#define PPT_PST_ExternalObject 4027
+#define PPT_PST_MetaFile 4033
+#define PPT_PST_ExOleObj 4034
+#define PPT_PST_ExOleObjAtom 4035
+#define PPT_PST_ExPlainLinkAtom 4036
+#define PPT_PST_CorePict 4037
+#define PPT_PST_CorePictAtom 4038
+#define PPT_PST_ExPlainAtom 4039
+#define PPT_PST_SrKinsoku 4040
+#define PPT_PST_Handout 4041
+#define PPT_PST_ExEmbed 4044
+#define PPT_PST_ExEmbedAtom 4045
+#define PPT_PST_ExLink 4046
+#define PPT_PST_ExLinkAtom_old 4047
+#define PPT_PST_BookmarkEntityAtom 4048
+#define PPT_PST_ExLinkAtom 4049
+#define PPT_PST_SrKinsokuAtom 4050
+#define PPT_PST_ExHyperlinkAtom 4051
+#define PPT_PST_ExPlain 4053
+#define PPT_PST_ExPlainLink 4054
+#define PPT_PST_ExHyperlink 4055
+#define PPT_PST_SlideNumberMCAtom 4056
+#define PPT_PST_HeadersFooters 4057
+#define PPT_PST_HeadersFootersAtom 4058
+#define PPT_PST_RecolorEntryAtom 4062
+#define PPT_PST_TxInteractiveInfoAtom 4063
+#define PPT_PST_EmFormatAtom 4065
+#define PPT_PST_CharFormatAtom 4066
+#define PPT_PST_ParaFormatAtom 4067
+#define PPT_PST_MasterText 4068
+#define PPT_PST_RecolorInfoAtom 4071
+#define PPT_PST_ExQuickTime 4073
+#define PPT_PST_ExQuickTimeMovie 4074
+#define PPT_PST_ExQuickTimeMovieData 4075
+#define PPT_PST_ExSubscription 4076
+#define PPT_PST_ExSubscriptionSection 4077
+#define PPT_PST_ExControl 4078
+#define PPT_PST_ExControlAtom 4091
+#define PPT_PST_SlideListWithText 4080
+#define PPT_PST_AnimationInfoAtom 4081
+#define PPT_PST_InteractiveInfo 4082
+#define PPT_PST_InteractiveInfoAtom 4083
+#define PPT_PST_SlideList 4084
+#define PPT_PST_UserEditAtom 4085
+#define PPT_PST_CurrentUserAtom 4086
+#define PPT_PST_DateTimeMCAtom 4087
+#define PPT_PST_GenericDateMCAtom 4088
+#define PPT_PST_HeaderMCAtom 4089
+#define PPT_PST_FooterMCAtom 4090
+#define PPT_PST_ExMediaAtom 4100
+#define PPT_PST_ExVideo 4101
+#define PPT_PST_ExAviMovie 4102
+#define PPT_PST_ExMCIMovie 4103
+#define PPT_PST_ExMIDIAudio 4109
+#define PPT_PST_ExCDAudio 4110
+#define PPT_PST_ExWAVAudioEmbedded 4111
+#define PPT_PST_ExWAVAudioLink 4112
+#define PPT_PST_ExOleObjStg 4113
+#define PPT_PST_ExCDAudioAtom 4114
+#define PPT_PST_ExWAVAudioEmbeddedAtom 4115
+#define PPT_PST_AnimationInfo 4116
+#define PPT_PST_RTFDateTimeMCAtom 4117
+#define PPT_PST_ProgTags 5000
+#define PPT_PST_ProgStringTag 5001
+#define PPT_PST_ProgBinaryTag 5002
+#define PPT_PST_BinaryTagData 5003
+#define PPT_PST_PrintOptions 6000
+#define PPT_PST_PersistPtrFullBlock 6001
+#define PPT_PST_PersistPtrIncrementalBlock 6002
+
+// these atoms first was seen in ppt2000 in a private Tag atom
+#define PPT_PST_NewlyAddedAtomByPPT2000_6010 6010
+#define PPT_PST_NewlyAddedAtomByPPT2000_6011 6011
+
+#define PPT_PST_RulerIndentAtom 10000
+#define PPT_PST_GscalingAtom 10001
+#define PPT_PST_GrColorAtom 10002
+#define PPT_PST_GLPointAtom 10003
+#define PPT_PST_GlineAtom 10004
+
+#define PPT_PST_NewlyAddedAtomByXP11008 11008
+#define PPT_PST_NewlyAddedAtomByXP11010 11010
+#define PPT_PST_Comment10 12000
+#define PPT_PST_CommentAtom10 12001
+#define PPT_PST_NewlyAddedAtomByXP12004 12004
+#define PPT_PST_NewlyAddedAtomByXP12010 12010
+#define PPT_PST_NewlyAddedAtomByXP12011 12011
+#define PPT_PST_NewlyAddedAtomByXP14001 14001
+
+// Attribute fuer PptTextStyleSheet
+#define PPT_ParaAttr_BulletOn 0 //00000001
+#define PPT_ParaAttr_BuHardFont 1 //00000002
+#define PPT_ParaAttr_BuHardColor 2 //00000004
+#define PPT_ParaAttr_BuHardHeight 3 //00000008
+#define PPT_ParaAttr_BulletFont 4 //00000010
+#define PPT_ParaAttr_BulletColor 5 //00000020
+#define PPT_ParaAttr_BulletHeight 6 //00000040
+#define PPT_ParaAttr_BulletChar 7 //00000080
+
+#define PPT_ParaAttr_DontKnow1 8 //00000100
+#define PPT_ParaAttr_DontKnow2 9 //00000200
+#define PPT_ParaAttr_DontKnow3 10 //00000400
+#define PPT_ParaAttr_Adjust 11 //00000800 0000=Left, 0001=Center, 0002=Right, 0003=Block
+
+#define PPT_ParaAttr_LineFeed 12 //00001000
+#define PPT_ParaAttr_UpperDist 13 //00002000 ist bei Textframes default immer auf 0032 gesetzt
+#define PPT_ParaAttr_LowerDist 14 //00004000
+#define PPT_ParaAttr_TextOfs 15 //00008000
+
+#define PPT_ParaAttr_BulletOfs 16 //00010000
+#define PPT_ParaAttr_DefaultTab 17 //00020000
+#define PPT_ParaAttr_AsianLB_1 18
+#define PPT_ParaAttr_AsianLB_2 19
+#define PPT_ParaAttr_AsianLB_3 20
+#define PPT_ParaAttr_BiDi 21 //00200000
+
+#define PPT_CharAttr_Bold 0 //00000001
+#define PPT_CharAttr_Italic 1 //00000002
+#define PPT_CharAttr_Underline 2 //00000004
+#define PPT_CharAttr_Shadow 4 //00000010
+#define PPT_CharAttr_Strikeout 8 //00000100
+#define PPT_CharAttr_Embossed 9 //00000200
+#define PPT_CharAttr_ResetNumbering 10 //00000400
+#define PPT_CharAttr_EnableNumbering1 11 //00000800
+#define PPT_CharAttr_EnableNumbering2 12 //00001000
+#define PPT_CharAttr_Font 16 //00010000
+#define PPT_CharAttr_AsianOrComplexFont 21 //00200000
+#define PPT_CharAttr_ANSITypeface 22 //00400000
+#define PPT_CharAttr_Symbol 23 //00800000
+#define PPT_CharAttr_FontHeight 17 //00020000
+#define PPT_CharAttr_FontColor 18 //00040000
+#define PPT_CharAttr_Escapement 19 //00080000
+
+// Werte fuer PptSlideLayoutAtom.eLayout
+#define PPT_LAYOUT_TITLESLIDE 0 // The slide is a title slide
+#define PPT_LAYOUT_TITLEANDBODYSLIDE 1 // Title and body slide
+#define PPT_LAYOUT_TITLEMASTERSLIDE 2 // Title master slide
+#define PPT_LAYOUT_MASTERSLIDE 3 // Master slide layout
+#define PPT_LAYOUT_MASTERNOTES 4 // Master notes layout
+#define PPT_LAYOUT_NOTESTITLEBODY 5 // Notes title/body layout
+#define PPT_LAYOUT_HANDOUTLAYOUT 6 // Handout layout, therefore it doesn't have placeholders except header, footer, and date
+#define PPT_LAYOUT_ONLYTITLE 7 // Only title placeholder
+#define PPT_LAYOUT_2COLUMNSANDTITLE 8 // Body of the slide has 2 columns and a title
+#define PPT_LAYOUT_2ROWSANDTITLE 9 // Slide's body has 2 rows and a title
+#define PPT_LAYOUT_RIGHTCOLUMN2ROWS 10 // Body contains 2 columns, right column has 2 rows
+#define PPT_LAYOUT_LEFTCOLUMN2ROWS 11 // Body contains 2 columns, left column has 2 rows
+#define PPT_LAYOUT_BOTTOMROW2COLUMNS 12 // Body contains 2 rows, bottom row has 2 columns
+#define PPT_LAYOUT_TOPROW2COLUMN 13 // Body contains 2 rows, top row has 2 columns
+#define PPT_LAYOUT_4OBJECTS 14 // 4 objects
+#define PPT_LAYOUT_BIGOBJECT 15 // Big object
+#define PPT_LAYOUT_BLANCSLIDE 16 // Blank slide
+#define PPT_LAYOUT_TITLERIGHTBODYLEFT 17 // Vertical title on the right, body on the left
+#define PPT_LAYOUT_TITLERIGHT2BODIESLEFT 18 // Vertical title on the right, body on the left split into 2 rows
+
+// the following table describes the placeholder id's (values from reality followed by values taken from the documentation)
+#define PPT_PLACEHOLDER_NONE 0 // 0 None
+#define PPT_PLACEHOLDER_MASTERTITLE 1 // 1 Master title
+#define PPT_PLACEHOLDER_MASTERBODY 2 // 2 Master body
+#define PPT_PLACEHOLDER_MASTERCENTEREDTITLE 3 // 3 Master centered title
+#define PPT_PLACEHOLDER_MASTERSUBTITLE 4 // 10 Master subtitle
+#define PPT_PLACEHOLDER_MASTERNOTESSLIDEIMAGE 5 // 4 Master notes slide image
+#define PPT_PLACEHOLDER_MASTERNOTESBODYIMAGE 6 // 5 Master notes body image
+#define PPT_PLACEHOLDER_MASTERDATE 7 // 6 Master date
+#define PPT_PLACEHOLDER_MASTERSLIDENUMBER 8 // 7 Master slide number
+#define PPT_PLACEHOLDER_MASTERFOOTER 9 // 8 Master footer
+#define PPT_PLACEHOLDER_MASTERHEADER 10 // 9 Master header
+#define PPT_PLACEHOLDER_GENERICTEXTOBJECT // 11 Generic text object
+#define PPT_PLACEHOLDER_TITLE 13 // 12 Title
+#define PPT_PLACEHOLDER_BODY 14 // 13 Body
+#define PPT_PLACEHOLDER_NOTESBODY 12 // 14 Notes body
+#define PPT_PLACEHOLDER_CENTEREDTITLE 15 // 15 Centered title
+#define PPT_PLACEHOLDER_SUBTITLE 16 // 16 Subtitle
+#define PPT_PLACEHOLDER_VERTICALTEXTTITLE 17 // 17 Vertical text title
+#define PPT_PLACEHOLDER_VERTICALTEXTBODY 18 // 18 Vertical text body
+#define PPT_PLACEHOLDER_NOTESSLIDEIMAGE 11 // 19 Notes slide image
+#define PPT_PLACEHOLDER_OBJECT 19 // 20 Object (no matter the size)
+#define PPT_PLACEHOLDER_GRAPH 20 // 21 Graph
+#define PPT_PLACEHOLDER_TABLE 21 // 22 Table
+#define PPT_PLACEHOLDER_CLIPART 22 // 23 Clip Art
+#define PPT_PLACEHOLDER_ORGANISZATIONCHART 23 // 24 Organization Chart
+#define PPT_PLACEHOLDER_MEDIACLIP 24 // 25 Media Clip
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif // SVX_LIGHT
+
+#endif //_SVDFPPT_HXX
+
diff --git a/filter/inc/filter/msfilter/svxmsbas.hxx b/filter/inc/filter/msfilter/svxmsbas.hxx
new file mode 100644
index 000000000000..641d71e3ac2d
--- /dev/null
+++ b/filter/inc/filter/msfilter/svxmsbas.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svxmsbas.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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 _SVXMSBAS_HXX
+#define _SVXMSBAS_HXX
+
+#include <tools/solar.h>
+#include "filter/msfilter/msfilterdllapi.h"
+
+#include <sot/storage.hxx>
+
+class SfxObjectShell;
+
+/* Construct with the root storage of the MS document, with bImportCode
+ * set the visual basic code will be imported into the stardocument when Import
+ * is called, with bCopyStorage set, the visual basic storage tree will be
+ * copied completely into staroffice, so that any future export to a msoffice
+ * format will retain the vba code, allowing a lossless roundtrip from
+ * msoffice to staroffice and back.
+ *
+ * Setting bAsComment to true in Import will import the visual basic as a
+ * starbasic comment. Which is currently necessary, as vb is not valid sb.
+ *
+ * Setting bStripped will remove the "Attribute" lines from the vb, msoffice
+ * does this itself when it shows the vb code in the vbeditor, so this is
+ * probably what the user expects to see when viewing the code
+ */
+
+class MSFILTER_DLLPUBLIC SvxImportMSVBasic
+{
+public:
+ SvxImportMSVBasic( SfxObjectShell &rDocS, SotStorage &rRoot,
+ BOOL bImportCode = TRUE, BOOL bCopyStorage = TRUE )
+ : xRoot(&rRoot), rDocSh(rDocS),
+ bImport(bImportCode), bCopy(bCopyStorage)
+ {}
+ // returns the status of import:
+ // 0 - nothing has done
+ // bit 0 = 1 -> any code is imported to the SO-Basic
+ // bit 1 = 1 -> the VBA - storage is copy to the ObjectShell storage
+ int Import( const String& rStorageName, const String &rSubStorageName,
+ BOOL bAsComment=TRUE, BOOL bStripped=TRUE );
+
+ // only for the export - copy or delete the saved VBA-macro-storage
+ // form the ObjectShell
+ // - returns a warning code if a modified basic exist, in all other
+ // cases return ERRCODE_NONE.
+ ULONG SaveOrDelMSVBAStorage( BOOL bSaveInto, const String& rStorageName );
+
+ // check if the MS-VBA-Storage exist in the RootStorage of the DocShell.
+ // If it exist, then return the WarningId for loosing the information.
+ static ULONG GetSaveWarningOfMSVBAStorage( SfxObjectShell &rDocS );
+
+ static String GetMSBasicStorageName();
+private:
+ SotStorageRef xRoot;
+ SfxObjectShell &rDocSh;
+ BOOL bImport;
+ BOOL bCopy;
+
+ MSFILTER_DLLPRIVATE BOOL ImportCode_Impl( const String& rStorageName,
+ const String &rSubStorageName,
+ BOOL bAsComment, BOOL bStripped);
+ MSFILTER_DLLPRIVATE bool ImportForms_Impl(const String& rStorageName,
+ const String &rSubStorageName);
+ MSFILTER_DLLPRIVATE BOOL CopyStorage_Impl( const String& rStorageName,
+ const String &rSubStorageName);
+};
+
+#endif
diff --git a/filter/prj/d.lst b/filter/prj/d.lst
index 3291c7c1bc4e..29f88653569c 100644
--- a/filter/prj/d.lst
+++ b/filter/prj/d.lst
@@ -48,3 +48,9 @@ mkdir: %_DEST%\bin%_EXT%\pdfimport
..\%__SRC%\bin\pdfunzip.* %_DEST%\bin%_EXT%\pdfunzip.*
..\%__SRC%\misc\filters\modulepacks\fcfg_*.xcu %_DEST%\xml%_EXT%\registry\spool\fcfg_*.xcu
..\%COMMON_OUTDIR%\bin\fcfg_langpack_*.zip %_DEST%\pck%_EXT%\fcfg_langpack_*.zip
+
+mkdir: %_DEST%\inc%_EXT%\filter
+mkdir: %_DEST%\inc%_EXT%\filter\msfilter
+..\inc\filter\msfilter\*.hxx %_DEST%\inc%_EXT%\filter\msfilter\*.hxx
+..\inc\filter\msfilter\*.h %_DEST%\inc%_EXT%\filter\msfilter\*.h
+
diff --git a/filter/source/msfilter/countryid.cxx b/filter/source/msfilter/countryid.cxx
new file mode 100644
index 000000000000..474fdb5a2823
--- /dev/null
+++ b/filter/source/msfilter/countryid.cxx
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: countryid.cxx,v $
+ * $Revision: 1.8.242.2 $
+ *
+ * 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_filter.hxx"
+
+// ============================================================================
+#include "filter/msfilter/countryid.hxx"
+
+#include <algorithm>
+
+// ----------------------------------------------------------------------------
+
+namespace msfilter {
+
+// Mapping table ==============================================================
+
+namespace {
+
+// ----------------------------------------------------------------------------
+
+/** Table entry for Windows country ID <-> language type conversion.
+
+ The first member is the Windows country ID, as defined in the header.
+
+ The second member contains the corresponding language type for each country
+ ID. This must be a full language, not only the primary language type.
+
+ The last bool flag defines, if the sub language type should be evaluated to
+ find the country ID from a language. If not set, all languages map to the
+ country which contain the given primary language type.
+
+ Example: The language entry (COUNTRY_USA,LANGUAGE_ENGLISH_US,false) maps
+ the country ID for USA to the language LANGUAGE_ENGLISH_US. The clear sub
+ language flag causes all english languages LANGUAGE_ENGLISH_*** to map to
+ this country ID by default. To map the special case LANGUAGE_ENGLISH_EIRE
+ to the country ID COUNTRY_IRELAND, the sub language flag must be set in the
+ respective table entry, here (COUNTRY_IRELAND,LANGUAGE_ENGLISH_EIRE,true).
+ */
+struct CountryEntry
+{
+ CountryId meCountry; /// Windows country ID.
+ LanguageType meLanguage; /// Corresponding language type.
+ bool mbUseSubLang; /// false = Primary only, true = Primary and sub language.
+};
+
+// ----------------------------------------------------------------------------
+
+/** Table for Windows country ID <-> language type conversion.
+
+ To map the same language to different country IDs, some of the entries
+ should contain a set sub language flag (see description of CountryEntry).
+ All table entries with a set flag take priority over the entry with the
+ same primary language, but cleared sub language flag, regardless of the
+ position in the table.
+
+ To map different languages to the same country ID, several entries with the
+ same country ID may be inserted. In this case the conversion to a language
+ is done with the first found entry (starting from top) containing the given
+ country ID.
+
+ For now all entries are sorted by country ID, but this is not required.
+ */
+static const CountryEntry pTable[] =
+{
+ { COUNTRY_USA, LANGUAGE_ENGLISH_US, false },
+ { COUNTRY_DOMINICAN_REPUBLIC, LANGUAGE_SPANISH_DOMINICAN_REPUBLIC, true },
+ { COUNTRY_JAMAICA, LANGUAGE_ENGLISH_JAMAICA, true },
+ { COUNTRY_PUERTO_RICO, LANGUAGE_SPANISH_PUERTO_RICO, true },
+ { COUNTRY_TRINIDAD_Y_TOBAGO, LANGUAGE_ENGLISH_TRINIDAD, true },
+ { COUNTRY_CANADA, LANGUAGE_ENGLISH_CAN, true },
+ { COUNTRY_CANADA, LANGUAGE_FRENCH_CANADIAN, true },
+ { COUNTRY_RUSSIA, LANGUAGE_RUSSIAN, false },
+ { COUNTRY_KAZAKHSTAN, LANGUAGE_KAZAK, false },
+ { COUNTRY_TATARSTAN, LANGUAGE_TATAR, false },
+ { COUNTRY_EGYPT, LANGUAGE_ARABIC_EGYPT, true },
+ { COUNTRY_SOUTH_AFRICA, LANGUAGE_AFRIKAANS, false },
+ { COUNTRY_SOUTH_AFRICA, LANGUAGE_ENGLISH_SAFRICA, true },
+ { COUNTRY_SOUTH_AFRICA, LANGUAGE_TSONGA, false },
+ { COUNTRY_SOUTH_AFRICA, LANGUAGE_VENDA, false },
+ { COUNTRY_SOUTH_AFRICA, LANGUAGE_XHOSA, false },
+ { COUNTRY_SOUTH_AFRICA, LANGUAGE_ZULU, false },
+ { COUNTRY_GREECE, LANGUAGE_GREEK, false },
+ { COUNTRY_NETHERLANDS, LANGUAGE_DUTCH, false },
+ { COUNTRY_NETHERLANDS, LANGUAGE_FRISIAN_NETHERLANDS, false },
+ { COUNTRY_BELGIUM, LANGUAGE_DUTCH_BELGIAN, true },
+ { COUNTRY_BELGIUM, LANGUAGE_FRENCH_BELGIAN, true },
+ { COUNTRY_FRANCE, LANGUAGE_FRENCH, false },
+ { COUNTRY_SPAIN, LANGUAGE_SPANISH_MODERN, false },
+ { COUNTRY_SPAIN, LANGUAGE_SPANISH_DATED, false },
+ { COUNTRY_SPAIN, LANGUAGE_CATALAN, false },
+ { COUNTRY_SPAIN, LANGUAGE_BASQUE, false },
+ { COUNTRY_SPAIN, LANGUAGE_GALICIAN, false },
+ { COUNTRY_HUNGARY, LANGUAGE_HUNGARIAN, false },
+ { COUNTRY_ITALY, LANGUAGE_ITALIAN, false },
+ { COUNTRY_ROMANIA, LANGUAGE_ROMANIAN, false },
+ { COUNTRY_SWITZERLAND, LANGUAGE_GERMAN_SWISS, true },
+ { COUNTRY_SWITZERLAND, LANGUAGE_FRENCH_SWISS, true },
+ { COUNTRY_SWITZERLAND, LANGUAGE_ITALIAN_SWISS, true },
+ { COUNTRY_SWITZERLAND, LANGUAGE_RHAETO_ROMAN, false },
+ { COUNTRY_AUSTRIA, LANGUAGE_GERMAN_AUSTRIAN, true },
+ { COUNTRY_UNITED_KINGDOM, LANGUAGE_ENGLISH_UK, true },
+ { COUNTRY_UNITED_KINGDOM, LANGUAGE_GAELIC_SCOTLAND, true },
+ { COUNTRY_UNITED_KINGDOM, LANGUAGE_WELSH, false },
+ { COUNTRY_DENMARK, LANGUAGE_DANISH, false },
+ { COUNTRY_SWEDEN, LANGUAGE_SWEDISH, false },
+ { COUNTRY_SWEDEN, LANGUAGE_SAMI_LAPPISH, false },
+ { COUNTRY_NORWAY, LANGUAGE_NORWEGIAN_BOKMAL, false },
+ { COUNTRY_POLAND, LANGUAGE_POLISH, false },
+ { COUNTRY_GERMANY, LANGUAGE_GERMAN, false },
+ { COUNTRY_GERMANY, LANGUAGE_SORBIAN, false },
+ { COUNTRY_PERU, LANGUAGE_SPANISH_PERU, true },
+ { COUNTRY_MEXICO, LANGUAGE_SPANISH_MEXICAN, true },
+ { COUNTRY_ARGENTINIA, LANGUAGE_SPANISH_ARGENTINA, true },
+ { COUNTRY_BRAZIL, LANGUAGE_PORTUGUESE_BRAZILIAN, true },
+ { COUNTRY_CHILE, LANGUAGE_SPANISH_CHILE, true },
+ { COUNTRY_COLOMBIA, LANGUAGE_SPANISH_COLOMBIA, true },
+ { COUNTRY_VENEZUELA, LANGUAGE_SPANISH_VENEZUELA, true },
+ { COUNTRY_MALAYSIA, LANGUAGE_MALAY_MALAYSIA, false },
+ { COUNTRY_AUSTRALIA, LANGUAGE_ENGLISH_AUS, true },
+ { COUNTRY_INDONESIA, LANGUAGE_INDONESIAN, false },
+ { COUNTRY_PHILIPPINES, LANGUAGE_ENGLISH_PHILIPPINES, true },
+ { COUNTRY_NEW_ZEALAND, LANGUAGE_MAORI_NEW_ZEALAND, false },
+ { COUNTRY_NEW_ZEALAND, LANGUAGE_ENGLISH_NZ, true },
+ { COUNTRY_SINGAPORE, LANGUAGE_CHINESE_SINGAPORE, true },
+ { COUNTRY_THAILAND, LANGUAGE_THAI, false },
+ { COUNTRY_JAPAN, LANGUAGE_JAPANESE, false },
+ { COUNTRY_SOUTH_KOREA, LANGUAGE_KOREAN, false },
+ { COUNTRY_VIET_NAM, LANGUAGE_VIETNAMESE, false },
+ { COUNTRY_PR_CHINA, LANGUAGE_CHINESE_SIMPLIFIED, false },
+ { COUNTRY_TIBET, LANGUAGE_TIBETAN, false },
+ { COUNTRY_TURKEY, LANGUAGE_TURKISH, false },
+ { COUNTRY_INDIA, LANGUAGE_HINDI, false },
+ { COUNTRY_INDIA, LANGUAGE_URDU_INDIA, true },
+ { COUNTRY_INDIA, LANGUAGE_PUNJABI, false },
+ { COUNTRY_INDIA, LANGUAGE_GUJARATI, false },
+ { COUNTRY_INDIA, LANGUAGE_ORIYA, false },
+ { COUNTRY_INDIA, LANGUAGE_TAMIL, false },
+ { COUNTRY_INDIA, LANGUAGE_TELUGU, false },
+ { COUNTRY_INDIA, LANGUAGE_KANNADA, false },
+ { COUNTRY_INDIA, LANGUAGE_MALAYALAM, false },
+ { COUNTRY_INDIA, LANGUAGE_ASSAMESE, false },
+ { COUNTRY_INDIA, LANGUAGE_MARATHI, false },
+ { COUNTRY_INDIA, LANGUAGE_SANSKRIT, false },
+ { COUNTRY_INDIA, LANGUAGE_KONKANI, false },
+ { COUNTRY_INDIA, LANGUAGE_MANIPURI, false },
+ { COUNTRY_INDIA, LANGUAGE_SINDHI, false },
+ { COUNTRY_INDIA, LANGUAGE_KASHMIRI, false },
+ { COUNTRY_PAKISTAN, LANGUAGE_URDU_PAKISTAN, false },
+ { COUNTRY_MYANMAR, LANGUAGE_BURMESE, false },
+ { COUNTRY_MOROCCO, LANGUAGE_ARABIC_MOROCCO, true },
+ { COUNTRY_ALGERIA, LANGUAGE_ARABIC_ALGERIA, true },
+ { COUNTRY_TUNISIA, LANGUAGE_ARABIC_TUNISIA, true },
+ { COUNTRY_LIBYA, LANGUAGE_ARABIC_LIBYA, true },
+ { COUNTRY_SENEGAL, LANGUAGE_FRENCH_SENEGAL, true },
+ { COUNTRY_MALI, LANGUAGE_FRENCH_MALI, true },
+ { COUNTRY_COTE_D_IVOIRE, LANGUAGE_FRENCH_COTE_D_IVOIRE, true },
+ { COUNTRY_CAMEROON, LANGUAGE_FRENCH_CAMEROON, true },
+ { COUNTRY_ZAIRE, LANGUAGE_FRENCH_ZAIRE, true },
+ { COUNTRY_RWANDA, LANGUAGE_KINYARWANDA_RWANDA, false },
+ { COUNTRY_KENYA, LANGUAGE_SWAHILI, false },
+ { COUNTRY_REUNION, LANGUAGE_FRENCH_REUNION, true },
+ { COUNTRY_ZIMBABWE, LANGUAGE_ENGLISH_ZIMBABWE, true },
+ { COUNTRY_LESOTHO, LANGUAGE_SESOTHO, false },
+ { COUNTRY_BOTSWANA, LANGUAGE_TSWANA, false },
+ { COUNTRY_FAEROE_ISLANDS, LANGUAGE_FAEROESE, false },
+ { COUNTRY_PORTUGAL, LANGUAGE_PORTUGUESE, false },
+ { COUNTRY_LUXEMBOURG, LANGUAGE_GERMAN_LUXEMBOURG, true },
+ { COUNTRY_LUXEMBOURG, LANGUAGE_FRENCH_LUXEMBOURG, true },
+ { COUNTRY_IRELAND, LANGUAGE_ENGLISH_EIRE, true },
+ { COUNTRY_IRELAND, LANGUAGE_GAELIC_IRELAND, true },
+ { COUNTRY_ICELAND, LANGUAGE_ICELANDIC, false },
+ { COUNTRY_ALBANIA, LANGUAGE_ALBANIAN, false },
+ { COUNTRY_MALTA, LANGUAGE_MALTESE, false },
+ { COUNTRY_FINLAND, LANGUAGE_FINNISH, false },
+ { COUNTRY_FINLAND, LANGUAGE_SWEDISH_FINLAND, true },
+ { COUNTRY_BULGARIA, LANGUAGE_BULGARIAN, false },
+ { COUNTRY_LITHUANIA, LANGUAGE_LITHUANIAN, false },
+ { COUNTRY_LATVIA, LANGUAGE_LATVIAN, false },
+ { COUNTRY_ESTONIA, LANGUAGE_ESTONIAN, false },
+ { COUNTRY_MOLDOVA, LANGUAGE_ROMANIAN_MOLDOVA, true },
+ { COUNTRY_MOLDOVA, LANGUAGE_RUSSIAN_MOLDOVA, true },
+ { COUNTRY_ARMENIA, LANGUAGE_ARMENIAN, false },
+ { COUNTRY_BELARUS, LANGUAGE_BELARUSIAN, false },
+ { COUNTRY_MONACO, LANGUAGE_FRENCH_MONACO, true },
+ { COUNTRY_UKRAINE, LANGUAGE_UKRAINIAN, false },
+ { COUNTRY_SERBIA, LANGUAGE_SERBIAN_LATIN, false },
+ { COUNTRY_CROATIA, LANGUAGE_CROATIAN, true }, // sub type of LANGUAGE_SERBIAN
+ { COUNTRY_SLOVENIA, LANGUAGE_SLOVENIAN, false },
+ { COUNTRY_MACEDONIA, LANGUAGE_MACEDONIAN, false },
+ { COUNTRY_CZECH, LANGUAGE_CZECH, false },
+ { COUNTRY_SLOVAK, LANGUAGE_SLOVAK, false },
+ { COUNTRY_LIECHTENSTEIN, LANGUAGE_GERMAN_LIECHTENSTEIN, true },
+ { COUNTRY_BELIZE, LANGUAGE_ENGLISH_BELIZE, true },
+ { COUNTRY_GUATEMALA, LANGUAGE_SPANISH_GUATEMALA, true },
+ { COUNTRY_EL_SALVADOR, LANGUAGE_SPANISH_EL_SALVADOR, true },
+ { COUNTRY_HONDURAS, LANGUAGE_SPANISH_HONDURAS, true },
+ { COUNTRY_NICARAGUA, LANGUAGE_SPANISH_NICARAGUA, true },
+ { COUNTRY_COSTA_RICA, LANGUAGE_SPANISH_COSTARICA, true },
+ { COUNTRY_PANAMA, LANGUAGE_SPANISH_PANAMA, true },
+ { COUNTRY_BOLIVIA, LANGUAGE_SPANISH_BOLIVIA, true },
+ { COUNTRY_ECUADOR, LANGUAGE_SPANISH_ECUADOR, true },
+ { COUNTRY_PARAGUAY, LANGUAGE_SPANISH_PARAGUAY, true },
+ { COUNTRY_URUGUAY, LANGUAGE_SPANISH_URUGUAY, true },
+ { COUNTRY_BRUNEI_DARUSSALAM, LANGUAGE_MALAY_BRUNEI_DARUSSALAM, true },
+ { COUNTRY_HONG_KONG, LANGUAGE_CHINESE_HONGKONG, true },
+ { COUNTRY_MACAU, LANGUAGE_CHINESE_MACAU, true },
+ { COUNTRY_CAMBODIA, LANGUAGE_KHMER, false },
+ { COUNTRY_LAOS, LANGUAGE_LAO, false },
+ { COUNTRY_BANGLADESH, LANGUAGE_BENGALI, false },
+ { COUNTRY_TAIWAN, LANGUAGE_CHINESE_TRADITIONAL, true },
+ { COUNTRY_MALDIVES, LANGUAGE_DHIVEHI, false },
+ { COUNTRY_LEBANON, LANGUAGE_ARABIC_LEBANON, true },
+ { COUNTRY_JORDAN, LANGUAGE_ARABIC_JORDAN, true },
+ { COUNTRY_SYRIA, LANGUAGE_ARABIC_SYRIA, true },
+ { COUNTRY_IRAQ, LANGUAGE_ARABIC_IRAQ, true },
+ { COUNTRY_KUWAIT, LANGUAGE_ARABIC_KUWAIT, true },
+ { COUNTRY_SAUDI_ARABIA, LANGUAGE_ARABIC_SAUDI_ARABIA, true },
+ { COUNTRY_YEMEN, LANGUAGE_ARABIC_YEMEN, true },
+ { COUNTRY_OMAN, LANGUAGE_ARABIC_OMAN, true },
+ { COUNTRY_UAE, LANGUAGE_ARABIC_UAE, true },
+ { COUNTRY_ISRAEL, LANGUAGE_HEBREW, false },
+ { COUNTRY_BAHRAIN, LANGUAGE_ARABIC_BAHRAIN, true },
+ { COUNTRY_QATAR, LANGUAGE_ARABIC_QATAR, true },
+ { COUNTRY_MONGOLIA, LANGUAGE_MONGOLIAN, false },
+ { COUNTRY_NEPAL, LANGUAGE_NEPALI, false },
+ { COUNTRY_IRAN, LANGUAGE_FARSI, false },
+ { COUNTRY_TAJIKISTAN, LANGUAGE_TAJIK, false },
+ { COUNTRY_TURKMENISTAN, LANGUAGE_TURKMEN, false },
+ { COUNTRY_AZERBAIJAN, LANGUAGE_AZERI_LATIN, false },
+ { COUNTRY_GEORGIA, LANGUAGE_GEORGIAN, false },
+ { COUNTRY_KYRGYZSTAN, LANGUAGE_KIRGHIZ, false },
+ { COUNTRY_UZBEKISTAN, LANGUAGE_UZBEK_LATIN, false }
+};
+
+const CountryEntry * const pEnd = pTable + sizeof( pTable ) / sizeof( pTable[ 0 ] );
+
+// ----------------------------------------------------------------------------
+
+/** Predicate comparing a country ID with the member of a CountryEntry. */
+struct CountryEntryPred_Country
+{
+ CountryId meCountry;
+
+ inline explicit CountryEntryPred_Country( CountryId eCountry ) :
+ meCountry( eCountry ) {}
+
+ inline bool operator()( const CountryEntry& rCmp ) const
+ { return rCmp.meCountry == meCountry; }
+};
+
+// ----------------------------------------------------------------------------
+
+/** Predicate comparing a language type with the member of a CountryEntry.
+
+ Compares by primary language only, if the passed CountryEntry allows it
+ (the member mbUseSubLang is cleared), otherwise by full language type. */
+struct CountryEntryPred_Language
+{
+ LanguageType meLanguage;
+
+ inline explicit CountryEntryPred_Language( LanguageType eLanguage ) :
+ meLanguage( eLanguage ) {}
+
+ inline bool operator()( const CountryEntry& rCmp ) const;
+};
+
+inline bool CountryEntryPred_Language::operator()( const CountryEntry& rCmp ) const
+{
+ // rCmp.mbUseSubLang==true -> compare full language type
+ // rCmp.mbUseSubLang==false -> compare primary language only
+ return rCmp.mbUseSubLang ? (meLanguage == rCmp.meLanguage) :
+ ((meLanguage & 0x03FF) == (rCmp.meLanguage & 0x03FF));
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace
+
+// Country ID <-> Language type conversion ====================================
+
+CountryId ConvertLanguageToCountry( LanguageType eLanguage )
+{
+ // country of a found primary language type
+ CountryId ePrimCountry = COUNTRY_DONTKNOW;
+
+ // find an exact match and a primary-language-only match, in one pass
+ const CountryEntry* pEntry = pTable;
+ do
+ {
+ pEntry = std::find_if( pEntry, pEnd, CountryEntryPred_Language( eLanguage ) );
+ if( pEntry != pEnd )
+ {
+ if( pEntry->mbUseSubLang )
+ return pEntry->meCountry; // exact match found -> return
+ if( ePrimCountry == COUNTRY_DONTKNOW )
+ ePrimCountry = pEntry->meCountry;
+ ++pEntry; // one entry forward for next find_if() call
+ }
+ }
+ while( pEntry != pEnd );
+
+ return ePrimCountry;
+}
+
+LanguageType ConvertCountryToLanguage( CountryId eCountry )
+{
+ // just find the first occurance of eCountry and return the language type
+ const CountryEntry* pEntry = std::find_if( pTable, pEnd, CountryEntryPred_Country( eCountry ) );
+ return (pEntry != pEnd) ? pEntry->meLanguage : LANGUAGE_DONTKNOW;
+}
+
+// ============================================================================
+
+} // namespace svx
+
+// ============================================================================
+
diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx
new file mode 100644
index 000000000000..b312988b5397
--- /dev/null
+++ b/filter/source/msfilter/escherex.cxx
@@ -0,0 +1,4848 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: escherex.cxx,v $
+ * $Revision: 1.77.64.1 $
+ *
+ * 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_filter.hxx"
+#include "svx/impgrf.hxx"
+#include "eschesdo.hxx"
+#include <filter/msfilter/escherex.hxx>
+#include <svx/unoapi.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdmodel.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <tools/stream.hxx>
+#include <tools/zcodec.hxx>
+#include <svx/svdopath.hxx>
+#include <stdlib.h>
+#include <svtools/filter.hxx>
+#include "svx/EnhancedCustomShapeTypeNames.hxx"
+#include "svx/EnhancedCustomShapeGeometry.hxx"
+#include <svx/EnhancedCustomShapeFunctionParser.hxx>
+#include "svx/EnhancedCustomShape2d.hxx"
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/awt/GradientStyle.hpp>
+#include <com/sun/star/awt/RasterOperation.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/LineJoint.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/drawing/BezierPoint.hpp>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
+#include <com/sun/star/drawing/ConnectionType.hpp>
+#include <com/sun/star/drawing/CircleKind.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <com/sun/star/drawing/FlagSequence.hpp>
+#include <com/sun/star/drawing/PolygonFlags.hpp>
+#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include <vcl/hatch.hxx>
+#include <com/sun/star/awt/XGraphics.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/drawing/ColorMode.hpp>
+#include <com/sun/star/drawing/Position3D.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/text/GraphicCrop.hpp>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <comphelper/extract.hxx>
+#include <toolkit/unohlp.hxx>
+#include <vcl/virdev.hxx>
+#include <rtl/crc.h>
+#include <vos/xception.hxx>
+#ifndef _VOS_NO_NAMESPACE
+using namespace vos;
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+
+// ---------------------------------------------------------------------------------------------
+
+EscherExContainer::EscherExContainer( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance ) :
+ rStrm ( rSt )
+{
+ rStrm << (sal_uInt32)( ( 0xf | ( nInstance << 4 ) ) | ( nRecType << 16 ) ) << (sal_uInt32)0;
+ nContPos = rStrm.Tell();
+}
+EscherExContainer::~EscherExContainer()
+{
+ sal_uInt32 nPos = rStrm.Tell();
+ sal_uInt32 nSize= nPos - nContPos;
+ if ( nSize )
+ {
+ rStrm.Seek( nContPos - 4 );
+ rStrm << nSize;
+ rStrm.Seek( nPos );
+ }
+}
+
+EscherExAtom::EscherExAtom( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance, const sal_uInt8 nVersion ) :
+ rStrm ( rSt )
+{
+ rStrm << (sal_uInt32)( ( nVersion | ( nInstance << 4 ) ) | ( nRecType << 16 ) ) << (sal_uInt32)0;
+ nContPos = rStrm.Tell();
+}
+EscherExAtom::~EscherExAtom()
+{
+ sal_uInt32 nPos = rStrm.Tell();
+ sal_uInt32 nSize= nPos - nContPos;
+ if ( nSize )
+ {
+ rStrm.Seek( nContPos - 4 );
+ rStrm << nSize;
+ rStrm.Seek( nPos );
+ }
+}
+
+// ---------------------------------------------------------------------------------------------
+
+EscherExClientRecord_Base::~EscherExClientRecord_Base()
+{
+}
+
+EscherExClientAnchor_Base::~EscherExClientAnchor_Base()
+{
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherPropertyContainer::ImplInit()
+{
+ nSortCount = 0;
+ nCountCount = 0;
+ nCountSize = 0;
+ nSortBufSize = 64;
+ bHasComplexData = sal_False;
+ bSuppressRotation = sal_False;
+ pSortStruct = new EscherPropSortStruct[ nSortBufSize ];
+}
+
+EscherPropertyContainer::EscherPropertyContainer() :
+ pGraphicProvider ( NULL ),
+ pPicOutStrm ( NULL )
+{
+ ImplInit();
+};
+
+EscherPropertyContainer::EscherPropertyContainer(
+ EscherGraphicProvider& rGraphProv,
+ SvStream* pPiOutStrm,
+ Rectangle& rBoundRect ) :
+
+ pGraphicProvider ( &rGraphProv ),
+ pPicOutStrm ( pPiOutStrm ),
+ pShapeBoundRect ( &rBoundRect )
+{
+ ImplInit();
+}
+
+EscherPropertyContainer::~EscherPropertyContainer()
+{
+ if ( bHasComplexData )
+ {
+ while ( nSortCount-- )
+ delete[] pSortStruct[ nSortCount ].pBuf;
+ }
+ delete[] pSortStruct;
+};
+
+void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, sal_uInt32 nPropValue, sal_Bool bBlib )
+{
+ AddOpt( nPropID, bBlib, nPropValue, NULL, 0 );
+}
+
+void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, const rtl::OUString& rString )
+{
+ sal_Int32 j, i, nLen = rString.getLength() * 2 + 2;
+ sal_uInt8* pBuf = new sal_uInt8[ nLen ];
+ for ( j = i = 0; i < rString.getLength(); i++ )
+ {
+ sal_uInt16 nChar = (sal_uInt16)rString[ i ];
+ pBuf[ j++ ] = (sal_uInt8)nChar;
+ pBuf[ j++ ] = (sal_uInt8)( nChar >> 8 );
+ }
+ pBuf[ j++ ] = 0;
+ pBuf[ j++ ] = 0;
+ AddOpt( nPropID, sal_True, nLen, pBuf, nLen );
+}
+
+void EscherPropertyContainer::AddOpt( sal_uInt16 nPropID, sal_Bool bBlib, sal_uInt32 nPropValue, sal_uInt8* pProp, sal_uInt32 nPropSize )
+{
+ if ( bBlib ) // bBlib is only valid when fComplex = 0
+ nPropID |= 0x4000;
+ if ( pProp )
+ nPropID |= 0x8000; // fComplex = TRUE;
+
+ sal_uInt32 i;
+ for( i = 0; i < nSortCount; i++ )
+ {
+ if ( ( pSortStruct[ i ].nPropId &~0xc000 ) == ( nPropID &~0xc000 ) ) // pruefen, ob Property nur ersetzt wird
+ {
+ pSortStruct[ i ].nPropId = nPropID;
+ if ( pSortStruct[ i ].pBuf )
+ {
+ nCountSize -= pSortStruct[ i ].nPropSize;
+ delete[] pSortStruct[ i ].pBuf;
+ }
+ pSortStruct[ i ].pBuf = pProp;
+ pSortStruct[ i ].nPropSize = nPropSize;
+ pSortStruct[ i ].nPropValue = nPropValue;
+ if ( pProp )
+ nCountSize += nPropSize;
+ return;
+ }
+ }
+ nCountCount++;
+ nCountSize += 6;
+ if ( nSortCount == nSortBufSize ) // buffer vergroessern
+ {
+ nSortBufSize <<= 1;
+ EscherPropSortStruct* pTemp = new EscherPropSortStruct[ nSortBufSize ];
+ for( i = 0; i < nSortCount; i++ )
+ {
+ pTemp[ i ] = pSortStruct[ i ];
+ }
+ delete pSortStruct;
+ pSortStruct = pTemp;
+ }
+ pSortStruct[ nSortCount ].nPropId = nPropID; // property einfuegen
+ pSortStruct[ nSortCount ].pBuf = pProp;
+ pSortStruct[ nSortCount ].nPropSize = nPropSize;
+ pSortStruct[ nSortCount++ ].nPropValue = nPropValue;
+
+ if ( pProp )
+ {
+ nCountSize += nPropSize;
+ bHasComplexData = sal_True;
+ }
+}
+
+sal_Bool EscherPropertyContainer::GetOpt( sal_uInt16 nPropId, sal_uInt32& rPropValue ) const
+{
+ EscherPropSortStruct aPropStruct;
+
+ if ( GetOpt( nPropId, aPropStruct ) )
+ {
+ rPropValue = aPropStruct.nPropValue;
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool EscherPropertyContainer::GetOpt( sal_uInt16 nPropId, EscherPropSortStruct& rPropValue ) const
+{
+ for( sal_uInt32 i = 0; i < nSortCount; i++ )
+ {
+ if ( ( pSortStruct[ i ].nPropId &~0xc000 ) == ( nPropId &~0xc000 ) )
+ {
+ rPropValue = pSortStruct[ i ];
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+EscherProperties EscherPropertyContainer::GetOpts() const
+{
+ EscherProperties aVector;
+
+ for ( sal_uInt32 i = 0; i < nSortCount; ++i )
+ aVector.push_back( pSortStruct[ i ] );
+
+ return aVector;
+}
+
+extern "C" int __LOADONCALLAPI EscherPropSortFunc( const void* p1, const void* p2 )
+{
+ INT16 nID1 = ((EscherPropSortStruct*)p1)->nPropId &~0xc000;
+ INT16 nID2 = ((EscherPropSortStruct*)p2)->nPropId &~0xc000;
+
+ if( nID1 < nID2 )
+ return -1;
+ else if( nID1 > nID2 )
+ return 1;
+ else
+ return 0;
+}
+
+void EscherPropertyContainer::Commit( SvStream& rSt, sal_uInt16 nVersion, sal_uInt16 nRecType )
+{
+ rSt << (sal_uInt16)( ( nCountCount << 4 ) | ( nVersion & 0xf ) ) << nRecType << nCountSize;
+ if ( nSortCount )
+ {
+ qsort( pSortStruct, nSortCount, sizeof( EscherPropSortStruct ), EscherPropSortFunc );
+ sal_uInt32 i;
+
+ for ( i = 0; i < nSortCount; i++ )
+ {
+ sal_uInt32 nPropValue = pSortStruct[ i ].nPropValue;
+ sal_uInt16 nPropId = pSortStruct[ i ].nPropId;
+
+ if ( bSuppressRotation && ( nPropId == ESCHER_Prop_Rotation ) )
+ nPropValue = 0;
+
+ rSt << nPropId
+ << nPropValue;
+ }
+ if ( bHasComplexData )
+ {
+ for ( i = 0; i < nSortCount; i++ )
+ {
+ if ( pSortStruct[ i ].pBuf )
+ rSt.Write( pSortStruct[ i ].pBuf, pSortStruct[ i ].nPropSize );
+ }
+ }
+ }
+}
+
+sal_Bool EscherPropertyContainer::IsFontWork() const
+{
+ sal_uInt32 nTextPathFlags = 0;
+ GetOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags );
+ return ( nTextPathFlags & 0x4000 ) != 0;
+}
+
+sal_uInt32 EscherPropertyContainer::ImplGetColor( const sal_uInt32 nSOColor, sal_Bool bSwap )
+{
+ if ( bSwap )
+ {
+ sal_uInt32 nColor = nSOColor & 0xff00; // GRUEN
+ nColor |= (sal_uInt8)( nSOColor ) << 16; // ROT
+ nColor |= (sal_uInt8)( nSOColor >> 16 ); // BLAU
+ return nColor;
+ }
+ else
+ return nSOColor & 0xffffff;
+}
+
+sal_uInt32 EscherPropertyContainer::GetGradientColor(
+ const ::com::sun::star::awt::Gradient* pGradient,
+ sal_uInt32 nStartColor )
+{
+ sal_uInt32 nIntensity = 100;
+ Color aColor;
+
+ if ( pGradient )
+ {
+ if ( nStartColor & 1 )
+ {
+ nIntensity = pGradient->StartIntensity;
+ aColor = pGradient->StartColor;
+ }
+ else
+ {
+ nIntensity = pGradient->EndIntensity;
+ aColor = pGradient->EndColor;
+ }
+ }
+ sal_uInt32 nRed = ( ( aColor.GetRed() * nIntensity ) / 100 );
+ sal_uInt32 nGreen = ( ( aColor.GetGreen() * nIntensity ) / 100 ) << 8;
+ sal_uInt32 nBlue = ( ( aColor.GetBlue() * nIntensity ) / 100 ) << 16;
+ return nRed | nGreen | nBlue;
+}
+
+void EscherPropertyContainer::CreateGradientProperties(
+ const ::com::sun::star::awt::Gradient & rGradient )
+{
+ sal_uInt32 nFillType = ESCHER_FillShadeScale;
+ sal_uInt32 nAngle = 0;
+ sal_uInt32 nFillFocus = 0;
+ sal_uInt32 nFillLR = 0;
+ sal_uInt32 nFillTB = 0;
+ sal_uInt32 nFirstColor = 0;
+ bool bWriteFillTo = false;
+
+ switch ( rGradient.Style )
+ {
+ case ::com::sun::star::awt::GradientStyle_LINEAR :
+ case ::com::sun::star::awt::GradientStyle_AXIAL :
+ {
+ nFillType = ESCHER_FillShadeScale;
+ nAngle = (rGradient.Angle * 0x10000) / 10;
+ nFillFocus = (sal::static_int_cast<int>(rGradient.Style) ==
+ sal::static_int_cast<int>(GradientStyle_LINEAR)) ? 0 : 50;
+ }
+ break;
+ case ::com::sun::star::awt::GradientStyle_RADIAL :
+ case ::com::sun::star::awt::GradientStyle_ELLIPTICAL :
+ case ::com::sun::star::awt::GradientStyle_SQUARE :
+ case ::com::sun::star::awt::GradientStyle_RECT :
+ {
+ nFillLR = (rGradient.XOffset * 0x10000) / 100;
+ nFillTB = (rGradient.YOffset * 0x10000) / 100;
+ if ( ((nFillLR > 0) && (nFillLR < 0x10000)) || ((nFillTB > 0) && (nFillTB < 0x10000)) )
+ nFillType = ESCHER_FillShadeShape;
+ else
+ nFillType = ESCHER_FillShadeCenter;
+ nFirstColor = 1;
+ bWriteFillTo = true;
+ }
+ break;
+ case ::com::sun::star::awt::GradientStyle_MAKE_FIXED_SIZE : break;
+ }
+ AddOpt( ESCHER_Prop_fillType, nFillType );
+ AddOpt( ESCHER_Prop_fillAngle, nAngle );
+ AddOpt( ESCHER_Prop_fillColor, GetGradientColor( &rGradient, nFirstColor ) );
+ AddOpt( ESCHER_Prop_fillBackColor, GetGradientColor( &rGradient, nFirstColor ^ 1 ) );
+ AddOpt( ESCHER_Prop_fillFocus, nFillFocus );
+ if ( bWriteFillTo )
+ {
+ AddOpt( ESCHER_Prop_fillToLeft, nFillLR );
+ AddOpt( ESCHER_Prop_fillToTop, nFillTB );
+ AddOpt( ESCHER_Prop_fillToRight, nFillLR );
+ AddOpt( ESCHER_Prop_fillToBottom, nFillTB );
+ }
+}
+
+void EscherPropertyContainer::CreateGradientProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet )
+{
+ ::com::sun::star::uno::Any aAny;
+ ::com::sun::star::awt::Gradient aGradient;
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillGradient" ) ), sal_False ) )
+ {
+ aGradient = *static_cast< const ::com::sun::star::awt::Gradient* >( aAny.getValue() );
+ }
+ CreateGradientProperties( aGradient );
+};
+
+void EscherPropertyContainer::CreateFillProperties(
+ const uno::Reference< beans::XPropertySet > & rXPropSet,
+ sal_Bool bEdge )
+{
+ ::com::sun::star::uno::Any aAny;
+ AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapNone );
+ AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
+
+ sal_uInt32 nFillBackColor = 0;
+
+ const rtl::OUString aPropName( String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) );
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, aPropName, sal_False ) )
+ {
+ ::com::sun::star::drawing::FillStyle eFS;
+ if ( ! ( aAny >>= eFS ) )
+ eFS = ::com::sun::star::drawing::FillStyle_SOLID;
+ switch( eFS )
+ {
+ case ::com::sun::star::drawing::FillStyle_GRADIENT :
+ {
+ CreateGradientProperties( rXPropSet );
+ AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
+ }
+ break;
+
+ case ::com::sun::star::drawing::FillStyle_BITMAP :
+ {
+ CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ), sal_True );
+ AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
+ AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
+ }
+ break;
+ case ::com::sun::star::drawing::FillStyle_HATCH :
+ {
+ CreateGraphicProperties( rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ), sal_True );
+ }
+ break;
+ case ::com::sun::star::drawing::FillStyle_SOLID :
+ default:
+ {
+ ::com::sun::star::beans::PropertyState ePropState = EscherPropertyValueHelper::GetPropertyState(
+ rXPropSet, aPropName );
+ if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
+ AddOpt( ESCHER_Prop_fillType, ESCHER_FillSolid );
+
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False ) )
+ {
+ sal_uInt32 nFillColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()) );
+ nFillBackColor = nFillColor ^ 0xffffff;
+ AddOpt( ESCHER_Prop_fillColor, nFillColor );
+ }
+ AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100010 );
+ AddOpt( ESCHER_Prop_fillBackColor, nFillBackColor );
+ break;
+ }
+ case ::com::sun::star::drawing::FillStyle_NONE :
+ AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
+ break;
+ }
+ if ( eFS != ::com::sun::star::drawing::FillStyle_NONE )
+ {
+ sal_uInt16 nTransparency = ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillTransparence" ) ), sal_True ) )
+ ? *((sal_Int16*)aAny.getValue() )
+ : 0;
+ if ( nTransparency )
+ AddOpt( ESCHER_Prop_fillOpacity, ( ( 100 - nTransparency ) << 16 ) / 100 );
+ }
+ }
+ CreateLineProperties( rXPropSet, bEdge );
+}
+
+void EscherPropertyContainer::CreateTextProperties(
+ const uno::Reference< beans::XPropertySet > & rXPropSet, sal_uInt32 nTextId,
+ const sal_Bool bIsCustomShape, const sal_Bool bIsTextFrame )
+{
+ uno::Any aAny;
+ text::WritingMode eWM( text::WritingMode_LR_TB );
+ drawing::TextVerticalAdjust eVA( drawing::TextVerticalAdjust_TOP );
+ drawing::TextHorizontalAdjust eHA( drawing::TextHorizontalAdjust_LEFT );
+
+ sal_Int32 nLeft ( 0 );
+ sal_Int32 nTop ( 0 );
+ sal_Int32 nRight ( 0 );
+ sal_Int32 nBottom ( 0 );
+
+ // used with normal shapes:
+ sal_Bool bAutoGrowWidth ( sal_False );
+ sal_Bool bAutoGrowHeight ( sal_False );
+ // used with ashapes:
+ sal_Bool bWordWrap ( sal_False );
+ sal_Bool bAutoGrowSize ( sal_False );
+
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextWritingMode" ) ), sal_True ) )
+ aAny >>= eWM;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextVerticalAdjust" ) ), sal_True ) )
+ aAny >>= eVA;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextHorizontalAdjust" ) ), sal_True ) )
+ aAny >>= eHA;
+ if ( bIsCustomShape )
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextWordWrap" ) ), sal_False ) )
+ aAny >>= bWordWrap;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) ), sal_True ) )
+ aAny >>= bAutoGrowSize;
+ }
+ else if ( bIsTextFrame )
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowWidth" ) ), sal_True ) )
+ aAny >>= bAutoGrowWidth;
+
+// i63936 not setting autogrowheight, because otherwise
+// the minframeheight of the text will be ignored
+//
+// if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextAutoGrowHeight" ) ), sal_True ) )
+// aAny >>= bAutoGrowHeight;
+ }
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextLeftDistance" ) ) ) )
+ aAny >>= nLeft;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextUpperDistance" ) ) ) )
+ aAny >>= nTop;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextRightDistance" ) ) ) )
+ aAny >>= nRight;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "TextLowerDistance" ) ) ) )
+ aAny >>= nBottom;
+
+/*
+ if ( rObj.ImplGetPropertyValue(
+ ::rtl::OUString::createFromAscii("TextWritingMode") ) )
+ {
+ ::com::sun::star::text::WritingMode eMode;
+ rObj.GetUsrAny() >>= eMode;
+ switch (eMode)
+ {
+ case ::com::sun::star::text::WritingMode_TB_RL:
+ //Well if it so happens that we are fliped 180 we can use
+ //this instead.
+ if (rObj.GetAngle() == 18000)
+ eFlow = ESCHER_txflBtoT;
+ else
+ eFlow = ESCHER_txflTtoBA;
+ break;
+ case ::com::sun::star::text::WritingMode_RL_TB:
+ eDir = ESCHER_txdirRTL;
+ break;
+ }
+ }
+*/
+
+ ESCHER_AnchorText eAnchor = ESCHER_AnchorTop;
+ ESCHER_WrapMode eWrapMode = ESCHER_WrapSquare;
+ sal_uInt32 nTextAttr = 0x40004; // rotate text with shape
+
+ if ( eWM == text::WritingMode_TB_RL )
+ { // verical writing
+ switch ( eHA )
+ {
+ case drawing::TextHorizontalAdjust_LEFT :
+ eAnchor = ESCHER_AnchorBottom;
+ break;
+ case drawing::TextHorizontalAdjust_CENTER :
+ eAnchor = ESCHER_AnchorMiddle;
+ break;
+ default :
+ case drawing::TextHorizontalAdjust_BLOCK :
+ case drawing::TextHorizontalAdjust_RIGHT :
+ eAnchor = ESCHER_AnchorTop;
+ break;
+ }
+ if ( eVA == drawing::TextVerticalAdjust_CENTER )
+ {
+ switch ( eAnchor )
+ {
+ case ESCHER_AnchorMiddle :
+ eAnchor = ESCHER_AnchorMiddleCentered;
+ break;
+ case ESCHER_AnchorBottom :
+ eAnchor = ESCHER_AnchorBottomCentered;
+ break;
+ default :
+ case ESCHER_AnchorTop :
+ eAnchor = ESCHER_AnchorTopCentered;
+ break;
+ }
+ }
+ if ( bIsCustomShape )
+ {
+ if ( bWordWrap )
+ eWrapMode = ESCHER_WrapSquare;
+ else
+ eWrapMode = ESCHER_WrapNone;
+ if ( bAutoGrowSize )
+ nTextAttr |= 0x20002;
+ }
+ else
+ {
+ if ( bAutoGrowHeight )
+ eWrapMode = ESCHER_WrapNone;
+ if ( bAutoGrowWidth )
+ nTextAttr |= 0x20002;
+ }
+
+ AddOpt( ESCHER_Prop_txflTextFlow, ESCHER_txflTtoBA ); // rotate text within shape by 90
+ }
+ else
+ { // normal from left to right
+ switch ( eVA )
+ {
+ case drawing::TextVerticalAdjust_CENTER :
+ eAnchor = ESCHER_AnchorMiddle;
+ break;
+
+ case drawing::TextVerticalAdjust_BOTTOM :
+ eAnchor = ESCHER_AnchorBottom;
+ break;
+
+ default :
+ case drawing::TextVerticalAdjust_TOP :
+ eAnchor = ESCHER_AnchorTop;
+ break;
+ }
+ if ( eHA == drawing::TextHorizontalAdjust_CENTER )
+ {
+ switch( eAnchor )
+ {
+ case ESCHER_AnchorMiddle :
+ eAnchor = ESCHER_AnchorMiddleCentered;
+ break;
+ case ESCHER_AnchorBottom :
+ eAnchor = ESCHER_AnchorBottomCentered;
+ break;
+ case ESCHER_AnchorTop :
+ eAnchor = ESCHER_AnchorTopCentered;
+ break;
+ default: break;
+ }
+ }
+ if ( bIsCustomShape )
+ {
+ if ( bWordWrap )
+ eWrapMode = ESCHER_WrapSquare;
+ else
+ eWrapMode = ESCHER_WrapNone;
+ if ( bAutoGrowSize )
+ nTextAttr |= 0x20002;
+ }
+ else
+ {
+ if ( bAutoGrowWidth )
+ eWrapMode = ESCHER_WrapNone;
+ if ( bAutoGrowHeight )
+ nTextAttr |= 0x20002;
+ }
+ }
+ AddOpt( ESCHER_Prop_dxTextLeft, nLeft * 360 );
+ AddOpt( ESCHER_Prop_dxTextRight, nRight * 360 );
+ AddOpt( ESCHER_Prop_dyTextTop, nTop * 360 );
+ AddOpt( ESCHER_Prop_dyTextBottom, nBottom * 360 );
+
+ AddOpt( ESCHER_Prop_WrapText, eWrapMode );
+ AddOpt( ESCHER_Prop_AnchorText, eAnchor );
+ AddOpt( ESCHER_Prop_FitTextToShape, nTextAttr );
+
+ if ( nTextId )
+ AddOpt( ESCHER_Prop_lTxid, nTextId );
+}
+
+sal_Bool EscherPropertyContainer::GetLineArrow( const sal_Bool bLineStart,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ ESCHER_LineEnd& reLineEnd, sal_Int32& rnArrowLength, sal_Int32& rnArrowWidth )
+{
+ static String sLineStart ( RTL_CONSTASCII_USTRINGPARAM( "LineStart" ) );
+ static String sLineStartName( RTL_CONSTASCII_USTRINGPARAM( "LineStartName" ) );
+ static String sLineEnd ( RTL_CONSTASCII_USTRINGPARAM( "LineEnd" ) );
+ static String sLineEndName ( RTL_CONSTASCII_USTRINGPARAM( "LineEndName" ) );
+
+ const String sLine ( bLineStart ? sLineStart : sLineEnd );
+ const String sLineName ( bLineStart ? sLineStartName : sLineEndName );
+
+ sal_Bool bIsArrow = sal_False;
+
+ ::com::sun::star::uno::Any aAny;
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, sLine, sal_False ) )
+ {
+ PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aAny ) );
+ if ( aPolyPoly.Count() && aPolyPoly[ 0 ].GetSize() )
+ {
+ bIsArrow = sal_True;
+
+ reLineEnd = ESCHER_LineArrowEnd;
+ rnArrowLength = 1;
+ rnArrowWidth = 1;
+
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, sLineName, sal_False ) )
+ {
+ String aArrowStartName = *(::rtl::OUString*)aAny.getValue();
+ rtl::OUString aApiName;
+ sal_Int16 nWhich = bLineStart ? XATTR_LINESTART : XATTR_LINEEND;
+
+ SvxUnogetApiNameForItem( nWhich, aArrowStartName, aApiName );
+ if ( aApiName.getLength() )
+ {
+
+ /* todo:
+ calculate the best option for ArrowLenght and ArrowWidth
+ */
+ if ( aApiName.equalsAscii( "Arrow concave" ) )
+ reLineEnd = ESCHER_LineArrowStealthEnd;
+ else if ( aApiName.equalsAscii( "Square 45" ) )
+ reLineEnd = ESCHER_LineArrowDiamondEnd;
+ else if ( aApiName.equalsAscii( "Small Arrow" ) )
+ reLineEnd = ESCHER_LineArrowEnd;
+ else if ( aApiName.equalsAscii( "Dimension Lines" ) )
+ {
+ rnArrowLength = 0;
+ rnArrowWidth = 2;
+ reLineEnd = ESCHER_LineArrowOvalEnd;
+ }
+ else if ( aApiName.equalsAscii( "Double Arrow" ) )
+ reLineEnd = ESCHER_LineArrowEnd;
+ else if ( aApiName.equalsAscii( "Rounded short Arrow" ) )
+ reLineEnd = ESCHER_LineArrowEnd;
+ else if ( aApiName.equalsAscii( "Symmetric Arrow" ) )
+ reLineEnd = ESCHER_LineArrowEnd;
+ else if ( aApiName.equalsAscii( "Line Arrow" ) )
+ reLineEnd = ESCHER_LineArrowOpenEnd;
+ else if ( aApiName.equalsAscii( "Rounded large Arrow" ) )
+ reLineEnd = ESCHER_LineArrowEnd;
+ else if ( aApiName.equalsAscii( "Circle" ) )
+ reLineEnd = ESCHER_LineArrowOvalEnd;
+ else if ( aApiName.equalsAscii( "Square" ) )
+ reLineEnd = ESCHER_LineArrowDiamondEnd;
+ else if ( aApiName.equalsAscii( "Arrow" ) )
+ reLineEnd = ESCHER_LineArrowEnd;
+ }
+ else if ( aArrowStartName.GetTokenCount( ' ' ) == 2 )
+ {
+ sal_Bool b = sal_True;
+ String aArrowName( aArrowStartName.GetToken( 0, ' ' ) );
+ if ( aArrowName.EqualsAscii( "msArrowEnd" ) )
+ reLineEnd = ESCHER_LineArrowEnd;
+ else if ( aArrowName.EqualsAscii( "msArrowOpenEnd" ) )
+ reLineEnd = ESCHER_LineArrowOpenEnd;
+ else if ( aArrowName.EqualsAscii( "msArrowStealthEnd" ) )
+ reLineEnd = ESCHER_LineArrowStealthEnd;
+ else if ( aArrowName.EqualsAscii( "msArrowDiamondEnd" ) )
+ reLineEnd = ESCHER_LineArrowDiamondEnd;
+ else if ( aArrowName.EqualsAscii( "msArrowOvalEnd" ) )
+ reLineEnd = ESCHER_LineArrowOvalEnd;
+ else
+ b = sal_False;
+
+ // now we have the arrow, and try to determine the arrow size;
+ if ( b )
+ {
+ String aArrowSize( aArrowStartName.GetToken( 1, ' ' ) );
+ sal_Int32 nArrowSize = aArrowSize.ToInt32();
+ rnArrowWidth = ( nArrowSize - 1 ) / 3;
+ rnArrowLength = nArrowSize - ( rnArrowWidth * 3 ) - 1;
+ }
+ }
+ }
+ }
+ }
+ return bIsArrow;
+}
+
+void EscherPropertyContainer::CreateLineProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ sal_Bool bEdge )
+{
+ ::com::sun::star::uno::Any aAny;
+ sal_uInt32 nLineFlags = 0x80008;
+
+ ESCHER_LineEnd eLineEnd;
+ sal_Int32 nArrowLength;
+ sal_Int32 nArrowWidth;
+
+ sal_Bool bSwapLineEnds = sal_False;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CircleKind" ) ), sal_True ) )
+ {
+ ::com::sun::star::drawing::CircleKind eCircleKind;
+ if ( aAny >>= eCircleKind )
+ {
+ if ( eCircleKind == ::com::sun::star::drawing::CircleKind_ARC )
+ bSwapLineEnds = sal_True;
+ }
+ }
+ if ( GetLineArrow( bSwapLineEnds ? sal_False : sal_True, rXPropSet, eLineEnd, nArrowLength, nArrowWidth ) )
+ {
+ AddOpt( ESCHER_Prop_lineStartArrowLength, nArrowLength );
+ AddOpt( ESCHER_Prop_lineStartArrowWidth, nArrowWidth );
+ AddOpt( ESCHER_Prop_lineStartArrowhead, eLineEnd );
+ nLineFlags |= 0x100010;
+ }
+ if ( GetLineArrow( bSwapLineEnds ? sal_True : sal_False, rXPropSet, eLineEnd, nArrowLength, nArrowWidth ) )
+ {
+ AddOpt( ESCHER_Prop_lineEndArrowLength, nArrowLength );
+ AddOpt( ESCHER_Prop_lineEndArrowWidth, nArrowWidth );
+ AddOpt( ESCHER_Prop_lineEndArrowhead, eLineEnd );
+ nLineFlags |= 0x100010;
+ }
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineStyle" ) ), sal_False ) )
+ {
+ ::com::sun::star::drawing::LineStyle eLS;
+ if ( aAny >>= eLS )
+ {
+ switch ( eLS )
+ {
+ case ::com::sun::star::drawing::LineStyle_NONE :
+ AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 ); // 80000
+ break;
+
+ case ::com::sun::star::drawing::LineStyle_DASH :
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineDash" ) ), sal_False ) )
+ {
+ ESCHER_LineDashing eDash = ESCHER_LineSolid;
+ ::com::sun::star::drawing::LineDash* pLineDash = (::com::sun::star::drawing::LineDash*)aAny.getValue();
+ sal_Int32 nDistance = pLineDash->Distance << 1;
+ switch ( pLineDash->Style )
+ {
+ case ::com::sun::star::drawing::DashStyle_ROUND :
+ case ::com::sun::star::drawing::DashStyle_ROUNDRELATIVE :
+ AddOpt( ESCHER_Prop_lineEndCapStyle, 0 ); // Style Round setzen
+ break;
+ default : break;
+ }
+ if ( ((!(pLineDash->Dots )) || (!(pLineDash->Dashes )) ) || ( pLineDash->DotLen == pLineDash->DashLen ) )
+ {
+ sal_Int32 nLen = pLineDash->DotLen;
+ if ( pLineDash->Dashes )
+ nLen = pLineDash->DashLen;
+
+ if ( nLen >= nDistance )
+ eDash = ESCHER_LineLongDashGEL;
+ else if ( pLineDash->Dots )
+ eDash = ESCHER_LineDotSys;
+ else
+ eDash = ESCHER_LineDashGEL;
+ }
+ else // X Y
+ {
+ if ( pLineDash->Dots != pLineDash->Dashes )
+ {
+ if ( ( pLineDash->DashLen > nDistance ) || ( pLineDash->DotLen > nDistance ) )
+ eDash = ESCHER_LineLongDashDotDotGEL;
+ else
+ eDash = ESCHER_LineDashDotDotSys;
+ }
+ else // X Y Y
+ {
+ if ( ( pLineDash->DashLen > nDistance ) || ( pLineDash->DotLen > nDistance ) )
+ eDash = ESCHER_LineLongDashDotGEL;
+ else
+ eDash = ESCHER_LineDashDotGEL;
+
+ }
+ }
+ AddOpt( ESCHER_Prop_lineDashing, eDash );
+ }
+ }
+ case ::com::sun::star::drawing::LineStyle_SOLID :
+ default:
+ {
+ AddOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
+ }
+ break;
+ }
+ }
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineColor" ) ), sal_False ) )
+ {
+ sal_uInt32 nLineColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()) );
+ AddOpt( ESCHER_Prop_lineColor, nLineColor );
+ AddOpt( ESCHER_Prop_lineBackColor, nLineColor ^ 0xffffff );
+ }
+ }
+
+ sal_uInt32 nLineSize = ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineWidth" ) ), sal_False ) )
+ ? *((sal_uInt32*)aAny.getValue())
+ : 0;
+ if ( nLineSize > 1 )
+ AddOpt( ESCHER_Prop_lineWidth, nLineSize * 360 ); // 100TH MM -> PT , 1PT = 12700 EMU
+
+ ESCHER_LineJoin eLineJoin = ESCHER_LineJoinMiter;
+ if ( EscherPropertyValueHelper::GetPropertyValue(
+ aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "LineJoint" ) ), sal_True ) )
+ {
+ ::com::sun::star::drawing::LineJoint eLJ;
+ if ( aAny >>= eLJ )
+ {
+ switch ( eLJ )
+ {
+ case com::sun::star::drawing::LineJoint_NONE :
+ case com::sun::star::drawing::LineJoint_MIDDLE :
+ case com::sun::star::drawing::LineJoint_BEVEL :
+ eLineJoin = ESCHER_LineJoinBevel;
+ break;
+ default:
+ case com::sun::star::drawing::LineJoint_MITER :
+ eLineJoin = ESCHER_LineJoinMiter;
+ break;
+ case com::sun::star::drawing::LineJoint_ROUND :
+ eLineJoin = ESCHER_LineJoinRound;
+ break;
+ }
+ }
+ }
+ AddOpt( ESCHER_Prop_lineJoinStyle, eLineJoin );
+
+ if ( bEdge == sal_False )
+ {
+ AddOpt( ESCHER_Prop_fFillOK, 0x1001 );
+ AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
+ }
+}
+
+static Size lcl_SizeToEmu(Size aPrefSize, MapMode aPrefMapMode)
+{
+ Size aRetSize;
+ if (aPrefMapMode == MAP_PIXEL)
+ aRetSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
+ else
+ aRetSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM );
+ return aRetSize;
+}
+
+void EscherPropertyContainer::ImplCreateGraphicAttributes( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ sal_uInt32 nBlibId, sal_Bool bCreateCroppingAttributes )
+{
+ ::com::sun::star::uno::Any aAny;
+
+ sal_uInt32 nPicFlags = 0;
+ ::com::sun::star::drawing::ColorMode eColorMode( ::com::sun::star::drawing::ColorMode_STANDARD );
+ sal_Int16 nLuminance = 0;
+ sal_Int32 nContrast = 0;
+ sal_Int16 nRed = 0;
+ sal_Int16 nGreen = 0;
+ sal_Int16 nBlue = 0;
+ double fGamma = 1.0;
+ sal_Int16 nTransparency = 0;
+
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicColorMode" ) ) ) )
+ aAny >>= eColorMode;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustLuminance" ) ) ) )
+ aAny >>= nLuminance;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustContrast" ) ) ) )
+ {
+ sal_Int16 nC = sal_Int16();
+ aAny >>= nC;
+ nContrast = nC;
+ }
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustRed" ) ) ) )
+ aAny >>= nRed;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustGreen" ) ) ) )
+ aAny >>= nGreen;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "AdjustBlue" ) ) ) )
+ aAny >>= nBlue;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Gamma" ) ) ) )
+ aAny >>= fGamma;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Transparency" ) ) ) )
+ aAny >>= nTransparency;
+
+ if ( eColorMode == ::com::sun::star::drawing::ColorMode_WATERMARK )
+ {
+ eColorMode = ::com::sun::star::drawing::ColorMode_STANDARD;
+ nLuminance += 70;
+ if ( nLuminance > 100 )
+ nLuminance = 100;
+ nContrast -= 70;
+ if ( nContrast < -100 )
+ nContrast = -100;
+ }
+ if ( eColorMode == ::com::sun::star::drawing::ColorMode_GREYS )
+ nPicFlags |= 0x40004;
+ else if ( eColorMode == ::com::sun::star::drawing::ColorMode_MONO )
+ nPicFlags |= 0x60006;
+
+ if ( nContrast )
+ {
+ nContrast += 100;
+ if ( nContrast == 100)
+ nContrast = 0x10000;
+ else if ( nContrast < 100 )
+ {
+ nContrast *= 0x10000;
+ nContrast /= 100;
+ }
+ else if ( nContrast < 200 )
+ nContrast = ( 100 * 0x10000 ) / ( 200 - nContrast );
+ else
+ nContrast = 0x7fffffff;
+ AddOpt( ESCHER_Prop_pictureContrast, nContrast );
+ }
+ if ( nLuminance )
+ AddOpt( ESCHER_Prop_pictureBrightness, nLuminance * 327 );
+ if ( nPicFlags )
+ AddOpt( ESCHER_Prop_pictureActive, nPicFlags );
+
+ if ( bCreateCroppingAttributes && pGraphicProvider )
+ {
+ Size aPrefSize;
+ MapMode aPrefMapMode;
+ if ( pGraphicProvider->GetPrefSize( nBlibId, aPrefSize, aPrefMapMode ) )
+ {
+ Size aCropSize(lcl_SizeToEmu(aPrefSize, aPrefMapMode));
+ if ( aCropSize.Width() && aCropSize.Height() )
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicCrop" ) ) ) )
+ {
+ ::com::sun::star::text::GraphicCrop aGraphCrop;
+ if ( aAny >>= aGraphCrop )
+ {
+ if ( aGraphCrop.Left )
+ {
+ sal_uInt32 nLeft = ( aGraphCrop.Left * 65536 ) / aCropSize.Width();
+ AddOpt( ESCHER_Prop_cropFromLeft, nLeft );
+ }
+ if ( aGraphCrop.Top )
+ {
+ sal_uInt32 nTop = ( aGraphCrop.Top * 65536 ) / aCropSize.Height();
+ AddOpt( ESCHER_Prop_cropFromTop, nTop );
+ }
+ if ( aGraphCrop.Right )
+ {
+ sal_uInt32 nRight = ( aGraphCrop.Right * 65536 ) / aCropSize.Width();
+ AddOpt( ESCHER_Prop_cropFromRight, nRight );
+ }
+ if ( aGraphCrop.Bottom )
+ {
+ sal_uInt32 nBottom = ( aGraphCrop.Bottom * 65536 ) / aCropSize.Height();
+ AddOpt( ESCHER_Prop_cropFromBottom, nBottom );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+sal_Bool EscherPropertyContainer::CreateOLEGraphicProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape )
+{
+ sal_Bool bRetValue = sal_False;
+
+ if ( rXShape.is() )
+ {
+ SdrObject* pSdrOLE2( GetSdrObjectFromXShape( rXShape ) ); // SJ: leaving unoapi, because currently there is
+ if ( pSdrOLE2 && pSdrOLE2->ISA( SdrOle2Obj ) ) // no access to the native graphic object
+ {
+ Graphic* pGraphic = ((SdrOle2Obj*)pSdrOLE2)->GetGraphic();
+ if ( pGraphic )
+ {
+ GraphicObject aGraphicObject( *pGraphic );
+ ByteString aUniqueId( aGraphicObject.GetUniqueID() );
+ if ( aUniqueId.Len() )
+ {
+ AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture );
+ uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY );
+
+ if ( pGraphicProvider && pPicOutStrm && pShapeBoundRect && aXPropSet.is() )
+ {
+ ::com::sun::star::uno::Any aAny;
+ ::com::sun::star::awt::Rectangle* pVisArea = NULL;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "VisibleArea" ) ) ) )
+ {
+ pVisArea = new ::com::sun::star::awt::Rectangle;
+ aAny >>= (*pVisArea);
+ }
+ Rectangle aRect( Point( 0, 0 ), pShapeBoundRect->GetSize() );
+ sal_uInt32 nBlibId = pGraphicProvider->GetBlibID( *pPicOutStrm, aUniqueId, aRect, pVisArea, NULL );
+ if ( nBlibId )
+ {
+ AddOpt( ESCHER_Prop_pib, nBlibId, sal_True );
+ ImplCreateGraphicAttributes( aXPropSet, nBlibId, sal_False );
+ bRetValue = sal_True;
+ }
+ delete pVisArea;
+ }
+ }
+ }
+ }
+ }
+ return bRetValue;
+}
+
+
+sal_Bool EscherPropertyContainer::ImplCreateEmbeddedBmp( const ByteString& rUniqueId )
+{
+ if( rUniqueId.Len() > 0 )
+ {
+ EscherGraphicProvider aProvider;
+ SvMemoryStream aMemStrm;
+ Rectangle aRect;
+ if ( aProvider.GetBlibID( aMemStrm, rUniqueId, aRect ) )
+ {
+ // grab BLIP from stream and insert directly as complex property
+ // ownership of stream memory goes to complex property
+ aMemStrm.ObjectOwnsMemory( FALSE );
+ sal_uInt8* pBuf = (sal_uInt8*) aMemStrm.GetData();
+ sal_uInt32 nSize = aMemStrm.Seek( STREAM_SEEK_TO_END );
+ AddOpt( ESCHER_Prop_fillBlip, sal_True, nSize, pBuf, nSize );
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+sal_Bool EscherPropertyContainer::CreateEmbeddedBitmapProperties(
+ const ::rtl::OUString& rBitmapUrl, ::com::sun::star::drawing::BitmapMode eBitmapMode )
+{
+ sal_Bool bRetValue = sal_False;
+ String aVndUrl( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
+ String aBmpUrl( rBitmapUrl );
+ xub_StrLen nIndex = aBmpUrl.Search( aVndUrl, 0 );
+ if( nIndex != STRING_NOTFOUND )
+ {
+ // note: += ist not defined for xub_StrLen -> conversion to int and back to xub_StrLen
+ nIndex = nIndex + aVndUrl.Len();
+ if( aBmpUrl.Len() > nIndex )
+ {
+ ByteString aUniqueId( aBmpUrl, nIndex, aBmpUrl.Len() - nIndex, RTL_TEXTENCODING_UTF8 );
+ bRetValue = ImplCreateEmbeddedBmp( aUniqueId );
+ if( bRetValue )
+ {
+ // bitmap mode property
+ bool bRepeat = eBitmapMode == ::com::sun::star::drawing::BitmapMode_REPEAT;
+ AddOpt( ESCHER_Prop_fillType, bRepeat ? ESCHER_FillTexture : ESCHER_FillPicture );
+ }
+ }
+ }
+ return bRetValue;
+}
+
+
+namespace {
+
+GraphicObject lclDrawHatch( const ::com::sun::star::drawing::Hatch& rHatch, const Color& rBackColor, bool bFillBackground )
+{
+ const MapMode aMap100( MAP_100TH_MM );
+ VirtualDevice aVDev( *Application::GetDefaultDevice(), 0, 1 );
+ aVDev.SetMapMode( aMap100 );
+
+ const Size aOutSize = aVDev.PixelToLogic( Size( 28, 28 ) );
+ aVDev.SetOutputSize( aOutSize );
+
+ Rectangle aRectangle( Point( 0, 0 ), aOutSize );
+ const PolyPolygon aPolyPoly( aRectangle );
+
+ aVDev.SetLineColor();
+ aVDev.SetFillColor( bFillBackground ? rBackColor : Color( COL_TRANSPARENT ) );
+ aVDev.DrawRect( Rectangle( Point(), aOutSize ) );
+
+ Hatch aVclHatch( (HatchStyle) rHatch.Style, Color( rHatch.Color ), rHatch.Distance, (sal_uInt16)rHatch.Angle );
+ aVDev.DrawHatch( aPolyPoly, aVclHatch );
+
+ return GraphicObject( Graphic( aVDev.GetBitmapEx( Point(), aOutSize ) ) );
+}
+
+} // namespace
+
+
+sal_Bool EscherPropertyContainer::CreateEmbeddedHatchProperties( const ::com::sun::star::drawing::Hatch& rHatch, const Color& rBackColor, bool bFillBackground )
+{
+ GraphicObject aGraphicObject = lclDrawHatch( rHatch, rBackColor, bFillBackground );
+ ByteString aUniqueId = aGraphicObject.GetUniqueID();
+ sal_Bool bRetValue = ImplCreateEmbeddedBmp( aUniqueId );
+ if ( bRetValue )
+ AddOpt( ESCHER_Prop_fillType, ESCHER_FillTexture );
+ return bRetValue;
+}
+
+
+sal_Bool EscherPropertyContainer::CreateGraphicProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ const String& rSource, const sal_Bool bCreateFillBitmap, const sal_Bool bCreateCroppingAttributes,
+ const sal_Bool bFillBitmapModeAllowed )
+{
+ sal_Bool bRetValue = sal_False;
+ sal_Bool bCreateFillStyles = sal_False;
+
+ sal_Bool bMirrored = sal_False;
+ sal_Bool bRotate = sal_True;
+ sal_uInt16 nAngle = 0;
+ GraphicAttr* pGraphicAttr = NULL;
+ GraphicObject aGraphicObject;
+ String aGraphicUrl;
+ ByteString aUniqueId;
+ bool bIsGraphicMtf(false);
+
+ ::com::sun::star::drawing::BitmapMode eBitmapMode( ::com::sun::star::drawing::BitmapMode_NO_REPEAT );
+ ::com::sun::star::uno::Any aAny;
+
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, rSource ) )
+ {
+ if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ) )
+ {
+ ::com::sun::star::uno::Sequence<sal_uInt8> aSeq = *(::com::sun::star::uno::Sequence<sal_uInt8>*)aAny.getValue();
+ const sal_uInt8* pAry = aSeq.getArray();
+ sal_uInt32 nAryLen = aSeq.getLength();
+
+ // the metafile is already rotated
+ bRotate = sal_False;
+
+ if ( pAry && nAryLen )
+ {
+ Graphic aGraphic;
+ SvMemoryStream aTemp( (void*)pAry, nAryLen, STREAM_READ );
+ sal_uInt32 nErrCode = GraphicConverter::Import( aTemp, aGraphic, CVT_WMF );
+ if ( nErrCode == ERRCODE_NONE )
+ {
+ aGraphicObject = aGraphic;
+ aUniqueId = aGraphicObject.GetUniqueID();
+ bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE;
+ }
+ }
+ }
+ else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ) )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap >xBitmap;
+ if ( ::cppu::extractInterface( xBitmap, aAny ) )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBmp;
+ if ( aAny >>= xBmp )
+ {
+ BitmapEx aBitmapEx( VCLUnoHelper::GetBitmap( xBmp ) );
+ Graphic aGraphic( aBitmapEx );
+ aGraphicObject = aGraphic;
+ aUniqueId = aGraphicObject.GetUniqueID();
+ bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE;
+ }
+ }
+ }
+ else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ) )
+ {
+ aGraphicUrl = *(::rtl::OUString*)aAny.getValue();
+ }
+ else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ) )
+ {
+ aGraphicUrl = *(::rtl::OUString*)aAny.getValue();
+ bCreateFillStyles = sal_True;
+ }
+ else if ( rSource == String( RTL_CONSTASCII_USTRINGPARAM( "FillHatch" ) ) )
+ {
+ ::com::sun::star::drawing::Hatch aHatch;
+ if ( aAny >>= aHatch )
+ {
+ Color aBackColor;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ), sal_False ) )
+ {
+ aBackColor = ImplGetColor( *((sal_uInt32*)aAny.getValue()), sal_False );
+ }
+ bool bFillBackground = false;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "FillBackground" ) ), sal_True ) )
+ {
+ aAny >>= bFillBackground;
+ }
+ aGraphicObject = lclDrawHatch( aHatch, aBackColor, bFillBackground );
+ aUniqueId = aGraphicObject.GetUniqueID();
+ eBitmapMode = ::com::sun::star::drawing::BitmapMode_REPEAT;
+ bIsGraphicMtf = aGraphicObject.GetType() == GRAPHIC_GDIMETAFILE;
+ }
+ }
+
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "IsMirrored" ) ), sal_True ) )
+ aAny >>= bMirrored;
+
+ if ( bCreateFillBitmap && bFillBitmapModeAllowed )
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapMode" ) ), sal_True ) )
+ aAny >>= eBitmapMode;
+ }
+ else
+ {
+ nAngle = bRotate && EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True )
+ ? (sal_uInt16)( ( *((sal_Int32*)aAny.getValue() ) ) + 5 ) / 10
+ : 0;
+ }
+
+ if ( aGraphicUrl.Len() )
+ {
+ String aVndUrl( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) );
+ xub_StrLen nIndex = aGraphicUrl.Search( aVndUrl, 0 );
+ if ( nIndex != STRING_NOTFOUND )
+ {
+ nIndex = nIndex + aVndUrl.Len();
+ if ( aGraphicUrl.Len() > nIndex )
+ aUniqueId = ByteString( aGraphicUrl, nIndex, aGraphicUrl.Len() - nIndex, RTL_TEXTENCODING_UTF8 );
+ }
+ else
+ {
+ // externally, linked graphic? convert to embedded
+ // one, if transformations are needed. this is because
+ // everything < msoxp cannot even handle rotated
+ // bitmaps.
+ // And check whether the graphic link target is
+ // actually supported by mso.
+ INetURLObject aTmp( aGraphicUrl );
+ GraphicDescriptor aDescriptor(aTmp);
+ aDescriptor.Detect();
+ const USHORT nFormat = aDescriptor.GetFileFormat();
+
+ // can MSO handle it?
+ if ( bMirrored || nAngle ||
+ (nFormat != GFF_BMP &&
+ nFormat != GFF_GIF &&
+ nFormat != GFF_JPG &&
+ nFormat != GFF_PNG &&
+ nFormat != GFF_TIF &&
+ nFormat != GFF_PCT &&
+ nFormat != GFF_WMF &&
+ nFormat != GFF_EMF) )
+ {
+ SvStream* pIn = ::utl::UcbStreamHelper::CreateStream(
+ aTmp.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
+ if ( pIn )
+ {
+ Graphic aGraphic;
+ sal_uInt32 nErrCode = GraphicConverter::Import( *pIn, aGraphic );
+
+ if ( nErrCode == ERRCODE_NONE )
+ {
+ // no.
+ aGraphicObject = aGraphic;
+ aUniqueId = aGraphicObject.GetUniqueID();
+ }
+ // else: simply keep the graphic link
+ delete pIn;
+ }
+ }
+ }
+ }
+
+ if ( aGraphicUrl.Len() || aUniqueId.Len() )
+ {
+ if ( bMirrored || nAngle )
+ {
+ pGraphicAttr = new GraphicAttr;
+ if ( bMirrored )
+ pGraphicAttr->SetMirrorFlags( BMP_MIRROR_HORZ );
+ if ( bIsGraphicMtf )
+ AddOpt( ESCHER_Prop_Rotation, ( ( ((sal_Int32)nAngle << 16 ) / 10 ) + 0x8000 ) &~ 0xffff );
+ else
+ {
+ pGraphicAttr->SetRotation( nAngle );
+ if ( nAngle && pShapeBoundRect ) // up to xp ppoint does not rotate bitmaps !
+ {
+ Polygon aPoly( *pShapeBoundRect );
+ aPoly.Rotate( pShapeBoundRect->TopLeft(), nAngle );
+ *pShapeBoundRect = aPoly.GetBoundRect();
+ bSuppressRotation = sal_True;
+ }
+ }
+ }
+
+ if ( eBitmapMode == ::com::sun::star::drawing::BitmapMode_REPEAT )
+ AddOpt( ESCHER_Prop_fillType, ESCHER_FillTexture );
+ else
+ AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture );
+
+ if ( aUniqueId.Len() )
+ {
+ // write out embedded graphic
+ if ( pGraphicProvider && pPicOutStrm && pShapeBoundRect )
+ {
+ Rectangle aRect( Point( 0, 0 ), pShapeBoundRect->GetSize() );
+
+ sal_uInt32 nBlibId = 0;
+ nBlibId = pGraphicProvider->GetBlibID( *pPicOutStrm, aUniqueId, aRect, NULL, pGraphicAttr );
+ if ( nBlibId )
+ {
+ if ( bCreateFillBitmap )
+ AddOpt( ESCHER_Prop_fillBlip, nBlibId, sal_True );
+ else
+ {
+ AddOpt( ESCHER_Prop_pib, nBlibId, sal_True );
+ ImplCreateGraphicAttributes( rXPropSet, nBlibId, bCreateCroppingAttributes );
+ }
+ bRetValue = sal_True;
+ }
+ }
+ else
+ {
+ EscherGraphicProvider aProvider;
+ SvMemoryStream aMemStrm;
+ Rectangle aRect;
+
+ if ( aProvider.GetBlibID( aMemStrm, aUniqueId, aRect, NULL, pGraphicAttr ) )
+ {
+ // grab BLIP from stream and insert directly as complex property
+ // ownership of stream memory goes to complex property
+ aMemStrm.ObjectOwnsMemory( FALSE );
+ sal_uInt8* pBuf = (sal_uInt8*) aMemStrm.GetData();
+ sal_uInt32 nSize = aMemStrm.Seek( STREAM_SEEK_TO_END );
+ AddOpt( ESCHER_Prop_fillBlip, sal_True, nSize, pBuf, nSize );
+ bRetValue = sal_True;
+ }
+ }
+ }
+ // write out link to graphic
+ else
+ {
+ OSL_ASSERT(aGraphicUrl.Len());
+
+ AddOpt( ESCHER_Prop_pibName, aGraphicUrl );
+ sal_uInt32 nPibFlags=0;
+ GetOpt( ESCHER_Prop_pibFlags, nPibFlags );
+ AddOpt( ESCHER_Prop_pibFlags,
+ ESCHER_BlipFlagLinkToFile|ESCHER_BlipFlagFile|ESCHER_BlipFlagDoNotSave | nPibFlags );
+ }
+ }
+ }
+ delete pGraphicAttr;
+ if ( bCreateFillStyles )
+ CreateFillProperties( rXPropSet, sal_True );
+
+ return bRetValue;
+}
+
+PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape )
+{
+ PolyPolygon aRetPolyPoly;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXPropSet;
+ ::com::sun::star::uno::Any aAny( rXShape->queryInterface(
+ ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >*) 0 ) ));
+
+ String sPolyPolygonBezier( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) );
+ String sPolyPolygon ( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) );
+ String sPolygon ( RTL_CONSTASCII_USTRINGPARAM( "Polygon" ) );
+
+ if ( aAny >>= aXPropSet )
+ {
+ sal_Bool bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolyPolygonBezier, sal_True );
+ if ( !bHasProperty )
+ bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolyPolygon, sal_True );
+ if ( !bHasProperty )
+ bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolygon, sal_True );
+ if ( bHasProperty )
+ aRetPolyPoly = GetPolyPolygon( aAny );
+ }
+ return aRetPolyPoly;
+}
+
+PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno::Any& rAny )
+{
+ sal_Bool bNoError = sal_True;
+
+ Polygon aPolygon;
+ PolyPolygon aPolyPolygon;
+
+ if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PolyPolygonBezierCoords* ) 0 ) )
+ {
+ ::com::sun::star::drawing::PolyPolygonBezierCoords* pSourcePolyPolygon
+ = (::com::sun::star::drawing::PolyPolygonBezierCoords*)rAny.getValue();
+ sal_uInt16 nOuterSequenceCount = (sal_uInt16)pSourcePolyPolygon->Coordinates.getLength();
+
+ // Zeiger auf innere sequences holen
+ ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->Coordinates.getArray();
+ ::com::sun::star::drawing::FlagSequence* pOuterFlags = pSourcePolyPolygon->Flags.getArray();
+
+ bNoError = pOuterSequence && pOuterFlags;
+ if ( bNoError )
+ {
+ sal_uInt16 a, b, nInnerSequenceCount;
+ ::com::sun::star::awt::Point* pArray;
+
+ // dies wird ein Polygon set
+ for ( a = 0; a < nOuterSequenceCount; a++ )
+ {
+ ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++;
+ ::com::sun::star::drawing::FlagSequence* pInnerFlags = pOuterFlags++;
+
+ bNoError = pInnerSequence && pInnerFlags;
+ if ( bNoError )
+ {
+ // Zeiger auf Arrays holen
+ pArray = pInnerSequence->getArray();
+ ::com::sun::star::drawing::PolygonFlags* pFlags = pInnerFlags->getArray();
+
+ if ( pArray && pFlags )
+ {
+ nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength();
+ aPolygon = Polygon( nInnerSequenceCount );
+ for( b = 0; b < nInnerSequenceCount; b++)
+ {
+ PolyFlags ePolyFlags( *( (PolyFlags*)pFlags++ ) );
+ ::com::sun::star::awt::Point aPoint( (::com::sun::star::awt::Point)*(pArray++) );
+ aPolygon[ b ] = Point( aPoint.X, aPoint.Y );
+ aPolygon.SetFlags( b, ePolyFlags );
+
+ if ( ePolyFlags == POLY_CONTROL )
+ continue;
+ }
+ aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND );
+ }
+ }
+ }
+ }
+ }
+ else if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PointSequenceSequence* ) 0 ) )
+ {
+ ::com::sun::star::drawing::PointSequenceSequence* pSourcePolyPolygon
+ = (::com::sun::star::drawing::PointSequenceSequence*)rAny.getValue();
+ sal_uInt16 nOuterSequenceCount = (sal_uInt16)pSourcePolyPolygon->getLength();
+
+ // Zeiger auf innere sequences holen
+ ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray();
+ bNoError = pOuterSequence != NULL;
+ if ( bNoError )
+ {
+ sal_uInt16 a, b, nInnerSequenceCount;
+
+ // dies wird ein Polygon set
+ for( a = 0; a < nOuterSequenceCount; a++ )
+ {
+ ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++;
+ bNoError = pInnerSequence != NULL;
+ if ( bNoError )
+ {
+ // Zeiger auf Arrays holen
+ ::com::sun::star::awt::Point* pArray =
+ pInnerSequence->getArray();
+ if ( pArray != NULL )
+ {
+ nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength();
+ aPolygon = Polygon( nInnerSequenceCount );
+ for( b = 0; b < nInnerSequenceCount; b++)
+ {
+ aPolygon[ b ] = Point( pArray->X, pArray->Y );
+ pArray++;
+ }
+ aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND );
+ }
+ }
+ }
+ }
+ }
+ else if ( rAny.getValueType() == ::getCppuType( ( const ::com::sun::star::drawing::PointSequence* ) 0 ) )
+ {
+ ::com::sun::star::drawing::PointSequence* pInnerSequence =
+ (::com::sun::star::drawing::PointSequence*)rAny.getValue();
+
+ bNoError = pInnerSequence != NULL;
+ if ( bNoError )
+ {
+ sal_uInt16 a, nInnerSequenceCount;
+
+ // Zeiger auf Arrays holen
+ ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray();
+ if ( pArray != NULL )
+ {
+ nInnerSequenceCount = (sal_uInt16)pInnerSequence->getLength();
+ aPolygon = Polygon( nInnerSequenceCount );
+ for( a = 0; a < nInnerSequenceCount; a++)
+ {
+ aPolygon[ a ] = Point( pArray->X, pArray->Y );
+ pArray++;
+ }
+ aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND );
+ }
+ }
+ }
+ return aPolyPolygon;
+}
+
+sal_Bool EscherPropertyContainer::CreatePolygonProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ sal_uInt32 nFlags,
+ sal_Bool bBezier,
+ ::com::sun::star::awt::Rectangle& rGeoRect,
+ Polygon* pPolygon )
+{
+ static String sPolyPolygonBezier( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) );
+ static String sPolyPolygon ( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) );
+
+ sal_Bool bRetValue = sal_True;
+ sal_Bool bLine = ( nFlags & ESCHER_CREATEPOLYGON_LINE ) != 0;
+
+ PolyPolygon aPolyPolygon;
+
+ if ( pPolygon )
+ aPolyPolygon.Insert( *pPolygon, POLYPOLY_APPEND );
+ else
+ {
+ ::com::sun::star::uno::Any aAny;
+ bRetValue = EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ ( bBezier ) ? sPolyPolygonBezier : sPolyPolygon, sal_True );
+ if ( bRetValue )
+ {
+ aPolyPolygon = GetPolyPolygon( aAny );
+ bRetValue = aPolyPolygon.Count() != 0;
+ }
+ }
+ if ( bRetValue )
+ {
+ if ( bLine )
+ {
+ if ( ( aPolyPolygon.Count() == 1 ) && ( aPolyPolygon[ 0 ].GetSize() == 2 ) )
+ {
+ const Polygon& rPoly = aPolyPolygon[ 0 ];
+ rGeoRect = ::com::sun::star::awt::Rectangle(
+ rPoly[ 0 ].X(),
+ rPoly[ 0 ].Y(),
+ rPoly[ 1 ].X() - rPoly[ 0 ].X(),
+ rPoly[ 1 ].Y() - rPoly[ 0 ].Y() );
+ }
+ else
+ bRetValue = sal_False;
+ }
+ else
+ {
+ Polygon aPolygon;
+
+ sal_uInt16 i, j, k, nPoints, nBezPoints, nPolyCount = aPolyPolygon.Count();
+ Rectangle aRect( aPolyPolygon.GetBoundRect() );
+ rGeoRect = ::com::sun::star::awt::Rectangle( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight() );
+
+ for ( nBezPoints = nPoints = i = 0; i < nPolyCount; i++ )
+ {
+ k = aPolyPolygon[ i ].GetSize();
+ nPoints = nPoints + k;
+ for ( j = 0; j < k; j++ )
+ {
+ if ( aPolyPolygon[ i ].GetFlags( j ) != POLY_CONTROL )
+ nBezPoints++;
+ }
+ }
+ sal_uInt32 nVerticesBufSize = ( nPoints << 2 ) + 6;
+ sal_uInt8* pVerticesBuf = new sal_uInt8[ nVerticesBufSize ];
+
+
+ sal_uInt32 nSegmentBufSize = ( ( nBezPoints << 2 ) + 8 );
+ if ( nPolyCount > 1 )
+ nSegmentBufSize += ( nPolyCount << 1 );
+ sal_uInt8* pSegmentBuf = new sal_uInt8[ nSegmentBufSize ];
+
+ sal_uInt8* pPtr = pVerticesBuf;
+ *pPtr++ = (sal_uInt8)( nPoints ); // Little endian
+ *pPtr++ = (sal_uInt8)( nPoints >> 8 );
+ *pPtr++ = (sal_uInt8)( nPoints );
+ *pPtr++ = (sal_uInt8)( nPoints >> 8 );
+ *pPtr++ = (sal_uInt8)0xf0;
+ *pPtr++ = (sal_uInt8)0xff;
+
+ for ( j = 0; j < nPolyCount; j++ )
+ {
+ aPolygon = aPolyPolygon[ j ];
+ nPoints = aPolygon.GetSize();
+ for ( i = 0; i < nPoints; i++ ) // Punkte aus Polygon in Buffer schreiben
+ {
+ Point aPoint = aPolygon[ i ];
+ aPoint.X() -= rGeoRect.X;
+ aPoint.Y() -= rGeoRect.Y;
+
+ *pPtr++ = (sal_uInt8)( aPoint.X() );
+ *pPtr++ = (sal_uInt8)( aPoint.X() >> 8 );
+ *pPtr++ = (sal_uInt8)( aPoint.Y() );
+ *pPtr++ = (sal_uInt8)( aPoint.Y() >> 8 );
+ }
+ }
+
+ pPtr = pSegmentBuf;
+ *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 1 );
+ *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 9 );
+ *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 1 );
+ *pPtr++ = (sal_uInt8)( ( nSegmentBufSize - 6 ) >> 9 );
+ *pPtr++ = (sal_uInt8)2;
+ *pPtr++ = (sal_uInt8)0;
+
+ for ( j = 0; j < nPolyCount; j++ )
+ {
+ *pPtr++ = 0x0; // Polygon start
+ *pPtr++ = 0x40;
+ aPolygon = aPolyPolygon[ j ];
+ nPoints = aPolygon.GetSize();
+ for ( i = 0; i < nPoints; i++ ) // Polyflags in Buffer schreiben
+ {
+ *pPtr++ = 0;
+ if ( bBezier )
+ *pPtr++ = 0xb3;
+ else
+ *pPtr++ = 0xac;
+ if ( ( i + 1 ) != nPoints )
+ {
+ *pPtr++ = 1;
+ if ( aPolygon.GetFlags( i + 1 ) == POLY_CONTROL )
+ {
+ *pPtr++ = 0x20;
+ i += 2;
+ }
+ else
+ *pPtr++ = 0;
+ }
+ }
+ if ( nPolyCount > 1 )
+ {
+ *pPtr++ = 1; // end of polygon
+ *pPtr++ = 0x60;
+ }
+ }
+ *pPtr++ = 0;
+ *pPtr++ = 0x80;
+
+ AddOpt( ESCHER_Prop_geoRight, rGeoRect.Width );
+ AddOpt( ESCHER_Prop_geoBottom, rGeoRect.Height );
+
+ AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
+ AddOpt( ESCHER_Prop_pVertices, TRUE, nVerticesBufSize - 6, (sal_uInt8*)pVerticesBuf, nVerticesBufSize );
+ AddOpt( ESCHER_Prop_pSegmentInfo, TRUE, nSegmentBufSize, (sal_uInt8*)pSegmentBuf, nSegmentBufSize );
+ }
+ }
+ return bRetValue;
+}
+
+sal_Bool EscherPropertyContainer::CreateConnectorProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape,
+ EscherSolverContainer& rSolverContainer, ::com::sun::star::awt::Rectangle& rGeoRect,
+ sal_uInt16& rShapeType, sal_uInt16& rShapeFlags )
+{
+ static String sEdgeKind ( RTL_CONSTASCII_USTRINGPARAM( "EdgeKind" ) );
+ static String sEdgeStartPoint ( RTL_CONSTASCII_USTRINGPARAM( "EdgeStartPoint" ) );
+ static String sEdgeEndPoint ( RTL_CONSTASCII_USTRINGPARAM( "EdgeEndPoint" ) );
+ static String sEdgeStartConnection ( RTL_CONSTASCII_USTRINGPARAM( "EdgeStartConnection" ) );
+ static String sEdgeEndConnection ( RTL_CONSTASCII_USTRINGPARAM( "EdgeEndConnection" ) );
+
+ sal_Bool bRetValue = sal_False;
+ rShapeType = rShapeFlags = 0;
+
+ if ( rXShape.is() )
+ {
+ ::com::sun::star::awt::Point aStartPoint, aEndPoint;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > aXPropSet;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > aShapeA, aShapeB;
+ ::com::sun::star::uno::Any aAny( rXShape->queryInterface( ::getCppuType( (const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >*) 0 ) ));
+ if ( aAny >>= aXPropSet )
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeKind, sal_True ) )
+ {
+ ::com::sun::star::drawing::ConnectorType eCt;
+ aAny >>= eCt;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeStartPoint ) )
+ {
+ aStartPoint = *(::com::sun::star::awt::Point*)aAny.getValue();
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeEndPoint ) )
+ {
+ aEndPoint = *(::com::sun::star::awt::Point*)aAny.getValue();
+
+ rShapeFlags = SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT | SHAPEFLAG_CONNECTOR;
+ rGeoRect = ::com::sun::star::awt::Rectangle( aStartPoint.X, aStartPoint.Y,
+ ( aEndPoint.X - aStartPoint.X ) + 1, ( aEndPoint.Y - aStartPoint.Y ) + 1 );
+ if ( rGeoRect.Height < 0 ) // justify
+ {
+ rShapeFlags |= SHAPEFLAG_FLIPV;
+ rGeoRect.Y = aEndPoint.Y;
+ rGeoRect.Height = -rGeoRect.Height;
+ }
+ if ( rGeoRect.Width < 0 )
+ {
+ rShapeFlags |= SHAPEFLAG_FLIPH;
+ rGeoRect.X = aEndPoint.X;
+ rGeoRect.Width = -rGeoRect.Width;
+ }
+ sal_uInt32 nAdjustValue1, nAdjustValue2, nAdjustValue3;
+ nAdjustValue1 = nAdjustValue2 = nAdjustValue3 = 0x2a30;
+
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeStartConnection ) )
+ aAny >>= aShapeA;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sEdgeEndConnection ) )
+ aAny >>= aShapeB;
+/*
+ if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine1Delta" ) ) ) )
+ {
+ }
+ if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine2Delta" ) ) ) )
+ {
+ }
+ if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeLine3Delta" ) ) ) )
+ {
+ }
+ if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode1HorzDist" ) ) ) )
+ {
+ }
+ if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode1VertDist" ) ) ) )
+ {
+ }
+ if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode2HorzDist" ) ) ) )
+ {
+ }
+ if ( ImplGetPropertyValue( String( RTL_CONSTASCII_USTRINGPARAM( "EdgeNode2VertDist" ) ) ) )
+ {
+ }
+*/
+ rSolverContainer.AddConnector( rXShape, aStartPoint, aShapeA, aEndPoint, aShapeB );
+ switch ( eCt )
+ {
+ case ::com::sun::star::drawing::ConnectorType_CURVE :
+ {
+ rShapeType = ESCHER_ShpInst_CurvedConnector3;
+ AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleCurved );
+ AddOpt( ESCHER_Prop_adjustValue, nAdjustValue1 );
+ AddOpt( ESCHER_Prop_adjust2Value, -(sal_Int32)nAdjustValue2 );
+ }
+ break;
+
+ case ::com::sun::star::drawing::ConnectorType_STANDARD :// Connector 2->5
+ {
+ rShapeType = ESCHER_ShpInst_BentConnector3;
+ AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleBent );
+ }
+ break;
+
+ default:
+ case ::com::sun::star::drawing::ConnectorType_LINE :
+ case ::com::sun::star::drawing::ConnectorType_LINES : // Connector 2->5
+ {
+ rShapeType = ESCHER_ShpInst_StraightConnector1;
+ AddOpt( ESCHER_Prop_cxstyle, ESCHER_cxstyleStraight );
+ }
+ break;
+ }
+ CreateLineProperties( aXPropSet, sal_False );
+ bRetValue = bSuppressRotation = sal_True;
+ }
+ }
+ }
+ }
+ }
+ return bRetValue;
+}
+
+sal_Bool EscherPropertyContainer::CreateShadowProperties(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet )
+{
+ ::com::sun::star::uno::Any aAny;
+
+ sal_Bool bHasShadow = sal_False; // shadow is possible only if at least a fillcolor, linecolor or graphic is set
+ sal_uInt32 nLineFlags = 0; // default : shape has no line
+ sal_uInt32 nFillFlags = 0x10; // shape is filled
+
+ GetOpt( ESCHER_Prop_fNoLineDrawDash, nLineFlags );
+ GetOpt( ESCHER_Prop_fNoFillHitTest, nFillFlags );
+
+ sal_uInt32 nDummy;
+ sal_Bool bGraphic = GetOpt( DFF_Prop_pib, nDummy ) || GetOpt( DFF_Prop_pibName, nDummy ) || GetOpt( DFF_Prop_pibFlags, nDummy );
+
+ sal_uInt32 nShadowFlags = 0x20000;
+ if ( ( nLineFlags & 8 ) || ( nFillFlags & 0x10 ) || bGraphic )
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "Shadow" ) ), sal_True ) )
+ {
+ if ( aAny >>= bHasShadow )
+ {
+ if ( bHasShadow )
+ {
+ nShadowFlags |= 2;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "ShadowColor" ) ), sal_False ) )
+ AddOpt( ESCHER_Prop_shadowColor, ImplGetColor( *((sal_uInt32*)aAny.getValue()) ) );
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "ShadowXDistance" ) ), sal_False ) )
+ AddOpt( ESCHER_Prop_shadowOffsetX, *((sal_Int32*)aAny.getValue()) * 360 );
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "ShadowYDistance" ) ), sal_False ) )
+ AddOpt( ESCHER_Prop_shadowOffsetY, *((sal_Int32*)aAny.getValue()) * 360 );
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "ShadowTransparence" ) ), sal_False ) )
+ AddOpt( ESCHER_Prop_shadowOpacity, 0x10000 - (((sal_uInt32)*((sal_uInt16*)aAny.getValue())) * 655 ) );
+ }
+ }
+ }
+ }
+ AddOpt( ESCHER_Prop_fshadowObscured, nShadowFlags );
+ return bHasShadow;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+sal_Int32 GetValueForEnhancedCustomShapeParameter( const com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter, const std::vector< sal_Int32 >& rEquationOrder )
+{
+ sal_Int32 nValue = 0;
+ if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
+ {
+ double fValue;
+ if ( rParameter.Value >>= fValue )
+ nValue = (sal_Int32)fValue;
+ }
+ else
+ rParameter.Value >>= nValue;
+
+ switch( rParameter.Type )
+ {
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION :
+ {
+ nValue = (sal_uInt16)rEquationOrder[ nValue ];
+ nValue |= (sal_uInt32)0x80000000;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL :
+ {
+
+ }
+ break;
+/* not sure if it is allowed to set following values
+(but they are not yet used)
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM :
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT :
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP :
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT :
+*/
+ }
+ return nValue;
+}
+
+sal_Bool GetValueForEnhancedCustomShapeHandleParameter( sal_Int32& nRetValue, const com::sun::star::drawing::EnhancedCustomShapeParameter& rParameter )
+{
+ sal_Bool bSpecial = sal_False;
+ nRetValue = 0;
+ if ( rParameter.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
+ {
+ double fValue;
+ if ( rParameter.Value >>= fValue )
+ nRetValue = (sal_Int32)fValue;
+ }
+ else
+ rParameter.Value >>= nRetValue;
+
+ switch( rParameter.Type )
+ {
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION :
+ {
+ nRetValue += 3;
+ bSpecial = sal_True;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::ADJUSTMENT :
+ {
+ nRetValue += 0x100;
+ bSpecial = sal_True;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::TOP :
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::LEFT :
+ {
+ nRetValue = 0;
+ bSpecial = sal_True;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::RIGHT :
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::BOTTOM :
+ {
+ nRetValue = 1;
+ bSpecial = sal_True;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeParameterType::NORMAL :
+ {
+
+ }
+ break;
+ }
+ return bSpecial;
+}
+
+void ConvertEnhancedCustomShapeEquation( SdrObjCustomShape* pCustoShape,
+ std::vector< EnhancedCustomShapeEquation >& rEquations, std::vector< sal_Int32 >& rEquationOrder )
+{
+ if ( pCustoShape )
+ {
+ uno::Sequence< rtl::OUString > sEquationSource;
+ const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
+ SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&)
+ pCustoShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+ const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sEquations );
+ if ( pAny )
+ *pAny >>= sEquationSource;
+ sal_Int32 nEquationSourceCount = sEquationSource.getLength();
+ if ( nEquationSourceCount )
+ {
+ sal_Int32 i;
+ for ( i = 0; i < nEquationSourceCount; i++ )
+ {
+ EnhancedCustomShape2d aCustoShape2d( pCustoShape );
+ try
+ {
+ ::boost::shared_ptr< EnhancedCustomShape::ExpressionNode > aExpressNode(
+ EnhancedCustomShape::FunctionParser::parseFunction( sEquationSource[ i ], aCustoShape2d ) );
+ com::sun::star::drawing::EnhancedCustomShapeParameter aPara( aExpressNode->fillNode( rEquations, NULL, 0 ) );
+ if ( aPara.Type != com::sun::star::drawing::EnhancedCustomShapeParameterType::EQUATION )
+ {
+ EnhancedCustomShapeEquation aEquation;
+ aEquation.nOperation = 0;
+ EnhancedCustomShape::FillEquationParameter( aPara, 0, aEquation );
+ rEquations.push_back( aEquation );
+ }
+ }
+ catch ( EnhancedCustomShape::ParseError& )
+ {
+ EnhancedCustomShapeEquation aEquation; // ups, we should not be here,
+ aEquation.nOperation = 0; // creating a default equation with value 1
+ aEquation.nPara[ 0 ] = 1; // hoping that this will not break anything
+ rEquations.push_back( aEquation );
+ }
+ rEquationOrder.push_back( rEquations.size() - 1 );
+ }
+ // now updating our old equation indices, they are marked with a bit in the hiword of nOperation
+ std::vector< EnhancedCustomShapeEquation >::iterator aIter( rEquations.begin() );
+ std::vector< EnhancedCustomShapeEquation >::iterator aEnd ( rEquations.end() );
+ while( aIter != aEnd )
+ {
+ sal_Int32 nMask = 0x20000000;
+ for( i = 0; i < 3; i++ )
+ {
+ if ( aIter->nOperation & nMask )
+ {
+ aIter->nOperation ^= nMask;
+ aIter->nPara[ i ] = rEquationOrder[ aIter->nPara[ i ] & 0x3ff ] | 0x400;
+ }
+ nMask <<= 1;
+ }
+ aIter++;
+ }
+ }
+ }
+}
+
+sal_Bool EscherPropertyContainer::IsDefaultObject( SdrObjCustomShape* pCustoShape )
+{
+ sal_Bool bIsDefaultObject = sal_False;
+ if ( pCustoShape )
+ {
+ if ( pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_EQUATIONS )
+ && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_VIEWBOX )
+ && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_PATH )
+ && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_GLUEPOINTS )
+ && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_SEGMENTS )
+ && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_STRETCHX )
+ && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_STRETCHY )
+// && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_HANDLES )
+ && pCustoShape->IsDefaultGeometry( SdrObjCustomShape::DEFAULT_TEXTFRAMES ) )
+ bIsDefaultObject = sal_True;
+ }
+
+ return bIsDefaultObject;
+}
+
+void EscherPropertyContainer::LookForPolarHandles( const MSO_SPT eShapeType, sal_Int32& nAdjustmentsWhichNeedsToBeConverted )
+{
+ const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eShapeType );
+ if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
+ {
+ sal_Int32 k, nkCount = pDefCustomShape->nHandles;
+ const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
+ for ( k = 0; k < nkCount; k++, pData++ )
+ {
+ if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR )
+ {
+ if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) )
+ nAdjustmentsWhichNeedsToBeConverted |= ( 1 << k );
+ }
+ }
+ }
+}
+
+sal_Bool EscherPropertyContainer::GetAdjustmentValue( const com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue & rkProp, sal_Int32 nIndex, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, sal_Int32& nValue )
+{
+ if ( rkProp.State != beans::PropertyState_DIRECT_VALUE )
+ return FALSE;
+
+ sal_Bool bUseFixedFloat = ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << nIndex ) ) != 0;
+ if ( rkProp.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
+ {
+ double fValue;
+ rkProp.Value >>= fValue;
+ if ( bUseFixedFloat )
+ fValue *= 65536.0;
+ nValue = (sal_Int32)fValue;
+ }
+ else
+ {
+ rkProp.Value >>= nValue;
+ if ( bUseFixedFloat )
+ nValue <<= 16;
+ }
+
+ return TRUE;
+}
+
+void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeType, const uno::Reference< drawing::XShape > & rXShape )
+{
+ uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY );
+ if ( aXPropSet.is() )
+ {
+ SdrObjCustomShape* pCustoShape = (SdrObjCustomShape*)GetSdrObjectFromXShape( rXShape );
+ const rtl::OUString sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM( "CustomShapeGeometry" ) );
+ uno::Any aGeoPropSet = aXPropSet->getPropertyValue( sCustomShapeGeometry );
+ uno::Sequence< beans::PropertyValue > aGeoPropSeq;
+ if ( aGeoPropSet >>= aGeoPropSeq )
+ {
+ const rtl::OUString sViewBox ( RTL_CONSTASCII_USTRINGPARAM( "ViewBox" ) );
+ const rtl::OUString sTextRotateAngle ( RTL_CONSTASCII_USTRINGPARAM( "TextRotateAngle" ) );
+ const rtl::OUString sExtrusion ( RTL_CONSTASCII_USTRINGPARAM( "Extrusion" ) );
+ const rtl::OUString sEquations ( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
+ const rtl::OUString sPath ( RTL_CONSTASCII_USTRINGPARAM( "Path" ) );
+ const rtl::OUString sTextPath ( RTL_CONSTASCII_USTRINGPARAM( "TextPath" ) );
+ const rtl::OUString sHandles ( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
+ const rtl::OUString sAdjustmentValues ( RTL_CONSTASCII_USTRINGPARAM( "AdjustmentValues" ) );
+
+ const beans::PropertyValue* pAdjustmentValuesProp = NULL;
+ sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
+ uno::Sequence< beans::PropertyValues > aHandlesPropSeq;
+ sal_Bool bPredefinedHandlesUsed = sal_True;
+ sal_Bool bIsDefaultObject = IsDefaultObject( pCustoShape );
+
+ // convert property "Equations" into std::vector< EnhancedCustomShapeEquationEquation >
+ std::vector< EnhancedCustomShapeEquation > aEquations;
+ std::vector< sal_Int32 > aEquationOrder;
+ ConvertEnhancedCustomShapeEquation( pCustoShape, aEquations, aEquationOrder );
+
+ sal_Int32 i, nCount = aGeoPropSeq.getLength();
+ for ( i = 0; i < nCount; i++ )
+ {
+ const beans::PropertyValue& rProp = aGeoPropSeq[ i ];
+ if ( rProp.Name.equals( sViewBox ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ awt::Rectangle aViewBox;
+ if ( rProp.Value >>= aViewBox )
+ {
+ AddOpt( DFF_Prop_geoLeft, aViewBox.X );
+ AddOpt( DFF_Prop_geoTop, aViewBox.Y );
+ AddOpt( DFF_Prop_geoRight, aViewBox.X + aViewBox.Width );
+ AddOpt( DFF_Prop_geoBottom,aViewBox.Y + aViewBox.Height );
+ }
+ }
+ }
+ else if ( rProp.Name.equals( sTextRotateAngle ) )
+ {
+ double f = 0, fTextRotateAngle;
+ if ( rProp.Value >>= f )
+ {
+ fTextRotateAngle = fmod( f, 360.0 );
+ if ( fTextRotateAngle < 0 )
+ fTextRotateAngle = 360 + fTextRotateAngle;
+ if ( ( fTextRotateAngle < 271.0 ) && ( fTextRotateAngle > 269.0 ) )
+ AddOpt( DFF_Prop_cdirFont, mso_cdir90 );
+ else if ( ( fTextRotateAngle < 181.0 ) && ( fTextRotateAngle > 179.0 ) )
+ AddOpt( DFF_Prop_cdirFont, mso_cdir180 );
+ else if ( ( fTextRotateAngle < 91.0 ) && ( fTextRotateAngle > 79.0 ) )
+ AddOpt( DFF_Prop_cdirFont, mso_cdir270 );
+ }
+ }
+ else if ( rProp.Name.equals( sExtrusion ) )
+ {
+ uno::Sequence< beans::PropertyValue > aExtrusionPropSeq;
+ if ( rProp.Value >>= aExtrusionPropSeq )
+ {
+ sal_uInt32 nLightFaceFlagsOrg, nLightFaceFlags;
+ sal_uInt32 nFillHarshFlagsOrg, nFillHarshFlags;
+ nLightFaceFlagsOrg = nLightFaceFlags = 0x000001;
+ nFillHarshFlagsOrg = nFillHarshFlags = 0x00001e;
+ if ( GetOpt( DFF_Prop_fc3DLightFace, nLightFaceFlags ) )
+ nLightFaceFlagsOrg = nLightFaceFlags;
+ if ( GetOpt( DFF_Prop_fc3DFillHarsh, nFillHarshFlags ) )
+ nFillHarshFlagsOrg = nFillHarshFlags;
+
+ sal_Int32 r, nrCount = aExtrusionPropSeq.getLength();
+ for ( r = 0; r < nrCount; r++ )
+ {
+ const beans::PropertyValue& rrProp = aExtrusionPropSeq[ r ];
+ const rtl::OUString sExtrusionBrightness ( RTL_CONSTASCII_USTRINGPARAM( "Brightness" ) );
+ const rtl::OUString sExtrusionDepth ( RTL_CONSTASCII_USTRINGPARAM( "Depth" ) );
+ const rtl::OUString sExtrusionDiffusion ( RTL_CONSTASCII_USTRINGPARAM( "Diffusion" ) );
+ const rtl::OUString sExtrusionNumberOfLineSegments ( RTL_CONSTASCII_USTRINGPARAM( "NumberOfLineSegments" ) );
+ const rtl::OUString sExtrusionLightFace ( RTL_CONSTASCII_USTRINGPARAM( "LightFace" ) );
+ const rtl::OUString sExtrusionFirstLightHarsh ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightHarsh" ) );
+ const rtl::OUString sExtrusionSecondLightHarsh ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightHarsh" ) );
+ const rtl::OUString sExtrusionFirstLightLevel ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightLevel" ) );
+ const rtl::OUString sExtrusionSecondLightLevel ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightLevel" ) );
+ const rtl::OUString sExtrusionFirstLightDirection ( RTL_CONSTASCII_USTRINGPARAM( "FirstLightDirection" ) );
+ const rtl::OUString sExtrusionSecondLightDirection ( RTL_CONSTASCII_USTRINGPARAM( "SecondLightDirection" ) );
+ const rtl::OUString sExtrusionMetal ( RTL_CONSTASCII_USTRINGPARAM( "Metal" ) );
+ const rtl::OUString sExtrusionShadeMode ( RTL_CONSTASCII_USTRINGPARAM( "ShadeMode" ) );
+ const rtl::OUString sExtrusionRotateAngle ( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) );
+ const rtl::OUString sExtrusionRotationCenter ( RTL_CONSTASCII_USTRINGPARAM( "RotationCenter" ) );
+ const rtl::OUString sExtrusionShininess ( RTL_CONSTASCII_USTRINGPARAM( "Shininess" ) );
+ const rtl::OUString sExtrusionSkew ( RTL_CONSTASCII_USTRINGPARAM( "Skew" ) );
+ const rtl::OUString sExtrusionSpecularity ( RTL_CONSTASCII_USTRINGPARAM( "Specularity" ) );
+ const rtl::OUString sExtrusionProjectionMode ( RTL_CONSTASCII_USTRINGPARAM( "ProjectionMode" ) );
+ const rtl::OUString sExtrusionViewPoint ( RTL_CONSTASCII_USTRINGPARAM( "ViewPoint" ) );
+ const rtl::OUString sExtrusionOrigin ( RTL_CONSTASCII_USTRINGPARAM( "Origin" ) );
+ const rtl::OUString sExtrusionColor ( RTL_CONSTASCII_USTRINGPARAM( "Color" ) );
+
+ if ( rrProp.Name.equals( sExtrusion ) )
+ {
+ sal_Bool bExtrusionOn = sal_Bool();
+ if ( rrProp.Value >>= bExtrusionOn )
+ {
+ nLightFaceFlags |= 0x80000;
+ if ( bExtrusionOn )
+ nLightFaceFlags |= 8;
+ else
+ nLightFaceFlags &=~8;
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionBrightness ) )
+ {
+ double fExtrusionBrightness = 0;
+ if ( rrProp.Value >>= fExtrusionBrightness )
+ AddOpt( DFF_Prop_c3DAmbientIntensity, (sal_Int32)( fExtrusionBrightness * 655.36 ) );
+ }
+ else if ( rrProp.Name.equals( sExtrusionDepth ) )
+ {
+ double fDepth = 0;
+ double fFraction = 0;
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair aDepthParaPair;
+ if ( ( rrProp.Value >>= aDepthParaPair ) && ( aDepthParaPair.First.Value >>= fDepth ) && ( aDepthParaPair.Second.Value >>= fFraction ) )
+ {
+ double fForeDepth = fDepth * fFraction;
+ double fBackDepth = fDepth - fForeDepth;
+
+ fBackDepth *= 360.0;
+ AddOpt( DFF_Prop_c3DExtrudeBackward, (sal_Int32)fBackDepth );
+
+ if ( fForeDepth != 0.0 )
+ {
+ fForeDepth *= 360.0;
+ AddOpt( DFF_Prop_c3DExtrudeForward, (sal_Int32)fForeDepth );
+ }
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionDiffusion ) )
+ {
+ double fExtrusionDiffusion = 0;
+ if ( rrProp.Value >>= fExtrusionDiffusion )
+ AddOpt( DFF_Prop_c3DDiffuseAmt, (sal_Int32)( fExtrusionDiffusion * 655.36 ) );
+ }
+ else if ( rrProp.Name.equals( sExtrusionNumberOfLineSegments ) )
+ {
+ sal_Int32 nExtrusionNumberOfLineSegments = 0;
+ if ( rrProp.Value >>= nExtrusionNumberOfLineSegments )
+ AddOpt( DFF_Prop_c3DTolerance, nExtrusionNumberOfLineSegments );
+ }
+ else if ( rrProp.Name.equals( sExtrusionLightFace ) )
+ {
+ sal_Bool bExtrusionLightFace = sal_Bool();
+ if ( rrProp.Value >>= bExtrusionLightFace )
+ {
+ nLightFaceFlags |= 0x10000;
+ if ( bExtrusionLightFace )
+ nLightFaceFlags |= 1;
+ else
+ nLightFaceFlags &=~1;
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionFirstLightHarsh ) )
+ {
+ sal_Bool bExtrusionFirstLightHarsh = sal_Bool();
+ if ( rrProp.Value >>= bExtrusionFirstLightHarsh )
+ {
+ nFillHarshFlags |= 0x20000;
+ if ( bExtrusionFirstLightHarsh )
+ nFillHarshFlags |= 2;
+ else
+ nFillHarshFlags &=~2;
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionSecondLightHarsh ) )
+ {
+ sal_Bool bExtrusionSecondLightHarsh = sal_Bool();
+ if ( rrProp.Value >>= bExtrusionSecondLightHarsh )
+ {
+ nFillHarshFlags |= 0x10000;
+ if ( bExtrusionSecondLightHarsh )
+ nFillHarshFlags |= 1;
+ else
+ nFillHarshFlags &=~1;
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionFirstLightLevel ) )
+ {
+ double fExtrusionFirstLightLevel = 0;
+ if ( rrProp.Value >>= fExtrusionFirstLightLevel )
+ AddOpt( DFF_Prop_c3DKeyIntensity, (sal_Int32)( fExtrusionFirstLightLevel * 655.36 ) );
+ }
+ else if ( rrProp.Name.equals( sExtrusionSecondLightLevel ) )
+ {
+ double fExtrusionSecondLightLevel = 0;
+ if ( rrProp.Value >>= fExtrusionSecondLightLevel )
+ AddOpt( DFF_Prop_c3DFillIntensity, (sal_Int32)( fExtrusionSecondLightLevel * 655.36 ) );
+ }
+ else if ( rrProp.Name.equals( sExtrusionFirstLightDirection ) )
+ {
+ drawing::Direction3D aExtrusionFirstLightDirection;
+ if ( rrProp.Value >>= aExtrusionFirstLightDirection )
+ {
+ AddOpt( DFF_Prop_c3DKeyX, (sal_Int32)aExtrusionFirstLightDirection.DirectionX );
+ AddOpt( DFF_Prop_c3DKeyY, (sal_Int32)aExtrusionFirstLightDirection.DirectionY );
+ AddOpt( DFF_Prop_c3DKeyZ, (sal_Int32)aExtrusionFirstLightDirection.DirectionZ );
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionSecondLightDirection ) )
+ {
+ drawing::Direction3D aExtrusionSecondLightPosition;
+ if ( rrProp.Value >>= aExtrusionSecondLightPosition )
+ {
+ AddOpt( DFF_Prop_c3DFillX, (sal_Int32)aExtrusionSecondLightPosition.DirectionX );
+ AddOpt( DFF_Prop_c3DFillY, (sal_Int32)aExtrusionSecondLightPosition.DirectionY );
+ AddOpt( DFF_Prop_c3DFillZ, (sal_Int32)aExtrusionSecondLightPosition.DirectionZ );
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionMetal ) )
+ {
+ sal_Bool bExtrusionMetal = sal_Bool();
+ if ( rrProp.Value >>= bExtrusionMetal )
+ {
+ nLightFaceFlags |= 0x40000;
+ if ( bExtrusionMetal )
+ nLightFaceFlags |= 4;
+ else
+ nLightFaceFlags &=~4;
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionShadeMode ) )
+ {
+ drawing::ShadeMode eExtrusionShadeMode;
+ if ( rrProp.Value >>= eExtrusionShadeMode )
+ {
+ sal_uInt32 nRenderMode;
+ switch( eExtrusionShadeMode )
+ {
+ default:
+ case drawing::ShadeMode_FLAT :
+ case drawing::ShadeMode_PHONG :
+ case drawing::ShadeMode_SMOOTH :
+ nRenderMode = mso_FullRender;
+ break;
+ case drawing::ShadeMode_DRAFT :
+ {
+ nRenderMode = mso_Wireframe;
+ }
+ break;
+ }
+ AddOpt( DFF_Prop_c3DRenderMode, nRenderMode );
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionRotateAngle ) )
+ {
+ double fExtrusionAngleX = 0;
+ double fExtrusionAngleY = 0;
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair aRotateAnglePair;
+ if ( ( rrProp.Value >>= aRotateAnglePair ) && ( aRotateAnglePair.First.Value >>= fExtrusionAngleX ) && ( aRotateAnglePair.Second.Value >>= fExtrusionAngleY ) )
+ {
+ fExtrusionAngleX *= 65536;
+ fExtrusionAngleY *= 65536;
+ AddOpt( DFF_Prop_c3DXRotationAngle, (sal_Int32)fExtrusionAngleX );
+ AddOpt( DFF_Prop_c3DYRotationAngle, (sal_Int32)fExtrusionAngleY );
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionRotationCenter ) )
+ {
+ drawing::Direction3D aExtrusionRotationCenter;
+ if ( rrProp.Value >>= aExtrusionRotationCenter )
+ {
+ AddOpt( DFF_Prop_c3DRotationCenterX, (sal_Int32)( aExtrusionRotationCenter.DirectionX * 360.0 ) );
+ AddOpt( DFF_Prop_c3DRotationCenterY, (sal_Int32)( aExtrusionRotationCenter.DirectionY * 360.0 ) );
+ AddOpt( DFF_Prop_c3DRotationCenterZ, (sal_Int32)( aExtrusionRotationCenter.DirectionZ * 360.0 ) );
+ nFillHarshFlags &=~8; // don't use AutoRotationCenter;
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionShininess ) )
+ {
+ double fExtrusionShininess = 0;
+ if ( rrProp.Value >>= fExtrusionShininess )
+ AddOpt( DFF_Prop_c3DShininess, (sal_Int32)( fExtrusionShininess * 655.36 ) );
+ }
+ else if ( rrProp.Name.equals( sExtrusionSkew ) )
+ {
+ double fSkewAmount = 0;
+ double fSkewAngle = 0;
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair aSkewParaPair;
+ if ( ( rrProp.Value >>= aSkewParaPair ) && ( aSkewParaPair.First.Value >>= fSkewAmount ) && ( aSkewParaPair.Second.Value >>= fSkewAngle ) )
+ {
+ AddOpt( DFF_Prop_c3DSkewAmount, (sal_Int32)fSkewAmount );
+ AddOpt( DFF_Prop_c3DSkewAngle, (sal_Int32)( fSkewAngle * 65536 ) );
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionSpecularity ) )
+ {
+ double fExtrusionSpecularity = 0;
+ if ( rrProp.Value >>= fExtrusionSpecularity )
+ AddOpt( DFF_Prop_c3DSpecularAmt, (sal_Int32)( fExtrusionSpecularity * 1333 ) );
+ }
+ else if ( rrProp.Name.equals( sExtrusionProjectionMode ) )
+ {
+ drawing::ProjectionMode eExtrusionProjectionMode;
+ if ( rrProp.Value >>= eExtrusionProjectionMode )
+ {
+ nFillHarshFlags |= 0x40000;
+ if ( eExtrusionProjectionMode == drawing::ProjectionMode_PARALLEL )
+ nFillHarshFlags |= 4;
+ else
+ nFillHarshFlags &=~4;
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionViewPoint ) )
+ {
+ drawing::Position3D aExtrusionViewPoint;
+ if ( rrProp.Value >>= aExtrusionViewPoint )
+ {
+ aExtrusionViewPoint.PositionX *= 360.0;
+ aExtrusionViewPoint.PositionY *= 360.0;
+ aExtrusionViewPoint.PositionZ *= 360.0;
+ AddOpt( DFF_Prop_c3DXViewpoint, (sal_Int32)aExtrusionViewPoint.PositionX );
+ AddOpt( DFF_Prop_c3DYViewpoint, (sal_Int32)aExtrusionViewPoint.PositionY );
+ AddOpt( DFF_Prop_c3DZViewpoint, (sal_Int32)aExtrusionViewPoint.PositionZ );
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionOrigin ) )
+ {
+ double fExtrusionOriginX = 0;
+ double fExtrusionOriginY = 0;
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair aOriginPair;
+ if ( ( rrProp.Value >>= aOriginPair ) && ( aOriginPair.First.Value >>= fExtrusionOriginX ) && ( aOriginPair.Second.Value >>= fExtrusionOriginY ) )
+ {
+ AddOpt( DFF_Prop_c3DOriginX, (sal_Int32)( fExtrusionOriginX * 65536 ) );
+ AddOpt( DFF_Prop_c3DOriginY, (sal_Int32)( fExtrusionOriginY * 65536 ) );
+ }
+ }
+ else if ( rrProp.Name.equals( sExtrusionColor ) )
+ {
+ sal_Bool bExtrusionColor = sal_Bool();
+ if ( rrProp.Value >>= bExtrusionColor )
+ {
+ nLightFaceFlags |= 0x20000;
+ if ( bExtrusionColor )
+ {
+ nLightFaceFlags |= 2;
+ uno::Any aFillColor2;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aFillColor2, aXPropSet,
+ String( RTL_CONSTASCII_USTRINGPARAM( "FillColor2" ) ), sal_True ) )
+ {
+ sal_uInt32 nFillColor = ImplGetColor( *((sal_uInt32*)aFillColor2.getValue()) );
+ AddOpt( DFF_Prop_c3DExtrusionColor, nFillColor );
+ }
+ }
+ else
+ nLightFaceFlags &=~2;
+ }
+ }
+ }
+ if ( nLightFaceFlags != nLightFaceFlagsOrg )
+ AddOpt( DFF_Prop_fc3DLightFace, nLightFaceFlags );
+ if ( nFillHarshFlags != nFillHarshFlagsOrg )
+ AddOpt( DFF_Prop_fc3DFillHarsh, nFillHarshFlags );
+ }
+ }
+ else if ( rProp.Name.equals( sEquations ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ sal_uInt16 nElements = (sal_uInt16)aEquations.size();
+ if ( nElements )
+ {
+ sal_uInt16 nElementSize = 8;
+ sal_uInt32 nStreamSize = nElementSize * nElements + 6;
+ SvMemoryStream aOut( nStreamSize );
+ aOut << nElements
+ << nElements
+ << nElementSize;
+
+ std::vector< EnhancedCustomShapeEquation >::const_iterator aIter( aEquations.begin() );
+ std::vector< EnhancedCustomShapeEquation >::const_iterator aEnd ( aEquations.end() );
+ while( aIter != aEnd )
+ {
+ aOut << (sal_uInt16)aIter->nOperation
+ << (sal_Int16)aIter->nPara[ 0 ]
+ << (sal_Int16)aIter->nPara[ 1 ]
+ << (sal_Int16)aIter->nPara[ 2 ];
+ aIter++;
+ }
+ sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
+ memcpy( pBuf, aOut.GetData(), nStreamSize );
+ AddOpt( DFF_Prop_pFormulas, sal_True, nStreamSize - 6, pBuf, nStreamSize );
+ }
+ else
+ {
+ sal_uInt8* pBuf = new sal_uInt8[ 1 ];
+ AddOpt( DFF_Prop_pFormulas, sal_True, 0, pBuf, 0 );
+ }
+ }
+ }
+ else if ( rProp.Name.equals( sPath ) )
+ {
+ uno::Sequence< beans::PropertyValue > aPathPropSeq;
+ if ( rProp.Value >>= aPathPropSeq )
+ {
+ sal_uInt32 nPathFlags, nPathFlagsOrg;
+ nPathFlagsOrg = nPathFlags = 0x39;
+ if ( GetOpt( DFF_Prop_fFillOK, nPathFlags ) )
+ nPathFlagsOrg = nPathFlags;
+
+ sal_Int32 r, nrCount = aPathPropSeq.getLength();
+ for ( r = 0; r < nrCount; r++ )
+ {
+ const beans::PropertyValue& rrProp = aPathPropSeq[ r ];
+ const rtl::OUString sPathExtrusionAllowed ( RTL_CONSTASCII_USTRINGPARAM( "ExtrusionAllowed" ) );
+ const rtl::OUString sPathConcentricGradientFillAllowed ( RTL_CONSTASCII_USTRINGPARAM( "ConcentricGradientFillAllowed" ) );
+ const rtl::OUString sPathTextPathAllowed ( RTL_CONSTASCII_USTRINGPARAM( "TextPathAllowed" ) );
+ const rtl::OUString sPathCoordinates ( RTL_CONSTASCII_USTRINGPARAM( "Coordinates" ) );
+ const rtl::OUString sPathGluePoints ( RTL_CONSTASCII_USTRINGPARAM( "GluePoints" ) );
+ const rtl::OUString sPathGluePointType ( RTL_CONSTASCII_USTRINGPARAM( "GluePointType" ) );
+ const rtl::OUString sPathSegments ( RTL_CONSTASCII_USTRINGPARAM( "Segments" ) );
+ const rtl::OUString sPathStretchX ( RTL_CONSTASCII_USTRINGPARAM( "StretchX" ) );
+ const rtl::OUString sPathStretchY ( RTL_CONSTASCII_USTRINGPARAM( "StretchY" ) );
+ const rtl::OUString sPathTextFrames ( RTL_CONSTASCII_USTRINGPARAM( "TextFrames" ) );
+
+ if ( rrProp.Name.equals( sPathExtrusionAllowed ) )
+ {
+ sal_Bool bExtrusionAllowed = sal_Bool();
+ if ( rrProp.Value >>= bExtrusionAllowed )
+ {
+ nPathFlags |= 0x100000;
+ if ( bExtrusionAllowed )
+ nPathFlags |= 16;
+ else
+ nPathFlags &=~16;
+ }
+ }
+ else if ( rrProp.Name.equals( sPathConcentricGradientFillAllowed ) )
+ {
+ sal_Bool bConcentricGradientFillAllowed = sal_Bool();
+ if ( rrProp.Value >>= bConcentricGradientFillAllowed )
+ {
+ nPathFlags |= 0x20000;
+ if ( bConcentricGradientFillAllowed )
+ nPathFlags |= 2;
+ else
+ nPathFlags &=~2;
+ }
+ }
+ else if ( rrProp.Name.equals( sPathTextPathAllowed ) )
+ {
+ sal_Bool bTextPathAllowed = sal_Bool();
+ if ( rrProp.Value >>= bTextPathAllowed )
+ {
+ nPathFlags |= 0x40000;
+ if ( bTextPathAllowed )
+ nPathFlags |= 4;
+ else
+ nPathFlags &=~4;
+ }
+ }
+ else if ( rrProp.Name.equals( sPathCoordinates ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
+ if ( rrProp.Value >>= aCoordinates )
+ {
+ // creating the vertices
+ if ( (sal_uInt16)aCoordinates.getLength() )
+ {
+ sal_uInt16 j, nElements = (sal_uInt16)aCoordinates.getLength();
+ sal_uInt16 nElementSize = 8;
+ sal_uInt32 nStreamSize = nElementSize * nElements + 6;
+ SvMemoryStream aOut( nStreamSize );
+ aOut << nElements
+ << nElements
+ << nElementSize;
+ for( j = 0; j < nElements; j++ )
+ {
+ sal_Int32 X = GetValueForEnhancedCustomShapeParameter( aCoordinates[ j ].First, aEquationOrder );
+ sal_Int32 Y = GetValueForEnhancedCustomShapeParameter( aCoordinates[ j ].Second, aEquationOrder );
+ aOut << X
+ << Y;
+ }
+ sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
+ memcpy( pBuf, aOut.GetData(), nStreamSize );
+ AddOpt( DFF_Prop_pVertices, sal_True, nStreamSize - 6, pBuf, nStreamSize ); // -6
+ }
+ else
+ {
+ sal_uInt8* pBuf = new sal_uInt8[ 1 ];
+ AddOpt( DFF_Prop_pVertices, sal_True, 0, pBuf, 0 );
+ }
+ }
+ }
+ }
+ else if ( rrProp.Name.equals( sPathGluePoints ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> aGluePoints;
+ if ( rrProp.Value >>= aGluePoints )
+ {
+ // creating the vertices
+ sal_uInt16 nElements = (sal_uInt16)aGluePoints.getLength();
+ if ( nElements )
+ {
+ sal_uInt16 j, nElementSize = 8;
+ sal_uInt32 nStreamSize = nElementSize * nElements + 6;
+ SvMemoryStream aOut( nStreamSize );
+ aOut << nElements
+ << nElements
+ << nElementSize;
+ for( j = 0; j < nElements; j++ )
+ {
+ sal_Int32 X = GetValueForEnhancedCustomShapeParameter( aGluePoints[ j ].First, aEquationOrder );
+ sal_Int32 Y = GetValueForEnhancedCustomShapeParameter( aGluePoints[ j ].Second, aEquationOrder );
+ aOut << X
+ << Y;
+ }
+ sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
+ memcpy( pBuf, aOut.GetData(), nStreamSize );
+ AddOpt( DFF_Prop_connectorPoints, sal_True, nStreamSize - 6, pBuf, nStreamSize ); // -6
+ }
+ else
+ {
+ sal_uInt8* pBuf = new sal_uInt8[ 1 ];
+ AddOpt( DFF_Prop_connectorPoints, sal_True, 0, pBuf, 0 );
+ }
+ }
+ }
+ }
+ else if ( rrProp.Name.equals( sPathGluePointType ) )
+ {
+ sal_Int16 nGluePointType = sal_Int16();
+ if ( rrProp.Value >>= nGluePointType )
+ AddOpt( DFF_Prop_connectorType, (sal_uInt16)nGluePointType );
+ }
+ else if ( rrProp.Name.equals( sPathSegments ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
+ if ( rrProp.Value >>= aSegments )
+ {
+ // creating seginfo
+ if ( (sal_uInt16)aSegments.getLength() )
+ {
+ sal_uInt16 j, nElements = (sal_uInt16)aSegments.getLength();
+ sal_uInt16 nElementSize = 2;
+ sal_uInt32 nStreamSize = nElementSize * nElements + 6;
+ SvMemoryStream aOut( nStreamSize );
+ aOut << nElements
+ << nElements
+ << nElementSize;
+ for ( j = 0; j < nElements; j++ )
+ {
+ sal_uInt16 nVal = (sal_uInt16)aSegments[ j ].Count;
+ switch( aSegments[ j ].Command )
+ {
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::UNKNOWN :
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::LINETO : break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::MOVETO :
+ {
+ nVal = 0x4000;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
+ {
+ nVal |= 0x2000;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
+ {
+ nVal = 0x6001;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
+ {
+ nVal = 0x8000;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
+ {
+ nVal = 0xaa00;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
+ {
+ nVal = 0xab00;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
+ {
+ nVal *= 3;
+ nVal |= 0xa100;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
+ {
+ nVal *= 3;
+ nVal |= 0xa200;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
+ {
+ nVal <<= 2;
+ nVal |= 0xa300;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ARC :
+ {
+ nVal <<= 2;
+ nVal |= 0xa400;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
+ {
+ nVal <<= 2;
+ nVal |= 0xa500;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
+ {
+ nVal <<= 2;
+ nVal |= 0xa600;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
+ {
+ nVal |= 0xa700;
+ }
+ break;
+ case com::sun::star::drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
+ {
+ nVal |= 0xa800;
+ }
+ break;
+ }
+ aOut << nVal;
+ }
+ sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
+ memcpy( pBuf, aOut.GetData(), nStreamSize );
+ AddOpt( DFF_Prop_pSegmentInfo, sal_False, nStreamSize - 6, pBuf, nStreamSize );
+ }
+ else
+ {
+ sal_uInt8* pBuf = new sal_uInt8[ 1 ];
+ AddOpt( DFF_Prop_pSegmentInfo, sal_True, 0, pBuf, 0 );
+ }
+ }
+ }
+ }
+ else if ( rrProp.Name.equals( sPathStretchX ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ sal_Int32 nStretchX = 0;
+ if ( rrProp.Value >>= nStretchX )
+ AddOpt( DFF_Prop_stretchPointX, nStretchX );
+ }
+ }
+ else if ( rrProp.Name.equals( sPathStretchY ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ sal_Int32 nStretchY = 0;
+ if ( rrProp.Value >>= nStretchY )
+ AddOpt( DFF_Prop_stretchPointY, nStretchY );
+ }
+ }
+ else if ( rrProp.Name.equals( sPathTextFrames ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aPathTextFrames;
+ if ( rrProp.Value >>= aPathTextFrames )
+ {
+ if ( (sal_uInt16)aPathTextFrames.getLength() )
+ {
+ sal_uInt16 j, nElements = (sal_uInt16)aPathTextFrames.getLength();
+ sal_uInt16 nElementSize = 16;
+ sal_uInt32 nStreamSize = nElementSize * nElements + 6;
+ SvMemoryStream aOut( nStreamSize );
+ aOut << nElements
+ << nElements
+ << nElementSize;
+ for ( j = 0; j < nElements; j++ )
+ {
+ sal_Int32 nLeft = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].TopLeft.First, aEquationOrder );
+ sal_Int32 nTop = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].TopLeft.Second, aEquationOrder );
+ sal_Int32 nRight = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].BottomRight.First, aEquationOrder );
+ sal_Int32 nBottom = GetValueForEnhancedCustomShapeParameter( aPathTextFrames[ j ].BottomRight.Second, aEquationOrder );
+
+ aOut << nLeft
+ << nTop
+ << nRight
+ << nBottom;
+ }
+ sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
+ memcpy( pBuf, aOut.GetData(), nStreamSize );
+ AddOpt( DFF_Prop_textRectangles, sal_True, nStreamSize - 6, pBuf, nStreamSize );
+ }
+ else
+ {
+ sal_uInt8* pBuf = new sal_uInt8[ 1 ];
+ AddOpt( DFF_Prop_textRectangles, sal_True, 0, pBuf, 0 );
+ }
+ }
+ }
+ }
+ }
+ if ( nPathFlags != nPathFlagsOrg )
+ AddOpt( DFF_Prop_fFillOK, nPathFlags );
+ }
+ }
+ else if ( rProp.Name.equals( sTextPath ) )
+ {
+ uno::Sequence< beans::PropertyValue > aTextPathPropSeq;
+ if ( rProp.Value >>= aTextPathPropSeq )
+ {
+ sal_uInt32 nTextPathFlagsOrg, nTextPathFlags;
+ nTextPathFlagsOrg = nTextPathFlags = 0xffff1000; // default
+ if ( GetOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags ) )
+ nTextPathFlagsOrg = nTextPathFlags;
+
+ sal_Int32 r, nrCount = aTextPathPropSeq.getLength();
+ for ( r = 0; r < nrCount; r++ )
+ {
+ const beans::PropertyValue& rrProp = aTextPathPropSeq[ r ];
+ const rtl::OUString sTextPathMode ( RTL_CONSTASCII_USTRINGPARAM( "TextPathMode" ) );
+ const rtl::OUString sTextPathScaleX ( RTL_CONSTASCII_USTRINGPARAM( "ScaleX" ) );
+ const rtl::OUString sSameLetterHeights ( RTL_CONSTASCII_USTRINGPARAM( "SameLetterHeights" ) );
+
+ if ( rrProp.Name.equals( sTextPath ) )
+ {
+ sal_Bool bTextPathOn = sal_Bool();
+ if ( rrProp.Value >>= bTextPathOn )
+ {
+ nTextPathFlags |= 0x40000000;
+ if ( bTextPathOn )
+ {
+ nTextPathFlags |= 0x4000;
+
+ sal_uInt32 nPathFlags = 0x39;
+ GetOpt( DFF_Prop_fFillOK, nPathFlags ); // SJ: can be removed if we are supporting the TextPathAllowed property in XML
+ nPathFlags |= 0x40004;
+ AddOpt( DFF_Prop_fFillOK, nPathFlags );
+ }
+ else
+ nTextPathFlags &=~0x4000;
+ }
+ }
+ else if ( rrProp.Name.equals( sTextPathMode ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeTextPathMode eTextPathMode;
+ if ( rrProp.Value >>= eTextPathMode )
+ {
+ nTextPathFlags |= 0x05000000;
+ nTextPathFlags &=~0x500; // TextPathMode_NORMAL
+ if ( eTextPathMode == com::sun::star::drawing::EnhancedCustomShapeTextPathMode_PATH )
+ nTextPathFlags |= 0x100;
+ else if ( eTextPathMode == com::sun::star::drawing::EnhancedCustomShapeTextPathMode_SHAPE )
+ nTextPathFlags |= 0x500;
+ }
+ }
+ else if ( rrProp.Name.equals( sTextPathScaleX ) )
+ {
+ sal_Bool bTextPathScaleX = sal_Bool();
+ if ( rrProp.Value >>= bTextPathScaleX )
+ {
+ nTextPathFlags |= 0x00400000;
+ if ( bTextPathScaleX )
+ nTextPathFlags |= 0x40;
+ else
+ nTextPathFlags &=~0x40;
+ }
+ }
+ else if ( rrProp.Name.equals( sSameLetterHeights ) )
+ {
+ sal_Bool bSameLetterHeights = sal_Bool();
+ if ( rrProp.Value >>= bSameLetterHeights )
+ {
+ nTextPathFlags |= 0x00800000;
+ if ( bSameLetterHeights )
+ nTextPathFlags |= 0x80;
+ else
+ nTextPathFlags &=~0x80;
+ }
+ }
+ }
+ if ( nTextPathFlags & 0x4000 ) // Is FontWork ?
+ {
+ // FontWork Text
+ rtl::OUString aText;
+ uno::Reference< text::XSimpleText > xText( rXShape, uno::UNO_QUERY );
+ if ( xText.is() )
+ aText = xText->getString();
+ if ( !aText.getLength() )
+ aText = ::rtl::OUString::createFromAscii( "your text" ); // todo: moving into a resource
+ AddOpt( DFF_Prop_gtextUNICODE, aText );
+
+ // FontWork Font
+ rtl::OUString aFontName;
+ const rtl::OUString sCharFontName ( RTL_CONSTASCII_USTRINGPARAM( "CharFontName" ) );
+ uno::Any aAny = aXPropSet->getPropertyValue( sCharFontName );
+ aAny >>= aFontName;
+ if ( !aFontName.getLength() )
+ aFontName = ::rtl::OUString::createFromAscii( "Arial Black" );
+ AddOpt( DFF_Prop_gtextFont, aFontName );
+
+ sal_Int16 nCharScaleWidth = 100;
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharScaleWidth" ) ), sal_True ) )
+ {
+ if ( aAny >>= nCharScaleWidth )
+ {
+ if ( nCharScaleWidth != 100 )
+ {
+ sal_Int32 nVal = nCharScaleWidth * 655;
+ AddOpt( DFF_Prop_gtextSpacing, nVal );
+ }
+ }
+ }
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharKerning" ) ), sal_True ) )
+ {
+ sal_Int16 nCharKerning = sal_Int16();
+ if ( aAny >>= nCharKerning )
+ {
+ nTextPathFlags |= 0x10000000;
+ if ( nCharKerning )
+ nTextPathFlags |= 0x1000;
+ else
+ nTextPathFlags &=~0x1000;
+ }
+ }
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharPosture" ) ), sal_True ) )
+ {
+ awt::FontSlant eFontSlant;
+ if ( aAny >>= eFontSlant )
+ {
+ nTextPathFlags |= 0x100010;
+ if ( eFontSlant != awt::FontSlant_NONE )
+ nTextPathFlags |= 0x10;
+ else
+ nTextPathFlags &=~0x10;
+ }
+ }
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "CharWeight" ) ), sal_True ) )
+ {
+ float fFontWidth = 0;
+ if ( aAny >>= fFontWidth )
+ {
+ nTextPathFlags |= 0x200020;
+ if ( fFontWidth > awt::FontWeight::NORMAL )
+ nTextPathFlags |= 0x20;
+ else
+ nTextPathFlags &=~0x20;
+ }
+ }
+ }
+ if ( nTextPathFlags != nTextPathFlagsOrg )
+ AddOpt( DFF_Prop_gtextFStrikethrough, nTextPathFlags );
+ }
+ }
+ else if ( rProp.Name.equals( sHandles ) )
+ {
+ if ( !bIsDefaultObject )
+ {
+ bPredefinedHandlesUsed = sal_False;
+ if ( rProp.Value >>= aHandlesPropSeq )
+ {
+ sal_uInt16 nElements = (sal_uInt16)aHandlesPropSeq.getLength();
+ if ( nElements )
+ {
+ const rtl::OUString sHandle ( RTL_CONSTASCII_USTRINGPARAM( "Handle" ) );
+
+ sal_uInt16 k, j, nElementSize = 36;
+ sal_uInt32 nStreamSize = nElementSize * nElements + 6;
+ SvMemoryStream aOut( nStreamSize );
+ aOut << nElements
+ << nElements
+ << nElementSize;
+
+ for ( k = 0; k < nElements; k++ )
+ {
+ sal_uInt32 nFlags = 0;
+ sal_Int32 nXPosition = 0;
+ sal_Int32 nYPosition = 0;
+ sal_Int32 nXMap = 0;
+ sal_Int32 nYMap = 0;
+ sal_Int32 nXRangeMin = 0x80000000;
+ sal_Int32 nXRangeMax = 0x7fffffff;
+ sal_Int32 nYRangeMin = 0x80000000;
+ sal_Int32 nYRangeMax = 0x7fffffff;
+
+ const uno::Sequence< beans::PropertyValue >& rPropSeq = aHandlesPropSeq[ k ];
+ for ( j = 0; j < rPropSeq.getLength(); j++ )
+ {
+ const beans::PropertyValue& rPropVal = rPropSeq[ j ];
+
+ const rtl::OUString sPosition ( RTL_CONSTASCII_USTRINGPARAM( "Position" ) );
+ const rtl::OUString sMirroredX ( RTL_CONSTASCII_USTRINGPARAM( "MirroredX" ) );
+ const rtl::OUString sMirroredY ( RTL_CONSTASCII_USTRINGPARAM( "MirroredY" ) );
+ const rtl::OUString sSwitched ( RTL_CONSTASCII_USTRINGPARAM( "Switched" ) );
+ const rtl::OUString sPolar ( RTL_CONSTASCII_USTRINGPARAM( "Polar" ) );
+ // const rtl::OUString sMap ( RTL_CONSTASCII_USTRINGPARAM( "Map" ) );
+ const rtl::OUString sRadiusRangeMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMinimum" ) );
+ const rtl::OUString sRadiusRangeMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RadiusRangeMaximum" ) );
+ const rtl::OUString sRangeXMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMinimum" ) );
+ const rtl::OUString sRangeXMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeXMaximum" ) );
+ const rtl::OUString sRangeYMinimum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMinimum" ) );
+ const rtl::OUString sRangeYMaximum ( RTL_CONSTASCII_USTRINGPARAM( "RangeYMaximum" ) );
+
+ if ( rPropVal.Name.equals( sPosition ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
+ if ( rPropVal.Value >>= aPosition )
+ {
+ GetValueForEnhancedCustomShapeHandleParameter( nXPosition, aPosition.First );
+ GetValueForEnhancedCustomShapeHandleParameter( nYPosition, aPosition.Second );
+ }
+ }
+ else if ( rPropVal.Name.equals( sMirroredX ) )
+ {
+ sal_Bool bMirroredX = sal_Bool();
+ if ( rPropVal.Value >>= bMirroredX )
+ {
+ if ( bMirroredX )
+ nFlags |= 1;
+ }
+ }
+ else if ( rPropVal.Name.equals( sMirroredY ) )
+ {
+ sal_Bool bMirroredY = sal_Bool();
+ if ( rPropVal.Value >>= bMirroredY )
+ {
+ if ( bMirroredY )
+ nFlags |= 2;
+ }
+ }
+ else if ( rPropVal.Name.equals( sSwitched ) )
+ {
+ sal_Bool bSwitched = sal_Bool();
+ if ( rPropVal.Value >>= bSwitched )
+ {
+ if ( bSwitched )
+ nFlags |= 4;
+ }
+ }
+ else if ( rPropVal.Name.equals( sPolar ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair aPolar;
+ if ( rPropVal.Value >>= aPolar )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aPolar.First ) )
+ nFlags |= 0x800;
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aPolar.Second ) )
+ nFlags |= 0x1000;
+ nFlags |= 8;
+ }
+ }
+ /* seems not to be used.
+ else if ( rPropVal.Name.equals( sMap ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair aMap;
+ if ( rPropVal.Value >>= aMap )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nXMap, aMap.First ) )
+ nFlags |= 0x800;
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nYMap, aMap.Second ) )
+ nFlags |= 0x1000;
+ nFlags |= 0x10;
+ }
+ }
+ */
+ else if ( rPropVal.Name.equals( sRadiusRangeMinimum ) )
+ {
+ nYRangeMin = (sal_Int32)0xff4c0000; // the range of angles seems to be a not
+ nYRangeMax = (sal_Int32)0x00b40000; // used feature, so we are defaulting this
+
+ com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
+ if ( rPropVal.Value >>= aRadiusRangeMinimum )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMin, aRadiusRangeMinimum ) )
+ nFlags |= 0x80;
+ nFlags |= 0x2000;
+ }
+ }
+ else if ( rPropVal.Name.equals( sRadiusRangeMaximum ) )
+ {
+ nYRangeMin = (sal_Int32)0xff4c0000; // the range of angles seems to be a not
+ nYRangeMax = (sal_Int32)0x00b40000; // used feature, so we are defaulting this
+
+ com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
+ if ( rPropVal.Value >>= aRadiusRangeMaximum )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMax, aRadiusRangeMaximum ) )
+ nFlags |= 0x100;
+ nFlags |= 0x2000;
+ }
+ }
+ else if ( rPropVal.Name.equals( sRangeXMinimum ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMinimum;
+ if ( rPropVal.Value >>= aXRangeMinimum )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMin, aXRangeMinimum ) )
+ nFlags |= 0x80;
+ nFlags |= 0x20;
+ }
+ }
+ else if ( rPropVal.Name.equals( sRangeXMaximum ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameter aXRangeMaximum;
+ if ( rPropVal.Value >>= aXRangeMaximum )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nXRangeMax, aXRangeMaximum ) )
+ nFlags |= 0x100;
+ nFlags |= 0x20;
+ }
+ }
+ else if ( rPropVal.Name.equals( sRangeYMinimum ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMinimum;
+ if ( rPropVal.Value >>= aYRangeMinimum )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nYRangeMin, aYRangeMinimum ) )
+ nFlags |= 0x200;
+ nFlags |= 0x20;
+ }
+ }
+ else if ( rPropVal.Name.equals( sRangeYMaximum ) )
+ {
+ com::sun::star::drawing::EnhancedCustomShapeParameter aYRangeMaximum;
+ if ( rPropVal.Value >>= aYRangeMaximum )
+ {
+ if ( GetValueForEnhancedCustomShapeHandleParameter( nYRangeMax, aYRangeMaximum ) )
+ nFlags |= 0x400;
+ nFlags |= 0x20;
+ }
+ }
+ }
+ aOut << nFlags
+ << nXPosition
+ << nYPosition
+ << nXMap
+ << nYMap
+ << nXRangeMin
+ << nXRangeMax
+ << nYRangeMin
+ << nYRangeMax;
+
+ if ( nFlags & 8 )
+ nAdjustmentsWhichNeedsToBeConverted |= ( 1 << ( nYPosition - 0x100 ) );
+ }
+ sal_uInt8* pBuf = new sal_uInt8[ nStreamSize ];
+ memcpy( pBuf, aOut.GetData(), nStreamSize );
+ AddOpt( DFF_Prop_Handles, sal_True, nStreamSize - 6, pBuf, nStreamSize );
+ }
+ else
+ {
+ sal_uInt8* pBuf = new sal_uInt8[ 1 ];
+ AddOpt( DFF_Prop_Handles, sal_True, 0, pBuf, 0 );
+ }
+ }
+ }
+ }
+ else if ( rProp.Name.equals( sAdjustmentValues ) )
+ {
+ // it is required, that the information which handle is polar has already be read,
+ // so we are able to change the polar value to a fixed float
+ pAdjustmentValuesProp = &rProp;
+ }
+ }
+ if ( pAdjustmentValuesProp )
+ {
+ uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
+ if ( pAdjustmentValuesProp->Value >>= aAdjustmentSeq )
+ {
+ if ( bPredefinedHandlesUsed )
+ LookForPolarHandles( eShapeType, nAdjustmentsWhichNeedsToBeConverted );
+
+ sal_Int32 k, nValue = 0, nAdjustmentValues = aAdjustmentSeq.getLength();
+ for ( k = 0; k < nAdjustmentValues; k++ )
+ if( GetAdjustmentValue( aAdjustmentSeq[ k ], k, nAdjustmentsWhichNeedsToBeConverted, nValue ) )
+ AddOpt( (sal_uInt16)( DFF_Prop_adjustValue + k ), (sal_uInt32)nValue );
+ }
+ }
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------------
+
+MSO_SPT EscherPropertyContainer::GetCustomShapeType( const uno::Reference< drawing::XShape > & rXShape, sal_uInt32& nMirrorFlags, rtl::OUString& rShapeType )
+{
+ MSO_SPT eShapeType = mso_sptNil;
+ nMirrorFlags = 0;
+ uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY );
+ if ( aXPropSet.is() )
+ {
+ try
+ {
+ const OUString sCustomShapeGeometry( RTL_CONSTASCII_USTRINGPARAM ( "CustomShapeGeometry" ) );
+ uno::Any aGeoPropSet = aXPropSet->getPropertyValue( sCustomShapeGeometry );
+ uno::Sequence< beans::PropertyValue > aGeoPropSeq;
+ if ( aGeoPropSet >>= aGeoPropSeq )
+ {
+ sal_Int32 i, nCount = aGeoPropSeq.getLength();
+ for ( i = 0; i < nCount; i++ )
+ {
+ const beans::PropertyValue& rProp = aGeoPropSeq[ i ];
+ if ( rProp.Name.equalsAscii( "Type" ) )
+ {
+ if ( rProp.Value >>= rShapeType )
+ eShapeType = EnhancedCustomShapeTypeNames::Get( rShapeType );
+ }
+ else if ( rProp.Name.equalsAscii( "MirroredX" ) )
+ {
+ sal_Bool bMirroredX = sal_Bool();
+ if ( ( rProp.Value >>= bMirroredX ) && bMirroredX )
+ nMirrorFlags |= SHAPEFLAG_FLIPH;
+ }
+ else if ( rProp.Name.equalsAscii( "MirroredY" ) )
+ {
+ sal_Bool bMirroredY = sal_Bool();
+ if ( ( rProp.Value >>= bMirroredY ) && bMirroredY )
+ nMirrorFlags |= SHAPEFLAG_FLIPV;
+ }
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ return eShapeType;
+}
+
+MSO_SPT EscherPropertyContainer::GetCustomShapeType( const uno::Reference< drawing::XShape > & rXShape, sal_uInt32& nMirrorFlags )
+{
+ rtl::OUString aShapeType;
+ return GetCustomShapeType( rXShape, nMirrorFlags, aShapeType );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+EscherPersistTable::EscherPersistTable()
+{
+}
+
+// ---------------------------------------------------------------------------------------------
+
+EscherPersistTable::~EscherPersistTable()
+{
+ for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() )
+ delete (EscherPersistEntry*)pPtr;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+BOOL EscherPersistTable::PtIsID( UINT32 nID )
+{
+ for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() )
+ {
+ if ( ((EscherPersistEntry*)pPtr)->mnID == nID )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherPersistTable::PtInsert( UINT32 nID, UINT32 nOfs )
+{
+ maPersistTable.Insert( new EscherPersistEntry( nID, nOfs ) );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+UINT32 EscherPersistTable::PtDelete( UINT32 nID )
+{
+ for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() )
+ {
+ if ( ((EscherPersistEntry*)pPtr)->mnID == nID )
+ {
+// UINT32 nRetValue = ((EscherPersistEntry*)pPtr)->mnOffset;
+ delete (EscherPersistEntry*) maPersistTable.Remove();
+ }
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+UINT32 EscherPersistTable::PtGetOffsetByID( UINT32 nID )
+{
+ for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() )
+ {
+ if ( ((EscherPersistEntry*)pPtr)->mnID == nID )
+ return ((EscherPersistEntry*)pPtr)->mnOffset;
+ }
+ return 0;
+};
+
+// ---------------------------------------------------------------------------------------------
+
+UINT32 EscherPersistTable::PtReplace( UINT32 nID, UINT32 nOfs )
+{
+ for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() )
+ {
+ if ( ((EscherPersistEntry*)pPtr)->mnID == nID )
+ {
+ UINT32 nRetValue = ((EscherPersistEntry*)pPtr)->mnOffset;
+ ((EscherPersistEntry*)pPtr)->mnOffset = nOfs;
+ return nRetValue;
+ }
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+UINT32 EscherPersistTable::PtReplaceOrInsert( UINT32 nID, UINT32 nOfs )
+{
+ for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() )
+ {
+ if ( ((EscherPersistEntry*)pPtr)->mnID == nID )
+ {
+ UINT32 nRetValue = ((EscherPersistEntry*)pPtr)->mnOffset;
+ ((EscherPersistEntry*)pPtr)->mnOffset = nOfs;
+ return nRetValue;
+ }
+ }
+ PtInsert( nID, nOfs );
+ return 0;
+}
+
+sal_Bool EscherPropertyValueHelper::GetPropertyValue(
+ ::com::sun::star::uno::Any& rAny,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ const String& rString,
+ sal_Bool bTestPropertyAvailability )
+{
+ sal_Bool bRetValue = sal_True;
+ if ( bTestPropertyAvailability )
+ {
+ bRetValue = sal_False;
+ try
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
+ aXPropSetInfo( rXPropSet->getPropertySetInfo() );
+ if ( aXPropSetInfo.is() )
+ bRetValue = aXPropSetInfo->hasPropertyByName( rString );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ bRetValue = sal_False;
+ }
+ }
+ if ( bRetValue )
+ {
+ try
+ {
+ rAny = rXPropSet->getPropertyValue( rString );
+ if ( !rAny.hasValue() )
+ bRetValue = sal_False;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ bRetValue = sal_False;
+ }
+ }
+ return bRetValue;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+::com::sun::star::beans::PropertyState EscherPropertyValueHelper::GetPropertyState(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ const String& rPropertyName )
+{
+ ::com::sun::star::beans::PropertyState eRetValue = ::com::sun::star::beans::PropertyState_AMBIGUOUS_VALUE;
+ try
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > aXPropState
+ ( rXPropSet, ::com::sun::star::uno::UNO_QUERY );
+ if ( aXPropState.is() )
+ eRetValue = aXPropState->getPropertyState( rPropertyName );
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ //...
+ }
+ return eRetValue;
+}
+
+// ---------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------
+
+EscherBlibEntry::EscherBlibEntry( sal_uInt32 nPictureOffset, const GraphicObject& rObject, const ByteString& rId,
+ const GraphicAttr* pGraphicAttr ) :
+ mnPictureOffset ( nPictureOffset ),
+ mnRefCount ( 1 ),
+ mnSizeExtra ( 0 ),
+ maPrefSize ( rObject.GetPrefSize() ),
+ maPrefMapMode ( rObject.GetPrefMapMode() ),
+ mbIsEmpty ( TRUE )
+{
+ mbIsNativeGraphicPossible = ( pGraphicAttr == NULL );
+ meBlibType = UNKNOWN;
+ mnSize = 0;
+
+ sal_uInt32 nLen = rId.Len();
+ const sal_Char* pData = rId.GetBuffer();
+ GraphicType eType( rObject.GetType() );
+ if ( nLen && pData && ( eType != GRAPHIC_NONE ) )
+ {
+ mnIdentifier[ 0 ] = rtl_crc32( 0,pData, nLen );
+ mnIdentifier[ 1 ] = 0;
+
+ if ( pGraphicAttr )
+ {
+ if ( pGraphicAttr->IsSpecialDrawMode()
+ || pGraphicAttr->IsMirrored()
+ || pGraphicAttr->IsCropped()
+ || pGraphicAttr->IsRotated()
+ || pGraphicAttr->IsTransparent()
+ || pGraphicAttr->IsAdjusted() )
+ {
+ SvMemoryStream aSt( sizeof( GraphicAttr ) );
+ aSt << static_cast<sal_uInt16>(pGraphicAttr->GetDrawMode())
+ << static_cast<sal_uInt32>(pGraphicAttr->GetMirrorFlags())
+ << pGraphicAttr->GetLeftCrop()
+ << pGraphicAttr->GetTopCrop()
+ << pGraphicAttr->GetRightCrop()
+ << pGraphicAttr->GetBottomCrop()
+ << pGraphicAttr->GetRotation()
+ << pGraphicAttr->GetLuminance()
+ << pGraphicAttr->GetContrast()
+ << pGraphicAttr->GetChannelR()
+ << pGraphicAttr->GetChannelG()
+ << pGraphicAttr->GetChannelB()
+ << pGraphicAttr->GetGamma()
+ << (BOOL)( pGraphicAttr->IsInvert() == TRUE )
+ << pGraphicAttr->GetTransparency();
+ mnIdentifier[ 1 ] = rtl_crc32( 0, aSt.GetData(), aSt.Tell() );
+ }
+ else
+ mbIsNativeGraphicPossible = TRUE;
+ }
+ sal_uInt32 i, nTmp, n1, n2;
+ n1 = n2 = 0;
+ for ( i = 0; i < nLen; i++ )
+ {
+ nTmp = n2 >> 28; // rotating 4 bit
+ n2 <<= 4;
+ n2 |= n1 >> 28;
+ n1 <<= 4;
+ n1 |= nTmp;
+ n1 ^= *pData++ - '0';
+ }
+ mnIdentifier[ 2 ] = n1;
+ mnIdentifier[ 3 ] = n2;
+ mbIsEmpty = FALSE;
+ }
+};
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherBlibEntry::WriteBlibEntry( SvStream& rSt, sal_Bool bWritePictureOffset, sal_uInt32 nResize )
+{
+ sal_uInt32 nPictureOffset = ( bWritePictureOffset ) ? mnPictureOffset : 0;
+
+ rSt << (sal_uInt32)( ( ESCHER_BSE << 16 ) | ( ( (sal_uInt16)meBlibType << 4 ) | 2 ) )
+ << (sal_uInt32)( 36 + nResize )
+ << (sal_uInt8)meBlibType;
+
+ switch ( meBlibType )
+ {
+ case EMF :
+ case WMF : // EMF/WMF auf OS2 zu Pict Konvertieren
+ rSt << (sal_uInt8)PICT;
+ break;
+ default:
+ rSt << (sal_uInt8)meBlibType;
+ };
+
+ rSt.Write( &mnIdentifier[ 0 ], 16 );
+ rSt << (sal_uInt16)0
+ << (sal_uInt32)( mnSize + mnSizeExtra )
+ << mnRefCount
+ << nPictureOffset
+ << (sal_uInt32)0;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+EscherBlibEntry::~EscherBlibEntry()
+{
+};
+
+// ---------------------------------------------------------------------------------------------
+
+BOOL EscherBlibEntry::operator==( const EscherBlibEntry& rEscherBlibEntry ) const
+{
+ for ( int i = 0; i < 3; i++ )
+ {
+ if ( mnIdentifier[ i ] != rEscherBlibEntry.mnIdentifier[ i ] )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// ---------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------
+
+EscherGraphicProvider::EscherGraphicProvider( sal_uInt32 nFlags ) :
+ mnFlags ( nFlags ),
+ mpBlibEntrys ( NULL ),
+ mnBlibBufSize ( 0 ),
+ mnBlibEntrys ( 0 )
+{
+}
+
+EscherGraphicProvider::~EscherGraphicProvider()
+{
+ for ( UINT32 i = 0; i < mnBlibEntrys; delete mpBlibEntrys[ i++ ] ) ;
+ delete[] mpBlibEntrys;
+}
+
+void EscherGraphicProvider::SetNewBlipStreamOffset( sal_Int32 nOffset )
+{
+ for( sal_uInt32 i = 0; i < mnBlibEntrys; i++ )
+ {
+ EscherBlibEntry* pBlibEntry = mpBlibEntrys[ i ];
+ pBlibEntry->mnPictureOffset += nOffset;
+ }
+}
+
+UINT32 EscherGraphicProvider::ImplInsertBlib( EscherBlibEntry* p_EscherBlibEntry )
+{
+ if ( mnBlibBufSize == mnBlibEntrys )
+ {
+ mnBlibBufSize += 64;
+ EscherBlibEntry** pTemp = new EscherBlibEntry*[ mnBlibBufSize ];
+ for ( UINT32 i = 0; i < mnBlibEntrys; i++ )
+ {
+ pTemp[ i ] = mpBlibEntrys[ i ];
+ }
+ delete[] mpBlibEntrys;
+ mpBlibEntrys = pTemp;
+ }
+ mpBlibEntrys[ mnBlibEntrys++ ] = p_EscherBlibEntry;
+ return mnBlibEntrys;
+}
+
+sal_uInt32 EscherGraphicProvider::GetBlibStoreContainerSize( SvStream* pMergePicStreamBSE ) const
+{
+ sal_uInt32 nSize = 44 * mnBlibEntrys + 8;
+ if ( pMergePicStreamBSE )
+ {
+ for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ )
+ nSize += mpBlibEntrys[ i ]->mnSize + mpBlibEntrys[ i ]->mnSizeExtra;
+ }
+ return nSize;
+}
+
+sal_Bool EscherGraphicProvider::WriteBlibStoreEntry(SvStream& rSt,
+ sal_uInt32 nBlipId, sal_Bool bWritePictureOffSet, sal_uInt32 nResize)
+{
+ if (nBlipId > mnBlibEntrys || nBlipId == 0)
+ return sal_False;
+ mpBlibEntrys[nBlipId-1]->WriteBlibEntry(rSt, bWritePictureOffSet, nResize);
+ return sal_True;
+}
+
+void EscherGraphicProvider::WriteBlibStoreContainer( SvStream& rSt, SvStream* pMergePicStreamBSE )
+{
+ sal_uInt32 nSize = GetBlibStoreContainerSize( pMergePicStreamBSE );
+ if ( nSize )
+ {
+ rSt << (sal_uInt32)( ( ESCHER_BstoreContainer << 16 ) | 0x1f )
+ << (sal_uInt32)( nSize - 8 );
+
+ if ( pMergePicStreamBSE )
+ {
+ sal_uInt32 i, nBlipSize, nOldPos = pMergePicStreamBSE->Tell();
+ const sal_uInt32 nBuf = 0x40000; // 256KB buffer
+ sal_uInt8* pBuf = new sal_uInt8[ nBuf ];
+
+ for ( i = 0; i < mnBlibEntrys; i++ )
+ {
+ EscherBlibEntry* pBlibEntry = mpBlibEntrys[ i ];
+
+ ESCHER_BlibType nBlibType = pBlibEntry->meBlibType;
+ nBlipSize = pBlibEntry->mnSize + pBlibEntry->mnSizeExtra;
+ pBlibEntry->WriteBlibEntry( rSt, sal_False, nBlipSize );
+
+ // BLIP
+ pMergePicStreamBSE->Seek( pBlibEntry->mnPictureOffset );
+ UINT16 n16;
+ // record version and instance
+ *pMergePicStreamBSE >> n16;
+ rSt << n16;
+ // record type
+ *pMergePicStreamBSE >> n16;
+ rSt << UINT16( ESCHER_BlipFirst + nBlibType );
+ DBG_ASSERT( n16 == ESCHER_BlipFirst + nBlibType , "EscherEx::Flush: BLIP record types differ" );
+ UINT32 n32;
+ // record size
+ *pMergePicStreamBSE >> n32;
+ nBlipSize -= 8;
+ rSt << nBlipSize;
+ DBG_ASSERT( nBlipSize == n32, "EscherEx::Flush: BLIP sizes differ" );
+ // record
+ while ( nBlipSize )
+ {
+ UINT32 nBytes = ( nBlipSize > nBuf ? nBuf : nBlipSize );
+ pMergePicStreamBSE->Read( pBuf, nBytes );
+ rSt.Write( pBuf, nBytes );
+ nBlipSize -= nBytes;
+ }
+ }
+ delete[] pBuf;
+ pMergePicStreamBSE->Seek( nOldPos );
+ }
+ else
+ {
+ for ( sal_uInt32 i = 0; i < mnBlibEntrys; i++ )
+ mpBlibEntrys[ i ]->WriteBlibEntry( rSt, sal_True );
+ }
+ }
+}
+
+sal_Bool EscherGraphicProvider::GetPrefSize( const sal_uInt32 nBlibId, Size& rPrefSize, MapMode& rPrefMapMode )
+{
+ sal_Bool bInRange = nBlibId && ( ( nBlibId - 1 ) < mnBlibEntrys );
+ if ( bInRange )
+ {
+ EscherBlibEntry* pEntry = mpBlibEntrys[ nBlibId - 1 ];
+ rPrefSize = pEntry->maPrefSize;
+ rPrefMapMode = pEntry->maPrefMapMode;
+ }
+ return bInRange;
+}
+
+sal_uInt32 EscherGraphicProvider::GetBlibID( SvStream& rPicOutStrm, const ByteString& rId,
+ const Rectangle& /* rBoundRect */, const com::sun::star::awt::Rectangle* pVisArea, const GraphicAttr* pGraphicAttr )
+{
+ sal_uInt32 nBlibId = 0;
+ GraphicObject aGraphicObject( rId );
+
+ EscherBlibEntry* p_EscherBlibEntry = new EscherBlibEntry( rPicOutStrm.Tell(), aGraphicObject, rId, pGraphicAttr );
+ if ( !p_EscherBlibEntry->IsEmpty() )
+ {
+ for ( UINT32 i = 0; i < mnBlibEntrys; i++ )
+ {
+ if ( *( mpBlibEntrys[ i ] ) == *p_EscherBlibEntry )
+ {
+ mpBlibEntrys[ i ]->mnRefCount++;
+ delete p_EscherBlibEntry;
+ return i + 1;
+ }
+ }
+
+ sal_Bool bUseNativeGraphic( FALSE );
+
+ Graphic aGraphic( aGraphicObject.GetTransformedGraphic( pGraphicAttr ) );
+ GfxLink aGraphicLink;
+ SvMemoryStream aStream;
+
+ const sal_uInt8* pGraphicAry = NULL;
+
+ if ( p_EscherBlibEntry->mbIsNativeGraphicPossible && aGraphic.IsLink() )
+ {
+ aGraphicLink = aGraphic.GetLink();
+
+ p_EscherBlibEntry->mnSize = aGraphicLink.GetDataSize();
+ pGraphicAry = aGraphicLink.GetData();
+
+ if ( p_EscherBlibEntry->mnSize && pGraphicAry )
+ {
+ switch ( aGraphicLink.GetType() )
+ {
+ case GFX_LINK_TYPE_NATIVE_JPG : p_EscherBlibEntry->meBlibType = PEG; break;
+ case GFX_LINK_TYPE_NATIVE_PNG : p_EscherBlibEntry->meBlibType = PNG; break;
+ case GFX_LINK_TYPE_NATIVE_WMF :
+ {
+ if ( pGraphicAry && ( p_EscherBlibEntry->mnSize > 0x2c ) )
+ {
+ if ( ( pGraphicAry[ 0x28 ] == 0x20 ) && ( pGraphicAry[ 0x29 ] == 0x45 ) // check the magic
+ && ( pGraphicAry[ 0x2a ] == 0x4d ) && ( pGraphicAry[ 0x2b ] == 0x46 ) ) // number ( emf detection )
+ {
+ p_EscherBlibEntry->meBlibType = EMF;
+ }
+ else
+ {
+ p_EscherBlibEntry->meBlibType = WMF;
+ if ( ( pGraphicAry[ 0 ] == 0xd7 ) && ( pGraphicAry[ 1 ] == 0xcd )
+ && ( pGraphicAry[ 2 ] == 0xc6 ) && ( pGraphicAry[ 3 ] == 0x9a ) )
+ { // we have to get rid of the metafileheader
+ pGraphicAry += 22;
+ p_EscherBlibEntry->mnSize -= 22;
+ }
+ }
+ }
+ }
+ break;
+ default: break;
+ }
+ if ( p_EscherBlibEntry->meBlibType != UNKNOWN )
+ bUseNativeGraphic = TRUE;
+ }
+ }
+ if ( !bUseNativeGraphic )
+ {
+ GraphicType eGraphicType = aGraphic.GetType();
+ if ( ( eGraphicType == GRAPHIC_BITMAP ) || ( eGraphicType == GRAPHIC_GDIMETAFILE ) )
+ {
+ sal_uInt32 nErrCode;
+ if ( !aGraphic.IsAnimated() )
+// !EMF nErrCode = GraphicConverter::Export( aStream, aGraphic, ( eGraphicType == GRAPHIC_BITMAP ) ? CVT_PNG : CVT_WMF );
+ nErrCode = GraphicConverter::Export( aStream, aGraphic, ( eGraphicType == GRAPHIC_BITMAP ) ? CVT_PNG : CVT_EMF );
+ else
+ { // to store a animation, a gif has to be included into the msOG chunk of a png #I5583#
+ GraphicFilter* pFilter = GetGrfFilter();
+ SvMemoryStream aGIFStream;
+ ByteString aVersion( "MSOFFICE9.0" );
+ aGIFStream.Write( aVersion.GetBuffer(), aVersion.Len() );
+ nErrCode = pFilter->ExportGraphic( aGraphic, String(), aGIFStream,
+ pFilter->GetExportFormatNumberForShortName( String( RTL_CONSTASCII_USTRINGPARAM( "GIF" ) ) ), NULL );
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aFilterData( 1 );
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence( 1 );
+ sal_uInt32 nGIFSreamLen = aGIFStream.Tell();
+ com::sun::star::uno::Sequence< sal_Int8 > aGIFSeq( nGIFSreamLen );
+ sal_Int8* pSeq = aGIFSeq.getArray();
+ aGIFStream.Seek( STREAM_SEEK_TO_BEGIN );
+ aGIFStream.Read( pSeq, nGIFSreamLen );
+ com::sun::star::beans::PropertyValue aChunkProp, aFilterProp;
+ aChunkProp.Name = String( RTL_CONSTASCII_USTRINGPARAM( "msOG" ) );
+ aChunkProp.Value <<= aGIFSeq;
+ aAdditionalChunkSequence[ 0 ] = aChunkProp;
+ aFilterProp.Name = String( RTL_CONSTASCII_USTRINGPARAM( "AdditionalChunks" ) );
+ aFilterProp.Value <<= aAdditionalChunkSequence;
+ aFilterData[ 0 ] = aFilterProp;
+ nErrCode = pFilter->ExportGraphic( aGraphic, String(), aStream,
+ pFilter->GetExportFormatNumberForShortName( String( RTL_CONSTASCII_USTRINGPARAM( "PNG" ) ) ), &aFilterData );
+ }
+ if ( nErrCode == ERRCODE_NONE )
+ {
+// !EMF p_EscherBlibEntry->meBlibType = ( eGraphicType == GRAPHIC_BITMAP ) ? PNG : WMF;
+ p_EscherBlibEntry->meBlibType = ( eGraphicType == GRAPHIC_BITMAP ) ? PNG : EMF;
+ aStream.Seek( STREAM_SEEK_TO_END );
+ p_EscherBlibEntry->mnSize = aStream.Tell();
+ pGraphicAry = (sal_uInt8*)aStream.GetData();
+
+ if ( p_EscherBlibEntry->meBlibType == WMF ) // the fileheader is not used
+ {
+ p_EscherBlibEntry->mnSize -= 22;
+ pGraphicAry += 22;
+ }
+ }
+ }
+ }
+
+ ESCHER_BlibType eBlibType = p_EscherBlibEntry->meBlibType;
+ if ( p_EscherBlibEntry->mnSize && pGraphicAry && ( eBlibType != UNKNOWN ) )
+ {
+ sal_uInt32 nExtra, nAtomSize = 0;
+ sal_uInt32 nInstance, nUncompressedSize = p_EscherBlibEntry->mnSize;
+
+ if ( mnFlags & _E_GRAPH_PROV_USE_INSTANCES )
+ {
+ rPicOutStrm << (UINT32)( 0x7f90000 | (UINT16)( mnBlibEntrys << 4 ) )
+ << (UINT32)0;
+ nAtomSize = rPicOutStrm.Tell();
+ if ( eBlibType == PNG )
+ rPicOutStrm << (sal_uInt16)0x0606;
+ else if ( eBlibType == WMF )
+ rPicOutStrm << (sal_uInt16)0x0403;
+ else if ( eBlibType == EMF )
+ rPicOutStrm << (sal_uInt16)0x0402;
+ else if ( eBlibType == PEG )
+ rPicOutStrm << (sal_uInt16)0x0505;
+ }
+ if ( ( eBlibType == PEG ) || ( eBlibType == PNG ) )
+ {
+ nExtra = 17;
+ p_EscherBlibEntry->mnSizeExtra = nExtra + 8;
+ nInstance = ( eBlibType == PNG ) ? 0xf01e6e00 : 0xf01d46a0;
+ rPicOutStrm << nInstance << (sal_uInt32)( p_EscherBlibEntry->mnSize + nExtra );
+ rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 );
+ rPicOutStrm << (sal_uInt8)0xff;
+ rPicOutStrm.Write( pGraphicAry, p_EscherBlibEntry->mnSize );
+ }
+ else
+ {
+ ZCodec aZCodec( 0x8000, 0x8000 );
+ aZCodec.BeginCompression();
+ SvMemoryStream aDestStrm;
+ aZCodec.Write( aDestStrm, pGraphicAry, p_EscherBlibEntry->mnSize );
+ aZCodec.EndCompression();
+ aDestStrm.Seek( STREAM_SEEK_TO_END );
+ p_EscherBlibEntry->mnSize = aDestStrm.Tell();
+ pGraphicAry = (sal_uInt8*)aDestStrm.GetData();
+ if ( p_EscherBlibEntry->mnSize && pGraphicAry )
+ {
+ nExtra = eBlibType == WMF ? 0x42 : 0x32; // !EMF -> no change
+ p_EscherBlibEntry->mnSizeExtra = nExtra + 8;
+ nInstance = ( eBlibType == WMF ) ? 0xf01b2170 : 0xf01a3d40; // !EMF -> no change
+ rPicOutStrm << nInstance << (sal_uInt32)( p_EscherBlibEntry->mnSize + nExtra );
+ if ( eBlibType == WMF ) // !EMF -> no change
+ rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 );
+ rPicOutStrm.Write( p_EscherBlibEntry->mnIdentifier, 16 );
+
+ /*
+ ##913##
+ For Word the stored size of the graphic is critical the
+ metafile boundaries must match the actual graphics
+ boundaries, and the width and height must be in EMU's
+
+ If you don't do it this way then objects edited in the
+ msoffice app may show strange behaviour as the size jumps
+ around, and the original size and scaling factor in word
+ will be a very strange figure
+ */
+ UINT32 nPrefWidth = p_EscherBlibEntry->maPrefSize.Width();
+ UINT32 nPrefHeight = p_EscherBlibEntry->maPrefSize.Height();
+ UINT32 nWidth, nHeight;
+ if ( pVisArea )
+ {
+ nWidth = pVisArea->Width * 360;
+ nHeight = pVisArea->Height * 360;
+ }
+ else
+ {
+ Size aPrefSize(lcl_SizeToEmu(p_EscherBlibEntry->maPrefSize, p_EscherBlibEntry->maPrefMapMode));
+ nWidth = aPrefSize.Width() * 360;
+ nHeight = aPrefSize.Height() * 360;
+ }
+ rPicOutStrm << nUncompressedSize // WMFSize without FileHeader
+ << (sal_Int32)0 // da die Originalgroesse des WMF's (ohne FileHeader)
+ << (sal_Int32)0 // nicht mehr feststellbar ist, schreiben wir 10cm / x
+ << nPrefWidth
+ << nPrefHeight
+ << nWidth
+ << nHeight
+ << p_EscherBlibEntry->mnSize
+ << (sal_uInt16)0xfe00; // compression Flags
+ rPicOutStrm.Write( pGraphicAry, p_EscherBlibEntry->mnSize );
+ }
+ }
+ if ( nAtomSize )
+ {
+ sal_uInt32 nPos = rPicOutStrm.Tell();
+ rPicOutStrm.Seek( nAtomSize - 4 );
+ rPicOutStrm << (sal_uInt32)( nPos - nAtomSize );
+ rPicOutStrm.Seek( nPos );
+ }
+ nBlibId = ImplInsertBlib( p_EscherBlibEntry ), p_EscherBlibEntry = NULL;
+ }
+ }
+ if ( p_EscherBlibEntry )
+ delete p_EscherBlibEntry;
+ return nBlibId;
+}
+
+// ---------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------
+
+struct EscherConnectorRule
+{
+ sal_uInt32 nRuleId;
+ sal_uInt32 nShapeA; // SPID of shape A
+ sal_uInt32 nShapeB; // SPID of shape B
+ sal_uInt32 nShapeC; // SPID of connector shape
+ sal_uInt32 ncptiA; // Connection site Index of shape A
+ sal_uInt32 ncptiB; // Connection site Index of shape B
+};
+
+struct EscherShapeListEntry
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > aXShape;
+ sal_uInt32 n_EscherId;
+
+ EscherShapeListEntry( const ::com::sun::star::uno::Reference
+ < ::com::sun::star::drawing::XShape > & rShape, sal_uInt32 nId ) :
+ aXShape ( rShape ),
+ n_EscherId ( nId ) {}
+};
+
+sal_uInt32 EscherConnectorListEntry::GetClosestPoint( const Polygon& rPoly, const ::com::sun::star::awt::Point& rPoint )
+{
+ sal_uInt16 nCount = rPoly.GetSize();
+ sal_uInt16 nClosest = nCount;
+ double fDist = (sal_uInt32)0xffffffff;
+ while( nCount-- )
+ {
+ double fDistance = hypot( rPoint.X - rPoly[ nCount ].X(), rPoint.Y - rPoly[ nCount ].Y() );
+ if ( fDistance < fDist )
+ {
+ nClosest = nCount;
+ fDist = fDistance;
+ }
+ }
+ return nClosest;
+};
+
+// ---------------------------------------------------------------------------------------------
+// bei Rechtecken bei Ellipsen bei Polygonen
+//
+// nRule = 0 ->Top 0 ->Top nRule = Index auf ein (Poly)Polygon Punkt
+// 1 ->Left 2 ->Left
+// 2 ->Bottom 4 ->Bottom
+// 3 ->Right 6 ->Right
+
+sal_uInt32 EscherConnectorListEntry::GetConnectorRule( sal_Bool bFirst )
+{
+ sal_uInt32 nRule = 0;
+
+ ::com::sun::star::uno::Any aAny;
+ ::com::sun::star::awt::Point aRefPoint( ( bFirst ) ? maPointA : maPointB );
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
+ aXShape( ( bFirst ) ? mXConnectToA : mXConnectToB );
+
+ String aString( (::rtl::OUString)aXShape->getShapeType() );
+ ByteString aType( aString, RTL_TEXTENCODING_UTF8 );
+ aType.Erase( 0, 13 ); // removing "com.sun.star."
+ sal_uInt16 nPos = aType.Search( "Shape" );
+ aType.Erase( nPos, 5 );
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
+ aPropertySet( aXShape, ::com::sun::star::uno::UNO_QUERY );
+
+ if ( aType == "drawing.PolyPolygon" || aType == "drawing.PolyLine" )
+ {
+ if ( aPropertySet.is() )
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny,
+ aPropertySet, String( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygon" ) ) ) )
+ {
+ ::com::sun::star::drawing::PointSequenceSequence* pSourcePolyPolygon =
+ (::com::sun::star::drawing::PointSequenceSequence*)aAny.getValue();
+ sal_Int32 nOuterSequenceCount = pSourcePolyPolygon->getLength();
+ ::com::sun::star::drawing::PointSequence* pOuterSequence = pSourcePolyPolygon->getArray();
+
+ if ( pOuterSequence )
+ {
+ sal_Int32 a, b, nIndex = 0;
+ sal_uInt32 nDistance = 0xffffffff;
+ for( a = 0; a < nOuterSequenceCount; a++ )
+ {
+ ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++;
+ if ( pInnerSequence )
+ {
+ ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray();
+ if ( pArray )
+ {
+ for ( b = 0; b < pInnerSequence->getLength(); b++, nIndex++, pArray++ )
+ {
+ sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - pArray->X, aRefPoint.Y - pArray->Y );
+ if ( nDist < nDistance )
+ {
+ nRule = nIndex;
+ nDistance = nDist;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if ( ( aType == "drawing.OpenBezier" ) || ( aType == "drawing.OpenFreeHand" ) || ( aType == "drawing.PolyLinePath" )
+ || ( aType == "drawing.ClosedBezier" ) || ( aType == "drawing.ClosedFreeHand" ) || ( aType == "drawing.PolyPolygonPath" ) )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
+ aPropertySet2( aXShape, ::com::sun::star::uno::UNO_QUERY );
+ if ( aPropertySet2.is() )
+ {
+ if ( EscherPropertyValueHelper::GetPropertyValue( aAny,
+ aPropertySet2, String( RTL_CONSTASCII_USTRINGPARAM( "PolyPolygonBezier" ) ) ) )
+ {
+ ::com::sun::star::drawing::PolyPolygonBezierCoords* pSourcePolyPolygon =
+ (::com::sun::star::drawing::PolyPolygonBezierCoords*)aAny.getValue();
+ sal_Int32 nOuterSequenceCount = pSourcePolyPolygon->Coordinates.getLength();
+
+ // Zeiger auf innere sequences holen
+ ::com::sun::star::drawing::PointSequence* pOuterSequence =
+ pSourcePolyPolygon->Coordinates.getArray();
+ ::com::sun::star::drawing::FlagSequence* pOuterFlags =
+ pSourcePolyPolygon->Flags.getArray();
+
+ if ( pOuterSequence && pOuterFlags )
+ {
+ sal_Int32 a, b, nIndex = 0;
+ sal_uInt32 nDistance = 0xffffffff;
+
+ for ( a = 0; a < nOuterSequenceCount; a++ )
+ {
+ ::com::sun::star::drawing::PointSequence* pInnerSequence = pOuterSequence++;
+ ::com::sun::star::drawing::FlagSequence* pInnerFlags = pOuterFlags++;
+ if ( pInnerSequence && pInnerFlags )
+ {
+ ::com::sun::star::awt::Point* pArray = pInnerSequence->getArray();
+ ::com::sun::star::drawing::PolygonFlags* pFlags = pInnerFlags->getArray();
+ if ( pArray && pFlags )
+ {
+ for ( b = 0; b < pInnerSequence->getLength(); b++, pArray++ )
+ {
+ PolyFlags ePolyFlags = *( (PolyFlags*)pFlags++ );
+ if ( ePolyFlags == POLY_CONTROL )
+ continue;
+ sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - pArray->X, aRefPoint.Y - pArray->Y );
+ if ( nDist < nDistance )
+ {
+ nRule = nIndex;
+ nDistance = nDist;
+ }
+ nIndex++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ bool bRectangularConnection = true;
+
+ if ( aType == "drawing.Custom" )
+ {
+ SdrObject* pCustoShape( GetSdrObjectFromXShape( aXShape ) );
+ if ( pCustoShape && pCustoShape->ISA( SdrObjCustomShape ) )
+ {
+ SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)(const SdrCustomShapeGeometryItem&)
+ pCustoShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+
+ const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM( "Path" ) );
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM( "GluePointType" ) );
+
+ rtl::OUString sShapeType;
+ uno::Any* pType = rGeometryItem.GetPropertyValueByName( sType );
+ if ( pType )
+ *pType >>= sShapeType;
+ MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
+
+ uno::Any* pGluePointType = ((SdrCustomShapeGeometryItem&)rGeometryItem).GetPropertyValueByName( sPath, sGluePointType );
+
+ sal_Int16 nGluePointType = sal_Int16();
+ if ( !( pGluePointType &&
+ ( *pGluePointType >>= nGluePointType ) ) )
+ nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType );
+
+ if ( nGluePointType == com::sun::star::drawing::EnhancedCustomShapeGluePointType::CUSTOM )
+ {
+ const SdrGluePointList* pList = pCustoShape->GetGluePointList();
+ if ( pList )
+ {
+ Polygon aPoly;
+ USHORT nNum, nAnz = pList->GetCount();
+ if ( nAnz )
+ {
+ for ( nNum = 0; nNum < nAnz; nNum++ )
+ {
+ const SdrGluePoint& rGP = (*pList)[ nNum ];
+ Point aPt( rGP.GetAbsolutePos( *pCustoShape ) );
+ aPoly.Insert( POLY_APPEND, aPt );
+ }
+ nRule = GetClosestPoint( aPoly, aRefPoint );
+ bRectangularConnection = false;
+ }
+ }
+ }
+ else if ( nGluePointType == com::sun::star::drawing::EnhancedCustomShapeGluePointType::SEGMENTS )
+ {
+ SdrObject* pPoly = pCustoShape->DoConvertToPolyObj( TRUE );
+ if ( pPoly && pPoly->ISA( SdrPathObj ) )
+ {
+ sal_Int16 a, b, nIndex = 0;
+ sal_uInt32 nDistance = 0xffffffff;
+
+ // #i74631# use explicit constructor here. Also XPolyPolygon is not necessary,
+ // reducing to PolyPolygon
+ const PolyPolygon aPolyPoly(((SdrPathObj*)pPoly)->GetPathPoly());
+
+ for ( a = 0; a < aPolyPoly.Count(); a++ )
+ {
+ const Polygon& rPoly = aPolyPoly.GetObject( a );
+ for ( b = 0; b < rPoly.GetSize(); b++ )
+ {
+ if ( rPoly.GetFlags( b ) != POLY_NORMAL )
+ continue;
+ const Point& rPt = rPoly[ b ];
+ sal_uInt32 nDist = (sal_uInt32)hypot( aRefPoint.X - rPt.X(), aRefPoint.Y - rPt.Y() );
+ if ( nDist < nDistance )
+ {
+ nRule = nIndex;
+ nDistance = nDist;
+ }
+ nIndex++;
+ }
+ }
+ if ( nDistance != 0xffffffff )
+ bRectangularConnection = false;
+ }
+ }
+ }
+ }
+ if ( bRectangularConnection )
+ {
+ ::com::sun::star::awt::Point aPoint( aXShape->getPosition() );
+ ::com::sun::star::awt::Size aSize( aXShape->getSize() );
+
+ Rectangle aRect( Point( aPoint.X, aPoint.Y ), Size( aSize.Width, aSize.Height ) );
+ Point aCenter( aRect.Center() );
+ Polygon aPoly( 4 );
+
+ aPoly[ 0 ] = Point( aCenter.X(), aRect.Top() );
+ aPoly[ 1 ] = Point( aRect.Left(), aCenter.Y() );
+ aPoly[ 2 ] = Point( aCenter.X(), aRect.Bottom() );
+ aPoly[ 3 ] = Point( aRect.Right(), aCenter.Y() );
+
+ sal_Int32 nAngle = ( EscherPropertyValueHelper::GetPropertyValue( aAny,
+ aPropertySet, String( RTL_CONSTASCII_USTRINGPARAM( "RotateAngle" ) ), sal_True ) )
+ ? *((sal_Int32*)aAny.getValue() )
+ : 0;
+ if ( nAngle )
+ aPoly.Rotate( aRect.TopLeft(), (sal_uInt16)( ( nAngle + 5 ) / 10 ) );
+ nRule = GetClosestPoint( aPoly, aRefPoint );
+
+ if ( aType == "drawing.Ellipse" )
+ nRule <<= 1; // In PPT hat eine Ellipse 8 Möglichkeiten sich zu connecten
+ }
+ }
+ return nRule;
+}
+
+EscherSolverContainer::~EscherSolverContainer()
+{
+ void* pP;
+
+ for( pP = maShapeList.First(); pP; pP = maShapeList.Next() )
+ delete (EscherShapeListEntry*)pP;
+ for( pP = maConnectorList.First(); pP; pP = maConnectorList.Next() )
+ delete (EscherConnectorListEntry*)pP;
+}
+
+void EscherSolverContainer::AddShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape, sal_uInt32 nId )
+{
+ maShapeList.Insert( new EscherShapeListEntry( rXShape, nId ), LIST_APPEND );
+}
+
+void EscherSolverContainer::AddConnector( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConnector,
+ const ::com::sun::star::awt::Point& rPA,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConA,
+ const ::com::sun::star::awt::Point& rPB,
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rConB )
+{
+ maConnectorList.Insert( new EscherConnectorListEntry( rConnector, rPA, rConA, rPB, rConB ), LIST_APPEND );
+}
+
+sal_uInt32 EscherSolverContainer::GetShapeId( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > & rXShape ) const
+{
+ for ( EscherShapeListEntry* pPtr = (EscherShapeListEntry*)((List&)maShapeList).First();
+ pPtr; pPtr = (EscherShapeListEntry*)((List&)maShapeList).Next() )
+ {
+ if ( rXShape == pPtr->aXShape )
+ return ( pPtr->n_EscherId );
+ }
+ return 0;
+}
+
+void EscherSolverContainer::WriteSolver( SvStream& rStrm )
+{
+ sal_uInt32 nCount = maConnectorList.Count();
+ if ( nCount )
+ {
+ sal_uInt32 nRecHdPos, nCurrentPos, nSize;
+ rStrm << (sal_uInt16)( ( nCount << 4 ) | 0xf ) // open an ESCHER_SolverContainer
+ << (sal_uInt16)ESCHER_SolverContainer //
+ << (sal_uInt32)0; //
+
+ nRecHdPos = rStrm.Tell() - 4;
+
+ EscherConnectorRule aConnectorRule;
+ aConnectorRule.nRuleId = 2;
+ for ( EscherConnectorListEntry* pPtr = (EscherConnectorListEntry*)maConnectorList.First();
+ pPtr; pPtr = (EscherConnectorListEntry*)maConnectorList.Next() )
+ {
+ aConnectorRule.ncptiA = aConnectorRule.ncptiB = 0xffffffff;
+ aConnectorRule.nShapeC = GetShapeId( pPtr->mXConnector );
+ aConnectorRule.nShapeA = GetShapeId( pPtr->mXConnectToA );
+ aConnectorRule.nShapeB = GetShapeId( pPtr->mXConnectToB );
+
+ if ( aConnectorRule.nShapeC )
+ {
+ if ( aConnectorRule.nShapeA )
+ aConnectorRule.ncptiA = pPtr->GetConnectorRule( sal_True );
+ if ( aConnectorRule.nShapeB )
+ aConnectorRule.ncptiB = pPtr->GetConnectorRule( sal_False );
+ }
+ rStrm << (sal_uInt32)( ( ESCHER_ConnectorRule << 16 ) | 1 ) // atom hd
+ << (sal_uInt32)24 //
+ << aConnectorRule.nRuleId
+ << aConnectorRule.nShapeA
+ << aConnectorRule.nShapeB
+ << aConnectorRule.nShapeC
+ << aConnectorRule.ncptiA
+ << aConnectorRule.ncptiB;
+
+ aConnectorRule.nRuleId += 2;
+ }
+
+ nCurrentPos = rStrm.Tell(); // close the ESCHER_SolverContainer
+ nSize = ( nCurrentPos - nRecHdPos ) - 4;//
+ rStrm.Seek( nRecHdPos ); //
+ rStrm << nSize; //
+ rStrm.Seek( nCurrentPos ); //
+ }
+}
+
+// ---------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------
+
+EscherEx::EscherEx( SvStream& rOutStrm, UINT32 nDrawings ) :
+ EscherGraphicProvider ( 0 ),
+ mpOutStrm ( &rOutStrm ),
+ mnDrawings ( nDrawings ),
+
+ mnGroupLevel ( 0 ),
+ mnHellLayerId ( USHRT_MAX ),
+
+ mbEscherSpgr ( FALSE ),
+ mbEscherDgg ( FALSE ), // TRUE, wenn jemals ein ESCHER_Dgg angelegt wurde, dieser wird dann im Dest. aktualisiert
+ mbEscherDg ( FALSE ),
+ mbOleEmf ( FALSE )
+{
+ mnStrmStartOfs = mpOutStrm->Tell();
+ mpImplEscherExSdr = new ImplEscherExSdr( *this );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::Flush( SvStream* pPicStreamMergeBSE /* = NULL */ )
+{
+ if ( mbEscherDgg ) // ESCHER_Dgg anpassen
+ {
+ PtReplaceOrInsert( ESCHER_Persist_CurrentPosition, mpOutStrm->Tell() );
+ if ( DoSeek( ESCHER_Persist_Dgg ) )
+ {
+ *mpOutStrm << mnCurrentShapeID << (UINT32)( mnFIDCLs + 1 ) << mnTotalShapesDgg << mnDrawings;
+ }
+ if ( HasGraphics() )
+ {
+ if ( DoSeek( ESCHER_Persist_BlibStoreContainer ) ) // ESCHER_BlibStoreContainer schreiben
+ {
+ sal_uInt32 nAddBytes = GetBlibStoreContainerSize( pPicStreamMergeBSE );
+ if ( nAddBytes )
+ {
+ InsertAtCurrentPos( nAddBytes, TRUE ); // platz schaffen fuer Blib Container samt seinen Blib Atomen
+ WriteBlibStoreContainer( *mpOutStrm, pPicStreamMergeBSE );
+ }
+ }
+ }
+ mpOutStrm->Seek( PtGetOffsetByID( ESCHER_Persist_CurrentPosition ) );
+ }
+}
+
+// ---------------------------------------------------------------------------------------------
+
+EscherEx::~EscherEx()
+{
+ delete mpImplEscherExSdr;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::InsertAtCurrentPos( UINT32 nBytes, BOOL bContainer )
+{
+ UINT32 nSize, nType, nSource, nBufSize, nToCopy, nCurPos = mpOutStrm->Tell();
+ BYTE* pBuf;
+
+ // Persist table anpassen
+ for ( void* pPtr = maPersistTable.First(); pPtr; pPtr = maPersistTable.Next() )
+ {
+ UINT32 nOfs = ((EscherPersistEntry*)pPtr)->mnOffset;
+ if ( nOfs >= nCurPos )
+ ((EscherPersistEntry*)pPtr)->mnOffset += nBytes;
+ }
+
+ // container und atom sizes anpassen
+ mpOutStrm->Seek( mnStrmStartOfs );
+ while ( mpOutStrm->Tell() < nCurPos )
+ {
+ *mpOutStrm >> nType >> nSize;
+ if ( ( mpOutStrm->Tell() + nSize ) >= ( ( bContainer ) ? nCurPos + 1 : nCurPos ) )
+ {
+ mpOutStrm->SeekRel( -4 );
+ *mpOutStrm << (UINT32)( nSize + nBytes );
+ if ( ( nType & 0xf ) != 0xf )
+ mpOutStrm->SeekRel( nSize );
+ }
+ else
+ mpOutStrm->SeekRel( nSize );
+ }
+ std::vector< sal_uInt32 >::iterator aIter( mOffsets.begin() );
+ std::vector< sal_uInt32 >::iterator aEnd( mOffsets.end() );
+ while( aIter != aEnd )
+ {
+ if ( *aIter > nCurPos )
+ *aIter += nBytes;
+ aIter++;
+ }
+ mpOutStrm->Seek( STREAM_SEEK_TO_END );
+ nSource = mpOutStrm->Tell();
+ nToCopy = nSource - nCurPos; // Stream um nBytes vergroessern
+ pBuf = new BYTE[ 0x40000 ]; // 256KB Buffer
+ while ( nToCopy )
+ {
+ nBufSize = ( nToCopy >= 0x40000 ) ? 0x40000 : nToCopy;
+ nToCopy -= nBufSize;
+ nSource -= nBufSize;
+ mpOutStrm->Seek( nSource );
+ mpOutStrm->Read( pBuf, nBufSize );
+ mpOutStrm->Seek( nSource + nBytes );
+ mpOutStrm->Write( pBuf, nBufSize );
+ }
+ delete[] pBuf;
+ mpOutStrm->Seek( nCurPos );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+BOOL EscherEx::SeekBehindRecHeader( UINT16 nRecType )
+{
+ UINT32 nOldPos, nStreamEnd, nType, nSize;
+
+ nOldPos = mpOutStrm->Tell();
+ nStreamEnd = mpOutStrm->Seek( STREAM_SEEK_TO_END );
+ mpOutStrm->Seek( nOldPos );
+ while ( mpOutStrm->Tell() < nStreamEnd )
+ {
+ *mpOutStrm >> nType >> nSize;
+ if ( ( nType >> 16 ) == nRecType )
+ return TRUE;
+ if ( ( nType & 0xf ) != 0xf )
+ mpOutStrm->SeekRel( nSize );
+ }
+ mpOutStrm->Seek( nOldPos );
+ return FALSE;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::InsertPersistOffset( UINT32 nKey, UINT32 nOffset )
+{
+ PtInsert( ESCHER_Persist_PrivateEntry | nKey, nOffset );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+BOOL EscherEx::DoSeek( UINT32 nKey )
+{
+ UINT32 nPos = PtGetOffsetByID( nKey );
+ if ( nPos )
+ mpOutStrm->Seek( nPos );
+ else
+ {
+ if (! PtIsID( nKey ) )
+ return FALSE;
+ mpOutStrm->Seek( 0 );
+ }
+ return TRUE;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+BOOL EscherEx::SeekToPersistOffset( UINT32 nKey )
+{
+ return DoSeek( ESCHER_Persist_PrivateEntry | nKey );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+BOOL EscherEx::InsertAtPersistOffset( UINT32 nKey, UINT32 nValue )
+{
+ UINT32 nOldPos = mpOutStrm->Tell();
+ BOOL bRetValue = SeekToPersistOffset( nKey );
+ if ( bRetValue )
+ {
+ *mpOutStrm << nValue;
+ mpOutStrm->Seek( nOldPos );
+ }
+ return bRetValue;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::OpenContainer( UINT16 nEscherContainer, int nRecInstance )
+{
+ *mpOutStrm << (UINT16)( ( nRecInstance << 4 ) | 0xf ) << nEscherContainer << (UINT32)0;
+ mOffsets.push_back( mpOutStrm->Tell() - 4 );
+ mRecTypes.push_back( nEscherContainer );
+ switch( nEscherContainer )
+ {
+ case ESCHER_DggContainer :
+ {
+ mbEscherDgg = TRUE;
+ mnFIDCLs = mnDrawings;
+ mnCurrentDg = 0;
+ mnCurrentShapeID = 0;
+ mnTotalShapesDgg = 0;
+ mnCurrentShapeMaximumID = 0;
+ AddAtom( 16 + ( mnDrawings << 3 ), ESCHER_Dgg ); // an FDGG and several FIDCLs
+ PtReplaceOrInsert( ESCHER_Persist_Dgg, mpOutStrm->Tell() );
+ *mpOutStrm << (UINT32)0 // the current maximum shape ID
+ << (UINT32)0 // the number of ID clusters + 1
+ << (UINT32)0 // the number of total shapes saved
+ << (UINT32)0; // the total number of drawings saved
+ PtReplaceOrInsert( ESCHER_Persist_Dgg_FIDCL, mpOutStrm->Tell() );
+ for ( UINT32 i = 0; i < mnFIDCLs; i++ ) // Dummy FIDCLs einfuegen
+ {
+ *mpOutStrm << (UINT32)0 << (UINT32)0; // Drawing Nummer, Anzahl der Shapes in diesem IDCL
+ }
+ PtReplaceOrInsert( ESCHER_Persist_BlibStoreContainer, mpOutStrm->Tell() );
+ }
+ break;
+
+ case ESCHER_DgContainer :
+ {
+ if ( mbEscherDgg )
+ {
+ if ( !mbEscherDg )
+ {
+ mbEscherDg = TRUE;
+ mnCurrentDg++;
+ mnTotalShapesDg = 0;
+ mnTotalShapeIdUsedDg = 0;
+ mnCurrentShapeID = ( mnCurrentShapeMaximumID &~0x3ff ) + 0x400; // eine neue Seite bekommt immer eine neue ShapeId die ein vielfaches von 1024 ist,
+ // damit ist erste aktuelle Shape ID 0x400
+ AddAtom( 8, ESCHER_Dg, 0, mnCurrentDg );
+ PtReplaceOrInsert( ESCHER_Persist_Dg | mnCurrentDg, mpOutStrm->Tell() );
+ *mpOutStrm << (UINT32)0 // The number of shapes in this drawing
+ << (UINT32)0; // The last MSOSPID given to an SP in this DG
+ }
+ }
+ }
+ break;
+
+ case ESCHER_SpgrContainer :
+ {
+ if ( mbEscherDg )
+ {
+ mbEscherSpgr = TRUE;
+ }
+ }
+ break;
+
+ case ESCHER_SpContainer :
+ {
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::CloseContainer()
+{
+ sal_uInt32 nSize, nPos = mpOutStrm->Tell();
+ nSize = ( nPos - mOffsets.back() ) - 4;
+ mpOutStrm->Seek( mOffsets.back() );
+ *mpOutStrm << nSize;
+
+ switch( mRecTypes.back() )
+ {
+ case ESCHER_DgContainer :
+ {
+ if ( mbEscherDg )
+ {
+ mbEscherDg = FALSE;
+ if ( DoSeek( ESCHER_Persist_Dg | mnCurrentDg ) )
+ {
+ // shapeanzahl des drawings setzen
+ mnTotalShapesDgg += mnTotalShapesDg;
+ *mpOutStrm << mnTotalShapesDg << mnCurrentShapeMaximumID;
+ if ( DoSeek( ESCHER_Persist_Dgg_FIDCL ) )
+ {
+ if ( mnTotalShapesDg == 0 )
+ {
+ mpOutStrm->SeekRel( 8 );
+ }
+ else
+ {
+ if ( mnTotalShapeIdUsedDg )
+ {
+ // die benutzten Shape Ids des drawings in die fidcls setzen
+ UINT32 i, nFIDCL = ( ( mnTotalShapeIdUsedDg - 1 ) / 0x400 );
+ if ( nFIDCL )
+ {
+ if ( nPos > mpOutStrm->Tell() )
+ nPos += ( nFIDCL << 3 );
+
+ mnFIDCLs += nFIDCL;
+ InsertAtCurrentPos( nFIDCL << 3 ); // platz schaffen fuer weitere FIDCL's
+ }
+ for ( i = 0; i <= nFIDCL; i++ )
+ {
+ *mpOutStrm << mnCurrentDg;
+ if ( i < nFIDCL )
+ *mpOutStrm << (UINT32)0x400;
+ else
+ {
+ UINT32 nShapesLeft = mnTotalShapeIdUsedDg % 0x400;
+ if ( !nShapesLeft )
+ nShapesLeft = 0x400;
+ *mpOutStrm << (UINT32)nShapesLeft;
+ }
+ }
+ }
+ }
+ PtReplaceOrInsert( ESCHER_Persist_Dgg_FIDCL, mpOutStrm->Tell() ); // neuen FIDCL Offset fuer naechste Seite
+ }
+ }
+ }
+ }
+ break;
+
+ case ESCHER_SpgrContainer :
+ {
+ if ( mbEscherSpgr )
+ {
+ mbEscherSpgr = FALSE;
+
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ mOffsets.pop_back();
+ mRecTypes.pop_back();
+ mpOutStrm->Seek( nPos );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::BeginAtom()
+{
+ mnCountOfs = mpOutStrm->Tell();
+ *mpOutStrm << (UINT32)0 << (UINT32)0; // record header wird spaeter geschrieben
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::EndAtom( UINT16 nRecType, int nRecVersion, int nRecInstance )
+{
+ UINT32 nOldPos = mpOutStrm->Tell();
+ mpOutStrm->Seek( mnCountOfs );
+ sal_uInt32 nSize = nOldPos - mnCountOfs;
+ *mpOutStrm << (UINT16)( ( nRecInstance << 4 ) | ( nRecVersion & 0xf ) ) << nRecType << (UINT32)( nSize - 8 );
+ mpOutStrm->Seek( nOldPos );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::AddAtom( UINT32 nAtomSize, UINT16 nRecType, int nRecVersion, int nRecInstance )
+{
+ *mpOutStrm << (UINT16)( ( nRecInstance << 4 ) | ( nRecVersion & 0xf ) ) << nRecType << nAtomSize;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::AddChildAnchor( const Rectangle& rRect )
+{
+ AddAtom( 16, ESCHER_ChildAnchor );
+ GetStream() << (INT32)rRect.Left()
+ << (INT32)rRect.Top()
+ << (INT32)rRect.Right()
+ << (INT32)rRect.Bottom();
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::AddClientAnchor( const Rectangle& rRect )
+{
+ AddAtom( 8, ESCHER_ClientAnchor );
+ *mpOutStrm << (sal_Int16)rRect.Top()
+ << (sal_Int16)rRect.Left()
+ << (sal_Int16)( rRect.GetWidth() + rRect.Left() )
+ << (sal_Int16)( rRect.GetHeight() + rRect.Top() );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+EscherExHostAppData* EscherEx::EnterAdditionalTextGroup()
+{
+ return NULL;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+UINT32 EscherEx::EnterGroup( const String& rShapeName, const Rectangle* pBoundRect )
+{
+ Rectangle aRect;
+ if( pBoundRect )
+ aRect = *pBoundRect;
+
+ OpenContainer( ESCHER_SpgrContainer );
+ OpenContainer( ESCHER_SpContainer );
+ AddAtom( 16, ESCHER_Spgr, 1 );
+ PtReplaceOrInsert( ESCHER_Persist_Grouping_Snap | mnGroupLevel,
+ mpOutStrm->Tell() );
+ *mpOutStrm << (INT32)aRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden
+ << (INT32)aRect.Top()
+ << (INT32)aRect.Right()
+ << (INT32)aRect.Bottom();
+
+ UINT32 nShapeId = GetShapeID();
+ if ( !mnGroupLevel )
+ AddShape( ESCHER_ShpInst_Min, 5, nShapeId ); // Flags: Group | Patriarch
+ else
+ {
+ AddShape( ESCHER_ShpInst_Min, 0x201, nShapeId ); // Flags: Group | HaveAnchor
+ EscherPropertyContainer aPropOpt;
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x00040004 );
+ aPropOpt.AddOpt( ESCHER_Prop_dxWrapDistLeft, 0 );
+ aPropOpt.AddOpt( ESCHER_Prop_dxWrapDistRight, 0 );
+
+ // #i51348# shape name
+ if( rShapeName.Len() > 0 )
+ aPropOpt.AddOpt( ESCHER_Prop_wzName, rShapeName );
+
+ Commit( aPropOpt, aRect );
+ if ( mnGroupLevel > 1 )
+ AddChildAnchor( aRect );
+
+ EscherExHostAppData* pAppData = mpImplEscherExSdr->ImplGetHostData();
+ if( pAppData )
+ {
+ if ( mnGroupLevel <= 1 )
+ pAppData->WriteClientAnchor( *this, aRect );
+ pAppData->WriteClientData( *this );
+ }
+ }
+ CloseContainer(); // ESCHER_SpContainer
+ mnGroupLevel++;
+ return nShapeId;
+}
+
+UINT32 EscherEx::EnterGroup( const Rectangle* pBoundRect )
+{
+ return EnterGroup( String::EmptyString(), pBoundRect );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+BOOL EscherEx::SetGroupSnapRect( UINT32 nGroupLevel, const Rectangle& rRect )
+{
+ BOOL bRetValue = FALSE;
+ if ( nGroupLevel )
+ {
+ UINT32 nCurrentPos = mpOutStrm->Tell();
+ if ( DoSeek( ESCHER_Persist_Grouping_Snap | ( nGroupLevel - 1 ) ) )
+ {
+ *mpOutStrm << (INT32)rRect.Left() // Bounding box fuer die Gruppierten shapes an die sie attached werden
+ << (INT32)rRect.Top()
+ << (INT32)rRect.Right()
+ << (INT32)rRect.Bottom();
+ mpOutStrm->Seek( nCurrentPos );
+ }
+ }
+ return bRetValue;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+BOOL EscherEx::SetGroupLogicRect( UINT32 nGroupLevel, const Rectangle& rRect )
+{
+ BOOL bRetValue = FALSE;
+ if ( nGroupLevel )
+ {
+ UINT32 nCurrentPos = mpOutStrm->Tell();
+ if ( DoSeek( ESCHER_Persist_Grouping_Logic | ( nGroupLevel - 1 ) ) )
+ {
+ *mpOutStrm << (INT16)rRect.Top() << (INT16)rRect.Left() << (INT16)rRect.Right() << (INT16)rRect.Bottom();
+ mpOutStrm->Seek( nCurrentPos );
+ }
+ }
+ return bRetValue;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::LeaveGroup()
+{
+ --mnGroupLevel;
+ PtDelete( ESCHER_Persist_Grouping_Snap | mnGroupLevel );
+ PtDelete( ESCHER_Persist_Grouping_Logic | mnGroupLevel );
+ CloseContainer();
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::AddShape( UINT32 nShpInstance, UINT32 nFlags, UINT32 nShapeID )
+{
+ AddAtom( 8, ESCHER_Sp, 2, nShpInstance );
+
+ if ( !nShapeID )
+ nShapeID = GetShapeID();
+
+ if ( nFlags ^ 1 ) // is this a group shape ?
+ { // if not
+ if ( mnGroupLevel > 1 )
+ nFlags |= 2; // this not a topmost shape
+ }
+ *mpOutStrm << nShapeID << nFlags;
+
+ if ( mbEscherSpgr )
+ mnTotalShapesDg++;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+UINT32 EscherEx::GetShapeID()
+{
+ mnCurrentShapeMaximumID = mnCurrentShapeID; // maximum setzen
+ mnCurrentShapeID++; // mnCurrentShape ID auf nachste freie ID
+ mnTotalShapeIdUsedDg++;
+ return mnCurrentShapeMaximumID;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+void EscherEx::Commit( EscherPropertyContainer& rProps, const Rectangle& )
+{
+ rProps.Commit( GetStream() );
+}
+
+// ---------------------------------------------------------------------------------------------
+
+UINT32 EscherEx::GetColor( const UINT32 nSOColor, BOOL bSwap )
+{
+ if ( bSwap )
+ {
+ UINT32 nColor = nSOColor & 0xff00; // GRUEN
+ nColor |= (BYTE)( nSOColor ) << 16; // ROT
+ nColor |= (BYTE)( nSOColor >> 16 ); // BLAU
+ return nColor;
+ }
+ else
+ return nSOColor & 0xffffff;
+}
+
+// ---------------------------------------------------------------------------------------------
+
+UINT32 EscherEx::GetColor( const Color& rSOColor, BOOL bSwap )
+{
+ UINT32 nColor = ( rSOColor.GetRed() << 16 );
+ nColor |= ( rSOColor.GetGreen() << 8 );
+ nColor |= rSOColor.GetBlue();
+
+ if ( !bSwap )
+ nColor = GetColor( nColor, TRUE );
+
+ return nColor;
+}
+
+// ---------------------------------------------------------------------------------------------
diff --git a/filter/source/msfilter/eschesdo.cxx b/filter/source/msfilter/eschesdo.cxx
new file mode 100644
index 000000000000..d5a60fff9aa9
--- /dev/null
+++ b/filter/source/msfilter/eschesdo.cxx
@@ -0,0 +1,1241 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eschesdo.cxx,v $
+ * $Revision: 1.39 $
+ *
+ * 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_filter.hxx"
+#include "eschesdo.hxx"
+#include <svx/svdobj.hxx>
+#include <svx/unoapi.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/unoshape.hxx>
+#include <vcl/outdev.hxx>
+#include <tools/poly.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/graph.hxx>
+#include <tools/debug.hxx>
+#include <svx/fmdpage.hxx>
+#include <toolkit/unohlp.hxx>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/drawing/FlagSequence.hpp>
+#include <com/sun/star/drawing/TextAdjust.hpp>
+#include <com/sun/star/drawing/LineDash.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/drawing/CircleKind.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <comphelper/extract.hxx>
+#include <svtools/fltcall.hxx>
+#include <vcl/cvtgrf.hxx>
+
+using ::rtl::OUString;
+using namespace ::vos;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::style;
+
+#define EES_MAP_FRACTION 1440 // 1440 dpi
+
+// ===================================================================
+
+ImplEESdrWriter::ImplEESdrWriter( EscherEx& rEx )
+ :
+ mpEscherEx ( &rEx ),
+ maMapModeSrc ( MAP_100TH_MM ),
+ // PowerPoint: 576 dpi, WinWord: 1440 dpi, Excel: 1440 dpi
+ maMapModeDest( MAP_INCH, Point(), Fraction( 1, EES_MAP_FRACTION ), Fraction( 1, EES_MAP_FRACTION ) ),
+// mXStatusIndicator ( rXStatInd ),
+ mpPicStrm ( NULL ),
+ mpHostAppData ( NULL ),
+ mnPagesWritten ( 0 ),
+ mnShapeMasterTitle ( 0 ),
+ mnShapeMasterBody ( 0 ),
+ mbStatusIndicator ( FALSE ),
+ mbStatus ( FALSE )
+{
+}
+
+
+// -------------------------------------------------------------------
+
+Point ImplEESdrWriter::ImplMapPoint( const Point& rPoint )
+{
+ return OutputDevice::LogicToLogic( rPoint, maMapModeSrc, maMapModeDest );
+}
+
+
+// -------------------------------------------------------------------
+
+Size ImplEESdrWriter::ImplMapSize( const Size& rSize )
+{
+ Size aRetSize( OutputDevice::LogicToLogic( rSize, maMapModeSrc, maMapModeDest ) );
+
+ if ( !aRetSize.Width() )
+ aRetSize.Width()++;
+ if ( !aRetSize.Height() )
+ aRetSize.Height()++;
+ return aRetSize;
+}
+
+// -------------------------------------------------------------------
+
+void ImplEESdrWriter::ImplFlipBoundingBox( ImplEESdrObject& rObj, EscherPropertyContainer& rPropOpt )
+{
+ INT32 nAngle = rObj.GetAngle();
+ Rectangle aRect( rObj.GetRect() );
+
+ if ( nAngle < 0 )
+ nAngle = ( 36000 + nAngle ) % 36000;
+ else
+ nAngle = ( 36000 - ( nAngle % 36000 ) );
+
+ double fVal = (double)nAngle * F_PI18000;
+ double fCos = cos( fVal );
+ double fSin = sin( fVal );
+
+ double nWidthHalf = (double) aRect.GetWidth() / 2;
+ double nHeightHalf = (double) aRect.GetHeight() / 2;
+
+ double nXDiff = fCos * nWidthHalf + fSin * (-nHeightHalf);
+ double nYDiff = - ( fSin * nWidthHalf - fCos * ( -nHeightHalf ) );
+
+ aRect.Move( (sal_Int32)( -( nWidthHalf - nXDiff ) ), (sal_Int32)( - ( nHeightHalf + nYDiff ) ) );
+
+ nAngle *= 655;
+ nAngle += 0x8000;
+ nAngle &=~0xffff; // nAngle auf volle Gradzahl runden
+ rPropOpt.AddOpt( ESCHER_Prop_Rotation, nAngle );
+
+ rObj.SetAngle( nAngle );
+ rObj.SetRect( aRect );
+}
+
+// -----------------------------------------------------------------------
+
+#define ADD_SHAPE( nType, nFlags ) \
+{ \
+ nShapeType = nType; \
+ nShapeID = mpEscherEx->GetShapeID(); \
+ rObj.SetShapeId( nShapeID ); \
+ mpEscherEx->AddShape( (UINT32)nType, (UINT32)nFlags, nShapeID ); \
+ rSolverContainer.AddShape( rObj.GetShapeRef(), nShapeID ); \
+}
+
+#define SHAPE_TEXT( bFill ) \
+{ \
+ mpEscherEx->OpenContainer( ESCHER_SpContainer ); \
+ ADD_SHAPE( ESCHER_ShpInst_TextBox, 0xa00 ); \
+ if ( bFill ) \
+ aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True ); \
+ if( rObj.ImplGetText() ) \
+ aPropOpt.CreateTextProperties( rObj.mXPropSet, \
+ mpEscherEx->QueryTextID( rObj.GetShapeRef(), \
+ rObj.GetShapeId() ) ); \
+}
+
+//Map from twips to export units, generally twips as well, only excel and word
+//export is happening here, so native units are export units, leave as
+//placeholder if required in future
+void ImplEESdrWriter::MapRect(ImplEESdrObject& /* rObj */ )
+{
+}
+
+UINT32 ImplEESdrWriter::ImplWriteShape( ImplEESdrObject& rObj,
+ EscherSolverContainer& rSolverContainer,
+ ImplEESdrPageType ePageType )
+{
+ UINT32 nShapeID = 0;
+ UINT16 nShapeType = 0;
+ BOOL bDontWriteText = FALSE; // if a metafile is written as shape replacement, then the text is already part of the metafile
+ BOOL bAdditionalText = FALSE;
+ UINT32 nGrpShapeID = 0;
+
+ do {
+ mpHostAppData = mpEscherEx->StartShape( rObj.GetShapeRef() );
+ if ( mpHostAppData && mpHostAppData->DontWriteShape() )
+ break;
+
+ // #i51348# get shape name
+ String aShapeName;
+ if( const SdrObject* pSdrObj = rObj.GetSdrObject() )
+ if( pSdrObj->GetName().Len() > 0 )
+ aShapeName = pSdrObj->GetName();
+
+ Point aTextRefPoint;
+
+ if( rObj.GetType().EqualsAscii( "drawing.Group" ))
+ {
+ Reference< XIndexAccess > xXIndexAccess( rObj.GetShapeRef(), UNO_QUERY );
+
+ if( xXIndexAccess.is() && 0 != xXIndexAccess->getCount() )
+ {
+ nShapeID = mpEscherEx->EnterGroup( aShapeName, &rObj.GetRect() );
+ nShapeType = ESCHER_ShpInst_Min;
+
+ for( UINT32 n = 0, nCnt = xXIndexAccess->getCount();
+ n < nCnt; ++n )
+ {
+ ImplEESdrObject aObj( *this, *(Reference< XShape >*)
+ xXIndexAccess->getByIndex( n ).getValue() );
+ if( aObj.IsValid() )
+ ImplWriteShape( aObj, rSolverContainer, ePageType );
+ }
+ mpEscherEx->LeaveGroup();
+ }
+ break;
+ }
+ rObj.SetAngle( rObj.ImplGetInt32PropertyValue( ::rtl::OUString::createFromAscii("RotateAngle") ));
+
+ if( ( rObj.ImplGetPropertyValue( ::rtl::OUString::createFromAscii("IsFontwork") ) &&
+ ::cppu::any2bool( rObj.GetUsrAny() ) ) ||
+ rObj.GetType().EqualsAscii( "drawing.Measure" ) || rObj.GetType().EqualsAscii( "drawing.Caption" ) )
+ {
+/*
+ if( rObj.ImplGetPropertyValue( ::rtl::OUString::createFromAscii("BoundRect") ) )
+ {
+ ::com::sun::star::awt::Rectangle aRect( *(::com::sun::star::awt::Rectangle*)rObj.GetUsrAny().getValue() );
+ rObj.SetRect( ImplMapPoint( Point( aRect.X, aRect.Y ) ),
+ ImplMapSize( Size( aRect.Width, aRect.Height ) ) );
+ }
+*/
+ rObj.SetType( String( RTL_CONSTASCII_STRINGPARAM(
+ "drawing.dontknow" ),
+ RTL_TEXTENCODING_MS_1252 ));
+ }
+
+ const ::com::sun::star::awt::Size aSize100thmm( rObj.GetShapeRef()->getSize() );
+ const ::com::sun::star::awt::Point aPoint100thmm( rObj.GetShapeRef()->getPosition() );
+ Rectangle aRect100thmm( Point( aPoint100thmm.X, aPoint100thmm.Y ), Size( aSize100thmm.Width, aSize100thmm.Height ) );
+ if ( !mpPicStrm )
+ mpPicStrm = mpEscherEx->QueryPicStream();
+ EscherPropertyContainer aPropOpt( (EscherGraphicProvider&)*mpEscherEx, mpPicStrm, aRect100thmm );
+
+ // #i51348# shape name
+ if( aShapeName.Len() > 0 )
+ aPropOpt.AddOpt( ESCHER_Prop_wzName, aShapeName );
+
+ if ( rObj.GetType().EqualsAscii( "drawing.Custom" ) )
+ {
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ sal_uInt32 nMirrorFlags;
+
+ rtl::OUString sCustomShapeType;
+ MSO_SPT eShapeType = aPropOpt.GetCustomShapeType( rObj.GetShapeRef(), nMirrorFlags, sCustomShapeType );
+ if ( sCustomShapeType.equalsAscii( "col-502ad400" ) || sCustomShapeType.equalsAscii( "col-60da8460" ) )
+ {
+ ADD_SHAPE( ESCHER_ShpInst_PictureFrame, 0xa00 );
+ if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) )
+ {
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 ); // no fill
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 ); // no linestyle
+ SdrObject* pObj = GetSdrObjectFromXShape( rObj.GetShapeRef() );
+ if ( pObj )
+ {
+ Rectangle aBound = pObj->GetCurrentBoundRect();
+ Point aPosition( ImplMapPoint( aBound.TopLeft() ) );
+ Size aSize( ImplMapSize( aBound.GetSize() ) );
+ rObj.SetRect( Rectangle( aPosition, aSize ) );
+ rObj.SetAngle( 0 );
+ bDontWriteText = sal_True;
+ }
+ }
+ }
+ else
+ {
+ ADD_SHAPE(
+ sal::static_int_cast< UINT16 >(eShapeType),
+ nMirrorFlags | 0xa00 );
+ aPropOpt.CreateCustomShapeProperties( eShapeType, rObj.GetShapeRef() );
+ aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
+ if ( rObj.ImplGetText() )
+ {
+ if ( !aPropOpt.IsFontWork() )
+ aPropOpt.CreateTextProperties( rObj.mXPropSet, mpEscherEx->QueryTextID(
+ rObj.GetShapeRef(), rObj.GetShapeId() ), sal_True, sal_False );
+ }
+ }
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Rectangle" ))
+ {
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ sal_Int32 nRadius = (sal_Int32)rObj.ImplGetInt32PropertyValue(
+ ::rtl::OUString::createFromAscii("CornerRadius"));
+ if( nRadius )
+ {
+ nRadius = ImplMapSize( Size( nRadius, 0 )).Width();
+ ADD_SHAPE( ESCHER_ShpInst_RoundRectangle, 0xa00 ); // Flags: Connector | HasSpt
+ INT32 nLenght = rObj.GetRect().GetWidth();
+ if ( nLenght > rObj.GetRect().GetHeight() )
+ nLenght = rObj.GetRect().GetHeight();
+ nLenght >>= 1;
+ if ( nRadius >= nLenght )
+ nRadius = 0x2a30; // 0x2a30 ist PPTs maximum radius
+ else
+ nRadius = ( 0x2a30 * nRadius ) / nLenght;
+ aPropOpt.AddOpt( ESCHER_Prop_adjustValue, nRadius );
+ }
+ else
+ {
+ ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0xa00 ); // Flags: Connector | HasSpt
+ }
+ aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
+ if( rObj.ImplGetText() )
+ aPropOpt.CreateTextProperties( rObj.mXPropSet,
+ mpEscherEx->QueryTextID( rObj.GetShapeRef(),
+ rObj.GetShapeId() ), sal_False, sal_False );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Ellipse" ))
+ {
+ CircleKind eCircleKind = CircleKind_FULL;
+ PolyStyle ePolyKind = PolyStyle();
+ if ( rObj.ImplGetPropertyValue( ::rtl::OUString::createFromAscii("CircleKind") ) )
+ {
+ eCircleKind = *( (CircleKind*)rObj.GetUsrAny().getValue() );
+ switch ( eCircleKind )
+ {
+ case CircleKind_SECTION :
+ {
+ ePolyKind = POLY_PIE;
+ }
+ break;
+ case CircleKind_ARC :
+ {
+ ePolyKind = POLY_ARC;
+ }
+ break;
+
+ case CircleKind_CUT :
+ {
+ ePolyKind = POLY_CHORD;
+ }
+ break;
+
+ default:
+ eCircleKind = CircleKind_FULL;
+ }
+ }
+ if ( eCircleKind == CircleKind_FULL )
+ {
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_Ellipse, 0xa00 ); // Flags: Connector | HasSpt
+ aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );;
+ }
+ else
+ {
+ INT32 nStartAngle, nEndAngle;
+ if ( !rObj.ImplGetPropertyValue( ::rtl::OUString::createFromAscii("CircleStartAngle") ) )
+ break;
+ nStartAngle = *( (INT32*)rObj.GetUsrAny().getValue() );
+ if( !rObj.ImplGetPropertyValue( ::rtl::OUString::createFromAscii("CircleEndAngle") ) )
+ break;
+ nEndAngle = *( (INT32*)rObj.GetUsrAny().getValue() );
+
+ Point aStart, aEnd, aCenter;
+ aStart.X() = (INT32)( ( cos( (double)( nStartAngle *
+ F_PI18000 ) ) * 100.0 ) );
+ aStart.Y() = - (INT32)( ( sin( (double)( nStartAngle *
+ F_PI18000 ) ) * 100.0 ) );
+ aEnd.X() = (INT32)( ( cos( (double)( nEndAngle *
+ F_PI18000 ) ) * 100.0 ) );
+ aEnd.Y() = - (INT32)( ( sin( (double)( nEndAngle *
+ F_PI18000 ) ) * 100.0 ) );
+ const Rectangle& rRect = aRect100thmm;
+ aCenter.X() = rRect.Left() + ( rRect.GetWidth() / 2 );
+ aCenter.Y() = rRect.Top() + ( rRect.GetHeight() / 2 );
+ aStart.X() += aCenter.X();
+ aStart.Y() += aCenter.Y();
+ aEnd.X() += aCenter.X();
+ aEnd.Y() += aCenter.Y();
+ Polygon aPolygon( rRect, aStart, aEnd, ePolyKind );
+ if( rObj.GetAngle() )
+ {
+ aPolygon.Rotate( rRect.TopLeft(), (sal_uInt16)( rObj.GetAngle() / 10 ) );
+ rObj.SetAngle( 0 );
+ }
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
+ ::com::sun::star::awt::Rectangle aNewRect;
+ switch ( ePolyKind )
+ {
+ case POLY_PIE :
+ case POLY_CHORD :
+ {
+ aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, &aPolygon );
+ aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
+ }
+ break;
+
+ case POLY_ARC :
+ {
+ aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, &aPolygon );
+ aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
+ }
+ break;
+ }
+ rObj.SetRect( Rectangle( ImplMapPoint( Point( aNewRect.X, aNewRect.Y ) ),
+ ImplMapSize( Size( aNewRect.Width, aNewRect.Height ) ) ) );
+ }
+ if ( rObj.ImplGetText() )
+ aPropOpt.CreateTextProperties( rObj.mXPropSet,
+ mpEscherEx->QueryTextID( rObj.GetShapeRef(),
+ rObj.GetShapeId() ), sal_False, sal_False );
+
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Control" ))
+ {
+ break;
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Connector" ))
+ {
+ sal_uInt16 nSpType, nSpFlags;
+ ::com::sun::star::awt::Rectangle aNewRect;
+ if ( aPropOpt.CreateConnectorProperties( rObj.GetShapeRef(),
+ rSolverContainer, aNewRect, nSpType, nSpFlags ) == sal_False )
+ break;
+ rObj.SetRect( Rectangle( ImplMapPoint( Point( aNewRect.X, aNewRect.Y ) ),
+ ImplMapSize( Size( aNewRect.Width, aNewRect.Height ) ) ) );
+
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( nSpType, nSpFlags );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Measure" ))
+ {
+/*
+ if ( ImplGetPropertyValue( L"MeasureKind" ) )
+ {
+ mpEscherEx->EnterGroup( &maRect );
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ImplWriteAny( ANY_FLAGS_LINE, FALSE );
+ UINT32 nFlags = 0xa00; // Flags: Connector | HasSpt
+ if ( maRect.Top() > maRect.Bottom() )
+ nFlags |= 0x80; // Flags: VertMirror
+ if ( maRect.Left() > maRect.Right() )
+ nFlags |= 0x40; // Flags: HorzMirror
+
+ ADD_SHAPE( ESCHER_ShpInst_Line, nFlags );
+ aPropOpt.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
+ aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
+ mpEscherEx->EndCount( ESCHER_OPT, 3 );
+ maRect.Justify();
+ mpEscherEx->AddClientAnchor( maRect );
+ mpEscherEx->CloseContainer(); // ESCHER_SpContainer
+
+ if ( ImplGetPropertyValue( L"MeasureTextHorizontalPosition" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureTextVerticalPosition" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureLineDistance" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureHelpLineOverhang" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureHelpLineDistance" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureHelpLine1Length" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureHelpLine2Length" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureBelowReferenceEdge" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureTextRotate90" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureTextUpsideDown" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureOverhang" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureUnit" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureScale" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureShowUnit" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureFormatString" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureTextAutoAngle" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureTextAutoAngleView" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureTextIsFixedAngle" ) )
+ {
+ }
+ if ( ImplGetPropertyValue( L"MeasureTextFixedAngle" ) )
+ {
+ }
+ mpEscherEx->LeaveGroup();
+ }
+*/
+ break;
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Line" ))
+ {
+ ::com::sun::star::awt::Rectangle aNewRect;
+ aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_LINE, sal_False, aNewRect, NULL );
+ MapRect(rObj);
+ //i27942: Poly/Lines/Bezier do not support text.
+
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ UINT32 nFlags = 0xa00; // Flags: Connector | HasSpt
+ if( aNewRect.Height < 0 )
+ nFlags |= 0x80; // Flags: VertMirror
+ if( aNewRect.Width < 0 )
+ nFlags |= 0x40; // Flags: HorzMirror
+
+ ADD_SHAPE( ESCHER_ShpInst_Line, nFlags );
+ aPropOpt.AddOpt( ESCHER_Prop_shapePath, ESCHER_ShapeComplex );
+ aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
+ rObj.SetAngle( 0 );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.PolyPolygon" ))
+ {
+ if( rObj.ImplHasText() )
+ {
+ nGrpShapeID = ImplEnterAdditionalTextGroup( rObj.GetShapeRef(), &rObj.GetRect() );
+ bAdditionalText = TRUE;
+ }
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
+ ::com::sun::star::awt::Rectangle aNewRect;
+ aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_False, aNewRect, NULL );
+ MapRect(rObj);
+ aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
+ rObj.SetAngle( 0 );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.PolyLine" ))
+ {
+ //i27942: Poly/Lines/Bezier do not support text.
+
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
+ ::com::sun::star::awt::Rectangle aNewRect;
+ aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_False, aNewRect, NULL );
+ MapRect(rObj);
+ aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
+ rObj.SetAngle( 0 );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.OpenBezier" ) )
+ {
+ //i27942: Poly/Lines/Bezier do not support text.
+
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
+ ::com::sun::star::awt::Rectangle aNewRect;
+ aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYLINE, sal_True, aNewRect, NULL );
+ MapRect(rObj);
+ aPropOpt.CreateLineProperties( rObj.mXPropSet, sal_False );
+ rObj.SetAngle( 0 );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.ClosedBezier" ) )
+ {
+ if ( rObj.ImplHasText() )
+ {
+ nGrpShapeID = ImplEnterAdditionalTextGroup( rObj.GetShapeRef(), &rObj.GetRect() );
+ bAdditionalText = TRUE;
+ }
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_NotPrimitive, 0xa00 ); // Flags: Connector | HasSpt
+ ::com::sun::star::awt::Rectangle aNewRect;
+ aPropOpt.CreatePolygonProperties( rObj.mXPropSet, ESCHER_CREATEPOLYGON_POLYPOLYGON, sal_True, aNewRect, NULL );
+ MapRect(rObj);
+ aPropOpt.CreateFillProperties( rObj.mXPropSet, sal_True );
+ rObj.SetAngle( 0 );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.GraphicObject" ))
+ {
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+
+ // ein GraphicObject kann auch ein ClickMe Element sein
+ if( rObj.IsEmptyPresObj() && ( ePageType == NORMAL ) )
+ {
+ ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0x220 ); // Flags: HaveAnchor | HaveMaster
+ UINT32 nTxtBxId = mpEscherEx->QueryTextID( rObj.GetShapeRef(),
+ rObj.GetShapeId() );
+ aPropOpt.AddOpt( ESCHER_Prop_lTxid, nTxtBxId );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 );
+ aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
+ }
+ else
+ {
+ if( rObj.ImplGetText() )
+ {
+ /* SJ #i34951#: because M. documents are not allowing GraphicObjects containing text, we
+ have to create a simpe Rectangle with fill bitmap instead (while not allowing BitmapMode_Repeat).
+ */
+ ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0xa00 ); // Flags: Connector | HasSpt
+ if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), sal_True, sal_True, sal_False ) )
+ {
+ aPropOpt.AddOpt( ESCHER_Prop_WrapText, ESCHER_WrapNone );
+ aPropOpt.AddOpt( ESCHER_Prop_AnchorText, ESCHER_AnchorMiddle );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
+ aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x8000000 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
+ if ( rObj.ImplGetText() )
+ aPropOpt.CreateTextProperties( rObj.mXPropSet,
+ mpEscherEx->QueryTextID( rObj.GetShapeRef(),
+ rObj.GetShapeId() ), sal_False, sal_False );
+ }
+ }
+ else
+ {
+ ADD_SHAPE( ESCHER_ShpInst_PictureFrame, 0xa00 );
+ if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "GraphicURL" ) ), sal_False, sal_True ) )
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
+ }
+ }
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Text" ))
+ {
+ SHAPE_TEXT( TRUE );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Page" ))
+ {
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0xa00 );
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x40004 );
+ aPropOpt.AddOpt( ESCHER_Prop_fFillOK, 0x100001 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x110011 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90008 );
+ aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x10001 );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.Frame" ))
+ {
+ break;
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.OLE2" ))
+ {
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ if( rObj.IsEmptyPresObj() && ( ePageType == NORMAL ) )
+ {
+ ADD_SHAPE( ESCHER_ShpInst_Rectangle, 0x220 ); // Flags: HaveAnchor | HaveMaster
+ UINT32 nTxtBxId = mpEscherEx->QueryTextID( rObj.GetShapeRef(),
+ rObj.GetShapeId() );
+ aPropOpt.AddOpt( ESCHER_Prop_lTxid, nTxtBxId );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x10001 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x10001 );
+ aPropOpt.AddOpt( ESCHER_Prop_hspMaster, mnShapeMasterBody );
+ }
+ else
+ {
+ //2do: could be made an option in HostAppData whether OLE object should be written or not
+ BOOL bAppOLE = TRUE;
+ ADD_SHAPE( ESCHER_ShpInst_PictureFrame,
+ 0xa00 | (bAppOLE ? SHAPEFLAG_OLESHAPE : 0) );
+ if ( aPropOpt.CreateOLEGraphicProperties( rObj.GetShapeRef() ) )
+ {
+ if ( bAppOLE )
+ { // snooped from Xcl hex dump, nobody knows the trouble I have seen
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 );
+ aPropOpt.AddOpt( ESCHER_Prop_pictureId, 0x00000001 );
+ aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000041 );
+ aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000041 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 );
+ aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x08000040 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash,0x00080008 );
+// aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured,0x00020000 );
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080000 );
+ }
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
+ }
+ }
+ }
+ else if( '3' == rObj.GetType().GetChar(8 ) &&
+ 'D' == rObj.GetType().GetChar( 9 ) ) // drawing.3D
+ {
+ // SceneObject, CubeObject, SphereObject, LatheObject, ExtrudeObject, PolygonObject
+ if ( !rObj.ImplGetPropertyValue( ::rtl::OUString::createFromAscii("Bitmap") ) )
+ break;
+
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_PictureFrame, 0xa00 );
+
+ if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "Bitmap" ) ), sal_False ) )
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
+ }
+ else if ( rObj.GetType().EqualsAscii( "drawing.dontknow" ))
+ {
+ rObj.SetAngle( 0 );
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ ADD_SHAPE( ESCHER_ShpInst_PictureFrame, 0xa00 );
+ if ( aPropOpt.CreateGraphicProperties( rObj.mXPropSet, String( RTL_CONSTASCII_USTRINGPARAM( "MetaFile" ) ), sal_False ) )
+ aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x800080 );
+ }
+ else
+ {
+ break;
+ }
+ aPropOpt.CreateShadowProperties( rObj.mXPropSet );
+
+ if( USHRT_MAX != mpEscherEx->GetHellLayerId() &&
+ rObj.ImplGetPropertyValue( ::rtl::OUString::createFromAscii("LayerID") ) &&
+ (*((UINT16*)rObj.GetUsrAny().getValue()) ) == mpEscherEx->GetHellLayerId() )
+ {
+ aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x200020 );
+ }
+
+ {
+ Rectangle aRect( rObj.GetRect() );
+ aRect.Justify();
+ rObj.SetRect( aRect );
+ }
+
+ if( rObj.GetAngle() )
+ ImplFlipBoundingBox( rObj, aPropOpt );
+
+ mpEscherEx->Commit( aPropOpt, rObj.GetRect() );
+ if( mpEscherEx->GetGroupLevel() > 1 )
+ mpEscherEx->AddChildAnchor( rObj.GetRect() );
+
+ if ( mpHostAppData )
+ { //! with AdditionalText the App has to control whether these are written or not
+ mpHostAppData->WriteClientAnchor( *mpEscherEx, rObj.GetRect() );
+ mpHostAppData->WriteClientData( *mpEscherEx );
+ if ( !bDontWriteText )
+ mpHostAppData->WriteClientTextbox( *mpEscherEx );
+ }
+ mpEscherEx->CloseContainer(); // ESCHER_SpContainer
+
+ if( bAdditionalText )
+ {
+ mpEscherEx->EndShape( nShapeType, nShapeID );
+ ImplWriteAdditionalText( rObj, aTextRefPoint );
+ }
+
+ } while ( 0 );
+
+ if ( bAdditionalText )
+ mpEscherEx->EndShape( ESCHER_ShpInst_Min, nGrpShapeID );
+ else
+ mpEscherEx->EndShape( nShapeType, nShapeID );
+ return nShapeID;
+}
+
+void ImplEESdrWriter::ImplWriteAdditionalText( ImplEESdrObject& rObj,
+ const Point& rTextRefPoint )
+{
+ UINT32 nShapeID = 0;
+ UINT16 nShapeType = 0;
+ do
+ {
+ mpHostAppData = mpEscherEx->StartShape( rObj.GetShapeRef() );
+ if ( mpHostAppData && mpHostAppData->DontWriteShape() )
+ break;
+
+ const ::com::sun::star::awt::Size aSize100thmm( rObj.GetShapeRef()->getSize() );
+ const ::com::sun::star::awt::Point aPoint100thmm( rObj.GetShapeRef()->getPosition() );
+ Rectangle aRect100thmm( Point( aPoint100thmm.X, aPoint100thmm.Y ), Size( aSize100thmm.Width, aSize100thmm.Height ) );
+ if ( !mpPicStrm )
+ mpPicStrm = mpEscherEx->QueryPicStream();
+ EscherPropertyContainer aPropOpt( (EscherGraphicProvider&)*mpEscherEx, mpPicStrm, aRect100thmm );
+ rObj.SetAngle( rObj.ImplGetInt32PropertyValue( ::rtl::OUString::createFromAscii("RotateAngle")));
+ INT32 nAngle = rObj.GetAngle();
+ if( rObj.GetType().EqualsAscii( "drawing.Line" ))
+ {
+//2do: this does not work right
+ double fDist = hypot( rObj.GetRect().GetWidth(),
+ rObj.GetRect().GetHeight() );
+ rObj.SetRect( Rectangle( rTextRefPoint,
+ Point( (sal_Int32)( rTextRefPoint.X() + fDist ), rTextRefPoint.Y() - 1 ) ) );
+
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ mpEscherEx->AddShape( ESCHER_ShpInst_TextBox, 0xa00 );
+ if ( rObj.ImplGetText() )
+ aPropOpt.CreateTextProperties( rObj.mXPropSet,
+ mpEscherEx->QueryTextID( rObj.GetShapeRef(),
+ rObj.GetShapeId() ) );
+
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
+ aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x60006 ); // Size Shape To Fit Text
+ if ( nAngle < 0 )
+ nAngle = ( 36000 + nAngle ) % 36000;
+ if ( nAngle )
+ ImplFlipBoundingBox( rObj, aPropOpt );
+ }
+ else
+ {
+ mpEscherEx->OpenContainer( ESCHER_SpContainer );
+ nShapeID = mpEscherEx->GetShapeID();
+ mpEscherEx->AddShape( nShapeType = ESCHER_ShpInst_TextBox, 0xa00, nShapeID );
+ if ( rObj.ImplGetText() )
+ aPropOpt.CreateTextProperties( rObj.mXPropSet,
+ mpEscherEx->QueryTextID( rObj.GetShapeRef(),
+ rObj.GetShapeId() ) );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x90000 );
+ aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
+
+ if( nAngle < 0 )
+ nAngle = ( 36000 + nAngle ) % 36000;
+ else
+ nAngle = ( 36000 - ( nAngle % 36000 ) );
+
+ nAngle *= 655;
+ nAngle += 0x8000;
+ nAngle &=~0xffff; // nAngle auf volle Gradzahl runden
+ aPropOpt.AddOpt( ESCHER_Prop_Rotation, nAngle );
+ mpEscherEx->SetGroupSnapRect( mpEscherEx->GetGroupLevel(),
+ rObj.GetRect() );
+ mpEscherEx->SetGroupLogicRect( mpEscherEx->GetGroupLevel(),
+ rObj.GetRect() );
+ }
+ rObj.SetAngle( nAngle );
+ mpEscherEx->Commit( aPropOpt, rObj.GetRect() );
+
+ // write the childanchor
+ mpEscherEx->AddChildAnchor( rObj.GetRect() );
+
+#if defined EES_WRITE_EPP
+ // ClientAnchor
+ mpEscherEx->AddClientAnchor( maRect );
+ // ClientTextbox
+ mpEscherEx->OpenContainer( ESCHER_ClientTextbox );
+ mpEscherEx->AddAtom( 4, EPP_TextHeaderAtom );
+ *mpStrm << (UINT32)EPP_TEXTTYPE_Other; // Text in a Shape
+ ImplWriteTextStyleAtom();
+ mpEscherEx->CloseContainer(); // ESCHER_ClientTextBox
+#else // !EES_WRITE_EPP
+ if ( mpHostAppData )
+ { //! the App has to control whether these are written or not
+ mpHostAppData->WriteClientAnchor( *mpEscherEx, rObj.GetRect() );
+ mpHostAppData->WriteClientData( *mpEscherEx );
+ mpHostAppData->WriteClientTextbox( *mpEscherEx );
+ }
+#endif // EES_WRITE_EPP
+ mpEscherEx->CloseContainer(); // ESCHER_SpContainer
+ } while ( 0 );
+ mpEscherEx->LeaveGroup();
+ mpEscherEx->EndShape( nShapeType, nShapeID );
+}
+
+
+// -------------------------------------------------------------------
+
+UINT32 ImplEESdrWriter::ImplEnterAdditionalTextGroup( const Reference< XShape >& rShape,
+ const Rectangle* pBoundRect )
+{
+ mpHostAppData = mpEscherEx->EnterAdditionalTextGroup();
+ UINT32 nGrpId = mpEscherEx->EnterGroup( pBoundRect );
+ mpHostAppData = mpEscherEx->StartShape( rShape );
+ return nGrpId;
+}
+
+
+// -------------------------------------------------------------------
+
+BOOL ImplEESdrWriter::ImplInitPageValues()
+{
+ mnIndices = 0;
+ mnOutlinerCount = 0; // die gliederungsobjekte muessen dem layout entsprechen,
+ mnEffectCount = 0;
+ mbIsTitlePossible = TRUE; // bei mehr als einem title geht powerpoint in die knie
+
+ return TRUE;
+}
+
+
+// -------------------------------------------------------------------
+
+void ImplEESdrWriter::ImplWritePage(
+ EscherSolverContainer& rSolverContainer,
+ ImplEESdrPageType ePageType, BOOL /* bBackGround */ )
+{
+ ImplInitPageValues();
+
+ UINT32 nLastPer = 0, nShapes = mXShapes->getCount();
+ for( UINT32 n = 0; n < nShapes; ++n )
+ {
+ UINT32 nPer = ( 5 * n ) / nShapes;
+ if( nPer != nLastPer )
+ {
+ nLastPer = nPer;
+ UINT32 nValue = mnPagesWritten * 5 + nPer;
+ if( nValue > mnStatMaxValue )
+ nValue = mnStatMaxValue;
+ if( mbStatusIndicator )
+ mXStatusIndicator->setValue( nValue );
+ }
+
+ ImplEESdrObject aObj( *this, *(Reference< XShape >*)
+ mXShapes->getByIndex( n ).getValue() );
+ if( aObj.IsValid() )
+ {
+ ImplWriteShape( aObj, rSolverContainer, ePageType );
+ }
+ }
+ mnPagesWritten++;
+}
+
+// ===================================================================
+
+ImplEscherExSdr::ImplEscherExSdr( EscherEx& rEx )
+ :
+ ImplEESdrWriter( rEx ),
+ mpSdrPage( NULL ),
+ mpSolverContainer( NULL )
+{
+}
+
+
+// -------------------------------------------------------------------
+
+ImplEscherExSdr::~ImplEscherExSdr()
+{
+ DBG_ASSERT( !mpSolverContainer, "ImplEscherExSdr::~ImplEscherExSdr: unwritten SolverContainer" );
+ delete mpSolverContainer;
+}
+
+
+// -------------------------------------------------------------------
+
+SvxDrawPage* ImplEscherExSdr::ImplInitPage( const SdrPage& rPage )
+{
+ do
+ {
+ SvxDrawPage* pSvxDrawPage;
+ if ( mpSdrPage != &rPage || !mXDrawPage.is() )
+ {
+ // eventually write SolverContainer of current page, deletes the Solver
+ ImplFlushSolverContainer();
+
+ mpSdrPage = NULL;
+ // why not declare a const parameter if the object will not be modified?
+// mXDrawPage = pSvxDrawPage = new SvxDrawPage( (SdrPage*) &rPage );
+ mXDrawPage = pSvxDrawPage = new SvxFmDrawPage( (SdrPage*) &rPage );
+ mXShapes = Reference< XShapes >::query( mXDrawPage );
+ if ( !mXShapes.is() )
+ break;
+ if ( !ImplInitPageValues() ) // ImplEESdrWriter
+ break;
+ mpSdrPage = &rPage;
+
+ mpSolverContainer = new EscherSolverContainer;
+ }
+ else
+ pSvxDrawPage = SvxDrawPage::getImplementation(mXDrawPage);
+
+ return pSvxDrawPage;
+ } while ( 0 );
+
+ return NULL;
+}
+
+
+// -------------------------------------------------------------------
+
+void ImplEscherExSdr::ImplExitPage()
+{
+ // close all groups before the solver container is written
+ while( mpEscherEx->GetGroupLevel() )
+ mpEscherEx->LeaveGroup();
+
+ ImplFlushSolverContainer();
+ mpSdrPage = NULL; // reset page for next init
+}
+
+
+// -------------------------------------------------------------------
+
+void ImplEscherExSdr::ImplFlushSolverContainer()
+{
+ if ( mpSolverContainer )
+ {
+ mpSolverContainer->WriteSolver( mpEscherEx->GetStream() );
+ delete mpSolverContainer;
+ mpSolverContainer = NULL;
+ }
+}
+
+
+// -------------------------------------------------------------------
+
+void ImplEscherExSdr::ImplWriteCurrentPage()
+{
+ DBG_ASSERT( mpSolverContainer, "ImplEscherExSdr::ImplWriteCurrentPage: no SolverContainer" );
+ ImplWritePage( *mpSolverContainer, NORMAL );
+ ImplExitPage();
+}
+
+
+// -------------------------------------------------------------------
+
+UINT32 ImplEscherExSdr::ImplWriteTheShape( ImplEESdrObject& rObj )
+{
+ DBG_ASSERT( mpSolverContainer, "ImplEscherExSdr::ImplWriteShape: no SolverContainer" );
+ return ImplWriteShape( rObj, *mpSolverContainer, NORMAL );
+}
+
+
+// ===================================================================
+
+void EscherEx::AddSdrPage( const SdrPage& rPage )
+{
+ if ( mpImplEscherExSdr->ImplInitPage( rPage ) )
+ mpImplEscherExSdr->ImplWriteCurrentPage();
+}
+
+
+// -------------------------------------------------------------------
+
+UINT32 EscherEx::AddSdrObject( const SdrObject& rObj )
+{
+ ImplEESdrObject aObj( *mpImplEscherExSdr, rObj );
+ if( aObj.IsValid() )
+ return mpImplEscherExSdr->ImplWriteTheShape( aObj );
+ return 0;
+}
+
+
+// -------------------------------------------------------------------
+
+void EscherEx::EndSdrObjectPage()
+{
+ mpImplEscherExSdr->ImplExitPage();
+}
+
+// -------------------------------------------------------------------
+
+EscherExHostAppData* EscherEx::StartShape( const Reference< XShape >& /* rShape */ )
+{
+ return NULL;
+}
+
+// -------------------------------------------------------------------
+
+void EscherEx::EndShape( UINT16 /* nShapeType */, UINT32 /* nShapeID */ )
+{
+}
+
+// -------------------------------------------------------------------
+
+SvStream* EscherEx::QueryPicStream()
+{
+ return NULL;
+}
+
+// -------------------------------------------------------------------
+
+UINT32 EscherEx::QueryTextID( const Reference< XShape >&, UINT32 )
+{
+ return 0;
+}
+
+// -------------------------------------------------------------------
+// add an dummy rectangle shape into the escher stream
+UINT32 EscherEx::AddDummyShape()
+{
+ OpenContainer( ESCHER_SpContainer );
+ UINT32 nShapeID = GetShapeID();
+ AddShape( ESCHER_ShpInst_Rectangle, 0xa00, nShapeID );
+//?? aSolverContainer.AddShape( mXShape, nShapeID );
+ CloseContainer();
+
+ return nShapeID;
+}
+
+// -------------------------------------------------------------------
+
+// static
+const SdrObject* EscherEx::GetSdrObject( const Reference< XShape >& rShape )
+{
+ const SdrObject* pRet = 0;
+ const SvxShape* pSvxShape = SvxShape::getImplementation( rShape );
+ DBG_ASSERT( pSvxShape, "EscherEx::GetSdrObject: no SvxShape" );
+ if( pSvxShape )
+ {
+ pRet = pSvxShape->GetSdrObject();
+ DBG_ASSERT( pRet, "EscherEx::GetSdrObject: no SdrObj" );
+ }
+ return pRet;
+}
+
+
+// -------------------------------------------------------------------
+
+ImplEESdrObject::ImplEESdrObject( ImplEscherExSdr& rEx,
+ const SdrObject& rObj ) :
+ mnShapeId( 0 ),
+ mnTextSize( 0 ),
+ mnAngle( 0 ),
+ mbValid( FALSE ),
+ mbPresObj( FALSE ),
+ mbEmptyPresObj( FALSE )
+{
+ SdrPage* pPage = rObj.GetPage();
+ DBG_ASSERT( pPage, "ImplEESdrObject::ImplEESdrObject: no SdrPage" );
+ if( pPage )
+ {
+ SvxDrawPage* pSvxDrawPage = rEx.ImplInitPage( *pPage );
+ if( pSvxDrawPage )
+ {
+ // why not declare a const parameter if the object will
+ // not be modified?
+ mXShape = uno::Reference< drawing::XShape >::query( ((SdrObject*)&rObj)->getUnoShape() );;
+ Init( rEx );
+ }
+ }
+}
+
+ImplEESdrObject::ImplEESdrObject( ImplEESdrWriter& rEx,
+ const Reference< XShape >& rShape ) :
+ mXShape( rShape ),
+ mnShapeId( 0 ),
+ mnTextSize( 0 ),
+ mnAngle( 0 ),
+ mbValid( FALSE ),
+ mbPresObj( FALSE ),
+ mbEmptyPresObj( FALSE )
+{
+ Init( rEx );
+}
+
+
+ImplEESdrObject::~ImplEESdrObject()
+{
+}
+
+void ImplEESdrObject::Init( ImplEESdrWriter& rEx )
+{
+ mXPropSet = Reference< XPropertySet >::query( mXShape );
+ if( mXPropSet.is() )
+ {
+ static const sal_Char aPrefix[] = "com.sun.star.";
+ static const xub_StrLen nPrefix = sizeof(aPrefix)-1;
+ SetRect( rEx.ImplMapPoint( Point( mXShape->getPosition().X, mXShape->getPosition().Y ) ),
+ rEx.ImplMapSize( Size( mXShape->getSize().Width, mXShape->getSize().Height ) ) );
+ mType = String( mXShape->getShapeType() );
+ mType.Erase( 0, nPrefix ); // strip "com.sun.star."
+ xub_StrLen nPos = mType.SearchAscii( "Shape" );
+ mType.Erase( nPos, 5 );
+
+ static const OUString sPresStr(rtl::OUString::createFromAscii("IsPresentationObject"));
+ static const OUString sEmptyPresStr(rtl::OUString::createFromAscii("IsEmptyPresentationObject"));
+
+ if( ImplGetPropertyValue( sPresStr ) )
+ mbPresObj = ::cppu::any2bool( mAny );
+
+ if( mbPresObj && ImplGetPropertyValue( sEmptyPresStr ) )
+ mbEmptyPresObj = ::cppu::any2bool( mAny );
+
+ mbValid = TRUE;
+ }
+}
+
+//BOOL ImplEESdrObject::ImplGetPropertyValue( const OUString& rString )
+BOOL ImplEESdrObject::ImplGetPropertyValue( const sal_Unicode* rString )
+{
+ BOOL bRetValue = FALSE;
+ if( mbValid )
+ {
+ try
+ {
+ mAny = mXPropSet->getPropertyValue( rString );
+ if( mAny.hasValue() )
+ bRetValue = TRUE;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ bRetValue = FALSE;
+ }
+ }
+ return bRetValue;
+}
+
+#ifdef USED
+BOOL ImplEESdrObject::ImplGetPropertyValue( const Reference< XPropertySet >& rXPropSet,
+ const OUString& rString )
+{
+ BOOL bRetValue = FALSE;
+ if( mbValid )
+ {
+ try
+ {
+ mAny = rXPropSet->getPropertyValue( rString );
+ if( 0 != mAny.get() )
+ bRetValue = TRUE;
+ }
+ catch( ::com::sun::star::uno::Exception& )
+ {
+ bRetValue = FALSE;
+ }
+ }
+ return bRetValue;
+}
+#endif
+
+void ImplEESdrObject::SetRect( const Point& rPos, const Size& rSz )
+{
+ maRect = Rectangle( rPos, rSz );
+}
+
+const SdrObject* ImplEESdrObject::GetSdrObject() const
+{
+ return EscherEx::GetSdrObject( mXShape );
+}
+
+// laedt und konvertiert text aus shape, ergebnis ist mnTextSize gespeichert
+UINT32 ImplEESdrObject::ImplGetText()
+{
+ Reference< XText > xXText( mXShape, UNO_QUERY );
+ mnTextSize = 0;
+ if( xXText.is() )
+ mnTextSize = xXText->getString().getLength();
+ return mnTextSize;
+}
+
+BOOL ImplEESdrObject::ImplHasText() const
+{
+ Reference< XText > xXText( mXShape, UNO_QUERY );
+ return xXText.is() && xXText->getString().getLength();
+}
+
diff --git a/filter/source/msfilter/eschesdo.hxx b/filter/source/msfilter/eschesdo.hxx
new file mode 100644
index 000000000000..b563d0c57ca7
--- /dev/null
+++ b/filter/source/msfilter/eschesdo.hxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eschesdo.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * 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 _ESCHESDO_HXX
+#define _ESCHESDO_HXX
+#include <filter/msfilter/escherex.hxx>
+#include <svx/unopage.hxx>
+#include <vcl/mapmod.hxx>
+
+// ===================================================================
+// fractions of Draw PPTWriter etc.
+
+enum ImplEESdrPageType { NORMAL = 0, MASTER = 1, NOTICE = 2, UNDEFINED = 3 };
+
+class ImplEESdrWriter;
+class ImplEscherExSdr;
+
+class ImplEESdrObject
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mXShape;
+// XTextRef mXText; // TextRef des globalen Text
+ ::com::sun::star::uno::Any mAny;
+ Rectangle maRect;
+ String mType;
+ UINT32 mnShapeId;
+ UINT32 mnTextSize;
+ INT32 mnAngle;
+ BOOL mbValid : 1;
+ BOOL mbPresObj : 1;
+ BOOL mbEmptyPresObj : 1;
+
+ void Init( ImplEESdrWriter& rEx );
+public:
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > mXPropSet;
+
+ ImplEESdrObject( ImplEscherExSdr& rEx, const SdrObject& rObj );
+ ImplEESdrObject( ImplEESdrWriter& rEx, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rShape );
+ ~ImplEESdrObject();
+
+ BOOL ImplGetPropertyValue( const sal_Unicode* pString );
+
+ INT32 ImplGetInt32PropertyValue( const sal_Unicode* pStr, UINT32 nDef = 0 )
+ { return ImplGetPropertyValue( pStr ) ? *(INT32*)mAny.getValue() : nDef; }
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& GetShapeRef() const { return mXShape; }
+ const ::com::sun::star::uno::Any& GetUsrAny() const { return mAny; }
+ const String& GetType() const { return mType; }
+ void SetType( const String& rS ) { mType = rS; }
+
+ const Rectangle& GetRect() const { return maRect; }
+ void SetRect( const Point& rPos, const Size& rSz );
+ void SetRect( const Rectangle& rRect )
+ { maRect = rRect; }
+
+ INT32 GetAngle() const { return mnAngle; }
+ void SetAngle( INT32 nVal ) { mnAngle = nVal; }
+
+ UINT32 GetTextSize() const { return mnTextSize; }
+
+ BOOL IsValid() const { return mbValid; }
+ BOOL IsPresObj() const { return mbPresObj; }
+ BOOL IsEmptyPresObj() const { return mbEmptyPresObj; }
+ UINT32 GetShapeId() const { return mnShapeId; }
+ void SetShapeId( UINT32 nVal ) { mnShapeId = nVal; }
+
+ const SdrObject* GetSdrObject() const;
+
+ UINT32 ImplGetText();
+ BOOL ImplHasText() const;
+};
+
+
+
+// -------------------------------------------------------------------
+// fractions of the Draw PPTWriter
+
+class EscherEx;
+namespace com { namespace sun { namespace star {
+ namespace drawing {
+ class XDrawPage;
+ class XShape;
+ }
+ namespace task {
+ class XStatusIndicator;
+ }
+}}}
+class EscherExHostAppData;
+class Polygon;
+
+class ImplEESdrWriter
+{
+protected:
+ EscherEx* mpEscherEx;
+ MapMode maMapModeSrc;
+ MapMode maMapModeDest;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator > mXStatusIndicator;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > mXDrawPage;
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > mXShapes;
+
+ SvStream* mpPicStrm;
+
+ // own extensions
+
+ EscherExHostAppData* mpHostAppData;
+
+ UINT32 mnPagesWritten;
+
+ UINT32 mnShapeMasterTitle;
+ UINT32 mnShapeMasterBody;
+
+ // per page values
+ UINT32 mnIndices;
+ UINT32 mnOutlinerCount;
+ UINT32 mnPrevTextStyle;
+ UINT32 mnStatMaxValue;
+
+ UINT16 mnEffectCount;
+
+ BOOL mbIsTitlePossible;
+ BOOL mbStatusIndicator;
+ BOOL mbStatus;
+
+
+ ImplEESdrWriter( EscherEx& rEx );
+
+ BOOL ImplInitPageValues();
+
+ void ImplWritePage(
+ EscherSolverContainer& rSolver,
+ ImplEESdrPageType ePageType,
+ BOOL bBackGround = FALSE );
+
+ UINT32 ImplWriteShape( ImplEESdrObject& rObj,
+ EscherSolverContainer& rSolver,
+ ImplEESdrPageType ePageType ); // returns ShapeID
+
+ void ImplFlipBoundingBox( ImplEESdrObject& rObj, EscherPropertyContainer& rPropOpt );
+ BOOL ImplGetText( ImplEESdrObject& rObj );
+ void ImplWriteAdditionalText(
+ ImplEESdrObject& rObj,
+ const Point& rTextRefPoint );
+ UINT32 ImplEnterAdditionalTextGroup(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rShape,
+ const Rectangle* pBoundRect = NULL );
+
+
+public:
+ Point ImplMapPoint( const Point& rPoint );
+ Size ImplMapSize( const Size& rSize );
+ EscherExHostAppData* ImplGetHostData() { return mpHostAppData; }
+ void MapRect(ImplEESdrObject& rObj);
+};
+
+
+// ===================================================================
+
+class SdrObject;
+class SdrPage;
+
+class ImplEscherExSdr : public ImplEESdrWriter
+{
+private:
+ const SdrPage* mpSdrPage;
+ EscherSolverContainer* mpSolverContainer;
+
+public:
+ ImplEscherExSdr( EscherEx& rEx );
+ virtual ~ImplEscherExSdr();
+
+ SvxDrawPage* ImplInitPage( const SdrPage& rPage );
+ void ImplWriteCurrentPage();
+
+ UINT32 ImplWriteTheShape( ImplEESdrObject& rObj );
+
+ void ImplExitPage();
+ void ImplFlushSolverContainer();
+};
+
+
+
+#endif // _ESCHESDO_HXX
diff --git a/filter/source/msfilter/makefile.mk b/filter/source/msfilter/makefile.mk
new file mode 100644
index 000000000000..69a4fba5f4c4
--- /dev/null
+++ b/filter/source/msfilter/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.17 $
+#
+# 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=filter
+TARGET=msfilter
+ENABLE_EXCEPTIONS=true
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/countryid.obj \
+ $(SLO)$/escherex.obj \
+ $(SLO)$/eschesdo.obj \
+ $(SLO)$/msdffimp.obj \
+ $(SLO)$/msoleexp.obj \
+ $(SLO)$/msvbasic.obj \
+ $(SLO)$/svxmsbas.obj \
+ $(SLO)$/msocximex.obj \
+ $(SLO)$/mscodec.obj \
+ $(SLO)$/msfiltertracer.obj \
+ $(SLO)$/svdfppt.obj \
+ $(SLO)$/svxmsbas2.obj
+
+SHL1TARGET= msfilter$(DLLPOSTFIX)
+SHL1IMPLIB= i$(TARGET)
+SHL1OBJS= $(SLOFILES)
+SHL1USE_EXPORTS=name
+SHL1STDLIBS= \
+ $(SVXCORELIB) \
+ $(SFX2LIB) \
+ $(XMLOFFLIB) \
+ $(GOODIESLIB) \
+ $(BASEGFXLIB) \
+ $(BASICLIB) \
+ $(SVTOOLLIB) \
+ $(TKLIB) \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(SOTLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(XMLSCRIPTLIB) \
+ $(COMPHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+DEF1NAME= $(SHL1TARGET)
+
+.INCLUDE : target.mk
+
+
diff --git a/filter/source/msfilter/makefile.pmk b/filter/source/msfilter/makefile.pmk
new file mode 100644
index 000000000000..48bcd6746271
--- /dev/null
+++ b/filter/source/msfilter/makefile.pmk
@@ -0,0 +1,34 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.pmk,v $
+#
+# $Revision: 1.3 $
+#
+# 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.
+#
+#*************************************************************************
+
+# Reduction of exported symbols:
+CDEFS += -DMSFILTER_DLLIMPLEMENTATION
+VISIBILITY_HIDDEN=TRUE
diff --git a/filter/source/msfilter/mscodec.cxx b/filter/source/msfilter/mscodec.cxx
new file mode 100644
index 000000000000..0c7bb9295290
--- /dev/null
+++ b/filter/source/msfilter/mscodec.cxx
@@ -0,0 +1,537 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mscodec.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * 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_filter.hxx"
+#include "filter/msfilter/mscodec.hxx"
+
+#include <osl/diagnose.h>
+#include <algorithm>
+#include <string.h>
+#include <tools/solar.h>
+
+#define DEBUG_MSO_ENCRYPTION_STD97 0
+
+#if DEBUG_MSO_ENCRYPTION_STD97
+#include <stdio.h>
+#endif
+
+
+namespace msfilter {
+
+// ============================================================================
+
+namespace {
+
+/** Rotates rnValue left by nBits bits. */
+template< typename Type >
+inline void lclRotateLeft( Type& rnValue, int nBits )
+{
+ OSL_ASSERT(
+ nBits >= 0 &&
+ sal::static_int_cast< unsigned int >(nBits) < sizeof( Type ) * 8 );
+ rnValue = static_cast< Type >( (rnValue << nBits) | (rnValue >> (sizeof( Type ) * 8 - nBits)) );
+}
+
+/** Rotates the lower nWidth bits of rnValue left by nBits bits. */
+template< typename Type >
+inline void lclRotateLeft( Type& rnValue, sal_uInt8 nBits, sal_uInt8 nWidth )
+{
+ OSL_ASSERT( (nBits < nWidth) && (nWidth < sizeof( Type ) * 8) );
+ Type nMask = static_cast< Type >( (1UL << nWidth) - 1 );
+ rnValue = static_cast< Type >(
+ ((rnValue << nBits) | ((rnValue & nMask) >> (nWidth - nBits))) & nMask );
+}
+
+sal_Size lclGetLen( const sal_uInt8* pnPassData, sal_Size nBufferSize )
+{
+ sal_Size nLen = 0;
+ while( (nLen < nBufferSize) && pnPassData[ nLen ] ) ++nLen;
+ return nLen;
+}
+
+sal_uInt16 lclGetKey( const sal_uInt8* pnPassData, sal_Size nBufferSize )
+{
+ sal_Size nLen = lclGetLen( pnPassData, nBufferSize );
+ if( !nLen ) return 0;
+
+ sal_uInt16 nKey = 0;
+ sal_uInt16 nKeyBase = 0x8000;
+ sal_uInt16 nKeyEnd = 0xFFFF;
+ const sal_uInt8* pnChar = pnPassData + nLen - 1;
+ for( sal_Size nIndex = 0; nIndex < nLen; ++nIndex, --pnChar )
+ {
+ sal_uInt8 cChar = *pnChar & 0x7F;
+ for( sal_uInt8 nBit = 0; nBit < 8; ++nBit )
+ {
+ lclRotateLeft( nKeyBase, 1 );
+ if( nKeyBase & 1 ) nKeyBase ^= 0x1020;
+ if( cChar & 1 ) nKey ^= nKeyBase;
+ cChar >>= 1;
+ lclRotateLeft( nKeyEnd, 1 );
+ if( nKeyEnd & 1 ) nKeyEnd ^= 0x1020;
+ }
+ }
+ return nKey ^ nKeyEnd;
+}
+
+sal_uInt16 lclGetHash( const sal_uInt8* pnPassData, sal_Size nBufferSize )
+{
+ sal_Size nLen = lclGetLen( pnPassData, nBufferSize );
+
+ sal_uInt16 nHash = static_cast< sal_uInt16 >( nLen );
+ if( nLen )
+ nHash ^= 0xCE4B;
+
+ const sal_uInt8* pnChar = pnPassData;
+ for( sal_Size nIndex = 0; nIndex < nLen; ++nIndex, ++pnChar )
+ {
+ sal_uInt16 cChar = *pnChar;
+ sal_uInt8 nRot = static_cast< sal_uInt8 >( (nIndex + 1) % 15 );
+ lclRotateLeft( cChar, nRot, 15 );
+ nHash ^= cChar;
+ }
+ return nHash;
+}
+
+
+} // namespace
+
+// ============================================================================
+
+MSCodec_Xor95::MSCodec_Xor95(int nRotateDistance) :
+ mnOffset( 0 ),
+ mnKey( 0 ),
+ mnHash( 0 ),
+ mnRotateDistance( nRotateDistance )
+{
+ (void)memset( mpnKey, 0, sizeof( mpnKey ) );
+}
+
+MSCodec_Xor95::~MSCodec_Xor95()
+{
+ (void)memset( mpnKey, 0, sizeof( mpnKey ) );
+ mnKey = mnHash = 0;
+}
+
+void MSCodec_Xor95::InitKey( const sal_uInt8 pnPassData[ 16 ] )
+{
+ mnKey = lclGetKey( pnPassData, 16 );
+ mnHash = lclGetHash( pnPassData, 16 );
+
+ (void)memcpy( mpnKey, pnPassData, 16 );
+
+ static const sal_uInt8 spnFillChars[] =
+ {
+ 0xBB, 0xFF, 0xFF, 0xBA,
+ 0xFF, 0xFF, 0xB9, 0x80,
+ 0x00, 0xBE, 0x0F, 0x00,
+ 0xBF, 0x0F, 0x00
+ };
+
+ sal_Size nIndex;
+ sal_Size nLen = lclGetLen( pnPassData, 16 );
+ const sal_uInt8* pnFillChar = spnFillChars;
+ for( nIndex = nLen; nIndex < sizeof( mpnKey ); ++nIndex, ++pnFillChar )
+ mpnKey[ nIndex ] = *pnFillChar;
+
+ SVBT16 pnOrigKey;
+ ShortToSVBT16( mnKey, pnOrigKey );
+ sal_uInt8* pnKeyChar = mpnKey;
+ for( nIndex = 0; nIndex < sizeof( mpnKey ); ++nIndex, ++pnKeyChar )
+ {
+ *pnKeyChar ^= pnOrigKey[ nIndex & 0x01 ];
+ lclRotateLeft( *pnKeyChar, mnRotateDistance );
+ }
+}
+
+bool MSCodec_Xor95::VerifyKey( sal_uInt16 nKey, sal_uInt16 nHash ) const
+{
+ return (nKey == mnKey) && (nHash == mnHash);
+}
+
+void MSCodec_Xor95::InitCipher()
+{
+ mnOffset = 0;
+}
+
+void MSCodec_XorXLS95::Decode( sal_uInt8* pnData, sal_Size nBytes )
+{
+ const sal_uInt8* pnCurrKey = mpnKey + mnOffset;
+ const sal_uInt8* pnKeyLast = mpnKey + 0x0F;
+
+ for( const sal_uInt8* pnDataEnd = pnData + nBytes; pnData < pnDataEnd; ++pnData )
+ {
+ lclRotateLeft( *pnData, 3 );
+ *pnData ^= *pnCurrKey;
+ if( pnCurrKey < pnKeyLast ) ++pnCurrKey; else pnCurrKey = mpnKey;
+ }
+
+ // update mnOffset
+ Skip( nBytes );
+}
+
+void MSCodec_XorWord95::Decode( sal_uInt8* pnData, sal_Size nBytes )
+{
+ const sal_uInt8* pnCurrKey = mpnKey + mnOffset;
+ const sal_uInt8* pnKeyLast = mpnKey + 0x0F;
+
+ for( const sal_uInt8* pnDataEnd = pnData + nBytes; pnData < pnDataEnd; ++pnData )
+ {
+ const sal_uInt8 cChar = *pnData ^ *pnCurrKey;
+ if (*pnData && cChar)
+ *pnData = cChar;
+ if( pnCurrKey < pnKeyLast ) ++pnCurrKey; else pnCurrKey = mpnKey;
+ }
+
+ // update mnOffset
+ Skip( nBytes );
+}
+
+
+void MSCodec_Xor95::Skip( sal_Size nBytes )
+{
+ mnOffset = (mnOffset + nBytes) & 0x0F;
+}
+
+sal_uInt16 MSCodec_Xor95::GetHash( const sal_uInt8* pnPassData, sal_Size nSize )
+{
+ return lclGetHash( pnPassData, nSize );
+}
+
+// ============================================================================
+
+MSCodec_Std97::MSCodec_Std97 ()
+{
+ m_hCipher = rtl_cipher_create (
+ rtl_Cipher_AlgorithmARCFOUR, rtl_Cipher_ModeStream);
+ OSL_ASSERT(m_hCipher != 0);
+
+ m_hDigest = rtl_digest_create (
+ rtl_Digest_AlgorithmMD5);
+ OSL_ASSERT(m_hDigest != 0);
+
+ (void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue));
+}
+
+MSCodec_Std97::~MSCodec_Std97 ()
+{
+ (void)memset (m_pDigestValue, 0, sizeof(m_pDigestValue));
+ rtl_digest_destroy (m_hDigest);
+ rtl_cipher_destroy (m_hCipher);
+}
+
+#if DEBUG_MSO_ENCRYPTION_STD97
+static void lcl_PrintKeyData(const sal_uInt8* pKeyData, const char* msg)
+{
+ printf("pKeyData: (%s)\n", msg);
+ for (int j = 0; j < 4; ++j)
+ {
+ for (int i = 0; i < 16; ++i)
+ printf("%2.2x ", pKeyData[j*16+i]);
+ printf("\n");
+ }
+}
+#else
+static void lcl_PrintKeyData(const sal_uInt8* /*pKeyData*/, const char* /*msg*/)
+{
+}
+#endif
+
+#if DEBUG_MSO_ENCRYPTION_STD97
+static void lcl_PrintDigest(const sal_uInt8* pDigest, const char* msg)
+{
+ printf("digest: (%s)\n", msg);
+ for (int i = 0; i < 16; ++i)
+ printf("%2.2x ", pDigest[i]);
+ printf("\n");
+}
+#else
+static void lcl_PrintDigest(const sal_uInt8* /*pDigest*/, const char* /*msg*/)
+{
+}
+#endif
+
+void MSCodec_Std97::InitKey (
+ const sal_uInt16 pPassData[16],
+ const sal_uInt8 pUnique[16])
+{
+#if DEBUG_MSO_ENCRYPTION_STD97
+ fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout);
+#endif
+ sal_uInt8 pKeyData[64];
+ int i, n;
+
+ // Fill PassData into KeyData.
+ (void)memset (pKeyData, 0, sizeof(pKeyData));
+ lcl_PrintKeyData(pKeyData, "initial");
+ for (i = 0, n = 16; (i < n) && pPassData[i]; i++)
+ {
+ pKeyData[2*i ] = sal::static_int_cast< sal_uInt8 >(
+ (pPassData[i] >> 0) & 0xff);
+ pKeyData[2*i + 1] = sal::static_int_cast< sal_uInt8 >(
+ (pPassData[i] >> 8) & 0xff);
+ }
+ pKeyData[2*i] = 0x80;
+ pKeyData[ 56] = sal::static_int_cast< sal_uInt8 >(i << 4);
+
+ lcl_PrintKeyData(pKeyData, "password data");
+
+ // Fill raw digest of KeyData into KeyData.
+ (void)rtl_digest_updateMD5 (
+ m_hDigest, pKeyData, sizeof(pKeyData));
+ (void)rtl_digest_rawMD5 (
+ m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5);
+
+ lcl_PrintKeyData(pKeyData, "raw digest of key data");
+
+ // Update digest with KeyData and Unique.
+ for (i = 0; i < 16; i++)
+ {
+ rtl_digest_updateMD5 (m_hDigest, pKeyData, 5);
+ rtl_digest_updateMD5 (m_hDigest, pUnique, 16);
+ }
+
+ // Update digest with padding.
+ pKeyData[16] = 0x80;
+ (void)memset (pKeyData + 17, 0, sizeof(pKeyData) - 17);
+ pKeyData[56] = 0x80;
+ pKeyData[57] = 0x0a;
+
+ lcl_PrintKeyData(pKeyData, "update digest with padding");
+
+ rtl_digest_updateMD5 (
+ m_hDigest, &(pKeyData[16]), sizeof(pKeyData) - 16);
+
+ // Fill raw digest of above updates into DigestValue.
+ rtl_digest_rawMD5 (
+ m_hDigest, m_pDigestValue, sizeof(m_pDigestValue));
+
+ lcl_PrintDigest(m_pDigestValue, "digest value");
+
+ // Erase KeyData array and leave.
+ (void)memset (pKeyData, 0, sizeof(pKeyData));
+}
+
+bool MSCodec_Std97::VerifyKey (
+ const sal_uInt8 pSaltData[16],
+ const sal_uInt8 pSaltDigest[16])
+{
+ // both the salt data and salt digest (hash) come from the document being imported.
+
+#if DEBUG_MSO_ENCRYPTION_STD97
+ fprintf(stdout, "MSCodec_Std97::VerifyKey: \n");
+ lcl_PrintDigest(pSaltData, "salt data");
+ lcl_PrintDigest(pSaltDigest, "salt hash");
+#endif
+ bool result = false;
+
+ if (InitCipher(0))
+ {
+ sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
+ GetDigestFromSalt(pSaltData, pDigest);
+
+ sal_uInt8 pBuffer[16];
+ // Decode original SaltDigest into Buffer.
+ rtl_cipher_decode (
+ m_hCipher, pSaltDigest, 16, pBuffer, sizeof(pBuffer));
+
+ // Compare Buffer with computed Digest.
+ result = (memcmp (pBuffer, pDigest, sizeof(pDigest)) == 0);
+
+ // Erase Buffer and Digest arrays.
+ (void)memset (pBuffer, 0, sizeof(pBuffer));
+ (void)memset (pDigest, 0, sizeof(pDigest));
+ }
+
+ return (result);
+}
+
+bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
+{
+ rtlCipherError result;
+ sal_uInt8 pKeyData[64]; // 512-bit message block
+
+ // Initialize KeyData array.
+ (void)memset (pKeyData, 0, sizeof(pKeyData));
+
+ // Fill 40 bit of DigestValue into [0..4].
+ (void)memcpy (pKeyData, m_pDigestValue, 5);
+
+ // Fill counter into [5..8].
+ pKeyData[ 5] = sal_uInt8((nCounter >> 0) & 0xff);
+ pKeyData[ 6] = sal_uInt8((nCounter >> 8) & 0xff);
+ pKeyData[ 7] = sal_uInt8((nCounter >> 16) & 0xff);
+ pKeyData[ 8] = sal_uInt8((nCounter >> 24) & 0xff);
+
+ pKeyData[ 9] = 0x80;
+ pKeyData[56] = 0x48;
+
+ // Fill raw digest of KeyData into KeyData.
+ (void)rtl_digest_updateMD5 (
+ m_hDigest, pKeyData, sizeof(pKeyData));
+ (void)rtl_digest_rawMD5 (
+ m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5);
+
+ // Initialize Cipher with KeyData (for decoding).
+ result = rtl_cipher_init (
+ m_hCipher, rtl_Cipher_DirectionBoth,
+ pKeyData, RTL_DIGEST_LENGTH_MD5, 0, 0);
+
+ // Erase KeyData array and leave.
+ (void)memset (pKeyData, 0, sizeof(pKeyData));
+
+ return (result == rtl_Cipher_E_None);
+}
+
+bool MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] )
+{
+#if DEBUG_MSO_ENCRYPTION_STD97
+ lcl_PrintDigest(pSaltData, "salt data");
+#endif
+ bool result = false;
+
+ if (InitCipher(0))
+ {
+ sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
+ GetDigestFromSalt(nSaltData, pDigest);
+
+ rtl_cipher_decode (
+ m_hCipher, pDigest, 16, pDigest, sizeof(pDigest));
+
+ (void)memcpy(nSaltDigest, pDigest, 16);
+ }
+
+ return (result);
+}
+
+bool MSCodec_Std97::Encode (
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen)
+{
+ rtlCipherError result;
+
+ result = rtl_cipher_encode (
+ m_hCipher, pData, nDatLen, pBuffer, nBufLen);
+
+ return (result == rtl_Cipher_E_None);
+}
+
+bool MSCodec_Std97::Decode (
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen)
+{
+ rtlCipherError result;
+
+ result = rtl_cipher_decode (
+ m_hCipher, pData, nDatLen, pBuffer, nBufLen);
+
+ return (result == rtl_Cipher_E_None);
+}
+
+bool MSCodec_Std97::Skip( sal_Size nDatLen )
+{
+ sal_uInt8 pnDummy[ 1024 ];
+ sal_Size nDatLeft = nDatLen;
+ bool bResult = true;
+
+ while (bResult && nDatLeft)
+ {
+ sal_Size nBlockLen = ::std::min< sal_Size >( nDatLeft, sizeof(pnDummy) );
+ bResult = Decode( pnDummy, nBlockLen, pnDummy, nBlockLen );
+ nDatLeft -= nBlockLen;
+ }
+
+ return bResult;
+}
+
+void MSCodec_Std97::GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] )
+{
+ sal_uInt8 pBuffer[64];
+ sal_uInt8 pDigestLocal[16];
+
+ // Decode SaltData into Buffer.
+ rtl_cipher_decode (
+ m_hCipher, pSaltData, 16, pBuffer, sizeof(pBuffer));
+
+ // set the 129th bit to make the buffer 128-bit in length.
+ pBuffer[16] = 0x80;
+
+ // erase the rest of the buffer with zeros.
+ (void)memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
+
+ // set the 441st bit.
+ pBuffer[56] = 0x80;
+
+ // Fill raw digest of Buffer into Digest.
+ rtl_digest_updateMD5 (
+ m_hDigest, pBuffer, sizeof(pBuffer));
+ rtl_digest_rawMD5 (
+ m_hDigest, pDigestLocal, sizeof(pDigestLocal));
+
+ memcpy(pDigest, pDigestLocal, 16);
+}
+
+void MSCodec_Std97::GetEncryptKey (
+ const sal_uInt8 pSalt[16],
+ sal_uInt8 pSaltData[16],
+ sal_uInt8 pSaltDigest[16])
+{
+ if (InitCipher(0))
+ {
+ sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
+ sal_uInt8 pBuffer[64];
+
+ rtl_cipher_encode (
+ m_hCipher, pSalt, 16, pSaltData, sizeof(pBuffer));
+
+ (void)memcpy( pBuffer, pSalt, 16 );
+
+ pBuffer[16] = 0x80;
+ (void)memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
+ pBuffer[56] = 0x80;
+
+ rtl_digest_updateMD5 (
+ m_hDigest, pBuffer, sizeof(pBuffer));
+ rtl_digest_rawMD5 (
+ m_hDigest, pDigest, sizeof(pDigest));
+
+ rtl_cipher_encode (
+ m_hCipher, pDigest, 16, pSaltDigest, 16);
+
+ (void)memset (pBuffer, 0, sizeof(pBuffer));
+ (void)memset (pDigest, 0, sizeof(pDigest));
+ }
+}
+
+// ============================================================================
+
+} // namespace svx
+
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
new file mode 100644
index 000000000000..9d98732f1e37
--- /dev/null
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -0,0 +1,8142 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msdffimp.cxx,v $
+ * $Revision: 1.157 $
+ *
+ * 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_filter.hxx"
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+#include <com/sun/star/embed/Aspects.hpp>
+
+#include <math.h>
+#include <limits.h>
+#include <vector>
+#include <osl/endian.h>
+#include <tools/solar.h> // UINTXX
+#include <rtl/math.hxx>
+
+#include <sot/clsids.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <unotools/streamwrap.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sot/exchange.hxx>
+#include <sot/storinfo.hxx>
+#include <vcl/cvtgrf.hxx>
+#include "viscache.hxx"
+
+// SvxItem-Mapping. Wird benoetigt um die SvxItem-Header erfolgreich zu includen
+#include <svx/eeitem.hxx>
+#include <svx/editdata.hxx>
+#include <svl/urihelper.hxx>
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include <tools/zcodec.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <filter/msfilter/escherex.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <com/sun/star/container/XIdentifierContainer.hpp>
+#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
+#include <com/sun/star/drawing/Position3D.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/GluePoint2.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <svx/charscaleitem.hxx>
+#include <svx/kernitem.hxx>
+#include <svtools/filter.hxx>
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/bmpacc.hxx>
+#include <sot/storage.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/module.hxx>
+#include <svx/sdgcpitm.hxx>
+#include <svx/sdgmoitm.hxx>
+#include <svx/tstpitem.hxx>
+#include <svx/fmmodel.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdorect.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdoedge.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/frmdir.hxx>
+#include <svx/frmdiritem.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/sxenditm.hxx>
+#include <svx/sdgluitm.hxx>
+#include <svx/fhgtitem.hxx>
+#include <svx/wghtitem.hxx>
+#include <svx/postitem.hxx>
+#include <svx/udlnitem.hxx>
+#include <svx/crsditem.hxx>
+#include <svx/shdditem.hxx>
+#include <svx/fontitem.hxx>
+#include <svx/colritem.hxx>
+#include <svx/sxekitm.hxx>
+#include <svx/bulitem.hxx>
+#include <svx/polysc3d.hxx>
+#include <svx/extrud3d.hxx>
+#include "svx/svditer.hxx"
+#include <svx/xpoly.hxx>
+#include "svx/xattr.hxx"
+#include "svx/impgrf.hxx"
+#include <filter/msfilter/msdffimp.hxx> // extern sichtbare Header-Datei
+#include <svx/outliner.hxx>
+#include <svx/outlobj.hxx>
+#include <svx/editobj.hxx>
+#include <svx/editeng.hxx>
+#include "svx/gallery.hxx"
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include <svl/itempool.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/svx3ditems.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/sdasaitm.hxx>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <vos/xception.hxx>
+#ifndef _VOS_NO_NAMESPACE
+using namespace vos;
+#endif
+#include "svx/EnhancedCustomShapeTypeNames.hxx"
+#include "svx/EnhancedCustomShapeGeometry.hxx"
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include "svx/EnhancedCustomShape2d.hxx"
+
+using namespace ::com::sun::star ;
+using namespace ::com::sun::star::drawing;
+using namespace uno ;
+using namespace beans ;
+using namespace drawing ;
+using namespace container ;
+
+#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
+
+// static counter for OLE-Objects
+static sal_uInt32 nMSOleObjCntr = 0;
+#define MSO_OLE_Obj "MSO_OLE_Obj"
+
+
+/*************************************************************************/
+BOOL Impl_OlePres::Read( SvStream & rStm )
+{
+ ULONG nBeginPos = rStm.Tell();
+ INT32 n;
+ rStm >> n;
+ if( n != -1 )
+ {
+ pBmp = new Bitmap;
+ rStm >> *pBmp;
+ if( rStm.GetError() == SVSTREAM_OK )
+ {
+ nFormat = FORMAT_BITMAP;
+ aSize = pBmp->GetPrefSize();
+ MapMode aMMSrc;
+ if( !aSize.Width() || !aSize.Height() )
+ {
+ // letzte Chance
+ aSize = pBmp->GetSizePixel();
+ aMMSrc = MAP_PIXEL;
+ }
+ else
+ aMMSrc = pBmp->GetPrefMapMode();
+ MapMode aMMDst( MAP_100TH_MM );
+ aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
+ return TRUE;
+ }
+ else
+ {
+ delete pBmp;
+ pBmp = NULL;
+
+ pMtf = new GDIMetaFile();
+ rStm.ResetError();
+ rStm >> *pMtf;
+ if( rStm.GetError() == SVSTREAM_OK )
+ {
+ nFormat = FORMAT_GDIMETAFILE;
+ aSize = pMtf->GetPrefSize();
+ MapMode aMMSrc = pMtf->GetPrefMapMode();
+ MapMode aMMDst( MAP_100TH_MM );
+ aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
+ return TRUE;
+ }
+ else
+ {
+ delete pMtf;
+ pMtf = NULL;
+ }
+ }
+
+ }
+
+ rStm.ResetError();
+ rStm.Seek( nBeginPos );
+ nFormat = ReadClipboardFormat( rStm );
+ // JobSetup, bzw. TargetDevice ueberlesen
+ // Information aufnehmen, um sie beim Schreiben nicht zu verlieren
+ nJobLen = 0;
+ rStm >> nJobLen;
+ if( nJobLen >= 4 )
+ {
+ nJobLen -= 4;
+ if( nJobLen )
+ {
+ pJob = new BYTE[ nJobLen ];
+ rStm.Read( pJob, nJobLen );
+ }
+ }
+ else
+ {
+ rStm.SetError( SVSTREAM_GENERALERROR );
+ return FALSE;
+ }
+ UINT32 nAsp;
+ rStm >> nAsp;
+ USHORT nSvAsp = USHORT( nAsp );
+ SetAspect( nSvAsp );
+ rStm.SeekRel( 4 ); //L-Index ueberlesen
+ rStm >> nAdvFlags;
+ rStm.SeekRel( 4 ); //Compression
+ UINT32 nWidth = 0;
+ UINT32 nHeight = 0;
+ UINT32 nSize = 0;
+ rStm >> nWidth >> nHeight >> nSize;
+ aSize.Width() = nWidth;
+ aSize.Height() = nHeight;
+
+ if( nFormat == FORMAT_GDIMETAFILE )
+ {
+ pMtf = new GDIMetaFile();
+ ReadWindowMetafile( rStm, *pMtf, NULL );
+ }
+ else if( nFormat == FORMAT_BITMAP )
+ {
+ pBmp = new Bitmap();
+ rStm >> *pBmp;
+ }
+ else
+ {
+ BYTE * p = new BYTE[ nSize ];
+ rStm.Read( p, nSize );
+ delete p;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/************************************************************************/
+void Impl_OlePres::Write( SvStream & rStm )
+{
+ WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE );
+ rStm << (INT32)(nJobLen +4); // immer leeres TargetDevice
+ if( nJobLen )
+ rStm.Write( pJob, nJobLen );
+ rStm << (UINT32)nAspect;
+ rStm << (INT32)-1; //L-Index immer -1
+ rStm << (INT32)nAdvFlags;
+ rStm << (INT32)0; //Compression
+ rStm << (INT32)aSize.Width();
+ rStm << (INT32)aSize.Height();
+ ULONG nPos = rStm.Tell();
+ rStm << (INT32)0;
+
+ if( GetFormat() == FORMAT_GDIMETAFILE && pMtf )
+ {
+ // Immer auf 1/100 mm, bis Mtf-Loesung gefunden
+ // Annahme (keine Skalierung, keine Org-Verschiebung)
+ DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ),
+ "X-Skalierung im Mtf" );
+ DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ),
+ "Y-Skalierung im Mtf" );
+ DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(),
+ "Origin-Verschiebung im Mtf" );
+ MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit();
+ if( MAP_100TH_MM != nMU )
+ {
+ Size aPrefS( pMtf->GetPrefSize() );
+ Size aS( aPrefS );
+ aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM );
+
+ pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ),
+ Fraction( aS.Height(), aPrefS.Height() ) );
+ pMtf->SetPrefMapMode( MAP_100TH_MM );
+ pMtf->SetPrefSize( aS );
+ }
+ WriteWindowMetafileBits( rStm, *pMtf );
+ }
+ else
+ {
+ DBG_ERROR( "unknown format" );
+ }
+ ULONG nEndPos = rStm.Tell();
+ rStm.Seek( nPos );
+ rStm << (UINT32)(nEndPos - nPos - 4);
+ rStm.Seek( nEndPos );
+}
+
+Impl_OlePres * CreateCache_Impl( SotStorage * pStor )
+{
+ SotStorageStreamRef xOleObjStm =pStor->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ),
+ STREAM_READ | STREAM_NOCREATE );
+ if( xOleObjStm->GetError() )
+ return NULL;
+ SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm );
+ if( xOleObjStor->GetError() )
+ return NULL;
+
+ String aStreamName;
+ if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) ) ) )
+ aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) );
+ else if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ) ) )
+ aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) );
+
+ if( aStreamName.Len() == 0 )
+ return NULL;
+
+
+ for( USHORT i = 1; i < 10; i++ )
+ {
+ SotStorageStreamRef xStm = xOleObjStor->OpenSotStream( aStreamName,
+ STREAM_READ | STREAM_NOCREATE );
+ if( xStm->GetError() )
+ break;
+
+ xStm->SetBufferSize( 8192 );
+ Impl_OlePres * pEle = new Impl_OlePres( 0 );
+ if( pEle->Read( *xStm ) && !xStm->GetError() )
+ {
+ if( pEle->GetFormat() == FORMAT_GDIMETAFILE || pEle->GetFormat() == FORMAT_BITMAP )
+ return pEle;
+ }
+ delete pEle;
+ aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres00" ) );
+ aStreamName += String( i );
+ };
+ return NULL;
+}
+
+
+
+//---------------------------------------------------------------------------
+// Hilfs Klassen aus MSDFFDEF.HXX
+//---------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIn, DffRecordHeader& rRec )
+{
+ rRec.nFilePos = rIn.Tell();
+ UINT16 nTmp(0);
+ rIn >> nTmp;
+ rRec.nImpVerInst = nTmp;
+ rRec.nRecVer = sal::static_int_cast< BYTE >(nTmp & 0x000F);
+ rRec.nRecInstance = nTmp >> 4;
+ rIn >> rRec.nRecType;
+ rIn >> rRec.nRecLen;
+ return rIn;
+}
+
+// Masse fuer dashed lines
+#define LLEN_MIDDLE (450)
+#define LLEN_SPACE_MIDDLE (360)
+#define LLEN_LONG (LLEN_MIDDLE * 2)
+#define LLEN_SPACE_LONG (LLEN_SPACE_MIDDLE + 20)
+#define LLEN_POINT (LLEN_MIDDLE / 4)
+#define LLEN_SPACE_POINT (LLEN_SPACE_MIDDLE / 4)
+
+SvStream& operator>>( SvStream& rIn, DffPropSet& rRec )
+{
+ rRec.InitializePropSet();
+
+ DffRecordHeader aHd;
+ rIn >> aHd;
+ UINT32 nPropCount = aHd.nRecInstance;
+
+ // FilePos der ComplexData merken
+ UINT32 nComplexDataFilePos = rIn.Tell() + ( nPropCount * 6 );
+
+ for( UINT32 nPropNum = 0; nPropNum < nPropCount; nPropNum++ )
+ {
+ sal_uInt16 nTmp;
+ sal_uInt32 nRecType, nContent, nContentEx = 0xffff0000;
+ rIn >> nTmp
+ >> nContent;
+
+ nRecType = nTmp & 0x3fff;
+
+ if ( nRecType > 0x3ff )
+ break;
+ if ( ( nRecType & 0x3f ) == 0x3f )
+ { // clear flags that have to be cleared
+ rRec.mpContents[ nRecType ] &= ( ( nContent >> 16 ) ^ 0xffffffff );
+ // set flags that have to be set
+ rRec.mpContents[ nRecType ] |= nContent;
+ nContentEx |= ( nContent >> 16 );
+ rRec.Replace( nRecType, (void*)nContentEx );
+ }
+ else
+ {
+ DffPropFlags aPropFlag = { 1, 0, 0, 0 };
+ if ( nTmp & 0x4000 )
+ aPropFlag.bBlip = sal_True;
+ if ( nTmp & 0x8000 )
+ aPropFlag.bComplex = sal_True;
+ if ( aPropFlag.bComplex && nContent && ( nComplexDataFilePos < aHd.GetRecEndFilePos() ) )
+ {
+ // normally nContent is the complete size of the complex property,
+ // but this is not always true for IMsoArrays ( what the hell is a IMsoArray ? )
+
+ // I love special threatments :-(
+ if ( ( nRecType == DFF_Prop_pVertices ) || ( nRecType == DFF_Prop_pSegmentInfo )
+ || ( nRecType == DFF_Prop_fillShadeColors ) || ( nRecType == DFF_Prop_lineDashStyle )
+ || ( nRecType == DFF_Prop_pWrapPolygonVertices ) || ( nRecType == DFF_Prop_connectorPoints )
+ || ( nRecType == DFF_Prop_Handles ) || ( nRecType == DFF_Prop_pFormulas )
+ || ( nRecType == DFF_Prop_textRectangles ) )
+ {
+ // now check if the current content size is possible, or 6 bytes too small
+ sal_uInt32 nOldPos = rIn.Tell();
+ sal_Int16 nNumElem, nNumElemReserved, nSize;
+
+ rIn.Seek( nComplexDataFilePos );
+ rIn >> nNumElem >> nNumElemReserved >> nSize;
+ if ( nNumElemReserved >= nNumElem )
+ {
+ // the size of these array elements is nowhere defined,
+ // what if the size is negative ?
+ // ok, we will make it positive and shift it.
+ // for -16 this works
+ if ( nSize < 0 )
+ nSize = ( -nSize ) >> 2;
+ sal_uInt32 nDataSize = (sal_uInt32)( nSize * nNumElem );
+
+ // sometimes the content size is 6 bytes too small (array header information is missing )
+ if ( nDataSize == nContent )
+ nContent += 6;
+
+ // check if array fits into the PropertyContainer
+ if ( ( nComplexDataFilePos + nContent ) > aHd.GetRecEndFilePos() )
+ nContent = 0;
+ }
+ else
+ nContent = 0;
+ rIn.Seek( nOldPos );
+ }
+ if ( nContent )
+ {
+ nContentEx = nComplexDataFilePos; // insert the filepos of this property;
+ nComplexDataFilePos += nContent; // store filepos, that is used for the next complex property
+ }
+ else // a complex property needs content
+ aPropFlag.bSet = sal_False; // otherwise something is wrong
+ }
+ rRec.mpContents[ nRecType ] = nContent;
+ rRec.mpFlags[ nRecType ] = aPropFlag;
+ rRec.Insert( nRecType, (void*)nContentEx );
+ }
+ }
+ aHd.SeekToEndOfRecord( rIn );
+ return rIn;
+}
+
+void DffPropSet::InitializePropSet() const
+{
+ /*
+ cmc:
+ " Boolean properties are grouped in bitfields by property set; note that
+ the Boolean properties in each property set are contiguous. They are saved
+ under the property ID of the last Boolean property in the set, and are
+ placed in the value field in reverse order starting with the last property
+ in the low bit. "
+
+ e.g.
+
+ fEditedWrap
+ fBehindDocument
+ fOnDblClickNotify
+ fIsButton
+ fOneD
+ fHidden
+ fPrint
+
+ are all part of a group and all are by default false except for fPrint,
+ which equates to a default bit sequence for the group of 0000001 -> 0x1
+
+ If at a later stage word sets fBehindDocument away from the default it
+ will be done by having a property named fPrint whose bitsequence will have
+ the fBehindDocument bit set. e.g. a DFF_Prop_fPrint with value 0x200020
+ has set bit 6 on so as to enable fBehindDocument (as well as disabling
+ everything else)
+ */
+
+ memset( ( (DffPropSet*) this )->mpFlags, 0, 0x400 * sizeof(DffPropFlags) );
+ ( (DffPropSet*) this )->Clear();
+
+ DffPropFlags nFlags = { 1, 0, 0, 1 };
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_LockAgainstGrouping ] = 0x0000; //0x01ff0000;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_LockAgainstGrouping ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_LockAgainstGrouping, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_FitTextToShape ] = 0x0010; //0x001f0010;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_FitTextToShape ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_FitTextToShape, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_gtextFStrikethrough ] = 0x0000; //0xffff0000;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_gtextFStrikethrough ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_gtextFStrikethrough, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_pictureActive ] = 0x0000; //0x000f0000;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_pictureActive ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_pictureActive, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fFillOK ] = 0x0039; //0x003f0039;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fFillOK ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fFillOK, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoFillHitTest ] = 0x001c; //0x001f001c;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoFillHitTest ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fNoFillHitTest, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoLineDrawDash ] = 0x001e; //0x001f000e;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoLineDrawDash ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fNoLineDrawDash, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fshadowObscured ] = 0x0000; //0x00030000;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fshadowObscured ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fshadowObscured, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fPerspective ] = 0x0000; //0x00010000;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPerspective ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fPerspective, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DLightFace ] = 0x0001; //0x000f0001;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DLightFace ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fc3DLightFace, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DFillHarsh ] = 0x0016; //0x001f0016;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DFillHarsh ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fc3DFillHarsh, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fBackground ] = 0x0000; //0x001f0000;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fBackground ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fBackground, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fCalloutLengthSpecified ] = 0x0010; //0x00ef0010;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fCalloutLengthSpecified ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fCalloutLengthSpecified, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fPrint ] = 0x0001; //0x00ef0001;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPrint ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fPrint, (void*)0xffff0000 );
+
+ ( (DffPropSet*) this )->mpContents[ DFF_Prop_fillColor ] = 0xffffff;
+ ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fillColor ] = nFlags;
+ ( (DffPropSet*) this )->Insert( DFF_Prop_fillColor, (void*)0xffff0000 );
+}
+
+void DffPropSet::Merge( DffPropSet& rMaster ) const
+{
+ for ( void* pDummy = rMaster.First(); pDummy; pDummy = rMaster.Next() )
+ {
+ UINT32 nRecType = rMaster.GetCurKey();
+ if ( ( nRecType & 0x3f ) == 0x3f ) // this is something called FLAGS
+ {
+ UINT32 nCurrentFlags = mpContents[ nRecType ];
+ UINT32 nMergeFlags = rMaster.mpContents[ nRecType ];
+ nMergeFlags &= ( nMergeFlags >> 16 ) | 0xffff0000; // clearing low word
+ nMergeFlags &= ( ( nCurrentFlags & 0xffff0000 ) // remove allready hard set
+ | ( nCurrentFlags >> 16 ) ) ^ 0xffffffff; // attributes from mergeflags
+ nCurrentFlags &= ( ( nMergeFlags & 0xffff0000 ) // apply zero master bits
+ | ( nMergeFlags >> 16 ) ) ^ 0xffffffff;
+ nCurrentFlags |= (UINT16)nMergeFlags; // apply filled master bits
+ ( (DffPropSet*) this )->mpContents[ nRecType ] = nCurrentFlags;
+
+
+ sal_uInt32 nNewContentEx = (sal_uInt32)(sal_uIntPtr)rMaster.GetCurObject();
+ if ( ((DffPropSet*)this)->Seek( nRecType ) )
+ nNewContentEx |= (sal_uInt32)(sal_uIntPtr)GetCurObject();
+ ( (DffPropSet*) this )->Replace( nRecType, (void*)nNewContentEx );
+ }
+ else
+ {
+ if ( !IsProperty( nRecType ) || !IsHardAttribute( nRecType ) )
+ {
+ ( (DffPropSet*) this )->mpContents[ nRecType ] = rMaster.mpContents[ nRecType ];
+ DffPropFlags nFlags( rMaster.mpFlags[ nRecType ] );
+ nFlags.bSoftAttr = TRUE;
+ ( (DffPropSet*) this )->mpFlags[ nRecType ] = nFlags;
+ ( (DffPropSet*) this )->Insert( nRecType, pDummy );
+ }
+ }
+ }
+}
+
+BOOL DffPropSet::IsHardAttribute( UINT32 nId ) const
+{
+ BOOL bRetValue = TRUE;
+ nId &= 0x3ff;
+ if ( ( nId & 0x3f ) >= 48 ) // is this a flag id
+ {
+ if ( ((DffPropSet*)this)->Seek( nId | 0x3f ) )
+ {
+ sal_uInt32 nContentEx = (sal_uInt32)(sal_uIntPtr)GetCurObject();
+ bRetValue = ( nContentEx & ( 1 << ( 0xf - ( nId & 0xf ) ) ) ) != 0;
+ }
+ }
+ else
+ bRetValue = ( mpFlags[ nId ].bSoftAttr == 0 );
+ return bRetValue;
+};
+
+UINT32 DffPropSet::GetPropertyValue( UINT32 nId, UINT32 nDefault ) const
+{
+ nId &= 0x3ff;
+ return ( mpFlags[ nId ].bSet ) ? mpContents[ nId ] : nDefault;
+};
+
+bool DffPropSet::GetPropertyBool( UINT32 nId, bool bDefault ) const
+{
+ UINT32 nBaseId = nId | 31; // base ID to get the UINT32 property value
+ UINT32 nMask = 1 << (nBaseId - nId); // bit mask of the boolean property
+
+ UINT32 nPropValue = GetPropertyValue( nBaseId, bDefault ? nMask : 0 );
+ return (nPropValue & nMask) != 0;
+}
+
+::rtl::OUString DffPropSet::GetPropertyString( UINT32 nId, SvStream& rStrm ) const
+{
+ sal_Size nOldPos = rStrm.Tell();
+ ::rtl::OUStringBuffer aBuffer;
+ sal_uInt32 nBufferSize = GetPropertyValue( nId );
+ if( (nBufferSize > 0) && SeekToContent( nId, rStrm ) )
+ {
+ sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufferSize / 2 );
+ aBuffer.ensureCapacity( nStrLen );
+ for( sal_Int32 nCharIdx = 0; nCharIdx < nStrLen; ++nCharIdx )
+ {
+ sal_uInt16 nChar = 0;
+ rStrm >> nChar;
+ if( nChar > 0 )
+ aBuffer.append( static_cast< sal_Unicode >( nChar ) );
+ else
+ break;
+ }
+ }
+ rStrm.Seek( nOldPos );
+ return aBuffer.makeStringAndClear();
+}
+
+void DffPropSet::SetPropertyValue( UINT32 nId, UINT32 nValue ) const
+{
+ if ( !mpFlags[ nId ].bSet )
+ {
+ ( (DffPropSet*) this )->Insert( nId, (void*)nValue );
+ ( (DffPropSet*) this )->mpFlags[ nId ].bSet = TRUE;
+ }
+ ( (DffPropSet*) this )->mpContents[ nId ] = nValue;
+};
+
+BOOL DffPropSet::SeekToContent( UINT32 nRecType, SvStream& rStrm ) const
+{
+ nRecType &= 0x3ff;
+ if ( mpFlags[ nRecType ].bSet )
+ {
+ if ( mpFlags[ nRecType ].bComplex )
+ {
+ if ( ((DffPropSet*)this)->Seek( nRecType ) )
+ {
+ sal_uInt32 nOffset = (sal_uInt32)(sal_uIntPtr)GetCurObject();
+ if ( nOffset && ( ( nOffset & 0xffff0000 ) != 0xffff0000 ) )
+ {
+ rStrm.Seek( nOffset );
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+DffPropertyReader::DffPropertyReader( const SvxMSDffManager& rMan ) :
+ rManager( rMan ),
+ pDefaultPropSet( NULL )
+{
+ InitializePropSet();
+}
+
+void DffPropertyReader::SetDefaultPropSet( SvStream& rStCtrl, UINT32 nOffsDgg ) const
+{
+ delete pDefaultPropSet;
+ UINT32 nMerk = rStCtrl.Tell();
+ rStCtrl.Seek( nOffsDgg );
+ DffRecordHeader aRecHd;
+ rStCtrl >> aRecHd;
+ if ( aRecHd.nRecType == DFF_msofbtDggContainer )
+ {
+ if ( rManager.SeekToRec( rStCtrl, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
+ {
+ ( (DffPropertyReader*) this )->pDefaultPropSet = new DffPropSet;
+ rStCtrl >> *pDefaultPropSet;
+ }
+ }
+ rStCtrl.Seek( nMerk );
+}
+
+#ifdef DBG_CUSTOMSHAPE
+void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData, UINT32 nShapeId ) const
+#else
+void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData ) const
+#endif
+{
+ ULONG nFilePos = rIn.Tell();
+ rIn >> (DffPropertyReader&)*this;
+
+ if ( IsProperty( DFF_Prop_hspMaster ) )
+ {
+ if ( rManager.SeekToShape( rIn, pClientData, GetPropertyValue( DFF_Prop_hspMaster ) ) )
+ {
+ DffRecordHeader aRecHd;
+ rIn >> aRecHd;
+ if ( rManager.SeekToRec( rIn, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
+ {
+ DffPropSet aMasterPropSet;
+ rIn >> aMasterPropSet;
+ Merge( aMasterPropSet );
+ }
+ }
+ }
+// if ( pDefaultPropSet )
+// Merge( *( pDefaultPropSet ) );
+
+ ( (DffPropertyReader*) this )->mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) );
+
+#ifdef DBG_CUSTOMSHAPE
+
+ String aURLStr;
+
+ if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( String( RTL_CONSTASCII_STRINGPARAM( "d:\\ashape.dbg" ) ), aURLStr ) )
+ {
+ SvStream* pOut = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_WRITE );
+
+ if( pOut )
+ {
+ pOut->Seek( STREAM_SEEK_TO_END );
+
+ if ( IsProperty( DFF_Prop_adjustValue ) || IsProperty( DFF_Prop_pVertices ) )
+ {
+ pOut->WriteLine( "" );
+ ByteString aString( "ShapeId: " );
+ aString.Append( ByteString::CreateFromInt32( nShapeId ) );
+ pOut->WriteLine( aString );
+ }
+ for ( sal_uInt32 i = DFF_Prop_adjustValue; i <= DFF_Prop_adjust10Value; i++ )
+ {
+ if ( IsProperty( i ) )
+ {
+ ByteString aString( "Prop_adjustValue" );
+ aString.Append( ByteString::CreateFromInt32( ( i - DFF_Prop_adjustValue ) + 1 ) );
+ aString.Append( ":" );
+ aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
+ pOut->WriteLine( aString );
+ }
+ }
+ sal_Int32 i;
+ for ( i = 320; i < 383; i++ )
+ {
+ if ( ( i >= DFF_Prop_adjustValue ) && ( i <= DFF_Prop_adjust10Value ) )
+ continue;
+ if ( IsProperty( i ) )
+ {
+ if ( SeekToContent( i, rIn ) )
+ {
+ INT32 nLen = (INT32)GetPropertyValue( i );
+ if ( nLen )
+ {
+ pOut->WriteLine( "" );
+ ByteString aDesc( "Property:" );
+ aDesc.Append( ByteString::CreateFromInt32( i ) );
+ aDesc.Append( ByteString( " Size:" ) );
+ aDesc.Append( ByteString::CreateFromInt32( nLen ) );
+ pOut->WriteLine( aDesc );
+ INT16 nNumElem, nNumElemMem, nNumSize;
+ rIn >> nNumElem >> nNumElemMem >> nNumSize;
+ aDesc = ByteString( "Entries: " );
+ aDesc.Append( ByteString::CreateFromInt32( nNumElem ) );
+ aDesc.Append( ByteString( " Size:" ) );
+ aDesc.Append( ByteString::CreateFromInt32( nNumSize ) );
+ pOut->WriteLine( aDesc );
+ if ( nNumSize < 0 )
+ nNumSize = ( ( -nNumSize ) >> 2 );
+ if ( !nNumSize )
+ nNumSize = 16;
+ nLen -= 6;
+ while ( nLen > 0 )
+ {
+ ByteString aString;
+ for ( UINT32 j = 0; nLen && ( j < ( nNumSize >> 1 ) ); j++ )
+ {
+ for ( UINT32 k = 0; k < 2; k++ )
+ {
+ if ( nLen )
+ {
+ BYTE nVal;
+ rIn >> nVal;
+ if ( ( nVal >> 4 ) > 9 )
+ *pOut << (BYTE)( ( nVal >> 4 ) + 'A' - 10 );
+ else
+ *pOut << (BYTE)( ( nVal >> 4 ) + '0' );
+
+ if ( ( nVal & 0xf ) > 9 )
+ *pOut << (BYTE)( ( nVal & 0xf ) + 'A' - 10 );
+ else
+ *pOut << (BYTE)( ( nVal & 0xf ) + '0' );
+
+ nLen--;
+ }
+ }
+ *pOut << (char)( ' ' );
+ }
+ pOut->WriteLine( aString );
+ }
+ }
+ }
+ else
+ {
+ ByteString aString( "Property" );
+ aString.Append( ByteString::CreateFromInt32( i ) );
+ aString.Append( ":" );
+ aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
+ pOut->WriteLine( aString );
+ }
+ }
+ }
+
+ delete pOut;
+ }
+ }
+
+#endif
+
+ rIn.Seek( nFilePos );
+}
+
+
+INT32 DffPropertyReader::Fix16ToAngle( INT32 nContent ) const
+{
+ INT32 nAngle = 0;
+ if ( nContent )
+ {
+ nAngle = ( (INT16)( nContent >> 16) * 100L ) + ( ( ( nContent & 0x0000ffff) * 100L ) >> 16 );
+ nAngle = NormAngle360( -nAngle );
+ }
+ return nAngle;
+}
+
+DffPropertyReader::~DffPropertyReader()
+{
+ delete pDefaultPropSet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>( SvStream& rIn, SvxMSDffConnectorRule& rRule )
+{
+ rIn >> rRule.nRuleId
+ >> rRule.nShapeA
+ >> rRule.nShapeB
+ >> rRule.nShapeC
+ >> rRule.ncptiA
+ >> rRule.ncptiB;
+
+ return rIn;
+}
+
+SvxMSDffSolverContainer::SvxMSDffSolverContainer()
+{
+}
+
+SvxMSDffSolverContainer::~SvxMSDffSolverContainer()
+{
+ for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)aCList.First();
+ pPtr; pPtr = (SvxMSDffConnectorRule*)aCList.Next() )
+ delete pPtr;
+}
+
+SvStream& operator>>( SvStream& rIn, SvxMSDffSolverContainer& rContainer )
+{
+ DffRecordHeader aHd;
+ rIn >> aHd;
+ if ( aHd.nRecType == DFF_msofbtSolverContainer )
+ {
+ DffRecordHeader aCRule;
+ while ( ( rIn.GetError() == 0 ) && ( rIn.Tell() < aHd.GetRecEndFilePos() ) )
+ {
+ rIn >> aCRule;
+ if ( aCRule.nRecType == DFF_msofbtConnectorRule )
+ {
+ SvxMSDffConnectorRule* pRule = new SvxMSDffConnectorRule;
+ rIn >> *pRule;
+ rContainer.aCList.Insert( pRule, LIST_APPEND );
+ }
+ aCRule.SeekToEndOfRecord( rIn );
+ }
+ }
+ return rIn;
+}
+
+void SvxMSDffManager::SolveSolver( const SvxMSDffSolverContainer& rSolver )
+{
+ sal_Int32 i, nCnt;
+ for ( i = 0, nCnt = rSolver.aCList.Count(); i < nCnt; i++ )
+ {
+ SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)rSolver.aCList.GetObject( i );
+ if ( pPtr->pCObj )
+ {
+ for ( int nN = 0; nN < 2; nN++ )
+ {
+ SdrObject* pO;
+ sal_uInt32 nC, nSpFlags;
+ sal_Bool bTail;
+ if ( !nN )
+ {
+ bTail = sal_True;
+ pO = pPtr->pAObj;
+ nC = pPtr->ncptiA;
+ nSpFlags = pPtr->nSpFlagsA;
+ }
+ else
+ {
+ bTail = sal_False;
+ pO = pPtr->pBObj;
+ nC = pPtr->ncptiB;
+ nSpFlags = pPtr->nSpFlagsB;
+ }
+ if ( pO )
+ {
+ Any aAny;
+ SdrGluePoint aGluePoint;
+ Reference< XShape > aXShape( pO->getUnoShape(), UNO_QUERY );
+ Reference< XShape > aXConnector( pPtr->pCObj->getUnoShape(), UNO_QUERY );
+ SdrGluePointList* pList = pO->ForceGluePointList();
+
+ sal_Bool bValidGluePoint = sal_False;
+ sal_Int32 nId = nC;
+ sal_uInt32 nInventor = pO->GetObjInventor();
+
+ if( nInventor == SdrInventor )
+ {
+ sal_uInt32 nObjId = pO->GetObjIdentifier();
+ switch( nObjId )
+ {
+ case OBJ_GRUP :
+ case OBJ_GRAF :
+ case OBJ_RECT :
+ case OBJ_TEXT :
+ case OBJ_PAGE :
+ case OBJ_TEXTEXT :
+ case OBJ_wegFITTEXT :
+ case OBJ_wegFITALLTEXT :
+ case OBJ_TITLETEXT :
+ case OBJ_OUTLINETEXT :
+ {
+ if ( nC & 1 )
+ {
+ if ( nSpFlags & SP_FFLIPH )
+ nC ^= 2; // 1 <-> 3
+ }
+ else
+ {
+ if ( nSpFlags & SP_FFLIPV )
+ nC ^= 1; // 0 <-> 2
+ }
+ switch( nC )
+ {
+ case 0 :
+ nId = 0; // SDRVERTALIGN_TOP;
+ break;
+ case 1 :
+ nId = 3; // SDRHORZALIGN_RIGHT;
+ break;
+ case 2 :
+ nId = 2; // SDRVERTALIGN_BOTTOM;
+ break;
+ case 3 :
+ nId = 1; // SDRHORZALIGN_LEFT;
+ break;
+ }
+ if ( nId <= 3 )
+ bValidGluePoint = sal_True;
+ }
+ break;
+ case OBJ_POLY :
+ case OBJ_PLIN :
+ case OBJ_LINE :
+ case OBJ_PATHLINE :
+ case OBJ_PATHFILL :
+ case OBJ_FREELINE :
+ case OBJ_FREEFILL :
+ case OBJ_SPLNLINE :
+ case OBJ_SPLNFILL :
+ case OBJ_PATHPOLY :
+ case OBJ_PATHPLIN :
+ {
+ if ( pList && ( pList->GetCount() > nC ) )
+ {
+ bValidGluePoint = sal_True;
+ nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
+ }
+ else
+ {
+ sal_Bool bNotFound = sal_True;
+
+ PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aXShape ) );
+ sal_uInt16 k, j, nPolySize = aPolyPoly.Count();
+ if ( nPolySize )
+ {
+ sal_uInt32 nPointCount = 0;
+ Rectangle aBoundRect( aPolyPoly.GetBoundRect() );
+ if ( aBoundRect.GetWidth() && aBoundRect.GetHeight() )
+ {
+ for ( k = 0; bNotFound && ( k < nPolySize ); k++ )
+ {
+ const Polygon& rPolygon = aPolyPoly.GetObject( k );
+ for ( j = 0; bNotFound && ( j < rPolygon.GetSize() ); j++ )
+ {
+ PolyFlags eFlags = rPolygon.GetFlags( j );
+ if ( eFlags == POLY_NORMAL )
+ {
+ if ( nC == nPointCount )
+ {
+ const Point& rPoint = rPolygon.GetPoint( j );
+ double fXRel = rPoint.X() - aBoundRect.Left();
+ double fYRel = rPoint.Y() - aBoundRect.Top();
+ sal_Int32 nWidth = aBoundRect.GetWidth();
+ if ( !nWidth )
+ nWidth = 1;
+ sal_Int32 nHeight= aBoundRect.GetHeight();
+ if ( !nHeight )
+ nHeight = 1;
+ fXRel /= (double)nWidth;
+ fXRel *= 10000;
+ fYRel /= (double)nHeight;
+ fYRel *= 10000;
+ aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) );
+ aGluePoint.SetPercent( sal_True );
+ aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
+ aGluePoint.SetEscDir( SDRESC_SMART );
+ nId = (sal_Int32)((*pList)[ pList->Insert( aGluePoint ) ].GetId() + 3 );
+ bNotFound = sal_False;
+ }
+ nPointCount++;
+ }
+ }
+ }
+ }
+ }
+ if ( !bNotFound )
+ {
+ bValidGluePoint = sal_True;
+ }
+ }
+ }
+ break;
+
+ case OBJ_CUSTOMSHAPE :
+ {
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pO)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
+ const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
+ sal_Int16 nGluePointType = EnhancedCustomShapeGluePointType::SEGMENTS;
+ com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePointType );
+ if ( pAny )
+ *pAny >>= nGluePointType;
+ else
+ {
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ rtl::OUString sShapeType;
+ pAny = aGeometryItem.GetPropertyValueByName( sType );
+ if ( pAny )
+ *pAny >>= sShapeType;
+ MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
+ nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType );
+ }
+ if ( nGluePointType == EnhancedCustomShapeGluePointType::CUSTOM )
+ {
+ if ( pList && ( pList->GetCount() > nC ) )
+ {
+ bValidGluePoint = sal_True;
+ nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
+ }
+ }
+ else if ( nGluePointType == EnhancedCustomShapeGluePointType::RECT )
+ {
+ if ( nC & 1 )
+ {
+ if ( nSpFlags & SP_FFLIPH )
+ nC ^= 2; // 1 <-> 3
+ }
+ else
+ {
+ if ( nSpFlags & SP_FFLIPV )
+ nC ^= 1; // 0 <-> 2
+ }
+ switch( nC )
+ {
+ case 0 :
+ nId = 0; // SDRVERTALIGN_TOP;
+ break;
+ case 1 :
+ nId = 3; // SDRHORZALIGN_RIGHT;
+ break;
+ case 2 :
+ nId = 2; // SDRVERTALIGN_BOTTOM;
+ break;
+ case 3 :
+ nId = 1; // SDRHORZALIGN_LEFT;
+ break;
+ }
+ if ( nId <= 3 )
+ bValidGluePoint = sal_True;
+ }
+ else if ( nGluePointType == EnhancedCustomShapeGluePointType::SEGMENTS )
+ {
+ const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
+ const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
+
+ sal_uInt32 k, nPt = nC;
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
+ pAny = aGeometryItem.GetPropertyValueByName( sPath, sSegments );
+ if ( pAny )
+ {
+ if ( *pAny >>= aSegments )
+ {
+ for ( nPt = 0, k = 1; nC && ( k < (sal_uInt32)aSegments.getLength() ); k++ )
+ {
+ sal_Int16 j, nCnt2 = aSegments[ k ].Count;
+ if ( aSegments[ k ].Command != EnhancedCustomShapeSegmentCommand::UNKNOWN )
+ {
+ for ( j = 0; nC && ( j < nCnt2 ); j++ )
+ {
+ switch( aSegments[ k ].Command )
+ {
+ case EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
+ case EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
+ case EnhancedCustomShapeSegmentCommand::LINETO :
+ case EnhancedCustomShapeSegmentCommand::MOVETO :
+ {
+ nC--;
+ nPt++;
+ }
+ break;
+ case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
+ case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
+ break;
+
+ case EnhancedCustomShapeSegmentCommand::CURVETO :
+ {
+ nC--;
+ nPt += 3;
+ }
+ break;
+
+ case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
+ case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
+ {
+ nC--;
+ nPt += 3;
+ }
+ break;
+ case EnhancedCustomShapeSegmentCommand::ARCTO :
+ case EnhancedCustomShapeSegmentCommand::ARC :
+ case EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
+ case EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
+ {
+ nC--;
+ nPt += 4;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ pAny = aGeometryItem.GetPropertyValueByName( sPath, sCoordinates );
+ if ( pAny )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
+ *pAny >>= aCoordinates;
+ if ( nPt < (sal_uInt32)aCoordinates.getLength() )
+ {
+ nId = 4;
+ com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPara = aCoordinates[ nPt ];
+ sal_Int32 nX = 0, nY = 0;
+ if ( ( rPara.First.Value >>= nX ) && ( rPara.Second.Value >>= nY ) )
+ {
+ const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
+ pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePoints );
+ if ( pAny )
+ *pAny >>= aGluePoints;
+ sal_Int32 nGluePoints = aGluePoints.getLength();
+ aGluePoints.realloc( nGluePoints + 1 );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].First, nX );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].Second, nY );
+ PropertyValue aProp;
+ aProp.Name = sGluePoints;
+ aProp.Value <<= aGluePoints;
+ aGeometryItem.SetPropertyValue( sPath, aProp );
+ bValidGluePoint = sal_True;
+ ((SdrObjCustomShape*)pO)->SetMergedItem( aGeometryItem );
+ SdrGluePointList* pLst = pO->ForceGluePointList();
+ if ( pLst->GetCount() > nGluePoints )
+ nId = (sal_Int32)((*pLst)[ (sal_uInt16)nGluePoints ].GetId() + 3 );
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ if ( bValidGluePoint )
+ {
+ Reference< XPropertySet > xPropSet( aXConnector, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ if ( nN )
+ {
+ String aPropName( RTL_CONSTASCII_USTRINGPARAM( "EndShape" ) );
+ aAny <<= aXShape;
+ SetPropValue( aAny, xPropSet, aPropName, sal_True );
+ aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "EndGluePointIndex" ) );
+ aAny <<= nId;
+ SetPropValue( aAny, xPropSet, aPropName, sal_True );
+ }
+ else
+ {
+ String aPropName( RTL_CONSTASCII_USTRINGPARAM( "StartShape" ) );
+ aAny <<= aXShape;
+ SetPropValue( aAny, xPropSet, aPropName, sal_True );
+ aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "StartGluePointIndex" ) );
+ aAny <<= nId;
+ SetPropValue( aAny, xPropSet, aPropName, sal_True );
+ }
+
+ // Not sure what this is good for, repaint or broadcast of object change.
+ //( Thus i am adding repaint here
+ pO->SetChanged();
+ pO->BroadcastObjectChange();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static basegfx::B2DPolygon GetLineArrow( const sal_Int32 nLineWidth, const MSO_LineEnd eLineEnd,
+ const MSO_LineEndWidth eLineWidth, const MSO_LineEndLength eLineLenght,
+ sal_Int32& rnArrowWidth, sal_Bool& rbArrowCenter,
+ String& rsArrowName, sal_Bool bScaleArrow )
+{
+ basegfx::B2DPolygon aRetval;
+ double fLineWidth = nLineWidth < 70 ? 70.0 : nLineWidth;
+ double fLenghtMul, fWidthMul;
+ sal_Int32 nLineNumber;
+ switch( eLineLenght )
+ {
+ default :
+ case mso_lineMediumLenArrow : fLenghtMul = 3.0; nLineNumber = 2; break;
+ case mso_lineShortArrow : fLenghtMul = 2.0; nLineNumber = 1; break;
+ case mso_lineLongArrow : fLenghtMul = 5.0; nLineNumber = 3; break;
+ }
+ switch( eLineWidth )
+ {
+ default :
+ case mso_lineMediumWidthArrow : fWidthMul = 3.0; nLineNumber += 3; break;
+ case mso_lineNarrowArrow : fWidthMul = 2.0; break;
+ case mso_lineWideArrow : fWidthMul = 5.0; nLineNumber += 6; break;
+ }
+
+ if ( bScaleArrow ) // #i33630 arrows imported from Word are too big
+ {
+ fWidthMul /= 1.75;
+ fLenghtMul/= 1.75;
+ }
+
+ rbArrowCenter = sal_False;
+ switch ( eLineEnd )
+ {
+ case mso_lineArrowEnd :
+ {
+ basegfx::B2DPolygon aTriangle;
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, 0.0 ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth ));
+ aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
+ aTriangle.setClosed(true);
+ aRetval = aTriangle;
+ rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowEnd " ), RTL_TEXTENCODING_UTF8 );
+ }
+ break;
+
+ case mso_lineArrowOpenEnd :
+ {
+ switch( eLineLenght )
+ {
+ default :
+ case mso_lineMediumLenArrow : fLenghtMul = 4.5; break;
+ case mso_lineShortArrow : fLenghtMul = 3.5; break;
+ case mso_lineLongArrow : fLenghtMul = 6.0; break;
+ }
+ switch( eLineWidth )
+ {
+ default :
+ case mso_lineMediumWidthArrow : fWidthMul = 4.5; break;
+ case mso_lineNarrowArrow : fWidthMul = 3.5; break;
+ case mso_lineWideArrow : fWidthMul = 6.0; break;
+ }
+ basegfx::B2DPolygon aTriangle;
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth * 0.91 ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.85, fLenghtMul * fLineWidth ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, fLenghtMul * fLineWidth * 0.36 ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.15, fLenghtMul * fLineWidth ));
+ aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.91 ));
+ aTriangle.setClosed(true);
+ aRetval = aTriangle;
+ rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOpenEnd " ), RTL_TEXTENCODING_UTF8 );
+ }
+ break;
+ case mso_lineArrowStealthEnd :
+ {
+ basegfx::B2DPolygon aTriangle;
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth * 0.60 ));
+ aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
+ aTriangle.setClosed(true);
+ aRetval = aTriangle;
+ rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowStealthEnd " ), RTL_TEXTENCODING_UTF8 );
+ }
+ break;
+ case mso_lineArrowDiamondEnd :
+ {
+ basegfx::B2DPolygon aTriangle;
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth * 0.50 ));
+ aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth ));
+ aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.50 ));
+ aTriangle.setClosed(true);
+ aRetval = aTriangle;
+ rbArrowCenter = sal_True;
+ rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowDiamondEnd " ), RTL_TEXTENCODING_UTF8 );
+ }
+ break;
+ case mso_lineArrowOvalEnd :
+ {
+ aRetval = XPolygon( Point( (sal_Int32)( fWidthMul * fLineWidth * 0.50 ), 0 ),
+ (sal_Int32)( fWidthMul * fLineWidth * 0.50 ),
+ (sal_Int32)( fLenghtMul * fLineWidth * 0.50 ), 0, 3600 ).getB2DPolygon();
+ rbArrowCenter = sal_True;
+ rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOvalEnd " ), RTL_TEXTENCODING_UTF8 );
+ }
+ break;
+ default: break;
+ }
+ rsArrowName.Append( String::CreateFromInt32( nLineNumber ) );
+ rnArrowWidth = (sal_Int32)( fLineWidth * fWidthMul );
+
+ return aRetval;
+}
+
+void DffPropertyReader::ApplyLineAttributes( SfxItemSet& rSet, const MSO_SPT eShapeType ) const // #i28269#
+{
+ UINT32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
+
+ if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( eShapeType ))
+ {
+ nLineFlags &= ~0x08;
+ }
+
+ if ( nLineFlags & 8 )
+ {
+ // Linienattribute
+ sal_Int32 nLineWidth = (INT32)GetPropertyValue( DFF_Prop_lineWidth, 9525 );
+
+ MSO_LineDashing eLineDashing = (MSO_LineDashing)GetPropertyValue( DFF_Prop_lineDashing, mso_lineSolid );
+ if ( eLineDashing == mso_lineSolid )
+ rSet.Put(XLineStyleItem( XLINE_SOLID ) );
+ else
+ {
+// MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare );
+
+ XDashStyle eDash = XDASH_RECT;
+ sal_uInt16 nDots = 1;
+ sal_uInt32 nDotLen = nLineWidth / 360;
+ sal_uInt16 nDashes = 0;
+ sal_uInt32 nDashLen = ( 8 * nLineWidth ) / 360;
+ sal_uInt32 nDistance = ( 3 * nLineWidth ) / 360;;
+
+ switch ( eLineDashing )
+ {
+ default:
+ case mso_lineDotSys :
+ {
+ nDots = 1;
+ nDashes = 0;
+ nDistance = nDotLen;
+ }
+ break;
+
+ case mso_lineDashGEL :
+ {
+ nDots = 0;
+ nDashes = 1;
+ nDashLen = ( 4 * nLineWidth ) / 360;
+ }
+ break;
+
+ case mso_lineDashDotGEL :
+ {
+ nDots = 1;
+ nDashes = 1;
+ nDashLen = ( 4 * nLineWidth ) / 360;
+ }
+ break;
+
+ case mso_lineLongDashGEL :
+ {
+ nDots = 0;
+ nDashes = 1;
+ }
+ break;
+
+ case mso_lineLongDashDotGEL :
+ {
+ nDots = 1;
+ nDashes = 1;
+ }
+ break;
+
+ case mso_lineLongDashDotDotGEL:
+ {
+ nDots = 2;
+ nDashes = 1;
+ }
+ break;
+ }
+
+ rSet.Put( XLineDashItem( String(), XDash( eDash, nDots, nDotLen, nDashes, nDashLen, nDistance ) ) );
+ rSet.Put( XLineStyleItem( XLINE_DASH ) );
+ }
+ rSet.Put( XLineColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_lineColor ), DFF_Prop_lineColor ) ) );
+ if ( IsProperty( DFF_Prop_lineOpacity ) )
+ {
+ double nTrans = GetPropertyValue(DFF_Prop_lineOpacity, 0x10000);
+ nTrans = (nTrans * 100) / 65536;
+ rSet.Put(XLineTransparenceItem(
+ sal_uInt16(100 - ::rtl::math::round(nTrans))));
+ }
+
+ rManager.ScaleEmu( nLineWidth );
+ rSet.Put( XLineWidthItem( nLineWidth ) );
+
+ // SJ: LineJoint (setting each time a line is set, because our internal joint type has another default)
+ MSO_LineJoin eLineJointDefault = mso_lineJoinMiter;
+ if ( eShapeType == mso_sptMin )
+ eLineJointDefault = mso_lineJoinRound;
+ MSO_LineJoin eLineJoint = (MSO_LineJoin)GetPropertyValue( DFF_Prop_lineJoinStyle, eLineJointDefault );
+ XLineJoint eXLineJoint( XLINEJOINT_MITER );
+ if ( eLineJoint == mso_lineJoinBevel )
+ eXLineJoint = XLINEJOINT_BEVEL;
+ else if ( eLineJoint == mso_lineJoinRound )
+ eXLineJoint = XLINEJOINT_ROUND;
+ rSet.Put( XLineJointItem( eXLineJoint ) );
+
+ if ( nLineFlags & 0x10 )
+ {
+ sal_Bool bScaleArrows = rManager.pSdrModel->GetScaleUnit() == MAP_TWIP;
+ ///////////////
+ // LineStart //
+ ///////////////
+ if ( IsProperty( DFF_Prop_lineStartArrowhead ) )
+ {
+ MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineStartArrowhead );
+ MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineStartArrowWidth, mso_lineMediumWidthArrow );
+ MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineStartArrowLength, mso_lineMediumLenArrow );
+
+ sal_Int32 nArrowWidth;
+ sal_Bool bArrowCenter;
+ String aArrowName;
+ basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
+
+ rSet.Put( XLineStartWidthItem( nArrowWidth ) );
+ rSet.Put( XLineStartItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
+ rSet.Put( XLineStartCenterItem( bArrowCenter ) );
+ }
+ /////////////
+ // LineEnd //
+ /////////////
+ if ( IsProperty( DFF_Prop_lineEndArrowhead ) )
+ {
+ MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineEndArrowhead );
+ MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineEndArrowWidth, mso_lineMediumWidthArrow );
+ MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineEndArrowLength, mso_lineMediumLenArrow );
+
+ sal_Int32 nArrowWidth;
+ sal_Bool bArrowCenter;
+ String aArrowName;
+ basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
+
+ rSet.Put( XLineEndWidthItem( nArrowWidth ) );
+ rSet.Put( XLineEndItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
+ rSet.Put( XLineEndCenterItem( bArrowCenter ) );
+ }
+ if ( IsProperty( DFF_Prop_lineEndCapStyle ) )
+ {
+ MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle );
+ const SfxPoolItem* pPoolItem = NULL;
+ if ( rSet.GetItemState( XATTR_LINEDASH, FALSE, &pPoolItem ) == SFX_ITEM_SET )
+ {
+ XDashStyle eNewStyle = XDASH_RECT;
+ if ( eLineCap == mso_lineEndCapRound )
+ eNewStyle = XDASH_ROUND;
+ const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue();
+ if ( rOldDash.GetDashStyle() != eNewStyle )
+ {
+ XDash aNew( rOldDash );
+ aNew.SetDashStyle( eNewStyle );
+ rSet.Put( XLineDashItem( XubString(), aNew ) );
+ }
+ }
+ }
+ }
+ }
+ else
+ rSet.Put( XLineStyleItem( XLINE_NONE ) );
+}
+
+struct ShadeColor
+{
+ Color aColor;
+ double fDist;
+
+ ShadeColor( const Color& rC, double fR ) : aColor( rC ), fDist( fR ) {};
+};
+
+void GetShadeColors( const SvxMSDffManager& rManager, const DffPropertyReader& rProperties, SvStream& rIn, std::vector< ShadeColor >& rShadeColors )
+{
+ sal_uInt32 nPos = rIn.Tell();
+ if ( rProperties.IsProperty( DFF_Prop_fillShadeColors ) )
+ {
+ if ( rProperties.SeekToContent( DFF_Prop_fillShadeColors, rIn ) )
+ {
+ sal_uInt16 i = 0, nNumElem = 0, nNumElemReserved = 0, nSize = 0;
+ rIn >> nNumElem >> nNumElemReserved >> nSize;
+ for ( ; i < nNumElem; i++ )
+ {
+ sal_Int32 nColor;
+ sal_Int32 nDist;
+
+ rIn >> nColor >> nDist;
+ rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( nColor, DFF_Prop_fillColor ), 1.0 - ( nDist / 65536.0 ) ) );
+ }
+ }
+ }
+ if ( !rShadeColors.size() )
+ {
+ rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ), 0 ) );
+ rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ), 1 ) );
+ }
+ rIn.Seek( nPos );
+}
+
+struct QuantErr
+{
+ double fRed;
+ double fGreen;
+ double fBlue;
+
+ QuantErr() : fRed( 0.0 ), fGreen( 0.0 ), fBlue( 0.0 ){};
+};
+
+void ApplyRectangularGradientAsBitmap( const SvxMSDffManager& rManager, SvStream& rIn, SfxItemSet& rSet, const std::vector< ShadeColor >& rShadeColors, const DffObjData& rObjData, sal_Int32 nFix16Angle )
+{
+ Size aBitmapSizePixel( static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetWidth() / 2540.0 ) * 90.0 ), // we will create a bitmap with 90 dpi
+ static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetHeight() / 2540.0 ) * 90.0 ) );
+ if ( aBitmapSizePixel.Width() && aBitmapSizePixel.Height() && ( aBitmapSizePixel.Width() <= 1024 ) && ( aBitmapSizePixel.Height() <= 1024 ) )
+ {
+// std::vector< QuantErr > aQuantErrCurrScan( aBitmapSizePixel.Width() + 1 );
+// std::vector< QuantErr > aQuantErrNextScan( aBitmapSizePixel.Width() + 1 );
+
+ double fFocusX = rManager.GetPropertyValue( DFF_Prop_fillToRight, 0 ) / 65536.0;
+ double fFocusY = rManager.GetPropertyValue( DFF_Prop_fillToBottom, 0 ) / 65536.0;
+
+ Bitmap aBitmap( aBitmapSizePixel, 24 );
+ BitmapWriteAccess* pAcc = aBitmap.AcquireWriteAccess();
+ if ( pAcc )
+ {
+ sal_Int32 nX, nY;
+ for ( nY = 0; nY < aBitmapSizePixel.Height(); nY++ )
+ {
+ for ( nX = 0; nX < aBitmapSizePixel.Width(); nX++ )
+ {
+ double fX = static_cast< double >( nX ) / aBitmapSizePixel.Width();
+ double fY = static_cast< double >( nY ) / aBitmapSizePixel.Height();
+
+ double fD, fDist;
+ if ( fX < fFocusX )
+ {
+ if ( fY < fFocusY )
+ {
+ if ( fX > fY )
+ fDist = fY, fD = fFocusY;
+ else
+ fDist = fX, fD = fFocusX;
+ }
+ else
+ {
+ if ( fX > ( 1 - fY ) )
+ fDist = ( 1 - fY ), fD = 1 - fFocusY;
+ else
+ fDist = fX, fD = fFocusX;
+ }
+ }
+ else
+ {
+ if ( fY < fFocusY )
+ {
+ if ( ( 1 - fX ) > fY )
+ fDist = fY, fD = fFocusY;
+ else
+ fDist = ( 1 - fX ), fD = 1 - fFocusX;
+ }
+ else
+ {
+ if ( ( 1 - fX ) > ( 1 - fY ) )
+ fDist = ( 1 - fY ), fD = 1 - fFocusY;
+ else
+ fDist = ( 1 - fX ), fD = 1 - fFocusX;
+ }
+ }
+ if ( fD != 0.0 )
+ fDist /= fD;
+
+ std::vector< ShadeColor >::const_iterator aIter( rShadeColors.begin() );
+ double fA = 0.0;
+ Color aColorA = aIter->aColor;
+ double fB = 1.0;
+ Color aColorB( aColorA );
+ while ( aIter != rShadeColors.end() )
+ {
+ if ( aIter->fDist <= fDist )
+ {
+ if ( aIter->fDist >= fA )
+ {
+ fA = aIter->fDist;
+ aColorA = aIter->aColor;
+ }
+ }
+ if ( aIter->fDist > fDist )
+ {
+ if ( aIter->fDist <= fB )
+ {
+ fB = aIter->fDist;
+ aColorB = aIter->aColor;
+ }
+ }
+ aIter++;
+ }
+ double fRed = aColorA.GetRed(), fGreen = aColorA.GetGreen(), fBlue = aColorA.GetBlue();
+ double fD1 = fB - fA;
+ if ( fD1 != 0.0 )
+ {
+ fRed += ( ( ( fDist - fA ) * ( aColorB.GetRed() - aColorA.GetRed() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fRed;
+ fGreen += ( ( ( fDist - fA ) * ( aColorB.GetGreen() - aColorA.GetGreen() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fGreen;
+ fBlue += ( ( ( fDist - fA ) * ( aColorB.GetBlue() - aColorA.GetBlue() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fBlue;
+ }
+ sal_Int16 nRed = static_cast< sal_Int16 >( fRed + 0.5 );
+ sal_Int16 nGreen = static_cast< sal_Int16 >( fGreen + 0.5 );
+ sal_Int16 nBlue = static_cast< sal_Int16 >( fBlue + 0.5 );
+/*
+ double fErr = fRed - nRed;
+ aQuantErrCurrScan[ nX + 1 ].fRed += 7.0 * fErr / 16.0;
+ if ( nX )
+ aQuantErrNextScan[ nX - 1 ].fRed += 3.0 * fErr / 16.0;
+ aQuantErrNextScan[ nX ].fRed += 5.0 * fErr / 16.0;
+ aQuantErrNextScan[ nX + 1 ].fRed += 1.0 * fErr / 16.0;
+
+ fErr = fGreen - nGreen;
+ aQuantErrCurrScan[ nX + 1 ].fGreen += 7.0 * fErr / 16.0;
+ if ( nX )
+ aQuantErrNextScan[ nX - 1 ].fGreen += 3.0 * fErr / 16.0;
+ aQuantErrNextScan[ nX ].fGreen += 5.0 * fErr / 16.0;
+ aQuantErrNextScan[ nX + 1 ].fGreen += 1.0 * fErr / 16.0;
+
+ fErr = fBlue - nBlue;
+ aQuantErrCurrScan[ nX + 1 ].fBlue += 7.0 * fErr / 16.0;
+ if ( nX )
+ aQuantErrNextScan[ nX - 1 ].fBlue += 3.0 * fErr / 16.0;
+ aQuantErrNextScan[ nX ].fBlue += 5.0 * fErr / 16.0;
+ aQuantErrNextScan[ nX + 1 ].fBlue += 1.0 * fErr / 16.0;
+*/
+ if ( nRed < 0 )
+ nRed = 0;
+ if ( nRed > 255 )
+ nRed = 255;
+ if ( nGreen < 0 )
+ nGreen = 0;
+ if ( nGreen > 255 )
+ nGreen = 255;
+ if ( nBlue < 0 )
+ nBlue = 0;
+ if ( nBlue > 255 )
+ nBlue = 255;
+
+ pAcc->SetPixel( nY, nX, BitmapColor( static_cast< sal_Int8 >( nRed ), static_cast< sal_Int8 >( nGreen ), static_cast< sal_Int8 >( nBlue ) ) );
+ }
+/*
+ aQuantErrCurrScan.swap( aQuantErrNextScan );
+ std::vector< QuantErr >::iterator aIter( aQuantErrNextScan.begin() );
+ while( aIter != aQuantErrNextScan.end() )
+ {
+ *aIter = QuantErr();
+ aIter++;
+ }
+*/
+ }
+ aBitmap.ReleaseAccess( pAcc );
+
+ if ( nFix16Angle )
+ {
+ sal_Bool bRotateWithShape = sal_True; // TRUE seems to be default
+ sal_uInt32 nPos = rIn.Tell();
+ if ( const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.SeekToContent( rIn, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ) )
+ {
+ const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.Current()->SeekToBegOfRecord( rIn );
+ DffPropertyReader aSecPropSet( rManager );
+ aSecPropSet.ReadPropSet( rIn, NULL );
+ sal_Int32 nSecFillProperties = aSecPropSet.GetPropertyValue( DFF_Prop_fNoFillHitTest, 0x200020 );
+ bRotateWithShape = ( nSecFillProperties & 0x0020 );
+ }
+ rIn.Seek( nPos );
+ if ( bRotateWithShape )
+ {
+ aBitmap.Rotate( nFix16Angle / 10, rShadeColors[ 0 ].aColor );
+
+ ULONG nMirrorFlags = BMP_MIRROR_NONE;
+ if ( rObjData.nSpFlags & SP_FFLIPV )
+ nMirrorFlags |= BMP_MIRROR_VERT;
+ if ( rObjData.nSpFlags & SP_FFLIPH )
+ nMirrorFlags |= BMP_MIRROR_HORZ;
+ if ( nMirrorFlags != BMP_MIRROR_NONE )
+ aBitmap.Mirror( nMirrorFlags );
+ }
+ }
+
+ XOBitmap aXBmp( aBitmap, XBITMAP_STRETCH );
+ rSet.Put( XFillBmpTileItem( sal_False ) );
+ rSet.Put( XFillBitmapItem( String(), aXBmp ) );
+ }
+ }
+}
+
+void DffPropertyReader::ApplyFillAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
+{
+ UINT32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
+
+ std::vector< ShadeColor > aShadeColors;
+ GetShadeColors( rManager, *this, rIn, aShadeColors );
+
+ if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType ))
+ {
+ nFillFlags &= ~0x10;
+ }
+
+ if ( nFillFlags & 0x10 )
+ {
+ MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
+ XFillStyle eXFill = XFILL_NONE;
+ switch( eMSO_FillType )
+ {
+ case mso_fillSolid : // Fill with a solid color
+ eXFill = XFILL_SOLID;
+ break;
+ case mso_fillPattern : // Fill with a pattern (bitmap)
+ case mso_fillTexture : // A texture (pattern with its own color map)
+ case mso_fillPicture : // Center a picture in the shape
+ eXFill = XFILL_BITMAP;
+ break;
+ case mso_fillShadeCenter : // Shade from bounding rectangle to end point
+ {
+ if ( rObjData.aBoundRect.IsEmpty() )// size of object needed to be able
+ eXFill = XFILL_GRADIENT; // to create a bitmap substitution
+ else
+ eXFill = XFILL_BITMAP;
+ }
+ break;
+ case mso_fillShade : // Shade from start to end points
+ case mso_fillShadeShape : // Shade from shape outline to end point
+ case mso_fillShadeScale : // Similar to mso_fillShade, but the fillAngle
+ case mso_fillShadeTitle : // special type - shade to title --- for PP
+ eXFill = XFILL_GRADIENT;
+ break;
+// case mso_fillBackground : // Use the background fill color/pattern
+ default: break;
+ }
+ rSet.Put( XFillStyleItem( eXFill ) );
+
+ if (IsProperty(DFF_Prop_fillOpacity))
+ {
+ double nTrans = GetPropertyValue(DFF_Prop_fillOpacity);
+ nTrans = (nTrans * 100) / 65536;
+ rSet.Put(XFillTransparenceItem(
+ sal_uInt16(100 - ::rtl::math::round(nTrans))));
+ }
+
+ if ( ( eMSO_FillType == mso_fillShadeCenter ) && ( eXFill == XFILL_BITMAP ) )
+ {
+ ApplyRectangularGradientAsBitmap( rManager, rIn, rSet, aShadeColors, rObjData, mnFix16Angle );
+ }
+ else if ( eXFill == XFILL_GRADIENT )
+ {
+ sal_Int32 nAngle = 3600 - ( ( Fix16ToAngle( GetPropertyValue( DFF_Prop_fillAngle, 0 ) ) + 5 ) / 10 );
+
+ // Rotationswinkel in Bereich zwingen
+ while ( nAngle >= 3600 )
+ nAngle -= 3600;
+ while ( nAngle < 0 )
+ nAngle += 3600;
+
+ sal_Int32 nFocus = GetPropertyValue( DFF_Prop_fillFocus, 0 );
+ XGradientStyle eGrad = XGRAD_LINEAR;
+ sal_Int32 nChgColors = 0;
+
+ if ( nFocus < 0 ) // Bei negativem Focus sind die Farben zu tauschen
+ {
+ nFocus =- nFocus;
+ nChgColors ^= 1;
+ }
+ if( nFocus > 40 && nFocus < 60 )
+ {
+ eGrad = XGRAD_AXIAL; // Besser gehts leider nicht
+ }
+
+ USHORT nFocusX = (USHORT)nFocus;
+ USHORT nFocusY = (USHORT)nFocus;
+
+ switch( eMSO_FillType )
+ {
+ case mso_fillShadeShape :
+ {
+ eGrad = XGRAD_RECT;
+ nFocusY = nFocusX = 50;
+ nChgColors ^= 1;
+ }
+ break;
+ case mso_fillShadeCenter :
+ {
+ eGrad = XGRAD_RECT;
+ nFocusX = ( IsProperty( DFF_Prop_fillToRight ) ) ? 100 : 0;
+ nFocusY = ( IsProperty( DFF_Prop_fillToBottom ) ) ? 100 : 0;
+ nChgColors ^= 1;
+ }
+ break;
+ default: break;
+ }
+ Color aCol1( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ) );
+ Color aCol2( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ) );
+
+ if ( nChgColors )
+ {
+ Color aZwi( aCol1 );
+ aCol1 = aCol2;
+ aCol2 = aZwi;
+ }
+ XGradient aGrad( aCol2, aCol1, eGrad, nAngle, nFocusX, nFocusY );
+ aGrad.SetStartIntens( 100 );
+ aGrad.SetEndIntens( 100 );
+ rSet.Put( XFillGradientItem( String(), aGrad ) );
+ }
+ else if ( eXFill == XFILL_BITMAP )
+ {
+ if( IsProperty( DFF_Prop_fillBlip ) )
+ {
+ Graphic aGraf;
+ // first try to get BLIP from cache
+ BOOL bOK = rManager.GetBLIP( GetPropertyValue( DFF_Prop_fillBlip ), aGraf, NULL );
+ // then try directly from stream (i.e. Excel chart hatches/bitmaps)
+ if ( !bOK )
+ bOK = SeekToContent( DFF_Prop_fillBlip, rIn ) && rManager.GetBLIPDirect( rIn, aGraf, NULL );
+ if ( bOK )
+ {
+ Bitmap aBmp( aGraf.GetBitmap() );
+
+ if ( eMSO_FillType == mso_fillPattern )
+ {
+ Color aCol1( COL_WHITE ), aCol2( COL_WHITE );
+ if ( IsProperty( DFF_Prop_fillColor ) )
+ aCol1 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor );
+ if ( IsProperty( DFF_Prop_fillBackColor ) )
+ aCol2 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor ), DFF_Prop_fillBackColor );
+
+ XOBitmap aXOBitmap;
+
+ // Bitmap einsetzen
+ aXOBitmap.SetBitmap( aBmp );
+ aXOBitmap.SetBitmapType( XBITMAP_IMPORT );
+
+ if( aBmp.GetSizePixel().Width() == 8 && aBmp.GetSizePixel().Height() == 8 && aBmp.GetColorCount() == 2)
+ {
+ aXOBitmap.Bitmap2Array();
+ aXOBitmap.SetBitmapType( XBITMAP_8X8 );
+ aXOBitmap.SetPixelSize( aBmp.GetSizePixel() );
+
+ if( aXOBitmap.GetBackgroundColor() == COL_BLACK )
+ {
+ aXOBitmap.SetPixelColor( aCol1 );
+ aXOBitmap.SetBackgroundColor( aCol2 );
+ }
+ else
+ {
+ aXOBitmap.SetPixelColor( aCol2 );
+ aXOBitmap.SetBackgroundColor( aCol1 );
+ }
+ }
+ rSet.Put( XFillBitmapItem( String(), aXOBitmap ) );
+ }
+ else if ( eMSO_FillType == mso_fillTexture )
+ {
+ XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
+ rSet.Put( XFillBmpTileItem( sal_True ) );
+ rSet.Put( XFillBitmapItem( String(), aXBmp ) );
+ rSet.Put( XFillBmpSizeXItem( GetPropertyValue( DFF_Prop_fillWidth, 0 ) / 360 ) );
+ rSet.Put( XFillBmpSizeYItem( GetPropertyValue( DFF_Prop_fillHeight, 0 ) / 360 ) );
+ rSet.Put( XFillBmpSizeLogItem( sal_True ) );
+ }
+ else
+ {
+ XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
+ rSet.Put( XFillBitmapItem( String(), aXBmp ) );
+ rSet.Put( XFillBmpTileItem( sal_False ) );
+ }
+ }
+ }
+ }
+ }
+ else
+ rSet.Put( XFillStyleItem( XFILL_NONE ) );
+}
+
+void DffPropertyReader::ApplyCustomShapeTextAttributes( SfxItemSet& rSet ) const
+{
+// sal_uInt32 nTextFlags = aTextObj.GetTextFlags();
+ sal_Bool bVerticalText = sal_False;
+ sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ) / 360; // 0.25 cm (emu)
+ sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ) / 360; // 0.25 cm (emu)
+ sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ) / 360; // 0.13 cm (emu)
+ sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 ) /360; // 0.13 cm (emu)
+
+ SdrTextVertAdjust eTVA;
+ SdrTextHorzAdjust eTHA;
+
+ if ( IsProperty( DFF_Prop_txflTextFlow ) )
+ {
+ MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
+ switch( eTextFlow )
+ {
+ case mso_txflTtoBA : /* #68110# */ // Top to Bottom @-font, oben -> unten
+ case mso_txflTtoBN : // Top to Bottom non-@, oben -> unten
+ case mso_txflVertN : // Vertical, non-@, oben -> unten
+ bVerticalText = sal_True; // nTextRotationAngle += 27000;
+ break;
+ default: break;
+ }
+ }
+ sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 );
+ if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) )
+ bVerticalText = !bVerticalText;
+
+ if ( bVerticalText )
+ {
+ eTVA = SDRTEXTVERTADJUST_BLOCK;
+ eTHA = SDRTEXTHORZADJUST_CENTER;
+
+ // Textverankerung lesen
+ MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+
+ switch( eTextAnchor )
+ {
+ case mso_anchorTop:
+ case mso_anchorTopCentered:
+ case mso_anchorTopBaseline:
+ case mso_anchorTopCenteredBaseline:
+ eTHA = SDRTEXTHORZADJUST_RIGHT;
+ break;
+
+ case mso_anchorMiddle :
+ case mso_anchorMiddleCentered:
+ eTHA = SDRTEXTHORZADJUST_CENTER;
+ break;
+
+ case mso_anchorBottom:
+ case mso_anchorBottomCentered:
+ case mso_anchorBottomBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ eTHA = SDRTEXTHORZADJUST_LEFT;
+ break;
+ }
+ // if there is a 100% use of following attributes, the textbox can been aligned also in vertical direction
+ switch ( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ case mso_anchorTopCenteredBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ eTVA = SDRTEXTVERTADJUST_CENTER;
+ break;
+
+ default :
+ eTVA = SDRTEXTVERTADJUST_TOP;
+ break;
+ }
+ }
+ else
+ {
+ eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_BLOCK;
+
+ // Textverankerung lesen
+ MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+
+ switch( eTextAnchor )
+ {
+ case mso_anchorTop:
+ case mso_anchorTopCentered:
+ case mso_anchorTopBaseline:
+ case mso_anchorTopCenteredBaseline:
+ eTVA = SDRTEXTVERTADJUST_TOP;
+ break;
+
+ case mso_anchorMiddle :
+ case mso_anchorMiddleCentered:
+ eTVA = SDRTEXTVERTADJUST_CENTER;
+ break;
+
+ case mso_anchorBottom:
+ case mso_anchorBottomCentered:
+ case mso_anchorBottomBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ break;
+ }
+ // if there is a 100% usage of following attributes, the textbox can be aligned also in horizontal direction
+ switch ( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ case mso_anchorTopCenteredBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ eTHA = SDRTEXTHORZADJUST_CENTER; // the text has to be displayed using the full width;
+ break;
+
+ default :
+ eTHA = SDRTEXTHORZADJUST_LEFT;
+ break;
+ }
+ }
+ rSet.Put( SvxFrameDirectionItem( bVerticalText ? FRMDIR_VERT_TOP_RIGHT : FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR ) );
+
+ rSet.Put( SdrTextVertAdjustItem( eTVA ) );
+ rSet.Put( SdrTextHorzAdjustItem( eTHA ) );
+
+ rSet.Put( SdrTextLeftDistItem( nTextLeft ) );
+ rSet.Put( SdrTextRightDistItem( nTextRight ) );
+ rSet.Put( SdrTextUpperDistItem( nTextTop ) );
+ rSet.Put( SdrTextLowerDistItem( nTextBottom ) );
+
+ rSet.Put( SdrTextWordWrapItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_True : sal_False ) );
+ rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
+
+// rSet.Put( SdrTextAutoGrowWidthItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_False : sal_True ) );
+// rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
+}
+
+void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
+{
+
+ sal_uInt32 nAdjustmentsWhichNeedsToBeConverted = 0;
+
+ ///////////////////////////////////////
+ // creating SdrCustomShapeGeometryItem //
+ ///////////////////////////////////////
+ typedef uno::Sequence< beans::PropertyValue > PropSeq;
+ typedef std::vector< beans::PropertyValue > PropVec;
+ typedef PropVec::iterator PropVecIter;
+ PropVecIter aIter;
+ PropVecIter aEnd;
+
+
+ // aPropVec will be filled with all PropertyValues
+ PropVec aPropVec;
+ PropertyValue aProp;
+
+ /////////////////////////////////////////////////////////////////////
+ // "Type" property, including the predefined CustomShape type name //
+ /////////////////////////////////////////////////////////////////////
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ aProp.Name = sType;
+ aProp.Value <<= EnhancedCustomShapeTypeNames::Get( rObjData.eShapeType );
+ aPropVec.push_back( aProp );
+
+/*
+ /////////////////
+ // "MirroredX" //
+ /////////////////
+ if ( nShapeFlags & SP_FFLIPH )
+ {
+ const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
+ sal_Bool bMirroredX = sal_True;
+ aProp.Name = sMirroredX;
+ aProp.Value <<= bMirroredX;
+ aPropVec.push_back( aProp );
+ }
+ /////////////////
+ // "MirroredY" //
+ /////////////////
+ if ( nShapeFlags & SP_FFLIPV )
+ {
+ const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
+ sal_Bool bMirroredY = sal_True;
+ aProp.Name = sMirroredY;
+ aProp.Value <<= bMirroredY;
+ aPropVec.push_back( aProp );
+ }
+*/
+ ///////////////
+ // "ViewBox" //
+ ///////////////
+
+ sal_Int32 nCoordWidth = 21600; // needed to replace handle type center with absolute value
+ sal_Int32 nCoordHeight= 21600;
+ if ( IsProperty( DFF_Prop_geoLeft ) || IsProperty( DFF_Prop_geoTop ) || IsProperty( DFF_Prop_geoRight ) || IsProperty( DFF_Prop_geoBottom ) )
+ {
+ com::sun::star::awt::Rectangle aViewBox;
+ const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
+ aViewBox.X = GetPropertyValue( DFF_Prop_geoLeft, 0 );
+ aViewBox.Y = GetPropertyValue( DFF_Prop_geoTop, 0 );
+ aViewBox.Width = nCoordWidth = ((sal_Int32)GetPropertyValue( DFF_Prop_geoRight, 21600 ) ) - aViewBox.X;
+ aViewBox.Height = nCoordHeight = ((sal_Int32)GetPropertyValue( DFF_Prop_geoBottom, 21600 ) ) - aViewBox.Y;
+ aProp.Name = sViewBox;
+ aProp.Value <<= aViewBox;
+ aPropVec.push_back( aProp );
+ }
+ /////////////////////
+ // TextRotateAngle //
+ /////////////////////
+ if ( IsProperty( DFF_Prop_txflTextFlow ) || IsProperty( DFF_Prop_cdirFont ) )
+ {
+ sal_Int32 nTextRotateAngle = 0;
+ MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
+/* sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ); */
+
+ if ( eTextFlow == mso_txflBtoT ) // Bottom to Top non-@, unten -> oben
+ nTextRotateAngle += 90;
+ switch( GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ) ) // SJ: mso_cdir90 and mso_cdir270 will be simulated by
+ { // activating vertical writing for the text objects
+ case mso_cdir90 :
+ {
+ if ( eTextFlow == mso_txflTtoBA )
+ nTextRotateAngle -= 180;
+ }
+ break;
+ case mso_cdir180: nTextRotateAngle -= 180; break;
+ case mso_cdir270:
+ {
+ if ( eTextFlow != mso_txflTtoBA )
+ nTextRotateAngle -= 180;
+ }
+ break;
+ default: break;
+ }
+ if ( nTextRotateAngle )
+ {
+ double fTextRotateAngle = nTextRotateAngle;
+ const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
+ aProp.Name = sTextRotateAngle;
+ aProp.Value <<= fTextRotateAngle;
+ aPropVec.push_back( aProp );
+ }
+ }
+ //////////////////////////////////////////
+ // "Extrusion" PropertySequence element //
+ //////////////////////////////////////////
+ sal_Bool bExtrusionOn = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 8 ) != 0;
+ if ( bExtrusionOn )
+ {
+ PropVec aExtrusionPropVec;
+
+ // "Extrusion"
+ const rtl::OUString sExtrusionOn( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
+ aProp.Name = sExtrusionOn;
+ aProp.Value <<= bExtrusionOn;
+ aExtrusionPropVec.push_back( aProp );
+
+ // "Brightness"
+ if ( IsProperty( DFF_Prop_c3DAmbientIntensity ) )
+ {
+ const rtl::OUString sExtrusionBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
+ double fBrightness = (sal_Int32)GetPropertyValue( DFF_Prop_c3DAmbientIntensity );
+ fBrightness /= 655.36;
+ aProp.Name = sExtrusionBrightness;
+ aProp.Value <<= fBrightness;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "Depth" in 1/100mm
+ if ( IsProperty( DFF_Prop_c3DExtrudeBackward ) || IsProperty( DFF_Prop_c3DExtrudeForward ) )
+ {
+ const rtl::OUString sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
+ double fBackDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeBackward, 1270 * 360 )) / 360.0;
+ double fForeDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeForward ), 0 ) / 360.0;
+ double fDepth = fBackDepth + fForeDepth;
+ double fFraction = fDepth != 0.0 ? fForeDepth / fDepth : 0;
+ EnhancedCustomShapeParameterPair aDepthParaPair;
+ aDepthParaPair.First.Value <<= fDepth;
+ aDepthParaPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
+ aDepthParaPair.Second.Value <<= fFraction;
+ aDepthParaPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
+ aProp.Name = sDepth;
+ aProp.Value <<= aDepthParaPair;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "Diffusion"
+ if ( IsProperty( DFF_Prop_c3DDiffuseAmt ) )
+ {
+ const rtl::OUString sExtrusionDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
+ double fDiffusion = (sal_Int32)GetPropertyValue( DFF_Prop_c3DDiffuseAmt );
+ fDiffusion /= 655.36;
+ aProp.Name = sExtrusionDiffusion;
+ aProp.Value <<= fDiffusion;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "NumberOfLineSegments"
+ if ( IsProperty( DFF_Prop_c3DTolerance ) )
+ {
+ const rtl::OUString sExtrusionNumberOfLineSegments( RTL_CONSTASCII_USTRINGPARAM ( "NumberOfLineSegments" ) );
+ aProp.Name = sExtrusionNumberOfLineSegments;
+ aProp.Value <<= (sal_Int32)GetPropertyValue( DFF_Prop_c3DTolerance );
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "LightFace"
+ const rtl::OUString sExtrusionLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) );
+ sal_Bool bExtrusionLightFace = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 1 ) != 0;
+ aProp.Name = sExtrusionLightFace;
+ aProp.Value <<= bExtrusionLightFace;
+ aExtrusionPropVec.push_back( aProp );
+ // "FirstLightHarsh"
+ const rtl::OUString sExtrusionFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) );
+ sal_Bool bExtrusionFirstLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 2 ) != 0;
+ aProp.Name = sExtrusionFirstLightHarsh;
+ aProp.Value <<= bExtrusionFirstLightHarsh;
+ aExtrusionPropVec.push_back( aProp );
+ // "SecondLightHarsh"
+ const rtl::OUString sExtrusionSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) );
+ sal_Bool bExtrusionSecondLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 1 ) != 0;
+ aProp.Name = sExtrusionSecondLightHarsh;
+ aProp.Value <<= bExtrusionSecondLightHarsh;
+ aExtrusionPropVec.push_back( aProp );
+ // "FirstLightLevel"
+ if ( IsProperty( DFF_Prop_c3DKeyIntensity ) )
+ {
+ const rtl::OUString sExtrusionFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) );
+ double fFirstLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyIntensity );
+ fFirstLightLevel /= 655.36;
+ aProp.Name = sExtrusionFirstLightLevel;
+ aProp.Value <<= fFirstLightLevel;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "SecondLightLevel"
+ if ( IsProperty( DFF_Prop_c3DFillIntensity ) )
+ {
+ const rtl::OUString sExtrusionSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) );
+ double fSecondLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DFillIntensity );
+ fSecondLightLevel /= 655.36;
+ aProp.Name = sExtrusionSecondLightLevel;
+ aProp.Value <<= fSecondLightLevel;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "FirtstLightDirection"
+ if ( IsProperty( DFF_Prop_c3DKeyX ) || IsProperty( DFF_Prop_c3DKeyY ) || IsProperty( DFF_Prop_c3DKeyZ ) )
+ {
+ double fLightX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyX, 50000 ));
+ double fLightY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyY, 0 ));
+ double fLightZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyZ, 10000 ));
+ ::com::sun::star::drawing::Direction3D aExtrusionFirstLightDirection( fLightX, fLightY, fLightZ );
+ const rtl::OUString sExtrusionFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
+ aProp.Name = sExtrusionFirstLightDirection;
+ aProp.Value <<= aExtrusionFirstLightDirection;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "SecondLightDirection"
+ if ( IsProperty( DFF_Prop_c3DFillX ) || IsProperty( DFF_Prop_c3DFillY ) || IsProperty( DFF_Prop_c3DFillZ ) )
+ {
+ double fLight2X = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillX, (sal_uInt32)-50000 ));
+ double fLight2Y = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillY, 0 ));
+ double fLight2Z = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillZ, 10000 ));
+ ::com::sun::star::drawing::Direction3D aExtrusionSecondLightDirection( fLight2X, fLight2Y, fLight2Z );
+ const rtl::OUString sExtrusionSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
+ aProp.Name = sExtrusionSecondLightDirection;
+ aProp.Value <<= aExtrusionSecondLightDirection;
+ aExtrusionPropVec.push_back( aProp );
+ }
+
+/* LockRotationCenter, OrientationAngle and Orientation needs to be converted to use the properties AngleX, AngleY and RotationAngle instead.
+ // "LockRotationCenter"
+ const rtl::OUString sExtrusionLockRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "LockRotationCenter" ) );
+ sal_Bool bExtrusionLockRotationCenter = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 16 ) != 0;
+ aProp.Name = sExtrusionLockRotationCenter;
+ aProp.Value <<= bExtrusionLockRotationCenter;
+ aExtrusionPropVec.push_back( aProp );
+
+ // "Orientation"
+ if ( IsProperty( DFF_Prop_c3DRotationAxisX ) || IsProperty( DFF_Prop_c3DRotationAxisY ) || IsProperty( DFF_Prop_c3DRotationAxisZ ) )
+ {
+ double fRotX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 ));
+ double fRotY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 ));
+ double fRotZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 ));
+ ::com::sun::star::drawing::Direction3D aExtrusionDirection( fRotX, fRotY, fRotZ );
+ const rtl::OUString sExtrusionDirection( RTL_CONSTASCII_USTRINGPARAM ( "Orientation" ) );
+ aProp.Name = sExtrusionDirection;
+ aProp.Value <<= aExtrusionDirection;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "OrientationAngle" in Grad
+ if ( IsProperty( DFF_Prop_c3DRotationAngle ) )
+ {
+ const rtl::OUString sExtrusionOrientationAngle( RTL_CONSTASCII_USTRINGPARAM ( "OrientationAngle" ) );
+ double fOrientationAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAngle )) / 65536.0;
+ aProp.Name = sExtrusionOrientationAngle;
+ aProp.Value <<= fOrientationAngle;
+ aExtrusionPropVec.push_back( aProp );
+ }
+*/
+
+ // "Metal"
+ const rtl::OUString sExtrusionMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
+ sal_Bool bExtrusionMetal = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 4 ) != 0;
+ aProp.Name = sExtrusionMetal;
+ aProp.Value <<= bExtrusionMetal;
+ aExtrusionPropVec.push_back( aProp );
+// if ( IsProperty( DFF_Prop_c3DExtrudePlane ) )
+// {
+// UPS
+// }
+ // "ShadeMode"
+ if ( IsProperty( DFF_Prop_c3DRenderMode ) )
+ {
+ const rtl::OUString sExtrusionShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
+ sal_uInt32 nExtrusionRenderMode = GetPropertyValue( DFF_Prop_c3DRenderMode );
+ com::sun::star::drawing::ShadeMode eExtrusionShadeMode( com::sun::star::drawing::ShadeMode_FLAT );
+ if ( nExtrusionRenderMode == mso_Wireframe )
+ eExtrusionShadeMode = com::sun::star::drawing::ShadeMode_DRAFT;
+
+ aProp.Name = sExtrusionShadeMode;
+ aProp.Value <<= eExtrusionShadeMode;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "RotateAngle" in Grad
+ if ( IsProperty( DFF_Prop_c3DXRotationAngle ) || IsProperty( DFF_Prop_c3DYRotationAngle ) )
+ {
+ const rtl::OUString sExtrusionAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) );
+ double fAngleX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXRotationAngle, 0 )) / 65536.0;
+ double fAngleY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYRotationAngle, 0 )) / 65536.0;
+ EnhancedCustomShapeParameterPair aRotateAnglePair;
+ aRotateAnglePair.First.Value <<= fAngleX;
+ aRotateAnglePair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
+ aRotateAnglePair.Second.Value <<= fAngleY;
+ aRotateAnglePair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
+ aProp.Name = sExtrusionAngle;
+ aProp.Value <<= aRotateAnglePair;
+ aExtrusionPropVec.push_back( aProp );
+ }
+
+ // "AutoRotationCenter"
+ if ( ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 8 ) == 0 )
+ {
+ // "RotationCenter"
+ if ( IsProperty( DFF_Prop_c3DRotationCenterX ) || IsProperty( DFF_Prop_c3DRotationCenterY ) || IsProperty( DFF_Prop_c3DRotationCenterZ ) )
+ {
+ ::com::sun::star::drawing::Direction3D aRotationCenter(
+ (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 )) / 360.0,
+ (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 )) / 360.0,
+ (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterZ, 0 )) / 360.0 );
+
+ const rtl::OUString sExtrusionRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) );
+ aProp.Name = sExtrusionRotationCenter;
+ aProp.Value <<= aRotationCenter;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ }
+ // "Shininess"
+ if ( IsProperty( DFF_Prop_c3DShininess ) )
+ {
+ const rtl::OUString sExtrusionShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) );
+ double fShininess = (sal_Int32)GetPropertyValue( DFF_Prop_c3DShininess );
+ fShininess /= 655.36;
+ aProp.Name = sExtrusionShininess;
+ aProp.Value <<= fShininess;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "Skew"
+ if ( IsProperty( DFF_Prop_c3DSkewAmount ) || IsProperty( DFF_Prop_c3DSkewAngle ) )
+ {
+ const rtl::OUString sExtrusionSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
+ double fSkewAmount = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAmount, 50 );
+ double fSkewAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAngle, sal::static_int_cast< UINT32 >(-135 * 65536) )) / 65536.0;
+
+ EnhancedCustomShapeParameterPair aSkewPair;
+ aSkewPair.First.Value <<= fSkewAmount;
+ aSkewPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
+ aSkewPair.Second.Value <<= fSkewAngle;
+ aSkewPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
+ aProp.Name = sExtrusionSkew;
+ aProp.Value <<= aSkewPair;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "Specularity"
+ if ( IsProperty( DFF_Prop_c3DSpecularAmt ) )
+ {
+ const rtl::OUString sExtrusionSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
+ double fSpecularity = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSpecularAmt );
+ fSpecularity /= 1333;
+ aProp.Name = sExtrusionSpecularity;
+ aProp.Value <<= fSpecularity;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "ProjectionMode"
+ const rtl::OUString sExtrusionProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
+ ProjectionMode eProjectionMode = GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 4 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE;
+ aProp.Name = sExtrusionProjectionMode;
+ aProp.Value <<= eProjectionMode;
+ aExtrusionPropVec.push_back( aProp );
+
+ // "ViewPoint" in 1/100mm
+ if ( IsProperty( DFF_Prop_c3DXViewpoint ) || IsProperty( DFF_Prop_c3DYViewpoint ) || IsProperty( DFF_Prop_c3DZViewpoint ) )
+ {
+ double fViewX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXViewpoint, 1249920 )) / 360.0;
+ double fViewY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYViewpoint, (sal_uInt32)-1249920 ))/ 360.0;
+ double fViewZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DZViewpoint, 9000000 )) / 360.0;
+ ::com::sun::star::drawing::Position3D aExtrusionViewPoint( fViewX, fViewY, fViewZ );
+ const rtl::OUString sExtrusionViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
+ aProp.Name = sExtrusionViewPoint;
+ aProp.Value <<= aExtrusionViewPoint;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "Origin"
+ if ( IsProperty( DFF_Prop_c3DOriginX ) || IsProperty( DFF_Prop_c3DOriginY ) )
+ {
+ const rtl::OUString sExtrusionOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
+ double fOriginX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginX, 0 ));
+ double fOriginY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginY, 0 ));
+ fOriginX /= 65536;
+ fOriginY /= 65536;
+ EnhancedCustomShapeParameterPair aOriginPair;
+ aOriginPair.First.Value <<= fOriginX;
+ aOriginPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
+ aOriginPair.Second.Value <<= fOriginY;
+ aOriginPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
+ aProp.Name = sExtrusionOrigin;
+ aProp.Value <<= aOriginPair;
+ aExtrusionPropVec.push_back( aProp );
+ }
+ // "ExtrusionColor"
+ const rtl::OUString sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
+ sal_Bool bExtrusionColor = IsProperty( DFF_Prop_c3DExtrusionColor ); // ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 2 ) != 0;
+ aProp.Name = sExtrusionColor;
+ aProp.Value <<= bExtrusionColor;
+ aExtrusionPropVec.push_back( aProp );
+ if ( IsProperty( DFF_Prop_c3DExtrusionColor ) )
+ rSet.Put( XSecondaryFillColorItem( String(), rManager.MSO_CLR_ToColor(
+ GetPropertyValue( DFF_Prop_c3DExtrusionColor ), DFF_Prop_c3DExtrusionColor ) ) );
+ // pushing the whole Extrusion element
+ const rtl::OUString sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
+ PropSeq aExtrusionPropSeq( aExtrusionPropVec.size() );
+ aIter = aExtrusionPropVec.begin();
+ aEnd = aExtrusionPropVec.end();
+ beans::PropertyValue* pExtrusionValues = aExtrusionPropSeq.getArray();
+ while ( aIter != aEnd )
+ *pExtrusionValues++ = *aIter++;
+ aProp.Name = sExtrusion;
+ aProp.Value <<= aExtrusionPropSeq;
+ aPropVec.push_back( aProp );
+ }
+
+ /////////////////////////////////////////
+ // "Equations" PropertySequence element //
+ /////////////////////////////////////////
+ if ( IsProperty( DFF_Prop_pFormulas ) )
+ {
+ sal_uInt16 i;
+ sal_uInt16 nNumElem = 0;
+ sal_uInt16 nNumElemMem = 0;
+ sal_uInt16 nElemSize = 8;
+
+ if ( SeekToContent( DFF_Prop_pFormulas, rIn ) )
+ rIn >> nNumElem >> nNumElemMem >> nElemSize;
+
+ sal_Int16 nP1, nP2, nP3;
+ sal_uInt16 nFlags;
+
+ uno::Sequence< rtl::OUString > aEquations( nNumElem );
+ for ( i = 0; i < nNumElem; i++ )
+ {
+ rIn >> nFlags >> nP1 >> nP2 >> nP3;
+ aEquations[ i ] = EnhancedCustomShape2d::GetEquation( nFlags, nP1, nP2, nP3 );
+ }
+ // pushing the whole Equations element
+ const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
+ aProp.Name = sEquations;
+ aProp.Value <<= aEquations;
+ aPropVec.push_back( aProp );
+ }
+
+ ////////////////////////////////////////
+ // "Handles" PropertySequence element //
+ ////////////////////////////////////////
+ if ( IsProperty( DFF_Prop_Handles ) )
+ {
+ sal_uInt16 i;
+ sal_uInt16 nNumElem = 0;
+ sal_uInt16 nNumElemMem = 0;
+ sal_uInt16 nElemSize = 36;
+
+ if ( SeekToContent( DFF_Prop_Handles, rIn ) )
+ rIn >> nNumElem >> nNumElemMem >> nElemSize;
+ if ( nElemSize == 36 )
+ {
+ uno::Sequence< beans::PropertyValues > aHandles( nNumElem );
+ for ( i = 0; i < nNumElem; i++ )
+ {
+ PropVec aHandlePropVec;
+ sal_uInt32 nFlags;
+ sal_Int32 nPositionX, nPositionY, nCenterX, nCenterY, nRangeXMin, nRangeXMax, nRangeYMin, nRangeYMax;
+ rIn >> nFlags
+ >> nPositionX
+ >> nPositionY
+ >> nCenterX
+ >> nCenterY
+ >> nRangeXMin
+ >> nRangeXMax
+ >> nRangeYMin
+ >> nRangeYMax;
+
+ if ( nPositionX == 2 ) // replacing center position with absolute value
+ nPositionX = nCoordWidth / 2;
+ if ( nPositionY == 2 )
+ nPositionY = nCoordHeight / 2;
+ EnhancedCustomShapeParameterPair aPosition;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, nPositionX, sal_True, sal_True );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, nPositionY, sal_True, sal_False );
+ const rtl::OUString sHandlePosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
+ aProp.Name = sHandlePosition;
+ aProp.Value <<= aPosition;
+ aHandlePropVec.push_back( aProp );
+
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
+ {
+ sal_Bool bMirroredX = sal_True;
+ const rtl::OUString sHandleMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
+ aProp.Name = sHandleMirroredX;
+ aProp.Value <<= bMirroredX;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
+ {
+ sal_Bool bMirroredY = sal_True;
+ const rtl::OUString sHandleMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
+ aProp.Name = sHandleMirroredY;
+ aProp.Value <<= bMirroredY;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
+ {
+ sal_Bool bSwitched = sal_True;
+ const rtl::OUString sHandleSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
+ aProp.Name = sHandleSwitched;
+ aProp.Value <<= bSwitched;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
+ {
+ if ( nCenterX == 2 )
+ nCenterX = nCoordWidth / 2;
+ if ( nCenterY == 2 )
+ nCenterY = nCoordHeight / 2;
+ if ( ( nPositionY >= 0x256 ) || ( nPositionY <= 0x107 ) ) // position y
+ nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
+ EnhancedCustomShapeParameterPair aPolar;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
+ const rtl::OUString sHandlePolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
+ aProp.Name = sHandlePolar;
+ aProp.Value <<= aPolar;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MAP )
+ {
+ if ( nCenterX == 2 )
+ nCenterX = nCoordWidth / 2;
+ if ( nCenterY == 2 )
+ nCenterY = nCoordHeight / 2;
+ EnhancedCustomShapeParameterPair aMap;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
+ const rtl::OUString sHandleMap( RTL_CONSTASCII_USTRINGPARAM ( "Map" ) );
+ aProp.Name = sHandleMap;
+ aProp.Value <<= aMap;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
+ {
+ if ( (sal_uInt32)nRangeXMin != 0x80000000 )
+ {
+ if ( nRangeXMin == 2 )
+ nRangeXMin = nCoordWidth / 2;
+ EnhancedCustomShapeParameter aRangeXMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, nRangeXMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
+ const rtl::OUString sHandleRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
+ aProp.Name = sHandleRangeXMinimum;
+ aProp.Value <<= aRangeXMinimum;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( (sal_uInt32)nRangeXMax != 0x7fffffff )
+ {
+ if ( nRangeXMax == 2 )
+ nRangeXMax = nCoordWidth / 2;
+ EnhancedCustomShapeParameter aRangeXMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, nRangeXMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
+ const rtl::OUString sHandleRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
+ aProp.Name = sHandleRangeXMaximum;
+ aProp.Value <<= aRangeXMaximum;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( (sal_uInt32)nRangeYMin != 0x80000000 )
+ {
+ if ( nRangeYMin == 2 )
+ nRangeYMin = nCoordHeight / 2;
+ EnhancedCustomShapeParameter aRangeYMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, nRangeYMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
+ const rtl::OUString sHandleRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
+ aProp.Name = sHandleRangeYMinimum;
+ aProp.Value <<= aRangeYMinimum;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( (sal_uInt32)nRangeYMax != 0x7fffffff )
+ {
+ if ( nRangeYMax == 2 )
+ nRangeYMax = nCoordHeight / 2;
+ EnhancedCustomShapeParameter aRangeYMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, nRangeYMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
+ const rtl::OUString sHandleRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
+ aProp.Name = sHandleRangeYMaximum;
+ aProp.Value <<= aRangeYMaximum;
+ aHandlePropVec.push_back( aProp );
+ }
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
+ {
+ if ( (sal_uInt32)nRangeXMin != 0x7fffffff )
+ {
+ if ( nRangeXMin == 2 )
+ nRangeXMin = nCoordWidth / 2;
+ EnhancedCustomShapeParameter aRadiusRangeMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, nRangeXMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
+ const rtl::OUString sHandleRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
+ aProp.Name = sHandleRadiusRangeMinimum;
+ aProp.Value <<= aRadiusRangeMinimum;
+ aHandlePropVec.push_back( aProp );
+ }
+ if ( (sal_uInt32)nRangeXMax != 0x80000000 )
+ {
+ if ( nRangeXMax == 2 )
+ nRangeXMax = nCoordWidth / 2;
+ EnhancedCustomShapeParameter aRadiusRangeMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, nRangeXMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
+ const rtl::OUString sHandleRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
+ aProp.Name = sHandleRadiusRangeMaximum;
+ aProp.Value <<= aRadiusRangeMaximum;
+ aHandlePropVec.push_back( aProp );
+ }
+ }
+ if ( aHandlePropVec.size() )
+ {
+ PropSeq aHandlePropSeq( aHandlePropVec.size() );
+ aIter = aHandlePropVec.begin();
+ aEnd = aHandlePropVec.end();
+ beans::PropertyValue* pHandleValues = aHandlePropSeq.getArray();
+ while ( aIter != aEnd )
+ *pHandleValues++ = *aIter++;
+ aHandles[ i ] = aHandlePropSeq;
+ }
+ }
+ // pushing the whole Handles element
+ const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
+ aProp.Name = sHandles;
+ aProp.Value <<= aHandles;
+ aPropVec.push_back( aProp );
+ }
+ }
+ else
+ {
+ const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( rObjData.eShapeType );
+ if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
+ {
+ sal_Int32 i, nCnt = pDefCustomShape->nHandles;
+ const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
+ for ( i = 0; i < nCnt; i++, pData++ )
+ {
+ if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR )
+ {
+ if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) )
+ nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
+ }
+ }
+ }
+ }
+ /////////////////////////////////////
+ // "Path" PropertySequence element //
+ /////////////////////////////////////
+ {
+ PropVec aPathPropVec;
+
+ // "Path/ExtrusionAllowed"
+ if ( IsHardAttribute( DFF_Prop_f3DOK ) )
+ {
+ const rtl::OUString sExtrusionAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ExtrusionAllowed" ) );
+ sal_Bool bExtrusionAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 16 ) != 0;
+ aProp.Name = sExtrusionAllowed;
+ aProp.Value <<= bExtrusionAllowed;
+ aPathPropVec.push_back( aProp );
+ }
+ // "Path/ConcentricGradientFillAllowed"
+ if ( IsHardAttribute( DFF_Prop_fFillShadeShapeOK ) )
+ {
+ const rtl::OUString sConcentricGradientFillAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ConcentricGradientFillAllowed" ) );
+ sal_Bool bConcentricGradientFillAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 2 ) != 0;
+ aProp.Name = sConcentricGradientFillAllowed;
+ aProp.Value <<= bConcentricGradientFillAllowed;
+ aPathPropVec.push_back( aProp );
+ }
+ // "Path/TextPathAllowed"
+ if ( IsHardAttribute( DFF_Prop_fGtextOK ) || ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) )
+ {
+ const rtl::OUString sTextPathAllowed( RTL_CONSTASCII_USTRINGPARAM ( "TextPathAllowed" ) );
+ sal_Bool bTextPathAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 4 ) != 0;
+ aProp.Name = sTextPathAllowed;
+ aProp.Value <<= bTextPathAllowed;
+ aPathPropVec.push_back( aProp );
+ }
+ // Path/Coordinates
+ if ( IsProperty( DFF_Prop_pVertices ) )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
+
+ sal_uInt16 i;
+ sal_uInt16 nNumElemVert = 0;
+ sal_uInt16 nNumElemMemVert = 0;
+ sal_uInt16 nElemSizeVert = 8;
+
+ if ( SeekToContent( DFF_Prop_pVertices, rIn ) )
+ rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
+ if ( nNumElemVert )
+ {
+ sal_Int32 nX, nY;
+ sal_Int16 nTmpA, nTmpB;
+ aCoordinates.realloc( nNumElemVert );
+ for ( i = 0; i < nNumElemVert; i++ )
+ {
+ if ( nElemSizeVert == 8 )
+ {
+ rIn >> nX
+ >> nY;
+ }
+ else
+ {
+ rIn >> nTmpA
+ >> nTmpB;
+
+ nX = nTmpA;
+ nY = nTmpB;
+ }
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].First, nX );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].Second, nY );
+ }
+ }
+ const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
+ aProp.Name = sCoordinates;
+ aProp.Value <<= aCoordinates;
+ aPathPropVec.push_back( aProp );
+ }
+ // Path/Segments
+ if ( IsProperty( DFF_Prop_pSegmentInfo ) )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
+
+ sal_uInt16 i, nTmp;
+ sal_uInt16 nNumElemSeg = 0;
+ sal_uInt16 nNumElemMemSeg = 0;
+ sal_uInt16 nElemSizeSeg = 2;
+
+ if ( SeekToContent( DFF_Prop_pSegmentInfo, rIn ) )
+ rIn >> nNumElemSeg >> nNumElemMemSeg >> nElemSizeSeg;
+ if ( nNumElemSeg )
+ {
+ sal_Int16 nCommand;
+ sal_Int16 nCnt;
+ aSegments.realloc( nNumElemSeg );
+ for ( i = 0; i < nNumElemSeg; i++ )
+ {
+ rIn >> nTmp;
+ nCommand = EnhancedCustomShapeSegmentCommand::UNKNOWN;
+ nCnt = (sal_Int16)( nTmp & 0xfff );
+ switch( nTmp >> 12 )
+ {
+ case 0x0: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break;
+ case 0x1: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break; // seems to the relative lineto
+ case 0x4: nCommand = EnhancedCustomShapeSegmentCommand::MOVETO; if ( !nCnt ) nCnt = 1; break;
+ case 0x2: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break;
+ case 0x3: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break; // seems to be the relative curveto
+ case 0x8: nCommand = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; nCnt = 0; break;
+ case 0x6: nCommand = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; nCnt = 0; break;
+ case 0xa:
+ case 0xb:
+ {
+ switch ( ( nTmp >> 8 ) & 0xf )
+ {
+ case 0x0:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::LINETO;
+ if ( !nCnt )
+ nCnt = 1;
+ }
+ break;
+ case 0x1:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
+ nCnt = ( nTmp & 0xff ) / 3;
+ }
+ break;
+ case 0x2:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
+ nCnt = ( nTmp & 0xff ) / 3;
+ }
+ break;
+ case 0x3:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::ARCTO;
+ nCnt = ( nTmp & 0xff ) >> 2;
+ };
+ break;
+ case 0x4:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::ARC;
+ nCnt = ( nTmp & 0xff ) >> 2;
+ }
+ break;
+ case 0x5:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
+ nCnt = ( nTmp & 0xff ) >> 2;
+ }
+ break;
+ case 0x6:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
+ nCnt = ( nTmp & 0xff ) >> 2;
+ }
+ break;
+ case 0x7:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
+ nCnt = nTmp & 0xff;
+ }
+ break;
+ case 0x8:
+ {
+ nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
+ nCnt = nTmp & 0xff;
+ }
+ break;
+ case 0xa: nCommand = EnhancedCustomShapeSegmentCommand::NOFILL; nCnt = 0; break;
+ case 0xb: nCommand = EnhancedCustomShapeSegmentCommand::NOSTROKE; nCnt = 0; break;
+ }
+ }
+ break;
+ }
+ // if the command is unknown, we will store all the data in nCnt, so it will be possible to export without loss
+ if ( nCommand == EnhancedCustomShapeSegmentCommand::UNKNOWN )
+ nCnt = (sal_Int16)nTmp;
+ aSegments[ i ].Command = nCommand;
+ aSegments[ i ].Count = nCnt;
+ }
+ }
+ const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
+ aProp.Name = sSegments;
+ aProp.Value <<= aSegments;
+ aPathPropVec.push_back( aProp );
+ }
+ // Path/StretchX
+ if ( IsProperty( DFF_Prop_stretchPointX ) )
+ {
+ const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
+ sal_Int32 nStretchX = GetPropertyValue( DFF_Prop_stretchPointX, 0 );
+ aProp.Name = sStretchX;
+ aProp.Value <<= nStretchX;
+ aPathPropVec.push_back( aProp );
+ }
+ // Path/StretchX
+ if ( IsProperty( DFF_Prop_stretchPointY ) )
+ {
+ const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
+ sal_Int32 nStretchY = GetPropertyValue( DFF_Prop_stretchPointY, 0 );
+ aProp.Name = sStretchY;
+ aProp.Value <<= nStretchY;
+ aPathPropVec.push_back( aProp );
+ }
+ // Path/TextFrames
+ if ( IsProperty( DFF_Prop_textRectangles ) )
+ {
+ sal_uInt16 i;
+ sal_uInt16 nNumElem = 0;
+ sal_uInt16 nNumElemMem = 0;
+ sal_uInt16 nElemSize = 16;
+
+ if ( SeekToContent( DFF_Prop_textRectangles, rIn ) )
+ rIn >> nNumElem >> nNumElemMem >> nElemSize;
+ if ( nElemSize == 16 )
+ {
+ sal_Int32 nLeft, nTop, nRight, nBottom;
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem );
+ for ( i = 0; i < nNumElem; i++ )
+ {
+ rIn >> nLeft
+ >> nTop
+ >> nRight
+ >> nBottom;
+
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.First, nLeft );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.Second, nTop );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.First, nRight );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.Second, nBottom);
+ }
+ const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
+ aProp.Name = sTextFrames;
+ aProp.Value <<= aTextFrames;
+ aPathPropVec.push_back( aProp );
+ }
+ }
+ //Path/GluePoints
+ if ( IsProperty( DFF_Prop_connectorPoints ) )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
+
+ sal_uInt16 i;
+ sal_uInt16 nNumElemVert = 0;
+ sal_uInt16 nNumElemMemVert = 0;
+ sal_uInt16 nElemSizeVert = 8;
+
+ if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) )
+ rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
+
+ sal_Int32 nX, nY;
+ sal_Int16 nTmpA, nTmpB;
+ aGluePoints.realloc( nNumElemVert );
+ for ( i = 0; i < nNumElemVert; i++ )
+ {
+ if ( nElemSizeVert == 8 )
+ {
+ rIn >> nX
+ >> nY;
+ }
+ else
+ {
+ rIn >> nTmpA
+ >> nTmpB;
+
+ nX = nTmpA;
+ nY = nTmpB;
+ }
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First, nX );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY );
+ }
+ const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
+ aProp.Name = sGluePoints;
+ aProp.Value <<= aGluePoints;
+ aPathPropVec.push_back( aProp );
+ }
+ if ( IsProperty( DFF_Prop_connectorType ) )
+ {
+ sal_Int16 nGluePointType = (sal_uInt16)GetPropertyValue( DFF_Prop_connectorType );
+ const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
+ aProp.Name = sGluePointType;
+ aProp.Value <<= nGluePointType;
+ aPathPropVec.push_back( aProp );
+ }
+ // pushing the whole Path element
+ if ( aPathPropVec.size() )
+ {
+ const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
+ PropSeq aPathPropSeq( aPathPropVec.size() );
+ aIter = aPathPropVec.begin();
+ aEnd = aPathPropVec.end();
+ beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
+ while ( aIter != aEnd )
+ *pPathValues++ = *aIter++;
+ aProp.Name = sPath;
+ aProp.Value <<= aPathPropSeq;
+ aPropVec.push_back( aProp );
+ }
+ }
+ /////////////////////////////////////////
+ // "TextPath" PropertySequence element //
+ /////////////////////////////////////////
+ sal_Bool bTextPathOn = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x4000 ) != 0;
+ if ( bTextPathOn )
+ {
+ PropVec aTextPathPropVec;
+
+ // TextPath
+ const rtl::OUString sTextPathOn( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
+ aProp.Name = sTextPathOn;
+ aProp.Value <<= bTextPathOn;
+ aTextPathPropVec.push_back( aProp );
+
+ // TextPathMode
+ const rtl::OUString sTextPathMode( RTL_CONSTASCII_USTRINGPARAM ( "TextPathMode" ) );
+ sal_Bool bTextPathFitPath = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x100 ) != 0;
+
+ sal_Bool bTextPathFitShape;
+ if ( IsHardAttribute( DFF_Prop_gtextFStretch ) )
+ bTextPathFitShape = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x400 ) != 0;
+ else
+ {
+ bTextPathFitShape = true;
+ switch( rObjData.eShapeType )
+ {
+ case mso_sptTextArchUpCurve :
+ case mso_sptTextArchDownCurve :
+ case mso_sptTextCircleCurve :
+ case mso_sptTextButtonCurve :
+ bTextPathFitShape = false;
+ default : break;
+ }
+ }
+ EnhancedCustomShapeTextPathMode eTextPathMode( EnhancedCustomShapeTextPathMode_NORMAL );
+ if ( bTextPathFitShape )
+ eTextPathMode = EnhancedCustomShapeTextPathMode_SHAPE;
+ else if ( bTextPathFitPath )
+ eTextPathMode = EnhancedCustomShapeTextPathMode_PATH;
+ aProp.Name = sTextPathMode;
+ aProp.Value <<= eTextPathMode;
+ aTextPathPropVec.push_back( aProp );
+
+ // ScaleX
+ const rtl::OUString sTextPathScaleX( RTL_CONSTASCII_USTRINGPARAM ( "ScaleX" ) );
+ sal_Bool bTextPathScaleX = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x40 ) != 0;
+ aProp.Name = sTextPathScaleX;
+ aProp.Value <<= bTextPathScaleX;
+ aTextPathPropVec.push_back( aProp );
+ // SameLetterHeights
+ const rtl::OUString sSameLetterHeight( RTL_CONSTASCII_USTRINGPARAM ( "SameLetterHeights" ) );
+ sal_Bool bSameLetterHeight = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x80 ) != 0;
+ aProp.Name = sSameLetterHeight;
+ aProp.Value <<= bSameLetterHeight;
+ aTextPathPropVec.push_back( aProp );
+
+ // pushing the whole TextPath element
+ const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
+ PropSeq aTextPathPropSeq( aTextPathPropVec.size() );
+ aIter = aTextPathPropVec.begin();
+ aEnd = aTextPathPropVec.end();
+ beans::PropertyValue* pTextPathValues = aTextPathPropSeq.getArray();
+ while ( aIter != aEnd )
+ *pTextPathValues++ = *aIter++;
+ aProp.Name = sTextPath;
+ aProp.Value <<= aTextPathPropSeq;
+ aPropVec.push_back( aProp );
+ }
+ ////////////////////////
+ // "AdjustmentValues" // The AdjustmentValues are imported at last, because depending to the type of the
+ //////////////////////// handle (POLAR) we will convert the adjustment value from a fixed float to double
+
+ // checking the last used adjustment handle, so we can determine how many handles are to allocate
+ sal_Int32 i = DFF_Prop_adjust10Value;
+ while ( ( i >= DFF_Prop_adjustValue ) && !IsProperty( i ) )
+ i--;
+ sal_Int32 nAdjustmentValues = ( i - DFF_Prop_adjustValue ) + 1;
+ if ( nAdjustmentValues )
+ {
+ uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq( nAdjustmentValues );
+ while( --nAdjustmentValues >= 0 )
+ {
+ sal_Int32 nValue = 0;
+ beans::PropertyState ePropertyState = beans::PropertyState_DEFAULT_VALUE;
+ if ( IsProperty( i ) )
+ {
+ nValue = GetPropertyValue( i );
+ ePropertyState = beans::PropertyState_DIRECT_VALUE;
+ }
+ if ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << ( i - DFF_Prop_adjustValue ) ) )
+ {
+ double fValue = nValue;
+ fValue /= 65536;
+ aAdjustmentSeq[ nAdjustmentValues ].Value <<= fValue;
+ }
+ else
+ aAdjustmentSeq[ nAdjustmentValues ].Value <<= nValue;
+ aAdjustmentSeq[ nAdjustmentValues ].State = ePropertyState;
+ i--;
+ }
+ const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
+ aProp.Name = sAdjustmentValues;
+ aProp.Value <<= aAdjustmentSeq;
+ aPropVec.push_back( aProp );
+ }
+
+ // creating the whole property set
+ PropSeq aSeq( aPropVec.size() );
+ beans::PropertyValue* pValues = aSeq.getArray();
+ aIter = aPropVec.begin();
+ aEnd = aPropVec.end();
+ while ( aIter != aEnd )
+ *pValues++ = *aIter++;
+ rSet.Put( SdrCustomShapeGeometryItem( aSeq ) );
+}
+
+void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet ) const
+{
+ Rectangle aEmptyRect;
+ DffRecordHeader aHdTemp;
+ DffObjData aDffObjTemp( aHdTemp, aEmptyRect, 0 );
+ ApplyAttributes( rIn, rSet, aDffObjTemp );
+}
+
+void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
+{
+// MapUnit eMap( rManager.GetModel()->GetScaleUnit() );
+
+ sal_Bool bHasShadow = sal_False;
+
+ for ( void* pDummy = ((DffPropertyReader*)this)->First(); pDummy; pDummy = ((DffPropertyReader*)this)->Next() )
+ {
+ UINT32 nRecType = GetCurKey();
+ UINT32 nContent = mpContents[ nRecType ];
+ switch ( nRecType )
+ {
+ case DFF_Prop_gtextSize :
+ rSet.Put( SvxFontHeightItem( rManager.ScalePt( nContent ), 100, EE_CHAR_FONTHEIGHT ) );
+ break;
+ // GeoText
+ case DFF_Prop_gtextFStrikethrough :
+ {
+ if ( nContent & 0x20 )
+ rSet.Put( SvxWeightItem( nContent ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
+ if ( nContent & 0x10 )
+ rSet.Put( SvxPostureItem( nContent ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
+ if ( nContent & 0x08 )
+ rSet.Put( SvxUnderlineItem( nContent ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
+ if ( nContent & 0x40 )
+ rSet.Put(SvxShadowedItem( nContent != 0, EE_CHAR_SHADOW ) );
+// if ( nContent & 0x02 )
+// rSet.Put( SvxCaseMapItem( nContent ? SVX_CASEMAP_KAPITAELCHEN : SVX_CASEMAP_NOT_MAPPED ) );
+ if ( nContent & 0x01 )
+ rSet.Put( SvxCrossedOutItem( nContent ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) );
+ }
+ break;
+
+ case DFF_Prop_fillColor :
+ rSet.Put( XFillColorItem( String(), rManager.MSO_CLR_ToColor( nContent, DFF_Prop_fillColor ) ) );
+ break;
+
+ // ShadowStyle
+ case DFF_Prop_shadowType :
+ {
+ MSO_ShadowType eShadowType = (MSO_ShadowType)nContent;
+ if( eShadowType != mso_shadowOffset )
+ {
+ // mso_shadowDouble
+ // mso_shadowRich
+ // mso_shadowEmbossOrEngrave
+ // koennen wir nicht, kreiere Default-Schatten mit default-
+ // Abstand
+ rSet.Put( SdrShadowXDistItem( 35 ) ); // 0,35 mm Schattendistanz
+ rSet.Put( SdrShadowYDistItem( 35 ) );
+ }
+ }
+ break;
+ case DFF_Prop_shadowColor :
+ rSet.Put( SdrShadowColorItem( String(), rManager.MSO_CLR_ToColor( nContent, DFF_Prop_shadowColor ) ) );
+ break;
+ case DFF_Prop_shadowOpacity :
+ rSet.Put( SdrShadowTransparenceItem( (sal_uInt16)( ( 0x10000 - nContent ) / 655 ) ) );
+ break;
+ case DFF_Prop_shadowOffsetX :
+ {
+ INT32 nVal = (INT32)nContent;
+ rManager.ScaleEmu( nVal );
+ if ( nVal )
+ rSet.Put( SdrShadowXDistItem( nVal ) );
+ }
+ break;
+ case DFF_Prop_shadowOffsetY :
+ {
+ INT32 nVal = (INT32)nContent;
+ rManager.ScaleEmu( nVal );
+ if ( nVal )
+ rSet.Put( SdrShadowYDistItem( nVal ) );
+ }
+ break;
+ case DFF_Prop_fshadowObscured :
+ {
+ bHasShadow = ( nContent & 2 ) != 0;
+ if ( bHasShadow )
+ {
+ if ( !IsProperty( DFF_Prop_shadowOffsetX ) )
+ rSet.Put( SdrShadowXDistItem( 35 ) );
+ if ( !IsProperty( DFF_Prop_shadowOffsetY ) )
+ rSet.Put( SdrShadowYDistItem( 35 ) );
+ }
+ }
+ break;
+ }
+ }
+
+ if ( bHasShadow )
+ {
+ // #160376# sj: activating shadow only if fill and or linestyle is used
+ // this is required because of the latest drawing layer core changes.
+ // Issue i104085 is related to this.
+ UINT32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
+ if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( rObjData.eShapeType ))
+ nLineFlags &= ~0x08;
+ UINT32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
+ if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType ))
+ nFillFlags &= ~0x10;
+ if ( nFillFlags & 0x10 )
+ {
+ MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
+ switch( eMSO_FillType )
+ {
+ case mso_fillSolid :
+ case mso_fillPattern :
+ case mso_fillTexture :
+ case mso_fillPicture :
+ case mso_fillShade :
+ case mso_fillShadeCenter :
+ case mso_fillShadeShape :
+ case mso_fillShadeScale :
+ case mso_fillShadeTitle :
+ break;
+ // case mso_fillBackground :
+ default:
+ nFillFlags &=~0x10; // no fillstyle used
+ break;
+ }
+ }
+ if ( ( ( nLineFlags & 0x08 ) == 0 ) && ( ( nFillFlags & 0x10 ) == 0 ) ) // if there is no fillstyle and linestyle
+ bHasShadow = sal_False; // we are turning shadow off.
+
+ if ( bHasShadow )
+ rSet.Put( SdrShadowItem( bHasShadow ) );
+ }
+ ApplyLineAttributes( rSet, rObjData.eShapeType ); // #i28269#
+ ApplyFillAttributes( rIn, rSet, rObjData );
+ if ( rObjData.eShapeType != mso_sptNil )
+ {
+ ApplyCustomShapeGeometryAttributes( rIn, rSet, rObjData );
+ ApplyCustomShapeTextAttributes( rSet );
+ }
+}
+
+//---------------------------------------------------------------------------
+//- Record Manager ----------------------------------------------------------
+//---------------------------------------------------------------------------
+
+DffRecordList::DffRecordList( DffRecordList* pList ) :
+ nCount ( 0 ),
+ nCurrent ( 0 ),
+ pPrev ( pList ),
+ pNext ( NULL )
+{
+ if ( pList )
+ pList->pNext = this;
+}
+
+DffRecordList::~DffRecordList()
+{
+ delete pNext;
+}
+
+DffRecordManager::DffRecordManager() :
+ DffRecordList ( NULL ),
+ pCList ( (DffRecordList*)this )
+{
+}
+
+DffRecordManager::DffRecordManager( SvStream& rIn ) :
+ DffRecordList ( NULL ),
+ pCList ( (DffRecordList*)this )
+{
+ Consume( rIn );
+}
+
+DffRecordManager::~DffRecordManager()
+{
+};
+
+
+void DffRecordManager::Consume( SvStream& rIn, BOOL bAppend, UINT32 nStOfs )
+{
+ if ( !bAppend )
+ Clear();
+ UINT32 nOldPos = rIn.Tell();
+ if ( !nStOfs )
+ {
+ DffRecordHeader aHd;
+ rIn >> aHd;
+ if ( aHd.nRecVer == DFF_PSFLAG_CONTAINER )
+ nStOfs = aHd.GetRecEndFilePos();
+ }
+ if ( nStOfs )
+ {
+ pCList = (DffRecordList*)this;
+ while ( pCList->pNext )
+ pCList = pCList->pNext;
+ while ( ( rIn.GetError() == 0 ) && ( ( rIn.Tell() + 8 ) <= nStOfs ) )
+ {
+ if ( pCList->nCount == DFF_RECORD_MANAGER_BUF_SIZE )
+ pCList = new DffRecordList( pCList );
+ rIn >> pCList->mHd[ pCList->nCount ];
+ pCList->mHd[ pCList->nCount++ ].SeekToEndOfRecord( rIn );
+ }
+ rIn.Seek( nOldPos );
+ }
+}
+
+void DffRecordManager::Clear()
+{
+ pCList = (DffRecordList*)this;
+ delete pNext, pNext = NULL;
+ nCurrent = 0;
+ nCount = 0;
+}
+
+DffRecordHeader* DffRecordManager::Current()
+{
+ DffRecordHeader* pRet = NULL;
+ if ( pCList->nCurrent < pCList->nCount )
+ pRet = &pCList->mHd[ pCList->nCurrent ];
+ return pRet;
+}
+
+DffRecordHeader* DffRecordManager::First()
+{
+ DffRecordHeader* pRet = NULL;
+ pCList = (DffRecordList*)this;
+ if ( pCList->nCount )
+ {
+ pCList->nCurrent = 0;
+ pRet = &pCList->mHd[ 0 ];
+ }
+ return pRet;
+}
+
+DffRecordHeader* DffRecordManager::Next()
+{
+ DffRecordHeader* pRet = NULL;
+ UINT32 nC = pCList->nCurrent + 1;
+ if ( nC < pCList->nCount )
+ {
+ pCList->nCurrent++;
+ pRet = &pCList->mHd[ nC ];
+ }
+ else if ( pCList->pNext )
+ {
+ pCList = pCList->pNext;
+ pCList->nCurrent = 0;
+ pRet = &pCList->mHd[ 0 ];
+ }
+ return pRet;
+}
+
+DffRecordHeader* DffRecordManager::Prev()
+{
+ DffRecordHeader* pRet = NULL;
+ UINT32 nCur = pCList->nCurrent;
+ if ( !nCur && pCList->pPrev )
+ {
+ pCList = pCList->pPrev;
+ nCur = pCList->nCount;
+ }
+ if ( nCur-- )
+ {
+ pCList->nCurrent = nCur;
+ pRet = &pCList->mHd[ nCur ];
+ }
+ return pRet;
+}
+
+DffRecordHeader* DffRecordManager::Last()
+{
+ DffRecordHeader* pRet = NULL;
+ while ( pCList->pNext )
+ pCList = pCList->pNext;
+ UINT32 nCnt = pCList->nCount;
+ if ( nCnt-- )
+ {
+ pCList->nCurrent = nCnt;
+ pRet = &pCList->mHd[ nCnt ];
+ }
+ return pRet;
+}
+
+BOOL DffRecordManager::SeekToContent( SvStream& rIn, UINT16 nRecId, DffSeekToContentMode eMode )
+{
+ DffRecordHeader* pHd = GetRecordHeader( nRecId, eMode );
+ if ( pHd )
+ {
+ pHd->SeekToContent( rIn );
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+DffRecordHeader* DffRecordManager::GetRecordHeader( UINT16 nRecId, DffSeekToContentMode eMode )
+{
+ UINT32 nOldCurrent = pCList->nCurrent;
+ DffRecordList* pOldList = pCList;
+ DffRecordHeader* pHd;
+
+ if ( eMode == SEEK_FROM_BEGINNING )
+ pHd = First();
+ else
+ pHd = Next();
+
+ while ( pHd )
+ {
+ if ( pHd->nRecType == nRecId )
+ break;
+ pHd = Next();
+ }
+ if ( !pHd && eMode == SEEK_FROM_CURRENT_AND_RESTART )
+ {
+ DffRecordHeader* pBreak = &pOldList->mHd[ nOldCurrent ];
+ pHd = First();
+ if ( pHd )
+ {
+ while ( pHd != pBreak )
+ {
+ if ( pHd->nRecType == nRecId )
+ break;
+ pHd = Next();
+ }
+ if ( pHd->nRecType != nRecId )
+ pHd = NULL;
+ }
+ }
+ if ( !pHd )
+ {
+ pCList = pOldList;
+ pOldList->nCurrent = nOldCurrent;
+ }
+ return pHd;
+}
+
+//---------------------------------------------------------------------------
+// private Methoden
+//---------------------------------------------------------------------------
+
+struct EscherBlipCacheEntry
+{
+ ByteString aUniqueID;
+ sal_uInt32 nBlip;
+
+ EscherBlipCacheEntry( sal_uInt32 nBlipId, const ByteString& rUniqueID ) :
+ aUniqueID( rUniqueID ),
+ nBlip( nBlipId ) {}
+};
+
+void SvxMSDffManager::Scale( sal_Int32& rVal ) const
+{
+ if ( bNeedMap )
+ rVal = BigMulDiv( rVal, nMapMul, nMapDiv );
+}
+
+void SvxMSDffManager::Scale( Point& rPos ) const
+{
+ rPos.X() += nMapXOfs;
+ rPos.Y() += nMapYOfs;
+ if ( bNeedMap )
+ {
+ rPos.X() = BigMulDiv( rPos.X(), nMapMul, nMapDiv );
+ rPos.Y() = BigMulDiv( rPos.Y(), nMapMul, nMapDiv );
+ }
+}
+
+void SvxMSDffManager::Scale( Size& rSiz ) const
+{
+ if ( bNeedMap )
+ {
+ rSiz.Width() = BigMulDiv( rSiz.Width(), nMapMul, nMapDiv );
+ rSiz.Height() = BigMulDiv( rSiz.Height(), nMapMul, nMapDiv );
+ }
+}
+
+void SvxMSDffManager::Scale( Rectangle& rRect ) const
+{
+ rRect.Move( nMapXOfs, nMapYOfs );
+ if ( bNeedMap )
+ {
+ rRect.Left() =BigMulDiv( rRect.Left() , nMapMul, nMapDiv );
+ rRect.Top() =BigMulDiv( rRect.Top() , nMapMul, nMapDiv );
+ rRect.Right() =BigMulDiv( rRect.Right() , nMapMul, nMapDiv );
+ rRect.Bottom()=BigMulDiv( rRect.Bottom(), nMapMul, nMapDiv );
+ }
+}
+
+void SvxMSDffManager::Scale( Polygon& rPoly ) const
+{
+ if ( !bNeedMap )
+ return;
+ USHORT nPointAnz = rPoly.GetSize();
+ for ( USHORT nPointNum = 0; nPointNum < nPointAnz; nPointNum++ )
+ Scale( rPoly[ nPointNum ] );
+}
+
+void SvxMSDffManager::Scale( PolyPolygon& rPoly ) const
+{
+ if ( !bNeedMap )
+ return;
+ USHORT nPolyAnz = rPoly.Count();
+ for ( USHORT nPolyNum = 0; nPolyNum < nPolyAnz; nPolyNum++ )
+ Scale( rPoly[ nPolyNum ] );
+}
+
+void SvxMSDffManager::ScaleEmu( sal_Int32& rVal ) const
+{
+ rVal = BigMulDiv( rVal, nEmuMul, nEmuDiv );
+}
+
+UINT32 SvxMSDffManager::ScalePt( UINT32 nVal ) const
+{
+ MapUnit eMap = pSdrModel->GetScaleUnit();
+ Fraction aFact( GetMapFactor( MAP_POINT, eMap ).X() );
+ long aMul = aFact.GetNumerator();
+ long aDiv = aFact.GetDenominator() * 65536;
+ aFact = Fraction( aMul, aDiv ); // nochmal versuchen zu kuerzen
+ return BigMulDiv( nVal, aFact.GetNumerator(), aFact.GetDenominator() );
+}
+
+INT32 SvxMSDffManager::ScalePoint( INT32 nVal ) const
+{
+ return BigMulDiv( nVal, nPntMul, nPntDiv );
+};
+
+void SvxMSDffManager::SetModel(SdrModel* pModel, long nApplicationScale)
+{
+ pSdrModel = pModel;
+ if( pModel && (0 < nApplicationScale) )
+ {
+ // PPT arbeitet nur mit Einheiten zu 576DPI
+ // WW hingegen verwendet twips, dh. 1440DPI.
+ MapUnit eMap = pSdrModel->GetScaleUnit();
+ Fraction aFact( GetMapFactor(MAP_INCH, eMap).X() );
+ long nMul=aFact.GetNumerator();
+ long nDiv=aFact.GetDenominator()*nApplicationScale;
+ aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
+ // Bei 100TH_MM -> 2540/576=635/144
+ // Bei Twip -> 1440/576=5/2
+ nMapMul = aFact.GetNumerator();
+ nMapDiv = aFact.GetDenominator();
+ bNeedMap = nMapMul!=nMapDiv;
+
+ // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
+ // 1mm=36000emu, 1twip=635emu
+ aFact=GetMapFactor(MAP_100TH_MM,eMap).X();
+ nMul=aFact.GetNumerator();
+ nDiv=aFact.GetDenominator()*360;
+ aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
+ // Bei 100TH_MM -> 1/360
+ // Bei Twip -> 14,40/(25,4*360)=144/91440=1/635
+ nEmuMul=aFact.GetNumerator();
+ nEmuDiv=aFact.GetDenominator();
+
+ // Und noch was fuer typografische Points
+ aFact=GetMapFactor(MAP_POINT,eMap).X();
+ nPntMul=aFact.GetNumerator();
+ nPntDiv=aFact.GetDenominator();
+ }
+ else
+ {
+ pModel = 0;
+ nMapMul = nMapDiv = nMapXOfs = nMapYOfs = nEmuMul = nEmuDiv = nPntMul = nPntDiv = 0;
+ bNeedMap = FALSE;
+ }
+}
+
+BOOL SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, UINT32 nId ) const
+{
+ BOOL bRet = FALSE;
+ if ( mpFidcls )
+ {
+ UINT32 nMerk = rSt.Tell();
+ UINT32 nShapeId, nSec = ( nId >> 10 ) - 1;
+ if ( nSec < mnIdClusters )
+ {
+ sal_IntPtr nOfs = (sal_IntPtr)maDgOffsetTable.Get( mpFidcls[ nSec ].dgid );
+ if ( nOfs )
+ {
+ rSt.Seek( nOfs );
+ DffRecordHeader aEscherF002Hd;
+ rSt >> aEscherF002Hd;
+ ULONG nEscherF002End = aEscherF002Hd.GetRecEndFilePos();
+ DffRecordHeader aEscherObjListHd;
+ while ( rSt.Tell() < nEscherF002End )
+ {
+ rSt >> aEscherObjListHd;
+ if ( aEscherObjListHd.nRecVer != 0xf )
+ aEscherObjListHd.SeekToEndOfRecord( rSt );
+ else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer )
+ {
+ DffRecordHeader aShapeHd;
+ if ( SeekToRec( rSt, DFF_msofbtSp, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) )
+ {
+ rSt >> nShapeId;
+ if ( nId == nShapeId )
+ {
+ aEscherObjListHd.SeekToBegOfRecord( rSt );
+ bRet = TRUE;
+ break;
+ }
+ }
+ aEscherObjListHd.SeekToEndOfRecord( rSt );
+ }
+ }
+ }
+ }
+ if ( !bRet )
+ rSt.Seek( nMerk );
+ }
+ return bRet;
+}
+
+FASTBOOL SvxMSDffManager::SeekToRec( SvStream& rSt, USHORT nRecId, ULONG nMaxFilePos, DffRecordHeader* pRecHd, ULONG nSkipCount ) const
+{
+ FASTBOOL bRet = FALSE;
+ ULONG nFPosMerk = rSt.Tell(); // FilePos merken fuer ggf. spaetere Restauration
+ DffRecordHeader aHd;
+ do
+ {
+ rSt >> aHd;
+ if ( aHd.nRecType == nRecId )
+ {
+ if ( nSkipCount )
+ nSkipCount--;
+ else
+ {
+ bRet = TRUE;
+ if ( pRecHd != NULL )
+ *pRecHd = aHd;
+ else
+ aHd.SeekToBegOfRecord( rSt );
+ }
+ }
+ if ( !bRet )
+ aHd.SeekToEndOfRecord( rSt );
+ }
+ while ( rSt.GetError() == 0 && rSt.Tell() < nMaxFilePos && !bRet );
+ if ( !bRet )
+ rSt.Seek( nFPosMerk ); // FilePos restaurieren
+ return bRet;
+}
+
+FASTBOOL SvxMSDffManager::SeekToRec2( USHORT nRecId1, USHORT nRecId2, ULONG nMaxFilePos, DffRecordHeader* pRecHd, ULONG nSkipCount ) const
+{
+ FASTBOOL bRet = FALSE;
+ ULONG nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer ggf. spaetere Restauration
+ DffRecordHeader aHd;
+ do
+ {
+ rStCtrl >> aHd;
+ if ( aHd.nRecType == nRecId1 || aHd.nRecType == nRecId2 )
+ {
+ if ( nSkipCount )
+ nSkipCount--;
+ else
+ {
+ bRet = TRUE;
+ if ( pRecHd )
+ *pRecHd = aHd;
+ else
+ aHd.SeekToBegOfRecord( rStCtrl );
+ }
+ }
+ if ( !bRet )
+ aHd.SeekToEndOfRecord( rStCtrl );
+ }
+ while ( rStCtrl.GetError() == 0 && rStCtrl.Tell() < nMaxFilePos && !bRet );
+ if ( !bRet )
+ rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
+ return bRet;
+}
+
+
+FASTBOOL SvxMSDffManager::GetColorFromPalette( USHORT /* nNum */, Color& rColor ) const
+{
+ // diese Methode ist in der zum Excel-Import
+ // abgeleiteten Klasse zu ueberschreiben...
+ rColor.SetColor( COL_WHITE );
+ return TRUE;
+}
+
+// sj: the documentation is not complete, especially in ppt the normal rgb for text
+// color is written as 0xfeRRGGBB, this can't be explained by the documentation, nearly
+// every bit in the upper code is set -> so there seems to be a special handling for
+// ppt text colors, i decided not to fix this in MSO_CLR_ToColor because of possible
+// side effects, instead MSO_TEXT_CLR_ToColor is called for PPT text colors, to map
+// the color code to something that behaves like the other standard color codes used by
+// fill and line color
+Color SvxMSDffManager::MSO_TEXT_CLR_ToColor( sal_uInt32 nColorCode ) const
+{
+ // Fuer Textfarben: Header ist 0xfeRRGGBB
+ if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 )
+ nColorCode &= 0x00ffffff;
+ else
+ {
+ // for colorscheme colors the color index are the lower three bits of the upper byte
+ if ( ( nColorCode & 0xf8000000 ) == 0 ) // this must be a colorscheme index
+ {
+ nColorCode >>= 24;
+ nColorCode |= 0x8000000;
+ }
+ }
+ return MSO_CLR_ToColor( nColorCode );
+}
+
+Color SvxMSDffManager::MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContentProperty ) const
+{
+ Color aColor( mnDefaultColor );
+
+ // Fuer Textfarben: Header ist 0xfeRRGGBB
+ if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 ) // sj: it needs to be checked if 0xfe is used in
+ nColorCode &= 0x00ffffff; // other cases than ppt text -> if not this code can be removed
+
+ sal_uInt8 nUpper = (sal_uInt8)( nColorCode >> 24 );
+
+ // sj: below change from 0x1b to 0x19 was done because of i84812 (0x02 -> rgb color),
+ // now I have some problems to fix i104685 (there the color value is 0x02000000 whichs requires
+ // a 0x2 scheme color to be displayed properly), the color docu seems to be incomplete
+ if( nUpper & 0x19 ) // if( nUpper & 0x1f )
+ {
+ if( ( nUpper & 0x08 ) || ( ( nUpper & 0x10 ) == 0 ) )
+ {
+ // SCHEMECOLOR
+ if ( !GetColorFromPalette( ( nUpper & 8 ) ? (sal_uInt16)nColorCode : nUpper, aColor ) )
+ {
+ switch( nContentProperty )
+ {
+ case DFF_Prop_pictureTransparent :
+ case DFF_Prop_shadowColor :
+ case DFF_Prop_fillBackColor :
+ case DFF_Prop_fillColor :
+ aColor = Color( COL_WHITE );
+ break;
+ case DFF_Prop_lineColor :
+ {
+ aColor = Color( COL_BLACK );
+ }
+ break;
+ }
+ }
+ }
+ else // SYSCOLOR
+ {
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+// UINT16 nParameter = (BYTE)( nColorCode >> 16); // SJ: nice compiler optimization bug on windows, though downcasting
+ UINT16 nParameter = sal_uInt16(( nColorCode >> 16 ) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o
+ UINT16 nFunctionBits = (UINT16)( ( nColorCode & 0x00000f00 ) >> 8 );
+ UINT16 nAdditionalFlags = (UINT16)( ( nColorCode & 0x0000f000) >> 8 );
+ UINT16 nColorIndex = sal_uInt16(nColorCode & 0x00ff);
+ UINT32 nPropColor = 0;
+
+ sal_uInt16 nCProp = 0;
+
+ switch ( nColorIndex )
+ {
+ case mso_syscolorButtonFace : aColor = rStyleSettings.GetFaceColor(); break;
+ case mso_syscolorWindowText : aColor = rStyleSettings.GetWindowTextColor(); break;
+ case mso_syscolorMenu : aColor = rStyleSettings.GetMenuColor(); break;
+ case mso_syscolor3DLight :
+ case mso_syscolorButtonHighlight :
+ case mso_syscolorHighlight : aColor = rStyleSettings.GetHighlightColor(); break;
+ case mso_syscolorHighlightText : aColor = rStyleSettings.GetHighlightTextColor(); break;
+ case mso_syscolorCaptionText : aColor = rStyleSettings.GetMenuTextColor(); break;
+ case mso_syscolorActiveCaption : aColor = rStyleSettings.GetHighlightColor(); break;
+ case mso_syscolorButtonShadow : aColor = rStyleSettings.GetShadowColor(); break;
+ case mso_syscolorButtonText : aColor = rStyleSettings.GetButtonTextColor(); break;
+ case mso_syscolorGrayText : aColor = rStyleSettings.GetDeactiveColor(); break;
+ case mso_syscolorInactiveCaption : aColor = rStyleSettings.GetDeactiveColor(); break;
+ case mso_syscolorInactiveCaptionText : aColor = rStyleSettings.GetDeactiveColor(); break;
+ case mso_syscolorInfoBackground : aColor = rStyleSettings.GetFaceColor(); break;
+ case mso_syscolorInfoText : aColor = rStyleSettings.GetInfoTextColor(); break;
+ case mso_syscolorMenuText : aColor = rStyleSettings.GetMenuTextColor(); break;
+ case mso_syscolorScrollbar : aColor = rStyleSettings.GetFaceColor(); break;
+ case mso_syscolorWindow : aColor = rStyleSettings.GetWindowColor(); break;
+ case mso_syscolorWindowFrame : aColor = rStyleSettings.GetWindowColor(); break;
+
+ case mso_colorFillColor :
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
+ nCProp = DFF_Prop_fillColor;
+ }
+ break;
+ case mso_colorLineOrFillColor : // ( use the line color only if there is a line )
+ {
+ if ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 )
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
+ nCProp = DFF_Prop_lineColor;
+ }
+ else
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
+ nCProp = DFF_Prop_fillColor;
+ }
+ }
+ break;
+ case mso_colorLineColor :
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
+ nCProp = DFF_Prop_lineColor;
+ }
+ break;
+ case mso_colorShadowColor :
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_shadowColor, 0x808080 );
+ nCProp = DFF_Prop_shadowColor;
+ }
+ break;
+ case mso_colorThis : // ( use this color ... )
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
+ nCProp = DFF_Prop_fillColor;
+ }
+ break;
+ case mso_colorFillBackColor :
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_fillBackColor, 0xffffff );
+ nCProp = DFF_Prop_fillBackColor;
+ }
+ break;
+ case mso_colorLineBackColor :
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_lineBackColor, 0xffffff );
+ nCProp = DFF_Prop_lineBackColor;
+ }
+ break;
+ case mso_colorFillThenLine : // ( use the fillcolor unless no fill and line )
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
+ nCProp = DFF_Prop_fillColor;
+ }
+ break;
+ case mso_colorIndexMask : // ( extract the color index ) ?
+ {
+ nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
+ nCProp = DFF_Prop_fillColor;
+ }
+ break;
+ }
+ if ( nCProp && ( nPropColor & 0x10000000 ) == 0 ) // beware of looping recursive
+ aColor = MSO_CLR_ToColor( nPropColor, nCProp );
+
+ if( nAdditionalFlags & 0x80 ) // make color gray
+ {
+ UINT8 nZwi = aColor.GetLuminance();
+ aColor = Color( nZwi, nZwi, nZwi );
+ }
+ switch( nFunctionBits )
+ {
+ case 0x01 : // darken color by parameter
+ {
+ aColor.SetRed( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetRed() ) >> 8 ) );
+ aColor.SetGreen( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetGreen() ) >> 8 ) );
+ aColor.SetBlue( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetBlue() ) >> 8 ) );
+ }
+ break;
+ case 0x02 : // lighten color by parameter
+ {
+ UINT16 nInvParameter = ( 0x00ff - nParameter ) * 0xff;
+ aColor.SetRed( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetRed() ) ) >> 8 ) );
+ aColor.SetGreen( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetGreen() ) ) >> 8 ) );
+ aColor.SetBlue( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetBlue() ) ) >> 8 ) );
+ }
+ break;
+ case 0x03 : // add grey level RGB(p,p,p)
+ {
+ INT16 nR = (INT16)aColor.GetRed() + (INT16)nParameter;
+ INT16 nG = (INT16)aColor.GetGreen() + (INT16)nParameter;
+ INT16 nB = (INT16)aColor.GetBlue() + (INT16)nParameter;
+ if ( nR > 0x00ff )
+ nR = 0x00ff;
+ if ( nG > 0x00ff )
+ nG = 0x00ff;
+ if ( nB > 0x00ff )
+ nB = 0x00ff;
+ aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
+ }
+ break;
+ case 0x04 : // substract grey level RGB(p,p,p)
+ {
+ INT16 nR = (INT16)aColor.GetRed() - (INT16)nParameter;
+ INT16 nG = (INT16)aColor.GetGreen() - (INT16)nParameter;
+ INT16 nB = (INT16)aColor.GetBlue() - (INT16)nParameter;
+ if ( nR < 0 )
+ nR = 0;
+ if ( nG < 0 )
+ nG = 0;
+ if ( nB < 0 )
+ nB = 0;
+ aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
+ }
+ break;
+ case 0x05 : // substract from grey level RGB(p,p,p)
+ {
+ INT16 nR = (INT16)nParameter - (INT16)aColor.GetRed();
+ INT16 nG = (INT16)nParameter - (INT16)aColor.GetGreen();
+ INT16 nB = (INT16)nParameter - (INT16)aColor.GetBlue();
+ if ( nR < 0 )
+ nR = 0;
+ if ( nG < 0 )
+ nG = 0;
+ if ( nB < 0 )
+ nB = 0;
+ aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
+ }
+ break;
+ case 0x06 : // per component: black if < p, white if >= p
+ {
+ aColor.SetRed( aColor.GetRed() < nParameter ? 0x00 : 0xff );
+ aColor.SetGreen( aColor.GetGreen() < nParameter ? 0x00 : 0xff );
+ aColor.SetBlue( aColor.GetBlue() < nParameter ? 0x00 : 0xff );
+ }
+ break;
+ }
+ if ( nAdditionalFlags & 0x40 ) // top-bit invert
+ aColor = Color( aColor.GetRed() ^ 0x80, aColor.GetGreen() ^ 0x80, aColor.GetBlue() ^ 0x80 );
+
+ if ( nAdditionalFlags & 0x20 ) // invert color
+ aColor = Color(0xff - aColor.GetRed(), 0xff - aColor.GetGreen(), 0xff - aColor.GetBlue());
+ }
+ }
+ else if ( ( nUpper & 4 ) && ( ( nColorCode & 0xfffff8 ) == 0 ) )
+ { // case of nUpper == 4 powerpoint takes this as agrument for a colorschemecolor
+ GetColorFromPalette( nUpper, aColor );
+ }
+ else // hart attributiert, eventuell mit Hinweis auf SYSTEMRGB
+ aColor = Color( (BYTE)nColorCode, (BYTE)( nColorCode >> 8 ), (BYTE)( nColorCode >> 16 ) );
+ return aColor;
+}
+
+FASTBOOL SvxMSDffManager::ReadDffString(SvStream& rSt, String& rTxt) const
+{
+ FASTBOOL bRet=FALSE;
+ DffRecordHeader aStrHd;
+ if( !ReadCommonRecordHeader(aStrHd, rSt) )
+ rSt.Seek( aStrHd.nFilePos );
+ else if ( aStrHd.nRecType == DFF_PST_TextBytesAtom || aStrHd.nRecType == DFF_PST_TextCharsAtom )
+ {
+ FASTBOOL bUniCode=aStrHd.nRecType==DFF_PST_TextCharsAtom;
+ bRet=TRUE;
+ ULONG nBytes = aStrHd.nRecLen;
+ MSDFFReadZString( rSt, rTxt, nBytes, bUniCode );
+ if( !bUniCode )
+ {
+ for ( xub_StrLen n = 0; n < nBytes; n++ )
+ {
+ if( rTxt.GetChar( n ) == 0x0B )
+ rTxt.SetChar( n, ' ' ); // Weicher Umbruch
+ // TODO: Zeilenumbruch im Absatz via Outliner setzen.
+ }
+ }
+ aStrHd.SeekToEndOfRecord( rSt );
+ }
+ else
+ aStrHd.SeekToBegOfRecord( rSt );
+ return bRet;
+}
+
+// sj: I just want to set a string for a text object that may contain multiple
+// paragraphs. If I now take a look at the follwing code I get the impression that
+// our outliner is too complicate to be used properly,
+void SvxMSDffManager::ReadObjText( const String& rText, SdrObject* pObj ) const
+{
+ SdrTextObj* pText = PTR_CAST( SdrTextObj, pObj );
+ if ( pText )
+ {
+ SdrOutliner& rOutliner = pText->ImpGetDrawOutliner();
+ rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
+
+ BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
+ rOutliner.SetUpdateMode( FALSE );
+ rOutliner.SetVertical( pText->IsVerticalWriting() );
+
+ sal_uInt16 nParaIndex = 0;
+ sal_uInt32 nParaSize;
+ const sal_Unicode* pCurrent, *pBuf = rText.GetBuffer();
+ const sal_Unicode* pEnd = rText.GetBuffer() + rText.Len();
+
+ while( pBuf < pEnd )
+ {
+ pCurrent = pBuf;
+
+ for ( nParaSize = 0; pBuf < pEnd; )
+ {
+ sal_Unicode nChar = *pBuf++;
+ if ( nChar == 0xa )
+ {
+ if ( ( pBuf < pEnd ) && ( *pBuf == 0xd ) )
+ pBuf++;
+ break;
+ }
+ else if ( nChar == 0xd )
+ {
+ if ( ( pBuf < pEnd ) && ( *pBuf == 0xa ) )
+ pBuf++;
+ break;
+ }
+ else
+ nParaSize++;
+ }
+ ESelection aSelection( nParaIndex, 0, nParaIndex, 0 );
+ String aParagraph( pCurrent, (sal_uInt16)nParaSize );
+ if ( !nParaIndex && !aParagraph.Len() ) // SJ: we are crashing if the first paragraph is empty ?
+ aParagraph += (sal_Unicode)' '; // otherwise these two lines can be removed.
+ rOutliner.Insert( aParagraph, nParaIndex, 0 );
+ rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() );
+
+ SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() );
+ if ( !aSelection.nStartPos )
+ aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, FALSE ) );
+ aSelection.nStartPos = 0;
+ rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection );
+ nParaIndex++;
+ }
+ OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
+ rOutliner.Clear();
+ rOutliner.SetUpdateMode( bOldUpdateMode );
+ pText->SetOutlinerParaObject( pNewText );
+ }
+}
+
+FASTBOOL SvxMSDffManager::ReadObjText(SvStream& rSt, SdrObject* pObj) const
+{
+ FASTBOOL bRet=FALSE;
+ SdrTextObj* pText = PTR_CAST(SdrTextObj, pObj);
+ if( pText )
+ {
+ DffRecordHeader aTextHd;
+ if( !ReadCommonRecordHeader(aTextHd, rSt) )
+ rSt.Seek( aTextHd.nFilePos );
+ else if ( aTextHd.nRecType==DFF_msofbtClientTextbox )
+ {
+ bRet=TRUE;
+ ULONG nRecEnd=aTextHd.GetRecEndFilePos();
+ DffRecordHeader aHd;
+ String aText;
+// UINT32 nInvent=pText->GetObjInventor();
+// UINT16 nIdent=pText->GetObjIdentifier();
+
+ SdrOutliner& rOutliner=pText->ImpGetDrawOutliner();
+// sal_Int16 nMinDepth = rOutliner.GetMinDepth();
+ USHORT nOutlMode = rOutliner.GetMode();
+
+ { // Wohl 'nen kleiner Bug der EditEngine, das die
+ // Absastzattribute bei Clear() nicht entfernt werden.
+ FASTBOOL bClearParaAttribs = TRUE;
+ rOutliner.SetStyleSheet( 0, NULL );
+ SfxItemSet aSet(rOutliner.GetEmptyItemSet());
+ aSet.Put(SvxColorItem( COL_BLACK ));
+ rOutliner.SetParaAttribs(0,aSet);
+ pText->SetMergedItemSet(aSet);
+
+ bClearParaAttribs = FALSE;
+ if( bClearParaAttribs )
+ {
+ // Wohl 'nen kleiner Bug der EditEngine, dass die
+ // Absastzattribute bei Clear() nicht entfernt werden.
+ rOutliner.SetParaAttribs(0,rOutliner.GetEmptyItemSet());
+ }
+ }
+ rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
+
+// ULONG nFilePosMerker=rSt.Tell();
+ ////////////////////////////////////
+ // TextString und MetaChars lesen //
+ ////////////////////////////////////
+ do
+ {
+ if( !ReadCommonRecordHeader(aHd, rSt) )
+ rSt.Seek( aHd.nFilePos );
+ else
+ {
+ switch (aHd.nRecType)
+ {
+ //case TextHeaderAtom
+ //case TextSpecInfoAtom
+ case DFF_PST_TextBytesAtom:
+ case DFF_PST_TextCharsAtom:
+ {
+ aHd.SeekToBegOfRecord(rSt);
+ ReadDffString(rSt, aText);
+ }
+ break;
+ case DFF_PST_TextRulerAtom :
+ {
+ UINT16 nLen = (UINT16)aHd.nRecLen;
+ if(nLen)
+ {
+ UINT16 nVal1, nVal2, nVal3;
+ UINT16 nDefaultTab = 2540; // PPT def: 1 Inch //rOutliner.GetDefTab();
+ UINT16 nMostrightTab = 0;
+ SfxItemSet aSet(rOutliner.GetEmptyItemSet());
+ SvxTabStopItem aTabItem(0, 0, SVX_TAB_ADJUST_DEFAULT, EE_PARA_TABS);
+
+ rSt >> nVal1;
+ rSt >> nVal2;
+ nLen -= 4;
+
+ // Allg. TAB verstellt auf Wert in nVal3
+ if(nLen && (nVal1 & 0x0001))
+ {
+ rSt >> nVal3;
+ nLen -= 2;
+ nDefaultTab = (UINT16)(((UINT32)nVal3 * 1000) / 240);
+ }
+
+ // Weitere, frei gesetzte TABs
+ if(nLen && (nVal1 & 0x0004))
+ {
+ rSt >> nVal1;
+ nLen -= 2;
+
+ // fest gesetzte TABs importieren
+ while(nLen && nVal1--)
+ {
+ rSt >> nVal2;
+ rSt >> nVal3;
+ nLen -= 4;
+
+ UINT16 nNewTabPos = (UINT16)(((UINT32)nVal2 * 1000) / 240);
+ if(nNewTabPos > nMostrightTab)
+ nMostrightTab = nNewTabPos;
+
+ SvxTabStop aTabStop(nNewTabPos);
+ aTabItem.Insert(aTabStop);
+ }
+ }
+
+ // evtl. noch default-TABs ergaenzen (immer)
+ UINT16 nObjWidth = sal_uInt16(pObj->GetSnapRect().GetWidth() + 1);
+ UINT16 nDefaultTabPos = nDefaultTab;
+
+ while(nDefaultTabPos <= nObjWidth && nDefaultTabPos <= nMostrightTab)
+ nDefaultTabPos =
+ nDefaultTabPos + nDefaultTab;
+
+ while(nDefaultTabPos <= nObjWidth)
+ {
+ SvxTabStop aTabStop(nDefaultTabPos);
+ aTabItem.Insert(aTabStop);
+ nDefaultTabPos =
+ nDefaultTabPos + nDefaultTab;
+ }
+
+ // Falls TABs angelegt wurden, setze diese
+ if(aTabItem.Count())
+ {
+ aSet.Put(aTabItem);
+ rOutliner.SetParaAttribs(0, aSet);
+ }
+ }
+ }
+ break;
+ }
+ aHd.SeekToEndOfRecord( rSt );
+ }
+ }
+ while ( rSt.GetError() == 0 && rSt.Tell() < nRecEnd );
+
+ ////////////////////////
+ // SHIFT-Ret ersetzen //
+ ////////////////////////
+ if ( aText.Len() )
+ {
+ aText += ' ';
+ aText.SetChar( aText.Len()-1, 0x0D );
+ rOutliner.SetText( aText, rOutliner.GetParagraph( 0 ) );
+
+ // SHIFT-Ret ersetzen im Outliner
+ if(aText.GetTokenCount(0x0B) > 1)
+ {
+ UINT32 nParaCount = rOutliner.GetParagraphCount();
+ for(UINT16 a=0;a<nParaCount;a++)
+ {
+ Paragraph* pActPara = rOutliner.GetParagraph(a);
+ String aParaText = rOutliner.GetText(pActPara);
+ for(UINT16 b=0;b<aParaText.Len();b++)
+ {
+ if( aParaText.GetChar( b ) == 0x0B)
+ {
+ ESelection aSelection(a, b, a, b+1);
+ rOutliner.QuickInsertLineBreak(aSelection);
+ }
+ }
+ }
+ }
+ }
+ OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
+ rOutliner.Init( nOutlMode );
+ pText->NbcSetOutlinerParaObject(pNewText);
+ }
+ else
+ aTextHd.SeekToBegOfRecord(rSt);
+
+ }
+ return bRet;
+}
+
+//static
+void SvxMSDffManager::MSDFFReadZString( SvStream& rIn, String& rStr,
+ ULONG nRecLen, FASTBOOL bUniCode )
+{
+ sal_uInt16 nLen = (sal_uInt16)nRecLen;
+ if( nLen )
+ {
+ if ( bUniCode )
+ nLen >>= 1;
+
+ String sBuf;
+ sal_Unicode* pBuf = sBuf.AllocBuffer( nLen );
+
+ if( bUniCode )
+ {
+ rIn.Read( (sal_Char*)pBuf, nLen << 1 );
+
+#ifdef OSL_BIGENDIAN
+ for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf )
+ *pBuf = SWAPSHORT( *pBuf );
+#endif // ifdef OSL_BIGENDIAN
+ }
+ else
+ {
+ // use the String-Data as buffer for the 8bit characters and
+ // change then all to unicode
+ sal_Char* pReadPos = ((sal_Char*)pBuf) + nLen;
+ rIn.Read( (sal_Char*)pReadPos, nLen );
+ for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf, ++pReadPos )
+ *pBuf = ByteString::ConvertToUnicode( *pReadPos, RTL_TEXTENCODING_MS_1252 );
+ }
+
+ rStr = sBuf.EraseTrailingChars( 0 );
+ }
+ else
+ rStr.Erase();
+}
+
+SdrObject* SvxMSDffManager::ImportFontWork( SvStream& rStCt, SfxItemSet& rSet, Rectangle& rBoundRect ) const
+{
+ SdrObject* pRet = NULL;
+ String aObjectText;
+ String aFontName;
+ BOOL bTextRotate = FALSE;
+
+ ((SvxMSDffManager*)this)->mnFix16Angle = 0; // we don't want to use this property in future
+ if ( SeekToContent( DFF_Prop_gtextUNICODE, rStCt ) )
+ MSDFFReadZString( rStCt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), TRUE );
+ if ( SeekToContent( DFF_Prop_gtextFont, rStCt ) )
+ MSDFFReadZString( rStCt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), TRUE );
+ if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 )
+ {
+ // Text ist senkrecht formatiert, Box Kippen
+ INT32 nHalfWidth = ( rBoundRect.GetWidth() + 1) >> 1;
+ INT32 nHalfHeight = ( rBoundRect.GetHeight() + 1) >> 1;
+ Point aTopLeft( rBoundRect.Left() + nHalfWidth - nHalfHeight,
+ rBoundRect.Top() + nHalfHeight - nHalfWidth);
+ Size aNewSize( rBoundRect.GetHeight(), rBoundRect.GetWidth() );
+ Rectangle aNewRect( aTopLeft, aNewSize );
+ rBoundRect = aNewRect;
+
+ String aSrcText( aObjectText );
+ aObjectText.Erase();
+ for( UINT16 a = 0; a < aSrcText.Len(); a++ )
+ {
+ aObjectText += aSrcText.GetChar( a );
+ aObjectText += '\n';
+ }
+ rSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) );
+ bTextRotate = TRUE;
+ }
+ if ( aObjectText.Len() )
+ { // FontWork-Objekt Mit dem Text in aObjectText erzeugen
+ SdrObject* pNewObj = new SdrRectObj( OBJ_TEXT, rBoundRect );
+ if( pNewObj )
+ {
+ pNewObj->SetModel( pSdrModel );
+ ((SdrRectObj*)pNewObj)->SetText( aObjectText );
+ SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
+ rSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
+ rSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
+ rSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
+ rSet.Put( SvxFontItem( FAMILY_DONTKNOW, aFontName, String(),
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
+
+ pNewObj->SetMergedItemSet(rSet);
+
+ pRet = pNewObj->ConvertToPolyObj( FALSE, FALSE );
+ if( !pRet )
+ pRet = pNewObj;
+ else
+ {
+ pRet->NbcSetSnapRect( rBoundRect );
+ SdrObject::Free( pNewObj );
+ }
+ if( bTextRotate )
+ {
+ double a = 9000 * nPi180;
+ pRet->NbcRotate( rBoundRect.Center(), 9000, sin( a ), cos( a ) );
+ }
+ }
+ }
+ return pRet;
+}
+
+static Size lcl_GetPrefSize(const Graphic& rGraf, MapMode aWanted)
+{
+ MapMode aPrefMapMode(rGraf.GetPrefMapMode());
+ if (aPrefMapMode == aWanted)
+ return rGraf.GetPrefSize();
+ Size aRetSize;
+ if (aPrefMapMode == MAP_PIXEL)
+ {
+ aRetSize = Application::GetDefaultDevice()->PixelToLogic(
+ rGraf.GetPrefSize(), aWanted);
+ }
+ else
+ {
+ aRetSize = Application::GetDefaultDevice()->LogicToLogic(
+ rGraf.GetPrefSize(), rGraf.GetPrefMapMode(), aWanted);
+ }
+ return aRetSize;
+}
+
+// sj: if the parameter pSet is null, then the resulting crop bitmap will be stored in rGraf,
+// otherwise rGraf is untouched and pSet is used to store the corresponding SdrGrafCropItem
+static void lcl_ApplyCropping( const DffPropSet& rPropSet, SfxItemSet* pSet, Graphic& rGraf )
+{
+ sal_Int32 nCropTop = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromTop, 0 );
+ sal_Int32 nCropBottom = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromBottom, 0 );
+ sal_Int32 nCropLeft = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromLeft, 0 );
+ sal_Int32 nCropRight = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromRight, 0 );
+
+ if( nCropTop || nCropBottom || nCropLeft || nCropRight )
+ {
+ double fFactor;
+ Size aCropSize;
+ BitmapEx aCropBitmap;
+ sal_uInt32 nTop( 0 ), nBottom( 0 ), nLeft( 0 ), nRight( 0 );
+
+ if ( pSet ) // use crop attributes ?
+ aCropSize = lcl_GetPrefSize( rGraf, MAP_100TH_MM );
+ else
+ {
+ aCropBitmap = rGraf.GetBitmapEx();
+ aCropSize = aCropBitmap.GetSizePixel();
+ }
+ if ( nCropTop )
+ {
+ fFactor = (double)nCropTop / 65536.0;
+ nTop = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
+ }
+ if ( nCropBottom )
+ {
+ fFactor = (double)nCropBottom / 65536.0;
+ nBottom = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
+ }
+ if ( nCropLeft )
+ {
+ fFactor = (double)nCropLeft / 65536.0;
+ nLeft = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
+ }
+ if ( nCropRight )
+ {
+ fFactor = (double)nCropRight / 65536.0;
+ nRight = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
+ }
+ if ( pSet ) // use crop attributes ?
+ pSet->Put( SdrGrafCropItem( nLeft, nTop, nRight, nBottom ) );
+ else
+ {
+ Rectangle aCropRect( nLeft, nTop, aCropSize.Width() - nRight, aCropSize.Height() - nBottom );
+ aCropBitmap.Crop( aCropRect );
+ rGraf = aCropBitmap;
+ }
+ }
+}
+
+SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, const DffObjData& rObjData ) const
+{
+ SdrObject* pRet = NULL;
+ String aFilename;
+ String aLinkFileName, aLinkFilterName;
+ Rectangle aVisArea;
+
+ MSO_BlipFlags eFlags = (MSO_BlipFlags)GetPropertyValue( DFF_Prop_pibFlags, mso_blipflagDefault );
+ sal_uInt32 nBlipId = GetPropertyValue( DFF_Prop_pib, 0 );
+ sal_Bool bGrfRead = sal_False,
+
+ // Grafik verlinkt
+ bLinkGrf = 0 != ( eFlags & mso_blipflagLinkToFile );
+ {
+ Graphic aGraf; // be sure this graphic is deleted before swapping out
+ if( SeekToContent( DFF_Prop_pibName, rSt ) )
+ MSDFFReadZString( rSt, aFilename, GetPropertyValue( DFF_Prop_pibName ), TRUE );
+
+ // UND, ODER folgendes:
+ if( !( eFlags & mso_blipflagDoNotSave ) ) // Grafik embedded
+ {
+ bGrfRead = GetBLIP( nBlipId, aGraf, &aVisArea );
+ if ( !bGrfRead )
+ {
+ /*
+ Still no luck, lets look at the end of this record for a FBSE pool,
+ this fallback is a specific case for how word does it sometimes
+ */
+ rObjData.rSpHd.SeekToEndOfRecord( rSt );
+ DffRecordHeader aHd;
+ rSt >> aHd;
+ if( DFF_msofbtBSE == aHd.nRecType )
+ {
+ const ULONG nSkipBLIPLen = 20;
+ const ULONG nSkipShapePos = 4;
+ const ULONG nSkipBLIP = 4;
+ const ULONG nSkip =
+ nSkipBLIPLen + 4 + nSkipShapePos + 4 + nSkipBLIP;
+
+ if (nSkip <= aHd.nRecLen)
+ {
+ rSt.SeekRel(nSkip);
+ if (0 == rSt.GetError())
+ bGrfRead = GetBLIPDirect( rSt, aGraf, &aVisArea );
+ }
+ }
+ }
+ }
+ if ( bGrfRead )
+ {
+ // the writer is doing it's own cropping, so this part affects only impress and calc
+ if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_CROP_BITMAPS )
+ lcl_ApplyCropping( *this, ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ? &rSet : NULL, aGraf );
+
+ if ( IsProperty( DFF_Prop_pictureTransparent ) )
+ {
+ UINT32 nTransColor = GetPropertyValue( DFF_Prop_pictureTransparent, 0 );
+
+ if ( aGraf.GetType() == GRAPHIC_BITMAP )
+ {
+ BitmapEx aBitmapEx( aGraf.GetBitmapEx() );
+ Bitmap aBitmap( aBitmapEx.GetBitmap() );
+ Bitmap aMask( aBitmap.CreateMask( MSO_CLR_ToColor( nTransColor, DFF_Prop_pictureTransparent ), 9 ) );
+ if ( aBitmapEx.IsTransparent() )
+ aMask.CombineSimple( aBitmapEx.GetMask(), BMP_COMBINE_OR );
+ aGraf = BitmapEx( aBitmap, aMask );
+ }
+ }
+
+ sal_Int32 nContrast = GetPropertyValue( DFF_Prop_pictureContrast, 0x10000 );
+ /*
+ 0x10000 is msoffice 50%
+ < 0x10000 is in units of 1/50th of 0x10000 per 1%
+ > 0x10000 is in units where
+ a msoffice x% is stored as 50/(100-x) * 0x10000
+
+ plus, a (ui) microsoft % ranges from 0 to 100, OOO
+ from -100 to 100, so also normalize into that range
+ */
+ if ( nContrast > 0x10000 )
+ {
+ double fX = nContrast;
+ fX /= 0x10000;
+ fX /= 51; // 50 + 1 to round
+ fX = 1/fX;
+ nContrast = static_cast<sal_Int32>(fX);
+ nContrast -= 100;
+ nContrast = -nContrast;
+ nContrast = (nContrast-50)*2;
+ }
+ else if ( nContrast == 0x10000 )
+ nContrast = 0;
+ else
+ {
+ nContrast *= 101; //100 + 1 to round
+ nContrast /= 0x10000;
+ nContrast -= 100;
+ }
+ sal_Int16 nBrightness = (sal_Int16)( (sal_Int32)GetPropertyValue( DFF_Prop_pictureBrightness, 0 ) / 327 );
+ sal_Int32 nGamma = GetPropertyValue( DFF_Prop_pictureGamma, 0x10000 );
+ GraphicDrawMode eDrawMode = GRAPHICDRAWMODE_STANDARD;
+ switch ( GetPropertyValue( DFF_Prop_pictureActive ) & 6 )
+ {
+ case 4 : eDrawMode = GRAPHICDRAWMODE_GREYS; break;
+ case 6 : eDrawMode = GRAPHICDRAWMODE_MONO; break;
+ case 0 :
+ {
+ //office considers the converted values of (in OOo) 70 to be the
+ //"watermark" values, which can vary slightly due to rounding from the
+ //above values
+ if (( nContrast == -70 ) && ( nBrightness == 70 ))
+ {
+ nContrast = 0;
+ nBrightness = 0;
+ eDrawMode = GRAPHICDRAWMODE_WATERMARK;
+ };
+ }
+ break;
+ }
+
+ if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) )
+ {
+ if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 )
+ {
+ if ( nBrightness )
+ rSet.Put( SdrGrafLuminanceItem( nBrightness ) );
+ if ( nContrast )
+ rSet.Put( SdrGrafContrastItem( (sal_Int16)nContrast ) );
+ if ( nGamma != 0x10000 )
+ rSet.Put( SdrGrafGamma100Item( nGamma / 655 ) );
+ if ( eDrawMode != GRAPHICDRAWMODE_STANDARD )
+ rSet.Put( SdrGrafModeItem( eDrawMode ) );
+ }
+ else
+ {
+ if ( eDrawMode == GRAPHICDRAWMODE_WATERMARK )
+ {
+ nContrast = 60;
+ nBrightness = 70;
+ eDrawMode = GRAPHICDRAWMODE_STANDARD;
+ }
+ switch ( aGraf.GetType() )
+ {
+ case GRAPHIC_BITMAP :
+ {
+ BitmapEx aBitmapEx( aGraf.GetBitmapEx() );
+ if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
+ aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, FALSE );
+ if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
+ aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
+ else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
+ aBitmapEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
+ aGraf = aBitmapEx;
+
+ }
+ break;
+
+ case GRAPHIC_GDIMETAFILE :
+ {
+ GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() );
+ if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
+ aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, FALSE );
+ if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
+ aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS );
+ else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
+ aGdiMetaFile.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
+ aGraf = aGdiMetaFile;
+ }
+ break;
+ default: break;
+ }
+ }
+ }
+ }
+
+ // sollte es ein OLE-Object sein?
+ if( bGrfRead && !bLinkGrf && IsProperty( DFF_Prop_pictureId ) )
+ {
+ // TODO/LATER: in future probably the correct aspect should be provided here
+ sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
+ // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method
+ pRet = ImportOLE( GetPropertyValue( DFF_Prop_pictureId ), aGraf, rObjData.aBoundRect, aVisArea, rObjData.nCalledByGroup, nAspect );
+ // <--
+ }
+ if( !pRet )
+ {
+ pRet = new SdrGrafObj;
+ if( bGrfRead )
+ ((SdrGrafObj*)pRet)->SetGraphic( aGraf );
+
+ if( bLinkGrf && !bGrfRead ) // sj: #i55484# if the graphic was embedded ( bGrfRead == true ) then
+ { // we do not need to set a link. TODO: not to lose the information where the graphic is linked from
+ UniString aName( ::URIHelper::SmartRel2Abs( INetURLObject(maBaseURL), aFilename, URIHelper::GetMaybeFileHdl(), true, false,
+ INetURLObject::WAS_ENCODED,
+ INetURLObject::DECODE_UNAMBIGUOUS ) );
+
+ String aFilterName;
+ INetURLObject aURLObj( aName );
+
+ if( aURLObj.GetProtocol() == INET_PROT_NOT_VALID )
+ {
+ String aValidURL;
+
+ if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aValidURL ) )
+ aURLObj = INetURLObject( aValidURL );
+ }
+
+ if( aURLObj.GetProtocol() != INET_PROT_NOT_VALID )
+ {
+ GraphicFilter* pGrfFilter = GetGrfFilter();
+ aFilterName = pGrfFilter->GetImportFormatName(
+ pGrfFilter->GetImportFormatNumberForShortName( aURLObj.getExtension() ) );
+ }
+
+ aLinkFileName = aName;
+ aLinkFilterName = aFilterName;
+ }
+ }
+
+ // set the size from BLIP if there is one
+ if ( pRet && bGrfRead && !aVisArea.IsEmpty() )
+ pRet->SetBLIPSizeRectangle( aVisArea );
+
+ if ( !pRet->GetName().Len() ) // SJ 22.02.00 : PPT OLE IMPORT:
+ { // name is already set in ImportOLE !!
+ // JP 01.12.99: SetName before SetModel - because in the other order the Bug 70098 is active
+ if ( ( eFlags & mso_blipflagType ) != mso_blipflagComment )
+ {
+ INetURLObject aURL;
+ aURL.SetSmartURL( aFilename );
+ pRet->SetName( aURL.getBase() );
+ }
+ else
+ pRet->SetName( aFilename );
+ }
+ }
+ pRet->SetModel( pSdrModel ); // fuer GraphicLink erforderlich
+ pRet->SetLogicRect( rObjData.aBoundRect );
+
+ if ( pRet->ISA( SdrGrafObj ) )
+ {
+ if( aLinkFileName.Len() )
+ ((SdrGrafObj*)pRet)->SetGraphicLink( aLinkFileName, aLinkFilterName );
+
+ if ( bLinkGrf && !bGrfRead )
+ {
+ ((SdrGrafObj*)pRet)->ForceSwapIn();
+ Graphic aGraf(((SdrGrafObj*)pRet)->GetGraphic());
+ lcl_ApplyCropping( *this, &rSet, aGraf );
+ }
+ ((SdrGrafObj*)pRet)->ForceSwapOut();
+ }
+
+ return pRet;
+}
+
+// PptSlidePersistEntry& rPersistEntry, SdPage* pPage
+SdrObject* SvxMSDffManager::ImportObj( SvStream& rSt, void* pClientData,
+ Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup, sal_Int32* pShapeId )
+{
+ SdrObject* pRet = NULL;
+ DffRecordHeader aObjHd;
+ rSt >> aObjHd;
+ if ( aObjHd.nRecType == DFF_msofbtSpgrContainer )
+ {
+ pRet = ImportGroup( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
+ }
+ else if ( aObjHd.nRecType == DFF_msofbtSpContainer )
+ {
+ pRet = ImportShape( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
+ }
+ aObjHd.SeekToBegOfRecord( rSt ); // FilePos restaurieren
+ return pRet;
+}
+
+SdrObject* SvxMSDffManager::ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
+ Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
+ int nCalledByGroup, sal_Int32* pShapeId )
+{
+ SdrObject* pRet = NULL;
+
+ if( pShapeId )
+ *pShapeId = 0;
+
+ rHd.SeekToContent( rSt );
+ DffRecordHeader aRecHd; // the first atom has to be the SpContainer for the GroupObject
+ rSt >> aRecHd;
+ if ( aRecHd.nRecType == DFF_msofbtSpContainer )
+ {
+ INT32 nGroupRotateAngle = 0;
+ INT32 nSpFlags = 0;
+ mnFix16Angle = 0;
+ aRecHd.SeekToBegOfRecord( rSt );
+ pRet = ImportObj( rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup + 1, pShapeId );
+ if ( pRet )
+ {
+ nSpFlags = nGroupShapeFlags;
+ nGroupRotateAngle = mnFix16Angle;
+
+ Rectangle aClientRect( rClientRect );
+
+ Rectangle aGlobalChildRect;
+ if ( !nCalledByGroup || rGlobalChildRect.IsEmpty() )
+ aGlobalChildRect = GetGlobalChildAnchor( rHd, rSt, aClientRect );
+ else
+ aGlobalChildRect = rGlobalChildRect;
+
+ if ( ( nGroupRotateAngle > 4500 && nGroupRotateAngle <= 13500 )
+ || ( nGroupRotateAngle > 22500 && nGroupRotateAngle <= 31500 ) )
+ {
+ sal_Int32 nHalfWidth = ( aClientRect.GetWidth() + 1 ) >> 1;
+ sal_Int32 nHalfHeight = ( aClientRect.GetHeight() + 1 ) >> 1;
+ Point aTopLeft( aClientRect.Left() + nHalfWidth - nHalfHeight,
+ aClientRect.Top() + nHalfHeight - nHalfWidth );
+ Size aNewSize( aClientRect.GetHeight(), aClientRect.GetWidth() );
+ Rectangle aNewRect( aTopLeft, aNewSize );
+ aClientRect = aNewRect;
+ }
+
+ // now importing the inner objects of the group
+ aRecHd.SeekToEndOfRecord( rSt );
+ while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aRecHd2;
+ rSt >> aRecHd2;
+ if ( aRecHd2.nRecType == DFF_msofbtSpgrContainer )
+ {
+ Rectangle aGroupClientAnchor, aGroupChildAnchor;
+ GetGroupAnchors( aRecHd2, rSt, aGroupClientAnchor, aGroupChildAnchor, aClientRect, aGlobalChildRect );
+ aRecHd2.SeekToBegOfRecord( rSt );
+ sal_Int32 nShapeId;
+ SdrObject* pTmp = ImportGroup( aRecHd2, rSt, pClientData, aGroupClientAnchor, aGroupChildAnchor, nCalledByGroup + 1, &nShapeId );
+ if ( pTmp )
+ {
+ ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
+ if( nShapeId )
+ insertShapeId( nShapeId, pTmp );
+ }
+ }
+ else if ( aRecHd2.nRecType == DFF_msofbtSpContainer )
+ {
+ aRecHd2.SeekToBegOfRecord( rSt );
+ sal_Int32 nShapeId;
+ SdrObject* pTmp = ImportShape( aRecHd2, rSt, pClientData, aClientRect, aGlobalChildRect, nCalledByGroup + 1, &nShapeId );
+ if ( pTmp )
+ {
+ ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
+ if( nShapeId )
+ insertShapeId( nShapeId, pTmp );
+ }
+ }
+ aRecHd2.SeekToEndOfRecord( rSt );
+ }
+
+ // pRet->NbcSetSnapRect( aGroupBound );
+ if ( nGroupRotateAngle )
+ {
+ double a = nGroupRotateAngle * nPi180;
+ pRet->NbcRotate( aClientRect.Center(), nGroupRotateAngle, sin( a ), cos( a ) );
+ }
+ if ( nSpFlags & SP_FFLIPV ) // Vertikal gespiegelt?
+ { // BoundRect in aBoundRect
+ Point aLeft( aClientRect.Left(), ( aClientRect.Top() + aClientRect.Bottom() ) >> 1 );
+ Point aRight( aLeft.X() + 1000, aLeft.Y() );
+ pRet->NbcMirror( aLeft, aRight );
+ }
+ if ( nSpFlags & SP_FFLIPH ) // Horizontal gespiegelt?
+ { // BoundRect in aBoundRect
+ Point aTop( ( aClientRect.Left() + aClientRect.Right() ) >> 1, aClientRect.Top() );
+ Point aBottom( aTop.X(), aTop.Y() + 1000 );
+ pRet->NbcMirror( aTop, aBottom );
+ }
+ }
+ }
+ return pRet;
+}
+
+SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
+ Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
+ int nCalledByGroup, sal_Int32* pShapeId )
+{
+ SdrObject* pRet = NULL;
+
+ if( pShapeId )
+ *pShapeId = 0;
+
+ rHd.SeekToBegOfRecord( rSt );
+ DffObjData aObjData( rHd, rClientRect, nCalledByGroup );
+ maShapeRecords.Consume( rSt, FALSE );
+ aObjData.bShapeType = maShapeRecords.SeekToContent( rSt, DFF_msofbtSp, SEEK_FROM_BEGINNING );
+ if ( aObjData.bShapeType )
+ {
+ rSt >> aObjData.nShapeId
+ >> aObjData.nSpFlags;
+ aObjData.eShapeType = (MSO_SPT)maShapeRecords.Current()->nRecInstance;
+ }
+ else
+ {
+ aObjData.nShapeId = 0;
+ aObjData.nSpFlags = 0;
+ aObjData.eShapeType = mso_sptNil;
+ }
+
+ if( pShapeId )
+ *pShapeId = aObjData.nShapeId;
+
+ if ( mbTracing )
+ mpTracer->AddAttribute( aObjData.nSpFlags & SP_FGROUP
+ ? rtl::OUString::createFromAscii( "GroupShape" )
+ : rtl::OUString::createFromAscii( "Shape" ),
+ rtl::OUString::valueOf( (sal_Int32)aObjData.nShapeId ) );
+ aObjData.bOpt = maShapeRecords.SeekToContent( rSt, DFF_msofbtOPT, SEEK_FROM_CURRENT_AND_RESTART );
+ if ( aObjData.bOpt )
+ {
+ maShapeRecords.Current()->SeekToBegOfRecord( rSt );
+#ifdef DBG_AUTOSHAPE
+ ReadPropSet( rSt, pClientData, (UINT32)aObjData.eShapeType );
+#else
+ ReadPropSet( rSt, pClientData );
+#endif
+ }
+ else
+ {
+ InitializePropSet(); // get the default PropSet
+ ( (DffPropertyReader*) this )->mnFix16Angle = 0;
+ }
+
+ aObjData.bChildAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtChildAnchor, SEEK_FROM_CURRENT_AND_RESTART );
+ if ( aObjData.bChildAnchor )
+ {
+ INT32 l, o, r, u;
+ rSt >> l >> o >> r >> u;
+ Scale( l );
+ Scale( o );
+ Scale( r );
+ Scale( u );
+ aObjData.aChildAnchor = Rectangle( l, o, r, u );
+ if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
+ {
+ double fl = l;
+ double fo = o;
+ double fWidth = r - l;
+ double fHeight= u - o;
+ double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
+ double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
+ fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
+ fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top();
+ fWidth *= fXScale;
+ fHeight *= fYScale;
+ aObjData.aChildAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
+ }
+ }
+
+ aObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtClientAnchor, SEEK_FROM_CURRENT_AND_RESTART );
+ if ( aObjData.bClientAnchor )
+ ProcessClientAnchor2( rSt, *maShapeRecords.Current(), pClientData, aObjData );
+
+ if ( aObjData.bChildAnchor )
+ aObjData.aBoundRect = aObjData.aChildAnchor;
+
+ if ( aObjData.nSpFlags & SP_FBACKGROUND )
+ aObjData.aBoundRect = Rectangle( Point(), Size( 1, 1 ) );
+
+ Rectangle aTextRect;
+ if ( !aObjData.aBoundRect.IsEmpty() )
+ { // Rotation auf BoundingBox anwenden, BEVOR ien Objekt generiert wurde
+ if( mnFix16Angle )
+ {
+ long nAngle = mnFix16Angle;
+ if ( ( nAngle > 4500 && nAngle <= 13500 ) || ( nAngle > 22500 && nAngle <= 31500 ) )
+ {
+ INT32 nHalfWidth = ( aObjData.aBoundRect.GetWidth() + 1 ) >> 1;
+ INT32 nHalfHeight = ( aObjData.aBoundRect.GetHeight() + 1 ) >> 1;
+ Point aTopLeft( aObjData.aBoundRect.Left() + nHalfWidth - nHalfHeight,
+ aObjData.aBoundRect.Top() + nHalfHeight - nHalfWidth );
+ Size aNewSize( aObjData.aBoundRect.GetHeight(), aObjData.aBoundRect.GetWidth() );
+ Rectangle aNewRect( aTopLeft, aNewSize );
+ aObjData.aBoundRect = aNewRect;
+ }
+ }
+ aTextRect = aObjData.aBoundRect;
+ FASTBOOL bGraphic = IsProperty( DFF_Prop_pib ) ||
+ IsProperty( DFF_Prop_pibName ) ||
+ IsProperty( DFF_Prop_pibFlags );
+
+ if ( aObjData.nSpFlags & SP_FGROUP )
+ {
+ pRet = new SdrObjGroup;
+ /* After CWS aw033 has been integrated, an empty group object
+ cannot store its resulting bounding rectangle anymore. We have
+ to return this rectangle via rClientRect now, but only, if
+ caller has not passed an own bounding ractangle. */
+ if ( rClientRect.IsEmpty() )
+ rClientRect = aObjData.aBoundRect;
+ nGroupShapeFlags = aObjData.nSpFlags; // #73013#
+ }
+ else if ( ( aObjData.eShapeType != mso_sptNil ) || IsProperty( DFF_Prop_pVertices ) || bGraphic )
+ {
+ SfxItemSet aSet( pSdrModel->GetItemPool() );
+
+ sal_Bool bIsConnector = ( ( aObjData.eShapeType >= mso_sptStraightConnector1 ) && ( aObjData.eShapeType <= mso_sptCurvedConnector5 ) );
+ sal_Bool bIsCustomShape = sal_False;
+ sal_Int32 nObjectRotation = mnFix16Angle;
+ sal_uInt32 nSpFlags = aObjData.nSpFlags;
+
+ if ( bGraphic )
+ {
+ pRet = ImportGraphic( rSt, aSet, aObjData ); // SJ: #68396# is no longer true (fixed in ppt2000)
+ ApplyAttributes( rSt, aSet, aObjData );
+ pRet->SetMergedItemSet(aSet);
+ }
+ else if ( aObjData.eShapeType == mso_sptLine )
+ {
+ basegfx::B2DPolygon aPoly;
+ aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Left(), aObjData.aBoundRect.Top()));
+ aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Right(), aObjData.aBoundRect.Bottom()));
+ pRet = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly));
+ pRet->SetModel( pSdrModel );
+ ApplyAttributes( rSt, aSet, aObjData );
+ pRet->SetMergedItemSet(aSet);
+ }
+ else
+ {
+ if ( GetCustomShapeContent( aObjData.eShapeType ) || IsProperty( DFF_Prop_pVertices ) )
+ {
+
+ ApplyAttributes( rSt, aSet, aObjData );
+
+// the com.sun.star.drawing.EnhancedCustomShapeEngine is default, so we do not need to set a hard attribute
+// aSet.Put( SdrCustomShapeEngineItem( String::CreateFromAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) );
+ pRet = new SdrObjCustomShape();
+ pRet->SetModel( pSdrModel );
+
+ sal_Bool bIsFontwork = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) != 0;
+
+ // in case of a FontWork, the text is set by the escher import
+ if ( bIsFontwork )
+ {
+ String aObjectText;
+ String aFontName;
+ MSO_GeoTextAlign eGeoTextAlign;
+
+ if ( SeekToContent( DFF_Prop_gtextFont, rSt ) )
+ {
+ SvxFontItem aLatin(EE_CHAR_FONTINFO), aAsian(EE_CHAR_FONTINFO_CJK), aComplex(EE_CHAR_FONTINFO_CTL);
+ GetDefaultFonts( aLatin, aAsian, aComplex );
+
+ MSDFFReadZString( rSt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), TRUE );
+ aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
+ aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CJK ) );
+ aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
+ PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CTL ) );
+ }
+
+ // SJ: applying fontattributes for Fontwork :
+ if ( IsHardAttribute( DFF_Prop_gtextFItalic ) )
+ aSet.Put( SvxPostureItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0010 ) != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
+
+ if ( IsHardAttribute( DFF_Prop_gtextFBold ) )
+ aSet.Put( SvxWeightItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0020 ) != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
+
+ // SJ TODO: Vertical Writing is not correct, instead this should be
+ // replaced through "CharacterRotation" by 90°, therefore a new Item has to be
+ // supported by svx core, api and xml file format
+ ((SdrObjCustomShape*)pRet)->SetVerticalWriting( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) != 0 );
+
+ if ( SeekToContent( DFF_Prop_gtextUNICODE, rSt ) )
+ {
+ MSDFFReadZString( rSt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), TRUE );
+ ReadObjText( aObjectText, pRet );
+ }
+
+ eGeoTextAlign = ( (MSO_GeoTextAlign)GetPropertyValue( DFF_Prop_gtextAlign, mso_alignTextCenter ) );
+ {
+ SdrTextHorzAdjust eHorzAdjust;
+ switch( eGeoTextAlign )
+ {
+ case mso_alignTextLetterJust :
+ case mso_alignTextWordJust :
+ case mso_alignTextStretch : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break;
+ default:
+ case mso_alignTextInvalid :
+ case mso_alignTextCenter : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break;
+ case mso_alignTextLeft : eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break;
+ case mso_alignTextRight : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break;
+ }
+ aSet.Put( SdrTextHorzAdjustItem( eHorzAdjust ) );
+
+ SdrFitToSizeType eFTS = SDRTEXTFIT_NONE;
+ if ( eGeoTextAlign == mso_alignTextStretch )
+ eFTS = SDRTEXTFIT_ALLLINES;
+ aSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
+ }
+ if ( IsProperty( DFF_Prop_gtextSpacing ) )
+ {
+ sal_Int32 nTextWidth = GetPropertyValue( DFF_Prop_gtextSpacing, 100 < 16 ) / 655;
+ if ( nTextWidth != 100 )
+ aSet.Put( SvxCharScaleWidthItem( (sal_uInt16)nTextWidth, EE_CHAR_FONTWIDTH ) );
+ }
+ if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x1000 ) // SJ: Font Kerning On ?
+ aSet.Put( SvxKerningItem( 1, EE_CHAR_KERNING ) );
+ }
+ pRet->SetMergedItemSet( aSet );
+
+ // sj: taking care of rtl, ltr. In case of fontwork mso. seems not to be able to set
+ // proper text directions, instead the text default is depending to the string.
+ // so we have to calculate the a text direction from string:
+ if ( bIsFontwork )
+ {
+ OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pRet)->GetOutlinerParaObject();
+ if ( pParaObj )
+ {
+ SdrOutliner& rOutliner = ((SdrObjCustomShape*)pRet)->ImpGetDrawOutliner();
+ BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
+ SdrModel* pModel = pRet->GetModel();
+ if ( pModel )
+ rOutliner.SetStyleSheetPool( (SfxStyleSheetPool*)pModel->GetStyleSheetPool() );
+ rOutliner.SetUpdateMode( FALSE );
+ rOutliner.SetText( *pParaObj );
+ VirtualDevice aVirDev( 1 );
+ aVirDev.SetMapMode( MAP_100TH_MM );
+ sal_uInt32 i, nParagraphs = rOutliner.GetParagraphCount();
+ if ( nParagraphs )
+ {
+ sal_Bool bCreateNewParaObject = sal_False;
+ for ( i = 0; i < nParagraphs; i++ )
+ {
+ BOOL bIsRTL = aVirDev.GetTextIsRTL( rOutliner.GetText( rOutliner.GetParagraph( i ) ), 0, STRING_LEN );
+ if ( bIsRTL )
+ {
+ SfxItemSet aSet2( rOutliner.GetParaAttribs( (USHORT)i ) );
+ aSet2.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
+ rOutliner.SetParaAttribs( (USHORT)i, aSet2 );
+ bCreateNewParaObject = sal_True;
+ }
+ }
+ if ( bCreateNewParaObject )
+ {
+ OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
+ rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
+ ((SdrObjCustomShape*)pRet)->NbcSetOutlinerParaObject( pNewText );
+ }
+ }
+ rOutliner.Clear();
+ rOutliner.SetUpdateMode( bOldUpdateMode );
+ }
+ }
+
+ // mso_sptArc special treating:
+ // sj: since we actually can't render the arc because of its weird SnapRect settings,
+ // we will create a new CustomShape, that can be saved/loaded without problems.
+ // We will change the shape type, so this code applys only if importing arcs from msoffice.
+ if ( aObjData.eShapeType == mso_sptArc )
+ {
+ const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
+ const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
+ const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
+ const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
+ const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
+ const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
+ const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
+
+ // before clearing the GeometryItem we have to store the current Coordinates
+ const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
+ Rectangle aPolyBoundRect;
+ if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) )
+ {
+ sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength();
+ XPolygon aXP( (sal_uInt16)nNumElemVert );
+// const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
+ for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ )
+ {
+ Point aP;
+ sal_Int32 nX = 0, nY = 0;
+ seqCoordinates[ nPtNum ].First.Value >>= nX;
+ seqCoordinates[ nPtNum ].Second.Value >>= nY;
+ aP.X() = nX;
+ aP.Y() = nY;
+ aXP[ (sal_uInt16)nPtNum ] = aP;
+ }
+ aPolyBoundRect = Rectangle( aXP.GetBoundRect() );
+ }
+ else
+ aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 ); // defaulting
+
+ // clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry
+ aGeometryItem.ClearPropertyValue( sHandles );
+ aGeometryItem.ClearPropertyValue( sEquations );
+ aGeometryItem.ClearPropertyValue( sViewBox );
+ aGeometryItem.ClearPropertyValue( sPath );
+
+ sal_Int32 nEndAngle = 9000;
+ sal_Int32 nStartAngle = 0;
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
+ if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 )
+ {
+ double fNumber;
+ if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
+ {
+ seqAdjustmentValues[ 0 ].Value >>= fNumber;
+ nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
+ }
+ else
+ {
+ fNumber = 270.0;
+ seqAdjustmentValues[ 0 ].Value <<= fNumber;
+ seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // so this value will properly be stored
+ }
+
+ if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
+ {
+ seqAdjustmentValues[ 1 ].Value >>= fNumber;
+ nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
+ }
+ else
+ {
+ fNumber = 0.0;
+ seqAdjustmentValues[ 0 ].Value <<= fNumber;
+ seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
+ }
+
+ PropertyValue aPropVal;
+ aPropVal.Name = sAdjustmentValues;
+ aPropVal.Value <<= seqAdjustmentValues;
+ aGeometryItem.SetPropertyValue( aPropVal ); // storing the angle attribute
+ }
+ if ( nStartAngle != nEndAngle )
+ {
+ XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2,
+ (USHORT)nStartAngle / 10, (USHORT)nEndAngle / 10, TRUE );
+ Rectangle aPolyPieRect( aXPoly.GetBoundRect() );
+
+ double fYScale, fXScale;
+ double fYOfs, fXOfs;
+
+ Point aP( aObjData.aBoundRect.Center() );
+ Size aS( aObjData.aBoundRect.GetSize() );
+ aP.X() -= aS.Width() / 2;
+ aP.Y() -= aS.Height() / 2;
+ Rectangle aLogicRect( aP, aS );
+
+ fYOfs = fXOfs = 0.0;
+
+ if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() )
+ {
+ fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth();
+ if ( nSpFlags & SP_FFLIPH )
+ fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale;
+ else
+ fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale;
+ }
+ if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() )
+ {
+ fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight();
+ if ( nSpFlags & SP_FFLIPV )
+ fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale;
+ else
+ fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale;
+ }
+
+ fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth();
+ fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight();
+
+ Rectangle aOldBoundRect( aObjData.aBoundRect );
+ aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ),
+ Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) );
+
+ // creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system
+ double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth();
+ double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight();
+ sal_Int32 nLeft = (sal_Int32)(( aPolyPieRect.Left() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
+ sal_Int32 nTop = (sal_Int32)(( aPolyPieRect.Top() - aPolyBoundRect.Top() ) * fTextFrameScaleY );
+ sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
+ sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() ) * fTextFrameScaleY );
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First, nLeft );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second, nTop );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom );
+ PropertyValue aProp;
+ aProp.Name = sTextFrames;
+ aProp.Value <<= aTextFrame;
+ aGeometryItem.SetPropertyValue( sPath, aProp );
+
+ // sj: taking care of the different rotation points, since the new arc is having a bigger snaprect
+ if ( mnFix16Angle )
+ {
+ sal_Int32 nAngle = mnFix16Angle;
+ if ( nSpFlags & SP_FFLIPH )
+ nAngle = 36000 - nAngle;
+ if ( nSpFlags & SP_FFLIPV )
+ nAngle = -nAngle;
+ double a = nAngle * F_PI18000;
+ double ss = sin( a );
+ double cc = cos( a );
+ Point aP1( aOldBoundRect.TopLeft() );
+ Point aC1( aObjData.aBoundRect.Center() );
+ Point aP2( aOldBoundRect.TopLeft() );
+ Point aC2( aOldBoundRect.Center() );
+ RotatePoint( aP1, aC1, ss, cc );
+ RotatePoint( aP2, aC2, ss, cc );
+ aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() );
+ }
+ }
+ ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem );
+ ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
+
+ // now setting a new name, so the above correction is only done once when importing from ms
+ SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ const rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) );
+ PropertyValue aPropVal;
+ aPropVal.Name = sType;
+ aPropVal.Value <<= sName;
+ aGeoName.SetPropertyValue( aPropVal );
+ ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName );
+ }
+ else
+ ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
+
+ pRet->SetSnapRect( aObjData.aBoundRect );
+ EnhancedCustomShape2d aCustomShape2d( pRet );
+ aTextRect = aCustomShape2d.GetTextRect();
+
+ bIsCustomShape = TRUE;
+
+ if( bIsConnector )
+ {
+ if( nObjectRotation )
+ {
+ double a = nObjectRotation * nPi180;
+ pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
+ }
+ // Horizontal gespiegelt?
+ if ( nSpFlags & SP_FFLIPH )
+ {
+ Rectangle aBndRect( pRet->GetSnapRect() );
+ Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
+ Point aBottom( aTop.X(), aTop.Y() + 1000 );
+ pRet->NbcMirror( aTop, aBottom );
+ }
+ // Vertikal gespiegelt?
+ if ( nSpFlags & SP_FFLIPV )
+ {
+ Rectangle aBndRect( pRet->GetSnapRect() );
+ Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
+ Point aRight( aLeft.X() + 1000, aLeft.Y() );
+ pRet->NbcMirror( aLeft, aRight );
+ }
+ basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) );
+ SdrObject::Free( pRet );
+
+ pRet = new SdrEdgeObj();
+ pRet->SetLogicRect( aObjData.aBoundRect );
+
+ // Konnektoren
+ MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight );
+
+ ((SdrEdgeObj*)pRet)->ConnectToNode(TRUE, NULL);
+ ((SdrEdgeObj*)pRet)->ConnectToNode(FALSE, NULL);
+
+ Point aPoint1( aObjData.aBoundRect.TopLeft() );
+ Point aPoint2( aObjData.aBoundRect.BottomRight() );
+
+ // Rotationen beachten
+ if ( nObjectRotation )
+ {
+ double a = nObjectRotation * nPi180;
+ Point aCenter( aObjData.aBoundRect.Center() );
+ double ss = sin(a);
+ double cc = cos(a);
+
+ RotatePoint(aPoint1, aCenter, ss, cc);
+ RotatePoint(aPoint2, aCenter, ss, cc);
+ }
+
+ // Linie innerhalb des Bereiches zurechtdrehen/spiegeln
+ if ( nSpFlags & SP_FFLIPH )
+ {
+ INT32 n = aPoint1.X();
+ aPoint1.X() = aPoint2.X();
+ aPoint2.X() = n;
+ }
+ if ( nSpFlags & SP_FFLIPV )
+ {
+ INT32 n = aPoint1.Y();
+ aPoint1.Y() = aPoint2.Y();
+ aPoint2.Y() = n;
+ }
+ nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH );
+
+ pRet->NbcSetPoint(aPoint1, 0L); // Startpunkt
+ pRet->NbcSetPoint(aPoint2, 1L); // Endpunkt
+
+ sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist;
+ n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0;
+ switch( eConnectorStyle )
+ {
+ case mso_cxstyleBent:
+ {
+ aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) );
+ n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630;
+ }
+ break;
+ case mso_cxstyleCurved:
+ aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) );
+ break;
+ default: // mso_cxstyleStraight || mso_cxstyleNone
+ aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) );
+ break;
+ }
+ aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) );
+ aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) );
+ aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) );
+ aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) );
+
+ ((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly );
+ }
+ }
+ }
+
+ if ( pRet )
+ {
+ if( nObjectRotation )
+ {
+ double a = nObjectRotation * nPi180;
+ pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
+ }
+ // Horizontal gespiegelt?
+ if ( nSpFlags & SP_FFLIPH )
+ {
+ Rectangle aBndRect( pRet->GetSnapRect() );
+ Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
+ Point aBottom( aTop.X(), aTop.Y() + 1000 );
+ pRet->NbcMirror( aTop, aBottom );
+ }
+ // Vertikal gespiegelt?
+ if ( nSpFlags & SP_FFLIPV )
+ {
+ Rectangle aBndRect( pRet->GetSnapRect() );
+ Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
+ Point aRight( aLeft.X() + 1000, aLeft.Y() );
+ pRet->NbcMirror( aLeft, aRight );
+ }
+ }
+ }
+ }
+
+ // #i51348# #118052# name of the shape
+ if( pRet )
+ {
+ ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt );
+ if( aObjName.getLength() > 0 )
+ pRet->SetName( aObjName );
+ }
+
+ pRet =
+ ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet);
+
+ if ( mbTracing )
+ mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP
+ ? rtl::OUString::createFromAscii( "GroupShape" )
+ : rtl::OUString::createFromAscii( "Shape" ) );
+ return pRet;
+}
+
+Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect )
+{
+ Rectangle aChildAnchor;
+ rHd.SeekToContent( rSt );
+ while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aShapeHd;
+ rSt >> aShapeHd;
+ if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
+ ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
+ {
+ DffRecordHeader aShapeHd2( aShapeHd );
+ if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
+ rSt >> aShapeHd2;
+ while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aShapeAtom;
+ rSt >> aShapeAtom;
+
+ if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor )
+ {
+ if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT )
+ {
+ sal_Int32 l, t, r, b;
+ if ( aShapeAtom.nRecLen == 16 )
+ {
+ rSt >> l >> t >> r >> b;
+ }
+ else
+ {
+ INT16 ls, ts, rs, bs;
+ rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ...
+ l = ls, t = ts, r = rs, b = bs;
+ }
+ Scale( l );
+ Scale( t );
+ Scale( r );
+ Scale( b );
+ aClientRect = Rectangle( l, t, r, b );
+ }
+ break;
+ }
+ else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
+ {
+ sal_Int32 l, o, r, u;
+ rSt >> l >> o >> r >> u;
+ Scale( l );
+ Scale( o );
+ Scale( r );
+ Scale( u );
+ Rectangle aChild( l, o, r, u );
+ aChildAnchor.Union( aChild );
+ break;
+ }
+ aShapeAtom.SeekToEndOfRecord( rSt );
+ }
+ }
+ aShapeHd.SeekToEndOfRecord( rSt );
+ }
+ return aChildAnchor;
+}
+
+void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt,
+ Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor,
+ const Rectangle& rClientRect, const Rectangle& rGlobalChildRect )
+{
+ sal_Bool bFirst = sal_True;
+ rHd.SeekToContent( rSt );
+ DffRecordHeader aShapeHd;
+ while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
+ {
+ rSt >> aShapeHd;
+ if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
+ ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
+ {
+ DffRecordHeader aShapeHd2( aShapeHd );
+ if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
+ rSt >> aShapeHd2;
+ while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aShapeAtom;
+ rSt >> aShapeAtom;
+ if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
+ {
+ sal_Int32 l, o, r, u;
+ rSt >> l >> o >> r >> u;
+ Scale( l );
+ Scale( o );
+ Scale( r );
+ Scale( u );
+ Rectangle aChild( l, o, r, u );
+
+ if ( bFirst )
+ {
+ if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
+ {
+ double fl = l;
+ double fo = o;
+ double fWidth = r - l;
+ double fHeight= u - o;
+ double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
+ double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
+ fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
+ fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top();
+ fWidth *= fXScale;
+ fHeight *= fYScale;
+ rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
+ }
+ bFirst = sal_False;
+ }
+ else
+ rGroupChildAnchor.Union( aChild );
+ break;
+ }
+ aShapeAtom.SeekToEndOfRecord( rSt );
+ }
+ }
+ aShapeHd.SeekToEndOfRecord( rSt );
+ }
+}
+
+SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt,
+ DffObjData& rObjData,
+ void* pData,
+ Rectangle& rTextRect,
+ SdrObject* pObj
+ )
+{
+ if( !rTextRect.IsEmpty() )
+ {
+ SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
+ SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
+ SvxMSDffImportRec* pTextImpRec = pImpRec;
+
+ // fill Import Record with data
+ pImpRec->nShapeId = rObjData.nShapeId;
+ pImpRec->eShapeType = rObjData.eShapeType;
+
+ MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue(
+ DFF_Prop_WrapText,
+ mso_wrapSquare ) );
+ rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
+ DFF_msofbtClientAnchor,
+ SEEK_FROM_CURRENT_AND_RESTART );
+ if( rObjData.bClientAnchor )
+ ProcessClientAnchor( rSt,
+ maShapeRecords.Current()->nRecLen,
+ pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
+
+ rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
+ DFF_msofbtClientData,
+ SEEK_FROM_CURRENT_AND_RESTART );
+ if( rObjData.bClientData )
+ ProcessClientData( rSt,
+ maShapeRecords.Current()->nRecLen,
+ pImpRec->pClientDataBuffer, pImpRec->nClientDataLen );
+
+
+ // process user (== Winword) defined parameters in 0xF122 record
+ if( maShapeRecords.SeekToContent( rSt,
+ DFF_msofbtUDefProp,
+ SEEK_FROM_CURRENT_AND_RESTART )
+ && maShapeRecords.Current()->nRecLen )
+ {
+ UINT32 nBytesLeft = maShapeRecords.Current()->nRecLen;
+ UINT32 nUDData;
+ UINT16 nPID;
+ while( 5 < nBytesLeft )
+ {
+ rSt >> nPID;
+ if ( rSt.GetError() != 0 )
+ break;
+ rSt >> nUDData;
+ switch( nPID )
+ {
+ case 0x038F: pImpRec->nXAlign = nUDData; break;
+ case 0x0390: pImpRec->nXRelTo = nUDData; break;
+ case 0x0391: pImpRec->nYAlign = nUDData; break;
+ case 0x0392: pImpRec->nYRelTo = nUDData; break;
+ case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break;
+ }
+ if ( rSt.GetError() != 0 )
+ break;
+ pImpRec->bHasUDefProp = TRUE;
+ nBytesLeft -= 6;
+ }
+ }
+
+ // Textrahmen, auch Title oder Outline
+ SdrObject* pOrgObj = pObj;
+ SdrRectObj* pTextObj = 0;
+ UINT32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
+ if( nTextId )
+ {
+ SfxItemSet aSet( pSdrModel->GetItemPool() );
+
+ //Originally anything that as a mso_sptTextBox was created as a
+ //textbox, this was changed for #88277# to be created as a simple
+ //rect to keep impress happy. For the rest of us we'd like to turn
+ //it back into a textbox again.
+ FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox);
+ if (!bTextFrame)
+ {
+ //Either
+ //a) its a simple text object or
+ //b) its a rectangle with text and square wrapping.
+ bTextFrame =
+ (
+ (pImpRec->eShapeType == mso_sptTextSimple) ||
+ (
+ (pImpRec->eShapeType == mso_sptRectangle)
+ && (eWrapMode == mso_wrapSquare)
+ && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
+ )
+ );
+ }
+
+ if (bTextFrame)
+ {
+ SdrObject::Free( pObj );
+ pObj = pOrgObj = 0;
+ }
+
+ // Distance of Textbox to it's surrounding Customshape
+ INT32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
+ INT32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
+ INT32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L );
+ INT32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
+
+ ScaleEmu( nTextLeft );
+ ScaleEmu( nTextRight );
+ ScaleEmu( nTextTop );
+ ScaleEmu( nTextBottom );
+
+ INT32 nTextRotationAngle=0;
+ bool bVerticalText = false;
+ if ( IsProperty( DFF_Prop_txflTextFlow ) )
+ {
+ MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue(
+ DFF_Prop_txflTextFlow) & 0xFFFF);
+ switch( eTextFlow )
+ {
+ case mso_txflBtoT:
+ nTextRotationAngle = 9000;
+ break;
+ case mso_txflVertN:
+ case mso_txflTtoBN:
+ nTextRotationAngle = 27000;
+ break;
+ case mso_txflTtoBA:
+ bVerticalText = true;
+ break;
+ case mso_txflHorzA:
+ bVerticalText = true;
+ nTextRotationAngle = 9000;
+ case mso_txflHorzN:
+ default :
+ break;
+ }
+ }
+
+ if (nTextRotationAngle)
+ {
+ while (nTextRotationAngle > 360000)
+ nTextRotationAngle-=9000;
+ switch (nTextRotationAngle)
+ {
+ case 9000:
+ {
+ long nWidth = rTextRect.GetWidth();
+ rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
+ rTextRect.Bottom() = rTextRect.Top() + nWidth;
+
+ INT32 nOldTextLeft = nTextLeft;
+ INT32 nOldTextRight = nTextRight;
+ INT32 nOldTextTop = nTextTop;
+ INT32 nOldTextBottom = nTextBottom;
+
+ nTextLeft = nOldTextBottom;
+ nTextRight = nOldTextTop;
+ nTextTop = nOldTextLeft;
+ nTextBottom = nOldTextRight;
+ }
+ break;
+ case 27000:
+ {
+ long nWidth = rTextRect.GetWidth();
+ rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
+ rTextRect.Bottom() = rTextRect.Top() + nWidth;
+
+ INT32 nOldTextLeft = nTextLeft;
+ INT32 nOldTextRight = nTextRight;
+ INT32 nOldTextTop = nTextTop;
+ INT32 nOldTextBottom = nTextBottom;
+
+ nTextLeft = nOldTextTop;
+ nTextRight = nOldTextBottom;
+ nTextTop = nOldTextRight;
+ nTextBottom = nOldTextLeft;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect);
+ pTextImpRec = new SvxMSDffImportRec(*pImpRec);
+
+ // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
+ // hier rausrechnen
+ Rectangle aNewRect(rTextRect);
+ aNewRect.Bottom() -= nTextTop + nTextBottom;
+ aNewRect.Right() -= nTextLeft + nTextRight;
+
+ // Nur falls es eine einfache Textbox ist, darf der Writer
+ // das Objekt durch einen Rahmen ersetzen, ansonsten
+ if( bTextFrame )
+ {
+ SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId );
+ aTmpRec.bSortByShapeId = TRUE;
+
+ USHORT nFound;
+ if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) )
+ {
+ SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound);
+ pTextImpRec->bReplaceByFly = rInfo.bReplaceByFly;
+ pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain;
+ }
+ }
+
+ if( !pObj )
+ ApplyAttributes( rSt, aSet, rObjData );
+
+ bool bFitText = false;
+ if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2)
+ {
+ aSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
+ aSet.Put( SdrTextMinFrameHeightItem(
+ aNewRect.Bottom() - aNewRect.Top() ) );
+ aSet.Put( SdrTextMinFrameWidthItem(
+ aNewRect.Right() - aNewRect.Left() ) );
+ bFitText = true;
+ }
+ else
+ {
+ aSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
+ aSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
+ }
+
+ switch ( (MSO_WrapMode)
+ GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) )
+ {
+ case mso_wrapNone :
+ aSet.Put( SdrTextAutoGrowWidthItem( TRUE ) );
+ if (bFitText)
+ {
+ //can't do autowidth in flys #i107184#
+ pTextImpRec->bReplaceByFly = false;
+ }
+ break;
+ case mso_wrapByPoints :
+ aSet.Put( SdrTextContourFrameItem( TRUE ) );
+ break;
+ default: break;
+ }
+
+ // Abstaende an den Raendern der Textbox setzen
+ aSet.Put( SdrTextLeftDistItem( nTextLeft ) );
+ aSet.Put( SdrTextRightDistItem( nTextRight ) );
+ aSet.Put( SdrTextUpperDistItem( nTextTop ) );
+ aSet.Put( SdrTextLowerDistItem( nTextBottom ) );
+ pTextImpRec->nDxTextLeft = nTextLeft;
+ pTextImpRec->nDyTextTop = nTextTop;
+ pTextImpRec->nDxTextRight = nTextRight;
+ pTextImpRec->nDyTextBottom = nTextBottom;
+
+ // Textverankerung lesen
+ if ( IsProperty( DFF_Prop_anchorText ) )
+ {
+ MSO_Anchor eTextAnchor =
+ (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText );
+
+ SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER;
+ BOOL bTVASet(FALSE);
+ SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER;
+ BOOL bTHASet(FALSE);
+
+ switch( eTextAnchor )
+ {
+ case mso_anchorTop:
+ {
+ eTVA = SDRTEXTVERTADJUST_TOP;
+ bTVASet = TRUE;
+ }
+ break;
+ case mso_anchorTopCentered:
+ {
+ eTVA = SDRTEXTVERTADJUST_TOP;
+ bTVASet = TRUE;
+ bTHASet = TRUE;
+ }
+ break;
+
+ case mso_anchorMiddle:
+ bTVASet = TRUE;
+ break;
+ case mso_anchorMiddleCentered:
+ {
+ bTVASet = TRUE;
+ bTHASet = TRUE;
+ }
+ break;
+ case mso_anchorBottom:
+ {
+ eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ bTVASet = TRUE;
+ }
+ break;
+ case mso_anchorBottomCentered:
+ {
+ eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ bTVASet = TRUE;
+ bTHASet = TRUE;
+ }
+ break;
+ /*
+ case mso_anchorTopBaseline:
+ case mso_anchorBottomBaseline:
+ case mso_anchorTopCenteredBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ break;
+ */
+ default : break;
+ }
+ // Einsetzen
+ if ( bTVASet )
+ aSet.Put( SdrTextVertAdjustItem( eTVA ) );
+ if ( bTHASet )
+ aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
+ }
+
+ pTextObj->SetMergedItemSet(aSet);
+ pTextObj->SetModel(pSdrModel);
+
+ if (bVerticalText)
+ pTextObj->SetVerticalWriting(sal_True);
+
+ if (nTextRotationAngle)
+ {
+ long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ?
+ rTextRect.GetWidth() : rTextRect.GetHeight();
+ nMinWH /= 2;
+ Point aPivot(rTextRect.TopLeft());
+ aPivot.X() += nMinWH;
+ aPivot.Y() += nMinWH;
+ double a = nTextRotationAngle * nPi180;
+ pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a));
+ }
+
+ // rotate text with shape ?
+ if ( mnFix16Angle )
+ {
+ double a = mnFix16Angle * nPi180;
+ pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle,
+ sin( a ), cos( a ) );
+ }
+
+ if( !pObj )
+ {
+ pObj = pTextObj;
+ }
+ else
+ {
+ if( pTextObj != pObj )
+ {
+ SdrObject* pGroup = new SdrObjGroup;
+ pGroup->GetSubList()->NbcInsertObject( pObj );
+ pGroup->GetSubList()->NbcInsertObject( pTextObj );
+ if (pOrgObj == pObj)
+ pOrgObj = pGroup;
+ else
+ pOrgObj = pObj;
+ pObj = pGroup;
+ }
+ }
+ }
+ else if( !pObj )
+ {
+ // simple rectangular objects are ignored by ImportObj() :-(
+ // this is OK for Draw but not for Calc and Writer
+ // cause here these objects have a default border
+ pObj = new SdrRectObj(rTextRect);
+ pOrgObj = pObj;
+ pObj->SetModel( pSdrModel );
+ SfxItemSet aSet( pSdrModel->GetItemPool() );
+ ApplyAttributes( rSt, aSet, rObjData );
+
+ const SfxPoolItem* pPoolItem=NULL;
+ SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
+ FALSE, &pPoolItem );
+ if( SFX_ITEM_DEFAULT == eState )
+ aSet.Put( XFillColorItem( String(),
+ Color( mnDefaultColor ) ) );
+ pObj->SetMergedItemSet(aSet);
+ }
+
+ //Means that fBehindDocument is set
+ if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
+ pImpRec->bDrawHell = TRUE;
+ else
+ pImpRec->bDrawHell = FALSE;
+ if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
+ pImpRec->bHidden = TRUE;
+ pTextImpRec->bDrawHell = pImpRec->bDrawHell;
+ pTextImpRec->bHidden = pImpRec->bHidden;
+ pImpRec->nNextShapeId = GetPropertyValue( DFF_Prop_hspNext, 0 );
+ pTextImpRec->nNextShapeId=pImpRec->nNextShapeId;
+
+ if ( nTextId )
+ {
+ pTextImpRec->aTextId.nTxBxS = (UINT16)( nTextId >> 16 );
+ pTextImpRec->aTextId.nSequence = (UINT16)nTextId;
+ }
+
+ pTextImpRec->nDxWrapDistLeft = GetPropertyValue(
+ DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
+ pTextImpRec->nDyWrapDistTop = GetPropertyValue(
+ DFF_Prop_dyWrapDistTop, 0 ) / 635L;
+ pTextImpRec->nDxWrapDistRight = GetPropertyValue(
+ DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
+ pTextImpRec->nDyWrapDistBottom = GetPropertyValue(
+ DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
+ // 16.16 fraction times total image width or height, as appropriate.
+
+ if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt))
+ {
+ delete pTextImpRec->pWrapPolygon;
+ sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
+ rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
+ if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
+ {
+ pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert);
+ for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
+ {
+ sal_Int32 nX, nY;
+ if (nElemSizeVert == 8)
+ rSt >> nX >> nY;
+ else
+ {
+ sal_Int16 nSmallX, nSmallY;
+ rSt >> nSmallX >> nSmallY;
+ nX = nSmallX;
+ nY = nSmallY;
+ }
+ (*(pTextImpRec->pWrapPolygon))[i].X() = nX;
+ (*(pTextImpRec->pWrapPolygon))[i].Y() = nY;
+ }
+ }
+ }
+
+ pImpRec->nCropFromTop = GetPropertyValue(
+ DFF_Prop_cropFromTop, 0 );
+ pImpRec->nCropFromBottom = GetPropertyValue(
+ DFF_Prop_cropFromBottom, 0 );
+ pImpRec->nCropFromLeft = GetPropertyValue(
+ DFF_Prop_cropFromLeft, 0 );
+ pImpRec->nCropFromRight = GetPropertyValue(
+ DFF_Prop_cropFromRight, 0 );
+
+ pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false;
+ pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false;
+
+ UINT32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
+ pImpRec->eLineStyle = (nLineFlags & 8)
+ ? (MSO_LineStyle)GetPropertyValue(
+ DFF_Prop_lineStyle,
+ mso_lineSimple )
+ : (MSO_LineStyle)USHRT_MAX;
+ pTextImpRec->eLineStyle = pImpRec->eLineStyle;
+
+ if( pImpRec->nShapeId )
+ {
+ // Import-Record-Liste ergaenzen
+ if( pOrgObj )
+ {
+ pImpRec->pObj = pOrgObj;
+ rImportData.aRecords.Insert( pImpRec );
+ }
+
+ if( pTextObj && (pOrgObj != pTextObj) )
+ {
+ // Modify ShapeId (must be unique)
+ pImpRec->nShapeId |= 0x8000000;
+ pTextImpRec->pObj = pTextObj;
+ rImportData.aRecords.Insert( pTextImpRec );
+ }
+
+ // Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen
+ /*Only store objects which are not deep inside the tree*/
+ if( ( rObjData.nCalledByGroup == 0 )
+ ||
+ ( (rObjData.nSpFlags & SP_FGROUP)
+ && (rObjData.nCalledByGroup < 2) )
+ )
+ StoreShapeOrder( pImpRec->nShapeId,
+ ( ( (ULONG)pImpRec->aTextId.nTxBxS ) << 16 )
+ + pImpRec->aTextId.nSequence, pObj );
+ }
+ else
+ delete pImpRec;
+ }
+
+ return pObj;
+};
+
+void SvxMSDffManager::StoreShapeOrder(ULONG nId,
+ ULONG nTxBx,
+ SdrObject* pObject,
+ SwFlyFrmFmt* pFly,
+ short nHdFtSection) const
+{
+ USHORT nShpCnt = pShapeOrders->Count();
+ for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
+ {
+ SvxMSDffShapeOrder& rOrder
+ = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
+
+ if( rOrder.nShapeId == nId )
+ {
+ rOrder.nTxBxComp = nTxBx;
+ rOrder.pObj = pObject;
+ rOrder.pFly = pFly;
+ rOrder.nHdFtSection = nHdFtSection;
+ }
+ }
+}
+
+
+void SvxMSDffManager::ExchangeInShapeOrder( SdrObject* pOldObject,
+ ULONG nTxBx,
+ SwFlyFrmFmt* pFly,
+ SdrObject* pObject) const
+{
+ USHORT nShpCnt = pShapeOrders->Count();
+ for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
+ {
+ SvxMSDffShapeOrder& rOrder
+ = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
+
+ if( rOrder.pObj == pOldObject )
+ {
+ rOrder.pFly = pFly;
+ rOrder.pObj = pObject;
+ rOrder.nTxBxComp = nTxBx;
+ }
+ }
+}
+
+
+void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const
+{
+ USHORT nShpCnt = pShapeOrders->Count();
+ for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
+ {
+ SvxMSDffShapeOrder& rOrder
+ = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
+
+ if( rOrder.pObj == pObject )
+ {
+ rOrder.pObj = 0;
+ rOrder.pFly = 0;
+ rOrder.nTxBxComp = 0;
+ }
+ }
+}
+
+
+
+
+//---------------------------------------------------------------------------
+// Hilfs Deklarationen
+//---------------------------------------------------------------------------
+
+/*struct SvxMSDffBLIPInfo -> in's Header-File
+{
+ USHORT nBLIPType; // Art des BLIP: z.B. 6 fuer PNG
+ ULONG nFilePos; // Offset des BLIP im Daten-Stream
+ ULONG nBLIPSize; // Anzahl Bytes, die der BLIP im Stream einnimmt
+ SvxMSDffBLIPInfo(USHORT nBType, ULONG nFPos, ULONG nBSize):
+ nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){}
+};
+*/
+
+SV_IMPL_PTRARR( SvxMSDffBLIPInfos, SvxMSDffBLIPInfo_Ptr );
+
+SV_IMPL_PTRARR( SvxMSDffShapeOrders, SvxMSDffShapeOrder_Ptr );
+
+SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeInfos, SvxMSDffShapeInfo_Ptr );
+
+SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeTxBxSort, SvxMSDffShapeOrder_Ptr );
+
+
+// Liste aller SvxMSDffImportRec fuer eine Gruppe
+SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr)
+
+//---------------------------------------------------------------------------
+// exportierte Klasse: oeffentliche Methoden
+//---------------------------------------------------------------------------
+
+SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_,
+ const String& rBaseURL,
+ long nOffsDgg_,
+ SvStream* pStData_,
+ SdrModel* pSdrModel_,// s. unten: SetModel()
+ long nApplicationScale,
+ ColorData mnDefaultColor_,
+ ULONG nDefaultFontHeight_,
+ SvStream* pStData2_,
+ MSFilterTracer* pTracer )
+ :DffPropertyReader( *this ),
+ pFormModel( NULL ),
+ pBLIPInfos( new SvxMSDffBLIPInfos ),
+ pShapeInfos( new SvxMSDffShapeInfos ),
+ pShapeOrders( new SvxMSDffShapeOrders ),
+ nDefaultFontHeight( nDefaultFontHeight_),
+ nOffsDgg( nOffsDgg_ ),
+ nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen,
+ nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt
+ maBaseURL( rBaseURL ),
+ mpFidcls( NULL ),
+ rStCtrl( rStCtrl_ ),
+ pStData( pStData_ ),
+ pStData2( pStData2_ ),
+ nSvxMSDffSettings( 0 ),
+ nSvxMSDffOLEConvFlags( 0 ),
+ pEscherBlipCache( NULL ),
+ mnDefaultColor( mnDefaultColor_),
+ mpTracer( pTracer ),
+ mbTracing( sal_False )
+{
+ if ( mpTracer )
+ {
+ uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
+ aAny >>= mbTracing;
+ }
+ SetModel( pSdrModel_, nApplicationScale );
+
+ // FilePos des/der Stream(s) merken
+ ULONG nOldPosCtrl = rStCtrl.Tell();
+ ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
+
+ // Falls kein Datenstream angegeben, gehen wir davon aus,
+ // dass die BLIPs im Steuerstream stehen.
+ if( !pStData )
+ pStData = &rStCtrl;
+
+ SetDefaultPropSet( rStCtrl, nOffsDgg );
+
+ // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
+ GetCtrlData( nOffsDgg );
+
+ // Text-Box-Story-Ketten-Infos ueberpruefen
+ CheckTxBxStoryChain();
+
+ // alte FilePos des/der Stream(s) restaurieren
+ rStCtrl.Seek( nOldPosCtrl );
+ if( &rStCtrl != pStData )
+ pStData->Seek( nOldPosData );
+}
+
+SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer )
+ :DffPropertyReader( *this ),
+ pFormModel( NULL ),
+ pBLIPInfos( new SvxMSDffBLIPInfos ),
+ pShapeInfos( new SvxMSDffShapeInfos ),
+ pShapeOrders( new SvxMSDffShapeOrders ),
+ nDefaultFontHeight( 24 ),
+ nOffsDgg( 0 ),
+ nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen,
+ nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt
+ maBaseURL( rBaseURL ),
+ mpFidcls( NULL ),
+ rStCtrl( rStCtrl_ ),
+ pStData( 0 ),
+ pStData2( 0 ),
+ nSvxMSDffSettings( 0 ),
+ nSvxMSDffOLEConvFlags( 0 ),
+ pEscherBlipCache( NULL ),
+ mnDefaultColor( COL_DEFAULT ),
+ mpTracer( pTracer ),
+ mbTracing( sal_False )
+{
+ if ( mpTracer )
+ {
+ uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
+ aAny >>= mbTracing;
+ }
+ SetModel( NULL, 0 );
+}
+
+SvxMSDffManager::~SvxMSDffManager()
+{
+ if ( pEscherBlipCache )
+ {
+ void* pPtr;
+ for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() )
+ delete (EscherBlipCacheEntry*)pPtr;
+ delete pEscherBlipCache;
+ }
+ delete pBLIPInfos;
+ delete pShapeInfos;
+ delete pShapeOrders;
+ delete pFormModel;
+ delete[] mpFidcls;
+}
+
+void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags )
+{
+ nOffsDgg = nOffsDgg_;
+ pStData = pStData_;
+ nSvxMSDffOLEConvFlags = nOleConvFlags;
+
+ // FilePos des/der Stream(s) merken
+ ULONG nOldPosCtrl = rStCtrl.Tell();
+
+ SetDefaultPropSet( rStCtrl, nOffsDgg );
+
+ // insert fidcl cluster table
+ GetFidclData( nOffsDgg );
+
+ // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
+ GetCtrlData( nOffsDgg );
+
+ // Text-Box-Story-Ketten-Infos ueberpruefen
+ CheckTxBxStoryChain();
+
+ // alte FilePos des/der Stream(s) restaurieren
+ rStCtrl.Seek( nOldPosCtrl );
+}
+
+void SvxMSDffManager::SetDgContainer( SvStream& rSt )
+{
+ UINT32 nFilePos = rSt.Tell();
+ DffRecordHeader aDgContHd;
+ rSt >> aDgContHd;
+ // insert this container only if there is also a DgAtom
+ if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aRecHd;
+ rSt >> aRecHd;
+ UINT32 nDrawingId = aRecHd.nRecInstance;
+ maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos );
+ rSt.Seek( nFilePos );
+ }
+}
+
+void SvxMSDffManager::GetFidclData( long nOffsDggL )
+{
+ if ( nOffsDggL )
+ {
+ UINT32 nDummy, nMerk = rStCtrl.Tell();
+ rStCtrl.Seek( nOffsDggL );
+
+ DffRecordHeader aRecHd;
+ rStCtrl >> aRecHd;
+
+ DffRecordHeader aDggAtomHd;
+ if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) )
+ {
+ aDggAtomHd.SeekToContent( rStCtrl );
+ rStCtrl >> mnCurMaxShapeId
+ >> mnIdClusters
+ >> nDummy
+ >> mnDrawingsSaved;
+
+ if ( mnIdClusters-- > 2 )
+ {
+ if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) )
+ {
+ mpFidcls = new FIDCL[ mnIdClusters ];
+ for ( UINT32 i = 0; i < mnIdClusters; i++ )
+ {
+ rStCtrl >> mpFidcls[ i ].dgid
+ >> mpFidcls[ i ].cspidCur;
+ }
+ }
+ }
+ }
+ rStCtrl.Seek( nMerk );
+ }
+}
+
+void SvxMSDffManager::CheckTxBxStoryChain()
+{
+ SvxMSDffShapeInfos* pOld = pShapeInfos;
+ USHORT nCnt = pOld->Count();
+ pShapeInfos = new SvxMSDffShapeInfos( (nCnt < 255)
+ ? nCnt
+ : 255 );
+ // altes Info-Array ueberarbeiten
+ // (ist sortiert nach nTxBxComp)
+ ULONG nChain = ULONG_MAX;
+ USHORT nObjMark = 0;
+ BOOL bSetReplaceFALSE = FALSE;
+ USHORT nObj;
+ for( nObj = 0; nObj < nCnt; ++nObj )
+ {
+ SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj );
+ if( pObj->nTxBxComp )
+ {
+ pObj->bLastBoxInChain = FALSE;
+ // Gruppenwechsel ?
+ // --> OD 2008-07-28 #156763#
+ // the text id also contains an internal drawing container id
+ // to distinguish between text id of drawing objects in different
+ // drawing containers.
+// if( nChain != (pObj->nTxBxComp & 0xFFFF0000) )
+ if( nChain != pObj->nTxBxComp )
+ // <--
+ {
+ // voriger war letzter seiner Gruppe
+ if( nObj )
+ pOld->GetObject( nObj-1 )->bLastBoxInChain = TRUE;
+ // Merker und Hilfs-Flag zuruecksetzen
+ nObjMark = nObj;
+ // --> OD 2008-07-28 #156763#
+// nChain = pObj->nTxBxComp & 0xFFFF0000;
+ nChain = pObj->nTxBxComp;
+ // <--
+ bSetReplaceFALSE = !pObj->bReplaceByFly;
+ }
+ else
+ if( !pObj->bReplaceByFly )
+ {
+ // Objekt, das NICHT durch Rahmen ersetzt werden darf ?
+ // Hilfs-Flag setzen
+ bSetReplaceFALSE = TRUE;
+ // ggfs Flag in Anfang der Gruppe austragen
+ for( USHORT nObj2 = nObjMark; nObj2 < nObj; ++nObj2 )
+ pOld->GetObject( nObj2 )->bReplaceByFly = FALSE;
+ }
+
+ if( bSetReplaceFALSE )
+ {
+ pObj->bReplaceByFly = FALSE;
+ }
+ }
+ // alle Shape-Info-Objekte in pShapeInfos umkopieren
+ // (aber nach nShapeId sortieren)
+ pObj->bSortByShapeId = TRUE;
+ // --> OD 2008-07-28 #156763#
+ pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000;
+ // <--
+ pShapeInfos->Insert( pObj );
+ }
+ // voriger war letzter seiner Gruppe
+ if( nObj )
+ pOld->GetObject( nObj-1 )->bLastBoxInChain = TRUE;
+ // urspruengliches Array freigeben, ohne Objekte zu zerstoeren
+ pOld->Remove((USHORT)0, nCnt);
+ delete pOld;
+}
+
+
+/*****************************************************************************
+
+ Einlesen der Shape-Infos im Ctor:
+ ---------------------------------
+ merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos
+ ========= ============ =============
+ und merken des File-Offsets fuer jedes Blip
+ ============
+******************************************************************************/
+void SvxMSDffManager::GetCtrlData( long nOffsDgg_ )
+{
+ // Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen
+ long nOffsDggL = nOffsDgg_;
+
+ // Kontroll Stream positionieren
+ rStCtrl.Seek( nOffsDggL );
+
+ BYTE nVer;
+ USHORT nInst;
+ USHORT nFbt;
+ UINT32 nLength;
+ if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return;
+
+ BOOL bOk;
+ ULONG nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE;
+
+ // Fall A: erst Drawing Group Container, dann n Mal Drawing Container
+ if( DFF_msofbtDggContainer == nFbt )
+ {
+ GetDrawingGroupContainerData( rStCtrl, nLength );
+
+ rStCtrl.Seek( STREAM_SEEK_TO_END );
+ UINT32 nMaxStrPos = rStCtrl.Tell();
+
+ nPos += nLength;
+ // --> OD 2008-07-28 #156763#
+ unsigned long nDrawingContainerId = 1;
+ // <--
+ do
+ {
+ rStCtrl.Seek( nPos );
+
+ bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt );
+
+ if( !bOk )
+ {
+ nPos++;
+ rStCtrl.Seek( nPos );
+ bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength )
+ && ( DFF_msofbtDgContainer == nFbt );
+ }
+ if( bOk )
+ {
+ // --> OD 2008-07-28 #156763#
+ GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId );
+ // <--
+ }
+ nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
+ // --> OD 2008-07-28 #156763#
+ ++nDrawingContainerId;
+ // <--
+ }
+ while( nPos < nMaxStrPos && bOk );
+ }
+}
+
+
+// ab hier: Drawing Group Container d.h. Dokument - weit gueltige Daten
+// ======================= ========
+//
+void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, ULONG nLenDgg )
+{
+ BYTE nVer;
+ USHORT nInst;
+ USHORT nFbt;
+ UINT32 nLength;
+
+ ULONG nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0;
+
+ // Nach einem BStore Container suchen
+ do
+ {
+ if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
+ nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
+ if( DFF_msofbtBstoreContainer == nFbt )
+ {
+ nLenBStoreCont = nLength; break;
+ }
+ rSt.SeekRel( nLength );
+ }
+ while( nRead < nLenDgg );
+
+ if( !nLenBStoreCont ) return;
+
+ // Im BStore Container alle Header der Container und Atome auslesen und die
+ // relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen.
+ // Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit.
+
+ const ULONG nSkipBLIPLen = 20; // bis zu nBLIPLen zu ueberspringende Bytes
+ const ULONG nSkipBLIPPos = 4; // dahinter bis zu nBLIPPos zu skippen
+
+ sal_uInt32 nBLIPLen = 0, nBLIPPos = 0;
+
+ nRead = 0;
+ do
+ {
+ if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
+ nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
+ if( DFF_msofbtBSE == nFbt )
+ {
+ nLenFBSE = nLength;
+ // ist FBSE gross genug fuer unsere Daten
+ BOOL bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE );
+
+ if( bOk )
+ {
+ rSt.SeekRel( nSkipBLIPLen );
+ rSt >> nBLIPLen;
+ rSt.SeekRel( nSkipBLIPPos );
+ rSt >> nBLIPPos;
+ bOk = rSt.GetError() == 0;
+
+ nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4;
+ }
+
+ if( bOk )
+ {
+ // Besonderheit:
+ // Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist,
+ // nehmen wir an, dass das Bild IM FBSE drin steht!
+ if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) )
+ nBLIPPos = rSt.Tell() + 4;
+
+ // Das hat ja fein geklappt!
+ // Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben.
+ nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell());
+
+ if( USHRT_MAX == nBLIPCount )
+ nBLIPCount = 1;
+ else
+ nBLIPCount++;
+
+ // Jetzt die Infos fuer spaetere Zugriffe speichern
+ pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ),
+ pBLIPInfos->Count() );
+ }
+ }
+ rSt.SeekRel( nLength );
+ }
+ while( nRead < nLenBStoreCont );
+}
+
+
+// ab hier: Drawing Container d.h. Seiten (Blatt, Dia) - weit gueltige Daten
+// ================= ======
+//
+void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, ULONG nLenDg,
+ const unsigned long nDrawingContainerId )
+{
+ BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
+
+ ULONG nReadDg = 0;
+
+ // Wir stehen in einem Drawing Container (je einer pro Seite)
+ // und muessen nun
+ // alle enthaltenen Shape Group Container abklappern
+ do
+ {
+ if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
+ nReadDg += DFF_COMMON_RECORD_HEADER_SIZE;
+ // Patriarch gefunden (der oberste Shape Group Container) ?
+ if( DFF_msofbtSpgrContainer == nFbt )
+ {
+ if(!this->GetShapeGroupContainerData( rSt, nLength, TRUE, nDrawingContainerId )) return;
+ }
+ else
+ // blanker Shape Container ? (ausserhalb vom Shape Group Container)
+ if( DFF_msofbtSpContainer == nFbt )
+ {
+ if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return;
+ }
+ else
+ rSt.SeekRel( nLength );
+ nReadDg += nLength;
+ }
+ while( nReadDg < nLenDg );
+}
+
+BOOL SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt,
+ ULONG nLenShapeGroupCont,
+ BOOL bPatriarch,
+ const unsigned long nDrawingContainerId )
+{
+ BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
+ long nStartShapeGroupCont = rSt.Tell();
+ // Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite)
+ // und muessen nun
+ // alle enthaltenen Shape Container abklappern
+ BOOL bFirst = !bPatriarch;
+ ULONG nReadSpGrCont = 0;
+ do
+ {
+ if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) )
+ return FALSE;
+ nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE;
+ // Shape Container ?
+ if( DFF_msofbtSpContainer == nFbt )
+ {
+ ULONG nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX;
+ if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) )
+ return FALSE;
+ bFirst = FALSE;
+ }
+ else
+ // eingeschachtelter Shape Group Container ?
+ if( DFF_msofbtSpgrContainer == nFbt )
+ {
+ if ( !this->GetShapeGroupContainerData( rSt, nLength, FALSE, nDrawingContainerId ) )
+ return FALSE;
+ }
+ else
+ rSt.SeekRel( nLength );
+ nReadSpGrCont += nLength;
+ }
+ while( nReadSpGrCont < nLenShapeGroupCont );
+ // den Stream wieder korrekt positionieren
+ rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont );
+ return TRUE;
+}
+
+BOOL SvxMSDffManager::GetShapeContainerData( SvStream& rSt,
+ ULONG nLenShapeCont,
+ ULONG nPosGroup,
+ const unsigned long nDrawingContainerId )
+{
+ BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
+ long nStartShapeCont = rSt.Tell();
+ // Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group)
+ // und muessen nun
+ // die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe)
+ // und den ersten BStore Verweis (falls vorhanden) entnehmen
+ ULONG nLenShapePropTbl = 0;
+ ULONG nReadSpCont = 0;
+
+ // File Offset des Shape-Containers bzw. der Gruppe(!) vermerken
+ //
+ ULONG nStartOffs = (ULONG_MAX > nPosGroup) ?
+ nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE;
+ SvxMSDffShapeInfo aInfo( nStartOffs );
+
+ // duerfte das Shape durch einen Rahmen ersetzt werden ?
+ // (vorausgesetzt, es zeigt sich, dass es eine TextBox ist,
+ // und der Text nicht gedreht ist)
+ BOOL bCanBeReplaced = (ULONG_MAX > nPosGroup) ? FALSE : TRUE;
+
+ // wir wissen noch nicht, ob es eine TextBox ist
+ MSO_SPT eShapeType = mso_sptNil;
+ MSO_WrapMode eWrapMode = mso_wrapSquare;
+// BOOL bIsTextBox = FALSE;
+
+ // Shape analysieren
+ //
+ do
+ {
+ if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return FALSE;
+ nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE;
+ // FSP ?
+ if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) )
+ {
+ // Wir haben den FSP gefunden: Shape Typ und Id vermerken!
+ eShapeType = (MSO_SPT)nInst;
+ rSt >> aInfo.nShapeId;
+ rSt.SeekRel( nLength - 4 );
+ nReadSpCont += nLength;
+ }
+ else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ?
+ {
+ // Wir haben die Property Table gefunden:
+ // nach der Blip Property suchen!
+ ULONG nPropRead = 0;
+ USHORT nPropId;
+ sal_uInt32 nPropVal;
+ nLenShapePropTbl = nLength;
+// UINT32 nPropCount = nInst;
+ long nStartShapePropTbl = rSt.Tell();
+// UINT32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6);
+ do
+ {
+ rSt >> nPropId
+ >> nPropVal;
+ nPropRead += 6;
+
+ switch( nPropId )
+ {
+ case DFF_Prop_txflTextFlow :
+ //Writer can now handle vertical textflows in its
+ //native frames, to only need to do this for the
+ //other two formats
+
+ //Writer will handle all textflow except BtoT
+ if (GetSvxMSDffSettings() &
+ (SVXMSDFF_SETTINGS_IMPORT_PPT |
+ SVXMSDFF_SETTINGS_IMPORT_EXCEL))
+ {
+ if( 0 != nPropVal )
+ bCanBeReplaced = false;
+ }
+ else if (
+ (nPropVal != mso_txflHorzN) &&
+ (nPropVal != mso_txflTtoBA)
+ )
+ {
+ bCanBeReplaced = false;
+ }
+ break;
+ case DFF_Prop_cdirFont :
+ //Writer can now handle right to left and left
+ //to right in its native frames, so only do
+ //this for the other two formats.
+ if (GetSvxMSDffSettings() &
+ (SVXMSDFF_SETTINGS_IMPORT_PPT |
+ SVXMSDFF_SETTINGS_IMPORT_EXCEL))
+ {
+ if( 0 != nPropVal )
+ bCanBeReplaced = FALSE;
+ }
+ break;
+ case DFF_Prop_Rotation :
+ if( 0 != nPropVal )
+ bCanBeReplaced = FALSE;
+ break;
+
+ case DFF_Prop_gtextFStrikethrough :
+ if( ( 0x20002000 & nPropVal ) == 0x20002000 )
+ bCanBeReplaced = FALSE;
+ break;
+
+ case DFF_Prop_fc3DLightFace :
+ if( ( 0x00080008 & nPropVal ) == 0x00080008 )
+ bCanBeReplaced = FALSE;
+ break;
+
+ case DFF_Prop_WrapText :
+ eWrapMode = (MSO_WrapMode)nPropVal;
+ break;
+
+ default:
+ {
+ // Bit gesetzt und gueltig?
+ if( 0x4000 == ( nPropId & 0xC000 ) )
+ {
+ // Blip Property gefunden: BStore Idx vermerken!
+ nPropRead = nLenShapePropTbl;
+ }
+ else if( 0x8000 & nPropId )
+ {
+ // komplexe Prop gefunden:
+ // Laenge ist immer 6, nur die Laenge der nach der
+ // eigentlichen Prop-Table anhaengenden Extra-Daten
+ // ist unterschiedlich
+ nPropVal = 6;
+ }
+ }
+ break;
+ }
+
+/*
+//JP 21.04.99: Bug 64510
+// alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge
+// Performance einbussen hat.
+
+ if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig?
+ {
+ // Blip Property gefunden: BStore Idx vermerken!
+ aInfo.nBStoreIdx = nPropVal; // Index im BStore Container
+ break;
+ }
+ else
+ if( ( ( (DFF_Prop_txflTextFlow == nPropId)
+ || (DFF_Prop_Rotation == nPropId)
+ || (DFF_Prop_cdirFont == nPropId) )
+ && (0 != nPropVal) )
+
+ || ( (DFF_Prop_gtextFStrikethrough == nPropId)
+ && ( (0x20002000 & nPropVal) == 0x20002000) ) // also DFF_Prop_gtextFVertical
+ || ( (DFF_Prop_fc3DLightFace == nPropId)
+ && ( (0x00080008 & nPropVal) == 0x00080008) ) // also DFF_Prop_f3D
+ )
+ {
+ bCanBeReplaced = FALSE; // Mist: gedrehter Text oder 3D-Objekt!
+ }
+ else
+ if( DFF_Prop_WrapText == nPropId )
+ {
+ eWrapMode = (MSO_WrapMode)nPropVal;
+ }
+ ////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////
+ // keine weitere Property-Auswertung: folge beim Shape-Import //
+ ////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////
+ else
+ if( 0x8000 & nPropId )
+ {
+ // komplexe Prop gefunden: Laenge lesen und ueberspringen
+ if(!SkipBytes( rSt, nPropVal )) return FALSE;
+ nPropRead += nPropVal;
+ }
+*/
+ }
+ while( nPropRead < nLenShapePropTbl );
+ rSt.Seek( nStartShapePropTbl + nLenShapePropTbl );
+ nReadSpCont += nLenShapePropTbl;
+ }
+ else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) ) // Text-Box-Story-Eintrag gefunden
+ {
+ rSt >> aInfo.nTxBxComp;
+ // --> OD 2008-07-28 #156763#
+ // Add internal drawing container id to text id.
+ // Note: The text id uses the first two bytes, while the internal
+ // drawing container id used the second two bytes.
+ aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) +
+ nDrawingContainerId;
+ DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId,
+ "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." );
+ // <--
+ }
+ else
+ {
+ rSt.SeekRel( nLength );
+ nReadSpCont += nLength;
+ }
+ }
+ while( nReadSpCont < nLenShapeCont );
+
+ //
+ // Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern
+ //
+ if( aInfo.nShapeId )
+ {
+ // fuer Textboxen ggfs. ersetzen durch Rahmen erlauben
+ if( bCanBeReplaced
+ && aInfo.nTxBxComp
+ && (
+ ( eShapeType == mso_sptTextSimple )
+ || ( eShapeType == mso_sptTextBox )
+ || ( ( ( eShapeType == mso_sptRectangle )
+ || ( eShapeType == mso_sptRoundRectangle )
+ )
+ ) ) )
+ {
+ aInfo.bReplaceByFly = TRUE;
+ }
+ pShapeInfos->Insert( new SvxMSDffShapeInfo( aInfo ) );
+ pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ),
+ pShapeOrders->Count() );
+ }
+
+ // und den Stream wieder korrekt positionieren
+ rSt.Seek( nStartShapeCont + nLenShapeCont );
+ return TRUE;
+}
+
+
+
+/*****************************************************************************
+
+ Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id)
+ ----------------------------------
+******************************************************************************/
+BOOL SvxMSDffManager::GetShape(ULONG nId, SdrObject*& rpShape,
+ SvxMSDffImportData& rData)
+{
+ SvxMSDffShapeInfo aTmpRec(0, nId);
+ aTmpRec.bSortByShapeId = TRUE;
+
+ USHORT nFound;
+ if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) )
+ {
+ SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound );
+
+ // eventuell altes Errorflag loeschen
+ if( rStCtrl.GetError() )
+ rStCtrl.ResetError();
+ // FilePos des/der Stream(s) merken
+ ULONG nOldPosCtrl = rStCtrl.Tell();
+ ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
+ // das Shape im Steuer Stream anspringen
+ rStCtrl.Seek( rInfo.nFilePos );
+
+ // Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt!
+ if( rStCtrl.GetError() )
+ rStCtrl.ResetError();
+ else
+ rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect );
+
+ // alte FilePos des/der Stream(s) restaurieren
+ rStCtrl.Seek( nOldPosCtrl );
+ if( &rStCtrl != pStData )
+ pStData->Seek( nOldPosData );
+ return ( 0 != rpShape );
+ }
+ return FALSE;
+}
+
+
+
+/* Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr)
+ ---------------------------------
+******************************************************************************/
+BOOL SvxMSDffManager::GetBLIP( ULONG nIdx_, Graphic& rData, Rectangle* pVisArea ) const
+{
+ BOOL bOk = FALSE; // Ergebnisvariable initialisieren
+ if ( pStData )
+ {
+ // check if a graphic for this blipId is already imported
+ if ( nIdx_ && pEscherBlipCache )
+ {
+ EscherBlipCacheEntry* pEntry;
+ for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry;
+ pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() )
+ {
+ if ( pEntry->nBlip == nIdx_ )
+ { /* if this entry is available, then it should be possible
+ to get the Graphic via GraphicObject */
+ GraphicObject aGraphicObject( pEntry->aUniqueID );
+ rData = aGraphicObject.GetGraphic();
+ if ( rData.GetType() != GRAPHIC_NONE )
+ bOk = sal_True;
+ else
+ delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove();
+ break;
+ }
+ }
+ }
+ if ( !bOk )
+ {
+ USHORT nIdx = USHORT( nIdx_ );
+ if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return FALSE;
+
+ // eventuell alte(s) Errorflag(s) loeschen
+ if( rStCtrl.GetError() )
+ rStCtrl.ResetError();
+ if( ( &rStCtrl != pStData )
+ && pStData->GetError() )
+ pStData->ResetError();
+
+ // FilePos des/der Stream(s) merken
+ ULONG nOldPosCtrl = rStCtrl.Tell();
+ ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
+
+ // passende Info-Struct aus unserem Pointer Array nehmen
+ SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ];
+
+ // das BLIP Atom im Daten Stream anspringen
+ pStData->Seek( rInfo.nFilePos );
+ // ggfs. Fehlerstatus zuruecksetzen
+ if( pStData->GetError() )
+ pStData->ResetError();
+ else
+ bOk = GetBLIPDirect( *pStData, rData, pVisArea );
+ if( pStData2 && !bOk )
+ {
+ // Fehler, aber zweite Chance: es gibt noch einen zweiten
+ // Datenstream, in dem die Grafik liegen koennte!
+ if( pStData2->GetError() )
+ pStData2->ResetError();
+ ULONG nOldPosData2 = pStData2->Tell();
+ // das BLIP Atom im zweiten Daten Stream anspringen
+ pStData2->Seek( rInfo.nFilePos );
+ // ggfs. Fehlerstatus zuruecksetzen
+ if( pStData2->GetError() )
+ pStData2->ResetError();
+ else
+ bOk = GetBLIPDirect( *pStData2, rData, pVisArea );
+ // alte FilePos des zweiten Daten-Stream restaurieren
+ pStData2->Seek( nOldPosData2 );
+ }
+ // alte FilePos des/der Stream(s) restaurieren
+ rStCtrl.Seek( nOldPosCtrl );
+ if( &rStCtrl != pStData )
+ pStData->Seek( nOldPosData );
+
+ if ( bOk )
+ {
+ // create new BlipCacheEntry for this graphic
+ GraphicObject aGraphicObject( rData );
+ if ( !pEscherBlipCache )
+ const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List();
+ EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() );
+ pEscherBlipCache->Insert( pNewEntry, LIST_APPEND );
+ }
+ }
+ }
+ return bOk;
+}
+
+/* Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream)
+ ---------------------------------
+******************************************************************************/
+BOOL SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const
+{
+ ULONG nOldPos = rBLIPStream.Tell();
+
+ int nRes = GRFILTER_OPENERROR; // Fehlervariable initialisieren
+
+ // nachschauen, ob es sich auch wirklich um ein BLIP handelt
+ UINT32 nLength;
+ USHORT nInst, nFbt( 0 );
+ BYTE nVer;
+ if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) )
+ {
+ Size aMtfSize100;
+ BOOL bMtfBLIP = FALSE;
+ BOOL bZCodecCompression = FALSE;
+ // Nun exakt auf den Beginn der eingebetteten Grafik positionieren
+ ULONG nSkip = ( nInst & 0x0001 ) ? 32 : 16;
+
+ switch( nInst & 0xFFFE )
+ {
+ case 0x216 : // Metafile header then compressed WMF
+ case 0x3D4 : // Metafile header then compressed EMF
+ case 0x542 : // Metafile hd. then compressed PICT
+ {
+ rBLIPStream.SeekRel( nSkip + 20 );
+
+ // read in size of metafile in EMUS
+ rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height();
+
+ // scale to 1/100mm
+ aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360;
+
+ if ( pVisArea ) // seem that we currently are skipping the visarea position
+ *pVisArea = Rectangle( Point(), aMtfSize100 );
+
+ // skip rest of header
+ nSkip = 6;
+ bMtfBLIP = bZCodecCompression = TRUE;
+ }
+ break;
+ case 0x46A : // One byte tag then JPEG (= JFIF) data
+ case 0x6E0 : // One byte tag then PNG data
+ case 0x7A8 :
+ nSkip += 1; // One byte tag then DIB data
+ break;
+ }
+ rBLIPStream.SeekRel( nSkip );
+
+ SvStream* pGrStream = &rBLIPStream;
+ SvMemoryStream* pOut = NULL;
+ if( bZCodecCompression )
+ {
+ pOut = new SvMemoryStream( 0x8000, 0x4000 );
+ ZCodec aZCodec( 0x8000, 0x8000 );
+ aZCodec.BeginCompression();
+ aZCodec.Decompress( rBLIPStream, *pOut );
+ aZCodec.EndCompression();
+ pOut->Seek( STREAM_SEEK_TO_BEGIN );
+ pGrStream = pOut;
+ }
+
+//#define DBG_EXTRACTGRAPHICS
+#ifdef DBG_EXTRACTGRAPHICS
+
+ static sal_Int32 nCount;
+
+ String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) );
+ aFileName.Append( String::CreateFromInt32( nCount++ ) );
+ switch( nInst &~ 1 )
+ {
+ case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break;
+ case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break;
+ case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break;
+ case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
+ case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break;
+ case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break;
+ }
+
+ String aURLStr;
+
+ if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
+ {
+ INetURLObject aURL( aURLStr );
+
+ aURL.removeSegment();
+ aURL.removeFinalSlash();
+ aURL.Append( aFileName );
+
+ SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE );
+
+ if( pDbgOut )
+ {
+ if ( bZCodecCompression )
+ {
+ pOut->Seek( STREAM_SEEK_TO_END );
+ pDbgOut->Write( pOut->GetData(), pOut->Tell() );
+ pOut->Seek( STREAM_SEEK_TO_BEGIN );
+ }
+ else
+ {
+ sal_Int32 nDbgLen = nLength - nSkip;
+ if ( nDbgLen )
+ {
+ sal_Char* pDat = new sal_Char[ nDbgLen ];
+ pGrStream->Read( pDat, nDbgLen );
+ pDbgOut->Write( pDat, nDbgLen );
+ pGrStream->SeekRel( -nDbgLen );
+ delete[] pDat;
+ }
+ }
+
+ delete pDbgOut;
+ }
+ }
+#endif
+
+ if( ( nInst & 0xFFFE ) == 0x7A8 )
+ { // DIBs direkt holen
+ Bitmap aNew;
+ if( aNew.Read( *pGrStream, FALSE ) )
+ {
+ rData = Graphic( aNew );
+ nRes = GRFILTER_OK;
+ }
+ }
+ else
+ { // und unsere feinen Filter darauf loslassen
+ GraphicFilter* pGF = GetGrfFilter();
+ String aEmptyStr;
+ nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW );
+
+ // SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems,
+ // then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the
+ // scaling has been implemented does not happen anymore.
+ //
+ // For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the
+ // dxarray is empty (this has been solved in wmf/emf but not for pict)
+ if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) )
+ {
+ if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) )
+ { // #75956#, scaling does not work properly, if the graphic is less than 1cm
+ GDIMetaFile aMtf( rData.GetGDIMetaFile() );
+ const Size aOldSize( aMtf.GetPrefSize() );
+
+ if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) &&
+ aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) )
+ {
+ aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(),
+ (double) aMtfSize100.Height() / aOldSize.Height() );
+ aMtf.SetPrefSize( aMtfSize100 );
+ aMtf.SetPrefMapMode( MAP_100TH_MM );
+ rData = aMtf;
+ }
+ }
+ }
+ }
+ // ggfs. Fehlerstatus zuruecksetzen
+ if ( ERRCODE_IO_PENDING == pGrStream->GetError() )
+ pGrStream->ResetError();
+ delete pOut;
+ }
+ rBLIPStream.Seek( nOldPos ); // alte FilePos des Streams restaurieren
+
+ return ( GRFILTER_OK == nRes ); // Ergebniss melden
+}
+
+/* static */
+BOOL SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn)
+{
+ rRec.nFilePos = rIn.Tell();
+ return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer,
+ rRec.nRecInstance,
+ rRec.nRecType,
+ rRec.nRecLen );
+}
+
+
+/* auch static */
+BOOL SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt,
+ BYTE& rVer,
+ USHORT& rInst,
+ USHORT& rFbt,
+ UINT32& rLength )
+{
+ sal_uInt16 nTmp;
+ rSt >> nTmp >> rFbt >> rLength;
+ rVer = sal::static_int_cast< BYTE >(nTmp & 15);
+ rInst = nTmp >> 4;
+ return rSt.GetError() == 0;
+}
+
+
+
+
+BOOL SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, ULONG nDatLen,
+ char*& rpBuff, UINT32& rBuffLen ) const
+{
+ if( nDatLen )
+ {
+ rpBuff = new char[ nDatLen ];
+ rBuffLen = nDatLen;
+ rStData.Read( rpBuff, nDatLen );
+ }
+ return TRUE;
+}
+
+BOOL SvxMSDffManager::ProcessClientData(SvStream& rStData, ULONG nDatLen,
+ char*& rpBuff, UINT32& rBuffLen ) const
+{
+ if( nDatLen )
+ {
+ rpBuff = new char[ nDatLen ];
+ rBuffLen = nDatLen;
+ rStData.Read( rpBuff, nDatLen );
+ }
+ return TRUE;
+}
+
+
+void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ )
+{
+ return; // wird von SJ im Draw ueberladen
+}
+
+ULONG SvxMSDffManager::Calc_nBLIPPos( ULONG nOrgVal, ULONG /* nStreamPos */ ) const
+{
+ return nOrgVal;
+}
+
+BOOL SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const
+{
+ return FALSE;
+}
+
+BOOL SvxMSDffManager::ShapeHasText( ULONG /* nShapeId */, ULONG /* nFilePos */ ) const
+{
+ return TRUE;
+}
+
+// --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup>
+SdrObject* SvxMSDffManager::ImportOLE( long nOLEId,
+ const Graphic& rGrf,
+ const Rectangle& rBoundRect,
+ const Rectangle& rVisArea,
+ const int /* _nCalledByGroup */,
+ sal_Int64 nAspect ) const
+// <--
+{
+ SdrObject* pRet = 0;
+ String sStorageName;
+ SvStorageRef xSrcStg;
+ ErrCode nError = ERRCODE_NONE;
+ uno::Reference < embed::XStorage > xDstStg;
+ if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
+ pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg,
+ rGrf, rBoundRect, rVisArea, pStData, nError,
+ nSvxMSDffOLEConvFlags, nAspect );
+ return pRet;
+}
+
+const GDIMetaFile* SvxMSDffManager::lcl_GetMetaFileFromGrf_Impl( const Graphic& rGrf,
+ GDIMetaFile& rMtf )
+{
+ const GDIMetaFile* pMtf;
+ if( GRAPHIC_BITMAP == rGrf.GetType() )
+ {
+ Point aPt;
+ const Size aSz(lcl_GetPrefSize(rGrf, MAP_100TH_MM));
+
+ VirtualDevice aVirtDev;
+ aVirtDev.EnableOutput( FALSE );
+ MapMode aMM(MAP_100TH_MM);
+ aVirtDev.SetMapMode( aMM );
+
+ rMtf.Record( &aVirtDev );
+ rGrf.Draw( &aVirtDev, aPt, aSz );
+ rMtf.Stop();
+ rMtf.SetPrefMapMode(aMM);
+ rMtf.SetPrefSize( aSz );
+
+ pMtf = &rMtf;
+ }
+ else
+ pMtf = &rGrf.GetGDIMetaFile();
+ return pMtf;
+}
+
+BOOL SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf )
+{
+ String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) );
+ SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream );
+ xStm->SetVersion( pStor->GetVersion() );
+ xStm->SetBufferSize( 8192 );
+
+ USHORT nAspect = ASPECT_CONTENT;
+ ULONG nAdviseModes = 2;
+
+ Impl_OlePres aEle( FORMAT_GDIMETAFILE );
+ // Die Groesse in 1/100 mm umrechnen
+ // Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird,
+ // versucht SV einen BestMatchden richtigen Wert zu raten.
+ Size aSize = rMtf.GetPrefSize();
+ MapMode aMMSrc = rMtf.GetPrefMapMode();
+ MapMode aMMDst( MAP_100TH_MM );
+ aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
+ aEle.SetSize( aSize );
+ aEle.SetAspect( nAspect );
+ aEle.SetAdviseFlags( nAdviseModes );
+ aEle.SetMtf( rMtf );
+ aEle.Write( *xStm );
+
+ xStm->SetBufferSize( 0 );
+ return xStm->GetError() == SVSTREAM_OK;
+}
+
+struct ClsIDs {
+ UINT32 nId;
+ const sal_Char* pSvrName;
+ const sal_Char* pDspName;
+};
+static ClsIDs aClsIDs[] = {
+
+ { 0x000212F0, "MSWordArt", "Microsoft Word Art" },
+ { 0x000212F0, "MSWordArt.2", "Microsoft Word Art 2.0" },
+
+ // MS Apps
+ { 0x00030000, "ExcelWorksheet", "Microsoft Excel Worksheet" },
+ { 0x00030001, "ExcelChart", "Microsoft Excel Chart" },
+ { 0x00030002, "ExcelMacrosheet", "Microsoft Excel Macro" },
+ { 0x00030003, "WordDocument", "Microsoft Word Document" },
+ { 0x00030004, "MSPowerPoint", "Microsoft PowerPoint" },
+ { 0x00030005, "MSPowerPointSho", "Microsoft PowerPoint Slide Show"},
+ { 0x00030006, "MSGraph", "Microsoft Graph" },
+ { 0x00030007, "MSDraw", "Microsoft Draw" },
+ { 0x00030008, "Note-It", "Microsoft Note-It" },
+ { 0x00030009, "WordArt", "Microsoft Word Art" },
+ { 0x0003000a, "PBrush", "Microsoft PaintBrush Picture" },
+ { 0x0003000b, "Equation", "Microsoft Equation Editor" },
+ { 0x0003000c, "Package", "Package" },
+ { 0x0003000d, "SoundRec", "Sound" },
+ { 0x0003000e, "MPlayer", "Media Player" },
+ // MS Demos
+ { 0x0003000f, "ServerDemo", "OLE 1.0 Server Demo" },
+ { 0x00030010, "Srtest", "OLE 1.0 Test Demo" },
+ { 0x00030011, "SrtInv", "OLE 1.0 Inv Demo" },
+ { 0x00030012, "OleDemo", "OLE 1.0 Demo" },
+
+ // Coromandel / Dorai Swamy / 718-793-7963
+ { 0x00030013, "CoromandelIntegra", "Coromandel Integra" },
+ { 0x00030014, "CoromandelObjServer","Coromandel Object Server" },
+
+ // 3-d Visions Corp / Peter Hirsch / 310-325-1339
+ { 0x00030015, "StanfordGraphics", "Stanford Graphics" },
+
+ // Deltapoint / Nigel Hearne / 408-648-4000
+ { 0x00030016, "DGraphCHART", "DeltaPoint Graph Chart" },
+ { 0x00030017, "DGraphDATA", "DeltaPoint Graph Data" },
+
+ // Corel / Richard V. Woodend / 613-728-8200 x1153
+ { 0x00030018, "PhotoPaint", "Corel PhotoPaint" },
+ { 0x00030019, "CShow", "Corel Show" },
+ { 0x0003001a, "CorelChart", "Corel Chart" },
+ { 0x0003001b, "CDraw", "Corel Draw" },
+
+ // Inset Systems / Mark Skiba / 203-740-2400
+ { 0x0003001c, "HJWIN1.0", "Inset Systems" },
+
+ // Mark V Systems / Mark McGraw / 818-995-7671
+ { 0x0003001d, "ObjMakerOLE", "MarkV Systems Object Maker" },
+
+ // IdentiTech / Mike Gilger / 407-951-9503
+ { 0x0003001e, "FYI", "IdentiTech FYI" },
+ { 0x0003001f, "FYIView", "IdentiTech FYI Viewer" },
+
+ // Inventa Corporation / Balaji Varadarajan / 408-987-0220
+ { 0x00030020, "Stickynote", "Inventa Sticky Note" },
+
+ // ShapeWare Corp. / Lori Pearce / 206-467-6723
+ { 0x00030021, "ShapewareVISIO10", "Shapeware Visio 1.0" },
+ { 0x00030022, "ImportServer", "Spaheware Import Server" },
+
+ // test app SrTest
+ { 0x00030023, "SrvrTest", "OLE 1.0 Server Test" },
+
+ // test app ClTest. Doesn't really work as a server but is in reg db
+ { 0x00030025, "Cltest", "OLE 1.0 Client Test" },
+
+ // Microsoft ClipArt Gallery Sherry Larsen-Holmes
+ { 0x00030026, "MS_ClipArt_Gallery", "Microsoft ClipArt Gallery" },
+ // Microsoft Project Cory Reina
+ { 0x00030027, "MSProject", "Microsoft Project" },
+
+ // Microsoft Works Chart
+ { 0x00030028, "MSWorksChart", "Microsoft Works Chart" },
+
+ // Microsoft Works Spreadsheet
+ { 0x00030029, "MSWorksSpreadsheet", "Microsoft Works Spreadsheet" },
+
+ // AFX apps - Dean McCrory
+ { 0x0003002A, "MinSvr", "AFX Mini Server" },
+ { 0x0003002B, "HierarchyList", "AFX Hierarchy List" },
+ { 0x0003002C, "BibRef", "AFX BibRef" },
+ { 0x0003002D, "MinSvrMI", "AFX Mini Server MI" },
+ { 0x0003002E, "TestServ", "AFX Test Server" },
+
+ // Ami Pro
+ { 0x0003002F, "AmiProDocument", "Ami Pro Document" },
+
+ // WordPerfect Presentations For Windows
+ { 0x00030030, "WPGraphics", "WordPerfect Presentation" },
+ { 0x00030031, "WPCharts", "WordPerfect Chart" },
+
+ // MicroGrafx Charisma
+ { 0x00030032, "Charisma", "MicroGrafx Charisma" },
+ { 0x00030033, "Charisma_30", "MicroGrafx Charisma 3.0" },
+ { 0x00030034, "CharPres_30", "MicroGrafx Charisma 3.0 Pres" },
+ // MicroGrafx Draw
+ { 0x00030035, "Draw", "MicroGrafx Draw" },
+ // MicroGrafx Designer
+ { 0x00030036, "Designer_40", "MicroGrafx Designer 4.0" },
+
+ // STAR DIVISION
+// { 0x000424CA, "StarMath", "StarMath 1.0" },
+ { 0x00043AD2, "FontWork", "Star FontWork" },
+// { 0x000456EE, "StarMath2", "StarMath 2.0" },
+
+ { 0, "", "" } };
+
+
+BOOL SvxMSDffManager::ConvertToOle2( SvStream& rStm, UINT32 nReadLen,
+ const GDIMetaFile * pMtf, const SotStorageRef& rDest )
+{
+ BOOL bMtfRead = FALSE;
+ SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ),
+ STREAM_WRITE| STREAM_SHARE_DENYALL );
+ if( xOle10Stm->GetError() )
+ return FALSE;
+
+ UINT32 nType;
+ UINT32 nRecType;
+ UINT32 nStrLen;
+ String aSvrName;
+ UINT32 nDummy0;
+ UINT32 nDummy1;
+ UINT32 nDataLen;
+ BYTE * pData;
+ UINT32 nBytesRead = 0;
+ do
+ {
+ rStm >> nType;
+ rStm >> nRecType;
+ rStm >> nStrLen;
+ if( nStrLen )
+ {
+ if( 0x10000L > nStrLen )
+ {
+ sal_Char * pBuf = new sal_Char[ nStrLen ];
+ rStm.Read( pBuf, nStrLen );
+ aSvrName.Assign( String( pBuf, (USHORT) nStrLen-1, gsl_getSystemTextEncoding() ) );
+ delete[] pBuf;
+ }
+ else
+ break;
+ }
+ rStm >> nDummy0;
+ rStm >> nDummy1;
+ rStm >> nDataLen;
+
+ nBytesRead += 6 * sizeof( UINT32 ) + nStrLen + nDataLen;
+
+ if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen )
+ {
+ if( xOle10Stm.Is() )
+ {
+ pData = new BYTE[ nDataLen ];
+ if( !pData )
+ return FALSE;
+
+ rStm.Read( pData, nDataLen );
+
+ // write to ole10 stream
+ *xOle10Stm << nDataLen;
+ xOle10Stm->Write( pData, nDataLen );
+ xOle10Stm = SotStorageStreamRef();
+
+ // set the compobj stream
+ ClsIDs* pIds;
+ for( pIds = aClsIDs; pIds->nId; pIds++ )
+ {
+ if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) )
+ break;
+ }
+// SvGlobalName* pClsId = NULL;
+ String aShort, aFull;
+ if( pIds->nId )
+ {
+ // gefunden!
+ ULONG nCbFmt = SotExchange::RegisterFormatName( aSvrName );
+ rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt,
+ String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) );
+ }
+ else
+ {
+ ULONG nCbFmt = SotExchange::RegisterFormatName( aSvrName );
+ rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName );
+ }
+
+ delete[] pData;
+ }
+ else if( nRecType == 5 && !pMtf )
+ {
+ ULONG nPos = rStm.Tell();
+ UINT16 sz[4];
+ rStm.Read( sz, 8 );
+ //rStm.SeekRel( 8 );
+ Graphic aGraphic;
+ if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() )
+ {
+ const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
+ MakeContentStream( rDest, rMtf );
+ bMtfRead = TRUE;
+ }
+ // set behind the data
+ rStm.Seek( nPos + nDataLen );
+ }
+ else
+ rStm.SeekRel( nDataLen );
+ }
+ } while( !rStm.IsEof() && nReadLen >= nBytesRead );
+
+ if( !bMtfRead && pMtf )
+ {
+ MakeContentStream( rDest, *pMtf );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName )
+{
+ if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 )
+ || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
+ return "swriter";
+ else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 )
+ || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
+ return "scalc";
+ else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 )
+ || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
+ return "simpress";
+ else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 )
+ || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
+ return "sdraw";
+ else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 )
+ || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
+ return "smath";
+ else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 )
+ || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
+ return "schart";
+ return 0;
+}
+
+::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
+{
+ if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) );
+
+ if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) );
+
+ return ::rtl::OUString();
+}
+
+com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > SvxMSDffManager::CheckForConvertToSOObj( UINT32 nConvertFlags,
+ SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage,
+ const Graphic& rGrf,
+ const Rectangle& rVisArea )
+{
+ uno::Reference < embed::XEmbeddedObject > xObj;
+ SvGlobalName aStgNm = rSrcStg.GetClassName();
+ const char* pName = GetInternalServerName_Impl( aStgNm );
+ String sStarName;
+ if ( pName )
+ sStarName = String::CreateFromAscii( pName );
+ else if ( nConvertFlags )
+ {
+ static struct _ObjImpType
+ {
+ UINT32 nFlag;
+ const char* pFactoryNm;
+ // GlobalNameId
+ UINT32 n1;
+ USHORT n2, n3;
+ BYTE b8, b9, b10, b11, b12, b13, b14, b15;
+ } aArr[] = {
+ { OLE_MATHTYPE_2_STARMATH, "smath",
+ 0x0002ce02L, 0x0000, 0x0000,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
+ { OLE_MATHTYPE_2_STARMATH, "smath",
+ 0x00021700L, 0x0000, 0x0000,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
+ { OLE_WINWORD_2_STARWRITER, "swriter",
+ 0x00020906L, 0x0000, 0x0000,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
+ { OLE_EXCEL_2_STARCALC, "scalc", // Excel table
+ 0x00020810L, 0x0000, 0x0000,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
+ { OLE_EXCEL_2_STARCALC, "scalc", // Excel chart
+ 0x00020820L, 0x0000, 0x0000,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
+ // 114465: additional Excel OLE chart classId to above.
+ { OLE_EXCEL_2_STARCALC, "scalc",
+ 0x00020821L, 0x0000, 0x0000,
+ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
+ { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint presentation
+ 0x64818d10L, 0x4f9b, 0x11cf,
+ 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
+ { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint slide
+ 0x64818d11L, 0x4f9b, 0x11cf,
+ 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
+ { 0, 0,
+ 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 }
+ };
+
+ for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr )
+ {
+ if( nConvertFlags & pArr->nFlag )
+ {
+ SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3,
+ pArr->b8, pArr->b9, pArr->b10, pArr->b11,
+ pArr->b12, pArr->b13, pArr->b14, pArr->b15 );
+
+ if ( aStgNm == aTypeName )
+ {
+ sStarName = String::CreateFromAscii( pArr->pFactoryNm );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( sStarName.Len() )
+ {
+ //TODO/MBA: check if (and when) storage and stream will be destroyed!
+ const SfxFilter* pFilter = 0;
+ SvMemoryStream* pStream = new SvMemoryStream;
+ if ( pName )
+ {
+ // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also
+ SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ );
+ *xStr >> *pStream;
+ }
+ else
+ {
+ SfxFilterMatcher aMatch( sStarName );
+ SotStorageRef xStorage = new SotStorage( FALSE, *pStream );
+ rSrcStg.CopyTo( xStorage );
+ xStorage->Commit();
+ xStorage.Clear();
+ String aType = SfxFilter::GetTypeFromStorage( rSrcStg );
+ if ( aType.Len() )
+ pFilter = aMatch.GetFilter4EA( aType );
+ }
+
+ if ( pName || pFilter )
+ {
+ //Reuse current ole name
+ String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
+ aDstStgName += String::CreateFromInt32(nMSOleObjCntr);
+
+ ::rtl::OUString aFilterName;
+ if ( pFilter )
+ aFilterName = pFilter->GetName();
+ else
+ aFilterName = GetFilterNameFromClassID_Impl( aStgNm );
+
+ uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2);
+ aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
+ uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream );
+ aMedium[0].Value <<= xStream;
+ aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
+ aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
+
+ if ( aFilterName.getLength() )
+ {
+ aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
+ aMedium[2].Value <<= aFilterName;
+ }
+
+ ::rtl::OUString aName( aDstStgName );
+ comphelper::EmbeddedObjectContainer aCnt( rDestStorage );
+ xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
+
+ if ( !xObj.is() )
+ {
+ if( aFilterName.getLength() )
+ {
+ // throw the filter parameter away as workaround
+ aMedium.realloc( 2 );
+ xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
+ }
+
+ if ( !xObj.is() )
+ return xObj;
+ }
+
+ // TODO/LATER: ViewAspect must be passed from outside!
+ sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT;
+
+ // JP 26.10.2001: Bug 93374 / 91928 the writer
+ // objects need the correct visarea needs the
+ // correct visarea, but this is not true for
+ // PowerPoint (see bugdoc 94908b)
+ // SJ: 19.11.2001 bug 94908, also chart objects
+ // needs the correct visarea
+
+ // If pName is set this is an own embedded object, it should have the correct size internally
+ // TODO/LATER: it might make sence in future to set the size stored in internal object
+ if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) )
+ {
+ MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) );
+ Size aSz;
+ if ( rVisArea.IsEmpty() )
+ aSz = lcl_GetPrefSize(rGrf, aMapMode );
+ else
+ {
+ aSz = rVisArea.GetSize();
+ aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode );
+ }
+
+ // don't modify the object
+ //TODO/LATER: remove those hacks, that needs to be done differently!
+ //xIPObj->EnableSetModified( FALSE );
+ awt::Size aSize;
+ aSize.Width = aSz.Width();
+ aSize.Height = aSz.Height();
+ xObj->setVisualAreaSize( nViewAspect, aSize );
+ //xIPObj->EnableSetModified( TRUE );
+ }
+ else if ( sStarName.EqualsAscii( "smath" ) )
+ { // SJ: force the object to recalc its visarea
+ //TODO/LATER: wait for PrinterChangeNotification
+ //xIPObj->OnDocumentPrinterChanged( NULL );
+ }
+ }
+ }
+
+ return xObj;
+}
+
+// TODO/MBA: code review and testing!
+SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage(
+ const String& rStorageName,
+ SotStorageRef& rSrcStorage,
+ const uno::Reference < embed::XStorage >& xDestStorage,
+ const Graphic& rGrf,
+ const Rectangle& rBoundRect,
+ const Rectangle& rVisArea,
+ SvStream* pDataStrm,
+ ErrCode& rError,
+ UINT32 nConvertFlags,
+ sal_Int64 nReccomendedAspect )
+{
+ sal_Int64 nAspect = nReccomendedAspect;
+ SdrOle2Obj* pRet = 0;
+ if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() )
+ {
+ comphelper::EmbeddedObjectContainer aCnt( xDestStorage );
+ // Ist der 01Ole-Stream ueberhaupt vorhanden ?
+ // ( ist er z.B. bei FontWork nicht )
+ // Wenn nicht -> Einbindung als Grafik
+ BOOL bValidStorage = FALSE;
+ String aDstStgName( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
+
+ aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr );
+
+ {
+ SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName,
+ STREAM_READWRITE| STREAM_SHARE_DENYALL );
+ if( xObjStg.Is() )
+ {
+ {
+ BYTE aTestA[10]; // exist the \1CompObj-Stream ?
+ SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream(
+ String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"),
+ RTL_TEXTENCODING_MS_1252 ));
+ bValidStorage = xSrcTst.Is() && sizeof( aTestA ) ==
+ xSrcTst->Read( aTestA, sizeof( aTestA ) );
+ if( !bValidStorage )
+ {
+ // or the \1Ole-Stream ?
+ xSrcTst = xObjStg->OpenSotStream(
+ String(RTL_CONSTASCII_STRINGPARAM("\1Ole"),
+ RTL_TEXTENCODING_MS_1252 ));
+ bValidStorage = xSrcTst.Is() && sizeof(aTestA) ==
+ xSrcTst->Read(aTestA, sizeof(aTestA));
+ }
+ }
+
+ if( bValidStorage )
+ {
+ if ( nAspect != embed::Aspects::MSOLE_ICON )
+ {
+ // check whether the object is iconified one
+ // usually this information is already known, the only exception
+ // is a kind of embedded objects in Word documents
+ // TODO/LATER: should the caller be notified if the aspect changes in future?
+
+ SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream(
+ String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ),
+ STREAM_STD_READ | STREAM_NOCREATE );
+ if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
+ {
+ BYTE nByte = 0;
+ *xObjInfoSrc >> nByte;
+ if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
+ nAspect = embed::Aspects::MSOLE_ICON;
+ }
+ }
+
+ uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj(
+ nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea ));
+ if ( xObj.is() )
+ {
+ svt::EmbeddedObjectRef aObj( xObj, nAspect );
+
+ // TODO/LATER: need MediaType
+ aObj.SetGraphic( rGrf, ::rtl::OUString() );
+
+ // TODO/MBA: check setting of PersistName
+ pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false);
+ // we have the Object, don't create another
+ bValidStorage = false;
+ }
+ }
+ }
+ }
+
+ if( bValidStorage )
+ {
+ // object is not an own object
+ SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE );
+
+ if ( xObjStor.Is() )
+ {
+ SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ );
+ xSrcStor->CopyTo( xObjStor );
+
+ if( !xObjStor->GetError() )
+ xObjStor->Commit();
+
+ if( xObjStor->GetError() )
+ {
+ rError = xObjStor->GetError();
+ bValidStorage = FALSE;
+ }
+ else if( !xObjStor.Is() )
+ bValidStorage = FALSE;
+ }
+ }
+ else if( pDataStrm )
+ {
+ UINT32 nLen, nDummy;
+ *pDataStrm >> nLen >> nDummy;
+ if( SVSTREAM_OK != pDataStrm->GetError() ||
+ // Id in BugDoc - exist there other Ids?
+ // The ConvertToOle2 - does not check for consistent
+ 0x30008 != nDummy )
+ bValidStorage = FALSE;
+ else
+ {
+ // or is it an OLE-1 Stream in the DataStream?
+ SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName );
+ //TODO/MBA: remove metafile conversion from ConvertToOle2
+ //when is this code used?!
+ GDIMetaFile aMtf;
+ bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor );
+ xObjStor->Commit();
+ }
+ }
+
+ if( bValidStorage )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName );
+ if( xObj.is() )
+ {
+ // the visual area must be retrieved from the metafile (object doesn't know it so far)
+
+ if ( nAspect != embed::Aspects::MSOLE_ICON )
+ {
+ // working with visual area can switch the object to running state
+ awt::Size aAwtSz;
+ try
+ {
+ // the provided visual area should be used, if there is any
+ if ( rVisArea.IsEmpty() )
+ {
+ MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
+ Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit)));
+ aAwtSz.Width = aSz.Width();
+ aAwtSz.Height = aSz.Height();
+ }
+ else
+ {
+ aAwtSz.Width = rVisArea.GetWidth();
+ aAwtSz.Height = rVisArea.GetHeight();
+ }
+ //xInplaceObj->EnableSetModified( FALSE );
+ xObj->setVisualAreaSize( nAspect, aAwtSz );
+ //xInplaceObj->EnableSetModified( TRUE );*/
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" );
+ }
+ }
+
+ svt::EmbeddedObjectRef aObj( xObj, nAspect );
+
+ // TODO/LATER: need MediaType
+ aObj.SetGraphic( rGrf, ::rtl::OUString() );
+
+ pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false);
+ }
+ }
+ }
+
+ return pRet;
+}
+
+SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const
+{
+ SdrObject* pRet = NULL;
+
+ if(120 >= UINT16(eTyp))
+ {
+ pRet = new SdrRectObj();
+ }
+
+ DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM");
+
+ return pRet;
+}
+
+sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
+ const String& rPropName, sal_Bool bTestPropertyAvailability )
+{
+ sal_Bool bRetValue = sal_True;
+ if ( bTestPropertyAvailability )
+ {
+ bRetValue = sal_False;
+ try
+ {
+ uno::Reference< beans::XPropertySetInfo >
+ aXPropSetInfo( rXPropSet->getPropertySetInfo() );
+ if ( aXPropSetInfo.is() )
+ bRetValue = aXPropSetInfo->hasPropertyByName( rPropName );
+ }
+ catch( uno::Exception& )
+ {
+ bRetValue = sal_False;
+ }
+ }
+ if ( bRetValue )
+ {
+ try
+ {
+ rXPropSet->setPropertyValue( rPropName, rAny );
+ bRetValue = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ bRetValue = sal_False;
+ }
+ }
+ return bRetValue;
+}
+
+SvxMSDffImportRec::SvxMSDffImportRec()
+ : pObj( 0 ),
+ pWrapPolygon(0),
+ pClientAnchorBuffer( 0 ),
+ nClientAnchorLen( 0 ),
+ pClientDataBuffer( 0 ),
+ nClientDataLen( 0 ),
+ nXAlign( 0 ), // position n cm from left
+ nXRelTo( 2 ), // relative to column
+ nYAlign( 0 ), // position n cm below
+ nYRelTo( 2 ), // relative to paragraph
+ nLayoutInTableCell( 0 ), // element is laid out in table cell
+ nTextRotationAngle( 0 ),
+ nDxTextLeft( 144 ),
+ nDyTextTop( 72 ),
+ nDxTextRight( 144 ),
+ nDyTextBottom( 72 ),
+ nDxWrapDistLeft( 0 ),
+ nDyWrapDistTop( 0 ),
+ nDxWrapDistRight( 0 ),
+ nDyWrapDistBottom(0 ),
+ nCropFromTop( 0 ),
+ nCropFromBottom( 0 ),
+ nCropFromLeft( 0 ),
+ nCropFromRight( 0 ),
+ aTextId( 0, 0 ),
+ nNextShapeId( 0 ),
+ nShapeId( 0 ),
+ eShapeType( mso_sptNil )
+{
+ eLineStyle = mso_lineSimple; // GPF-Bug #66227#
+ bDrawHell = FALSE;
+ bHidden = FALSE;
+// bInGroup = FALSE;
+ bReplaceByFly = FALSE;
+ bLastBoxInChain = TRUE;
+ bHasUDefProp = FALSE; // was the DFF_msofbtUDefProp record set?
+ bVFlip = FALSE;
+ bHFlip = FALSE;
+ bAutoWidth = FALSE;
+}
+
+SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy)
+ : pObj( rCopy.pObj ),
+ nXAlign( rCopy.nXAlign ),
+ nXRelTo( rCopy.nXRelTo ),
+ nYAlign( rCopy.nYAlign ),
+ nYRelTo( rCopy.nYRelTo ),
+ nLayoutInTableCell( rCopy.nLayoutInTableCell ),
+ nTextRotationAngle( rCopy.nTextRotationAngle ),
+ nDxTextLeft( rCopy.nDxTextLeft ),
+ nDyTextTop( rCopy.nDyTextTop ),
+ nDxTextRight( rCopy.nDxTextRight ),
+ nDyTextBottom( rCopy.nDyTextBottom ),
+ nDxWrapDistLeft( rCopy.nDxWrapDistLeft ),
+ nDyWrapDistTop( rCopy.nDyWrapDistTop ),
+ nDxWrapDistRight( rCopy.nDxWrapDistRight ),
+ nDyWrapDistBottom(rCopy.nDyWrapDistBottom ),
+ nCropFromTop( rCopy.nCropFromTop ),
+ nCropFromBottom( rCopy.nCropFromBottom ),
+ nCropFromLeft( rCopy.nCropFromLeft ),
+ nCropFromRight( rCopy.nCropFromRight ),
+ aTextId( rCopy.aTextId ),
+ nNextShapeId( rCopy.nNextShapeId ),
+ nShapeId( rCopy.nShapeId ),
+ eShapeType( rCopy.eShapeType )
+{
+ eLineStyle = rCopy.eLineStyle; // GPF-Bug #66227#
+ bDrawHell = rCopy.bDrawHell;
+ bHidden = rCopy.bHidden;
+// bInGroup = rCopy.bInGroup;
+ bReplaceByFly = rCopy.bReplaceByFly;
+ bAutoWidth = rCopy.bAutoWidth;
+ bLastBoxInChain = rCopy.bLastBoxInChain;
+ bHasUDefProp = rCopy.bHasUDefProp;
+ bVFlip = rCopy.bVFlip;
+ bHFlip = rCopy.bHFlip;
+ nClientAnchorLen = rCopy.nClientAnchorLen;
+ if( rCopy.nClientAnchorLen )
+ {
+ pClientAnchorBuffer = new char[ nClientAnchorLen ];
+ memcpy( pClientAnchorBuffer,
+ rCopy.pClientAnchorBuffer,
+ nClientAnchorLen );
+ }
+ else
+ pClientAnchorBuffer = 0;
+
+ nClientDataLen = rCopy.nClientDataLen;
+ if( rCopy.nClientDataLen )
+ {
+ pClientDataBuffer = new char[ nClientDataLen ];
+ memcpy( pClientDataBuffer,
+ rCopy.pClientDataBuffer,
+ nClientDataLen );
+ }
+ else
+ pClientDataBuffer = 0;
+
+ if (rCopy.pWrapPolygon)
+ pWrapPolygon = new Polygon(*rCopy.pWrapPolygon);
+ else
+ pWrapPolygon = 0;
+}
+
+SvxMSDffImportRec::~SvxMSDffImportRec()
+{
+ if (pClientAnchorBuffer)
+ delete[] pClientAnchorBuffer;
+ if (pClientDataBuffer)
+ delete[] pClientDataBuffer;
+ if (pWrapPolygon)
+ delete pWrapPolygon;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
+
+void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape )
+{
+ maShapeIdContainer[nShapeId] = pShape;
+}
+
+void SvxMSDffManager::removeShapeId( SdrObject* pShape )
+{
+ SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() );
+ const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() );
+ while( aIter != aEnd )
+ {
+ if( (*aIter).second == pShape )
+ {
+ maShapeIdContainer.erase( aIter );
+ break;
+ }
+ }
+}
+
+SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId )
+{
+ SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) );
+ return aIter != maShapeIdContainer.end() ? (*aIter).second : 0;
+}
diff --git a/filter/source/msfilter/msfiltertracer.cxx b/filter/source/msfilter/msfiltertracer.cxx
new file mode 100644
index 000000000000..417fd906f22f
--- /dev/null
+++ b/filter/source/msfilter/msfiltertracer.cxx
@@ -0,0 +1,254 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msfiltertracer.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * 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_filter.hxx"
+#include <filter/msfilter/msfiltertracer.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/util/logging/LogLevel.hpp>
+#include <com/sun/star/util/SearchAlgorithms.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <svtools/FilterConfigItem.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+
+// --------------
+// - Namespaces -
+// --------------
+
+using namespace ::com::sun::star;
+
+MSFilterTracer::MSFilterTracer( const ::rtl::OUString& rConfigPath, uno::Sequence< beans::PropertyValue >* pConfigData ) :
+ mpCfgItem( new FilterConfigItem( rConfigPath, pConfigData ) ),
+ mpAttributeList( new SvXMLAttributeList() ),
+ mpStream( NULL ),
+ mbEnabled( sal_False ) // will be set to true in StartTracing()
+{
+ if ( mpCfgItem->ReadBool( rtl::OUString::createFromAscii( "On" ), sal_False ) )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
+ if ( xMgr.is() )
+ {
+ /* the following methods try to read a property, if it is not available it will put the second
+ parameter as default into the property sequence of the FilterConfigItem. It means we ensure that
+ the property is available by trying to read it (the return value of the method is ignored) */
+ ::rtl::OUString aEmptyString;
+ mpCfgItem->ReadInt32( rtl::OUString::createFromAscii( "LogLevel" ), util::logging::LogLevel::ALL );
+ mpCfgItem->ReadString( rtl::OUString::createFromAscii( "ClassFilter" ), aEmptyString );
+ mpCfgItem->ReadString( rtl::OUString::createFromAscii( "MethodFilter" ), aEmptyString );
+ mpCfgItem->ReadString( rtl::OUString::createFromAscii( "MessageFilter" ), aEmptyString );
+ util::SearchAlgorithms eSearchAlgorithm = (util::SearchAlgorithms)
+ mpCfgItem->ReadInt32( rtl::OUString::createFromAscii( "SearchAlgorithm" ), util::SearchAlgorithms_ABSOLUTE );
+
+ // creating the name of the log file
+ rtl::OUString aPath( mpCfgItem->ReadString( rtl::OUString::createFromAscii( "Path" ), aEmptyString ) );
+ rtl::OUString aName( mpCfgItem->ReadString( rtl::OUString::createFromAscii( "Name" ), aEmptyString ) );
+ rtl::OUString aDocumentURL( mpCfgItem->ReadString( rtl::OUString::createFromAscii( "DocumentURL" ), aEmptyString ) );
+ INetURLObject aLogFile( aDocumentURL );
+ if ( aLogFile.GetMainURL( INetURLObject::NO_DECODE ).getLength() )
+ {
+ if ( aPath.getLength() )
+ {
+ String aOldName( aLogFile.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::NO_DECODE ) );
+ aLogFile = INetURLObject( aPath );
+ aLogFile.insertName( aOldName );
+ }
+ if ( aName.getLength() )
+ aLogFile.setName( aName );
+ }
+ else
+ {
+ if ( aPath.getLength() )
+ aLogFile = INetURLObject( aPath );
+ else
+ {
+ String aURLStr;
+ if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
+ {
+ aLogFile = INetURLObject(aURLStr);
+ aLogFile .removeSegment();
+ aLogFile .removeFinalSlash();
+ }
+ }
+ if ( !aName.getLength() )
+ aName = rtl::OUString::createFromAscii( "tracer" );
+ aLogFile.insertName( aName );
+ }
+ aLogFile.setExtension( rtl::OUString::createFromAscii( "log" ) );
+
+ // creating the file stream
+ mpStream = ::utl::UcbStreamHelper::CreateStream( aLogFile.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_TRUNC | STREAM_SHARE_DENYNONE );
+ if ( mpStream && !mpStream->GetError() )
+ {
+ // creating a wrapper for our stream
+ utl::OOutputStreamWrapper* pHelper = new ::utl::OOutputStreamWrapper( *mpStream );
+ uno::Reference< io::XOutputStream > xOutputStream( pHelper );
+
+ // instanciating the DocumentHandler, then setting the OutputStream
+ mxHandler = uno::Reference< xml::sax::XDocumentHandler >( xMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), uno::UNO_QUERY );
+ uno::Reference< io::XActiveDataSource > xDocSrc( mxHandler, uno::UNO_QUERY );
+ xDocSrc->setOutputStream( xOutputStream );
+ mxHandler->startDocument();
+ mxHandler->ignorableWhitespace ( rtl::OUString::createFromAscii( " " ) );
+
+ // writing the "DocumentHandler" property, so the FilterTracer component
+ // will use it for the output
+ uno::Any aAny;
+ aAny <<= xDocSrc;
+ mpCfgItem->WriteAny( rtl::OUString::createFromAscii( "DocumentHandler" ), aAny );
+
+ SvXMLAttributeList* pAttrList = new SvXMLAttributeList;
+ pAttrList->AddAttribute( rtl::OUString::createFromAscii( "DocumentURL" ), aDocumentURL );
+ uno::Reference < xml::sax::XAttributeList > xAttributeList(pAttrList);
+ mxHandler->startElement( rtl::OUString::createFromAscii( "Document" ), xAttributeList );
+ }
+
+ uno::Sequence< uno::Any > aArgument( 1 );
+ uno::Sequence< beans::PropertyValue > aPropValues( mpCfgItem->GetFilterData() );
+ aArgument[ 0 ] <<= aPropValues;
+ mxFilterTracer = xMgr->createInstanceWithArguments( rtl::OUString::createFromAscii( "com.sun.star.util.FilterTracer" ), aArgument );
+ if ( mxFilterTracer.is() )
+ {
+ mxTextSearch = uno::Reference< util::XTextSearch >( mxFilterTracer, uno::UNO_QUERY );
+ mxLogger = uno::Reference< util::logging::XLogger >( mxFilterTracer, uno::UNO_QUERY );
+ if ( mxTextSearch.is() )
+ {
+ maSearchOptions.algorithmType = eSearchAlgorithm;
+ mxTextSearch->setOptions( maSearchOptions );
+ }
+ }
+ }
+ }
+}
+
+MSFilterTracer::~MSFilterTracer()
+{
+ mxLogger = NULL;
+ mxFilterTracer = NULL;
+ if ( mxHandler.is() )
+ {
+ mxHandler->ignorableWhitespace ( rtl::OUString::createFromAscii( " " ) );
+ mxHandler->endElement( rtl::OUString::createFromAscii( "Document" ) );
+ mxHandler->ignorableWhitespace ( rtl::OUString::createFromAscii( " " ) );
+ mxHandler->endDocument();
+ mxHandler = NULL;
+ }
+ delete mpAttributeList;
+ delete mpCfgItem;
+ delete mpStream;
+}
+
+void MSFilterTracer::StartTracing()
+{
+ mbEnabled = mpCfgItem->ReadBool( rtl::OUString::createFromAscii( "On" ), sal_False );
+}
+
+void MSFilterTracer::EndTracing()
+{
+ mbEnabled = sal_False;
+}
+
+void MSFilterTracer::StartElement( const rtl::OUString& rName, uno::Reference< xml::sax::XAttributeList > xAttribs )
+{
+ if ( mxHandler.is() )
+ mxHandler->startElement( rName, xAttribs );
+}
+
+void MSFilterTracer::EndElement( const rtl::OUString& rName )
+{
+ if ( mxHandler.is() )
+ mxHandler->endElement( rName );
+}
+
+void MSFilterTracer::Trace( const rtl::OUString& rElement, const rtl::OUString& rMessage )
+{
+ if ( mbEnabled && mxLogger.is() )
+ {
+ sal_Bool bFilter = sal_False;
+ if ( rMessage.getLength() && mxTextSearch.is() )
+ {
+ maSearchOptions.searchString = rMessage;
+ mxTextSearch->setOptions( maSearchOptions );
+ util::SearchResult aSearchResult = mxTextSearch->searchForward( rMessage, 0, rMessage.getLength() );
+ bFilter = aSearchResult.subRegExpressions != 0;
+ }
+ if ( !bFilter )
+ {
+ uno::Reference < xml::sax::XAttributeList > xAttrList( new SvXMLAttributeList( *mpAttributeList ) );
+ if ( mxHandler.is() )
+ mxHandler->startElement( rElement, xAttrList );
+ if ( rMessage.getLength() )
+ {
+ rtl::OUString aEmpty;
+ mxLogger->logp( 0, aEmpty, aEmpty, rMessage );
+ }
+ if ( mxHandler.is() )
+ mxHandler->endElement( rElement );
+ }
+ }
+}
+
+void MSFilterTracer::AddAttribute( const ::rtl::OUString& sName , const ::rtl::OUString& sValue )
+{
+ if ( mbEnabled )
+ mpAttributeList->AddAttribute( sName, sValue );
+}
+void MSFilterTracer::ClearAttributes()
+{
+ if ( mbEnabled )
+ mpAttributeList->Clear();
+}
+
+void MSFilterTracer::RemoveAttribute( const ::rtl::OUString& sName )
+{
+ if ( mbEnabled )
+ mpAttributeList->RemoveAttribute( sName );
+}
+
+uno::Any MSFilterTracer::GetProperty( const rtl::OUString& rPropName, const uno::Any* pDefault ) const
+{
+ uno::Any aDefault;
+ if ( pDefault )
+ aDefault = *pDefault;
+ return mpCfgItem->ReadAny( rPropName, aDefault );
+}
+
+void MSFilterTracer::SetProperty( const ::rtl::OUString& rPropName, const uno::Any& rProperty )
+{
+ mpCfgItem->WriteAny( rPropName, rProperty );
+}
+
diff --git a/filter/source/msfilter/msocximex.cxx b/filter/source/msfilter/msocximex.cxx
new file mode 100644
index 000000000000..92c2ed1bd767
--- /dev/null
+++ b/filter/source/msfilter/msocximex.cxx
@@ -0,0 +1,5960 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msocximex.cxx,v $
+ * $Revision: 1.38 $
+ *
+ * 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_filter.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/XText.hpp>
+#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HDL_
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#endif
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/FormComponentType.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontStrikeout.hpp>
+#include <com/sun/star/awt/ScrollBarOrientation.hpp>
+#include <com/sun/star/style/VerticalAlignment.hpp>
+#include <comphelper/extract.hxx>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/io/XInputStreamProvider.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/objsh.hxx>
+#include <xmlscript/xmldlg_imexp.hxx>
+#include <filter/msfilter/msocximex.hxx>
+#include <osl/file.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <comphelper/processfactory.hxx> // shouldn't be needed
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <algorithm>
+#include <memory>
+
+#ifndef C2S
+#define C2S(cChar) String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(cChar))
+#endif
+#ifndef C2U
+#define C2U(cChar) rtl::OUString::createFromAscii(cChar)
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::rtl;
+using namespace cppu;
+
+
+#define WW8_ASCII2STR(s) String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(s))
+
+
+static char sWW8_form[] = "WW-Standard";
+
+
+struct SortOrderByTabPos
+{
+ bool operator()( const OCX_Control* a, const OCX_Control* b )
+ {
+ return a->mnTabPos < b->mnTabPos;
+ }
+};
+
+
+sal_uInt8 __READONLY_DATA OCX_Control::aObjInfo[4] = { 0x00, 0x12, 0x03, 0x00 };
+
+long ReadAlign(SvStorageStream *pS, long nPos, int nAmount)
+{
+ if (long nAlign = nPos % nAmount)
+ {
+
+ long nLen = nAmount - nAlign;
+ pS->SeekRel(nLen);
+ return nLen;
+ }
+ return 0;
+}
+
+
+// NP - Images in controls in OO2.0/SO8 exist as links, e.g. they are not part of the document so are
+// referenced externally. On import from ms document try to save images for controls here.
+// Images are stored in directory called temp in the user installation directory. Next version of OO/SO
+// hopefully will address this issue and allow a choice e.g. images for controls to be stored as links
+// or embeded in the document.
+
+// [out]location path to the stream to where the image is to be stored,
+// if same name exists in folder then this function calcuates a new name
+// [in] data raw bytes of image to be stored.
+// [in] dataLen no. byte to be stored
+//
+// returns, true if successful
+
+bool storePictureInFileSystem( OUString& location, sal_uInt8* data, sal_uInt32 dataLen )
+{
+ bool result = true;
+ OUString origPath = location;
+ try
+ {
+ uno::Reference<lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory(),
+ uno::UNO_QUERY_THROW );
+ uno::Reference< com::sun::star::ucb::XSimpleFileAccess> xSFA( xMSF->createInstance(
+ S2U("com.sun.star.ucb.SimpleFileAccess" ) ),
+ uno::UNO_QUERY_THROW );
+ OUString ext;
+ sal_Int32 index = 0;
+ while ( xSFA->exists( location ) )
+ {
+ ext = OUString::valueOf( ++index );
+ location = origPath + ext;
+ }
+
+ SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( location, STREAM_WRITE | STREAM_TRUNC );
+ if ( pStream )
+ {
+ pStream->Write(data, dataLen);
+ delete pStream;
+ }
+ else
+ {
+ result = false;
+ }
+ }
+ catch( uno::Exception& )
+ {
+ result = false;
+ }
+ return result;
+}
+
+// NP - Images in controls in OO2.0/SO8 exist as links, e.g. they are not part of the document so are
+// referenced externally. On import from ms document try to save images from controls here so this
+// at least a macro programmer has a chance to accessed them manually later. Next version of OO/SO
+// hopefully will address this issue.
+// Images will be stored in a top level folder in the document package, folder is named "MigratedImages"
+
+// [in] pDocSh* the document shell.
+// [in] name name of stream image to stored in.
+// [in] data raw bytes of image to be stored.
+// [in] dataLen no. byte to be stored
+
+bool storePictureInDoc( SfxObjectShell* pDocSh, OUString& name, sal_uInt8* data, sal_uInt32 dataLen )
+{
+ uno::Reference < embed::XStorage > xStor;
+ if (pDocSh)
+ {
+ xStor = pDocSh->GetStorage();
+ if( xStor.is() )
+ {
+ try
+ {
+ uno::Reference< embed::XStorage > xPictures = xStor->openStorageElement(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "MigratedImages" ) ),
+ embed::ElementModes::READWRITE );
+ uno::Reference< beans::XPropertySet > xPropSet( xPictures, uno::UNO_QUERY );
+
+ // Set media type of folder MigratedImages to something ( that is unknown ) so that
+ // it will get copied to exported OO/SO format after SaveAs
+ if ( xPropSet.is() )
+ {
+ OUString aMediaType = C2U("MigrationImages");
+ uno::Any a;
+ a <<= aMediaType;
+ xPropSet->setPropertyValue( C2U("MediaType"), a );
+ }
+
+ uno::Reference< io::XStream > xObjReplStr = xPictures->openStreamElement(
+ name,
+ embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
+ uno::Reference< io::XOutputStream > xOutStream( xObjReplStr->getOutputStream(), uno::UNO_QUERY_THROW );
+ uno::Sequence< sal_Int8 > imageBytes( (sal_Int8*)data, dataLen );
+ xOutStream->writeBytes( imageBytes );
+ xOutStream->closeOutput();
+
+ uno::Reference< embed::XTransactedObject > xTransact( xPictures, uno::UNO_QUERY );
+ if ( xTransact.is() )
+ {
+ xTransact->commit();
+ }
+ }
+ catch( uno::Exception& )
+ {
+ return false;
+ }
+
+ }
+ else
+ {
+ // no storage something wrong
+ return false;
+ }
+ }
+ else
+ {
+ //No doc shell
+ return false;
+ }
+ return true;
+}
+
+long WriteAlign(SvStorageStream *pS, int nAmount)
+{
+ if (long nAlign = pS->Tell() % nAmount)
+ {
+ long nLen = nAmount - nAlign;
+ for (long i=0; i< nLen; ++i)
+ *pS << sal_uInt8(0x00);
+ return nLen;
+ }
+ return 0;
+}
+// string import/export =======================================================
+/** #117832# import of form control names
+* control name is located in stream ("\3OCXNAME")
+* a strings in "\3OCXNAME" stream seem to be terminated by 4 trailing bytes of 0's.
+* ====
+* Note: If the string in the stream is overwritten by a shorter string
+* some characters from the original string may remain, the new string however
+* will still be terminated in the same way e.g. by 4 bytes with value 0.
+*/
+
+bool writeOCXNAME( const OUString& sOCXName, SvStorageStream* pStream )
+{
+ const sal_Unicode* buffer = sOCXName.getStr();
+ for ( sal_Int32 index=0; index < sOCXName.getLength(); index++ )
+ {
+ sal_uInt16 ch = static_cast< sal_uInt16 >( buffer[ index ] );
+ *pStream << ch;
+ }
+ // write
+ *pStream << sal_uInt32(0);
+ return ( SVSTREAM_OK == pStream->GetError() );
+
+}
+
+bool readOCXNAME( OUString& sCName, SvStorageStream* pStream )
+{
+ /*
+ * Read uniCode until no data or 0 encountered
+ */
+ OUStringBuffer buf(40);
+ do
+ {
+ sal_uInt16 ch = 0;
+ *pStream >> ch;
+ sal_Unicode uni = static_cast< sal_Unicode >( ch );
+ if ( uni == 0 )
+ {
+ break;
+ }
+ buf.append( &uni, 1 );
+
+ } while ( !pStream->IsEof() );
+
+ sCName = buf.makeStringAndClear();
+ return ( SVSTREAM_OK == pStream->GetError() );
+}
+
+
+/* #110435# (DR, 2003-11-12) ** Import of Unicode strings in form controls **
+
+ Strings may be stored either as compressed or uncompressed Unicode
+ character array. There are no encoded byte strings anywhere.
+
+ The string length field stores the length of the character array (not the
+ character count of the string) in the lower 31 bits, and the compression
+ state in the highest bit.
+
+ A set bit means the character array is compressed. This means all Unicode
+ characters are <=0xFF. Therefore the high bytes of all characters are left
+ out, and the character array size is equal to the string length.
+
+ A cleared bit means the character array is not compressed. The buffer
+ contains Little-Endian Unicode characters, and the resulting string length
+ is half the buffer size.
+
+ TODO: This implementation of the new string import is a hack to keep
+ msocximex.hxx unchanged. A better implementation would replace the char*
+ members of all classes by something more reasonable.
+ */
+
+namespace {
+
+const sal_uInt32 SVX_MSOCX_SIZEMASK = 0x7FFFFFFF; /// Mask for character buffer size.
+const sal_uInt32 SVX_MSOCX_COMPRESSED = 0x80000000; /// 1 = compressed Unicode array.
+
+
+/** Returns true, if the passed length field specifies a compressed character array.
+ */
+inline bool lclIsCompressed( sal_uInt32 nLenFld )
+{
+ return (nLenFld & SVX_MSOCX_COMPRESSED) != 0;
+}
+
+
+/** Extracts and returns the memory size of the character buffer.
+ @return Character buffer size (may differ from resulting string length!).
+ */
+inline sal_uInt32 lclGetBufferSize( sal_uInt32 nLenFld )
+{
+ return nLenFld & SVX_MSOCX_SIZEMASK;
+}
+
+
+// import ---------------------------------------------------------------------
+
+/** Reads the character array of a string in a form control.
+
+ Creates a new character array containing the character data.
+ The length field must be read before and passed to this function.
+ Aligns stream position to multiple of 4 before.
+
+ @param rStrm
+ The input stream.
+
+ @param rpcCharArr
+ (out-param) Will point to the created character array,
+ or will be 0 if string is empty. The array is NOT null-terminated.
+ If the passed pointer points to an old existing array, it will be
+ deleted before. Caller must delete the returned array.
+
+ @param nLenFld
+ The corresponding string length field read somewhere before.
+ */
+void lclReadCharArray( SvStorageStream& rStrm, char*& rpcCharArr, sal_uInt32 nLenFld, long nPos )
+{
+ delete[] rpcCharArr;
+ rpcCharArr = 0;
+ sal_uInt32 nBufSize = lclGetBufferSize( nLenFld );
+ DBG_ASSERT( nBufSize <= 0xFFFF, "lclReadCharArray - possible read error: char array is too big" );
+ if( nBufSize && nBufSize <= 0xFFFF )
+ {
+ rpcCharArr = new char[ nBufSize ];
+ if( rpcCharArr )
+ {
+ ReadAlign( &rStrm, nPos, 4 );
+ rStrm.Read( rpcCharArr, nBufSize );
+ }
+ }
+}
+
+
+/** Creates an OUString from a character array created with lclReadCharArray().
+
+ The passed parameters must match, that means the length field must be the
+ same used to create the passed character array.
+
+ @param pcCharArr
+ The character array returned by lclReadCharArray(). May be compressed
+ or uncompressed, next parameter nLenFld will specify this.
+
+ @param nLenFld
+ MUST be the same string length field that has been passed to
+ lclReadCharArray() to create the character array in previous parameter
+ pcCharArr.
+
+ @return
+ An OUString containing the decoded string data. Will be empty if
+ pcCharArr is 0.
+ */
+OUString lclCreateOUString( const char* pcCharArr, sal_uInt32 nLenFld )
+{
+ OUStringBuffer aBuffer;
+ sal_uInt32 nBufSize = lclGetBufferSize( nLenFld );
+ if( lclIsCompressed( nLenFld ) )
+ {
+ // buffer contains compressed Unicode, not encoded bytestring
+ sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufSize );
+ aBuffer.setLength( nStrLen );
+ const char* pcCurrChar = pcCharArr;
+ for( sal_Int32 nChar = 0; nChar < nStrLen; ++nChar, ++pcCurrChar )
+ /* *pcCurrChar may contain negative values and therefore MUST be
+ casted to unsigned char, before assigned to a sal_Unicode. */
+ aBuffer.setCharAt( nChar, static_cast< unsigned char >( *pcCurrChar ) );
+ }
+ else
+ {
+ // buffer contains Little-Endian Unicode
+ sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufSize ) / 2;
+ aBuffer.setLength( nStrLen );
+ const char* pcCurrChar = pcCharArr;
+ for( sal_Int32 nChar = 0; nChar < nStrLen; ++nChar )
+ {
+ /* *pcCurrChar may contain negative values and therefore MUST be
+ casted to unsigned char, before assigned to a sal_Unicode. */
+ sal_Unicode cChar = static_cast< unsigned char >( *pcCurrChar++ );
+ cChar |= (static_cast< unsigned char >( *pcCurrChar++ ) << 8);
+ aBuffer.setCharAt( nChar, cChar );
+ }
+ }
+ return aBuffer.makeStringAndClear();
+}
+
+// export ---------------------------------------------------------------------
+
+/** This class implements writing a character array from a Unicode string.
+
+ Usage:
+ 1) Construct an instance, either directly with an OUString, or with an UNO
+ Any containing an OUString.
+ 2) Check with HasData(), if there is something to write.
+ 3) Write the string length field with WriteLenField() at the right place.
+ 4) Write the encoded character array with WriteCharArray().
+ */
+class SvxOcxString
+{
+public:
+ /** Constructs an empty string. String data may be set later by assignment. */
+ inline explicit SvxOcxString() : mnLenFld( 0 ) {}
+ /** Constructs the string from the passed OUString. */
+ inline explicit SvxOcxString( const OUString& rStr ) { Init( rStr ); }
+ /** Constructs the string from the passed UNO Any. */
+ inline explicit SvxOcxString( const uno::Any& rAny ) { Init( rAny ); }
+
+ /** Assigns the passed string to the object. */
+ inline SvxOcxString& operator=( const OUString& rStr ) { Init( rStr ); return *this; }
+ /** Assigns the string in the passed UNO Any to the object. */
+ inline SvxOcxString& operator=( const uno::Any& rAny ) { Init( rAny ); return *this; }
+
+ /** Returns true, if the string contains at least one character to write. */
+ inline bool HasData() const { return maString.getLength() > 0; }
+
+ /** Writes the encoded 32-bit string length field. Aligns stream position to mult. of 4 before. */
+ void WriteLenField( SvStorageStream& rStrm ) const;
+ /** Writes the encoded character array. Aligns stream position to mult. of 4 before. */
+ void WriteCharArray( SvStorageStream& rStrm ) const;
+
+private:
+ inline void Init( const OUString& rStr ) { maString = rStr; Init(); }
+ void Init( const uno::Any& rAny );
+ void Init();
+
+ OUString maString; /// The initial string data.
+ sal_uInt32 mnLenFld; /// The encoded string length field.
+};
+
+void SvxOcxString::Init( const uno::Any& rAny )
+{
+ if( !(rAny >>= maString) )
+ maString = OUString();
+ Init();
+}
+
+void SvxOcxString::Init()
+{
+ mnLenFld = static_cast< sal_uInt32 >( maString.getLength() );
+ bool bCompr = true;
+ // try to find a character >= 0x100 -> character array will be stored uncompressed then
+ if( const sal_Unicode* pChar = maString.getStr() )
+ for( const sal_Unicode* pEnd = pChar + maString.getLength(); bCompr && (pChar < pEnd); ++pChar )
+ bCompr = (*pChar < 0x100);
+ if( bCompr )
+ mnLenFld |= SVX_MSOCX_COMPRESSED;
+ else
+ mnLenFld *= 2;
+}
+
+void SvxOcxString::WriteLenField( SvStorageStream& rStrm ) const
+{
+ if( HasData() )
+ {
+ WriteAlign( &rStrm, 4);
+ rStrm << mnLenFld;
+ }
+}
+
+void SvxOcxString::WriteCharArray( SvStorageStream& rStrm ) const
+{
+ if( HasData() )
+ {
+ const sal_Unicode* pChar = maString.getStr();
+ const sal_Unicode* pEnd = pChar + maString.getLength();
+ bool bCompr = lclIsCompressed( mnLenFld );
+
+ WriteAlign( &rStrm, 4);
+ for( ; pChar < pEnd; ++pChar )
+ {
+ // write compressed Unicode (not encoded bytestring), or Little-Endian Unicode
+ rStrm << static_cast< sal_uInt8 >( *pChar );
+ if( !bCompr )
+ rStrm << static_cast< sal_uInt8 >( *pChar >> 8 );
+ }
+ }
+}
+
+const sal_uInt16 USERFORM = (sal_uInt16)0xFF;
+const sal_uInt16 STDCONTAINER = (sal_uInt16)0xFE;
+
+const sal_uInt16 PAGE = (sal_uInt16)0x07;
+
+const sal_uInt16 IMAGE = (sal_uInt16)0x0C;
+const sal_uInt16 FRAME = (sal_uInt16)0x0E;
+
+const sal_uInt16 SPINBUTTON = (sal_uInt16)0x10;
+const sal_uInt16 CMDBUTTON = (sal_uInt16)0x11;
+const sal_uInt16 TABSTRIP = (sal_uInt16)0x12;
+
+const sal_uInt16 LABEL = (sal_uInt16)0x15;
+
+const sal_uInt16 TEXTBOX = (sal_uInt16)0x17;
+const sal_uInt16 LISTBOX = (sal_uInt16)0x18;
+const sal_uInt16 COMBOBOX = (sal_uInt16)0x19;
+const sal_uInt16 CHECKBOX = (sal_uInt16)0x1A;
+
+const sal_uInt16 OPTIONBUTTON = (sal_uInt16)0x1B;
+const sal_uInt16 TOGGLEBUTTON = (sal_uInt16)0x1C;
+
+const sal_uInt16 SCROLLBAR = (sal_uInt16)0x2F;
+
+const sal_uInt16 MULTIPAGE = (sal_uInt16)0x39;
+const sal_uInt16 PROGRESSBAR = (sal_uInt16)0x8000;
+
+typedef std::vector< ContainerRecord > ContainerRecordList;
+
+class ContainerRecReader
+{
+ public:
+
+ virtual ~ContainerRecReader() {}
+
+ virtual bool Read( OCX_ContainerControl* pContainerControl, SvStorageStream *pS)
+ {
+ *pS >> nNoRecords;
+ *pS >> nTotalLen;
+
+ if ( isMultiPage )
+ {
+ if ( !handleMultiPageHdr( pS ) )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if ( !handleStandardHdr( pS ) )
+ {
+ return false;
+ }
+ }
+
+ records.clear();
+ for (sal_uInt32 nRecord = 0; nRecord < nNoRecords; ++nRecord)
+ {
+ // DR #134146# redo loading of FrameChild data
+
+ ContainerRecord rec;
+
+ // record header
+ sal_uInt16 nId, nSize;
+ *pS >> nId >> nSize;
+ sal_Size nStartPos = pS->Tell();
+
+ // content flags
+ sal_uInt32 nContentFlags;
+ *pS >> nContentFlags;
+
+ // length of control name
+ sal_uInt32 nNameLen = 0;
+ if( nContentFlags & 0x00000001 )
+ *pS >> nNameLen;
+ // length of control tag
+ sal_uInt32 nTagLen = 0;
+ if( nContentFlags & 0x00000002 )
+ *pS >> nTagLen;
+ // substorage id for frames
+ if( nContentFlags & 0x00000004 )
+ *pS >> rec.nSubStorageId;
+ // help-context id
+ if( nContentFlags & 0x00000008 )
+ pS->SeekRel( 4 );
+ // option flags
+ if( nContentFlags & 0x00000010 )
+ {
+ sal_uInt32 nBitFlags = 0;
+ *pS >> nBitFlags;
+ rec.bVisible = ( ( nBitFlags & 0x02 ) == 0x02 );
+ }
+ // substream size
+ if( nContentFlags & 0x00000020 )
+ *pS >> rec.nSubStreamLen;
+ // tabstop position
+ if( nContentFlags & 0x00000040 )
+ *pS >> rec.nTabPos;
+ // control type
+ if( nContentFlags & 0x00000080 )
+ *pS >> rec.nTypeIdent;
+ // length of infotip
+ sal_uInt32 nTipLen = 0;
+ if( nContentFlags & 0x00000800 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> nTipLen;
+ }
+
+ sal_uInt32 nCntrlIdLen = 0;
+ if( nContentFlags & 0x00001000 )
+ *pS >> nCntrlIdLen;
+
+ // length of control source name
+ sal_uInt32 nCtrlSrcLen = 0;
+ if( nContentFlags & 0x00002000 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> nCtrlSrcLen;
+ }
+
+ // length of row source name
+ sal_uInt32 nRowSrcLen = 0;
+ if( nContentFlags & 0x00004000 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> nRowSrcLen;
+ }
+
+ // control name
+ sal_Char* pName = 0;
+ sal_uInt32 nNameBufSize = lclGetBufferSize( nNameLen );
+ if( nNameBufSize > 0 )
+ {
+ pName = new char[ nNameBufSize ];
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pS->Read( pName, nNameBufSize );
+ }
+ // control tag
+ sal_uInt32 nTagBufSize = lclGetBufferSize( nTagLen );
+ if( nTagBufSize > 0 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pS->SeekRel( nTagBufSize );
+ }
+
+ // control position
+ if( nContentFlags & 0x00000100 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> rec.nLeft >> rec.nTop;
+ }
+
+ // control infotip
+ sal_uInt32 nTipBufSize = lclGetBufferSize( nTipLen );
+ if( nTipBufSize > 0 )
+ {
+ std::auto_ptr< sal_Char > pTipName;
+ pTipName.reset( new sal_Char[ nTipBufSize ] );
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pS->Read( pTipName.get(), nTipBufSize );
+ rec.controlTip = lclCreateOUString( pTipName.get(), nTipLen );
+ }
+ // control id
+ sal_uInt32 nCntrlIdSize = lclGetBufferSize( nCntrlIdLen );
+ if( nCntrlIdSize > 0 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pS->SeekRel( nCntrlIdSize );
+ }
+ // control source name
+ sal_uInt32 nCtrlSrcBufSize = lclGetBufferSize( nCtrlSrcLen );
+ if( nCtrlSrcBufSize > 0 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pS->SeekRel( nCtrlSrcBufSize );
+ }
+ // row source name
+ sal_uInt32 nRowSrcBufSize = lclGetBufferSize( nRowSrcLen );
+ if( nRowSrcBufSize > 0 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pS->SeekRel( nRowSrcBufSize );
+ }
+
+ // seek to end of data
+ pS->Seek( nStartPos + nSize );
+
+ rec.cName = lclCreateOUString(pName, nNameLen);
+ delete[] pName;
+
+ OCX_Control* pControl = NULL;
+ if( pContainerControl->createFromContainerRecord( rec, pControl ) &&
+ pControl )
+ {
+ // propagate doc shell from parent
+ pControl->pDocSh = pContainerControl->pDocSh;
+ pContainerControl->ProcessControl( pControl, pS, rec );
+ }
+ else
+ {
+ DBG_ERROR("Terminating import, unexpected error");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected:
+ ContainerRecReader() : isMultiPage(false){}
+ bool isMultiPage;
+ sal_uInt32 nNoRecords;
+ sal_uInt32 nTotalLen;
+
+ private:
+ bool handleStandardHdr( SvStorageStream* pS )
+ {
+ sal_uInt8 aUnknown11[4];
+ pS->Read(aUnknown11, sizeof(aUnknown11));
+ return true;
+ }
+
+ bool handleMultiPageHdr( SvStorageStream* pS )
+ {
+ sal_uInt32 nUnknown_32b; // unknown 32 bit structure, flags ?
+ sal_uInt16 nUnknown_16b; // unknown 16 bit structure
+ sal_uInt16 nMysteryLen; // lenght of unknown sub record
+
+ *pS >> nUnknown_32b;
+ *pS >> nUnknown_16b;
+ *pS >> nMysteryLen;
+
+ pS->SeekRel( nMysteryLen );
+ return true;
+ }
+ ContainerRecordList records;
+};
+
+class StdContainerRecReader : public ContainerRecReader
+{
+ public:
+ StdContainerRecReader(){}
+};
+
+class MultiPageContainerRecReader : public ContainerRecReader
+{
+ public:
+ MultiPageContainerRecReader()
+ {
+ // NP ( 27-01-05 )
+ // Strictly speaking this approach shouldn't be necessary.
+ // It should be possible to have a common routine read the
+ // container record array and by examining the flags present in
+ // the record to determine we expect to read or not.
+ // In this case for a MultPage control there is no Top or Left
+ // values in the control record array, however time contraints
+ // and associated risk prevent further investigation of this
+ // at the moment.
+ // similar situation exists for the start of the container record
+ // which in the case of the MultiPage is different from
+ // UserForm & Frame ( the other containers )
+
+ isMultiPage = true; // tell the base class skip
+ }
+};
+
+class ContainerRecordReaderFac
+{
+ public:
+ static ContainerRecReader* instance( sal_uInt32 containerType )
+ {
+ switch( containerType )
+ {
+ case PAGE:
+ case FRAME:
+ case USERFORM:
+ case STDCONTAINER:
+ return new StdContainerRecReader();
+ case MULTIPAGE:
+ return new MultiPageContainerRecReader();
+ default:
+ DBG_ERROR("Illegal container type for factory");
+ return NULL;
+ }
+ }
+ private:
+ ContainerRecordReaderFac();
+};
+
+} // namespace
+
+// ============================================================================
+
+void RBGroup::add(OCX_Control* pRB)
+{
+ // The tab index for the group is calculated as
+ // the lowest tab index found in the list of RadioButtons
+ if ( pRB->mnTabPos < mRBGroupPos )
+ {
+ mRBGroupPos = pRB->mnTabPos;
+ CtrlIterator aEnd = mpControls.end();
+ for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
+ {
+ (*aIter)->mnTabPos = mRBGroupPos;
+ }
+ }
+ mpControls.push_back( pRB );
+}
+
+struct SortGroupByTabPos
+{
+ bool operator()( const RBGroup* a, const RBGroup* b )
+ {
+ return a->tabPos() < b->tabPos();
+ }
+};
+
+RBGroupManager::RBGroupManager( String& defaultName ):mSDefaultName( defaultName ),
+ numRadioButtons(0)
+{
+ groupList.reserve( 8 ); // reserve far more than we expect
+}
+
+RBGroupManager::~RBGroupManager()
+{
+ for ( GroupIterator gIter=groupList.begin(); gIter!=groupList.end(); ++gIter )
+ {
+ delete( *gIter );
+ }
+}
+
+// Loose description of the method below ( I sure there is a better way to do
+// this )
+// In order to "fake" MS grouping behavior for OptionButtons the OptionButtons
+// in the same group need to have consecutive tab indices ( regardless of the
+// imported tab indices of the RadioButtons ). Additionally if two
+// groups of OptionButtons end up having all consecutive indices they
+// will be treated as a single group by OpenOffice. In this case
+// a dummy seperator control needs to be inserted between the groups.
+//
+// This method returns a new list "destinationList" containing the controls
+// passed in "sourceList" and the OptionButtons contained in the various
+// Groups maintained by this class.
+// Controls are ordered in the destination list by tab index.
+// Each RadioButtonGroup has a tab index associated with it.
+// ( Tab index of a RadioGroup is determined as the tab index of the
+// OptionButton control with the lowest tab index in the group )
+
+
+void RBGroupManager::addRadioButton( OCX_OptionButton* pRButton )
+{
+ if ( pRButton )
+ {
+ OUString groupName = mSDefaultName;
+ if ( pRButton->nGroupNameLen )
+ {
+ groupName =
+ lclCreateOUString(pRButton->pGroupName,
+ pRButton->nGroupNameLen);
+ }
+ ++numRadioButtons;
+ RBGroupHash::iterator iter = rbGroups.find( groupName );
+ if ( iter != rbGroups.end() )
+ {
+ iter->second->controls().push_back( pRButton );
+ }
+ else
+ {
+ RBGroup* newGroup = new RBGroup(pRButton->mnTabPos);
+ newGroup->controls().push_back( pRButton );
+ rbGroups[ groupName ] = newGroup;
+ groupList.push_back( newGroup );
+ }
+
+ }
+}
+
+CtrlList RBGroupManager::insertGroupsIntoControlList( const CtrlList& sourceList )
+{
+ ::std::sort( groupList.begin(), groupList.end(), SortGroupByTabPos() );
+ std::vector<OCX_Control*> destinationList;
+ if ( groupList.size() )
+ {
+ destinationList.reserve( sourceList.size() + numRadioButtons );
+
+ GroupIterator groupEnd = groupList.end();
+ CtrlIteratorConst sourceEnd = sourceList.end();
+
+ size_t prevGroupListSize = 0;
+
+ CtrlIteratorConst containees = sourceList.begin();
+ GroupIterator groupIter=groupList.begin();
+ while ( containees != sourceEnd ||
+ groupIter != groupEnd )
+ {
+ bool addGroupSeperator = false;
+ if ( containees != sourceEnd )
+ {
+ if ( groupIter != groupEnd )
+ {
+ sal_Int16 groupTabPos = (*groupIter)->tabPos();
+ if ( (*containees)->mnTabPos >= groupTabPos )
+ {
+ if ( !(destinationList.size() >= prevGroupListSize ))
+ {
+ addGroupSeperator = true;
+ }
+ copyList( (*groupIter)->controls(), destinationList, addGroupSeperator );
+ ++groupIter;
+
+ prevGroupListSize = destinationList.size();
+ }
+ }
+ destinationList.push_back(*containees);
+ ++containees;
+ }
+ else
+ {
+ if ( groupIter != groupEnd )
+ {
+ if ( !(destinationList.size() > prevGroupListSize ))
+ {
+ addGroupSeperator = true;
+ }
+ copyList( (*groupIter)->controls(), destinationList, addGroupSeperator );
+ ++groupIter;
+ prevGroupListSize = destinationList.size();
+ }
+ }
+ }
+ }
+ else
+ {
+ destinationList = sourceList;
+ }
+ return destinationList;
+
+}
+
+
+void RBGroupManager::addSeperator( std::vector< OCX_Control* >& dest )
+{
+ OCX_Control* seperator = new OCX_CommandButton;
+ seperator->SetInDialog(true);
+ seperator->sName = C2S("GroupSeperator");
+ dest.push_back( seperator );
+}
+
+void RBGroupManager::copyList( std::vector< OCX_Control* >& src,
+ std::vector< OCX_Control* >& dest,
+ bool addGroupSeperator )
+{
+ if ( addGroupSeperator )
+ {
+ addSeperator( dest );
+ }
+
+ for ( CtrlIterator rbIter = src.begin(); rbIter != src.end(); ++rbIter )
+ {
+ dest.push_back( *rbIter );
+ }
+}
+
+class OCX_UserFormLabel : public OCX_Label
+{
+public:
+ OCX_UserFormLabel(OCX_Control* pParent ) : OCX_Label( pParent )
+ {
+ mnForeColor = 0x80000012L;
+ mnBackColor = 0x8000000FL;
+ }
+};
+
+
+sal_uInt16 OCX_Control::nStandardId(0x0200);
+sal_uInt16 OCX_FontData::nStandardId(0x0200);
+
+sal_uInt32 OCX_Control::pColor[25] = {
+0xC0C0C0, 0x008080, 0x000080, 0x808080, 0xC0C0C0, 0xFFFFFF, 0x000000,
+0x000000, 0x000000, 0xFFFFFF, 0xC0C0C0, 0xC0C0C0, 0x808080, 0x000080,
+0xFFFFFF, 0xC0C0C0, 0x808080, 0x808080, 0x000000, 0xC0C0C0, 0xFFFFFF,
+0x000000, 0xC0C0C0, 0x000000, 0xFFFFC0 };
+
+void OCX_Control::FillSystemColors()
+{
+ // overwrite the predefined colors with available system colors
+ const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
+
+ pColor[ 0x00 ] = rSett.GetFaceColor().GetColor();
+ pColor[ 0x01 ] = rSett.GetWorkspaceColor().GetColor();
+ pColor[ 0x02 ] = rSett.GetActiveColor().GetColor();
+ pColor[ 0x03 ] = rSett.GetDeactiveColor().GetColor();
+ pColor[ 0x04 ] = rSett.GetMenuBarColor().GetColor();
+ pColor[ 0x05 ] = rSett.GetWindowColor().GetColor();
+ pColor[ 0x07 ] = rSett.GetMenuTextColor().GetColor();
+ pColor[ 0x08 ] = rSett.GetWindowTextColor().GetColor();
+ pColor[ 0x09 ] = rSett.GetActiveTextColor().GetColor();
+ pColor[ 0x0A ] = rSett.GetActiveBorderColor().GetColor();
+ pColor[ 0x0B ] = rSett.GetDeactiveBorderColor().GetColor();
+ pColor[ 0x0C ] = rSett.GetWorkspaceColor().GetColor();
+ pColor[ 0x0D ] = rSett.GetHighlightColor().GetColor();
+ pColor[ 0x0E ] = rSett.GetHighlightTextColor().GetColor();
+ pColor[ 0x0F ] = rSett.GetFaceColor().GetColor();
+ pColor[ 0x10 ] = rSett.GetShadowColor().GetColor();
+ pColor[ 0x12 ] = rSett.GetButtonTextColor().GetColor();
+ pColor[ 0x13 ] = rSett.GetDeactiveTextColor().GetColor();
+ pColor[ 0x14 ] = rSett.GetHighlightColor().GetColor();
+ pColor[ 0x15 ] = rSett.GetDarkShadowColor().GetColor();
+ pColor[ 0x16 ] = rSett.GetShadowColor().GetColor();
+ pColor[ 0x17 ] = rSett.GetHelpTextColor().GetColor();
+ pColor[ 0x18 ] = rSett.GetHelpColor().GetColor();
+}
+
+sal_uInt32 OCX_Control::ImportColor(sal_uInt32 nColor) const
+{
+ sal_uInt8 nUpper = (sal_uInt8)( nColor >> 24 );
+ if (nUpper & 0x80) //Palette color, should be switch on bottom 24 bits
+ {
+ /*Might as well use my systems ones in the absence of any other ideas*/
+ nColor = nColor&0x00FFFFFF;
+ DBG_ASSERT (nColor <= 24,"Unknown Palette Index");
+ if (nColor > 24)
+ nColor = 0xFFFFFF;
+ else
+ nColor = pColor[nColor];
+ }
+ else
+ {
+ //Stored in bgr! rather than rgb
+ nColor = SwapColor(nColor);
+ }
+ return nColor;
+}
+
+sal_Int16 OCX_FontData::ImportAlign(sal_uInt8 _nJustification) const
+{
+ sal_Int16 nRet;
+ switch (_nJustification)
+ {
+ default:
+ case 1:
+ nRet = 0;
+ break;
+ case 2:
+ nRet = 2;
+ break;
+ case 3:
+ nRet = 1;
+ break;
+ }
+ return nRet;
+}
+
+sal_uInt8 OCX_FontData::ExportAlign(sal_Int16 nAlign) const
+{
+ sal_Int8 nRet;
+ switch (nAlign)
+ {
+ default:
+ case 0:
+ nRet = 1;
+ break;
+ case 2:
+ nRet = 2;
+ break;
+ case 1:
+ nRet = 3;
+ break;
+ }
+ return nRet;
+}
+
+sal_uInt32 OCX_Control::SwapColor(sal_uInt32 nColor) const
+{
+ sal_uInt8
+ r(static_cast<sal_uInt8>(nColor&0xFF)),
+ g(static_cast<sal_uInt8>(((nColor)>>8)&0xFF)),
+ b(static_cast<sal_uInt8>((nColor>>16)&0xFF));
+ nColor = (r<<16) + (g<<8) + b;
+ return nColor;
+}
+
+sal_uInt32 OCX_Control::ExportColor(sal_uInt32 nColor) const
+{
+ sal_uInt8 nUpper = (sal_uInt8)( nColor >> 24 );
+ if (nUpper & 0x80) //Palette color, should be switch on bottom 24 bits
+ {
+ /*Might as well use my systems ones in the absence of any other ideas*/
+ nColor = nColor&0x00FFFFFF;
+ DBG_ASSERT (nColor <= 24,"Unknown Palette Index");
+ if (nColor > 24)
+ nColor = 0xFFFFFF;
+ else
+ nColor = pColor[nColor];
+ }
+
+ //Stored in bgr! rather than rgb
+ nColor = SwapColor(nColor);
+ return nColor;
+}
+
+sal_Bool OCX_Control::Import(
+ const uno::Reference< lang::XMultiServiceFactory > &rServiceFactory,
+ uno::Reference< form::XFormComponent > &rFComp, awt::Size &rSz)
+{
+
+ if(msFormType.getLength() == 0)
+ return sal_False;
+
+ rSz.Width = nWidth;
+ rSz.Height = nHeight;
+
+ uno::Reference<uno::XInterface> xCreate =
+ rServiceFactory->createInstance(msFormType);
+ if (!xCreate.is())
+ return sal_False;
+
+ rFComp = uno::Reference<form::XFormComponent>(xCreate,uno::UNO_QUERY);
+ if (!rFComp.is())
+ return sal_False;
+ uno::Reference<beans::XPropertySet> xPropSet(xCreate,uno::UNO_QUERY);
+ if (!xPropSet.is())
+ return sal_False;
+ return Import(xPropSet);
+}
+
+sal_Bool OCX_Control::Import(uno::Reference<container::XNameContainer> &rDialog
+ )
+{
+ uno::Reference<lang::XMultiServiceFactory>
+ xFactory(rDialog, uno::UNO_QUERY);
+
+ uno::Reference<uno::XInterface> xCreate =
+ xFactory->createInstance(msDialogType);
+ if (!xCreate.is())
+ return sal_False;
+
+ uno::Reference<awt::XControlModel> xModel(xCreate, uno::UNO_QUERY);
+ if (!xModel.is())
+ return sal_False;
+
+ /* #147900# sometimes insertion of a control fails due to existing name,
+ do not break entire form import then... */
+ try
+ {
+ rDialog->insertByName(sName, uno::makeAny(xModel));
+ }
+ catch( uno::Exception& )
+ {
+ DBG_ERRORFILE(
+ ByteString( "OCX_Control::Import - cannot insert control \"" ).
+ Append( ByteString( sName, RTL_TEXTENCODING_UTF8 ) ).
+ Append( '"' ).GetBuffer() );
+ }
+
+ uno::Reference<beans::XPropertySet> xPropSet(xCreate, uno::UNO_QUERY);
+ if (!xPropSet.is())
+ return sal_False;
+
+ if (!Import(xPropSet))
+ return sal_False;
+
+ uno::Any aTmp;
+ aTmp <<= sal_Int32((mnLeft * 2) / 100);
+ xPropSet->setPropertyValue(WW8_ASCII2STR("PositionX"), aTmp);
+ aTmp <<= sal_Int32((mnTop * 2) / 100);
+ xPropSet->setPropertyValue(WW8_ASCII2STR("PositionY"), aTmp);
+ aTmp <<= sal_Int32((nWidth * 2) / 100);
+ xPropSet->setPropertyValue(WW8_ASCII2STR("Width"), aTmp);
+ aTmp <<= sal_Int32((nHeight * 2) / 100);
+ xPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
+ if ( msToolTip.Len() > 0 )
+ xPropSet->setPropertyValue(WW8_ASCII2STR("HelpText"), uno::Any(OUString(msToolTip)));
+
+ if ( mnStep )
+ {
+ aTmp <<= mnStep;
+ xPropSet->setPropertyValue(WW8_ASCII2STR("Step"), aTmp);
+ }
+
+ try
+ {
+ xPropSet->setPropertyValue(WW8_ASCII2STR("EnableVisible"), uno::makeAny( mbVisible ) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ return sal_True;
+}
+
+sal_Int16 OCX_Control::ImportBorder(sal_uInt16 nSpecialEffect,
+ sal_uInt16 nBorderStyle) const
+{
+ if ((nSpecialEffect == 0) && (nBorderStyle == 0))
+ return 0; //No Border
+ else if ((nSpecialEffect == 0) && (nBorderStyle == 1))
+ return 2; //Flat Border
+ return 1; //3D Border
+}
+
+sal_uInt8 OCX_Control::ExportBorder(sal_uInt16 nBorder,sal_uInt8 &rBorderStyle)
+ const
+{
+ sal_uInt8 nRet;
+ switch(nBorder)
+ {
+ case 0:
+ nRet = rBorderStyle = 0;
+ break;
+ default:
+ case 1:
+ nRet = 2;
+ rBorderStyle = 0;
+ break;
+ case 2:
+ nRet = 0;
+ rBorderStyle = 1;
+ break;
+ }
+ return nRet;
+}
+
+sal_Int16 OCX_Control::ImportSpecEffect( sal_uInt8 nSpecialEffect ) const
+{
+ return (nSpecialEffect == 0) ? 2 : 1;
+}
+
+sal_uInt8 OCX_Control::ExportSpecEffect( sal_Int16 nApiEffect ) const
+{
+ return (nApiEffect == 2) ? 0 : 2;
+}
+
+sal_Bool OCX_Control::ReadFontData(SvStorageStream *pS)
+{
+ return aFontData.Read(pS);
+}
+
+
+const uno::Reference< drawing::XDrawPage >&
+ SvxMSConvertOCXControls::GetDrawPage()
+{
+ if( !xDrawPage.is() && pDocSh )
+ {
+ uno::Reference< drawing::XDrawPageSupplier > xTxtDoc(pDocSh->GetModel(),
+ uno::UNO_QUERY);
+ DBG_ASSERT(xTxtDoc.is(),"XDrawPageSupplier nicht vom XModel erhalten");
+ xDrawPage = xTxtDoc->getDrawPage();
+ DBG_ASSERT( xDrawPage.is(), "XDrawPage nicht erhalten" );
+ }
+
+ return xDrawPage;
+}
+
+
+const uno::Reference< lang::XMultiServiceFactory >&
+ SvxMSConvertOCXControls::GetServiceFactory()
+{
+ if( !xServiceFactory.is() && pDocSh )
+ {
+ xServiceFactory = uno::Reference< lang::XMultiServiceFactory >
+ (pDocSh->GetBaseModel(), uno::UNO_QUERY);
+ DBG_ASSERT( xServiceFactory.is(),
+ "XMultiServiceFactory nicht vom Model erhalten" );
+ }
+
+ return xServiceFactory;
+}
+
+const uno::Reference< drawing::XShapes >& SvxMSConvertOCXControls::GetShapes()
+{
+ if( !xShapes.is() )
+ {
+ GetDrawPage();
+ if( xDrawPage.is() )
+ {
+
+ xShapes = uno::Reference< drawing::XShapes >(xDrawPage,
+ uno::UNO_QUERY);
+ DBG_ASSERT( xShapes.is(), "XShapes nicht vom XDrawPage erhalten" );
+ }
+ }
+ return xShapes;
+}
+
+const uno::Reference< container::XIndexContainer >&
+ SvxMSConvertOCXControls::GetFormComps()
+{
+ if( !xFormComps.is() )
+ {
+ GetDrawPage();
+ if( xDrawPage.is() )
+ {
+ uno::Reference< form::XFormsSupplier > xFormsSupplier( xDrawPage,
+ uno::UNO_QUERY );
+ DBG_ASSERT( xFormsSupplier.is(),
+ "XFormsSupplier nicht vom XDrawPage erhalten" );
+
+ uno::Reference< container::XNameContainer > xNameCont =
+ xFormsSupplier->getForms();
+
+ // Das Formular bekommt einen Namen wie "WW-Standard[n]" und
+ // wird in jedem Fall neu angelegt.
+ UniString sName( sWW8_form, RTL_TEXTENCODING_MS_1252 );
+ sal_uInt16 n = 0;
+
+ while( xNameCont->hasByName( sName ) )
+ {
+ sName.AssignAscii( sWW8_form );
+ sName += String::CreateFromInt32( ++n );
+ }
+
+ const uno::Reference< lang::XMultiServiceFactory > &rServiceFactory
+ = GetServiceFactory();
+ if( !rServiceFactory.is() )
+ return xFormComps;
+
+ uno::Reference< uno::XInterface > xCreate =
+ rServiceFactory->createInstance(WW8_ASCII2STR(
+ "com.sun.star.form.component.Form"));
+ if( xCreate.is() )
+ {
+ uno::Reference< beans::XPropertySet > xFormPropSet( xCreate,
+ uno::UNO_QUERY );
+
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ xFormPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ uno::Reference< form::XForm > xForm( xCreate, uno::UNO_QUERY );
+ DBG_ASSERT(xForm.is(), "keine Form?");
+
+ uno::Reference< container::XIndexContainer > xForms( xNameCont,
+ uno::UNO_QUERY );
+ DBG_ASSERT( xForms.is(), "XForms nicht erhalten" );
+
+ aTmp.setValue( &xForm,
+ ::getCppuType((uno::Reference < form::XForm >*)0));
+ xForms->insertByIndex( xForms->getCount(), aTmp );
+
+ xFormComps = uno::Reference< container::XIndexContainer >
+ (xCreate, uno::UNO_QUERY);
+ }
+ }
+ }
+
+ return xFormComps;
+}
+
+sal_Bool OCX_CommandButton::Import( com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ aTmp <<= ImportColor(mnForeColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TextColor"), aTmp);
+
+ // fake transparent push button by setting window background color
+ if( !fBackStyle )
+ mnBackColor = 0x80000005;
+ aTmp <<= ImportColor(mnBackColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ sal_Bool bTemp;
+ if ((!(fEnabled)) || (fLocked))
+ bTemp = sal_False;
+ else
+ bTemp = sal_True;
+ aTmp = bool2any(bTemp);
+
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ bTemp = fWordWrap != 0;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MultiLine"), aTmp);
+
+ if (pCaption)
+ {
+ aTmp <<= lclCreateOUString( pCaption, nCaptionLen );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Label"), aTmp);
+ }
+
+ aTmp = bool2any( mbTakeFocus );
+ rPropSet->setPropertyValue( WW8_ASCII2STR( "FocusOnClick" ), aTmp );
+
+ aFontData.Import(rPropSet);
+ return sal_True;
+}
+
+sal_Bool OCX_GroupBox::Export(SvStorageRef& /* rObj */,
+ const uno::Reference< beans::XPropertySet >& /* rPropSet */,
+ const awt::Size& /* rSize */ )
+{
+ sal_Bool bRet=sal_True;
+ return bRet;
+}
+
+sal_Bool OCX_GroupBox::WriteContents(SvStorageStreamRef& /* rObj */,
+ const uno::Reference< beans::XPropertySet >& /* rPropSet */,
+ const awt::Size& /* rSize */)
+{
+ sal_Bool bRet=sal_True;
+ return bRet;
+}
+
+sal_Bool OCX_CommandButton::WriteContents(SvStorageStreamRef& rContents,
+ const uno::Reference< beans::XPropertySet >& rPropSet,
+ const awt::Size& rSize )
+{
+ sal_Bool bRet=sal_True;
+
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(8);
+
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+ sal_uInt8 nTemp=0;//fEnabled;
+ if (fEnabled)
+ nTemp |= 0x02;
+ if (fBackStyle)
+ nTemp |= 0x08;
+ *rContents << nTemp;
+ *rContents << sal_uInt8(0x00);
+
+ nTemp = 0;
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("MultiLine"));
+ fWordWrap = any2bool(aTmp);
+ if (fWordWrap)
+ nTemp |= 0x80;
+ *rContents << nTemp;
+ *rContents << sal_uInt8(0x00);
+
+ SvxOcxString aCaption( rPropSet->getPropertyValue(WW8_ASCII2STR("Label")) );
+ aCaption.WriteLenField( *rContents );
+ aCaption.WriteCharArray( *rContents );
+
+ WriteAlign(rContents,4);
+
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+ // "take focus on click" is directly in content flags, not in option field...
+ mbTakeFocus = any2bool( rPropSet->getPropertyValue( WW8_ASCII2STR( "FocusOnClick" ) ) );
+
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+
+ bRet = aFontData.Export(rContents,rPropSet);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ sal_uInt8 nTmp = 0x27;
+ if (aCaption.HasData())
+ nTmp |= 0x08;
+ *rContents << nTmp;
+ nTmp = 0x00;
+ if( !mbTakeFocus ) // flag is set, if option is off
+ nTmp |= 0x02;
+ *rContents << nTmp;
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+
+ DBG_ASSERT((rContents.Is() && (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+
+
+sal_Bool OCX_CommandButton::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x32, 0x05, 0xD7,
+ 0x69, 0xCE, 0xCD, 0x11, 0xA7, 0x77, 0x00, 0xDD,
+ 0x01, 0x14, 0x3C, 0x57, 0x22, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6d, 0x73, 0x20,
+ 0x32, 0x2e, 0x30, 0x20, 0x43, 0x6F, 0x6D, 0x6D,
+ 0x61, 0x6E, 0x64, 0x42, 0x75, 0x74, 0x74, 0x6F,
+ 0x6E, 0x00, 0x10, 0x00, 0x00, 0x00, 0x45, 0x6D,
+ 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x4F,
+ 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x2E,
+ 0x43, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x42,
+ 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2E, 0x31, 0x00,
+ 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x43, 0x00, 0x6F, 0x00, 0x6D, 0x00, 0x6D, 0x00,
+ 0x61, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x42, 0x00,
+ 0x75, 0x00, 0x74, 0x00, 0x74, 0x00, 0x6F, 0x00,
+ 0x6E, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+
+ return WriteContents(xContents,rPropSet,rSize);
+}
+
+sal_Bool OCX_ImageButton::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet=sal_True;
+
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(8);
+
+ uno::Any aTmp=rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+ sal_uInt8 nTemp=0;//fEnabled;
+ if (fEnabled)
+ nTemp |= 0x02;
+ *rContents << nTemp;
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+
+ WriteAlign(rContents,4);
+
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+
+ bRet = aFontData.Export(rContents,rPropSet);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ sal_uInt8 nTmp = 0x26;
+ *rContents << nTmp;
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+
+ DBG_ASSERT((rContents.Is() && (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+
+
+sal_Bool OCX_ImageButton::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x32, 0x05, 0xD7,
+ 0x69, 0xCE, 0xCD, 0x11, 0xA7, 0x77, 0x00, 0xDD,
+ 0x01, 0x14, 0x3C, 0x57, 0x22, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6d, 0x73, 0x20,
+ 0x32, 0x2e, 0x30, 0x20, 0x43, 0x6F, 0x6D, 0x6D,
+ 0x61, 0x6E, 0x64, 0x42, 0x75, 0x74, 0x74, 0x6F,
+ 0x6E, 0x00, 0x10, 0x00, 0x00, 0x00, 0x45, 0x6D,
+ 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x4F,
+ 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x2E,
+ 0x43, 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x42,
+ 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2E, 0x31, 0x00,
+ 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x43, 0x00, 0x6F, 0x00, 0x6D, 0x00, 0x6D, 0x00,
+ 0x61, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x42, 0x00,
+ 0x75, 0x00, 0x74, 0x00, 0x74, 0x00, 0x6F, 0x00,
+ 0x6E, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents,rPropSet,rSize);
+}
+
+
+sal_Bool OCX_OptionButton::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ // background color: fBackStyle==0 -> transparent
+ if( fBackStyle )
+ aTmp <<= ImportColor(mnBackColor);
+ else
+ aTmp = uno::Any();
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ sal_Bool bTemp;
+ if ((!(fEnabled)) || (fLocked))
+ bTemp = sal_False;
+ else
+ bTemp = sal_True;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ bTemp = fWordWrap != 0;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MultiLine"), aTmp);
+
+ aTmp <<= ImportColor(mnForeColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TextColor"), aTmp);
+
+ aTmp <<= ImportSpecEffect( nSpecialEffect );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("VisualEffect"), aTmp);
+
+ if (pValue && !bSetInDialog)
+ {
+ INT16 nTmp = pValue[0]-0x30;
+ aTmp <<= nTmp;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultState"), aTmp);
+ }
+
+ if (pCaption)
+ {
+ aTmp <<= lclCreateOUString( pCaption, nCaptionLen );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Label"), aTmp);
+ }
+
+ // #i40279# always centered vertically
+ aTmp <<= ::com::sun::star::style::VerticalAlignment_MIDDLE;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("VerticalAlign"), aTmp );
+
+ aFontData.Import(rPropSet);
+ return sal_True;
+}
+
+sal_Bool OCX_OptionButton::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet=sal_True;
+
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(12);
+
+ pBlockFlags[0] = 0;
+ pBlockFlags[1] = 0x01;
+ pBlockFlags[2] = 0;
+ pBlockFlags[3] = 0x80;
+ pBlockFlags[4] = 0;
+ pBlockFlags[5] = 0;
+ pBlockFlags[6] = 0;
+ pBlockFlags[7] = 0;
+
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ else
+ fBackStyle = 0;
+
+ sal_uInt8 nTemp=0;//=fEnabled;
+ if (fEnabled)
+ nTemp |= 0x02;
+ if (fBackStyle)
+ nTemp |= 0x08;
+ *rContents << nTemp;
+ pBlockFlags[0] |= 0x01;
+ *rContents << sal_uInt8(0x00);
+ nTemp = 0;
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("MultiLine"));
+ fWordWrap = any2bool(aTmp);
+ if (fWordWrap)
+ nTemp |= 0x80;
+ *rContents << nTemp;
+ *rContents << sal_uInt8(0x00);
+
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+ pBlockFlags[0] |= 0x04;
+
+ nStyle = 5;
+ *rContents << nStyle;
+ pBlockFlags[0] |= 0x40;
+
+ WriteAlign(rContents,4);
+ nValueLen = 1|SVX_MSOCX_COMPRESSED;
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("DefaultState"));
+ sal_Int16 nDefault = sal_Int16();
+ aTmp >>= nDefault;
+ *rContents << nValueLen;
+ pBlockFlags[2] |= 0x40;
+
+
+ SvxOcxString aCaption( rPropSet->getPropertyValue(WW8_ASCII2STR("Label")) );
+ if (aCaption.HasData())
+ pBlockFlags[2] |= 0x80;
+ aCaption.WriteLenField( *rContents );
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("VisualEffect"));
+ if (aTmp.hasValue())
+ {
+ sal_Int16 nApiSpecEffect = sal_Int16();
+ aTmp >>= nApiSpecEffect;
+ nSpecialEffect = ExportSpecEffect( nApiSpecEffect );
+ }
+ *rContents << nSpecialEffect;
+ pBlockFlags[3] |= 0x04;
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+ nDefault += 0x30;
+ *rContents << sal_uInt8(nDefault);
+ *rContents << sal_uInt8(0x00);
+
+ aCaption.WriteCharArray( *rContents );
+
+ WriteAlign(rContents,4);
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+ bRet = aFontData.Export(rContents,rPropSet);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+ *rContents << pBlockFlags[4];
+ *rContents << pBlockFlags[5];
+ *rContents << pBlockFlags[6];
+ *rContents << pBlockFlags[7];
+
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+
+
+sal_Bool OCX_OptionButton::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x1D, 0xD2, 0x8B,
+ 0x42, 0xEC, 0xCE, 0x11, 0x9E, 0x0D, 0x00, 0xAA,
+ 0x00, 0x60, 0x02, 0xF3, 0x21, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x4F, 0x70, 0x74, 0x69,
+ 0x6F, 0x6E, 0x42, 0x75, 0x74, 0x74, 0x6F, 0x6E,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x45, 0x6D, 0x62,
+ 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x4F, 0x62,
+ 0x6A, 0x65, 0x63, 0x74, 0x00, 0x15, 0x00, 0x00,
+ 0x00, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x2E, 0x4F,
+ 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x42, 0x75, 0x74,
+ 0x74, 0x6F, 0x6E, 0x2E, 0x31, 0x00, 0xF4, 0x39,
+ 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x4F, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69, 0x00,
+ 0x6F, 0x00, 0x6E, 0x00, 0x42, 0x00, 0x75, 0x00,
+ 0x74, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x6E, 0x00,
+ 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+
+sal_Bool OCX_TextBox::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ aTmp = bool2any( fEnabled != 0 );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ aTmp = bool2any( fLocked != 0 );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ReadOnly"), aTmp);
+
+ aTmp = bool2any( fHideSelection != 0 );
+ rPropSet->setPropertyValue( WW8_ASCII2STR( "HideInactiveSelection" ), aTmp);
+
+ aTmp <<= ImportColor(mnForeColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TextColor"), aTmp);
+
+ aTmp <<= ImportColor(mnBackColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ aTmp <<= ImportBorder(nSpecialEffect,nBorderStyle);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Border"), aTmp);
+
+ aTmp <<= ImportColor( nBorderColor );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BorderColor"), aTmp);
+
+ aTmp = bool2any( fMultiLine != 0 );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MultiLine"), aTmp);
+
+ sal_uInt16 nTmp = static_cast<sal_uInt16>(nMaxLength);
+ aTmp <<= nTmp;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MaxTextLen"), aTmp);
+
+
+ sal_Bool bTemp1,bTemp2;
+ uno::Any aBarsH,aBarsV;
+ switch(nScrollBars)
+ {
+ case 1:
+ bTemp1 = sal_True;
+ bTemp2 = sal_False;
+ break;
+ case 2:
+ bTemp1 = sal_False;
+ bTemp2 = sal_True;
+ break;
+ case 3:
+ bTemp1 = sal_True;
+ bTemp2 = sal_True;
+ break;
+ case 0:
+ default:
+ bTemp1 = sal_False;
+ bTemp2 = sal_False;
+ break;
+ }
+
+ aBarsH = bool2any(bTemp1);
+ aBarsV = bool2any(bTemp2);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("HScroll"), aBarsH);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("VScroll"), aBarsV);
+
+ nTmp = nPasswordChar;
+ aTmp <<= nTmp;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("EchoChar"), aTmp);
+
+ if (pValue)
+ {
+ aTmp <<= lclCreateOUString( pValue, nValueLen );
+ // DefaultText seems to no longer be in UnoEditControlModel
+ if ( bSetInDialog )
+ {
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Text"), aTmp);
+ }
+ else
+ {
+ rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultText"), aTmp);
+ }
+ }
+
+ aFontData.Import(rPropSet);
+ return sal_True;
+}
+
+sal_Bool OCX_TextBox::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet=sal_True;
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(12);
+
+ pBlockFlags[0] = 0;
+ pBlockFlags[1] = 0x01;
+ pBlockFlags[2] = 0x00;
+ pBlockFlags[3] = 0x80;
+ pBlockFlags[4] = 0;
+ pBlockFlags[5] = 0;
+ pBlockFlags[6] = 0;
+ pBlockFlags[7] = 0;
+
+
+ sal_uInt8 nTemp=0x19;
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+ if (fEnabled)
+ nTemp |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("ReadOnly"));
+ fLocked = any2bool(aTmp);
+ if (fLocked)
+ nTemp |= 0x04;
+
+ *rContents << nTemp;
+ pBlockFlags[0] |= 0x01;
+ *rContents << sal_uInt8(0x48);
+ *rContents << sal_uInt8(0x80);
+
+ fMultiLine = any2bool(rPropSet->getPropertyValue(WW8_ASCII2STR("MultiLine")));
+ fHideSelection = any2bool(rPropSet->getPropertyValue(WW8_ASCII2STR("HideInactiveSelection")));
+ nTemp = 0x0C;
+ if (fMultiLine)
+ nTemp |= 0x80;
+ if( fHideSelection )
+ nTemp |= 0x20;
+ *rContents << nTemp;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+ pBlockFlags[0] |= 0x04;
+
+ aTmp = rPropSet->getPropertyValue( WW8_ASCII2STR("MaxTextLen"));
+ aTmp >>= nMaxLength;
+ *rContents << nMaxLength;
+ pBlockFlags[0] |= 0x08;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Border"));
+ sal_Int16 nBorder = sal_Int16();
+ aTmp >>= nBorder;
+ nSpecialEffect = ExportBorder(nBorder,nBorderStyle);
+ *rContents << nBorderStyle;
+ pBlockFlags[0] |= 0x10;
+
+ aTmp = rPropSet->getPropertyValue( WW8_ASCII2STR("HScroll"));
+ sal_Bool bTemp1 = any2bool(aTmp);
+ aTmp = rPropSet->getPropertyValue( WW8_ASCII2STR("VScroll"));
+ sal_Bool bTemp2 = any2bool(aTmp);
+ if (!bTemp1 && !bTemp2)
+ nScrollBars =0;
+ else if (bTemp1 && bTemp2)
+ nScrollBars = 3;
+ else if (!bTemp1 && bTemp2)
+ nScrollBars = 2;
+ else
+ nScrollBars = 1;
+ *rContents << nScrollBars;
+ pBlockFlags[0] |= 0x20;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("EchoChar"));
+ sal_uInt16 nTmp = sal_uInt16();
+ aTmp >>= nTmp;
+ nPasswordChar = static_cast<sal_uInt8>(nTmp);
+ *rContents << nPasswordChar;
+ pBlockFlags[1] |= 0x02;
+
+ SvxOcxString aValue( rPropSet->getPropertyValue(WW8_ASCII2STR("DefaultText")) );
+ aValue.WriteLenField( *rContents );
+ if (aValue.HasData())
+ pBlockFlags[2] |= 0x40;
+
+ WriteAlign(rContents,4);
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BorderColor"));
+ if (aTmp.hasValue())
+ aTmp >>= nBorderColor;
+ *rContents << ExportColor(nBorderColor);
+ pBlockFlags[3] |= 0x02;
+
+ *rContents << nSpecialEffect;
+ pBlockFlags[3] |= 0x04;
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+ aValue.WriteCharArray( *rContents );
+
+ WriteAlign(rContents,4);
+
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+
+ bRet = aFontData.Export(rContents,rPropSet);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+ *rContents << pBlockFlags[4];
+ *rContents << pBlockFlags[5];
+ *rContents << pBlockFlags[6];
+ *rContents << pBlockFlags[7];
+
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK == rContents->GetError())),"damn");
+ return bRet;
+}
+
+
+sal_Bool OCX_TextBox::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x1D, 0xD2, 0x8B,
+ 0x42, 0xEC, 0xCE, 0x11, 0x9E, 0x0D, 0x00, 0xAA,
+ 0x00, 0x60, 0x02, 0xF3, 0x1C, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x54, 0x65, 0x78, 0x74,
+ 0x42, 0x6F, 0x78, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64,
+ 0x20, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x46, 0x6F, 0x72, 0x6D,
+ 0x73, 0x2E, 0x54, 0x65, 0x78, 0x74, 0x42, 0x6F,
+ 0x78, 0x2E, 0x31, 0x00, 0xF4, 0x39, 0xB2, 0x71,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x54, 0x00, 0x65, 0x00, 0x78, 0x00, 0x74, 0x00,
+ 0x42, 0x00, 0x6F, 0x00, 0x78, 0x00, 0x31, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+sal_Bool OCX_FieldControl::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet=sal_True;
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(12);
+
+ pBlockFlags[0] = 0;
+ pBlockFlags[1] = 0x01;
+ pBlockFlags[2] = 0x00;
+ pBlockFlags[3] = 0x80;
+ pBlockFlags[4] = 0;
+ pBlockFlags[5] = 0;
+ pBlockFlags[6] = 0;
+ pBlockFlags[7] = 0;
+
+
+ sal_uInt8 nTemp=0x19;
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+ if (fEnabled)
+ nTemp |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("ReadOnly"));
+ fLocked = any2bool(aTmp);
+ if (fLocked)
+ nTemp |= 0x04;
+
+ *rContents << nTemp;
+ pBlockFlags[0] |= 0x01;
+ *rContents << sal_uInt8(0x48);
+ *rContents << sal_uInt8(0x80);
+
+ nTemp = 0x2C;
+ *rContents << nTemp;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+ pBlockFlags[0] |= 0x04;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Border"));
+ sal_Int16 nBorder = sal_Int16();
+ aTmp >>= nBorder;
+ nSpecialEffect = ExportBorder(nBorder,nBorderStyle);
+ *rContents << nBorderStyle;
+ pBlockFlags[0] |= 0x10;
+
+#if 0 //Each control has a different Value format, and how to convert each to text has to be found out
+ SvxOcxString aValue( rPropSet->getPropertyValue(WW8_ASCII2STR("DefaultText")) );
+ aValue.WriteLenField( *rContents );
+ if (aValue.HasData())
+ pBlockFlags[2] |= 0x40;
+#endif
+
+ *rContents << nSpecialEffect;
+ pBlockFlags[3] |= 0x04;
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+#if 0
+ aValue.WriteCharArray( *rContents );
+#endif
+
+ WriteAlign(rContents,4);
+
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+
+ bRet = aFontData.Export(rContents,rPropSet);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+ *rContents << pBlockFlags[4];
+ *rContents << pBlockFlags[5];
+ *rContents << pBlockFlags[6];
+ *rContents << pBlockFlags[7];
+
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+sal_Bool OCX_FieldControl::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x1D, 0xD2, 0x8B,
+ 0x42, 0xEC, 0xCE, 0x11, 0x9E, 0x0D, 0x00, 0xAA,
+ 0x00, 0x60, 0x02, 0xF3, 0x1C, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x54, 0x65, 0x78, 0x74,
+ 0x42, 0x6F, 0x78, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64,
+ 0x20, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x46, 0x6F, 0x72, 0x6D,
+ 0x73, 0x2E, 0x54, 0x65, 0x78, 0x74, 0x42, 0x6F,
+ 0x78, 0x2E, 0x31, 0x00, 0xF4, 0x39, 0xB2, 0x71,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x54, 0x00, 0x65, 0x00, 0x78, 0x00, 0x74, 0x00,
+ 0x42, 0x00, 0x6F, 0x00, 0x78, 0x00, 0x31, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+
+
+sal_Bool OCX_ToggleButton::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ aTmp = bool2any(true);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Toggle"), aTmp );
+
+ sal_Bool bTemp;
+ if ((!(fEnabled)) || (fLocked))
+ bTemp = sal_False;
+ else
+ bTemp = sal_True;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ bTemp = fWordWrap != 0;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MultiLine"), aTmp);
+
+ aTmp <<= ImportColor(mnForeColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TextColor"), aTmp);
+
+ // fake transparent toggle button by setting window background color
+ if( !fBackStyle )
+ mnBackColor = 0x80000005;
+ aTmp <<= ImportColor(mnBackColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ if (pValue)
+ {
+ INT16 nTmp=pValue[0]-0x30;
+ aTmp <<= nTmp;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("State"), aTmp);
+ }
+
+ if (pCaption)
+ {
+ aTmp <<= lclCreateOUString( pCaption, nCaptionLen );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Label"), aTmp);
+ }
+
+ aFontData.Import(rPropSet);
+ return sal_True;
+}
+
+sal_Bool OCX_ToggleButton::Export(
+ SvStorageRef &rObj, const uno::Reference< beans::XPropertySet> &rPropSet,
+ const awt::Size& rSize )
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x1D, 0xD2, 0x8B,
+ 0x42, 0xEC, 0xCE, 0x11, 0x9E, 0x0D, 0x00, 0xAA,
+ 0x00, 0x60, 0x02, 0xF3, 0x21, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x54, 0x6F, 0x67, 0x67,
+ 0x6C, 0x65, 0x42, 0x75, 0x74, 0x74, 0x6F, 0x6E,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x45, 0x6D, 0x62,
+ 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x4F, 0x62,
+ 0x6A, 0x65, 0x63, 0x74, 0x00, 0x15, 0x00, 0x00,
+ 0x00, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x2E, 0x54,
+ 0x6F, 0x67, 0x67, 0x6C, 0x65, 0x42, 0x75, 0x74,
+ 0x74, 0x6F, 0x6E, 0x2E, 0x31, 0x00, 0xF4, 0x39,
+ 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x54, 0x00, 0x6F, 0x00, 0x67, 0x00, 0x67, 0x00,
+ 0x6C, 0x00, 0x65, 0x00, 0x42, 0x00, 0x75, 0x00,
+ 0x74, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x6E, 0x00,
+ 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+
+ return WriteContents(xContents,rPropSet,rSize);
+}
+
+sal_Bool OCX_ToggleButton::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet=sal_True;
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(12);
+
+ pBlockFlags[0] = 0;
+ pBlockFlags[1] = 0x01;
+ pBlockFlags[2] = 0;
+ pBlockFlags[3] = 0x80;
+ pBlockFlags[4] = 0;
+ pBlockFlags[5] = 0;
+ pBlockFlags[6] = 0;
+ pBlockFlags[7] = 0;
+
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+
+ sal_uInt8 nTemp=fEnabled;
+ if (fEnabled)
+ nTemp = nTemp << 1;
+ if (fBackStyle)
+ nTemp |= 0x08;
+ *rContents << nTemp;
+ pBlockFlags[0] |= 0x01;
+ *rContents << sal_uInt8(0x00);
+ nTemp = 0;
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("MultiLine"));
+ fWordWrap = any2bool(aTmp);
+ if (fWordWrap)
+ nTemp |= 0x80;
+ *rContents << nTemp;
+ *rContents << sal_uInt8(0x00);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+ pBlockFlags[0] |= 0x04;
+
+ nStyle = 6;
+ *rContents << nStyle;
+ pBlockFlags[0] |= 0x40;
+
+ WriteAlign(rContents,4);
+ nValueLen = 1|SVX_MSOCX_COMPRESSED;
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("State"));
+ sal_Int16 nDefault = sal_Int16();
+ aTmp >>= nDefault;
+ *rContents << nValueLen;
+ pBlockFlags[2] |= 0x40;
+
+ SvxOcxString aCaption( rPropSet->getPropertyValue(WW8_ASCII2STR("Label")) );
+ aCaption.WriteLenField( *rContents );
+ if (aCaption.HasData())
+ pBlockFlags[2] |= 0x80;
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+ nDefault += 0x30;
+ *rContents << sal_uInt8(nDefault);
+ *rContents << sal_uInt8(0x00);
+
+ aCaption.WriteCharArray( *rContents );
+
+ WriteAlign(rContents,4);
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+ bRet = aFontData.Export(rContents,rPropSet);
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+ *rContents << pBlockFlags[4];
+ *rContents << pBlockFlags[5];
+ *rContents << pBlockFlags[6];
+ *rContents << pBlockFlags[7];
+
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+sal_Bool OCX_Label::Import(uno::Reference< beans::XPropertySet > &rPropSet)
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ sal_Bool bTemp;
+ if ((!(fEnabled)) || (fLocked))
+ bTemp = sal_False;
+ else
+ bTemp = sal_True;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ aTmp <<= ImportColor(mnForeColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TextColor"), aTmp);
+
+ // background color: fBackStyle==0 -> transparent
+ if( fBackStyle )
+ {
+ aTmp <<= ImportColor(mnBackColor);
+ }
+ else
+ {
+ // try fake transparent by using parents backColor
+ if ( bSetInDialog && mpParent != NULL )
+ {
+ aTmp <<= ImportColor( mpParent->mnBackColor );
+ }
+ else
+ {
+ aTmp = uno::Any(); // use SO default
+ }
+ }
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ aTmp <<= ImportBorder(nSpecialEffect,nBorderStyle);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Border"), aTmp);
+
+ aTmp <<= ImportColor( nBorderColor );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BorderColor"), aTmp);
+
+ bTemp=fWordWrap;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MultiLine"), aTmp);
+
+ if (pCaption)
+ {
+ aTmp <<= lclCreateOUString( pCaption, nCaptionLen );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Label"), aTmp);
+ }
+
+ aFontData.Import(rPropSet);
+ return sal_True;
+}
+
+sal_Bool OCX_ComboBox::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ aTmp = bool2any(fEnabled != 0);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ aTmp = bool2any(fLocked != 0);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ReadOnly"), aTmp);
+
+ aTmp = bool2any( nDropButtonStyle != 0 );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Dropdown"), aTmp);
+
+ aTmp = bool2any( fHideSelection != 0 );
+ rPropSet->setPropertyValue( WW8_ASCII2STR( "HideInactiveSelection" ), aTmp);
+
+ aTmp <<= ImportColor(mnForeColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TextColor"), aTmp);
+
+ if (pValue)
+ {
+ aTmp <<= lclCreateOUString( pValue, nValueLen );
+ if ( bSetInDialog )
+ {
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Text"), aTmp);
+ }
+ else
+ {
+ rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultText"), aTmp);
+ }
+ }
+
+ aTmp <<= ImportColor(mnBackColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ aTmp <<= ImportBorder(nSpecialEffect,nBorderStyle);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Border"), aTmp);
+
+ aTmp <<= ImportColor( nBorderColor );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BorderColor"), aTmp);
+
+ sal_Int16 nTmp=static_cast<sal_Int16>(nMaxLength);
+ aTmp <<= nTmp;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MaxTextLen"), aTmp);
+
+ aFontData.Import(rPropSet);
+ return sal_True;
+}
+
+sal_Bool OCX_ComboBox::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet=sal_True;
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(12);
+
+ pBlockFlags[0] = 0;
+ pBlockFlags[1] = 0x01;
+ pBlockFlags[2] = 0x00;
+ pBlockFlags[3] = 0x80;
+ pBlockFlags[4] = 0;
+ pBlockFlags[5] = 0;
+ pBlockFlags[6] = 0;
+ pBlockFlags[7] = 0;
+
+
+ sal_uInt8 nTemp=0x19;//fEnabled;
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+ if (fEnabled)
+ nTemp |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("ReadOnly"));
+ fLocked = any2bool(aTmp);
+ if (fLocked)
+ nTemp |= 0x04;
+
+ *rContents << nTemp;
+ pBlockFlags[0] |= 0x01;
+ *rContents << sal_uInt8(0x48);
+ *rContents << sal_uInt8(0x80);
+
+ nTemp = 0x0C;
+ fHideSelection = any2bool(rPropSet->getPropertyValue(WW8_ASCII2STR("HideInactiveSelection")));
+ if( fHideSelection )
+ nTemp |= 0x20;
+ *rContents << nTemp;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+ pBlockFlags[0] |= 0x04;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Border"));
+ sal_Int16 nBorder = sal_Int16();
+ aTmp >>= nBorder;
+ nSpecialEffect = ExportBorder(nBorder,nBorderStyle);
+ *rContents << nBorderStyle;
+ pBlockFlags[0] |= 0x10;
+
+ nStyle = 3;
+ *rContents << nStyle;
+ pBlockFlags[0] |= 0x40;
+
+ WriteAlign(rContents,2);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("LineCount"));
+ aTmp >>= nListRows;
+ *rContents << nListRows;
+ pBlockFlags[1] |= 0x40;
+
+ *rContents << sal_uInt8(1); //DefaultSelected One
+ pBlockFlags[2] |= 0x01;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Dropdown"));
+ nDropButtonStyle = any2bool(aTmp);
+ if (nDropButtonStyle)
+ nDropButtonStyle=0x02;
+ *rContents << nDropButtonStyle;
+ pBlockFlags[2] |= 0x04;
+
+ SvxOcxString aValue( rPropSet->getPropertyValue(WW8_ASCII2STR("Text")) );
+ aValue.WriteLenField( *rContents );
+ if (aValue.HasData())
+ pBlockFlags[2] |= 0x40;
+
+ WriteAlign(rContents,4);
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BorderColor"));
+ if (aTmp.hasValue())
+ aTmp >>= nBorderColor;
+ *rContents << ExportColor(nBorderColor);
+ pBlockFlags[3] |= 0x02;
+
+ *rContents << nSpecialEffect;
+ pBlockFlags[3] |= 0x04;
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+ aValue.WriteCharArray( *rContents );
+
+ WriteAlign(rContents,4);
+
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+
+ bRet = aFontData.Export(rContents,rPropSet);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+ *rContents << pBlockFlags[4];
+ *rContents << pBlockFlags[5];
+ *rContents << pBlockFlags[6];
+ *rContents << pBlockFlags[7];
+
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+
+sal_Bool OCX_ComboBox::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x1D, 0xD2, 0x8B,
+ 0x42, 0xEC, 0xCE, 0x11, 0x9E, 0x0D, 0x00, 0xAA,
+ 0x00, 0x60, 0x02, 0xF3, 0x1D, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x43, 0x6F, 0x6D, 0x62,
+ 0x6F, 0x42, 0x6F, 0x78, 0x00, 0x10, 0x00, 0x00,
+ 0x00, 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65,
+ 0x64, 0x20, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74,
+ 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x6F, 0x72,
+ 0x6D, 0x73, 0x2E, 0x43, 0x6F, 0x6D, 0x62, 0x6F,
+ 0x42, 0x6F, 0x78, 0x2E, 0x31, 0x00, 0xF4, 0x39,
+ 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x43, 0x00, 0x6F, 0x00, 0x6D, 0x00, 0x62, 0x00,
+ 0x6F, 0x00, 0x42, 0x00, 0x6F, 0x00, 0x78, 0x00,
+ 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+
+
+sal_Bool OCX_ListBox::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ sal_Bool bTmp=fEnabled;
+ aTmp = bool2any(bTmp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ bTmp=fLocked;
+ aTmp = bool2any(bTmp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ReadOnly"), aTmp);
+
+ aTmp <<= ImportColor(mnForeColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TextColor"), aTmp);
+
+ sal_Bool bTemp = nMultiState;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MultiSelection"), aTmp);
+
+#if 0 //Don't delete this for now until I figure out if I can make this
+ if (pValue)
+ {
+ aTmp <<= lclCreateOUString( pValue, nValueLen );
+ xPropSet->setPropertyValue( WW8_ASCII2STR("DefaultText"), aTmp);
+ }
+#endif
+
+ aTmp <<= ImportColor(mnBackColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ aTmp <<= ImportBorder(nSpecialEffect,nBorderStyle);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Border"), aTmp);
+
+ aTmp <<= ImportColor( nBorderColor );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BorderColor"), aTmp);
+
+ aFontData.Import(rPropSet);
+ return sal_True;
+}
+
+sal_Bool OCX_ListBox::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet=sal_True;
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(12);
+
+ pBlockFlags[0] = 0;
+ pBlockFlags[1] = 0x01;
+ pBlockFlags[2] = 0x01;
+ pBlockFlags[3] = 0x80;
+ pBlockFlags[4] = 0;
+ pBlockFlags[5] = 0;
+ pBlockFlags[6] = 0;
+ pBlockFlags[7] = 0;
+
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+ sal_uInt8 nTemp=fEnabled;
+ if (fEnabled)
+ nTemp = nTemp << 1;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("ReadOnly"));
+ fLocked = any2bool(aTmp);
+ if (fLocked)
+ nTemp |= 0x04;
+
+ *rContents << nTemp;
+ pBlockFlags[0] |= 0x01;
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+ pBlockFlags[0] |= 0x04;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Border"));
+ sal_Int16 nBorder = sal_Int16();
+ aTmp >>= nBorder;
+ nSpecialEffect = ExportBorder(nBorder,nBorderStyle);
+ WriteAlign(rContents,2);
+ *rContents << nBorderStyle;
+ pBlockFlags[0] |= 0x10;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("MultiSelection"));
+ nMultiState = any2bool(aTmp);
+
+ if (nMultiState)
+ {
+ *rContents << nMultiState;
+ pBlockFlags[0] |= 0x20;
+ }
+
+ nStyle = 2;
+ *rContents << nStyle;
+ pBlockFlags[0] |= 0x40;
+
+
+ WriteAlign(rContents,4);
+
+#if 0
+ SvxOcxString aValue( rPropSet->getPropertyValue(WW8_ASCII2STR("DefaultText")) );
+ aValue.WriteLenField( *rContents );
+ if (aValue.HasData())
+ pBlockFlags[2] |= 0x40;
+
+ WriteAlign(rContents,4);
+#endif
+
+ WriteAlign(rContents,4);
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BorderColor"));
+ if (aTmp.hasValue())
+ aTmp >>= nBorderColor;
+ *rContents << ExportColor(nBorderColor);
+ pBlockFlags[3] |= 0x02;
+
+ *rContents << nSpecialEffect;
+ pBlockFlags[3] |= 0x04;
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+#if 0
+ aValue.WriteCharArray( *rContents );
+#endif
+
+ WriteAlign(rContents,4);
+
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+
+ bRet = aFontData.Export(rContents,rPropSet);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+ *rContents << pBlockFlags[4];
+ *rContents << pBlockFlags[5];
+ *rContents << pBlockFlags[6];
+ *rContents << pBlockFlags[7];
+
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+sal_Bool OCX_ListBox::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x1D, 0xD2, 0x8B,
+ 0x42, 0xEC, 0xCE, 0x11, 0x9E, 0x0D, 0x00, 0xAA,
+ 0x00, 0x60, 0x02, 0xF3, 0x1C, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x4C, 0x69, 0x73, 0x74,
+ 0x42, 0x6F, 0x78, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64,
+ 0x20, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x46, 0x6F, 0x72, 0x6D,
+ 0x73, 0x2E, 0x4C, 0x69, 0x73, 0x74, 0x42, 0x6F,
+ 0x78, 0x2E, 0x31, 0x00, 0xF4, 0x39, 0xB2, 0x71,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x4C, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00,
+ 0x42, 0x00, 0x6F, 0x00, 0x78, 0x00, 0x31, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+sal_Bool OCX_Control::Read(SvStorageStream *pS)
+{
+ sal_uInt16 nIdentifier, nFixedAreaLen;
+ *pS >> nIdentifier;
+ DBG_ASSERT(nStandardId==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+ pS->SeekRel(nFixedAreaLen);
+ return true;
+}
+
+sal_Bool OCX_ModernControl::Read(SvStorageStream *pS)
+{
+ long nStart = pS->Tell();
+ *pS >> nIdentifier;
+ DBG_ASSERT(nIdentifier==nStandardId,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+ pS->Read(pBlockFlags,8);
+
+ if (pBlockFlags[0] & 0x01)
+ {
+ sal_uInt8 nTemp;
+ *pS >> nTemp;
+
+ fEnabled = (nTemp & 0x02) >> 1;
+ fLocked = (nTemp & 0x04) >> 2;
+ fBackStyle = (nTemp & 0x08) >> 3;
+
+ *pS >> nTemp;
+
+ fColumnHeads = (nTemp & 0x04) >> 2;
+ fIntegralHeight = (nTemp & 0x08) >> 3;
+ fMatchRequired = (nTemp & 0x10) >> 4;
+ fAlignment = (nTemp & 0x20) >> 5;
+
+ *pS >> nTemp;
+
+ fDragBehaviour = (nTemp & 0x08) >> 3;
+ fEnterKeyBehaviour = (nTemp & 0x10) >> 4;
+ fEnterFieldBehaviour = (nTemp & 0x20) >> 5;
+ fTabKeyBehaviour = (nTemp & 0x40) >> 6;
+ fWordWrap = (nTemp & 0x80) >> 7;
+
+ *pS >> nTemp;
+ fSelectionMargin = (nTemp & 0x04) >> 2;
+ fAutoWordSelect = (nTemp & 0x08) >> 3;
+ fAutoSize = (nTemp & 0x10) >> 4;
+ fHideSelection = (nTemp & 0x20) >> 5;
+ fAutoTab = (nTemp & 0x40) >> 6;
+ fMultiLine = (nTemp & 0x80) >> 7;
+
+ }
+
+ /*If any of these are set they follow eachother in this order one after
+ another padded out to the next U32 boundary with 0's
+ U8 can abut each other U16 must start on a U16 boundary and are padded to
+ that with 0's. A standardish word alignment structure*/
+
+ if (pBlockFlags[0] & 0x02)
+ *pS >> mnBackColor;
+ if (pBlockFlags[0] & 0x04)
+ *pS >> mnForeColor;
+ if (pBlockFlags[0] & 0x08)
+ *pS >> nMaxLength;
+
+ if (pBlockFlags[0] & 0x10)
+ *pS >> nBorderStyle;
+ if (pBlockFlags[0] & 0x20)
+ *pS >> nScrollBars;
+ if (pBlockFlags[0] & 0x40)
+ *pS >> nStyle;// (UI 0 == Data 3, UI 2 = Data 7)
+ if (pBlockFlags[0] & 0x80)
+ *pS >> nMousePointer;
+
+ if (pBlockFlags[1] & 0x02)
+ *pS >> nPasswordChar; //HUH ??? always 0 ??? not sure maybe just padding
+
+ if (pBlockFlags[1] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nListWidth;
+ }
+
+ if (pBlockFlags[1] & 0x08)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nBoundColumn;
+ }
+ if (pBlockFlags[1] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nTextColumn;
+ }
+ if (pBlockFlags[1] & 0x20)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nColumnCount;
+ }
+ if (pBlockFlags[1] & 0x40)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nListRows;
+ }
+ if (pBlockFlags[1] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nUnknown8; //something to do with ColumnWidths
+ }
+ if (pBlockFlags[2] & 0x01)
+ *pS >> nMatchEntry;
+ if (pBlockFlags[2] & 0x02)
+ *pS >> nListStyle;
+ if (pBlockFlags[2] & 0x04)
+ *pS >> nShowDropButtonWhen;
+ if (pBlockFlags[2] & 0x10)
+ *pS >> nDropButtonStyle;
+ if (pBlockFlags[2] & 0x20)
+ *pS >> nMultiState;
+
+ bool bValue = (pBlockFlags[2] & 0x40) != 0;
+ if (bValue)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nValueLen;
+ }
+ bool bCaption = (pBlockFlags[2] & 0x80) != 0;
+ if (bCaption)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nCaptionLen;
+ }
+ if (pBlockFlags[3] & 0x01)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nHorzPos;
+ *pS >> nVertPos;
+ }
+ if (pBlockFlags[3] & 0x02)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nBorderColor;
+ }
+ if (pBlockFlags[3] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4); // NEW
+ *pS >> nSpecialEffect;
+ pS->SeekRel( 3 ); // special effect is 32bit, not 8bit
+ }
+ if (pBlockFlags[3] & 0x08)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nIcon;
+ DBG_ASSERT(nIcon == 0xFFFF, "Unexpected nIcon");
+ }
+ if (pBlockFlags[3] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nPicture;
+ DBG_ASSERT(nPicture == 0xFFFF, "Unexpected nIcon");
+ }
+ if (pBlockFlags[3] & 0x20)
+ *pS >> nAccelerator;
+ /*
+ if (pBlockFlags[3] & 0x80)
+ *pS >> nUnknown9;
+ */
+ bool bGroupName = (pBlockFlags[4] & 0x01) != 0;
+ if (bGroupName)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nGroupNameLen;
+ }
+
+ //End
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nWidth;
+ *pS >> nHeight;
+
+ if (bValue)
+ lclReadCharArray( *pS, pValue, nValueLen, pS->Tell() - nStart);
+
+ if (bCaption)
+ lclReadCharArray( *pS, pCaption, nCaptionLen, pS->Tell() - nStart);
+
+ if (bGroupName)
+ lclReadCharArray( *pS, pGroupName, nGroupNameLen, pS->Tell() - nStart);
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ if (nIcon)
+ {
+ pS->Read(pIconHeader,20);
+ *pS >> nIconLen;
+ pIcon = new sal_uInt8[nIconLen];
+ pS->Read(pIcon,nIconLen);
+ }
+
+ if (nPicture)
+ {
+ pS->Read(pPictureHeader,20);
+ *pS >> nPictureLen;
+ pPicture = new sal_uInt8[nPictureLen];
+ pS->Read(pPicture,nPictureLen);
+ }
+
+ return sal_True;
+}
+
+
+sal_Bool OCX_CommandButton::Read(SvStorageStream *pS)
+{
+ long nStart = pS->Tell();
+ *pS >> nIdentifier;
+ DBG_ASSERT(nStandardId==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+ pS->Read(pBlockFlags,4);
+
+
+ if (pBlockFlags[0] & 0x01)
+ *pS >> mnForeColor;
+ if (pBlockFlags[0] & 0x02)
+ *pS >> mnBackColor;
+
+ if (pBlockFlags[0] & 0x04)
+ {
+ sal_uInt8 nTemp;
+ *pS >> nTemp;
+ fEnabled = (nTemp&0x02)>>1;
+ fLocked = (nTemp&0x04)>>2;
+ fBackStyle = (nTemp&0x08)>>3;
+ *pS >> nTemp;
+ *pS >> nTemp;
+ fWordWrap = (nTemp&0x80)>>7;
+ *pS >> nTemp;
+ fAutoSize = (nTemp&0x10)>>4;
+ }
+
+ bool bCaption = (pBlockFlags[0] & 0x08) != 0;
+ if (bCaption)
+ {
+ *pS >> nCaptionLen;
+ }
+ if (pBlockFlags[0] & 0x10) /*Picture Position, a strange mechanism here*/
+ {
+ *pS >> nVertPos;
+ *pS >> nHorzPos;
+ }
+
+ if (pBlockFlags[0] & 0x40) /*MousePointer*/
+ *pS >> nMousePointer;
+
+ if (pBlockFlags[0] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nPicture;
+ }
+
+ if (pBlockFlags[1] & 0x01)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nAccelerator;
+ }
+
+ // "take focus on click" is directly in content flags, not in option field...
+ mbTakeFocus = (pBlockFlags[1] & 0x02) == 0; // option is on, if flag is not set
+
+ if (pBlockFlags[1] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nIcon;
+ }
+
+ if (bCaption)
+ lclReadCharArray( *pS, pCaption, nCaptionLen, pS->Tell() - nStart);
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nWidth;
+ *pS >> nHeight;
+
+ if (nIcon)
+ {
+ pS->Read(pIconHeader,20);
+ *pS >> nIconLen;
+ pIcon = new sal_uInt8[nIconLen];
+ pS->Read(pIcon,nIconLen);
+ }
+
+ if (nPicture)
+ {
+ pS->Read(pPictureHeader,20);
+ *pS >> nPictureLen;
+ pPicture = new sal_uInt8[nPictureLen];
+ pS->Read(pPicture,nPictureLen);
+ }
+
+ return sal_True;
+}
+
+sal_Bool OCX_Label::Read(SvStorageStream *pS)
+{
+ long nStart = pS->Tell();
+ *pS >> nIdentifier;
+ DBG_ASSERT(nStandardId==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+ pS->Read(pBlockFlags,4);
+
+
+ if (pBlockFlags[0] & 0x01)
+ *pS >> mnForeColor;
+ if (pBlockFlags[0] & 0x02)
+ *pS >> mnBackColor;
+
+
+ if (pBlockFlags[0] & 0x04)
+ {
+ sal_uInt8 nTemp;
+ *pS >> nTemp;
+ fEnabled = (nTemp&0x02)>>1;
+ fLocked = (nTemp&0x04)>>2;
+ fBackStyle = (nTemp&0x08)>>3;
+ *pS >> nTemp;
+ *pS >> nTemp;
+ fWordWrap = (nTemp&0x80)>>7;
+ *pS >> nTemp;
+ fAutoSize = (nTemp&0x10)>>4;
+ }
+ bool bCaption = (pBlockFlags[0] & 0x08) != 0;
+ if (bCaption)
+ *pS >> nCaptionLen;
+
+ if (pBlockFlags[0] & 0x10)
+ {
+ *pS >> nVertPos;
+ *pS >> nHorzPos;
+ }
+
+ if (pBlockFlags[0] & 0x40)
+ *pS >> nMousePointer;
+
+ if (pBlockFlags[0] & 0x80)
+ {
+ ReadAlign(pS,pS->Tell() - nStart, 4);
+ *pS >> nBorderColor;
+ }
+
+ if (pBlockFlags[1] & 0x01)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nBorderStyle;
+ }
+
+ if (pBlockFlags[1] & 0x02)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nSpecialEffect;
+ }
+
+ if (pBlockFlags[1] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nPicture;
+ }
+
+ if (pBlockFlags[1] & 0x08)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nAccelerator;
+ }
+
+ if (pBlockFlags[1] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nIcon;
+ }
+
+ if (bCaption)
+ lclReadCharArray( *pS, pCaption, nCaptionLen, pS->Tell() - nStart);
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nWidth;
+ *pS >> nHeight;
+
+ if (nPicture)
+ {
+ pS->Read(pPictureHeader,20);
+ *pS >> nPictureLen;
+ pPicture = new sal_uInt8[nPictureLen];
+ pS->Read(pPicture,nPictureLen);
+ }
+ if (nIcon)
+ {
+ pS->Read(pIconHeader,20);
+ *pS >> nIconLen;
+ pIcon = new sal_uInt8[nIconLen];
+ pS->Read(pIcon,nIconLen);
+ }
+
+ return sal_True;
+}
+
+TypeName::TypeName(sal_Char *pName, sal_uInt32 nStoreId, sal_uInt32 nLen, sal_uInt16 nType, sal_Int32 nLeft,
+ sal_Int32 nTop)
+ : msName(lclCreateOUString(pName, nLen)), mnType(nType), mnLeft(nLeft),
+ mnTop(nTop),mnStoreId(nStoreId)
+{
+}
+
+OCX_ContainerControl::OCX_ContainerControl( SotStorageRef& parent,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const uno::Reference< container::XNameContainer > &rParent,
+ OCX_Control* pParent ) :
+ OCX_Control(sN, pParent), rbGroupMgr( sName ), mxParent(rParent), nNoRecords(0), nTotalLen(0), containerType( STDCONTAINER )
+{
+
+ mContainerStorage = parent->OpenSotStorage(storageName,
+ STREAM_READWRITE |
+ STREAM_NOCREATE |
+ STREAM_SHARE_DENYALL);
+ mContainerStream = mContainerStorage->OpenSotStream(
+ String(RTL_CONSTASCII_STRINGPARAM("f"),
+ RTL_TEXTENCODING_MS_1252),
+ STREAM_STD_READ | STREAM_NOCREATE);
+ mContainedControlsStream = mContainerStorage->OpenSotStream( String(RTL_CONSTASCII_STRINGPARAM("o"),
+ RTL_TEXTENCODING_MS_1252),
+ STREAM_STD_READ | STREAM_NOCREATE);
+}
+OCX_ContainerControl::~OCX_ContainerControl()
+{
+ CtrlIterator aEnd = mpControls.end();
+ for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
+ {
+ delete *aIter;
+ }
+}
+
+// Really import should receive the parent e.g. a Userform, Frame or Multi Page
+// and call import on its containees with itself ( up-called from
+// the base class ) but... the reality is we have no containment model
+// so we make sure rPropSet is always the parent Dialog
+
+sal_Bool OCX_ContainerControl::Import(uno::Reference<beans::XPropertySet>& /* rProps */ )
+{
+ if ( !mxParent.is() )
+ {
+ return sal_False;
+ }
+ CtrlIterator aEnd = mpControls.end();
+// int count = 0;
+ for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
+ {
+ if ( !(*aIter)->Import( mxParent ) )
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+}
+
+OUString OCX_ContainerControl::createSubStreamName( const sal_uInt32& subStorageId )
+{
+ static OUString sI = OUString::createFromAscii("i");
+ static OUString sZero = OUString::createFromAscii( "0" );
+ OUStringBuffer buf( 6 );
+ buf.append( sI );
+ // for subStorage id < 10 stream name has leading '0'
+ // eg "i07"
+ if ( subStorageId < 10 )
+ {
+ buf.append( sZero );
+ }
+ buf.append( OUString::valueOf( (sal_Int32)subStorageId ) );
+ return buf.makeStringAndClear();
+}
+
+bool OCX_ContainerControl::createFromContainerRecord( const ContainerRecord& record, OCX_Control*& pControl )
+{
+ pControl = NULL;
+ switch ( record.nTypeIdent)
+ {
+ case CMDBUTTON:
+ pControl = new OCX_CommandButton;
+ break;
+ case LABEL:
+ pControl = new OCX_UserFormLabel(this);
+ break;
+ case TEXTBOX:
+ pControl = new OCX_TextBox;
+ break;
+ case LISTBOX:
+ pControl = new OCX_ListBox;
+ break;
+ case COMBOBOX:
+ pControl = new OCX_ComboBox;
+ break;
+ case CHECKBOX:
+ pControl = new OCX_CheckBox;
+ break;
+ case OPTIONBUTTON:
+ pControl = new OCX_OptionButton;
+ break;
+ case TOGGLEBUTTON:
+ pControl = new OCX_ToggleButton;
+ break;
+ case IMAGE: //Image
+ {
+ pControl = new OCX_Image;
+ break;
+ }
+ case PAGE: // Page
+ {
+ OUString sMSStore = createSubStreamName( record.nSubStorageId );
+ pControl = new OCX_Page(mContainerStorage, sMSStore,
+ record.cName, mxParent, this);
+ break;
+ }
+ case MULTIPAGE: // MultiPage
+ {
+ OUString sMSStore = createSubStreamName( record.nSubStorageId );
+ pControl = new OCX_MultiPage( mContainerStorage, sMSStore,
+ record.cName, mxParent, this);
+ break;
+ }
+ case FRAME: //Frame
+ {
+ OUString sFrameStore = createSubStreamName( record.nSubStorageId );
+ pControl = new OCX_Frame(mContainerStorage, sFrameStore,
+ record.cName, mxParent, this);
+
+ break;
+ }
+ case SPINBUTTON: //SpinButton
+ {
+ pControl = new OCX_SpinButton;
+ break;
+ }
+ case TABSTRIP: //TabStrip
+ {
+ pControl = new OCX_TabStrip;
+ break;
+ }
+ case SCROLLBAR: //ScrollBar
+ pControl = new OCX_ScrollBar;
+ break;
+ case PROGRESSBAR: //ProgressBar Active X control
+ pControl = new OCX_ProgressBar;
+ break;
+ default:
+ OSL_TRACE( "**** Unknown control 0x%x", record.nTypeIdent );
+ DBG_ERROR( "Unknown control");
+ return false;
+ }
+ pControl->sName = record.cName;
+ return true;
+}
+
+
+void addSeperator( std::vector< OCX_Control* >& dest )
+{
+ OCX_Control* seperator = new OCX_CommandButton;
+ seperator->SetInDialog(true);
+ seperator->sName = C2S("GroupSeperator");
+ dest.push_back( seperator );
+}
+
+void addRButtons( std::vector< OCX_Control* >& src,
+ std::vector< OCX_Control* >& dest,
+ bool addGroupSeperator )
+{
+ if ( addGroupSeperator )
+ {
+ addSeperator( dest );
+ }
+
+ for ( CtrlIterator rbIter = src.begin(); rbIter != src.end(); ++rbIter )
+ {
+ dest.push_back( *rbIter );
+ }
+}
+
+void OCX_ContainerControl::ProcessControl(OCX_Control* pControl,SvStorageStream* /* pS */, ContainerRecord& rec )
+{
+ SotStorageStreamRef oStream = mContainedControlsStream;
+
+ // can insert into OO Dialog (e.g is this a supported dialog control)??
+ if ( rec.nTypeIdent == SPINBUTTON ||
+ rec.nTypeIdent == TABSTRIP)
+ {
+ // skip the record in the stream, discard the control
+ oStream->SeekRel( rec.nSubStreamLen );
+ delete pControl;
+ }
+ else
+ {
+ // A container control needs to read the f stream in
+ // the folder ( substorage ) associated with this control
+ if ( rec.nTypeIdent == FRAME ||
+ rec.nTypeIdent == MULTIPAGE||
+ rec.nTypeIdent == PAGE )
+ {
+ OCX_ContainerControl* pContainer =
+ static_cast< OCX_ContainerControl* >( pControl );
+ oStream = pContainer->getContainerStream();
+ }
+
+ pControl->sName = rec.cName;
+ pControl->msToolTip = rec.controlTip;
+ // Position of controls is relative to the container
+ pControl->mnTop = rec.nTop + mnTop;
+ pControl->mnLeft = rec.nLeft + mnLeft;
+ // MS tabIndex, pretty useless in OpenOffice land
+ // as tab indexes in MS are relative to parent container.
+ // However we need this value in order to set
+ // OpenOffice tab indices in a sensible way to
+ // reflect the ms tabbing from orig MS UserForm, see below
+ pControl->mnTabPos = rec.nTabPos;
+ pControl->SetInDialog(true);
+ pControl->mbVisible = rec.bVisible;
+ if ( mnStep )
+ {
+ // If the container has a step then it should be
+ // applied to all containees
+ pControl->mnStep = mnStep;
+ }
+
+ // #117490# DR: container records provide size of substream, use it here...
+
+ // remember initial position to set correct stream position
+ ULONG nStrmPos = oStream->Tell();
+ // import control, may return with invalid stream position
+ pControl->FullRead(oStream);
+ // set stream to position behind substream of this control
+ oStream->Seek( nStrmPos + rec.nSubStreamLen );
+
+ //need to fake grouping behaviour for radio ( option ) buttons
+ if ( rec.nTypeIdent == OPTIONBUTTON )
+ {
+ OCX_OptionButton* pRButton =
+ static_cast< OCX_OptionButton*>(pControl);
+ rbGroupMgr.addRadioButton( pRButton );
+ }
+ else
+ {
+ mpControls.push_back( pControl );
+ }
+ }
+}
+
+sal_Bool OCX_ContainerControl::Read(SvStorageStream *pS)
+{
+
+ if ( mpParent )
+ {
+ mnBackColor = mpParent->mnBackColor;
+ }
+
+ std::auto_ptr< ContainerRecReader > reader (
+ ContainerRecordReaderFac::instance( containerType ) );
+
+ reader->Read( this, pS );
+ // Need to honour the MS Tab Indexes. However MS tab indexes are
+ // relative to parent, this hack sorts the controls in each container
+ // based on the ms tab indexes. When import is called we create the
+ // controls in Open/Star office based on the order of the tab indexes,
+ // this ensures that the default tab index created by Star/Open office
+ // reflects the "flattened" ms tab order.
+ ::std::sort( mpControls.begin(), mpControls.end(), SortOrderByTabPos() );
+ mpControls = rbGroupMgr.insertGroupsIntoControlList( mpControls );
+ return true;
+}
+
+OCX_MultiPage::OCX_MultiPage( SotStorageRef& parent,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const uno::Reference< container::XNameContainer > &rDialog,
+ OCX_Control* pParent):
+ OCX_ContainerControl(parent, storageName, sN, rDialog, pParent ), fUnknown1(0), fEnabled(1),
+ fLocked(0), fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0),
+ nVertPos(1), nHorzPos(7), nMousePointer(0), nBorderColor(0x80000012),
+ nKeepScrollBarsVisible(3), nCycle(0), nBorderStyle(0), nSpecialEffect(0),
+ nPicture(0), nPictureAlignment(2), nPictureSizeMode(0),
+ bPictureTiling(FALSE), nAccelerator(0), nIcon(0), pCaption(0),
+ nScrollWidth(0), nScrollHeight(0), nIconLen(0), pIcon(0), nPictureLen(0),
+ pPicture(0)
+{
+ msDialogType = C2U("NotSupported");
+ mnForeColor = 0x80000012L,
+ mnBackColor = 0x8000000FL;
+ bSetInDialog = true;// UserForm control only
+ aFontData.SetHasAlign(TRUE);
+ containerType = MULTIPAGE;
+ mnCurrentPageStep = 0;
+}
+
+void OCX_MultiPage::ProcessControl(OCX_Control* pControl, SvStorageStream* /* pS */, ContainerRecord& rec )
+{
+ SotStorageStreamRef oStream = mContainedControlsStream;
+
+ OCX_Page *pPage = NULL;
+ if ( rec.nTypeIdent == PAGE )
+ pPage = static_cast< OCX_Page* >( pControl );
+ if ( pPage != NULL )
+ {
+ pPage->mnStep = ++mnCurrentPageStep;
+
+ pPage->mnTop = mnTop;// move these to Page::import ?
+ pPage->mnLeft = mnLeft;
+ pPage->mnBackColor = mnBackColor;
+
+ oStream = pPage->getContainerStream();;
+ // Position of controls is relative to pos of this MuliPage
+ // Control
+ pPage->FullRead( oStream );
+
+ mpControls.push_back( pPage );
+ }
+ else
+ {
+ OSL_TRACE("!!!! Unsupported Control 0x%x ", rec.nTypeIdent);
+ DBG_ERROR("MultiPage error expected Page control");
+ }
+
+}
+
+sal_Bool OCX_MultiPage::Read(SvStorageStream *pS)
+{
+ // Unlike the other containers e.g. UserForm & Frame
+ // the o stream is does not contain info for the contained controls
+ // ( e.g. the pages themselves ) but seems to be for the MultiPage
+ // itself - need to check this in more detail
+
+ // For the moment skip read of the MultiPage specific properties
+ // not much point reading these as we can't display the multi page
+ // control or in fact any sort of tabbed layout, best we can do is
+ // import just the contained controls of the individual pages
+ // Note: the record skipped below ( does not contain the expected
+ // info on this control, that seems to be contained in the o stream,
+ // see comment above)
+ OCX_Control skip(C2S("Dummy"));
+ skip.Read( pS );
+ mnCurrentPageStep = mnStep; //( set step of of pages relative to step
+ //of this MultiPage ( e.g. emulate containment )
+ return OCX_ContainerControl::Read(pS);
+}
+
+
+sal_Bool OCX_MultiPage::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ // Calls import on contained controls
+ OCX_ContainerControl::Import( rPropSet );
+ return sal_True;
+}
+
+sal_Bool OCX_MultiPage::Import(com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer>
+ &rDialog)
+{
+ uno::Reference<beans::XPropertySet> xPropSet( rDialog, uno::UNO_QUERY );
+
+ // Although MultiPage is not represeted by a "real" control we still
+ // need to propagate the backcolor of this logical parent
+ // ( the dialog or Frame or whatever ) to the children of this control.
+ // For example the controls contained in the Page of a
+ // MultiPage control use the parents backcolor ( e,g,
+ // Pages backcolor ) when trying to fake transparency
+ mnBackColor = mpParent->mnBackColor;
+
+ if ( xPropSet.is() )
+ {
+ // Calls import on contained pages
+ return OCX_ContainerControl::Import( xPropSet );
+ }
+ OSL_TRACE("*** Major problem, no dialog to add controls to ");
+ DBG_ERROR(" Major problem, no dialog to add controls to ");
+ return false;
+}
+
+
+
+OCX_Page::OCX_Page( SotStorageRef& parent,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const uno::Reference< container::XNameContainer > &rDialog,
+ OCX_Control* pParent):
+ OCX_ContainerControl(parent, storageName, sN, rDialog, pParent ),
+ fUnknown1(0), fEnabled(1), fLocked(0),
+ fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0), nVertPos(1),
+ nHorzPos(7), nMousePointer(0), nBorderColor(0x80000012),
+ nKeepScrollBarsVisible(3), nCycle(0), nBorderStyle(0), nSpecialEffect(0),
+ nPicture(0), nPictureAlignment(2), nPictureSizeMode(0),
+ bPictureTiling(FALSE), nAccelerator(0), nIcon(0), pCaption(0),
+ nScrollWidth(0), nScrollHeight(0), nIconLen(0), pIcon(0), nPictureLen(0),
+ pPicture(0)
+{
+ msDialogType = C2U("NotSupported");
+ mnForeColor = 0x80000012,
+ mnBackColor = 0x8000000F,
+ bSetInDialog = true;// UserForm control only
+ aFontData.SetHasAlign(TRUE);
+}
+
+
+sal_Bool OCX_Page::Read(SvStorageStream *pS)
+{
+ long nStart = pS->Tell();
+ *pS >> nIdentifier;
+ DBG_ASSERT(0x400==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+ pS->Read(pBlockFlags,4);
+
+ pS->SeekRel( nFixedAreaLen - sizeof( pBlockFlags ) );
+
+ ReadAlign( pS, pS->Tell() - nStart, 4);
+
+ if (pBlockFlags[2] & 0x10)
+ {
+ //Font Stuff..
+ pS->SeekRel(0x1a);
+ sal_uInt8 nFontLen;
+ *pS >> nFontLen;
+ pS->SeekRel(nFontLen);
+ }
+ return OCX_ContainerControl::Read(pS);
+
+}
+
+sal_Bool OCX_Page::Import(com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer>
+ &rDialog)
+{
+
+ uno::Reference<beans::XPropertySet> xPropSet( rDialog, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ // apply Step to contained controls
+ CtrlIterator aEnd = mpControls.end();
+ for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
+ {
+ (*aIter)->mnStep = mnStep;
+ }
+ // Calls import on contained pages
+ return OCX_ContainerControl::Import( xPropSet );
+ }
+ OSL_TRACE("*** Major problem, no dialog to add controls to ");
+ DBG_ERROR("*** Major problem, no dialog to add controls to ");
+ return sal_False;
+}
+
+OCX_Frame::OCX_Frame( SotStorageRef& parent,
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const uno::Reference< container::XNameContainer > &rDialog, OCX_Control* pParent):
+ OCX_ContainerControl(parent, storageName, sN, rDialog, pParent ),fUnknown1(0),fEnabled(1), fLocked(0),
+ fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0), nVertPos(1),
+ nHorzPos(7), nMousePointer(0), nBorderColor(0x80000012),
+ nKeepScrollBarsVisible(3), nCycle(0), nBorderStyle(0), nSpecialEffect(0),
+ nPicture(0), nPictureAlignment(2), nPictureSizeMode(0),
+ bPictureTiling(FALSE), nAccelerator(0), nIcon(0), pCaption(0),
+ nScrollWidth(0), nScrollHeight(0), nScrollLeft(0), nScrollTop(0), nIconLen(0), pIcon(0), nPictureLen(0),
+ pPicture(0)
+{
+ msDialogType = C2U("com.sun.star.awt.UnoControlGroupBoxModel");
+ mnForeColor = 0x80000012;
+ mnBackColor = 0x8000000F;
+ bSetInDialog = true;// UserForm control only
+ aFontData.SetHasAlign(TRUE);
+}
+
+
+sal_Bool OCX_Frame::Read(SvStorageStream *pS)
+{
+ long nStart = pS->Tell();
+ *pS >> nIdentifier;
+ DBG_ASSERT(0x400==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+ pS->Read(pBlockFlags,4);
+
+ if (pBlockFlags[0] & 0x01)
+ {
+ DBG_ASSERT(!this, "ARSE");
+ }
+ if (pBlockFlags[0] & 0x02)
+ *pS >> mnBackColor;
+ if (pBlockFlags[0] & 0x04)
+ *pS >> mnForeColor;
+ if (pBlockFlags[0] & 0x08)
+ *pS >> fUnknown1;
+ if (pBlockFlags[0] & 0x40)
+ {
+ sal_uInt8 nTemp;
+ *pS >> nTemp;
+ fEnabled = (nTemp&0x04)>>2;
+ fBackStyle = (nTemp&0x08)>>3;
+ *pS >> nTemp;
+ *pS >> nTemp;
+ fWordWrap = (nTemp&0x80)>>7;
+ *pS >> nTemp;
+ fAutoSize = (nTemp&0x10)>>4;
+ }
+ if (pBlockFlags[0] & 0x80)
+ {
+ *pS >> nBorderStyle;
+ }
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+
+ if (pBlockFlags[1] & 0x01)
+ *pS >> nMousePointer;
+ if (pBlockFlags[1] & 0x02)
+ *pS >> nKeepScrollBarsVisible;
+ if (pBlockFlags[1] & 0x20)
+ *pS >> fUnknown1; // another unknown 32 bit ( or is 8 or 16 bit with padding ? )
+
+ if (pBlockFlags[1] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nIcon;
+ DBG_ASSERT(nIcon == 0xFFFF, "Unexpected nIcon");
+ }
+
+ bool bCaption = false;
+
+ if (pBlockFlags[2] & 0x01)
+ *pS >> nCycle;
+ if (pBlockFlags[2] & 0x02)
+ *pS >> nSpecialEffect;
+
+ if (pBlockFlags[2] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nBorderColor;
+ }
+
+ if (pBlockFlags[2] & 0x08)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nCaptionLen;
+ bCaption = true;
+ }
+
+ if (pBlockFlags[2] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ sal_uInt16 nNoIdea;
+ *pS >> nNoIdea;
+ DBG_ASSERT(nNoIdea == 0xFFFF, "Expected 0xFFFF, (related to font ?)");
+ }
+
+ if (pBlockFlags[2] & 0x20)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nPicture;
+ DBG_ASSERT(nPicture == 0xFFFF, "Unexpected nIcon");
+ }
+
+ if (pBlockFlags[2] & 0x80)
+ *pS >> nPictureAlignment;
+
+ if (pBlockFlags[3] & 0x01)
+ bPictureTiling = true;
+
+ if (pBlockFlags[3] & 0x02)
+ *pS >> nPictureSizeMode;
+
+ if (pBlockFlags[3] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> fUnknown8;
+ }
+
+ if (pBlockFlags[3] & 0x08)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> fUnknown9;
+ }
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nWidth;
+ *pS >> nHeight;
+ *pS >> nScrollWidth;
+ *pS >> nScrollHeight;
+
+ if (pBlockFlags[1] & 0x10)
+ {
+ *pS >> nScrollLeft;
+ *pS >> nScrollTop;
+ }
+
+ if ( bCaption )
+ {
+ lclReadCharArray( *pS, pCaption, nCaptionLen, pS->Tell() - nStart);
+ }
+
+ OUString tempCaption = lclCreateOUString( pCaption, nCaptionLen );
+
+ if (nIcon)
+ {
+ pS->Read(pIconHeader,20);
+ *pS >> nIconLen;
+ pIcon = new sal_uInt8[nIconLen];
+ pS->Read(pIcon,nIconLen);
+ }
+
+ if (nPicture)
+ {
+ pS->Read(pPictureHeader,20);
+ *pS >> nPictureLen;
+ pPicture = new sal_uInt8[nPictureLen];
+ pS->Read(pPicture,nPictureLen);
+ }
+
+ ReadAlign( pS, pS->Tell() - nStart, 4);
+
+ if (pBlockFlags[2] & 0x10)
+ {
+ //Font Stuff..
+ pS->SeekRel(0x1a);
+ sal_uInt8 nFontLen;
+ *pS >> nFontLen;
+ pS->SeekRel(nFontLen);
+ }
+
+ return OCX_ContainerControl::Read( pS );
+}
+
+sal_Bool OCX_Frame::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), aTmp);
+ if ( pCaption )
+ {
+ aTmp <<= lclCreateOUString( pCaption, nCaptionLen );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Label"), aTmp);
+ }
+
+ // Calls import on contained controls
+ OCX_ContainerControl::Import( rPropSet );
+ return sal_True;
+}
+OCX_UserForm::OCX_UserForm( SotStorageRef& parent,
+ const OUString& storageName,
+ const OUString& sN,
+ const ::uno::Reference< container::XNameContainer > &rDialog,
+ const ::uno::Reference< lang::XMultiServiceFactory >& rMsf):
+ OCX_ContainerControl(parent, storageName, sN, rDialog),
+ nChildrenA(0), fEnabled(1), fLocked(0),
+ fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0), nVertPos(1),
+ nHorzPos(7), nMousePointer(0), nBorderColor(0x80000012), nChildrenB(0),
+ nKeepScrollBarsVisible(3), nCycle(0), nBorderStyle(0), nSpecialEffect(0),
+ nPicture(0), nPictureAlignment(2), nPictureSizeMode(0),
+ bPictureTiling(FALSE), nAccelerator(0), nIcon(0), pCaption(0),
+ nScrollWidth(0), nScrollHeight(0), nScrollLeft(0), nScrollTop(0), nIconLen(0), pIcon(0), nPictureLen(0),
+ pPicture(0)
+ {
+ mnForeColor = 0x80000012;
+ mnBackColor = 0x8000000F;
+ uno::Reference< beans::XPropertySet> xProps( rMsf, uno::UNO_QUERY);
+ if ( xProps.is() )
+ {
+ xProps->getPropertyValue(C2S("DefaultContext")) >>= mxCtx;
+ }
+ aFontData.SetHasAlign(TRUE);
+ }
+sal_Bool OCX_UserForm::Read(SvStorageStream *pS)
+{
+ long nStart = pS->Tell();
+ *pS >> nIdentifier;
+ DBG_ASSERT(0x400==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+ pS->Read(pBlockFlags,4);
+
+ if (pBlockFlags[0] & 0x01)
+ {
+ DBG_ASSERT(!this, "ARSE");
+ }
+ if (pBlockFlags[0] & 0x02)
+ *pS >> mnBackColor;
+ if (pBlockFlags[0] & 0x04)
+ *pS >> mnForeColor;
+ if (pBlockFlags[0] & 0x08)
+ *pS >> nChildrenA;
+ if (pBlockFlags[0] & 0x40)
+ {
+ sal_uInt8 nTemp;
+ *pS >> nTemp;
+ fEnabled = (nTemp&0x04)>>2;
+ fBackStyle = (nTemp&0x08)>>3;
+ *pS >> nTemp;
+ *pS >> nTemp;
+ fWordWrap = (nTemp&0x80)>>7;
+ *pS >> nTemp;
+ fAutoSize = (nTemp&0x10)>>4;
+ }
+ if (pBlockFlags[0] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nBorderStyle;
+ }
+#if 0
+ sal_uInt16 nFixedOrAlign;
+ *pS >> nFixedOrAlign;
+#endif
+ if (pBlockFlags[1] & 0x01)
+ *pS >> nMousePointer;
+ if (pBlockFlags[1] & 0x02)
+ *pS >> nKeepScrollBarsVisible;
+ if (pBlockFlags[1] & 0x20)
+ {
+ sal_uInt32 nUnknown32;
+ *pS >> nUnknown32;
+ }
+ if (pBlockFlags[1] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nIcon;
+ DBG_ASSERT(nIcon == 0xFFFF, "Unexpected nIcon");
+ }
+ if (pBlockFlags[2] & 0x01)
+ *pS >> nCycle;
+ if (pBlockFlags[2] & 0x02)
+ *pS >> nSpecialEffect;
+
+ if (pBlockFlags[2] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nBorderColor;
+ }
+
+ if (pBlockFlags[2] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ sal_uInt16 nNoIdea;
+ *pS >> nNoIdea;
+ DBG_ASSERT(nNoIdea == 0xFFFF, "Expected 0xFFFF, (related to font ?)");
+ }
+
+ if (pBlockFlags[2] & 0x20)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nPicture;
+ DBG_ASSERT(nPicture == 0xFFFF, "Unexpected nIcon");
+ }
+
+ if (pBlockFlags[2] & 0x80)
+ *pS >> nPictureAlignment;
+
+ if (pBlockFlags[3] & 0x01)
+ bPictureTiling = true;
+
+ if (pBlockFlags[3] & 0x02)
+ *pS >> nPictureSizeMode;
+
+ if (pBlockFlags[3] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nChildrenB;
+ }
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nDrawBuffer;
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nWidth;
+ *pS >> nHeight;
+ *pS >> nScrollWidth;
+ *pS >> nScrollHeight;
+
+ if (pBlockFlags[1] & 0x10)
+ {
+ *pS >> nScrollLeft;
+ *pS >> nScrollTop;
+ }
+
+ if (nIcon)
+ {
+ pS->Read(pIconHeader,20);
+ *pS >> nIconLen;
+ pIcon = new sal_uInt8[nIconLen];
+ pS->Read(pIcon,nIconLen);
+ }
+
+ if (nPicture)
+ {
+ pS->Read(pPictureHeader,20);
+ *pS >> nPictureLen;
+ pPicture = new sal_uInt8[nPictureLen];
+ pS->Read(pPicture,nPictureLen);
+ }
+
+ ReadAlign( pS, pS->Tell() - nStart, 4);
+
+ if (pBlockFlags[2] & 0x10)
+ {
+ //Font Stuff..
+ pS->SeekRel(0x1a);
+ sal_uInt8 nFontLen;
+ *pS >> nFontLen;
+ pS->SeekRel(nFontLen);
+ }
+
+ sal_Int16 numTrailingRecs = 0;
+ *pS >> numTrailingRecs;
+ // seems to be no. of trailing records,
+ // before container record starts proper
+ // ( unknown what these trailing records are for)
+ if ( numTrailingRecs )
+ {
+ for ( ; numTrailingRecs ; --numTrailingRecs )
+ {
+ OCX_Control skip(C2S("dummy")) ;
+ skip.Read( pS );
+ }
+ }
+ return OCX_ContainerControl::Read( pS );
+}
+
+sal_Bool OCX_UserForm::Import(
+ uno::Reference<container::XNameContainer> &rLib )
+{
+ uno::Reference<beans::XPropertySet>
+ xDialogPropSet(mxParent, uno::UNO_QUERY);
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ xDialogPropSet->setPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), aTmp);
+ xDialogPropSet->setPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Title")), aTmp);
+ aTmp <<= ImportColor(mnBackColor);
+ xDialogPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ aTmp <<= sal_Int32((nWidth * 2) / 100);
+ xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Width"), aTmp);
+ aTmp <<= sal_Int32((nHeight * 2) / 100);
+ xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
+
+ uno::Reference<beans::XPropertySet> xPropSet( mxParent, uno::UNO_QUERY );
+ OCX_ContainerControl::Import( xPropSet );
+
+ uno::Reference<io::XInputStreamProvider> xSource =
+ xmlscript::exportDialogModel(mxParent, mxCtx);
+ uno::Any aSourceAny(uno::makeAny(xSource));
+ if (rLib->hasByName(sName))
+ rLib->replaceByName(sName, aSourceAny);
+ else
+ rLib->insertByName(sName, aSourceAny);
+ return sal_True;
+}
+
+sal_Bool OCX_Label::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet = sal_True;
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(8);
+ pBlockFlags[0] = 0x20;
+ pBlockFlags[1] = 0;
+ pBlockFlags[2] = 0;
+ pBlockFlags[3] = 0;
+
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+ pBlockFlags[0] |= 0x01;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+ sal_uInt8 nTemp=fEnabled;
+ if (fEnabled)
+ nTemp = nTemp << 1;
+ *rContents << nTemp;
+ *rContents << sal_uInt8(0x00);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("MultiLine"));
+ fWordWrap = any2bool(aTmp);
+ nTemp=fWordWrap;
+ nTemp = nTemp << 7;
+ *rContents << nTemp;
+ *rContents << sal_uInt8(0x00);
+ pBlockFlags[0] |= 0x04;
+
+ SvxOcxString aCaption( rPropSet->getPropertyValue(WW8_ASCII2STR("Label")) );
+ aCaption.WriteLenField( *rContents );
+ if (aCaption.HasData())
+ pBlockFlags[0] |= 0x08;
+
+ WriteAlign(rContents,4);
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BorderColor"));
+ if (aTmp.hasValue())
+ aTmp >>= nBorderColor;
+ *rContents << ExportColor(nBorderColor);
+ pBlockFlags[0] |= 0x80;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Border"));
+ sal_Int16 nBorder = sal_Int16();
+ aTmp >>= nBorder;
+ sal_uInt8 nNewBorder;
+ nSpecialEffect = ExportBorder(nBorder,nNewBorder);
+ nBorderStyle = nNewBorder;
+ *rContents << nBorderStyle;
+ pBlockFlags[1] |= 0x01;
+ *rContents << nSpecialEffect;
+ pBlockFlags[1] |= 0x02;
+
+ aCaption.WriteCharArray( *rContents );
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+
+ bRet = aFontData.Export(rContents,rPropSet);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+
+
+sal_Bool OCX_Label::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x23, 0x9E, 0x8C, 0x97,
+ 0xB0, 0xD4, 0xCE, 0x11, 0xBF, 0x2D, 0x00, 0xAA,
+ 0x00, 0x3F, 0x40, 0xD0, 0x1A, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x4C, 0x61, 0x62, 0x65,
+ 0x6C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x45, 0x6D,
+ 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x4F,
+ 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00, 0x0E, 0x00,
+ 0x00, 0x00, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x2E,
+ 0x4C, 0x61, 0x62, 0x65, 0x6C, 0x2E, 0x31, 0x00,
+ 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x4C, 0x00, 0x61, 0x00, 0x62, 0x00, 0x65, 0x00,
+ 0x6C, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+/*
+ static sal_uInt8 __READONLY_DATA aTest[] = {
+ 0x00, 0x02, 0x20, 0x00, 0x2B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
+ 0x06, 0x00, 0x00, 0x80, 0x4C, 0x61, 0x62, 0x65,
+ 0x6C, 0x31, 0x18, 0x00, 0xEC, 0x09, 0x00, 0x00,
+ 0x7B, 0x02, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00,
+ 0x35, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x80,
+ 0xC3, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x54, 0x69, 0x6D, 0x65, 0x73, 0x20, 0x4E, 0x65,
+ 0x77, 0x20, 0x52, 0x6F, 0x6D, 0x61, 0x6E, 0x00,
+ };
+*/
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+typedef OCX_Control *(*FNCreate)();
+
+
+struct OCX_map
+{
+ FNCreate pCreate;
+ const char *sId;
+ sal_Int16 nId;
+ const char *sName;
+};
+
+OCX_map aOCXTab[] =
+{
+ // Command button MUST be at index 0
+ {&OCX_CommandButton::Create,"D7053240-CE69-11CD-a777-00dd01143c57",
+ form::FormComponentType::COMMANDBUTTON,"CommandButton"},
+ // Toggle button MUST be at index 1
+ {&OCX_ToggleButton::Create,"8BD21D60-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::COMMANDBUTTON,"ToggleButton"},
+ {&OCX_Label::Create, "978C9E23-D4B0-11CE-bf2d-00aa003f40d0",
+ form::FormComponentType::FIXEDTEXT,"Label"},
+ {&OCX_TextBox::Create,"8BD21D10-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::TEXTFIELD,"TextBox"},
+ {&OCX_ListBox::Create,"8BD21D20-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::LISTBOX,"ListBox"},
+ {&OCX_ComboBox::Create,"8BD21D30-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::COMBOBOX,"ComboBox"},
+ {&OCX_CheckBox::Create,"8BD21D40-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::CHECKBOX,"CheckBox"},
+ {&OCX_OptionButton::Create,"8BD21D50-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::RADIOBUTTON,"OptionButton"},
+ {&OCX_Image::Create,"4C599241-6926-101B-9992-00000b65c6f9",
+ form::FormComponentType::IMAGECONTROL,"Image"},
+ {&OCX_FieldControl::Create,"8BD21D10-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::DATEFIELD,"TextBox"},
+ {&OCX_FieldControl::Create,"8BD21D10-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::TIMEFIELD,"TextBox"},
+ {&OCX_FieldControl::Create,"8BD21D10-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::NUMERICFIELD,"TextBox"},
+ {&OCX_FieldControl::Create,"8BD21D10-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::CURRENCYFIELD,"TextBox"},
+ {&OCX_FieldControl::Create,"8BD21D10-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::PATTERNFIELD,"TextBox"},
+#if 0
+ {&OCX_FieldControl::Create,"8BD21D10-EC42-11CE-9e0d-00aa006002f3",
+ form::FormComponentType::FORMULAFIELD,"TextBox"},
+#endif
+ {&OCX_ImageButton::Create,"D7053240-CE69-11CD-a777-00dd01143c57",
+ form::FormComponentType::IMAGEBUTTON,"CommandButton"},
+ {&OCX_SpinButton::Create,"79176FB0-B7F2-11CE-97ef-00aa006d2776",
+ form::FormComponentType::SPINBUTTON,"SpinButton"},
+ {&OCX_ScrollBar::Create,"DFD181E0-5E2F-11CE-a449-00aa004a803d",
+ form::FormComponentType::SCROLLBAR,"ScrollBar"},
+ {&OCX_GroupBox::Create,"",
+ form::FormComponentType::GROUPBOX,""},
+ {&OCX_ProgressBar::Create,"",
+ form::FormComponentType::CONTROL,""}
+};
+
+const int NO_OCX = sizeof( aOCXTab ) / sizeof( *aOCXTab );
+
+SvxMSConvertOCXControls::SvxMSConvertOCXControls(SfxObjectShell *pDSh, SwPaM *pP) :
+ pDocSh(pDSh), pPaM(pP), nEdit(0), nCheckbox(0)
+{
+ DBG_ASSERT( pDocSh, "No DocShell, Cannot do Controls" );
+ OCX_Control::FillSystemColors();
+}
+
+SvxMSConvertOCXControls::~SvxMSConvertOCXControls()
+{
+}
+
+OCX_Control * SvxMSConvertOCXControls::OCX_Factory(const String &sName)
+{
+ for (int i=0;i<NO_OCX;i++)
+ {
+ if ( sName.EqualsIgnoreCaseAscii( aOCXTab[i].sId ))
+ return(aOCXTab[i].pCreate());
+ }
+ return(NULL);
+}
+
+OCX_Control * SvxMSConvertOCXControls::OCX_Factory(
+ const uno::Reference< awt::XControlModel > &rControlModel,
+ String &rId, String &rName)
+{
+ rName.Erase();
+ rId.Erase();
+
+ uno::Reference< beans::XPropertySet > xPropSet(
+ rControlModel,uno::UNO_QUERY);
+
+ uno::Any aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii("ClassId"));
+ sal_Int16 nClassId = *(sal_Int16*) aTmp.getValue();
+
+//Begin nasty hack
+ /*
+ There is a truly horrible thing with EditControls and FormattedField
+ Controls, they both pretend to have an EDITBOX ClassId for compability
+ reasons, at some stage in the future hopefully there will be a proper
+ FormulaField ClassId rather than this piggybacking two controls onto the
+ same ClassId, when this happens uncomment the FORMULAFIELD in the OCX_Tab
+ and delete this block, cmc.
+
+ And also the nClassId for ImageControls is being reported as "CONTROL"
+ rather than IMAGECONTROL
+ */
+ if (nClassId == form::FormComponentType::TEXTFIELD)
+ {
+ uno::Reference< lang::XServiceInfo > xInfo(rControlModel,
+ uno::UNO_QUERY);
+ if (xInfo->
+ supportsService(OUString::createFromAscii(
+ "com.sun.star.form.component.FormattedField")))
+ {
+ rId.AppendAscii("8BD21D10-EC42-11CE-9e0d-00aa006002f3");
+ rName.AppendAscii("TextBox");
+ return new OCX_FieldControl;
+ }
+ }
+ else if (nClassId == form::FormComponentType::CONTROL)
+ {
+ uno::Reference< lang::XServiceInfo > xInfo(rControlModel,
+ uno::UNO_QUERY);
+ if (xInfo->
+ supportsService(OUString::createFromAscii(
+ "com.sun.star.form.component.ImageControl")))
+ nClassId = form::FormComponentType::IMAGECONTROL;
+ }
+//End nasty hack
+
+ const OCX_map* pEntry = 0;
+
+ // distinguish between push button and toggle button
+ if( nClassId == form::FormComponentType::COMMANDBUTTON )
+ {
+ pEntry = any2bool(xPropSet->getPropertyValue(WW8_ASCII2STR("Toggle"))) ?
+ (aOCXTab + 1) : aOCXTab;
+ }
+ else
+ {
+ for( int i = 2; (i < NO_OCX) && !pEntry; ++i )
+ if( nClassId == aOCXTab[ i ].nId )
+ pEntry = aOCXTab + i;
+ }
+
+ if( pEntry )
+ {
+ rId.AppendAscii( pEntry->sId );
+ rName.AppendAscii( pEntry->sName );
+ return pEntry->pCreate();
+ }
+
+ return 0;
+}
+
+
+sal_Bool SvxMSConvertOCXControls::ReadOCXStream( SvStorageRef& rSrc1,
+ uno::Reference < drawing::XShape > *pShapeRef,BOOL bFloatingCtrl)
+{
+
+ SvStorageStreamRef xCrash = rSrc1->OpenSotStream( WW8_ASCII2STR("contents") );
+ sal_Bool bRet=sal_False;
+
+ SvStorageStreamRef xSrc2 = rSrc1->OpenSotStream( WW8_ASCII2STR("\3OCXNAME") );
+ SvStorageStream* pSt = xSrc2;
+ pSt->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ /* #117832# import control name */
+ OUString controlName;
+ bool hasCName = readOCXNAME( controlName, pSt );
+
+ xSrc2 = rSrc1->OpenSotStream( WW8_ASCII2STR("contents") );
+ pSt = xSrc2;
+ pSt->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ /*Get Class Id of this object, see if it is one of the types
+ *that this importer can handle, call the appropiate handler
+ to read that control, and call the appropiate handler to
+ insert that control
+ */
+
+ SvGlobalName aTest = rSrc1->GetClassName();
+ OCX_Control *pObj = OCX_Factory(aTest.GetHexName());
+ if (pObj)
+ {
+ pObj->pDocSh = pDocSh;
+ /* #117832# set imported control name */
+ if ( hasCName )
+ {
+ pObj->sName = controlName;
+ }
+ com::sun::star::awt::Size aSz;
+ uno::Reference< form::XFormComponent > xFComp;
+ const uno::Reference< lang::XMultiServiceFactory > & rServiceFactory =
+ GetServiceFactory();
+ if(!rServiceFactory.is())
+ return(sal_False);
+ bRet = pObj->FullRead(pSt);
+ if(bRet)
+ if (pObj->Import(rServiceFactory,xFComp,aSz))
+ bRet = InsertControl( xFComp, aSz,pShapeRef,bFloatingCtrl);
+ delete pObj;
+ }
+ return bRet;
+}
+
+
+sal_Bool SvxMSConvertOCXControls::ReadOCXExcelKludgeStream(
+ SvStorageStreamRef& rSrc1, uno::Reference < drawing::XShape > *
+ pShapeRef,BOOL bFloatingCtrl)
+{
+ sal_Bool bRet=sal_False;
+ /*Get Class Id of this object, see if it is one of the types
+ *that this importer can handle, call the appropiate handler
+ to read that control, and call the appropiate handler to
+ insert that control
+ */
+ /*The Excel Kludge is to concatenate a class id with a contents
+ * stream, and then concatenate all the controls together,
+ * This means that you should have the cnts stream wound to the
+ * correct location before passing the control stream in here*/
+ SvStream *pSt = rSrc1;
+ pSt->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ SvGlobalName aTest;
+ *pSt >> aTest;
+ OCX_Control *pObj = OCX_Factory(aTest.GetHexName());
+ if (pObj)
+ {
+
+ com::sun::star::awt::Size aSz;
+ uno::Reference< form::XFormComponent > xFComp;
+ const uno::Reference< lang::XMultiServiceFactory > & rServiceFactory =
+ GetServiceFactory();
+ if(!rServiceFactory.is())
+ return(sal_False);
+ bRet = pObj->FullRead(rSrc1);
+ if(bRet)
+ if (pObj->Import(rServiceFactory,xFComp,aSz))
+ bRet = InsertControl( xFComp, aSz,pShapeRef,bFloatingCtrl);
+ delete pObj;
+ }
+ return bRet;
+}
+
+
+sal_Bool SvxMSConvertOCXControls::WriteOCXStream( SvStorageRef& rSrc1,
+ const uno::Reference< awt::XControlModel > &rControlModel,
+ const awt::Size &rSize, String &rName)
+{
+ sal_Bool bRet=sal_False;
+
+ DBG_ASSERT( rControlModel.is(), "UNO-Control missing Model, panic!" );
+ if( !rControlModel.is() )
+ return sal_False;
+
+#if 0
+ uno::Any aTmp = xPropSet->getPropertyValue(
+ OUString::createFromAscii("ClassId"));
+ sal_Int16 nClassId = *(sal_Int16*) aTmp.getValue();
+#endif
+
+ String sId;
+ OCX_Control *pObj = OCX_Factory(rControlModel,sId,rName);
+ if (pObj != NULL)
+ {
+ uno::Reference<beans::XPropertySet> xPropSet(rControlModel,
+ uno::UNO_QUERY);
+
+ /* #117832# - also enable export of control name */
+ OUString sCName;
+ xPropSet->getPropertyValue(C2S("Name")) >>= sCName;
+ pObj->sName = sCName;
+
+ SvGlobalName aName;
+ aName.MakeId(sId);
+ String sFullName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(
+ "Microsoft Forms 2.0 ")));
+ sFullName.Append(rName);
+ rSrc1->SetClass(aName,0x5C,sFullName);
+ // ^^^^, this pathetic 0x5c is the magic number
+ // which the lack of originally blocked the implementation of
+ // the controls export
+ // cmc
+
+ bRet = pObj->Export(rSrc1,xPropSet,rSize);
+ SvStorageStreamRef xStor2( rSrc1->OpenSotStream( WW8_ASCII2STR("\3OCXNAME")));
+ /* #117832# - also enable export of control name */
+ writeOCXNAME( sCName, xStor2 );
+ delete pObj;
+ }
+ return bRet;
+}
+
+
+//I think this should work for excel documents, create the "Ctls" stream
+//and give it here as rContents, we'll append out streams ole id and
+//contents here and that appears to be what Excel is doing
+sal_Bool SvxMSConvertOCXControls::WriteOCXExcelKludgeStream(
+ SvStorageStreamRef& rContents,
+ const uno::Reference< awt::XControlModel > &rControlModel,
+ const awt::Size &rSize, String &rName)
+{
+ sal_Bool bRet=sal_False;
+
+ DBG_ASSERT( rControlModel.is(), "UNO-Control missing Model, panic!" );
+ if( !rControlModel.is() )
+ return sal_False;
+
+ String sId;
+ OCX_Control *pObj = OCX_Factory(rControlModel,sId,rName);
+ if (pObj != NULL)
+ {
+ uno::Reference<beans::XPropertySet> xPropSet(rControlModel,
+ uno::UNO_QUERY);
+
+ SvGlobalName aName;
+ aName.MakeId(sId);
+ String sFullName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(
+ "Microsoft Forms 2.0 ")));
+ sFullName.Append(rName);
+ SvStream *pS=rContents;
+ *pS << aName;
+ bRet = pObj->WriteContents(rContents,xPropSet,rSize);
+ delete pObj;
+ // export needs correct stream position
+ rContents->Seek( STREAM_SEEK_TO_END );
+ }
+ return bRet;
+}
+
+
+
+
+
+
+
+sal_Bool OCX_CheckBox::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ // background color: fBackStyle==0 -> transparent
+ if( fBackStyle )
+ aTmp <<= ImportColor(mnBackColor);
+ else
+ aTmp = uno::Any();
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ sal_Bool bTemp;
+ if ((!(fEnabled)) || (fLocked))
+ bTemp = sal_False;
+ else
+ bTemp = sal_True;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ bTemp = fWordWrap != 0;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MultiLine"), aTmp);
+
+ aTmp <<= ImportColor(mnForeColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TextColor"), aTmp);
+
+ bTemp = nMultiState;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("TriState"), aTmp);
+
+ aTmp <<= ImportSpecEffect( nSpecialEffect );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("VisualEffect"), aTmp);
+
+ if (pValue && !bSetInDialog)
+ {
+ INT16 nTmp=pValue[0]-0x30;
+ aTmp <<= nTmp;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultState"), aTmp);
+ }
+
+ if (pCaption)
+ {
+ aTmp <<= lclCreateOUString( pCaption, nCaptionLen );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Label"), aTmp);
+ }
+
+ // #i40279# always centered vertically
+ aTmp <<= ::com::sun::star::style::VerticalAlignment_MIDDLE;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("VerticalAlign"), aTmp );
+
+ aFontData.Import(rPropSet);
+ return(sal_True);
+}
+
+sal_Bool OCX_CheckBox::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+
+{
+ sal_Bool bRet=sal_True;
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(12);
+
+ pBlockFlags[0] = 0;
+ pBlockFlags[1] = 0x01;
+ pBlockFlags[2] = 0;
+ pBlockFlags[3] = 0x80;
+ pBlockFlags[4] = 0;
+ pBlockFlags[5] = 0;
+ pBlockFlags[6] = 0;
+ pBlockFlags[7] = 0;
+
+ uno::Any aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("BackgroundColor"));
+ fBackStyle = aTmp.hasValue() ? 1 : 0;
+ if (fBackStyle)
+ aTmp >>= mnBackColor;
+
+ sal_uInt8 nTemp=fEnabled;
+ if (fEnabled)
+ nTemp = nTemp << 1;
+ if (fBackStyle)
+ nTemp |= 0x08;
+ *rContents << nTemp;
+ pBlockFlags[0] |= 0x01;
+ *rContents << sal_uInt8(0x00);
+ nTemp = 0;
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("MultiLine"));
+ fWordWrap = any2bool(aTmp);
+ if (fWordWrap)
+ nTemp |= 0x80;
+ *rContents << nTemp;
+ *rContents << sal_uInt8(0x00);
+
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x02;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TextColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnForeColor;
+ *rContents << ExportColor(mnForeColor);
+ pBlockFlags[0] |= 0x04;
+
+ nStyle = 4;
+ *rContents << nStyle;
+ pBlockFlags[0] |= 0x40;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("TriState"));
+ nMultiState = any2bool(aTmp);
+ *rContents << nMultiState;
+ pBlockFlags[2] |= 0x20;
+
+ WriteAlign(rContents,4);
+ nValueLen = 1|SVX_MSOCX_COMPRESSED;
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("DefaultState"));
+ sal_Int16 nDefault = sal_Int16();
+ aTmp >>= nDefault;
+ *rContents << nValueLen;
+ pBlockFlags[2] |= 0x40;
+
+ SvxOcxString aCaption( rPropSet->getPropertyValue(WW8_ASCII2STR("Label")) );
+ aCaption.WriteLenField( *rContents );
+ if (aCaption.HasData())
+ pBlockFlags[2] |= 0x80;
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("VisualEffect"));
+ if (aTmp.hasValue())
+ {
+ sal_Int16 nApiSpecEffect = sal_Int16();
+ aTmp >>= nApiSpecEffect;
+ nSpecialEffect = ExportSpecEffect( nApiSpecEffect );
+ }
+ WriteAlign(rContents,4);
+ *rContents << nSpecialEffect;
+ pBlockFlags[3] |= 0x04;
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+ nDefault += 0x30;
+ *rContents << sal_uInt8(nDefault);
+ *rContents << sal_uInt8(0x00);
+
+ aCaption.WriteCharArray( *rContents );
+
+ WriteAlign(rContents,4);
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+ bRet = aFontData.Export(rContents,rPropSet);
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+ *rContents << pBlockFlags[4];
+ *rContents << pBlockFlags[5];
+ *rContents << pBlockFlags[6];
+ *rContents << pBlockFlags[7];
+
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+
+sal_Bool OCX_CheckBox::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x1D, 0xD2, 0x8B,
+ 0x42, 0xEC, 0xCE, 0x11, 0x9E, 0x0D, 0x00, 0xAA,
+ 0x00, 0x60, 0x02, 0xF3, 0x1D, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x43, 0x68, 0x65, 0x63,
+ 0x6B, 0x42, 0x6F, 0x78, 0x00, 0x10, 0x00, 0x00,
+ 0x00, 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65,
+ 0x64, 0x20, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74,
+ 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x6F, 0x72,
+ 0x6D, 0x73, 0x2E, 0x43, 0x68, 0x65, 0x63, 0x6B,
+ 0x42, 0x6F, 0x78, 0x2E, 0x31, 0x00, 0xF4, 0x39,
+ 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x43, 0x00, 0x68, 0x00, 0x65, 0x00, 0x63, 0x00,
+ 0x6B, 0x00, 0x42, 0x00, 0x6F, 0x00, 0x78, 0x00,
+ 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+/*
+ static sal_uInt8 __READONLY_DATA aTest[] = {
+ 0x00, 0x02, 0x34, 0x00, 0x46, 0x01, 0xC0, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x80,
+ 0xE2, 0x0E, 0x00, 0x00, 0x95, 0x02, 0x00, 0x00,
+ 0x30, 0x69, 0x1D, 0x00, 0x43, 0x68, 0x65, 0x63,
+ 0x6B, 0x42, 0x6F, 0x78, 0x31, 0x20, 0x52, 0x6F,
+ 0x00, 0x02, 0x20, 0x00, 0x35, 0x00, 0x00, 0x00,
+ 0x0F, 0x00, 0x00, 0x80, 0xC3, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x54, 0x69, 0x6D, 0x65,
+ 0x73, 0x20, 0x4E, 0x65, 0x77, 0x20, 0x52, 0x6F,
+ 0x6D, 0x61, 0x6E, 0x00,
+ };
+*/
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+
+sal_Bool OCX_FontData::Read(SvStorageStream *pS)
+{
+ long nStart = pS->Tell();
+ *pS >> nIdentifier;
+ *pS >> nFixedAreaLen;
+ pS->Read(pBlockFlags,4);
+
+ bool bFontName = (pBlockFlags[0] & 0x01) != 0;
+ if (bFontName)
+ *pS >> nFontNameLen;
+ if (pBlockFlags[0] & 0x02)
+ {
+ sal_uInt8 nTmp;
+ *pS >> nTmp;
+ fBold = nTmp & 0x01;
+ fItalic = (nTmp & 0x02) >> 1;
+ fUnderline = (nTmp & 0x04) >> 2;
+ fStrike = (nTmp & 0x08) >> 3;
+ fUnknown1 = (nTmp & 0xF0) >> 4;
+ *pS >> nUnknown2;
+ *pS >> nUnknown3;
+ *pS >> nUnknown4;
+ }
+ if (pBlockFlags[0] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nFontSize;
+ }
+ else
+ nFontSize = 240;
+ if (pBlockFlags[0] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nLanguageID;
+ }
+ if (pBlockFlags[0] & 0x40)
+ {
+ *pS >> nJustification;
+ }
+ if (pBlockFlags[0] & 0x80) // font weight before font name
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nFontWeight;
+ }
+
+ if (bFontName)
+ lclReadCharArray( *pS, pFontName, nFontNameLen, pS->Tell() - nStart);
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ return(TRUE);
+}
+
+void OCX_FontData::Import(uno::Reference< beans::XPropertySet > &rPropSet)
+{
+ uno::Any aTmp;
+ if (pFontName)
+ {
+ aTmp <<= lclCreateOUString( pFontName, nFontNameLen );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("FontName"), aTmp);
+ }
+
+ if (bHasAlign)
+ {
+ sal_Int16 nAlign = ImportAlign(nJustification);
+ aTmp <<= nAlign;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Align"), aTmp);
+ }
+
+ if (fBold)
+ {
+ aTmp <<= awt::FontWeight::BOLD;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("FontWeight"), aTmp);
+ }
+
+ if (fItalic)
+ {
+ aTmp <<= (sal_Int16)awt::FontSlant_ITALIC;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("FontSlant"), aTmp);
+ }
+
+ if (fUnderline)
+ {
+ aTmp <<= awt::FontUnderline::SINGLE;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("FontUnderline"), aTmp);
+ }
+
+ if (fStrike)
+ {
+ aTmp <<= awt::FontStrikeout::SINGLE;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("FontStrikeout"), aTmp);
+ }
+
+ // 2004-09-17: very strange way of storing font sizes...
+ // 1pt->30, 2pt->45, 3pt->60, 4pt->75, 5pt->105, 6pt->120, 7pt->135
+ // 8pt->165, 9pt->180, 10pt->195, 11pt->225, ...
+ aTmp <<= sal_Int16( (nFontSize <= 30) ? 1 : ((nFontSize + 10) / 20) );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("FontHeight"), aTmp);
+}
+
+sal_Bool OCX_FontData::Export(SvStorageStreamRef &rContent,
+ const uno::Reference< beans::XPropertySet > &rPropSet)
+{
+ sal_uInt8 nFlags=0x00;
+ sal_uInt32 nOldPos = rContent->Tell();
+ rContent->SeekRel(8);
+ SvxOcxString aFontName;
+ uno::Any aTmp;
+
+ if (bHasFont)
+ aFontName = rPropSet->getPropertyValue(WW8_ASCII2STR("FontName"));
+ if (!aFontName.HasData())
+ aFontName = OUString( RTL_CONSTASCII_USTRINGPARAM( "Times New Roman" ) );
+ aFontName.WriteLenField( *rContent );
+ nFlags |= 0x01;
+
+ if (bHasFont)
+ {
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("FontWeight"));
+ float nBold = 0;
+ aTmp >>= nBold;
+
+ if (nBold >= 150)
+ {
+ nFlags |= 0x02;
+ sal_uInt8 nTmp=0x01;
+ *rContent << nTmp;
+ nTmp=0x00;
+ *rContent << nTmp;
+ *rContent << nTmp;
+ *rContent << nTmp;
+ }
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("FontHeight"));
+ float nFontHeight = 0;
+ aTmp >>= nFontHeight;
+ if (nFontHeight)
+ {
+ nFlags |= 0x04;
+ // 2004-09-17: very strange way of storing font sizes:
+ // 1pt->30, 2pt->45, 3pt->60, 4pt->75, 5pt->105, 6pt->120, 7pt->135
+ // 8pt->165, 9pt->180, 10pt->195, 11pt->225, ...
+ nFontSize = (nFontHeight == 1) ? 30 : (static_cast<sal_uInt32>((nFontHeight*4+1)/3)*15);
+ *rContent << nFontSize;
+ }
+
+ if (bHasAlign)
+ {
+ *rContent << sal_uInt16(0x0200);
+ nFlags |= 0x10;
+
+ nFlags |= 0x20; // ?
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Align"));
+ nFlags |= 0x40;
+ sal_Int16 nAlign(0);
+ if (aTmp.hasValue())
+ aTmp >>= nAlign;
+ nJustification = ExportAlign(nAlign);
+ *rContent << nJustification;
+ }
+ }
+
+ aFontName.WriteCharArray( *rContent );
+ WriteAlign(rContent,4);
+
+ sal_uInt16 nFixedAreaLn = static_cast<sal_uInt16>(rContent->Tell()-nOldPos-4);
+ rContent->Seek(nOldPos);
+ *rContent << nStandardId;
+ *rContent << nFixedAreaLn;
+ *rContent << nFlags;
+ *rContent << sal_uInt8(0x00);
+ *rContent << sal_uInt8(0x00);
+ *rContent << sal_uInt8(0x00);
+
+ WriteAlign(rContent,4);
+ return sal_True;
+}
+
+// Doesn't really read anything but just skips the
+// record.
+sal_Bool OCX_TabStrip::Read(SotStorageStream *pS)
+{
+ const long skipLen = 0x18;
+ *pS >> nIdentifier;
+ DBG_ASSERT(nStandardId==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+
+ pS->Read(pBlockFlags, sizeof(pBlockFlags));
+ pS->SeekRel(skipLen);
+ *pS >> nNumTabs;
+ // skip to end of control
+ pS->SeekRel(nFixedAreaLen - sizeof(pBlockFlags) - sizeof(nNumTabs) - skipLen );
+ return sal_True;
+}
+
+sal_Bool OCX_TabStrip::ReadFontData(SotStorageStream *pS)
+{
+ // Seems like there is a real font record followed by
+ // a number of blank records ( e.g. nFixedAreaLen = 0 )
+ // The number of trailing blank records is equal to the number of tabs
+ OCX_Control::ReadFontData(pS);
+ for ( sal_uInt16 index = 0; index < nNumTabs; index++ )
+ {
+ OCX_Control::Read(pS); // read trailing records
+ }
+ return sal_True;
+}
+
+sal_Bool OCX_Image::Read(SotStorageStream *pS)
+{
+ if ( !bSetInDialog )
+ {
+ // preserve the present behavior at the moment.
+ // only import image control for UserForms
+ return sal_False;
+ }
+ ULONG nStart = pS->Tell();
+ *pS >> nIdentifier;
+ DBG_ASSERT(nStandardId==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+
+ pS->Read(pBlockFlags, sizeof(pBlockFlags));
+
+ bool hasEmbeddedImage = false;
+
+ if ( pBlockFlags[0] & 0x04 )
+ {
+ bAutoSize = true;
+ }
+ if ( pBlockFlags[0] & 0x08 )
+ {
+ *pS >> nBorderColor;
+ }
+ if ( pBlockFlags[0] & 0x10 )
+ {
+ *pS >> mnBackColor;
+ }
+ if ( pBlockFlags[0] & 0x20 )
+ {
+ *pS >> nBorderStyle;
+ }
+ if ( pBlockFlags[0] & 0x40 )
+ {
+ *pS >> nMousePointer;
+ }
+ if ( pBlockFlags[0] & 0x80 )
+ {
+ *pS >> nPictureSizeMode;
+ }
+
+ if ( pBlockFlags[ 1 ] & 0x1 )
+ {
+ *pS >> nSpecialEffect;
+ }
+ // investigate if valid also for formcontrols, although for controls
+ // images themselves seem to come through from escher ( as shape, think
+ // its probably a preview? )
+
+ // np a bit of a guess ( until proved incorrect )
+ if ( pBlockFlags[ 1 ] & 0x4 )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ hasEmbeddedImage = true;
+ sal_uInt16 unknown;
+ *pS >> unknown;
+ }
+
+
+ if ( pBlockFlags[ 1 ] & 0x8 )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nPictureAlignment;
+
+ }
+ if ( pBlockFlags[ 1 ] & 0x10 )
+ {
+ bPictureTiling = true;
+ }
+ if ( pBlockFlags[1] & 0x20 )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_uInt8 nTemp;
+ *pS >> nTemp;
+ fEnabled = (nTemp&0x02)>>1;
+ fBackStyle = (nTemp&0x08)>>3;
+ // padding?
+ *pS >> nTemp;
+ *pS >> nTemp;
+ *pS >> nTemp;
+ }
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nWidth;
+ *pS >> nHeight;
+
+ if ( hasEmbeddedImage )
+ {
+ //image follows this block
+ //len of image is 0x14 relative to end of this block
+ pS->Seek( pS->Tell() + 0x14 );
+
+ sal_uInt32 nImageLen = 0;
+ *pS >> nImageLen;
+
+ long imagePos = pS->Tell();
+
+ pS->Seek( imagePos );
+
+ sImageUrl = C2U("vnd.sun.star.expand:${$BRAND_BASE_DIR/program/") + C2U( SAL_CONFIGFILE( "bootstrap" ) ) + C2U("::UserInstallation}/user/temp/") + sName;
+
+ sal_uInt8* pImage = new sal_uInt8[ nImageLen ];
+ pS->Read(pImage, nImageLen);
+ bool result = storePictureInFileSystem( sImageUrl, pImage, nImageLen );
+ OUString pictName = sImageUrl.copy( sImageUrl.lastIndexOf('/') + 1 );
+ result = storePictureInDoc( pDocSh, pictName, pImage, nImageLen );
+ delete pImage;
+ }
+ return sal_True;
+}
+
+sal_Bool OCX_Image::Import( uno::Reference< beans::XPropertySet > &rPropSet )
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+
+ if( fBackStyle )
+ aTmp <<= ImportColor(mnBackColor);
+ else
+ aTmp = uno::Any();
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ sal_Bool bTemp;
+ if (fEnabled)
+ bTemp = sal_True;
+ else
+ bTemp = sal_False;
+ aTmp = bool2any(bTemp);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+ if ( sImageUrl.getLength() )
+ {
+ aTmp <<= sImageUrl;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ImageURL"), aTmp);
+ }
+ return sal_True;
+}
+
+sal_Bool OCX_Image::WriteContents(SvStorageStreamRef &rContents,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ sal_Bool bRet=sal_True;
+ sal_uInt32 nOldPos = rContents->Tell();
+ rContents->SeekRel(8);
+
+ pBlockFlags[0] = 0;
+ pBlockFlags[1] = 0x02;
+ pBlockFlags[2] = 0;
+ pBlockFlags[3] = 0;
+
+ uno::Any aTmp = rPropSet->getPropertyValue(
+ WW8_ASCII2STR("BackgroundColor"));
+ if (aTmp.hasValue())
+ aTmp >>= mnBackColor;
+ *rContents << ExportColor(mnBackColor);
+ pBlockFlags[0] |= 0x10;
+
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Border"));
+ sal_Int16 nBorder = sal_Int16();
+ aTmp >>= nBorder;
+ nSpecialEffect = ExportBorder(nBorder,nBorderStyle);
+ *rContents << nBorderStyle;
+ pBlockFlags[0] |= 0x20;
+
+ *rContents << nSpecialEffect;
+ pBlockFlags[1] |= 0x01;
+
+ WriteAlign(rContents,4);
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("Enabled"));
+ fEnabled = any2bool(aTmp);
+ if (fEnabled)
+ {
+ sal_uInt8 nTemp = 0x19;
+ *rContents << nTemp;
+ pBlockFlags[1] |= 0x20;
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+ *rContents << sal_uInt8(0x00);
+ }
+
+ aTmp = rPropSet->getPropertyValue(WW8_ASCII2STR("ImageURL"));
+// OUString *pStr = (OUString *)aTmp.getValue();
+ /*Magically fetch that image and turn it into something that
+ *we can store in ms controls, wmf,png,jpg are almost certainly
+ *the options we have for export...*/
+
+ WriteAlign(rContents,4);
+ *rContents << rSize.Width;
+ *rContents << rSize.Height;
+
+ WriteAlign(rContents,4);
+ nFixedAreaLen = static_cast<sal_uInt16>(rContents->Tell()-nOldPos-4);
+
+ rContents->Seek(nOldPos);
+ *rContents << nStandardId;
+ *rContents << nFixedAreaLen;
+
+ *rContents << pBlockFlags[0];
+ *rContents << pBlockFlags[1];
+ *rContents << pBlockFlags[2];
+ *rContents << pBlockFlags[3];
+ DBG_ASSERT((rContents.Is() &&
+ (SVSTREAM_OK==rContents->GetError())),"damn");
+ return bRet;
+}
+
+
+sal_Bool OCX_Image::Export(SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet > &rPropSet,
+ const awt::Size &rSize)
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] = {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x41, 0x92, 0x59, 0x4C,
+ 0x26, 0x69, 0x1B, 0x10, 0x99, 0x92, 0x00, 0x00,
+ 0x0B, 0x65, 0xC6, 0xF9, 0x1A, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x49, 0x6D, 0x61, 0x67,
+ 0x65, 0x00, 0x10, 0x00, 0x00, 0x00, 0x45, 0x6D,
+ 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x4F,
+ 0x62, 0x6A, 0x65, 0x63, 0x74, 0x00, 0x0E, 0x00,
+ 0x00, 0x00, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x2E,
+ 0x49, 0x6D, 0x61, 0x67, 0x65, 0x2E, 0x31, 0x00,
+ 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] = {
+ 0x49, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x67, 0x00,
+ 0x65, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+// ============================================================================
+
+OCX_SpinButton::OCX_SpinButton() :
+ OCX_Control( OUString( RTL_CONSTASCII_USTRINGPARAM( "SpinButton" ) ) ),
+ mnBlockFlags( 0 ),
+ mnValue( 0 ),
+ mnMin( 0 ),
+ mnMax( 100 ),
+ mnSmallStep( 1 ),
+ mnPageStep( 1 ),
+ mnOrient( -1 ),
+ mnDelay( 50 ),
+ mbEnabled( true ),
+ mbLocked( false ),
+ mbPropThumb( true )
+{
+ msFormType = C2U("com.sun.star.form.component.SpinButton");
+ msDialogType = C2U("com.sun.star.awt.UnoControlSpinButtonModel");
+ mnBackColor = 0x8000000F;
+ mnForeColor = 0x80000012;
+}
+
+OCX_Control* OCX_SpinButton::Create()
+{
+ return new OCX_SpinButton;
+}
+
+sal_Bool OCX_SpinButton::Read( SvStorageStream *pS )
+{
+ if( !pS ) return sal_False;
+
+ SvStream& rStrm = *pS;
+ sal_uInt16 nId, nSize;
+ sal_Int32 nIcon = 0;
+
+ rStrm >> nId >> nSize >> mnBlockFlags;
+
+ DBG_ASSERT( nStandardId == nId, "OCX_SpinButton::Read - unknown identifier" );
+
+ if( mnBlockFlags & 0x00000001 ) rStrm >> mnForeColor;
+ if( mnBlockFlags & 0x00000002 ) rStrm >> mnBackColor;
+ if( mnBlockFlags & 0x00000004 )
+ {
+ sal_Int32 nFlags;
+ rStrm >> nFlags;
+ mbEnabled = (nFlags & 0x00000002) != 0;
+ mbLocked = (nFlags & 0x00000004) != 0;
+ }
+ if( mnBlockFlags & 0x00000010 ) rStrm.SeekRel( 4 ); // mouse pointer
+ if( mnBlockFlags & 0x00000020 ) rStrm >> mnMin;
+ if( mnBlockFlags & 0x00000040 ) rStrm >> mnMax;
+ if( mnBlockFlags & 0x00000080 ) rStrm >> mnValue;
+ if( mnBlockFlags & 0x00000100 ) rStrm.SeekRel( 4 ); // unknown
+ if( mnBlockFlags & 0x00000200 ) rStrm.SeekRel( 4 ); // unknown
+ if( mnBlockFlags & 0x00000400 ) rStrm.SeekRel( 4 ); // unknown
+ if( mnBlockFlags & 0x00000800 ) rStrm >> mnSmallStep;
+ if( mnBlockFlags & 0x00001000 ) rStrm >> mnPageStep;
+ if( mnBlockFlags & 0x00002000 ) rStrm >> mnOrient;
+ if( mnBlockFlags & 0x00004000 )
+ {
+ sal_Int32 nThumb;
+ *pS >> nThumb;
+ mbPropThumb = nThumb != 0;
+ }
+ if( mnBlockFlags & 0x00008000 ) rStrm >> mnDelay;
+ if( mnBlockFlags & 0x00010000 ) rStrm >> nIcon;
+ if( mnBlockFlags & 0x00000008 ) rStrm >> nWidth >> nHeight;
+
+ if( nIcon )
+ {
+ sal_Int32 nIconSize;
+ pS->SeekRel( 20 );
+ *pS >> nIconSize;
+ pS->SeekRel( nIconSize );
+ }
+
+ return sal_True;
+}
+
+sal_Bool OCX_SpinButton::ReadFontData( SvStorageStream* /* pS */ )
+{
+ // spin buttons and scroll bars do not support font data
+ return sal_True;
+}
+
+sal_Bool OCX_SpinButton::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ if( (nWidth < 1) || (nHeight < 1) )
+ return sal_False;
+
+ uno::Any aTmp( &sName, getCppuType((OUString *)0) );
+ rPropSet->setPropertyValue( WW8_ASCII2STR( "Name" ), aTmp );
+
+ aTmp <<= ImportColor( mnForeColor );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("SymbolColor"), aTmp);
+
+ aTmp <<= ImportColor( mnBackColor );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ aTmp = bool2any( mbEnabled && !mbLocked );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ aTmp <<= mnValue;
+ if ( bSetInDialog )
+ {
+ rPropSet->setPropertyValue( WW8_ASCII2STR("SpinValue"), aTmp );
+ }
+ else
+ {
+ rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultSpinValue"), aTmp );
+ }
+
+ aTmp <<= mnMin;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("SpinValueMin"), aTmp );
+
+ aTmp <<= mnMax;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("SpinValueMax"), aTmp );
+
+ aTmp <<= mnSmallStep;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("SpinIncrement"), aTmp );
+
+ namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
+ switch( mnOrient )
+ {
+ case 0: aTmp <<= AwtScrollOrient::VERTICAL; break;
+ case 1: aTmp <<= AwtScrollOrient::HORIZONTAL; break;
+ default: aTmp <<= (nWidth < nHeight) ? AwtScrollOrient::VERTICAL : AwtScrollOrient::HORIZONTAL;
+ }
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Orientation"), aTmp );
+
+ aTmp = bool2any( true );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Repeat"), aTmp );
+
+ aTmp <<= mnDelay;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("RepeatDelay"), aTmp );
+
+ aTmp <<= sal_Int16( 0 );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Border"), aTmp);
+
+ return sal_True;
+}
+
+sal_Bool OCX_SpinButton::Export(
+ SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet>& rPropSet,
+ const awt::Size& rSize )
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] =
+ {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0x6F, 0x17, 0x79,
+ 0xF2, 0xB7, 0xCE, 0x11, 0x97, 0xEF, 0x00, 0xAA,
+ 0x00, 0x6D, 0x27, 0x76, 0x1F, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x53, 0x70, 0x69, 0x6E,
+ 0x42, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x45, 0x6D, 0x62, 0x65, 0x64,
+ 0x64, 0x65, 0x64, 0x20, 0x4F, 0x62, 0x6A, 0x65,
+ 0x63, 0x74, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46,
+ 0x6E, 0x42, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x2E,
+ 0x31, 0x00, 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] =
+ {
+ 0x53, 0x00, 0x70, 0x00, 0x69, 0x00, 0x6E, 0x00,
+ 0x42, 0x00, 0x75, 0x00, 0x74, 0x00, 0x74, 0x00,
+ 0x6F, 0x00, 0x6E, 0x00, 0x31, 0x00, 0x00, 0x00,
+ 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+sal_Bool OCX_SpinButton::WriteContents(
+ SvStorageStreamRef &rObj,
+ const uno::Reference< beans::XPropertySet> &rPropSet,
+ const awt::Size& rSize )
+{
+ if( !rObj.Is() )
+ return sal_False;
+
+ mnBlockFlags = 0x00000008;
+ nWidth = rSize.Width;
+ nHeight = rSize.Height;
+
+ GetInt32Property( mnForeColor, rPropSet, WW8_ASCII2STR( "SymbolColor" ), 0x00000001 );
+ GetInt32Property( mnBackColor, rPropSet, WW8_ASCII2STR( "BackgroundColor" ), 0x00000002 );
+ GetBoolProperty( mbEnabled, rPropSet, WW8_ASCII2STR( "Enabled" ), 0x00000304 );
+ GetInt32Property( mnMin, rPropSet, WW8_ASCII2STR( "SpinValueMin" ), 0x00000020 );
+ GetInt32Property( mnMax, rPropSet, WW8_ASCII2STR( "SpinValueMax" ), 0x00000040 );
+ GetInt32Property( mnValue, rPropSet, WW8_ASCII2STR( "SpinValue" ), 0x00000080 );
+ GetInt32Property( mnSmallStep, rPropSet, WW8_ASCII2STR( "SpinIncrement" ), 0x00000800 );
+ GetInt32Property( mnDelay, rPropSet, WW8_ASCII2STR( "RepeatDelay" ), 0x00008000 );
+
+ namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
+ sal_Int16 nApiOrient = sal_Int16();
+ if( rPropSet->getPropertyValue( WW8_ASCII2STR( "Orientation" ) ) >>= nApiOrient )
+ UpdateInt32Property( mnOrient, (nApiOrient == AwtScrollOrient::VERTICAL) ? 0 : 1, 0x00002000 );
+
+ return WriteData( *rObj );
+}
+
+void OCX_SpinButton::UpdateInt32Property(
+ sal_Int32& rnCoreValue, sal_Int32 nNewValue, sal_Int32 nBlockFlag )
+{
+ if( nNewValue != rnCoreValue )
+ {
+ rnCoreValue = nNewValue;
+ mnBlockFlags |= nBlockFlag;
+ }
+}
+
+void OCX_SpinButton::GetInt32Property(
+ sal_Int32& rnCoreValue, const uno::Reference< beans::XPropertySet>& rxPropSet,
+ const OUString& rPropName, sal_Int32 nBlockFlag )
+{
+ sal_Int32 nNewValue = 0;
+ if( rxPropSet->getPropertyValue( rPropName ) >>= nNewValue )
+ UpdateInt32Property( rnCoreValue, nNewValue, nBlockFlag );
+}
+
+void OCX_SpinButton::UpdateBoolProperty(
+ bool& rbCoreValue, bool bNewValue, sal_Int32 nBlockFlag )
+{
+ if( bNewValue != rbCoreValue )
+ {
+ rbCoreValue = bNewValue;
+ mnBlockFlags |= nBlockFlag;
+ }
+}
+
+void OCX_SpinButton::GetBoolProperty(
+ bool& rbCoreValue, const uno::Reference< beans::XPropertySet>& rxPropSet,
+ const OUString& rPropName, sal_Int32 nBlockFlag )
+{
+ UpdateBoolProperty( rbCoreValue,
+ any2bool( rxPropSet->getPropertyValue( rPropName ) ), nBlockFlag );
+}
+
+sal_Bool OCX_SpinButton::WriteData( SvStream& rStrm ) const
+{
+ sal_Bool bRet = sal_True;
+ ULONG nStartPos = rStrm.Tell();
+
+ rStrm << sal_Int32( 0 ) << mnBlockFlags;
+
+ if( mnBlockFlags & 0x00000001 ) rStrm << ExportColor( mnForeColor );
+ if( mnBlockFlags & 0x00000002 ) rStrm << ExportColor( mnBackColor );
+ if( mnBlockFlags & 0x00000004 )
+ {
+ sal_Int32 nFlags = 0x00000019; // always set
+ if( mbEnabled ) nFlags |= 0x00000002;
+ if( mbLocked ) nFlags |= 0x00000004;
+ rStrm << nFlags;
+ }
+ if( mnBlockFlags & 0x00000020 ) rStrm << mnMin;
+ if( mnBlockFlags & 0x00000040 ) rStrm << mnMax;
+ if( mnBlockFlags & 0x00000080 ) rStrm << mnValue;
+ if( mnBlockFlags & 0x00000100 ) rStrm << sal_Int32( 0 ); // unknown
+ if( mnBlockFlags & 0x00000200 ) rStrm << sal_Int32( 0 ); // unknown
+ if( mnBlockFlags & 0x00000400 ) rStrm << sal_Int32( 0 ); // unknown
+ if( mnBlockFlags & 0x00000800 ) rStrm << mnSmallStep;
+ if( mnBlockFlags & 0x00001000 ) rStrm << mnPageStep;
+ if( mnBlockFlags & 0x00002000 ) rStrm << mnOrient;
+ if( mnBlockFlags & 0x00004000 ) rStrm << sal_Int32( mbPropThumb ? 1 : 0 );
+ if( mnBlockFlags & 0x00008000 ) rStrm << mnDelay;
+ if( mnBlockFlags & 0x00000008 ) rStrm << nWidth << nHeight;
+
+ sal_uInt16 nSize = static_cast< sal_uInt16 >( rStrm.Tell() - nStartPos - 4 );
+ rStrm.Seek( nStartPos );
+ rStrm << nStandardId << nSize;
+
+ DBG_ASSERT( rStrm.GetError() == SVSTREAM_OK, "OCX_SpinButton::WriteData - error in stream" );
+ return bRet;
+}
+
+// ============================================================================
+
+OCX_ScrollBar::OCX_ScrollBar()
+{
+ sName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScrollBar" ) );
+ mnMax = 32767;
+ msFormType = C2U("com.sun.star.form.component.ScrollBar");
+ msDialogType = C2U("com.sun.star.awt.UnoControlScrollBarModel");
+
+}
+
+OCX_Control* OCX_ScrollBar::Create()
+{
+ return new OCX_ScrollBar;
+}
+
+sal_Bool OCX_ScrollBar::Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet)
+{
+ if( (nWidth < 1) || (nHeight < 1) )
+ return sal_False;
+
+ uno::Any aTmp( &sName, getCppuType((OUString *)0) );
+ rPropSet->setPropertyValue( WW8_ASCII2STR( "Name" ), aTmp );
+
+ aTmp <<= ImportColor( mnForeColor );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("SymbolColor"), aTmp);
+
+ aTmp <<= ImportColor( mnBackColor );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ aTmp = bool2any( mbEnabled && !mbLocked );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), aTmp);
+
+ aTmp <<= mnValue;
+ if ( bSetInDialog )
+ {
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ScrollValue"), aTmp );
+ }
+ else
+ {
+ rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultScrollValue"), aTmp );
+ }
+
+ aTmp <<= mnMin;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ScrollValueMin"), aTmp );
+
+ aTmp <<= mnMax;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ScrollValueMax"), aTmp );
+
+ aTmp <<= mnSmallStep;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("LineIncrement"), aTmp );
+
+ aTmp <<= mnPageStep;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BlockIncrement"), aTmp );
+ if( mbPropThumb && (mnPageStep > 0) )
+ rPropSet->setPropertyValue( WW8_ASCII2STR("VisibleSize"), aTmp );
+
+ namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
+ switch( mnOrient )
+ {
+ case 0: aTmp <<= AwtScrollOrient::VERTICAL; break;
+ case 1: aTmp <<= AwtScrollOrient::HORIZONTAL; break;
+ default: aTmp <<= (nWidth < nHeight) ? AwtScrollOrient::VERTICAL : AwtScrollOrient::HORIZONTAL;
+ }
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Orientation"), aTmp );
+
+ aTmp <<= mnDelay;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("RepeatDelay"), aTmp );
+
+ aTmp <<= sal_Int16( 0 );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Border"), aTmp);
+
+ return sal_True;
+}
+
+sal_Bool OCX_ScrollBar::Export(
+ SvStorageRef &rObj,
+ const uno::Reference< beans::XPropertySet>& rPropSet,
+ const awt::Size& rSize )
+{
+ static sal_uInt8 __READONLY_DATA aCompObj[] =
+ {
+ 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x81, 0xD1, 0xDF,
+ 0x2F, 0x5E, 0xCE, 0x11, 0xA4, 0x49, 0x00, 0xAA,
+ 0x00, 0x4A, 0x80, 0x3D, 0x1E, 0x00, 0x00, 0x00,
+ 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
+ 0x74, 0x20, 0x46, 0x6F, 0x72, 0x6D, 0x73, 0x20,
+ 0x32, 0x2E, 0x30, 0x20, 0x53, 0x63, 0x72, 0x6F,
+ 0x6C, 0x6C, 0x42, 0x61, 0x72, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x45, 0x6D, 0x62, 0x65, 0x64, 0x64,
+ 0x65, 0x64, 0x20, 0x4F, 0x62, 0x6A, 0x65, 0x63,
+ 0x74, 0x00, 0x12, 0x00, 0x00, 0x00, 0x46, 0x6F,
+ 0x72, 0x6D, 0x73, 0x2E, 0x53, 0x63, 0x72, 0x6F,
+ 0x6C, 0x6C, 0x42, 0x61, 0x72, 0x2E, 0x31, 0x00,
+ 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor( rObj->OpenSotStream( C2S("\1CompObj")));
+ xStor->Write(aCompObj,sizeof(aCompObj));
+ DBG_ASSERT((xStor.Is() && (SVSTREAM_OK == xStor->GetError())),"damn");
+ }
+
+ {
+ SvStorageStreamRef xStor3( rObj->OpenSotStream( C2S("\3ObjInfo")));
+ xStor3->Write(aObjInfo,sizeof(aObjInfo));
+ DBG_ASSERT((xStor3.Is() && (SVSTREAM_OK == xStor3->GetError())),"damn");
+ }
+
+ static sal_uInt8 __READONLY_DATA aOCXNAME[] =
+ {
+ 0x53, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F, 0x00,
+ 0x6C, 0x00, 0x6C, 0x00, 0x42, 0x00, 0x61, 0x00,
+ 0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ {
+ SvStorageStreamRef xStor2( rObj->OpenSotStream( C2S("\3OCXNAME")));
+ xStor2->Write(aOCXNAME,sizeof(aOCXNAME));
+ DBG_ASSERT((xStor2.Is() && (SVSTREAM_OK == xStor2->GetError())),"damn");
+ }
+
+ SvStorageStreamRef xContents( rObj->OpenSotStream( C2S("contents")));
+ return WriteContents(xContents, rPropSet, rSize);
+}
+
+sal_Bool OCX_ScrollBar::WriteContents(
+ SvStorageStreamRef &rObj,
+ const uno::Reference< beans::XPropertySet> &rPropSet,
+ const awt::Size& rSize )
+{
+ if( !rObj.Is() )
+ return sal_False;
+
+ mnBlockFlags = 0x00000008;
+ nWidth = rSize.Width;
+ nHeight = rSize.Height;
+
+ GetInt32Property( mnForeColor, rPropSet, WW8_ASCII2STR( "SymbolColor" ), 0x00000001 );
+ GetInt32Property( mnBackColor, rPropSet, WW8_ASCII2STR( "BackgroundColor" ), 0x00000002 );
+ GetBoolProperty( mbEnabled, rPropSet, WW8_ASCII2STR( "Enabled" ), 0x00000304 );
+ GetInt32Property( mnMin, rPropSet, WW8_ASCII2STR( "ScrollValueMin" ), 0x00000020 );
+ GetInt32Property( mnMax, rPropSet, WW8_ASCII2STR( "ScrollValueMax" ), 0x00000040 );
+ GetInt32Property( mnValue, rPropSet, WW8_ASCII2STR( "ScrollValue" ), 0x00000080 );
+ GetInt32Property( mnSmallStep, rPropSet, WW8_ASCII2STR( "LineIncrement" ), 0x00000800 );
+ GetInt32Property( mnPageStep, rPropSet, WW8_ASCII2STR( "BlockIncrement" ), 0x00001000 );
+ GetInt32Property( mnDelay, rPropSet, WW8_ASCII2STR( "RepeatDelay" ), 0x00008000 );
+
+ namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
+ sal_Int16 nApiOrient = sal_Int16();
+ if( rPropSet->getPropertyValue( WW8_ASCII2STR( "Orientation" ) ) >>= nApiOrient )
+ UpdateInt32Property( mnOrient, (nApiOrient == AwtScrollOrient::VERTICAL) ? 0 : 1, 0x00002000 );
+
+ UpdateBoolProperty( mbPropThumb, true, 0x00004000 );
+
+ return WriteData( *rObj );
+}
+
+OCX_ProgressBar::OCX_ProgressBar() :
+ OCX_Control( OUString( RTL_CONSTASCII_USTRINGPARAM( "ProgressBar" ) ) ),
+ nMin( 0 ),
+ nMax( 0 ),
+ bFixedSingle(true),
+ bEnabled( true ),
+ b3d( true )
+{
+ msDialogType = C2U("com.sun.star.awt.UnoControlProgressBarModel");
+ bSetInDialog = true;
+}
+
+sal_Bool OCX_ProgressBar::Read( SvStorageStream *pS )
+{
+ pS->SeekRel( 8 );
+ *pS >> nWidth >> nHeight;
+ pS->SeekRel( 12 );
+
+ float fMin, fMax;
+ *pS >> fMin >> fMax;
+ nMin = static_cast< sal_Int32 >( fMin );
+ nMax = static_cast< sal_Int32 >( fMax );
+ bool bVisible = true;
+ sal_uInt8 pUnknownFlags[4];
+ pS->Read(pUnknownFlags,4);
+
+ // complete guess, but we don't handle visible anyway
+ if ( ( pUnknownFlags[2] & 0x8 ) && ( pUnknownFlags[2] & 0x2 ) )
+ bVisible = false;
+
+ sal_uInt32 nFlags;
+ *pS >> nFlags;
+
+ // seems these work out
+ bFixedSingle = (nFlags & 0x01) != 0;
+ bEnabled = (nFlags & 0x02) != 0;
+ b3d = (nFlags & 0x04) != 0;
+
+ return true;
+}
+
+OCX_Control* OCX_ProgressBar::Create()
+{
+ return new OCX_ProgressBar;
+}
+
+sal_Bool OCX_ProgressBar::Import(uno::Reference< beans::XPropertySet > &rPropSet)
+{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+ aTmp <<= nMax;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ProgressValueMax"), aTmp );
+ aTmp <<= nMin;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ProgressValueMin"), aTmp );
+
+ if ( !bEnabled )
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), uno::makeAny( sal_False ) );
+ return sal_True;
+}
+// ============================================================================
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/filter/source/msfilter/msoleexp.cxx b/filter/source/msfilter/msoleexp.cxx
new file mode 100644
index 000000000000..71b01bafd7dd
--- /dev/null
+++ b/filter/source/msfilter/msoleexp.cxx
@@ -0,0 +1,367 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msoleexp.cxx,v $
+ * $Revision: 1.22 $
+ *
+ * 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_filter.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <sot/clsids.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sot/formats.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <svtools/embedhlp.hxx>
+#include <filter/msfilter/msdffimp.hxx> // extern sichtbare Header-Datei
+
+#include "filter/msfilter/msoleexp.hxx"
+
+#define CREATE_CONST_ASC(s) String::CreateFromAscii( \
+ RTL_CONSTASCII_STRINGPARAM(s))
+
+using namespace ::com::sun::star;
+
+SvGlobalName GetEmbeddedVersion( const SvGlobalName& aAppName )
+{
+ if ( aAppName == SvGlobalName( SO3_SM_CLASSID_60 ) )
+ return SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 );
+ else if ( aAppName == SvGlobalName( SO3_SW_CLASSID_60 ) )
+ return SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 );
+ else if ( aAppName == SvGlobalName( SO3_SC_CLASSID_60 ) )
+ return SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 );
+ else if ( aAppName == SvGlobalName( SO3_SDRAW_CLASSID_60 ) )
+ return SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 );
+ else if ( aAppName == SvGlobalName( SO3_SIMPRESS_CLASSID_60 ) )
+ return SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 );
+ else if ( aAppName == SvGlobalName( SO3_SCH_CLASSID_60 ) )
+ return SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 );
+
+ return SvGlobalName();
+}
+
+String GetStorageType( const SvGlobalName& aEmbName )
+{
+ if ( aEmbName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
+ return String::CreateFromAscii( "opendocument.MathDocument.1" );
+ else if ( aEmbName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
+ return String::CreateFromAscii( "opendocument.WriterDocument.1" );
+ else if ( aEmbName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
+ return String::CreateFromAscii( "opendocument.CalcDocument.1" );
+ else if ( aEmbName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
+ return String::CreateFromAscii( "opendocument.DrawDocument.1" );
+ else if ( aEmbName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
+ return String::CreateFromAscii( "opendocument.ImpressDocument.1" );
+ else if ( aEmbName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
+ return String::CreateFromAscii( "opendocument.ChartDocument.1" );
+
+ return String();
+}
+
+sal_Bool UseOldMSExport()
+{
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+
+ if ( xFactory.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xProvider( xFactory->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider"))),
+ uno::UNO_QUERY);
+ if ( xProvider.is() )
+ {
+ try {
+ uno::Sequence< uno::Any > aArg( 1 );
+ aArg[0] <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/InternalMSExport") );
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xProvider->createInstanceWithArguments(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) ),
+ aArg ),
+ uno::UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ uno::Any aResult = xNameAccess->getByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseOldExport" ) ) );
+
+ sal_Bool bResult = sal_Bool();
+ if ( aResult >>= bResult )
+ return bResult;
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ OSL_ENSURE( sal_False, "Could not get access to configuration entry!\n" );
+ return sal_False;
+}
+
+void SvxMSExportOLEObjects::ExportOLEObject( const com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject>& rObj, SotStorage& rDestStg )
+{
+ svt::EmbeddedObjectRef aObj( rObj, embed::Aspects::MSOLE_CONTENT );
+ ExportOLEObject( aObj, rDestStg );
+}
+
+void SvxMSExportOLEObjects::ExportOLEObject( svt::EmbeddedObjectRef& rObj, SvStorage& rDestStg )
+{
+ SvGlobalName aOwnGlobalName;
+ SvGlobalName aObjName( rObj->getClassID() );
+ const SfxFilter* pExpFilter = NULL;
+ {
+ static struct _ObjExpType {
+ UINT32 nFlag;
+ const char* pFilterNm;
+ // GlobalNameId
+ struct _GlobalNameIds {
+ UINT32 n1;
+ USHORT n2, n3;
+ BYTE b8, b9, b10, b11, b12, b13, b14, b15;
+ }
+ aGlNmIds[4];
+ } aArr[] = {
+ { OLE_STARMATH_2_MATHTYPE, "MathType 3.x",
+ {{SO3_SM_CLASSID_60}, {SO3_SM_CLASSID_50},
+ {SO3_SM_CLASSID_40}, {SO3_SM_CLASSID_30 }}},
+ { OLE_STARWRITER_2_WINWORD, "MS Word 97",
+ {{SO3_SW_CLASSID_60}, {SO3_SW_CLASSID_50},
+ {SO3_SW_CLASSID_40}, {SO3_SW_CLASSID_30 }}},
+ { OLE_STARCALC_2_EXCEL, "MS Excel 97",
+ {{SO3_SC_CLASSID_60}, {SO3_SC_CLASSID_50},
+ {SO3_SC_CLASSID_40}, {SO3_SC_CLASSID_30 }}},
+ { OLE_STARIMPRESS_2_POWERPOINT, "MS PowerPoint 97",
+ {{SO3_SIMPRESS_CLASSID_60}, {SO3_SIMPRESS_CLASSID_50},
+ {SO3_SIMPRESS_CLASSID_40}, {SO3_SIMPRESS_CLASSID_30 }}},
+ { 0, "",
+ {{SO3_SCH_CLASSID_60}, {SO3_SCH_CLASSID_50},
+ {SO3_SCH_CLASSID_40}, {SO3_SCH_CLASSID_30 }}},
+ { 0, "",
+ {{SO3_SDRAW_CLASSID_60}, {SO3_SDRAW_CLASSID_50}, // SJ: !!!! SO3_SDRAW_CLASSID is only available up from
+ {SO3_SDRAW_CLASSID_60}, {SO3_SDRAW_CLASSID_50 }}}, // ver 5.0, it is purpose to have double entrys here.
+
+ { 0xffff,0,
+ {{SO3_SDRAW_CLASSID_60}, {SO3_SDRAW_CLASSID_50},
+ {SO3_SDRAW_CLASSID_60}, {SO3_SDRAW_CLASSID_50}}}
+ };
+
+ for( const _ObjExpType* pArr = aArr; !pExpFilter && ( pArr->nFlag != 0xffff ); ++pArr )
+ {
+ for ( int n = 0; n < 4; ++n )
+ {
+ const _ObjExpType::_GlobalNameIds& rId = pArr->aGlNmIds[ n ];
+ SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
+ rId.b8, rId.b9, rId.b10, rId.b11,
+ rId.b12, rId.b13, rId.b14, rId.b15 );
+ if( aObjName == aGlbNm )
+ {
+ aOwnGlobalName = aGlbNm;
+
+ // flags for checking if conversion is wanted at all (SaveOptions?!)
+ if( GetFlags() & pArr->nFlag )
+ {
+ pExpFilter = SfxFilterMatcher().GetFilter4FilterName(String::CreateFromAscii(pArr->pFilterNm));
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if( pExpFilter ) // use this filter for the export
+ {
+ try
+ {
+ if ( rObj->getCurrentState() == embed::EmbedStates::LOADED )
+ rObj->changeState( embed::EmbedStates::RUNNING );
+ //TODO/LATER: is stream instead of outputstream a better choice?!
+ //TODO/LATER: a "StoreTo" method at embedded object would be nice
+ uno::Sequence < beans::PropertyValue > aSeq(2);
+ SvStream* pStream = new SvMemoryStream;
+ aSeq[0].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
+ ::uno::Reference < io::XOutputStream > xOut = new ::utl::OOutputStreamWrapper( *pStream );
+ aSeq[0].Value <<= xOut;
+ aSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
+ aSeq[1].Value <<= ::rtl::OUString( pExpFilter->GetName() );
+ uno::Reference < frame::XStorable > xStor( rObj->getComponent(), uno::UNO_QUERY );
+ xStor->storeToURL( ::rtl::OUString::createFromAscii( "private:stream" ), aSeq );
+ SotStorageRef xOLEStor = new SotStorage( pStream, TRUE );
+ xOLEStor->CopyTo( &rDestStg );
+ rDestStg.Commit();
+ }
+ catch( uno::Exception& )
+ {
+ // TODO/LATER: Error handling
+ DBG_ERROR( "The object could not be exported!" );
+ }
+ }
+ else if( aOwnGlobalName != SvGlobalName() )
+ {
+ // own format, maybe SO6 format or lower
+ SvGlobalName aEmbName = GetEmbeddedVersion( aOwnGlobalName );
+ if ( aEmbName != SvGlobalName() && !UseOldMSExport() )
+ {
+ // this is a SO6 embedded object, save in old binary format
+ rDestStg.SetVersion( SOFFICE_FILEFORMAT_31 );
+ rDestStg.SetClass( aEmbName,
+ SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE,
+ GetStorageType( aEmbName ) );
+ SotStorageStreamRef xExtStm = rDestStg.OpenSotStream(
+ String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "properties_stream" ) ),
+ STREAM_STD_READWRITE );
+
+ sal_Bool bExtentSuccess = sal_False;
+ if( !xExtStm->GetError() )
+ {
+ // write extent
+ //TODO/MBA: check if writing a size is enough
+ if( rObj.GetObject().is() )
+ {
+ // MSOLE objects don't need to be in running state for VisualArea access
+ awt::Size aSize;
+ try
+ {
+ // this is an own object, the content size must be stored in the
+ // extension stream
+ aSize = rObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
+ }
+ catch( embed::NoVisualAreaSizeException& )
+ {
+ OSL_ENSURE( sal_False, "Could not get visual area size!\n" );
+ aSize.Width = 5000;
+ aSize.Height = 5000;
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Unexpected exception while getting visual area size!\n" );
+ aSize.Width = 5000;
+ aSize.Height = 5000;
+ }
+
+ //Rectangle aVisArea = xSfxIPObj->GetVisArea( ASPECT_CONTENT );
+ sal_Int32 pRect[4];
+ //pRect[0] = aVisArea.Left();
+ //pRect[1] = aVisArea.Right();
+ //pRect[2] = aVisArea.Top();
+ //pRect[3] = aVisArea.Bottom();
+ pRect[0] = 0;
+ pRect[1] = aSize.Width;
+ pRect[2] = 0;
+ pRect[3] = aSize.Height;
+
+ sal_Int8 aWriteSet[16];
+ for ( int ind = 0; ind < 4; ind++ )
+ {
+ sal_Int32 nVal = pRect[ind];
+ for ( int nByte = 0; nByte < 4; nByte++ )
+ {
+ aWriteSet[ind*4+nByte] = (sal_Int8) nVal % 0x100;
+ nVal /= 0x100;
+ }
+ }
+
+ bExtentSuccess = ( xExtStm->Write( aWriteSet, 16 ) == 16 );
+ }
+ }
+
+ if ( bExtentSuccess )
+ {
+ SotStorageStreamRef xEmbStm = rDestStg.OpenSotStream(
+ String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "package_stream" ) ),
+ STREAM_STD_READWRITE );
+ if( !xEmbStm->GetError() )
+ {
+ try
+ {
+ if ( rObj->getCurrentState() == embed::EmbedStates::LOADED )
+ rObj->changeState( embed::EmbedStates::RUNNING );
+ //TODO/LATER: is stream instead of outputstream a better choice?!
+ //TODO/LATER: a "StoreTo" method at embedded object would be nice
+ uno::Sequence < beans::PropertyValue > aSeq(1);
+ aSeq[0].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
+ ::uno::Reference < io::XOutputStream > xOut = new ::utl::OOutputStreamWrapper( *xEmbStm );
+ aSeq[0].Value <<= xOut;
+ uno::Reference < frame::XStorable > xStor( rObj->getComponent(), uno::UNO_QUERY );
+ xStor->storeToURL( ::rtl::OUString::createFromAscii( "private:stream" ), aSeq );
+ }
+ catch( uno::Exception& )
+ {
+ // TODO/LATER: Error handling
+ DBG_ERROR( "The object could not be exported!" );
+ }
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("Own binary format inside own container document!");
+ }
+ }
+ else
+ {
+ // alien objects
+ //TODO/LATER: a "StoreTo" method at embedded object would be nice
+ rDestStg.SetVersion( SOFFICE_FILEFORMAT_31 );
+ uno::Reference < embed::XStorage > xStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
+ uno::Reference < embed::XEmbedPersist > xPers( rObj.GetObject(), uno::UNO_QUERY );
+ if ( xPers.is() )
+ {
+ uno::Sequence < beans::PropertyValue > aEmptySeq;
+ ::rtl::OUString aTempName(::rtl::OUString::createFromAscii("bla"));
+ try
+ {
+ xPers->storeToEntry( xStor, aTempName, aEmptySeq, aEmptySeq );
+ }
+ catch ( uno::Exception& )
+ {}
+
+ SotStorageRef xOLEStor = SotStorage::OpenOLEStorage( xStor, aTempName, STREAM_STD_READ );
+ xOLEStor->CopyTo( &rDestStg );
+ rDestStg.Commit();
+ }
+ }
+
+ //We never need this stream: See #99809# and #i2179#
+ rDestStg.Remove(CREATE_CONST_ASC(SVEXT_PERSIST_STREAM));
+}
+
+
+
diff --git a/filter/source/msfilter/msvbasic.cxx b/filter/source/msfilter/msvbasic.cxx
new file mode 100644
index 000000000000..b7d5b7da1d1b
--- /dev/null
+++ b/filter/source/msfilter/msvbasic.cxx
@@ -0,0 +1,677 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msvbasic.cxx,v $
+ * $Revision: 1.22 $
+ *
+ * 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_filter.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#include <string.h> // memset(), ...
+#ifndef UNX
+#include <io.h> // access()
+#endif
+#include <osl/endian.h>
+#include <rtl/tencinfo.h> //rtl_getTextEncodingFromWindowsCodePage
+#include "msvbasic.hxx"
+
+/*
+A few urls which may in the future be of some use
+http://www.virusbtn.com/vb2000/Programme/papers/bontchev.pdf
+*/
+
+/* class VBA_Impl:
+ * The VBA class provides a set of methods to handle Visual Basic For
+ * Applications streams, the constructor is given the root ole2 stream
+ * of the document, Open reads the VBA project file and figures out
+ * the number of VBA streams, and the offset of the data within them.
+ * Decompress decompresses a particular numbered stream, NoStreams returns
+ * this number, and StreamName can give you the streams name. Decompress
+ * will call Output when it has a 4096 byte collection of data to output,
+ * and also with the final remainder of data if there is still some left
+ * at the end of compression. Output is virtual to allow custom handling
+ * of each chunk of decompressed data. So inherit from this to do something
+ * useful with the data.
+ *
+ * cmc
+ * */
+const int MINVBASTRING = 6;
+
+VBA_Impl::VBA_Impl(SvStorage &rIn, bool bCmmntd)
+ : aVBAStrings(0),
+ sComment(RTL_CONSTASCII_USTRINGPARAM("Rem ")),
+ xStor(&rIn), pOffsets(0), nOffsets(0), meCharSet(RTL_TEXTENCODING_MS_1252),
+ bCommented(bCmmntd), mbMac(false), nLines(0)
+{
+}
+
+VBA_Impl::~VBA_Impl()
+{
+ delete [] pOffsets;
+ for (ULONG i=0;i<aVBAStrings.GetSize();++i)
+ delete aVBAStrings.Get(i);
+}
+
+sal_uInt8 VBA_Impl::ReadPString(SvStorageStreamRef &xVBAProject,
+ bool bIsUnicode)
+{
+ sal_uInt16 nIdLen, nOut16;
+ sal_uInt8 nType = 0, nOut8;
+ String sReference;
+
+ *xVBAProject >> nIdLen;
+
+ if (nIdLen < MINVBASTRING) //Error recovery
+ xVBAProject->SeekRel(-2); //undo 2 byte len
+ else
+ {
+ for(sal_uInt16 i=0; i < nIdLen / (bIsUnicode ? 2 : 1); i++)
+ {
+ if (bIsUnicode)
+ *xVBAProject >> nOut16;
+ else
+ {
+ *xVBAProject >> nOut8;
+ nOut16 = nOut8;
+ }
+ sReference += nOut16;
+ if (i==2)
+ {
+ if ((nOut16 == 'G') || (nOut16 == 'H') || (nOut16 == 'C') ||
+ nOut16 == 'D')
+ {
+ nType = static_cast<sal_uInt8>(nOut16);
+ }
+ if (nType == 0)
+ {
+ //Error recovery, 2byte len + 3 characters of used type
+ xVBAProject->SeekRel(-(2 + 3 * (bIsUnicode ? 2 : 1)));
+ break;
+ }
+ }
+ }
+ maReferences.push_back(sReference);
+ }
+ return nType;
+}
+
+void VBA_Impl::Output( int nLen, const sal_uInt8*pData )
+{
+ /*
+ Each StarBasic module is tragically limited to the maximum len of a
+ string and WordBasic is not, so each overlarge module must be split
+ */
+ String sTemp((const sal_Char *)pData, (xub_StrLen)nLen,
+ meCharSet);
+ int nTmp = sTemp.GetTokenCount('\x0D');
+ int nIndex = aVBAStrings.GetSize()-1;
+ if (aVBAStrings.Get(nIndex)->Len() +
+ nLen + ((nLines+nTmp) * sComment.Len()) >= STRING_MAXLEN)
+ {
+ //DBG_ASSERT(0,"New Module String\n");
+ //we are too large for our boots, break out into another
+ //string
+ nLines=0;
+ nIndex++;
+ aVBAStrings.SetSize(nIndex+1);
+ aVBAStrings.Put(nIndex,new String);
+ }
+ *(aVBAStrings.Get(nIndex)) += sTemp;
+ nLines+=nTmp;
+}
+
+
+int VBA_Impl::ReadVBAProject(const SvStorageRef &rxVBAStorage)
+{
+ SvStorageStreamRef xVBAProject;
+ xVBAProject = rxVBAStorage->OpenSotStream(
+ String( RTL_CONSTASCII_USTRINGPARAM( "_VBA_PROJECT" ) ),
+ STREAM_STD_READ | STREAM_NOCREATE );
+
+ if( !xVBAProject.Is() || SVSTREAM_OK != xVBAProject->GetError() )
+ {
+ DBG_WARNING("Not able to find vba project, cannot find macros");
+ return 0;
+ }
+
+ static const sal_uInt8 aKnownId[] = {0xCC, 0x61};
+ sal_uInt8 aId[2];
+ xVBAProject->Read( aId, sizeof(aId) );
+ if (memcmp( aId, aKnownId, sizeof(aId)))
+ {
+ DBG_WARNING("unrecognized VBA macro project type");
+ return 0;
+ }
+
+ static const sal_uInt8 aOffice2003LE_2[] =
+ {
+ 0x79, 0x00, 0x00, 0x01, 0x00, 0xFF
+ };
+
+ static const sal_uInt8 aOffice2003LE[] =
+ {
+ 0x76, 0x00, 0x00, 0x01, 0x00, 0xFF
+ };
+
+ static const sal_uInt8 aOfficeXPLE[] =
+ {
+ 0x73, 0x00, 0x00, 0x01, 0x00, 0xFF
+ };
+
+ static const sal_uInt8 aOfficeXPBE[] =
+ {
+ 0x63, 0x00, 0x00, 0x0E, 0x00, 0xFF
+ };
+
+ static const sal_uInt8 aOffice2000LE[] =
+ {
+ 0x6D, 0x00, 0x00, 0x01, 0x00, 0xFF
+ };
+ static const sal_uInt8 aOffice98BE[] =
+ {
+ 0x60, 0x00, 0x00, 0x0E, 0x00, 0xFF
+ };
+ static const sal_uInt8 aOffice97LE[] =
+ {
+ 0x5E, 0x00, 0x00, 0x01, 0x00, 0xFF
+ };
+ sal_uInt8 aProduct[6];
+ xVBAProject->Read( aProduct, sizeof(aProduct) );
+
+ bool bIsUnicode;
+ if (!(memcmp(aProduct, aOffice2003LE, sizeof(aProduct))) ||
+ !(memcmp(aProduct, aOffice2003LE_2, sizeof(aProduct))) )
+ {
+ xVBAProject->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ bIsUnicode = true;
+ }
+ else if (!(memcmp(aProduct, aOfficeXPLE, sizeof(aProduct))))
+ {
+ xVBAProject->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ bIsUnicode = true;
+ }
+ else if (!(memcmp(aProduct, aOfficeXPBE, sizeof(aProduct))))
+ {
+ xVBAProject->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ mbMac = true;
+ bIsUnicode = false;
+ }
+ else if (!(memcmp(aProduct, aOffice2000LE, sizeof(aProduct))))
+ {
+ xVBAProject->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ bIsUnicode = true;
+ }
+ else if (!(memcmp(aProduct, aOffice98BE, sizeof(aProduct))))
+ {
+ xVBAProject->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
+ mbMac = true;
+ bIsUnicode = false;
+ }
+ else if (!(memcmp(aProduct, aOffice97LE, sizeof(aProduct))))
+ {
+ xVBAProject->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ bIsUnicode = true;
+ }
+ else
+ {
+ switch (aProduct[3])
+ {
+ case 0x1:
+ xVBAProject->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
+ bIsUnicode = true;
+ DBG_ASSERT(!this, "unrecognized VBA macro version, report to cmc. Guessing at unicode little endian");
+ break;
+ case 0xe:
+ xVBAProject->SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
+ mbMac = true;
+ bIsUnicode = false;
+ DBG_ASSERT(!this, "unrecognized VBA macro version, report to cmc. Guessing at 8bit big endian");
+ break;
+ default:
+ DBG_ASSERT(!this, "totally unrecognized VBA macro version, report to cmc");
+ return 0;
+ }
+ }
+
+ sal_uInt32 nLidA; //Language identifiers
+ sal_uInt32 nLidB;
+ sal_uInt16 nCharSet;
+ sal_uInt16 nLenA;
+ sal_uInt32 nUnknownB;
+ sal_uInt32 nUnknownC;
+ sal_uInt16 nLenB;
+ sal_uInt16 nLenC;
+ sal_uInt16 nLenD;
+
+ *xVBAProject >> nLidA >> nLidB >> nCharSet >> nLenA >> nUnknownB;
+ *xVBAProject >> nUnknownC >> nLenB >> nLenC >> nLenD;
+
+ meCharSet = rtl_getTextEncodingFromWindowsCodePage(nCharSet);
+
+ DBG_ASSERT(meCharSet != RTL_TEXTENCODING_DONTKNOW,
+ "don't know what vba charset to use");
+ if (meCharSet == RTL_TEXTENCODING_DONTKNOW)
+ meCharSet = RTL_TEXTENCODING_MS_1252;
+
+ if (nLenD != 0x02)
+ {
+ DBG_WARNING("Warning VBA number is different, please report");
+ return 0;
+ }
+
+ /*
+ A sequence of string that are prepended with a len and then begin with G
+ or H, there are also those that begin with C or D. If a string begins with
+ C or D, it is really two strings, one right after the other. Each string
+ then has a 12 bytes suffix
+
+ Recognizing the end of the sequence is done by finding a str len of < 6
+ which does not appear to be the beginning of an object id. Admittedly this
+ isn't a great test, but nothing in the header appears to count the number
+ of strings, and nothing else seems to match. So it'll have to do, its
+ protected by a number of secondry tests to prove its a valid string, and
+ everything gives up if this isn't proven.
+ */
+ bool bPredictsTrailingTwenty = false;
+ while (1)
+ {
+ sal_uInt8 nType = ReadPString(xVBAProject,bIsUnicode);
+ //Type C and D seem to come as pairs, so skip the following one
+ if (nType == 'C' || nType == 'D')
+ {
+ nType = ReadPString(xVBAProject,bIsUnicode);
+ DBG_ASSERT( nType == 'C' || nType == 'D',
+ "VBA: This must be a 'C' or 'D' string!" );
+ if (nType != 'C' && nType != 'D')
+ return 0;
+ }
+ if (!nType)
+ break;
+ xVBAProject->SeekRel(10);
+ sal_uInt16 nPredictsTrailingTwenty;
+ *xVBAProject >> nPredictsTrailingTwenty;
+ if (nPredictsTrailingTwenty)
+ bPredictsTrailingTwenty = true;
+ if (bPredictsTrailingTwenty)
+ {
+ sal_uInt16 nTestIsNotString;
+ *xVBAProject >> nTestIsNotString;
+ if (nTestIsNotString < MINVBASTRING)
+ {
+ DBG_ASSERT(nTestIsNotString <= 1,
+ "Haven't seen a len like this in VBA, report to CMC");
+ xVBAProject->SeekRel(18);
+ bPredictsTrailingTwenty = false;
+ }
+ else
+ xVBAProject->SeekRel(-2);
+ }
+ }
+
+ sal_Int16 nInt16s;
+ *xVBAProject >> nInt16s;
+ DBG_ASSERT( nInt16s >= 0, "VBA: Bad no of records in VBA Project, panic!" );
+ if (!nInt16s)
+ return 0;
+
+ xVBAProject->SeekRel(2*nInt16s);
+
+ sal_Int16 nInt32s;
+ *xVBAProject >> nInt32s;
+ DBG_ASSERT( nInt32s >= 0, "VBA: Bad no of records in VBA Project, panic!" );
+ if (!nInt32s)
+ return 0;
+ xVBAProject->SeekRel(4*nInt32s);
+
+ xVBAProject->SeekRel(2);
+ for(int k=0;k<3;k++)
+ {
+ sal_uInt16 nLen;
+ *xVBAProject >> nLen;
+ if (nLen != 0xFFFF)
+ xVBAProject->SeekRel(nLen);
+ }
+ xVBAProject->SeekRel(100); //Seems fixed len
+
+ *xVBAProject >> nOffsets;
+ DBG_ASSERT( nOffsets != 0xFFFF, "VBA: Bad nOffsets, panic!!" );
+ if ((nOffsets == 0xFFFF) || (nOffsets == 0))
+ return 0;
+ pOffsets = new VBAOffset_Impl[ nOffsets ];
+
+ int i, j;
+ for( i=0; i < nOffsets; i++)
+ {
+ sal_uInt16 nLen;
+ *xVBAProject >> nLen;
+
+ if (bIsUnicode)
+ {
+ sal_Unicode* pBuf = pOffsets[i].sName.AllocBuffer( nLen / 2 );
+ xVBAProject->Read( (sal_Char*)pBuf, nLen );
+
+#ifdef OSL_BIGENDIAN
+ for( j = 0; j < nLen / 2; ++j, ++pBuf )
+ *pBuf = SWAPSHORT( *pBuf );
+#endif // ifdef OSL_BIGENDIAN
+ }
+ else
+ {
+ ByteString aByteStr;
+ sal_Char* pByteData = aByteStr.AllocBuffer( nLen );
+ sal_Size nWasRead = xVBAProject->Read( pByteData, nLen );
+ if( nWasRead != nLen )
+ aByteStr.ReleaseBufferAccess();
+ pOffsets[i].sName += String( aByteStr, meCharSet);
+ }
+
+ *xVBAProject >> nLen;
+ xVBAProject->SeekRel( nLen );
+
+ //begin section, another problem area
+ *xVBAProject >> nLen;
+ if ( nLen == 0xFFFF)
+ {
+ xVBAProject->SeekRel(2);
+ *xVBAProject >> nLen;
+ xVBAProject->SeekRel( nLen );
+ }
+ else
+ xVBAProject->SeekRel( nLen+2 );
+
+ *xVBAProject >> nLen;
+ DBG_ASSERT( nLen == 0xFFFF, "VBA: Bad field in VBA Project, panic!!" );
+ if ( nLen != 0xFFFF)
+ return 0;
+
+ xVBAProject->SeekRel(6);
+ sal_uInt16 nOctects;
+ *xVBAProject >> nOctects;
+ for(j=0;j<nOctects;j++)
+ xVBAProject->SeekRel(8);
+
+ xVBAProject->SeekRel(5);
+ //end section
+
+ *xVBAProject >> pOffsets[i].nOffset;
+ xVBAProject->SeekRel(2);
+ }
+
+ return nOffsets;
+}
+
+
+/* #117718# For a given Module name return its type,
+ * Form, Class, Document, Normal or Unknown
+ *
+*/
+
+ModuleType VBA_Impl::GetModuleType( const UniString& rModuleName )
+{
+ ModuleTypeHash::iterator iter = mhModHash.find( rModuleName );
+ ModuleTypeHash::iterator iterEnd = mhModHash.end();
+ if ( iter != iterEnd )
+ {
+ return iter->second;
+ }
+ return Unknown;
+}
+
+bool VBA_Impl::Open( const String &rToplevel, const String &rSublevel )
+{
+ /* beginning test for vba stuff */
+ bool bRet = false;
+ SvStorageRef xMacros= xStor->OpenSotStorage( rToplevel,
+ STREAM_READWRITE | STREAM_NOCREATE |
+ STREAM_SHARE_DENYALL );
+ if( !xMacros.Is() || SVSTREAM_OK != xMacros->GetError() )
+ {
+ DBG_WARNING("No Macros Storage");
+ }
+ else
+ {
+ xVBA = xMacros->OpenSotStorage( rSublevel,
+ STREAM_READWRITE | STREAM_NOCREATE |
+ STREAM_SHARE_DENYALL );
+ if( !xVBA.Is() || SVSTREAM_OK != xVBA->GetError() )
+ {
+ DBG_WARNING("No Visual Basic in Storage");
+ }
+ else
+ {
+ if (ReadVBAProject(xVBA))
+ bRet = true;
+ }
+ /* #117718#
+ * Information regarding the type of module is contained in the
+ * "PROJECT" stream, this stream consists of a number of ascii lines
+ * entries are of the form Key=Value, the ones that we are interested
+ * in have the keys; Class, BaseClass & Module indicating the module
+ * ( value ) is either a Class Module, Form Module or a plain VB Module. */
+ SvStorageStreamRef xProject = xMacros->OpenSotStream(
+ String( RTL_CONSTASCII_USTRINGPARAM( "PROJECT" ) ) );
+ SvStorageStream* pStp = xProject;
+ UniString tmp;
+ static const String sThisDoc( RTL_CONSTASCII_USTRINGPARAM( "ThisDocument" ) );
+ static const String sModule( RTL_CONSTASCII_USTRINGPARAM( "Module" ) );
+ static const String sClass( RTL_CONSTASCII_USTRINGPARAM( "Class" ) );
+ static const String sBaseClass( RTL_CONSTASCII_USTRINGPARAM( "BaseClass" ) );
+ static const String sDocument( RTL_CONSTASCII_USTRINGPARAM( "Document" ) );
+ mhModHash[ sThisDoc ] = Class;
+ while ( pStp->ReadByteStringLine( tmp, meCharSet ) )
+ {
+ xub_StrLen index = tmp.Search( '=' );
+ if ( index != STRING_NOTFOUND )
+ {
+ String key = tmp.Copy( 0, index );
+ String value = tmp.Copy( index + 1 );
+ if ( key == sClass )
+ {
+ mhModHash[ value ] = Class;
+ OSL_TRACE("Module %s is of type Class",
+ ::rtl::OUStringToOString( value ,
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+ }
+ else if ( key == sBaseClass )
+ {
+ mhModHash[ value ] = Form;
+ OSL_TRACE("Module %s is of type Form",
+ ::rtl::OUStringToOString( value ,
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+ }
+ else if ( key == sDocument )
+ {
+ /* #i37965# DR 2004-12-03: add "Document", used i.e.
+ in Excel for macros attached to sheet or document. */
+
+ // value is of form <name>/&H<identifier>, strip the identifier
+ value.Erase( value.Search( '/' ) );
+
+ mhModHash[ value ] = Document;
+ OSL_TRACE("Module %s is of type Document VBA",
+ ::rtl::OUStringToOString( value ,
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+ }
+ else if ( key == sModule )
+ {
+ mhModHash[ value ] = Normal;
+ OSL_TRACE("Module %s is of type Normal VBA",
+ ::rtl::OUStringToOString( value ,
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+ }
+ }
+ }
+ }
+ /* end test for vba stuff */
+ return bRet;
+}
+
+const StringArray &VBA_Impl::Decompress(sal_uInt16 nIndex, int *pOverflow)
+{
+ DBG_ASSERT( nIndex < nOffsets, "Index out of range" );
+ SvStorageStreamRef xVBAStream;
+ aVBAStrings.SetSize(1);
+ aVBAStrings.Put(0,new String);
+
+ xVBAStream = xVBA->OpenSotStream( pOffsets[nIndex].sName,
+ STREAM_STD_READ | STREAM_NOCREATE );
+ if (pOverflow)
+ *pOverflow=0;
+
+ if( !xVBAStream.Is() || SVSTREAM_OK != xVBAStream->GetError() )
+ {
+ DBG_WARNING("Not able to open vb module ");
+ }
+ else
+ {
+ xVBAStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ DecompressVBA( nIndex, xVBAStream );
+ /*
+ * if len was too big for a single string set that variable ?
+ * if ((len > XX) && (pOverflow))
+ *pOverflow=1;
+ */
+ if (bCommented)
+ {
+ String sTempStringa;
+ if (mbMac)
+ sTempStringa = String( RTL_CONSTASCII_USTRINGPARAM( "\x0D" ) );
+ else
+ sTempStringa = String( RTL_CONSTASCII_USTRINGPARAM( "\x0D\x0A" ) );
+ String sTempStringb(sTempStringa);
+ sTempStringb+=sComment;
+ for(ULONG i=0;i<aVBAStrings.GetSize();i++)
+ {
+ aVBAStrings.Get(i)->SearchAndReplaceAll(
+ sTempStringa,sTempStringb);
+ aVBAStrings.Get(i)->Insert(sComment,0);
+ }
+ }
+ }
+ return aVBAStrings;
+}
+
+
+int VBA_Impl::DecompressVBA( int nIndex, SvStorageStreamRef &xVBAStream )
+{
+ sal_uInt8 nLeadbyte;
+ sal_uInt16 nToken;
+ unsigned int nPos = 0;
+ int nLen, nDistance, nShift, nClean=1;
+
+ xVBAStream->Seek( pOffsets[ nIndex ].nOffset + 3 );
+
+ while(xVBAStream->Read(&nLeadbyte,1))
+ {
+ for(int nPosition=0x01;nPosition < 0x100;nPosition=nPosition<<1)
+ {
+ //we see if the leadbyte has flagged this location as a dataunit
+ //which is actually a token which must be looked up in the history
+ if (nLeadbyte & nPosition)
+ {
+ *xVBAStream >> nToken;
+
+ if (nClean == 0)
+ nClean=1;
+
+ //For some reason the division of the token into the length
+ //field of the data to be inserted, and the distance back into
+ //the history differs depending on how full the history is
+ int nPos2 = nPos % nWINDOWLEN;
+ if (nPos2 <= 0x10)
+ nShift = 12;
+ else if (nPos2 <= 0x20)
+ nShift = 11;
+ else if (nPos2 <= 0x40)
+ nShift = 10;
+ else if (nPos2 <= 0x80)
+ nShift = 9;
+ else if (nPos2 <= 0x100)
+ nShift = 8;
+ else if (nPos2 <= 0x200)
+ nShift = 7;
+ else if (nPos2 <= 0x400)
+ nShift = 6;
+ else if (nPos2 <= 0x800)
+ nShift = 5;
+ else
+ nShift = 4;
+
+ int i;
+ nLen=0;
+ for(i=0;i<nShift;i++)
+ nLen |= nToken & (1<<i);
+
+ nLen += 3;
+
+ nDistance = nToken >> nShift;
+
+ //read the len of data from the history, wrapping around the
+ //nWINDOWLEN boundary if necessary data read from the history
+ //is also copied into the recent part of the history as well.
+ for (i = 0; i < nLen; i++)
+ {
+ unsigned char c;
+ c = aHistory[(nPos-nDistance-1) % nWINDOWLEN];
+ aHistory[nPos % nWINDOWLEN] = c;
+ nPos++;
+ }
+ }
+ else
+ {
+ // special boundary case code, not guarantueed to be correct
+ // seems to work though, there is something wrong with the
+ // compression scheme (or maybe a feature) where when the data
+ // ends on a nWINDOWLEN boundary and the excess bytes in the 8
+ // dataunit list are discarded, and not interpreted as tokens
+ // or normal data.
+ if ((nPos != 0) && ((nPos % nWINDOWLEN) == 0) && (nClean))
+ {
+ xVBAStream->SeekRel(2);
+ nClean=0;
+ Output(nWINDOWLEN, aHistory);
+ break;
+ }
+ //This is the normal case for when the data unit is not a
+ //token to be looked up, but instead some normal data which
+ //can be output, and placed in the history.
+ if (xVBAStream->Read(&aHistory[nPos % nWINDOWLEN],1))
+ nPos++;
+
+ if (nClean == 0)
+ nClean=1;
+ }
+ }
+ }
+ if (nPos % nWINDOWLEN)
+ Output(nPos % nWINDOWLEN,aHistory);
+ return(nPos);
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/filter/source/msfilter/msvbasic.hxx b/filter/source/msfilter/msvbasic.hxx
new file mode 100644
index 000000000000..b4ffd8514d4a
--- /dev/null
+++ b/filter/source/msfilter/msvbasic.hxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msvbasic.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#ifndef _MSVBASIC_HXX
+#define _MSVBASIC_HXX
+
+#ifdef _SOLAR_H
+#include <tools/solar.h>
+#endif
+#include <tools/debug.hxx>
+#include <sot/storage.hxx>
+#include <tools/dynary.hxx>
+#ifndef __SGI_STL_VECTOR
+#include <vector>
+#endif
+#include<map>
+
+/* class VBA:
+ * The VBA class provides a set of methods to handle Visual Basic For
+ * Applications streams, the constructor is given the root ole2 stream
+ * of the document, Open reads the VBA project file and figures out
+ * the number of VBA streams, and the offset of the data within them.
+ * Decompress decompresses a particular numbered stream, NoStreams returns
+ * this number, and StreamName can give you the streams name. Decompress
+ * will return a string with the decompressed data. The optional extra
+ * argument will be set if not NULL to 1 in the case of a string overflow,
+ * if I can figure out how to do that.
+ *
+ * Otherwise it is possible to inherit from VBA and implement a Output
+ * member which gets called with each 4096 output sized block.
+ *
+ * cmc
+ * */
+
+DECLARE_DYNARRAY(StringArray,String *)
+
+// #117718# define internal types to distinguish between
+// module types, form, class & normal
+// #i37965# DR 2004-12-03: add "Document", used in Excel for macros attached to sheet
+enum ModuleType { Unknown = 0, Normal, Class, Form, Document };
+
+// #117718# define map to hold types of module
+//
+
+typedef ::std::map< UniString,
+ ModuleType > ModuleTypeHash;
+
+class VBA_Impl
+{
+public:
+ VBA_Impl(SvStorage &rIn, bool bCmmntd = true);
+ ~VBA_Impl();
+ //0 for failure, 1 for success
+ bool Open( const String &rToplevel, const String &rSublevel);
+ const StringArray & Decompress(sal_uInt16 nIndex, int *pOverflow=0);
+ sal_uInt16 GetNoStreams() const { return nOffsets; }
+ const String &GetStreamName(sal_uInt16 nIndex) const
+ {
+ DBG_ASSERT( nIndex < nOffsets, "Index out of range" );
+ return pOffsets[ nIndex ].sName;
+ }
+ //I'm the method that would be made virtual to make this class
+ //useful elsewhere
+ void Output(int len, const sal_uInt8 *data);
+ //
+ // #117718# member map of module names to types of module
+ ModuleType GetModuleType( const UniString& rModuleName );
+
+ std::vector<String> maReferences;
+private:
+ struct VBAOffset_Impl
+ {
+ String sName;
+ sal_uInt32 nOffset;
+ };
+
+ // #117718# member map of module names to types of module
+ ModuleTypeHash mhModHash;
+ SvStorageRef xVBA;
+ StringArray aVBAStrings;
+ String sComment;
+ SvStorageRef xStor;
+ VBAOffset_Impl *pOffsets;
+ sal_uInt16 nOffsets;
+ enum Limits {nWINDOWLEN = 4096};
+ sal_uInt8 aHistory[nWINDOWLEN];
+ rtl_TextEncoding meCharSet;
+ bool bCommented;
+ bool mbMac;
+ int nLines;
+
+ //0 for failure, anything else for success
+ int ReadVBAProject(const SvStorageRef &rxVBAStorage);
+ int DecompressVBA(int index, SvStorageStreamRef &rxVBAStream);
+ sal_uInt8 ReadPString(SvStorageStreamRef &xVBAProject, bool bIsUnicode);
+};
+
+#endif
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx
new file mode 100644
index 000000000000..def643c93ffc
--- /dev/null
+++ b/filter/source/msfilter/svdfppt.cxx
@@ -0,0 +1,7802 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svdfppt.cxx,v $
+ * $Revision: 1.163.6.5 $
+ *
+ * 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_filter.hxx"
+#include <osl/endian.h>
+#include <vcl/svapp.hxx>
+#include <unotools/tempfile.hxx>
+#include <math.h>
+#include <svx/eeitem.hxx>
+#include <sot/storage.hxx>
+#include <sot/storinfo.hxx>
+#include <sot/stg.hxx>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/office/XAnnotation.hpp>
+#include <com/sun/star/office/XAnnotationAccess.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/geometry/RealPoint2D.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <unotools/streamwrap.hxx>
+#include <filter/msfilter/svdfppt.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdorect.hxx>
+#include <svx/svdopage.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdotable.hxx>
+#include <svx/outlobj.hxx>
+#include <svx/svdattr.hxx>
+#include "svx/xattr.hxx"
+#include "svx/svditext.hxx"
+#include <svx/svdetc.hxx>
+#include <svx/bulitem.hxx>
+#include <svx/polysc3d.hxx>
+#include <svx/extrud3d.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/tstpitem.hxx>
+#include <svx/unoprnms.hxx>
+
+#if defined(JOEENV) && defined(JOEDEBUG)
+#include "impinccv.h" // etwas Testkram
+#endif
+
+#if defined(DBG_EXTRACTOLEOBJECTS) || defined(DBG_EXTRACTFONTMETRICS)
+#include <tools/urlobj.hxx>
+#include <unotools/localfilehelper.hxx>
+#endif
+
+#define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
+#include <svx/adjitem.hxx>
+#include <svx/escpitem.hxx>
+#include <svx/colritem.hxx>
+#include <svx/fhgtitem.hxx>
+#include <svx/wghtitem.hxx>
+#include <svx/postitem.hxx>
+#include <svx/udlnitem.hxx>
+#include <svx/crsditem.hxx>
+#include <svx/shdditem.hxx>
+#include <svx/charreliefitem.hxx>
+#include <svx/fontitem.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/editeng.hxx>
+#include <svx/lspcitem.hxx>
+#include <svx/ulspitem.hxx>
+#include <svx/lrspitem.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/bmpacc.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdoedge.hxx>
+#include <svx/sxekitm.hxx>
+#include <svx/flditem.hxx>
+#include <svtools/sychconv.hxx>
+#include <tools/zcodec.hxx>
+#include <filter/msfilter/svxmsbas.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/brshitem.hxx>
+#include <svx/langitem.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/unoapi.hxx>
+#include <toolkit/unohlp.hxx>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/form/XFormComponent.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <svx/writingmodeitem.hxx>
+#include <vcl/print.hxx>
+#include <svx/svxfont.hxx>
+#include <svx/frmdiritem.hxx>
+#include <svx/sdtfchim.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <svx/scripttypeitem.hxx>
+#include "com/sun/star/awt/Gradient.hpp"
+#include <com/sun/star/table/XMergeableCellRange.hpp>
+#include <com/sun/star/table/BorderLine.hpp>
+#include <vcl/virdev.hxx>
+#include <algorithm>
+#include <set>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// PPT ColorScheme Slots
+#define PPT_COLSCHEME (0x08000000)
+#define PPT_COLSCHEME_HINTERGRUND (0x08000000)
+#define PPT_COLSCHEME_TEXT_UND_ZEILEN (0x08000001)
+#define PPT_COLSCHEME_SCHATTEN (0x08000002)
+#define PPT_COLSCHEME_TITELTEXT (0x08000003)
+#define PPT_COLSCHEME_FUELLBEREICHE (0x08000004)
+#define PPT_COLSCHEME_AKZENT (0x08000005)
+#define PPT_COLSCHEME_A_UND_HYPERLINK (0x08000006)
+#define PPT_COLSCHEME_A_H_GESICHERT (0x08000007)
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define ANSI_CHARSET 0
+#define DEFAULT_CHARSET 1
+#define SYMBOL_CHARSET 2
+#define SHIFTJIS_CHARSET 128
+#define HANGEUL_CHARSET 129
+#define CHINESEBIG5_CHARSET 136
+#define OEM_CHARSET 255
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/* Font Families */
+#define FF_DONTCARE 0x00
+#define FF_ROMAN 0x10
+#define FF_SWISS 0x20
+#define FF_MODERN 0x30
+#define FF_SCRIPT 0x40
+#define FF_DECORATIVE 0x50
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define DEFAULT_PITCH 0x00
+#define FIXED_PITCH 0x01
+#define VARIABLE_PITCH 0x02
+
+using namespace ::com::sun::star ;
+using namespace uno ;
+using namespace beans ;
+using namespace drawing ;
+using namespace container ;
+using namespace table ;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PowerPointImportParam::PowerPointImportParam( SvStream& rDocStrm, sal_uInt32 nFlags, MSFilterTracer* pT ) :
+ rDocStream ( rDocStrm ),
+ nImportFlags ( nFlags ),
+ pTracer ( pT )
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>( SvStream& rIn, PptCurrentUserAtom& rAtom )
+{
+ DffRecordHeader aHd;
+ rIn >> aHd;
+ if ( aHd.nRecType == PPT_PST_CurrentUserAtom )
+ {
+ sal_uInt32 nLen;
+ sal_uInt16 nUserNameLen, nPad;
+ rIn >> nLen
+ >> rAtom.nMagic
+ >> rAtom.nCurrentUserEdit
+ >> nUserNameLen
+ >> rAtom.nDocFileVersion
+ >> rAtom.nMajorVersion
+ >> rAtom.nMinorVersion
+ >> nPad;
+ SvxMSDffManager::MSDFFReadZString( rIn, rAtom.aCurrentUser, nUserNameLen, sal_True );
+ }
+ aHd.SeekToEndOfRecord( rIn );
+ return rIn;
+}
+
+void PptSlidePersistAtom::Clear()
+{
+ nReserved = nPsrReference = nFlags = nNumberTexts = nSlideId = 0;
+}
+
+SvStream& operator>>( SvStream& rIn, PptSlidePersistAtom& rAtom )
+{
+ DffRecordHeader aHd;
+ rIn >> aHd
+ >> rAtom.nPsrReference
+ >> rAtom.nFlags
+ >> rAtom.nNumberTexts
+ >> rAtom.nSlideId;
+// >> rAtom.nReserved;
+ aHd.SeekToEndOfRecord( rIn );
+ return rIn;
+}
+
+SV_IMPL_PTRARR(_PptSlidePersistList,PptSlidePersistEntry*);
+
+USHORT PptSlidePersistList::FindPage(UINT32 nId) const
+{
+ for ( USHORT i=0; i < Count(); i++ )
+ {
+ if (operator[](i)->GetSlideId()==nId) return i;
+ }
+ return PPTSLIDEPERSIST_ENTRY_NOTFOUND;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>( SvStream& rIn, PptInteractiveInfoAtom& rAtom )
+{
+ rIn >> rAtom.nSoundRef
+ >> rAtom.nExHyperlinkId
+ >> rAtom.nAction
+ >> rAtom.nOleVerb
+ >> rAtom.nJump
+ >> rAtom.nFlags
+ >> rAtom.nHyperlinkType
+ >> rAtom.nUnknown1
+ >> rAtom.nUnknown2
+ >> rAtom.nUnknown3;
+ return rIn;
+}
+
+SvStream& operator>>( SvStream& rIn, PptExOleObjAtom& rAtom )
+{
+ rIn >> rAtom.nAspect
+ >> rAtom.nDummy1
+ >> rAtom.nId
+ >> rAtom.nDummy2
+ >> rAtom.nPersistPtr
+ >> rAtom.nDummy4;
+ return rIn;
+}
+
+Size PptDocumentAtom::GetPageSize(const Size& rSiz) const
+{
+ return rSiz;
+/*
+ Size aRet;
+ switch ( eSlidesPageFormat )
+ {
+ // Wenn man in Powerpoint als Seitenformat "Bildschirmgroesse"
+ // einstellt, dann zeigt dieser Dialog zwar 24x18cm an, die
+ // angezeigte Seite ist aber anders. Das sieht man, wenn man
+ // ein Rechteck seitenfuellend aufzieht und sich dessen Groesse
+ // ansieht. Die importierten Abmessungen sind auf jeden Fall
+ // die, die auch im Ppt-File stehen. Ich denke, das es sich
+ // hier eher um ein Bug in PowerPoint handelt, das im
+ // Seitenformat-Dialog bei "Bildschirmgroesse" falsche Masse
+ // angezeigt werden (vielleicht ja auch bildschirmabhaengig?).
+// case PPTPF_SCREEN : aRet.Width()=4082; aRet.Height()=5443; break;
+ case PPTPF_USLETTER: aRet.Width()=4896; aRet.Height()=6336; break;
+ case PPTPF_A4 : aRet.Width()=4762; aRet.Height()=6735; break;
+// case PPTPF_35MMDIA : aRet.Width()=4082; aRet.Height()=6123; break;
+// case PPTPF_OVERHEAD: aRet.Width()=4082; aRet.Height()=5443; break;
+ }
+ if ( aRet.Width() )
+ {
+ if ( rSiz.Width() > rSiz.Height() )
+ { // Querformat
+ long nMerk = aRet.Width();
+ aRet.Width() = aRet.Height();
+ aRet.Height() = nMerk;
+ }
+ }
+ else // CustomFormat oder Unbekannt oder Screen,Dia,Overhead
+ aRet = rSiz;
+ return aRet;
+*/
+}
+
+SvStream& operator>>(SvStream& rIn, PptDocumentAtom& rAtom)
+{
+// Tatsaechliches Format:
+// 00 aSlidePageSizeXY 8
+// 08 aNotesPageSizeXY 8
+// 16 aZoomRatio (OLE) 8
+// 24 nNotesMasterPersist 4
+// 28 nHandoutMasterPersist 4
+// 32 n1stPageNumber 2
+// 34 ePageFormat 2
+// 36 bEmbeddedTrueType 1
+// 37 bOmitTitlePlace 1
+// 38 bRightToLeft 1
+// 39 bShowComments 1
+
+ DffRecordHeader aHd;
+ INT32 nSlideX,nSlideY, nNoticeX, nNoticeY, nDummy;
+ UINT16 nSlidePageFormat;
+ INT8 nEmbeddedTrueType, nTitlePlaceHoldersOmitted, nRightToLeft, nShowComments;
+
+ rIn >> aHd
+ >> nSlideX >> nSlideY
+ >> nNoticeX >> nNoticeY
+ >> nDummy >> nDummy // ZoomRation ueberspringen
+ >> rAtom.nNotesMasterPersist
+ >> rAtom.nHandoutMasterPersist
+ >> rAtom.n1stPageNumber
+ >> nSlidePageFormat
+ >> nEmbeddedTrueType
+ >> nTitlePlaceHoldersOmitted
+ >> nRightToLeft
+ >> nShowComments;
+ rAtom.aSlidesPageSize.Width() = nSlideX;
+ rAtom.aSlidesPageSize.Height() = nSlideY;
+ rAtom.aNotesPageSize.Width() = nNoticeX;
+ rAtom.aNotesPageSize.Height() = nNoticeY;
+ rAtom.eSlidesPageFormat = (PptPageFormat)nSlidePageFormat;
+ rAtom.bEmbeddedTrueType = nEmbeddedTrueType;
+ rAtom.bTitlePlaceholdersOmitted = nTitlePlaceHoldersOmitted;
+ rAtom.bRightToLeft = nRightToLeft;
+ rAtom.bShowComments = nShowComments;
+ aHd.SeekToEndOfRecord( rIn );
+ return rIn;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void PptSlideLayoutAtom::Clear()
+{
+ eLayout = 0;
+ for ( USHORT i = 0; i < 8; i++ )
+ {
+ aPlaceholderId[ i ] = 0;
+ aPlacementId[ i ] = 0;
+ }
+}
+
+SvStream& operator>>( SvStream& rIn, PptSlideLayoutAtom& rAtom )
+{
+ rIn >> rAtom.eLayout;
+ rIn.Read( rAtom.aPlaceholderId, 8 );
+ return rIn;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>( SvStream& rIn, PptSlideAtom& rAtom )
+{
+ DffRecordHeader aHd;
+ rIn >> aHd
+ >> rAtom.aLayout
+ >> rAtom.nMasterId
+ >> rAtom.nNotesId
+ >> rAtom.nFlags;
+ aHd.SeekToEndOfRecord( rIn );
+ return rIn;
+}
+
+void PptSlideAtom::Clear()
+{
+ nMasterId = nNotesId = 0;
+ nFlags = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>( SvStream& rIn, PptNotesAtom& rAtom )
+{
+ DffRecordHeader aHd;
+ rIn >> aHd
+ >> rAtom.nSlideId
+ >> rAtom.nFlags;
+ aHd.SeekToEndOfRecord( rIn );
+ return rIn;
+}
+
+void PptNotesAtom::Clear()
+{
+ nSlideId = 0;
+ nFlags = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void PptColorSchemeAtom::Clear()
+{
+ memset(&aData[0], 0, 32);
+}
+
+Color PptColorSchemeAtom::GetColor( USHORT nNum ) const
+{
+ Color aRetval;
+ if ( nNum < 8 )
+ {
+ nNum <<= 2;
+ aRetval.SetRed( aData[ nNum++ ] );
+ aRetval.SetGreen( aData[ nNum++ ] );
+ aRetval.SetBlue( aData[ nNum++ ] );
+ }
+ return aRetval;
+}
+
+SvStream& operator>>( SvStream& rIn, PptColorSchemeAtom& rAtom )
+{
+ DffRecordHeader aHd;
+ rIn >> aHd;
+ rIn.Read( rAtom.aData, 32 );
+ aHd.SeekToEndOfRecord( rIn );
+ return rIn;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>( SvStream& rIn, PptFontEntityAtom& rAtom )
+{
+ DffRecordHeader aHd;
+ rIn >> aHd;
+ sal_Unicode nTemp, cData[ 32 ];
+ rIn.Read( cData, 64 );
+
+ sal_uInt8 lfCharset, lfPitchAndFamily;
+
+ rIn >> lfCharset
+ >> rAtom.lfClipPrecision
+ >> rAtom.lfQuality
+ >> lfPitchAndFamily;
+
+ switch( lfCharset )
+ {
+ case SYMBOL_CHARSET :
+ rAtom.eCharSet = RTL_TEXTENCODING_SYMBOL;
+ break;
+ case ANSI_CHARSET :
+ rAtom.eCharSet = RTL_TEXTENCODING_MS_1252;
+ break;
+
+// case DEFAULT_CHARSET :
+// case SHIFTJIS_CHARSET :
+// case HANGEUL_CHARSET :
+// case CHINESEBIG5_CHARSET :
+// case OEM_CHARSET :
+ default :
+ rAtom.eCharSet = gsl_getSystemTextEncoding();
+ }
+ switch ( lfPitchAndFamily & 0xf0 )
+ {
+ case FF_ROMAN:
+ rAtom.eFamily = FAMILY_ROMAN;
+ break;
+
+ case FF_SWISS:
+ rAtom.eFamily = FAMILY_SWISS;
+ break;
+
+ case FF_MODERN:
+ rAtom.eFamily = FAMILY_MODERN;
+ break;
+
+ case FF_SCRIPT:
+ rAtom.eFamily = FAMILY_SCRIPT;
+ break;
+
+ case FF_DECORATIVE:
+ rAtom.eFamily = FAMILY_DECORATIVE;
+ break;
+
+ default:
+ rAtom.eFamily = FAMILY_DONTKNOW;
+ break;
+ }
+
+ switch ( lfPitchAndFamily & 0x0f )
+ {
+ case FIXED_PITCH:
+ rAtom.ePitch = PITCH_FIXED;
+ break;
+
+ case DEFAULT_PITCH:
+ case VARIABLE_PITCH:
+ default:
+ rAtom.ePitch = PITCH_VARIABLE;
+ break;
+ }
+ sal_uInt16 i;
+ for ( i = 0; i < 32; i++ )
+ {
+ nTemp = cData[ i ];
+ if ( !nTemp )
+ break;
+#ifdef OSL_BIGENDIAN
+ cData[ i ] = ( nTemp >> 8 ) | ( nTemp << 8 );
+#endif
+ }
+ rAtom.aName = String( cData, i );
+ OutputDevice* pDev = (OutputDevice*)Application::GetDefaultDevice();
+ rAtom.bAvailable = pDev->IsFontAvailable( rAtom.aName );
+ aHd.SeekToEndOfRecord( rIn );
+ return rIn;
+}
+
+SV_DECL_PTRARR_DEL( PptFontEntityAtomList, PptFontEntityAtom*, 16, 16 )
+SV_IMPL_PTRARR( PptFontEntityAtomList, PptFontEntityAtom* );
+
+class PptFontCollection: public PptFontEntityAtomList {
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>( SvStream& rIn, PptUserEditAtom& rAtom )
+{
+ rIn >> rAtom.aHd
+ >> rAtom.nLastSlideID
+ >> rAtom.nVersion
+ >> rAtom.nOffsetLastEdit
+ >> rAtom.nOffsetPersistDirectory
+ >> rAtom.nDocumentRef
+ >> rAtom.nMaxPersistWritten
+ >> rAtom.eLastViewType;
+ rAtom.aHd.SeekToEndOfRecord(rIn);
+ return rIn;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void PptOEPlaceholderAtom::Clear()
+{
+ nPlacementId = 0;
+ nPlaceholderSize = nPlaceholderId = 0;
+}
+
+SvStream& operator>>( SvStream& rIn, PptOEPlaceholderAtom& rAtom )
+{
+ rIn >> rAtom.nPlacementId
+ >> rAtom.nPlaceholderId
+ >> rAtom.nPlaceholderSize;
+ return rIn;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PptSlidePersistEntry::PptSlidePersistEntry() :
+ pStyleSheet ( NULL ),
+ pHeaderFooterEntry ( NULL ),
+ pSolverContainer ( NULL ),
+ nSlidePersistStartOffset( 0 ),
+ nSlidePersistEndOffset ( 0 ),
+ nBackgroundOffset ( 0 ),
+ nDrawingDgId ( 0xffffffff ),
+ pPresentationObjects ( NULL ),
+ pBObj ( NULL ),
+ bBObjIsTemporary ( sal_True ),
+ ePageKind ( PPT_MASTERPAGE ),
+ bNotesMaster ( FALSE ),
+ bHandoutMaster ( FALSE ),
+ bStarDrawFiller ( FALSE )
+{
+ HeaderFooterOfs[ 0 ] = HeaderFooterOfs[ 1 ] = HeaderFooterOfs[ 2 ] = HeaderFooterOfs[ 3 ] = 0;
+}
+
+
+PptSlidePersistEntry::~PptSlidePersistEntry()
+{
+ delete pStyleSheet;
+ delete pSolverContainer;
+ delete[] pPresentationObjects;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrEscherImport::SdrEscherImport( PowerPointImportParam& rParam, const String& rBaseURL ) :
+ SvxMSDffManager ( rParam.rDocStream, rBaseURL, rParam.pTracer ),
+ pFonts ( NULL ),
+ nStreamLen ( 0 ),
+ nTextStylesIndex ( 0xffff ),
+ eCharSetSystem ( gsl_getSystemTextEncoding() ),
+ bWingdingsChecked ( FALSE ),
+ bWingdingsAvailable ( FALSE ),
+ bMonotypeSortsChecked ( FALSE ),
+ bMonotypeSortsAvailable ( FALSE ),
+ bTimesNewRomanChecked ( FALSE ),
+ bTimesNewRomanAvailable ( FALSE ),
+ rImportParam ( rParam )
+{
+}
+
+SdrEscherImport::~SdrEscherImport()
+{
+ void* pPtr;
+ for ( pPtr = aOleObjectList.First(); pPtr; pPtr = aOleObjectList.Next() )
+ delete (PPTOleEntry*)pPtr;
+ delete pFonts;
+}
+
+const PptSlideLayoutAtom* SdrEscherImport::GetSlideLayoutAtom() const
+{
+ return NULL;
+}
+
+sal_Bool SdrEscherImport::ReadString( String& rStr ) const
+{
+ sal_Bool bRet = FALSE;
+ DffRecordHeader aStrHd;
+ rStCtrl >> aStrHd;
+ if (aStrHd.nRecType == PPT_PST_TextBytesAtom
+ || aStrHd.nRecType == PPT_PST_TextCharsAtom
+ || aStrHd.nRecType == PPT_PST_CString)
+ {
+ sal_Bool bUniCode =
+ (aStrHd.nRecType == PPT_PST_TextCharsAtom
+ || aStrHd.nRecType == PPT_PST_CString);
+ bRet=TRUE;
+ ULONG nBytes = aStrHd.nRecLen;
+ MSDFFReadZString( rStCtrl, rStr, nBytes, bUniCode );
+ aStrHd.SeekToEndOfRecord( rStCtrl );
+ }
+ else
+ aStrHd.SeekToBegOfRecord( rStCtrl );
+ return bRet;
+}
+
+FASTBOOL SdrEscherImport::GetColorFromPalette(USHORT /*nNum*/, Color& /*rColor*/) const
+{
+ return FALSE;
+}
+
+BOOL SdrEscherImport::SeekToShape( SvStream& /*rSt*/, void* /*pClientData*/, UINT32 /*nId*/) const
+{
+ return FALSE;
+}
+
+PptFontEntityAtom* SdrEscherImport::GetFontEnityAtom( UINT32 nNum ) const
+{
+ PptFontEntityAtom* pRetValue = NULL;
+ if ( pFonts && ( nNum < pFonts->Count() ) )
+ pRetValue = (*pFonts)[ (USHORT)nNum ];
+ return pRetValue;
+}
+
+CharSet SdrEscherImport::GetCharSet( UINT32 nNum ) const
+{
+ CharSet eRetValue( eCharSetSystem );
+ if ( pFonts && ( nNum < pFonts->Count() ) )
+ eRetValue = (*pFonts)[ (USHORT)nNum ]->eCharSet;
+ return eRetValue;
+}
+
+BOOL SdrEscherImport::IsFontAvailable( UINT32 nNum ) const
+{
+ BOOL bRetValue = FALSE;
+ if ( pFonts && ( nNum < pFonts->Count() ) )
+ bRetValue = (*pFonts)[ (USHORT)nNum ]->bAvailable;
+ return bRetValue;
+}
+
+SdrObject* SdrEscherImport::ReadObjText( PPTTextObj* /*pTextObj*/, SdrObject* pObj, SdPage* /*pPage*/) const
+{
+ return pObj;
+}
+
+void SdrEscherImport::ProcessClientAnchor2( SvStream& rSt, DffRecordHeader& rHd, void* /*pData*/, DffObjData& rObj )
+{
+ sal_Int32 l, t, r, b;
+ if ( rHd.nRecLen == 16 )
+ {
+ rSt >> l >> t >> r >> b;
+ }
+ else
+ {
+ INT16 ls, ts, rs, bs;
+ rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ...
+ l = ls, t = ts, r = rs, b = bs;
+ }
+ Scale( l );
+ Scale( t );
+ Scale( r );
+ Scale( b );
+ rObj.aChildAnchor = Rectangle( l, t, r, b );
+ rObj.bChildAnchor = TRUE;
+ return;
+};
+
+void SdrEscherImport::RecolorGraphic( SvStream& rSt, sal_uInt32 nRecLen, Graphic& rGraphic )
+{
+ if ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE )
+ {
+ sal_uInt16 nX, nGlobalColorsCount, nFillColorsCount;
+
+ rSt >> nX
+ >> nGlobalColorsCount
+ >> nFillColorsCount
+ >> nX
+ >> nX
+ >> nX;
+
+ if ( ( nGlobalColorsCount <= 64 ) && ( nFillColorsCount <= 64 ) )
+ {
+ if ( (sal_uInt32)( ( nGlobalColorsCount + nFillColorsCount ) * 44 + 12 ) == nRecLen )
+ {
+ sal_uInt32 OriginalGlobalColors[ 64 ];
+ sal_uInt32 NewGlobalColors[ 64 ];
+ sal_uInt32 OriginalFillColors[ 64 ];
+ sal_uInt32 NewFillColors[ 64 ];
+
+ sal_uInt32 i, j, nGlobalColorsChanged, nFillColorsChanged;
+ nGlobalColorsChanged = nFillColorsChanged = 0;
+
+ sal_uInt32* pCurrentOriginal = OriginalGlobalColors;
+ sal_uInt32* pCurrentNew = NewGlobalColors;
+ sal_uInt32* pCount = &nGlobalColorsChanged;
+ i = nGlobalColorsCount;
+
+ for ( j = 0; j < 2; j++ )
+ {
+ for ( ; i > 0; i-- )
+ {
+ sal_uInt32 nIndex, nPos = rSt.Tell();
+ sal_uInt8 nDummy, nRed, nGreen, nBlue;
+ sal_uInt16 nChanged;
+ rSt >> nChanged;
+ if ( nChanged & 1 )
+ {
+ sal_uInt32 nColor = 0;
+ rSt >> nDummy
+ >> nRed
+ >> nDummy
+ >> nGreen
+ >> nDummy
+ >> nBlue
+ >> nIndex;
+
+ if ( nIndex < 8 )
+ {
+ Color aColor = MSO_CLR_ToColor( nIndex << 24 );
+ nRed = aColor.GetRed();
+ nGreen = aColor.GetGreen();
+ nBlue = aColor.GetBlue();
+ }
+ nColor = nRed | ( nGreen << 8 ) | ( nBlue << 16 );
+ *pCurrentNew++ = nColor;
+ rSt >> nDummy
+ >> nRed
+ >> nDummy
+ >> nGreen
+ >> nDummy
+ >> nBlue;
+ nColor = nRed | ( nGreen << 8 ) | ( nBlue << 16 );
+ *pCurrentOriginal++ = nColor;
+ (*pCount)++;
+ }
+ rSt.Seek( nPos + 44 );
+ }
+ pCurrentOriginal = OriginalFillColors;
+ pCurrentNew = NewFillColors;
+ pCount = &nFillColorsChanged;
+ i = nFillColorsCount;
+ }
+ if ( nGlobalColorsChanged || nFillColorsChanged )
+ {
+ Color* pSearchColors = new Color[ nGlobalColorsChanged ];
+ Color* pReplaceColors = new Color[ nGlobalColorsChanged ];
+
+ for ( j = 0; j < nGlobalColorsChanged; j++ )
+ {
+ sal_uInt32 nSearch = OriginalGlobalColors[ j ];
+ sal_uInt32 nReplace = NewGlobalColors[ j ];
+
+ pSearchColors[ j ].SetRed( (BYTE)nSearch );
+ pSearchColors[ j ].SetGreen( (BYTE)( nSearch >> 8 ) );
+ pSearchColors[ j ].SetBlue( (BYTE)( nSearch >> 16 ) );
+
+ pReplaceColors[ j ].SetRed( (BYTE)nReplace );
+ pReplaceColors[ j ].SetGreen( (BYTE)( nReplace >> 8 ) );
+ pReplaceColors[ j ].SetBlue( (BYTE)( nReplace >> 16 ) );
+ }
+ GDIMetaFile aGdiMetaFile( rGraphic.GetGDIMetaFile() );
+ aGdiMetaFile.ReplaceColors( pSearchColors, pReplaceColors,
+ nGlobalColorsChanged, NULL );
+ rGraphic = aGdiMetaFile;
+
+ delete[] pSearchColors;
+ delete[] pReplaceColors;
+ }
+ }
+ }
+ }
+}
+
+/* ProcessObject is called from ImplSdPPTImport::ProcessObj to hanlde all application specific things,
+ such as the import of text, animation effects, header footer and placeholder.
+
+ The parameter pOriginalObj is the object as it was imported by our general escher import, it must either
+ be deleted or it can be returned to be inserted into the sdr page.
+*/
+SdrObject* SdrEscherImport::ProcessObj( SvStream& rSt, DffObjData& rObjData, void* pData, Rectangle& rTextRect, SdrObject* pOriginalObj )
+{
+ if ( pOriginalObj && pOriginalObj->ISA( SdrObjCustomShape ) )
+ pOriginalObj->SetMergedItem( SdrTextFixedCellHeightItem( TRUE ) );
+
+ // we are initializing our return value with the object that was imported by our escher import
+ SdrObject* pRet = pOriginalObj;
+
+ ProcessData& rData = *((ProcessData*)pData);
+ PptSlidePersistEntry& rPersistEntry = rData.rPersistEntry;
+
+ if ( ! ( rObjData.nSpFlags & SP_FGROUP ) ) // sj: #114758# ...
+ {
+ PptOEPlaceholderAtom aPlaceholderAtom;
+ INT16 nHeaderFooterInstance = -1;
+
+ if ( maShapeRecords.SeekToContent( rSt, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) )
+ {
+ DffRecordHeader aClientDataHd;
+ while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < maShapeRecords.Current()->GetRecEndFilePos() ) )
+ {
+ rSt >> aClientDataHd;
+ switch ( aClientDataHd.nRecType )
+ {
+ // importing header/footer object from master page
+ case PPT_PST_OEPlaceholderAtom :
+ {
+ rSt >> aPlaceholderAtom;
+ if ( nHeaderFooterInstance == -1 )
+ {
+ switch ( aPlaceholderAtom.nPlaceholderId )
+ {
+ case PPT_PLACEHOLDER_MASTERSLIDENUMBER : nHeaderFooterInstance++;
+ case PPT_PLACEHOLDER_MASTERFOOTER : nHeaderFooterInstance++;
+ case PPT_PLACEHOLDER_MASTERHEADER : nHeaderFooterInstance++;
+ case PPT_PLACEHOLDER_MASTERDATE : nHeaderFooterInstance++; break;
+ }
+ if ( ! ( nHeaderFooterInstance & 0xfffc ) ) // is this a valid instance ( 0->3 )
+ rPersistEntry.HeaderFooterOfs[ nHeaderFooterInstance ] = rObjData.rSpHd.GetRecBegFilePos();
+ }
+ }
+ break;
+
+ case PPT_PST_RecolorInfoAtom :
+ {
+ if ( pRet && ( pRet->ISA( SdrGrafObj ) && ((SdrGrafObj*)pRet)->HasGDIMetaFile() ) )
+ {
+ Graphic aGraphic( ((SdrGrafObj*)pRet)->GetGraphic() );
+ RecolorGraphic( rSt, aClientDataHd.nRecLen, aGraphic );
+ ((SdrGrafObj*)pRet)->SetGraphic( aGraphic );
+ }
+ }
+ break;
+ }
+ aClientDataHd.SeekToEndOfRecord( rSt );
+ }
+ }
+ if ( ( aPlaceholderAtom.nPlaceholderId == PPT_PLACEHOLDER_NOTESSLIDEIMAGE ) && ( rPersistEntry.bNotesMaster == FALSE ) )
+ {
+ USHORT nPageNum = pSdrModel->GetPageCount();
+ if ( nPageNum > 0 )
+ nPageNum--;
+
+ // replacing the object which we will return with a SdrPageObj
+ SdrObject::Free( pRet );
+ pRet = new SdrPageObj( rObjData.aBoundRect, pSdrModel->GetPage( nPageNum - 1 ) );
+ }
+ else
+ {
+ // try to load some ppt text
+ PPTTextObj aTextObj( rSt, (SdrPowerPointImport&)*this, rPersistEntry, &rObjData );
+ if ( ( aTextObj.Count() || aTextObj.GetOEPlaceHolderAtom() ) )
+ {
+ sal_Bool bVerticalText = sal_False;
+ // and if the text object is not empty, it must be applied to pRet, the object we
+ // initially got from our escher import
+ INT32 nTextRotationAngle = 0;
+ if ( IsProperty( DFF_Prop_txflTextFlow ) )
+ {
+ MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
+ switch( eTextFlow )
+ {
+ case mso_txflBtoT : // Bottom to Top non-@, unten -> oben
+ nTextRotationAngle += 9000;
+ break;
+ case mso_txflTtoBA : /* #68110# */ // Top to Bottom @-font, oben -> unten
+ case mso_txflTtoBN : // Top to Bottom non-@, oben -> unten
+ case mso_txflVertN : // Vertical, non-@, oben -> unten
+ bVerticalText = !bVerticalText; // nTextRotationAngle += 27000;
+ break;
+ // case mso_txflHorzN : // Horizontal non-@, normal
+ // case mso_txflHorzA : // Horizontal @-font, normal
+ default: break;
+ }
+ }
+ sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 );
+ nTextRotationAngle -= nFontDirection * 9000;
+ if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) ) // #104546#
+ {
+ bVerticalText = !bVerticalText;
+/*
+ sal_Int32 nHalfWidth = ( rTextRect.GetWidth() + 1 ) >> 1;
+ sal_Int32 nHalfHeight = ( rTextRect.GetHeight() + 1 ) >> 1;
+ Point aTopLeft( rTextRect.Left() + nHalfWidth - nHalfHeight,
+ rTextRect.Top() + nHalfHeight - nHalfWidth );
+ Size aNewSize( rTextRect.GetHeight(), rTextRect.GetWidth() );
+ Rectangle aNewRect( aTopLeft, aNewSize );
+ rTextRect = aNewRect;
+*/
+ }
+ aTextObj.SetVertical( bVerticalText );
+ if ( pRet )
+ {
+ BOOL bDeleteSource = aTextObj.GetOEPlaceHolderAtom() != 0;
+ if ( bDeleteSource && ( pRet->ISA( SdrGrafObj ) == FALSE ) // we are not allowed to get
+ && ( pRet->ISA( SdrObjGroup ) == FALSE ) // grouped placeholder objects
+ && ( pRet->ISA( SdrOle2Obj ) == FALSE ) )
+ SdrObject::Free( pRet );
+ }
+ sal_uInt32 nTextFlags = aTextObj.GetTextFlags();
+ sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ); // 0.25 cm (emu)
+ sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ); // 0.25 cm (emu)
+ sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ); // 0.13 cm (emu)
+ sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 );
+ ScaleEmu( nTextLeft );
+ ScaleEmu( nTextRight );
+ ScaleEmu( nTextTop );
+ ScaleEmu( nTextBottom );
+
+ sal_Int32 nMinFrameWidth = 0;
+ sal_Int32 nMinFrameHeight = 0;
+ sal_Bool bAutoGrowWidth, bAutoGrowHeight;
+
+ SdrTextVertAdjust eTVA;
+ SdrTextHorzAdjust eTHA;
+
+ nTextFlags &= PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT
+ | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK;
+
+ if ( bVerticalText )
+ {
+ eTVA = SDRTEXTVERTADJUST_BLOCK;
+ eTHA = SDRTEXTHORZADJUST_CENTER;
+
+ // Textverankerung lesen
+ MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+
+ switch( eTextAnchor )
+ {
+ case mso_anchorTop:
+ case mso_anchorTopCentered:
+ case mso_anchorTopBaseline:
+ case mso_anchorTopCenteredBaseline:
+ eTHA = SDRTEXTHORZADJUST_RIGHT;
+ break;
+
+ case mso_anchorMiddle :
+ case mso_anchorMiddleCentered:
+ eTHA = SDRTEXTHORZADJUST_CENTER;
+ break;
+
+ case mso_anchorBottom:
+ case mso_anchorBottomCentered:
+ case mso_anchorBottomBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ eTHA = SDRTEXTHORZADJUST_LEFT;
+ break;
+ }
+ // if there is a 100% use of following attributes, the textbox can been aligned also in vertical direction
+ switch ( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ case mso_anchorTopCenteredBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ {
+ // check if it is sensible to use the centered alignment
+ sal_uInt32 nMask = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT;
+ if ( ( nTextFlags & nMask ) != nMask ) // if the textobject has left and also right aligned pararagraphs
+ eTVA = SDRTEXTVERTADJUST_CENTER; // the text has to be displayed using the full width;
+ }
+ break;
+
+ default :
+ {
+ if ( nTextFlags == PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT )
+ eTVA = SDRTEXTVERTADJUST_TOP;
+ else if ( nTextFlags == PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT )
+ eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ }
+ break;
+ }
+ nMinFrameWidth = rTextRect.GetWidth() - ( nTextLeft + nTextRight );
+ }
+ else
+ {
+ eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_BLOCK;
+
+ // Textverankerung lesen
+ MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+
+ switch( eTextAnchor )
+ {
+ case mso_anchorTop:
+ case mso_anchorTopCentered:
+ case mso_anchorTopBaseline:
+ case mso_anchorTopCenteredBaseline:
+ eTVA = SDRTEXTVERTADJUST_TOP;
+ break;
+
+ case mso_anchorMiddle :
+ case mso_anchorMiddleCentered:
+ eTVA = SDRTEXTVERTADJUST_CENTER;
+ break;
+
+ case mso_anchorBottom:
+ case mso_anchorBottomCentered:
+ case mso_anchorBottomBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ break;
+ }
+ // if there is a 100% usage of following attributes, the textbox can be aligned also in horizontal direction
+ switch ( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ case mso_anchorTopCenteredBaseline:
+ case mso_anchorBottomCenteredBaseline:
+ {
+ // check if it is sensible to use the centered alignment
+ sal_uInt32 nMask = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT;
+ if ( ( nTextFlags & nMask ) != nMask ) // if the textobject has left and also right aligned pararagraphs
+ eTHA = SDRTEXTHORZADJUST_CENTER; // the text has to be displayed using the full width;
+ }
+ break;
+
+ default :
+ break;
+ }
+ nMinFrameHeight = rTextRect.GetHeight() - ( nTextTop + nTextBottom );
+ }
+
+ SdrObjKind eTextKind = OBJ_RECT;
+ if ( ( aPlaceholderAtom.nPlaceholderId == PPT_PLACEHOLDER_NOTESSLIDEIMAGE )
+ || ( aPlaceholderAtom.nPlaceholderId == PPT_PLACEHOLDER_MASTERNOTESSLIDEIMAGE ) )
+ {
+ aTextObj.SetInstance( 2 );
+ eTextKind = OBJ_TITLETEXT;
+ }
+ else if ( ( aPlaceholderAtom.nPlaceholderId == PPT_PLACEHOLDER_MASTERNOTESBODYIMAGE )
+ || ( aPlaceholderAtom.nPlaceholderId == PPT_PLACEHOLDER_NOTESBODY ) )
+ {
+ aTextObj.SetInstance( 2 );
+ eTextKind = OBJ_TEXT;
+ }
+
+ sal_uInt32 nDestinationInstance = aTextObj.GetInstance();
+ if ( ( rPersistEntry.ePageKind == PPT_MASTERPAGE ) )
+ {
+ if ( !rPersistEntry.pPresentationObjects )
+ {
+ rPersistEntry.pPresentationObjects = new UINT32[ PPT_STYLESHEETENTRYS ];
+ memset( rPersistEntry.pPresentationObjects, 0, PPT_STYLESHEETENTRYS * 4 );
+ }
+ if ( !rPersistEntry.pPresentationObjects[ nDestinationInstance ] )
+ rPersistEntry.pPresentationObjects[ nDestinationInstance ] = rObjData.rSpHd.GetRecBegFilePos();
+ }
+ switch ( nDestinationInstance )
+ {
+ case TSS_TYPE_PAGETITLE :
+ case TSS_TYPE_TITLE :
+ {
+ if ( GetSlideLayoutAtom()->eLayout == PPT_LAYOUT_TITLEMASTERSLIDE )
+ nDestinationInstance = TSS_TYPE_TITLE;
+ else
+ nDestinationInstance = TSS_TYPE_PAGETITLE;
+ }
+ break;
+ case TSS_TYPE_BODY :
+ // case TSS_TYPE_SUBTITLE :
+ case TSS_TYPE_HALFBODY :
+ case TSS_TYPE_QUARTERBODY :
+ nDestinationInstance = TSS_TYPE_BODY;
+ break;
+ }
+ aTextObj.SetDestinationInstance( (sal_uInt16)nDestinationInstance );
+
+ switch ( aTextObj.GetInstance() )
+ {
+ case TSS_TYPE_PAGETITLE :
+ case TSS_TYPE_TITLE : eTextKind = OBJ_TITLETEXT; break;
+ case TSS_TYPE_SUBTITLE : eTextKind = OBJ_TEXT; break;
+ case TSS_TYPE_BODY :
+ case TSS_TYPE_HALFBODY :
+ case TSS_TYPE_QUARTERBODY : eTextKind = OBJ_OUTLINETEXT; break;
+ }
+ if ( aTextObj.GetDestinationInstance() != TSS_TYPE_TEXT_IN_SHAPE )
+ {
+ if ( !aTextObj.GetOEPlaceHolderAtom() || !aTextObj.GetOEPlaceHolderAtom()->nPlaceholderId )
+ {
+ aTextObj.SetDestinationInstance( TSS_TYPE_TEXT_IN_SHAPE );
+ eTextKind = OBJ_RECT;
+ }
+ }
+ SdrObject* pTObj = NULL;
+ sal_Bool bWordWrap = (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone;
+ sal_Bool bFitShapeToText = ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0;
+
+ if ( pRet && pRet->ISA( SdrObjCustomShape ) && ( eTextKind == OBJ_RECT ) )
+ {
+ bAutoGrowHeight = bFitShapeToText;
+ if ( bWordWrap )
+ bAutoGrowWidth = sal_False;
+ else
+ bAutoGrowWidth = sal_True;
+ pTObj = pRet;
+ pRet = NULL;
+ }
+ else
+ {
+ if ( pRet && pRet->ISA( SdrObjCustomShape ) )
+ {
+ SdrObject::Free( pRet );
+ pRet = NULL;
+ }
+ pTObj = new SdrRectObj( eTextKind != OBJ_RECT ? eTextKind : OBJ_TEXT );
+ pTObj->SetModel( pSdrModel );
+ SfxItemSet aSet( pSdrModel->GetItemPool() );
+ if ( !pRet )
+ ((SdrEscherImport*)this)->ApplyAttributes( rSt, aSet, rObjData );
+ pTObj->SetMergedItemSet( aSet );
+ if ( pRet )
+ {
+ pTObj->SetMergedItem( XLineStyleItem( XLINE_NONE ) );
+ pTObj->SetMergedItem( XFillStyleItem( XFILL_NONE ) );
+ }
+ if ( bVerticalText )
+ {
+ bAutoGrowWidth = bFitShapeToText; // bFitShapeToText; can't be used, because we cut the text if it is too height,
+ bAutoGrowHeight = sal_False;
+ }
+ else
+ {
+ bAutoGrowWidth = sal_False;
+ bAutoGrowHeight = sal_True; // bFitShapeToText; can't be used, because we cut the text if it is too height,
+ }
+ }
+ pTObj->SetMergedItem( SvxFrameDirectionItem( bVerticalText ? FRMDIR_VERT_TOP_RIGHT : FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR ) );
+
+ if ( !pTObj->ISA( SdrObjCustomShape ) )
+ {
+ pTObj->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoGrowWidth ) );
+ pTObj->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoGrowHeight ) );
+ }
+ else
+ {
+ pTObj->SetMergedItem( SdrTextWordWrapItem( bWordWrap ) );
+ pTObj->SetMergedItem( SdrTextAutoGrowHeightItem( bFitShapeToText ) );
+ }
+
+ pTObj->SetMergedItem( SdrTextVertAdjustItem( eTVA ) );
+ pTObj->SetMergedItem( SdrTextHorzAdjustItem( eTHA ) );
+
+ if ( nMinFrameHeight < 0 )
+ nMinFrameHeight = 0;
+ if ( !pTObj->ISA( SdrObjCustomShape ) )
+ pTObj->SetMergedItem( SdrTextMinFrameHeightItem( nMinFrameHeight ) );
+
+ if ( nMinFrameWidth < 0 )
+ nMinFrameWidth = 0;
+ if ( !pTObj->ISA( SdrObjCustomShape ) )
+ pTObj->SetMergedItem( SdrTextMinFrameWidthItem( nMinFrameWidth ) );
+
+ // Abstaende an den Raendern der Textbox setzen
+ pTObj->SetMergedItem( SdrTextLeftDistItem( nTextLeft ) );
+ pTObj->SetMergedItem( SdrTextRightDistItem( nTextRight ) );
+ pTObj->SetMergedItem( SdrTextUpperDistItem( nTextTop ) );
+ pTObj->SetMergedItem( SdrTextLowerDistItem( nTextBottom ) );
+ pTObj->SetMergedItem( SdrTextFixedCellHeightItem( TRUE ) );
+
+ if ( !pTObj->ISA( SdrObjCustomShape ) )
+ pTObj->SetSnapRect( rTextRect );
+ pTObj = ReadObjText( &aTextObj, pTObj, rData.pPage );
+ if ( pTObj )
+ {
+ /* check if our new snaprect makes trouble,
+ because we do not display the ADJUST_BLOCK
+ properly if the textsize is bigger than the
+ snaprect of the object. Then we will use
+ ADJUST_CENTER instead of ADJUST_BLOCK.
+ */
+ if ( !pTObj->ISA( SdrObjCustomShape ) && !bFitShapeToText && !bWordWrap )
+ {
+ SdrTextObj* pText = PTR_CAST( SdrTextObj, pTObj );
+ if ( pText )
+ {
+ if ( bVerticalText )
+ {
+ if ( eTVA == SDRTEXTVERTADJUST_BLOCK )
+ {
+ Size aTextSize( pText->GetTextSize() );
+ aTextSize.Width() += nTextLeft + nTextRight;
+ aTextSize.Height() += nTextTop + nTextBottom;
+ if ( rTextRect.GetHeight() < aTextSize.Height() )
+ pTObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) );
+ }
+ }
+ else
+ {
+ if ( eTHA == SDRTEXTHORZADJUST_BLOCK )
+ {
+ Size aTextSize( pText->GetTextSize() );
+ aTextSize.Width() += nTextLeft + nTextRight;
+ aTextSize.Height() += nTextTop + nTextBottom;
+ if ( rTextRect.GetWidth() < aTextSize.Width() )
+ pTObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) );
+ }
+ }
+ }
+ }
+ // rotate text with shape ?
+ sal_Int32 nAngle = ( rObjData.nSpFlags & SP_FFLIPV ) ? -mnFix16Angle : mnFix16Angle; // #72116# vertical flip -> rotate by using the other way
+ nAngle += nTextRotationAngle;
+
+ if ( pTObj->ISA( SdrObjCustomShape ) )
+ {
+/*
+ if ( nTextRotationAngle )
+ {
+ double fTextRotateAngle = (double)nTextRotationAngle / 100.0;
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pTObj)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
+ PropertyValue aPropValue;
+ aPropValue.Name = sTextRotateAngle;
+ aPropValue.Value <<= fTextRotateAngle;
+ aGeometryItem.SetPropertyValue( aPropValue );
+ ((SdrObjCustomShape*)pTObj)->SetMergedItem( aGeometryItem );
+ }
+*/
+ }
+ else
+ {
+ if ( rObjData.nSpFlags & SP_FFLIPV )
+ {
+ double a = 18000 * nPi180;
+ pTObj->Rotate( rTextRect.Center(), 18000, sin( a ), cos( a ) );
+ }
+ if ( rObjData.nSpFlags & SP_FFLIPH )
+ nAngle = 36000 - nAngle;
+ if ( nAngle )
+ {
+ double a = nAngle * nPi180;
+ pTObj->NbcRotate( rObjData.aBoundRect.Center(), nAngle, sin( a ), cos( a ) );
+ }
+ }
+ if ( pRet )
+ {
+ SdrObject* pGroup = new SdrObjGroup;
+ pGroup->GetSubList()->NbcInsertObject( pRet );
+ pGroup->GetSubList()->NbcInsertObject( pTObj );
+ pRet = pGroup;
+ }
+ else
+ pRet = pTObj;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( maShapeRecords.SeekToContent( rSt, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ) )
+ {
+ maShapeRecords.Current()->SeekToBegOfRecord( rSt );
+ DffPropertyReader aSecPropSet( *this );
+ aSecPropSet.ReadPropSet( rSt, (ProcessData*)pData );
+ sal_Int32 nTableProperties = aSecPropSet.GetPropertyValue( DFF_Prop_tableProperties, 0 );
+ if ( nTableProperties & 3 )
+ {
+ if ( aSecPropSet.SeekToContent( DFF_Prop_tableRowProperties, rSt ) )
+ {
+ sal_Int16 i, nRowCount = 0;
+ rSt >> nRowCount >> i >> i;
+ if ( nRowCount )
+ {
+ sal_uInt32* pTableArry = new sal_uInt32[ nRowCount + 2 ];
+ pTableArry[ 0 ] = nTableProperties;
+ pTableArry[ 1 ] = nRowCount;
+ for ( i = 0; i < nRowCount; i++ )
+ rSt >> pTableArry[ i + 2 ];
+ rData.pTableRowProperties = pTableArry;
+ }
+ }
+ }
+ }
+ }
+ if ( pRet ) // sj: #i38501#, and and taking care of connections to group objects
+ {
+ if ( rObjData.nSpFlags & SP_FBACKGROUND )
+ {
+ pRet->NbcSetSnapRect( Rectangle( Point(), ((SdrPage*)rData.pPage)->GetSize() ) ); // Groesse setzen
+ }
+ if ( rPersistEntry.pSolverContainer )
+ {
+ for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)rPersistEntry.pSolverContainer->aCList.First();
+ pPtr; pPtr = (SvxMSDffConnectorRule*)rPersistEntry.pSolverContainer->aCList.Next() )
+ {
+ if ( rObjData.nShapeId == pPtr->nShapeC )
+ pPtr->pCObj = pRet;
+ else
+ {
+ SdrObject* pConnectObj = pRet;
+ if ( pOriginalObj && pRet->ISA( SdrObjGroup ) )
+ { /* check if the original object from the escherimport is part of the group object,
+ if this is the case, we will use the original object to connect to */
+ SdrObjListIter aIter( *pRet, IM_DEEPWITHGROUPS );
+ while( aIter.IsMore() )
+ {
+ SdrObject* pPartObj = aIter.Next();
+ if ( pPartObj == pOriginalObj )
+ {
+ pConnectObj = pPartObj;
+ break;
+ }
+ }
+ }
+ if ( rObjData.nShapeId == pPtr->nShapeA )
+ {
+ pPtr->pAObj = pConnectObj;
+ pPtr->nSpFlagsA = rObjData.nSpFlags;
+ }
+ if ( rObjData.nShapeId == pPtr->nShapeB )
+ {
+ pPtr->pBObj = pConnectObj;
+ pPtr->nSpFlagsB = rObjData.nSpFlags;
+ }
+ }
+ }
+ }
+ if ( rPersistEntry.ePageKind == PPT_MASTERPAGE )
+ { // maybe the escher clusterlist is not correct, but we have to got the right page by using the
+ // spMaster property, so we are patching the table
+ if ( rPersistEntry.nDrawingDgId != 0xffffffff )
+ {
+ UINT32 nSec = ( rObjData.nShapeId >> 10 ) - 1;
+ if ( mpFidcls && ( nSec < mnIdClusters ) )
+ mpFidcls[ nSec ].dgid = rPersistEntry.nDrawingDgId; // insert the correct drawing id;
+ }
+ }
+ if ( GetPropertyValue( DFF_Prop_fNoFillHitTest ) & 0x10 )
+ {
+ if ( (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid ) == mso_fillBackground )
+ {
+ if ( !rData.pBackgroundColoredObjects )
+ rData.pBackgroundColoredObjects = new List;
+ rData.pBackgroundColoredObjects->Insert( pRet, LIST_APPEND );
+ }
+ }
+ }
+ return pRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEscherImport::CheckWingdings() const
+{
+ OutputDevice* pDev = (OutputDevice*)Application::GetDefaultDevice();
+ ((SdrEscherImport*)this)->bWingdingsAvailable = pDev->IsFontAvailable( String( RTL_CONSTASCII_USTRINGPARAM( "WINGDINGS" ) ) );
+ ((SdrEscherImport*)this)->bWingdingsChecked = TRUE;
+}
+
+void SdrEscherImport::CheckMonotypeSorts() const
+{
+ OutputDevice* pDev = (OutputDevice*)Application::GetDefaultDevice();
+ ((SdrEscherImport*)this)->bMonotypeSortsAvailable = pDev->IsFontAvailable( String( RTL_CONSTASCII_USTRINGPARAM( "MONOTYPE SORTS" ) ) );
+ ((SdrEscherImport*)this)->bMonotypeSortsChecked = TRUE;
+}
+
+void SdrEscherImport::CheckTimesNewRoman() const
+{
+ OutputDevice* pDev = (OutputDevice*)Application::GetDefaultDevice();
+ ((SdrEscherImport*)this)->bTimesNewRomanAvailable = pDev->IsFontAvailable( String( RTL_CONSTASCII_USTRINGPARAM( "TIMES NEW ROMAN" ) ) );
+ ((SdrEscherImport*)this)->bTimesNewRomanChecked = TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrPowerPointImport::SdrPowerPointImport( PowerPointImportParam& rParam, const String& rBaseURL ) :
+ SdrEscherImport ( rParam, rBaseURL ),
+ bOk ( rStCtrl.GetErrorCode() == SVSTREAM_OK ),
+ pPersistPtr ( NULL ),
+ nPersistPtrAnz ( 0 ),
+ pDefaultSheet ( NULL ),
+ pMasterPages ( NULL ),
+ pSlidePages ( NULL ),
+ pNotePages ( NULL ),
+ nAktPageNum ( 0 ),
+ nDocStreamPos ( 0 ),
+ nPageColorsNum ( 0xFFFF ),
+ ePageColorsKind ( PPT_MASTERPAGE ),
+ eAktPageKind ( PPT_MASTERPAGE )
+{
+ DffRecordHeader* pHd;
+ if ( bOk )
+ {
+ rStCtrl.Seek( STREAM_SEEK_TO_END );
+ nStreamLen = rStCtrl.Tell();
+
+ // try to allocate the UserEditAtom via CurrentUserAtom
+ sal_uInt32 nCurrentUserEdit = rParam.aCurrentUserAtom.nCurrentUserEdit;
+ if ( nCurrentUserEdit )
+ {
+ rStCtrl.Seek( nCurrentUserEdit );
+ rStCtrl >> aUserEditAtom;
+ }
+ if ( !aUserEditAtom.nOffsetPersistDirectory )
+ { // if there is no UserEditAtom try to search the last one
+
+ rStCtrl.Seek( 0 );
+ DffRecordManager aPptRecManager; // contains all first level container and atoms
+ aPptRecManager.Consume( rStCtrl, FALSE, nStreamLen );
+ for ( pHd = aPptRecManager.Last(); pHd; pHd = aPptRecManager.Prev() )
+ {
+ if ( pHd->nRecType == PPT_PST_UserEditAtom )
+ {
+ pHd->SeekToBegOfRecord( rStCtrl );
+ rStCtrl >> aUserEditAtom;
+ break;
+ }
+ }
+ if ( !pHd )
+ bOk = FALSE;
+ }
+ }
+ if ( rStCtrl.GetError() != 0 )
+ bOk = FALSE;
+
+ if ( bOk )
+ {
+ // PersistPtrs lesen (alle)
+ nPersistPtrAnz = aUserEditAtom.nMaxPersistWritten + 1; // 1 mehr, damit ich immer direkt indizieren kann
+ pPersistPtr = new UINT32[ nPersistPtrAnz ]; // (die fangen naemlich eigentlich bei 1 an)
+ if ( !pPersistPtr )
+ bOk = FALSE;
+ else
+ {
+ memset( pPersistPtr, 0x00, nPersistPtrAnz * 4 );
+
+ // SJ: new search mechanism from bottom to top (Issue 21122)
+ PptUserEditAtom aCurrentEditAtom( aUserEditAtom );
+ sal_uInt32 nCurrentEditAtomStrmPos = aCurrentEditAtom.aHd.GetRecEndFilePos();
+ while( nCurrentEditAtomStrmPos )
+ {
+ sal_uInt32 nPersistIncPos = aCurrentEditAtom.nOffsetPersistDirectory;
+ if ( nPersistIncPos )
+ {
+ rStCtrl.Seek( nPersistIncPos );
+ DffRecordHeader aPersistHd;
+ rStCtrl >> aPersistHd;
+ if ( aPersistHd.nRecType == PPT_PST_PersistPtrIncrementalBlock )
+ {
+ ULONG nPibLen = aPersistHd.GetRecEndFilePos();
+ while ( bOk && ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < nPibLen ) )
+ {
+ sal_uInt32 nOfs, nAnz;
+ rStCtrl >> nOfs;
+ nAnz = nOfs;
+ nOfs &= 0x000FFFFF;
+ nAnz >>= 20;
+ while ( bOk && ( rStCtrl.GetError() == 0 ) && ( nAnz > 0 ) && ( nOfs <= nPersistPtrAnz ) )
+ {
+ sal_uInt32 nPt;
+ rStCtrl >> nPt;
+ if ( !pPersistPtr[ nOfs ] )
+ {
+ pPersistPtr[ nOfs ] = nPt;
+ if ( pPersistPtr[ nOfs ] > nStreamLen )
+ {
+ bOk = FALSE;
+ DBG_ERROR("SdrPowerPointImport::Ctor(): Ungueltiger Eintrag im Persist-Directory!");
+ }
+ }
+ nAnz--;
+ nOfs++;
+ }
+ if ( bOk && nAnz > 0 )
+ {
+ DBG_ERROR("SdrPowerPointImport::Ctor(): Nicht alle Persist-Directory Entraege gelesen!");
+ bOk = FALSE;
+ }
+ }
+ }
+ }
+ nCurrentEditAtomStrmPos = aCurrentEditAtom.nOffsetLastEdit < nCurrentEditAtomStrmPos ? aCurrentEditAtom.nOffsetLastEdit : 0;
+ if ( nCurrentEditAtomStrmPos )
+ {
+ rStCtrl.Seek( nCurrentEditAtomStrmPos );
+ rStCtrl >> aCurrentEditAtom;
+ }
+ }
+ }
+ }
+ if ( rStCtrl.GetError() != 0 )
+ bOk = FALSE;
+ if ( bOk )
+ { // Document PersistEntry checken
+ nDocStreamPos = aUserEditAtom.nDocumentRef;
+ if ( nDocStreamPos > nPersistPtrAnz )
+ {
+ DBG_ERROR("SdrPowerPointImport::Ctor(): aUserEditAtom.nDocumentRef ungueltig!");
+ bOk = FALSE;
+ }
+ }
+ if ( bOk )
+ { // Document FilePos checken
+ nDocStreamPos = pPersistPtr[ nDocStreamPos ];
+ if ( nDocStreamPos >= nStreamLen )
+ {
+ DBG_ERROR("SdrPowerPointImport::Ctor(): nDocStreamPos >= nStreamLen!");
+ bOk = FALSE;
+ }
+ }
+ if ( bOk )
+ {
+ rStCtrl.Seek( nDocStreamPos );
+ aDocRecManager.Consume( rStCtrl );
+
+ DffRecordHeader aDocHd;
+ rStCtrl >> aDocHd;
+ // DocumentAtom lesen
+ DffRecordHeader aDocAtomHd;
+ rStCtrl >> aDocAtomHd;
+ if ( aDocHd.nRecType == PPT_PST_Document && aDocAtomHd.nRecType == PPT_PST_DocumentAtom )
+ {
+ aDocAtomHd.SeekToBegOfRecord( rStCtrl );
+ rStCtrl >> aDocAtom;
+ }
+ else
+ bOk = FALSE;
+
+ if ( bOk )
+ {
+ if ( !pFonts )
+ ReadFontCollection();
+
+ // reading TxPF, TxSI
+ PPTTextCharacterStyleAtomInterpreter aTxCFStyle; // SJ: ToDo, this atom needs to be interpreted, it contains character default styles for standard objects (instance4)
+ PPTTextParagraphStyleAtomInterpreter aTxPFStyle;
+ PPTTextSpecInfoAtomInterpreter aTxSIStyle; // styles (default language setting ... )
+
+ DffRecordHeader* pEnvHd = aDocRecManager.GetRecordHeader( PPT_PST_Environment );
+ if ( pEnvHd )
+ {
+ pEnvHd->SeekToContent( rStCtrl );
+ DffRecordHeader aTxPFStyleRecHd;
+ if ( SeekToRec( rStCtrl, PPT_PST_TxPFStyleAtom, pEnvHd->GetRecEndFilePos(), &aTxPFStyleRecHd ) )
+ aTxPFStyle.Read( rStCtrl, aTxPFStyleRecHd );
+
+ pEnvHd->SeekToContent( rStCtrl );
+ DffRecordHeader aTxSIStyleRecHd;
+ if ( SeekToRec( rStCtrl, PPT_PST_TxSIStyleAtom, pEnvHd->GetRecEndFilePos(), &aTxSIStyleRecHd ) )
+ {
+ aTxSIStyle.Read( rStCtrl, aTxSIStyleRecHd, PPT_PST_TxSIStyleAtom );
+#ifdef DBG_UTIL
+ if ( !aTxSIStyle.bValid )
+ {
+ if (!(rImportParam.nImportFlags & PPT_IMPORTFLAGS_NO_TEXT_ASSERT ))
+ {
+ DBG_ERROR( "SdrTextSpecInfoAtomInterpreter::Ctor(): parsing error, this document needs to be analysed (SJ)" );
+ }
+ }
+#endif
+ }
+ }
+
+ // todo:: PPT_PST_TxPFStyleAtom
+
+ // SlidePersists Lesen
+ pMasterPages=new PptSlidePersistList;
+ pSlidePages =new PptSlidePersistList;
+ pNotePages =new PptSlidePersistList;
+
+ // now always creating the handout page, it will be the first in our masterpage list
+ PptSlidePersistEntry* pE = new PptSlidePersistEntry;
+ pE->aPersistAtom.nPsrReference = aDocAtom.nHandoutMasterPersist;
+ pE->bHandoutMaster = sal_True;
+ if ( !aDocAtom.nHandoutMasterPersist )
+ pE->bStarDrawFiller = sal_True; // this is a dummy master page
+ pMasterPages->C40_INSERT( PptSlidePersistEntry, pE, 0 );
+
+ USHORT nPageListNum = 0;
+ DffRecordHeader* pSlideListWithTextHd = aDocRecManager.GetRecordHeader( PPT_PST_SlideListWithText );
+ PptSlidePersistEntry* pPreviousPersist = NULL;
+ while ( pSlideListWithTextHd && ( nPageListNum < 3 ) )
+ {
+ pSlideListWithTextHd->SeekToContent( rStCtrl );
+ PptSlidePersistList* pPageList = GetPageList( PptPageKind( nPageListNum ) );
+ sal_uInt32 nSlideListWithTextHdEndOffset = pSlideListWithTextHd->GetRecEndFilePos();
+ while ( SeekToRec( rStCtrl, PPT_PST_SlidePersistAtom, nSlideListWithTextHdEndOffset ) )
+ {
+ if ( pPreviousPersist )
+ pPreviousPersist->nSlidePersistEndOffset = rStCtrl.Tell();
+ PptSlidePersistEntry* pE2 = new PptSlidePersistEntry;
+ rStCtrl >> pE2->aPersistAtom;
+ pE2->nSlidePersistStartOffset = rStCtrl.Tell();
+ pE2->ePageKind = PptPageKind( nPageListNum );
+ pPageList->C40_INSERT( PptSlidePersistEntry, pE2, pPageList->Count() );
+ pPreviousPersist = pE2;
+ }
+ if ( pPreviousPersist )
+ pPreviousPersist->nSlidePersistEndOffset = nSlideListWithTextHdEndOffset;
+ pSlideListWithTextHd = aDocRecManager.GetRecordHeader( PPT_PST_SlideListWithText, SEEK_FROM_CURRENT );
+ nPageListNum++;
+ }
+
+ // we will ensure that there is at least one master page
+ if ( pMasterPages->Count() == 1 ) // -> there is only a handout page available
+ {
+ PptSlidePersistEntry* pE2 = new PptSlidePersistEntry;
+ pE2->bStarDrawFiller = sal_True; // this is a dummy master page
+ pMasterPages->C40_INSERT( PptSlidePersistEntry, pE2, 1 );
+ }
+
+ // now we will insert at least one notes master for each master page
+ sal_uInt16 nMasterPage;
+ sal_uInt16 nMasterPages = pMasterPages->Count() - 1;
+ for ( nMasterPage = 0; nMasterPage < nMasterPages; nMasterPage++ )
+ {
+ PptSlidePersistEntry* pE2 = new PptSlidePersistEntry;
+ pE2->bNotesMaster = sal_True;
+ pE2->bStarDrawFiller = sal_True; // this is a dummy master page
+ if ( !nMasterPage && aDocAtom.nNotesMasterPersist )
+ { // special treatment for the first notes master
+ pE2->aPersistAtom.nPsrReference = aDocAtom.nNotesMasterPersist;
+ pE2->bStarDrawFiller = sal_False; // this is a dummy master page
+ }
+ pMasterPages->C40_INSERT( PptSlidePersistEntry, pE2, ( nMasterPage + 1 ) << 1 );
+ }
+
+ // Zu jeder Page noch das SlideAtom bzw. NotesAtom lesen, soweit vorhanden
+ nPageListNum = 0;
+ for ( nPageListNum = 0; nPageListNum < 3; nPageListNum++ )
+ {
+ PptSlidePersistList* pPageList = GetPageList( PptPageKind( nPageListNum ) );
+ for ( USHORT nPageNum = 0; nPageNum < pPageList->Count(); nPageNum++ )
+ {
+ PptSlidePersistEntry* pE2 = (*pPageList)[ nPageNum ];
+ ULONG nPersist = pE2->aPersistAtom.nPsrReference;
+ if ( ( nPersist > 0 ) && ( nPersist < nPersistPtrAnz ) )
+ {
+ ULONG nFPos = pPersistPtr[ nPersist ];
+ if ( nFPos < nStreamLen )
+ {
+ rStCtrl.Seek( nFPos );
+ DffRecordHeader aSlideHd;
+ rStCtrl >> aSlideHd;
+ if ( SeekToRec( rStCtrl, PPT_PST_SlideAtom, aSlideHd.GetRecEndFilePos() ) )
+ rStCtrl >> pE2->aSlideAtom;
+ else if ( SeekToRec( rStCtrl, PPT_PST_NotesAtom, aSlideHd.GetRecEndFilePos() ) )
+ rStCtrl >> pE2->aNotesAtom;
+ aSlideHd.SeekToContent( rStCtrl );
+
+ DffRecordHeader aPPTDrawingHd;
+ if ( SeekToRec( rStCtrl, PPT_PST_PPDrawing, aSlideHd.GetRecEndFilePos(), &aPPTDrawingHd ) )
+ {
+ DffRecordHeader aPPTDgContainer;
+ if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, aPPTDrawingHd.GetRecEndFilePos(), &aPPTDgContainer ) )
+ {
+ if ( SeekToRec( rStCtrl, DFF_msofbtDg, aPPTDrawingHd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aDgRecordHeader;
+ rStCtrl >> aDgRecordHeader;
+ pE2->nDrawingDgId = aDgRecordHeader.nRecInstance;
+ aDgRecordHeader.SeekToEndOfRecord( rStCtrl );
+ }
+ if ( SeekToRec( rStCtrl, DFF_msofbtSolverContainer, aPPTDgContainer.GetRecEndFilePos() ) )
+ {
+ pE2->pSolverContainer = new SvxMSDffSolverContainer;
+ rStCtrl >> *( pE2->pSolverContainer );
+ }
+ aPPTDgContainer.SeekToBegOfRecord( rStCtrl );
+ SetDgContainer( rStCtrl ); // set this, so that the escherimport is knowing of our drawings
+ }
+ }
+ // office xp is supporting more than one stylesheet
+ if ( ( pE2->ePageKind == PPT_MASTERPAGE ) && ( pE2->aSlideAtom.nMasterId == 0 ) && ( pE2->bNotesMaster == 0 ) )
+ {
+ PPTTextSpecInfo aTxSI( 0 );
+ if ( aTxSIStyle.bValid && aTxSIStyle.aList.Count() )
+ aTxSI = *( ( (PPTTextSpecInfo*)aTxSIStyle.aList.GetObject( 0 ) ) );
+
+ pE2->pStyleSheet = new PPTStyleSheet( aSlideHd, rStCtrl, *this, aTxCFStyle, aTxPFStyle, aTxSI );
+ pDefaultSheet = pE2->pStyleSheet;
+ }
+ if ( SeekToRec( rStCtrl, PPT_PST_ColorSchemeAtom, aSlideHd.GetRecEndFilePos() ) )
+ rStCtrl >> pE2->aColorScheme;
+ else
+ {
+ DBG_ERROR( "SdrPowerPointImport::Ctor(): could not get SlideColorScheme! (SJ)" );
+ }
+ }
+ else
+ {
+ DBG_ERROR("SdrPowerPointImport::Ctor(): Persist-Eintrag fehlerhaft! (SJ)");
+ }
+ }
+ }
+ }
+ DffRecordHeader* pHeadersFootersHd = aDocRecManager.GetRecordHeader( PPT_PST_HeadersFooters, SEEK_FROM_BEGINNING );
+ if ( pHeadersFootersHd )
+ {
+ HeaderFooterEntry aNormalMaster, aNotesMaster;
+ for ( ; pHeadersFootersHd; pHeadersFootersHd = aDocRecManager.GetRecordHeader( PPT_PST_HeadersFooters, SEEK_FROM_CURRENT ) )
+ {
+ if ( pHeadersFootersHd->nRecInstance == 3 ) // normal master
+ ImportHeaderFooterContainer( *pHeadersFootersHd, aNormalMaster );
+ else if ( pHeadersFootersHd->nRecInstance == 4 ) // notes master
+ ImportHeaderFooterContainer( *pHeadersFootersHd, aNotesMaster );
+ }
+ for ( USHORT i = 0; i < pMasterPages->Count(); i++ )
+ {
+ if ( (*pMasterPages)[ i ]->bNotesMaster )
+ (*pMasterPages)[ i ]->pHeaderFooterEntry = new HeaderFooterEntry( aNotesMaster );
+ else
+ (*pMasterPages)[ i ]->pHeaderFooterEntry = new HeaderFooterEntry( aNormalMaster );
+ }
+ }
+ }
+ }
+ if ( ( rStCtrl.GetError() != 0 ) || ( pDefaultSheet == NULL ) )
+ bOk = FALSE;
+ pPPTStyleSheet = pDefaultSheet;
+ rStCtrl.Seek( 0 );
+}
+
+SdrPowerPointImport::~SdrPowerPointImport()
+{
+ for ( void* pPtr = aHyperList.First(); pPtr; pPtr = aHyperList.Next() )
+ delete (SdHyperlinkEntry*)pPtr;
+ delete pMasterPages;
+ delete pSlidePages;
+ delete pNotePages;
+ delete[] pPersistPtr;
+}
+
+sal_Bool PPTConvertOCXControls::InsertControl(
+ const com::sun::star::uno::Reference<
+ com::sun::star::form::XFormComponent > &rFComp,
+ const com::sun::star::awt::Size& rSize,
+ com::sun::star::uno::Reference<
+ com::sun::star::drawing::XShape > *pShape,
+ BOOL /*bFloatingCtrl*/)
+{
+ sal_Bool bRetValue = FALSE;
+ try
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape;
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > & rFormComps =
+ GetFormComps();
+
+ ::com::sun::star::uno::Any aTmp( &rFComp, ::getCppuType((const ::com::sun::star::uno::Reference<
+ com::sun::star::form::XFormComponent >*)0) );
+
+ rFormComps->insertByIndex( rFormComps->getCount(), aTmp );
+
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rServiceFactory =
+ GetServiceFactory();
+ if( rServiceFactory.is() )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xCreate = rServiceFactory
+ ->createInstance(String( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.ControlShape" ) ) );
+ if( xCreate.is() )
+ {
+ xShape = ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >(xCreate, ::com::sun::star::uno::UNO_QUERY);
+ if ( xShape.is() )
+ {
+ xShape->setSize(rSize);
+// GetShapes()->add( xShape );
+ // Das Control-Model am Control-Shape setzen
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XControlShape > xControlShape( xShape,
+ ::com::sun::star::uno::UNO_QUERY );
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xControlModel( rFComp,
+ ::com::sun::star::uno::UNO_QUERY );
+ if ( xControlShape.is() && xControlModel.is() )
+ {
+ xControlShape->setControl( xControlModel );
+ if (pShape)
+ *pShape = xShape;
+ bRetValue = TRUE;
+ }
+ }
+ }
+ }
+ }
+ catch( ... )
+ {
+ bRetValue = FALSE;
+ }
+ return bRetValue;
+};
+
+const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& PPTConvertOCXControls::GetDrawPage()
+{
+ if( !xDrawPage.is() && pDocSh )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > xModel( pDocSh->GetModel() );
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPages > xDrawPages;
+ switch( ePageKind )
+ {
+ case PPT_SLIDEPAGE :
+ case PPT_NOTEPAGE :
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPagesSupplier >
+ xDrawPagesSupplier( xModel, ::com::sun::star::uno::UNO_QUERY);
+ if ( xDrawPagesSupplier.is() )
+ xDrawPages = xDrawPagesSupplier->getDrawPages();
+ }
+ break;
+
+ case PPT_MASTERPAGE :
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XMasterPagesSupplier >
+ xMasterPagesSupplier( xModel, ::com::sun::star::uno::UNO_QUERY);
+ if ( xMasterPagesSupplier.is() )
+ xDrawPages = xMasterPagesSupplier->getMasterPages();
+ }
+ break;
+ }
+ if ( xDrawPages.is() && xDrawPages->getCount() )
+ {
+ xDrawPages->getCount();
+ ::com::sun::star::uno::Any aAny( xDrawPages->getByIndex( xDrawPages->getCount() - 1 ) );
+ aAny >>= xDrawPage;
+ }
+ }
+ return xDrawPage;
+}
+
+sal_Bool SdrPowerPointOLEDecompress( SvStream& rOutput, SvStream& rInput, sal_uInt32 nInputSize )
+{
+ sal_uInt32 nOldPos = rInput.Tell();
+ char* pBuf = new char[ nInputSize ];
+ rInput.Read( pBuf, nInputSize );
+ ZCodec aZCodec( 0x8000, 0x8000 );
+ aZCodec.BeginCompression();
+ SvMemoryStream aSource( pBuf, nInputSize, STREAM_READ );
+ aZCodec.Decompress( aSource, rOutput );
+ const sal_Bool bSuccess(0L != aZCodec.EndCompression());
+ delete[] pBuf;
+ rInput.Seek( nOldPos );
+ return bSuccess;
+}
+
+// --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup>
+SdrObject* SdrPowerPointImport::ImportOLE( long nOLEId,
+ const Graphic& rGraf,
+ const Rectangle& rBoundRect,
+ const Rectangle& rVisArea,
+ const int /*_nCalledByGroup*/,
+ sal_Int64 /*nAspect*/ ) const
+// <--
+{
+ SdrObject* pRet = NULL;
+
+ UINT32 nOldPos = rStCtrl.Tell();
+
+ Graphic aGraphic( rGraf );
+
+ if ( ((SdrPowerPointImport*)this)->maShapeRecords.SeekToContent( rStCtrl, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) )
+ {
+ DffRecordHeader aPlaceHd;
+ while ( ( rStCtrl.GetError() == 0 )
+ && ( rStCtrl.Tell() < ((SdrPowerPointImport*)this)->maShapeRecords.Current()->GetRecEndFilePos() ) )
+ {
+ rStCtrl >> aPlaceHd;
+ if ( aPlaceHd.nRecType == PPT_PST_RecolorInfoAtom )
+ {
+ ((SdrPowerPointImport*)this)->RecolorGraphic( rStCtrl, aPlaceHd.nRecLen, aGraphic );
+ break;
+ }
+ else
+ aPlaceHd.SeekToEndOfRecord( rStCtrl );
+ }
+ }
+
+ PPTOleEntry* pOe;
+ for ( pOe = (PPTOleEntry*)((SdrPowerPointImport*)this)->aOleObjectList.First(); pOe;
+ pOe = (PPTOleEntry*)((SdrPowerPointImport*)this)->aOleObjectList.Next() )
+ {
+ if ( pOe->nId != (sal_uInt32)nOLEId )
+ continue;
+
+ rStCtrl.Seek( pOe->nRecHdOfs );
+
+ DffRecordHeader aHd;
+ rStCtrl >> aHd;
+
+ sal_uInt32 nLen = aHd.nRecLen - 4;
+ if ( (INT32)nLen > 0 )
+ {
+ sal_Bool bSuccess = sal_False;
+
+ rStCtrl.SeekRel( 4 );
+
+ ::utl::TempFile aTmpFile;
+ aTmpFile.EnableKillingFile( sal_True );
+
+ if ( aTmpFile.IsValid() )
+ {
+ SvStream* pDest = ::utl::UcbStreamHelper::CreateStream( aTmpFile.GetURL(), STREAM_TRUNC | STREAM_WRITE );
+ if ( pDest )
+ bSuccess = SdrPowerPointOLEDecompress( *pDest, rStCtrl, nLen );
+ delete pDest;
+ }
+ if ( bSuccess )
+ {
+ SvStream* pDest = ::utl::UcbStreamHelper::CreateStream( aTmpFile.GetURL(), STREAM_READ );
+ Storage* pObjStor = pDest ? new Storage( *pDest, TRUE ) : NULL;
+ if ( pObjStor )
+ {
+ SotStorageRef xObjStor( new SotStorage( pObjStor ) );
+ if ( xObjStor.Is() && !xObjStor->GetError() )
+ {
+ if ( xObjStor->GetClassName() == SvGlobalName() )
+ {
+ ClsId aId( pObjStor->GetClassId() );
+ xObjStor->SetClass( SvGlobalName( aId.n1, aId.n2, aId.n3, aId.n4, aId.n5, aId.n6, aId.n7, aId.n8, aId.n9, aId.n10, aId.n11 ),
+ pObjStor->GetFormat(), pObjStor->GetUserName() );
+ }
+ SotStorageStreamRef xSrcTst = xObjStor->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "\1Ole" ) ) );
+ if ( xSrcTst.Is() )
+ {
+ BYTE aTestA[ 10 ];
+ BOOL bGetItAsOle = ( sizeof( aTestA ) == xSrcTst->Read( aTestA, sizeof( aTestA ) ) );
+ if ( !bGetItAsOle )
+ { // maybe there is a contentsstream in here
+ xSrcTst = xObjStor->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "Contents" ) ), STREAM_READWRITE | STREAM_NOCREATE );
+ bGetItAsOle = ( xSrcTst.Is() && sizeof( aTestA ) == xSrcTst->Read( aTestA, sizeof( aTestA ) ) );
+ }
+ if ( bGetItAsOle )
+ {
+ ::rtl::OUString aNm;
+ // if ( nSvxMSDffOLEConvFlags )
+ {
+ uno::Reference < embed::XStorage > xDestStorage( pOe->pShell->GetStorage() );
+ uno::Reference < embed::XEmbeddedObject > xObj =
+ CheckForConvertToSOObj( nSvxMSDffOLEConvFlags, *xObjStor, xDestStorage, rGraf, rVisArea );
+ if( xObj.is() )
+ {
+ pOe->pShell->getEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aNm );
+
+ svt::EmbeddedObjectRef aObj( xObj, pOe->nAspect );
+
+ // TODO/LATER: need MediaType for Graphic
+ aObj.SetGraphic( rGraf, ::rtl::OUString() );
+ pRet = new SdrOle2Obj( aObj, aNm, rBoundRect, FALSE );
+ }
+ }
+ if ( !pRet && ( pOe->nType == PPT_PST_ExControl ) )
+ {
+ PPTConvertOCXControls aPPTConvertOCXControls( pOe->pShell, eAktPageKind );
+ ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape;
+ if ( aPPTConvertOCXControls.ReadOCXStream( xObjStor, &xShape, FALSE ) )
+ pRet = GetSdrObjectFromXShape( xShape );
+ }
+ if ( !pRet )
+ {
+ aNm = pOe->pShell->getEmbeddedObjectContainer().CreateUniqueObjectName();
+ ErrCode aErrCode = 0;
+
+ // object is not an own object
+ SotStorageRef xTarget = SotStorage::OpenOLEStorage( pOe->pShell->GetStorage(), aNm, STREAM_READWRITE );
+ if ( xObjStor.Is() && xTarget.Is() )
+ {
+ xObjStor->CopyTo( xTarget );
+ if( !xTarget->GetError() )
+ xTarget->Commit();
+ if( xTarget->GetError() )
+ aErrCode = xTarget->GetError();
+ }
+ xTarget.Clear();
+
+ uno::Reference < embed::XEmbeddedObject > xObj =
+ pOe->pShell->getEmbeddedObjectContainer().GetEmbeddedObject( aNm );
+ if ( xObj.is() )
+ {
+ if ( pOe->nAspect != embed::Aspects::MSOLE_ICON )
+ {
+ //TODO/LATER: keep on hacking?!
+ // modifiziert wollen wir nicht werden
+ //xInplaceObj->EnableSetModified( FALSE );
+ if ( rVisArea.IsEmpty() )
+ {
+ MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( pOe->nAspect ) );
+ Size aSize( OutputDevice::LogicToLogic( aGraphic.GetPrefSize(),
+ aGraphic.GetPrefMapMode(), MapMode( aMapUnit ) ) );
+
+ awt::Size aSz;
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xObj->setVisualAreaSize( pOe->nAspect, aSz );
+ }
+ else
+ {
+ awt::Size aSize( rVisArea.GetSize().Width(), rVisArea.GetSize().Height() );
+ xObj->setVisualAreaSize( pOe->nAspect, aSize );
+ }
+ //xInplaceObj->EnableSetModified( TRUE );
+ }
+
+ svt::EmbeddedObjectRef aObj( xObj, pOe->nAspect );
+
+ // TODO/LATER: need MediaType for Graphic
+ aObj.SetGraphic( aGraphic, ::rtl::OUString() );
+
+ pRet = new SdrOle2Obj( aObj, aNm, rBoundRect, FALSE );
+ }
+ }
+ }
+ }
+ }
+ }
+ delete pDest;
+ }
+ }
+ }
+ rStCtrl.Seek( nOldPos );
+
+ return pRet;
+}
+
+SvMemoryStream* SdrPowerPointImport::ImportExOleObjStg( UINT32 nPersistPtr, UINT32& nOleId ) const
+{
+ SvMemoryStream* pRet = NULL;
+ if ( nPersistPtr && ( nPersistPtr < nPersistPtrAnz ) )
+ {
+ UINT32 nOldPos, nOfs = pPersistPtr[ nPersistPtr ];
+ nOldPos = rStCtrl.Tell();
+ rStCtrl.Seek( nOfs );
+ DffRecordHeader aHd;
+ rStCtrl >> aHd;
+ if ( aHd.nRecType == DFF_PST_ExOleObjStg )
+ {
+ UINT32 nLen = aHd.nRecLen - 4;
+ if ( (INT32)nLen > 0 )
+ {
+ rStCtrl >> nOleId;
+ pRet = new SvMemoryStream;
+ ZCodec aZCodec( 0x8000, 0x8000 );
+ aZCodec.BeginCompression();
+ aZCodec.Decompress( rStCtrl, *pRet );
+ if ( !aZCodec.EndCompression() )
+ delete pRet, pRet = NULL;
+ }
+ }
+ rStCtrl.Seek( nOldPos );
+ }
+ return pRet;
+}
+
+void SdrPowerPointImport::SeekOle( SfxObjectShell* pShell, sal_uInt32 nFilterOptions )
+{
+ if ( pShell )
+ {
+ DffRecordHeader* pHd;
+
+ UINT32 nOldPos = rStCtrl.Tell();
+ if ( nFilterOptions & 1 )
+ {
+ pHd = aDocRecManager.GetRecordHeader( PPT_PST_List, SEEK_FROM_BEGINNING );
+ if ( pHd )
+ {
+ // we try to locate the basic atom
+ pHd->SeekToContent( rStCtrl );
+ if ( SeekToRec( rStCtrl, PPT_PST_VBAInfo, pHd->GetRecEndFilePos(), pHd ) )
+ {
+ if ( SeekToRec( rStCtrl, PPT_PST_VBAInfoAtom, pHd->GetRecEndFilePos(), pHd ) )
+ {
+ UINT32 nPersistPtr, nIDoNotKnow1, nIDoNotKnow2;
+ rStCtrl >> nPersistPtr
+ >> nIDoNotKnow1
+ >> nIDoNotKnow2;
+
+ UINT32 nOleId;
+ SvMemoryStream* pBas = ImportExOleObjStg( nPersistPtr, nOleId );
+ if ( pBas )
+ {
+ SotStorageRef xSource( new SotStorage( pBas, TRUE ) );
+ SotStorageRef xDest( new SotStorage( new SvMemoryStream(), TRUE ) );
+ if ( xSource.Is() && xDest.Is() )
+ {
+ // is this a visual basic storage ?
+ SotStorageRef xSubStorage = xSource->OpenSotStorage( String( RTL_CONSTASCII_USTRINGPARAM( "VBA" ) ),
+ STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL );
+ if( xSubStorage.Is() && ( SVSTREAM_OK == xSubStorage->GetError() ) )
+ {
+ SotStorageRef xMacros = xDest->OpenSotStorage( String( RTL_CONSTASCII_USTRINGPARAM( "MACROS" ) ) );
+ if ( xMacros.Is() )
+ {
+ SvStorageInfoList aList;
+ xSource->FillInfoList( &aList );
+ UINT32 i;
+
+ BOOL bCopied = TRUE;
+ for ( i = 0; i < aList.Count(); i++ ) // copy all entrys
+ {
+ const SvStorageInfo& rInfo = aList[ i ];
+ if ( !xSource->CopyTo( rInfo.GetName(), xMacros, rInfo.GetName() ) )
+ bCopied = FALSE;
+ }
+ if ( i && bCopied )
+ {
+ SvxImportMSVBasic aMSVBas( *pShell, *xDest, TRUE, FALSE );
+ //int nSuccess = aMSVBas.Import( String( RTL_CONSTASCII_USTRINGPARAM( "MACROS" ) ),
+ // String( RTL_CONSTASCII_USTRINGPARAM( "VBA" ) ), TRUE, FALSE );
+
+ uno::Reference < embed::XStorage > xDoc( pShell->GetStorage() );
+ if ( xDoc.is() )
+ {
+ SotStorageRef xVBA = SotStorage::OpenOLEStorage( xDoc, String( RTL_CONSTASCII_USTRINGPARAM( "_MS_VBA_Macros" ) ) );
+ if ( xVBA.Is() && ( xVBA->GetError() == SVSTREAM_OK ) )
+ {
+ SotStorageRef xSubVBA = xVBA->OpenSotStorage( String( RTL_CONSTASCII_USTRINGPARAM( "_MS_VBA_Overhead" ) ) );
+ if ( xSubVBA.Is() && ( xSubVBA->GetError() == SVSTREAM_OK ) )
+ {
+ SotStorageStreamRef xOriginal = xSubVBA->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM( "_MS_VBA_Overhead2" ) ) );
+ if ( xOriginal.Is() && ( xOriginal->GetError() == SVSTREAM_OK ) )
+ {
+ if ( nPersistPtr && ( nPersistPtr < nPersistPtrAnz ) )
+ {
+ rStCtrl.Seek( pPersistPtr[ nPersistPtr ] );
+ rStCtrl >> *pHd;
+
+ *xOriginal << nIDoNotKnow1
+ << nIDoNotKnow2;
+
+ UINT32 nSource, nToCopy, nBufSize;
+ nSource = rStCtrl.Tell();
+ nToCopy = pHd->nRecLen;
+ BYTE* pBuf = new BYTE[ 0x40000 ]; // 256KB Buffer
+ if ( pBuf )
+ {
+ while ( nToCopy )
+ {
+ nBufSize = ( nToCopy >= 0x40000 ) ? 0x40000 : nToCopy;
+ rStCtrl.Read( pBuf, nBufSize );
+ xOriginal->Write( pBuf, nBufSize );
+ nToCopy -= nBufSize;
+ }
+ delete[] pBuf;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ pHd = aDocRecManager.GetRecordHeader( PPT_PST_ExObjList, SEEK_FROM_BEGINNING );
+ if ( pHd )
+ {
+ DffRecordManager* pExObjListManager = NULL;
+ DffRecordHeader* pExEmbed = NULL;
+
+ pHd->SeekToBegOfRecord( rStCtrl );
+ pExObjListManager = new DffRecordManager( rStCtrl );
+ sal_uInt16 i, nRecType(PPT_PST_ExEmbed);
+
+ for ( i = 0; i < 2; i++ )
+ {
+ switch ( i )
+ {
+ case 0 : nRecType = PPT_PST_ExEmbed; break;
+ case 1 : nRecType = PPT_PST_ExControl; break;
+ }
+ for ( pExEmbed = pExObjListManager->GetRecordHeader( nRecType, SEEK_FROM_BEGINNING );
+ pExEmbed; pExEmbed = pExObjListManager->GetRecordHeader( nRecType, SEEK_FROM_CURRENT ) )
+ {
+ pExEmbed->SeekToContent( rStCtrl );
+
+ DffRecordHeader aExOleAtHd;
+ if ( SeekToRec( rStCtrl, PPT_PST_ExOleObjAtom, pExEmbed->GetRecEndFilePos(), &aExOleAtHd ) )
+ {
+ PptExOleObjAtom aAt;
+ rStCtrl >> aAt;
+
+ if ( aAt.nPersistPtr && ( aAt.nPersistPtr < nPersistPtrAnz ) )
+ {
+ UINT32 nId;
+ rStCtrl.Seek( pPersistPtr[ aAt.nPersistPtr ] );
+ DffRecordHeader aHd;
+ rStCtrl >> aHd;
+ if ( aHd.nRecType == DFF_PST_ExOleObjStg )
+ {
+ rStCtrl >> nId;
+ aOleObjectList.Insert(
+ new PPTOleEntry( aAt.nId, aHd.nFilePos, pShell, nRecType, aAt.nAspect ) );
+ }
+ }
+ }
+ }
+ }
+ delete pExObjListManager;
+ }
+ rStCtrl.Seek( nOldPos );
+ }
+}
+
+sal_Bool SdrPowerPointImport::ReadFontCollection()
+{
+ sal_Bool bRet = FALSE;
+ DffRecordHeader* pEnvHd = aDocRecManager.GetRecordHeader( PPT_PST_Environment );
+ if ( pEnvHd )
+ {
+ ULONG nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer spaetere Restauration
+ pEnvHd->SeekToContent( rStCtrl );
+ DffRecordHeader aListHd;
+ if ( SeekToRec( rStCtrl, PPT_PST_FontCollection, pEnvHd->GetRecEndFilePos(), &aListHd ) )
+ {
+ sal_uInt16 nCount2 = 0;
+ VirtualDevice* pVDev = NULL;
+ while ( SeekToRec( rStCtrl, PPT_PST_FontEntityAtom, aListHd.GetRecEndFilePos() ) )
+ {
+ bRet = TRUE;
+ if ( !pFonts )
+ pFonts = new PptFontCollection;
+ PptFontEntityAtom* pFont = new PptFontEntityAtom;
+ rStCtrl >> *pFont;
+
+ Font aFont;
+ aFont.SetCharSet( pFont->eCharSet );
+ aFont.SetName( pFont->aName );
+ aFont.SetFamily( pFont->eFamily );
+ aFont.SetPitch( pFont->ePitch );
+ aFont.SetHeight( 100 );
+
+ if ( mbTracing && !pFont->bAvailable )
+ mpTracer->Trace( rtl::OUString::createFromAscii( "sd1000" ), pFont->aName );
+
+#ifdef DBG_EXTRACTFONTMETRICS
+
+ SvxFont aTmpFont( aFont );
+
+ if ( !pVDev )
+ pVDev = new VirtualDevice;
+ aTmpFont.SetPhysFont( pVDev );
+ FontMetric aMetric( pVDev->GetFontMetric() );
+ sal_uInt16 nTxtHeight = (sal_uInt16)aMetric.GetAscent() + (sal_uInt16)aMetric.GetDescent();
+
+ String aFileURLStr;
+ if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aFileURLStr ) )
+ {
+ INetURLObject aURL( aFileURLStr );
+ aURL.SetName( String( RTL_CONSTASCII_STRINGPARAM( "dbgfontmetrics.txt" ) ) );
+
+ SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE );
+ if( pDbgOut )
+ {
+ pDbgOut->Seek( STREAM_SEEK_TO_END );
+
+ Printer* pPrinter = NULL;
+ if ( pSdrModel->GetRefDevice() && pSdrModel->GetRefDevice()->GetOutDevType() == OUTDEV_PRINTER )
+ pPrinter = (Printer*)pSdrModel->GetRefDevice();
+ if ( pPrinter )
+ {
+ Font aOldFont( pPrinter->GetFont() );
+ aFont.SetKerning( TRUE );
+ pPrinter->SetFont( aFont );
+ aMetric = pPrinter->GetFontMetric();
+ pPrinter->SetFont( aOldFont );
+ }
+
+ if ( ( pPrinter == NULL ) || ( aMetric.GetIntLeading() == 0 ) )
+ {
+ VirtualDevice aVirDev( 1 );
+ aVirDev.SetFont( aFont );
+ aMetric = aVirDev.GetFontMetric();
+ }
+ ByteString aFontName( aFont.GetName(), RTL_TEXTENCODING_UTF8 );
+ ByteString aHeight( ByteString::CreateFromInt32( aMetric.GetLineHeight() ) );
+ ByteString aAscent( ByteString::CreateFromInt32( aMetric.GetAscent() ) );
+ ByteString aDescent( ByteString::CreateFromInt32( aMetric.GetDescent() ) );
+ ByteString aLeading( ByteString::CreateFromInt32( aMetric.GetIntLeading() ) );
+ ByteString aPhysHeight( ByteString::CreateFromInt32( nTxtHeight ) );
+
+ *pDbgOut << (sal_uInt8)0xa
+ << "FontName : " << aFontName.GetBuffer() << (sal_uInt8)0xa
+ << " Height: " << aHeight.GetBuffer() << (sal_uInt8)0xa
+ << " Ascent: " << aAscent.GetBuffer() << (sal_uInt8)0xa
+ << " Descent:" << aDescent.GetBuffer() << (sal_uInt8)0xa
+ << " Leading:" << aLeading.GetBuffer() << (sal_uInt8)0xa
+ << "PhysHeight :" << aPhysHeight.GetBuffer()<< (sal_uInt8)0xa;
+ }
+ delete pDbgOut;
+ }
+#endif
+ // following block is necessary, because our old PowerPoint export did not set the
+ // correct charset
+ if ( pFont->aName.EqualsIgnoreCaseAscii( "Wingdings" ) ||
+ pFont->aName.EqualsIgnoreCaseAscii( "Wingdings 2" ) ||
+ pFont->aName.EqualsIgnoreCaseAscii( "Wingdings 3" ) ||
+ pFont->aName.EqualsIgnoreCaseAscii( "Monotype Sorts" ) ||
+ pFont->aName.EqualsIgnoreCaseAscii( "Monotype Sorts 2" ) ||
+ pFont->aName.EqualsIgnoreCaseAscii( "Webdings" ) ||
+ pFont->aName.EqualsIgnoreCaseAscii( "StarBats" ) ||
+ pFont->aName.EqualsIgnoreCaseAscii( "StarMath" ) ||
+ pFont->aName.EqualsIgnoreCaseAscii( "ZapfDingbats" ) )
+ {
+ pFont->eCharSet = RTL_TEXTENCODING_SYMBOL;
+ };
+ pFonts->C40_INSERT( PptFontEntityAtom, pFont, nCount2++ );
+ }
+ delete pVDev;
+ }
+ rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
+ }
+ return bRet;
+}
+
+PptSlidePersistList* SdrPowerPointImport::GetPageList(PptPageKind ePageKind) const
+{
+ if ( ePageKind == PPT_MASTERPAGE )
+ return pMasterPages;
+ if ( ePageKind == PPT_SLIDEPAGE )
+ return pSlidePages;
+ if ( ePageKind == PPT_NOTEPAGE )
+ return pNotePages;
+ return NULL;
+}
+
+SdrOutliner* SdrPowerPointImport::GetDrawOutliner( SdrTextObj* pSdrText ) const
+{
+ if ( !pSdrText )
+ return NULL;
+ else
+ return &pSdrText->ImpGetDrawOutliner();
+}
+
+
+SdrObject* SdrPowerPointImport::ReadObjText( PPTTextObj* pTextObj, SdrObject* pSdrObj, SdPage* pPage ) const
+{
+ SdrTextObj* pText = PTR_CAST( SdrTextObj, pSdrObj );
+ if ( pText )
+ {
+ if ( !ApplyTextObj( pTextObj, pText, pPage, NULL, NULL ) )
+ pSdrObj = NULL;
+ }
+ return pSdrObj;
+}
+
+
+SdrObject* SdrPowerPointImport::ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pSdrText, SdPage* /*pPage*/,
+ SfxStyleSheet* pSheet, SfxStyleSheet** ppStyleSheetAry ) const
+{
+ SdrTextObj* pText = pSdrText;
+ if ( pTextObj->Count() )
+ {
+ UINT32 nDestinationInstance = pTextObj->GetDestinationInstance() ;
+ SdrOutliner& rOutliner = pText->ImpGetDrawOutliner();
+ if ( ( pText->GetObjInventor() == SdrInventor ) && ( pText->GetObjIdentifier() == OBJ_TITLETEXT ) ) // Outliner-Style fuer Titel-Textobjekt?!? (->von DL)
+ rOutliner.Init( OUTLINERMODE_TITLEOBJECT ); // Outliner reset
+
+ BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
+ rOutliner.SetUpdateMode( FALSE );
+ if ( pSheet )
+ {
+ if ( rOutliner.GetStyleSheet( 0 ) != pSheet )
+ rOutliner.SetStyleSheet( 0, pSheet );
+ }
+ rOutliner.SetVertical( pTextObj->GetVertical() );
+ sal_Int16 nLastStartNumbering = -1;
+ const PPTParagraphObj* pPreviousParagraph = NULL;
+ for ( PPTParagraphObj* pPara = pTextObj->First(); pPara; pPara = pTextObj->Next() )
+ {
+ UINT32 nTextSize = pPara->GetTextSize();
+ if ( ! ( nTextSize & 0xffff0000 ) )
+ {
+ PPTPortionObj* pPortion;
+ sal_Unicode* pParaText = new sal_Unicode[ nTextSize ];
+ UINT32 nCurrentIndex = 0;
+ for ( pPortion = pPara->First(); pPortion; pPortion = pPara->Next() )
+ {
+ if ( pPortion->mpFieldItem )
+ pParaText[ nCurrentIndex++ ] = ' ';
+ else
+ {
+ sal_uInt32 nCharacters = pPortion->Count();
+ const sal_Unicode* pSource = pPortion->maString.GetBuffer();
+ sal_Unicode* pDest = pParaText + nCurrentIndex;
+
+ sal_uInt32 nFont;
+ pPortion->GetAttrib( PPT_CharAttr_Font, nFont, pTextObj->GetInstance() );
+ PptFontEntityAtom* pFontEnityAtom = GetFontEnityAtom( nFont );
+ if ( pFontEnityAtom && ( pFontEnityAtom->eCharSet == RTL_TEXTENCODING_SYMBOL ) )
+ {
+ sal_uInt32 i;
+ sal_Unicode nUnicode;
+ for ( i = 0; i < nCharacters; i++ )
+ {
+ nUnicode = pSource[ i ];
+ if ( ! ( nUnicode & 0xff00 ) )
+ nUnicode |= 0xf000;
+ pDest[ i ] = nUnicode;
+ }
+ }
+ else
+ memcpy( pDest, pSource, nCharacters << 1 );
+ nCurrentIndex += nCharacters;
+ }
+ }
+ sal_uInt16 nParaIndex = (UINT16)pTextObj->GetCurrentIndex();
+ SfxStyleSheet* pS = ( ppStyleSheetAry ) ? ppStyleSheetAry[ pPara->pParaSet->mnDepth ] : pSheet;
+
+ ESelection aSelection( nParaIndex, 0, nParaIndex, 0 );
+ rOutliner.Insert( String(), nParaIndex, pPara->pParaSet->mnDepth );
+ rOutliner.QuickInsertText( String( pParaText, (UINT16)nCurrentIndex ), aSelection );
+ rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() );
+ if ( pS )
+ rOutliner.SetStyleSheet( nParaIndex, pS );
+
+ for ( pPortion = pPara->First(); pPortion; pPortion = pPara->Next() )
+ {
+ SfxItemSet aPortionAttribs( rOutliner.GetEmptyItemSet() );
+ SvxFieldItem* pFieldItem = pPortion->GetTextField();
+ if ( pFieldItem )
+ {
+ rOutliner.QuickInsertField( *pFieldItem, ESelection( nParaIndex, aSelection.nEndPos, nParaIndex, aSelection.nEndPos + 1 ) );
+ aSelection.nEndPos++;
+ delete pFieldItem;
+ }
+ else
+ {
+ const sal_Unicode *pF, *pPtr = pPortion->maString.GetBuffer();
+ const sal_Unicode *pMax = pPtr + pPortion->maString.Len();
+ sal_Int32 nLen;
+ for ( pF = pPtr; pPtr < pMax; pPtr++ )
+ {
+ if ( *pPtr == 0xb )
+ {
+ nLen = pPtr - pF;
+ if ( nLen )
+ aSelection.nEndPos =
+ sal::static_int_cast< USHORT >(
+ aSelection.nEndPos + nLen );
+ pF = pPtr + 1;
+ rOutliner.QuickInsertLineBreak( ESelection( nParaIndex, aSelection.nEndPos, nParaIndex, aSelection.nEndPos + 1 ) );
+ aSelection.nEndPos++;
+ }
+ }
+ nLen = pPtr - pF;
+ if ( nLen )
+ aSelection.nEndPos = sal::static_int_cast< USHORT >(
+ aSelection.nEndPos + nLen );
+ }
+ pPortion->ApplyTo( aPortionAttribs, (SdrPowerPointImport&)*this, nDestinationInstance, pTextObj );
+ rOutliner.QuickSetAttribs( aPortionAttribs, aSelection );
+ aSelection.nStartPos = aSelection.nEndPos;
+ }
+ boost::optional< sal_Int16 > oStartNumbering;
+ SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() );
+ pPara->ApplyTo( aParagraphAttribs, oStartNumbering, (SdrPowerPointImport&)*this, nDestinationInstance, pPreviousParagraph );
+
+ UINT32 nIsBullet2 = 0; //, nInstance = nDestinationInstance != 0xffffffff ? nDestinationInstance : pTextObj->GetInstance();
+ pPara->GetAttrib( PPT_ParaAttr_BulletOn, nIsBullet2, nDestinationInstance );
+ if ( !nIsBullet2 )
+ aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, FALSE ) );
+
+ if ( oStartNumbering )
+ {
+ if ( *oStartNumbering != nLastStartNumbering )
+ rOutliner.SetNumberingStartValue( nParaIndex, *oStartNumbering );
+ else
+ rOutliner.SetNumberingStartValue( nParaIndex, -1 );
+ nLastStartNumbering = *oStartNumbering;
+ }
+ else
+ {
+ nLastStartNumbering = -1;
+ rOutliner.SetNumberingStartValue( nParaIndex, nLastStartNumbering );
+ }
+
+ pPreviousParagraph = pPara;
+ if ( !aSelection.nStartPos ) // in PPT empty paragraphs never gets a bullet
+ {
+ aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, FALSE ) );
+// rOutliner.SetDepth( rOutliner.GetParagraph( nParaIndex ), -1 );
+ }
+ aSelection.nStartPos = 0;
+ rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection );
+ delete[] pParaText;
+ }
+ }
+ OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
+ rOutliner.Clear();
+ rOutliner.SetUpdateMode( bOldUpdateMode );
+ pText->SetOutlinerParaObject( pNewText );
+ }
+ return pText;
+}
+
+sal_Bool SdrPowerPointImport::SeekToDocument( DffRecordHeader* pRecHd ) const
+{
+ sal_Bool bRet;
+ ULONG nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer ggf. spaetere Restauration
+ rStCtrl.Seek( nDocStreamPos );
+ DffRecordHeader aDocHd;
+ rStCtrl >> aDocHd;
+ bRet = aDocHd.nRecType == PPT_PST_Document;
+ if ( bRet )
+ {
+ if ( pRecHd )
+ *pRecHd = aDocHd;
+ else
+ aDocHd.SeekToBegOfRecord( rStCtrl );
+ }
+ if ( !bRet )
+ rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
+ return bRet;
+}
+
+sal_Bool SdrPowerPointImport::SeekToContentOfProgTag( sal_Int32 nVersion, SvStream& rSt,
+ const DffRecordHeader& rSourceHd, DffRecordHeader& rContentHd )
+{
+ sal_Bool bRetValue = sal_False;
+ sal_uInt32 nOldPos = rSt.Tell();
+
+ DffRecordHeader aProgTagsHd, aProgTagBinaryDataHd;
+ rSourceHd.SeekToContent( rSt );
+ sal_Bool bFound = rSourceHd.nRecType == PPT_PST_ProgTags;
+ if ( !bFound )
+ bFound = SeekToRec( rSt, PPT_PST_ProgTags, rSourceHd.GetRecEndFilePos(), &aProgTagsHd );
+ if ( bFound )
+ {
+ while( SeekToRec( rSt, PPT_PST_ProgBinaryTag, aProgTagsHd.GetRecEndFilePos(), &aProgTagBinaryDataHd ) )
+ {
+ rSt >> rContentHd;
+ if ( rContentHd.nRecType == PPT_PST_CString )
+ {
+ sal_uInt16 n = 6;
+ sal_uInt32 i = rContentHd.nRecLen >> 1;
+ if ( i > n )
+ {
+ String aPre, aSuf;
+ sal_Unicode *pTmp = aPre.AllocBuffer( n );
+ while ( n-- )
+ rSt >> *pTmp++;
+ n = (sal_uInt16)( i - 6 );
+ pTmp = aSuf.AllocBuffer( n );
+ while ( n-- )
+ rSt >> *pTmp++;
+ sal_Int32 nV = aSuf.ToInt32();
+ if ( ( nV == nVersion ) && ( aPre == String( RTL_CONSTASCII_USTRINGPARAM( "___PPT" ) ) ) )
+ {
+ rContentHd.SeekToEndOfRecord( rSt );
+ rSt >> rContentHd;
+ if ( rContentHd.nRecType == PPT_PST_BinaryTagData )
+ {
+ bRetValue = sal_True;
+ break;
+ }
+ }
+ }
+ }
+ aProgTagBinaryDataHd.SeekToEndOfRecord( rSt );
+ }
+ }
+ if ( !bRetValue )
+ rSt.Seek( nOldPos );
+ return bRetValue;
+}
+
+UINT32 SdrPowerPointImport::GetAktPageId()
+{
+ PptSlidePersistList* pList = GetPageList( eAktPageKind );
+ if ( pList && nAktPageNum < pList->Count() )
+ return (*pList)[ (USHORT)nAktPageNum ]->aPersistAtom.nSlideId;
+ return 0;
+}
+
+sal_Bool SdrPowerPointImport::SeekToAktPage( DffRecordHeader* pRecHd ) const
+{
+ sal_Bool bRet = FALSE;
+ PptSlidePersistList* pList = GetPageList( eAktPageKind );
+ if ( pList && ( nAktPageNum < pList->Count() ) )
+ {
+ ULONG nPersist = (*pList)[ (USHORT)nAktPageNum ]->aPersistAtom.nPsrReference;
+ if ( nPersist > 0 && nPersist < nPersistPtrAnz )
+ {
+ ULONG nFPos = 0;
+ nFPos = pPersistPtr[ nPersist ];
+ if ( nFPos < nStreamLen )
+ {
+ rStCtrl.Seek( nFPos );
+ if ( pRecHd )
+ rStCtrl >> *pRecHd;
+ bRet = TRUE;
+ }
+ }
+ }
+ return bRet;
+}
+
+USHORT SdrPowerPointImport::GetPageCount( PptPageKind ePageKind ) const
+{
+ PptSlidePersistList* pList = GetPageList( ePageKind );
+ if ( pList )
+ return pList->Count();
+ return 0;
+}
+
+void SdrPowerPointImport::SetPageNum( sal_uInt16 nPageNum, PptPageKind eKind )
+{
+ eAktPageKind = eKind;
+ nAktPageNum = nPageNum;
+
+ pPPTStyleSheet = NULL;
+
+ sal_Bool bHasMasterPage = sal_True;
+ sal_uInt16 nMasterIndex = 0;
+
+ if ( eKind == PPT_MASTERPAGE )
+ nMasterIndex = nPageNum;
+ else
+ {
+ if ( HasMasterPage( nPageNum, eKind ) )
+ nMasterIndex = GetMasterPageIndex( nPageNum, eKind );
+ else
+ bHasMasterPage = sal_False;
+ }
+ if ( bHasMasterPage )
+ {
+ PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE );
+ if ( pPageList && nMasterIndex < pPageList->Count() )
+ {
+ PptSlidePersistEntry* pMasterPersist = (*pPageList)[ nMasterIndex ];
+ if ( ( pMasterPersist->pStyleSheet == NULL ) && pMasterPersist->aSlideAtom.nMasterId )
+ {
+ nMasterIndex = pMasterPages->FindPage( pMasterPersist->aSlideAtom.nMasterId );
+ if ( nMasterIndex != PPTSLIDEPERSIST_ENTRY_NOTFOUND )
+ pMasterPersist = (*pPageList)[ nMasterIndex ];
+ }
+ pPPTStyleSheet = pMasterPersist->pStyleSheet;
+ }
+ }
+ if ( !pPPTStyleSheet )
+ pPPTStyleSheet = pDefaultSheet;
+}
+
+Size SdrPowerPointImport::GetPageSize() const
+{
+ Size aRet( IsNoteOrHandout( nAktPageNum, eAktPageKind ) ? aDocAtom.GetNotesPageSize() : aDocAtom.GetSlidesPageSize() );
+ Scale( aRet );
+ // PPT arbeitet nur mit Einheiten zu 576DPI. Um Ungenauigkeiten zu
+ // vermeiden runde ich die letzte Nachkommastelle metrisch weg.
+ if ( nMapMul > 2 * nMapDiv )
+ {
+ MapUnit eMap = pSdrModel->GetScaleUnit();
+ bool bInch = IsInch( eMap );
+ long nInchMul = 1, nInchDiv = 1;
+ if ( bInch )
+ { // Size temporaer (zum runden) in nach metric konvertieren
+ Fraction aFact(GetMapFactor(eMap,MAP_100TH_MM).X());
+ nInchMul = aFact.GetNumerator();
+ nInchDiv = aFact.GetDenominator();
+ aRet.Width() = BigMulDiv( aRet.Width(), nInchMul, nInchDiv );
+ aRet.Height() = BigMulDiv( aRet.Height(), nInchMul, nInchDiv );
+ }
+ aRet.Width() += 5; aRet.Width() /= 10; aRet.Width()*=10;
+ aRet.Height() += 5; aRet.Height() /= 10; aRet.Height()*=10;
+ if ( bInch )
+ {
+ aRet.Width() = BigMulDiv( aRet.Width(), nInchDiv, nInchMul );
+ aRet.Height() = BigMulDiv( aRet.Height(), nInchDiv, nInchMul );
+ }
+ }
+ return aRet;
+}
+
+FASTBOOL SdrPowerPointImport::GetColorFromPalette( USHORT nNum, Color& rColor ) const
+{
+ if ( nPageColorsNum != nAktPageNum || ePageColorsKind != eAktPageKind )
+ {
+ UINT16 nSlideFlags = 0;
+ PptSlidePersistList* pPageList = GetPageList( eAktPageKind );
+ if ( pPageList && ( nAktPageNum < pPageList->Count() ) )
+ {
+ PptSlidePersistEntry* pE = (*pPageList)[ nAktPageNum ];
+ if ( pE )
+ nSlideFlags = pE->aSlideAtom.nFlags;
+ if ( ! ( nSlideFlags & 2 ) )
+ ((SdrPowerPointImport*)this)->aPageColors = pE->aColorScheme;
+ }
+ if ( nSlideFlags & 2 ) // follow master colorscheme ?
+ {
+ PptSlidePersistList* pPageList2 = GetPageList( PPT_MASTERPAGE );
+ if ( pPageList2 )
+ {
+ PptSlidePersistEntry* pMasterPersist = NULL;
+ if ( eAktPageKind == PPT_MASTERPAGE )
+ pMasterPersist = (*pPageList2)[ nAktPageNum ];
+ else
+ {
+ if ( HasMasterPage( nAktPageNum, eAktPageKind ) )
+ {
+ sal_uInt16 nMasterNum = GetMasterPageIndex( nAktPageNum, eAktPageKind );
+ if ( nMasterNum < pPageList2->Count() )
+ pMasterPersist = (*pPageList2)[ nMasterNum ];
+ }
+ }
+ if ( pMasterPersist )
+ {
+ while( ( pMasterPersist && pMasterPersist->aSlideAtom.nFlags & 2 ) // it is possible that a masterpage
+ && pMasterPersist->aSlideAtom.nMasterId ) // itself is following a master colorscheme
+ {
+ sal_uInt16 nNextMaster = pMasterPages->FindPage( pMasterPersist->aSlideAtom.nMasterId );
+ if ( nNextMaster == PPTSLIDEPERSIST_ENTRY_NOTFOUND )
+ break;
+ else
+ pMasterPersist = (*pPageList2)[ nNextMaster ];
+ }
+ ((SdrPowerPointImport*)this)->aPageColors = pMasterPersist->aColorScheme;
+ }
+ }
+ }
+ // momentanes Farbschema eintragen
+ ((SdrPowerPointImport*)this)->nPageColorsNum = nAktPageNum;
+ ((SdrPowerPointImport*)this)->ePageColorsKind = eAktPageKind;
+ }
+ rColor = aPageColors.GetColor( nNum );
+ return TRUE;
+}
+
+BOOL SdrPowerPointImport::SeekToShape( SvStream& rSt, void* pClientData, UINT32 nId ) const
+{
+ BOOL bRet = SvxMSDffManager::SeekToShape( rSt, pClientData, nId );
+ if ( !bRet )
+ {
+ ProcessData& rData = *( (ProcessData*)pClientData );
+ PptSlidePersistEntry& rPersistEntry = rData.rPersistEntry;
+ if ( rPersistEntry.ePageKind == PPT_SLIDEPAGE )
+ {
+ if ( HasMasterPage( nAktPageNum, eAktPageKind ) )
+ {
+ USHORT nMasterNum = GetMasterPageIndex( nAktPageNum, eAktPageKind );
+ PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE );
+ if ( pPageList && ( nMasterNum < pPageList->Count() ) )
+ {
+ PptSlidePersistEntry* pPersist = (*pPageList)[ nMasterNum ]; // get the masterpage's persistentry
+ if ( pPersist && pPersist->pPresentationObjects )
+ {
+ UINT32 nCurrent(0L);
+ DffRecordList* pCList = maShapeRecords.pCList; // we got a backup of the current position
+ if ( pCList )
+ nCurrent = pCList->nCurrent;
+ if ( ((SdrEscherImport*)this )->maShapeRecords.SeekToContent( rSt, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) )
+ {
+ UINT32 nStreamPos = rSt.Tell();
+ PPTTextObj aTextObj( rSt, (SdrPowerPointImport&)*this, rPersistEntry, NULL );
+ if ( aTextObj.Count() || aTextObj.GetOEPlaceHolderAtom() )
+ {
+ UINT32 nShapePos = 0;
+ switch ( aTextObj.GetInstance() )
+ {
+ case TSS_TYPE_TITLE :
+ nShapePos = pPersist->pPresentationObjects[ TSS_TYPE_PAGETITLE ];
+ break;
+ case TSS_TYPE_PAGETITLE :
+ nShapePos = pPersist->pPresentationObjects[ TSS_TYPE_PAGETITLE ];
+ break;
+ case TSS_TYPE_SUBTITLE :
+ case TSS_TYPE_HALFBODY :
+ case TSS_TYPE_QUARTERBODY :
+ case TSS_TYPE_BODY :
+ nShapePos = pPersist->pPresentationObjects[ TSS_TYPE_BODY ];
+ break;
+// case TSS_TYPE_NOTES :
+// case TSS_TYPE_UNUSED :
+// case TSS_TYPE_TEXT_IN_SHAPE :
+ }
+ if ( nShapePos )
+ {
+ rSt.Seek( nShapePos );
+ bRet = TRUE;
+ }
+ }
+ if ( !bRet )
+ rSt.Seek( nStreamPos );
+ }
+ if ( pCList ) // restoring
+ pCList->nCurrent = nCurrent;
+ ((SdrEscherImport*)this )->maShapeRecords.pCList = pCList;
+ }
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+SdrPage* SdrPowerPointImport::MakeBlancPage( sal_Bool bMaster ) const
+{
+ SdrPage* pRet = pSdrModel->AllocPage( bMaster );
+ pRet->SetSize( GetPageSize() );
+
+/*
+ SJ (21.08.00) : since bug #77576# i decided not to set a border size.
+
+ Size aPageSize( aDocAtom.GetSlidesPageSize() ); // PageSize in 576DPI-Units
+ long nHMarg = aPageSize.Width() - aDocAtom.aSlidesPageSize.Width();
+ long nVMarg = aPageSize.Height() - aDocAtom.aSlidesPageSize.Height();
+ if ( nHMarg > 0 )
+ {
+ Scale( nHMarg );
+ pRet->SetLftBorder( nHMarg / 2 );
+ pRet->SetRgtBorder( nHMarg - nHMarg / 2 );
+ }
+ if ( nVMarg > 0 )
+ {
+ Scale( nVMarg );
+ pRet->SetUppBorder( nVMarg / 2 );
+ pRet->SetLwrBorder( nVMarg - nVMarg / 2 );
+ }
+*/
+ return pRet;
+}
+
+void ImportComment10( SvxMSDffManager& rMan, SvStream& rStCtrl, SdrPage* pPage, DffRecordHeader& rComment10Hd )
+{
+ rtl::OUString sAuthor;
+ rtl::OUString sText;
+ rtl::OUString sInitials;
+
+ sal_Int32 nIndex = 0;
+ util::DateTime aDateTime;
+ sal_Int32 nPosX = 0;
+ sal_Int32 nPosY = 0;
+
+ while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < rComment10Hd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aCommentHd;
+ rStCtrl >> aCommentHd;
+ switch( aCommentHd.nRecType )
+ {
+ case PPT_PST_CString :
+ {
+ String aString;
+ SvxMSDffManager::MSDFFReadZString( rStCtrl, aString, aCommentHd.nRecLen, TRUE );
+ switch ( aCommentHd.nRecInstance )
+ {
+ case 0 : sAuthor = aString; break;
+ case 1 : sText = aString; break;
+ case 2 : sInitials = aString; break;
+ }
+ }
+ break;
+
+ case PPT_PST_CommentAtom10 :
+ {
+ rStCtrl >> nIndex
+ >> aDateTime.Year
+ >> aDateTime.Month
+ >> aDateTime.Day // DayOfWeek
+ >> aDateTime.Day
+ >> aDateTime.Hours
+ >> aDateTime.Minutes
+ >> aDateTime.Seconds
+ >> aDateTime.HundredthSeconds
+ >> nPosX
+ >> nPosY;
+
+ aDateTime.HundredthSeconds /= 10;
+ }
+ break;
+ }
+ aCommentHd.SeekToEndOfRecord( rStCtrl );
+ }
+ Point aPosition( nPosX, nPosY );
+ rMan.Scale( aPosition );
+
+ try
+ {
+ uno::Reference< office::XAnnotationAccess > xAnnotationAccess( pPage->getUnoPage(), UNO_QUERY_THROW );
+ uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() );
+ xAnnotation->setPosition( geometry::RealPoint2D( aPosition.X() / 100.0, aPosition.Y() / 100.0 ) );
+ xAnnotation->setAuthor( sAuthor );
+ xAnnotation->setDateTime( aDateTime );
+ uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
+ xText->setString( sText );
+ }
+ catch( uno::Exception& )
+ {
+
+ }
+}
+
+
+// be sure not to import masterpages with this method
+// be sure not to import masterpages with this method
+void SdrPowerPointImport::ImportPage( SdrPage* pRet, const PptSlidePersistEntry* pMasterPersist )
+{
+ UINT32 nMerk = rStCtrl.Tell();
+ PptSlidePersistList* pList = GetPageList( eAktPageKind );
+ if ( ( !pList ) || ( pList->Count() <= nAktPageNum ) )
+ return;
+ PptSlidePersistEntry& rSlidePersist = *(*pList)[ nAktPageNum ];
+ if ( rSlidePersist.bStarDrawFiller )
+ return;
+
+ DffRecordHeader aPageHd;
+ if ( SeekToAktPage( &aPageHd ) )
+ {
+ if ( mbTracing )
+ mpTracer->AddAttribute( eAktPageKind == PPT_SLIDEPAGE
+ ? rtl::OUString::createFromAscii( "Page" )
+ : rtl::OUString::createFromAscii( "NotesPage" ),
+ rtl::OUString::valueOf( (sal_Int32)nAktPageNum + 1 ) );
+
+ rSlidePersist.pHeaderFooterEntry = new HeaderFooterEntry( pMasterPersist );
+ ProcessData aProcessData( rSlidePersist, (SdPage*)pRet );
+ while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPageHd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aHd;
+ rStCtrl >> aHd;
+ switch ( aHd.nRecType )
+ {
+ case PPT_PST_HeadersFooters :
+ {
+ ImportHeaderFooterContainer( aHd, *rSlidePersist.pHeaderFooterEntry );
+ }
+ break;
+
+ case PPT_PST_ProgTags :
+ {
+ DffRecordHeader aContentDataHd;
+ if ( SeekToContentOfProgTag( 10, rStCtrl, aHd, aContentDataHd ) )
+ {
+ DffRecordHeader aComment10Hd;
+ while( ( rStCtrl.GetError() == 0 ) && SeekToRec( rStCtrl, PPT_PST_Comment10, aContentDataHd.GetRecEndFilePos(), &aComment10Hd ) )
+ {
+ ImportComment10( *this, rStCtrl, pRet, aComment10Hd );
+ aComment10Hd.SeekToEndOfRecord( rStCtrl );
+ }
+ }
+ }
+ break;
+
+ case PPT_PST_PPDrawing :
+ {
+ DffRecordHeader aPPDrawHd;
+ if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, aHd.GetRecEndFilePos(), &aPPDrawHd ) )
+ {
+ sal_uInt32 nPPDrawOfs = rStCtrl.Tell();
+
+ // importing the background object before importing the page
+ while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPPDrawHd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aEscherObjListHd;
+ rStCtrl >> aEscherObjListHd;
+ switch ( aEscherObjListHd.nRecType )
+ {
+ case DFF_msofbtSpContainer :
+ {
+ Rectangle aPageSize( Point(), pRet->GetSize() );
+ if ( rSlidePersist.aSlideAtom.nFlags & 4 ) // follow master background ?
+ {
+ if ( HasMasterPage( nAktPageNum, eAktPageKind ) )
+ {
+ sal_uInt16 nMasterNum = GetMasterPageIndex( nAktPageNum, eAktPageKind );
+ PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE );
+ PptSlidePersistEntry* pE = (*pPageList)[ nMasterNum ];
+ while( ( pE->aSlideAtom.nFlags & 4 ) && pE->aSlideAtom.nMasterId )
+ {
+ sal_uInt16 nNextMaster = pMasterPages->FindPage( pE->aSlideAtom.nMasterId );
+ if ( nNextMaster == PPTSLIDEPERSIST_ENTRY_NOTFOUND )
+ break;
+ else
+ pE = (*pPageList)[ nNextMaster ];
+ }
+ if ( pE->nBackgroundOffset )
+ {
+ // do not follow master colorscheme ?
+ sal_Bool bTemporary = ( rSlidePersist.aSlideAtom.nFlags & 2 ) != 0;
+ sal_uInt32 nPos = rStCtrl.Tell();
+ rStCtrl.Seek( pE->nBackgroundOffset );
+ rSlidePersist.pBObj = ImportObj( rStCtrl, (void*)&aProcessData, aPageSize, aPageSize );
+ rSlidePersist.bBObjIsTemporary = bTemporary;
+ rStCtrl.Seek( nPos );
+ }
+ }
+ }
+ else
+ {
+ DffRecordHeader aShapeHd;
+ rStCtrl >> aShapeHd;
+ if ( aShapeHd.nRecType == DFF_msofbtSp )
+ {
+ UINT32 nSpFlags;
+ rStCtrl >> nSpFlags >> nSpFlags;
+ if ( nSpFlags & SP_FBACKGROUND )
+ {
+ aEscherObjListHd.SeekToBegOfRecord( rStCtrl );
+ rSlidePersist.pBObj = ImportObj( rStCtrl, (void*)&aProcessData, aPageSize, aPageSize );
+ rSlidePersist.bBObjIsTemporary = sal_False;
+ }
+ }
+ }
+ }
+ break;
+ }
+ if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer )
+ break;
+ aEscherObjListHd.SeekToEndOfRecord( rStCtrl );
+ }
+
+ // now importing page
+ rStCtrl.Seek( nPPDrawOfs );
+ while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aPPDrawHd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aEscherObjListHd;
+ rStCtrl >> aEscherObjListHd;
+ switch ( aEscherObjListHd.nRecType )
+ {
+ case DFF_msofbtSpgrContainer :
+ {
+ DffRecordHeader aShapeHd;
+ if ( SeekToRec( rStCtrl, DFF_msofbtSpContainer, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) )
+ {
+ aShapeHd.SeekToEndOfRecord( rStCtrl );
+ while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < aEscherObjListHd.GetRecEndFilePos() ) )
+ {
+ rStCtrl >> aShapeHd;
+ if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
+ {
+ Rectangle aEmpty;
+ aShapeHd.SeekToBegOfRecord( rStCtrl );
+ sal_Int32 nShapeId;
+ aProcessData.pTableRowProperties = NULL;
+ SdrObject* pObj = ImportObj( rStCtrl, (void*)&aProcessData, aEmpty, aEmpty, 0, &nShapeId );
+ if ( pObj )
+ {
+ if ( aProcessData.pTableRowProperties )
+ pObj = CreateTable( pObj, aProcessData.pTableRowProperties, aProcessData.rPersistEntry.pSolverContainer );
+
+ pRet->NbcInsertObject( pObj );
+
+ if( nShapeId )
+ insertShapeId( nShapeId, pObj );
+ }
+ }
+ aShapeHd.SeekToEndOfRecord( rStCtrl );
+ }
+ }
+ }
+ break;
+ }
+ if ( aEscherObjListHd.nRecType == DFF_msofbtSpgrContainer )
+ break;
+ aEscherObjListHd.SeekToEndOfRecord( rStCtrl );
+ }
+
+ /* There are a lot of Shapes who are dependent to
+ the current background color */
+ if ( rSlidePersist.ePageKind == PPT_SLIDEPAGE )
+ {
+ List* pList2 = aProcessData.pBackgroundColoredObjects;
+ if ( pList2 )
+ {
+ if ( rSlidePersist.pBObj )
+ {
+ void* pPtr;
+ const SfxPoolItem* pPoolItem = NULL;
+ const SfxItemSet& rObjectItemSet = rSlidePersist.pBObj->GetMergedItemSet();
+
+ //SfxItemState eState = rObjectItemSet.GetItemState( XATTR_FILLCOLOR, FALSE, &pPoolItem );
+ if ( pPoolItem )
+ {
+ SfxItemSet aNewSet(*rObjectItemSet.GetPool());
+ aNewSet.Put(*pPoolItem);
+ aNewSet.Put(XFillStyleItem( XFILL_SOLID ));
+
+ for ( pPtr = pList2->First(); pPtr; pPtr = pList2->Next() )
+ {
+ ((SdrObject*)pPtr)->SetMergedItemSet(aNewSet);
+ }
+ }
+ }
+ }
+ }
+ if ( rSlidePersist.pBObj )
+ {
+ if ( rSlidePersist.bBObjIsTemporary )
+ SdrObject::Free( rSlidePersist.pBObj );
+ else
+ pRet->SetBackgroundObj( rSlidePersist.pBObj );
+ }
+ }
+ }
+ break;
+ }
+ aHd.SeekToEndOfRecord( rStCtrl );
+ }
+ if ( rSlidePersist.pSolverContainer )
+ SolveSolver( *rSlidePersist.pSolverContainer );
+ if ( mbTracing )
+ mpTracer->RemoveAttribute( eAktPageKind == PPT_SLIDEPAGE
+ ? rtl::OUString::createFromAscii( "Page" )
+ : rtl::OUString::createFromAscii( "NotesPage" ) );
+ }
+ rStCtrl.Seek( nMerk );
+}
+
+const PptSlideLayoutAtom* SdrPowerPointImport::GetSlideLayoutAtom() const
+{
+ PptSlidePersistList* pPageList = GetPageList( eAktPageKind );
+ if ( pPageList && nAktPageNum < pPageList->Count() )
+ {
+ PptSlidePersistEntry* pE = (*pPageList)[ nAktPageNum ];
+ if ( pE )
+ return &pE->aSlideAtom.aLayout;
+ }
+ return NULL;
+}
+
+sal_Bool SdrPowerPointImport::IsNoteOrHandout( USHORT nPageNum, PptPageKind /*ePageKind*/) const
+{
+ sal_Bool bNote = eAktPageKind == PPT_NOTEPAGE;
+ if ( eAktPageKind == PPT_MASTERPAGE )
+ bNote = ( nPageNum & 1 ) == 0;
+ return bNote;
+}
+
+UINT32 SdrPowerPointImport::GetMasterPageId( USHORT nPageNum, PptPageKind ePageKind ) const
+{
+ PptSlidePersistList* pPageList = GetPageList( ePageKind );
+ if ( pPageList && nPageNum < pPageList->Count() )
+ return (*pPageList)[ nPageNum ]->aSlideAtom.nMasterId;
+ return 0;
+}
+
+UINT32 SdrPowerPointImport::GetNotesPageId( USHORT nPageNum ) const
+{
+ PptSlidePersistList* pPageList=GetPageList( PPT_SLIDEPAGE );
+ if ( pPageList && nPageNum < pPageList->Count() )
+ return (*pPageList)[ nPageNum ]->aSlideAtom.nNotesId;
+ return 0;
+}
+
+sal_Bool SdrPowerPointImport::HasMasterPage( USHORT nPageNum, PptPageKind ePageKind ) const
+{
+ if ( ePageKind == PPT_NOTEPAGE )
+ return aDocAtom.nNotesMasterPersist != 0;
+ if ( ePageKind == PPT_MASTERPAGE )
+ return FALSE;
+ return GetMasterPageId( nPageNum, ePageKind ) != 0;
+}
+
+USHORT SdrPowerPointImport::GetMasterPageIndex( USHORT nPageNum, PptPageKind ePageKind ) const
+{
+ USHORT nIdx = 0;
+ if ( ePageKind == PPT_NOTEPAGE )
+ return 2;
+ UINT32 nId = GetMasterPageId( nPageNum, ePageKind );
+ if ( nId && pMasterPages )
+ {
+ nIdx = pMasterPages->FindPage( nId );
+ if ( nIdx == PPTSLIDEPERSIST_ENTRY_NOTFOUND )
+ nIdx = 0;
+ }
+ return nIdx;
+}
+
+SdrObject* SdrPowerPointImport::ImportPageBackgroundObject( const SdrPage& rPage, sal_uInt32& nBgFileOffset, sal_Bool bForce )
+{
+ SdrObject* pRet = NULL;
+ sal_Bool bCreateObj = bForce;
+ SfxItemSet* pSet = NULL;
+ ULONG nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer spaetere Restauration
+ DffRecordHeader aPageHd;
+ if ( SeekToAktPage( &aPageHd ) )
+ { // und nun die Hintergrundattribute der Page suchen
+ ULONG nPageRecEnd = aPageHd.GetRecEndFilePos();
+ DffRecordHeader aPPDrawHd;
+ if ( SeekToRec( rStCtrl, PPT_PST_PPDrawing, nPageRecEnd, &aPPDrawHd ) )
+ {
+ ULONG nPPDrawEnd = aPPDrawHd.GetRecEndFilePos();
+ DffRecordHeader aEscherF002Hd;
+ if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, nPPDrawEnd, &aEscherF002Hd ) )
+ {
+ ULONG nEscherF002End = aEscherF002Hd.GetRecEndFilePos();
+ DffRecordHeader aEscherObjectHd;
+ if ( SeekToRec( rStCtrl, DFF_msofbtSpContainer, nEscherF002End, &aEscherObjectHd ) )
+ {
+ nBgFileOffset = aEscherObjectHd.GetRecBegFilePos();
+ //ULONG nEscherObjectEnd = aEscherObjectHd.GetRecEndFilePos();
+ //DffRecordHeader aEscherPropertiesHd;
+ if ( SeekToRec( rStCtrl, DFF_msofbtOPT,nEscherF002End ) )
+ {
+ rStCtrl >> (DffPropertyReader&)*this;
+ mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) );
+ UINT32 nColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
+ pSet = new SfxItemSet( pSdrModel->GetItemPool() );
+ DffObjData aObjData( aEscherObjectHd, Rectangle( 0, 0, 28000, 21000 ), 0 );
+ ApplyAttributes( rStCtrl, *pSet, aObjData );
+ Color aColor( MSO_CLR_ToColor( nColor ) );
+ pSet->Put( XFillColorItem( String(), aColor ) );
+ }
+ }
+ }
+ }
+ }
+ rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
+ if ( bCreateObj )
+ {
+ if ( !pSet )
+ {
+ pSet = new SfxItemSet( pSdrModel->GetItemPool() );
+ pSet->Put( XFillStyleItem( XFILL_NONE ) );
+ }
+ pSet->Put( XLineStyleItem( XLINE_NONE ) );
+ Rectangle aRect( rPage.GetLftBorder(), rPage.GetUppBorder(), rPage.GetWdt()-rPage.GetRgtBorder(), rPage.GetHgt()-rPage.GetLwrBorder() );
+ pRet = new SdrRectObj( aRect );
+ pRet->SetModel( pSdrModel );
+
+ pRet->SetMergedItemSet(*pSet);
+
+ pRet->SetMarkProtect( TRUE );
+ pRet->SetMoveProtect( TRUE );
+ pRet->SetResizeProtect( TRUE );
+ }
+ delete pSet;
+ return pRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+HeaderFooterEntry::HeaderFooterEntry( const PptSlidePersistEntry* pMPE ) :
+ pMasterPersist ( pMPE ),
+ nAtom ( 0 )
+{
+ if ( pMPE )
+ {
+ HeaderFooterEntry* pMHFE = pMPE->pHeaderFooterEntry;
+ if ( pMHFE )
+ {
+ nAtom = pMPE->pHeaderFooterEntry->nAtom;
+ pPlaceholder[ 0 ] = pMHFE->pPlaceholder[ 0 ];
+ pPlaceholder[ 1 ] = pMHFE->pPlaceholder[ 1 ];
+ pPlaceholder[ 2 ] = pMHFE->pPlaceholder[ 2 ];
+ pPlaceholder[ 3 ] = pMHFE->pPlaceholder[ 3 ];
+ }
+ }
+}
+
+HeaderFooterEntry::~HeaderFooterEntry()
+{
+}
+
+UINT32 HeaderFooterEntry::GetMaskForInstance( UINT32 nInstance )
+{
+ UINT32 nRet = 0;
+ switch ( nInstance )
+ {
+ case 0 : nRet = 0x07ffff; break;
+ case 1 : nRet = 0x100000; break;
+ case 2 : nRet = 0x200000; break;
+ case 3 : nRet = 0x080000; break;
+ }
+ return nRet;
+}
+
+UINT32 HeaderFooterEntry::IsToDisplay( UINT32 nInstance )
+{
+ UINT32 nMask = 0;
+ switch ( nInstance )
+ {
+ case 0 : nMask = 0x010000; break;
+ case 1 : nMask = 0x100000; break;
+ case 2 : nMask = 0x200000; break;
+ case 3 : nMask = 0x080000; break;
+ }
+ return ( nAtom & nMask );
+}
+
+// The following method checks if the slide is using a different colorscheme than
+// its master, if this is the fact, then the HeaderFooter must probably be
+// imported as real sdrobject. In this case, the return value is the offset to the
+// master header footer object, so it can be re-loaded with a different color set
+sal_uInt32 HeaderFooterEntry::NeedToImportInstance( const sal_uInt32 nInstance, const PptSlidePersistEntry& rSlidePersist )
+{
+ sal_uInt32 nRet = 0;
+ if ( pMasterPersist )
+ {
+ if ( !( rSlidePersist.aSlideAtom.nFlags & 2 ) )
+ { // not following the master persist, so we have to check if the colors are changed
+ if ( memcmp( &rSlidePersist.aColorScheme, &pMasterPersist->aColorScheme, 32 ) )
+ {
+ nRet = pMasterPersist->HeaderFooterOfs[ nInstance ];
+ }
+ }
+ }
+ return nRet;
+}
+
+void SdrEscherImport::ImportHeaderFooterContainer( DffRecordHeader& rHd, HeaderFooterEntry& rE )
+{
+ rHd.SeekToContent( rStCtrl );
+ while ( ( rStCtrl.GetError() == 0 ) && ( rStCtrl.Tell() < rHd.GetRecEndFilePos() ) )
+ {
+ DffRecordHeader aHd;
+ rStCtrl >> aHd;
+ switch ( aHd.nRecType )
+ {
+ case PPT_PST_HeadersFootersAtom :
+ rStCtrl >> rE.nAtom;
+ break;
+
+ case PPT_PST_CString :
+ {
+ if ( aHd.nRecInstance < 4 )
+ MSDFFReadZString( rStCtrl, rE.pPlaceholder[ aHd.nRecInstance ], aHd.nRecLen, TRUE );
+ }
+ break;
+ }
+ aHd.SeekToEndOfRecord( rStCtrl );
+ }
+}
+
+//static sal_Unicode PPTExportMapper( sal_Unicode nUni, BOOL& bNeedsStarBats )
+//{
+// bNeedsStarBats = FALSE;
+//
+// sal_Unicode cLo, cReplace;
+// cLo = cReplace = 0;
+// switch ( nUni )
+// {
+// case 132 : cLo = 175; break;
+// case 147 : cLo = 174; break;
+// // Currency
+// case 0x00A2: cReplace = 224; break;
+// case 0x00A4: cReplace = 225; break;
+// case 0x00A5: cReplace = 226; break;
+// case 0x20A1: cReplace = 228; break;
+// case 0x20A2: cReplace = 229; break;
+// case 0x20A3: cReplace = 230; break;
+// case 0x20A4: cReplace = 231; break;
+// case 0x20A7: cReplace = 227; break;
+// case 0x20A8: cReplace = 234; break;
+// case 0x20A9: cReplace = 232; break;
+// case 0x20AB: cReplace = 233; break;
+// case 0x20AC: cReplace = 128; break;
+// // Punctuation and other
+// case 0x201A: cReplace = 130; break; // SINGLE LOW-9 QUOTATION MARK
+// case 0x0192: cReplace = 131; break; // LATIN SMALL LETTER F WITH HOOK
+// case 0x201E: // DOUBLE LOW-9 QUOTATION MARK
+// case 0x301F: // LOW DOUBLE PRIME QUOTATION MARK
+// cReplace = 132; break;
+// case 0x2026: cReplace = 133; break; // HORIZONTAL ELLIPSES
+// case 0x2020: cReplace = 134; break; // DAGGER
+// case 0x2021: cReplace = 135; break; // DOUBLE DAGGER
+// case 0x02C6: cReplace = 136; break; // MODIFIER LETTER CIRCUMFLEX ACCENT
+// case 0x2030: cReplace = 137; break; // PER MILLE SIGN
+// case 0x0160: cReplace = 138; break; // LATIN CAPITAL LETTER S WITH CARON
+// case 0x2039: cReplace = 139; break; // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+// case 0x0152: cReplace = 140; break; // LATIN CAPITAL LIGATURE OE
+// case 0x017D: cReplace = 142; break; // LATIN CAPITAL LETTER Z WITH CARON
+// case 0x2018: // LEFT SINGLE QUOTATION MARK
+// case 0x02BB: // MODIFIER LETTER TURNED COMMA
+// cReplace = 145; break;
+// case 0x2019: // RIGHT SINGLE QUOTATION MARK
+// case 0x02BC: // MODIFIER LETTER APOSTROPHE
+// cReplace = 146; break;
+// case 0x201C: // LEFT DOUBLE QUOTATION MARK
+// case 0x301D: // REVERSED DOUBLE PRIME QUOTATION MARK
+// cReplace = 147; break;
+// case 0x201D: // RIGHT DOUBLE QUOTATION MARK
+// case 0x301E: // REVERSED DOUBLE PRIME QUOTATION MARK
+// cReplace = 148; break;
+// case 0x2022: cReplace = 149; break; // BULLET
+// case 0x2013: cReplace = 150; break; // EN DASH
+// case 0x2014: cReplace = 151; break; // EM DASH
+// case 0x02DC: cReplace = 152; break; // SMALL TILDE
+// case 0x2122: cReplace = 153; break; // TRADE MARK SIGN
+// case 0x0161: cReplace = 154; break; // LATIN SMALL LETTER S WITH CARON
+// case 0x203A: cReplace = 155; break; // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+// case 0x0153: cReplace = 156; break; // LATIN SMALL LIGATURE OE
+// case 0x017E: cReplace = 158; break; // LATIN SMALL LETTER Z WITH CARON
+// case 0x0178: cReplace = 159; break; // LATIN CAPITAL LETTER Y WITH DIAERESIS
+// case 0x00B6: cReplace = 222; break; // PILCROW SIGN / PARAGRAPH SIGN
+// }
+// if ( cReplace )
+// {
+// bNeedsStarBats = TRUE;
+// return cReplace;
+// }
+// else
+// return cLo;
+//}
+
+// no longer needed
+sal_Unicode SdrPowerPointImport::PPTSubstitute( UINT16 /*nFont*/, sal_Unicode /*nChar*/,
+ UINT32& /*nMappedFontId*/, Font& /*rFont*/, char /*nDefault*/) const
+{
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PPTBuGraEntry::PPTBuGraEntry( Graphic& rGraphic, UINT32 nInst ) :
+ nInstance ( nInst ),
+ aBuGra ( rGraphic ) {}
+
+PPTExtParaLevel::PPTExtParaLevel()
+: mnExtParagraphMask( 0 )
+, mnBuBlip( 0xffff )
+, mnHasAnm( 0 )
+, mnAnmScheme( 0 )
+, mpfPP10Ext( 0 )
+, mnExtCharacterMask( 0 )
+, mcfPP10Ext( 0 )
+, mbSet( sal_False )
+{}
+
+SvStream& operator>>( SvStream& rIn, PPTExtParaLevel& rLevel )
+{
+ rLevel.mbSet = TRUE;
+ rIn >> rLevel.mnExtParagraphMask;
+ if ( rLevel.mnExtParagraphMask & 0x00800000 )
+ rIn >> rLevel.mnBuBlip;
+ if ( rLevel.mnExtParagraphMask & 0x02000000 )
+ rIn >> rLevel.mnHasAnm;
+ if ( rLevel.mnExtParagraphMask & 0x01000000 )
+ rIn >> rLevel.mnAnmScheme;
+ if ( rLevel.mnExtParagraphMask & 0x04000000 )
+ rIn >> rLevel.mpfPP10Ext;
+ rIn >> rLevel.mnExtCharacterMask;
+ if ( rLevel.mnExtCharacterMask & 0x100000 )
+ rIn >> rLevel.mcfPP10Ext;
+ return rIn;
+}
+
+BOOL PPTExtParaProv::GetGraphic( UINT32 nInstance, Graphic& rGraph ) const
+{
+ BOOL bRetValue = FALSE;
+ PPTBuGraEntry* pPtr = NULL;
+ if ( nInstance < aBuGraList.Count() )
+ {
+ pPtr = (PPTBuGraEntry*)aBuGraList.GetObject( nInstance );
+ if ( pPtr->nInstance == nInstance )
+ bRetValue = TRUE;
+ }
+ if ( !bRetValue )
+ {
+ sal_uInt32 i;
+ for ( i = 0; i < aBuGraList.Count(); i++ )
+ {
+ pPtr = (PPTBuGraEntry*)aBuGraList.GetObject( i );
+ if ( pPtr->nInstance == nInstance )
+ {
+ bRetValue = TRUE;
+ break;
+ }
+ }
+ }
+ if ( bRetValue )
+ rGraph = pPtr->aBuGra;
+ return bRetValue;
+}
+
+PPTExtParaProv::PPTExtParaProv( SdrPowerPointImport& rMan, SvStream& rSt, const DffRecordHeader* pHd ) :
+ bStyles ( FALSE ),
+ bGraphics ( FALSE )
+{
+ UINT32 nOldPos = rSt.Tell();
+
+ // here we have to get the graphical bullets...
+
+ DffRecordHeader aHd;
+ DffRecordHeader aContentDataHd;
+
+ const DffRecordHeader* pListHd = rMan.aDocRecManager.GetRecordHeader( PPT_PST_List, SEEK_FROM_BEGINNING );
+ while( pListHd )
+ {
+ pListHd->SeekToContent( rSt );
+ if ( !rMan.SeekToContentOfProgTag( 9, rSt, *pListHd, aContentDataHd ) )
+ break;
+ while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aContentDataHd.GetRecEndFilePos() ) )
+ {
+ rSt >> aHd;
+ switch ( aHd.nRecType )
+ {
+ case PPT_PST_ExtendedBuGraContainer :
+ {
+ while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aHd.GetRecEndFilePos() ) )
+ {
+ UINT16 nType;
+ DffRecordHeader aBuGraAtomHd;
+ rSt >> aBuGraAtomHd;
+ if ( aBuGraAtomHd.nRecType == PPT_PST_ExtendedBuGraAtom )
+ {
+ rSt >> nType;
+ Graphic aGraphic;
+ if ( rMan.GetBLIPDirect( rSt, aGraphic, NULL ) )
+ {
+ UINT32 nInstance = aBuGraAtomHd.nRecInstance;
+ PPTBuGraEntry* pBuGra = new PPTBuGraEntry( aGraphic, nInstance );
+ UINT32 n = 0;
+ UINT32 nBuGraCount = aBuGraList.Count();
+ if ( nBuGraCount )
+ {
+ if ( ( (PPTBuGraEntry*)aBuGraList.GetObject( nBuGraCount - 1 ) )->nInstance < nInstance )
+ n = nBuGraCount;
+ else
+ { // maybe the instances are not sorted, we sort it
+ for ( n = 0; n < nBuGraCount; n++ )
+ { // sorting fields ( hi >> lo )
+ if ( ( (PPTBuGraEntry*)aBuGraList.GetObject( n ) )->nInstance < nInstance )
+ break;
+ }
+ }
+ }
+ aBuGraList.Insert( pBuGra, (UINT32)n );
+ }
+#ifdef DBG_UTIL
+ else DBG_ERROR( "PPTExParaProv::PPTExParaProv - bullet graphic is not valid (SJ)" );
+#endif
+ }
+#ifdef DBG_UTIL
+ else DBG_ERROR( "PPTExParaProv::PPTExParaProv - unknown atom interpreting the PPT_PST_ExtendedBuGraContainer (SJ)" );
+#endif
+ aBuGraAtomHd.SeekToEndOfRecord( rSt );
+ }
+ if ( aBuGraList.Count() )
+ bGraphics = TRUE;
+ }
+ break;
+
+ case PPT_PST_ExtendedPresRuleContainer :
+ aExtendedPresRules.Consume( rSt, FALSE, aHd.GetRecEndFilePos() );
+ break;
+#ifdef DBG_UTIL
+ default :
+ DBG_ERROR( "PPTExParaProv::PPTExParaProv - unknown atom reading ppt2000 num rules (SJ)" );
+ case PPT_PST_MasterText : // first seen in: ms-tt02.ppt
+ case PPT_PST_SrKinsoku :
+ case PPT_PST_NewlyAddedAtom4016 :
+ case PPT_PST_NewlyAddedAtomByPPT2000_6010 :
+ case PPT_PST_NewlyAddedAtomByPPT2000_6011 :
+ case PPT_PST_NewlyAddedAtomByXP1037 :
+ case PPT_PST_NewlyAddedAtomByXP12004 :
+ case PPT_PST_NewlyAddedAtomByXP14001 :
+ break;
+#endif
+ }
+ aHd.SeekToEndOfRecord( rSt );
+ }
+ break;
+ }
+
+ while( pHd )
+ { // get the extended paragraph styles on mainmaster ( graphical bullets, num ruling ... )
+ if ( !rMan.SeekToContentOfProgTag( 9, rSt, *pHd, aContentDataHd ) )
+ break;
+ while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aContentDataHd.GetRecEndFilePos() ) )
+ {
+ rSt >> aHd;
+ switch ( aHd.nRecType )
+ {
+ case PPT_PST_ExtendedParagraphMasterAtom :
+ {
+ if ( aHd.nRecInstance < PPT_STYLESHEETENTRYS )
+ {
+ UINT16 nDepth, i = 0;
+ rSt >> nDepth;
+ if ( i <= 5 )
+ {
+
+ while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aHd.GetRecEndFilePos() ) && ( i < nDepth ) )
+ {
+ bStyles = TRUE;
+ rSt >> aExtParaSheet[ aHd.nRecInstance ].aExtParaLevel[ i++ ];
+ }
+#ifdef DBG_UTIL
+ if ( rSt.Tell() != aHd.GetRecEndFilePos() )
+ DBG_ERROR( "PPTExParaProv::PPTExParaProv - error reading PPT_PST_ExtendedParagraphMasterAtom (SJ)" );
+#endif
+ }
+#ifdef DBG_UTIL
+ else DBG_ERROR( "PPTExParaProv::PPTExParaProv - depth is greater than 5 (SJ)" );
+#endif
+ }
+#ifdef DBG_UTIL
+ else DBG_ERROR( "PPTExParaProv::PPTExParaProv - instance out of range (SJ)" );
+#endif
+ }
+ break;
+ default :
+ DBG_ERROR( "PPTExParaProv::PPTExParaProv - unknown atom, assuming PPT_PST_ExtendedParagraphMasterAtom (SJ)" );
+ case PPT_PST_NewlyAddedAtomByXP11008 :
+ case PPT_PST_NewlyAddedAtomByXP11010 :
+ case PPT_PST_NewlyAddedAtomByXP12010 :
+ case PPT_PST_NewlyAddedAtomByXP12011 :
+ case 0xf144 :
+ break;
+ }
+ aHd.SeekToEndOfRecord( rSt );
+ }
+ break;
+ }
+ rSt.Seek( nOldPos );
+}
+
+PPTExtParaProv::~PPTExtParaProv()
+{
+ void* pPtr;
+ for ( pPtr = aBuGraList.First(); pPtr; pPtr = aBuGraList.Next() )
+ delete (PPTBuGraEntry*)pPtr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PPTNumberFormatCreator::PPTNumberFormatCreator( PPTExtParaProv* pParaProv ) :
+ pExtParaProv ( pParaProv )
+{
+}
+
+PPTNumberFormatCreator::~PPTNumberFormatCreator()
+{
+ delete pExtParaProv;
+}
+
+BOOL PPTNumberFormatCreator::ImplGetExtNumberFormat( SdrPowerPointImport& rManager,
+ SvxNumberFormat& rNumberFormat, UINT32 nLevel, UINT32 nInstance, UINT32 nDestinationInstance,
+ boost::optional< sal_Int16 >& rStartNumbering, UINT32 nFontHeight, PPTParagraphObj* pPara )
+{
+ BOOL bHardAttribute = ( nDestinationInstance == 0xffffffff );
+
+ UINT32 nBuFlags = 0;
+ UINT16 nHasAnm = 0;
+ UINT32 nAnmScheme = 0x10003;
+ UINT16 nBuBlip = 0xffff;
+
+ const PPTExtParaProv* pParaProv = pExtParaProv;
+ if ( !pExtParaProv )
+ pParaProv = ( pPara ) ? pPara->mrStyleSheet.pExtParaProv
+ : rManager.pPPTStyleSheet->pExtParaProv;
+ if ( pPara )
+ {
+ nBuFlags = pPara->pParaSet->mnExtParagraphMask;
+ if ( nBuFlags )
+ {
+ if ( nBuFlags & 0x00800000 )
+ nBuBlip = pPara->pParaSet->mnBuBlip;
+ if ( nBuFlags & 0x01000000 )
+ nAnmScheme = pPara->pParaSet->mnAnmScheme;
+ if ( nBuFlags & 0x02000000 )
+ nHasAnm = pPara->pParaSet->mnHasAnm;
+ bHardAttribute = TRUE;
+ }
+ }
+
+ if ( ( nBuFlags & 0x03800000 ) != 0x03800000 ) // merge style sheet
+ { // we have to read the master attributes
+ if ( pParaProv && ( nLevel < 5 ) )
+ {
+ if ( pParaProv->bStyles )
+ {
+ const PPTExtParaLevel& rLev = pParaProv->aExtParaSheet[ nInstance ].aExtParaLevel[ nLevel ];
+ if ( rLev.mbSet )
+ {
+ UINT32 nMaBuFlags = rLev.mnExtParagraphMask;
+
+ if ( (!( nBuFlags & 0x00800000)) && ( nMaBuFlags & 0x00800000 ) )
+ {
+ if (!( nBuFlags & 0x02000000)) // if there is a BuStart without BuInstance,
+ nBuBlip = rLev.mnBuBlip; // then there is no graphical Bullet possible
+ }
+ if ( (!( nBuFlags & 0x01000000)) && ( nMaBuFlags & 0x01000000 ) )
+ nAnmScheme = rLev.mnAnmScheme;
+ if ( (!( nBuFlags & 0x02000000)) && ( nMaBuFlags & 0x02000000 ) )
+ nHasAnm = rLev.mnHasAnm;
+ nBuFlags |= nMaBuFlags;
+ }
+ }
+ }
+ }
+ if ( nBuBlip != 0xffff ) // set graphical bullet
+ {
+ Graphic aGraphic;
+ if ( pParaProv->GetGraphic( nBuBlip, aGraphic ) )
+ {
+ SvxBrushItem aBrush( aGraphic, GPOS_MM, SID_ATTR_BRUSH );
+ rNumberFormat.SetGraphicBrush( &aBrush );
+ sal_uInt32 nHeight = (sal_uInt32)( (double)nFontHeight * 0.2540 * nBulletHeight + 0.5 );
+ Size aPrefSize( aGraphic.GetPrefSize() );
+ UINT32 nWidth = ( nHeight * aPrefSize.Width() ) / aPrefSize.Height();
+ rNumberFormat.SetGraphicSize( Size( nWidth, nHeight ) );
+ rNumberFormat.SetNumberingType ( SVX_NUM_BITMAP );
+ }
+ }
+ else if ( nHasAnm )
+ {
+ switch( static_cast< sal_uInt16 >( nAnmScheme ) )
+ {
+ default :
+ case 0 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_CHARS_LOWER_LETTER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( "." ) ) );
+ }
+ break;
+ case 1 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_CHARS_UPPER_LETTER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( "." ) ) );
+ }
+ break;
+ case 2 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ARABIC );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ }
+ break;
+ case 3 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ARABIC );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( "." ) ) );
+ }
+ break;
+ case 4 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_LOWER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ rNumberFormat.SetPrefix( String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) );
+ }
+ break;
+ case 5 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_LOWER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ }
+ break;
+ case 6 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_LOWER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( "." ) ) );
+ }
+ break;
+ case 7 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_UPPER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( "." ) ) );
+ }
+ break;
+ case 8 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_CHARS_LOWER_LETTER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ rNumberFormat.SetPrefix( String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) );
+ }
+ break;
+ case 9 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_CHARS_LOWER_LETTER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ }
+ break;
+ case 10 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_CHARS_UPPER_LETTER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ rNumberFormat.SetPrefix( String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) );
+ }
+ break;
+ case 11 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_CHARS_UPPER_LETTER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ }
+ break;
+ case 12 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ARABIC );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ rNumberFormat.SetPrefix( String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) );
+ }
+ break;
+ case 13 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ARABIC );
+ }
+ break;
+ case 14 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_UPPER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ rNumberFormat.SetPrefix( String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) );
+ }
+ break;
+ case 15 :
+ {
+ rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_UPPER );
+ rNumberFormat.SetSuffix( String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) );
+ }
+ break;
+ }
+ rStartNumbering = boost::optional< sal_Int16 >( nAnmScheme >> 16 );
+ }
+ return bHardAttribute;
+}
+
+void PPTNumberFormatCreator::GetNumberFormat( SdrPowerPointImport& rManager, SvxNumberFormat& rNumberFormat, UINT32 nLevel, const PPTParaLevel& rParaLevel, const PPTCharLevel& rCharLevel, UINT32 nInstance )
+{
+ nIsBullet = ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BulletOn ) ) != 0 ? 1 : 0;
+ nBulletChar = rParaLevel.mnBulletChar;
+
+ sal_Bool bBuHardFont;
+ bBuHardFont = ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BuHardFont ) ) != 0;
+ if ( bBuHardFont )
+ nBulletFont = rParaLevel.mnBulletFont;
+ else
+ nBulletFont = rCharLevel.mnFont;
+ nBulletHeight = rParaLevel.mnBulletHeight;
+ nBulletColor = rParaLevel.mnBulletColor;
+ nTextOfs = rParaLevel.mnTextOfs;
+ nBulletOfs = rParaLevel.mnBulletOfs;
+
+ boost::optional< sal_Int16 > oStartNumbering;
+ ImplGetExtNumberFormat( rManager, rNumberFormat, nLevel, nInstance, 0xffffffff, oStartNumbering, rCharLevel.mnFontHeight, NULL );
+ if ( ( rNumberFormat.GetNumberingType() != SVX_NUM_BITMAP ) && ( nBulletHeight > 0x7fff ) )
+ nBulletHeight = rCharLevel.mnFontHeight ? ((-((sal_Int16)nBulletHeight)) * 100 ) / rCharLevel.mnFontHeight : 100;
+ ImplGetNumberFormat( rManager, rNumberFormat, nLevel );
+ switch ( rNumberFormat.GetNumberingType() )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER :
+ case SVX_NUM_CHARS_LOWER_LETTER :
+ case SVX_NUM_ROMAN_UPPER :
+ case SVX_NUM_ROMAN_LOWER :
+ case SVX_NUM_ARABIC :
+ case SVX_NUM_CHARS_UPPER_LETTER_N :
+ case SVX_NUM_CHARS_LOWER_LETTER_N :
+ {
+ sal_uInt32 nFont = rCharLevel.mnFont;
+ PptFontEntityAtom* pFontEnityAtom = rManager.GetFontEnityAtom( nFont );
+ if ( pFontEnityAtom )
+ {
+ Font aFont;
+ aFont.SetCharSet( pFontEnityAtom->eCharSet );
+ aFont.SetName( pFontEnityAtom->aName );
+ aFont.SetFamily( pFontEnityAtom->eFamily );
+ aFont.SetPitch( pFontEnityAtom->ePitch );
+ rNumberFormat.SetBulletFont( &aFont );
+ }
+ }
+ break;
+ }
+}
+
+BOOL PPTNumberFormatCreator::GetNumberFormat( SdrPowerPointImport& rManager, SvxNumberFormat& rNumberFormat, PPTParagraphObj* pParaObj,
+ UINT32 nDestinationInstance, boost::optional< sal_Int16 >& rStartNumbering )
+{
+ UINT32 nHardCount = 0;
+ nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletOn, nIsBullet, nDestinationInstance );
+ nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletChar, nBulletChar, nDestinationInstance );
+ nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletFont, nBulletFont, nDestinationInstance );
+ nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletHeight, nBulletHeight, nDestinationInstance );
+ nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletColor, nBulletColor, nDestinationInstance );
+ nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_TextOfs, nTextOfs, nDestinationInstance );
+ nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletOfs, nBulletOfs, nDestinationInstance );
+
+ if ( nIsBullet )
+ rNumberFormat.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
+
+ UINT32 nFontHeight = 24;
+ PPTPortionObj* pPtr = pParaObj->First();
+ if ( pPtr )
+ pPtr->GetAttrib( PPT_CharAttr_FontHeight, nFontHeight, nDestinationInstance );
+ if ( nIsBullet )
+ nHardCount += ImplGetExtNumberFormat( rManager, rNumberFormat, pParaObj->pParaSet->mnDepth,
+ pParaObj->mnInstance, nDestinationInstance, rStartNumbering, nFontHeight, pParaObj );
+
+ if ( rNumberFormat.GetNumberingType() != SVX_NUM_BITMAP )
+ pParaObj->UpdateBulletRelSize( nBulletHeight );
+ if ( nHardCount )
+ ImplGetNumberFormat( rManager, rNumberFormat, pParaObj->pParaSet->mnDepth );
+
+ if ( nHardCount )
+ {
+ switch ( rNumberFormat.GetNumberingType() )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER :
+ case SVX_NUM_CHARS_LOWER_LETTER :
+ case SVX_NUM_ROMAN_UPPER :
+ case SVX_NUM_ROMAN_LOWER :
+ case SVX_NUM_ARABIC :
+ case SVX_NUM_CHARS_UPPER_LETTER_N :
+ case SVX_NUM_CHARS_LOWER_LETTER_N :
+ {
+ if ( pPtr )
+ {
+ sal_uInt32 nFont;
+ pPtr->GetAttrib( PPT_CharAttr_Font, nFont, nDestinationInstance );
+ PptFontEntityAtom* pFontEnityAtom = rManager.GetFontEnityAtom( nFont );
+ if ( pFontEnityAtom )
+ {
+ Font aFont;
+ aFont.SetCharSet( pFontEnityAtom->eCharSet );
+ aFont.SetName( pFontEnityAtom->aName );
+ aFont.SetFamily( pFontEnityAtom->eFamily );
+ aFont.SetPitch( pFontEnityAtom->ePitch );
+ rNumberFormat.SetBulletFont( &aFont );
+ }
+ }
+ }
+ break;
+ }
+ }
+ return ( nHardCount ) ? TRUE : FALSE;
+}
+
+void PPTNumberFormatCreator::ImplGetNumberFormat( SdrPowerPointImport& rManager, SvxNumberFormat& rNumberFormat, UINT32 /*nLevel*/)
+{
+ Font aFont;
+ PptFontEntityAtom* pAtom = rManager.GetFontEnityAtom( nBulletFont );
+ if ( pAtom )
+ {
+ CharSet eCharSet( pAtom->eCharSet );
+ aFont.SetName( pAtom->aName );
+ aFont.SetCharSet( eCharSet );
+ aFont.SetFamily( pAtom->eFamily );
+ aFont.SetPitch( pAtom->ePitch );
+ }
+ Color aCol( rManager.MSO_TEXT_CLR_ToColor( nBulletColor ) );
+ aFont.SetColor( aCol );
+
+ sal_uInt16 nBuChar = (sal_uInt16)nBulletChar;
+ if ( aFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
+ {
+ nBuChar &= 0x00ff;
+ nBuChar |= 0xf000;
+ }
+ rNumberFormat.SetBulletFont( &aFont );
+ rNumberFormat.SetBulletChar( nBuChar );
+ rNumberFormat.SetBulletRelSize( (UINT16)nBulletHeight );
+ rNumberFormat.SetBulletColor( aCol );
+ UINT16 nAbsLSpace = (UINT16)( ( (UINT32)nTextOfs * 2540 ) / 576 );
+ UINT16 nFirstLineOffset = nAbsLSpace - (UINT16)( ( (UINT32)nBulletOfs * 2540 ) / 576 );
+ rNumberFormat.SetAbsLSpace( nAbsLSpace );
+ rNumberFormat.SetFirstLineOffset( -nFirstLineOffset );
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PPTCharSheet::PPTCharSheet( UINT32 nInstance )
+{
+ UINT32 nColor = PPT_COLSCHEME_TEXT_UND_ZEILEN;
+ UINT16 nFontHeight(0);
+ switch ( nInstance )
+ {
+ case TSS_TYPE_PAGETITLE :
+ case TSS_TYPE_TITLE :
+ {
+ nColor = PPT_COLSCHEME_TITELTEXT;
+ nFontHeight = 44;
+ }
+ break;
+ case TSS_TYPE_BODY :
+ case TSS_TYPE_SUBTITLE :
+ case TSS_TYPE_HALFBODY :
+ case TSS_TYPE_QUARTERBODY :
+ nFontHeight = 32;
+ break;
+ case TSS_TYPE_NOTES :
+ nFontHeight = 12;
+ break;
+ case TSS_TYPE_UNUSED :
+ case TSS_TYPE_TEXT_IN_SHAPE :
+ nFontHeight = 24;
+ break;
+ }
+ for ( UINT32 nDepth = 0; nDepth < 5; nDepth++ )
+ {
+ maCharLevel[ nDepth ].mnFlags = 0;
+ maCharLevel[ nDepth ].mnFont = 0;
+ maCharLevel[ nDepth ].mnAsianOrComplexFont = 0xffff;
+ maCharLevel[ nDepth ].mnFontHeight = nFontHeight;
+ maCharLevel[ nDepth ].mnFontColor = nColor;
+ maCharLevel[ nDepth ].mnFontColorInStyleSheet = Color( (BYTE)nColor, (BYTE)( nColor >> 8 ), (BYTE)( nColor >> 16 ) );
+ maCharLevel[ nDepth ].mnEscapement = 0;
+ }
+}
+
+PPTCharSheet::PPTCharSheet( const PPTCharSheet& rAttr )
+{
+ *this = rAttr;
+}
+
+void PPTCharSheet::Read( SvStream& rIn, sal_Bool /*bMasterStyle*/, sal_uInt32 nLevel, sal_Bool /*bFirst*/)
+{
+ // Zeichenattribute
+ sal_uInt32 nCMask;
+ sal_uInt16 nVal16;
+ rIn >> nCMask;
+
+ if ( nCMask & 0x0000FFFF )
+ {
+ sal_uInt16 nBitAttr;
+ maCharLevel[ nLevel ].mnFlags &= ~( (sal_uInt16)nCMask );
+ rIn >> nBitAttr; // Bit-Attribute (Fett, Unterstrichen, ...)
+ maCharLevel[ nLevel ].mnFlags |= nBitAttr;
+ }
+ if ( nCMask & ( 1 << PPT_CharAttr_Font ) ) // 0x00010000
+ rIn >> maCharLevel[ nLevel ].mnFont;
+ if ( nCMask & ( 1 << PPT_CharAttr_AsianOrComplexFont ) ) // 0x00200000
+ rIn >> maCharLevel[ nLevel ].mnAsianOrComplexFont;
+ if ( nCMask & ( 1 << PPT_CharAttr_ANSITypeface ) ) // 0x00400000
+ rIn >> nVal16;
+ if ( nCMask & ( 1 << PPT_CharAttr_Symbol ) ) // 0x00800000
+ rIn >> nVal16;
+ if ( nCMask & ( 1 << PPT_CharAttr_FontHeight ) ) // 0x00020000
+ rIn >> maCharLevel[ nLevel ].mnFontHeight;
+ if ( nCMask & ( 1 << PPT_CharAttr_FontColor ) ) // 0x00040000
+ {
+ rIn >> maCharLevel[ nLevel ].mnFontColor;
+ if( ! (maCharLevel[ nLevel ].mnFontColor & 0xff000000 ) )
+ maCharLevel[ nLevel ].mnFontColor = PPT_COLSCHEME_HINTERGRUND;
+ }
+ if ( nCMask & ( 1 << PPT_CharAttr_Escapement ) ) // 0x00080000
+ rIn >> maCharLevel[ nLevel ].mnEscapement;
+ if ( nCMask & 0x00100000 ) // 0x00100000
+ rIn >> nVal16;
+
+ nCMask >>= 24;
+ while( nCMask )
+ {
+ if ( nCMask & 1 )
+ {
+ DBG_ERROR( "PPTCharSheet::Read - unknown attribute, send me this document (SJ)" );
+ rIn >> nVal16;
+ }
+ nCMask >>= 1;
+ }
+}
+
+PPTParaSheet::PPTParaSheet( UINT32 nInstance )
+{
+ sal_uInt16 nBuFlags = 0;
+ sal_uInt32 nBulletColor = 0x8000000;
+ sal_uInt16 nUpperDist = 0;
+
+ switch ( nInstance )
+ {
+ case TSS_TYPE_PAGETITLE :
+ case TSS_TYPE_TITLE :
+ nBulletColor = PPT_COLSCHEME_TITELTEXT;
+ break;
+ case TSS_TYPE_BODY :
+ case TSS_TYPE_SUBTITLE :
+ case TSS_TYPE_HALFBODY :
+ case TSS_TYPE_QUARTERBODY :
+ {
+ nBuFlags = 1;
+ nUpperDist = 0x14;
+ }
+ break;
+ case TSS_TYPE_NOTES :
+ nUpperDist = 0x1e;
+ break;
+/*
+ default :
+ case TSS_TYPE_UNUSED :
+ case TSS_TYPE_TEXT_IN_SHAPE :
+ break;
+*/
+ }
+ for ( UINT32 i = 0; i < 5; i++ )
+ {
+ maParaLevel[ i ].mnBuFlags = nBuFlags;
+ maParaLevel[ i ].mnBulletChar = 0x2022;
+ maParaLevel[ i ].mnBulletFont = 0;
+ maParaLevel[ i ].mnBulletHeight = 100;
+ maParaLevel[ i ].mnBulletColor = nBulletColor;
+ maParaLevel[ i ].mnAdjust = 0;
+ maParaLevel[ i ].mnLineFeed = 100;
+ maParaLevel[ i ].mnLowerDist = 0;
+ maParaLevel[ i ].mnUpperDist = nUpperDist;
+ maParaLevel[ i ].mnTextOfs = 0;
+ maParaLevel[ i ].mnBulletOfs = 0;
+ maParaLevel[ i ].mnDefaultTab = 0x240;
+ maParaLevel[ i ].mnAsianLineBreak = 0;
+ maParaLevel[ i ].mnBiDi = 0;
+ }
+}
+
+PPTParaSheet::PPTParaSheet( const PPTParaSheet& rSheet )
+{
+ *this = rSheet;
+}
+
+void PPTParaSheet::Read( SdrPowerPointImport&
+#ifdef DBG_UTIL
+ rManager
+#endif
+ , SvStream& rIn, sal_Bool /*bMasterStyle*/,
+ sal_uInt32 nLevel, sal_Bool bFirst )
+{
+ // Absatzattribute
+ sal_uInt16 nVal16, i, nMask16;
+ sal_uInt32 nVal32, nPMask;
+ rIn >> nPMask;
+
+ nMask16 = (sal_uInt16)nPMask & 0xf;
+ if ( nMask16 )
+ {
+ rIn >> nVal16;
+ maParaLevel[ nLevel ].mnBuFlags &=~ nMask16;
+ nVal16 &= nMask16;
+ maParaLevel[ nLevel ].mnBuFlags |= nVal16;
+ }
+ if ( nPMask & 0x0080 )
+ rIn >> maParaLevel[ nLevel ].mnBulletChar;
+ if ( nPMask & 0x0010 )
+ rIn >> maParaLevel[ nLevel ].mnBulletFont;
+ if ( nPMask & 0x0040 )
+ {
+ rIn >> nVal16;
+ maParaLevel[ nLevel ].mnBulletHeight = nVal16;
+ }
+ if ( nPMask & 0x0020 )
+ {
+ rIn >> nVal32;
+ maParaLevel[ nLevel ].mnBulletColor = nVal32;
+ }
+ if ( bFirst )
+ {
+ if ( nPMask & 0xF00 )
+ { // AbsJust!
+ rIn >> nVal16;
+ maParaLevel[ nLevel ].mnAdjust = nVal16 & 3;
+ }
+ if ( nPMask & 0x1000 )
+ rIn >> maParaLevel[ nLevel ].mnLineFeed;
+ if ( nPMask & 0x2000 )
+ rIn >> maParaLevel[ nLevel ].mnUpperDist;
+ if ( nPMask & 0x4000 )
+ rIn >> maParaLevel[ nLevel ].mnLowerDist;
+ if ( nPMask & 0x8000 )
+ rIn >> maParaLevel[ nLevel ].mnTextOfs;
+ if ( nPMask & 0x10000 )
+ rIn >> maParaLevel[ nLevel ].mnBulletOfs;
+ if ( nPMask & 0x20000 )
+ rIn >> maParaLevel[ nLevel ].mnDefaultTab;
+ if ( nPMask & 0x200000 )
+ {
+ // number of tabulators
+ rIn >> nVal16;
+ for ( i = 0; i < nVal16; i++ )
+ rIn >> nVal32; // reading the tabulators
+ }
+ if ( nPMask & 0x40000 )
+ rIn >> nVal16;
+ if ( nPMask & 0x80000 )
+ rIn >> maParaLevel[ nLevel ].mnAsianLineBreak;
+ if ( nPMask & 0x100000 )
+ rIn >> maParaLevel[ nLevel ].mnBiDi;
+ }
+ else
+ {
+ if ( nPMask & 0x800 )
+ {
+ rIn >> nVal16;
+ maParaLevel[ nLevel ].mnAdjust = nVal16 & 3;
+ }
+ if ( nPMask & 0x1000 )
+ rIn >> maParaLevel[ nLevel ].mnLineFeed;
+ if ( nPMask & 0x2000 )
+ rIn >> maParaLevel[ nLevel ].mnUpperDist;
+ if ( nPMask & 0x4000 )
+ rIn >> maParaLevel[ nLevel ].mnLowerDist;
+ if ( nPMask & 0x8000 )
+ rIn >> nVal16;
+ if ( nPMask & 0x100 )
+ rIn >> maParaLevel[ nLevel ].mnTextOfs;
+ if ( nPMask & 0x200 )
+ rIn >> nVal16;
+ if ( nPMask & 0x400 )
+ rIn >> maParaLevel[ nLevel ].mnBulletOfs;
+ if ( nPMask & 0x10000 )
+ rIn >> nVal16;
+ if ( nPMask & 0xe0000 )
+ {
+ sal_uInt16 nFlagsToModifyMask = (sal_uInt16)( ( nPMask >> 17 ) & 7 );
+ rIn >> nVal16;
+ // bits that are not involved to zero
+ nVal16 &= nFlagsToModifyMask;
+ // bits that are to change to zero
+ maParaLevel[ nLevel ].mnAsianLineBreak &=~nFlagsToModifyMask;
+ // now set the corresponding bits
+ maParaLevel[ nLevel ].mnAsianLineBreak |= nVal16;
+ }
+ if ( nPMask & 0x100000 )
+ {
+ // number of tabulators
+ rIn >> nVal16;
+ for ( i = 0; i < nVal16; i++ )
+ rIn >> nVal32; // reading the tabulators
+ }
+ if ( nPMask & 0x200000 )
+ rIn >> maParaLevel[ nLevel ].mnBiDi; // #88602#
+ }
+
+ nPMask >>= 22;
+ while( nPMask )
+ {
+ if ( nPMask & 1 )
+ {
+#ifdef DBG_UTIL
+ if (!(rManager.rImportParam.nImportFlags & PPT_IMPORTFLAGS_NO_TEXT_ASSERT))
+ {
+ DBG_ERROR( "PPTParaSheet::Read - unknown attribute, send me this document (SJ)" );
+ }
+#endif
+ rIn >> nVal16;
+ }
+ nPMask >>= 1;
+ }
+}
+
+PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, SdrPowerPointImport& rManager,
+ const PPTTextCharacterStyleAtomInterpreter& /*rTxCFStyle*/, const PPTTextParagraphStyleAtomInterpreter& rTxPFStyle,
+ const PPTTextSpecInfo& rTextSpecInfo ) :
+
+ PPTNumberFormatCreator ( new PPTExtParaProv( rManager, rIn, &rSlideHd ) ),
+ maTxSI ( rTextSpecInfo )
+{
+ UINT32 i;
+ UINT32 nOldFilePos = rIn.Tell();
+
+ // default stylesheets
+ mpCharSheet[ TSS_TYPE_PAGETITLE ] = new PPTCharSheet( TSS_TYPE_PAGETITLE );
+ mpCharSheet[ TSS_TYPE_BODY ] = new PPTCharSheet( TSS_TYPE_BODY );
+ mpCharSheet[ TSS_TYPE_NOTES ] = new PPTCharSheet( TSS_TYPE_NOTES );
+ mpCharSheet[ TSS_TYPE_UNUSED ] = new PPTCharSheet( TSS_TYPE_UNUSED ); // this entry is not used by ppt
+ mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ] = new PPTCharSheet( TSS_TYPE_TEXT_IN_SHAPE );
+ mpParaSheet[ TSS_TYPE_PAGETITLE ] = new PPTParaSheet( TSS_TYPE_PAGETITLE );
+ mpParaSheet[ TSS_TYPE_BODY ] = new PPTParaSheet( TSS_TYPE_BODY );
+ mpParaSheet[ TSS_TYPE_NOTES ] = new PPTParaSheet( TSS_TYPE_NOTES );
+ mpParaSheet[ TSS_TYPE_UNUSED ] = new PPTParaSheet( TSS_TYPE_UNUSED );
+ mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ] = new PPTParaSheet( TSS_TYPE_TEXT_IN_SHAPE );
+ mpCharSheet[ TSS_TYPE_QUARTERBODY ] = mpCharSheet[ TSS_TYPE_HALFBODY ] = mpCharSheet[ TSS_TYPE_TITLE ] = mpCharSheet[ TSS_TYPE_SUBTITLE ] = NULL;
+ mpParaSheet[ TSS_TYPE_QUARTERBODY ] = mpParaSheet[ TSS_TYPE_HALFBODY ] = mpParaSheet[ TSS_TYPE_TITLE ] = mpParaSheet[ TSS_TYPE_SUBTITLE ] = NULL;
+
+ /* SJ: try to locate the txMasterStyleAtom in the Environment
+
+ it seems that the environment TextStyle is having a higher priority
+ than the TextStyle that can be found within the master page
+ */
+ sal_Bool bFoundTxMasterStyleAtom04 = sal_False;
+ DffRecordHeader* pEnvHeader = rManager.aDocRecManager.GetRecordHeader( PPT_PST_Environment );
+ if ( pEnvHeader )
+ {
+ pEnvHeader->SeekToContent( rIn );
+ DffRecordHeader aTxMasterStyleHd;
+ while ( rIn.Tell() < pEnvHeader->GetRecEndFilePos() )
+ {
+ rIn >> aTxMasterStyleHd;
+ if ( aTxMasterStyleHd.nRecType == PPT_PST_TxMasterStyleAtom )
+ {
+ sal_uInt16 nLevelAnz;
+ rIn >> nLevelAnz;
+
+ sal_uInt16 nLev = 0;
+ sal_Bool bFirst = sal_True;
+ bFoundTxMasterStyleAtom04 = sal_True;
+ while ( rIn.GetError() == 0 && rIn.Tell() < aTxMasterStyleHd.GetRecEndFilePos() && nLev < nLevelAnz )
+ {
+ if ( nLev )
+ {
+ mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maParaLevel[ nLev ] = mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maParaLevel[ nLev - 1 ];
+ mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maCharLevel[ nLev ] = mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maCharLevel[ nLev - 1 ];
+ }
+ mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->Read( rManager, rIn, sal_True, nLev, bFirst );
+ if ( !nLev )
+ {
+ // set paragraph defaults for instance 4 (TSS_TYPE_TEXT_IN_SHAPE)
+ if ( rTxPFStyle.bValid )
+ {
+ PPTParaLevel& rParaLevel = mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maParaLevel[ 0 ];
+ rParaLevel.mnAsianLineBreak = 0;
+ if ( rTxPFStyle.bForbiddenRules )
+ rParaLevel.mnAsianLineBreak |= 1;
+ if ( !rTxPFStyle.bLatinTextWrap )
+ rParaLevel.mnAsianLineBreak |= 2;
+ if ( rTxPFStyle.bHangingPunctuation )
+ rParaLevel.mnAsianLineBreak |= 4;
+ }
+ }
+ mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->Read( rIn, sal_True, nLev, bFirst );
+ bFirst = sal_False;
+ nLev++;
+ }
+ break;
+ }
+ else
+ aTxMasterStyleHd.SeekToEndOfRecord( rIn );
+ }
+ }
+
+ rSlideHd.SeekToContent( rIn );
+ DffRecordHeader aTxMasterStyleHd;
+ while ( rIn.Tell() < rSlideHd.GetRecEndFilePos() )
+ {
+ rIn >> aTxMasterStyleHd;
+ if ( aTxMasterStyleHd.nRecType == PPT_PST_TxMasterStyleAtom )
+ break;
+ else
+ aTxMasterStyleHd.SeekToEndOfRecord( rIn );
+ }
+ while ( ( aTxMasterStyleHd.nRecType == PPT_PST_TxMasterStyleAtom ) && ( rIn.Tell() < rSlideHd.GetRecEndFilePos() ) ) //TODO: aTxMasterStyleHd may be used without having been properly initialized
+ {
+ sal_uInt32 nInstance = aTxMasterStyleHd.nRecInstance;
+ if ( ( nInstance < PPT_STYLESHEETENTRYS ) &&
+ ( ( nInstance != TSS_TYPE_TEXT_IN_SHAPE ) || ( bFoundTxMasterStyleAtom04 == sal_False ) ) )
+ {
+ if ( nInstance > 4 )
+ {
+ delete mpCharSheet[ nInstance ]; // be sure to delete the old one if this instance comes twice
+ delete mpParaSheet[ nInstance ];
+
+ switch ( nInstance )
+ {
+ case TSS_TYPE_SUBTITLE :
+ {
+ mpCharSheet[ TSS_TYPE_SUBTITLE ] = new PPTCharSheet( *( mpCharSheet[ TSS_TYPE_BODY ] ) );
+ mpParaSheet[ TSS_TYPE_SUBTITLE ] = new PPTParaSheet( *( mpParaSheet[ TSS_TYPE_BODY ] ) );
+ }
+ break;
+ case TSS_TYPE_TITLE :
+ {
+ mpCharSheet[ TSS_TYPE_TITLE ] = new PPTCharSheet( *( mpCharSheet[ TSS_TYPE_PAGETITLE ] ) );
+ mpParaSheet[ TSS_TYPE_TITLE ] = new PPTParaSheet( *( mpParaSheet[ TSS_TYPE_PAGETITLE ] ) );
+ }
+ break;
+ case TSS_TYPE_HALFBODY :
+ {
+ mpCharSheet[ TSS_TYPE_HALFBODY ] = new PPTCharSheet( *( mpCharSheet[ TSS_TYPE_BODY ] ) );
+ mpParaSheet[ TSS_TYPE_HALFBODY ] = new PPTParaSheet( *( mpParaSheet[ TSS_TYPE_BODY ] ) );
+ }
+ break;
+
+ case TSS_TYPE_QUARTERBODY :
+ {
+ mpCharSheet[ TSS_TYPE_QUARTERBODY ] = new PPTCharSheet( *( mpCharSheet[ TSS_TYPE_BODY ] ) );
+ mpParaSheet[ TSS_TYPE_QUARTERBODY ] = new PPTParaSheet( *( mpParaSheet[ TSS_TYPE_BODY ] ) );
+ }
+ break;
+ }
+ }
+ sal_uInt16 nLevelAnz;
+ rIn >> nLevelAnz;
+ if ( nLevelAnz > 5 )
+ {
+ DBG_ERROR( "PPTStyleSheet::Ppt-TextStylesheet hat mehr als 5 Ebenen! (SJ)" );
+ nLevelAnz = 5;
+ }
+ sal_uInt16 nLev = 0;
+ sal_Bool bFirst = sal_True;
+
+ while ( rIn.GetError() == 0 && rIn.Tell() < aTxMasterStyleHd.GetRecEndFilePos() && nLev < nLevelAnz )
+ {
+ if ( nLev && ( nInstance < 5 ) )
+ {
+ mpParaSheet[ nInstance ]->maParaLevel[ nLev ] = mpParaSheet[ nInstance ]->maParaLevel[ nLev - 1 ];
+ mpCharSheet[ nInstance ]->maCharLevel[ nLev ] = mpCharSheet[ nInstance ]->maCharLevel[ nLev - 1 ];
+ }
+
+ // Ausnahme: Vorlage 5, 6 (MasterTitle Titel und SubTitel)
+ if ( nInstance >= TSS_TYPE_SUBTITLE )
+ {
+ bFirst = sal_False;
+
+ sal_uInt16 nDontKnow;
+ rIn >> nDontKnow;
+ }
+ mpParaSheet[ nInstance ]->Read( rManager, rIn, sal_True, nLev, bFirst );
+ mpCharSheet[ nInstance ]->Read( rIn, sal_True, nLev, bFirst );
+ bFirst = sal_False;
+ nLev++;
+ }
+#ifdef DBG_UTIL
+ if (!(rManager.rImportParam.nImportFlags & PPT_IMPORTFLAGS_NO_TEXT_ASSERT))
+ {
+ if ( rIn.GetError() == 0 )
+ {
+ ByteString aMsg;
+ if ( rIn.Tell() > aTxMasterStyleHd.GetRecEndFilePos() )
+ {
+ aMsg += "\n ";
+ aMsg += "reading too many bytes:";
+ aMsg += ByteString::CreateFromInt32( rIn.Tell() - aTxMasterStyleHd.GetRecEndFilePos() );
+ }
+ if ( rIn.Tell() < aTxMasterStyleHd.GetRecEndFilePos() )
+ {
+ aMsg += "\n ";
+ aMsg += "reading too less bytes:";
+ aMsg += ByteString::CreateFromInt32( aTxMasterStyleHd.GetRecEndFilePos() - rIn.Tell() );
+ }
+ if ( aMsg.Len() != 0 )
+ {
+ aMsg.Insert( "]:", 0 );
+ aMsg.Insert( "PptStyleSheet::operator>>[", 0 );
+ DBG_ERROR(aMsg.GetBuffer());
+ }
+ }
+ if ( rIn.Tell() != aTxMasterStyleHd.GetRecEndFilePos() )
+ DBG_ASSERT(0, "SJ: Falsche Anzahl von Bytes gelesen beim Import der PPT-Formatvorlagen");
+ }
+#endif
+ }
+ aTxMasterStyleHd.SeekToEndOfRecord( rIn );
+ rIn >> aTxMasterStyleHd;
+ }
+ if ( !mpCharSheet[ TSS_TYPE_SUBTITLE ] )
+ {
+ mpCharSheet[ TSS_TYPE_SUBTITLE ] = new PPTCharSheet( *( mpCharSheet[ TSS_TYPE_BODY ] ) );
+ mpParaSheet[ TSS_TYPE_SUBTITLE ] = new PPTParaSheet( *( mpParaSheet[ TSS_TYPE_BODY ] ) );
+ }
+ if ( !mpCharSheet[ TSS_TYPE_TITLE ] )
+ {
+ mpCharSheet[ TSS_TYPE_TITLE ] = new PPTCharSheet( *( mpCharSheet[ TSS_TYPE_PAGETITLE ] ) );
+ mpParaSheet[ TSS_TYPE_TITLE ] = new PPTParaSheet( *( mpParaSheet[ TSS_TYPE_PAGETITLE ] ) );
+ }
+ if ( !mpCharSheet[ TSS_TYPE_HALFBODY ] )
+ {
+ mpCharSheet[ TSS_TYPE_HALFBODY ] = new PPTCharSheet( *( mpCharSheet[ TSS_TYPE_BODY ] ) );
+ mpParaSheet[ TSS_TYPE_HALFBODY ] = new PPTParaSheet( *( mpParaSheet[ TSS_TYPE_BODY ] ) );
+ }
+ if ( !mpCharSheet[ TSS_TYPE_QUARTERBODY ] )
+ {
+ mpCharSheet[ TSS_TYPE_QUARTERBODY ] = new PPTCharSheet( *( mpCharSheet[ TSS_TYPE_BODY ] ) );
+ mpParaSheet[ TSS_TYPE_QUARTERBODY ] = new PPTParaSheet( *( mpParaSheet[ TSS_TYPE_BODY ] ) );
+ }
+ if ( !bFoundTxMasterStyleAtom04 )
+ { // try to locate the txMasterStyleAtom in the Environment
+ DffRecordHeader* pEnvHeader2 = rManager.aDocRecManager.GetRecordHeader( PPT_PST_Environment );
+ if ( pEnvHeader2 )
+ {
+ pEnvHeader2->SeekToContent( rIn );
+ DffRecordHeader aTxMasterStyleHd2;
+ while ( rIn.Tell() < pEnvHeader2->GetRecEndFilePos() )
+ {
+ rIn >> aTxMasterStyleHd2;
+ if ( aTxMasterStyleHd2.nRecType == PPT_PST_TxMasterStyleAtom )
+ {
+ sal_uInt16 nLevelAnz;
+ rIn >> nLevelAnz;
+
+ sal_uInt16 nLev = 0;
+ sal_Bool bFirst = sal_True;
+ while ( rIn.GetError() == 0 && rIn.Tell() < aTxMasterStyleHd2.GetRecEndFilePos() && nLev < nLevelAnz )
+ {
+ if ( nLev )
+ {
+ mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maParaLevel[ nLev ] = mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maParaLevel[ nLev - 1 ];
+ mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maCharLevel[ nLev ] = mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maCharLevel[ nLev - 1 ];
+ }
+ mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->Read( rManager, rIn, sal_True, nLev, bFirst );
+ if ( !nLev )
+ {
+ // set paragraph defaults for instance 4 (TSS_TYPE_TEXT_IN_SHAPE)
+ if ( rTxPFStyle.bValid )
+ {
+ PPTParaLevel& rParaLevel = mpParaSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->maParaLevel[ 0 ];
+ rParaLevel.mnAsianLineBreak = 0;
+ if ( rTxPFStyle.bForbiddenRules )
+ rParaLevel.mnAsianLineBreak |= 1;
+ if ( !rTxPFStyle.bLatinTextWrap )
+ rParaLevel.mnAsianLineBreak |= 2;
+ if ( rTxPFStyle.bHangingPunctuation )
+ rParaLevel.mnAsianLineBreak |= 4;
+ }
+ }
+ mpCharSheet[ TSS_TYPE_TEXT_IN_SHAPE ]->Read( rIn, sal_True, nLev, bFirst );
+ bFirst = sal_False;
+ nLev++;
+ }
+ break;
+ }
+ else
+ aTxMasterStyleHd2.SeekToEndOfRecord( rIn );
+ }
+ }
+ }
+ rIn.Seek( nOldFilePos );
+
+ // will will create the default numbulletitem for each instance
+ for ( i = 0; i < PPT_STYLESHEETENTRYS; i++ )
+ {
+ UINT16 nLevels, nDepth = 0;
+ SvxNumRuleType eNumRuleType;
+
+ switch ( i )
+ {
+ case TSS_TYPE_PAGETITLE :
+ case TSS_TYPE_TITLE :
+ nLevels = 1;
+ eNumRuleType = SVX_RULETYPE_NUMBERING;
+ break;
+ case TSS_TYPE_SUBTITLE :
+ nLevels = 10;
+ eNumRuleType = SVX_RULETYPE_NUMBERING;
+ break;
+ case TSS_TYPE_BODY :
+ case TSS_TYPE_HALFBODY :
+ case TSS_TYPE_QUARTERBODY :
+ nLevels = 10;
+ eNumRuleType = SVX_RULETYPE_PRESENTATION_NUMBERING;
+ break;
+ default :
+ case TSS_TYPE_NOTES :
+ case TSS_TYPE_UNUSED :
+ case TSS_TYPE_TEXT_IN_SHAPE :
+ nLevels = 10;
+ eNumRuleType = SVX_RULETYPE_NUMBERING;
+ break;
+ }
+ SvxNumRule aRule( NUM_BULLET_REL_SIZE | NUM_BULLET_COLOR |
+ NUM_CHAR_TEXT_DISTANCE | NUM_SYMBOL_ALIGNMENT,
+ nLevels, FALSE, eNumRuleType );
+ for ( UINT16 nCount = 0; nDepth < nLevels; nCount++ )
+ {
+ const PPTParaLevel& rParaLevel = mpParaSheet[ i ]->maParaLevel[ nCount ];
+ const PPTCharLevel& rCharLevel = mpCharSheet[ i ]->maCharLevel[ nCount ];
+ SvxNumberFormat aNumberFormat( SVX_NUM_CHAR_SPECIAL );
+ aNumberFormat.SetBulletChar( ' ' );
+ GetNumberFormat( rManager, aNumberFormat, nCount, rParaLevel, rCharLevel, i );
+ aRule.SetLevel( nDepth++, aNumberFormat );
+ if ( nCount >= 4 )
+ {
+ for ( ;nDepth < nLevels; nDepth++ )
+ aRule.SetLevel( nDepth, aNumberFormat );
+ if ( eNumRuleType == SVX_RULETYPE_PRESENTATION_NUMBERING )
+ aRule.SetLevel( 0, aNumberFormat );
+ }
+ }
+ mpNumBulletItem[ i ] = new SvxNumBulletItem( aRule, EE_PARA_NUMBULLET );
+ }
+}
+
+PPTStyleSheet::~PPTStyleSheet()
+{
+ for ( UINT32 i = 0; i < PPT_STYLESHEETENTRYS; i++ )
+ {
+ delete mpCharSheet[ i ];
+ delete mpParaSheet[ i ];
+ delete mpNumBulletItem[ i ];
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PPTParaPropSet::PPTParaPropSet() :
+ pParaSet( new ImplPPTParaPropSet )
+{
+ pParaSet->mnHasAnm = 1;
+}
+
+PPTParaPropSet::PPTParaPropSet( PPTParaPropSet& rParaPropSet )
+{
+ pParaSet = rParaPropSet.pParaSet;
+ pParaSet->mnRefCount++;
+
+ mnOriginalTextPos = rParaPropSet.mnOriginalTextPos;
+}
+
+PPTParaPropSet::~PPTParaPropSet()
+{
+ if ( ! ( --pParaSet->mnRefCount ) )
+ delete pParaSet;
+}
+
+PPTParaPropSet& PPTParaPropSet::operator=( PPTParaPropSet& rParaPropSet )
+{
+ if ( this != &rParaPropSet )
+ {
+ if ( ! ( --pParaSet->mnRefCount ) )
+ delete pParaSet;
+ pParaSet = rParaPropSet.pParaSet;
+ pParaSet->mnRefCount++;
+
+ mnOriginalTextPos = rParaPropSet.mnOriginalTextPos;
+ }
+ return *this;
+}
+
+PPTCharPropSet::PPTCharPropSet( sal_uInt32 nParagraph ) :
+ mnParagraph ( nParagraph ),
+ mpFieldItem ( NULL ),
+ pCharSet ( new ImplPPTCharPropSet )
+{
+ mnLanguage[ 0 ] = mnLanguage[ 1 ] = mnLanguage[ 2 ] = 0;
+}
+
+PPTCharPropSet::PPTCharPropSet( PPTCharPropSet& rCharPropSet )
+{
+ pCharSet = rCharPropSet.pCharSet;
+ pCharSet->mnRefCount++;
+
+ mnParagraph = rCharPropSet.mnParagraph;
+ mnOriginalTextPos = rCharPropSet.mnOriginalTextPos;
+ maString = rCharPropSet.maString;
+ mpFieldItem = ( rCharPropSet.mpFieldItem ) ? new SvxFieldItem( *rCharPropSet.mpFieldItem ) : NULL;
+ mnLanguage[ 0 ] = rCharPropSet.mnLanguage[ 0 ];
+ mnLanguage[ 1 ] = rCharPropSet.mnLanguage[ 1 ];
+ mnLanguage[ 2 ] = rCharPropSet.mnLanguage[ 2 ];
+}
+
+PPTCharPropSet::PPTCharPropSet( PPTCharPropSet& rCharPropSet, sal_uInt32 nParagraph )
+{
+ pCharSet = rCharPropSet.pCharSet;
+ pCharSet->mnRefCount++;
+
+ mnParagraph = nParagraph;
+ mnOriginalTextPos = rCharPropSet.mnOriginalTextPos;
+ maString = rCharPropSet.maString;
+ mpFieldItem = ( rCharPropSet.mpFieldItem ) ? new SvxFieldItem( *rCharPropSet.mpFieldItem ) : NULL;
+ mnLanguage[ 0 ] = mnLanguage[ 1 ] = mnLanguage[ 2 ] = 0;
+}
+
+PPTCharPropSet::~PPTCharPropSet()
+{
+ if ( ! ( --pCharSet->mnRefCount ) )
+ delete pCharSet;
+ delete mpFieldItem;
+}
+
+PPTCharPropSet& PPTCharPropSet::operator=( PPTCharPropSet& rCharPropSet )
+{
+ if ( this != &rCharPropSet )
+ {
+ if ( ! ( --pCharSet->mnRefCount ) )
+ delete pCharSet;
+ pCharSet = rCharPropSet.pCharSet;
+ pCharSet->mnRefCount++;
+
+ mnOriginalTextPos = rCharPropSet.mnOriginalTextPos;
+ mnParagraph = rCharPropSet.mnParagraph;
+ maString = rCharPropSet.maString;
+ mpFieldItem = ( rCharPropSet.mpFieldItem ) ? new SvxFieldItem( *rCharPropSet.mpFieldItem ) : NULL;
+ }
+ return *this;
+}
+
+void PPTCharPropSet::ImplMakeUnique()
+{
+ if ( pCharSet->mnRefCount > 1 )
+ {
+ ImplPPTCharPropSet& rOld = *pCharSet;
+ rOld.mnRefCount--;
+ pCharSet = new ImplPPTCharPropSet( rOld );
+ pCharSet->mnRefCount = 1;
+ }
+}
+
+void PPTCharPropSet::SetFont( UINT16 nFont )
+{
+ UINT32 nMask = 1 << PPT_CharAttr_Font;
+ UINT32 bDoNotMake = pCharSet->mnAttrSet & nMask;
+
+ if ( bDoNotMake )
+ bDoNotMake = nFont == pCharSet->mnFont;
+
+ if ( !bDoNotMake )
+ {
+ ImplMakeUnique();
+ pCharSet->mnFont = nFont;
+ pCharSet->mnAttrSet |= nMask;
+ }
+}
+
+void PPTCharPropSet::SetColor( sal_uInt32 nColor )
+{
+ ImplMakeUnique();
+ pCharSet->mnColor = nColor;
+ pCharSet->mnAttrSet |= 1 << PPT_CharAttr_FontColor;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PPTRuler::PPTRuler() :
+ nRefCount ( 1 ),
+ nFlags ( 0 ),
+ pTab ( NULL ),
+ nTabCount ( 0 )
+{
+}
+
+PPTRuler::~PPTRuler()
+{
+ delete[] pTab;
+};
+
+
+PPTTextRulerInterpreter::PPTTextRulerInterpreter() :
+ mpImplRuler ( new PPTRuler() )
+{
+}
+
+PPTTextRulerInterpreter::PPTTextRulerInterpreter( PPTTextRulerInterpreter& rRuler )
+{
+ mpImplRuler = rRuler.mpImplRuler;
+ mpImplRuler->nRefCount++;
+}
+
+PPTTextRulerInterpreter::PPTTextRulerInterpreter( UINT32 nFileOfs, SdrPowerPointImport& rMan, DffRecordHeader& rHeader, SvStream& rIn ) :
+ mpImplRuler ( new PPTRuler() )
+{
+ if ( nFileOfs != 0xffffffff )
+ {
+ UINT32 nOldPos = rIn.Tell();
+ DffRecordHeader rHd;
+ if ( nFileOfs )
+ {
+ rIn.Seek( nFileOfs );
+ rIn >> rHd;
+ }
+ else
+ {
+ rHeader.SeekToContent( rIn );
+ if ( rMan.SeekToRec( rIn, PPT_PST_TextRulerAtom, rHeader.GetRecEndFilePos(), &rHd ) )
+ nFileOfs++;
+ }
+ if ( nFileOfs )
+ {
+ sal_Int16 nTCount;
+ sal_Int32 i;
+ rIn >> mpImplRuler->nFlags;
+ if ( mpImplRuler->nFlags & 1 )
+ rIn >> mpImplRuler->nDefaultTab;
+ if ( mpImplRuler->nFlags & 4 )
+ {
+ rIn >> nTCount;
+ if ( nTCount )
+ {
+ mpImplRuler->nTabCount = (UINT16)nTCount;
+ mpImplRuler->pTab = new PPTTabEntry[ mpImplRuler->nTabCount ];
+ for ( i = 0; i < nTCount; i++ )
+ {
+ rIn >> mpImplRuler->pTab[ i ].nOffset
+ >> mpImplRuler->pTab[ i ].nStyle;
+ }
+ }
+ }
+ for ( i = 0; i < 5; i++ )
+ {
+ if ( mpImplRuler->nFlags & ( 8 << i ) )
+ rIn >> mpImplRuler->nTextOfs[ i ];
+ if ( mpImplRuler->nFlags & ( 256 << i ) )
+ rIn >> mpImplRuler->nBulletOfs[ i ];
+ }
+ }
+ rIn.Seek( nOldPos );
+ }
+}
+
+BOOL PPTTextRulerInterpreter::GetDefaultTab( UINT32 /*nLevel*/, UINT16& nValue ) const
+{
+ if ( ! ( mpImplRuler->nFlags & 1 ) )
+ return FALSE;
+ nValue = mpImplRuler->nDefaultTab;
+ return TRUE;
+}
+
+BOOL PPTTextRulerInterpreter::GetTextOfs( UINT32 nLevel, UINT16& nValue ) const
+{
+ if ( ! ( ( nLevel < 5 ) && ( mpImplRuler->nFlags & ( 8 << nLevel ) ) ) )
+ return FALSE;
+ nValue = mpImplRuler->nTextOfs[ nLevel ];
+ return TRUE;
+}
+
+BOOL PPTTextRulerInterpreter::GetBulletOfs( UINT32 nLevel, UINT16& nValue ) const
+{
+ if ( ! ( ( nLevel < 5 ) && ( mpImplRuler->nFlags & ( 256 << nLevel ) ) ) )
+ return FALSE;
+ nValue = mpImplRuler->nBulletOfs[ nLevel ];
+ return TRUE;
+}
+
+PPTTextRulerInterpreter& PPTTextRulerInterpreter::operator=( PPTTextRulerInterpreter& rRuler )
+{
+ if ( this != &rRuler )
+ {
+ if ( ! ( --mpImplRuler->nRefCount ) )
+ delete mpImplRuler;
+ mpImplRuler = rRuler.mpImplRuler;
+ mpImplRuler->nRefCount++;
+ }
+ return *this;
+}
+
+PPTTextRulerInterpreter::~PPTTextRulerInterpreter()
+{
+ if ( ! ( --mpImplRuler->nRefCount ) )
+ delete mpImplRuler;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PPTTextCharacterStyleAtomInterpreter::PPTTextCharacterStyleAtomInterpreter() :
+ nFlags1 ( 0 ),
+ nFlags2 ( 0 ),
+ nFlags3 ( 0 )
+{
+}
+
+sal_Bool PPTTextCharacterStyleAtomInterpreter::Read( SvStream& rIn, const DffRecordHeader& rRecHd )
+{
+ rRecHd.SeekToContent( rIn );
+
+ rIn >> nFlags1
+ >> nFlags2
+ >> nFlags3
+ >> n1
+ >> nFontHeight
+ >> nFontColor;
+
+ return sal_True;
+}
+
+PPTTextCharacterStyleAtomInterpreter::~PPTTextCharacterStyleAtomInterpreter()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+PPTTextParagraphStyleAtomInterpreter::PPTTextParagraphStyleAtomInterpreter() :
+ bValid ( sal_False ),
+ bForbiddenRules ( sal_False ),
+ bHangingPunctuation ( sal_False ),
+ bLatinTextWrap ( sal_False )
+{
+}
+
+sal_Bool PPTTextParagraphStyleAtomInterpreter::Read( SvStream& rIn, const DffRecordHeader& rRecHd )
+{
+ bValid = sal_False;
+ rRecHd.SeekToContent( rIn );
+ sal_uInt32 nDummy32, nFlags, nRecEndPos = rRecHd.GetRecEndFilePos();
+ sal_uInt16 nDummy16;
+
+ rIn >> nDummy16
+ >> nFlags;
+
+ if ( nFlags & 0xf && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16; // BuFlags
+ if ( nFlags & 0x80 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16; // BuChar
+ if ( nFlags & 0x10 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16; // nBuFont;
+ if ( nFlags & 0x40 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16; // nBuHeight;
+ if ( nFlags & 0x0020 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy32; // nBuColor;
+ if ( nFlags & 0x800 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16; // AbsJust!
+ if ( nFlags & 0x400 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16;
+ if ( nFlags & 0x200 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16;
+ if ( nFlags & 0x100 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16;
+ if ( nFlags & 0x1000 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16; // LineFeed
+ if ( nFlags & 0x2000 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16; // nUpperDist
+ if ( nFlags & 0x4000 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16; // nLowerDist
+ if ( nFlags & 0x8000 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16;
+ if ( nFlags & 0x10000 && ( rIn.Tell() < nRecEndPos ) )
+ rIn >> nDummy16;
+ if ( nFlags & 0xe0000 && ( rIn.Tell() < nRecEndPos ) )
+ {
+ rIn >> nDummy16;
+ if ( nFlags & 0x20000 )
+ bForbiddenRules = ( nDummy16 & 1 ) == 1;
+ if ( nFlags & 0x40000 )
+ bLatinTextWrap = ( nDummy16 & 2 ) == 0;
+ if ( nFlags & 0x80000 )
+ bHangingPunctuation = ( nDummy16 & 4 ) == 4;
+ }
+ nFlags &=~ 0xfffff;
+ sal_uInt32 nMask = 0x100000;
+ while ( nFlags && nMask && ( rIn.Tell() < nRecEndPos ) )
+ {
+ if ( nFlags & nMask )
+ {
+ rIn >> nDummy16;
+ nFlags ^= nMask;
+ }
+ nMask <<= 1;
+ }
+ bValid = rIn.Tell() == nRecEndPos;
+ return bValid;
+}
+
+PPTTextParagraphStyleAtomInterpreter::~PPTTextParagraphStyleAtomInterpreter()
+{
+
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PPTTextSpecInfo::PPTTextSpecInfo( sal_uInt32 _nCharIdx ) :
+ nCharIdx ( _nCharIdx ),
+ nDontKnow ( 1 )
+{
+ nLanguage[ 0 ] = 0x400;
+ nLanguage[ 1 ] = 0;
+ nLanguage[ 2 ] = 0;
+}
+
+PPTTextSpecInfo::~PPTTextSpecInfo()
+{
+}
+
+PPTTextSpecInfoAtomInterpreter::PPTTextSpecInfoAtomInterpreter() :
+ bValid ( sal_False )
+{
+}
+
+sal_Bool PPTTextSpecInfoAtomInterpreter::Read( SvStream& rIn, const DffRecordHeader& rRecHd,
+ sal_uInt16 nRecordType, const PPTTextSpecInfo* pTextSpecDefault )
+{
+ bValid = sal_False;
+ sal_uInt32 nCharIdx = 0;
+ rRecHd.SeekToContent( rIn );
+
+ while ( rIn.Tell() < rRecHd.GetRecEndFilePos() )
+ {
+ sal_uInt32 nCharCount,
+ nFlags, i;
+
+ if ( nRecordType == PPT_PST_TextSpecInfoAtom )
+ {
+ rIn >> nCharCount;
+ nCharIdx += nCharCount;
+ }
+ rIn >> nFlags;
+
+ PPTTextSpecInfo* pEntry = new PPTTextSpecInfo( nCharIdx );
+ if ( pTextSpecDefault )
+ {
+ pEntry->nDontKnow = pTextSpecDefault->nDontKnow;
+ pEntry->nLanguage[ 0 ] = pTextSpecDefault->nLanguage[ 0 ];
+ pEntry->nLanguage[ 1 ] = pTextSpecDefault->nLanguage[ 1 ];
+ pEntry->nLanguage[ 2 ] = pTextSpecDefault->nLanguage[ 2 ];
+ }
+ for ( i = 1; nFlags && i ; i <<= 1 )
+ {
+ sal_uInt16 nLang = 0;
+ switch( nFlags & i )
+ {
+ case 0 : break;
+ case 1 : rIn >> pEntry->nDontKnow; break;
+ case 2 : rIn >> nLang; break;
+ case 4 : rIn >> nLang; break;
+ default :
+ {
+ rIn.SeekRel( 2 );
+ }
+ }
+ if ( nLang )
+ {
+ sal_uInt16 nScriptType = GetI18NScriptTypeOfLanguage( nLang );
+ if ( nScriptType & SCRIPTTYPE_LATIN )
+ pEntry->nLanguage[ 0 ] = nLang;
+ if ( nScriptType & SCRIPTTYPE_ASIAN )
+ pEntry->nLanguage[ 1 ] = nLang;
+ if ( nScriptType & SCRIPTTYPE_COMPLEX )
+ pEntry->nLanguage[ 2 ] = nLang;
+ }
+ nFlags &= ~i;
+ }
+ aList.Insert( pEntry, LIST_APPEND );
+ }
+ bValid = rIn.Tell() == rRecHd.GetRecEndFilePos();
+ return bValid;
+}
+
+PPTTextSpecInfoAtomInterpreter::~PPTTextSpecInfoAtomInterpreter()
+{
+ void *pPtr;
+ for ( pPtr = aList.First(); pPtr; pPtr = aList.Next() )
+ delete (PPTTextSpecInfo*)pPtr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void StyleTextProp9::Read( SvStream& rIn )
+{
+ rIn >> mnExtParagraphMask;
+ if ( mnExtParagraphMask & 0x800000 )
+ rIn >> mnBuBlip;
+ if ( mnExtParagraphMask & 0x2000000 )
+ rIn >> mnHasAnm;
+ if ( mnExtParagraphMask & 0x1000000 )
+ rIn >> mnAnmScheme;
+ if ( mnExtParagraphMask & 0x4000000 )
+ rIn >> mpfPP10Ext;
+ rIn >> mnExtCharacterMask;
+ if ( mnExtCharacterMask & 0x100000 )
+ rIn >> mncfPP10Ext;
+ rIn >> mnSpecialInfoMask;
+ if ( mnSpecialInfoMask & 0x20 )
+ rIn >> mnPP10Ext;
+ if ( mnSpecialInfoMask & 0x40 )
+ rIn >> mfBidi;
+}
+
+PPTStyleTextPropReader::PPTStyleTextPropReader( SvStream& rIn, SdrPowerPointImport& rMan, const DffRecordHeader& rTextHeader,
+ PPTTextRulerInterpreter& rRuler, const DffRecordHeader& rExtParaHd, sal_uInt32 nInstance )
+{
+ Init(rIn, rMan, rTextHeader, rRuler, rExtParaHd, nInstance);
+}
+
+void PPTStyleTextPropReader::ReadParaProps( SvStream& rIn, SdrPowerPointImport& rMan, const DffRecordHeader& rTextHeader,
+ const String& aString, PPTTextRulerInterpreter& rRuler,
+ sal_uInt32& nCharCount, sal_Bool& bTextPropAtom )
+{
+ sal_uInt32 nMask = 0; //TODO: nMask initialized here to suppress warning for now, see corresponding TODO below
+ sal_uInt32 nCharAnzRead = 0;
+ sal_uInt16 nDummy16;
+
+ sal_uInt16 nStringLen = aString.Len();
+
+ DffRecordHeader aTextHd2;
+ rTextHeader.SeekToContent( rIn );
+ if ( rMan.SeekToRec( rIn, PPT_PST_StyleTextPropAtom, rTextHeader.GetRecEndFilePos(), &aTextHd2 ) )
+ bTextPropAtom = sal_True;
+ while ( nCharAnzRead <= nStringLen )
+ {
+ PPTParaPropSet aParaPropSet;
+ ImplPPTParaPropSet& aSet = *aParaPropSet.pParaSet;
+ if ( bTextPropAtom )
+ {
+ rIn >> nCharCount
+ >> aParaPropSet.pParaSet->mnDepth; // Einruecktiefe
+
+ nCharCount--;
+
+ rIn >> nMask;
+ aSet.mnAttrSet = nMask & 0x207df7;
+ sal_uInt16 nBulFlg = 0;
+ if ( nMask & 0xF )
+ rIn >> nBulFlg; // Bullet-HardAttr-Flags
+ aSet.mpArry[ PPT_ParaAttr_BulletOn ] = ( nBulFlg & 1 ) ? 1 : 0;
+ aSet.mpArry[ PPT_ParaAttr_BuHardFont ] = ( nBulFlg & 2 ) ? 1 : 0;
+ aSet.mpArry[ PPT_ParaAttr_BuHardColor ] = ( nBulFlg & 4 ) ? 1 : 0;
+
+ if ( nMask & 0x0080 ) // buChar
+ rIn >> aSet.mpArry[ PPT_ParaAttr_BulletChar ];
+ if ( nMask & 0x0010 ) // buTypeface
+ rIn >> aSet.mpArry[ PPT_ParaAttr_BulletFont ];
+ if ( nMask & 0x0040 ) // buSize
+ {
+ rIn >> aSet.mpArry[ PPT_ParaAttr_BulletHeight ];
+ if ( ! ( ( nMask & ( 1 << PPT_ParaAttr_BuHardHeight ) )
+ && ( nBulFlg && ( 1 << PPT_ParaAttr_BuHardHeight ) ) ) )
+ aSet.mnAttrSet ^= 0x40;
+ }
+ if ( nMask & 0x0020 ) // buColor
+ {
+ sal_uInt32 nVal32, nHiByte;
+ rIn >> nVal32;
+ nHiByte = nVal32 >> 24;
+ if ( nHiByte <= 8 )
+ nVal32 = nHiByte | PPT_COLSCHEME;
+ aSet.mnBulletColor = nVal32;
+ }
+ if ( nMask & 0x0800 ) // pfAlignment
+ {
+ rIn >> nDummy16;
+ aSet.mpArry[ PPT_ParaAttr_Adjust ] = nDummy16 & 3;
+ }
+ if ( nMask & 0x1000 ) // pfLineSpacing
+ rIn >> aSet.mpArry[ PPT_ParaAttr_LineFeed ];
+ if ( nMask & 0x2000 ) // pfSpaceBefore
+ rIn >> aSet.mpArry[ PPT_ParaAttr_UpperDist ];
+ if ( nMask & 0x4000 ) // pfSpaceAfter
+ rIn >> aSet.mpArry[ PPT_ParaAttr_LowerDist ];
+ if ( nMask & 0x100 ) // pfLeftMargin
+ rIn >> nDummy16;
+ if ( nMask & 0x400 ) // pfIndent
+ rIn >> nDummy16;
+ if ( nMask & 0x8000 ) // pfDefaultTabSize
+ rIn >> nDummy16;
+ if ( nMask & 0x100000 ) // pfTabStops
+ {
+ sal_uInt16 i, nDistance, nAlignment, nNumberOfTabStops = 0;
+ rIn >> nNumberOfTabStops;
+ for ( i = 0; i < nNumberOfTabStops; i++ )
+ {
+ rIn >> nDistance
+ >> nAlignment;
+ }
+ }
+ if ( nMask & 0x10000 ) // pfBaseLine
+ rIn >> nDummy16;
+ if ( nMask & 0xe0000 ) // pfCharWrap, pfWordWrap, pfOverflow
+ {
+ rIn >> nDummy16;
+ if ( nMask & 0x20000 )
+ aSet.mpArry[ PPT_ParaAttr_AsianLB_1 ] = nDummy16 & 1;
+ if ( nMask & 0x40000 )
+ aSet.mpArry[ PPT_ParaAttr_AsianLB_2 ] = ( nDummy16 >> 1 ) & 1;
+ if ( nMask & 0x80000 )
+ aSet.mpArry[ PPT_ParaAttr_AsianLB_3 ] = ( nDummy16 >> 2 ) & 1;
+ aSet.mnAttrSet |= ( ( nMask >> 17 ) & 7 ) << PPT_ParaAttr_AsianLB_1;
+ }
+ if ( nMask & 0x200000 ) // pfTextDirection
+ rIn >> aSet.mpArry[ PPT_ParaAttr_BiDi ];
+ }
+ else
+ nCharCount = nStringLen;
+
+ if ( rRuler.GetTextOfs( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_TextOfs ] ) )
+ aSet.mnAttrSet |= 1 << PPT_ParaAttr_TextOfs;
+ if ( rRuler.GetBulletOfs( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_BulletOfs ] ) )
+ aSet.mnAttrSet |= 1 << PPT_ParaAttr_BulletOfs;
+ if ( rRuler.GetDefaultTab( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_DefaultTab ] ) )
+ aSet.mnAttrSet |= 1 << PPT_ParaAttr_DefaultTab;
+
+ if ( ( nCharCount > nStringLen ) || ( nStringLen < nCharAnzRead + nCharCount ) )
+ {
+ bTextPropAtom = sal_False;
+ nCharCount = nStringLen - nCharAnzRead;
+ // please fix the right hand side of
+ // PPTParaPropSet& PPTParaPropSet::operator=(PPTParaPropSet&),
+ // it should be a const reference
+ PPTParaPropSet aTmpPPTParaPropSet;
+ aParaPropSet = aTmpPPTParaPropSet;
+ DBG_ERROR( "SJ:PPTStyleTextPropReader::could not get this PPT_PST_StyleTextPropAtom by reading the paragraph attributes" );
+ }
+ PPTParaPropSet* pPara = new PPTParaPropSet( aParaPropSet );
+ pPara->mnOriginalTextPos = nCharAnzRead;
+ aParaPropList.Insert( pPara, LIST_APPEND );
+ if ( nCharCount )
+ {
+ sal_uInt32 nCount;
+ const sal_Unicode* pDat = aString.GetBuffer() + nCharAnzRead;
+ for ( nCount = 0; nCount < nCharCount; nCount++ )
+ {
+ if ( pDat[ nCount ] == 0xd )
+ {
+ pPara = new PPTParaPropSet( aParaPropSet );
+ pPara->mnOriginalTextPos = nCharAnzRead + nCount + 1;
+ aParaPropList.Insert( pPara, LIST_APPEND );
+ }
+ }
+ }
+ nCharAnzRead += nCharCount + 1;
+ }
+}
+
+void PPTStyleTextPropReader::ReadCharProps( SvStream& rIn, PPTCharPropSet& aCharPropSet, const String& aString,
+ sal_uInt32& nCharCount, sal_uInt32 nCharAnzRead,
+ sal_Bool& bTextPropAtom, sal_uInt32 nExtParaPos,
+ const std::vector< StyleTextProp9 >& aStyleTextProp9,
+ sal_uInt32& nExtParaFlags, sal_uInt16& nBuBlip,
+ sal_uInt16& nHasAnm, sal_uInt32& nAnmScheme )
+{
+ sal_uInt32 nMask = 0; //TODO: nMask initialized here to suppress warning for now, see corresponding TODO below
+ sal_uInt16 nDummy16;
+ sal_Int32 nCharsToRead;
+ sal_uInt32 nExtParaNibble = 0;
+
+ sal_uInt16 nStringLen = aString.Len();
+
+ rIn >> nDummy16;
+ nCharCount = nDummy16;
+ rIn >> nDummy16;
+ nCharsToRead = nStringLen - ( nCharAnzRead + nCharCount );
+ if ( nCharsToRead < 0 )
+ {
+ nCharCount = nStringLen - nCharAnzRead;
+ if ( nCharsToRead < -1 )
+ {
+ bTextPropAtom = sal_False;
+ DBG_ERROR( "SJ:PPTStyleTextPropReader::could not get this PPT_PST_StyleTextPropAtom by reading the character attributes" );
+ }
+ }
+ ImplPPTCharPropSet& aSet = *aCharPropSet.pCharSet;
+
+ // character attributes
+ rIn >> nMask;
+ if ( (sal_uInt16)nMask )
+ {
+ aSet.mnAttrSet |= (sal_uInt16)nMask;
+ rIn >> aSet.mnFlags;
+ }
+ if ( nMask & 0x10000 ) // cfTypeface
+ {
+ rIn >> aSet.mnFont;
+ aSet.mnAttrSet |= 1 << PPT_CharAttr_Font;
+ }
+ if ( nMask & 0x200000 ) // cfFEOldTypeface
+ {
+ rIn >> aSet.mnAsianOrComplexFont;
+ aSet.mnAttrSet |= 1 << PPT_CharAttr_AsianOrComplexFont;
+ }
+ if ( nMask & 0x400000 ) // cfANSITypeface
+ {
+ rIn >> aSet.mnANSITypeface;
+ aSet.mnAttrSet |= 1 << PPT_CharAttr_ANSITypeface;
+ }
+ if ( nMask & 0x800000 ) // cfSymbolTypeface
+ {
+ rIn >> aSet.mnSymbolFont;
+ aSet.mnAttrSet |= 1 << PPT_CharAttr_Symbol;
+ }
+ if ( nMask & 0x20000 ) // cfSize
+ {
+ rIn >> aSet.mnFontHeight;
+ aSet.mnAttrSet |= 1 << PPT_CharAttr_FontHeight;
+ }
+ if ( nMask & 0x40000 ) // cfColor
+ {
+ sal_uInt32 nVal;
+ rIn >> nVal;
+ if ( !( nVal & 0xff000000 ) )
+ nVal = PPT_COLSCHEME_HINTERGRUND;
+ aSet.mnColor = nVal;
+ aSet.mnAttrSet |= 1 << PPT_CharAttr_FontColor;
+ }
+ if ( nMask & 0x80000 ) // cfPosition
+ {
+ rIn >> aSet.mnEscapement;
+ aSet.mnAttrSet |= 1 << PPT_CharAttr_Escapement;
+ }
+ if ( nExtParaPos )
+ {
+ sal_uInt32 nExtBuInd = nMask & 0x3c00;
+ if ( nExtBuInd )
+ nExtBuInd = ( aSet.mnFlags & 0x3c00 ) >> 10;
+ if ( nExtBuInd < aStyleTextProp9.size() )
+ {
+ if ( nExtParaNibble && ( ( nExtBuInd + nExtParaNibble ) < aStyleTextProp9.size() ) )
+ nExtBuInd += nExtParaNibble;
+
+ nExtParaFlags = aStyleTextProp9[ nExtBuInd ].mnExtParagraphMask;
+ nBuBlip = aStyleTextProp9[ nExtBuInd ].mnBuBlip;
+ nHasAnm = aStyleTextProp9[ nExtBuInd ].mnHasAnm;
+ nAnmScheme = aStyleTextProp9[ nExtBuInd ].mnAnmScheme;
+ }
+ if ( ( nExtBuInd & 0xf ) == 0xf )
+ nExtParaNibble += 16;
+ }
+}
+
+void PPTStyleTextPropReader::Init( SvStream& rIn, SdrPowerPointImport& rMan, const DffRecordHeader& rTextHeader,
+ PPTTextRulerInterpreter& rRuler, const DffRecordHeader& rExtParaHd, sal_uInt32 nInstance )
+{
+ sal_uInt32 nMerk = rIn.Tell();
+ sal_uInt32 nExtParaPos = ( rExtParaHd.nRecType == PPT_PST_ExtendedParagraphAtom ) ? rExtParaHd.nFilePos + 8 : 0;
+
+ std::vector< StyleTextProp9 > aStyleTextProp9;
+ if ( rExtParaHd.nRecType == PPT_PST_ExtendedParagraphAtom )
+ {
+ rIn.Seek( rExtParaHd.nFilePos + 8 );
+ while( ( rIn.GetError() == 0 ) && ( rIn.Tell() < rExtParaHd.GetRecEndFilePos() ) )
+ {
+ aStyleTextProp9.resize( aStyleTextProp9.size() + 1 );
+ aStyleTextProp9.back().Read( rIn );
+ }
+ rIn.Seek( nMerk );
+ }
+
+ String aString;
+ DffRecordHeader aTextHd;
+ rIn >> aTextHd;
+ sal_uInt32 nMaxLen = aTextHd.nRecLen;
+ if ( nMaxLen > 0xFFFF )
+ nMaxLen = 0xFFFF;
+
+ if( aTextHd.nRecType == PPT_PST_TextCharsAtom )
+ {
+ sal_uInt32 i;
+ sal_Unicode nChar,*pBuf = new sal_Unicode[ ( nMaxLen >> 1 ) + 1 ];
+ rIn.Read( pBuf, nMaxLen );
+ nMaxLen >>= 1;
+ pBuf[ nMaxLen ] = 0;
+ sal_Unicode* pPtr = pBuf;
+#ifdef OSL_BIGENDIAN
+ sal_Unicode nTemp;
+ for ( i = 0; i < nMaxLen; i++ )
+ {
+ nTemp = *pPtr;
+ *pPtr++ = ( nTemp << 8 ) | ( nTemp >> 8 );
+ }
+ pPtr = pBuf;
+#endif
+
+ for ( i = 0; i < nMaxLen; pPtr++, i++ )
+ {
+ nChar = *pPtr;
+ if ( !nChar )
+ break;
+ if ( ( nChar & 0xff00 ) == 0xf000 ) // in this special case we got a symbol
+ aSpecMarkerList.Insert( (void*)( i | PPT_SPEC_SYMBOL ), LIST_APPEND );
+ else if ( nChar == 0xd )
+ {
+ if ( nInstance == TSS_TYPE_PAGETITLE )
+ *pPtr = 0xb;
+ else
+ aSpecMarkerList.Insert( (void*)( i | PPT_SPEC_NEWLINE ), LIST_APPEND );
+ }
+ }
+ if ( i )
+ aString = String( pBuf, (sal_uInt16)i );
+ delete[] pBuf;
+ }
+ else if( aTextHd.nRecType == PPT_PST_TextBytesAtom )
+ {
+ sal_Char *pBuf = new sal_Char[ nMaxLen + 1 ];
+ pBuf[ nMaxLen ] = 0;
+ rIn.Read( pBuf, nMaxLen );
+ sal_Char* pPtr = pBuf;
+ for (;;)
+ {
+ sal_Char cLo = *pPtr;
+ if ( cLo == 0 )
+ break;
+ if ( cLo == 0xd )
+ {
+ if ( nInstance == TSS_TYPE_PAGETITLE )
+ *pPtr = 0xb;
+ else
+ aSpecMarkerList.Insert( (void*)( pPtr - pBuf | PPT_SPEC_NEWLINE ), LIST_APPEND );
+ }
+ pPtr++;
+ }
+ xub_StrLen nLen = sal::static_int_cast< xub_StrLen >( pPtr - pBuf );
+ if ( nLen )
+ aString = String( pBuf, nLen, RTL_TEXTENCODING_MS_1252 );
+ delete[] pBuf;
+ }
+ else
+ {
+ // no chars, but potentially char/para props?
+ sal_uInt32 nCharCount;
+ sal_Bool bTextPropAtom = sal_False;
+ ReadParaProps( rIn, rMan, rTextHeader, aString, rRuler, nCharCount, bTextPropAtom );
+
+ if ( bTextPropAtom )
+ {
+ // yeah, StyleTextProp is there, read it all & push to
+ // aParaPropList
+ PPTCharPropSet aCharPropSet(0);
+ aCharPropSet.mnOriginalTextPos = 0;
+
+ sal_uInt32 nCharAnzRead = 0;
+ sal_uInt32 nExtParaFlags = 0, nAnmScheme = 0;
+ sal_uInt16 nBuBlip = 0xffff, nHasAnm = 0;
+ ReadCharProps( rIn, aCharPropSet, aString, nCharCount, nCharAnzRead,
+ bTextPropAtom, nExtParaPos, aStyleTextProp9, nExtParaFlags,
+ nBuBlip, nHasAnm, nAnmScheme );
+
+ aCharPropList.Insert(
+ new PPTCharPropSet( aCharPropSet, 0 ), LIST_APPEND );
+ }
+ }
+
+ if ( aString.Len() )
+ {
+ sal_uInt32 nCharCount;
+ sal_Bool bTextPropAtom = sal_False;
+
+ ReadParaProps( rIn, rMan, rTextHeader, aString, rRuler, nCharCount, bTextPropAtom );
+
+ sal_Bool bEmptyParaPossible = sal_True;
+ sal_uInt32 nCharAnzRead = 0;
+ sal_uInt32 nCurrentPara = 0;
+ sal_uInt32 nCurrentSpecMarker = (sal_uInt32)(sal_uIntPtr)aSpecMarkerList.First();
+ sal_uInt16 nStringLen = aString.Len();
+
+ while ( nCharAnzRead < nStringLen )
+ {
+ sal_uInt32 nExtParaFlags = 0, nLatestParaUpdate = 0xffffffff, nAnmScheme = 0;
+ sal_uInt16 nBuBlip = 0xffff, nHasAnm = 0;
+
+ PPTCharPropSet aCharPropSet( nCurrentPara );
+ if ( bTextPropAtom )
+ ReadCharProps( rIn, aCharPropSet, aString, nCharCount, nCharAnzRead,
+ bTextPropAtom, nExtParaPos, aStyleTextProp9, nExtParaFlags,
+ nBuBlip, nHasAnm, nAnmScheme );
+ else
+ nCharCount = nStringLen;
+
+ sal_uInt32 nLen;
+ while( nCharCount )
+ {
+ if ( nExtParaPos && ( nLatestParaUpdate != nCurrentPara ) && ( nCurrentPara < aParaPropList.Count() ) )
+ {
+ PPTParaPropSet* pPropSet = (PPTParaPropSet*)aParaPropList.GetObject( nCurrentPara );
+ pPropSet->pParaSet->mnExtParagraphMask = nExtParaFlags;
+ if ( nExtParaFlags & 0x800000 )
+ pPropSet->pParaSet->mnBuBlip = nBuBlip;
+ if ( nExtParaFlags & 0x01000000 )
+ pPropSet->pParaSet->mnAnmScheme = nAnmScheme;
+ if ( nExtParaFlags & 0x02000000 )
+ pPropSet->pParaSet->mnHasAnm = nHasAnm;
+ nLatestParaUpdate = nCurrentPara;
+ }
+ aCharPropSet.mnOriginalTextPos = nCharAnzRead;
+ if ( nCurrentSpecMarker && ( ( nCurrentSpecMarker & 0xffff ) < ( nCharAnzRead + nCharCount ) ) )
+ {
+ if ( nCurrentSpecMarker & PPT_SPEC_NEWLINE )
+ {
+ nLen = ( nCurrentSpecMarker & 0xffff ) - nCharAnzRead;
+ if ( nLen )
+ aCharPropSet.maString = String( aString, (sal_uInt16)nCharAnzRead, (sal_uInt16)nLen );
+ else if ( bEmptyParaPossible )
+ aCharPropSet.maString = String();
+ if ( nLen || bEmptyParaPossible )
+ aCharPropList.Insert( new PPTCharPropSet( aCharPropSet, nCurrentPara ), LIST_APPEND );
+ nCurrentPara++;
+ nLen++;
+ nCharAnzRead += nLen;
+ nCharCount -= nLen;
+ bEmptyParaPossible = sal_True;
+ }
+ else if ( nCurrentSpecMarker & PPT_SPEC_SYMBOL )
+ {
+ if ( ( nCurrentSpecMarker & 0xffff ) != nCharAnzRead )
+ {
+ nLen = ( nCurrentSpecMarker & 0xffff ) - nCharAnzRead;
+ aCharPropSet.maString = String( aString, (sal_uInt16)nCharAnzRead, (sal_uInt16)nLen );
+ aCharPropList.Insert( new PPTCharPropSet( aCharPropSet, nCurrentPara ), LIST_APPEND );
+ nCharCount -= nLen;
+ nCharAnzRead += nLen;
+ }
+ PPTCharPropSet* pCPropSet = new PPTCharPropSet( aCharPropSet, nCurrentPara );
+ pCPropSet->maString = aString.GetChar( (sal_uInt16)nCharAnzRead );
+ if ( aCharPropSet.pCharSet->mnAttrSet & ( 1 << PPT_CharAttr_Symbol ) )
+ pCPropSet->SetFont( aCharPropSet.pCharSet->mnSymbolFont );
+ aCharPropList.Insert( pCPropSet, LIST_APPEND );
+ nCharCount--;
+ nCharAnzRead++;
+ bEmptyParaPossible = sal_False;
+ }
+ nCurrentSpecMarker = (sal_uInt32)(sal_uIntPtr)aSpecMarkerList.Next();
+ }
+ else
+ {
+ aCharPropSet.maString = String( aString, (sal_uInt16)nCharAnzRead, (sal_uInt16)nCharCount );
+ aCharPropList.Insert( new PPTCharPropSet( aCharPropSet, nCurrentPara ), LIST_APPEND );
+ nCharAnzRead += nCharCount;
+ bEmptyParaPossible = sal_False;
+ break;
+ }
+ }
+ }
+ if ( aCharPropList.Count() && ( ((PPTCharPropSet*)aCharPropList.Last())->mnParagraph != nCurrentPara ) )
+ {
+ PPTCharPropSet* pCharPropSet = new PPTCharPropSet( *(PPTCharPropSet*)aCharPropList.Last(), nCurrentPara );
+ pCharPropSet->maString = String();
+ pCharPropSet->mnOriginalTextPos = nStringLen - 1;
+ aCharPropList.Insert( pCharPropSet, LIST_APPEND );
+ }
+ }
+ rIn.Seek( nMerk );
+}
+
+PPTStyleTextPropReader::~PPTStyleTextPropReader()
+{
+ void* pTmp;
+ for ( pTmp = aParaPropList.First(); pTmp; pTmp = aParaPropList.Next() )
+ delete (PPTParaPropSet*)pTmp;
+ for ( pTmp = aCharPropList.First(); pTmp; pTmp = aCharPropList.Next() )
+ delete (PPTCharPropSet*)pTmp;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+struct FieldEntry
+{
+ UINT32 nFieldType;
+ UINT32 nFieldStartPos;
+ UINT32 nFieldEndPos;
+ String aFieldUrl;
+
+ FieldEntry( UINT32 nType, UINT32 nStart, UINT32 nEnd )
+ {
+ nFieldType = nType;
+ nFieldStartPos = nStart;
+ nFieldEndPos = nEnd;
+ }
+ FieldEntry( FieldEntry& rFieldEntry )
+ {
+ nFieldType = rFieldEntry.nFieldType;
+ nFieldStartPos = rFieldEntry.nFieldStartPos;
+ nFieldEndPos = rFieldEntry.nFieldEndPos;
+ aFieldUrl = rFieldEntry.aFieldUrl;
+ }
+};
+
+
+PPTPortionObj::PPTPortionObj( const PPTStyleSheet& rStyleSheet, UINT32 nInstance, UINT32 nDepth ) :
+ PPTCharPropSet ( 0 ),
+ mrStyleSheet ( rStyleSheet ),
+ mnInstance ( nInstance ),
+ mnDepth ( ( nDepth > 4 ) ? 4 : nDepth )
+{
+}
+
+PPTPortionObj::PPTPortionObj( PPTCharPropSet& rCharPropSet, const PPTStyleSheet& rStyleSheet, UINT32 nInstance, UINT32 nDepth ) :
+ PPTCharPropSet ( rCharPropSet ),
+ mrStyleSheet ( rStyleSheet ),
+ mnInstance ( nInstance ),
+ mnDepth ( nDepth )
+{
+}
+
+PPTPortionObj::PPTPortionObj( PPTPortionObj& rPortionObj ) :
+ PPTCharPropSet ( rPortionObj ),
+ mrStyleSheet ( rPortionObj.mrStyleSheet ),
+ mnInstance ( rPortionObj.mnInstance ),
+ mnDepth ( rPortionObj.mnDepth )
+{
+}
+
+PPTPortionObj::~PPTPortionObj()
+{
+}
+
+BOOL PPTPortionObj::HasTabulator()
+{
+ BOOL bRetValue = FALSE;
+ sal_Int32 nCount;
+ const sal_Unicode* pPtr = maString.GetBuffer();
+ for ( nCount = 0; nCount < maString.Len(); nCount++ )
+ {
+ if ( pPtr[ nCount ] == 0x9 )
+ {
+ bRetValue = TRUE;
+ break;
+ }
+
+ }
+ return bRetValue;
+}
+
+BOOL PPTPortionObj::GetAttrib( UINT32 nAttr, UINT32& nRetValue, UINT32 nDestinationInstance )
+{
+ UINT32 nMask = 1 << nAttr;
+ nRetValue = 0;
+
+ UINT32 bIsHardAttribute = ( ( pCharSet->mnAttrSet & nMask ) != 0 ) ? 1 : 0;
+
+ if ( bIsHardAttribute )
+ {
+ switch ( nAttr )
+ {
+ case PPT_CharAttr_Bold :
+ case PPT_CharAttr_Italic :
+ case PPT_CharAttr_Underline :
+ case PPT_CharAttr_Shadow :
+ case PPT_CharAttr_Strikeout :
+ case PPT_CharAttr_Embossed :
+ nRetValue = ( pCharSet->mnFlags & nMask ) ? 1 : 0;
+ break;
+ case PPT_CharAttr_Font :
+ nRetValue = pCharSet->mnFont;
+ break;
+ case PPT_CharAttr_AsianOrComplexFont :
+ nRetValue = pCharSet->mnAsianOrComplexFont;
+ break;
+ case PPT_CharAttr_FontHeight :
+ nRetValue = pCharSet->mnFontHeight;
+ break;
+ case PPT_CharAttr_FontColor :
+ nRetValue = pCharSet->mnColor;
+ break;
+ case PPT_CharAttr_Escapement :
+ nRetValue = pCharSet->mnEscapement;
+ break;
+ default :
+ DBG_ERROR( "SJ:PPTPortionObj::GetAttrib ( hard attribute does not exist )" );
+ }
+ }
+ else
+ {
+ const PPTCharLevel& rCharLevel = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ mnDepth ];
+ PPTCharLevel* pCharLevel = NULL;
+ if ( ( nDestinationInstance == 0xffffffff )
+ || ( mnDepth && ( ( mnInstance == TSS_TYPE_SUBTITLE ) || ( mnInstance == TSS_TYPE_TEXT_IN_SHAPE ) ) ) )
+ bIsHardAttribute = 1;
+ else if ( nDestinationInstance != mnInstance )
+ pCharLevel = &mrStyleSheet.mpCharSheet[ nDestinationInstance ]->maCharLevel[ mnDepth ];
+ switch( nAttr )
+ {
+ case PPT_CharAttr_Bold :
+ case PPT_CharAttr_Italic :
+ case PPT_CharAttr_Underline :
+ case PPT_CharAttr_Shadow :
+ case PPT_CharAttr_Strikeout :
+ case PPT_CharAttr_Embossed :
+ {
+ nRetValue = ( rCharLevel.mnFlags & nMask ) ? 1 : 0;
+ if ( pCharLevel )
+ {
+ UINT32 nTmp = ( pCharLevel->mnFlags & nMask ) ? 1 : 0;
+ if ( nRetValue != nTmp )
+ bIsHardAttribute = 1;
+ }
+ }
+ break;
+ case PPT_CharAttr_Font :
+ {
+ nRetValue = rCharLevel.mnFont;
+ if ( pCharLevel && ( nRetValue != pCharLevel->mnFont ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_CharAttr_AsianOrComplexFont :
+ {
+ nRetValue = rCharLevel.mnAsianOrComplexFont;
+ if ( pCharLevel && ( nRetValue != pCharLevel->mnAsianOrComplexFont ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_CharAttr_FontHeight :
+ {
+ nRetValue = rCharLevel.mnFontHeight;
+ if ( pCharLevel && ( nRetValue != pCharLevel->mnFontHeight ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_CharAttr_FontColor :
+ {
+ nRetValue = rCharLevel.mnFontColor;
+ if ( pCharLevel && ( nRetValue != pCharLevel->mnFontColor ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_CharAttr_Escapement :
+ {
+ nRetValue = rCharLevel.mnEscapement;
+ if ( pCharLevel && ( nRetValue != pCharLevel->mnEscapement ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ default :
+ DBG_ERROR( "SJ:PPTPortionObj::GetAttrib ( attribute does not exist )" );
+ }
+ }
+ return (BOOL)bIsHardAttribute;
+}
+
+void PPTPortionObj::ApplyTo( SfxItemSet& rSet, SdrPowerPointImport& rManager, UINT32 nDestinationInstance )
+{
+ ApplyTo( rSet, rManager, nDestinationInstance, NULL );
+}
+
+void PPTPortionObj::ApplyTo( SfxItemSet& rSet, SdrPowerPointImport& rManager, UINT32 nDestinationInstance, const PPTTextObj* pTextObj )
+{
+ UINT32 nVal;
+ if ( GetAttrib( PPT_CharAttr_Bold, nVal, nDestinationInstance ) )
+ {
+ rSet.Put( SvxWeightItem( nVal != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
+ rSet.Put( SvxWeightItem( nVal != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT_CJK ) );
+ rSet.Put( SvxWeightItem( nVal != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT_CTL ) );
+ }
+ if ( GetAttrib( PPT_CharAttr_Italic, nVal, nDestinationInstance ) )
+ {
+ rSet.Put( SvxPostureItem( nVal != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
+ rSet.Put( SvxPostureItem( nVal != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC_CJK ) );
+ rSet.Put( SvxPostureItem( nVal != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC_CTL ) );
+ }
+ if ( GetAttrib( PPT_CharAttr_Underline, nVal, nDestinationInstance ) )
+ rSet.Put( SvxUnderlineItem( nVal != 0 ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
+
+ if ( GetAttrib( PPT_CharAttr_Shadow, nVal, nDestinationInstance ) )
+ rSet.Put( SvxShadowedItem( nVal != 0, EE_CHAR_SHADOW ) );
+
+ if ( GetAttrib( PPT_CharAttr_Strikeout, nVal, nDestinationInstance ) )
+ rSet.Put( SvxCrossedOutItem( nVal != 0 ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) );
+
+ sal_uInt32 nAsianFontId = 0xffff;
+ if ( GetAttrib( PPT_CharAttr_AsianOrComplexFont, nAsianFontId, nDestinationInstance ) )
+ {
+ if ( nAsianFontId != 0xffff )
+ {
+ PptFontEntityAtom* pFontEnityAtom = rManager.GetFontEnityAtom( nAsianFontId );
+ if ( pFontEnityAtom )
+ {
+ rSet.Put( SvxFontItem( pFontEnityAtom->eFamily, pFontEnityAtom->aName,
+ String(), pFontEnityAtom->ePitch, pFontEnityAtom->eCharSet, EE_CHAR_FONTINFO_CJK ) );
+ rSet.Put( SvxFontItem( pFontEnityAtom->eFamily, pFontEnityAtom->aName,
+ String(), pFontEnityAtom->ePitch, pFontEnityAtom->eCharSet, EE_CHAR_FONTINFO_CTL ) );
+ }
+ }
+ }
+ if ( GetAttrib( PPT_CharAttr_Font, nVal, nDestinationInstance ) )
+ {
+ PptFontEntityAtom* pFontEnityAtom = rManager.GetFontEnityAtom( nVal );
+ if ( pFontEnityAtom )
+ rSet.Put( SvxFontItem( pFontEnityAtom->eFamily, pFontEnityAtom->aName, String(), pFontEnityAtom->ePitch, pFontEnityAtom->eCharSet, EE_CHAR_FONTINFO ) );
+ }
+ if ( GetAttrib( PPT_CharAttr_FontHeight, nVal, nDestinationInstance ) ) // Schriftgrad in Point
+ {
+ sal_uInt32 nHeight = rManager.ScalePoint( nVal );
+ rSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
+ rSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ rSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+ }
+
+ if ( GetAttrib( PPT_CharAttr_Embossed, nVal, nDestinationInstance ) )
+ rSet.Put( SvxCharReliefItem( nVal != 0 ? RELIEF_EMBOSSED : RELIEF_NONE, EE_CHAR_RELIEF ) );
+ if ( nVal ) /* if Embossed is set, the font color depends to the fillstyle/color of the object,
+ if the object has no fillstyle, the font color depends to fillstyle of the background */
+ {
+ Color aDefColor( COL_BLACK );
+ MSO_FillType eFillType = mso_fillSolid;
+ if ( rManager.GetPropertyValue( DFF_Prop_fNoFillHitTest ) & 0x10 )
+ eFillType = (MSO_FillType)rManager.GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
+ else
+ eFillType = mso_fillBackground;
+ switch( eFillType )
+ {
+ case mso_fillShade :
+ case mso_fillShadeCenter :
+ case mso_fillShadeShape :
+ case mso_fillShadeScale :
+ case mso_fillShadeTitle :
+ case mso_fillSolid :
+ aDefColor = rManager.MSO_CLR_ToColor( rManager.GetPropertyValue( DFF_Prop_fillColor ) );
+ break;
+ case mso_fillPattern :
+ aDefColor = rManager.MSO_CLR_ToColor( rManager.GetPropertyValue( DFF_Prop_fillBackColor ) );
+ break;
+ case mso_fillTexture :
+ {
+ Graphic aGraf;
+ if ( rManager.GetBLIP( rManager.GetPropertyValue( DFF_Prop_fillBlip ), aGraf, NULL ) )
+ {
+ Bitmap aBmp( aGraf.GetBitmap() );
+ Size aSize( aBmp.GetSizePixel() );
+ if ( aSize.Width() && aSize.Height() )
+ {
+ if ( aSize.Width () > 64 )
+ aSize.Width () = 64;
+ if ( aSize.Height() > 64 )
+ aSize.Height() = 64;
+
+ ULONG nRt = 0, nGn = 0, nBl = 0;
+ BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ if( pAcc )
+ {
+ const long nWidth = aSize.Width();
+ const long nHeight = aSize.Height();
+
+ if( pAcc->HasPalette() )
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ const BitmapColor& rCol = pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( nY, nX ) );
+ nRt+=rCol.GetRed(); nGn+=rCol.GetGreen(); nBl+=rCol.GetBlue();
+ }
+ }
+ }
+ else
+ {
+ for( long nY = 0L; nY < nHeight; nY++ )
+ {
+ for( long nX = 0L; nX < nWidth; nX++ )
+ {
+ const BitmapColor aCol( pAcc->GetPixel( nY, nX ) );
+ nRt+=aCol.GetRed(); nGn+=aCol.GetGreen(); nBl+=aCol.GetBlue();
+ }
+ }
+ }
+ aBmp.ReleaseAccess( pAcc );
+ sal_uInt32 nC = ( aSize.Width() * aSize.Height() );
+ nRt /= nC;
+ nGn /= nC;
+ nBl /= nC;
+ aDefColor = Color(sal_uInt8( nRt ), sal_uInt8( nGn ),sal_uInt8( nBl ) );
+ }
+ }
+ }
+ }
+ break;
+ case mso_fillBackground :
+ {
+ if ( pTextObj ) // the textobject is needed
+ {
+ const SfxItemSet* pItemSet = pTextObj->GetBackground();
+ if ( pItemSet )
+ {
+ const SfxPoolItem* pFillStyleItem = NULL;
+ pItemSet->GetItemState( XATTR_FILLSTYLE, FALSE, &pFillStyleItem );
+ if ( pFillStyleItem )
+ {
+ XFillStyle eFillStyle = ((XFillStyleItem*)pFillStyleItem)->GetValue();
+ switch( eFillStyle )
+ {
+ case XFILL_SOLID :
+ {
+ const SfxPoolItem* pFillColorItem = NULL;
+ pItemSet->GetItemState( XATTR_FILLCOLOR, FALSE, &pFillColorItem );
+ if ( pFillColorItem )
+ aDefColor = ((XColorItem*)pFillColorItem)->GetColorValue();
+ }
+ break;
+ case XFILL_GRADIENT :
+ {
+ const SfxPoolItem* pGradientItem = NULL;
+ pItemSet->GetItemState( XATTR_FILLGRADIENT, FALSE, &pGradientItem );
+ if ( pGradientItem )
+ aDefColor = ((XFillGradientItem*)pGradientItem)->GetGradientValue().GetStartColor();
+ }
+ break;
+ case XFILL_HATCH :
+ case XFILL_BITMAP :
+ aDefColor = Color( COL_WHITE );
+ break;
+ default: break;
+ }
+ }
+ }
+ }
+ }
+ break;
+// case mso_fillPicture :
+ default: break;
+ }
+ rSet.Put( SvxColorItem( aDefColor, EE_CHAR_COLOR ) );
+ }
+ else
+ {
+ if ( GetAttrib( PPT_CharAttr_FontColor, nVal, nDestinationInstance ) ) // Textfarbe (4Byte-Arg)
+ {
+ Color aCol( rManager.MSO_TEXT_CLR_ToColor( nVal ) );
+ rSet.Put( SvxColorItem( aCol, EE_CHAR_COLOR ) );
+ if ( nDestinationInstance == 0xffffffff )
+ mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ mnDepth ].mnFontColorInStyleSheet = aCol;
+ }
+ else if ( nVal & 0x0f000000 ) // this is not a hard attribute, but maybe the page has a different colerscheme,
+ { // so that in this case we must use a hard color attribute
+ Color aCol( rManager.MSO_TEXT_CLR_ToColor( nVal ) );
+ Color& aColorInSheet = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ mnDepth ].mnFontColorInStyleSheet;
+ if ( aColorInSheet != aCol )
+ rSet.Put( SvxColorItem( aCol, EE_CHAR_COLOR ) );
+ }
+ }
+
+ if ( GetAttrib( PPT_CharAttr_Escapement, nVal, nDestinationInstance ) ) // Hoch/Tiefstellung in %
+ {
+ sal_uInt16 nEsc = 0;
+ sal_uInt8 nProp = 100;
+
+ if ( nVal )
+ {
+ nEsc = (sal_Int16)nVal;
+ nProp = DFLT_ESC_PROP;
+ }
+ SvxEscapementItem aItem( nEsc, nProp, EE_CHAR_ESCAPEMENT );
+ rSet.Put( aItem );
+ }
+ if ( mnLanguage[ 0 ] )
+ rSet.Put( SvxLanguageItem( mnLanguage[ 0 ], EE_CHAR_LANGUAGE ) );
+ if ( mnLanguage[ 1 ] )
+ rSet.Put( SvxLanguageItem( mnLanguage[ 1 ], EE_CHAR_LANGUAGE_CJK ) );
+ if ( mnLanguage[ 2 ] )
+ rSet.Put( SvxLanguageItem( mnLanguage[ 2 ], EE_CHAR_LANGUAGE_CTL ) );
+}
+
+SvxFieldItem* PPTPortionObj::GetTextField()
+{
+ if ( mpFieldItem )
+ return new SvxFieldItem( *mpFieldItem );
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+PPTParagraphObj::PPTParagraphObj( const PPTStyleSheet& rStyleSheet, UINT32 nInstance, UINT16 nDepth ) :
+ PPTNumberFormatCreator ( NULL ),
+ mrStyleSheet ( rStyleSheet ),
+ mnInstance ( nInstance ),
+ mbTab ( TRUE ), // style sheets always have to get the right tabulator setting
+ mnPortionCount ( 0 ),
+ mpPortionList ( NULL )
+{
+ if ( nDepth > 4 )
+ nDepth = 4;
+ pParaSet->mnDepth = nDepth;
+}
+
+PPTParagraphObj::PPTParagraphObj( PPTStyleTextPropReader& rPropReader, const PPTStyleSheet& rStyleSheet,
+ UINT32 nInstance, PPTTextRulerInterpreter& rRuler ) :
+ PPTParaPropSet ( *( (PPTParaPropSet*)rPropReader.aParaPropList.GetCurObject() ) ),
+ PPTNumberFormatCreator ( NULL ),
+ PPTTextRulerInterpreter ( rRuler ),
+ mrStyleSheet ( rStyleSheet ),
+ mnInstance ( nInstance ),
+ mbTab ( FALSE ),
+ mnCurrentObject ( 0 ),
+ mnPortionCount ( 0 ),
+ mpPortionList ( NULL )
+{
+ sal_uInt32 nCurPos = rPropReader.aCharPropList.GetCurPos();
+ PPTCharPropSet* pCharPropSet = (PPTCharPropSet*)rPropReader.aCharPropList.GetCurObject();
+ if ( pCharPropSet )
+ {
+ sal_uInt32 nCurrentParagraph = pCharPropSet->mnParagraph;
+ for ( ; pCharPropSet && ( pCharPropSet->mnParagraph == nCurrentParagraph ); pCharPropSet = (PPTCharPropSet*)rPropReader.aCharPropList.Next() )
+ mnPortionCount++; // counting number of portions that are part of this paragraph
+ pCharPropSet = (PPTCharPropSet*)rPropReader.aCharPropList.Seek( nCurPos );
+
+ mpPortionList = new PPTPortionObj*[ mnPortionCount ];
+ for ( UINT32 i = 0; i < mnPortionCount; i++ )
+ {
+ if ( pCharPropSet )
+ {
+ PPTPortionObj* pPPTPortion = new PPTPortionObj( *pCharPropSet, rStyleSheet, nInstance, pParaSet->mnDepth );
+ mpPortionList[ i ] = pPPTPortion;
+ if ( !mbTab )
+ mbTab = mpPortionList[ i ]->HasTabulator();
+ }
+ else
+ {
+ DBG_ERROR( "SJ:PPTParagraphObj::It seems that there are missing some textportions" );
+ mpPortionList[ i ] = NULL;
+ }
+ pCharPropSet = (PPTCharPropSet*)rPropReader.aCharPropList.Next();
+ }
+ }
+}
+
+PPTParagraphObj::~PPTParagraphObj()
+{
+ ImplClear();
+}
+
+void PPTParagraphObj::AppendPortion( PPTPortionObj& rPPTPortion )
+{
+ UINT32 i;
+ PPTPortionObj** mpOldPortionList = mpPortionList;
+ mpPortionList = new PPTPortionObj*[ ++mnPortionCount ];
+ for ( i = 0; i < mnPortionCount - 1; i++ )
+ mpPortionList[ i ] = mpOldPortionList[ i ];
+ delete[] mpOldPortionList;
+ mpPortionList[ mnPortionCount - 1 ] = new PPTPortionObj( rPPTPortion );
+ if ( !mbTab )
+ mbTab = mpPortionList[ mnPortionCount - 1 ]->HasTabulator();
+}
+
+void PPTParagraphObj::UpdateBulletRelSize( sal_uInt32& nBulletRelSize ) const
+{
+ if ( nBulletRelSize > 0x7fff ) // a negative value is the absolute bullet height
+ {
+ sal_uInt16 nFontHeight = 0;
+ if ( mpPortionList )
+ {
+ PPTPortionObj* pPortion = mpPortionList[ 0 ];
+ if ( pPortion && ( pPortion->pCharSet->mnAttrSet & ( 1 << PPT_CharAttr_FontHeight ) ) )
+ nFontHeight = pPortion->pCharSet->mnFontHeight;
+ }
+ // if we do not have a hard attributed fontheight, the fontheight is taken from the style
+ if ( !nFontHeight )
+ nFontHeight = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ pParaSet->mnDepth ].mnFontHeight;
+ nBulletRelSize = nFontHeight ? ((-((sal_Int16)nBulletRelSize)) * 100 ) / nFontHeight : 100;
+ }
+}
+
+BOOL PPTParagraphObj::GetAttrib( UINT32 nAttr, UINT32& nRetValue, UINT32 nDestinationInstance )
+{
+ UINT32 nMask = 1 << nAttr;
+ nRetValue = 0;
+
+ if ( nAttr > 21 )
+ {
+ DBG_ERROR( "SJ:PPTParagraphObj::GetAttrib - attribute does not exist" );
+ return FALSE;
+ }
+
+ UINT32 bIsHardAttribute = ( ( pParaSet->mnAttrSet & nMask ) != 0 ) ? 1 : 0;
+
+ if ( bIsHardAttribute )
+ {
+ if ( nAttr == PPT_ParaAttr_BulletColor )
+ {
+ sal_Bool bHardBulletColor;
+ if ( pParaSet->mnAttrSet & ( 1 << PPT_ParaAttr_BuHardColor ) )
+ bHardBulletColor = pParaSet->mpArry[ PPT_ParaAttr_BuHardColor ] != 0;
+ else
+ bHardBulletColor = ( mrStyleSheet.mpParaSheet[ mnInstance ]->maParaLevel[ pParaSet->mnDepth ].mnBuFlags
+ & ( 1 << PPT_ParaAttr_BuHardColor ) ) != 0;
+ if ( bHardBulletColor )
+ nRetValue = pParaSet->mnBulletColor;
+ else
+ {
+ nRetValue = PPT_COLSCHEME_TEXT_UND_ZEILEN;
+ if ( ( nDestinationInstance != 0xffffffff ) && mnPortionCount )
+ {
+ PPTPortionObj* pPortion = mpPortionList[ 0 ];
+ if ( pPortion )
+ {
+ if ( pPortion->pCharSet->mnAttrSet & ( 1 << PPT_CharAttr_FontColor ) )
+ nRetValue = pPortion->pCharSet->mnColor;
+ else
+ nRetValue = mrStyleSheet.mpCharSheet[ nDestinationInstance ]->maCharLevel[ pParaSet->mnDepth ].mnFontColor;
+ }
+ }
+ }
+ }
+ else if ( nAttr == PPT_ParaAttr_BulletFont )
+ {
+ sal_Bool bHardBuFont;
+ if ( pParaSet->mnAttrSet & ( 1 << PPT_ParaAttr_BuHardFont ) )
+ bHardBuFont = pParaSet->mpArry[ PPT_ParaAttr_BuHardFont ] != 0;
+ else
+ bHardBuFont = ( mrStyleSheet.mpParaSheet[ mnInstance ]->maParaLevel[ pParaSet->mnDepth ].mnBuFlags
+ & ( 1 << PPT_ParaAttr_BuHardFont ) ) != 0;
+ if ( bHardBuFont )
+ nRetValue = pParaSet->mpArry[ PPT_ParaAttr_BulletFont ];
+ else
+ {
+ // it is the font used which assigned to the first character of the following text
+ nRetValue = 0;
+ if ( ( nDestinationInstance != 0xffffffff ) && mnPortionCount )
+ {
+ PPTPortionObj* pPortion = mpPortionList[ 0 ];
+ if ( pPortion )
+ {
+ if ( pPortion->pCharSet->mnAttrSet & ( 1 << PPT_CharAttr_Font ) )
+ nRetValue = pPortion->pCharSet->mnFont;
+ else
+ nRetValue = mrStyleSheet.mpCharSheet[ nDestinationInstance ]->maCharLevel[ pParaSet->mnDepth ].mnFont;
+ }
+ }
+ }
+ }
+ else
+ nRetValue = pParaSet->mpArry[ nAttr ];
+ }
+ else
+ {
+ const PPTParaLevel& rParaLevel = mrStyleSheet.mpParaSheet[ mnInstance ]->maParaLevel[ pParaSet->mnDepth ];
+
+ PPTParaLevel* pParaLevel = NULL;
+ if ( ( nDestinationInstance == 0xffffffff )
+ || ( pParaSet->mnDepth && ( ( mnInstance == TSS_TYPE_SUBTITLE ) || ( mnInstance == TSS_TYPE_TEXT_IN_SHAPE ) ) ) )
+ bIsHardAttribute = 1;
+ else if ( nDestinationInstance != mnInstance )
+ pParaLevel = &mrStyleSheet.mpParaSheet[ nDestinationInstance ]->maParaLevel[ pParaSet->mnDepth ];
+ switch ( nAttr )
+ {
+ case PPT_ParaAttr_BulletOn :
+ {
+ nRetValue = rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BulletOn );
+ if ( pParaLevel )
+ {
+ if ( nRetValue != ( (sal_uInt32)pParaLevel->mnBuFlags & ( 1 << PPT_ParaAttr_BulletOn ) ) )
+ bIsHardAttribute = 1;
+ }
+ }
+ break;
+ case PPT_ParaAttr_BuHardFont :
+ case PPT_ParaAttr_BuHardColor :
+ case PPT_ParaAttr_BuHardHeight :
+ DBG_ERROR( "SJ:PPTParagraphObj::GetAttrib - this attribute does not make sense" );
+ break;
+ case PPT_ParaAttr_BulletChar :
+ {
+ nRetValue = rParaLevel.mnBulletChar;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnBulletChar ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_BulletFont :
+ {
+ sal_Bool bHardBuFont;
+ if ( pParaSet->mnAttrSet & ( 1 << PPT_ParaAttr_BuHardFont ) )
+ bHardBuFont = pParaSet->mpArry[ PPT_ParaAttr_BuHardFont ] != 0;
+ else
+ bHardBuFont = ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BuHardFont ) ) != 0;
+ if ( bHardBuFont )
+ {
+ nRetValue = rParaLevel.mnBulletFont;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnBulletFont ) )
+ bIsHardAttribute = 1;
+ }
+ else
+ {
+ if ( mnPortionCount )
+ {
+ PPTPortionObj* pPortion = mpPortionList[ 0 ];
+ if ( pPortion )
+ bIsHardAttribute = pPortion->GetAttrib( PPT_CharAttr_Font, nRetValue, nDestinationInstance );
+ }
+ else
+ {
+ nRetValue = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ pParaSet->mnDepth ].mnFont;
+ bIsHardAttribute = 1;
+ }
+ }
+ }
+ break;
+ case PPT_ParaAttr_BulletHeight :
+ {
+ nRetValue = rParaLevel.mnBulletHeight;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnBulletHeight ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_BulletColor :
+ {
+ sal_Bool bHardBulletColor;
+ if ( pParaSet->mnAttrSet & ( 1 << PPT_ParaAttr_BuHardColor ) )
+ bHardBulletColor = pParaSet->mpArry[ PPT_ParaAttr_BuHardColor ] != 0;
+ else
+ bHardBulletColor = ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BuHardColor ) ) != 0;
+ if ( bHardBulletColor )
+ {
+ nRetValue = rParaLevel.mnBulletColor;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnBulletColor ) )
+ bIsHardAttribute = 1;
+ }
+ else
+ {
+ if ( mnPortionCount )
+ {
+ PPTPortionObj* pPortion = mpPortionList[ 0 ];
+ if ( pPortion )
+ bIsHardAttribute = pPortion->GetAttrib( PPT_CharAttr_FontColor, nRetValue, nDestinationInstance );
+ }
+ else
+ {
+ nRetValue = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ pParaSet->mnDepth ].mnFontColor;
+ bIsHardAttribute = 1;
+ }
+ }
+ }
+ break;
+ case PPT_ParaAttr_Adjust :
+ {
+ nRetValue = rParaLevel.mnAdjust;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnAdjust ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_LineFeed :
+ {
+ nRetValue = rParaLevel.mnLineFeed;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnLineFeed ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_UpperDist :
+ {
+ nRetValue = rParaLevel.mnUpperDist;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnUpperDist ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_LowerDist :
+ {
+ nRetValue = rParaLevel.mnLowerDist;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnLowerDist ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_TextOfs :
+ {
+ nRetValue = rParaLevel.mnTextOfs;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnTextOfs ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_BulletOfs :
+ {
+ nRetValue = rParaLevel.mnBulletOfs;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnBulletOfs ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_DefaultTab :
+ {
+ nRetValue = rParaLevel.mnDefaultTab;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnBulletOfs ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_AsianLB_1 :
+ {
+ nRetValue = rParaLevel.mnAsianLineBreak & 1;
+ if ( pParaLevel && ( nRetValue != ( (sal_uInt32)pParaLevel->mnAsianLineBreak & 1 ) ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_AsianLB_2 :
+ {
+ nRetValue = ( rParaLevel.mnAsianLineBreak >> 1 ) & 1;
+ if ( pParaLevel && ( nRetValue != ( ( (sal_uInt32)pParaLevel->mnAsianLineBreak >> 1 ) & 1 ) ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_AsianLB_3 :
+ {
+ nRetValue = ( rParaLevel.mnAsianLineBreak >> 2 ) & 1;
+ if ( pParaLevel && ( nRetValue != ( ( (sal_uInt32)pParaLevel->mnAsianLineBreak >> 2 ) & 1 ) ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ case PPT_ParaAttr_BiDi :
+ {
+ nRetValue = rParaLevel.mnBiDi;
+ if ( pParaLevel && ( nRetValue != pParaLevel->mnBiDi ) )
+ bIsHardAttribute = 1;
+ }
+ break;
+ }
+ }
+ return (BOOL)bIsHardAttribute;
+}
+
+void PPTParagraphObj::ApplyTo( SfxItemSet& rSet, boost::optional< sal_Int16 >& rStartNumbering, SdrPowerPointImport& rManager, sal_uInt32 nDestinationInstance, const PPTParagraphObj* /*pPrev*/)
+{
+ INT16 nVal2;
+ UINT32 nVal, nUpperDist, nLowerDist;
+ UINT32 nInstance = nDestinationInstance != 0xffffffff ? nDestinationInstance : mnInstance;
+
+ if ( ( nDestinationInstance != 0xffffffff ) || ( pParaSet->mnDepth <= 1 ) )
+ {
+ SvxNumBulletItem* pNumBulletItem = mrStyleSheet.mpNumBulletItem[ nInstance ];
+ if ( pNumBulletItem )
+ {
+ SvxNumberFormat aNumberFormat( SVX_NUM_NUMBER_NONE );
+ if ( GetNumberFormat( rManager, aNumberFormat, this, nDestinationInstance, rStartNumbering ) )
+ {
+ if ( aNumberFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE )
+ {
+ aNumberFormat.SetLSpace( 0 );
+ aNumberFormat.SetAbsLSpace( 0 );
+ aNumberFormat.SetFirstLineOffset( 0 );
+ aNumberFormat.SetCharTextDistance( 0 );
+ aNumberFormat.SetFirstLineIndent( 0 );
+ aNumberFormat.SetIndentAt( 0 );
+ }
+ SvxNumBulletItem aNewNumBulletItem( *pNumBulletItem );
+ SvxNumRule* pRule = aNewNumBulletItem.GetNumRule();
+ if ( pRule )
+ {
+ pRule->SetLevel( pParaSet->mnDepth, aNumberFormat );
+ sal_uInt16 i, n;
+ for ( i = 0; i < pRule->GetLevelCount(); i++ )
+ {
+ if ( i != pParaSet->mnDepth )
+ {
+ n = i > 4 ? 4 : i;
+
+ SvxNumberFormat aNumberFormat2( pRule->GetLevel( i ) );
+ const PPTParaLevel& rParaLevel = mrStyleSheet.mpParaSheet[ nInstance ]->maParaLevel[ n ];
+ const PPTCharLevel& rCharLevel = mrStyleSheet.mpCharSheet[ nInstance ]->maCharLevel[ n ];
+ sal_uInt32 nColor;
+ if ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BuHardColor ) )
+ nColor = rParaLevel.mnBulletColor;
+ else
+ nColor = rCharLevel.mnFontColor;
+ aNumberFormat2.SetBulletColor( rManager.MSO_TEXT_CLR_ToColor( nColor ) );
+ pRule->SetLevel( i, aNumberFormat2 );
+ }
+ }
+ rSet.Put( aNewNumBulletItem );
+ }
+ }
+ }
+ }
+
+ UINT32 nIsBullet2, _nTextOfs, _nBulletOfs, nHardAttribute = 0;
+ GetAttrib( PPT_ParaAttr_BulletOn, nIsBullet2, nDestinationInstance );
+ nHardAttribute += GetAttrib( PPT_ParaAttr_TextOfs, _nTextOfs, nDestinationInstance );
+ nHardAttribute += GetAttrib( PPT_ParaAttr_BulletOfs, _nBulletOfs, nDestinationInstance );
+ if ( !nIsBullet2 )
+ {
+ SvxLRSpaceItem aLRSpaceItem( EE_PARA_LRSPACE );
+ UINT16 nAbsLSpace = (UINT16)( ( (UINT32)_nTextOfs * 2540 ) / 576 );
+ UINT16 nFirstLineOffset = nAbsLSpace - (UINT16)( ( (UINT32)_nBulletOfs * 2540 ) / 576 );
+ aLRSpaceItem.SetLeft( nAbsLSpace );
+ aLRSpaceItem.SetTxtFirstLineOfstValue( -nFirstLineOffset );
+ rSet.Put( aLRSpaceItem );
+ }
+ else
+ {
+ SvxLRSpaceItem aLRSpaceItem( EE_PARA_LRSPACE );
+ aLRSpaceItem.SetLeft( 0 );
+ aLRSpaceItem.SetTxtFirstLineOfstValue( 0 );
+ rSet.Put( aLRSpaceItem );
+ }
+ if ( GetAttrib( PPT_ParaAttr_Adjust, nVal, nDestinationInstance ) )
+ {
+ if ( nVal <= 3 )
+ { // Absatzausrichtung
+ static SvxAdjust __READONLY_DATA aAdj[ 4 ] = { SVX_ADJUST_LEFT, SVX_ADJUST_CENTER, SVX_ADJUST_RIGHT, SVX_ADJUST_BLOCK };
+ rSet.Put( SvxAdjustItem( aAdj[ nVal ], EE_PARA_JUST ) );
+ }
+ }
+
+ if ( GetAttrib( PPT_ParaAttr_AsianLB_1, nVal, nDestinationInstance ) )
+ rSet.Put( SfxBoolItem( EE_PARA_FORBIDDENRULES, nVal != 0 ) );
+ if ( GetAttrib( PPT_ParaAttr_AsianLB_3, nVal, nDestinationInstance ) )
+ rSet.Put( SfxBoolItem( EE_PARA_HANGINGPUNCTUATION, nVal != 0 ) );
+
+ if ( GetAttrib( PPT_ParaAttr_BiDi, nVal, nDestinationInstance ) )
+ rSet.Put( SvxFrameDirectionItem( nVal == 1 ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR ) );
+
+ // LineSpacing
+ PPTPortionObj* pPortion = First();
+ BOOL bIsHardAttribute = GetAttrib( PPT_ParaAttr_LineFeed, nVal, nDestinationInstance );
+ nVal2 = (INT16)nVal;
+ sal_uInt32 nFont = sal_uInt32();
+ if ( pPortion && pPortion->GetAttrib( PPT_CharAttr_Font, nFont, nDestinationInstance ) )
+ bIsHardAttribute = TRUE;
+
+ if ( bIsHardAttribute )
+ {
+ if ( pPortion && ( nVal2 > 200 ) )
+ {
+ UINT32 nFontHeight;
+ pPortion->GetAttrib( PPT_CharAttr_FontHeight, nFontHeight, nDestinationInstance );
+ nVal2 = -(sal_Int16)( ( nFontHeight * nVal * 8 ) / 100 );
+ }
+ rSet.Put( SdrTextFixedCellHeightItem( TRUE ), SDRATTR_TEXT_USEFIXEDCELLHEIGHT );
+ SvxLineSpacingItem aItem( 200, EE_PARA_SBL );
+ if ( nVal2 <= 0 )
+ aItem.SetLineHeight( (UINT16)( rManager.ScalePoint( -nVal2 ) / 8 ) );
+ else
+ {
+ sal_uInt8 nPropLineSpace = (BYTE)nVal2;
+ aItem.SetPropLineSpace( nPropLineSpace );
+ aItem.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
+ }
+ rSet.Put( aItem );
+ }
+
+ // Paragraph Spacing
+ UINT32 nFontHeight = 0;
+ bIsHardAttribute = ( (UINT32)GetAttrib( PPT_ParaAttr_UpperDist, nUpperDist, nDestinationInstance ) +
+ (UINT32)GetAttrib( PPT_ParaAttr_LowerDist, nLowerDist, nDestinationInstance ) ) != 0;
+ if ( ( nUpperDist > 0 ) || ( nLowerDist > 0 ) )
+ {
+ if ( mnPortionCount )
+ {
+ mpPortionList[ mnPortionCount - 1 ]->GetAttrib( PPT_CharAttr_FontHeight, nFontHeight, nDestinationInstance );
+ if ( ((INT16)nUpperDist) > 0 )
+ nUpperDist = - (sal_Int16)( ( nFontHeight * nUpperDist * 100 ) / 1000 );
+ if ( ((INT16)nLowerDist) > 0 )
+ nLowerDist = - (sal_Int16)( ( nFontHeight * nLowerDist * 100 ) / 1000 );
+ }
+ bIsHardAttribute = TRUE;
+ }
+ if ( bIsHardAttribute )
+ {
+ SvxULSpaceItem aULSpaceItem( EE_PARA_ULSPACE );
+ nVal2 = (INT16)nUpperDist;
+ if ( nVal2 <= 0 )
+ aULSpaceItem.SetUpper( (UINT16)(((UINT32) - nVal2 * 2540 ) / ( 72 * 8 ) ) );
+ else
+ {
+ aULSpaceItem.SetUpperValue( 0 );
+ aULSpaceItem.SetPropUpper( (UINT16)nUpperDist == 100 ? 101 : (UINT16)nUpperDist );
+ }
+ nVal2 = (INT16)nLowerDist;
+ if ( nVal2 <= 0 )
+ aULSpaceItem.SetLower( (UINT16)(((UINT32) - nVal2 * 2540 ) / ( 72 * 8 ) ) );
+ else
+ {
+ aULSpaceItem.SetLowerValue( 0 );
+ aULSpaceItem.SetPropLower( (UINT16)nLowerDist == 100 ? 101 : (UINT16)nLowerDist );
+ }
+ rSet.Put( aULSpaceItem );
+ }
+
+ if ( mbTab ) // makes it sense to apply tabsettings
+ {
+ UINT32 i, nDefaultTab, nTab, nTextOfs2 = 0;
+ UINT32 nLatestManTab = 0;
+ GetAttrib( PPT_ParaAttr_TextOfs, nTextOfs2, nDestinationInstance );
+ GetAttrib( PPT_ParaAttr_BulletOfs, nTab, nDestinationInstance );
+ GetAttrib( PPT_ParaAttr_BulletOn, i, nDestinationInstance );
+ GetAttrib( PPT_ParaAttr_DefaultTab, nDefaultTab, nDestinationInstance );
+ SvxTabStopItem aTabItem( 0, 0, SVX_TAB_ADJUST_DEFAULT, EE_PARA_TABS );
+ if ( GetTabCount() )
+ {
+ for ( i = 0; i < GetTabCount(); i++ )
+ {
+ SvxTabAdjust eTabAdjust;
+ nTab = GetTabOffsetByIndex( (sal_uInt16)i );
+ switch( GetTabStyleByIndex( (sal_uInt16)i ) )
+ {
+ case 1 : eTabAdjust = SVX_TAB_ADJUST_CENTER; break;
+ case 2 : eTabAdjust = SVX_TAB_ADJUST_RIGHT; break;
+ case 3 : eTabAdjust = SVX_TAB_ADJUST_DECIMAL; break;
+ default : eTabAdjust = SVX_TAB_ADJUST_LEFT;
+ }
+ if ( nTab > nTextOfs2 )
+ aTabItem.Insert( SvxTabStop( (UINT16)( ( ( nTab - nTextOfs2 ) * 2540 ) / 576 ), eTabAdjust ) );
+ }
+ nLatestManTab = nTab;
+ }
+ if ( nIsBullet2 == 0 )
+ aTabItem.Insert( SvxTabStop( (sal_uInt16)0 ) );
+ if ( nDefaultTab )
+ {
+ nTab = ( nTextOfs2 > nLatestManTab ) ? nTextOfs2 : nLatestManTab;
+ nTab /= nDefaultTab;
+ nTab = nDefaultTab * ( 1 + nTab );
+ for ( i = 0; ( i < 20 ) && ( nTab < 0x1b00 ); i++ )
+ {
+ aTabItem.Insert( SvxTabStop( (UINT16)( ( ( nTab - nTextOfs2 ) * 2540 ) / 576 ) ) );
+ nTab += nDefaultTab;
+ }
+ }
+ rSet.Put( aTabItem );
+ }
+}
+
+UINT32 PPTParagraphObj::GetTextSize()
+{
+ UINT32 nCount, nRetValue = 0;
+ for ( UINT32 i = 0; i < mnPortionCount; i++ )
+ {
+ PPTPortionObj* pPortionObj = mpPortionList[ i ];
+ nCount = pPortionObj->Count();
+ if ( ( !nCount ) && pPortionObj->mpFieldItem )
+ nCount++;
+ nRetValue += nCount;
+ }
+ return nRetValue;
+}
+
+PPTPortionObj* PPTParagraphObj::First()
+{
+ mnCurrentObject = 0;
+ if ( !mnPortionCount )
+ return NULL;
+ return mpPortionList[ 0 ];
+}
+
+PPTPortionObj* PPTParagraphObj::Next()
+{
+ UINT32 i = mnCurrentObject + 1;
+ if ( i >= mnPortionCount )
+ return NULL;
+ mnCurrentObject++;
+ return mpPortionList[ i ];
+}
+
+void PPTParagraphObj::ImplClear()
+{
+ for ( void* pPtr = First(); pPtr; pPtr = Next() )
+ delete (PPTPortionObj*)pPtr;
+ delete[] mpPortionList;
+}
+
+PPTFieldEntry::~PPTFieldEntry()
+{
+ delete pField1;
+ delete pField2;
+ delete pString;
+};
+
+void PPTFieldEntry::GetDateTime( const sal_uInt32 nVal, SvxDateFormat& eDateFormat, SvxTimeFormat& eTimeFormat )
+{
+ eDateFormat = SVXDATEFORMAT_APPDEFAULT;
+ eTimeFormat = SVXTIMEFORMAT_APPDEFAULT;
+ // ID auswerten
+ switch( nVal )
+ {
+ case 0:
+ case 6:
+ eDateFormat = SVXDATEFORMAT_A;
+ break;
+ case 1:
+ eDateFormat = SVXDATEFORMAT_F;
+ break;
+ case 2:
+ case 3:
+ eDateFormat = SVXDATEFORMAT_D;
+ break;
+ case 4:
+ case 5:
+ eDateFormat = SVXDATEFORMAT_C;
+ break;
+ case 7:
+ eDateFormat = SVXDATEFORMAT_A;
+ case 9:
+ eTimeFormat = SVXTIMEFORMAT_24_HM;
+ break;
+ case 8:
+ eDateFormat = SVXDATEFORMAT_A;
+ case 11:
+ eTimeFormat = SVXTIMEFORMAT_12_HM;
+ break;
+ case 10:
+ eTimeFormat = SVXTIMEFORMAT_24_HMS;
+ break;
+ case 12:
+ eTimeFormat = SVXTIMEFORMAT_12_HMS;
+ break;
+ }
+}
+
+void PPTFieldEntry::SetDateTime( UINT32 nVal )
+{
+ SvxDateFormat eDateFormat;
+ SvxTimeFormat eTimeFormat;
+ GetDateTime( nVal, eDateFormat, eTimeFormat );
+ if ( eDateFormat != SVXDATEFORMAT_APPDEFAULT )
+ pField1 = new SvxFieldItem( SvxDateField( Date(), SVXDATETYPE_VAR, eDateFormat ), EE_FEATURE_FIELD );
+ if ( eTimeFormat != SVXTIMEFORMAT_APPDEFAULT )
+ {
+ SvxFieldItem* pFieldItem = new SvxFieldItem( SvxExtTimeField( Time(), SVXTIMETYPE_VAR, eTimeFormat ), EE_FEATURE_FIELD );
+ if ( pField1 )
+ pField2 = pFieldItem;
+ else
+ pField1 = pFieldItem;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+PPTTextObj::PPTTextObj( SvStream& rIn, SdrPowerPointImport& rSdrPowerPointImport, PptSlidePersistEntry& rPersistEntry, DffObjData* pObjData ) :
+ mpImplTextObj ( new ImplPPTTextObj( rPersistEntry ) )
+{
+ mpImplTextObj->mnRefCount = 1;
+ mpImplTextObj->mnShapeId = 0;
+ mpImplTextObj->mnShapeMaster = 0;
+ mpImplTextObj->mpPlaceHolderAtom = NULL;
+ mpImplTextObj->mnDestinationInstance = mpImplTextObj->mnInstance = 4;
+ mpImplTextObj->mnCurrentObject = 0;
+ mpImplTextObj->mnParagraphCount = 0;
+ mpImplTextObj->mpParagraphList = NULL;
+ mpImplTextObj->mnTextFlags = 0;
+ mpImplTextObj->meShapeType = ( pObjData && pObjData->bShapeType ) ? pObjData->eShapeType : mso_sptMin;
+
+ DffRecordHeader aExtParaHd;
+ aExtParaHd.nRecType = 0; // set empty
+
+ UINT32 bStatus = TRUE;
+
+ DffRecordHeader aShapeContainerHd;
+ rIn >> aShapeContainerHd;
+
+ if ( ( pObjData == NULL ) || ( pObjData->bShapeType ) )
+ {
+ PPTExtParaProv* pExtParaProv = rSdrPowerPointImport.pPPTStyleSheet->pExtParaProv;
+ if ( pObjData )
+ {
+ mpImplTextObj->mnShapeId = pObjData->nShapeId;
+ if ( pObjData->nSpFlags & SP_FHAVEMASTER )
+ mpImplTextObj->mnShapeMaster = rSdrPowerPointImport.GetPropertyValue( DFF_Prop_hspMaster, 0 );
+ }
+ ////////////////
+ // ClientData //
+ ////////////////
+ if ( rSdrPowerPointImport.maShapeRecords.SeekToContent( rIn, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) )
+ {
+ UINT32 nOldPos = rIn.Tell();
+ DffRecordHeader& aClientDataContainerHd = *rSdrPowerPointImport.maShapeRecords.Current();
+ DffRecordHeader aPlaceHolderAtomHd;
+ if ( rSdrPowerPointImport.SeekToRec( rIn, PPT_PST_OEPlaceholderAtom, aClientDataContainerHd.GetRecEndFilePos(), &aPlaceHolderAtomHd ) )
+ {
+ mpImplTextObj->mpPlaceHolderAtom = new PptOEPlaceholderAtom;
+ rIn >> *( mpImplTextObj->mpPlaceHolderAtom );
+ }
+ rIn.Seek( nOldPos );
+ DffRecordHeader aProgTagHd;
+ if ( rSdrPowerPointImport.SeekToContentOfProgTag( 9, rIn, aClientDataContainerHd, aProgTagHd ) )
+ {
+ rIn >> aExtParaHd;
+ }
+ }
+
+ ///////////////////
+ // ClientTextBox //
+ ///////////////////
+ if ( rSdrPowerPointImport.maShapeRecords.SeekToContent( rIn, DFF_msofbtClientTextbox, SEEK_FROM_CURRENT_AND_RESTART ) )
+ {
+ DffRecordHeader aClientTextBoxHd( *rSdrPowerPointImport.maShapeRecords.Current() );
+ UINT32 nTextRulerAtomOfs = 0; // case of zero -> this atom may be found in aClientDataContainerHd;
+ // case of -1 -> ther is no atom of this kind
+ // else -> this is the fileofs where we can get it
+
+ //////////////////////////////////////
+ // checkout if this is a referenced //
+ // textobj, if so the we will patch //
+ // the ClientTextBoxHd for a //
+ // equivalent one //
+ //////////////////////////////////////
+ DffRecordHeader aTextHd;
+ if ( rSdrPowerPointImport.SeekToRec( rIn, PPT_PST_OutlineTextRefAtom, aClientTextBoxHd.GetRecEndFilePos(), &aTextHd ) )
+ {
+ UINT32 nRefNum;
+ rIn >> nRefNum;
+
+ if ( rSdrPowerPointImport.SeekToRec( rIn, PPT_PST_TextRulerAtom, aClientTextBoxHd.GetRecEndFilePos() ) )
+ nTextRulerAtomOfs = rIn.Tell();
+ else
+ nTextRulerAtomOfs = 0xffffffff;
+
+ UINT32 nInstance = 0;
+ switch( rSdrPowerPointImport.eAktPageKind )
+ {
+ case PPT_NOTEPAGE :
+ nInstance++;
+ case PPT_MASTERPAGE :
+ nInstance++;
+ case PPT_SLIDEPAGE :
+ break;
+ default :
+ bStatus = FALSE;
+ }
+ if ( bStatus )
+ {
+ sal_uInt32 nSlideId = rSdrPowerPointImport.GetAktPageId();
+ if ( !nSlideId )
+ bStatus = FALSE;
+ else
+ {
+ if ( !aExtParaHd.nRecType )
+ {
+ UINT32 nOldPos = rIn.Tell();
+ // try to locate the referenced ExtendedParaHd
+ DffRecordHeader* pHd = pExtParaProv->
+ aExtendedPresRules.GetRecordHeader( PPT_PST_ExtendedParagraphHeaderAtom,
+ SEEK_FROM_CURRENT_AND_RESTART );
+ DffRecordHeader aPresRuleHd;
+ DffRecordHeader* pFirst = pHd;
+
+ UINT32 nTmpSlideId, nTmpRef;
+ while ( pHd )
+ {
+ pHd->SeekToContent( rIn );
+ rIn >> nTmpSlideId
+ >> nTmpRef; // this seems to be the instance
+
+ if ( ( nTmpSlideId == nSlideId ) && ( pHd->nRecInstance == nRefNum ) )
+ {
+ pHd->SeekToEndOfRecord( rIn );
+ rIn >> aPresRuleHd;
+ if ( aPresRuleHd.nRecType == PPT_PST_ExtendedParagraphAtom )
+ {
+ aExtParaHd = aPresRuleHd;
+ break;
+ }
+ }
+ pHd = pExtParaProv->
+ aExtendedPresRules.GetRecordHeader( PPT_PST_ExtendedParagraphHeaderAtom,
+ SEEK_FROM_CURRENT_AND_RESTART );
+ if ( pHd == pFirst )
+ break;
+ }
+ rIn.Seek( nOldPos );
+ }
+ // now pHd points to the right SlideListWithText Container
+ PptSlidePersistList* pPageList = rSdrPowerPointImport.GetPageList( rSdrPowerPointImport.eAktPageKind );
+ PptSlidePersistEntry* pE = NULL;
+ if ( pPageList && ( rSdrPowerPointImport.nAktPageNum < pPageList->Count() ) )
+ pE = (*pPageList)[ rSdrPowerPointImport.nAktPageNum ];
+ if ( (!pE) || (!pE->nSlidePersistStartOffset) || ( pE->aPersistAtom.nSlideId != nSlideId ) )
+ bStatus = sal_False;
+ else
+ {
+ rIn.Seek( pE->nSlidePersistStartOffset );
+ // now we got the right page and are searching for the right
+ // TextHeaderAtom
+ while ( rIn.Tell() < pE->nSlidePersistEndOffset )
+ {
+ rIn >> aClientTextBoxHd;
+ if ( aClientTextBoxHd.nRecType == PPT_PST_TextHeaderAtom )
+ {
+ if ( aClientTextBoxHd.nRecInstance == nRefNum )
+ {
+ aClientTextBoxHd.SeekToEndOfRecord( rIn );
+ break;
+ }
+ }
+ aClientTextBoxHd.SeekToEndOfRecord( rIn );
+ }
+ if ( rIn.Tell() > pE->nSlidePersistEndOffset )
+ bStatus = FALSE;
+ else
+ { // patching the RecordHeader
+ aClientTextBoxHd.nFilePos -= DFF_COMMON_RECORD_HEADER_SIZE;
+ aClientTextBoxHd.nRecLen += DFF_COMMON_RECORD_HEADER_SIZE;
+ aClientTextBoxHd.nRecType = DFF_msofbtClientTextbox;
+ aClientTextBoxHd.nRecVer = DFF_PSFLAG_CONTAINER;
+
+ // we have to calculate the correct record len
+ DffRecordHeader aTmpHd;
+ while ( rIn.Tell() < pE->nSlidePersistEndOffset )
+ {
+ rIn >> aTmpHd;
+ if ( ( aTmpHd.nRecType == PPT_PST_SlidePersistAtom ) || ( aTmpHd.nRecType == PPT_PST_TextHeaderAtom ) )
+ break;
+ aTmpHd.SeekToEndOfRecord( rIn );
+ aClientTextBoxHd.nRecLen += aTmpHd.nRecLen + DFF_COMMON_RECORD_HEADER_SIZE;
+ }
+ aClientTextBoxHd.SeekToContent( rIn );
+ }
+ }
+ }
+ }
+ }
+
+ if ( bStatus )
+ {
+ if ( rSdrPowerPointImport.SeekToRec( rIn, PPT_PST_TextHeaderAtom, aClientTextBoxHd.GetRecEndFilePos(), &aTextHd ) )
+ {
+ // TextHeaderAtom is always the first Atom
+ UINT16 nInstance;
+ rIn >> nInstance; // this number tells us the TxMasterStyleAtom Instance
+ if ( nInstance > 8 )
+ nInstance = 4;
+ aTextHd.SeekToEndOfRecord( rIn );
+ mpImplTextObj->mnInstance = nInstance;
+
+ UINT32 nFilePos = rIn.Tell();
+ if ( rSdrPowerPointImport.SeekToRec2( PPT_PST_TextBytesAtom,
+ PPT_PST_TextCharsAtom,
+ aClientTextBoxHd.GetRecEndFilePos() )
+ || rSdrPowerPointImport.SeekToRec( rIn,
+ PPT_PST_StyleTextPropAtom,
+ aClientTextBoxHd.GetRecEndFilePos() ) )
+ {
+ PPTTextRulerInterpreter aTextRulerInterpreter( nTextRulerAtomOfs, rSdrPowerPointImport,
+ aClientTextBoxHd, rIn );
+
+ PPTStyleTextPropReader aStyleTextPropReader( rIn, rSdrPowerPointImport, aClientTextBoxHd,
+ aTextRulerInterpreter, aExtParaHd, nInstance );
+ sal_uInt32 nParagraphs = mpImplTextObj->mnParagraphCount = aStyleTextPropReader.aParaPropList.Count();
+ if ( nParagraphs )
+ {
+ // the language settings will be merged into the list of PPTCharPropSet
+ DffRecordHeader aTextSpecInfoHd;
+ PPTTextSpecInfoAtomInterpreter aTextSpecInfoAtomInterpreter;
+ if ( rSdrPowerPointImport.SeekToRec( rIn, PPT_PST_TextSpecInfoAtom,
+ aClientTextBoxHd.GetRecEndFilePos(), &aTextSpecInfoHd ) )
+ {
+ if ( aTextSpecInfoAtomInterpreter.Read( rIn, aTextSpecInfoHd, PPT_PST_TextSpecInfoAtom,
+ &(rSdrPowerPointImport.pPPTStyleSheet->maTxSI) ) )
+ {
+ sal_uInt32 nI = 0;
+ PPTTextSpecInfo* pSpecInfo;
+ for ( pSpecInfo = (PPTTextSpecInfo*)aTextSpecInfoAtomInterpreter.aList.First();
+ pSpecInfo; pSpecInfo =(PPTTextSpecInfo*)aTextSpecInfoAtomInterpreter.aList.Next() )
+ {
+ sal_uInt32 nCharIdx = pSpecInfo->nCharIdx;
+
+ // portions and text have to been splitted in some cases
+ for ( ; nI < aStyleTextPropReader.aCharPropList.Count(); )
+ {
+ PPTCharPropSet* pSet = (PPTCharPropSet*)aStyleTextPropReader.aCharPropList.GetObject( nI );
+ if ( pSet->mnOriginalTextPos < nCharIdx )
+ {
+ pSet->mnLanguage[ 0 ] = pSpecInfo->nLanguage[ 0 ];
+ pSet->mnLanguage[ 1 ] = pSpecInfo->nLanguage[ 1 ];
+ pSet->mnLanguage[ 2 ] = pSpecInfo->nLanguage[ 2 ];
+ // test if the current portion needs to be splitted
+ if ( pSet->maString.Len() > 1 )
+ {
+ sal_Int32 nIndexOfNextPortion = pSet->maString.Len() + pSet->mnOriginalTextPos;
+ sal_Int32 nNewLen = nIndexOfNextPortion - nCharIdx;
+ sal_Int32 nOldLen = pSet->maString.Len() - nNewLen;
+
+ if ( ( nNewLen > 0 ) && ( nOldLen > 0 ) )
+ {
+ String aString( pSet->maString );
+ PPTCharPropSet* pNew = new PPTCharPropSet( *pSet );
+ pSet->maString = String( aString, 0, (sal_uInt16)nOldLen );
+ pNew->maString = String( aString, (sal_uInt16)nOldLen, (sal_uInt16)nNewLen );
+ pNew->mnOriginalTextPos += nOldLen;
+ aStyleTextPropReader.aCharPropList.Insert( pNew, nI + 1 );
+ }
+ }
+ }
+ else
+ break;
+ nI++;
+ }
+ }
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ if (!(rSdrPowerPointImport.rImportParam.nImportFlags & PPT_IMPORTFLAGS_NO_TEXT_ASSERT))
+ {
+ DBG_ERROR( "SdrTextSpecInfoAtomInterpreter::Ctor(): parsing error, this document needs to be analysed (SJ)" );
+ }
+ }
+#endif
+ }
+ //
+ // now will search for possible textextensions such as date/time fields
+ // or ParaTabStops and append them on this textobj
+ //
+ rIn.Seek( nFilePos );
+ List* pFieldList = NULL;
+ while ( rIn.Tell() < aClientTextBoxHd.GetRecEndFilePos() )
+ {
+ rIn >> aTextHd;
+ UINT16 nVal = 0;
+ PPTFieldEntry* pEntry = NULL;
+ switch ( aTextHd.nRecType )
+ {
+ case PPT_PST_DateTimeMCAtom :
+ {
+ pEntry = new PPTFieldEntry;
+ rIn >> pEntry->nPos
+ >> nVal
+ >> nVal;
+ pEntry->SetDateTime( nVal & 0xff );
+ }
+ break;
+
+ case PPT_PST_FooterMCAtom :
+ {
+ pEntry = new PPTFieldEntry;
+ rIn >> pEntry->nPos;
+ pEntry->pField1 = new SvxFieldItem( SvxFooterField(), EE_FEATURE_FIELD );
+ }
+ break;
+
+ case PPT_PST_HeaderMCAtom :
+ {
+ pEntry = new PPTFieldEntry;
+ rIn >> pEntry->nPos;
+ pEntry->pField1 = new SvxFieldItem( SvxHeaderField(), EE_FEATURE_FIELD );
+ }
+ break;
+
+ case PPT_PST_GenericDateMCAtom :
+ {
+ pEntry = new PPTFieldEntry;
+ rIn >> pEntry->nPos;
+ pEntry->pField1 = new SvxFieldItem( SvxDateTimeField(), EE_FEATURE_FIELD );
+ if ( rPersistEntry.pHeaderFooterEntry ) // sj: #i34111# on master pages it is possible
+ { // that there is no HeaderFooterEntry available
+ if ( rPersistEntry.pHeaderFooterEntry->nAtom & 0x20000 ) // auto date time
+ pEntry->SetDateTime( rPersistEntry.pHeaderFooterEntry->nAtom & 0xff );
+ else
+ pEntry->pString = new String( rPersistEntry.pHeaderFooterEntry->pPlaceholder[ nVal ] );
+ }
+ }
+ break;
+
+ case PPT_PST_SlideNumberMCAtom :
+ case PPT_PST_RTFDateTimeMCAtom :
+ {
+ pEntry = new PPTFieldEntry;
+ if ( aTextHd.nRecLen >= 4 )
+ {
+ rIn >> pEntry->nPos
+ >> nVal;
+
+ // ID auswerten
+ //SvxFieldItem* pFieldItem = NULL;
+ switch( aTextHd.nRecType )
+ {
+ case PPT_PST_SlideNumberMCAtom:
+ pEntry->pField1 = new SvxFieldItem( SvxPageField(), EE_FEATURE_FIELD );
+ break;
+
+ case PPT_PST_RTFDateTimeMCAtom:
+ {
+ // Rude workaround for one specal case reported
+ // by a customer. (#i75203#)
+
+ // Don't even attempt to handle the general use
+ // case for PPT_PST_RTFDateTimeMCAtom (a generic
+ // MS style date/time format string). Just handle
+ // the special case where the format string
+ // contains only one or several possibly empty
+ // quoted strings. I.e. something that doesn't
+ // expand to any date or time at all, but to a
+ // fixed string. How on earth somebody manages to
+ // produce such things in PPT slides I have no
+ // idea.
+ if (nVal == 0)
+ {
+ sal_Unicode n;
+ xub_StrLen nLen;
+ String aStr;
+ bool inquote = FALSE;
+ for (nLen = 0, n = 0; nLen < 64; nLen++)
+ {
+ rIn >> n;
+
+ // Collect quoted characters into aStr
+ if ( n == '\'')
+ inquote = !inquote;
+ else if (!n)
+ {
+ // End of format string
+ pEntry->pString = new String( aStr );
+ break;
+ }
+ else if (!inquote)
+ {
+ // Non-quoted character, i.e. a real
+ // format specifier. We don't handle
+ // those. Sorry.
+ break;
+ }
+ else
+ {
+ aStr += n;
+ }
+ }
+ }
+ if ( pEntry->pString == NULL )
+ {
+ // Handle as previously
+ pEntry->pField1 = new SvxFieldItem( SvxDateField( Date(), SVXDATETYPE_FIX ), EE_FEATURE_FIELD );
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case PPT_PST_InteractiveInfo :
+ {
+ DffRecordHeader aHdInteractiveInfoAtom;
+ if ( rSdrPowerPointImport.SeekToRec( rIn, PPT_PST_InteractiveInfoAtom, aTextHd.GetRecEndFilePos(), &aHdInteractiveInfoAtom ) )
+ {
+ PptInteractiveInfoAtom aInteractiveInfoAtom;
+ rIn >> aInteractiveInfoAtom;
+ for ( SdHyperlinkEntry* pHyperlink = (SdHyperlinkEntry*)rSdrPowerPointImport.aHyperList.First();
+ pHyperlink; pHyperlink = (SdHyperlinkEntry*)rSdrPowerPointImport.aHyperList.Next() )
+ {
+ if ( pHyperlink->nIndex == aInteractiveInfoAtom.nExHyperlinkId )
+ {
+ aTextHd.SeekToEndOfRecord( rIn );
+ rIn >> aTextHd;
+ if ( aTextHd.nRecType != PPT_PST_TxInteractiveInfoAtom )
+ {
+ aTextHd.SeekToBegOfRecord( rIn );
+ continue;
+ }
+ else
+ {
+ sal_uInt32 nStartPos, nEndPos;
+ rIn >> nStartPos
+ >> nEndPos;
+ if ( nEndPos )
+ {
+ pEntry = new PPTFieldEntry;
+ pEntry->nPos = (sal_uInt16)nStartPos;
+ pEntry->nTextRangeEnd = (sal_uInt16)nEndPos;
+ String aTarget( pHyperlink->aTarget );
+ if ( pHyperlink->aConvSubString.Len() )
+ {
+ aTarget.Append( (sal_Unicode)'#' );
+ aTarget.Append( pHyperlink->aConvSubString );
+ }
+ pEntry->pField1 = new SvxFieldItem( SvxURLField( aTarget, String(), SVXURLFORMAT_REPR ), EE_FEATURE_FIELD );
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ aTextHd.SeekToEndOfRecord( rIn );
+ if ( pEntry )
+ {
+ if ( !pFieldList )
+ pFieldList = new List;
+ UINT32 n;
+ for ( n = 0; n < pFieldList->Count(); n++ )
+ { // sorting fields ( hi >> lo )
+ if ( ( (PPTFieldEntry*)pFieldList->GetObject( n ) )->nPos < pEntry->nPos )
+ break;
+ }
+ pFieldList->Insert( pEntry, (UINT32)n );
+ }
+ }
+ if ( pFieldList )
+ {
+ PPTFieldEntry* pFE = (PPTFieldEntry*)pFieldList->First();
+ List& aCharPropList = aStyleTextPropReader.aCharPropList;
+
+ sal_Int32 i = nParagraphs - 1;
+ sal_Int32 n = aCharPropList.Count() - 1;
+
+ // at this point we just have a list of textportions(aCharPropList)
+ // the next while loop tries to resolve the list of fields(pFieldList)
+ while( pFE && ( n >= 0 ) && ( i >= 0 ) )
+ {
+ PPTCharPropSet* pSet = (PPTCharPropSet*)aCharPropList.GetObject( n );
+ String aString( pSet->maString );
+ UINT32 nCount = aString.Len();
+ UINT32 nPos = pSet->mnOriginalTextPos + nCount;
+ while ( pFE && nCount-- )
+ {
+ nPos--;
+ while ( pFE && ( pFE->nPos > nPos ) )
+ pFE = (PPTFieldEntry*)pFieldList->Next();
+ if ( !pFE )
+ break;
+
+ if ( pFE->nPos == nPos )
+ {
+ if ( aString.GetChar( (sal_uInt16)nCount ) == 0x2a )
+ {
+ UINT32 nBehind = aString.Len() - ( nCount + 1 );
+ pSet->maString = String();
+ if ( nBehind )
+ {
+ PPTCharPropSet* pNewCPS = new PPTCharPropSet( *pSet );
+ pNewCPS->maString = String( aString, (UINT16)nCount + 1, (UINT16)nBehind );
+ aCharPropList.Insert( pNewCPS, n + 1 );
+ }
+ if ( pFE->pField2 )
+ {
+ PPTCharPropSet* pNewCPS = new PPTCharPropSet( *pSet );
+ pNewCPS->mpFieldItem = pFE->pField2, pFE->pField2 = NULL;
+ aCharPropList.Insert( pNewCPS, n + 1 );
+
+ pNewCPS = new PPTCharPropSet( *pSet );
+ pNewCPS->maString = String( String( RTL_CONSTASCII_USTRINGPARAM( " " ) ) );
+ aCharPropList.Insert( pNewCPS, n + 1 );
+ }
+ if ( nCount )
+ {
+ PPTCharPropSet* pNewCPS = new PPTCharPropSet( *pSet );
+ pNewCPS->maString = String( aString, (UINT16)0, (UINT16)nCount );
+ aCharPropList.Insert( pNewCPS, n++ );
+ }
+ if ( pFE->pField1 )
+ {
+ pSet->mpFieldItem = pFE->pField1, pFE->pField1 = NULL;
+ }
+ else if ( pFE->pString )
+ pSet->maString = *pFE->pString;
+ }
+ else
+ {
+ if ( pFE->nTextRangeEnd ) // text range hyperlink
+ {
+ sal_uInt32 nHyperLen = pFE->nTextRangeEnd - nPos;
+ if ( nHyperLen )
+ {
+ PPTCharPropSet* pBefCPS = NULL;
+ if ( nCount )
+ {
+ pBefCPS = new PPTCharPropSet( *pSet );
+ pSet->maString = String( pSet->maString, (UINT16)nCount, (UINT16)( pSet->maString.Len() - nCount ) );
+ }
+ sal_uInt32 nIdx = n;
+ sal_Int32 nHyperLenLeft = nHyperLen;
+
+ while ( ( aCharPropList.Count() > nIdx ) && nHyperLenLeft )
+ {
+ // the textrange hyperlink can take more than 1 paragraph
+ // the solution here is to clone the hyperlink...
+
+ PPTCharPropSet* pCurrent = (PPTCharPropSet*)aCharPropList.GetObject( nIdx );
+ sal_Int32 nNextStringLen = pCurrent->maString.Len();
+
+ const SvxURLField* pField = (const SvxURLField*)pFE->pField1->GetField();
+
+ if ( pCurrent->mpFieldItem )
+ {
+ pCurrent->SetColor( PPT_COLSCHEME_A_UND_HYPERLINK );
+ if ( pCurrent->mpFieldItem->GetField()->ISA( SvxURLField ) )
+ break;
+ nHyperLenLeft--;
+ }
+ else if ( nNextStringLen )
+ {
+ if ( nNextStringLen <= nHyperLenLeft )
+ {
+ pCurrent->mpFieldItem = new SvxFieldItem( SvxURLField( pField->GetURL(), pCurrent->maString, SVXURLFORMAT_REPR ), EE_FEATURE_FIELD );
+ nHyperLenLeft -= nNextStringLen;
+
+ if ( nHyperLenLeft )
+ {
+ // if the next portion is in a higher paragraph,
+ // the textrange is to decrease (because of the LineBreak character)
+ if ( aCharPropList.Count() > ( nIdx + 1 ) )
+ {
+ PPTCharPropSet* pNext = (PPTCharPropSet*)aCharPropList.GetObject( nIdx + 1 );
+ if ( pNext->mnParagraph > pCurrent->mnParagraph )
+ nHyperLenLeft--;
+ }
+ }
+ }
+ else
+ {
+ PPTCharPropSet* pNewCPS = new PPTCharPropSet( *pCurrent );
+ pNewCPS->maString = String( pCurrent->maString, (UINT16)nHyperLenLeft, (UINT16)( nNextStringLen - nHyperLenLeft ) );
+ aCharPropList.Insert( pNewCPS, nIdx + 1 );
+ String aRepresentation( pCurrent->maString, 0, (UINT16)nHyperLenLeft );
+ pCurrent->mpFieldItem = new SvxFieldItem( SvxURLField( pField->GetURL(), aRepresentation, SVXURLFORMAT_REPR ), EE_FEATURE_FIELD );
+ nHyperLenLeft = 0;
+ }
+ pCurrent->maString = String();
+ pCurrent->SetColor( PPT_COLSCHEME_A_UND_HYPERLINK );
+ }
+ nIdx++;
+ }
+ delete pFE->pField1, pFE->pField1 = NULL;
+
+ if ( pBefCPS )
+ {
+ pBefCPS->maString = String( aString, (UINT16)0, (UINT16)nCount );
+ aCharPropList.Insert( pBefCPS, n++ );
+
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ n--;
+ }
+ for ( void* pPtr = pFieldList->First(); pPtr; pPtr = pFieldList->Next() )
+ delete (PPTFieldEntry*)pPtr;
+ delete pFieldList;
+ }
+ mpImplTextObj->mpParagraphList = new PPTParagraphObj*[ nParagraphs ];
+ aStyleTextPropReader.aCharPropList.First();
+ UINT32 nCount = 0;
+ for ( void* pPtr = aStyleTextPropReader.aParaPropList.First();
+ pPtr;
+ pPtr = aStyleTextPropReader.aParaPropList.Next() )
+ {
+ PPTParagraphObj* pPara = new PPTParagraphObj( aStyleTextPropReader, *rSdrPowerPointImport.pPPTStyleSheet, nInstance, aTextRulerInterpreter );
+ mpImplTextObj->mpParagraphList[ nCount++ ] = pPara;
+
+ sal_uInt32 nParaAdjust, nFlags = 0;
+ pPara->GetAttrib( PPT_ParaAttr_Adjust, nParaAdjust, GetInstance() );
+
+ switch ( nParaAdjust )
+ {
+ case 0 : nFlags = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT; break;
+ case 1 : nFlags = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER; break;
+ case 2 : nFlags = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT; break;
+ case 3 : nFlags = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK; break;
+ }
+ mpImplTextObj->mnTextFlags |= nFlags;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+PPTTextObj::PPTTextObj( PPTTextObj& rTextObj )
+{
+ mpImplTextObj = rTextObj.mpImplTextObj;
+ mpImplTextObj->mnRefCount++;
+}
+
+PPTTextObj::~PPTTextObj()
+{
+ ImplClear();
+}
+
+PPTParagraphObj* PPTTextObj::First()
+{
+ mpImplTextObj->mnCurrentObject = 0;
+ if ( !mpImplTextObj->mnParagraphCount )
+ return NULL;
+ return mpImplTextObj->mpParagraphList[ 0 ];
+}
+
+PPTParagraphObj* PPTTextObj::Next()
+{
+ UINT32 i = mpImplTextObj->mnCurrentObject + 1;
+ if ( i >= mpImplTextObj->mnParagraphCount )
+ return NULL;
+ mpImplTextObj->mnCurrentObject++;
+ return mpImplTextObj->mpParagraphList[ i ];
+}
+
+const SfxItemSet* PPTTextObj::GetBackground() const
+{
+ if ( mpImplTextObj->mrPersistEntry.pBObj )
+ return &mpImplTextObj->mrPersistEntry.pBObj->GetMergedItemSet();
+ else
+ return NULL;
+}
+
+void PPTTextObj::ImplClear()
+{
+ if ( ! ( --mpImplTextObj->mnRefCount ) )
+ {
+ for ( PPTParagraphObj* pPtr = First(); pPtr; pPtr = Next() )
+ delete pPtr;
+ delete[] mpImplTextObj->mpParagraphList;
+ delete mpImplTextObj->mpPlaceHolderAtom;
+ delete mpImplTextObj;
+ }
+}
+
+PPTTextObj& PPTTextObj::operator=( PPTTextObj& rTextObj )
+{
+ if ( this != &rTextObj )
+ {
+ ImplClear();
+ mpImplTextObj = rTextObj.mpImplTextObj;
+ mpImplTextObj->mnRefCount++;
+ }
+ return *this;
+}
+
+sal_Bool IsLine( const SdrObject* pObj )
+{
+ return pObj->ISA( SdrPathObj ) && ((SdrPathObj*)pObj)->IsLine() && (((SdrPathObj*)pObj)->GetPointCount() == 2 );
+}
+
+sal_Bool GetCellPosition( const SdrObject* pObj, const std::set< sal_Int32 >& rRows, const std::set< sal_Int32 >& rColumns,
+ sal_Int32& nTableIndex, sal_Int32& nRow, sal_Int32& nRowCount, sal_Int32& nColumn, sal_Int32& nColumnCount )
+{
+ Rectangle aSnapRect( pObj->GetSnapRect() );
+ sal_Bool bCellObject = ( aSnapRect.GetWidth() > 1 ) && ( aSnapRect.GetHeight() > 1 );
+ if ( bCellObject )
+ {
+ std::set< sal_Int32 >::const_iterator aRowIter( rRows.find( aSnapRect.Top() ) );
+ std::set< sal_Int32 >::const_iterator aColumnIter( rColumns.find( aSnapRect.Left() ) );
+ if ( ( aRowIter == rRows.end() ) || ( aColumnIter == rColumns.end() ) )
+ bCellObject = sal_False;
+ else
+ {
+ nRowCount = 1;
+ nRow = std::distance( rRows.begin(), aRowIter );
+ while( ++aRowIter != rRows.end() )
+ {
+ if ( *aRowIter >= aSnapRect.Bottom() )
+ break;
+ nRowCount++;
+ }
+ nColumnCount = 1;
+ nColumn = std::distance( rColumns.begin(), aColumnIter );
+ while( ++aColumnIter != rColumns.end() )
+ {
+ if ( *aColumnIter >= aSnapRect.Right() )
+ break;
+ nColumnCount++;
+ }
+ nTableIndex = nRow * rColumns.size() + nColumn;
+ }
+ }
+ return bCellObject;
+}
+
+#define LinePositionLeft 0x01000000
+#define LinePositionTop 0x02000000
+#define LinePositionRight 0x04000000
+#define LinePositionBottom 0x08000000
+#define LinePositionTLBR 0x10000000
+#define LinePositionBLTR 0x20000000
+
+
+void GetRowPositions( const Rectangle& rSnapRect, const std::set< sal_Int32 >& rRows,
+ const std::set< sal_Int32 >& rColumns, std::vector< sal_Int32 >& rPositions, sal_Int32 nColumn, sal_Int32 nFlags )
+{
+ std::set< sal_Int32 >::const_iterator aRow( rRows.find( rSnapRect.Top() ) );
+ if ( aRow != rRows.end() )
+ {
+ sal_Int32 nRow = std::distance( rRows.begin(), aRow );
+ while( ( aRow != rRows.end() ) && ((*aRow) < rSnapRect.Bottom() ) )
+ {
+ if ( nFlags & LinePositionLeft )
+ rPositions.push_back( ( ( nRow * rColumns.size() ) + nColumn ) | LinePositionLeft );
+ if ( nFlags & LinePositionRight )
+ rPositions.push_back( ( ( nRow * rColumns.size() ) + ( nColumn - 1 ) ) | LinePositionRight );
+
+ nRow++;
+ aRow++;
+ }
+ }
+}
+
+
+void GetColumnPositions( const Rectangle& rSnapRect, const std::set< sal_Int32 >& /* rRows */,
+ const std::set< sal_Int32 >& rColumns, std::vector< sal_Int32 >& rPositions, sal_Int32 nRow, sal_Int32 nFlags )
+{
+ std::set< sal_Int32 >::const_iterator aColumn( rColumns.find( rSnapRect.Left() ) );
+ if ( aColumn != rColumns.end() )
+ {
+ sal_Int32 nColumn = std::distance( rColumns.begin(), aColumn );
+ while( ( aColumn != rColumns.end() ) && ((*aColumn) < rSnapRect.Right() ) )
+ {
+ if ( nFlags & LinePositionTop )
+ rPositions.push_back( ( ( nRow * rColumns.size() ) + nColumn ) | LinePositionTop );
+ if ( nFlags & LinePositionBottom )
+ rPositions.push_back( ( ( ( nRow - 1 ) * rColumns.size() ) + nColumn ) | LinePositionBottom );
+
+ nColumn++;
+ aColumn++;
+ }
+ }
+}
+
+void GetLinePositions( const SdrObject* pObj, const std::set< sal_Int32 >& rRows, const std::set< sal_Int32 >& rColumns,
+ std::vector< sal_Int32 >& rPositions, const Rectangle& rGroupSnap )
+{
+ Rectangle aSnapRect( pObj->GetSnapRect() );
+ if ( aSnapRect.Left() == aSnapRect.Right() )
+ {
+ std::set< sal_Int32 >::const_iterator aColumn( rColumns.find( aSnapRect.Left() ) );
+ if ( ( aColumn != rColumns.end() ) || ( aSnapRect.Left() == rGroupSnap.Right() ) )
+ {
+ sal_Int32 nColumn, nFlags;
+ if ( aColumn != rColumns.end() )
+ {
+ nColumn = std::distance( rColumns.begin(), aColumn );
+ nFlags = LinePositionLeft;
+ if ( aColumn != rColumns.begin() )
+ nFlags |= LinePositionRight;
+ }
+ else
+ {
+ nColumn = rColumns.size();
+ nFlags = LinePositionRight;
+ }
+ GetRowPositions( aSnapRect, rRows, rColumns, rPositions, nColumn, nFlags );
+ }
+ }
+ else if ( aSnapRect.Top() == aSnapRect.Bottom() )
+ {
+ std::set< sal_Int32 >::const_iterator aRow( rRows.find( aSnapRect.Top() ) );
+ if ( ( aRow != rRows.end() ) || ( aSnapRect.Top() == rGroupSnap.Bottom() ) )
+ {
+ sal_Int32 nRow, nFlags;
+ if ( aRow != rRows.end() )
+ {
+ nRow = std::distance( rRows.begin(), aRow );
+ nFlags = LinePositionTop;
+ if ( aRow != rRows.begin() )
+ nFlags |= LinePositionBottom;
+ }
+ else
+ {
+ nRow = rRows.size();
+ nFlags = LinePositionBottom;
+ }
+ GetColumnPositions( aSnapRect, rRows, rColumns, rPositions, nRow, nFlags );
+ }
+ }
+ else
+ {
+ sal_uInt32 nPosition = 0;
+ Point aPt1( ((SdrPathObj*)pObj)->GetPoint( 0 ) );
+ Point aPt2( ((SdrPathObj*)pObj)->GetPoint( 1 ) );
+ if ( aPt1.X() < aPt2.X() )
+ nPosition |= aPt1.Y() < aPt2.Y() ? LinePositionTLBR : LinePositionBLTR;
+ else
+ nPosition |= aPt1.Y() < aPt2.Y() ? LinePositionBLTR : LinePositionTLBR;
+
+ std::set< sal_Int32 >::const_iterator aRow( rRows.find( aPt1.Y() < aPt2.Y() ? aPt1.Y() : aPt2.Y() ) );
+ std::set< sal_Int32 >::const_iterator aColumn( rColumns.find( aPt1.X() < aPt2.X() ? aPt1.X() : aPt2.X() ) );
+ if ( ( aRow != rRows.end() ) && ( aColumn != rColumns.end() ) )
+ {
+ nPosition |= ( std::distance( rRows.begin(), aRow ) * rColumns.size() ) + std::distance( rColumns.begin(), aColumn );
+ rPositions.push_back( nPosition );
+ }
+ }
+}
+
+void CreateTableRows( Reference< XTableRows > xTableRows, const std::set< sal_Int32 >& rRows, sal_Int32 nTableBottom )
+{
+ if ( rRows.size() > 1 )
+ xTableRows->insertByIndex( 0, rRows.size() - 1 );
+
+ std::set< sal_Int32 >::const_iterator aIter( rRows.begin() );
+ sal_Int32 nLastPosition( *aIter );
+ Reference< XIndexAccess > xIndexAccess( xTableRows, UNO_QUERY_THROW );
+ for ( sal_Int32 n = 0; n < xIndexAccess->getCount(); n++ )
+ {
+ sal_Int32 nHeight;
+ if ( ++aIter != rRows.end() )
+ {
+ nHeight = *aIter - nLastPosition;
+ nLastPosition = *aIter;
+ }
+ else
+ nHeight = nTableBottom - nLastPosition;
+
+ static const rtl::OUString sWidth( RTL_CONSTASCII_USTRINGPARAM ( "Height" ) );
+ Reference< XPropertySet > xPropSet( xIndexAccess->getByIndex( n ), UNO_QUERY_THROW );
+ xPropSet->setPropertyValue( sWidth, Any( nHeight ) );
+ }
+}
+
+void CreateTableColumns( Reference< XTableColumns > xTableColumns, const std::set< sal_Int32 >& rColumns, sal_Int32 nTableRight )
+{
+ if ( rColumns.size() > 1 )
+ xTableColumns->insertByIndex( 0, rColumns.size() - 1 );
+
+ std::set< sal_Int32 >::const_iterator aIter( rColumns.begin() );
+ sal_Int32 nLastPosition( *aIter );
+ Reference< XIndexAccess > xIndexAccess( xTableColumns, UNO_QUERY_THROW );
+ for ( sal_Int32 n = 0; n < xIndexAccess->getCount(); n++ )
+ {
+ sal_Int32 nWidth;
+ if ( ++aIter != rColumns.end() )
+ {
+ nWidth = *aIter - nLastPosition;
+ nLastPosition = *aIter;
+ }
+ else
+ nWidth = nTableRight - nLastPosition;
+
+ static const rtl::OUString sWidth( RTL_CONSTASCII_USTRINGPARAM ( "Width" ) );
+ Reference< XPropertySet > xPropSet( xIndexAccess->getByIndex( n ), UNO_QUERY_THROW );
+ xPropSet->setPropertyValue( sWidth, Any( nWidth ) );
+ }
+}
+
+void MergeCells( const Reference< XTable >& xTable, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan )
+{
+ DBG_ASSERT( (nColSpan > 1) || (nRowSpan > 1), "nonsense parameter!!" );
+ DBG_ASSERT( (nCol >= 0) && (nCol < xTable->getColumnCount()) && (nRow >= 0) && (nRow < xTable->getRowCount()), "die celle gibts nicht!!" );
+ DBG_ASSERT( (nColSpan >= 1) && ((nCol + nColSpan - 1) < xTable->getColumnCount()), "nColSpan murks!" );
+ DBG_ASSERT( (nRowSpan >= 1) && ((nRow + nRowSpan - 1) < xTable->getRowCount()), "nRowSpan murks!" );
+
+ if( xTable.is() ) try
+ {
+ Reference< XMergeableCellRange > xRange( xTable->createCursorByRange( xTable->getCellRangeByPosition( nCol, nRow,nCol + nColSpan - 1, nRow + nRowSpan - 1 ) ), UNO_QUERY_THROW );
+ if( xRange->isMergeable() )
+ xRange->merge();
+ }
+ catch( Exception& )
+ {
+ DBG_ASSERT( false, "exception caught!" );
+ }
+}
+
+void ApplyCellAttributes( const SdrObject* pObj, Reference< XCell >& xCell )
+{
+ try
+ {
+ Reference< XPropertySet > xPropSet( xCell, UNO_QUERY_THROW );
+
+ const sal_Int32 nLeftDist(((const SdrTextLeftDistItem&)pObj->GetMergedItem(SDRATTR_TEXT_LEFTDIST)).GetValue());
+ const sal_Int32 nRightDist(((const SdrTextRightDistItem&)pObj->GetMergedItem(SDRATTR_TEXT_RIGHTDIST)).GetValue());
+ const sal_Int32 nUpperDist(((const SdrTextUpperDistItem&)pObj->GetMergedItem(SDRATTR_TEXT_UPPERDIST)).GetValue());
+ const sal_Int32 nLowerDist(((const SdrTextLowerDistItem&)pObj->GetMergedItem(SDRATTR_TEXT_LOWERDIST)).GetValue());
+ static const rtl::OUString sTopBorder( RTL_CONSTASCII_USTRINGPARAM( "TextUpperDistance" ) );
+ static const rtl::OUString sBottomBorder( RTL_CONSTASCII_USTRINGPARAM( "TextLowerDistance" ) );
+ static const rtl::OUString sLeftBorder( RTL_CONSTASCII_USTRINGPARAM( "TextLeftDistance" ) );
+ static const rtl::OUString sRightBorder( RTL_CONSTASCII_USTRINGPARAM( "TextRightDistance" ) );
+ xPropSet->setPropertyValue( sTopBorder, Any( nUpperDist ) );
+ xPropSet->setPropertyValue( sRightBorder, Any( nRightDist ) );
+ xPropSet->setPropertyValue( sLeftBorder, Any( nLeftDist ) );
+ xPropSet->setPropertyValue( sBottomBorder, Any( nLowerDist ) );
+
+ static const rtl::OUString sTextVerticalAdjust( RTL_CONSTASCII_USTRINGPARAM( "TextVerticalAdjust" ) );
+ const SdrTextVertAdjust eTextVertAdjust(((const SdrTextVertAdjustItem&)pObj->GetMergedItem(SDRATTR_TEXT_VERTADJUST)).GetValue());
+ drawing::TextVerticalAdjust eVA( drawing::TextVerticalAdjust_TOP );
+ if ( eTextVertAdjust == SDRTEXTVERTADJUST_CENTER )
+ eVA = drawing::TextVerticalAdjust_CENTER;
+ else if ( eTextVertAdjust == SDRTEXTVERTADJUST_BOTTOM )
+ eVA = drawing::TextVerticalAdjust_BOTTOM;
+ xPropSet->setPropertyValue( sTextVerticalAdjust, Any( eVA ) );
+
+ SfxItemSet aSet( pObj->GetMergedItemSet() );
+ XFillStyle eFillStyle(((XFillStyleItem&)pObj->GetMergedItem( XATTR_FILLSTYLE )).GetValue());
+ ::com::sun::star::drawing::FillStyle eFS( com::sun::star::drawing::FillStyle_NONE );
+ switch( eFillStyle )
+ {
+ case XFILL_SOLID :
+ {
+ static const rtl::OUString sFillColor( String( RTL_CONSTASCII_USTRINGPARAM( "FillColor" ) ) );
+ eFS = com::sun::star::drawing::FillStyle_SOLID;
+ Color aFillColor( ((XFillColorItem&)pObj->GetMergedItem( XATTR_FILLCOLOR )).GetColorValue() );
+ sal_Int32 nFillColor( aFillColor.GetColor() );
+ xPropSet->setPropertyValue( sFillColor, Any( nFillColor ) );
+ }
+ break;
+ case XFILL_GRADIENT :
+ {
+ eFS = com::sun::star::drawing::FillStyle_GRADIENT;
+ XGradient aXGradient(((const XFillGradientItem&)pObj->GetMergedItem(XATTR_FILLGRADIENT)).GetGradientValue());
+
+ com::sun::star::awt::Gradient aGradient;
+ aGradient.Style = (awt::GradientStyle) aXGradient.GetGradientStyle();
+ aGradient.StartColor = (INT32)aXGradient.GetStartColor().GetColor();
+ aGradient.EndColor = (INT32)aXGradient.GetEndColor().GetColor();
+ aGradient.Angle = (short)aXGradient.GetAngle();
+ aGradient.Border = aXGradient.GetBorder();
+ aGradient.XOffset = aXGradient.GetXOffset();
+ aGradient.YOffset = aXGradient.GetYOffset();
+ aGradient.StartIntensity = aXGradient.GetStartIntens();
+ aGradient.EndIntensity = aXGradient.GetEndIntens();
+ aGradient.StepCount = aXGradient.GetSteps();
+
+ static const rtl::OUString sFillGradient( String( RTL_CONSTASCII_USTRINGPARAM( "FillGradient" ) ) );
+ xPropSet->setPropertyValue( sFillGradient, Any( aGradient ) );
+ }
+ break;
+ case XFILL_HATCH :
+ eFS = com::sun::star::drawing::FillStyle_HATCH;
+ break;
+ case XFILL_BITMAP :
+ {
+ eFS = com::sun::star::drawing::FillStyle_BITMAP;
+
+ XFillBitmapItem aXFillBitmapItem((const XFillBitmapItem&)pObj->GetMergedItem( XATTR_FILLBITMAP ));
+ XOBitmap aLocalXOBitmap( aXFillBitmapItem.GetBitmapValue() );
+ rtl::OUString aURL( RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
+ aURL += rtl::OUString::createFromAscii( aLocalXOBitmap.GetGraphicObject().GetUniqueID().GetBuffer() );
+
+ static const rtl::OUString sFillBitmapURL( String( RTL_CONSTASCII_USTRINGPARAM( "FillBitmapURL" ) ) );
+ xPropSet->setPropertyValue( sFillBitmapURL, Any( aURL ) );
+ }
+ break;
+ case XFILL_NONE :
+ eFS = com::sun::star::drawing::FillStyle_NONE;
+ break;
+
+ }
+ static const rtl::OUString sFillStyle( String( RTL_CONSTASCII_USTRINGPARAM( "FillStyle" ) ) );
+ xPropSet->setPropertyValue( sFillStyle, Any( eFS ) );
+ if ( eFillStyle != XFILL_NONE )
+ {
+ sal_Int16 nFillTransparence( ( (const XFillTransparenceItem&)pObj->GetMergedItem( XATTR_FILLTRANSPARENCE ) ).GetValue() );
+ if ( nFillTransparence != 100 )
+ {
+ nFillTransparence *= 100;
+ static const rtl::OUString sFillTransparence( String( RTL_CONSTASCII_USTRINGPARAM( "FillTransparence" ) ) );
+ xPropSet->setPropertyValue( sFillTransparence, Any( nFillTransparence ) );
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void ApplyCellLineAttributes( const SdrObject* pLine, Reference< XTable >& xTable, const std::vector< sal_Int32 > vPositions, sal_Int32 nColumns )
+{
+ try
+ {
+ SfxItemSet aSet( pLine->GetMergedItemSet() );
+ XLineStyle eLineStyle(((XLineStyleItem&)pLine->GetMergedItem( XATTR_LINESTYLE )).GetValue());
+ com::sun::star::table::BorderLine aBorderLine;
+ switch( eLineStyle )
+ {
+ case XLINE_DASH :
+ case XLINE_SOLID :
+ {
+ Color aLineColor( ((XLineColorItem&)pLine->GetMergedItem( XATTR_LINECOLOR )).GetColorValue() );
+ aBorderLine.Color = aLineColor.GetColor();
+ aBorderLine.OuterLineWidth = static_cast< sal_Int16 >( ((const XLineWidthItem&)(pLine->GetMergedItem(XATTR_LINEWIDTH))).GetValue() / 4 );
+ aBorderLine.InnerLineWidth = static_cast< sal_Int16 >( ((const XLineWidthItem&)(pLine->GetMergedItem(XATTR_LINEWIDTH))).GetValue() / 4 );
+ aBorderLine.LineDistance = 0;
+ }
+ break;
+ case XLINE_NONE :
+ {
+ aBorderLine.OuterLineWidth = 0;
+ aBorderLine.InnerLineWidth = 0;
+ aBorderLine.LineDistance = 0;
+ }
+ break;
+ }
+ Reference< XCellRange > xCellRange( xTable, UNO_QUERY_THROW );
+ std::vector< sal_Int32 >::const_iterator aIter( vPositions.begin() );
+ while( aIter != vPositions.end() )
+ {
+ static const rtl::OUString sTopBorder( String( RTL_CONSTASCII_USTRINGPARAM( "TopBorder" ) ) );
+ static const rtl::OUString sBottomBorder( String( RTL_CONSTASCII_USTRINGPARAM( "BottomBorder" ) ) );
+ static const rtl::OUString sLeftBorder( String( RTL_CONSTASCII_USTRINGPARAM( "LeftBorder" ) ) );
+ static const rtl::OUString sRightBorder( String( RTL_CONSTASCII_USTRINGPARAM( "RightBorder" ) ) );
+ static const rtl::OUString sDiagonalTLBR( RTL_CONSTASCII_USTRINGPARAM ( "DiagonalTLBR" ) );
+ static const rtl::OUString sDiagonalBLTR( RTL_CONSTASCII_USTRINGPARAM ( "DiagonalBLTR" ) );
+
+ sal_Int32 nPosition = *aIter & 0xffffff;
+ sal_Int32 nFlags = *aIter &~0xffffff;
+ sal_Int32 nRow = nPosition / nColumns;
+ sal_Int32 nColumn = nPosition - ( nRow * nColumns );
+ Reference< XCell > xCell( xCellRange->getCellByPosition( nColumn, nRow ) );
+ Reference< XPropertySet > xPropSet( xCell, UNO_QUERY_THROW );
+
+ if ( nFlags & LinePositionLeft )
+ xPropSet->setPropertyValue( sLeftBorder, Any( aBorderLine ) );
+ if ( nFlags & LinePositionTop )
+ xPropSet->setPropertyValue( sTopBorder, Any( aBorderLine ) );
+ if ( nFlags & LinePositionRight )
+ xPropSet->setPropertyValue( sRightBorder, Any( aBorderLine ) );
+ if ( nFlags & LinePositionBottom )
+ xPropSet->setPropertyValue( sBottomBorder, Any( aBorderLine ) );
+ if ( nFlags & LinePositionTLBR )
+ xPropSet->setPropertyValue( sDiagonalTLBR, Any( sal_True ) );
+ if ( nFlags & LinePositionBLTR )
+ xPropSet->setPropertyValue( sDiagonalBLTR, Any( sal_True ) );
+ aIter++;
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+SdrObject* SdrPowerPointImport::CreateTable( SdrObject* pGroup, sal_uInt32* pTableArry, SvxMSDffSolverContainer* pSolverContainer ) const
+{
+ SdrObject* pRet = pGroup;
+ sal_uInt32 nRows = pTableArry[ 1 ];
+ if ( nRows && pGroup->ISA( SdrObjGroup ) )
+ {
+ SdrObjList* pSubList(((SdrObjGroup*)pGroup)->GetSubList());
+ if ( pSubList )
+ {
+ std::set< sal_Int32 > aRows;
+ std::set< sal_Int32 > aColumns;
+
+ SdrObjListIter aGroupIter( *pSubList, IM_DEEPNOGROUPS, FALSE );
+ while( aGroupIter.IsMore() )
+ {
+ const SdrObject* pObj( aGroupIter.Next() );
+ if ( !IsLine( pObj ) )
+ {
+ Rectangle aSnapRect( pObj->GetSnapRect() );
+ aRows.insert( aSnapRect.Top() );
+ aColumns.insert( aSnapRect.Left() );
+ }
+ }
+ ::sdr::table::SdrTableObj* pTable = new ::sdr::table::SdrTableObj( pSdrModel );
+ pTable->uno_lock();
+ Reference< XTable > xTable( pTable->getTable() );
+ try
+ {
+ Reference< XColumnRowRange > xColumnRowRange( xTable, UNO_QUERY_THROW );
+
+ CreateTableRows( xColumnRowRange->getRows(), aRows, pGroup->GetSnapRect().Bottom() );
+ CreateTableColumns( xColumnRowRange->getColumns(), aColumns, pGroup->GetSnapRect().Right() );
+
+ sal_Int32 nCellCount = aRows.size() * aColumns.size();
+ sal_Int32 *pMergedCellIndexTable = new sal_Int32[ nCellCount ];
+ for ( sal_Int32 i = 0; i < nCellCount; i++ )
+ pMergedCellIndexTable[ i ] = i;
+
+ aGroupIter.Reset();
+ while( aGroupIter.IsMore() )
+ {
+ SdrObject* pObj( aGroupIter.Next() );
+ if ( !IsLine( pObj ) )
+ {
+ Rectangle aSnapRect( pObj->GetSnapRect() );
+ sal_Int32 nTableIndex = 0;
+ sal_Int32 nRow = 0;
+ sal_Int32 nRowCount = 0;
+ sal_Int32 nColumn = 0;
+ sal_Int32 nColumnCount = 0;
+ if ( GetCellPosition( pObj, aRows, aColumns, nTableIndex, nRow, nRowCount, nColumn, nColumnCount ) )
+ {
+ Reference< XCellRange > xCellRange( xTable, UNO_QUERY_THROW );
+ Reference< XCell > xCell( xCellRange->getCellByPosition( nColumn, nRow ) );
+
+ ApplyCellAttributes( pObj, xCell );
+
+ if ( ( nRowCount > 1 ) || ( nColumnCount > 1 ) ) // cell merging
+ {
+ MergeCells( xTable, nColumn, nRow, nColumnCount, nRowCount );
+ for ( sal_Int32 nRowIter = 0; nRowIter < nRowCount; nRowIter++ )
+ {
+ for ( sal_Int32 nColumnIter = 0; nColumnIter < nColumnCount; nColumnIter++ )
+ { // now set the correct index for the merged cell
+ pMergedCellIndexTable[ ( ( nRow + nRowIter ) * aColumns.size() ) + nColumn + nColumnIter ] = nTableIndex;
+ }
+ }
+ }
+
+ // applying text
+ OutlinerParaObject* pParaObject = pObj->GetOutlinerParaObject();
+ if ( pParaObject )
+ {
+ SdrText* pSdrText = pTable->getText( nTableIndex );
+ if ( pSdrText )
+ pSdrText->SetOutlinerParaObject(new OutlinerParaObject(*pParaObject) );
+ }
+ }
+ }
+ }
+ aGroupIter.Reset();
+ while( aGroupIter.IsMore() )
+ {
+ SdrObject* pObj( aGroupIter.Next() );
+ if ( IsLine( pObj ) )
+ {
+ std::vector< sal_Int32 > vPositions; // containing cell indexes + cell position
+ GetLinePositions( pObj, aRows, aColumns, vPositions, pGroup->GetSnapRect() );
+
+ // correcting merged cell position
+ std::vector< sal_Int32 >::iterator aIter( vPositions.begin() );
+ while( aIter != vPositions.end() )
+ {
+ sal_Int32 nOldPosition = *aIter & 0xffff;
+ sal_Int32 nOldFlags = *aIter & 0xffff0000;
+ sal_Int32 nNewPosition = pMergedCellIndexTable[ nOldPosition ] | nOldFlags;
+ *aIter++ = nNewPosition;
+ }
+ ApplyCellLineAttributes( pObj, xTable, vPositions, aColumns.size() );
+ }
+ }
+ delete[] pMergedCellIndexTable;
+
+ // we are replacing the whole group object by a single table object, so
+ // possibly connections to the group object have to be removed.
+ if ( pSolverContainer )
+ {
+ for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)pSolverContainer->aCList.First();
+ pPtr; pPtr = (SvxMSDffConnectorRule*)pSolverContainer->aCList.Next() )
+ {
+ SdrObjListIter aIter( *pGroup, IM_DEEPWITHGROUPS );
+ while( aIter.IsMore() )
+ {
+ SdrObject* pPartObj = aIter.Next();
+ if ( pPtr->pAObj == pPartObj )
+ pPtr->pAObj = NULL;
+ if ( pPtr->pBObj == pPartObj )
+ pPtr->pBObj = NULL;
+ }
+ }
+ }
+ pTable->uno_unlock();
+ pTable->SetSnapRect( pGroup->GetSnapRect() );
+ pRet = pTable;
+ SdrObject::Free( pGroup );
+ }
+ catch( Exception& )
+ {
+ pTable->uno_unlock();
+ SdrObject* pObj = pTable;
+ SdrObject::Free( pObj );
+ }
+ }
+ }
+ return pRet;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/filter/source/msfilter/svxmsbas.cxx b/filter/source/msfilter/svxmsbas.cxx
new file mode 100644
index 000000000000..02370dd75c92
--- /dev/null
+++ b/filter/source/msfilter/svxmsbas.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svxmsbas.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * 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_filter.hxx"
+
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+#include <tools/debug.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/app.hxx>
+#include <basic/basmgr.hxx>
+#include <basic/sbmod.hxx>
+#include <svx/svxerr.hxx>
+#include <filter/msfilter/svxmsbas.hxx>
+#include <msvbasic.hxx>
+#include <filter/msfilter/msocximex.hxx>
+#include <sot/storinfo.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+using namespace com::sun::star::beans;
+using namespace com::sun::star::io;
+using namespace com::sun::star::awt;
+#include <comphelper/storagehelper.hxx>
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+using namespace com::sun::star::container;
+using namespace com::sun::star::script;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star;
+
+using rtl::OUString;
+
+int SvxImportMSVBasic::Import( const String& rStorageName,
+ const String &rSubStorageName,
+ BOOL bAsComment, BOOL bStripped )
+{
+ int nRet = 0;
+ if( bImport && ImportCode_Impl( rStorageName, rSubStorageName,
+ bAsComment, bStripped ))
+ nRet |= 1;
+
+ if (bImport)
+ ImportForms_Impl(rStorageName, rSubStorageName);
+
+ if( bCopy && CopyStorage_Impl( rStorageName, rSubStorageName ))
+ nRet |= 2;
+
+ return nRet;
+}
+
+bool SvxImportMSVBasic::ImportForms_Impl(const String& rStorageName,
+ const String& rSubStorageName)
+{
+ SvStorageRef xVBAStg(xRoot->OpenSotStorage(rStorageName,
+ STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL));
+ if (!xVBAStg.Is() || xVBAStg->GetError())
+ return false;
+
+ std::vector<String> aUserForms;
+ SvStorageInfoList aContents;
+ xVBAStg->FillInfoList(&aContents);
+ for (USHORT nI = 0; nI < aContents.Count(); ++nI)
+ {
+ SvStorageInfo& rInfo = aContents.GetObject(nI);
+ if (!rInfo.IsStream() && rInfo.GetName() != rSubStorageName)
+ aUserForms.push_back(rInfo.GetName());
+ }
+
+ if (aUserForms.empty())
+ return false;
+
+ bool bRet = true;
+ SFX_APP()->EnterBasicCall();
+ try
+ {
+ Reference<XMultiServiceFactory> xSF(comphelper::getProcessServiceFactory());
+
+ Reference<XComponentContext> xContext;
+ Reference<XPropertySet> xProps(xSF, UNO_QUERY);
+ xProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")) ) >>= xContext;
+
+
+ Reference<XLibraryContainer> xLibContainer = rDocSh.GetDialogContainer();
+ DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
+
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ Reference<XNameContainer> xLib;
+ if (xLibContainer.is())
+ {
+ if( !xLibContainer->hasByName(aLibName))
+ xLibContainer->createLibrary(aLibName);
+
+ Any aLibAny = xLibContainer->getByName( aLibName );
+ aLibAny >>= xLib;
+ }
+
+ if(xLib.is())
+ {
+ typedef std::vector<String>::iterator myIter;
+ myIter aEnd = aUserForms.end();
+ for (myIter aIter = aUserForms.begin(); aIter != aEnd; ++aIter)
+ {
+ SvStorageRef xForm (xVBAStg->OpenSotStorage(*aIter,
+ STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL));
+
+ if (!xForm.Is() || xForm->GetError())
+ continue;
+
+ SvStorageStreamRef xFrame = xForm->OpenSotStream(
+ String( RTL_CONSTASCII_USTRINGPARAM( "\3VBFrame" ) ),
+ STREAM_STD_READ | STREAM_NOCREATE);
+
+ if (!xFrame.Is() || xFrame->GetError())
+ continue;
+
+ SvStorageStreamRef xTypes = xForm->OpenSotStream(
+ String( 'f' ), STREAM_STD_READ | STREAM_NOCREATE);
+
+ if (!xTypes.Is() || xTypes->GetError())
+ continue;
+
+ //<UserForm Name=""><VBFrame></VBFrame>"
+ String sData;
+ String sLine;
+ while(xFrame->ReadByteStringLine(sLine, RTL_TEXTENCODING_MS_1252))
+ {
+ sData += sLine;
+ sData += '\n';
+ }
+ sData.ConvertLineEnd();
+
+ Reference<container::XNameContainer> xDialog(
+ xSF->createInstance(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.awt.UnoControlDialogModel"))), uno::UNO_QUERY);
+
+ OCX_UserForm aForm(xVBAStg, *aIter, *aIter, xDialog, xSF );
+ aForm.pDocSh = &rDocSh;
+ sal_Bool bOk = aForm.Read(xTypes);
+ DBG_ASSERT(bOk, "Had unexpected content, not risking this module");
+ if (bOk)
+ aForm.Import(xLib);
+ }
+ }
+ }
+ catch(...)
+ {
+ DBG_ERRORFILE( "SvxImportMSVBasic::ImportForms_Impl - any exception caught" );
+ //bRet = false;
+ }
+ SFX_APP()->LeaveBasicCall();
+ return bRet;
+}
+
+
+BOOL SvxImportMSVBasic::CopyStorage_Impl( const String& rStorageName,
+ const String& rSubStorageName)
+{
+ BOOL bValidStg = FALSE;
+ {
+ SvStorageRef xVBAStg( xRoot->OpenSotStorage( rStorageName,
+ STREAM_READWRITE | STREAM_NOCREATE |
+ STREAM_SHARE_DENYALL ));
+ if( xVBAStg.Is() && !xVBAStg->GetError() )
+ {
+ SvStorageRef xVBASubStg( xVBAStg->OpenSotStorage( rSubStorageName,
+ STREAM_READWRITE | STREAM_NOCREATE |
+ STREAM_SHARE_DENYALL ));
+ if( xVBASubStg.Is() && !xVBASubStg->GetError() )
+ {
+ // then we will copy these storages into the (temporary) storage of the document
+ bValidStg = TRUE;
+ }
+ }
+ }
+
+ if( bValidStg )
+ {
+ String aDstStgName( GetMSBasicStorageName() );
+ SotStorageRef xDst = SotStorage::OpenOLEStorage( rDocSh.GetStorage(), aDstStgName, STREAM_READWRITE | STREAM_TRUNC );
+ SotStorageRef xSrc = xRoot->OpenSotStorage( rStorageName, STREAM_STD_READ );
+
+ // TODO/LATER: should we commit the storage?
+ xSrc->CopyTo( xDst );
+ xDst->Commit();
+ ErrCode nError = xDst->GetError();
+ if ( nError == ERRCODE_NONE )
+ nError = xSrc->GetError();
+ if ( nError != ERRCODE_NONE )
+ xRoot->SetError( nError );
+ else
+ bValidStg = TRUE;
+ }
+
+ return bValidStg;
+}
+
+BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
+ const String &rSubStorageName,
+ BOOL bAsComment, BOOL bStripped )
+{
+ BOOL bRet = FALSE;
+ VBA_Impl aVBA( *xRoot, bAsComment );
+ if( aVBA.Open(rStorageName,rSubStorageName) )
+ {
+ SFX_APP()->EnterBasicCall();
+ Reference<XLibraryContainer> xLibContainer = rDocSh.GetBasicContainer();
+ DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
+
+ UINT16 nStreamCount = aVBA.GetNoStreams();
+ Reference<XNameContainer> xLib;
+ if( xLibContainer.is() && nStreamCount )
+ {
+ String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if( !xLibContainer->hasByName( aLibName ) )
+ xLibContainer->createLibrary( aLibName );
+
+ Any aLibAny = xLibContainer->getByName( aLibName );
+ aLibAny >>= xLib;
+ }
+ if( xLib.is() )
+ {
+ for( UINT16 i=0; i<nStreamCount;i++)
+ {
+ StringArray aDecompressed = aVBA.Decompress(i);
+#if 0
+/* DR 2005-08-11 #124850# Do not filter special characters from module name.
+ Just put the original module name and let the Basic interpreter deal with
+ it. Needed for roundtrip...
+ */
+ ByteString sByteBasic(aVBA.GetStreamName(i),
+ RTL_TEXTENCODING_ASCII_US,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE|
+ RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 |
+ RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE)
+ );
+
+ const String sBasicModule(sByteBasic,
+ RTL_TEXTENCODING_ASCII_US);
+#else
+ const String &sBasicModule = aVBA.GetStreamName( i);
+#endif
+ /* #117718# expose information regarding type of Module
+ * Class, Form or plain 'ould VBA module with a REM statment
+ * at the top of the module. Mapping of Module Name
+ * to type is performed in VBA_Impl::Open() method,
+ * ( msvbasic.cxx ) by examining the PROJECT stream.
+ */
+
+ // using name from aVBA.GetStreamName
+ // because the encoding of the same returned
+ // is the same as the encoding for the names
+ // that are keys in the map used by GetModuleType method
+ const String &sOrigVBAModName = aVBA.GetStreamName( i );
+ ModuleType mType = aVBA.GetModuleType( sOrigVBAModName );
+
+ rtl::OUString sClassRem( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=" ) );
+
+ rtl::OUString modeTypeComment;
+
+ switch( mType )
+ {
+ case Class:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAClassModule\n" ) );
+ break;
+ case Form:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAFormModule\n" ) );
+ break;
+ case Document:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBADocumentModule\n" ) );
+ break;
+ case Normal:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAModule\n" ) );
+ break;
+ case Unknown:
+ modeTypeComment = sClassRem +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAUnknown\n" ) );
+ break;
+ default:
+ DBG_ERRORFILE( "SvxImportMSVBasic::ImportCode_Impl - unknown module type" );
+ break;
+ }
+ static ::rtl::OUString sVBAOption( RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) );
+ static ::rtl::OUString sClassOption( RTL_CONSTASCII_USTRINGPARAM( "Option ClassModule\n" ) );
+ if ( !bAsComment )
+ {
+ modeTypeComment = modeTypeComment + sVBAOption;
+ if ( mType == Class )
+ modeTypeComment = modeTypeComment + sClassOption;
+
+ }
+
+ String sModule(sBasicModule); //#i52606# no need to split Macros in 64KB blocks any more!
+ String sTemp;
+ if (bAsComment)
+ {
+ sTemp+=String(RTL_CONSTASCII_USTRINGPARAM( "Sub " ));
+ String sMunge(sModule);
+ //Streams can have spaces in them, but modulenames
+ //cannot !
+ sMunge.SearchAndReplaceAll(' ','_');
+
+ sTemp += sMunge;
+ sTemp.AppendAscii("\n");
+ };
+ ::rtl::OUString aSource(sTemp);
+
+ for(ULONG j=0;j<aDecompressed.GetSize();j++)
+ {
+ if (bStripped)
+ {
+ String *pStr = aDecompressed.Get(j);
+ bool bMac = true;
+ xub_StrLen nBegin = pStr->Search('\x0D');
+ if ((STRING_NOTFOUND != nBegin) && (pStr->Len() > 1) && (pStr->GetChar(nBegin+1) == '\x0A'))
+ bMac = false;
+
+ const char cLineEnd = bMac ? '\x0D' : '\x0A';
+ const String sAttribute(String::CreateFromAscii(
+ bAsComment ? "Rem Attribute" : "Attribute"));
+ nBegin = 0;
+ while (STRING_NOTFOUND != (nBegin = pStr->Search(sAttribute, nBegin)))
+ {
+ if ((nBegin) && pStr->GetChar(nBegin-1) != cLineEnd)
+ {
+ // npower #i63766# Need to skip instances of Attribute
+ // that are NOT Attribute statements
+ nBegin = nBegin + sAttribute.Len();
+ continue;
+ }
+ xub_StrLen nEnd = pStr->Search(cLineEnd ,nBegin);
+ // DR #i26521# catch STRING_NOTFOUND, will loop endless otherwise
+ if( nEnd == STRING_NOTFOUND )
+ pStr->Erase();
+ else
+ pStr->Erase(nBegin, (nEnd-nBegin)+1);
+ }
+ }
+ if( aDecompressed.Get(j)->Len() )
+ {
+ aSource+=::rtl::OUString( *aDecompressed.Get(j) );
+ }
+
+ }
+ if (bAsComment)
+ {
+ aSource += rtl::OUString::createFromAscii("\nEnd Sub");
+ }
+ ::rtl::OUString aModName( sModule );
+ if ( aSource.getLength() )
+ {
+ aSource = modeTypeComment + aSource;
+
+ Any aSourceAny;
+ aSourceAny <<= aSource;
+ if( xLib->hasByName( aModName ) )
+ xLib->replaceByName( aModName, aSourceAny );
+ else
+ xLib->insertByName( aModName, aSourceAny );
+ }
+
+ bRet = true;
+ }
+ }
+ SFX_APP()->LeaveBasicCall();
+ }
+ return bRet;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/filter/source/msfilter/svxmsbas2.cxx b/filter/source/msfilter/svxmsbas2.cxx
new file mode 100644
index 000000000000..6e784811dd56
--- /dev/null
+++ b/filter/source/msfilter/svxmsbas2.cxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: svxmsbas.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * 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_filter.hxx"
+
+#include <basic/basmgr.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/svxerr.hxx>
+#include <filter/msfilter/svxmsbas.hxx>
+
+using namespace com::sun::star;
+
+ULONG SvxImportMSVBasic::SaveOrDelMSVBAStorage( BOOL bSaveInto,
+ const String& rStorageName )
+{
+ ULONG nRet = ERRCODE_NONE;
+ uno::Reference < embed::XStorage > xSrcRoot( rDocSh.GetStorage() );
+ String aDstStgName( GetMSBasicStorageName() );
+ SotStorageRef xVBAStg( SotStorage::OpenOLEStorage( xSrcRoot, aDstStgName,
+ STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL ) );
+ if( xVBAStg.Is() && !xVBAStg->GetError() )
+ {
+ xVBAStg = 0;
+ if( bSaveInto )
+ {
+ BasicManager *pBasicMan = rDocSh.GetBasicManager();
+ if( pBasicMan && pBasicMan->IsBasicModified() )
+ nRet = ERRCODE_SVX_MODIFIED_VBASIC_STORAGE;
+
+ SotStorageRef xSrc = SotStorage::OpenOLEStorage( xSrcRoot, aDstStgName, STREAM_STD_READ );
+ SotStorageRef xDst = xRoot->OpenSotStorage( rStorageName, STREAM_READWRITE | STREAM_TRUNC );
+ xSrc->CopyTo( xDst );
+ xDst->Commit();
+ ErrCode nError = xDst->GetError();
+ if ( nError == ERRCODE_NONE )
+ nError = xSrc->GetError();
+ if ( nError != ERRCODE_NONE )
+ xRoot->SetError( nError );
+ }
+ }
+
+ return nRet;
+}
+
+// check if the MS-VBA-Storage exists in the RootStorage of the DocShell.
+// If it exists, then return the WarningId for losing the information.
+ULONG SvxImportMSVBasic::GetSaveWarningOfMSVBAStorage( SfxObjectShell &rDocSh)
+{
+ uno::Reference < embed::XStorage > xSrcRoot( rDocSh.GetStorage() );
+ SvStorageRef xVBAStg( SotStorage::OpenOLEStorage( xSrcRoot, GetMSBasicStorageName(),
+ STREAM_READ | STREAM_NOCREATE | STREAM_SHARE_DENYALL ));
+ return ( xVBAStg.Is() && !xVBAStg->GetError() )
+ ? ERRCODE_SVX_VBASIC_STORAGE_EXIST
+ : ERRCODE_NONE;
+}
+
+String SvxImportMSVBasic::GetMSBasicStorageName()
+{
+ return String( RTL_CONSTASCII_USTRINGPARAM( "_MS_VBA_Macros" ) );
+}
diff --git a/filter/source/msfilter/viscache.hxx b/filter/source/msfilter/viscache.hxx
new file mode 100644
index 000000000000..ceea10e28f27
--- /dev/null
+++ b/filter/source/msfilter/viscache.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viscache.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * 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 <tools/stream.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/bitmap.hxx>
+
+/************************************************************************
+|* Impl_CacheElement
+|* Impl_Cache
+|*
+|* Beschreibung
+*************************************************************************/
+class Impl_OlePres
+{
+ ULONG nFormat;
+ USHORT nAspect;
+ Bitmap * pBmp;
+ GDIMetaFile * pMtf;
+
+ UINT32 nAdvFlags;
+ INT32 nJobLen;
+ BYTE* pJob;
+ Size aSize; // Groesse in 100TH_MM
+public:
+ Impl_OlePres( ULONG nF )
+ : nFormat( nF )
+ , pBmp( NULL )
+ , pMtf( NULL )
+ , nAdvFlags( 0x2 ) // in Dokument gefunden
+ , nJobLen( 0 )
+ , pJob( NULL )
+ {}
+ ~Impl_OlePres()
+ {
+ delete pJob;
+ delete pBmp;
+ delete pMtf;
+ }
+ void SetMtf( const GDIMetaFile & rMtf )
+ {
+ if( pMtf )
+ delete pMtf;
+ pMtf = new GDIMetaFile( rMtf );
+ }
+ Bitmap *GetBitmap() const { return pBmp; }
+ GDIMetaFile *GetMetaFile() const { return pMtf; }
+ ULONG GetFormat() const { return nFormat; }
+ void SetAspect( USHORT nAsp ) { nAspect = nAsp; }
+ ULONG GetAdviseFlags() const { return nAdvFlags; }
+ void SetAdviseFlags( ULONG nAdv ) { nAdvFlags = nAdv; }
+ void SetSize( const Size & rSize ) { aSize = rSize; }
+ /// return FALSE => unknown format
+ BOOL Read( SvStream & rStm );
+ void Write( SvStream & rStm );
+};
+
+