xref: /trunk/main/sc/source/ui/unoobj/cellsuno.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 #include "scitems.hxx"
33 #include <editeng/eeitem.hxx>
34 #include <svx/svdpool.hxx>
35 
36 #include <svx/algitem.hxx>
37 #include <editeng/boxitem.hxx>
38 #include <editeng/brshitem.hxx>
39 #include <editeng/editeng.hxx>
40 #include <editeng/flditem.hxx>
41 #include <svx/fmdpage.hxx>
42 #include <editeng/langitem.hxx>
43 #include <sfx2/linkmgr.hxx>
44 #include <svl/srchitem.hxx>
45 #include <svx/unomid.hxx>
46 #include <editeng/unoprnms.hxx>
47 #include <editeng/unotext.hxx>
48 #include <svx/svdpage.hxx>
49 #include <sfx2/bindings.hxx>
50 #include <svl/zforlist.hxx>
51 #include <svl/zformat.hxx>
52 #include <rtl/uuid.h>
53 #include <float.h>              // DBL_MIN
54 
55 #include <com/sun/star/awt/XBitmap.hpp>
56 #include <com/sun/star/util/CellProtection.hpp>
57 #include <com/sun/star/table/CellHoriJustify.hpp>
58 #include <com/sun/star/table/CellOrientation.hpp>
59 #include <com/sun/star/table/CellVertJustify.hpp>
60 #include <com/sun/star/table/ShadowFormat.hpp>
61 #include <com/sun/star/table/TableBorder.hpp>
62 #include <com/sun/star/sheet/CellFlags.hpp>
63 #include <com/sun/star/sheet/FormulaResult.hpp>
64 #include <com/sun/star/beans/PropertyAttribute.hpp>
65 #include <com/sun/star/lang/Locale.hpp>
66 #include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
67 #include <com/sun/star/beans/SetPropertyTolerantFailed.hpp>
68 #include <com/sun/star/text/WritingMode2.hpp>
69 
70 #include "autoform.hxx"
71 #include "cellsuno.hxx"
72 #include "cursuno.hxx"
73 #include "textuno.hxx"
74 #include "editsrc.hxx"
75 #include "notesuno.hxx"
76 #include "fielduno.hxx"
77 #include "docuno.hxx"       // ScTableColumnsObj etc
78 #include "datauno.hxx"
79 #include "dapiuno.hxx"
80 #include "chartuno.hxx"
81 #include "fmtuno.hxx"
82 #include "miscuno.hxx"
83 #include "convuno.hxx"
84 #include "srchuno.hxx"
85 #include "targuno.hxx"
86 #include "tokenuno.hxx"
87 #include "eventuno.hxx"
88 #include "docsh.hxx"
89 #include "markdata.hxx"
90 #include "patattr.hxx"
91 #include "docpool.hxx"
92 #include "docfunc.hxx"
93 #include "dbdocfun.hxx"
94 #include "olinefun.hxx"
95 #include "hints.hxx"
96 #include "cell.hxx"
97 #include "undocell.hxx"
98 #include "undotab.hxx"
99 #include "undoblk.hxx"      // fuer lcl_ApplyBorder - nach docfunc verschieben!
100 #include "stlsheet.hxx"
101 #include "dbcolect.hxx"
102 #include "attrib.hxx"
103 #include "chartarr.hxx"
104 #include "chartlis.hxx"
105 #include "drwlayer.hxx"
106 #include "printfun.hxx"
107 #include "prnsave.hxx"
108 #include "tablink.hxx"
109 #include "dociter.hxx"
110 #include "rangeutl.hxx"
111 #include "conditio.hxx"
112 #include "validat.hxx"
113 #include "sc.hrc"
114 #include "brdcst.hxx"
115 #include "unoguard.hxx"
116 #include "cellform.hxx"
117 #include "globstr.hrc"
118 #include "unonames.hxx"
119 #include "styleuno.hxx"
120 #include "rangeseq.hxx"
121 #include "unowids.hxx"
122 #include "paramisc.hxx"
123 #include "formula/errorcodes.hxx"
124 #include "unoreflist.hxx"
125 #include "formula/grammar.hxx"
126 
127 #include <list>
128 
129 using namespace com::sun::star;
130 
131 //------------------------------------------------------------------------
132 
133 
134 class ScNamedEntry
135 {
136     String  aName;
137     ScRange aRange;
138 
139 public:
140             ScNamedEntry(const String& rN, const ScRange& rR) :
141                 aName(rN), aRange(rR) {}
142 
143     const String&   GetName() const     { return aName; }
144     const ScRange&  GetRange() const    { return aRange; }
145 };
146 
147 
148 //------------------------------------------------------------------------
149 
150 //  Die Namen in den Maps muessen (nach strcmp) sortiert sein!
151 //! statt Which-ID 0 special IDs verwenden, und nicht ueber Namen vergleichen !!!!!!!!!
152 
153 //  Left/Right/Top/BottomBorder are mapped directly to the core items,
154 //  not collected/applied to the borders of a range -> ATTR_BORDER can be used directly
155 
156 const SfxItemPropertySet* lcl_GetCellsPropertySet()
157 {
158     static SfxItemPropertyMapEntry aCellsPropertyMap_Impl[] =
159     {
160         {MAP_CHAR_LEN(SC_UNONAME_ABSNAME),  SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0),        0 | beans::PropertyAttribute::READONLY, 0 },
161         {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(),                  0, 0 },
162         {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
163         {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND,    &getCppuType((sal_Int32*)0),            0, MID_BACK_COLOR },
164         {MAP_CHAR_LEN(SC_UNONAME_CELLPRO),  ATTR_PROTECTION,    &getCppuType((util::CellProtection*)0), 0, 0 },
165         {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0),        0, 0 },
166         {MAP_CHAR_LEN(SC_UNONAME_CCOLOR),   ATTR_FONT_COLOR,    &getCppuType((sal_Int32*)0),            0, 0 },
167         {MAP_CHAR_LEN(SC_UNONAME_COUTL),    ATTR_FONT_CONTOUR,  &getBooleanCppuType(),                  0, 0 },
168         {MAP_CHAR_LEN(SC_UNONAME_CCROSS),   ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(),                 0, MID_CROSSED_OUT },
169         {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS),  ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0),         0, MID_EMPHASIS },
170         {MAP_CHAR_LEN(SC_UNONAME_CFONT),    ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
171         {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
172         {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
173         {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
174         {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
175         {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
176         {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
177         {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
178         {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
179         {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
180         {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
181         {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
182         {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
183         {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
184         {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
185         {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
186         {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT),  ATTR_FONT_HEIGHT,   &getCppuType((float*)0),                0, MID_FONTHEIGHT | CONVERT_TWIPS },
187         {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT),  ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
188         {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT),  ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
189         {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),   ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0),         0, MID_LANG_LOCALE },
190         {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),   ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
191         {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),   ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
192         {MAP_CHAR_LEN(SC_UNONAME_COVER),    ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
193         {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
194         {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
195         {MAP_CHAR_LEN(SC_UNONAME_CPOST),    ATTR_FONT_POSTURE,  &getCppuType((awt::FontSlant*)0),       0, MID_POSTURE },
196         {MAP_CHAR_LEN(SC_UNO_CJK_CPOST),    ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
197         {MAP_CHAR_LEN(SC_UNO_CTL_CPOST),    ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
198         {MAP_CHAR_LEN(SC_UNONAME_CRELIEF),  ATTR_FONT_RELIEF,   &getCppuType((sal_Int16*)0),            0, MID_RELIEF },
199         {MAP_CHAR_LEN(SC_UNONAME_CSHADD),   ATTR_FONT_SHADOWED, &getBooleanCppuType(),                  0, 0 },
200         {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE),  ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0),           0, MID_CROSS_OUT },
201         {MAP_CHAR_LEN(SC_UNONAME_CUNDER),   ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
202         {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
203         {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
204         {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT),  ATTR_FONT_WEIGHT,   &getCppuType((float*)0),                0, MID_WEIGHT },
205         {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT),  ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
206         {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT),  ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
207         {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(),                  0, 0 },
208         {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(),                  0, 0 },
209         {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(),                  0, 0 },
210         {MAP_CHAR_LEN(SC_UNONAME_CONDFMT),  SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
211         {MAP_CHAR_LEN(SC_UNONAME_CONDLOC),  SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
212         {MAP_CHAR_LEN(SC_UNONAME_CONDXML),  SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
213         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
214         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
215         {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY,   &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
216         {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND,    &getBooleanCppuType(),                  0, MID_GRAPHIC_TRANSPARENT },
217         {MAP_CHAR_LEN(SC_UNONAME_WRAP),     ATTR_LINEBREAK,     &getBooleanCppuType(),                  0, 0 },
218         {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
219         {MAP_CHAR_LEN(SC_UNONAME_NUMFMT),   ATTR_VALUE_FORMAT,  &getCppuType((sal_Int32*)0),            0, 0 },
220         {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
221         {MAP_CHAR_LEN(SC_UNONAME_CELLORI),  ATTR_STACKED,       &getCppuType((table::CellOrientation*)0), 0, 0 },
222         {MAP_CHAR_LEN(SC_UNONAME_PADJUST),  ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
223         {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
224         {MAP_CHAR_LEN(SC_UNONAME_PINDENT),  ATTR_INDENT,        &getCppuType((sal_Int16*)0),            0, 0 }, //! CONVERT_TWIPS
225         {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE,   &getBooleanCppuType(),                  0, 0 },
226         {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(),                 0, 0 },
227         {MAP_CHAR_LEN(SC_UNONAME_PISHANG),  ATTR_HANGPUNCTUATION,&getBooleanCppuType(),                 0, 0 },
228         {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE,     &getBooleanCppuType(),                  0, 0 },
229         {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
230         {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_L_MARGIN  | CONVERT_TWIPS },
231         {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_R_MARGIN  | CONVERT_TWIPS },
232         {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
233         {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER,      &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
234         {MAP_CHAR_LEN(SC_UNONAME_ROTANG),   ATTR_ROTATE_VALUE,  &getCppuType((sal_Int32*)0),            0, 0 },
235         {MAP_CHAR_LEN(SC_UNONAME_ROTREF),   ATTR_ROTATE_MODE,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
236         {MAP_CHAR_LEN(SC_UNONAME_SHADOW),   ATTR_SHADOW,        &getCppuType((table::ShadowFormat*)0),  0, 0 | CONVERT_TWIPS },
237         {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(),               0, 0 },
238         {MAP_CHAR_LEN(SC_UNONAME_TBLBORD),  SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0),   0, 0 | CONVERT_TWIPS },
239         {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER,        &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
240         {MAP_CHAR_LEN(SC_UNONAME_USERDEF),  ATTR_USERDEF,       &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
241         {MAP_CHAR_LEN(SC_UNONAME_VALIDAT),  SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
242         {MAP_CHAR_LEN(SC_UNONAME_VALILOC),  SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
243         {MAP_CHAR_LEN(SC_UNONAME_VALIXML),  SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
244         {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
245         {MAP_CHAR_LEN(SC_UNONAME_WRITING),  ATTR_WRITINGDIR,    &getCppuType((sal_Int16*)0),            0, 0 },
246         {0,0,0,0,0,0}
247     };
248     static SfxItemPropertySet aCellsPropertySet( aCellsPropertyMap_Impl );
249     return &aCellsPropertySet;
250 }
251 
252 //  CellRange enthaelt alle Eintraege von Cells, zusaetzlich eigene Eintraege
253 //  mit Which-ID 0 (werden nur fuer getPropertySetInfo benoetigt).
254 
255 const SfxItemPropertySet* lcl_GetRangePropertySet()
256 {
257     static SfxItemPropertyMapEntry aRangePropertyMap_Impl[] =
258     {
259         {MAP_CHAR_LEN(SC_UNONAME_ABSNAME),  SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0),        0 | beans::PropertyAttribute::READONLY, 0 },
260         {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(),                  0, 0 },
261         {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
262         {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND,    &getCppuType((sal_Int32*)0),            0, MID_BACK_COLOR },
263         {MAP_CHAR_LEN(SC_UNONAME_CELLPRO),  ATTR_PROTECTION,    &getCppuType((util::CellProtection*)0), 0, 0 },
264         {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0),        0, 0 },
265         {MAP_CHAR_LEN(SC_UNONAME_CCOLOR),   ATTR_FONT_COLOR,    &getCppuType((sal_Int32*)0),            0, 0 },
266         {MAP_CHAR_LEN(SC_UNONAME_COUTL),    ATTR_FONT_CONTOUR,  &getBooleanCppuType(),                  0, 0 },
267         {MAP_CHAR_LEN(SC_UNONAME_CCROSS),   ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(),                 0, MID_CROSSED_OUT },
268         {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS),  ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0),         0, MID_EMPHASIS },
269         {MAP_CHAR_LEN(SC_UNONAME_CFONT),    ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
270         {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
271         {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
272         {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
273         {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
274         {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
275         {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
276         {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
277         {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
278         {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
279         {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
280         {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
281         {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
282         {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
283         {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
284         {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
285         {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT),  ATTR_FONT_HEIGHT,   &getCppuType((float*)0),                0, MID_FONTHEIGHT | CONVERT_TWIPS },
286         {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT),  ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
287         {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT),  ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
288         {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),   ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0),         0, MID_LANG_LOCALE },
289         {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),   ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
290         {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),   ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
291         {MAP_CHAR_LEN(SC_UNONAME_COVER),    ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
292         {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
293         {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
294         {MAP_CHAR_LEN(SC_UNONAME_CPOST),    ATTR_FONT_POSTURE,  &getCppuType((awt::FontSlant*)0),       0, MID_POSTURE },
295         {MAP_CHAR_LEN(SC_UNO_CJK_CPOST),    ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
296         {MAP_CHAR_LEN(SC_UNO_CTL_CPOST),    ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
297         {MAP_CHAR_LEN(SC_UNONAME_CRELIEF),  ATTR_FONT_RELIEF,   &getCppuType((sal_Int16*)0),            0, MID_RELIEF },
298         {MAP_CHAR_LEN(SC_UNONAME_CSHADD),   ATTR_FONT_SHADOWED, &getBooleanCppuType(),                  0, 0 },
299         {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE),  ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0),           0, MID_CROSS_OUT },
300         {MAP_CHAR_LEN(SC_UNONAME_CUNDER),   ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
301         {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
302         {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
303         {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT),  ATTR_FONT_WEIGHT,   &getCppuType((float*)0),                0, MID_WEIGHT },
304         {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT),  ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
305         {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT),  ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
306         {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(),                  0, 0 },
307         {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(),                  0, 0 },
308         {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(),                  0, 0 },
309         {MAP_CHAR_LEN(SC_UNONAME_CONDFMT),  SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
310         {MAP_CHAR_LEN(SC_UNONAME_CONDLOC),  SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
311         {MAP_CHAR_LEN(SC_UNONAME_CONDXML),  SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
312         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
313         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
314         {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY,   &getCppuType((table::CellHoriJustify*)0),   0, MID_HORJUST_HORJUST },
315         {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND,    &getBooleanCppuType(),                  0, MID_GRAPHIC_TRANSPARENT },
316         {MAP_CHAR_LEN(SC_UNONAME_WRAP),     ATTR_LINEBREAK,     &getBooleanCppuType(),                  0, 0 },
317         {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
318         {MAP_CHAR_LEN(SC_UNONAME_NUMFMT),   ATTR_VALUE_FORMAT,  &getCppuType((sal_Int32*)0),            0, 0 },
319         {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
320         {MAP_CHAR_LEN(SC_UNONAME_CELLORI),  ATTR_STACKED,       &getCppuType((table::CellOrientation*)0), 0, 0 },
321         {MAP_CHAR_LEN(SC_UNONAME_PADJUST),  ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
322         {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
323         {MAP_CHAR_LEN(SC_UNONAME_PINDENT),  ATTR_INDENT,        &getCppuType((sal_Int16*)0),            0, 0 }, //! CONVERT_TWIPS
324         {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE,   &getBooleanCppuType(),                  0, 0 },
325         {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(),                 0, 0 },
326         {MAP_CHAR_LEN(SC_UNONAME_PISHANG),  ATTR_HANGPUNCTUATION,&getBooleanCppuType(),                 0, 0 },
327         {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE,     &getBooleanCppuType(),                  0, 0 },
328         {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
329         {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_L_MARGIN  | CONVERT_TWIPS },
330         {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_R_MARGIN  | CONVERT_TWIPS },
331         {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
332         {MAP_CHAR_LEN(SC_UNONAME_POS),      SC_WID_UNO_POS,     &getCppuType((awt::Point*)0),           0 | beans::PropertyAttribute::READONLY, 0 },
333         {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER,      &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
334         {MAP_CHAR_LEN(SC_UNONAME_ROTANG),   ATTR_ROTATE_VALUE,  &getCppuType((sal_Int32*)0),            0, 0 },
335         {MAP_CHAR_LEN(SC_UNONAME_ROTREF),   ATTR_ROTATE_MODE,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
336         {MAP_CHAR_LEN(SC_UNONAME_SHADOW),   ATTR_SHADOW,        &getCppuType((table::ShadowFormat*)0),  0, 0 | CONVERT_TWIPS },
337         {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(),               0, 0 },
338         {MAP_CHAR_LEN(SC_UNONAME_SIZE),     SC_WID_UNO_SIZE,    &getCppuType((awt::Size*)0),            0 | beans::PropertyAttribute::READONLY, 0 },
339         {MAP_CHAR_LEN(SC_UNONAME_TBLBORD),  SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0),   0, 0 | CONVERT_TWIPS },
340         {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER,        &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
341         {MAP_CHAR_LEN(SC_UNONAME_USERDEF),  ATTR_USERDEF,       &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
342         {MAP_CHAR_LEN(SC_UNONAME_VALIDAT),  SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
343         {MAP_CHAR_LEN(SC_UNONAME_VALILOC),  SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
344         {MAP_CHAR_LEN(SC_UNONAME_VALIXML),  SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
345         {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
346         {MAP_CHAR_LEN(SC_UNONAME_WRITING),  ATTR_WRITINGDIR,    &getCppuType((sal_Int16*)0),            0, 0 },
347         {0,0,0,0,0,0}
348     };
349     static SfxItemPropertySet aRangePropertySet( aRangePropertyMap_Impl );
350     return &aRangePropertySet;
351 }
352 
353 //  Cell enthaelt alle Eintraege von CellRange, zusaetzlich eigene Eintraege
354 //  mit Which-ID 0 (werden nur fuer getPropertySetInfo benoetigt).
355 
356 const SfxItemPropertySet* lcl_GetCellPropertySet()
357 {
358     static SfxItemPropertyMapEntry aCellPropertyMap_Impl[] =
359     {
360         {MAP_CHAR_LEN(SC_UNONAME_ABSNAME),  SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0),        0 | beans::PropertyAttribute::READONLY, 0 },
361         {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(),                  0, 0 },
362         {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
363         {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND,    &getCppuType((sal_Int32*)0),            0, MID_BACK_COLOR },
364         {MAP_CHAR_LEN(SC_UNONAME_CELLPRO),  ATTR_PROTECTION,    &getCppuType((util::CellProtection*)0), 0, 0 },
365         {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0),        0, 0 },
366         {MAP_CHAR_LEN(SC_UNONAME_CCOLOR),   ATTR_FONT_COLOR,    &getCppuType((sal_Int32*)0),            0, 0 },
367         {MAP_CHAR_LEN(SC_UNONAME_COUTL),    ATTR_FONT_CONTOUR,  &getBooleanCppuType(),                  0, 0 },
368         {MAP_CHAR_LEN(SC_UNONAME_CCROSS),   ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(),                 0, MID_CROSSED_OUT },
369         {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS),  ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0),         0, MID_EMPHASIS },
370         {MAP_CHAR_LEN(SC_UNONAME_CFONT),    ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
371         {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
372         {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
373         {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
374         {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
375         {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
376         {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
377         {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
378         {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
379         {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
380         {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
381         {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
382         {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
383         {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
384         {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
385         {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
386         {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT),  ATTR_FONT_HEIGHT,   &getCppuType((float*)0),                0, MID_FONTHEIGHT | CONVERT_TWIPS },
387         {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT),  ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
388         {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT),  ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
389         {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),   ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0),         0, MID_LANG_LOCALE },
390         {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),   ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
391         {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),   ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
392         {MAP_CHAR_LEN(SC_UNONAME_COVER),    ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
393         {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
394         {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
395         {MAP_CHAR_LEN(SC_UNONAME_CPOST),    ATTR_FONT_POSTURE,  &getCppuType((awt::FontSlant*)0),       0, MID_POSTURE },
396         {MAP_CHAR_LEN(SC_UNO_CJK_CPOST),    ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
397         {MAP_CHAR_LEN(SC_UNO_CTL_CPOST),    ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
398         {MAP_CHAR_LEN(SC_UNONAME_CRELIEF),  ATTR_FONT_RELIEF,   &getCppuType((sal_Int16*)0),            0, MID_RELIEF },
399         {MAP_CHAR_LEN(SC_UNONAME_CSHADD),   ATTR_FONT_SHADOWED, &getBooleanCppuType(),                  0, 0 },
400         {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE),  ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0),           0, MID_CROSS_OUT },
401         {MAP_CHAR_LEN(SC_UNONAME_CUNDER),   ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
402         {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
403         {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
404         {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT),  ATTR_FONT_WEIGHT,   &getCppuType((float*)0),                0, MID_WEIGHT },
405         {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT),  ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
406         {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT),  ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
407         {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(),                  0, 0 },
408         {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(),                  0, 0 },
409         {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(),                  0, 0 },
410         {MAP_CHAR_LEN(SC_UNONAME_CONDFMT),  SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
411         {MAP_CHAR_LEN(SC_UNONAME_CONDLOC),  SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
412         {MAP_CHAR_LEN(SC_UNONAME_CONDXML),  SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
413         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
414         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
415         {MAP_CHAR_LEN(SC_UNONAME_FORMLOC),  SC_WID_UNO_FORMLOC, &getCppuType((rtl::OUString*)0),        0, 0 },
416         {MAP_CHAR_LEN(SC_UNONAME_FORMRT),   SC_WID_UNO_FORMRT,  &getCppuType((table::CellContentType*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
417         {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY,   &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
418         {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND,    &getBooleanCppuType(),                  0, MID_GRAPHIC_TRANSPARENT },
419         {MAP_CHAR_LEN(SC_UNONAME_WRAP),     ATTR_LINEBREAK,     &getBooleanCppuType(),                  0, 0 },
420         {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
421         {MAP_CHAR_LEN(SC_UNONAME_NUMFMT),   ATTR_VALUE_FORMAT,  &getCppuType((sal_Int32*)0),            0, 0 },
422         {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
423         {MAP_CHAR_LEN(SC_UNONAME_CELLORI),  ATTR_STACKED,       &getCppuType((table::CellOrientation*)0), 0, 0 },
424         {MAP_CHAR_LEN(SC_UNONAME_PADJUST),  ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
425         {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
426         {MAP_CHAR_LEN(SC_UNONAME_PINDENT),  ATTR_INDENT,        &getCppuType((sal_Int16*)0),            0, 0 }, //! CONVERT_TWIPS
427         {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE,   &getBooleanCppuType(),                  0, 0 },
428         {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(),                 0, 0 },
429         {MAP_CHAR_LEN(SC_UNONAME_PISHANG),  ATTR_HANGPUNCTUATION,&getBooleanCppuType(),                 0, 0 },
430         {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE,     &getBooleanCppuType(),                  0, 0 },
431         {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
432         {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_L_MARGIN  | CONVERT_TWIPS },
433         {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_R_MARGIN  | CONVERT_TWIPS },
434         {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
435         {MAP_CHAR_LEN(SC_UNONAME_POS),      SC_WID_UNO_POS,     &getCppuType((awt::Point*)0),           0 | beans::PropertyAttribute::READONLY, 0 },
436         {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER,      &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
437         {MAP_CHAR_LEN(SC_UNONAME_ROTANG),   ATTR_ROTATE_VALUE,  &getCppuType((sal_Int32*)0),            0, 0 },
438         {MAP_CHAR_LEN(SC_UNONAME_ROTREF),   ATTR_ROTATE_MODE,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
439         {MAP_CHAR_LEN(SC_UNONAME_SHADOW),   ATTR_SHADOW,        &getCppuType((table::ShadowFormat*)0),  0, 0 | CONVERT_TWIPS },
440         {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(),               0, 0 },
441         {MAP_CHAR_LEN(SC_UNONAME_SIZE),     SC_WID_UNO_SIZE,    &getCppuType((awt::Size*)0),            0 | beans::PropertyAttribute::READONLY, 0 },
442         {MAP_CHAR_LEN(SC_UNONAME_TBLBORD),  SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0),   0, 0 | CONVERT_TWIPS },
443         {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER,        &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
444         {MAP_CHAR_LEN(SC_UNONAME_USERDEF),  ATTR_USERDEF,       &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
445         {MAP_CHAR_LEN(SC_UNONAME_VALIDAT),  SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
446         {MAP_CHAR_LEN(SC_UNONAME_VALILOC),  SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
447         {MAP_CHAR_LEN(SC_UNONAME_VALIXML),  SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
448         {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
449         {MAP_CHAR_LEN(SC_UNONAME_WRITING),  ATTR_WRITINGDIR,    &getCppuType((sal_Int16*)0),            0, 0 },
450         {0,0,0,0,0,0}
451     };
452     static SfxItemPropertySet aCellPropertySet( aCellPropertyMap_Impl );
453     return &aCellPropertySet;
454 }
455 
456 //  Column und Row enthalten alle Eintraege von CellRange, zusaetzlich eigene Eintraege
457 //  mit Which-ID 0 (werden nur fuer getPropertySetInfo benoetigt).
458 
459 const SfxItemPropertySet* lcl_GetColumnPropertySet()
460 {
461     static SfxItemPropertyMapEntry aColumnPropertyMap_Impl[] =
462     {
463         {MAP_CHAR_LEN(SC_UNONAME_ABSNAME),  SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0),        0 | beans::PropertyAttribute::READONLY, 0 },
464         {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(),                  0, 0 },
465         {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
466         {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND,    &getCppuType((sal_Int32*)0),            0, MID_BACK_COLOR },
467         {MAP_CHAR_LEN(SC_UNONAME_CELLPRO),  ATTR_PROTECTION,    &getCppuType((util::CellProtection*)0), 0, 0 },
468         {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0),        0, 0 },
469         {MAP_CHAR_LEN(SC_UNONAME_CCOLOR),   ATTR_FONT_COLOR,    &getCppuType((sal_Int32*)0),            0, 0 },
470         {MAP_CHAR_LEN(SC_UNONAME_COUTL),    ATTR_FONT_CONTOUR,  &getBooleanCppuType(),                  0, 0 },
471         {MAP_CHAR_LEN(SC_UNONAME_CCROSS),   ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(),                 0, MID_CROSSED_OUT },
472         {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS),  ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0),         0, MID_EMPHASIS },
473         {MAP_CHAR_LEN(SC_UNONAME_CFONT),    ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
474         {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
475         {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
476         {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
477         {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
478         {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
479         {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
480         {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
481         {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
482         {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
483         {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
484         {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
485         {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
486         {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
487         {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
488         {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
489         {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT),  ATTR_FONT_HEIGHT,   &getCppuType((float*)0),                0, MID_FONTHEIGHT | CONVERT_TWIPS },
490         {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT),  ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
491         {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT),  ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
492         {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),   ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0),         0, MID_LANG_LOCALE },
493         {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),   ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
494         {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),   ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
495         {MAP_CHAR_LEN(SC_UNONAME_COVER),    ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
496         {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
497         {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
498         {MAP_CHAR_LEN(SC_UNONAME_CPOST),    ATTR_FONT_POSTURE,  &getCppuType((awt::FontSlant*)0),       0, MID_POSTURE },
499         {MAP_CHAR_LEN(SC_UNO_CJK_CPOST),    ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
500         {MAP_CHAR_LEN(SC_UNO_CTL_CPOST),    ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
501         {MAP_CHAR_LEN(SC_UNONAME_CRELIEF),  ATTR_FONT_RELIEF,   &getCppuType((sal_Int16*)0),            0, MID_RELIEF },
502         {MAP_CHAR_LEN(SC_UNONAME_CSHADD),   ATTR_FONT_SHADOWED, &getBooleanCppuType(),                  0, 0 },
503         {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE),  ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0),           0, MID_CROSS_OUT },
504         {MAP_CHAR_LEN(SC_UNONAME_CUNDER),   ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
505         {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
506         {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
507         {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT),  ATTR_FONT_WEIGHT,   &getCppuType((float*)0),                0, MID_WEIGHT },
508         {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT),  ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
509         {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT),  ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
510         {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(),                  0, 0 },
511         {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(),                  0, 0 },
512         {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(),                  0, 0 },
513         {MAP_CHAR_LEN(SC_UNONAME_CONDFMT),  SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
514         {MAP_CHAR_LEN(SC_UNONAME_CONDLOC),  SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
515         {MAP_CHAR_LEN(SC_UNONAME_CONDXML),  SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
516         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
517         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
518         {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY,   &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
519         {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND,    &getBooleanCppuType(),                  0, MID_GRAPHIC_TRANSPARENT },
520 //      {MAP_CHAR_LEN(SC_UNONAME_CELLFILT), SC_WID_UNO_CELLFILT,&getBooleanCppuType(),                  0, 0 },
521         {MAP_CHAR_LEN(SC_UNONAME_MANPAGE),  SC_WID_UNO_MANPAGE, &getBooleanCppuType(),                  0, 0 },
522         {MAP_CHAR_LEN(SC_UNONAME_NEWPAGE),  SC_WID_UNO_NEWPAGE, &getBooleanCppuType(),                  0, 0 },
523         {MAP_CHAR_LEN(SC_UNONAME_WRAP),     ATTR_LINEBREAK,     &getBooleanCppuType(),                  0, 0 },
524         {MAP_CHAR_LEN(SC_UNONAME_CELLVIS),  SC_WID_UNO_CELLVIS, &getBooleanCppuType(),                  0, 0 },
525         {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
526         {MAP_CHAR_LEN(SC_UNONAME_NUMFMT),   ATTR_VALUE_FORMAT,  &getCppuType((sal_Int32*)0),            0, 0 },
527         {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
528         {MAP_CHAR_LEN(SC_UNONAME_OWIDTH),   SC_WID_UNO_OWIDTH,  &getBooleanCppuType(),                  0, 0 },
529         {MAP_CHAR_LEN(SC_UNONAME_CELLORI),  ATTR_STACKED,       &getCppuType((table::CellOrientation*)0), 0, 0 },
530         {MAP_CHAR_LEN(SC_UNONAME_PADJUST),  ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
531         {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
532         {MAP_CHAR_LEN(SC_UNONAME_PINDENT),  ATTR_INDENT,        &getCppuType((sal_Int16*)0),            0, 0 }, //! CONVERT_TWIPS
533         {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE,   &getBooleanCppuType(),                  0, 0 },
534         {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(),                 0, 0 },
535         {MAP_CHAR_LEN(SC_UNONAME_PISHANG),  ATTR_HANGPUNCTUATION,&getBooleanCppuType(),                 0, 0 },
536         {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE,     &getBooleanCppuType(),                  0, 0 },
537         {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
538         {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_L_MARGIN  | CONVERT_TWIPS },
539         {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_R_MARGIN  | CONVERT_TWIPS },
540         {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
541         {MAP_CHAR_LEN(SC_UNONAME_POS),      SC_WID_UNO_POS,     &getCppuType((awt::Point*)0),           0 | beans::PropertyAttribute::READONLY, 0 },
542         {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER,      &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
543         {MAP_CHAR_LEN(SC_UNONAME_ROTANG),   ATTR_ROTATE_VALUE,  &getCppuType((sal_Int32*)0),            0, 0 },
544         {MAP_CHAR_LEN(SC_UNONAME_ROTREF),   ATTR_ROTATE_MODE,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
545         {MAP_CHAR_LEN(SC_UNONAME_SHADOW),   ATTR_SHADOW,        &getCppuType((table::ShadowFormat*)0),  0, 0 | CONVERT_TWIPS },
546         {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(),               0, 0 },
547         {MAP_CHAR_LEN(SC_UNONAME_SIZE),     SC_WID_UNO_SIZE,    &getCppuType((awt::Size*)0),            0 | beans::PropertyAttribute::READONLY, 0 },
548         {MAP_CHAR_LEN(SC_UNONAME_TBLBORD),  SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0),   0, 0 | CONVERT_TWIPS },
549         {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER,        &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
550         {MAP_CHAR_LEN(SC_UNONAME_USERDEF),  ATTR_USERDEF,       &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
551         {MAP_CHAR_LEN(SC_UNONAME_VALIDAT),  SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
552         {MAP_CHAR_LEN(SC_UNONAME_VALILOC),  SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
553         {MAP_CHAR_LEN(SC_UNONAME_VALIXML),  SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
554         {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
555         {MAP_CHAR_LEN(SC_UNONAME_CELLWID),  SC_WID_UNO_CELLWID, &getCppuType((sal_Int32*)0),            0, 0 },
556         {MAP_CHAR_LEN(SC_UNONAME_WRITING),  ATTR_WRITINGDIR,    &getCppuType((sal_Int16*)0),            0, 0 },
557         {0,0,0,0,0,0}
558     };
559     static SfxItemPropertySet aColumnPropertySet( aColumnPropertyMap_Impl );
560     return &aColumnPropertySet;
561 }
562 
563 const SfxItemPropertySet* lcl_GetRowPropertySet()
564 {
565     static SfxItemPropertyMapEntry aRowPropertyMap_Impl[] =
566     {
567         {MAP_CHAR_LEN(SC_UNONAME_ABSNAME),  SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0),        0 | beans::PropertyAttribute::READONLY, 0 },
568         {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(),                  0, 0 },
569         {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
570         {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND,    &getCppuType((sal_Int32*)0),            0, MID_BACK_COLOR },
571         {MAP_CHAR_LEN(SC_UNONAME_CELLPRO),  ATTR_PROTECTION,    &getCppuType((util::CellProtection*)0), 0, 0 },
572         {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0),        0, 0 },
573         {MAP_CHAR_LEN(SC_UNONAME_CCOLOR),   ATTR_FONT_COLOR,    &getCppuType((sal_Int32*)0),            0, 0 },
574         {MAP_CHAR_LEN(SC_UNONAME_COUTL),    ATTR_FONT_CONTOUR,  &getBooleanCppuType(),                  0, 0 },
575         {MAP_CHAR_LEN(SC_UNONAME_CCROSS),   ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(),                 0, MID_CROSSED_OUT },
576         {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS),  ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0),         0, MID_EMPHASIS },
577         {MAP_CHAR_LEN(SC_UNONAME_CFONT),    ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
578         {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
579         {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
580         {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
581         {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
582         {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
583         {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
584         {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
585         {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
586         {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
587         {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
588         {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
589         {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
590         {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
591         {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
592         {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
593         {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT),  ATTR_FONT_HEIGHT,   &getCppuType((float*)0),                0, MID_FONTHEIGHT | CONVERT_TWIPS },
594         {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT),  ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
595         {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT),  ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
596         {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),   ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0),         0, MID_LANG_LOCALE },
597         {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),   ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
598         {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),   ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
599         {MAP_CHAR_LEN(SC_UNONAME_COVER),    ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
600         {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
601         {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
602         {MAP_CHAR_LEN(SC_UNONAME_CPOST),    ATTR_FONT_POSTURE,  &getCppuType((awt::FontSlant*)0),       0, MID_POSTURE },
603         {MAP_CHAR_LEN(SC_UNO_CJK_CPOST),    ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
604         {MAP_CHAR_LEN(SC_UNO_CTL_CPOST),    ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
605         {MAP_CHAR_LEN(SC_UNONAME_CRELIEF),  ATTR_FONT_RELIEF,   &getCppuType((sal_Int16*)0),            0, MID_RELIEF },
606         {MAP_CHAR_LEN(SC_UNONAME_CSHADD),   ATTR_FONT_SHADOWED, &getBooleanCppuType(),                  0, 0 },
607         {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE),  ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0),           0, MID_CROSS_OUT },
608         {MAP_CHAR_LEN(SC_UNONAME_CUNDER),   ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
609         {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
610         {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
611         {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT),  ATTR_FONT_WEIGHT,   &getCppuType((float*)0),                0, MID_WEIGHT },
612         {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT),  ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
613         {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT),  ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
614         {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(),                  0, 0 },
615         {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(),                  0, 0 },
616         {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(),                  0, 0 },
617         {MAP_CHAR_LEN(SC_UNONAME_CONDFMT),  SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
618         {MAP_CHAR_LEN(SC_UNONAME_CONDLOC),  SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
619         {MAP_CHAR_LEN(SC_UNONAME_CONDXML),  SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
620         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
621         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
622         {MAP_CHAR_LEN(SC_UNONAME_CELLHGT),  SC_WID_UNO_CELLHGT, &getCppuType((sal_Int32*)0),            0, 0 },
623         {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY,   &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
624         {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND,    &getBooleanCppuType(),                  0, MID_GRAPHIC_TRANSPARENT },
625         {MAP_CHAR_LEN(SC_UNONAME_CELLFILT), SC_WID_UNO_CELLFILT,&getBooleanCppuType(),                  0, 0 },
626         {MAP_CHAR_LEN(SC_UNONAME_MANPAGE),  SC_WID_UNO_MANPAGE, &getBooleanCppuType(),                  0, 0 },
627         {MAP_CHAR_LEN(SC_UNONAME_NEWPAGE),  SC_WID_UNO_NEWPAGE, &getBooleanCppuType(),                  0, 0 },
628         {MAP_CHAR_LEN(SC_UNONAME_WRAP),     ATTR_LINEBREAK,     &getBooleanCppuType(),                  0, 0 },
629         {MAP_CHAR_LEN(SC_UNONAME_CELLVIS),  SC_WID_UNO_CELLVIS, &getBooleanCppuType(),                  0, 0 },
630         {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
631         {MAP_CHAR_LEN(SC_UNONAME_NUMFMT),   ATTR_VALUE_FORMAT,  &getCppuType((sal_Int32*)0),            0, 0 },
632         {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
633         {MAP_CHAR_LEN(SC_UNONAME_OHEIGHT),  SC_WID_UNO_OHEIGHT, &getBooleanCppuType(),                  0, 0 },
634         {MAP_CHAR_LEN(SC_UNONAME_CELLORI),  ATTR_STACKED,       &getCppuType((table::CellOrientation*)0), 0, 0 },
635         {MAP_CHAR_LEN(SC_UNONAME_PADJUST),  ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
636         {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
637         {MAP_CHAR_LEN(SC_UNONAME_PINDENT),  ATTR_INDENT,        &getCppuType((sal_Int16*)0),            0, 0 }, //! CONVERT_TWIPS
638         {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE,   &getBooleanCppuType(),                  0, 0 },
639         {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(),                 0, 0 },
640         {MAP_CHAR_LEN(SC_UNONAME_PISHANG),  ATTR_HANGPUNCTUATION,&getBooleanCppuType(),                 0, 0 },
641         {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE,     &getBooleanCppuType(),                  0, 0 },
642         {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
643         {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_L_MARGIN  | CONVERT_TWIPS },
644         {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_R_MARGIN  | CONVERT_TWIPS },
645         {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
646         {MAP_CHAR_LEN(SC_UNONAME_POS),      SC_WID_UNO_POS,     &getCppuType((awt::Point*)0),           0 | beans::PropertyAttribute::READONLY, 0 },
647         {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER,      &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
648         {MAP_CHAR_LEN(SC_UNONAME_ROTANG),   ATTR_ROTATE_VALUE,  &getCppuType((sal_Int32*)0),            0, 0 },
649         {MAP_CHAR_LEN(SC_UNONAME_ROTREF),   ATTR_ROTATE_MODE,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
650         {MAP_CHAR_LEN(SC_UNONAME_SHADOW),   ATTR_SHADOW,        &getCppuType((table::ShadowFormat*)0),  0, 0 | CONVERT_TWIPS },
651         {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(),               0, 0 },
652         {MAP_CHAR_LEN(SC_UNONAME_SIZE),     SC_WID_UNO_SIZE,    &getCppuType((awt::Size*)0),            0 | beans::PropertyAttribute::READONLY, 0 },
653         {MAP_CHAR_LEN(SC_UNONAME_TBLBORD),  SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0),   0, 0 | CONVERT_TWIPS },
654         {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER,        &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
655         {MAP_CHAR_LEN(SC_UNONAME_USERDEF),  ATTR_USERDEF,       &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
656         {MAP_CHAR_LEN(SC_UNONAME_VALIDAT),  SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
657         {MAP_CHAR_LEN(SC_UNONAME_VALILOC),  SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
658         {MAP_CHAR_LEN(SC_UNONAME_VALIXML),  SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
659         {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
660         {MAP_CHAR_LEN(SC_UNONAME_WRITING),  ATTR_WRITINGDIR,    &getCppuType((sal_Int16*)0),            0, 0 },
661         {0,0,0,0,0,0}
662     };
663     static SfxItemPropertySet aRowPropertySet( aRowPropertyMap_Impl );
664     return &aRowPropertySet;
665 }
666 
667 const SfxItemPropertySet* lcl_GetSheetPropertySet()
668 {
669     static SfxItemPropertyMapEntry aSheetPropertyMap_Impl[] =
670     {
671         {MAP_CHAR_LEN(SC_UNONAME_ABSNAME),  SC_WID_UNO_ABSNAME, &getCppuType((rtl::OUString*)0),        0 | beans::PropertyAttribute::READONLY, 0 },
672         {MAP_CHAR_LEN(SC_UNONAME_ASIANVERT),ATTR_VERTICAL_ASIAN,&getBooleanCppuType(),                  0, 0 },
673         {MAP_CHAR_LEN(SC_UNONAME_AUTOPRINT),SC_WID_UNO_AUTOPRINT,&getBooleanCppuType(),                 0, 0 },
674         {MAP_CHAR_LEN(SC_UNONAME_BORDCOL),  SC_WID_UNO_BORDCOL, &getCppuType((sal_Int32*)0),            0, 0 },
675         {MAP_CHAR_LEN(SC_UNONAME_BOTTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, BOTTOM_BORDER | CONVERT_TWIPS },
676         {MAP_CHAR_LEN(SC_UNONAME_CELLBACK), ATTR_BACKGROUND,    &getCppuType((sal_Int32*)0),            0, MID_BACK_COLOR },
677         {MAP_CHAR_LEN(SC_UNONAME_CELLPRO),  ATTR_PROTECTION,    &getCppuType((util::CellProtection*)0), 0, 0 },
678         {MAP_CHAR_LEN(SC_UNONAME_CELLSTYL), SC_WID_UNO_CELLSTYL,&getCppuType((rtl::OUString*)0),        0, 0 },
679         {MAP_CHAR_LEN(SC_UNONAME_CCOLOR),   ATTR_FONT_COLOR,    &getCppuType((sal_Int32*)0),            0, 0 },
680         {MAP_CHAR_LEN(SC_UNONAME_COUTL),    ATTR_FONT_CONTOUR,  &getBooleanCppuType(),                  0, 0 },
681         {MAP_CHAR_LEN(SC_UNONAME_CCROSS),   ATTR_FONT_CROSSEDOUT,&getBooleanCppuType(),                 0, MID_CROSSED_OUT },
682         {MAP_CHAR_LEN(SC_UNONAME_CEMPHAS),  ATTR_FONT_EMPHASISMARK,&getCppuType((sal_Int16*)0),         0, MID_EMPHASIS },
683         {MAP_CHAR_LEN(SC_UNONAME_CFONT),    ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
684         {MAP_CHAR_LEN(SC_UNONAME_CFCHARS),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
685         {MAP_CHAR_LEN(SC_UNO_CJK_CFCHARS),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
686         {MAP_CHAR_LEN(SC_UNO_CTL_CFCHARS),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_CHAR_SET },
687         {MAP_CHAR_LEN(SC_UNONAME_CFFAMIL),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
688         {MAP_CHAR_LEN(SC_UNO_CJK_CFFAMIL),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
689         {MAP_CHAR_LEN(SC_UNO_CTL_CFFAMIL),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_FAMILY },
690         {MAP_CHAR_LEN(SC_UNONAME_CFNAME),   ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
691         {MAP_CHAR_LEN(SC_UNO_CJK_CFNAME),   ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
692         {MAP_CHAR_LEN(SC_UNO_CTL_CFNAME),   ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_FAMILY_NAME },
693         {MAP_CHAR_LEN(SC_UNONAME_CFPITCH),  ATTR_FONT,          &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
694         {MAP_CHAR_LEN(SC_UNO_CJK_CFPITCH),  ATTR_CJK_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
695         {MAP_CHAR_LEN(SC_UNO_CTL_CFPITCH),  ATTR_CTL_FONT,      &getCppuType((sal_Int16*)0),            0, MID_FONT_PITCH },
696         {MAP_CHAR_LEN(SC_UNONAME_CFSTYLE),  ATTR_FONT,          &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
697         {MAP_CHAR_LEN(SC_UNO_CJK_CFSTYLE),  ATTR_CJK_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
698         {MAP_CHAR_LEN(SC_UNO_CTL_CFSTYLE),  ATTR_CTL_FONT,      &getCppuType((rtl::OUString*)0),        0, MID_FONT_STYLE_NAME },
699         {MAP_CHAR_LEN(SC_UNONAME_CHEIGHT),  ATTR_FONT_HEIGHT,   &getCppuType((float*)0),                0, MID_FONTHEIGHT | CONVERT_TWIPS },
700         {MAP_CHAR_LEN(SC_UNO_CJK_CHEIGHT),  ATTR_CJK_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
701         {MAP_CHAR_LEN(SC_UNO_CTL_CHEIGHT),  ATTR_CTL_FONT_HEIGHT,&getCppuType((float*)0),               0, MID_FONTHEIGHT | CONVERT_TWIPS },
702         {MAP_CHAR_LEN(SC_UNONAME_CLOCAL),   ATTR_FONT_LANGUAGE, &getCppuType((lang::Locale*)0),         0, MID_LANG_LOCALE },
703         {MAP_CHAR_LEN(SC_UNO_CJK_CLOCAL),   ATTR_CJK_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
704         {MAP_CHAR_LEN(SC_UNO_CTL_CLOCAL),   ATTR_CTL_FONT_LANGUAGE,&getCppuType((lang::Locale*)0),          0, MID_LANG_LOCALE },
705         {MAP_CHAR_LEN(SC_UNONAME_COVER),    ATTR_FONT_OVERLINE, &getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
706         {MAP_CHAR_LEN(SC_UNONAME_COVRLCOL), ATTR_FONT_OVERLINE, &getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
707         {MAP_CHAR_LEN(SC_UNONAME_COVRLHAS), ATTR_FONT_OVERLINE, &getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
708         {MAP_CHAR_LEN(SC_UNONAME_CPOST),    ATTR_FONT_POSTURE,  &getCppuType((awt::FontSlant*)0),       0, MID_POSTURE },
709         {MAP_CHAR_LEN(SC_UNO_CJK_CPOST),    ATTR_CJK_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
710         {MAP_CHAR_LEN(SC_UNO_CTL_CPOST),    ATTR_CTL_FONT_POSTURE,&getCppuType((awt::FontSlant*)0),     0, MID_POSTURE },
711         {MAP_CHAR_LEN(SC_UNONAME_CRELIEF),  ATTR_FONT_RELIEF,   &getCppuType((sal_Int16*)0),            0, MID_RELIEF },
712         {MAP_CHAR_LEN(SC_UNONAME_CSHADD),   ATTR_FONT_SHADOWED, &getBooleanCppuType(),                  0, 0 },
713         {MAP_CHAR_LEN(SC_UNONAME_CSTRIKE),  ATTR_FONT_CROSSEDOUT,&getCppuType((sal_Int16*)0),           0, MID_CROSS_OUT },
714         {MAP_CHAR_LEN(SC_UNONAME_CUNDER),   ATTR_FONT_UNDERLINE,&getCppuType((sal_Int16*)0),            0, MID_TL_STYLE },
715         {MAP_CHAR_LEN(SC_UNONAME_CUNDLCOL), ATTR_FONT_UNDERLINE,&getCppuType((sal_Int32*)0),            0, MID_TL_COLOR },
716         {MAP_CHAR_LEN(SC_UNONAME_CUNDLHAS), ATTR_FONT_UNDERLINE,&getBooleanCppuType(),                  0, MID_TL_HASCOLOR },
717         {MAP_CHAR_LEN(SC_UNONAME_CWEIGHT),  ATTR_FONT_WEIGHT,   &getCppuType((float*)0),                0, MID_WEIGHT },
718         {MAP_CHAR_LEN(SC_UNO_CJK_CWEIGHT),  ATTR_CJK_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
719         {MAP_CHAR_LEN(SC_UNO_CTL_CWEIGHT),  ATTR_CTL_FONT_WEIGHT,&getCppuType((float*)0),               0, MID_WEIGHT },
720         {MAP_CHAR_LEN(SC_UNONAME_CWORDMOD), ATTR_FONT_WORDLINE, &getBooleanCppuType(),                  0, 0 },
721         {MAP_CHAR_LEN(SC_UNONAME_CHCOLHDR), SC_WID_UNO_CHCOLHDR,&getBooleanCppuType(),                  0, 0 },
722         {MAP_CHAR_LEN(SC_UNONAME_CHROWHDR), SC_WID_UNO_CHROWHDR,&getBooleanCppuType(),                  0, 0 },
723         {MAP_CHAR_LEN(SC_UNONAME_CONDFMT),  SC_WID_UNO_CONDFMT, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
724         {MAP_CHAR_LEN(SC_UNONAME_CONDLOC),  SC_WID_UNO_CONDLOC, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
725         {MAP_CHAR_LEN(SC_UNONAME_CONDXML),  SC_WID_UNO_CONDXML, &getCppuType((uno::Reference<sheet::XSheetConditionalEntries>*)0), 0, 0 },
726         {MAP_CHAR_LEN(SC_UNONAME_COPYBACK), SC_WID_UNO_COPYBACK,&getBooleanCppuType(),                  0, 0 },
727         {MAP_CHAR_LEN(SC_UNONAME_COPYFORM), SC_WID_UNO_COPYFORM,&getBooleanCppuType(),                  0, 0 },
728         {MAP_CHAR_LEN(SC_UNONAME_COPYSTYL), SC_WID_UNO_COPYSTYL,&getBooleanCppuType(),                  0, 0 },
729         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_BLTR), ATTR_BORDER_BLTR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
730         {MAP_CHAR_LEN(SC_UNONAME_DIAGONAL_TLBR), ATTR_BORDER_TLBR, &::getCppuType((const table::BorderLine*)0), 0, 0 | CONVERT_TWIPS },
731         {MAP_CHAR_LEN(SC_UNONAME_CELLHJUS), ATTR_HOR_JUSTIFY,   &getCppuType((table::CellHoriJustify*)0), 0, MID_HORJUST_HORJUST },
732         {MAP_CHAR_LEN(SC_UNONAME_ISACTIVE), SC_WID_UNO_ISACTIVE,&getBooleanCppuType(),                  0, 0 },
733         {MAP_CHAR_LEN(SC_UNONAME_CELLTRAN), ATTR_BACKGROUND,    &getBooleanCppuType(),                  0, MID_GRAPHIC_TRANSPARENT },
734         {MAP_CHAR_LEN(SC_UNONAME_WRAP),     ATTR_LINEBREAK,     &getBooleanCppuType(),                  0, 0 },
735         {MAP_CHAR_LEN(SC_UNONAME_CELLVIS),  SC_WID_UNO_CELLVIS, &getBooleanCppuType(),                  0, 0 },
736         {MAP_CHAR_LEN(SC_UNONAME_LEFTBORDER),ATTR_BORDER,       &::getCppuType((const table::BorderLine*)0), 0, LEFT_BORDER | CONVERT_TWIPS },
737         {MAP_CHAR_LEN(SC_UNO_LINKDISPBIT),  SC_WID_UNO_LINKDISPBIT,&getCppuType((uno::Reference<awt::XBitmap>*)0), 0 | beans::PropertyAttribute::READONLY, 0 },
738         {MAP_CHAR_LEN(SC_UNO_LINKDISPNAME), SC_WID_UNO_LINKDISPNAME,&getCppuType((rtl::OUString*)0),    0 | beans::PropertyAttribute::READONLY, 0 },
739         {MAP_CHAR_LEN(SC_UNONAME_NUMFMT),   ATTR_VALUE_FORMAT,  &getCppuType((sal_Int32*)0),            0, 0 },
740         {MAP_CHAR_LEN(SC_UNONAME_NUMRULES), SC_WID_UNO_NUMRULES,&getCppuType((const uno::Reference<container::XIndexReplace>*)0), 0, 0 },
741         {MAP_CHAR_LEN(SC_UNONAME_CELLORI),  ATTR_STACKED,       &getCppuType((table::CellOrientation*)0), 0, 0 },
742         {MAP_CHAR_LEN(SC_UNONAME_PAGESTL),  SC_WID_UNO_PAGESTL, &getCppuType((rtl::OUString*)0),        0, 0 },
743         {MAP_CHAR_LEN(SC_UNONAME_PADJUST),  ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
744         {MAP_CHAR_LEN(SC_UNONAME_PBMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
745         {MAP_CHAR_LEN(SC_UNONAME_PINDENT),  ATTR_INDENT,        &getCppuType((sal_Int16*)0),            0, 0 }, //! CONVERT_TWIPS
746         {MAP_CHAR_LEN(SC_UNONAME_PISCHDIST),ATTR_SCRIPTSPACE,   &getBooleanCppuType(),                  0, 0 },
747         {MAP_CHAR_LEN(SC_UNONAME_PISFORBID),ATTR_FORBIDDEN_RULES,&getBooleanCppuType(),                 0, 0 },
748         {MAP_CHAR_LEN(SC_UNONAME_PISHANG),  ATTR_HANGPUNCTUATION,&getBooleanCppuType(),                 0, 0 },
749         {MAP_CHAR_LEN(SC_UNONAME_PISHYPHEN),ATTR_HYPHENATE,     &getBooleanCppuType(),                  0, 0 },
750         {MAP_CHAR_LEN(SC_UNONAME_PLASTADJ), ATTR_HOR_JUSTIFY,   &::getCppuType((const sal_Int16*)0),    0, MID_HORJUST_ADJUST },
751         {MAP_CHAR_LEN(SC_UNONAME_PLMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_L_MARGIN  | CONVERT_TWIPS },
752         {MAP_CHAR_LEN(SC_UNONAME_PRMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_R_MARGIN  | CONVERT_TWIPS },
753         {MAP_CHAR_LEN(SC_UNONAME_PTMARGIN), ATTR_MARGIN,        &getCppuType((sal_Int32*)0),            0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
754         {MAP_CHAR_LEN(SC_UNONAME_POS),      SC_WID_UNO_POS,     &getCppuType((awt::Point*)0),           0 | beans::PropertyAttribute::READONLY, 0 },
755         {MAP_CHAR_LEN(SC_UNONAME_PRINTBORD),SC_WID_UNO_PRINTBORD,&getBooleanCppuType(),                 0, 0 },
756         {MAP_CHAR_LEN(SC_UNONAME_PROTECT),  SC_WID_UNO_PROTECT, &getBooleanCppuType(),                  0, 0 },
757         {MAP_CHAR_LEN(SC_UNONAME_RIGHTBORDER),ATTR_BORDER,      &::getCppuType((const table::BorderLine*)0), 0, RIGHT_BORDER | CONVERT_TWIPS },
758         {MAP_CHAR_LEN(SC_UNONAME_ROTANG),   ATTR_ROTATE_VALUE,  &getCppuType((sal_Int32*)0),            0, 0 },
759         {MAP_CHAR_LEN(SC_UNONAME_ROTREF),   ATTR_ROTATE_MODE,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
760         {MAP_CHAR_LEN(SC_UNONAME_SHADOW),   ATTR_SHADOW,        &getCppuType((table::ShadowFormat*)0),  0, 0 | CONVERT_TWIPS },
761         {MAP_CHAR_LEN(SC_UNONAME_SHOWBORD), SC_WID_UNO_SHOWBORD,&getBooleanCppuType(),                  0, 0 },
762         {MAP_CHAR_LEN(SC_UNONAME_SHRINK_TO_FIT), ATTR_SHRINKTOFIT, &getBooleanCppuType(),               0, 0 },
763         {MAP_CHAR_LEN(SC_UNONAME_SIZE),     SC_WID_UNO_SIZE,    &getCppuType((awt::Size*)0),            0 | beans::PropertyAttribute::READONLY, 0 },
764         {MAP_CHAR_LEN(SC_UNONAME_TBLBORD),  SC_WID_UNO_TBLBORD, &getCppuType((table::TableBorder*)0),   0, 0 | CONVERT_TWIPS },
765         {MAP_CHAR_LEN(SC_UNONAME_TABLAYOUT),SC_WID_UNO_TABLAYOUT,&getCppuType((sal_Int16*)0),           0, 0 },
766         {MAP_CHAR_LEN(SC_UNONAME_TOPBORDER),ATTR_BORDER,        &::getCppuType((const table::BorderLine*)0), 0, TOP_BORDER | CONVERT_TWIPS },
767         {MAP_CHAR_LEN(SC_UNONAME_USERDEF),  ATTR_USERDEF,       &getCppuType((uno::Reference<container::XNameContainer>*)0), 0, 0 },
768         {MAP_CHAR_LEN(SC_UNONAME_VALIDAT),  SC_WID_UNO_VALIDAT, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
769         {MAP_CHAR_LEN(SC_UNONAME_VALILOC),  SC_WID_UNO_VALILOC, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
770         {MAP_CHAR_LEN(SC_UNONAME_VALIXML),  SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 },
771         {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY,   &getCppuType((table::CellVertJustify*)0), 0, 0 },
772         {MAP_CHAR_LEN(SC_UNONAME_WRITING),  ATTR_WRITINGDIR,    &getCppuType((sal_Int16*)0),            0, 0 },
773         {MAP_CHAR_LEN(SC_UNONAME_TABCOLOR), SC_WID_UNO_TABCOLOR, &getCppuType((sal_Int32*)0), 0, 0 },
774         {MAP_CHAR_LEN(SC_UNO_CODENAME),        SC_WID_UNO_CODENAME, &getCppuType(static_cast< const rtl::OUString * >(0)),    0, 0},
775         {0,0,0,0,0,0}
776     };
777     static SfxItemPropertySet aSheetPropertySet( aSheetPropertyMap_Impl );
778     return &aSheetPropertySet;
779 }
780 
781 const SfxItemPropertyMapEntry* lcl_GetEditPropertyMap()
782 {
783     static SfxItemPropertyMapEntry aEditPropertyMap_Impl[] =
784     {
785         SVX_UNOEDIT_CHAR_PROPERTIES,
786         SVX_UNOEDIT_FONT_PROPERTIES,
787         SVX_UNOEDIT_PARA_PROPERTIES,
788         SVX_UNOEDIT_NUMBERING_PROPERTIE,    // for completeness of service ParagraphProperties
789         {MAP_CHAR_LEN(SC_UNONAME_TEXTUSER), EE_CHAR_XMLATTRIBS, &getCppuType((const uno::Reference< container::XNameContainer >*)0), 0, 0},
790         {MAP_CHAR_LEN(SC_UNONAME_USERDEF),  EE_PARA_XMLATTRIBS, &getCppuType((const uno::Reference< container::XNameContainer >*)0), 0, 0},
791         {0,0,0,0,0,0}
792     };
793     return aEditPropertyMap_Impl;
794 }
795 const SvxItemPropertySet* lcl_GetEditPropertySet()
796 {
797     static SvxItemPropertySet aEditPropertySet( lcl_GetEditPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool() );
798     return &aEditPropertySet;
799 }
800 
801 
802 //------------------------------------------------------------------------
803 
804 //! diese Funktionen in einen allgemeinen Header verschieben
805 inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
806 inline long HMMToTwips(long nHMM)   { return (nHMM * 72 + 63) / 127; }
807 
808 //------------------------------------------------------------------------
809 
810 #define SCCHARPROPERTIES_SERVICE    "com.sun.star.style.CharacterProperties"
811 #define SCPARAPROPERTIES_SERVICE    "com.sun.star.style.ParagraphProperties"
812 #define SCCELLPROPERTIES_SERVICE    "com.sun.star.table.CellProperties"
813 #define SCCELLRANGE_SERVICE         "com.sun.star.table.CellRange"
814 #define SCCELL_SERVICE              "com.sun.star.table.Cell"
815 #define SCSHEETCELLRANGES_SERVICE   "com.sun.star.sheet.SheetCellRanges"
816 #define SCSHEETCELLRANGE_SERVICE    "com.sun.star.sheet.SheetCellRange"
817 #define SCSPREADSHEET_SERVICE       "com.sun.star.sheet.Spreadsheet"
818 #define SCSHEETCELL_SERVICE         "com.sun.star.sheet.SheetCell"
819 
820 SC_SIMPLE_SERVICE_INFO( ScCellFormatsEnumeration, "ScCellFormatsEnumeration", "com.sun.star.sheet.CellFormatRangesEnumeration" )
821 SC_SIMPLE_SERVICE_INFO( ScCellFormatsObj, "ScCellFormatsObj", "com.sun.star.sheet.CellFormatRanges" )
822 SC_SIMPLE_SERVICE_INFO( ScUniqueCellFormatsEnumeration, "ScUniqueCellFormatsEnumeration", "com.sun.star.sheet.UniqueCellFormatRangesEnumeration" )
823 SC_SIMPLE_SERVICE_INFO( ScUniqueCellFormatsObj, "ScUniqueCellFormatsObj", "com.sun.star.sheet.UniqueCellFormatRanges" )
824 SC_SIMPLE_SERVICE_INFO( ScCellRangesBase, "ScCellRangesBase", "stardiv.unknown" )
825 SC_SIMPLE_SERVICE_INFO( ScCellsEnumeration, "ScCellsEnumeration", "com.sun.star.sheet.CellsEnumeration" )
826 SC_SIMPLE_SERVICE_INFO( ScCellsObj, "ScCellsObj", "com.sun.star.sheet.Cells" )
827 SC_SIMPLE_SERVICE_INFO( ScTableColumnObj, "ScTableColumnObj", "com.sun.star.table.TableColumn" )
828 SC_SIMPLE_SERVICE_INFO( ScTableRowObj, "ScTableRowObj", "com.sun.star.table.TableRow" )
829 
830 //------------------------------------------------------------------------
831 
832 SV_IMPL_PTRARR( XModifyListenerArr_Impl, XModifyListenerPtr );
833 SV_IMPL_PTRARR( ScNamedEntryArr_Impl, ScNamedEntryPtr );
834 
835 //------------------------------------------------------------------------
836 
837 //! ScLinkListener in anderes File verschieben !!!
838 
839 ScLinkListener::~ScLinkListener()
840 {
841 }
842 
843 void ScLinkListener::Notify( SvtBroadcaster&, const SfxHint& rHint )
844 {
845     aLink.Call( (SfxHint*)&rHint );
846 }
847 
848 //------------------------------------------------------------------------
849 
850 void lcl_CopyProperties( beans::XPropertySet& rDest, beans::XPropertySet& rSource )
851 {
852     uno::Reference<beans::XPropertySetInfo> xInfo(rSource.getPropertySetInfo());
853     if (xInfo.is())
854     {
855         uno::Sequence<beans::Property> aSeq(xInfo->getProperties());
856         const beans::Property* pAry = aSeq.getConstArray();
857         sal_uLong nCount = aSeq.getLength();
858         for (sal_uLong i=0; i<nCount; i++)
859         {
860             rtl::OUString aName(pAry[i].Name);
861             rDest.setPropertyValue( aName, rSource.getPropertyValue( aName ) );
862         }
863     }
864 }
865 
866 SCTAB lcl_FirstTab( const ScRangeList& rRanges )
867 {
868     DBG_ASSERT(rRanges.Count() >= 1, "was fuer Ranges ?!?!");
869     const ScRange* pFirst = rRanges.GetObject(0);
870     if (pFirst)
871         return pFirst->aStart.Tab();
872 
873     return 0;   // soll nicht sein
874 }
875 
876 sal_Bool lcl_WholeSheet( const ScRangeList& rRanges )
877 {
878     if ( rRanges.Count() == 1 )
879     {
880         ScRange* pRange = rRanges.GetObject(0);
881         if ( pRange && pRange->aStart.Col() == 0 && pRange->aEnd.Col() == MAXCOL &&
882                        pRange->aStart.Row() == 0 && pRange->aEnd.Row() == MAXROW )
883             return sal_True;
884     }
885     return sal_False;
886 }
887 
888 //------------------------------------------------------------------------
889 
890 ScSubTotalFunc lcl_SummaryToSubTotal( sheet::GeneralFunction eSummary )
891 {
892     ScSubTotalFunc eSubTotal;
893     switch (eSummary)
894     {
895         case sheet::GeneralFunction_SUM:
896             eSubTotal = SUBTOTAL_FUNC_SUM;
897             break;
898         case sheet::GeneralFunction_COUNT:
899             eSubTotal = SUBTOTAL_FUNC_CNT2;
900             break;
901         case sheet::GeneralFunction_AVERAGE:
902             eSubTotal = SUBTOTAL_FUNC_AVE;
903             break;
904         case sheet::GeneralFunction_MAX:
905             eSubTotal = SUBTOTAL_FUNC_MAX;
906             break;
907         case sheet::GeneralFunction_MIN:
908             eSubTotal = SUBTOTAL_FUNC_MIN;
909             break;
910         case sheet::GeneralFunction_PRODUCT:
911             eSubTotal = SUBTOTAL_FUNC_PROD;
912             break;
913         case sheet::GeneralFunction_COUNTNUMS:
914             eSubTotal = SUBTOTAL_FUNC_CNT;
915             break;
916         case sheet::GeneralFunction_STDEV:
917             eSubTotal = SUBTOTAL_FUNC_STD;
918             break;
919         case sheet::GeneralFunction_STDEVP:
920             eSubTotal = SUBTOTAL_FUNC_STDP;
921             break;
922         case sheet::GeneralFunction_VAR:
923             eSubTotal = SUBTOTAL_FUNC_VAR;
924             break;
925         case sheet::GeneralFunction_VARP:
926             eSubTotal = SUBTOTAL_FUNC_VARP;
927             break;
928 
929         case sheet::GeneralFunction_NONE:
930         case sheet::GeneralFunction_AUTO:
931         default:
932             eSubTotal = SUBTOTAL_FUNC_NONE;
933             break;
934     }
935     return eSubTotal;
936 }
937 
938 //------------------------------------------------------------------------
939 
940 const SvxBorderLine* ScHelperFunctions::GetBorderLine( SvxBorderLine& rLine, const table::BorderLine& rStruct )
941 {
942     //  Calc braucht Twips, im Uno-Struct sind 1/100mm
943 
944     rLine.SetOutWidth( (sal_uInt16)HMMToTwips( rStruct.OuterLineWidth ) );
945     rLine.SetInWidth(  (sal_uInt16)HMMToTwips( rStruct.InnerLineWidth ) );
946     rLine.SetDistance( (sal_uInt16)HMMToTwips( rStruct.LineDistance ) );
947     rLine.SetColor( ColorData( rStruct.Color ) );
948 
949     if ( rLine.GetOutWidth() || rLine.GetInWidth() || rLine.GetDistance() )
950         return &rLine;
951     else
952         return NULL;
953 }
954 
955 void ScHelperFunctions::FillBoxItems( SvxBoxItem& rOuter, SvxBoxInfoItem& rInner, const table::TableBorder& rBorder )
956 {
957     SvxBorderLine aLine;
958     rOuter.SetDistance( (sal_uInt16)HMMToTwips( rBorder.Distance ) );
959     rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.TopLine ),     BOX_LINE_TOP );
960     rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.BottomLine ),      BOX_LINE_BOTTOM );
961     rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.LeftLine ),        BOX_LINE_LEFT );
962     rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.RightLine ),       BOX_LINE_RIGHT );
963     rInner.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.HorizontalLine ),  BOXINFO_LINE_HORI );
964     rInner.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.VerticalLine ),    BOXINFO_LINE_VERT );
965     rInner.SetValid( VALID_TOP,      rBorder.IsTopLineValid );
966     rInner.SetValid( VALID_BOTTOM,   rBorder.IsBottomLineValid );
967     rInner.SetValid( VALID_LEFT,     rBorder.IsLeftLineValid );
968     rInner.SetValid( VALID_RIGHT,    rBorder.IsRightLineValid );
969     rInner.SetValid( VALID_HORI,     rBorder.IsHorizontalLineValid );
970     rInner.SetValid( VALID_VERT,     rBorder.IsVerticalLineValid );
971     rInner.SetValid( VALID_DISTANCE, rBorder.IsDistanceValid );
972     rInner.SetTable( sal_True );
973 }
974 
975 void ScHelperFunctions::FillBorderLine( table::BorderLine& rStruct, const SvxBorderLine* pLine )
976 {
977     if (pLine)
978     {
979         rStruct.Color          = pLine->GetColor().GetColor();
980         rStruct.InnerLineWidth = (sal_Int16)TwipsToHMM( pLine->GetInWidth() );
981         rStruct.OuterLineWidth = (sal_Int16)TwipsToHMM( pLine->GetOutWidth() );
982         rStruct.LineDistance   = (sal_Int16)TwipsToHMM( pLine->GetDistance() );
983     }
984     else
985         rStruct.Color = rStruct.InnerLineWidth =
986             rStruct.OuterLineWidth = rStruct.LineDistance = 0;
987 }
988 
989 void ScHelperFunctions::FillTableBorder( table::TableBorder& rBorder,
990                             const SvxBoxItem& rOuter, const SvxBoxInfoItem& rInner )
991 {
992     ScHelperFunctions::FillBorderLine( rBorder.TopLine,         rOuter.GetTop() );
993     ScHelperFunctions::FillBorderLine( rBorder.BottomLine,      rOuter.GetBottom() );
994     ScHelperFunctions::FillBorderLine( rBorder.LeftLine,        rOuter.GetLeft() );
995     ScHelperFunctions::FillBorderLine( rBorder.RightLine,       rOuter.GetRight() );
996     ScHelperFunctions::FillBorderLine( rBorder.HorizontalLine,  rInner.GetHori() );
997     ScHelperFunctions::FillBorderLine( rBorder.VerticalLine,    rInner.GetVert() );
998 
999     rBorder.Distance                = rOuter.GetDistance();
1000     rBorder.IsTopLineValid          = rInner.IsValid(VALID_TOP);
1001     rBorder.IsBottomLineValid       = rInner.IsValid(VALID_BOTTOM);
1002     rBorder.IsLeftLineValid         = rInner.IsValid(VALID_LEFT);
1003     rBorder.IsRightLineValid        = rInner.IsValid(VALID_RIGHT);
1004     rBorder.IsHorizontalLineValid   = rInner.IsValid(VALID_HORI);
1005     rBorder.IsVerticalLineValid     = rInner.IsValid(VALID_VERT);
1006     rBorder.IsDistanceValid         = rInner.IsValid(VALID_DISTANCE);
1007 }
1008 
1009 //------------------------------------------------------------------------
1010 
1011 //! lcl_ApplyBorder nach docfunc verschieben!
1012 
1013 void ScHelperFunctions::ApplyBorder( ScDocShell* pDocShell, const ScRangeList& rRanges,
1014                         const SvxBoxItem& rOuter, const SvxBoxInfoItem& rInner )
1015 {
1016     ScDocument* pDoc = pDocShell->GetDocument();
1017     sal_Bool bUndo(pDoc->IsUndoEnabled());
1018     ScDocument* pUndoDoc = NULL;
1019     if (bUndo)
1020         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1021     sal_uLong nCount = rRanges.Count();
1022     sal_uLong i;
1023     for (i=0; i<nCount; i++)
1024     {
1025         ScRange aRange(*rRanges.GetObject(i));
1026         SCTAB nTab = aRange.aStart.Tab();
1027 
1028         if (bUndo)
1029         {
1030             if ( i==0 )
1031                 pUndoDoc->InitUndo( pDoc, nTab, nTab );
1032             else
1033                 pUndoDoc->AddUndoTab( nTab, nTab );
1034             pDoc->CopyToDocument( aRange, IDF_ATTRIB, sal_False, pUndoDoc );
1035         }
1036 
1037         ScMarkData aMark;
1038         aMark.SetMarkArea( aRange );
1039         aMark.SelectTable( nTab, sal_True );
1040 
1041         pDoc->ApplySelectionFrame( aMark, &rOuter, &rInner );
1042         // RowHeight bei Umrandung alleine nicht noetig
1043     }
1044 
1045     if (bUndo)
1046     {
1047         pDocShell->GetUndoManager()->AddUndoAction(
1048                 new ScUndoBorder( pDocShell, rRanges, pUndoDoc, rOuter, rInner ) );
1049     }
1050 
1051     for (i=0; i<nCount; i++)
1052         pDocShell->PostPaint( *rRanges.GetObject(i), PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
1053 
1054     pDocShell->SetDocumentModified();
1055 }
1056 
1057 //! move lcl_PutDataArray to docfunc?
1058 //! merge loop with ScFunctionAccess::callFunction
1059 
1060 sal_Bool lcl_PutDataArray( ScDocShell& rDocShell, const ScRange& rRange,
1061                         const uno::Sequence< uno::Sequence<uno::Any> >& aData )
1062 {
1063 //  sal_Bool bApi = sal_True;
1064 
1065     ScDocument* pDoc = rDocShell.GetDocument();
1066     SCTAB nTab = rRange.aStart.Tab();
1067     SCCOL nStartCol = rRange.aStart.Col();
1068     SCROW nStartRow = rRange.aStart.Row();
1069     SCCOL nEndCol = rRange.aEnd.Col();
1070     SCROW nEndRow = rRange.aEnd.Row();
1071     sal_Bool bUndo(pDoc->IsUndoEnabled());
1072 
1073     if ( !pDoc->IsBlockEditable( nTab, nStartCol,nStartRow, nEndCol,nEndRow ) )
1074     {
1075         //! error message
1076         return sal_False;
1077     }
1078 
1079     long nCols = 0;
1080     long nRows = aData.getLength();
1081     const uno::Sequence<uno::Any>* pArray = aData.getConstArray();
1082     if ( nRows )
1083         nCols = pArray[0].getLength();
1084 
1085     if ( nCols != nEndCol-nStartCol+1 || nRows != nEndRow-nStartRow+1 )
1086     {
1087         //! error message?
1088         return sal_False;
1089     }
1090 
1091     ScDocument* pUndoDoc = NULL;
1092     if ( bUndo )
1093     {
1094         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1095         pUndoDoc->InitUndo( pDoc, nTab, nTab );
1096         pDoc->CopyToDocument( rRange, IDF_CONTENTS|IDF_NOCAPTIONS, sal_False, pUndoDoc );
1097     }
1098 
1099     pDoc->DeleteAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, IDF_CONTENTS );
1100 
1101     /*  #164410# Use double allocation, which will speed up import filters
1102         using XCellRangeData::setDataArray() significantly. */
1103     bool bDoubleAlloc = ScColumn::bDoubleAlloc;
1104     ScColumn::bDoubleAlloc = true;
1105 
1106     sal_Bool bError = sal_False;
1107     SCROW nDocRow = nStartRow;
1108     for (long nRow=0; nRow<nRows; nRow++)
1109     {
1110         const uno::Sequence<uno::Any>& rColSeq = pArray[nRow];
1111         if ( rColSeq.getLength() == nCols )
1112         {
1113             SCCOL nDocCol = nStartCol;
1114             const uno::Any* pColArr = rColSeq.getConstArray();
1115             for (long nCol=0; nCol<nCols; nCol++)
1116             {
1117                 const uno::Any& rElement = pColArr[nCol];
1118                 switch( rElement.getValueTypeClass() )
1119                 {
1120                     case uno::TypeClass_VOID:
1121                     {
1122                         // void = "no value"
1123                         pDoc->SetError( nDocCol, nDocRow, nTab, NOTAVAILABLE );
1124                     }
1125                     break;
1126 
1127                     //  #87871# accept integer types because Basic passes a floating point
1128                     //  variable as byte, short or long if it's an integer number.
1129                     case uno::TypeClass_BYTE:
1130                     case uno::TypeClass_SHORT:
1131                     case uno::TypeClass_UNSIGNED_SHORT:
1132                     case uno::TypeClass_LONG:
1133                     case uno::TypeClass_UNSIGNED_LONG:
1134                     case uno::TypeClass_FLOAT:
1135                     case uno::TypeClass_DOUBLE:
1136                     {
1137                         double fVal(0.0);
1138                         rElement >>= fVal;
1139                         pDoc->SetValue( nDocCol, nDocRow, nTab, fVal );
1140                     }
1141                     break;
1142 
1143                     case uno::TypeClass_STRING:
1144                     {
1145                         rtl::OUString aUStr;
1146                         rElement >>= aUStr;
1147                         if ( aUStr.getLength() )
1148                             pDoc->PutCell( nDocCol, nDocRow, nTab, new ScStringCell( aUStr ) );
1149                     }
1150                     break;
1151 
1152                     // accept Sequence<FormulaToken> for formula cells
1153                     case uno::TypeClass_SEQUENCE:
1154                     {
1155                         uno::Sequence< sheet::FormulaToken > aTokens;
1156                         if ( rElement >>= aTokens )
1157                         {
1158                             ScTokenArray aTokenArray;
1159                             ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, aTokens );
1160                             ScAddress aPos( nDocCol, nDocRow, nTab );
1161                             ScBaseCell* pNewCell = new ScFormulaCell( pDoc, aPos, &aTokenArray );
1162                             pDoc->PutCell( aPos, pNewCell );
1163                         }
1164                         else
1165                             bError = true;
1166                     }
1167                     break;
1168 
1169                     default:
1170                         bError = true;      // invalid type
1171                 }
1172 
1173                 ++nDocCol;
1174             }
1175         }
1176         else
1177             bError = sal_True;                          // wrong size
1178 
1179         ++nDocRow;
1180     }
1181     ScColumn::bDoubleAlloc = bDoubleAlloc;
1182 
1183     sal_Bool bHeight = rDocShell.AdjustRowHeight( nStartRow, nEndRow, nTab );
1184 
1185     if ( pUndoDoc )
1186     {
1187         ScMarkData aDestMark;
1188         aDestMark.SelectOneTable( nTab );
1189         rDocShell.GetUndoManager()->AddUndoAction(
1190             new ScUndoPaste( &rDocShell,
1191                 nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, aDestMark,
1192                 pUndoDoc, NULL, IDF_CONTENTS, NULL,NULL,NULL,NULL, sal_False ) );
1193     }
1194 
1195     if (!bHeight)
1196         rDocShell.PostPaint( rRange, PAINT_GRID );      // AdjustRowHeight may have painted already
1197 
1198     rDocShell.SetDocumentModified();
1199 
1200     return !bError;
1201 }
1202 
1203 sal_Bool lcl_PutFormulaArray( ScDocShell& rDocShell, const ScRange& rRange,
1204         const uno::Sequence< uno::Sequence<rtl::OUString> >& aData,
1205         const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
1206 {
1207 //  sal_Bool bApi = sal_True;
1208 
1209     ScDocument* pDoc = rDocShell.GetDocument();
1210     SCTAB nTab = rRange.aStart.Tab();
1211     SCCOL nStartCol = rRange.aStart.Col();
1212     SCROW nStartRow = rRange.aStart.Row();
1213     SCCOL nEndCol = rRange.aEnd.Col();
1214     SCROW nEndRow = rRange.aEnd.Row();
1215     sal_Bool bUndo(pDoc->IsUndoEnabled());
1216 
1217     if ( !pDoc->IsBlockEditable( nTab, nStartCol,nStartRow, nEndCol,nEndRow ) )
1218     {
1219         //! error message
1220         return sal_False;
1221     }
1222 
1223     long nCols = 0;
1224     long nRows = aData.getLength();
1225     const uno::Sequence<rtl::OUString>* pArray = aData.getConstArray();
1226     if ( nRows )
1227         nCols = pArray[0].getLength();
1228 
1229     if ( nCols != nEndCol-nStartCol+1 || nRows != nEndRow-nStartRow+1 )
1230     {
1231         //! error message?
1232         return sal_False;
1233     }
1234 
1235     ScDocument* pUndoDoc = NULL;
1236     if ( bUndo )
1237     {
1238         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1239         pUndoDoc->InitUndo( pDoc, nTab, nTab );
1240         pDoc->CopyToDocument( rRange, IDF_CONTENTS, sal_False, pUndoDoc );
1241     }
1242 
1243     pDoc->DeleteAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, IDF_CONTENTS );
1244 
1245     ScDocFunc aFunc( rDocShell );       // for InterpretEnglishString
1246 
1247     sal_Bool bError = sal_False;
1248     SCROW nDocRow = nStartRow;
1249     for (long nRow=0; nRow<nRows; nRow++)
1250     {
1251         const uno::Sequence<rtl::OUString>& rColSeq = pArray[nRow];
1252         if ( rColSeq.getLength() == nCols )
1253         {
1254             SCCOL nDocCol = nStartCol;
1255             const rtl::OUString* pColArr = rColSeq.getConstArray();
1256             for (long nCol=0; nCol<nCols; nCol++)
1257             {
1258                 String aText(pColArr[nCol]);
1259                 ScAddress aPos( nDocCol, nDocRow, nTab );
1260                 ScBaseCell* pNewCell = aFunc.InterpretEnglishString( aPos, aText, rFormulaNmsp, eGrammar );
1261                 pDoc->PutCell( aPos, pNewCell );
1262 
1263                 ++nDocCol;
1264             }
1265         }
1266         else
1267             bError = sal_True;                          // wrong size
1268 
1269         ++nDocRow;
1270     }
1271 
1272     sal_Bool bHeight = rDocShell.AdjustRowHeight( nStartRow, nEndRow, nTab );
1273 
1274     if ( pUndoDoc )
1275     {
1276         ScMarkData aDestMark;
1277         aDestMark.SelectOneTable( nTab );
1278         rDocShell.GetUndoManager()->AddUndoAction(
1279             new ScUndoPaste( &rDocShell,
1280                 nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, aDestMark,
1281                 pUndoDoc, NULL, IDF_CONTENTS, NULL,NULL,NULL,NULL, sal_False ) );
1282     }
1283 
1284     if (!bHeight)
1285         rDocShell.PostPaint( rRange, PAINT_GRID );      // AdjustRowHeight may have painted already
1286 
1287     rDocShell.SetDocumentModified();
1288 
1289     return !bError;
1290 }
1291 
1292 //  used in ScCellRangeObj::getFormulaArray and ScCellObj::GetInputString_Impl
1293 String lcl_GetInputString( ScDocument* pDoc, const ScAddress& rPosition, sal_Bool bEnglish )
1294 {
1295     String aVal;
1296     if ( pDoc )
1297     {
1298         ScBaseCell* pCell = pDoc->GetCell( rPosition );
1299         if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
1300         {
1301             CellType eType = pCell->GetCellType();
1302             if ( eType == CELLTYPE_FORMULA )
1303             {
1304                 ScFormulaCell* pForm = (ScFormulaCell*)pCell;
1305                 pForm->GetFormula( aVal,formula::FormulaGrammar::mapAPItoGrammar( bEnglish, false));
1306             }
1307             else
1308             {
1309                 SvNumberFormatter* pFormatter = bEnglish ? ScGlobal::GetEnglishFormatter() :
1310                                                             pDoc->GetFormatTable();
1311                 // Since the English formatter was constructed with
1312                 // LANGUAGE_ENGLISH_US the "General" format has index key 0,
1313                 // we don't have to query.
1314                 sal_uInt32 nNumFmt = bEnglish ?
1315 //                      pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US) :
1316                         0 :
1317                         pDoc->GetNumberFormat( rPosition );
1318 
1319                 if ( eType == CELLTYPE_EDIT )
1320                 {
1321                     //  GetString an der EditCell macht Leerzeichen aus Umbruechen,
1322                     //  hier werden die Umbrueche aber gebraucht
1323                     const EditTextObject* pData = ((ScEditCell*)pCell)->GetData();
1324                     if (pData)
1325                     {
1326                         EditEngine& rEngine = pDoc->GetEditEngine();
1327                         rEngine.SetText( *pData );
1328                         aVal = rEngine.GetText( LINEEND_LF );
1329                     }
1330                 }
1331                 else
1332                     ScCellFormat::GetInputString( pCell, nNumFmt, aVal, *pFormatter );
1333 
1334                 //  ggf. ein ' davorhaengen wie in ScTabViewShell::UpdateInputHandler
1335                 if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
1336                 {
1337                     double fDummy;
1338                     sal_Bool bIsNumberFormat(pFormatter->IsNumberFormat(aVal, nNumFmt, fDummy));
1339                     if ( bIsNumberFormat )
1340                         aVal.Insert('\'',0);
1341                     else if ( aVal.Len() && aVal.GetChar(0) == '\'' )
1342                     {
1343                         //  if the string starts with a "'", add another one because setFormula
1344                         //  strips one (like text input, except for "text" number formats)
1345                         if ( bEnglish || ( pFormatter->GetType(nNumFmt) != NUMBERFORMAT_TEXT ) )
1346                             aVal.Insert('\'',0);
1347                     }
1348                 }
1349             }
1350         }
1351     }
1352     return aVal;
1353 }
1354 
1355 //------------------------------------------------------------------------
1356 
1357 // Default-ctor fuer SMART_REFLECTION Krempel
1358 ScCellRangesBase::ScCellRangesBase() :
1359     pPropSet(lcl_GetCellsPropertySet()),
1360     pDocShell( NULL ),
1361     pValueListener( NULL ),
1362     pCurrentFlat( NULL ),
1363     pCurrentDeep( NULL ),
1364     pCurrentDataSet( NULL ),
1365     pNoDfltCurrentDataSet( NULL ),
1366     pMarkData( NULL ),
1367     nObjectId( 0 ),
1368     bChartColAsHdr( sal_False ),
1369     bChartRowAsHdr( sal_False ),
1370     bCursorOnly( sal_False ),
1371     bGotDataChangedHint( sal_False ),
1372     aValueListeners( 0 )
1373 {
1374 }
1375 
1376 ScCellRangesBase::ScCellRangesBase(ScDocShell* pDocSh, const ScRange& rR) :
1377     pPropSet(lcl_GetCellsPropertySet()),
1378     pDocShell( pDocSh ),
1379     pValueListener( NULL ),
1380     pCurrentFlat( NULL ),
1381     pCurrentDeep( NULL ),
1382     pCurrentDataSet( NULL ),
1383     pNoDfltCurrentDataSet( NULL ),
1384     pMarkData( NULL ),
1385     nObjectId( 0 ),
1386     bChartColAsHdr( sal_False ),
1387     bChartRowAsHdr( sal_False ),
1388     bCursorOnly( sal_False ),
1389     bGotDataChangedHint( sal_False ),
1390     aValueListeners( 0 )
1391 {
1392     ScRange aCellRange(rR);
1393     aCellRange.Justify();
1394     aRanges.Append( aCellRange );
1395 
1396     if (pDocShell)  // Null if created with createInstance
1397     {
1398         ScDocument* pDoc = pDocShell->GetDocument();
1399         pDoc->AddUnoObject(*this);
1400         nObjectId = pDoc->GetNewUnoId();
1401     }
1402 }
1403 
1404 ScCellRangesBase::ScCellRangesBase(ScDocShell* pDocSh, const ScRangeList& rR) :
1405     pPropSet(lcl_GetCellsPropertySet()),
1406     pDocShell( pDocSh ),
1407     pValueListener( NULL ),
1408     pCurrentFlat( NULL ),
1409     pCurrentDeep( NULL ),
1410     pCurrentDataSet( NULL ),
1411     pNoDfltCurrentDataSet( NULL ),
1412     pMarkData( NULL ),
1413     aRanges( rR ),
1414     nObjectId( 0 ),
1415     bChartColAsHdr( sal_False ),
1416     bChartRowAsHdr( sal_False ),
1417     bCursorOnly( sal_False ),
1418     bGotDataChangedHint( sal_False ),
1419     aValueListeners( 0 )
1420 {
1421     if (pDocShell)  // Null if created with createInstance
1422     {
1423         ScDocument* pDoc = pDocShell->GetDocument();
1424         pDoc->AddUnoObject(*this);
1425         nObjectId = pDoc->GetNewUnoId();
1426     }
1427 }
1428 
1429 ScCellRangesBase::~ScCellRangesBase()
1430 {
1431     //  #107294# call RemoveUnoObject first, so no notification can happen
1432     //  during ForgetCurrentAttrs
1433 
1434     if (pDocShell)
1435         pDocShell->GetDocument()->RemoveUnoObject(*this);
1436 
1437     ForgetCurrentAttrs();
1438     ForgetMarkData();
1439 
1440     delete pValueListener;
1441 
1442     //! XChartDataChangeEventListener abmelden ??
1443     //! (ChartCollection haelt dann auch dieses Objekt fest!)
1444 }
1445 
1446 void ScCellRangesBase::ForgetCurrentAttrs()
1447 {
1448     delete pCurrentFlat;
1449     delete pCurrentDeep;
1450     delete pCurrentDataSet;
1451     delete pNoDfltCurrentDataSet;
1452     pCurrentFlat = NULL;
1453     pCurrentDeep = NULL;
1454     pCurrentDataSet = NULL;
1455     pNoDfltCurrentDataSet = NULL;
1456 
1457     // #i62483# pMarkData can remain unchanged, is deleted only if the range changes (RefChanged)
1458 }
1459 
1460 void ScCellRangesBase::ForgetMarkData()
1461 {
1462     delete pMarkData;
1463     pMarkData = NULL;
1464 }
1465 
1466 const ScPatternAttr* ScCellRangesBase::GetCurrentAttrsFlat()
1467 {
1468     //  get and cache direct cell attributes for this object's range
1469 
1470     if ( !pCurrentFlat && pDocShell )
1471     {
1472         ScDocument* pDoc = pDocShell->GetDocument();
1473         pCurrentFlat = pDoc->CreateSelectionPattern( *GetMarkData(), sal_False );
1474     }
1475     return pCurrentFlat;
1476 }
1477 
1478 const ScPatternAttr* ScCellRangesBase::GetCurrentAttrsDeep()
1479 {
1480     //  get and cache cell attributes (incl. styles) for this object's range
1481 
1482     if ( !pCurrentDeep && pDocShell )
1483     {
1484         ScDocument* pDoc = pDocShell->GetDocument();
1485         pCurrentDeep = pDoc->CreateSelectionPattern( *GetMarkData(), sal_True );
1486     }
1487     return pCurrentDeep;
1488 }
1489 
1490 SfxItemSet* ScCellRangesBase::GetCurrentDataSet(bool bNoDflt)
1491 {
1492     if(!pCurrentDataSet)
1493     {
1494         const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
1495         if ( pPattern )
1496         {
1497             //  Dontcare durch Default ersetzen, damit man immer eine Reflection hat
1498             pCurrentDataSet = new SfxItemSet( pPattern->GetItemSet() );
1499             pNoDfltCurrentDataSet = new SfxItemSet( pPattern->GetItemSet() );
1500             pCurrentDataSet->ClearInvalidItems();
1501         }
1502     }
1503     return bNoDflt ? pNoDfltCurrentDataSet : pCurrentDataSet;
1504 }
1505 
1506 const ScMarkData* ScCellRangesBase::GetMarkData()
1507 {
1508     if (!pMarkData)
1509     {
1510         pMarkData = new ScMarkData();
1511         pMarkData->MarkFromRangeList( aRanges, sal_False );
1512     }
1513     return pMarkData;
1514 }
1515 
1516 void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
1517 {
1518     if ( rHint.ISA( ScUpdateRefHint ) )
1519     {
1520         const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
1521 
1522         ScDocument* pDoc = pDocShell->GetDocument();
1523         ScRangeList* pUndoRanges = NULL;
1524         if ( pDoc->HasUnoRefUndo() )
1525             pUndoRanges = new ScRangeList( aRanges );
1526 
1527         if ( aRanges.UpdateReference( rRef.GetMode(), pDoc, rRef.GetRange(),
1528                                     rRef.GetDx(), rRef.GetDy(), rRef.GetDz() ) )
1529         {
1530             if (rRef.GetMode() == URM_INSDEL &&
1531                 aRanges.Count() == 1 &&
1532                 ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ))
1533             {
1534                 // #101755#; the range size of a sheet does not change
1535                 ScRange* pR = aRanges.First();
1536                 if (pR)
1537                 {
1538                     pR->aStart.SetCol(0);
1539                     pR->aStart.SetRow(0);
1540                     pR->aEnd.SetCol(MAXCOL);
1541                     pR->aEnd.SetRow(MAXROW);
1542                 }
1543             }
1544             RefChanged();
1545 
1546             // #129050# any change of the range address is broadcast to value (modify) listeners
1547             if ( aValueListeners.Count() )
1548                 bGotDataChangedHint = sal_True;
1549 
1550             if ( pUndoRanges )
1551                 pDoc->AddUnoRefChange( nObjectId, *pUndoRanges );
1552         }
1553 
1554         delete pUndoRanges;
1555     }
1556     else if ( rHint.ISA( SfxSimpleHint ) )
1557     {
1558         sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
1559         if ( nId == SFX_HINT_DYING )
1560         {
1561             ForgetCurrentAttrs();
1562             pDocShell = NULL;           // invalid
1563 
1564             if ( aValueListeners.Count() != 0 )
1565             {
1566                 //  dispose listeners
1567 
1568                 lang::EventObject aEvent;
1569                 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
1570                 for ( sal_uInt16 n=0; n<aValueListeners.Count(); n++ )
1571                     (*aValueListeners[n])->disposing( aEvent );
1572 
1573                 aValueListeners.DeleteAndDestroy( 0, aValueListeners.Count() );
1574 
1575                 //  The listeners can't have the last ref to this, as it's still held
1576                 //  by the DocShell.
1577             }
1578         }
1579         else if ( nId == SFX_HINT_DATACHANGED )
1580         {
1581             // document content changed -> forget cached attributes
1582             ForgetCurrentAttrs();
1583 
1584             if ( bGotDataChangedHint && pDocShell )
1585             {
1586                 //  This object was notified of content changes, so one call
1587                 //  for each listener is generated now.
1588                 //  The calls can't be executed directly because the document's
1589                 //  UNO broadcaster list must not be modified.
1590                 //  Instead, add to the document's list of listener calls,
1591                 //  which will be executed directly after the broadcast of
1592                 //  SFX_HINT_DATACHANGED.
1593 
1594                 lang::EventObject aEvent;
1595                 aEvent.Source.set((cppu::OWeakObject*)this);
1596 
1597                 // the EventObject holds a Ref to this object until after the listener calls
1598 
1599                 ScDocument* pDoc = pDocShell->GetDocument();
1600                 for ( sal_uInt16 n=0; n<aValueListeners.Count(); n++ )
1601                     pDoc->AddUnoListenerCall( *aValueListeners[n], aEvent );
1602 
1603                 bGotDataChangedHint = sal_False;
1604             }
1605         }
1606         else if ( nId == SC_HINT_CALCALL )
1607         {
1608             // broadcast from DoHardRecalc - set bGotDataChangedHint
1609             // (SFX_HINT_DATACHANGED follows separately)
1610 
1611             if ( aValueListeners.Count() )
1612                 bGotDataChangedHint = sal_True;
1613         }
1614     }
1615     else if ( rHint.ISA( ScUnoRefUndoHint ) )
1616     {
1617         const ScUnoRefUndoHint& rUndoHint = static_cast<const ScUnoRefUndoHint&>(rHint);
1618         if ( rUndoHint.GetObjectId() == nObjectId )
1619         {
1620             // restore ranges from hint
1621 
1622             aRanges = rUndoHint.GetRanges();
1623 
1624             RefChanged();
1625             if ( aValueListeners.Count() )
1626                 bGotDataChangedHint = sal_True;     // need to broadcast the undo, too
1627         }
1628     }
1629 }
1630 
1631 void ScCellRangesBase::RefChanged()
1632 {
1633     //! adjust XChartDataChangeEventListener
1634 
1635     if ( pValueListener && aValueListeners.Count() != 0 )
1636     {
1637         pValueListener->EndListeningAll();
1638 
1639         ScDocument* pDoc = pDocShell->GetDocument();
1640         sal_uLong nCount = aRanges.Count();
1641         for (sal_uLong i=0; i<nCount; i++)
1642             pDoc->StartListeningArea( *aRanges.GetObject(i), pValueListener );
1643     }
1644 
1645     ForgetCurrentAttrs();
1646     ForgetMarkData();
1647 }
1648 
1649 ScDocument* ScCellRangesBase::GetDocument() const
1650 {
1651     if (pDocShell)
1652         return pDocShell->GetDocument();
1653     else
1654         return NULL;
1655 }
1656 
1657 void ScCellRangesBase::InitInsertRange(ScDocShell* pDocSh, const ScRange& rR)
1658 {
1659     if ( !pDocShell && pDocSh )
1660     {
1661         pDocShell = pDocSh;
1662 
1663         ScRange aCellRange(rR);
1664         aCellRange.Justify();
1665         aRanges.RemoveAll();
1666         aRanges.Append( aCellRange );
1667 
1668         pDocShell->GetDocument()->AddUnoObject(*this);
1669 
1670         RefChanged();   // Range im Range-Objekt anpassen
1671     }
1672 }
1673 
1674 void ScCellRangesBase::AddRange(const ScRange& rRange, const sal_Bool bMergeRanges)
1675 {
1676     if (bMergeRanges)
1677         aRanges.Join(rRange);
1678     else
1679         aRanges.Append(rRange);
1680     RefChanged();
1681 }
1682 
1683 void ScCellRangesBase::SetNewRange(const ScRange& rNew)
1684 {
1685     ScRange aCellRange(rNew);
1686     aCellRange.Justify();
1687 
1688     aRanges.RemoveAll();
1689     aRanges.Append( aCellRange );
1690     RefChanged();
1691 }
1692 
1693 void ScCellRangesBase::SetNewRanges(const ScRangeList& rNew)
1694 {
1695     aRanges = rNew;
1696     RefChanged();
1697 }
1698 
1699 void ScCellRangesBase::SetCursorOnly( sal_Bool bSet )
1700 {
1701     //  set for a selection object that is created from the cursor position
1702     //  without anything selected (may contain several sheets)
1703 
1704     bCursorOnly = bSet;
1705 }
1706 
1707 uno::Any SAL_CALL ScCellRangesBase::queryInterface( const uno::Type& rType )
1708                                                 throw(uno::RuntimeException)
1709 {
1710     SC_QUERYINTERFACE( beans::XPropertySet )
1711     SC_QUERYINTERFACE( beans::XMultiPropertySet )
1712     SC_QUERYINTERFACE( beans::XTolerantMultiPropertySet )
1713     SC_QUERYINTERFACE( beans::XPropertyState )
1714     SC_QUERYINTERFACE( sheet::XSheetOperation )
1715     SC_QUERYINTERFACE( chart::XChartDataArray )
1716     SC_QUERYINTERFACE( chart::XChartData )
1717     SC_QUERYINTERFACE( util::XIndent )
1718     SC_QUERYINTERFACE( sheet::XCellRangesQuery )
1719     SC_QUERYINTERFACE( sheet::XFormulaQuery )
1720     SC_QUERYINTERFACE( util::XReplaceable )
1721     SC_QUERYINTERFACE( util::XSearchable )
1722     SC_QUERYINTERFACE( util::XModifyBroadcaster )
1723     SC_QUERYINTERFACE( lang::XServiceInfo )
1724     SC_QUERYINTERFACE( lang::XUnoTunnel )
1725     SC_QUERYINTERFACE( lang::XTypeProvider )
1726 
1727     return OWeakObject::queryInterface( rType );
1728 }
1729 
1730 void SAL_CALL ScCellRangesBase::acquire() throw()
1731 {
1732     OWeakObject::acquire();
1733 }
1734 
1735 void SAL_CALL ScCellRangesBase::release() throw()
1736 {
1737     OWeakObject::release();
1738 }
1739 
1740 uno::Sequence<uno::Type> SAL_CALL ScCellRangesBase::getTypes() throw(uno::RuntimeException)
1741 {
1742     static uno::Sequence<uno::Type> aTypes;
1743     if ( aTypes.getLength() == 0 )
1744     {
1745         aTypes.realloc(13);
1746         uno::Type* pPtr = aTypes.getArray();
1747         pPtr[0] = getCppuType((const uno::Reference<beans::XPropertySet>*)0);
1748         pPtr[1] = getCppuType((const uno::Reference<beans::XMultiPropertySet>*)0);
1749         pPtr[2] = getCppuType((const uno::Reference<beans::XPropertyState>*)0);
1750         pPtr[3] = getCppuType((const uno::Reference<sheet::XSheetOperation>*)0);
1751         pPtr[4] = getCppuType((const uno::Reference<chart::XChartDataArray>*)0);
1752         pPtr[5] = getCppuType((const uno::Reference<util::XIndent>*)0);
1753         pPtr[6] = getCppuType((const uno::Reference<sheet::XCellRangesQuery>*)0);
1754         pPtr[7] = getCppuType((const uno::Reference<sheet::XFormulaQuery>*)0);
1755         pPtr[8] = getCppuType((const uno::Reference<util::XReplaceable>*)0);
1756         pPtr[9] = getCppuType((const uno::Reference<util::XModifyBroadcaster>*)0);
1757         pPtr[10]= getCppuType((const uno::Reference<lang::XServiceInfo>*)0);
1758         pPtr[11]= getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
1759         pPtr[12]= getCppuType((const uno::Reference<lang::XTypeProvider>*)0);
1760     }
1761     return aTypes;
1762 }
1763 
1764 uno::Sequence<sal_Int8> SAL_CALL ScCellRangesBase::getImplementationId()
1765                                                     throw(uno::RuntimeException)
1766 {
1767     static uno::Sequence< sal_Int8 > aId;
1768     if( aId.getLength() == 0 )
1769     {
1770         aId.realloc( 16 );
1771         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
1772     }
1773     return aId;
1774 }
1775 
1776 // ---
1777 
1778 void ScCellRangesBase::PaintRanges_Impl( sal_uInt16 nPart )
1779 {
1780     sal_uLong nCount = aRanges.Count();
1781     for (sal_uLong i=0; i<nCount; i++)
1782         pDocShell->PostPaint( *aRanges.GetObject(i), nPart );
1783 }
1784 
1785 // XSheetOperation
1786 
1787 double SAL_CALL ScCellRangesBase::computeFunction( sheet::GeneralFunction nFunction )
1788                                                 throw(uno::Exception, uno::RuntimeException)
1789 {
1790     ScUnoGuard aGuard;
1791     ScMarkData aMark(*GetMarkData());
1792     aMark.MarkToSimple();
1793     if (!aMark.IsMarked())
1794         aMark.SetMarkNegative(sal_True);    // um Dummy Position angeben zu koennen
1795 
1796     ScAddress aDummy;                   // wenn nicht Marked, ignoriert wegen Negative
1797     double fVal;
1798     ScSubTotalFunc eFunc = lcl_SummaryToSubTotal( nFunction );
1799     ScDocument* pDoc = pDocShell->GetDocument();
1800     if ( !pDoc->GetSelectionFunction( eFunc, aDummy, aMark, fVal ) )
1801     {
1802         throw uno::RuntimeException();      //! own exception?
1803     }
1804 
1805     return fVal;
1806 }
1807 
1808 void SAL_CALL ScCellRangesBase::clearContents( sal_Int32 nContentFlags ) throw(uno::RuntimeException)
1809 {
1810     ScUnoGuard aGuard;
1811     if ( aRanges.Count() )
1812     {
1813         // only for clearContents: EDITATTR is only used if no contents are deleted
1814         sal_uInt16 nDelFlags = static_cast< sal_uInt16 >( nContentFlags & IDF_ALL );
1815         if ( ( nContentFlags & IDF_EDITATTR ) && ( nContentFlags & IDF_CONTENTS ) == 0 )
1816             nDelFlags |= IDF_EDITATTR;
1817 
1818         ScDocFunc aFunc(*pDocShell);
1819         aFunc.DeleteContents( *GetMarkData(), nDelFlags, sal_True, sal_True );
1820     }
1821     // sonst ist nichts zu tun
1822 }
1823 
1824 // XPropertyState
1825 
1826 const SfxItemPropertyMap* ScCellRangesBase::GetItemPropertyMap()
1827 {
1828     return pPropSet->getPropertyMap();
1829 }
1830 
1831 void lcl_GetPropertyWhich( const SfxItemPropertySimpleEntry* pEntry,
1832                                                 sal_uInt16& rItemWhich )
1833 {
1834     //  Which-ID des betroffenen Items, auch wenn das Item die Property
1835     //  nicht alleine behandeln kann
1836     if ( pEntry )
1837     {
1838         if ( IsScItemWid( pEntry->nWID ) )
1839             rItemWhich = pEntry->nWID;
1840         else
1841             switch ( pEntry->nWID )
1842             {
1843                 case SC_WID_UNO_TBLBORD:
1844                     rItemWhich = ATTR_BORDER;
1845                     break;
1846                 case SC_WID_UNO_CONDFMT:
1847                 case SC_WID_UNO_CONDLOC:
1848                 case SC_WID_UNO_CONDXML:
1849                     rItemWhich = ATTR_CONDITIONAL;
1850                     break;
1851                 case SC_WID_UNO_VALIDAT:
1852                 case SC_WID_UNO_VALILOC:
1853                 case SC_WID_UNO_VALIXML:
1854                     rItemWhich = ATTR_VALIDDATA;
1855                     break;
1856             }
1857     }
1858 
1859 }
1860 
1861 beans::PropertyState ScCellRangesBase::GetOnePropertyState( sal_uInt16 nItemWhich, const SfxItemPropertySimpleEntry* pEntry )
1862 {
1863     beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
1864     if ( nItemWhich )                   // item wid (from map or special case)
1865     {
1866         //  For items that contain several properties (like background),
1867         //  "ambiguous" is returned too often here
1868 
1869         //  for PropertyState, don't look at styles
1870         const ScPatternAttr* pPattern = GetCurrentAttrsFlat();
1871         if ( pPattern )
1872         {
1873             SfxItemState eState = pPattern->GetItemSet().GetItemState( nItemWhich, sal_False );
1874 
1875 //           //  if no rotate value is set, look at orientation
1876 //           //! also for a fixed value of 0 (in case orientation is ambiguous)?
1877 //           if ( nItemWhich == ATTR_ROTATE_VALUE && eState == SFX_ITEM_DEFAULT )
1878 //               eState = pPattern->GetItemSet().GetItemState( ATTR_ORIENTATION, sal_False );
1879 
1880             if ( nItemWhich == ATTR_VALUE_FORMAT && eState == SFX_ITEM_DEFAULT )
1881                 eState = pPattern->GetItemSet().GetItemState( ATTR_LANGUAGE_FORMAT, sal_False );
1882 
1883             if ( eState == SFX_ITEM_SET )
1884                 eRet = beans::PropertyState_DIRECT_VALUE;
1885             else if ( eState == SFX_ITEM_DEFAULT )
1886                 eRet = beans::PropertyState_DEFAULT_VALUE;
1887             else if ( eState == SFX_ITEM_DONTCARE )
1888                 eRet = beans::PropertyState_AMBIGUOUS_VALUE;
1889             else
1890             {
1891                 DBG_ERROR("unbekannter ItemState");
1892             }
1893         }
1894     }
1895     else if ( pEntry )
1896     {
1897         if ( pEntry->nWID == SC_WID_UNO_CHCOLHDR || pEntry->nWID == SC_WID_UNO_CHROWHDR || pEntry->nWID == SC_WID_UNO_ABSNAME )
1898             eRet = beans::PropertyState_DIRECT_VALUE;
1899         else if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
1900         {
1901             //  a style is always set, there's no default state
1902             const ScStyleSheet* pStyle = pDocShell->GetDocument()->GetSelectionStyle(*GetMarkData());
1903             if (pStyle)
1904                 eRet = beans::PropertyState_DIRECT_VALUE;
1905             else
1906                 eRet = beans::PropertyState_AMBIGUOUS_VALUE;
1907         }
1908         else if ( pEntry->nWID == SC_WID_UNO_NUMRULES )
1909             eRet = beans::PropertyState_DEFAULT_VALUE;      // numbering rules are always default
1910     }
1911     return eRet;
1912 }
1913 
1914 beans::PropertyState SAL_CALL ScCellRangesBase::getPropertyState( const rtl::OUString& aPropertyName )
1915                                 throw(beans::UnknownPropertyException, uno::RuntimeException)
1916 {
1917     ScUnoGuard aGuard;
1918     if ( aRanges.Count() == 0 )
1919         throw uno::RuntimeException();
1920 
1921     const SfxItemPropertyMap* pMap = GetItemPropertyMap();     // from derived class
1922     sal_uInt16 nItemWhich = 0;
1923     const SfxItemPropertySimpleEntry* pEntry  = pMap->getByName( aPropertyName );
1924     lcl_GetPropertyWhich( pEntry, nItemWhich );
1925     return GetOnePropertyState( nItemWhich, pEntry );
1926 }
1927 
1928 uno::Sequence<beans::PropertyState> SAL_CALL ScCellRangesBase::getPropertyStates(
1929                                 const uno::Sequence<rtl::OUString>& aPropertyNames )
1930                             throw(beans::UnknownPropertyException, uno::RuntimeException)
1931 {
1932     ScUnoGuard aGuard;
1933 
1934     const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
1935 
1936     uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
1937     beans::PropertyState* pStates = aRet.getArray();
1938     for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
1939     {
1940         sal_uInt16 nItemWhich = 0;
1941         const SfxItemPropertySimpleEntry* pEntry  = pPropertyMap->getByName( aPropertyNames[i] );
1942         lcl_GetPropertyWhich( pEntry, nItemWhich );
1943         pStates[i] = GetOnePropertyState(nItemWhich, pEntry);
1944     }
1945     return aRet;
1946 }
1947 
1948 void SAL_CALL ScCellRangesBase::setPropertyToDefault( const rtl::OUString& aPropertyName )
1949                             throw(beans::UnknownPropertyException, uno::RuntimeException)
1950 {
1951     ScUnoGuard aGuard;
1952     if ( pDocShell )
1953     {
1954         const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
1955         sal_uInt16 nItemWhich = 0;
1956         const SfxItemPropertySimpleEntry* pEntry  = pPropertyMap->getByName( aPropertyName );
1957         lcl_GetPropertyWhich( pEntry, nItemWhich );
1958         if ( nItemWhich )               // item wid (from map or special case)
1959         {
1960             if ( aRanges.Count() )      // leer = nichts zu tun
1961             {
1962                 ScDocFunc aFunc(*pDocShell);
1963 
1964                 //! Bei Items, die mehrere Properties enthalten (z.B. Hintergrund)
1965                 //! wird hier zuviel zurueckgesetzt
1966 
1967 //               //! for ATTR_ROTATE_VALUE, also reset ATTR_ORIENTATION?
1968 
1969                 sal_uInt16 aWIDs[3];
1970                 aWIDs[0] = nItemWhich;
1971                 if ( nItemWhich == ATTR_VALUE_FORMAT )
1972                 {
1973                     aWIDs[1] = ATTR_LANGUAGE_FORMAT;    // #67847# language for number formats
1974                     aWIDs[2] = 0;
1975                 }
1976                 else
1977                     aWIDs[1] = 0;
1978                 aFunc.ClearItems( *GetMarkData(), aWIDs, sal_True );
1979             }
1980         }
1981         else if ( pEntry )
1982         {
1983             if ( pEntry->nWID == SC_WID_UNO_CHCOLHDR )
1984                 bChartColAsHdr = sal_False;
1985             else if ( pEntry->nWID == SC_WID_UNO_CHROWHDR )
1986                 bChartRowAsHdr = sal_False;
1987             else if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
1988             {
1989                 ScDocFunc aFunc(*pDocShell);
1990                 aFunc.ApplyStyle( *GetMarkData(), ScGlobal::GetRscString(STR_STYLENAME_STANDARD), sal_True, sal_True );
1991             }
1992         }
1993     }
1994 }
1995 
1996 uno::Any SAL_CALL ScCellRangesBase::getPropertyDefault( const rtl::OUString& aPropertyName )
1997                                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
1998                                         uno::RuntimeException)
1999 {
2000     //! mit getPropertyValue zusammenfassen
2001 
2002     ScUnoGuard aGuard;
2003     uno::Any aAny;
2004 
2005     if ( pDocShell )
2006     {
2007         ScDocument* pDoc = pDocShell->GetDocument();
2008         const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
2009         const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyName );
2010         if ( pEntry )
2011         {
2012             if ( IsScItemWid( pEntry->nWID ) )
2013             {
2014                 const ScPatternAttr* pPattern = pDoc->GetDefPattern();
2015                 if ( pPattern )
2016                 {
2017                     const SfxItemSet& rSet = pPattern->GetItemSet();
2018 
2019                     switch ( pEntry->nWID )     // fuer Item-Spezial-Behandlungen
2020                     {
2021                         case ATTR_VALUE_FORMAT:
2022                             //  default has no language set
2023                             aAny <<= (sal_Int32)( ((const SfxUInt32Item&)rSet.Get(pEntry->nWID)).GetValue() );
2024                             break;
2025                         case ATTR_INDENT:
2026                             aAny <<= (sal_Int16)( TwipsToHMM(((const SfxUInt16Item&)
2027                                             rSet.Get(pEntry->nWID)).GetValue()) );
2028                             break;
2029                         default:
2030                             pPropSet->getPropertyValue(aPropertyName, rSet, aAny);
2031                     }
2032                 }
2033             }
2034             else
2035                 switch ( pEntry->nWID )
2036                 {
2037                     case SC_WID_UNO_CHCOLHDR:
2038                     case SC_WID_UNO_CHROWHDR:
2039                         ScUnoHelpFunctions::SetBoolInAny( aAny, sal_False );
2040                         break;
2041                     case SC_WID_UNO_CELLSTYL:
2042                         aAny <<= rtl::OUString( ScStyleNameConversion::DisplayToProgrammaticName(
2043                                     ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA ) );
2044                         break;
2045                     case SC_WID_UNO_TBLBORD:
2046                         {
2047                             const ScPatternAttr* pPattern = pDoc->GetDefPattern();
2048                             if ( pPattern )
2049                             {
2050                                 table::TableBorder aBorder;
2051                                 ScHelperFunctions::FillTableBorder( aBorder,
2052                                         (const SvxBoxItem&)pPattern->GetItem(ATTR_BORDER),
2053                                         (const SvxBoxInfoItem&)pPattern->GetItem(ATTR_BORDER_INNER) );
2054                                 aAny <<= aBorder;
2055                             }
2056                         }
2057                         break;
2058                     case SC_WID_UNO_CONDFMT:
2059                     case SC_WID_UNO_CONDLOC:
2060                     case SC_WID_UNO_CONDXML:
2061                         {
2062                             sal_Bool bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
2063                             sal_Bool bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
2064                             formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2065                                     pDoc->GetStorageGrammar() :
2066                                    formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2067 
2068                             aAny <<= uno::Reference<sheet::XSheetConditionalEntries>(
2069                                     new ScTableConditionalFormat( pDoc, 0, eGrammar ));
2070                         }
2071                         break;
2072                     case SC_WID_UNO_VALIDAT:
2073                     case SC_WID_UNO_VALILOC:
2074                     case SC_WID_UNO_VALIXML:
2075                         {
2076                             sal_Bool bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
2077                             sal_Bool bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
2078                             formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2079                                     pDoc->GetStorageGrammar() :
2080                                    formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2081 
2082                             aAny <<= uno::Reference<beans::XPropertySet>(
2083                                     new ScTableValidationObj( pDoc, 0, eGrammar ));
2084                         }
2085                         break;
2086                     case SC_WID_UNO_NUMRULES:
2087                         {
2088                             aAny <<= uno::Reference<container::XIndexReplace>(ScStyleObj::CreateEmptyNumberingRules());
2089                         }
2090                         break;
2091                 }
2092         }
2093     }
2094 
2095     return aAny;
2096 }
2097 
2098 // XPropertySet
2099 
2100 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellRangesBase::getPropertySetInfo()
2101                                                         throw(uno::RuntimeException)
2102 {
2103     ScUnoGuard aGuard;
2104     static uno::Reference<beans::XPropertySetInfo> aRef(
2105         new SfxItemPropertySetInfo( pPropSet->getPropertyMap() ));
2106     return aRef;
2107 }
2108 
2109 
2110 void lcl_SetCellProperty( const SfxItemPropertySimpleEntry& rEntry, const uno::Any& rValue,
2111                             ScPatternAttr& rPattern, ScDocument* pDoc,
2112                             sal_uInt16& rFirstItemId, sal_uInt16& rSecondItemId )
2113 {
2114     rFirstItemId = rEntry.nWID;
2115     rSecondItemId = 0;
2116 
2117     SfxItemSet& rSet = rPattern.GetItemSet();
2118     switch ( rEntry.nWID )
2119     {
2120         case ATTR_VALUE_FORMAT:
2121             {
2122                 // #67847# language for number formats
2123                 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
2124                 sal_uLong nOldFormat = ((const SfxUInt32Item&)rSet.Get( ATTR_VALUE_FORMAT )).GetValue();
2125                 LanguageType eOldLang = ((const SvxLanguageItem&)rSet.Get( ATTR_LANGUAGE_FORMAT )).GetLanguage();
2126                 nOldFormat = pFormatter->GetFormatForLanguageIfBuiltIn( nOldFormat, eOldLang );
2127 
2128                 sal_Int32 nIntVal = 0;
2129                 if ( rValue >>= nIntVal )
2130                 {
2131                     sal_uLong nNewFormat = (sal_uLong)nIntVal;
2132                     rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
2133 
2134                     const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
2135                     LanguageType eNewLang =
2136                         pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
2137                     if ( eNewLang != eOldLang && eNewLang != LANGUAGE_DONTKNOW )
2138                     {
2139                         rSet.Put( SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
2140 
2141                         // #40606# if only language is changed,
2142                         // don't touch number format attribute
2143                         sal_uLong nNewMod = nNewFormat % SV_COUNTRY_LANGUAGE_OFFSET;
2144                         if ( nNewMod == ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) &&
2145                              nNewMod <= SV_MAX_ANZ_STANDARD_FORMATE )
2146                         {
2147                             rFirstItemId = 0;       // don't use ATTR_VALUE_FORMAT value
2148                         }
2149 
2150                         rSecondItemId = ATTR_LANGUAGE_FORMAT;
2151                     }
2152                 }
2153                 else
2154                     throw lang::IllegalArgumentException();
2155             }
2156             break;
2157         case ATTR_INDENT:
2158             {
2159                 sal_Int16 nIntVal = 0;
2160                 if ( rValue >>= nIntVal )
2161                     rSet.Put( SfxUInt16Item( rEntry.nWID, (sal_uInt16)HMMToTwips(nIntVal) ) );
2162                 else
2163                     throw lang::IllegalArgumentException();
2164             }
2165             break;
2166         case ATTR_ROTATE_VALUE:
2167             {
2168                 sal_Int32 nRotVal = 0;
2169                 if ( rValue >>= nRotVal )
2170                 {
2171                     //  stored value is always between 0 and 360 deg.
2172                     nRotVal %= 36000;
2173                     if ( nRotVal < 0 )
2174                         nRotVal += 36000;
2175 
2176                     rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, nRotVal ) );
2177                 }
2178                 else
2179                     throw lang::IllegalArgumentException();
2180             }
2181             break;
2182         case ATTR_STACKED:
2183             {
2184                 table::CellOrientation eOrient;
2185                 if( rValue >>= eOrient )
2186                 {
2187                     switch( eOrient )
2188                     {
2189                         case table::CellOrientation_STANDARD:
2190                             rSet.Put( SfxBoolItem( ATTR_STACKED, sal_False ) );
2191                         break;
2192                         case table::CellOrientation_TOPBOTTOM:
2193                             rSet.Put( SfxBoolItem( ATTR_STACKED, sal_False ) );
2194                             rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 27000 ) );
2195                             rSecondItemId = ATTR_ROTATE_VALUE;
2196                         break;
2197                         case table::CellOrientation_BOTTOMTOP:
2198                             rSet.Put( SfxBoolItem( ATTR_STACKED, sal_False ) );
2199                             rSet.Put( SfxInt32Item( ATTR_ROTATE_VALUE, 9000 ) );
2200                             rSecondItemId = ATTR_ROTATE_VALUE;
2201                         break;
2202                         case table::CellOrientation_STACKED:
2203                             rSet.Put( SfxBoolItem( ATTR_STACKED, sal_True ) );
2204                         break;
2205                         default:
2206                         {
2207                             // added to avoid warnings
2208                         }
2209                     }
2210                 }
2211             }
2212             break;
2213         default:
2214             {
2215                 lcl_GetCellsPropertySet()->setPropertyValue(rEntry, rValue, rSet);
2216             }
2217     }
2218 }
2219 
2220 void SAL_CALL ScCellRangesBase::setPropertyValue(
2221                         const rtl::OUString& aPropertyName, const uno::Any& aValue )
2222                 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
2223                         lang::IllegalArgumentException, lang::WrappedTargetException,
2224                         uno::RuntimeException)
2225 {
2226     ScUnoGuard aGuard;
2227 
2228     if ( !pDocShell || aRanges.Count() == 0 )
2229         throw uno::RuntimeException();
2230 
2231     const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
2232     const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyName );
2233     if ( !pEntry )
2234         throw beans::UnknownPropertyException();
2235 
2236     SetOnePropertyValue( pEntry, aValue );
2237 }
2238 
2239 void ScCellRangesBase::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
2240                                 throw(lang::IllegalArgumentException, uno::RuntimeException)
2241 {
2242     if ( pEntry )
2243     {
2244         if ( IsScItemWid( pEntry->nWID ) )
2245         {
2246             if ( aRanges.Count() )      // leer = nichts zu tun
2247             {
2248                 ScDocument* pDoc = pDocShell->GetDocument();
2249                 ScDocFunc aFunc(*pDocShell);
2250 
2251                 //  Fuer Teile von zusammengesetzten Items mit mehreren Properties (z.B. Hintergrund)
2252                 //  muss vorher das alte Item aus dem Dokument geholt werden
2253                 //! Das kann hier aber nicht erkannt werden
2254                 //! -> eigenes Flag im PropertyMap-Eintrag, oder was ???
2255                 //! Item direkt von einzelner Position im Bereich holen?
2256                 //  ClearInvalidItems, damit auf jeden Fall ein Item vom richtigen Typ da ist
2257 
2258                 ScPatternAttr aPattern( *GetCurrentAttrsDeep() );
2259                 SfxItemSet& rSet = aPattern.GetItemSet();
2260                 rSet.ClearInvalidItems();
2261 
2262                 sal_uInt16 nFirstItem, nSecondItem;
2263                 lcl_SetCellProperty( *pEntry, aValue, aPattern, pDoc, nFirstItem, nSecondItem );
2264 
2265                 for (sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; nWhich++)
2266                     if ( nWhich != nFirstItem && nWhich != nSecondItem )
2267                         rSet.ClearItem(nWhich);
2268 
2269                 aFunc.ApplyAttributes( *GetMarkData(), aPattern, sal_True, sal_True );
2270             }
2271         }
2272         else        // implemented here
2273             switch ( pEntry->nWID )
2274             {
2275                 case SC_WID_UNO_CHCOLHDR:
2276                     // chart header flags are set for this object, not stored with document
2277                     bChartColAsHdr = ScUnoHelpFunctions::GetBoolFromAny( aValue );
2278                     break;
2279                 case SC_WID_UNO_CHROWHDR:
2280                     bChartRowAsHdr = ScUnoHelpFunctions::GetBoolFromAny( aValue );
2281                     break;
2282                 case SC_WID_UNO_CELLSTYL:
2283                     {
2284                         rtl::OUString aStrVal;
2285                         aValue >>= aStrVal;
2286                         String aString(ScStyleNameConversion::ProgrammaticToDisplayName(
2287                                                             aStrVal, SFX_STYLE_FAMILY_PARA ));
2288                         ScDocFunc aFunc(*pDocShell);
2289                         aFunc.ApplyStyle( *GetMarkData(), aString, sal_True, sal_True );
2290                     }
2291                     break;
2292                 case SC_WID_UNO_TBLBORD:
2293                     {
2294                         table::TableBorder aBorder;
2295                         if ( aRanges.Count() && ( aValue >>= aBorder ) )    // empty = nothing to do
2296                         {
2297                             SvxBoxItem aOuter(ATTR_BORDER);
2298                             SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
2299                             ScHelperFunctions::FillBoxItems( aOuter, aInner, aBorder );
2300 
2301                             ScHelperFunctions::ApplyBorder( pDocShell, aRanges, aOuter, aInner );   //! docfunc
2302                         }
2303                     }
2304                     break;
2305                 case SC_WID_UNO_CONDFMT:
2306                 case SC_WID_UNO_CONDLOC:
2307                 case SC_WID_UNO_CONDXML:
2308                     {
2309                         uno::Reference<sheet::XSheetConditionalEntries> xInterface(aValue, uno::UNO_QUERY);
2310                         if ( aRanges.Count() && xInterface.is() )   // leer = nichts zu tun
2311                         {
2312                             ScTableConditionalFormat* pFormat =
2313                                     ScTableConditionalFormat::getImplementation( xInterface );
2314                             if (pFormat)
2315                             {
2316                                 ScDocument* pDoc = pDocShell->GetDocument();
2317                                 sal_Bool bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
2318                                 sal_Bool bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
2319                                 formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2320                                        formula::FormulaGrammar::GRAM_UNSPECIFIED :
2321                                        formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2322 
2323                                 ScConditionalFormat aNew( 0, pDoc );    // Index wird beim Einfuegen gesetzt
2324                                 pFormat->FillFormat( aNew, pDoc, eGrammar );
2325                                 sal_uLong nIndex = pDoc->AddCondFormat( aNew );
2326 
2327                                 ScDocFunc aFunc(*pDocShell);
2328 
2329                                 ScPatternAttr aPattern( pDoc->GetPool() );
2330                                 aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_CONDITIONAL, nIndex ) );
2331                                 aFunc.ApplyAttributes( *GetMarkData(), aPattern, sal_True, sal_True );
2332                             }
2333                         }
2334                     }
2335                     break;
2336                 case SC_WID_UNO_VALIDAT:
2337                 case SC_WID_UNO_VALILOC:
2338                 case SC_WID_UNO_VALIXML:
2339                     {
2340                         uno::Reference<beans::XPropertySet> xInterface(aValue, uno::UNO_QUERY);
2341                         if ( aRanges.Count() && xInterface.is() )   // leer = nichts zu tun
2342                         {
2343                             ScTableValidationObj* pValidObj =
2344                                     ScTableValidationObj::getImplementation( xInterface );
2345                             if (pValidObj)
2346                             {
2347                                 ScDocument* pDoc = pDocShell->GetDocument();
2348                                 sal_Bool bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
2349                                 sal_Bool bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
2350                                 formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2351                                        formula::FormulaGrammar::GRAM_UNSPECIFIED :
2352                                        formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2353 
2354                                 ScValidationData* pNewData =
2355                                         pValidObj->CreateValidationData( pDoc, eGrammar );
2356                                 sal_uLong nIndex = pDoc->AddValidationEntry( *pNewData );
2357                                 delete pNewData;
2358 
2359                                 ScDocFunc aFunc(*pDocShell);
2360 
2361                                 ScPatternAttr aPattern( pDoc->GetPool() );
2362                                 aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nIndex ) );
2363                                 aFunc.ApplyAttributes( *GetMarkData(), aPattern, sal_True, sal_True );
2364                             }
2365                         }
2366                     }
2367                     break;
2368                 // SC_WID_UNO_NUMRULES is ignored...
2369             }
2370     }
2371 }
2372 
2373 uno::Any SAL_CALL ScCellRangesBase::getPropertyValue( const rtl::OUString& aPropertyName )
2374                 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
2375                         uno::RuntimeException)
2376 {
2377     ScUnoGuard aGuard;
2378 
2379     if ( !pDocShell || aRanges.Count() == 0 )
2380         throw uno::RuntimeException();
2381 
2382     const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
2383     const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyName );
2384     if ( !pEntry )
2385         throw beans::UnknownPropertyException();
2386 
2387     uno::Any aAny;
2388     GetOnePropertyValue( pEntry, aAny );
2389     return aAny;
2390 }
2391 
2392 void ScCellRangesBase::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
2393                                                 uno::Any& rAny )
2394                                                 throw(uno::RuntimeException)
2395 {
2396     if ( pEntry )
2397     {
2398         if ( IsScItemWid( pEntry->nWID ) )
2399         {
2400             SfxItemSet* pDataSet = GetCurrentDataSet();
2401             if ( pDataSet )
2402             {
2403                 switch ( pEntry->nWID )     // fuer Item-Spezial-Behandlungen
2404                 {
2405                     case ATTR_VALUE_FORMAT:
2406                         {
2407                             ScDocument* pDoc = pDocShell->GetDocument();
2408 
2409                             sal_uLong nOldFormat = ((const SfxUInt32Item&)
2410                                     pDataSet->Get( ATTR_VALUE_FORMAT )).GetValue();
2411                             LanguageType eOldLang = ((const SvxLanguageItem&)
2412                                     pDataSet->Get( ATTR_LANGUAGE_FORMAT )).GetLanguage();
2413                             nOldFormat = pDoc->GetFormatTable()->
2414                                     GetFormatForLanguageIfBuiltIn( nOldFormat, eOldLang );
2415                             rAny <<= (sal_Int32)( nOldFormat );
2416                         }
2417                         break;
2418                     case ATTR_INDENT:
2419                         rAny <<= (sal_Int16)( TwipsToHMM(((const SfxUInt16Item&)
2420                                         pDataSet->Get(pEntry->nWID)).GetValue()) );
2421                         break;
2422                     case ATTR_STACKED:
2423                         {
2424                             sal_Int32 nRot = ((const SfxInt32Item&)pDataSet->Get(ATTR_ROTATE_VALUE)).GetValue();
2425                             sal_Bool bStacked = ((const SfxBoolItem&)pDataSet->Get(pEntry->nWID)).GetValue();
2426                             SvxOrientationItem( nRot, bStacked, 0 ).QueryValue( rAny );
2427                         }
2428                         break;
2429                     default:
2430                         pPropSet->getPropertyValue(*pEntry, *pDataSet, rAny);
2431                 }
2432             }
2433         }
2434         else        // implemented here
2435             switch ( pEntry->nWID )
2436             {
2437                 case SC_WID_UNO_CHCOLHDR:
2438                     ScUnoHelpFunctions::SetBoolInAny( rAny, bChartColAsHdr );
2439                     break;
2440                 case SC_WID_UNO_CHROWHDR:
2441                     ScUnoHelpFunctions::SetBoolInAny( rAny, bChartRowAsHdr );
2442                     break;
2443                 case SC_WID_UNO_CELLSTYL:
2444                     {
2445                         String aStyleName;
2446                         const ScStyleSheet* pStyle = pDocShell->GetDocument()->GetSelectionStyle(*GetMarkData());
2447                         if (pStyle)
2448                             aStyleName = pStyle->GetName();
2449                         rAny <<= rtl::OUString( ScStyleNameConversion::DisplayToProgrammaticName(
2450                                                                 aStyleName, SFX_STYLE_FAMILY_PARA ) );
2451                     }
2452                     break;
2453                 case SC_WID_UNO_TBLBORD:
2454                     {
2455                         //! loop throgh all ranges
2456                         const ScRange* pFirst = aRanges.GetObject(0);
2457                         if (pFirst)
2458                         {
2459                             SvxBoxItem aOuter(ATTR_BORDER);
2460                             SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
2461 
2462                             ScDocument* pDoc = pDocShell->GetDocument();
2463                             ScMarkData aMark;
2464                             aMark.SetMarkArea( *pFirst );
2465                             aMark.SelectTable( pFirst->aStart.Tab(), sal_True );
2466                             pDoc->GetSelectionFrame( aMark, aOuter, aInner );
2467 
2468                             table::TableBorder aBorder;
2469                             ScHelperFunctions::FillTableBorder( aBorder, aOuter, aInner );
2470                             rAny <<= aBorder;
2471                         }
2472                     }
2473                     break;
2474                 case SC_WID_UNO_CONDFMT:
2475                 case SC_WID_UNO_CONDLOC:
2476                 case SC_WID_UNO_CONDXML:
2477                     {
2478                         const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
2479                         if ( pPattern )
2480                         {
2481                             ScDocument* pDoc = pDocShell->GetDocument();
2482                             sal_Bool bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
2483                             sal_Bool bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
2484                             formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2485                                     pDoc->GetStorageGrammar() :
2486                                    formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2487                             sal_uLong nIndex = ((const SfxUInt32Item&)
2488                                     pPattern->GetItem(ATTR_CONDITIONAL)).GetValue();
2489                             rAny <<= uno::Reference<sheet::XSheetConditionalEntries>(
2490                                     new ScTableConditionalFormat( pDoc, nIndex, eGrammar ));
2491                         }
2492                     }
2493                     break;
2494                 case SC_WID_UNO_VALIDAT:
2495                 case SC_WID_UNO_VALILOC:
2496                 case SC_WID_UNO_VALIXML:
2497                     {
2498                         const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
2499                         if ( pPattern )
2500                         {
2501                             ScDocument* pDoc = pDocShell->GetDocument();
2502                             sal_Bool bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
2503                             sal_Bool bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
2504                             formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2505                                     pDoc->GetStorageGrammar() :
2506                                    formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2507                             sal_uLong nIndex = ((const SfxUInt32Item&)
2508                                     pPattern->GetItem(ATTR_VALIDDATA)).GetValue();
2509                             rAny <<= uno::Reference<beans::XPropertySet>(
2510                                     new ScTableValidationObj( pDoc, nIndex, eGrammar ));
2511                         }
2512                     }
2513                     break;
2514                 case SC_WID_UNO_NUMRULES:
2515                     {
2516                         // always return empty numbering rules object
2517                         rAny <<= uno::Reference<container::XIndexReplace>(ScStyleObj::CreateEmptyNumberingRules());
2518                     }
2519                     break;
2520                 case SC_WID_UNO_ABSNAME:
2521                     {
2522                         String sRet;
2523                         aRanges.Format(sRet, SCR_ABS_3D, pDocShell->GetDocument());
2524                         rAny <<= rtl::OUString(sRet);
2525                     }
2526             }
2527     }
2528 }
2529 
2530 void SAL_CALL ScCellRangesBase::addPropertyChangeListener( const rtl::OUString& /* aPropertyName */,
2531                             const uno::Reference<beans::XPropertyChangeListener>& /* aListener */)
2532                             throw(beans::UnknownPropertyException,
2533                                     lang::WrappedTargetException, uno::RuntimeException)
2534 {
2535     ScUnoGuard aGuard;
2536     if ( aRanges.Count() == 0 )
2537         throw uno::RuntimeException();
2538 
2539     DBG_ERROR("not implemented");
2540 }
2541 
2542 void SAL_CALL ScCellRangesBase::removePropertyChangeListener( const rtl::OUString& /* aPropertyName */,
2543                             const uno::Reference<beans::XPropertyChangeListener>& /* aListener */)
2544                             throw(beans::UnknownPropertyException,
2545                                     lang::WrappedTargetException, uno::RuntimeException)
2546 {
2547     ScUnoGuard aGuard;
2548     if ( aRanges.Count() == 0 )
2549         throw uno::RuntimeException();
2550 
2551     DBG_ERROR("not implemented");
2552 }
2553 
2554 void SAL_CALL ScCellRangesBase::addVetoableChangeListener( const rtl::OUString&,
2555                             const uno::Reference<beans::XVetoableChangeListener>&)
2556                             throw(beans::UnknownPropertyException,
2557                                 lang::WrappedTargetException, uno::RuntimeException)
2558 {
2559     DBG_ERROR("not implemented");
2560 }
2561 
2562 void SAL_CALL ScCellRangesBase::removeVetoableChangeListener( const rtl::OUString&,
2563                             const uno::Reference<beans::XVetoableChangeListener>&)
2564                             throw(beans::UnknownPropertyException,
2565                                 lang::WrappedTargetException, uno::RuntimeException)
2566 {
2567     DBG_ERROR("not implemented");
2568 }
2569 
2570 // XMultiPropertySet
2571 
2572 void SAL_CALL ScCellRangesBase::setPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames,
2573                                     const uno::Sequence< uno::Any >& aValues )
2574                                 throw (beans::PropertyVetoException,
2575                                     lang::IllegalArgumentException,
2576                                     lang::WrappedTargetException,
2577                                     uno::RuntimeException)
2578 {
2579     ScUnoGuard aGuard;
2580 
2581     sal_Int32 nCount(aPropertyNames.getLength());
2582     sal_Int32 nValues(aValues.getLength());
2583     if (nCount != nValues)
2584         throw lang::IllegalArgumentException();
2585 
2586     if ( pDocShell && nCount )
2587     {
2588         const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();      // from derived class
2589         const rtl::OUString* pNames = aPropertyNames.getConstArray();
2590         const uno::Any* pValues = aValues.getConstArray();
2591 
2592         const SfxItemPropertySimpleEntry** pEntryArray = new const SfxItemPropertySimpleEntry*[nCount];
2593 
2594         sal_Int32 i;
2595         for(i = 0; i < nCount; i++)
2596         {
2597             // first loop: find all properties in map, but handle only CellStyle
2598             // (CellStyle must be set before any other cell properties)
2599 
2600             const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( pNames[i] );
2601             pEntryArray[i] = pEntry;
2602             if (pEntry)
2603             {
2604                 if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
2605                 {
2606                     try
2607                     {
2608                         SetOnePropertyValue( pEntry, pValues[i] );
2609                     }
2610                     catch ( lang::IllegalArgumentException& )
2611                     {
2612                         DBG_ERROR("exception when setting cell style");     // not supposed to happen
2613                     }
2614                 }
2615             }
2616         }
2617 
2618         ScDocument* pDoc = pDocShell->GetDocument();
2619         ScPatternAttr* pOldPattern = NULL;
2620         ScPatternAttr* pNewPattern = NULL;
2621 
2622         for(i = 0; i < nCount; i++)
2623         {
2624             // second loop: handle other properties
2625 
2626             const SfxItemPropertySimpleEntry* pEntry = pEntryArray[i];
2627             if ( pEntry )
2628             {
2629                 if ( IsScItemWid( pEntry->nWID ) )  // can be handled by SfxItemPropertySet
2630                 {
2631                     if ( !pOldPattern )
2632                     {
2633                         pOldPattern = new ScPatternAttr( *GetCurrentAttrsDeep() );
2634                         pOldPattern->GetItemSet().ClearInvalidItems();
2635                         pNewPattern = new ScPatternAttr( pDoc->GetPool() );
2636                     }
2637 
2638                     //  collect items in pNewPattern, apply with one call after the loop
2639 
2640                     sal_uInt16 nFirstItem, nSecondItem;
2641                     lcl_SetCellProperty( *pEntry, pValues[i], *pOldPattern, pDoc, nFirstItem, nSecondItem );
2642 
2643                     //  put only affected items into new set
2644                     if ( nFirstItem )
2645                         pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nFirstItem ) );
2646                     if ( nSecondItem )
2647                         pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nSecondItem ) );
2648                 }
2649                 else if ( pEntry->nWID != SC_WID_UNO_CELLSTYL )   // CellStyle is handled above
2650                 {
2651                     //  call virtual method to set a single property
2652                     SetOnePropertyValue( pEntry, pValues[i] );
2653                 }
2654             }
2655         }
2656 
2657         if ( pNewPattern && aRanges.Count() )
2658         {
2659             ScDocFunc aFunc(*pDocShell);
2660             aFunc.ApplyAttributes( *GetMarkData(), *pNewPattern, sal_True, sal_True );
2661         }
2662 
2663         delete pNewPattern;
2664         delete pOldPattern;
2665         delete[] pEntryArray;
2666     }
2667 }
2668 
2669 uno::Sequence<uno::Any> SAL_CALL ScCellRangesBase::getPropertyValues(
2670                                 const uno::Sequence< rtl::OUString >& aPropertyNames )
2671                                     throw (uno::RuntimeException)
2672 {
2673     ScUnoGuard aGuard;
2674 
2675     const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
2676 
2677     uno::Sequence<uno::Any> aRet(aPropertyNames.getLength());
2678     uno::Any* pProperties = aRet.getArray();
2679     for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
2680     {
2681         const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyNames[i] );
2682         GetOnePropertyValue( pEntry, pProperties[i] );
2683     }
2684     return aRet;
2685 }
2686 
2687 void SAL_CALL ScCellRangesBase::addPropertiesChangeListener( const uno::Sequence< rtl::OUString >& /* aPropertyNames */,
2688                                     const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
2689                                 throw (uno::RuntimeException)
2690 {
2691     DBG_ERROR("not implemented");
2692 }
2693 
2694 void SAL_CALL ScCellRangesBase::removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
2695                                 throw (uno::RuntimeException)
2696 {
2697     DBG_ERROR("not implemented");
2698 }
2699 
2700 void SAL_CALL ScCellRangesBase::firePropertiesChangeEvent( const uno::Sequence< rtl::OUString >& /* aPropertyNames */,
2701                                     const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
2702                                 throw (uno::RuntimeException)
2703 {
2704     DBG_ERROR("not implemented");
2705 }
2706 
2707 IMPL_LINK( ScCellRangesBase, ValueListenerHdl, SfxHint*, pHint )
2708 {
2709     if ( pDocShell && pHint && pHint->ISA( SfxSimpleHint ) &&
2710             ((const SfxSimpleHint*)pHint)->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING) )
2711     {
2712         //  This may be called several times for a single change, if several formulas
2713         //  in the range are notified. So only a flag is set that is checked when
2714         //  SFX_HINT_DATACHANGED is received.
2715 
2716         bGotDataChangedHint = sal_True;
2717     }
2718     return 0;
2719 }
2720 
2721 // XTolerantMultiPropertySet
2722 uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL ScCellRangesBase::setPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames,
2723                                     const uno::Sequence< uno::Any >& aValues )
2724                                     throw (lang::IllegalArgumentException, uno::RuntimeException)
2725 {
2726     ScUnoGuard aGuard;
2727 
2728     sal_Int32 nCount(aPropertyNames.getLength());
2729     sal_Int32 nValues(aValues.getLength());
2730     if (nCount != nValues)
2731         throw lang::IllegalArgumentException();
2732 
2733     if ( pDocShell && nCount )
2734     {
2735         uno::Sequence < beans::SetPropertyTolerantFailed > aReturns(nCount);
2736         beans::SetPropertyTolerantFailed* pReturns = aReturns.getArray();
2737 
2738         const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
2739         const rtl::OUString* pNames = aPropertyNames.getConstArray();
2740         const uno::Any* pValues = aValues.getConstArray();
2741 
2742         const SfxItemPropertySimpleEntry** pMapArray = new const SfxItemPropertySimpleEntry*[nCount];
2743 
2744         sal_Int32 i;
2745         for(i = 0; i < nCount; i++)
2746         {
2747             // first loop: find all properties in map, but handle only CellStyle
2748             // (CellStyle must be set before any other cell properties)
2749 
2750             const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( pNames[i] );
2751             pMapArray[i] = pEntry;
2752             if (pEntry)
2753             {
2754                 if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
2755                 {
2756                     try
2757                     {
2758                         SetOnePropertyValue( pEntry, pValues[i] );
2759                     }
2760                     catch ( lang::IllegalArgumentException& )
2761                     {
2762                         DBG_ERROR("exception when setting cell style");     // not supposed to happen
2763                     }
2764                 }
2765             }
2766         }
2767 
2768         ScDocument* pDoc = pDocShell->GetDocument();
2769         ScPatternAttr* pOldPattern = NULL;
2770         ScPatternAttr* pNewPattern = NULL;
2771 
2772         sal_Int32 nFailed(0);
2773         for(i = 0; i < nCount; i++)
2774         {
2775             // second loop: handle other properties
2776 
2777             const SfxItemPropertySimpleEntry* pEntry = pMapArray[i];
2778             if ( pEntry && ((pEntry->nFlags & beans::PropertyAttribute::READONLY) == 0))
2779             {
2780                 if ( IsScItemWid( pEntry->nWID ) )  // can be handled by SfxItemPropertySet
2781                 {
2782                     if ( !pOldPattern )
2783                     {
2784                         pOldPattern = new ScPatternAttr( *GetCurrentAttrsDeep() );
2785                         pOldPattern->GetItemSet().ClearInvalidItems();
2786                         pNewPattern = new ScPatternAttr( pDoc->GetPool() );
2787                     }
2788 
2789                     //  collect items in pNewPattern, apply with one call after the loop
2790 
2791                     sal_uInt16 nFirstItem, nSecondItem;
2792                     try
2793                     {
2794                         lcl_SetCellProperty( *pEntry, pValues[i], *pOldPattern, pDoc, nFirstItem, nSecondItem );
2795 
2796                         //  put only affected items into new set
2797                         if ( nFirstItem )
2798                             pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nFirstItem ) );
2799                         if ( nSecondItem )
2800                             pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nSecondItem ) );
2801                     }
2802                     catch ( lang::IllegalArgumentException& )
2803                     {
2804                         pReturns[nFailed].Name = pNames[i];
2805                         pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
2806                     }
2807                 }
2808                 else if ( pEntry->nWID != SC_WID_UNO_CELLSTYL )   // CellStyle is handled above
2809                 {
2810                     //  call virtual method to set a single property
2811                     try
2812                     {
2813                         SetOnePropertyValue( pEntry, pValues[i] );
2814                     }
2815                     catch ( lang::IllegalArgumentException& )
2816                     {
2817                         pReturns[nFailed].Name = pNames[i];
2818                         pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
2819                     }
2820                 }
2821             }
2822             else
2823             {
2824                 pReturns[nFailed].Name = pNames[i];
2825                 if (pEntry)
2826                     pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::PROPERTY_VETO;
2827                 else
2828                     pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
2829             }
2830         }
2831 
2832         if ( pNewPattern && aRanges.Count() )
2833         {
2834             ScDocFunc aFunc(*pDocShell);
2835             aFunc.ApplyAttributes( *GetMarkData(), *pNewPattern, sal_True, sal_True );
2836         }
2837 
2838         delete pNewPattern;
2839         delete pOldPattern;
2840         delete[] pMapArray;
2841 
2842         aReturns.realloc(nFailed);
2843 
2844         return aReturns;
2845     }
2846     return uno::Sequence < beans::SetPropertyTolerantFailed >();
2847 }
2848 
2849 uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL ScCellRangesBase::getPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames )
2850                                     throw (uno::RuntimeException)
2851 {
2852     ScUnoGuard aGuard;
2853 
2854     sal_Int32 nCount(aPropertyNames.getLength());
2855     uno::Sequence < beans::GetPropertyTolerantResult > aReturns(nCount);
2856     beans::GetPropertyTolerantResult* pReturns = aReturns.getArray();
2857 
2858     const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
2859 
2860     for(sal_Int32 i = 0; i < nCount; i++)
2861     {
2862         const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyNames[i] );
2863         if (!pEntry)
2864         {
2865             pReturns[i].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
2866         }
2867         else
2868         {
2869             sal_uInt16 nItemWhich = 0;
2870             lcl_GetPropertyWhich( pEntry, nItemWhich );
2871             pReturns[i].State = GetOnePropertyState( nItemWhich, pEntry );
2872             GetOnePropertyValue( pEntry, pReturns[i].Value );
2873             pReturns[i].Result = beans::TolerantPropertySetResultType::SUCCESS;
2874         }
2875     }
2876     return aReturns;
2877 }
2878 
2879 uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL ScCellRangesBase::getDirectPropertyValuesTolerant( const uno::Sequence< ::rtl::OUString >& aPropertyNames )
2880                                     throw (uno::RuntimeException)
2881 {
2882     ScUnoGuard aGuard;
2883 
2884     sal_Int32 nCount(aPropertyNames.getLength());
2885     uno::Sequence < beans::GetDirectPropertyTolerantResult > aReturns(nCount);
2886     beans::GetDirectPropertyTolerantResult* pReturns = aReturns.getArray();
2887 
2888     const SfxItemPropertyMap* pPropertyMap = GetItemPropertyMap();     // from derived class
2889 
2890     sal_Int32 j = 0;
2891     for(sal_Int32 i = 0; i < nCount; i++)
2892     {
2893         const SfxItemPropertySimpleEntry* pEntry = pPropertyMap->getByName( aPropertyNames[i] );
2894         if (!pEntry)
2895         {
2896             pReturns[i].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
2897         }
2898         else
2899         {
2900             sal_uInt16 nItemWhich = 0;
2901             lcl_GetPropertyWhich( pEntry, nItemWhich );
2902             pReturns[j].State = GetOnePropertyState( nItemWhich, pEntry );
2903             if (pReturns[j].State == beans::PropertyState_DIRECT_VALUE)
2904             {
2905                 GetOnePropertyValue( pEntry, pReturns[j].Value );
2906                 pReturns[j].Result = beans::TolerantPropertySetResultType::SUCCESS;
2907                 pReturns[j].Name = aPropertyNames[i];
2908                 ++j;
2909             }
2910         }
2911     }
2912     if (j < nCount)
2913         aReturns.realloc(j);
2914     return aReturns;
2915 }
2916 
2917 // XIndent
2918 
2919 void SAL_CALL ScCellRangesBase::decrementIndent() throw(::com::sun::star::uno::RuntimeException)
2920 {
2921     ScUnoGuard aGuard;
2922     if ( pDocShell && aRanges.Count() )     // leer = nichts zu tun
2923     {
2924         ScDocFunc aFunc(*pDocShell);
2925         //#97041#; put only MultiMarked ScMarkData in ChangeIndent
2926         ScMarkData aMarkData(*GetMarkData());
2927         aMarkData.MarkToMulti();
2928         aFunc.ChangeIndent( aMarkData, sal_False, sal_True );
2929     }
2930 }
2931 
2932 void SAL_CALL ScCellRangesBase::incrementIndent() throw(::com::sun::star::uno::RuntimeException)
2933 {
2934     ScUnoGuard aGuard;
2935     if ( pDocShell && aRanges.Count() )     // leer = nichts zu tun
2936     {
2937         ScDocFunc aFunc(*pDocShell);
2938         //#97041#; put only MultiMarked ScMarkData in ChangeIndent
2939         ScMarkData aMarkData(*GetMarkData());
2940         aMarkData.MarkToMulti();
2941         aFunc.ChangeIndent( aMarkData, sal_True, sal_True );
2942     }
2943 }
2944 
2945 // XChartData
2946 
2947 ScMemChart* ScCellRangesBase::CreateMemChart_Impl() const
2948 {
2949     if ( pDocShell && aRanges.Count() )
2950     {
2951         ScRangeListRef xChartRanges;
2952         if ( aRanges.Count() == 1 )
2953         {
2954             //  ganze Tabelle sinnvoll begrenzen (auf belegten Datenbereich)
2955             //  (nur hier, Listener werden auf den ganzen Bereich angemeldet)
2956             //! direkt testen, ob es ein ScTableSheetObj ist?
2957 
2958             ScRange* pRange = aRanges.GetObject(0);
2959             if ( pRange->aStart.Col() == 0 && pRange->aEnd.Col() == MAXCOL &&
2960                  pRange->aStart.Row() == 0 && pRange->aEnd.Row() == MAXROW )
2961             {
2962                 SCTAB nTab = pRange->aStart.Tab();
2963 
2964                 SCCOL nStartX;
2965                 SCROW nStartY; // Anfang holen
2966                 if (!pDocShell->GetDocument()->GetDataStart( nTab, nStartX, nStartY ))
2967                 {
2968                     nStartX = 0;
2969                     nStartY = 0;
2970                 }
2971 
2972                 SCCOL nEndX;
2973                 SCROW nEndY; // Ende holen
2974                 if (!pDocShell->GetDocument()->GetTableArea( nTab, nEndX, nEndY ))
2975                 {
2976                     nEndX = 0;
2977                     nEndY = 0;
2978                 }
2979 
2980                 xChartRanges = new ScRangeList;
2981                 xChartRanges->Append( ScRange( nStartX, nStartY, nTab, nEndX, nEndY, nTab ) );
2982             }
2983         }
2984         if (!xChartRanges.Is())         //  sonst Ranges direkt uebernehmen
2985             xChartRanges = new ScRangeList(aRanges);
2986         ScChartArray aArr( pDocShell->GetDocument(), xChartRanges, String() );
2987 
2988         // RowAsHdr = ColHeaders und umgekehrt
2989         aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr );
2990 
2991         return aArr.CreateMemChart();
2992     }
2993     return NULL;
2994 }
2995 
2996 uno::Sequence< uno::Sequence<double> > SAL_CALL ScCellRangesBase::getData()
2997                                                 throw(uno::RuntimeException)
2998 {
2999     ScUnoGuard aGuard;
3000     ScMemChart* pMemChart = CreateMemChart_Impl();
3001     if ( pMemChart )
3002     {
3003         sal_Int32 nColCount = pMemChart->GetColCount();
3004         sal_Int32 nRowCount = static_cast<sal_Int32>(pMemChart->GetRowCount());
3005 
3006         uno::Sequence< uno::Sequence<double> > aRowSeq( nRowCount );
3007         uno::Sequence<double>* pRowAry = aRowSeq.getArray();
3008         for (sal_Int32 nRow = 0; nRow < nRowCount; nRow++)
3009         {
3010             uno::Sequence<double> aColSeq( nColCount );
3011             double* pColAry = aColSeq.getArray();
3012             for (sal_Int32 nCol = 0; nCol < nColCount; nCol++)
3013                 pColAry[nCol] = pMemChart->GetData( static_cast<short>(nCol), static_cast<short>(nRow) );
3014 
3015             pRowAry[nRow] = aColSeq;
3016         }
3017 
3018         delete pMemChart;
3019         return aRowSeq;
3020     }
3021 
3022     return uno::Sequence< uno::Sequence<double> >(0);
3023 }
3024 
3025 ScRangeListRef ScCellRangesBase::GetLimitedChartRanges_Impl( long nDataColumns, long nDataRows ) const
3026 {
3027     if ( aRanges.Count() == 1 )
3028     {
3029         ScRange* pRange = aRanges.GetObject(0);
3030         if ( pRange->aStart.Col() == 0 && pRange->aEnd.Col() == MAXCOL &&
3031              pRange->aStart.Row() == 0 && pRange->aEnd.Row() == MAXROW )
3032         {
3033             //  if aRanges is a complete sheet, limit to given size
3034 
3035             SCTAB nTab = pRange->aStart.Tab();
3036 
3037             long nEndColumn = nDataColumns - 1 + ( bChartColAsHdr ? 1 : 0 );
3038             if ( nEndColumn < 0 )
3039                 nEndColumn = 0;
3040             if ( nEndColumn > MAXCOL )
3041                 nEndColumn = MAXCOL;
3042 
3043             long nEndRow = nDataRows - 1 + ( bChartRowAsHdr ? 1 : 0 );
3044             if ( nEndRow < 0 )
3045                 nEndRow = 0;
3046             if ( nEndRow > MAXROW )
3047                 nEndRow = MAXROW;
3048 
3049             ScRangeListRef xChartRanges = new ScRangeList;
3050             xChartRanges->Append( ScRange( 0, 0, nTab, (SCCOL)nEndColumn, (SCROW)nEndRow, nTab ) );
3051             return xChartRanges;
3052         }
3053     }
3054 
3055     return new ScRangeList(aRanges);        // as-is
3056 }
3057 
3058 void SAL_CALL ScCellRangesBase::setData( const uno::Sequence< uno::Sequence<double> >& aData )
3059                                                 throw(uno::RuntimeException)
3060 {
3061     ScUnoGuard aGuard;
3062     sal_Bool bDone = sal_False;
3063     long nRowCount = aData.getLength();
3064     long nColCount = nRowCount ? aData[0].getLength() : 0;
3065     ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( nColCount, nRowCount );
3066     if ( pDocShell && xChartRanges.Is() )
3067     {
3068         ScDocument* pDoc = pDocShell->GetDocument();
3069         ScChartArray aArr( pDoc, xChartRanges, String() );
3070         aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr );      // RowAsHdr = ColHeaders
3071         const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
3072         if (pPosMap)
3073         {
3074             if ( pPosMap->GetColCount() == static_cast<SCCOL>(nColCount) &&
3075                  pPosMap->GetRowCount() == static_cast<SCROW>(nRowCount) )
3076             {
3077                 for (long nRow=0; nRow<nRowCount; nRow++)
3078                 {
3079                     const uno::Sequence<double>& rRowSeq = aData[nRow];
3080                     const double* pArray = rRowSeq.getConstArray();
3081                     nColCount = rRowSeq.getLength();
3082                     for (long nCol=0; nCol<nColCount; nCol++)
3083                     {
3084                         const ScAddress* pPos = pPosMap->GetPosition(
3085                                 sal::static_int_cast<SCCOL>(nCol),
3086                                 sal::static_int_cast<SCROW>(nRow) );
3087                         if (pPos)
3088                         {
3089                             double fVal = pArray[nCol];
3090                             if ( fVal == DBL_MIN )
3091                                 pDoc->PutCell( *pPos, NULL );       // empty cell
3092                             else
3093                                 pDoc->SetValue( pPos->Col(), pPos->Row(), pPos->Tab(), pArray[nCol] );
3094                         }
3095                     }
3096                 }
3097 
3098                 //! undo
3099                 PaintRanges_Impl( PAINT_GRID );
3100                 pDocShell->SetDocumentModified();
3101                 ForceChartListener_Impl();          // call listeners for this object synchronously
3102                 bDone = sal_True;
3103             }
3104         }
3105     }
3106 
3107     if (!bDone)
3108         throw uno::RuntimeException();
3109 }
3110 
3111 uno::Sequence<rtl::OUString> SAL_CALL ScCellRangesBase::getRowDescriptions()
3112                                                 throw(uno::RuntimeException)
3113 {
3114     ScUnoGuard aGuard;
3115     ScMemChart* pMemChart = CreateMemChart_Impl();
3116     if ( pMemChart )
3117     {
3118         sal_Int32 nRowCount = static_cast<sal_Int32>(pMemChart->GetRowCount());
3119         uno::Sequence<rtl::OUString> aSeq( nRowCount );
3120         rtl::OUString* pAry = aSeq.getArray();
3121         for (sal_Int32 nRow = 0; nRow < nRowCount; nRow++)
3122             pAry[nRow] = pMemChart->GetRowText(static_cast<short>(nRow));
3123 
3124         delete pMemChart;
3125         return aSeq;
3126     }
3127     return uno::Sequence<rtl::OUString>(0);
3128 }
3129 
3130 void SAL_CALL ScCellRangesBase::setRowDescriptions(
3131                         const uno::Sequence<rtl::OUString>& aRowDescriptions )
3132                                                 throw(uno::RuntimeException)
3133 {
3134     ScUnoGuard aGuard;
3135     sal_Bool bDone = sal_False;
3136     if ( bChartColAsHdr )
3137     {
3138         long nRowCount = aRowDescriptions.getLength();
3139         ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( 1, nRowCount );
3140         if ( pDocShell && xChartRanges.Is() )
3141         {
3142             ScDocument* pDoc = pDocShell->GetDocument();
3143             ScChartArray aArr( pDoc, xChartRanges, String() );
3144             aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr );      // RowAsHdr = ColHeaders
3145             const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
3146             if (pPosMap)
3147             {
3148                 if ( pPosMap->GetRowCount() == static_cast<SCROW>(nRowCount) )
3149                 {
3150                     const rtl::OUString* pArray = aRowDescriptions.getConstArray();
3151                     for (long nRow=0; nRow<nRowCount; nRow++)
3152                     {
3153                         const ScAddress* pPos = pPosMap->GetRowHeaderPosition(
3154                                 static_cast<SCSIZE>(nRow) );
3155                         if (pPos)
3156                         {
3157                             String aStr = pArray[nRow];
3158                             if ( aStr.Len() )
3159                                 pDoc->PutCell( *pPos, new ScStringCell( aStr ) );
3160                             else
3161                                 pDoc->PutCell( *pPos, NULL );       // empty cell
3162                         }
3163                     }
3164 
3165                     //! undo
3166                     PaintRanges_Impl( PAINT_GRID );
3167                     pDocShell->SetDocumentModified();
3168                     ForceChartListener_Impl();          // call listeners for this object synchronously
3169                     bDone = sal_True;
3170                 }
3171             }
3172         }
3173     }
3174 
3175     if (!bDone)
3176         throw uno::RuntimeException();
3177 }
3178 
3179 uno::Sequence<rtl::OUString> SAL_CALL ScCellRangesBase::getColumnDescriptions()
3180                                                 throw(uno::RuntimeException)
3181 {
3182     ScUnoGuard aGuard;
3183     ScMemChart* pMemChart = CreateMemChart_Impl();
3184     if ( pMemChart )
3185     {
3186         sal_Int32 nColCount = pMemChart->GetColCount();
3187         uno::Sequence<rtl::OUString> aSeq( nColCount );
3188         rtl::OUString* pAry = aSeq.getArray();
3189         for (sal_Int32 nCol = 0; nCol < nColCount; nCol++)
3190             pAry[nCol] = pMemChart->GetColText(static_cast<short>(nCol));
3191 
3192         delete pMemChart;
3193         return aSeq;
3194     }
3195     return uno::Sequence<rtl::OUString>(0);
3196 }
3197 
3198 void SAL_CALL ScCellRangesBase::setColumnDescriptions(
3199                         const uno::Sequence<rtl::OUString>& aColumnDescriptions )
3200                                                 throw(uno::RuntimeException)
3201 {
3202     ScUnoGuard aGuard;
3203     sal_Bool bDone = sal_False;
3204     if ( bChartRowAsHdr )
3205     {
3206         long nColCount = aColumnDescriptions.getLength();
3207         ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( nColCount, 1 );
3208         if ( pDocShell && xChartRanges.Is() )
3209         {
3210             ScDocument* pDoc = pDocShell->GetDocument();
3211             ScChartArray aArr( pDoc, xChartRanges, String() );
3212             aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr );      // RowAsHdr = ColHeaders
3213             const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
3214             if (pPosMap)
3215             {
3216                 if ( pPosMap->GetColCount() == static_cast<SCCOL>(nColCount) )
3217                 {
3218                     const rtl::OUString* pArray = aColumnDescriptions.getConstArray();
3219                     for (long nCol=0; nCol<nColCount; nCol++)
3220                     {
3221                         const ScAddress* pPos = pPosMap->GetColHeaderPosition(
3222                             sal::static_int_cast<SCCOL>(nCol) );
3223                         if (pPos)
3224                         {
3225                             String aStr(pArray[nCol]);
3226                             if ( aStr.Len() )
3227                                 pDoc->PutCell( *pPos, new ScStringCell( aStr ) );
3228                             else
3229                                 pDoc->PutCell( *pPos, NULL );       // empty cell
3230                         }
3231                     }
3232 
3233                     //! undo
3234                     PaintRanges_Impl( PAINT_GRID );
3235                     pDocShell->SetDocumentModified();
3236                     ForceChartListener_Impl();          // call listeners for this object synchronously
3237                     bDone = sal_True;
3238                 }
3239             }
3240         }
3241     }
3242 
3243     if (!bDone)
3244         throw uno::RuntimeException();
3245 }
3246 
3247 void ScCellRangesBase::ForceChartListener_Impl()
3248 {
3249     //  call Update immediately so the caller to setData etc. can
3250     //  regognize the listener call
3251 
3252     if ( pDocShell )
3253     {
3254         ScChartListenerCollection* pColl = pDocShell->GetDocument()->GetChartListenerCollection();
3255         if ( pColl )
3256         {
3257             sal_uInt16 nCollCount = pColl->GetCount();
3258             for ( sal_uInt16 nIndex = 0; nIndex < nCollCount; nIndex++ )
3259             {
3260                 ScChartListener* pChartListener = (ScChartListener*)pColl->At(nIndex);
3261                 if ( pChartListener &&
3262                         pChartListener->GetUnoSource() == static_cast<chart::XChartData*>(this) &&
3263                         pChartListener->IsDirty() )
3264                     pChartListener->Update();
3265             }
3266         }
3267     }
3268 }
3269 
3270 String lcl_UniqueName( ScStrCollection& rColl, const String& rPrefix )
3271 {
3272     long nNumber = 1;
3273     sal_uInt16 nCollCount = rColl.GetCount();
3274     while (sal_True)
3275     {
3276         String aName(rPrefix);
3277         aName += String::CreateFromInt32( nNumber );
3278         sal_Bool bFound = sal_False;
3279         for (sal_uInt16 i=0; i<nCollCount; i++)
3280             if ( rColl[i]->GetString() == aName )
3281             {
3282                 bFound = sal_True;
3283                 break;
3284             }
3285         if (!bFound)
3286             return aName;
3287         ++nNumber;
3288     }
3289 }
3290 
3291 void SAL_CALL ScCellRangesBase::addChartDataChangeEventListener( const uno::Reference<
3292                                     chart::XChartDataChangeEventListener >& aListener )
3293                                 throw(uno::RuntimeException)
3294 {
3295     ScUnoGuard aGuard;
3296     if ( pDocShell && aRanges.Count() )
3297     {
3298         //! auf doppelte testen?
3299 
3300         ScDocument* pDoc = pDocShell->GetDocument();
3301         ScRangeListRef aRangesRef( new ScRangeList(aRanges) );
3302         ScChartListenerCollection* pColl = pDoc->GetChartListenerCollection();
3303         String aName(lcl_UniqueName( *pColl,
3304                         String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("__Uno")) ));
3305         ScChartListener* pListener = new ScChartListener( aName, pDoc, aRangesRef );
3306         pListener->SetUno( aListener, this );
3307         pColl->Insert( pListener );
3308         pListener->StartListeningTo();
3309     }
3310 }
3311 
3312 void SAL_CALL ScCellRangesBase::removeChartDataChangeEventListener( const uno::Reference<
3313                                     chart::XChartDataChangeEventListener >& aListener )
3314                                 throw(uno::RuntimeException)
3315 {
3316     ScUnoGuard aGuard;
3317     if ( pDocShell && aRanges.Count() )
3318     {
3319         ScDocument* pDoc = pDocShell->GetDocument();
3320         ScChartListenerCollection* pColl = pDoc->GetChartListenerCollection();
3321         pColl->FreeUno( aListener, this );
3322     }
3323 }
3324 
3325 double SAL_CALL ScCellRangesBase::getNotANumber() throw(::com::sun::star::uno::RuntimeException)
3326 {
3327     //  im ScChartArray wird DBL_MIN verwendet, weil das Chart es so will
3328     return DBL_MIN;
3329 }
3330 
3331 sal_Bool SAL_CALL ScCellRangesBase::isNotANumber( double nNumber ) throw(uno::RuntimeException)
3332 {
3333     //  im ScChartArray wird DBL_MIN verwendet, weil das Chart es so will
3334     return (nNumber == DBL_MIN);
3335 }
3336 
3337 // XModifyBroadcaster
3338 
3339 void SAL_CALL ScCellRangesBase::addModifyListener( const uno::Reference<util::XModifyListener>& aListener )
3340                                 throw(uno::RuntimeException)
3341 {
3342     ScUnoGuard aGuard;
3343     if ( aRanges.Count() == 0 )
3344         throw uno::RuntimeException();
3345 
3346     uno::Reference<util::XModifyListener> *pObj =
3347             new uno::Reference<util::XModifyListener>( aListener );
3348     aValueListeners.Insert( pObj, aValueListeners.Count() );
3349 
3350     if ( aValueListeners.Count() == 1 )
3351     {
3352         if (!pValueListener)
3353             pValueListener = new ScLinkListener( LINK( this, ScCellRangesBase, ValueListenerHdl ) );
3354 
3355         ScDocument* pDoc = pDocShell->GetDocument();
3356         sal_uLong nCount = aRanges.Count();
3357         for (sal_uLong i=0; i<nCount; i++)
3358             pDoc->StartListeningArea( *aRanges.GetObject(i), pValueListener );
3359 
3360         acquire();  // don't lose this object (one ref for all listeners)
3361     }
3362 }
3363 
3364 void SAL_CALL ScCellRangesBase::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
3365                                 throw(uno::RuntimeException)
3366 {
3367 
3368     ScUnoGuard aGuard;
3369     if ( aRanges.Count() == 0 )
3370         throw uno::RuntimeException();
3371 
3372     acquire();      // in case the listeners have the last ref - released below
3373 
3374     sal_uInt16 nCount = aValueListeners.Count();
3375     for ( sal_uInt16 n=nCount; n--; )
3376     {
3377         uno::Reference<util::XModifyListener> *pObj = aValueListeners[n];
3378         if ( *pObj == aListener )
3379         {
3380             aValueListeners.DeleteAndDestroy( n );
3381 
3382             if ( aValueListeners.Count() == 0 )
3383             {
3384                 if (pValueListener)
3385                     pValueListener->EndListeningAll();
3386 
3387                 release();      // release the ref for the listeners
3388             }
3389 
3390             break;
3391         }
3392     }
3393 
3394     release();      // might delete this object
3395 }
3396 
3397 // XCellRangesQuery
3398 
3399 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryVisibleCells()
3400                                     throw(uno::RuntimeException)
3401 {
3402     ScUnoGuard aGuard;
3403     if (pDocShell)
3404     {
3405         //! fuer alle Tabellen getrennt, wenn Markierungen pro Tabelle getrennt sind!
3406         SCTAB nTab = lcl_FirstTab(aRanges);
3407 
3408         ScMarkData aMarkData(*GetMarkData());
3409 
3410         ScDocument* pDoc = pDocShell->GetDocument();
3411         SCCOL nCol = 0, nLastCol;
3412         while (nCol <= MAXCOL)
3413         {
3414             if (pDoc->ColHidden(nCol, nTab, nLastCol))
3415                 // hidden columns.  Unselect them.
3416                 aMarkData.SetMultiMarkArea(ScRange(nCol, 0, nTab, nLastCol, MAXROW, nTab), false);
3417 
3418             nCol = nLastCol + 1;
3419         }
3420 
3421         SCROW nRow = 0, nLastRow;
3422         while (nRow <= MAXROW)
3423         {
3424             if (pDoc->RowHidden(nRow, nTab, nLastRow))
3425                 // These rows are hidden.  Unselect them.
3426                 aMarkData.SetMultiMarkArea(ScRange(0, nRow, nTab, MAXCOL, nLastRow, nTab), false);
3427 
3428             nRow = nLastRow + 1;
3429         }
3430 
3431         ScRangeList aNewRanges;
3432         aMarkData.FillRangeListWithMarks( &aNewRanges, sal_False );
3433         return new ScCellRangesObj( pDocShell, aNewRanges );
3434     }
3435 
3436     return NULL;
3437 }
3438 
3439 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryEmptyCells()
3440                                     throw(uno::RuntimeException)
3441 {
3442     ScUnoGuard aGuard;
3443     if (pDocShell)
3444     {
3445         ScDocument* pDoc = pDocShell->GetDocument();
3446 
3447         ScMarkData aMarkData(*GetMarkData());
3448 
3449         //  belegte Zellen wegmarkieren
3450         sal_uLong nCount = aRanges.Count();
3451         for (sal_uLong i=0; i<nCount; i++)
3452         {
3453             ScRange aRange = *aRanges.GetObject(i);
3454 
3455             ScCellIterator aIter( pDoc, aRange );
3456             ScBaseCell* pCell = aIter.GetFirst();
3457             while (pCell)
3458             {
3459                 //  Notizen zaehlen als nicht-leer
3460                 if ( !pCell->IsBlank() )
3461                     aMarkData.SetMultiMarkArea(
3462                             ScRange( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ),
3463                             sal_False );
3464 
3465                 pCell = aIter.GetNext();
3466             }
3467         }
3468 
3469         ScRangeList aNewRanges;
3470         //  IsMultiMarked reicht hier nicht (wird beim deselektieren nicht zurueckgesetzt)
3471         if (aMarkData.HasAnyMultiMarks())
3472             aMarkData.FillRangeListWithMarks( &aNewRanges, sal_False );
3473 
3474         return new ScCellRangesObj( pDocShell, aNewRanges );    // aNewRanges kann leer sein
3475     }
3476 
3477     return NULL;
3478 }
3479 
3480 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryContentCells(
3481                                                     sal_Int16 nContentFlags )
3482                                     throw(uno::RuntimeException)
3483 {
3484     ScUnoGuard aGuard;
3485     if (pDocShell)
3486     {
3487         ScDocument* pDoc = pDocShell->GetDocument();
3488 
3489         ScMarkData aMarkData;
3490 
3491         //  passende Zellen selektieren
3492         sal_uLong nCount = aRanges.Count();
3493         for (sal_uLong i=0; i<nCount; i++)
3494         {
3495             ScRange aRange = *aRanges.GetObject(i);
3496 
3497             ScCellIterator aIter( pDoc, aRange );
3498             ScBaseCell* pCell = aIter.GetFirst();
3499             while (pCell)
3500             {
3501                 sal_Bool bAdd = sal_False;
3502                 if ( pCell->HasNote() && ( nContentFlags & sheet::CellFlags::ANNOTATION ) )
3503                     bAdd = sal_True;
3504                 else
3505                     switch ( pCell->GetCellType() )
3506                     {
3507                         case CELLTYPE_STRING:
3508                             if ( nContentFlags & sheet::CellFlags::STRING )
3509                                 bAdd = sal_True;
3510                             break;
3511                         case CELLTYPE_EDIT:
3512                             if ( (nContentFlags & sheet::CellFlags::STRING) || (nContentFlags & sheet::CellFlags::FORMATTED) )
3513                                 bAdd = sal_True;
3514                             break;
3515                         case CELLTYPE_FORMULA:
3516                             if ( nContentFlags & sheet::CellFlags::FORMULA )
3517                                 bAdd = sal_True;
3518                             break;
3519                         case CELLTYPE_VALUE:
3520                             if ( (nContentFlags & (sheet::CellFlags::VALUE|sheet::CellFlags::DATETIME))
3521                                     == (sheet::CellFlags::VALUE|sheet::CellFlags::DATETIME) )
3522                                 bAdd = sal_True;
3523                             else
3524                             {
3525                                 //  Date/Time Erkennung
3526 
3527                                 sal_uLong nIndex = (sal_uLong)((SfxUInt32Item*)pDoc->GetAttr(
3528                                         aIter.GetCol(), aIter.GetRow(), aIter.GetTab(),
3529                                         ATTR_VALUE_FORMAT ))->GetValue();
3530                                 short nTyp = pDoc->GetFormatTable()->GetType(nIndex);
3531                                 if ((nTyp == NUMBERFORMAT_DATE) || (nTyp == NUMBERFORMAT_TIME) ||
3532                                     (nTyp == NUMBERFORMAT_DATETIME))
3533                                 {
3534                                     if ( nContentFlags & sheet::CellFlags::DATETIME )
3535                                         bAdd = sal_True;
3536                                 }
3537                                 else
3538                                 {
3539                                     if ( nContentFlags & sheet::CellFlags::VALUE )
3540                                         bAdd = sal_True;
3541                                 }
3542                             }
3543                             break;
3544                         default:
3545                         {
3546                             // added to avoid warnings
3547                         }
3548                     }
3549 
3550                 if (bAdd)
3551                     aMarkData.SetMultiMarkArea(
3552                             ScRange( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ),
3553                             sal_True );
3554 
3555                 pCell = aIter.GetNext();
3556             }
3557         }
3558 
3559         ScRangeList aNewRanges;
3560         if (aMarkData.IsMultiMarked())
3561             aMarkData.FillRangeListWithMarks( &aNewRanges, sal_False );
3562 
3563         return new ScCellRangesObj( pDocShell, aNewRanges );    // aNewRanges kann leer sein
3564     }
3565 
3566     return NULL;
3567 }
3568 
3569 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryFormulaCells(
3570                                                     sal_Int32 nResultFlags )
3571                                     throw(uno::RuntimeException)
3572 {
3573     ScUnoGuard aGuard;
3574     if (pDocShell)
3575     {
3576         ScDocument* pDoc = pDocShell->GetDocument();
3577 
3578         ScMarkData aMarkData;
3579 
3580         //  passende Zellen selektieren
3581         sal_uLong nCount = aRanges.Count();
3582         for (sal_uLong i=0; i<nCount; i++)
3583         {
3584             ScRange aRange = *aRanges.GetObject(i);
3585 
3586             ScCellIterator aIter( pDoc, aRange );
3587             ScBaseCell* pCell = aIter.GetFirst();
3588             while (pCell)
3589             {
3590                 if (pCell->GetCellType() == CELLTYPE_FORMULA)
3591                 {
3592                     ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
3593                     sal_Bool bAdd = sal_False;
3594                     if (pFCell->GetErrCode())
3595                     {
3596                         if ( nResultFlags & sheet::FormulaResult::ERROR )
3597                             bAdd = sal_True;
3598                     }
3599                     else if (pFCell->IsValue())
3600                     {
3601                         if ( nResultFlags & sheet::FormulaResult::VALUE )
3602                             bAdd = sal_True;
3603                     }
3604                     else    // String
3605                     {
3606                         if ( nResultFlags & sheet::FormulaResult::STRING )
3607                             bAdd = sal_True;
3608                     }
3609 
3610                     if (bAdd)
3611                         aMarkData.SetMultiMarkArea(
3612                                 ScRange( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() ),
3613                                 sal_True );
3614                 }
3615 
3616                 pCell = aIter.GetNext();
3617             }
3618         }
3619 
3620         ScRangeList aNewRanges;
3621         if (aMarkData.IsMultiMarked())
3622             aMarkData.FillRangeListWithMarks( &aNewRanges, sal_False );
3623 
3624         return new ScCellRangesObj( pDocShell, aNewRanges );    // aNewRanges kann leer sein
3625     }
3626 
3627     return NULL;
3628 }
3629 
3630 uno::Reference<sheet::XSheetCellRanges> ScCellRangesBase::QueryDifferences_Impl(
3631                         const table::CellAddress& aCompare, sal_Bool bColumnDiff)
3632 {
3633     if (pDocShell)
3634     {
3635         sal_uLong nRangeCount = aRanges.Count();
3636         sal_uLong i;
3637         ScDocument* pDoc = pDocShell->GetDocument();
3638         ScMarkData aMarkData;
3639 
3640         SCCOLROW nCmpPos = bColumnDiff ? (SCCOLROW)aCompare.Row : (SCCOLROW)aCompare.Column;
3641 
3642         //  zuerst alles selektieren, wo ueberhaupt etwas in der Vergleichsspalte steht
3643         //  (fuer gleiche Zellen wird die Selektion im zweiten Schritt aufgehoben)
3644 
3645         SCTAB nTab = lcl_FirstTab(aRanges); //! fuer alle Tabellen, wenn Markierungen pro Tabelle!
3646         ScRange aCmpRange, aCellRange;
3647         if (bColumnDiff)
3648             aCmpRange = ScRange( 0,nCmpPos,nTab, MAXCOL,nCmpPos,nTab );
3649         else
3650             aCmpRange = ScRange( static_cast<SCCOL>(nCmpPos),0,nTab, static_cast<SCCOL>(nCmpPos),MAXROW,nTab );
3651         ScCellIterator aCmpIter( pDoc, aCmpRange );
3652         ScBaseCell* pCmpCell = aCmpIter.GetFirst();
3653         while (pCmpCell)
3654         {
3655             if (pCmpCell->GetCellType() != CELLTYPE_NOTE)
3656             {
3657                 SCCOLROW nCellPos = bColumnDiff ? static_cast<SCCOLROW>(aCmpIter.GetCol()) : static_cast<SCCOLROW>(aCmpIter.GetRow());
3658                 if (bColumnDiff)
3659                     aCellRange = ScRange( static_cast<SCCOL>(nCellPos),0,nTab,
3660                             static_cast<SCCOL>(nCellPos),MAXROW,nTab );
3661                 else
3662                     aCellRange = ScRange( 0,nCellPos,nTab, MAXCOL,nCellPos,nTab );
3663 
3664                 for (i=0; i<nRangeCount; i++)
3665                 {
3666                     ScRange aRange(*aRanges.GetObject(i));
3667                     if ( aRange.Intersects( aCellRange ) )
3668                     {
3669                         if (bColumnDiff)
3670                         {
3671                             aRange.aStart.SetCol(static_cast<SCCOL>(nCellPos));
3672                             aRange.aEnd.SetCol(static_cast<SCCOL>(nCellPos));
3673                         }
3674                         else
3675                         {
3676                             aRange.aStart.SetRow(nCellPos);
3677                             aRange.aEnd.SetRow(nCellPos);
3678                         }
3679                         aMarkData.SetMultiMarkArea( aRange );
3680                     }
3681                 }
3682             }
3683             pCmpCell = aCmpIter.GetNext();
3684         }
3685 
3686         //  alle nichtleeren Zellen mit der Vergleichsspalte vergleichen und entsprechend
3687         //  selektieren oder aufheben
3688 
3689         ScAddress aCmpAddr;
3690         for (i=0; i<nRangeCount; i++)
3691         {
3692             ScRange aRange(*aRanges.GetObject(i));
3693 
3694             ScCellIterator aIter( pDoc, aRange );
3695             ScBaseCell* pCell = aIter.GetFirst();
3696             while (pCell)
3697             {
3698                 if (bColumnDiff)
3699                     aCmpAddr = ScAddress( aIter.GetCol(), nCmpPos, aIter.GetTab() );
3700                 else
3701                     aCmpAddr = ScAddress( static_cast<SCCOL>(nCmpPos), aIter.GetRow(), aIter.GetTab() );
3702                 const ScBaseCell* pOtherCell = pDoc->GetCell( aCmpAddr );
3703 
3704                 ScRange aOneRange( aIter.GetCol(), aIter.GetRow(), aIter.GetTab() );
3705                 if ( !ScBaseCell::CellEqual( pCell, pOtherCell ) )
3706                     aMarkData.SetMultiMarkArea( aOneRange );
3707                 else
3708                     aMarkData.SetMultiMarkArea( aOneRange, sal_False );     // deselect
3709 
3710                 pCell = aIter.GetNext();
3711             }
3712         }
3713 
3714         ScRangeList aNewRanges;
3715         if (aMarkData.IsMultiMarked())
3716             aMarkData.FillRangeListWithMarks( &aNewRanges, sal_False );
3717 
3718         return new ScCellRangesObj( pDocShell, aNewRanges );    // aNewRanges kann leer sein
3719     }
3720     return NULL;
3721 }
3722 
3723 uno::Reference<sheet::XSheetCellRanges > SAL_CALL ScCellRangesBase::queryColumnDifferences(
3724                             const table::CellAddress& aCompare ) throw(uno::RuntimeException)
3725 {
3726     ScUnoGuard aGuard;
3727     return QueryDifferences_Impl( aCompare, sal_True );
3728 }
3729 
3730 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryRowDifferences(
3731                             const table::CellAddress& aCompare ) throw(uno::RuntimeException)
3732 {
3733     ScUnoGuard aGuard;
3734     return QueryDifferences_Impl( aCompare, sal_False );
3735 }
3736 
3737 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryIntersection(
3738                             const table::CellRangeAddress& aRange ) throw(uno::RuntimeException)
3739 {
3740     ScUnoGuard aGuard;
3741     ScRange aMask( (SCCOL)aRange.StartColumn, (SCROW)aRange.StartRow, aRange.Sheet,
3742                    (SCCOL)aRange.EndColumn,   (SCROW)aRange.EndRow,   aRange.Sheet );
3743 
3744     ScRangeList aNew;
3745     sal_uLong nCount = aRanges.Count();
3746     for (sal_uLong i=0; i<nCount; i++)
3747     {
3748         ScRange aTemp(*aRanges.GetObject(i));
3749         if ( aTemp.Intersects( aMask ) )
3750             aNew.Join( ScRange( Max( aTemp.aStart.Col(), aMask.aStart.Col() ),
3751                                 Max( aTemp.aStart.Row(), aMask.aStart.Row() ),
3752                                 Max( aTemp.aStart.Tab(), aMask.aStart.Tab() ),
3753                                 Min( aTemp.aEnd.Col(), aMask.aEnd.Col() ),
3754                                 Min( aTemp.aEnd.Row(), aMask.aEnd.Row() ),
3755                                 Min( aTemp.aEnd.Tab(), aMask.aEnd.Tab() ) ) );
3756     }
3757 
3758     return new ScCellRangesObj( pDocShell, aNew );  // kann leer sein
3759 }
3760 
3761 // XFormulaQuery
3762 
3763 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryPrecedents(
3764                                 sal_Bool bRecursive ) throw(uno::RuntimeException)
3765 {
3766     ScUnoGuard aGuard;
3767     if ( pDocShell )
3768     {
3769         ScDocument* pDoc = pDocShell->GetDocument();
3770 
3771         ScRangeList aNewRanges(aRanges);
3772         sal_Bool bFound;
3773         do
3774         {
3775             bFound = sal_False;
3776 
3777             //  #97205# aMarkData uses aNewRanges, not aRanges, so GetMarkData can't be used
3778             ScMarkData aMarkData;
3779             aMarkData.MarkFromRangeList( aNewRanges, sal_False );
3780             aMarkData.MarkToMulti();        // needed for IsAllMarked
3781 
3782             sal_uLong nCount = aNewRanges.Count();
3783             for (sal_uLong nR=0; nR<nCount; nR++)
3784             {
3785                 ScRange aRange(*aNewRanges.GetObject(nR));
3786                 ScCellIterator aIter( pDoc, aRange );
3787                 ScBaseCell* pCell = aIter.GetFirst();
3788                 while (pCell)
3789                 {
3790                     if ( pCell->GetCellType() == CELLTYPE_FORMULA )
3791                     {
3792                         ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
3793 
3794                         ScDetectiveRefIter aRefIter( pFCell );
3795                         ScRange aRefRange;
3796                         while ( aRefIter.GetNextRef( aRefRange) )
3797                         {
3798                             if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aRefRange ) )
3799                                 bFound = sal_True;
3800                             aMarkData.SetMultiMarkArea( aRefRange, sal_True );
3801                         }
3802                     }
3803                     pCell = aIter.GetNext();
3804                 }
3805             }
3806 
3807             aMarkData.FillRangeListWithMarks( &aNewRanges, sal_True );
3808         }
3809         while ( bRecursive && bFound );
3810 
3811         return new ScCellRangesObj( pDocShell, aNewRanges );
3812     }
3813 
3814     return NULL;
3815 }
3816 
3817 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryDependents(
3818                                 sal_Bool bRecursive ) throw(uno::RuntimeException)
3819 {
3820     ScUnoGuard aGuard;
3821     if ( pDocShell )
3822     {
3823         ScDocument* pDoc = pDocShell->GetDocument();
3824 
3825         ScRangeList aNewRanges(aRanges);
3826         sal_Bool bFound;
3827         do
3828         {
3829             bFound = sal_False;
3830             sal_uLong nRangesCount = aNewRanges.Count();
3831 
3832             //  #97205# aMarkData uses aNewRanges, not aRanges, so GetMarkData can't be used
3833             ScMarkData aMarkData;
3834             aMarkData.MarkFromRangeList( aNewRanges, sal_False );
3835             aMarkData.MarkToMulti();        // needed for IsAllMarked
3836 
3837             SCTAB nTab = lcl_FirstTab(aNewRanges);              //! alle Tabellen
3838 
3839             ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
3840             ScBaseCell* pCell = aCellIter.GetFirst();
3841             while (pCell)
3842             {
3843                 if (pCell->GetCellType() == CELLTYPE_FORMULA)
3844                 {
3845                     sal_Bool bMark = sal_False;
3846                     ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
3847                     ScRange aRefRange;
3848                     while ( aIter.GetNextRef( aRefRange) )
3849                     {
3850                         for (sal_uLong nR=0; nR<nRangesCount; nR++)
3851                         {
3852                             ScRange aRange(*aNewRanges.GetObject(nR));
3853                             if (aRange.Intersects(aRefRange))
3854                                 bMark = sal_True;                   // von Teil des Ranges abhaengig
3855                         }
3856                     }
3857                     if (bMark)
3858                     {
3859                         ScRange aCellRange( aCellIter.GetCol(),
3860                                             aCellIter.GetRow(),
3861                                             aCellIter.GetTab() );
3862                         if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aCellRange ) )
3863                             bFound = sal_True;
3864                         aMarkData.SetMultiMarkArea( aCellRange, sal_True );
3865                     }
3866                 }
3867                 pCell = aCellIter.GetNext();
3868             }
3869 
3870             aMarkData.FillRangeListWithMarks( &aNewRanges, sal_True );
3871         }
3872         while ( bRecursive && bFound );
3873 
3874         return new ScCellRangesObj( pDocShell, aNewRanges );
3875     }
3876 
3877     return NULL;
3878 }
3879 
3880 // XSearchable
3881 
3882 uno::Reference<util::XSearchDescriptor> SAL_CALL ScCellRangesBase::createSearchDescriptor()
3883                                                             throw(uno::RuntimeException)
3884 {
3885     ScUnoGuard aGuard;
3886     return new ScCellSearchObj;
3887 }
3888 
3889 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangesBase::findAll(
3890                         const uno::Reference<util::XSearchDescriptor>& xDesc )
3891                                                     throw(uno::RuntimeException)
3892 {
3893     //  Wenn nichts gefunden wird, soll Null zurueckgegeben werden (?)
3894     uno::Reference<container::XIndexAccess> xRet;
3895     if ( pDocShell && xDesc.is() )
3896     {
3897         ScCellSearchObj* pSearch = ScCellSearchObj::getImplementation( xDesc );
3898         if (pSearch)
3899         {
3900             SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
3901             if (pSearchItem)
3902             {
3903                 ScDocument* pDoc = pDocShell->GetDocument();
3904                 pSearchItem->SetCommand( SVX_SEARCHCMD_FIND_ALL );
3905                 //  immer nur innerhalb dieses Objekts
3906                 pSearchItem->SetSelection( !lcl_WholeSheet(aRanges) );
3907 
3908                 ScMarkData aMark(*GetMarkData());
3909 
3910                 String aDummyUndo;
3911                 SCCOL nCol = 0;
3912                 SCROW nRow = 0;
3913                 SCTAB nTab = 0;
3914                 sal_Bool bFound = pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab,
3915                                                         aMark, aDummyUndo, NULL );
3916                 if (bFound)
3917                 {
3918                     ScRangeList aNewRanges;
3919                     aMark.FillRangeListWithMarks( &aNewRanges, sal_True );
3920                     //  bei findAll immer CellRanges, egal wieviel gefunden wurde
3921                     xRet.set(new ScCellRangesObj( pDocShell, aNewRanges ));
3922                 }
3923             }
3924         }
3925     }
3926     return xRet;
3927 }
3928 
3929 uno::Reference<uno::XInterface> ScCellRangesBase::Find_Impl(
3930                                     const uno::Reference<util::XSearchDescriptor>& xDesc,
3931                                     const ScAddress* pLastPos )
3932 {
3933     uno::Reference<uno::XInterface> xRet;
3934     if ( pDocShell && xDesc.is() )
3935     {
3936         ScCellSearchObj* pSearch = ScCellSearchObj::getImplementation( xDesc );
3937         if (pSearch)
3938         {
3939             SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
3940             if (pSearchItem)
3941             {
3942                 ScDocument* pDoc = pDocShell->GetDocument();
3943                 pSearchItem->SetCommand( SVX_SEARCHCMD_FIND );
3944                 //  immer nur innerhalb dieses Objekts
3945                 pSearchItem->SetSelection( !lcl_WholeSheet(aRanges) );
3946 
3947                 ScMarkData aMark(*GetMarkData());
3948 
3949                 SCCOL nCol;
3950                 SCROW nRow;
3951                 SCTAB nTab;
3952                 if (pLastPos)
3953                     pLastPos->GetVars( nCol, nRow, nTab );
3954                 else
3955                 {
3956                     nTab = lcl_FirstTab(aRanges);   //! mehrere Tabellen?
3957                     ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
3958                 }
3959 
3960                 String aDummyUndo;
3961                 sal_Bool bFound = pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab,
3962                                                         aMark, aDummyUndo, NULL );
3963                 if (bFound)
3964                 {
3965                     ScAddress aFoundPos( nCol, nRow, nTab );
3966                     xRet.set((cppu::OWeakObject*) new ScCellObj( pDocShell, aFoundPos ));
3967                 }
3968             }
3969         }
3970     }
3971     return xRet;
3972 }
3973 
3974 uno::Reference<uno::XInterface> SAL_CALL ScCellRangesBase::findFirst(
3975                         const uno::Reference<util::XSearchDescriptor>& xDesc )
3976                                                 throw(uno::RuntimeException)
3977 {
3978     ScUnoGuard aGuard;
3979     return Find_Impl( xDesc, NULL );
3980 }
3981 
3982 uno::Reference<uno::XInterface> SAL_CALL ScCellRangesBase::findNext(
3983                         const uno::Reference<uno::XInterface>& xStartAt,
3984                         const uno::Reference<util::XSearchDescriptor >& xDesc )
3985                                                 throw(uno::RuntimeException)
3986 {
3987     ScUnoGuard aGuard;
3988     if ( xStartAt.is() )
3989     {
3990         ScCellRangesBase* pRangesImp = ScCellRangesBase::getImplementation( xStartAt );
3991         if ( pRangesImp && pRangesImp->GetDocShell() == pDocShell )
3992         {
3993             const ScRangeList& rStartRanges = pRangesImp->GetRangeList();
3994             if ( rStartRanges.Count() == 1 )
3995             {
3996                 ScAddress aStartPos = rStartRanges.GetObject(0)->aStart;
3997                 return Find_Impl( xDesc, &aStartPos );
3998             }
3999         }
4000     }
4001     return NULL;
4002 }
4003 
4004 // XReplaceable
4005 
4006 uno::Reference<util::XReplaceDescriptor> SAL_CALL ScCellRangesBase::createReplaceDescriptor()
4007                                                 throw(uno::RuntimeException)
4008 {
4009     ScUnoGuard aGuard;
4010     return new ScCellSearchObj;
4011 }
4012 
4013 sal_Int32 SAL_CALL ScCellRangesBase::replaceAll( const uno::Reference<util::XSearchDescriptor>& xDesc )
4014                                                 throw(uno::RuntimeException)
4015 {
4016     ScUnoGuard aGuard;
4017     sal_Int32 nReplaced = 0;
4018     if ( pDocShell && xDesc.is() )
4019     {
4020         ScCellSearchObj* pSearch = ScCellSearchObj::getImplementation( xDesc );
4021         if (pSearch)
4022         {
4023             SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
4024             if (pSearchItem)
4025             {
4026                 ScDocument* pDoc = pDocShell->GetDocument();
4027                 sal_Bool bUndo(pDoc->IsUndoEnabled());
4028                 pSearchItem->SetCommand( SVX_SEARCHCMD_REPLACE_ALL );
4029                 //  immer nur innerhalb dieses Objekts
4030                 pSearchItem->SetSelection( !lcl_WholeSheet(aRanges) );
4031 
4032                 ScMarkData aMark(*GetMarkData());
4033 
4034                 SCTAB nTabCount = pDoc->GetTableCount();
4035                 sal_Bool bProtected = !pDocShell->IsEditable();
4036                 for (SCTAB i=0; i<nTabCount; i++)
4037                     if ( aMark.GetTableSelect(i) && pDoc->IsTabProtected(i) )
4038                         bProtected = sal_True;
4039                 if (bProtected)
4040                 {
4041                     //! Exception, oder was?
4042                 }
4043                 else
4044                 {
4045                     SCTAB nTab = aMark.GetFirstSelected();      // bei SearchAndReplace nicht benutzt
4046                     SCCOL nCol = 0;
4047                     SCROW nRow = 0;
4048 
4049                     String aUndoStr;
4050                     ScDocument* pUndoDoc = NULL;
4051                     if (bUndo)
4052                     {
4053                         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4054                         pUndoDoc->InitUndo( pDoc, nTab, nTab );
4055                     }
4056                     for (SCTAB i=0; i<nTabCount; i++)
4057                         if ( aMark.GetTableSelect(i) && i != nTab && bUndo)
4058                             pUndoDoc->AddUndoTab( i, i );
4059                     ScMarkData* pUndoMark = NULL;
4060                     if (bUndo)
4061                         pUndoMark = new ScMarkData(aMark);
4062 
4063                     sal_Bool bFound(sal_False);
4064                     if (bUndo)
4065                         bFound = pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab,
4066                                                             aMark, aUndoStr, pUndoDoc );
4067                     if (bFound)
4068                     {
4069                         nReplaced = pUndoDoc->GetCellCount();
4070 
4071                         pDocShell->GetUndoManager()->AddUndoAction(
4072                             new ScUndoReplace( pDocShell, *pUndoMark, nCol, nRow, nTab,
4073                                                         aUndoStr, pUndoDoc, pSearchItem ) );
4074 
4075                         pDocShell->PostPaintGridAll();
4076                         pDocShell->SetDocumentModified();
4077                     }
4078                     else
4079                     {
4080                         delete pUndoDoc;
4081                         delete pUndoMark;
4082                         // nReplaced bleibt 0
4083                     }
4084                 }
4085             }
4086         }
4087     }
4088     return nReplaced;
4089 }
4090 
4091 // XUnoTunnel
4092 
4093 sal_Int64 SAL_CALL ScCellRangesBase::getSomething(
4094                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
4095 {
4096     if ( rId.getLength() == 16 &&
4097           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
4098                                     rId.getConstArray(), 16 ) )
4099     {
4100         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
4101     }
4102     return 0;
4103 }
4104 
4105 // static
4106 const uno::Sequence<sal_Int8>& ScCellRangesBase::getUnoTunnelId()
4107 {
4108     static uno::Sequence<sal_Int8> * pSeq = 0;
4109     if( !pSeq )
4110     {
4111         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
4112         if( !pSeq )
4113         {
4114             static uno::Sequence< sal_Int8 > aSeq( 16 );
4115             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
4116             pSeq = &aSeq;
4117         }
4118     }
4119     return *pSeq;
4120 }
4121 
4122 // static
4123 ScCellRangesBase* ScCellRangesBase::getImplementation( const uno::Reference<uno::XInterface> xObj )
4124 {
4125     ScCellRangesBase* pRet = NULL;
4126     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
4127     if (xUT.is())
4128         pRet = reinterpret_cast<ScCellRangesBase*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
4129     return pRet;
4130 }
4131 
4132 //------------------------------------------------------------------------
4133 
4134 ScCellRangesObj::ScCellRangesObj(ScDocShell* pDocSh, const ScRangeList& rR) :
4135     ScCellRangesBase( pDocSh, rR )
4136 {
4137 }
4138 
4139 ScCellRangesObj::~ScCellRangesObj()
4140 {
4141 }
4142 
4143 void ScCellRangesObj::RefChanged()
4144 {
4145     ScCellRangesBase::RefChanged();
4146 
4147     //  nix weiter...
4148 }
4149 
4150 uno::Any SAL_CALL ScCellRangesObj::queryInterface( const uno::Type& rType )
4151                                                 throw(uno::RuntimeException)
4152 {
4153     SC_QUERYINTERFACE( sheet::XSheetCellRangeContainer )
4154     SC_QUERYINTERFACE( sheet::XSheetCellRanges )
4155     SC_QUERYINTERFACE( container::XIndexAccess )
4156     SC_QUERY_MULTIPLE( container::XElementAccess, container::XIndexAccess )
4157     SC_QUERYINTERFACE( container::XEnumerationAccess )
4158     SC_QUERYINTERFACE( container::XNameContainer )
4159     SC_QUERYINTERFACE( container::XNameReplace )
4160     SC_QUERYINTERFACE( container::XNameAccess )
4161 
4162     return ScCellRangesBase::queryInterface( rType );
4163 }
4164 
4165 void SAL_CALL ScCellRangesObj::acquire() throw()
4166 {
4167     ScCellRangesBase::acquire();
4168 }
4169 
4170 void SAL_CALL ScCellRangesObj::release() throw()
4171 {
4172     ScCellRangesBase::release();
4173 }
4174 
4175 uno::Sequence<uno::Type> SAL_CALL ScCellRangesObj::getTypes() throw(uno::RuntimeException)
4176 {
4177     static uno::Sequence<uno::Type> aTypes;
4178     if ( aTypes.getLength() == 0 )
4179     {
4180         uno::Sequence<uno::Type> aParentTypes(ScCellRangesBase::getTypes());
4181         long nParentLen = aParentTypes.getLength();
4182         const uno::Type* pParentPtr = aParentTypes.getConstArray();
4183 
4184         aTypes.realloc( nParentLen + 3 );
4185         uno::Type* pPtr = aTypes.getArray();
4186         pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSheetCellRangeContainer>*)0);
4187         pPtr[nParentLen + 1] = getCppuType((const uno::Reference<container::XNameContainer>*)0);
4188         pPtr[nParentLen + 2] = getCppuType((const uno::Reference<container::XEnumerationAccess>*)0);
4189 
4190         for (long i=0; i<nParentLen; i++)
4191             pPtr[i] = pParentPtr[i];                // parent types first
4192     }
4193     return aTypes;
4194 }
4195 
4196 uno::Sequence<sal_Int8> SAL_CALL ScCellRangesObj::getImplementationId()
4197                                                     throw(uno::RuntimeException)
4198 {
4199     static uno::Sequence< sal_Int8 > aId;
4200     if( aId.getLength() == 0 )
4201     {
4202         aId.realloc( 16 );
4203         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
4204     }
4205     return aId;
4206 }
4207 
4208 // XCellRanges
4209 
4210 ScCellRangeObj* ScCellRangesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
4211 {
4212     ScDocShell* pDocSh = GetDocShell();
4213     const ScRangeList& rRanges = GetRangeList();
4214     if ( pDocSh && nIndex >= 0 && nIndex < sal::static_int_cast<sal_Int32>(rRanges.Count()) )
4215     {
4216         ScRange aRange(*rRanges.GetObject(nIndex));
4217         if ( aRange.aStart == aRange.aEnd )
4218             return new ScCellObj( pDocSh, aRange.aStart );
4219         else
4220             return new ScCellRangeObj( pDocSh, aRange );
4221     }
4222 
4223     return NULL;        // keine DocShell oder falscher Index
4224 }
4225 
4226 uno::Sequence<table::CellRangeAddress> SAL_CALL ScCellRangesObj::getRangeAddresses()
4227                                                     throw(uno::RuntimeException)
4228 {
4229     ScUnoGuard aGuard;
4230     ScDocShell* pDocSh = GetDocShell();
4231     const ScRangeList& rRanges = GetRangeList();
4232     sal_uLong nCount = rRanges.Count();
4233     if ( pDocSh && nCount )
4234     {
4235         table::CellRangeAddress aRangeAddress;
4236         uno::Sequence<table::CellRangeAddress> aSeq(nCount);
4237         table::CellRangeAddress* pAry = aSeq.getArray();
4238         for (sal_uInt32 i=0; i<nCount; i++)
4239         {
4240             ScUnoConversion::FillApiRange( aRangeAddress, *rRanges.GetObject(i) );
4241             pAry[i] = aRangeAddress;
4242         }
4243         return aSeq;
4244     }
4245 
4246     return uno::Sequence<table::CellRangeAddress>(0);   // leer ist moeglich
4247 }
4248 
4249 uno::Reference<container::XEnumerationAccess> SAL_CALL ScCellRangesObj::getCells()
4250                                                     throw(uno::RuntimeException)
4251 {
4252     ScUnoGuard aGuard;
4253 
4254     //  getCells with empty range list is possible (no exception),
4255     //  the resulting enumeration just has no elements
4256     //  (same behaviour as a valid range with no cells)
4257     //  This is handled in ScCellsEnumeration ctor.
4258 
4259     const ScRangeList& rRanges = GetRangeList();
4260     ScDocShell* pDocSh = GetDocShell();
4261     if (pDocSh)
4262         return new ScCellsObj( pDocSh, rRanges );
4263     return NULL;
4264 }
4265 
4266 rtl::OUString SAL_CALL ScCellRangesObj::getRangeAddressesAsString()
4267                                                 throw(uno::RuntimeException)
4268 {
4269     ScUnoGuard aGuard;
4270     String aString;
4271     ScDocShell* pDocSh = GetDocShell();
4272     const ScRangeList& rRanges = GetRangeList();
4273     if (pDocSh)
4274         rRanges.Format( aString, SCA_VALID | SCA_TAB_3D, pDocSh->GetDocument() );
4275     return aString;
4276 }
4277 
4278 // XSheetCellRangeContainer
4279 
4280 void SAL_CALL ScCellRangesObj::addRangeAddress( const table::CellRangeAddress& rRange,
4281                                     sal_Bool bMergeRanges )
4282                                     throw(::com::sun::star::uno::RuntimeException)
4283 {
4284     ScUnoGuard aGuard;
4285     ScRange aRange(static_cast<SCCOL>(rRange.StartColumn),
4286             static_cast<SCROW>(rRange.StartRow),
4287             static_cast<SCTAB>(rRange.Sheet),
4288             static_cast<SCCOL>(rRange.EndColumn),
4289             static_cast<SCROW>(rRange.EndRow),
4290             static_cast<SCTAB>(rRange.Sheet));
4291     AddRange(aRange, bMergeRanges);
4292 }
4293 
4294 void lcl_RemoveNamedEntry( ScNamedEntryArr_Impl& rNamedEntries, const ScRange& rRange )
4295 {
4296     sal_uInt16 nCount = rNamedEntries.Count();
4297     for ( sal_uInt16 n=nCount; n--; )
4298         if ( rNamedEntries[n]->GetRange() == rRange )
4299             rNamedEntries.DeleteAndDestroy( n );
4300 }
4301 
4302 void SAL_CALL ScCellRangesObj::removeRangeAddress( const table::CellRangeAddress& rRange )
4303                                 throw(::com::sun::star::container::NoSuchElementException,
4304                                     ::com::sun::star::uno::RuntimeException)
4305 {
4306     ScUnoGuard aGuard;
4307     const ScRangeList& rRanges = GetRangeList();
4308 
4309     ScRangeList aSheetRanges;
4310     ScRangeList aNotSheetRanges;
4311     for (sal_uInt32 i = 0; i < rRanges.Count(); ++i)
4312     {
4313         if (rRanges.GetObject(i)->aStart.Tab() == rRange.Sheet)
4314         {
4315             aSheetRanges.Append(*rRanges.GetObject(i));
4316         }
4317         else
4318         {
4319             aNotSheetRanges.Append(*rRanges.GetObject(i));
4320         }
4321     }
4322     ScMarkData aMarkData;
4323     aMarkData.MarkFromRangeList( aSheetRanges, sal_False );
4324     ScRange aRange(static_cast<SCCOL>(rRange.StartColumn),
4325                 static_cast<SCROW>(rRange.StartRow),
4326                 static_cast<SCTAB>(rRange.Sheet),
4327                 static_cast<SCCOL>(rRange.EndColumn),
4328                 static_cast<SCROW>(rRange.EndRow),
4329                 static_cast<SCTAB>(rRange.Sheet));
4330     if (aMarkData.GetTableSelect( aRange.aStart.Tab() ))
4331     {
4332         aMarkData.MarkToMulti();
4333         if (aMarkData.IsAllMarked( aRange ) )
4334         {
4335             aMarkData.SetMultiMarkArea( aRange, sal_False );
4336             lcl_RemoveNamedEntry(aNamedEntries, aRange);
4337         }
4338         else
4339             throw container::NoSuchElementException();
4340     }
4341     SetNewRanges(aNotSheetRanges);
4342     ScRangeList aNew;
4343     aMarkData.FillRangeListWithMarks( &aNew, sal_False );
4344     for (sal_uInt32 j = 0; j < aNew.Count(); ++j)
4345     {
4346         AddRange(*aNew.GetObject(j), sal_False);
4347     }
4348 }
4349 
4350 void SAL_CALL ScCellRangesObj::addRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRanges,
4351                                     sal_Bool bMergeRanges )
4352                                     throw(::com::sun::star::uno::RuntimeException)
4353 {
4354     ScUnoGuard aGuard;
4355     sal_Int32 nCount(rRanges.getLength());
4356     if (nCount)
4357     {
4358         const table::CellRangeAddress* pRanges = rRanges.getConstArray();
4359         for (sal_Int32 i = 0; i < rRanges.getLength(); i++, pRanges++)
4360         {
4361             ScRange aRange(static_cast<SCCOL>(pRanges->StartColumn),
4362                     static_cast<SCROW>(pRanges->StartRow),
4363                     static_cast<SCTAB>(pRanges->Sheet),
4364                     static_cast<SCCOL>(pRanges->EndColumn),
4365                     static_cast<SCROW>(pRanges->EndRow),
4366                     static_cast<SCTAB>(pRanges->Sheet));
4367             AddRange(aRange, bMergeRanges);
4368         }
4369     }
4370 }
4371 
4372 void SAL_CALL ScCellRangesObj::removeRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRangeSeq )
4373                                 throw(::com::sun::star::container::NoSuchElementException,
4374                                     ::com::sun::star::uno::RuntimeException)
4375 {
4376     // with this implementation not needed
4377 //  ScUnoGuard aGuard;
4378 
4379 
4380     // use sometimes a better/faster implementation
4381     sal_uInt32 nCount(rRangeSeq.getLength());
4382     if (nCount)
4383     {
4384         const table::CellRangeAddress* pRanges = rRangeSeq.getConstArray();
4385         for (sal_uInt32 i=0; i < nCount; ++i, ++pRanges)
4386         {
4387             removeRangeAddress(*pRanges);
4388         }
4389     }
4390 }
4391 
4392 // XNameContainer
4393 
4394 void lcl_RemoveNamedEntry( ScNamedEntryArr_Impl& rNamedEntries, const String& rName )
4395 {
4396     sal_uInt16 nCount = rNamedEntries.Count();
4397     for ( sal_uInt16 n=nCount; n--; )
4398         if ( rNamedEntries[n]->GetName() == rName )
4399             rNamedEntries.DeleteAndDestroy( n );
4400 }
4401 
4402 void SAL_CALL ScCellRangesObj::insertByName( const rtl::OUString& aName, const uno::Any& aElement )
4403                             throw(lang::IllegalArgumentException, container::ElementExistException,
4404                                     lang::WrappedTargetException, uno::RuntimeException)
4405 {
4406     ScUnoGuard aGuard;
4407     ScDocShell* pDocSh = GetDocShell();
4408     sal_Bool bDone = sal_False;
4409 
4410     //! Type of aElement can be some specific interface instead of XInterface
4411 
4412     uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
4413     if ( pDocSh && xInterface.is() )
4414     {
4415         ScCellRangesBase* pRangesImp = ScCellRangesBase::getImplementation( xInterface );
4416         if ( pRangesImp && pRangesImp->GetDocShell() == pDocSh )
4417         {
4418             //  if explicit name is given and already existing, throw exception
4419 
4420             String aNamStr(aName);
4421             if ( aNamStr.Len() )
4422             {
4423                 sal_uInt16 nNamedCount = aNamedEntries.Count();
4424                 for (sal_uInt16 n=0; n<nNamedCount; n++)
4425                     if ( aNamedEntries[n]->GetName() == aNamStr )
4426                         throw container::ElementExistException();
4427             }
4428 
4429             ScRangeList aNew(GetRangeList());
4430             const ScRangeList& rAddRanges = pRangesImp->GetRangeList();
4431             sal_uLong nAddCount = rAddRanges.Count();
4432             for (sal_uLong i=0; i<nAddCount; i++)
4433                 aNew.Join( *rAddRanges.GetObject(i) );
4434             SetNewRanges(aNew);
4435             bDone = sal_True;
4436 
4437             if ( aName.getLength() && nAddCount == 1 )
4438             {
4439                 //  if a name is given, also insert into list of named entries
4440                 //  (only possible for a single range)
4441                 //  name is not in aNamedEntries (tested above)
4442 
4443                 ScNamedEntry* pEntry = new ScNamedEntry( aNamStr, *rAddRanges.GetObject(0) );
4444                 aNamedEntries.Insert( pEntry, aNamedEntries.Count() );
4445             }
4446         }
4447     }
4448 
4449     if (!bDone)
4450     {
4451         //  invalid element - double names are handled above
4452         throw lang::IllegalArgumentException();
4453     }
4454 }
4455 
4456 sal_Bool lcl_FindRangeByName( const ScRangeList& rRanges, ScDocShell* pDocSh,
4457                             const String& rName, sal_uLong& rIndex )
4458 {
4459     if (pDocSh)
4460     {
4461         String aRangeStr;
4462         ScDocument* pDoc = pDocSh->GetDocument();
4463         sal_uLong nCount = rRanges.Count();
4464         for (sal_uLong i=0; i<nCount; i++)
4465         {
4466             rRanges.GetObject(i)->Format( aRangeStr, SCA_VALID | SCA_TAB_3D, pDoc );
4467             if ( aRangeStr == rName )
4468             {
4469                 rIndex = i;
4470                 return sal_True;
4471             }
4472         }
4473     }
4474     return sal_False;   // nicht gefunden
4475 }
4476 
4477 sal_Bool lcl_FindRangeOrEntry( const ScNamedEntryArr_Impl& rNamedEntries,
4478                             const ScRangeList& rRanges, ScDocShell* pDocSh,
4479                             const String& rName, ScRange& rFound )
4480 {
4481     //  exact range in list?
4482 
4483     sal_uLong nIndex = 0;
4484     if ( lcl_FindRangeByName( rRanges, pDocSh, rName, nIndex ) )
4485     {
4486         rFound = *rRanges.GetObject(nIndex);
4487         return sal_True;
4488     }
4489 
4490     //  range contained in selection? (sheet must be specified)
4491 
4492     ScRange aCellRange;
4493     sal_uInt16 nParse = aCellRange.ParseAny( rName, pDocSh->GetDocument() );
4494     if ( ( nParse & ( SCA_VALID | SCA_TAB_3D ) ) == ( SCA_VALID | SCA_TAB_3D ) )
4495     {
4496         ScMarkData aMarkData;
4497         aMarkData.MarkFromRangeList( rRanges, sal_False );
4498         aMarkData.MarkToMulti();        // needed for IsAllMarked
4499         if ( aMarkData.IsAllMarked( aCellRange ) )
4500         {
4501             rFound = aCellRange;
4502             return sal_True;
4503         }
4504     }
4505 
4506     //  named entry in this object?
4507 
4508     if ( rNamedEntries.Count() )
4509     {
4510         for ( sal_uInt16 n=0; n<rNamedEntries.Count(); n++ )
4511             if ( rNamedEntries[n]->GetName() == rName )
4512             {
4513                 //  test if named entry is contained in rRanges
4514 
4515                 const ScRange& rComp = rNamedEntries[n]->GetRange();
4516                 ScMarkData aMarkData;
4517                 aMarkData.MarkFromRangeList( rRanges, sal_False );
4518                 aMarkData.MarkToMulti();        // needed for IsAllMarked
4519                 if ( aMarkData.IsAllMarked( rComp ) )
4520                 {
4521                     rFound = rComp;
4522                     return sal_True;
4523                 }
4524             }
4525     }
4526 
4527     return sal_False;       // not found
4528 }
4529 
4530 void SAL_CALL ScCellRangesObj::removeByName( const rtl::OUString& aName )
4531                                 throw(container::NoSuchElementException,
4532                                     lang::WrappedTargetException, uno::RuntimeException)
4533 {
4534     ScUnoGuard aGuard;
4535     sal_Bool bDone = sal_False;
4536     String aNameStr(aName);
4537     ScDocShell* pDocSh = GetDocShell();
4538     const ScRangeList& rRanges = GetRangeList();
4539     sal_uLong nIndex = 0;
4540     if ( lcl_FindRangeByName( rRanges, pDocSh, aNameStr, nIndex ) )
4541     {
4542         //  einzelnen Range weglassen
4543         ScRangeList aNew;
4544         sal_uLong nCount = rRanges.Count();
4545         for (sal_uLong i=0; i<nCount; i++)
4546             if (i != nIndex)
4547                 aNew.Append( *rRanges.GetObject(i) );
4548         SetNewRanges(aNew);
4549         bDone = sal_True;
4550     }
4551     else if (pDocSh)
4552     {
4553         //  deselect any ranges (parsed or named entry)
4554         ScRangeList aDiff;
4555         sal_Bool bValid = ( aDiff.Parse( aNameStr, pDocSh->GetDocument() ) & SCA_VALID ) != 0;
4556         if ( !bValid && aNamedEntries.Count() )
4557         {
4558             sal_uInt16 nCount = aNamedEntries.Count();
4559             for (sal_uInt16 n=0; n<nCount && !bValid; n++)
4560                 if (aNamedEntries[n]->GetName() == aNameStr)
4561                 {
4562                     aDiff.RemoveAll();
4563                     aDiff.Append( aNamedEntries[n]->GetRange() );
4564                     bValid = sal_True;
4565                 }
4566         }
4567         if ( bValid )
4568         {
4569             ScMarkData aMarkData;
4570             aMarkData.MarkFromRangeList( rRanges, sal_False );
4571 
4572             sal_uLong nDiffCount = aDiff.Count();
4573             for (sal_uLong i=0; i<nDiffCount; i++)
4574             {
4575                 ScRange* pDiffRange = aDiff.GetObject(i);
4576                 if (aMarkData.GetTableSelect( pDiffRange->aStart.Tab() ))
4577                     aMarkData.SetMultiMarkArea( *pDiffRange, sal_False );
4578             }
4579 
4580             ScRangeList aNew;
4581             aMarkData.FillRangeListWithMarks( &aNew, sal_False );
4582             SetNewRanges(aNew);
4583 
4584             bDone = sal_True;       //! error if range was not selected before?
4585         }
4586     }
4587 
4588     if (aNamedEntries.Count())
4589         lcl_RemoveNamedEntry( aNamedEntries, aNameStr );    //  remove named entry
4590 
4591     if (!bDone)
4592         throw container::NoSuchElementException();      // not found
4593 }
4594 
4595 // XNameReplace
4596 
4597 void SAL_CALL ScCellRangesObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement )
4598                             throw(lang::IllegalArgumentException, container::NoSuchElementException,
4599                                     lang::WrappedTargetException, uno::RuntimeException)
4600 {
4601     ScUnoGuard aGuard;
4602     //! zusammenfassen?
4603     removeByName( aName );
4604     insertByName( aName, aElement );
4605 }
4606 
4607 // XNameAccess
4608 
4609 uno::Any SAL_CALL ScCellRangesObj::getByName( const rtl::OUString& aName )
4610             throw(container::NoSuchElementException,
4611                     lang::WrappedTargetException, uno::RuntimeException)
4612 {
4613     ScUnoGuard aGuard;
4614     uno::Any aRet;
4615 
4616     String aNameStr(aName);
4617     ScDocShell* pDocSh = GetDocShell();
4618     const ScRangeList& rRanges = GetRangeList();
4619     ScRange aRange;
4620     if ( lcl_FindRangeOrEntry( aNamedEntries, rRanges, pDocSh, aNameStr, aRange ) )
4621     {
4622         uno::Reference<table::XCellRange> xRange;
4623         if ( aRange.aStart == aRange.aEnd )
4624             xRange.set(new ScCellObj( pDocSh, aRange.aStart ));
4625         else
4626             xRange.set(new ScCellRangeObj( pDocSh, aRange ));
4627         aRet <<= xRange;
4628     }
4629     else
4630         throw container::NoSuchElementException();
4631     return aRet;
4632 }
4633 
4634 sal_Bool lcl_FindEntryName( const ScNamedEntryArr_Impl& rNamedEntries,
4635                         const ScRange& rRange, String& rName )
4636 {
4637     sal_uInt16 nCount = rNamedEntries.Count();
4638     for (sal_uInt16 i=0; i<nCount; i++)
4639         if (rNamedEntries[i]->GetRange() == rRange)
4640         {
4641             rName = rNamedEntries[i]->GetName();
4642             return sal_True;
4643         }
4644     return sal_False;
4645 }
4646 
4647 uno::Sequence<rtl::OUString> SAL_CALL ScCellRangesObj::getElementNames()
4648                                                 throw(uno::RuntimeException)
4649 {
4650     ScUnoGuard aGuard;
4651 
4652     ScDocShell* pDocSh = GetDocShell();
4653     const ScRangeList& rRanges = GetRangeList();
4654     if (pDocSh)
4655     {
4656         String aRangeStr;
4657         ScDocument* pDoc = pDocSh->GetDocument();
4658         sal_uLong nCount = rRanges.Count();
4659 
4660         uno::Sequence<rtl::OUString> aSeq(nCount);
4661         rtl::OUString* pAry = aSeq.getArray();
4662         for (sal_uLong i=0; i<nCount; i++)
4663         {
4664             //  use given name if for exactly this range, otherwise just format
4665             ScRange aRange = *rRanges.GetObject(i);
4666             if ( !aNamedEntries.Count() || !lcl_FindEntryName( aNamedEntries, aRange, aRangeStr ) )
4667                 aRange.Format( aRangeStr, SCA_VALID | SCA_TAB_3D, pDoc );
4668             pAry[i] = aRangeStr;
4669         }
4670         return aSeq;
4671     }
4672     return uno::Sequence<rtl::OUString>(0);
4673 }
4674 
4675 sal_Bool SAL_CALL ScCellRangesObj::hasByName( const rtl::OUString& aName )
4676                                         throw(uno::RuntimeException)
4677 {
4678     ScUnoGuard aGuard;
4679     String aNameStr(aName);
4680     ScDocShell* pDocSh = GetDocShell();
4681     const ScRangeList& rRanges = GetRangeList();
4682     ScRange aRange;
4683     return lcl_FindRangeOrEntry( aNamedEntries, rRanges, pDocSh, aNameStr, aRange );
4684 }
4685 
4686 // XEnumerationAccess
4687 
4688 uno::Reference<container::XEnumeration> SAL_CALL ScCellRangesObj::createEnumeration()
4689                                                     throw(uno::RuntimeException)
4690 {
4691     ScUnoGuard aGuard;
4692     return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SheetCellRangesEnumeration")));
4693 }
4694 
4695 // XIndexAccess
4696 
4697 sal_Int32 SAL_CALL ScCellRangesObj::getCount() throw(uno::RuntimeException)
4698 {
4699     ScUnoGuard aGuard;
4700     const ScRangeList& rRanges = GetRangeList();
4701     return rRanges.Count();
4702 }
4703 
4704 uno::Any SAL_CALL ScCellRangesObj::getByIndex( sal_Int32 nIndex )
4705                             throw(lang::IndexOutOfBoundsException,
4706                                     lang::WrappedTargetException, uno::RuntimeException)
4707 {
4708     ScUnoGuard aGuard;
4709     uno::Reference<table::XCellRange> xRange(GetObjectByIndex_Impl(nIndex));
4710     if (xRange.is())
4711         return uno::makeAny(xRange);
4712     else
4713         throw lang::IndexOutOfBoundsException();
4714 //    return uno::Any();
4715 }
4716 
4717 uno::Type SAL_CALL ScCellRangesObj::getElementType() throw(uno::RuntimeException)
4718 {
4719     ScUnoGuard aGuard;
4720     return getCppuType((uno::Reference<table::XCellRange>*)0);
4721 }
4722 
4723 sal_Bool SAL_CALL ScCellRangesObj::hasElements() throw(uno::RuntimeException)
4724 {
4725     ScUnoGuard aGuard;
4726     const ScRangeList& rRanges = GetRangeList();
4727     return rRanges.Count() != 0;
4728 }
4729 
4730 // XServiceInfo
4731 
4732 rtl::OUString SAL_CALL ScCellRangesObj::getImplementationName() throw(uno::RuntimeException)
4733 {
4734     return rtl::OUString::createFromAscii( "ScCellRangesObj" );
4735 }
4736 
4737 sal_Bool SAL_CALL ScCellRangesObj::supportsService( const rtl::OUString& rServiceName )
4738                                                     throw(uno::RuntimeException)
4739 {
4740     String aServiceStr(rServiceName);
4741     return aServiceStr.EqualsAscii( SCSHEETCELLRANGES_SERVICE ) ||
4742            aServiceStr.EqualsAscii( SCCELLPROPERTIES_SERVICE ) ||
4743            aServiceStr.EqualsAscii( SCCHARPROPERTIES_SERVICE ) ||
4744            aServiceStr.EqualsAscii( SCPARAPROPERTIES_SERVICE );
4745 }
4746 
4747 uno::Sequence<rtl::OUString> SAL_CALL ScCellRangesObj::getSupportedServiceNames()
4748                                                     throw(uno::RuntimeException)
4749 {
4750     uno::Sequence<rtl::OUString> aRet(4);
4751     rtl::OUString* pArray = aRet.getArray();
4752     pArray[0] = rtl::OUString::createFromAscii( SCSHEETCELLRANGES_SERVICE );
4753     pArray[1] = rtl::OUString::createFromAscii( SCCELLPROPERTIES_SERVICE );
4754     pArray[2] = rtl::OUString::createFromAscii( SCCHARPROPERTIES_SERVICE );
4755     pArray[3] = rtl::OUString::createFromAscii( SCPARAPROPERTIES_SERVICE );
4756     return aRet;
4757 }
4758 
4759 //------------------------------------------------------------------------
4760 
4761 // static
4762 uno::Reference<table::XCellRange> ScCellRangeObj::CreateRangeFromDoc( ScDocument* pDoc, const ScRange& rR )
4763 {
4764     SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
4765     if ( pObjSh && pObjSh->ISA(ScDocShell) )
4766         return new ScCellRangeObj( (ScDocShell*) pObjSh, rR );
4767     return NULL;
4768 }
4769 
4770 //------------------------------------------------------------------------
4771 
4772 ScCellRangeObj::ScCellRangeObj(ScDocShell* pDocSh, const ScRange& rR) :
4773     ScCellRangesBase( pDocSh, rR ),
4774     pRangePropSet( lcl_GetRangePropertySet() ),
4775     aRange( rR )
4776 {
4777     aRange.Justify();       // Anfang / Ende richtig
4778 }
4779 
4780 ScCellRangeObj::~ScCellRangeObj()
4781 {
4782 }
4783 
4784 void ScCellRangeObj::RefChanged()
4785 {
4786     ScCellRangesBase::RefChanged();
4787 
4788     const ScRangeList& rRanges = GetRangeList();
4789     DBG_ASSERT(rRanges.Count() == 1, "was fuer Ranges ?!?!");
4790     const ScRange* pFirst = rRanges.GetObject(0);
4791     if (pFirst)
4792     {
4793         aRange = *pFirst;
4794         aRange.Justify();
4795     }
4796 }
4797 
4798 uno::Any SAL_CALL ScCellRangeObj::queryInterface( const uno::Type& rType )
4799                                                 throw(uno::RuntimeException)
4800 {
4801     SC_QUERYINTERFACE( sheet::XCellRangeAddressable )
4802     SC_QUERYINTERFACE( table::XCellRange )
4803     SC_QUERYINTERFACE( sheet::XSheetCellRange )
4804     SC_QUERYINTERFACE( sheet::XArrayFormulaRange )
4805     SC_QUERYINTERFACE( sheet::XArrayFormulaTokens )
4806     SC_QUERYINTERFACE( sheet::XCellRangeData )
4807     SC_QUERYINTERFACE( sheet::XCellRangeFormula )
4808     SC_QUERYINTERFACE( sheet::XMultipleOperation )
4809     SC_QUERYINTERFACE( util::XMergeable )
4810     SC_QUERYINTERFACE( sheet::XCellSeries )
4811     SC_QUERYINTERFACE( table::XAutoFormattable )
4812     SC_QUERYINTERFACE( util::XSortable )
4813     SC_QUERYINTERFACE( sheet::XSheetFilterableEx )
4814     SC_QUERYINTERFACE( sheet::XSheetFilterable )
4815     SC_QUERYINTERFACE( sheet::XSubTotalCalculatable )
4816     SC_QUERYINTERFACE( table::XColumnRowRange )
4817     SC_QUERYINTERFACE( util::XImportable )
4818     SC_QUERYINTERFACE( sheet::XCellFormatRangesSupplier )
4819     SC_QUERYINTERFACE( sheet::XUniqueCellFormatRangesSupplier )
4820 
4821     return ScCellRangesBase::queryInterface( rType );
4822 }
4823 
4824 void SAL_CALL ScCellRangeObj::acquire() throw()
4825 {
4826     ScCellRangesBase::acquire();
4827 }
4828 
4829 void SAL_CALL ScCellRangeObj::release() throw()
4830 {
4831     ScCellRangesBase::release();
4832 }
4833 
4834 uno::Sequence<uno::Type> SAL_CALL ScCellRangeObj::getTypes() throw(uno::RuntimeException)
4835 {
4836     static uno::Sequence<uno::Type> aTypes;
4837     if ( aTypes.getLength() == 0 )
4838     {
4839         uno::Sequence<uno::Type> aParentTypes(ScCellRangesBase::getTypes());
4840         long nParentLen = aParentTypes.getLength();
4841         const uno::Type* pParentPtr = aParentTypes.getConstArray();
4842 
4843         aTypes.realloc( nParentLen + 17 );
4844         uno::Type* pPtr = aTypes.getArray();
4845         pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XCellRangeAddressable>*)0);
4846         pPtr[nParentLen + 1] = getCppuType((const uno::Reference<sheet::XSheetCellRange>*)0);
4847         pPtr[nParentLen + 2] = getCppuType((const uno::Reference<sheet::XArrayFormulaRange>*)0);
4848         pPtr[nParentLen + 3] = getCppuType((const uno::Reference<sheet::XArrayFormulaTokens>*)0);
4849         pPtr[nParentLen + 4] = getCppuType((const uno::Reference<sheet::XCellRangeData>*)0);
4850         pPtr[nParentLen + 5] = getCppuType((const uno::Reference<sheet::XCellRangeFormula>*)0);
4851         pPtr[nParentLen + 6] = getCppuType((const uno::Reference<sheet::XMultipleOperation>*)0);
4852         pPtr[nParentLen + 7] = getCppuType((const uno::Reference<util::XMergeable>*)0);
4853         pPtr[nParentLen + 8] = getCppuType((const uno::Reference<sheet::XCellSeries>*)0);
4854         pPtr[nParentLen + 9] = getCppuType((const uno::Reference<table::XAutoFormattable>*)0);
4855         pPtr[nParentLen +10] = getCppuType((const uno::Reference<util::XSortable>*)0);
4856         pPtr[nParentLen +11] = getCppuType((const uno::Reference<sheet::XSheetFilterableEx>*)0);
4857         pPtr[nParentLen +12] = getCppuType((const uno::Reference<sheet::XSubTotalCalculatable>*)0);
4858         pPtr[nParentLen +13] = getCppuType((const uno::Reference<table::XColumnRowRange>*)0);
4859         pPtr[nParentLen +14] = getCppuType((const uno::Reference<util::XImportable>*)0);
4860         pPtr[nParentLen +15] = getCppuType((const uno::Reference<sheet::XCellFormatRangesSupplier>*)0);
4861         pPtr[nParentLen +16] = getCppuType((const uno::Reference<sheet::XUniqueCellFormatRangesSupplier>*)0);
4862 
4863         for (long i=0; i<nParentLen; i++)
4864             pPtr[i] = pParentPtr[i];                // parent types first
4865     }
4866     return aTypes;
4867 }
4868 
4869 uno::Sequence<sal_Int8> SAL_CALL ScCellRangeObj::getImplementationId()
4870                                                     throw(uno::RuntimeException)
4871 {
4872     static uno::Sequence< sal_Int8 > aId;
4873     if( aId.getLength() == 0 )
4874     {
4875         aId.realloc( 16 );
4876         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
4877     }
4878     return aId;
4879 }
4880 
4881 // XCellRange
4882 
4883 //  ColumnCount / RowCount sind weggefallen
4884 //! werden im Writer fuer Tabellen noch gebraucht ???
4885 
4886 uno::Reference<table::XCell> ScCellRangeObj::GetCellByPosition_Impl(
4887                                         sal_Int32 nColumn, sal_Int32 nRow )
4888                                 throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
4889 {
4890     ScDocShell* pDocSh = GetDocShell();
4891     if (!pDocSh)
4892         throw uno::RuntimeException();
4893 
4894     if ( nColumn >= 0 && nRow >= 0 )
4895     {
4896         sal_Int32 nPosX = aRange.aStart.Col() + nColumn;
4897         sal_Int32 nPosY = aRange.aStart.Row() + nRow;
4898 
4899         if ( nPosX <= aRange.aEnd.Col() && nPosY <= aRange.aEnd.Row() )
4900         {
4901             ScAddress aNew( (SCCOL)nPosX, (SCROW)nPosY, aRange.aStart.Tab() );
4902             return new ScCellObj( pDocSh, aNew );
4903         }
4904     }
4905 
4906     throw lang::IndexOutOfBoundsException();
4907 //    return NULL;
4908 }
4909 
4910 uno::Reference<table::XCell> SAL_CALL ScCellRangeObj::getCellByPosition(
4911                                         sal_Int32 nColumn, sal_Int32 nRow )
4912                                 throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
4913 {
4914     ScUnoGuard aGuard;
4915 
4916     return GetCellByPosition_Impl(nColumn, nRow);
4917 }
4918 
4919 uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByPosition(
4920                 sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
4921                                     throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
4922 {
4923     ScUnoGuard aGuard;
4924 
4925     ScDocShell* pDocSh = GetDocShell();
4926     if (!pDocSh)
4927         throw uno::RuntimeException();
4928 
4929     if ( nLeft >= 0 && nTop >= 0 && nRight >= 0 && nBottom >= 0 )
4930     {
4931         sal_Int32 nStartX = aRange.aStart.Col() + nLeft;
4932         sal_Int32 nStartY = aRange.aStart.Row() + nTop;
4933         sal_Int32 nEndX = aRange.aStart.Col() + nRight;
4934         sal_Int32 nEndY = aRange.aStart.Row() + nBottom;
4935 
4936         if ( nStartX <= nEndX && nEndX <= aRange.aEnd.Col() &&
4937              nStartY <= nEndY && nEndY <= aRange.aEnd.Row() )
4938         {
4939             ScRange aNew( (SCCOL)nStartX, (SCROW)nStartY, aRange.aStart.Tab(),
4940                           (SCCOL)nEndX, (SCROW)nEndY, aRange.aEnd.Tab() );
4941             return new ScCellRangeObj( pDocSh, aNew );
4942         }
4943     }
4944 
4945     throw lang::IndexOutOfBoundsException();
4946 //    return NULL;
4947 }
4948 
4949 
4950 uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByName(
4951                         const rtl::OUString& aName ) throw(uno::RuntimeException)
4952 {
4953     return getCellRangeByName( aName, ScAddress::detailsOOOa1 );
4954 }
4955 
4956 uno::Reference<table::XCellRange>  ScCellRangeObj::getCellRangeByName(
4957                         const rtl::OUString& aName, const ScAddress::Details& rDetails  ) throw(uno::RuntimeException)
4958 {
4959     //  name refers to the whole document (with the range's table as default),
4960     //  valid only if the range is within this range
4961 
4962     ScUnoGuard aGuard;
4963     ScDocShell* pDocSh = GetDocShell();
4964     if ( pDocSh )
4965     {
4966         ScDocument* pDoc = pDocSh->GetDocument();
4967         SCTAB nTab = aRange.aStart.Tab();
4968 
4969         ScRange aCellRange;
4970         sal_Bool bFound = sal_False;
4971         String aString(aName);
4972         sal_uInt16 nParse = aCellRange.ParseAny( aString, pDoc, rDetails );
4973         if ( nParse & SCA_VALID )
4974         {
4975             if ( !(nParse & SCA_TAB_3D) )   // keine Tabelle angegeben -> auf dieser Tabelle
4976             {
4977                 aCellRange.aStart.SetTab(nTab);
4978                 aCellRange.aEnd.SetTab(nTab);
4979             }
4980             bFound = sal_True;
4981         }
4982         else
4983         {
4984             ScRangeUtil aRangeUtil;
4985             if ( aRangeUtil.MakeRangeFromName( aString, pDoc, nTab, aCellRange, RUTL_NAMES ) ||
4986                  aRangeUtil.MakeRangeFromName( aString, pDoc, nTab, aCellRange, RUTL_DBASE ) )
4987                 bFound = sal_True;
4988         }
4989 
4990         if (bFound)         // valid only if within this object's range
4991         {
4992             if (!aRange.In(aCellRange))
4993                 bFound = sal_False;
4994         }
4995 
4996         if (bFound)
4997         {
4998             if ( aCellRange.aStart == aCellRange.aEnd )
4999                 return new ScCellObj( pDocSh, aCellRange.aStart );
5000             else
5001                 return new ScCellRangeObj( pDocSh, aCellRange );
5002         }
5003     }
5004 
5005     throw uno::RuntimeException();
5006 //    return NULL;
5007 }
5008 
5009 // XColumnRowRange
5010 
5011 uno::Reference<table::XTableColumns> SAL_CALL ScCellRangeObj::getColumns() throw(uno::RuntimeException)
5012 {
5013     ScUnoGuard aGuard;
5014     ScDocShell* pDocSh = GetDocShell();
5015     if (pDocSh)
5016         return new ScTableColumnsObj( pDocSh, aRange.aStart.Tab(),
5017                                         aRange.aStart.Col(), aRange.aEnd.Col() );
5018 
5019     DBG_ERROR("Dokument ungueltig");
5020     return NULL;
5021 }
5022 
5023 uno::Reference<table::XTableRows> SAL_CALL ScCellRangeObj::getRows() throw(uno::RuntimeException)
5024 {
5025     ScUnoGuard aGuard;
5026     ScDocShell* pDocSh = GetDocShell();
5027     if (pDocSh)
5028         return new ScTableRowsObj( pDocSh, aRange.aStart.Tab(),
5029                                     aRange.aStart.Row(), aRange.aEnd.Row() );
5030 
5031     DBG_ERROR("Dokument ungueltig");
5032     return NULL;
5033 }
5034 
5035 // XAddressableCellRange
5036 
5037 table::CellRangeAddress SAL_CALL ScCellRangeObj::getRangeAddress() throw(uno::RuntimeException)
5038 {
5039     ScUnoGuard aGuard;
5040     table::CellRangeAddress aRet;
5041     ScUnoConversion::FillApiRange( aRet, aRange );
5042     return aRet;
5043 }
5044 
5045 // XSheetCellRange
5046 
5047 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScCellRangeObj::getSpreadsheet()
5048                                                 throw(uno::RuntimeException)
5049 {
5050     ScUnoGuard aGuard;
5051     ScDocShell* pDocSh = GetDocShell();
5052     if (pDocSh)
5053         return new ScTableSheetObj( pDocSh, aRange.aStart.Tab() );
5054 
5055     DBG_ERROR("Dokument ungueltig");
5056     return NULL;
5057 }
5058 
5059 // XArrayFormulaRange
5060 
5061 rtl::OUString SAL_CALL ScCellRangeObj::getArrayFormula() throw(uno::RuntimeException)
5062 {
5063     ScUnoGuard aGuard;
5064 
5065     //  Matrix-Formel, wenn eindeutig Teil einer Matrix,
5066     //  also wenn Anfang und Ende des Blocks zur selben Matrix gehoeren.
5067     //  Sonst Leerstring.
5068 
5069     String aFormula;
5070     ScDocShell* pDocSh = GetDocShell();
5071     if (pDocSh)
5072     {
5073         ScDocument* pDoc = pDocSh->GetDocument();
5074         const ScBaseCell* pCell1 = pDoc->GetCell( aRange.aStart );
5075         const ScBaseCell* pCell2 = pDoc->GetCell( aRange.aEnd );
5076         if ( pCell1 && pCell2 && pCell1->GetCellType() == CELLTYPE_FORMULA &&
5077                                  pCell2->GetCellType() == CELLTYPE_FORMULA )
5078         {
5079             const ScFormulaCell* pFCell1 = (const ScFormulaCell*)pCell1;
5080             const ScFormulaCell* pFCell2 = (const ScFormulaCell*)pCell2;
5081             ScAddress aStart1;
5082             ScAddress aStart2;
5083             if ( pFCell1->GetMatrixOrigin( aStart1 ) && pFCell2->GetMatrixOrigin( aStart2 ) )
5084             {
5085                 if ( aStart1 == aStart2 )               // beides dieselbe Matrix
5086                     pFCell1->GetFormula( aFormula );    // egal, von welcher Zelle
5087             }
5088         }
5089     }
5090     return aFormula;
5091 }
5092 
5093 void ScCellRangeObj::SetArrayFormula_Impl( const rtl::OUString& rFormula,
5094         const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
5095 {
5096     ScDocShell* pDocSh = GetDocShell();
5097     if (pDocSh)
5098     {
5099         ScDocFunc aFunc(*pDocSh);
5100         if ( rFormula.getLength() )
5101         {
5102             if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
5103             {
5104                 //  #74681# don't set array formula for sheet object
5105                 throw uno::RuntimeException();
5106             }
5107 
5108             aFunc.EnterMatrix( aRange, NULL, NULL, rFormula, sal_True, sal_True, rFormulaNmsp, eGrammar );
5109         }
5110         else
5111         {
5112             //  empty string -> erase array formula
5113             ScMarkData aMark;
5114             aMark.SetMarkArea( aRange );
5115             aMark.SelectTable( aRange.aStart.Tab(), sal_True );
5116             aFunc.DeleteContents( aMark, IDF_CONTENTS, sal_True, sal_True );
5117         }
5118     }
5119 }
5120 
5121 void SAL_CALL ScCellRangeObj::setArrayFormula( const rtl::OUString& aFormula )
5122                                                 throw(uno::RuntimeException)
5123 {
5124     ScUnoGuard aGuard;
5125     // GRAM_PODF_A1 for API compatibility.
5126     SetArrayFormula_Impl( aFormula, ::rtl::OUString(), formula::FormulaGrammar::GRAM_PODF_A1);
5127 }
5128 
5129 void ScCellRangeObj::SetArrayFormulaWithGrammar( const rtl::OUString& rFormula,
5130         const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ) throw(uno::RuntimeException)
5131 {
5132     ScUnoGuard aGuard;
5133     SetArrayFormula_Impl( rFormula, rFormulaNmsp, eGrammar);
5134 }
5135 
5136 // XArrayFormulaTokens
5137 
5138 uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellRangeObj::getArrayTokens() throw(uno::RuntimeException)
5139 {
5140     ScUnoGuard aGuard;
5141 
5142     // same cell logic as in getArrayFormula
5143 
5144     uno::Sequence<sheet::FormulaToken> aSequence;
5145     ScDocShell* pDocSh = GetDocShell();
5146     if ( pDocSh )
5147     {
5148         ScDocument* pDoc = pDocSh->GetDocument();
5149         const ScBaseCell* pCell1 = pDoc->GetCell( aRange.aStart );
5150         const ScBaseCell* pCell2 = pDoc->GetCell( aRange.aEnd );
5151         if ( pCell1 && pCell2 && pCell1->GetCellType() == CELLTYPE_FORMULA &&
5152                                  pCell2->GetCellType() == CELLTYPE_FORMULA )
5153         {
5154             const ScFormulaCell* pFCell1 = (const ScFormulaCell*)pCell1;
5155             const ScFormulaCell* pFCell2 = (const ScFormulaCell*)pCell2;
5156             ScAddress aStart1;
5157             ScAddress aStart2;
5158             if ( pFCell1->GetMatrixOrigin( aStart1 ) && pFCell2->GetMatrixOrigin( aStart2 ) )
5159             {
5160                 if ( aStart1 == aStart2 )
5161                 {
5162                     ScTokenArray* pTokenArray = pFCell1->GetCode();
5163                     if ( pTokenArray )
5164                         (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aSequence, *pTokenArray );
5165                 }
5166             }
5167         }
5168     }
5169     return aSequence;
5170 }
5171 
5172 void SAL_CALL ScCellRangeObj::setArrayTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException)
5173 {
5174     ScUnoGuard aGuard;
5175     ScDocShell* pDocSh = GetDocShell();
5176     if ( pDocSh )
5177     {
5178         ScDocFunc aFunc(*pDocSh);
5179         if ( rTokens.getLength() )
5180         {
5181             if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
5182             {
5183                 throw uno::RuntimeException();
5184             }
5185 
5186             ScDocument* pDoc = pDocSh->GetDocument();
5187             ScTokenArray aTokenArray;
5188             (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, rTokens );
5189 
5190             // Actually GRAM_PODF_A1 is a don't-care here because of the token
5191             // array being set, it fits with other API compatibility grammars
5192             // though.
5193             aFunc.EnterMatrix( aRange, NULL, &aTokenArray, EMPTY_STRING, sal_True, sal_True, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
5194         }
5195         else
5196         {
5197             //  empty sequence -> erase array formula
5198             ScMarkData aMark;
5199             aMark.SetMarkArea( aRange );
5200             aMark.SelectTable( aRange.aStart.Tab(), sal_True );
5201             aFunc.DeleteContents( aMark, IDF_CONTENTS, sal_True, sal_True );
5202         }
5203     }
5204 }
5205 
5206 // XCellRangeData
5207 
5208 uno::Sequence< uno::Sequence<uno::Any> > SAL_CALL ScCellRangeObj::getDataArray()
5209                                     throw(uno::RuntimeException)
5210 {
5211     ScUnoGuard aGuard;
5212 
5213     if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
5214     {
5215         //  don't create a data array for the sheet
5216         throw uno::RuntimeException();
5217     }
5218 
5219     ScDocShell* pDocSh = GetDocShell();
5220     if (pDocSh)
5221     {
5222         uno::Any aAny;
5223         // bAllowNV = TRUE: errors as void
5224         if ( ScRangeToSequence::FillMixedArray( aAny, pDocSh->GetDocument(), aRange, sal_True ) )
5225         {
5226             uno::Sequence< uno::Sequence<uno::Any> > aSeq;
5227             if ( aAny >>= aSeq )
5228                 return aSeq;            // success
5229         }
5230     }
5231 
5232     throw uno::RuntimeException();      // no other exceptions specified
5233 //    return uno::Sequence< uno::Sequence<uno::Any> >(0);
5234 }
5235 
5236 void SAL_CALL ScCellRangeObj::setDataArray(
5237                         const uno::Sequence< uno::Sequence<uno::Any> >& aArray )
5238                                     throw(uno::RuntimeException)
5239 {
5240     ScUnoGuard aGuard;
5241 
5242     sal_Bool bDone = sal_False;
5243     ScDocShell* pDocSh = GetDocShell();
5244     if (pDocSh)
5245     {
5246         //! move lcl_PutDataArray to docfunc?
5247         bDone = lcl_PutDataArray( *pDocSh, aRange, aArray );
5248     }
5249 
5250     if (!bDone)
5251         throw uno::RuntimeException();      // no other exceptions specified
5252 }
5253 
5254 // XCellRangeFormula
5255 
5256 uno::Sequence< uno::Sequence<rtl::OUString> > SAL_CALL ScCellRangeObj::getFormulaArray()
5257                                     throw(uno::RuntimeException)
5258 {
5259     ScUnoGuard aGuard;
5260 
5261     if ( ScTableSheetObj::getImplementation( (cppu::OWeakObject*)this ) )
5262     {
5263         //  don't create a data array for the sheet
5264         throw uno::RuntimeException();
5265     }
5266 
5267     ScDocShell* pDocSh = GetDocShell();
5268     if (pDocSh)
5269     {
5270         SCCOL nStartCol = aRange.aStart.Col();
5271         SCROW nStartRow = aRange.aStart.Row();
5272         SCCOL nEndCol = aRange.aEnd.Col();
5273         SCROW nEndRow = aRange.aEnd.Row();
5274         SCCOL nColCount = nEndCol + 1 - nStartCol;
5275         SCROW nRowCount = nEndRow + 1 - nStartRow;
5276         SCTAB nTab = aRange.aStart.Tab();
5277 
5278         uno::Sequence< uno::Sequence<rtl::OUString> > aRowSeq( nRowCount );
5279         uno::Sequence<rtl::OUString>* pRowAry = aRowSeq.getArray();
5280         for (SCROW nRowIndex = 0; nRowIndex < nRowCount; nRowIndex++)
5281         {
5282             uno::Sequence<rtl::OUString> aColSeq( nColCount );
5283             rtl::OUString* pColAry = aColSeq.getArray();
5284             for (SCCOL nColIndex = 0; nColIndex < nColCount; nColIndex++)
5285                 pColAry[nColIndex] = lcl_GetInputString( pDocSh->GetDocument(),
5286                                     ScAddress( nStartCol+nColIndex, nStartRow+nRowIndex, nTab ), sal_True );
5287 
5288             pRowAry[nRowIndex] = aColSeq;
5289         }
5290 
5291         return aRowSeq;
5292     }
5293 
5294     throw uno::RuntimeException();      // no other exceptions specified
5295 //    return uno::Sequence< uno::Sequence<rtl::OUString> >(0);
5296 }
5297 
5298 void SAL_CALL ScCellRangeObj::setFormulaArray(
5299                         const uno::Sequence< uno::Sequence<rtl::OUString> >& aArray )
5300                                     throw(uno::RuntimeException)
5301 {
5302     ScUnoGuard aGuard;
5303 
5304     sal_Bool bDone = sal_False;
5305     ScDocShell* pDocSh = GetDocShell();
5306     if (pDocSh)
5307     {
5308         ScExternalRefManager::ApiGuard aExtRefGuard(pDocSh->GetDocument());
5309 
5310         // GRAM_PODF_A1 for API compatibility.
5311         bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
5312     }
5313 
5314     if (!bDone)
5315         throw uno::RuntimeException();      // no other exceptions specified
5316 }
5317 
5318 // XMultipleOperation
5319 
5320 void SAL_CALL ScCellRangeObj::setTableOperation( const table::CellRangeAddress& aFormulaRange,
5321                                         sheet::TableOperationMode nMode,
5322                                         const table::CellAddress& aColumnCell,
5323                                         const table::CellAddress& aRowCell )
5324                                     throw(uno::RuntimeException)
5325 {
5326     ScUnoGuard aGuard;
5327     ScDocShell* pDocSh = GetDocShell();
5328     if (pDocSh)
5329     {
5330         sal_Bool bError = sal_False;
5331         ScTabOpParam aParam;
5332         aParam.aRefFormulaCell = ScRefAddress( (SCCOL)aFormulaRange.StartColumn,
5333                                               (SCROW)aFormulaRange.StartRow, aFormulaRange.Sheet,
5334                                               sal_False, sal_False, sal_False );
5335         aParam.aRefFormulaEnd  = ScRefAddress( (SCCOL)aFormulaRange.EndColumn,
5336                                               (SCROW)aFormulaRange.EndRow, aFormulaRange.Sheet,
5337                                               sal_False, sal_False, sal_False );
5338         aParam.aRefRowCell     = ScRefAddress( (SCCOL)aRowCell.Column,
5339                                               (SCROW)aRowCell.Row, aRowCell.Sheet,
5340                                               sal_False, sal_False, sal_False );
5341         aParam.aRefColCell     = ScRefAddress( (SCCOL)aColumnCell.Column,
5342                                               (SCROW)aColumnCell.Row, aColumnCell.Sheet,
5343                                               sal_False, sal_False, sal_False );
5344         switch (nMode)
5345         {
5346             case sheet::TableOperationMode_COLUMN:
5347                 aParam.nMode = 0;
5348                 break;
5349             case sheet::TableOperationMode_ROW:
5350                 aParam.nMode = 1;
5351                 break;
5352             case sheet::TableOperationMode_BOTH:
5353                 aParam.nMode = 2;
5354                 break;
5355             default:
5356                 bError = sal_True;
5357         }
5358 
5359         if (!bError)
5360         {
5361             ScDocFunc aFunc(*pDocSh);
5362             aFunc.TabOp( aRange, NULL, aParam, sal_True, sal_True );
5363         }
5364     }
5365 }
5366 
5367 // XMergeable
5368 
5369 void SAL_CALL ScCellRangeObj::merge( sal_Bool bMerge ) throw(uno::RuntimeException)
5370 {
5371     ScUnoGuard aGuard;
5372     ScDocShell* pDocSh = GetDocShell();
5373     if ( pDocSh )
5374     {
5375         ScDocFunc aFunc(*pDocSh);
5376         if ( bMerge )
5377             aFunc.MergeCells( aRange, sal_False, sal_True, sal_True );
5378         else
5379             aFunc.UnmergeCells( aRange, sal_True, sal_True );
5380 
5381         //! Fehler abfangen?
5382     }
5383 }
5384 
5385 sal_Bool SAL_CALL ScCellRangeObj::getIsMerged() throw(uno::RuntimeException)
5386 {
5387     ScUnoGuard aGuard;
5388     ScDocShell* pDocSh = GetDocShell();
5389     return pDocSh && pDocSh->GetDocument()->HasAttrib( aRange, HASATTR_MERGED );
5390 }
5391 
5392 // XCellSeries
5393 
5394 void SAL_CALL ScCellRangeObj::fillSeries( sheet::FillDirection nFillDirection,
5395                         sheet::FillMode nFillMode, sheet::FillDateMode nFillDateMode,
5396                         double fStep, double fEndValue ) throw(uno::RuntimeException)
5397 {
5398     ScUnoGuard aGuard;
5399     ScDocShell* pDocSh = GetDocShell();
5400     if ( pDocSh )
5401     {
5402         sal_Bool bError = sal_False;
5403 
5404         FillDir eDir = FILL_TO_BOTTOM;
5405         switch (nFillDirection)
5406         {
5407             case sheet::FillDirection_TO_BOTTOM:
5408                 eDir = FILL_TO_BOTTOM;
5409                 break;
5410             case sheet::FillDirection_TO_RIGHT:
5411                 eDir = FILL_TO_RIGHT;
5412                 break;
5413             case sheet::FillDirection_TO_TOP:
5414                 eDir = FILL_TO_TOP;
5415                 break;
5416             case sheet::FillDirection_TO_LEFT:
5417                 eDir = FILL_TO_LEFT;
5418                 break;
5419             default:
5420                 bError = sal_True;
5421         }
5422 
5423         FillCmd eCmd = FILL_SIMPLE;
5424         switch ( nFillMode )
5425         {
5426             case sheet::FillMode_SIMPLE:
5427                 eCmd = FILL_SIMPLE;
5428                 break;
5429             case sheet::FillMode_LINEAR:
5430                 eCmd = FILL_LINEAR;
5431                 break;
5432             case sheet::FillMode_GROWTH:
5433                 eCmd = FILL_GROWTH;
5434                 break;
5435             case sheet::FillMode_DATE:
5436                 eCmd = FILL_DATE;
5437                 break;
5438             case sheet::FillMode_AUTO:
5439                 eCmd = FILL_AUTO;
5440                 break;
5441             default:
5442                 bError = sal_True;
5443         }
5444 
5445         FillDateCmd eDateCmd = FILL_DAY;
5446         switch ( nFillDateMode )
5447         {
5448             case sheet::FillDateMode_FILL_DATE_DAY:
5449                 eDateCmd = FILL_DAY;
5450                 break;
5451             case sheet::FillDateMode_FILL_DATE_WEEKDAY:
5452                 eDateCmd = FILL_WEEKDAY;
5453                 break;
5454             case sheet::FillDateMode_FILL_DATE_MONTH:
5455                 eDateCmd = FILL_MONTH;
5456                 break;
5457             case sheet::FillDateMode_FILL_DATE_YEAR:
5458                 eDateCmd = FILL_YEAR;
5459                 break;
5460             default:
5461                 bError = sal_True;
5462         }
5463 
5464         if (!bError)
5465         {
5466             ScDocFunc aFunc(*pDocSh);
5467             aFunc.FillSeries( aRange, NULL, eDir, eCmd, eDateCmd,
5468                                 MAXDOUBLE, fStep, fEndValue, sal_True, sal_True );
5469         }
5470     }
5471 }
5472 
5473 void SAL_CALL ScCellRangeObj::fillAuto( sheet::FillDirection nFillDirection,
5474                                 sal_Int32 nSourceCount ) throw(uno::RuntimeException)
5475 {
5476     ScUnoGuard aGuard;
5477     ScDocShell* pDocSh = GetDocShell();
5478     if ( pDocSh && nSourceCount )
5479     {
5480         ScRange aSourceRange(aRange);
5481         SCsCOLROW nCount = 0;                   // "Dest-Count"
5482         FillDir eDir = FILL_TO_BOTTOM;
5483         sal_Bool bError = sal_False;
5484         switch (nFillDirection)
5485         {
5486             case sheet::FillDirection_TO_BOTTOM:
5487                 aSourceRange.aEnd.SetRow( static_cast<SCROW>( aSourceRange.aStart.Row() + nSourceCount - 1 ) );
5488                 nCount = aRange.aEnd.Row() - aSourceRange.aEnd.Row();
5489                 eDir = FILL_TO_BOTTOM;
5490                 break;
5491             case sheet::FillDirection_TO_RIGHT:
5492                 aSourceRange.aEnd.SetCol( static_cast<SCCOL>( aSourceRange.aStart.Col() + nSourceCount - 1 ) );
5493                 nCount = aRange.aEnd.Col() - aSourceRange.aEnd.Col();
5494                 eDir = FILL_TO_RIGHT;
5495                 break;
5496             case sheet::FillDirection_TO_TOP:
5497                 aSourceRange.aStart.SetRow( static_cast<SCROW>( aSourceRange.aEnd.Row() - nSourceCount + 1 ) );
5498                 nCount = aSourceRange.aStart.Row() - aRange.aStart.Row();
5499                 eDir = FILL_TO_TOP;
5500                 break;
5501             case sheet::FillDirection_TO_LEFT:
5502                 aSourceRange.aStart.SetCol( static_cast<SCCOL>( aSourceRange.aEnd.Col() - nSourceCount + 1 ) );
5503                 nCount = aSourceRange.aStart.Col() - aRange.aStart.Col();
5504                 eDir = FILL_TO_LEFT;
5505                 break;
5506             default:
5507                 bError = sal_True;
5508         }
5509         if (nCount < 0 || nCount > MAXROW)      // overflow
5510             bError = sal_True;
5511 
5512         if (!bError)
5513         {
5514             ScDocFunc aFunc(*pDocSh);
5515             aFunc.FillAuto( aSourceRange, NULL, eDir, nCount, sal_True, sal_True );
5516         }
5517     }
5518 }
5519 
5520 // XAutoFormattable
5521 
5522 void SAL_CALL ScCellRangeObj::autoFormat( const rtl::OUString& aName )
5523                     throw(lang::IllegalArgumentException, uno::RuntimeException)
5524 {
5525     ScUnoGuard aGuard;
5526     ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
5527     ScDocShell* pDocSh = GetDocShell();
5528     if ( pDocSh && pAutoFormat )
5529     {
5530         String aNameString(aName);
5531         sal_uInt16 nCount = pAutoFormat->GetCount();
5532         sal_uInt16 nIndex;
5533         String aCompare;
5534         for (nIndex=0; nIndex<nCount; nIndex++)
5535         {
5536             (*pAutoFormat)[nIndex]->GetName(aCompare);
5537             if ( aCompare == aNameString )                      //! Case-insensitiv ???
5538                 break;
5539         }
5540         if (nIndex<nCount)
5541         {
5542             ScDocFunc aFunc(*pDocSh);
5543             aFunc.AutoFormat( aRange, NULL, nIndex, sal_True, sal_True );
5544         }
5545         else
5546             throw lang::IllegalArgumentException();
5547     }
5548 }
5549 
5550 // XSortable
5551 
5552 uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createSortDescriptor()
5553                                                 throw(uno::RuntimeException)
5554 {
5555     ScUnoGuard aGuard;
5556     ScSortParam aParam;
5557     ScDocShell* pDocSh = GetDocShell();
5558     if ( pDocSh )
5559     {
5560         // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich
5561         ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
5562         if (pData)
5563         {
5564             pData->GetSortParam(aParam);
5565 
5566             //  im SortDescriptor sind die Fields innerhalb des Bereichs gezaehlt
5567             ScRange aDBRange;
5568             pData->GetArea(aDBRange);
5569             SCCOLROW nFieldStart = aParam.bByRow ?
5570                 static_cast<SCCOLROW>(aDBRange.aStart.Col()) :
5571                 static_cast<SCCOLROW>(aDBRange.aStart.Row());
5572             for (sal_uInt16 i=0; i<MAXSORT; i++)
5573                 if ( aParam.bDoSort[i] && aParam.nField[i] >= nFieldStart )
5574                     aParam.nField[i] -= nFieldStart;
5575         }
5576     }
5577 
5578     uno::Sequence<beans::PropertyValue> aSeq( ScSortDescriptor::GetPropertyCount() );
5579     ScSortDescriptor::FillProperties( aSeq, aParam );
5580     return aSeq;
5581 }
5582 
5583 void SAL_CALL ScCellRangeObj::sort( const uno::Sequence<beans::PropertyValue>& aDescriptor )
5584                                                 throw(uno::RuntimeException)
5585 {
5586     ScUnoGuard aGuard;
5587     ScDocShell* pDocSh = GetDocShell();
5588     if (pDocSh)
5589     {
5590         sal_uInt16 i;
5591         ScSortParam aParam;
5592         ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK ); // ggf. Bereich anlegen
5593         if (pData)
5594         {
5595             //  alten Einstellungen holen, falls nicht alles neu gesetzt wird
5596             pData->GetSortParam(aParam);
5597             SCCOLROW nOldStart = aParam.bByRow ?
5598                 static_cast<SCCOLROW>(aRange.aStart.Col()) :
5599                 static_cast<SCCOLROW>(aRange.aStart.Row());
5600             for (i=0; i<MAXSORT; i++)
5601                 if ( aParam.bDoSort[i] && aParam.nField[i] >= nOldStart )
5602                     aParam.nField[i] -= nOldStart;
5603         }
5604 
5605         ScSortDescriptor::FillSortParam( aParam, aDescriptor );
5606 
5607         //  im SortDescriptor sind die Fields innerhalb des Bereichs gezaehlt
5608         //  ByRow kann bei FillSortParam umgesetzt worden sein
5609         SCCOLROW nFieldStart = aParam.bByRow ?
5610             static_cast<SCCOLROW>(aRange.aStart.Col()) :
5611             static_cast<SCCOLROW>(aRange.aStart.Row());
5612         for (i=0; i<MAXSORT; i++)
5613             aParam.nField[i] += nFieldStart;
5614 
5615         SCTAB nTab = aRange.aStart.Tab();
5616         aParam.nCol1 = aRange.aStart.Col();
5617         aParam.nRow1 = aRange.aStart.Row();
5618         aParam.nCol2 = aRange.aEnd.Col();
5619         aParam.nRow2 = aRange.aEnd.Row();
5620 
5621         pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK );       // ggf. Bereich anlegen
5622 
5623         ScDBDocFunc aFunc(*pDocSh);                         // Bereich muss angelegt sein
5624         aFunc.Sort( nTab, aParam, sal_True, sal_True, sal_True );
5625     }
5626 }
5627 
5628 // XFilterable
5629 
5630 uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFilterDescriptor(
5631                                 sal_Bool bEmpty ) throw(uno::RuntimeException)
5632 {
5633     ScUnoGuard aGuard;
5634     ScDocShell* pDocSh = GetDocShell();
5635     ScFilterDescriptor* pNew = new ScFilterDescriptor(pDocSh);
5636     if ( !bEmpty && pDocSh )
5637     {
5638         // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich
5639         ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
5640         if (pData)
5641         {
5642             ScQueryParam aParam;
5643             pData->GetQueryParam(aParam);
5644             //  im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
5645             ScRange aDBRange;
5646             pData->GetArea(aDBRange);
5647             SCCOLROW nFieldStart = aParam.bByRow ?
5648                 static_cast<SCCOLROW>(aDBRange.aStart.Col()) :
5649                 static_cast<SCCOLROW>(aDBRange.aStart.Row());
5650             SCSIZE nCount = aParam.GetEntryCount();
5651             for (SCSIZE i=0; i<nCount; i++)
5652             {
5653                 ScQueryEntry& rEntry = aParam.GetEntry(i);
5654                 if (rEntry.bDoQuery && rEntry.nField >= nFieldStart)
5655                     rEntry.nField -= nFieldStart;
5656             }
5657             pNew->SetParam(aParam);
5658         }
5659     }
5660     return pNew;
5661 }
5662 
5663 void SAL_CALL ScCellRangeObj::filter( const uno::Reference<sheet::XSheetFilterDescriptor>& xDescriptor )
5664                                                 throw(uno::RuntimeException)
5665 {
5666     ScUnoGuard aGuard;
5667 
5668     //  das koennte theoretisch ein fremdes Objekt sein, also nur das
5669     //  oeffentliche XSheetFilterDescriptor Interface benutzen, um
5670     //  die Daten in ein ScFilterDescriptor Objekt zu kopieren:
5671     //! wenn es schon ein ScFilterDescriptor ist, direkt per getImplementation?
5672 
5673     ScDocShell* pDocSh = GetDocShell();
5674     ScFilterDescriptor aImpl(pDocSh);
5675     uno::Reference< sheet::XSheetFilterDescriptor2 > xDescriptor2( xDescriptor, uno::UNO_QUERY );
5676     if ( xDescriptor2.is() )
5677     {
5678         aImpl.setFilterFields2( xDescriptor2->getFilterFields2() );
5679     }
5680     else
5681     {
5682         aImpl.setFilterFields( xDescriptor->getFilterFields() );
5683     }
5684     //  Rest sind jetzt Properties...
5685 
5686     uno::Reference<beans::XPropertySet> xPropSet( xDescriptor, uno::UNO_QUERY );
5687     if (xPropSet.is())
5688         lcl_CopyProperties( aImpl, *(beans::XPropertySet*)xPropSet.get() );
5689 
5690     //
5691     //  ausfuehren...
5692     //
5693 
5694     if (pDocSh)
5695     {
5696         ScQueryParam aParam = aImpl.GetParam();
5697         //  im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
5698         SCCOLROW nFieldStart = aParam.bByRow ?
5699             static_cast<SCCOLROW>(aRange.aStart.Col()) :
5700             static_cast<SCCOLROW>(aRange.aStart.Row());
5701         SCSIZE nCount = aParam.GetEntryCount();
5702         for (SCSIZE i=0; i<nCount; i++)
5703         {
5704             ScQueryEntry& rEntry = aParam.GetEntry(i);
5705             if (rEntry.bDoQuery)
5706             {
5707                 rEntry.nField += nFieldStart;
5708                 //  Im Dialog wird immer der String angezeigt -> muss zum Wert passen
5709                 if ( !rEntry.bQueryByString )
5710                     pDocSh->GetDocument()->GetFormatTable()->
5711                         GetInputLineString( rEntry.nVal, 0, *rEntry.pStr );
5712             }
5713         }
5714 
5715         SCTAB nTab = aRange.aStart.Tab();
5716         aParam.nCol1 = aRange.aStart.Col();
5717         aParam.nRow1 = aRange.aStart.Row();
5718         aParam.nCol2 = aRange.aEnd.Col();
5719         aParam.nRow2 = aRange.aEnd.Row();
5720 
5721         pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK );   // ggf. Bereich anlegen
5722 
5723         //! keep source range in filter descriptor
5724         //! if created by createFilterDescriptorByObject ???
5725 
5726         ScDBDocFunc aFunc(*pDocSh);
5727         aFunc.Query( nTab, aParam, NULL, sal_True, sal_True );  // Bereich muss angelegt sein
5728     }
5729 }
5730 
5731 //! get/setAutoFilter als Properties!!!
5732 
5733 // XAdvancedFilterSource
5734 
5735 uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFilterDescriptorByObject(
5736                         const uno::Reference<sheet::XSheetFilterable>& xObject )
5737                                                 throw(uno::RuntimeException)
5738 {
5739     ScUnoGuard aGuard;
5740 
5741     //  this ist hier nicht der Bereich, der gefiltert wird, sondern der
5742     //  Bereich mit der Abfrage...
5743 
5744     uno::Reference<sheet::XCellRangeAddressable> xAddr( xObject, uno::UNO_QUERY );
5745 
5746     ScDocShell* pDocSh = GetDocShell();
5747     if ( pDocSh && xAddr.is() )
5748     {
5749         //! Test, ob xObject im selben Dokument ist
5750 
5751         ScFilterDescriptor* pNew = new ScFilterDescriptor(pDocSh);  //! stattdessen vom Objekt?
5752         //XSheetFilterDescriptorRef xNew = xObject->createFilterDescriptor(sal_True);
5753 
5754         ScQueryParam aParam = pNew->GetParam();
5755         aParam.bHasHeader = sal_True;
5756 
5757         table::CellRangeAddress aDataAddress(xAddr->getRangeAddress());
5758         aParam.nCol1 = (SCCOL)aDataAddress.StartColumn;
5759         aParam.nRow1 = (SCROW)aDataAddress.StartRow;
5760         aParam.nCol2 = (SCCOL)aDataAddress.EndColumn;
5761         aParam.nRow2 = (SCROW)aDataAddress.EndRow;
5762         aParam.nTab  = aDataAddress.Sheet;
5763 
5764         ScDocument* pDoc = pDocSh->GetDocument();
5765         sal_Bool bOk = pDoc->CreateQueryParam(
5766                             aRange.aStart.Col(), aRange.aStart.Row(),
5767                             aRange.aEnd.Col(), aRange.aEnd.Row(),
5768                             aRange.aStart.Tab(), aParam );
5769         if ( bOk )
5770         {
5771             //  im FilterDescriptor sind die Fields innerhalb des Bereichs gezaehlt
5772             SCCOLROW nFieldStart = aParam.bByRow ?
5773                 static_cast<SCCOLROW>(aDataAddress.StartColumn) :
5774                 static_cast<SCCOLROW>(aDataAddress.StartRow);
5775             SCSIZE nCount = aParam.GetEntryCount();
5776             for (SCSIZE i=0; i<nCount; i++)
5777             {
5778                 ScQueryEntry& rEntry = aParam.GetEntry(i);
5779                 if (rEntry.bDoQuery && rEntry.nField >= nFieldStart)
5780                     rEntry.nField -= nFieldStart;
5781             }
5782 
5783             pNew->SetParam( aParam );
5784             return pNew;
5785         }
5786         else
5787         {
5788             delete pNew;
5789             return NULL;        // ungueltig -> null
5790         }
5791     }
5792 
5793     DBG_ERROR("kein Dokument oder kein Bereich");
5794     return NULL;
5795 }
5796 
5797 // XSubTotalSource
5798 
5799 uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL ScCellRangeObj::createSubTotalDescriptor(
5800                                 sal_Bool bEmpty ) throw(uno::RuntimeException)
5801 {
5802     ScUnoGuard aGuard;
5803     ScSubTotalDescriptor* pNew = new ScSubTotalDescriptor;
5804     ScDocShell* pDocSh = GetDocShell();
5805     if ( !bEmpty && pDocSh )
5806     {
5807         // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich
5808         ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
5809         if (pData)
5810         {
5811             ScSubTotalParam aParam;
5812             pData->GetSubTotalParam(aParam);
5813             //  im SubTotalDescriptor sind die Fields innerhalb des Bereichs gezaehlt
5814             ScRange aDBRange;
5815             pData->GetArea(aDBRange);
5816             SCCOL nFieldStart = aDBRange.aStart.Col();
5817             for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
5818             {
5819                 if ( aParam.bGroupActive[i] )
5820                 {
5821                     if ( aParam.nField[i] >= nFieldStart )
5822                         aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] - nFieldStart );
5823                     for (SCCOL j=0; j<aParam.nSubTotals[i]; j++)
5824                         if ( aParam.pSubTotals[i][j] >= nFieldStart )
5825                             aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] - nFieldStart );
5826                 }
5827             }
5828             pNew->SetParam(aParam);
5829         }
5830     }
5831     return pNew;
5832 }
5833 
5834 void SAL_CALL ScCellRangeObj::applySubTotals(
5835                 const uno::Reference<sheet::XSubTotalDescriptor>& xDescriptor,
5836                 sal_Bool bReplace ) throw(uno::RuntimeException)
5837 {
5838     ScUnoGuard aGuard;
5839 
5840     if (!xDescriptor.is()) return;
5841 
5842     ScDocShell* pDocSh = GetDocShell();
5843     ScSubTotalDescriptorBase* pImp =
5844         ScSubTotalDescriptorBase::getImplementation( xDescriptor );
5845 
5846     if (pDocSh && pImp)
5847     {
5848         ScSubTotalParam aParam;
5849         pImp->GetData(aParam);      // virtuelle Methode der Basisklasse
5850 
5851         //  im SubTotalDescriptor sind die Fields innerhalb des Bereichs gezaehlt
5852         SCCOL nFieldStart = aRange.aStart.Col();
5853         for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++)
5854         {
5855             if ( aParam.bGroupActive[i] )
5856             {
5857                 aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] + nFieldStart );
5858                 for (SCCOL j=0; j<aParam.nSubTotals[i]; j++)
5859                     aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] + nFieldStart );
5860             }
5861         }
5862 
5863         aParam.bReplace = bReplace;
5864 
5865         SCTAB nTab = aRange.aStart.Tab();
5866         aParam.nCol1 = aRange.aStart.Col();
5867         aParam.nRow1 = aRange.aStart.Row();
5868         aParam.nCol2 = aRange.aEnd.Col();
5869         aParam.nRow2 = aRange.aEnd.Row();
5870 
5871         pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK );   // ggf. Bereich anlegen
5872 
5873         ScDBDocFunc aFunc(*pDocSh);
5874         aFunc.DoSubTotals( nTab, aParam, NULL, sal_True, sal_True );    // Bereich muss angelegt sein
5875     }
5876 }
5877 
5878 void SAL_CALL ScCellRangeObj::removeSubTotals() throw(uno::RuntimeException)
5879 {
5880     ScUnoGuard aGuard;
5881 
5882     ScDocShell* pDocSh = GetDocShell();
5883     if (pDocSh)
5884     {
5885         ScSubTotalParam aParam;
5886         ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
5887         if (pData)
5888             pData->GetSubTotalParam(aParam);    // auch bei Remove die Feld-Eintraege behalten
5889 
5890         aParam.bRemoveOnly = sal_True;
5891 
5892         SCTAB nTab = aRange.aStart.Tab();
5893         aParam.nCol1 = aRange.aStart.Col();
5894         aParam.nRow1 = aRange.aStart.Row();
5895         aParam.nCol2 = aRange.aEnd.Col();
5896         aParam.nRow2 = aRange.aEnd.Row();
5897 
5898         pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK );   // ggf. Bereich anlegen
5899 
5900         ScDBDocFunc aFunc(*pDocSh);
5901         aFunc.DoSubTotals( nTab, aParam, NULL, sal_True, sal_True );    // Bereich muss angelegt sein
5902     }
5903 }
5904 
5905 uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createImportDescriptor( sal_Bool bEmpty )
5906                                                 throw(uno::RuntimeException)
5907 {
5908     ScUnoGuard aGuard;
5909     ScImportParam aParam;
5910     ScDocShell* pDocSh = GetDocShell();
5911     if ( !bEmpty && pDocSh )
5912     {
5913         // DB-Bereich anlegen erst beim Ausfuehren, per API immer genau den Bereich
5914         ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, SC_DBSEL_FORCE_MARK );
5915         if (pData)
5916             pData->GetImportParam(aParam);
5917     }
5918 
5919     uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
5920     ScImportDescriptor::FillProperties( aSeq, aParam );
5921     return aSeq;
5922 }
5923 
5924 void SAL_CALL ScCellRangeObj::doImport( const uno::Sequence<beans::PropertyValue>& aDescriptor )
5925                                             throw(uno::RuntimeException)
5926 {
5927     ScUnoGuard aGuard;
5928     ScDocShell* pDocSh = GetDocShell();
5929     if (pDocSh)
5930     {
5931         ScImportParam aParam;
5932         ScImportDescriptor::FillImportParam( aParam, aDescriptor );
5933 
5934         SCTAB nTab = aRange.aStart.Tab();
5935         aParam.nCol1 = aRange.aStart.Col();
5936         aParam.nRow1 = aRange.aStart.Row();
5937         aParam.nCol2 = aRange.aEnd.Col();
5938         aParam.nRow2 = aRange.aEnd.Row();
5939 
5940         //! TODO: could we get passed a valid result set by any means?
5941 
5942         pDocSh->GetDBData( aRange, SC_DB_MAKE, SC_DBSEL_FORCE_MARK );       // ggf. Bereich anlegen
5943 
5944         ScDBDocFunc aFunc(*pDocSh);                         // Bereich muss angelegt sein
5945         aFunc.DoImport( nTab, aParam, NULL, sal_True );         //! Api-Flag as parameter
5946     }
5947 }
5948 
5949 // XCellFormatRangesSupplier
5950 
5951 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangeObj::getCellFormatRanges()
5952                                                 throw(uno::RuntimeException)
5953 {
5954     ScUnoGuard aGuard;
5955     ScDocShell* pDocSh = GetDocShell();
5956     if ( pDocSh )
5957         return new ScCellFormatsObj( pDocSh, aRange );
5958     return NULL;
5959 }
5960 
5961 // XUniqueCellFormatRangesSupplier
5962 
5963 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangeObj::getUniqueCellFormatRanges()
5964                                                 throw(uno::RuntimeException)
5965 {
5966     ScUnoGuard aGuard;
5967     ScDocShell* pDocSh = GetDocShell();
5968     if ( pDocSh )
5969         return new ScUniqueCellFormatsObj( pDocSh, aRange );
5970     return NULL;
5971 }
5972 
5973 // XPropertySet erweitert fuer Range-Properties
5974 
5975 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellRangeObj::getPropertySetInfo()
5976                                                         throw(uno::RuntimeException)
5977 {
5978     ScUnoGuard aGuard;
5979     static uno::Reference<beans::XPropertySetInfo> aRef(
5980         new SfxItemPropertySetInfo( pRangePropSet->getPropertyMap() ));
5981     return aRef;
5982 }
5983 
5984 void ScCellRangeObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
5985                                 throw(lang::IllegalArgumentException, uno::RuntimeException)
5986 {
5987     //  Range has only Position and Size in addition to ScCellRangesBase, both are ReadOnly
5988     //  -> nothing to do here
5989 
5990     ScCellRangesBase::SetOnePropertyValue( pEntry, aValue );
5991 }
5992 
5993 void ScCellRangeObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
5994                                             uno::Any& rAny )
5995                                                 throw(uno::RuntimeException)
5996 {
5997     if ( pEntry )
5998     {
5999         if ( pEntry->nWID == SC_WID_UNO_POS )
6000         {
6001             ScDocShell* pDocSh = GetDocShell();
6002             if (pDocSh)
6003             {
6004                 //  GetMMRect converts using HMM_PER_TWIPS, like the DrawingLayer
6005                 Rectangle aMMRect(pDocSh->GetDocument()->GetMMRect(
6006                                         aRange.aStart.Col(), aRange.aStart.Row(),
6007                                         aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
6008                 awt::Point aPos( aMMRect.Left(), aMMRect.Top() );
6009                 rAny <<= aPos;
6010             }
6011         }
6012         else if ( pEntry->nWID == SC_WID_UNO_SIZE )
6013         {
6014             ScDocShell* pDocSh = GetDocShell();
6015             if (pDocSh)
6016             {
6017                 //  GetMMRect converts using HMM_PER_TWIPS, like the DrawingLayer
6018                 Rectangle aMMRect = pDocSh->GetDocument()->GetMMRect(
6019                                         aRange.aStart.Col(), aRange.aStart.Row(),
6020                                         aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() );
6021                 Size aSize(aMMRect.GetSize());
6022                 awt::Size aAwtSize( aSize.Width(), aSize.Height() );
6023                 rAny <<= aAwtSize;
6024             }
6025         }
6026         else
6027             ScCellRangesBase::GetOnePropertyValue( pEntry, rAny );
6028 
6029     }
6030 }
6031 
6032 const SfxItemPropertyMap* ScCellRangeObj::GetItemPropertyMap()
6033 {
6034     return pRangePropSet->getPropertyMap();
6035 }
6036 
6037 // XServiceInfo
6038 
6039 rtl::OUString SAL_CALL ScCellRangeObj::getImplementationName() throw(uno::RuntimeException)
6040 {
6041     return rtl::OUString::createFromAscii( "ScCellRangeObj" );
6042 }
6043 
6044 sal_Bool SAL_CALL ScCellRangeObj::supportsService( const rtl::OUString& rServiceName )
6045                                                     throw(uno::RuntimeException)
6046 {
6047     String aServiceStr( rServiceName );
6048     return aServiceStr.EqualsAscii( SCSHEETCELLRANGE_SERVICE ) ||
6049            aServiceStr.EqualsAscii( SCCELLRANGE_SERVICE ) ||
6050            aServiceStr.EqualsAscii( SCCELLPROPERTIES_SERVICE ) ||
6051            aServiceStr.EqualsAscii( SCCHARPROPERTIES_SERVICE ) ||
6052            aServiceStr.EqualsAscii( SCPARAPROPERTIES_SERVICE );
6053 }
6054 
6055 uno::Sequence<rtl::OUString> SAL_CALL ScCellRangeObj::getSupportedServiceNames()
6056                                                     throw(uno::RuntimeException)
6057 {
6058     uno::Sequence<rtl::OUString> aRet(5);
6059     rtl::OUString* pArray = aRet.getArray();
6060     pArray[0] = rtl::OUString::createFromAscii( SCSHEETCELLRANGE_SERVICE );
6061     pArray[1] = rtl::OUString::createFromAscii( SCCELLRANGE_SERVICE );
6062     pArray[2] = rtl::OUString::createFromAscii( SCCELLPROPERTIES_SERVICE );
6063     pArray[3] = rtl::OUString::createFromAscii( SCCHARPROPERTIES_SERVICE );
6064     pArray[4] = rtl::OUString::createFromAscii( SCPARAPROPERTIES_SERVICE );
6065     return aRet;
6066 }
6067 
6068 //------------------------------------------------------------------------
6069 
6070 const SvxItemPropertySet* ScCellObj::GetEditPropertySet()      // static
6071 {
6072     return lcl_GetEditPropertySet();
6073 }
6074 const SfxItemPropertyMap* ScCellObj::GetCellPropertyMap()
6075 {
6076     return lcl_GetCellPropertySet()->getPropertyMap();
6077 }
6078 
6079 ScCellObj::ScCellObj(ScDocShell* pDocSh, const ScAddress& rP) :
6080     ScCellRangeObj( pDocSh, ScRange(rP,rP) ),
6081     pUnoText( NULL ),
6082     pCellPropSet( lcl_GetCellPropertySet() ),
6083     aCellPos( rP ),
6084     nActionLockCount( 0 )
6085 {
6086     //  pUnoText is allocated on demand (GetUnoText)
6087     //  can't be aggregated because getString/setString is handled here
6088 }
6089 
6090 SvxUnoText& ScCellObj::GetUnoText()
6091 {
6092     if (!pUnoText)
6093     {
6094         pUnoText = new ScCellTextObj( GetDocShell(), aCellPos );
6095         pUnoText->acquire();
6096         if (nActionLockCount)
6097         {
6098             ScSharedCellEditSource* pEditSource =
6099                 static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
6100             if (pEditSource)
6101                 pEditSource->SetDoUpdateData(sal_False);
6102         }
6103     }
6104     return *pUnoText;
6105 }
6106 
6107 ScCellObj::~ScCellObj()
6108 {
6109     if (pUnoText)
6110         pUnoText->release();
6111 }
6112 
6113 void ScCellObj::RefChanged()
6114 {
6115     ScCellRangeObj::RefChanged();
6116 
6117     const ScRangeList& rRanges = GetRangeList();
6118     DBG_ASSERT(rRanges.Count() == 1, "was fuer Ranges ?!?!");
6119     const ScRange* pFirst = rRanges.GetObject(0);
6120     if (pFirst)
6121         aCellPos = pFirst->aStart;
6122 }
6123 
6124 uno::Any SAL_CALL ScCellObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
6125 {
6126     SC_QUERYINTERFACE( table::XCell )
6127     SC_QUERYINTERFACE( sheet::XFormulaTokens )
6128     SC_QUERYINTERFACE( sheet::XCellAddressable )
6129     SC_QUERYINTERFACE( text::XText )
6130     SC_QUERYINTERFACE( text::XSimpleText )
6131     SC_QUERYINTERFACE( text::XTextRange )
6132     SC_QUERYINTERFACE( container::XEnumerationAccess )
6133     SC_QUERYINTERFACE( container::XElementAccess )
6134     SC_QUERYINTERFACE( sheet::XSheetAnnotationAnchor )
6135     SC_QUERYINTERFACE( text::XTextFieldsSupplier )
6136     SC_QUERYINTERFACE( document::XActionLockable )
6137 
6138     return ScCellRangeObj::queryInterface( rType );
6139 }
6140 
6141 void SAL_CALL ScCellObj::acquire() throw()
6142 {
6143     ScCellRangeObj::acquire();
6144 }
6145 
6146 void SAL_CALL ScCellObj::release() throw()
6147 {
6148     ScCellRangeObj::release();
6149 }
6150 
6151 uno::Sequence<uno::Type> SAL_CALL ScCellObj::getTypes() throw(uno::RuntimeException)
6152 {
6153     static uno::Sequence<uno::Type> aTypes;
6154     if ( aTypes.getLength() == 0 )
6155     {
6156         uno::Sequence<uno::Type> aParentTypes(ScCellRangeObj::getTypes());
6157         long nParentLen = aParentTypes.getLength();
6158         const uno::Type* pParentPtr = aParentTypes.getConstArray();
6159 
6160         aTypes.realloc( nParentLen + 8 );
6161         uno::Type* pPtr = aTypes.getArray();
6162         pPtr[nParentLen + 0] = getCppuType((const uno::Reference<table::XCell>*)0);
6163         pPtr[nParentLen + 1] = getCppuType((const uno::Reference<sheet::XCellAddressable>*)0);
6164         pPtr[nParentLen + 2] = getCppuType((const uno::Reference<text::XText>*)0);
6165         pPtr[nParentLen + 3] = getCppuType((const uno::Reference<container::XEnumerationAccess>*)0);
6166         pPtr[nParentLen + 4] = getCppuType((const uno::Reference<sheet::XSheetAnnotationAnchor>*)0);
6167         pPtr[nParentLen + 5] = getCppuType((const uno::Reference<text::XTextFieldsSupplier>*)0);
6168         pPtr[nParentLen + 6] = getCppuType((const uno::Reference<document::XActionLockable>*)0);
6169         pPtr[nParentLen + 7] = getCppuType((const uno::Reference<sheet::XFormulaTokens>*)0);
6170 
6171         for (long i=0; i<nParentLen; i++)
6172             pPtr[i] = pParentPtr[i];                // parent types first
6173     }
6174     return aTypes;
6175 }
6176 
6177 uno::Sequence<sal_Int8> SAL_CALL ScCellObj::getImplementationId() throw(uno::RuntimeException)
6178 {
6179     static uno::Sequence< sal_Int8 > aId;
6180     if( aId.getLength() == 0 )
6181     {
6182         aId.realloc( 16 );
6183         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
6184     }
6185     return aId;
6186 }
6187 
6188 //  Hilfsfunktionen
6189 
6190 String ScCellObj::GetInputString_Impl(sal_Bool bEnglish) const      // fuer getFormula / FormulaLocal
6191 {
6192     if (GetDocShell())
6193         return lcl_GetInputString( GetDocShell()->GetDocument(), aCellPos, bEnglish );
6194     return String();
6195 }
6196 
6197 String ScCellObj::GetOutputString_Impl(ScDocument* pDoc, const ScAddress& aCellPos)
6198 {
6199     String aVal;
6200     if ( pDoc )
6201     {
6202         ScBaseCell* pCell = pDoc->GetCell( aCellPos );
6203         if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
6204         {
6205             if ( pCell->GetCellType() == CELLTYPE_EDIT )
6206             {
6207                 //  GetString an der EditCell macht Leerzeichen aus Umbruechen,
6208                 //  hier werden die Umbrueche aber gebraucht
6209                 const EditTextObject* pData = ((ScEditCell*)pCell)->GetData();
6210                 if (pData)
6211                 {
6212                     EditEngine& rEngine = pDoc->GetEditEngine();
6213                     rEngine.SetText( *pData );
6214                     aVal = rEngine.GetText( LINEEND_LF );
6215                 }
6216                 //  Edit-Zellen auch nicht per NumberFormatter formatieren
6217                 //  (passend zur Ausgabe)
6218             }
6219             else
6220             {
6221                 //  wie in GetString am Dokument (column)
6222                 Color* pColor;
6223                 sal_uLong nNumFmt = pDoc->GetNumberFormat( aCellPos );
6224                 ScCellFormat::GetString( pCell, nNumFmt, aVal, &pColor, *pDoc->GetFormatTable() );
6225             }
6226         }
6227     }
6228     return aVal;
6229 }
6230 
6231 String ScCellObj::GetOutputString_Impl() const
6232 {
6233     ScDocShell* pDocSh = GetDocShell();
6234     String aVal;
6235     if ( pDocSh )
6236         aVal = GetOutputString_Impl(pDocSh->GetDocument(), aCellPos);
6237     return aVal;
6238 }
6239 
6240 void ScCellObj::SetString_Impl(const String& rString, sal_Bool bInterpret, sal_Bool bEnglish)
6241 {
6242     ScDocShell* pDocSh = GetDocShell();
6243     if ( pDocSh )
6244     {
6245         ScDocFunc aFunc(*pDocSh);
6246         // GRAM_PODF_A1 for API compatibility.
6247         (void)aFunc.SetCellText( aCellPos, rString, bInterpret, bEnglish, sal_True, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
6248     }
6249 }
6250 
6251 double ScCellObj::GetValue_Impl() const
6252 {
6253     ScDocShell* pDocSh = GetDocShell();
6254     if ( pDocSh )
6255         return pDocSh->GetDocument()->GetValue( aCellPos );
6256 
6257     return 0.0;
6258 }
6259 
6260 void ScCellObj::SetValue_Impl(double fValue)
6261 {
6262     ScDocShell* pDocSh = GetDocShell();
6263     if ( pDocSh )
6264     {
6265         ScDocFunc aFunc(*pDocSh);
6266         (void)aFunc.PutCell( aCellPos, new ScValueCell(fValue), sal_True );
6267     }
6268 }
6269 
6270 // only for XML import
6271 
6272 void ScCellObj::SetFormulaResultString( const ::rtl::OUString& rResult )
6273 {
6274     ScDocShell* pDocSh = GetDocShell();
6275     if ( pDocSh )
6276     {
6277         ScBaseCell* pCell = pDocSh->GetDocument()->GetCell( aCellPos );
6278         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
6279             ((ScFormulaCell*)pCell)->SetHybridString( rResult );
6280     }
6281 }
6282 
6283 void ScCellObj::SetFormulaResultDouble( double fResult )
6284 {
6285     ScDocShell* pDocSh = GetDocShell();
6286     if ( pDocSh )
6287     {
6288         ScBaseCell* pCell = pDocSh->GetDocument()->GetCell( aCellPos );
6289         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
6290             ((ScFormulaCell*)pCell)->SetHybridDouble( fResult );
6291     }
6292 }
6293 
6294 void ScCellObj::SetFormulaWithGrammar( const ::rtl::OUString& rFormula,
6295         const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
6296 {
6297     ScDocShell* pDocSh = GetDocShell();
6298     if ( pDocSh )
6299     {
6300         ScDocFunc aFunc(*pDocSh);
6301         aFunc.SetCellText( aCellPos, rFormula, sal_True, sal_True, sal_True, rFormulaNmsp, eGrammar);
6302     }
6303 }
6304 
6305 void ScCellObj::InputEnglishString( const ::rtl::OUString& rText )
6306 {
6307     // This is like a mixture of setFormula and property FormulaLocal:
6308     // The cell's number format is checked for "text", a new cell format may be set,
6309     // but all parsing is in English.
6310 
6311     ScDocShell* pDocSh = GetDocShell();
6312     if ( pDocSh )
6313     {
6314         String aString(rText);
6315         ScDocument* pDoc = pDocSh->GetDocument();
6316         SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
6317         sal_uInt32 nOldFormat = pDoc->GetNumberFormat( aCellPos );
6318         if ( pFormatter->GetType( nOldFormat ) == NUMBERFORMAT_TEXT )
6319         {
6320             SetString_Impl(aString, sal_False, sal_False);      // text cell
6321         }
6322         else
6323         {
6324             ScDocFunc aFunc(*pDocSh);
6325             short nFormatType = 0;
6326             ScBaseCell* pNewCell = aFunc.InterpretEnglishString( aCellPos, aString,
6327                                     EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1, &nFormatType );
6328             if (pNewCell)
6329             {
6330                 if ( ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 && nFormatType != 0 )
6331                 {
6332                     // apply a format for the recognized type and the old format's language
6333                     sal_uInt32 nNewFormat = ScGlobal::GetStandardFormat( *pFormatter, nOldFormat, nFormatType );
6334                     if ( nNewFormat != nOldFormat )
6335                     {
6336                         ScPatternAttr aPattern( pDoc->GetPool() );
6337                         aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
6338                         // ATTR_LANGUAGE_FORMAT remains unchanged
6339                         aFunc.ApplyAttributes( *GetMarkData(), aPattern, sal_True, sal_True );
6340                     }
6341                 }
6342                 // put the cell into the document
6343                 // (after applying the format, so possible formula recalculation already uses the new format)
6344                 (void)aFunc.PutCell( aCellPos, pNewCell, sal_True );
6345             }
6346             else
6347                 SetString_Impl(aString, sal_False, sal_False);      // no cell from InterpretEnglishString, probably empty string
6348         }
6349     }
6350 }
6351 
6352 //  XText
6353 
6354 uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursor()
6355                                                     throw(uno::RuntimeException)
6356 {
6357     ScUnoGuard aGuard;
6358     return new ScCellTextCursor( *this );
6359 }
6360 
6361 uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursorByRange(
6362                                     const uno::Reference<text::XTextRange>& aTextPosition )
6363                                                     throw(uno::RuntimeException)
6364 {
6365     ScUnoGuard aGuard;
6366     SvxUnoTextCursor* pCursor = new ScCellTextCursor( *this );
6367     uno::Reference<text::XTextCursor> xCursor(pCursor);
6368 
6369     SvxUnoTextRangeBase* pRange = SvxUnoTextRangeBase::getImplementation( aTextPosition );
6370     if(pRange)
6371         pCursor->SetSelection( pRange->GetSelection() );
6372     else
6373     {
6374         ScCellTextCursor* pOther = ScCellTextCursor::getImplementation( aTextPosition );
6375         if(pOther)
6376             pCursor->SetSelection( pOther->GetSelection() );
6377         else
6378             throw uno::RuntimeException();
6379     }
6380 
6381     return xCursor;
6382 }
6383 
6384 rtl::OUString SAL_CALL ScCellObj::getString() throw(uno::RuntimeException)
6385 {
6386     ScUnoGuard aGuard;
6387     return GetOutputString_Impl();
6388 }
6389 
6390 void SAL_CALL ScCellObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
6391 {
6392     ScUnoGuard aGuard;
6393     String aString(aText);
6394     SetString_Impl(aString, sal_False, sal_False);  // immer Text
6395 
6396     // don't create pUnoText here if not there
6397     if (pUnoText)
6398         pUnoText->SetSelection(ESelection( 0,0, 0,aString.Len() ));
6399 }
6400 
6401 void SAL_CALL ScCellObj::insertString( const uno::Reference<text::XTextRange>& xRange,
6402                                         const rtl::OUString& aString, sal_Bool bAbsorb )
6403                                     throw(uno::RuntimeException)
6404 {
6405     // special handling for ScCellTextCursor is no longer needed,
6406     // SvxUnoText::insertString checks for SvxUnoTextRangeBase instead of SvxUnoTextRange
6407 
6408     ScUnoGuard aGuard;
6409     GetUnoText().insertString(xRange, aString, bAbsorb);
6410 }
6411 
6412 void SAL_CALL ScCellObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
6413                                                 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
6414                                     throw(lang::IllegalArgumentException, uno::RuntimeException)
6415 {
6416     ScUnoGuard aGuard;
6417     GetUnoText().insertControlCharacter(xRange, nControlCharacter, bAbsorb);
6418 }
6419 
6420 void SAL_CALL ScCellObj::insertTextContent( const uno::Reference<text::XTextRange >& xRange,
6421                                                 const uno::Reference<text::XTextContent >& xContent,
6422                                                 sal_Bool bAbsorb )
6423                                     throw(lang::IllegalArgumentException, uno::RuntimeException)
6424 {
6425     ScUnoGuard aGuard;
6426     ScDocShell* pDocSh = GetDocShell();
6427     if ( pDocSh && xContent.is() )
6428     {
6429         ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent );
6430         SvxUnoTextRangeBase* pTextRange = ScCellTextCursor::getImplementation( xRange );
6431 
6432 #if 0
6433         if (!pTextRange)
6434             pTextRange = SvxUnoTextRangeBase::getImplementation( xRange );
6435 
6436         //! bei SvxUnoTextRange testen, ob in passendem Objekt !!!
6437 #endif
6438 
6439         if ( pCellField && !pCellField->IsInserted() && pTextRange )
6440         {
6441             SvxEditSource* pEditSource = pTextRange->GetEditSource();
6442             ESelection aSelection(pTextRange->GetSelection());
6443 
6444             if (!bAbsorb)
6445             {
6446                 //  nicht ersetzen -> hinten anhaengen
6447                 aSelection.Adjust();
6448                 aSelection.nStartPara = aSelection.nEndPara;
6449                 aSelection.nStartPos  = aSelection.nEndPos;
6450             }
6451 
6452             SvxFieldItem aItem(pCellField->CreateFieldItem());
6453 
6454             SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
6455             pForwarder->QuickInsertField( aItem, aSelection );
6456             pEditSource->UpdateData();
6457 
6458             //  neue Selektion: ein Zeichen
6459             aSelection.Adjust();
6460             aSelection.nEndPara = aSelection.nStartPara;
6461             aSelection.nEndPos = aSelection.nStartPos + 1;
6462             pCellField->InitDoc( pDocSh, aCellPos, aSelection );
6463 
6464             //  #91431# for bAbsorb=sal_False, the new selection must be behind the inserted content
6465             //  (the xml filter relies on this)
6466             if (!bAbsorb)
6467                 aSelection.nStartPos = aSelection.nEndPos;
6468 
6469             pTextRange->SetSelection( aSelection );
6470 
6471             return;
6472         }
6473     }
6474     GetUnoText().insertTextContent(xRange, xContent, bAbsorb);
6475 }
6476 
6477 void SAL_CALL ScCellObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
6478                                 throw(container::NoSuchElementException, uno::RuntimeException)
6479 {
6480     ScUnoGuard aGuard;
6481     if ( xContent.is() )
6482     {
6483         ScCellFieldObj* pCellField = ScCellFieldObj::getImplementation( xContent );
6484         if ( pCellField && pCellField->IsInserted() )
6485         {
6486             //! Testen, ob das Feld in dieser Zelle ist
6487             pCellField->DeleteField();
6488             return;
6489         }
6490     }
6491     GetUnoText().removeTextContent(xContent);
6492 }
6493 
6494 uno::Reference<text::XText> SAL_CALL ScCellObj::getText() throw(uno::RuntimeException)
6495 {
6496     ScUnoGuard aGuard;
6497     return this;
6498 }
6499 
6500 uno::Reference<text::XTextRange> SAL_CALL ScCellObj::getStart() throw(uno::RuntimeException)
6501 {
6502     ScUnoGuard aGuard;
6503     return GetUnoText().getStart();
6504 }
6505 
6506 uno::Reference<text::XTextRange> SAL_CALL ScCellObj::getEnd() throw(uno::RuntimeException)
6507 {
6508     ScUnoGuard aGuard;
6509     return GetUnoText().getEnd();
6510 }
6511 
6512 uno::Reference<container::XEnumeration> SAL_CALL ScCellObj::createEnumeration()
6513                                                     throw(uno::RuntimeException)
6514 {
6515     ScUnoGuard aGuard;
6516     return GetUnoText().createEnumeration();
6517 }
6518 
6519 uno::Type SAL_CALL ScCellObj::getElementType() throw(uno::RuntimeException)
6520 {
6521     ScUnoGuard aGuard;
6522     return GetUnoText().getElementType();
6523 }
6524 
6525 sal_Bool SAL_CALL ScCellObj::hasElements() throw(uno::RuntimeException)
6526 {
6527     ScUnoGuard aGuard;
6528     return GetUnoText().hasElements();
6529 }
6530 
6531 //  XCell
6532 
6533 rtl::OUString SAL_CALL ScCellObj::getFormula() throw(uno::RuntimeException)
6534 {
6535     ScUnoGuard aGuard;
6536     //  sal_True = englisch
6537     return GetInputString_Impl(sal_True);
6538 }
6539 
6540 void SAL_CALL ScCellObj::setFormula( const rtl::OUString& aFormula ) throw(uno::RuntimeException)
6541 {
6542     ScUnoGuard aGuard;
6543     String aString(aFormula);
6544     SetString_Impl(aString, sal_True, sal_True);    // englisch interpretieren
6545 }
6546 
6547 double SAL_CALL ScCellObj::getValue() throw(uno::RuntimeException)
6548 {
6549     ScUnoGuard aGuard;
6550     return GetValue_Impl();
6551 }
6552 
6553 void SAL_CALL ScCellObj::setValue( double nValue ) throw(uno::RuntimeException)
6554 {
6555     ScUnoGuard aGuard;
6556     SetValue_Impl(nValue);
6557 }
6558 
6559 table::CellContentType SAL_CALL ScCellObj::getType() throw(uno::RuntimeException)
6560 {
6561     ScUnoGuard aGuard;
6562     table::CellContentType eRet = table::CellContentType_EMPTY;
6563     ScDocShell* pDocSh = GetDocShell();
6564     if (pDocSh)
6565     {
6566         CellType eCalcType = pDocSh->GetDocument()->GetCellType( aCellPos );
6567         switch (eCalcType)
6568         {
6569             case CELLTYPE_VALUE:
6570                 eRet = table::CellContentType_VALUE;
6571                 break;
6572             case CELLTYPE_STRING:
6573             case CELLTYPE_EDIT:
6574                 eRet = table::CellContentType_TEXT;
6575                 break;
6576             case CELLTYPE_FORMULA:
6577                 eRet = table::CellContentType_FORMULA;
6578                 break;
6579             default:
6580                 eRet = table::CellContentType_EMPTY;
6581         }
6582     }
6583     else
6584     {
6585         DBG_ERROR("keine DocShell");        //! Exception oder so?
6586     }
6587 
6588     return eRet;
6589 }
6590 
6591 table::CellContentType ScCellObj::GetResultType_Impl()
6592 {
6593     ScDocShell* pDocSh = GetDocShell();
6594     if ( pDocSh )
6595     {
6596         ScBaseCell* pCell = pDocSh->GetDocument()->GetCell(aCellPos);
6597         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
6598         {
6599             sal_Bool bValue = ((ScFormulaCell*)pCell)->IsValue();
6600             return bValue ? table::CellContentType_VALUE : table::CellContentType_TEXT;
6601         }
6602     }
6603     return getType();   // wenn keine Formel
6604 }
6605 
6606 sal_Int32 SAL_CALL ScCellObj::getError() throw(uno::RuntimeException)
6607 {
6608     ScUnoGuard aGuard;
6609     sal_uInt16 nError = 0;
6610     ScDocShell* pDocSh = GetDocShell();
6611     if (pDocSh)
6612     {
6613         ScBaseCell* pCell = pDocSh->GetDocument()->GetCell( aCellPos );
6614         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
6615             nError = ((ScFormulaCell*)pCell)->GetErrCode();
6616         // sonst bleibt's bei 0
6617     }
6618     else
6619     {
6620         DBG_ERROR("keine DocShell");        //! Exception oder so?
6621     }
6622 
6623     return nError;
6624 }
6625 
6626 // XFormulaTokens
6627 
6628 uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellObj::getTokens() throw(uno::RuntimeException)
6629 {
6630     ScUnoGuard aGuard;
6631     uno::Sequence<sheet::FormulaToken> aSequence;
6632     ScDocShell* pDocSh = GetDocShell();
6633     if ( pDocSh )
6634     {
6635         ScDocument* pDoc = pDocSh->GetDocument();
6636         ScBaseCell* pCell = pDoc->GetCell( aCellPos );
6637         if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
6638         {
6639             ScTokenArray* pTokenArray = static_cast<ScFormulaCell*>(pCell)->GetCode();
6640             if ( pTokenArray )
6641                 (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aSequence, *pTokenArray );
6642         }
6643     }
6644     return aSequence;
6645 }
6646 
6647 void SAL_CALL ScCellObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException)
6648 {
6649     ScUnoGuard aGuard;
6650     ScDocShell* pDocSh = GetDocShell();
6651     if ( pDocSh )
6652     {
6653         ScDocument* pDoc = pDocSh->GetDocument();
6654         ScTokenArray aTokenArray;
6655         (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, rTokens );
6656 
6657         ScDocFunc aFunc( *pDocSh );
6658         ScBaseCell* pNewCell = new ScFormulaCell( pDoc, aCellPos, &aTokenArray );
6659         (void)aFunc.PutCell( aCellPos, pNewCell, sal_True );
6660     }
6661 }
6662 
6663 // XCellAddressable
6664 
6665 table::CellAddress SAL_CALL ScCellObj::getCellAddress() throw(uno::RuntimeException)
6666 {
6667     ScUnoGuard aGuard;
6668     table::CellAddress aAdr;
6669     aAdr.Sheet  = aCellPos.Tab();
6670     aAdr.Column = aCellPos.Col();
6671     aAdr.Row    = aCellPos.Row();
6672     return aAdr;
6673 }
6674 
6675 // XSheetAnnotationAnchor
6676 
6677 uno::Reference<sheet::XSheetAnnotation> SAL_CALL ScCellObj::getAnnotation()
6678                                                 throw(uno::RuntimeException)
6679 {
6680     ScUnoGuard aGuard;
6681     ScDocShell* pDocSh = GetDocShell();
6682     if ( pDocSh )
6683         return new ScAnnotationObj( pDocSh, aCellPos );
6684 
6685     DBG_ERROR("getAnnotation ohne DocShell");
6686     return NULL;
6687 }
6688 
6689 // XFieldTypesSupplier
6690 
6691 uno::Reference<container::XEnumerationAccess> SAL_CALL ScCellObj::getTextFields()
6692                                                 throw(uno::RuntimeException)
6693 {
6694     ScUnoGuard aGuard;
6695     ScDocShell* pDocSh = GetDocShell();
6696     if ( pDocSh )
6697         return new ScCellFieldsObj( pDocSh, aCellPos );
6698 
6699     return NULL;
6700 }
6701 
6702 uno::Reference<container::XNameAccess> SAL_CALL ScCellObj::getTextFieldMasters()
6703                                                 throw(uno::RuntimeException)
6704 {
6705     //  sowas gibts nicht im Calc (?)
6706     return NULL;
6707 }
6708 
6709 // XPropertySet erweitert fuer Zell-Properties
6710 
6711 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellObj::getPropertySetInfo()
6712                                                         throw(uno::RuntimeException)
6713 {
6714     ScUnoGuard aGuard;
6715     static uno::Reference<beans::XPropertySetInfo> aRef(
6716         new SfxItemPropertySetInfo( pCellPropSet->getPropertyMap() ));
6717     return aRef;
6718 }
6719 
6720 void ScCellObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
6721                                 throw(lang::IllegalArgumentException, uno::RuntimeException)
6722 {
6723     if ( pEntry )
6724     {
6725         if ( pEntry->nWID == SC_WID_UNO_FORMLOC )
6726         {
6727             rtl::OUString aStrVal;
6728             aValue >>= aStrVal;
6729             String aString(aStrVal);
6730             SetString_Impl(aString, sal_True, sal_False);   // lokal interpretieren
6731         }
6732         else if ( pEntry->nWID == SC_WID_UNO_FORMRT )
6733         {
6734             //  Read-Only
6735             //! Exception oder so...
6736         }
6737         else
6738             ScCellRangeObj::SetOnePropertyValue( pEntry, aValue );
6739     }
6740 }
6741 
6742 void ScCellObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
6743                                         uno::Any& rAny )
6744                                             throw(uno::RuntimeException)
6745 {
6746     if ( pEntry )
6747     {
6748         if ( pEntry->nWID == SC_WID_UNO_FORMLOC )
6749         {
6750             // sal_False = lokal
6751             rAny <<= rtl::OUString( GetInputString_Impl(sal_False) );
6752         }
6753         else if ( pEntry->nWID == SC_WID_UNO_FORMRT )
6754         {
6755             table::CellContentType eType = GetResultType_Impl();
6756             rAny <<= eType;
6757         }
6758         else
6759             ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
6760     }
6761 }
6762 
6763 const SfxItemPropertyMap* ScCellObj::GetItemPropertyMap()
6764 {
6765     return pCellPropSet->getPropertyMap();
6766 }
6767 
6768 // XServiceInfo
6769 
6770 rtl::OUString SAL_CALL ScCellObj::getImplementationName() throw(uno::RuntimeException)
6771 {
6772     return rtl::OUString::createFromAscii( "ScCellObj" );
6773 }
6774 
6775 sal_Bool SAL_CALL ScCellObj::supportsService( const rtl::OUString& rServiceName )
6776                                                     throw(uno::RuntimeException)
6777 {
6778     //  CellRange/SheetCellRange are not in SheetCell service description,
6779     //  but ScCellObj is used instead of ScCellRangeObj in CellRanges collections,
6780     //  so it must support them
6781 
6782     String aServiceStr(rServiceName);
6783     return aServiceStr.EqualsAscii( SCSHEETCELL_SERVICE ) ||
6784            aServiceStr.EqualsAscii( SCCELL_SERVICE ) ||
6785            aServiceStr.EqualsAscii( SCCELLPROPERTIES_SERVICE ) ||
6786            aServiceStr.EqualsAscii( SCCHARPROPERTIES_SERVICE ) ||
6787            aServiceStr.EqualsAscii( SCPARAPROPERTIES_SERVICE ) ||
6788            aServiceStr.EqualsAscii( SCSHEETCELLRANGE_SERVICE ) ||
6789            aServiceStr.EqualsAscii( SCCELLRANGE_SERVICE );
6790 }
6791 
6792 uno::Sequence<rtl::OUString> SAL_CALL ScCellObj::getSupportedServiceNames()
6793                                                     throw(uno::RuntimeException)
6794 {
6795     uno::Sequence<rtl::OUString> aRet(7);
6796     rtl::OUString* pArray = aRet.getArray();
6797     pArray[0] = rtl::OUString::createFromAscii( SCSHEETCELL_SERVICE );
6798     pArray[1] = rtl::OUString::createFromAscii( SCCELL_SERVICE );
6799     pArray[2] = rtl::OUString::createFromAscii( SCCELLPROPERTIES_SERVICE );
6800     pArray[3] = rtl::OUString::createFromAscii( SCCHARPROPERTIES_SERVICE );
6801     pArray[4] = rtl::OUString::createFromAscii( SCPARAPROPERTIES_SERVICE );
6802     pArray[5] = rtl::OUString::createFromAscii( SCSHEETCELLRANGE_SERVICE );
6803     pArray[6] = rtl::OUString::createFromAscii( SCCELLRANGE_SERVICE );
6804     return aRet;
6805 }
6806 
6807 // XActionLockable
6808 
6809 sal_Bool SAL_CALL ScCellObj::isActionLocked() throw(uno::RuntimeException)
6810 {
6811     ScUnoGuard aGuard;
6812     return nActionLockCount != 0;
6813 }
6814 
6815 void SAL_CALL ScCellObj::addActionLock() throw(uno::RuntimeException)
6816 {
6817     ScUnoGuard aGuard;
6818     if (!nActionLockCount)
6819     {
6820         if (pUnoText)
6821         {
6822             ScSharedCellEditSource* pEditSource =
6823                 static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
6824             if (pEditSource)
6825                 pEditSource->SetDoUpdateData(sal_False);
6826         }
6827     }
6828     nActionLockCount++;
6829 }
6830 
6831 void SAL_CALL ScCellObj::removeActionLock() throw(uno::RuntimeException)
6832 {
6833     ScUnoGuard aGuard;
6834     if (nActionLockCount > 0)
6835     {
6836         nActionLockCount--;
6837         if (!nActionLockCount)
6838         {
6839             if (pUnoText)
6840             {
6841                 ScSharedCellEditSource* pEditSource =
6842                     static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
6843                 if (pEditSource)
6844                 {
6845                     pEditSource->SetDoUpdateData(sal_True);
6846                     if (pEditSource->IsDirty())
6847                         pEditSource->UpdateData();
6848                 }
6849             }
6850         }
6851     }
6852 }
6853 
6854 void SAL_CALL ScCellObj::setActionLocks( sal_Int16 nLock ) throw(uno::RuntimeException)
6855 {
6856     ScUnoGuard aGuard;
6857     if (pUnoText)
6858     {
6859         ScSharedCellEditSource* pEditSource =
6860             static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
6861         if (pEditSource)
6862         {
6863             pEditSource->SetDoUpdateData(nLock == 0);
6864             if ((nActionLockCount > 0) && (nLock == 0) && pEditSource->IsDirty())
6865                 pEditSource->UpdateData();
6866         }
6867     }
6868     nActionLockCount = nLock;
6869 }
6870 
6871 sal_Int16 SAL_CALL ScCellObj::resetActionLocks() throw(uno::RuntimeException)
6872 {
6873     ScUnoGuard aGuard;
6874     sal_uInt16 nRet(nActionLockCount);
6875     if (pUnoText)
6876     {
6877         ScSharedCellEditSource* pEditSource =
6878             static_cast<ScSharedCellEditSource*> (pUnoText->GetEditSource());
6879         if (pEditSource)
6880         {
6881             pEditSource->SetDoUpdateData(sal_True);
6882             if (pEditSource->IsDirty())
6883                 pEditSource->UpdateData();
6884         }
6885     }
6886     nActionLockCount = 0;
6887     return nRet;
6888 }
6889 
6890 //------------------------------------------------------------------------
6891 
6892 ScTableSheetObj::ScTableSheetObj( ScDocShell* pDocSh, SCTAB nTab ) :
6893     ScCellRangeObj( pDocSh, ScRange(0,0,nTab, MAXCOL,MAXROW,nTab) ),
6894     pSheetPropSet(lcl_GetSheetPropertySet())
6895 {
6896 }
6897 
6898 ScTableSheetObj::~ScTableSheetObj()
6899 {
6900 }
6901 
6902 void ScTableSheetObj::InitInsertSheet(ScDocShell* pDocSh, SCTAB nTab)
6903 {
6904     InitInsertRange( pDocSh, ScRange(0,0,nTab, MAXCOL,MAXROW,nTab) );
6905 }
6906 
6907 uno::Any SAL_CALL ScTableSheetObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
6908 {
6909     SC_QUERYINTERFACE( sheet::XSpreadsheet )
6910     SC_QUERYINTERFACE( container::XNamed )
6911     SC_QUERYINTERFACE( sheet::XSheetPageBreak )
6912     SC_QUERYINTERFACE( sheet::XCellRangeMovement )
6913     SC_QUERYINTERFACE( table::XTableChartsSupplier )
6914     SC_QUERYINTERFACE( sheet::XDataPilotTablesSupplier )
6915     SC_QUERYINTERFACE( sheet::XScenariosSupplier )
6916     SC_QUERYINTERFACE( sheet::XSheetAnnotationsSupplier )
6917     SC_QUERYINTERFACE( drawing::XDrawPageSupplier )
6918     SC_QUERYINTERFACE( sheet::XPrintAreas )
6919     SC_QUERYINTERFACE( sheet::XSheetAuditing )
6920     SC_QUERYINTERFACE( sheet::XSheetOutline )
6921     SC_QUERYINTERFACE( util::XProtectable )
6922     SC_QUERYINTERFACE( sheet::XScenario )
6923     SC_QUERYINTERFACE( sheet::XScenarioEnhanced )
6924     SC_QUERYINTERFACE( sheet::XSheetLinkable )
6925     SC_QUERYINTERFACE( sheet::XExternalSheetName )
6926     SC_QUERYINTERFACE( document::XEventsSupplier )
6927 
6928     return ScCellRangeObj::queryInterface( rType );
6929 }
6930 
6931 void SAL_CALL ScTableSheetObj::acquire() throw()
6932 {
6933     ScCellRangeObj::acquire();
6934 }
6935 
6936 void SAL_CALL ScTableSheetObj::release() throw()
6937 {
6938     ScCellRangeObj::release();
6939 }
6940 
6941 uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() throw(uno::RuntimeException)
6942 {
6943     static uno::Sequence<uno::Type> aTypes;
6944     if ( aTypes.getLength() == 0 )
6945     {
6946         uno::Sequence<uno::Type> aParentTypes = ScCellRangeObj::getTypes();
6947         long nParentLen = aParentTypes.getLength();
6948         const uno::Type* pParentPtr = aParentTypes.getConstArray();
6949 
6950         aTypes.realloc( nParentLen + 18 );
6951         uno::Type* pPtr = aTypes.getArray();
6952         pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheet>*)0);
6953         pPtr[nParentLen + 1] = getCppuType((const uno::Reference<container::XNamed>*)0);
6954         pPtr[nParentLen + 2] = getCppuType((const uno::Reference<sheet::XSheetPageBreak>*)0);
6955         pPtr[nParentLen + 3] = getCppuType((const uno::Reference<sheet::XCellRangeMovement>*)0);
6956         pPtr[nParentLen + 4] = getCppuType((const uno::Reference<table::XTableChartsSupplier>*)0);
6957         pPtr[nParentLen + 5] = getCppuType((const uno::Reference<sheet::XDataPilotTablesSupplier>*)0);
6958         pPtr[nParentLen + 6] = getCppuType((const uno::Reference<sheet::XScenariosSupplier>*)0);
6959         pPtr[nParentLen + 7] = getCppuType((const uno::Reference<sheet::XSheetAnnotationsSupplier>*)0);
6960         pPtr[nParentLen + 8] = getCppuType((const uno::Reference<drawing::XDrawPageSupplier>*)0);
6961         pPtr[nParentLen + 9] = getCppuType((const uno::Reference<sheet::XPrintAreas>*)0);
6962         pPtr[nParentLen +10] = getCppuType((const uno::Reference<sheet::XSheetAuditing>*)0);
6963         pPtr[nParentLen +11] = getCppuType((const uno::Reference<sheet::XSheetOutline>*)0);
6964         pPtr[nParentLen +12] = getCppuType((const uno::Reference<util::XProtectable>*)0);
6965         pPtr[nParentLen +13] = getCppuType((const uno::Reference<sheet::XScenario>*)0);
6966         pPtr[nParentLen +14] = getCppuType((const uno::Reference<sheet::XScenarioEnhanced>*)0);
6967         pPtr[nParentLen +15] = getCppuType((const uno::Reference<sheet::XSheetLinkable>*)0);
6968         pPtr[nParentLen +16] = getCppuType((const uno::Reference<sheet::XExternalSheetName>*)0);
6969         pPtr[nParentLen +17] = getCppuType((const uno::Reference<document::XEventsSupplier>*)0);
6970 
6971         for (long i=0; i<nParentLen; i++)
6972             pPtr[i] = pParentPtr[i];                // parent types first
6973     }
6974     return aTypes;
6975 }
6976 
6977 uno::Sequence<sal_Int8> SAL_CALL ScTableSheetObj::getImplementationId() throw(uno::RuntimeException)
6978 {
6979     static uno::Sequence< sal_Int8 > aId;
6980     if( aId.getLength() == 0 )
6981     {
6982         aId.realloc( 16 );
6983         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
6984     }
6985     return aId;
6986 }
6987 
6988 //  Hilfsfunktionen
6989 
6990 SCTAB ScTableSheetObj::GetTab_Impl() const
6991 {
6992     const ScRangeList& rRanges = GetRangeList();
6993     DBG_ASSERT(rRanges.Count() == 1, "was fuer Ranges ?!?!");
6994     const ScRange* pFirst = rRanges.GetObject(0);
6995     if (pFirst)
6996         return pFirst->aStart.Tab();
6997 
6998     return 0;   // soll nicht sein
6999 }
7000 
7001 // former XSheet
7002 
7003 uno::Reference<table::XTableCharts> SAL_CALL ScTableSheetObj::getCharts() throw(uno::RuntimeException)
7004 {
7005     ScUnoGuard aGuard;
7006     ScDocShell* pDocSh = GetDocShell();
7007     if ( pDocSh )
7008         return new ScChartsObj( pDocSh, GetTab_Impl() );
7009 
7010     DBG_ERROR("kein Dokument");
7011     return NULL;
7012 }
7013 
7014 uno::Reference<sheet::XDataPilotTables> SAL_CALL ScTableSheetObj::getDataPilotTables()
7015                                                 throw(uno::RuntimeException)
7016 {
7017     ScUnoGuard aGuard;
7018     ScDocShell* pDocSh = GetDocShell();
7019     if ( pDocSh )
7020         return new ScDataPilotTablesObj( pDocSh, GetTab_Impl() );
7021 
7022     DBG_ERROR("kein Dokument");
7023     return NULL;
7024 }
7025 
7026 uno::Reference<sheet::XScenarios> SAL_CALL ScTableSheetObj::getScenarios() throw(uno::RuntimeException)
7027 {
7028     ScUnoGuard aGuard;
7029     ScDocShell* pDocSh = GetDocShell();
7030 
7031     if ( pDocSh )
7032         return new ScScenariosObj( pDocSh, GetTab_Impl() );
7033 
7034     DBG_ERROR("kein Dokument");
7035     return NULL;
7036 }
7037 
7038 uno::Reference<sheet::XSheetAnnotations> SAL_CALL ScTableSheetObj::getAnnotations()
7039                                                 throw(uno::RuntimeException)
7040 {
7041     ScUnoGuard aGuard;
7042     ScDocShell* pDocSh = GetDocShell();
7043 
7044     if ( pDocSh )
7045         return new ScAnnotationsObj( pDocSh, GetTab_Impl() );
7046 
7047     DBG_ERROR("kein Dokument");
7048     return NULL;
7049 }
7050 
7051 uno::Reference<table::XCellRange> SAL_CALL ScTableSheetObj::getCellRangeByName(
7052                         const rtl::OUString& rRange ) throw(uno::RuntimeException)
7053 {
7054     ScUnoGuard aGuard;
7055     return ScCellRangeObj::getCellRangeByName( rRange );
7056 }
7057 
7058 uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursor()
7059                                                 throw(uno::RuntimeException)
7060 {
7061     ScUnoGuard aGuard;
7062     ScDocShell* pDocSh = GetDocShell();
7063     if ( pDocSh )
7064     {
7065         //! einzelne Zelle oder ganze Tabelle???????
7066         SCTAB nTab = GetTab_Impl();
7067         return new ScCellCursorObj( pDocSh, ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) );
7068     }
7069     return NULL;
7070 }
7071 
7072 uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursorByRange(
7073                         const uno::Reference<sheet::XSheetCellRange>& xCellRange )
7074                                                 throw(uno::RuntimeException)
7075 {
7076     ScUnoGuard aGuard;
7077     ScDocShell* pDocSh = GetDocShell();
7078     if ( pDocSh && xCellRange.is() )
7079     {
7080         ScCellRangesBase* pRangesImp = ScCellRangesBase::getImplementation( xCellRange );
7081         if (pRangesImp)
7082         {
7083             const ScRangeList& rRanges = pRangesImp->GetRangeList();
7084             DBG_ASSERT( rRanges.Count() == 1, "Range? Ranges?" );
7085             return new ScCellCursorObj( pDocSh, *rRanges.GetObject(0) );
7086         }
7087     }
7088     return NULL;
7089 }
7090 
7091 // XSheetCellRange
7092 
7093 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScTableSheetObj::getSpreadsheet()
7094                                                 throw(uno::RuntimeException)
7095 {
7096     ScUnoGuard aGuard;
7097     return this;        //!???
7098 }
7099 
7100 // XCellRange
7101 
7102 uno::Reference<table::XCell> SAL_CALL ScTableSheetObj::getCellByPosition(
7103                                         sal_Int32 nColumn, sal_Int32 nRow )
7104                                 throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
7105 {
7106     ScUnoGuard aGuard;
7107     return ScCellRangeObj::GetCellByPosition_Impl(nColumn, nRow);
7108 }
7109 
7110 uno::Reference<table::XCellRange> SAL_CALL ScTableSheetObj::getCellRangeByPosition(
7111                 sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
7112                                 throw(lang::IndexOutOfBoundsException, uno::RuntimeException)
7113 {
7114     ScUnoGuard aGuard;
7115     return ScCellRangeObj::getCellRangeByPosition(nLeft,nTop,nRight,nBottom);
7116 }
7117 
7118 uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getColumnPageBreaks()
7119                                                 throw(uno::RuntimeException)
7120 {
7121     ScUnoGuard aGuard;
7122     ScDocShell* pDocSh = GetDocShell();
7123     if ( pDocSh )
7124     {
7125         ScDocument* pDoc = pDocSh->GetDocument();
7126         SCTAB nTab = GetTab_Impl();
7127 
7128         Size aSize(pDoc->GetPageSize( nTab ));
7129         if (aSize.Width() && aSize.Height())        // effektive Groesse schon gesetzt?
7130             pDoc->UpdatePageBreaks( nTab );
7131         else
7132         {
7133             //  Umbrueche updaten wie in ScDocShell::PageStyleModified:
7134             ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab );
7135             aPrintFunc.UpdatePages();
7136         }
7137 
7138         SCCOL nCount = 0;
7139         SCCOL nCol;
7140         for (nCol=0; nCol<=MAXCOL; nCol++)
7141             if (pDoc->HasColBreak(nCol, nTab))
7142                 ++nCount;
7143 
7144         sheet::TablePageBreakData aData;
7145         uno::Sequence<sheet::TablePageBreakData> aSeq(nCount);
7146         sheet::TablePageBreakData* pAry = aSeq.getArray();
7147         sal_uInt16 nPos = 0;
7148         for (nCol=0; nCol<=MAXCOL; nCol++)
7149         {
7150             ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
7151             if (nBreak)
7152             {
7153                 aData.Position    = nCol;
7154                 aData.ManualBreak = (nBreak & BREAK_MANUAL);
7155                 pAry[nPos] = aData;
7156                 ++nPos;
7157             }
7158         }
7159         return aSeq;
7160     }
7161     return uno::Sequence<sheet::TablePageBreakData>(0);
7162 }
7163 
7164 uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getRowPageBreaks()
7165                                                 throw(uno::RuntimeException)
7166 {
7167     ScUnoGuard aGuard;
7168     ScDocShell* pDocSh = GetDocShell();
7169     if ( pDocSh )
7170     {
7171         ScDocument* pDoc = pDocSh->GetDocument();
7172         SCTAB nTab = GetTab_Impl();
7173 
7174         Size aSize(pDoc->GetPageSize( nTab ));
7175         if (aSize.Width() && aSize.Height())        // effektive Groesse schon gesetzt?
7176             pDoc->UpdatePageBreaks( nTab );
7177         else
7178         {
7179             //  Umbrueche updaten wie in ScDocShell::PageStyleModified:
7180             ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab );
7181             aPrintFunc.UpdatePages();
7182         }
7183         return pDoc->GetRowBreakData(nTab);
7184     }
7185     return uno::Sequence<sheet::TablePageBreakData>(0);
7186 }
7187 
7188 void SAL_CALL ScTableSheetObj::removeAllManualPageBreaks() throw(uno::RuntimeException)
7189 {
7190     ScUnoGuard aGuard;
7191     ScDocShell* pDocSh = GetDocShell();
7192     if ( pDocSh )
7193     {
7194         //! docfunc Funktion, auch fuer ScViewFunc::RemoveManualBreaks
7195 
7196         ScDocument* pDoc = pDocSh->GetDocument();
7197         sal_Bool bUndo (pDoc->IsUndoEnabled());
7198         SCTAB nTab = GetTab_Impl();
7199 
7200         if (bUndo)
7201         {
7202             ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
7203             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
7204             pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, sal_False, pUndoDoc );
7205             pDocSh->GetUndoManager()->AddUndoAction(
7206                                     new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
7207         }
7208 
7209         pDoc->RemoveManualBreaks(nTab);
7210         pDoc->UpdatePageBreaks(nTab);
7211 
7212         //? UpdatePageBreakData( sal_True );
7213         pDocSh->SetDocumentModified();
7214         pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
7215     }
7216 }
7217 
7218 // XNamed
7219 
7220 rtl::OUString SAL_CALL ScTableSheetObj::getName() throw(uno::RuntimeException)
7221 {
7222     ScUnoGuard aGuard;
7223     String aName;
7224     ScDocShell* pDocSh = GetDocShell();
7225     if ( pDocSh )
7226         pDocSh->GetDocument()->GetName( GetTab_Impl(), aName );
7227     return aName;
7228 }
7229 
7230 void SAL_CALL ScTableSheetObj::setName( const rtl::OUString& aNewName )
7231                                                 throw(uno::RuntimeException)
7232 {
7233     ScUnoGuard aGuard;
7234     ScDocShell* pDocSh = GetDocShell();
7235     if ( pDocSh )
7236     {
7237         String aString(aNewName);
7238         ScDocFunc aFunc( *pDocSh );
7239         aFunc.RenameTable( GetTab_Impl(), aString, sal_True, sal_True );
7240     }
7241 }
7242 
7243 // XDrawPageSupplier
7244 
7245 uno::Reference<drawing::XDrawPage> SAL_CALL ScTableSheetObj::getDrawPage()
7246                                                 throw(uno::RuntimeException)
7247 {
7248     ScUnoGuard aGuard;
7249     ScDocShell* pDocSh = GetDocShell();
7250     if ( pDocSh )
7251     {
7252         ScDrawLayer* pDrawLayer = pDocSh->MakeDrawLayer();
7253         DBG_ASSERT(pDrawLayer,"kann Draw-Layer nicht anlegen");
7254 
7255         SCTAB nTab = GetTab_Impl();
7256         SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
7257         DBG_ASSERT(pPage,"Draw-Page nicht gefunden");
7258         if (pPage)
7259             return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
7260 
7261         //  Das DrawPage-Objekt meldet sich als Listener am SdrModel an
7262         //  und sollte von dort alle Aktionen mitbekommen
7263     }
7264     return NULL;
7265 }
7266 
7267 // XCellMovement
7268 
7269 void SAL_CALL ScTableSheetObj::insertCells( const table::CellRangeAddress& rRangeAddress,
7270                                 sheet::CellInsertMode nMode ) throw(uno::RuntimeException)
7271 {
7272     ScUnoGuard aGuard;
7273     ScDocShell* pDocSh = GetDocShell();
7274     if ( pDocSh )
7275     {
7276         sal_Bool bDo = sal_True;
7277         InsCellCmd eCmd = INS_NONE;
7278         switch (nMode)
7279         {
7280             case sheet::CellInsertMode_NONE:    bDo = sal_False;            break;
7281             case sheet::CellInsertMode_DOWN:    eCmd = INS_CELLSDOWN;   break;
7282             case sheet::CellInsertMode_RIGHT:   eCmd = INS_CELLSRIGHT;  break;
7283             case sheet::CellInsertMode_ROWS:    eCmd = INS_INSROWS;     break;
7284             case sheet::CellInsertMode_COLUMNS: eCmd = INS_INSCOLS;     break;
7285             default:
7286                 DBG_ERROR("insertCells: falscher Mode");
7287                 bDo = sal_False;
7288         }
7289 
7290         if (bDo)
7291         {
7292             DBG_ASSERT( rRangeAddress.Sheet == GetTab_Impl(), "falsche Tabelle in CellRangeAddress" );
7293             ScRange aScRange;
7294             ScUnoConversion::FillScRange( aScRange, rRangeAddress );
7295             ScDocFunc aFunc(*pDocSh);
7296             aFunc.InsertCells( aScRange, NULL, eCmd, sal_True, sal_True );
7297         }
7298     }
7299 }
7300 
7301 void SAL_CALL ScTableSheetObj::removeRange( const table::CellRangeAddress& rRangeAddress,
7302                                 sheet::CellDeleteMode nMode ) throw(uno::RuntimeException)
7303 {
7304     ScUnoGuard aGuard;
7305     ScDocShell* pDocSh = GetDocShell();
7306     if ( pDocSh )
7307     {
7308         sal_Bool bDo = sal_True;
7309         DelCellCmd eCmd = DEL_NONE;
7310         switch (nMode)
7311         {
7312             case sheet::CellDeleteMode_NONE:     bDo = sal_False;           break;
7313             case sheet::CellDeleteMode_UP:       eCmd = DEL_CELLSUP;    break;
7314             case sheet::CellDeleteMode_LEFT:     eCmd = DEL_CELLSLEFT;  break;
7315             case sheet::CellDeleteMode_ROWS:     eCmd = DEL_DELROWS;    break;
7316             case sheet::CellDeleteMode_COLUMNS:  eCmd = DEL_DELCOLS;    break;
7317             default:
7318                 DBG_ERROR("deleteCells: falscher Mode");
7319                 bDo = sal_False;
7320         }
7321 
7322         if (bDo)
7323         {
7324             DBG_ASSERT( rRangeAddress.Sheet == GetTab_Impl(), "falsche Tabelle in CellRangeAddress" );
7325             ScRange aScRange;
7326             ScUnoConversion::FillScRange( aScRange, rRangeAddress );
7327             ScDocFunc aFunc(*pDocSh);
7328             aFunc.DeleteCells( aScRange, NULL, eCmd, sal_True, sal_True );
7329         }
7330     }
7331 }
7332 
7333 void SAL_CALL ScTableSheetObj::moveRange( const table::CellAddress& aDestination,
7334                                         const table::CellRangeAddress& aSource )
7335                                         throw(uno::RuntimeException)
7336 {
7337     ScUnoGuard aGuard;
7338     ScDocShell* pDocSh = GetDocShell();
7339     if ( pDocSh )
7340     {
7341         DBG_ASSERT( aSource.Sheet == GetTab_Impl(), "falsche Tabelle in CellRangeAddress" );
7342         ScRange aSourceRange;
7343         ScUnoConversion::FillScRange( aSourceRange, aSource );
7344         ScAddress aDestPos( (SCCOL)aDestination.Column, (SCROW)aDestination.Row, aDestination.Sheet );
7345         ScDocFunc aFunc(*pDocSh);
7346         aFunc.MoveBlock( aSourceRange, aDestPos, sal_True, sal_True, sal_True, sal_True );
7347     }
7348 }
7349 
7350 void SAL_CALL ScTableSheetObj::copyRange( const table::CellAddress& aDestination,
7351                                         const table::CellRangeAddress& aSource )
7352                                         throw(uno::RuntimeException)
7353 {
7354     ScUnoGuard aGuard;
7355     ScDocShell* pDocSh = GetDocShell();
7356     if ( pDocSh )
7357     {
7358         DBG_ASSERT( aSource.Sheet == GetTab_Impl(), "falsche Tabelle in CellRangeAddress" );
7359         ScRange aSourceRange;
7360         ScUnoConversion::FillScRange( aSourceRange, aSource );
7361         ScAddress aDestPos( (SCCOL)aDestination.Column, (SCROW)aDestination.Row, aDestination.Sheet );
7362         ScDocFunc aFunc(*pDocSh);
7363         aFunc.MoveBlock( aSourceRange, aDestPos, sal_False, sal_True, sal_True, sal_True );
7364     }
7365 }
7366 
7367 // XPrintAreas
7368 
7369 void ScTableSheetObj::PrintAreaUndo_Impl( ScPrintRangeSaver* pOldRanges )
7370 {
7371     //  Umbrueche und Undo
7372 
7373     ScDocShell* pDocSh = GetDocShell();
7374     if ( pDocSh )
7375     {
7376         ScDocument* pDoc = pDocSh->GetDocument();
7377         sal_Bool bUndo(pDoc->IsUndoEnabled());
7378         SCTAB nTab = GetTab_Impl();
7379 
7380         ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
7381         if (bUndo)
7382         {
7383             pDocSh->GetUndoManager()->AddUndoAction(
7384                         new ScUndoPrintRange( pDocSh, nTab, pOldRanges, pNewRanges ) );
7385         }
7386 
7387         ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
7388 
7389         SfxBindings* pBindings = pDocSh->GetViewBindings();
7390         if (pBindings)
7391             pBindings->Invalidate( SID_DELETE_PRINTAREA );
7392 
7393         pDocSh->SetDocumentModified();
7394     }
7395     else
7396         delete pOldRanges;
7397 }
7398 
7399 uno::Sequence<table::CellRangeAddress> SAL_CALL ScTableSheetObj::getPrintAreas()
7400                                                 throw(uno::RuntimeException)
7401 {
7402     ScUnoGuard aGuard;
7403     ScDocShell* pDocSh = GetDocShell();
7404     if ( pDocSh )
7405     {
7406         ScDocument* pDoc = pDocSh->GetDocument();
7407         SCTAB nTab = GetTab_Impl();
7408         sal_uInt16 nCount = pDoc->GetPrintRangeCount( nTab );
7409 
7410         table::CellRangeAddress aRangeAddress;
7411         uno::Sequence<table::CellRangeAddress> aSeq(nCount);
7412         table::CellRangeAddress* pAry = aSeq.getArray();
7413         for (sal_uInt16 i=0; i<nCount; i++)
7414         {
7415             const ScRange* pRange = pDoc->GetPrintRange( nTab, i );
7416             DBG_ASSERT(pRange,"wo ist der Druckbereich");
7417             if (pRange)
7418             {
7419                 ScUnoConversion::FillApiRange( aRangeAddress, *pRange );
7420                 aRangeAddress.Sheet = nTab; // core does not care about sheet index
7421                 pAry[i] = aRangeAddress;
7422             }
7423         }
7424         return aSeq;
7425     }
7426     return uno::Sequence<table::CellRangeAddress>();
7427 }
7428 
7429 void SAL_CALL ScTableSheetObj::setPrintAreas(
7430                     const uno::Sequence<table::CellRangeAddress>& aPrintAreas )
7431                                                 throw(uno::RuntimeException)
7432 {
7433     ScUnoGuard aGuard;
7434     ScDocShell* pDocSh = GetDocShell();
7435     if ( pDocSh )
7436     {
7437         ScDocument* pDoc = pDocSh->GetDocument();
7438         SCTAB nTab = GetTab_Impl();
7439 
7440         ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
7441 
7442         sal_uInt16 nCount = (sal_uInt16) aPrintAreas.getLength();
7443         pDoc->ClearPrintRanges( nTab );
7444         if (nCount)
7445         {
7446             ScRange aPrintRange;
7447             const table::CellRangeAddress* pAry = aPrintAreas.getConstArray();
7448             for (sal_uInt16 i=0; i<nCount; i++)
7449             {
7450                 ScUnoConversion::FillScRange( aPrintRange, pAry[i] );
7451                 pDoc->AddPrintRange( nTab, aPrintRange );
7452             }
7453         }
7454 
7455         PrintAreaUndo_Impl( pOldRanges );   // Undo, Umbrueche, Modified etc.
7456     }
7457 }
7458 
7459 sal_Bool SAL_CALL ScTableSheetObj::getPrintTitleColumns() throw(uno::RuntimeException)
7460 {
7461     ScUnoGuard aGuard;
7462     ScDocShell* pDocSh = GetDocShell();
7463     if ( pDocSh )
7464     {
7465         ScDocument* pDoc = pDocSh->GetDocument();
7466         SCTAB nTab = GetTab_Impl();
7467         return ( pDoc->GetRepeatColRange(nTab) != NULL );
7468     }
7469     return sal_False;
7470 }
7471 
7472 void SAL_CALL ScTableSheetObj::setPrintTitleColumns( sal_Bool bPrintTitleColumns )
7473                                                     throw(uno::RuntimeException)
7474 {
7475     ScUnoGuard aGuard;
7476     ScDocShell* pDocSh = GetDocShell();
7477     if ( pDocSh )
7478     {
7479         ScDocument* pDoc = pDocSh->GetDocument();
7480         SCTAB nTab = GetTab_Impl();
7481 
7482         ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
7483 
7484         if ( bPrintTitleColumns )
7485         {
7486             if ( !pDoc->GetRepeatColRange( nTab ) )         // keinen bestehenden Bereich veraendern
7487             {
7488                 ScRange aNew( 0, 0, nTab, 0, 0, nTab );     // Default
7489                 pDoc->SetRepeatColRange( nTab, &aNew );     // einschalten
7490             }
7491         }
7492         else
7493             pDoc->SetRepeatColRange( nTab, NULL );          // abschalten
7494 
7495         PrintAreaUndo_Impl( pOldRanges );   // Undo, Umbrueche, Modified etc.
7496 
7497         //! zuletzt gesetzten Bereich beim Abschalten merken und beim Einschalten wiederherstellen ???
7498     }
7499 }
7500 
7501 table::CellRangeAddress SAL_CALL ScTableSheetObj::getTitleColumns() throw(uno::RuntimeException)
7502 {
7503     ScUnoGuard aGuard;
7504     table::CellRangeAddress aRet;
7505     ScDocShell* pDocSh = GetDocShell();
7506     if ( pDocSh )
7507     {
7508         ScDocument* pDoc = pDocSh->GetDocument();
7509         SCTAB nTab = GetTab_Impl();
7510         const ScRange* pRange = pDoc->GetRepeatColRange(nTab);
7511         if (pRange)
7512         {
7513             ScUnoConversion::FillApiRange( aRet, *pRange );
7514             aRet.Sheet = nTab; // core does not care about sheet index
7515         }
7516     }
7517     return aRet;
7518 }
7519 
7520 void SAL_CALL ScTableSheetObj::setTitleColumns( const table::CellRangeAddress& aTitleColumns )
7521                                                     throw(uno::RuntimeException)
7522 {
7523     ScUnoGuard aGuard;
7524     ScDocShell* pDocSh = GetDocShell();
7525     if ( pDocSh )
7526     {
7527         ScDocument* pDoc = pDocSh->GetDocument();
7528         SCTAB nTab = GetTab_Impl();
7529 
7530         ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
7531 
7532         ScRange aNew;
7533         ScUnoConversion::FillScRange( aNew, aTitleColumns );
7534         pDoc->SetRepeatColRange( nTab, &aNew );     // immer auch einschalten
7535 
7536         PrintAreaUndo_Impl( pOldRanges );           // Undo, Umbrueche, Modified etc.
7537     }
7538 }
7539 
7540 sal_Bool SAL_CALL ScTableSheetObj::getPrintTitleRows() throw(uno::RuntimeException)
7541 {
7542     ScUnoGuard aGuard;
7543     ScDocShell* pDocSh = GetDocShell();
7544     if ( pDocSh )
7545     {
7546         ScDocument* pDoc = pDocSh->GetDocument();
7547         SCTAB nTab = GetTab_Impl();
7548         return ( pDoc->GetRepeatRowRange(nTab) != NULL );
7549     }
7550     return sal_False;
7551 }
7552 
7553 void SAL_CALL ScTableSheetObj::setPrintTitleRows( sal_Bool bPrintTitleRows )
7554                                                 throw(uno::RuntimeException)
7555 {
7556     ScUnoGuard aGuard;
7557     ScDocShell* pDocSh = GetDocShell();
7558     if ( pDocSh )
7559     {
7560         ScDocument* pDoc = pDocSh->GetDocument();
7561         SCTAB nTab = GetTab_Impl();
7562 
7563         ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
7564 
7565         if ( bPrintTitleRows )
7566         {
7567             if ( !pDoc->GetRepeatRowRange( nTab ) )         // keinen bestehenden Bereich veraendern
7568             {
7569                 ScRange aNew( 0, 0, nTab, 0, 0, nTab );     // Default
7570                 pDoc->SetRepeatRowRange( nTab, &aNew );     // einschalten
7571             }
7572         }
7573         else
7574             pDoc->SetRepeatRowRange( nTab, NULL );          // abschalten
7575 
7576         PrintAreaUndo_Impl( pOldRanges );   // Undo, Umbrueche, Modified etc.
7577 
7578         //! zuletzt gesetzten Bereich beim Abschalten merken und beim Einschalten wiederherstellen ???
7579     }
7580 }
7581 
7582 table::CellRangeAddress SAL_CALL ScTableSheetObj::getTitleRows() throw(uno::RuntimeException)
7583 {
7584     ScUnoGuard aGuard;
7585     table::CellRangeAddress aRet;
7586     ScDocShell* pDocSh = GetDocShell();
7587     if ( pDocSh )
7588     {
7589         ScDocument* pDoc = pDocSh->GetDocument();
7590         SCTAB nTab = GetTab_Impl();
7591         const ScRange* pRange = pDoc->GetRepeatRowRange(nTab);
7592         if (pRange)
7593         {
7594             ScUnoConversion::FillApiRange( aRet, *pRange );
7595             aRet.Sheet = nTab; // core does not care about sheet index
7596         }
7597     }
7598     return aRet;
7599 }
7600 
7601 void SAL_CALL ScTableSheetObj::setTitleRows( const table::CellRangeAddress& aTitleRows )
7602                                                     throw(uno::RuntimeException)
7603 {
7604     ScUnoGuard aGuard;
7605     ScDocShell* pDocSh = GetDocShell();
7606     if ( pDocSh )
7607     {
7608         ScDocument* pDoc = pDocSh->GetDocument();
7609         SCTAB nTab = GetTab_Impl();
7610 
7611         ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
7612 
7613         ScRange aNew;
7614         ScUnoConversion::FillScRange( aNew, aTitleRows );
7615         pDoc->SetRepeatRowRange( nTab, &aNew );     // immer auch einschalten
7616 
7617         PrintAreaUndo_Impl( pOldRanges );           // Undo, Umbrueche, Modified etc.
7618     }
7619 }
7620 
7621 // XSheetLinkable
7622 
7623 sheet::SheetLinkMode SAL_CALL ScTableSheetObj::getLinkMode() throw(uno::RuntimeException)
7624 {
7625     ScUnoGuard aGuard;
7626     sheet::SheetLinkMode eRet = sheet::SheetLinkMode_NONE;
7627     ScDocShell* pDocSh = GetDocShell();
7628     if ( pDocSh )
7629     {
7630         sal_uInt8 nMode = pDocSh->GetDocument()->GetLinkMode( GetTab_Impl() );
7631         if ( nMode == SC_LINK_NORMAL )
7632             eRet = sheet::SheetLinkMode_NORMAL;
7633         else if ( nMode == SC_LINK_VALUE )
7634             eRet = sheet::SheetLinkMode_VALUE;
7635     }
7636     return eRet;
7637 }
7638 
7639 void SAL_CALL ScTableSheetObj::setLinkMode( sheet::SheetLinkMode nLinkMode )
7640                                                 throw(uno::RuntimeException)
7641 {
7642     ScUnoGuard aGuard;
7643 
7644     //! Filter und Options aus altem Link suchen
7645 
7646     rtl::OUString aUrl(getLinkUrl());
7647     rtl::OUString aSheet(getLinkSheetName());
7648 
7649     rtl::OUString aEmpty;
7650     link( aUrl, aSheet, aEmpty, aEmpty, nLinkMode );
7651 }
7652 
7653 rtl::OUString SAL_CALL ScTableSheetObj::getLinkUrl() throw(uno::RuntimeException)
7654 {
7655     ScUnoGuard aGuard;
7656     String aFile;
7657     ScDocShell* pDocSh = GetDocShell();
7658     if ( pDocSh )
7659         aFile = pDocSh->GetDocument()->GetLinkDoc( GetTab_Impl() );
7660     return aFile;
7661 }
7662 
7663 void SAL_CALL ScTableSheetObj::setLinkUrl( const rtl::OUString& aLinkUrl )
7664                                                 throw(uno::RuntimeException)
7665 {
7666     ScUnoGuard aGuard;
7667 
7668     //! Filter und Options aus altem Link suchen
7669 
7670     sheet::SheetLinkMode eMode = getLinkMode();
7671     rtl::OUString aSheet(getLinkSheetName());
7672 
7673     rtl::OUString aEmpty;
7674     link( aLinkUrl, aSheet, aEmpty, aEmpty, eMode );
7675 }
7676 
7677 rtl::OUString SAL_CALL ScTableSheetObj::getLinkSheetName() throw(uno::RuntimeException)
7678 {
7679     ScUnoGuard aGuard;
7680     String aSheet;
7681     ScDocShell* pDocSh = GetDocShell();
7682     if ( pDocSh )
7683         aSheet = pDocSh->GetDocument()->GetLinkTab( GetTab_Impl() );
7684     return aSheet;
7685 }
7686 
7687 void SAL_CALL ScTableSheetObj::setLinkSheetName( const rtl::OUString& aLinkSheetName )
7688                                                 throw(uno::RuntimeException)
7689 {
7690     ScUnoGuard aGuard;
7691 
7692     //! Filter und Options aus altem Link suchen
7693 
7694     sheet::SheetLinkMode eMode = getLinkMode();
7695     rtl::OUString aUrl(getLinkUrl());
7696 
7697     rtl::OUString aEmpty;
7698     link( aUrl, aLinkSheetName, aEmpty, aEmpty, eMode );
7699 }
7700 
7701 void SAL_CALL ScTableSheetObj::link( const rtl::OUString& aUrl, const rtl::OUString& aSheetName,
7702                         const rtl::OUString& aFilterName, const rtl::OUString& aFilterOptions,
7703                         sheet::SheetLinkMode nMode ) throw(uno::RuntimeException)
7704 {
7705     ScUnoGuard aGuard;
7706     ScDocShell* pDocSh = GetDocShell();
7707     if ( pDocSh )
7708     {
7709         ScDocument* pDoc = pDocSh->GetDocument();
7710         SCTAB nTab = GetTab_Impl();
7711 
7712         String aFileString   (aUrl);
7713         String aFilterString (aFilterName);
7714         String aOptString    (aFilterOptions);
7715         String aSheetString  (aSheetName);
7716 
7717         aFileString = ScGlobal::GetAbsDocName( aFileString, pDocSh );
7718         if ( !aFilterString.Len() )
7719             ScDocumentLoader::GetFilterName( aFileString, aFilterString, aOptString, sal_True, sal_False );
7720 
7721         //  remove application prefix from filter name here, so the filter options
7722         //  aren't reset when the filter name is changed in ScTableLink::DataChanged
7723         ScDocumentLoader::RemoveAppPrefix( aFilterString );
7724 
7725         sal_uInt8 nLinkMode = SC_LINK_NONE;
7726         if ( nMode == sheet::SheetLinkMode_NORMAL )
7727             nLinkMode = SC_LINK_NORMAL;
7728         else if ( nMode == sheet::SheetLinkMode_VALUE )
7729             nLinkMode = SC_LINK_VALUE;
7730 
7731         sal_uLong nRefresh = 0;
7732         pDoc->SetLink( nTab, nLinkMode, aFileString, aFilterString, aOptString, aSheetString, nRefresh );
7733 
7734         pDocSh->UpdateLinks();                  // ggf. Link eintragen oder loeschen
7735         SfxBindings* pBindings = pDocSh->GetViewBindings();
7736         if (pBindings)
7737             pBindings->Invalidate(SID_LINKS);
7738 
7739         //! Undo fuer Link-Daten an der Table
7740 
7741         if ( nLinkMode != SC_LINK_NONE && pDoc->IsExecuteLinkEnabled() )        // Link updaten
7742         {
7743             //  Update immer, auch wenn der Link schon da war
7744             //! Update nur fuer die betroffene Tabelle???
7745 
7746             sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
7747             sal_uInt16 nCount = pLinkManager->GetLinks().Count();
7748             for ( sal_uInt16 i=0; i<nCount; i++ )
7749             {
7750                 ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[i];
7751                 if (pBase->ISA(ScTableLink))
7752                 {
7753                     ScTableLink* pTabLink = (ScTableLink*)pBase;
7754                     if ( pTabLink->GetFileName() == aFileString )
7755                         pTabLink->Update();                         // inkl. Paint&Undo
7756 
7757                     //! Der Dateiname sollte nur einmal vorkommen (?)
7758                 }
7759             }
7760         }
7761 
7762         //! Notify fuer ScSheetLinkObj Objekte!!!
7763     }
7764 }
7765 
7766 // XSheetAuditing
7767 
7768 sal_Bool SAL_CALL ScTableSheetObj::hideDependents( const table::CellAddress& aPosition )
7769                                                 throw(uno::RuntimeException)
7770 {
7771     ScUnoGuard aGuard;
7772     ScDocShell* pDocSh = GetDocShell();
7773     if ( pDocSh )
7774     {
7775         SCTAB nTab = GetTab_Impl();
7776         DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
7777         ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
7778         ScDocFunc aFunc(*pDocSh);
7779         return aFunc.DetectiveDelSucc( aPos );
7780     }
7781     return sal_False;
7782 }
7783 
7784 sal_Bool SAL_CALL ScTableSheetObj::hidePrecedents( const table::CellAddress& aPosition )
7785                                             throw(uno::RuntimeException)
7786 {
7787     ScUnoGuard aGuard;
7788     ScDocShell* pDocSh = GetDocShell();
7789     if ( pDocSh )
7790     {
7791         SCTAB nTab = GetTab_Impl();
7792         DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
7793         ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
7794         ScDocFunc aFunc(*pDocSh);
7795         return aFunc.DetectiveDelPred( aPos );
7796     }
7797     return sal_False;
7798 }
7799 
7800 sal_Bool SAL_CALL ScTableSheetObj::showDependents( const table::CellAddress& aPosition )
7801                                             throw(uno::RuntimeException)
7802 {
7803     ScUnoGuard aGuard;
7804     ScDocShell* pDocSh = GetDocShell();
7805     if ( pDocSh )
7806     {
7807         SCTAB nTab = GetTab_Impl();
7808         DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
7809         ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
7810         ScDocFunc aFunc(*pDocSh);
7811         return aFunc.DetectiveAddSucc( aPos );
7812     }
7813     return sal_False;
7814 }
7815 
7816 sal_Bool SAL_CALL ScTableSheetObj::showPrecedents( const table::CellAddress& aPosition )
7817                                             throw(uno::RuntimeException)
7818 {
7819     ScUnoGuard aGuard;
7820     ScDocShell* pDocSh = GetDocShell();
7821     if ( pDocSh )
7822     {
7823         SCTAB nTab = GetTab_Impl();
7824         DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
7825         ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
7826         ScDocFunc aFunc(*pDocSh);
7827         return aFunc.DetectiveAddPred( aPos );
7828     }
7829     return sal_False;
7830 }
7831 
7832 sal_Bool SAL_CALL ScTableSheetObj::showErrors( const table::CellAddress& aPosition )
7833                                             throw(uno::RuntimeException)
7834 {
7835     ScUnoGuard aGuard;
7836     ScDocShell* pDocSh = GetDocShell();
7837     if ( pDocSh )
7838     {
7839         SCTAB nTab = GetTab_Impl();
7840         DBG_ASSERT( aPosition.Sheet == nTab, "falsche Tabelle in CellAddress" );
7841         ScAddress aPos( (SCCOL)aPosition.Column, (SCROW)aPosition.Row, nTab );
7842         ScDocFunc aFunc(*pDocSh);
7843         return aFunc.DetectiveAddError( aPos );
7844     }
7845     return sal_False;
7846 }
7847 
7848 sal_Bool SAL_CALL ScTableSheetObj::showInvalid() throw(uno::RuntimeException)
7849 {
7850     ScUnoGuard aGuard;
7851     ScDocShell* pDocSh = GetDocShell();
7852     if ( pDocSh )
7853     {
7854         ScDocFunc aFunc(*pDocSh);
7855         return aFunc.DetectiveMarkInvalid( GetTab_Impl() );
7856     }
7857     return sal_False;
7858 }
7859 
7860 void SAL_CALL ScTableSheetObj::clearArrows() throw(uno::RuntimeException)
7861 {
7862     ScUnoGuard aGuard;
7863     ScDocShell* pDocSh = GetDocShell();
7864     if ( pDocSh )
7865     {
7866         ScDocFunc aFunc(*pDocSh);
7867         aFunc.DetectiveDelAll( GetTab_Impl() );
7868     }
7869 }
7870 
7871 // XSheetOutline
7872 
7873 void SAL_CALL ScTableSheetObj::group( const table::CellRangeAddress& rGroupRange,
7874                                         table::TableOrientation nOrientation )
7875                                     throw(uno::RuntimeException)
7876 {
7877     ScUnoGuard aGuard;
7878     ScDocShell* pDocSh = GetDocShell();
7879     if ( pDocSh )
7880     {
7881         sal_Bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
7882         ScRange aGroupRange;
7883         ScUnoConversion::FillScRange( aGroupRange, rGroupRange );
7884         ScOutlineDocFunc aFunc(*pDocSh);
7885         aFunc.MakeOutline( aGroupRange, bColumns, sal_True, sal_True );
7886     }
7887 }
7888 
7889 void SAL_CALL ScTableSheetObj::ungroup( const table::CellRangeAddress& rGroupRange,
7890                                         table::TableOrientation nOrientation )
7891                                     throw(uno::RuntimeException)
7892 {
7893     ScUnoGuard aGuard;
7894     ScDocShell* pDocSh = GetDocShell();
7895     if ( pDocSh )
7896     {
7897         sal_Bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
7898         ScRange aGroupRange;
7899         ScUnoConversion::FillScRange( aGroupRange, rGroupRange );
7900         ScOutlineDocFunc aFunc(*pDocSh);
7901         aFunc.RemoveOutline( aGroupRange, bColumns, sal_True, sal_True );
7902     }
7903 }
7904 
7905 void SAL_CALL ScTableSheetObj::autoOutline( const table::CellRangeAddress& rCellRange )
7906                                     throw(uno::RuntimeException)
7907 {
7908     ScUnoGuard aGuard;
7909     ScDocShell* pDocSh = GetDocShell();
7910     if ( pDocSh )
7911     {
7912         ScRange aFormulaRange;
7913         ScUnoConversion::FillScRange( aFormulaRange, rCellRange );
7914         ScOutlineDocFunc aFunc(*pDocSh);
7915         aFunc.AutoOutline( aFormulaRange, sal_True, sal_True );
7916     }
7917 }
7918 
7919 void SAL_CALL ScTableSheetObj::clearOutline() throw(uno::RuntimeException)
7920 {
7921     ScUnoGuard aGuard;
7922     ScDocShell* pDocSh = GetDocShell();
7923     if ( pDocSh )
7924     {
7925         SCTAB nTab = GetTab_Impl();
7926         ScOutlineDocFunc aFunc(*pDocSh);
7927         aFunc.RemoveAllOutlines( nTab, sal_True, sal_True );
7928     }
7929 }
7930 
7931 void SAL_CALL ScTableSheetObj::hideDetail( const table::CellRangeAddress& rCellRange )
7932                                             throw(uno::RuntimeException)
7933 {
7934     ScUnoGuard aGuard;
7935     ScDocShell* pDocSh = GetDocShell();
7936     if ( pDocSh )
7937     {
7938         ScRange aMarkRange;
7939         ScUnoConversion::FillScRange( aMarkRange, rCellRange );
7940         ScOutlineDocFunc aFunc(*pDocSh);
7941         aFunc.HideMarkedOutlines( aMarkRange, sal_True, sal_True );
7942     }
7943 }
7944 
7945 void SAL_CALL ScTableSheetObj::showDetail( const table::CellRangeAddress& rCellRange )
7946                                             throw(uno::RuntimeException)
7947 {
7948     ScUnoGuard aGuard;
7949     ScDocShell* pDocSh = GetDocShell();
7950     if ( pDocSh )
7951     {
7952         ScRange aMarkRange;
7953         ScUnoConversion::FillScRange( aMarkRange, rCellRange );
7954         ScOutlineDocFunc aFunc(*pDocSh);
7955         aFunc.ShowMarkedOutlines( aMarkRange, sal_True, sal_True );
7956     }
7957 }
7958 
7959 void SAL_CALL ScTableSheetObj::showLevel( sal_Int16 nLevel, table::TableOrientation nOrientation )
7960                                             throw(uno::RuntimeException)
7961 {
7962     ScUnoGuard aGuard;
7963     ScDocShell* pDocSh = GetDocShell();
7964     if ( pDocSh )
7965     {
7966         sal_Bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
7967         SCTAB nTab = GetTab_Impl();
7968         ScOutlineDocFunc aFunc(*pDocSh);
7969         aFunc.SelectLevel( nTab, bColumns, nLevel, sal_True, sal_True, sal_True );
7970     }
7971 }
7972 
7973 // XProtectable
7974 
7975 void SAL_CALL ScTableSheetObj::protect( const rtl::OUString& aPassword )
7976                                             throw(uno::RuntimeException)
7977 {
7978     ScUnoGuard aGuard;
7979     ScDocShell* pDocSh = GetDocShell();
7980     // #i108245# if already protected, don't change anything
7981     if ( pDocSh && !pDocSh->GetDocument()->IsTabProtected( GetTab_Impl() ) )
7982     {
7983         String aString(aPassword);
7984         ScDocFunc aFunc(*pDocSh);
7985         aFunc.Protect( GetTab_Impl(), aString, sal_True );
7986     }
7987 }
7988 
7989 void SAL_CALL ScTableSheetObj::unprotect( const rtl::OUString& aPassword )
7990                             throw(lang::IllegalArgumentException, uno::RuntimeException)
7991 {
7992     ScUnoGuard aGuard;
7993     ScDocShell* pDocSh = GetDocShell();
7994     if ( pDocSh )
7995     {
7996         String aString(aPassword);
7997         ScDocFunc aFunc(*pDocSh);
7998         sal_Bool bDone = aFunc.Unprotect( GetTab_Impl(), aString, sal_True );
7999         if (!bDone)
8000             throw lang::IllegalArgumentException();
8001     }
8002 }
8003 
8004 sal_Bool SAL_CALL ScTableSheetObj::isProtected() throw(uno::RuntimeException)
8005 {
8006     ScUnoGuard aGuard;
8007     ScDocShell* pDocSh = GetDocShell();
8008     if ( pDocSh )
8009         return pDocSh->GetDocument()->IsTabProtected( GetTab_Impl() );
8010 
8011     DBG_ERROR("keine DocShell");        //! Exception oder so?
8012     return sal_False;
8013 }
8014 
8015 // XScenario
8016 
8017 sal_Bool SAL_CALL ScTableSheetObj::getIsScenario() throw(uno::RuntimeException)
8018 {
8019     ScUnoGuard aGuard;
8020     ScDocShell* pDocSh = GetDocShell();
8021     if ( pDocSh )
8022         return pDocSh->GetDocument()->IsScenario( GetTab_Impl() );
8023 
8024     return sal_False;
8025 }
8026 
8027 rtl::OUString SAL_CALL ScTableSheetObj::getScenarioComment() throw(uno::RuntimeException)
8028 {
8029     ScUnoGuard aGuard;
8030     ScDocShell* pDocSh = GetDocShell();
8031     if ( pDocSh )
8032     {
8033         String aComment;
8034         Color  aColor;
8035         sal_uInt16 nFlags;
8036         pDocSh->GetDocument()->GetScenarioData( GetTab_Impl(), aComment, aColor, nFlags );
8037         return aComment;
8038     }
8039     return rtl::OUString();
8040 }
8041 
8042 void SAL_CALL ScTableSheetObj::setScenarioComment( const rtl::OUString& aScenarioComment )
8043                                                 throw(uno::RuntimeException)
8044 {
8045     ScUnoGuard aGuard;
8046     ScDocShell* pDocSh = GetDocShell();
8047     if ( pDocSh )
8048     {
8049         ScDocument* pDoc = pDocSh->GetDocument();
8050         SCTAB nTab = GetTab_Impl();
8051 
8052         String aName;
8053         String aComment;
8054         Color  aColor;
8055         sal_uInt16 nFlags;
8056         pDoc->GetName( nTab, aName );
8057         pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8058 
8059         aComment = String( aScenarioComment );
8060 
8061         pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
8062     }
8063 }
8064 
8065 void SAL_CALL ScTableSheetObj::addRanges( const uno::Sequence<table::CellRangeAddress>& rScenRanges )
8066                                                 throw(uno::RuntimeException)
8067 {
8068     ScUnoGuard aGuard;
8069     ScDocShell* pDocSh = GetDocShell();
8070     if ( pDocSh )
8071     {
8072         ScDocument* pDoc = pDocSh->GetDocument();
8073         SCTAB nTab = GetTab_Impl();
8074 
8075         if (pDoc->IsScenario(nTab))
8076         {
8077             ScMarkData aMarkData;
8078             aMarkData.SelectTable( nTab, sal_True );
8079 
8080             sal_uInt16 nRangeCount = (sal_uInt16)rScenRanges.getLength();
8081             if (nRangeCount)
8082             {
8083                 const table::CellRangeAddress* pAry = rScenRanges.getConstArray();
8084                 for (sal_uInt16 i=0; i<nRangeCount; i++)
8085                 {
8086                     DBG_ASSERT( pAry[i].Sheet == nTab, "addRanges mit falscher Tab" );
8087                     ScRange aOneRange( (SCCOL)pAry[i].StartColumn, (SCROW)pAry[i].StartRow, nTab,
8088                                        (SCCOL)pAry[i].EndColumn,   (SCROW)pAry[i].EndRow,   nTab );
8089 
8090                     aMarkData.SetMultiMarkArea( aOneRange );
8091                 }
8092             }
8093 
8094             //  Szenario-Ranges sind durch Attribut gekennzeichnet
8095             ScPatternAttr aPattern( pDoc->GetPool() );
8096             aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
8097             aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
8098             ScDocFunc aFunc(*pDocSh);
8099             aFunc.ApplyAttributes( aMarkData, aPattern, sal_True, sal_True );
8100         }
8101 
8102         // don't use. We should use therefor a private interface, so we can also set the flags.
8103 /*      else if (nTab > 0 && pDoc->IsImportingXML()) // make this sheet as an scenario and only if it is not the first sheet and only if it is ImportingXML,
8104             // because than no UNDO and repaint is necessary.
8105         {
8106             sal_uInt16 nRangeCount = (sal_uInt16)rScenRanges.getLength();
8107             if (nRangeCount)
8108             {
8109                 pDoc->SetScenario( nTab, sal_True );
8110 
8111                 // default flags
8112                 Color aColor( COL_LIGHTGRAY );  // Default
8113                 sal_uInt16 nFlags = SC_SCENARIO_SHOWFRAME | SC_SCENARIO_PRINTFRAME | SC_SCENARIO_TWOWAY;
8114                 String aComment;
8115 
8116                 pDoc->SetScenarioData( nTab, aComment, aColor, nFlags );
8117                 const table::CellRangeAddress* pAry = rScenRanges.getConstArray();
8118                 for (sal_uInt16 i=0; i<nRangeCount; i++)
8119                 {
8120                     DBG_ASSERT( pAry[i].Sheet == nTab, "addRanges mit falscher Tab" );
8121                     pDoc->ApplyFlagsTab( (sal_uInt16)pAry[i].StartColumn, (sal_uInt16)pAry[i].StartRow,
8122                             (sal_uInt16)pAry[i].EndColumn, (sal_uInt16)pAry[i].EndRow, nTab, SC_MF_SCENARIO );
8123                 }
8124                 pDoc->SetActiveScenario( nTab, sal_True );
8125 
8126                 // set to next visible tab
8127                 sal_uInt16 j = nTab - 1;
8128                 sal_Bool bFinished = sal_False;
8129                 while (j < nTab && !bFinished)
8130                 {
8131                     if (pDoc->IsVisible(j))
8132                     {
8133                         pDoc->SetVisibleTab(j);
8134                         bFinished = sal_True;
8135                     }
8136                     else
8137                         --j;
8138                 }
8139 
8140                 ScDocFunc aFunc(*pDocSh);
8141                 aFunc.SetTableVisible( nTab, sal_False, sal_True );
8142             }
8143         }*/
8144     }
8145 }
8146 
8147 void SAL_CALL ScTableSheetObj::apply() throw(uno::RuntimeException)
8148 {
8149     ScUnoGuard aGuard;
8150     ScDocShell* pDocSh = GetDocShell();
8151     if ( pDocSh )
8152     {
8153         ScDocument* pDoc = pDocSh->GetDocument();
8154         SCTAB nTab = GetTab_Impl();
8155         String aName;
8156         pDoc->GetName( nTab, aName );       // Name dieses Szenarios
8157 
8158         SCTAB nDestTab = nTab;
8159         while ( nDestTab > 0 && pDoc->IsScenario(nDestTab) )
8160             --nDestTab;
8161 
8162         if ( !pDoc->IsScenario(nDestTab) )
8163             pDocSh->UseScenario( nDestTab, aName );
8164 
8165         //! sonst Fehler oder so
8166     }
8167 }
8168 
8169 // XScenarioEnhanced
8170 
8171 uno::Sequence< table::CellRangeAddress > SAL_CALL ScTableSheetObj::getRanges(  )
8172                                     throw(uno::RuntimeException)
8173 {
8174     ScUnoGuard aGuard;
8175     ScDocShell* pDocSh = GetDocShell();
8176     if ( pDocSh )
8177     {
8178         ScDocument* pDoc = pDocSh->GetDocument();
8179         SCTAB nTab = GetTab_Impl();
8180         const ScRangeList* pRangeList = pDoc->GetScenarioRanges(nTab);
8181         if (pRangeList)
8182         {
8183             sal_Int32 nCount = pRangeList->Count();
8184             uno::Sequence< table::CellRangeAddress > aRetRanges(nCount);
8185             table::CellRangeAddress* pAry = aRetRanges.getArray();
8186             for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
8187             {
8188                 const ScRange* pRange = pRangeList->GetObject( nIndex );
8189                 pAry->StartColumn = pRange->aStart.Col();
8190                 pAry->StartRow = pRange->aStart.Row();
8191                 pAry->EndColumn = pRange->aEnd.Col();
8192                 pAry->EndRow = pRange->aEnd.Row();
8193                 pAry->Sheet = pRange->aStart.Tab();
8194                 ++pAry;
8195             }
8196             return aRetRanges;
8197         }
8198     }
8199     return uno::Sequence< table::CellRangeAddress > ();
8200 }
8201 
8202 // XExternalSheetName
8203 
8204 void ScTableSheetObj::setExternalName( const ::rtl::OUString& aUrl, const ::rtl::OUString& aSheetName )
8205     throw (container::ElementExistException, uno::RuntimeException)
8206 {
8207     ScUnoGuard aGuard;
8208     ScDocShell* pDocSh = GetDocShell();
8209     if ( pDocSh )
8210     {
8211         ScDocument* pDoc = pDocSh->GetDocument();
8212         if ( pDoc )
8213         {
8214             const SCTAB nTab = GetTab_Impl();
8215             const String aAbsDocName( ScGlobal::GetAbsDocName( aUrl, pDocSh ) );
8216             const String aDocTabName( ScGlobal::GetDocTabName( aAbsDocName, aSheetName ) );
8217             if ( !pDoc->RenameTab( nTab, aDocTabName, sal_False /*bUpdateRef*/, sal_True /*bExternalDocument*/ ) )
8218             {
8219                 throw container::ElementExistException( ::rtl::OUString(), *this );
8220             }
8221         }
8222     }
8223 }
8224 
8225 // XEventsSupplier
8226 
8227 uno::Reference<container::XNameReplace> SAL_CALL ScTableSheetObj::getEvents() throw (uno::RuntimeException)
8228 {
8229     ScUnoGuard aGuard;
8230     ScDocShell* pDocSh = GetDocShell();
8231     if ( pDocSh )
8232         return new ScSheetEventsObj( pDocSh, GetTab_Impl() );
8233 
8234     return NULL;
8235 }
8236 
8237 // XPropertySet erweitert fuer Sheet-Properties
8238 
8239 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableSheetObj::getPropertySetInfo()
8240                                                         throw(uno::RuntimeException)
8241 {
8242     ScUnoGuard aGuard;
8243     static uno::Reference<beans::XPropertySetInfo> aRef(
8244         new SfxItemPropertySetInfo( pSheetPropSet->getPropertyMap() ));
8245     return aRef;
8246 }
8247 
8248 void ScTableSheetObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
8249                                 throw(lang::IllegalArgumentException, uno::RuntimeException)
8250 {
8251     if ( pEntry )
8252     {
8253         if ( IsScItemWid( pEntry->nWID ) )
8254         {
8255             //  for Item WIDs, call ScCellRangesBase directly
8256             ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
8257             return;
8258         }
8259 
8260         //  own properties
8261 
8262         ScDocShell* pDocSh = GetDocShell();
8263         if (!pDocSh)
8264             return;                                                 //! Exception oder so?
8265         ScDocument* pDoc = pDocSh->GetDocument();
8266         SCTAB nTab = GetTab_Impl();
8267         ScDocFunc aFunc(*pDocSh);
8268 
8269         if ( pEntry->nWID == SC_WID_UNO_PAGESTL )
8270         {
8271             rtl::OUString aStrVal;
8272             aValue >>= aStrVal;
8273             String aNewStr(ScStyleNameConversion::ProgrammaticToDisplayName(
8274                                                 aStrVal, SFX_STYLE_FAMILY_PAGE ));
8275 
8276             //! Undo? (auch bei SID_STYLE_APPLY an der View)
8277 
8278             if ( pDoc->GetPageStyle( nTab ) != aNewStr )
8279             {
8280                 pDoc->SetPageStyle( nTab, aNewStr );
8281                 if (!pDoc->IsImportingXML())
8282                 {
8283                     ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
8284 
8285                     SfxBindings* pBindings = pDocSh->GetViewBindings();
8286                     if (pBindings)
8287                     {
8288                         pBindings->Invalidate( SID_STYLE_FAMILY4 );
8289                         pBindings->Invalidate( SID_STATUS_PAGESTYLE );
8290                         pBindings->Invalidate( FID_RESET_PRINTZOOM );
8291                         pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
8292                         pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
8293                     }
8294                 }
8295                 pDocSh->SetDocumentModified();
8296             }
8297         }
8298         else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
8299         {
8300             sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8301             aFunc.SetTableVisible( nTab, bVis, sal_True );
8302         }
8303         else if ( pEntry->nWID == SC_WID_UNO_ISACTIVE )
8304         {
8305             if (pDoc->IsScenario(nTab))
8306                 pDoc->SetActiveScenario( nTab, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
8307         }
8308         else if ( pEntry->nWID == SC_WID_UNO_BORDCOL )
8309         {
8310             if (pDoc->IsScenario(nTab))
8311             {
8312                 sal_Int32 nNewColor = 0;
8313                 if (aValue >>= nNewColor)
8314                 {
8315                     String aName;
8316                     String aComment;
8317                     Color  aColor;
8318                     sal_uInt16 nFlags;
8319                     pDoc->GetName( nTab, aName );
8320                     pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8321 
8322                     aColor = Color(static_cast<sal_uInt32>(nNewColor));
8323 
8324                     pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
8325                 }
8326             }
8327         }
8328         else if ( pEntry->nWID == SC_WID_UNO_PROTECT )
8329         {
8330             if (pDoc->IsScenario(nTab))
8331             {
8332                 String aName;
8333                 String aComment;
8334                 Color  aColor;
8335                 sal_uInt16 nFlags;
8336                 pDoc->GetName( nTab, aName );
8337                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8338                 sal_Bool bModify(sal_False);
8339 
8340                 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
8341                 {
8342                     if (!(nFlags & SC_SCENARIO_PROTECT))
8343                     {
8344                         nFlags |= SC_SCENARIO_PROTECT;
8345                         bModify = sal_True;
8346                     }
8347                 }
8348                 else
8349                 {
8350                     if (nFlags & SC_SCENARIO_PROTECT)
8351                     {
8352                         nFlags -= SC_SCENARIO_PROTECT;
8353                         bModify = sal_True;
8354                     }
8355                 }
8356 
8357                 if (bModify)
8358                     pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
8359             }
8360         }
8361         else if ( pEntry->nWID == SC_WID_UNO_SHOWBORD )
8362         {
8363             if (pDoc->IsScenario(nTab))
8364             {
8365                 String aName;
8366                 String aComment;
8367                 Color  aColor;
8368                 sal_uInt16 nFlags;
8369                 pDoc->GetName( nTab, aName );
8370                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8371                 sal_Bool bModify(sal_False);
8372 
8373                 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
8374                 {
8375                     if (!(nFlags & SC_SCENARIO_SHOWFRAME))
8376                     {
8377                         nFlags |= SC_SCENARIO_SHOWFRAME;
8378                         bModify = sal_True;
8379                     }
8380                 }
8381                 else
8382                 {
8383                     if (nFlags & SC_SCENARIO_SHOWFRAME)
8384                     {
8385                         nFlags -= SC_SCENARIO_SHOWFRAME;
8386                         bModify = sal_True;
8387                     }
8388                 }
8389 
8390                 if (bModify)
8391                     pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
8392             }
8393         }
8394         else if ( pEntry->nWID == SC_WID_UNO_PRINTBORD )
8395         {
8396             if (pDoc->IsScenario(nTab))
8397             {
8398                 String aName;
8399                 String aComment;
8400                 Color  aColor;
8401                 sal_uInt16 nFlags;
8402                 pDoc->GetName( nTab, aName );
8403                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8404                 sal_Bool bModify(sal_False);
8405 
8406                 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
8407                 {
8408                     if (!(nFlags & SC_SCENARIO_PRINTFRAME))
8409                     {
8410                         nFlags |= SC_SCENARIO_PRINTFRAME;
8411                         bModify = sal_True;
8412                     }
8413                 }
8414                 else
8415                 {
8416                     if (nFlags & SC_SCENARIO_PRINTFRAME)
8417                     {
8418                         nFlags -= SC_SCENARIO_PRINTFRAME;
8419                         bModify = sal_True;
8420                     }
8421                 }
8422 
8423                 if (bModify)
8424                     pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
8425             }
8426         }
8427         else if ( pEntry->nWID == SC_WID_UNO_COPYBACK )
8428         {
8429             if (pDoc->IsScenario(nTab))
8430             {
8431                 String aName;
8432                 String aComment;
8433                 Color  aColor;
8434                 sal_uInt16 nFlags;
8435                 pDoc->GetName( nTab, aName );
8436                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8437                 sal_Bool bModify(sal_False);
8438 
8439                 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
8440                 {
8441                     if (!(nFlags & SC_SCENARIO_TWOWAY))
8442                     {
8443                         nFlags |= SC_SCENARIO_TWOWAY;
8444                         bModify = sal_True;
8445                     }
8446                 }
8447                 else
8448                 {
8449                     if (nFlags & SC_SCENARIO_TWOWAY)
8450                     {
8451                         nFlags -= SC_SCENARIO_TWOWAY;
8452                         bModify = sal_True;
8453                     }
8454                 }
8455 
8456                 if (bModify)
8457                     pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
8458             }
8459         }
8460         else if ( pEntry->nWID == SC_WID_UNO_COPYSTYL )
8461         {
8462             if (pDoc->IsScenario(nTab))
8463             {
8464                 String aName;
8465                 String aComment;
8466                 Color  aColor;
8467                 sal_uInt16 nFlags;
8468                 pDoc->GetName( nTab, aName );
8469                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8470                 sal_Bool bModify(sal_False);
8471 
8472                 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
8473                 {
8474                     if (!(nFlags & SC_SCENARIO_ATTRIB))
8475                     {
8476                         nFlags |= SC_SCENARIO_ATTRIB;
8477                         bModify = sal_True;
8478                     }
8479                 }
8480                 else
8481                 {
8482                     if (nFlags & SC_SCENARIO_ATTRIB)
8483                     {
8484                         nFlags -= SC_SCENARIO_ATTRIB;
8485                         bModify = sal_True;
8486                     }
8487                 }
8488 
8489                 if (bModify)
8490                     pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
8491             }
8492         }
8493         else if ( pEntry->nWID == SC_WID_UNO_COPYFORM )
8494         {
8495             if (pDoc->IsScenario(nTab))
8496             {
8497                 String aName;
8498                 String aComment;
8499                 Color  aColor;
8500                 sal_uInt16 nFlags;
8501                 pDoc->GetName( nTab, aName );
8502                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8503                 sal_Bool bModify(sal_False);
8504 
8505                 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
8506                 {
8507                     if (nFlags & SC_SCENARIO_VALUE)
8508                     {
8509                         nFlags -= SC_SCENARIO_VALUE;
8510                         bModify = sal_True;
8511                     }
8512                 }
8513                 else
8514                 {
8515                     if (!(nFlags & SC_SCENARIO_VALUE))
8516                     {
8517                         nFlags |= SC_SCENARIO_VALUE;
8518                         bModify = sal_True;
8519                     }
8520                 }
8521 
8522                 if (bModify)
8523                     pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
8524             }
8525         }
8526         else if ( pEntry->nWID == SC_WID_UNO_TABLAYOUT )
8527         {
8528             sal_Int16 nValue = 0;
8529             if (aValue >>= nValue)
8530             {
8531                 if (nValue == com::sun::star::text::WritingMode2::RL_TB)
8532                     aFunc.SetLayoutRTL(nTab, sal_True, sal_True);
8533                 else
8534                     aFunc.SetLayoutRTL(nTab, sal_False, sal_True);
8535             }
8536         }
8537         else if ( pEntry->nWID == SC_WID_UNO_AUTOPRINT )
8538         {
8539             sal_Bool bAutoPrint = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8540             if (bAutoPrint)
8541                 pDoc->SetPrintEntireSheet( nTab ); // clears all print ranges
8542             else
8543             {
8544                 if (pDoc->IsPrintEntireSheet( nTab ))
8545                     pDoc->ClearPrintRanges( nTab ); // if this flag is true, there are no PrintRanges, so Clear clears only the flag.
8546             }
8547         }
8548         else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR )
8549         {
8550             sal_Int32 nColor = COL_AUTO;
8551             if (aValue >>= nColor)
8552             {
8553                 if (static_cast<ColorData>(nColor) != COL_AUTO)
8554                     pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor)));
8555             }
8556         }
8557         else if ( pEntry->nWID == SC_WID_UNO_CODENAME )
8558         {
8559             rtl::OUString aCodeName;
8560             if ( pDocSh && ( aValue >>= aCodeName ) )
8561             {
8562                 pDocSh->GetDocument()->SetCodeName( GetTab_Impl(), aCodeName );
8563             }
8564         }
8565         else
8566             ScCellRangeObj::SetOnePropertyValue(pEntry, aValue);        // base class, no Item WID
8567     }
8568 }
8569 
8570 void ScTableSheetObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
8571                                             uno::Any& rAny )
8572                                                 throw(uno::RuntimeException)
8573 {
8574     if ( pEntry )
8575     {
8576         ScDocShell* pDocSh = GetDocShell();
8577         if (!pDocSh)
8578             throw uno::RuntimeException();
8579         ScDocument* pDoc = pDocSh->GetDocument();
8580         SCTAB nTab = GetTab_Impl();
8581 
8582         if ( pEntry->nWID == SC_WID_UNO_PAGESTL )
8583         {
8584             rAny <<= rtl::OUString( ScStyleNameConversion::DisplayToProgrammaticName(
8585                                 pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE ) );
8586         }
8587         else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
8588         {
8589             sal_Bool bVis = pDoc->IsVisible( nTab );
8590             ScUnoHelpFunctions::SetBoolInAny( rAny, bVis );
8591         }
8592         else if ( pEntry->nWID == SC_WID_UNO_LINKDISPBIT )
8593         {
8594             //  no target bitmaps for individual entries (would be all equal)
8595             // ScLinkTargetTypeObj::SetLinkTargetBitmap( aAny, SC_LINKTARGETTYPE_SHEET );
8596         }
8597         else if ( pEntry->nWID == SC_WID_UNO_LINKDISPNAME )
8598         {
8599             //  LinkDisplayName for hyperlink dialog
8600             rAny <<= getName();     // sheet name
8601         }
8602         else if ( pEntry->nWID == SC_WID_UNO_ISACTIVE )
8603         {
8604             if (pDoc->IsScenario(nTab))
8605                 ScUnoHelpFunctions::SetBoolInAny( rAny, pDoc->IsActiveScenario( nTab ));
8606         }
8607         else if ( pEntry->nWID == SC_WID_UNO_BORDCOL )
8608         {
8609             if (pDoc->IsScenario(nTab))
8610             {
8611                 String aComment;
8612                 Color  aColor;
8613                 sal_uInt16 nFlags;
8614                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8615 
8616                 rAny <<= static_cast<sal_Int32>(aColor.GetColor());
8617             }
8618         }
8619         else if ( pEntry->nWID == SC_WID_UNO_PROTECT )
8620         {
8621             if (pDoc->IsScenario(nTab))
8622             {
8623                 String aComment;
8624                 Color  aColor;
8625                 sal_uInt16 nFlags;
8626                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8627 
8628                 ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_PROTECT) != 0 );
8629             }
8630         }
8631         else if ( pEntry->nWID == SC_WID_UNO_SHOWBORD )
8632         {
8633             if (pDoc->IsScenario(nTab))
8634             {
8635                 String aComment;
8636                 Color  aColor;
8637                 sal_uInt16 nFlags;
8638                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8639 
8640                 ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_SHOWFRAME) != 0 );
8641             }
8642         }
8643         else if ( pEntry->nWID == SC_WID_UNO_PRINTBORD )
8644         {
8645             if (pDoc->IsScenario(nTab))
8646             {
8647                 String aComment;
8648                 Color  aColor;
8649                 sal_uInt16 nFlags;
8650                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8651 
8652                 ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_PRINTFRAME) != 0 );
8653             }
8654         }
8655         else if ( pEntry->nWID == SC_WID_UNO_COPYBACK )
8656         {
8657             if (pDoc->IsScenario(nTab))
8658             {
8659                 String aComment;
8660                 Color  aColor;
8661                 sal_uInt16 nFlags;
8662                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8663 
8664                 ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_TWOWAY) != 0 );
8665             }
8666         }
8667         else if ( pEntry->nWID == SC_WID_UNO_COPYSTYL )
8668         {
8669             if (pDoc->IsScenario(nTab))
8670             {
8671                 String aComment;
8672                 Color  aColor;
8673                 sal_uInt16 nFlags;
8674                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8675 
8676                 ScUnoHelpFunctions::SetBoolInAny( rAny, (nFlags & SC_SCENARIO_ATTRIB) != 0 );
8677             }
8678         }
8679         else if ( pEntry->nWID == SC_WID_UNO_COPYFORM )
8680         {
8681             if (pDoc->IsScenario(nTab))
8682             {
8683                 String aComment;
8684                 Color  aColor;
8685                 sal_uInt16 nFlags;
8686                 pDoc->GetScenarioData( nTab, aComment, aColor, nFlags );
8687 
8688                 ScUnoHelpFunctions::SetBoolInAny( rAny, !(nFlags & SC_SCENARIO_VALUE));
8689             }
8690         }
8691         else if ( pEntry->nWID == SC_WID_UNO_TABLAYOUT )
8692         {
8693             if (pDoc->IsLayoutRTL(nTab))
8694                 rAny <<= sal_Int16(com::sun::star::text::WritingMode2::RL_TB);
8695             else
8696                 rAny <<= sal_Int16(com::sun::star::text::WritingMode2::LR_TB);
8697         }
8698         else if ( pEntry->nWID == SC_WID_UNO_AUTOPRINT )
8699         {
8700             sal_Bool bAutoPrint = pDoc->IsPrintEntireSheet( nTab );
8701             ScUnoHelpFunctions::SetBoolInAny( rAny, bAutoPrint );
8702         }
8703         else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR )
8704         {
8705             rAny <<= sal_Int32(pDoc->GetTabBgColor(nTab).GetColor());
8706         }
8707         else if ( pEntry->nWID == SC_WID_UNO_CODENAME )
8708         {
8709             String aCodeName;
8710             if ( pDocSh )
8711                 pDocSh->GetDocument()->GetCodeName( GetTab_Impl(), aCodeName );
8712             rAny <<= rtl::OUString( aCodeName );
8713         }
8714         else
8715             ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
8716     }
8717 }
8718 
8719 const SfxItemPropertyMap* ScTableSheetObj::GetItemPropertyMap()
8720 {
8721     return pSheetPropSet->getPropertyMap();
8722 }
8723 
8724 // XServiceInfo
8725 
8726 rtl::OUString SAL_CALL ScTableSheetObj::getImplementationName() throw(uno::RuntimeException)
8727 {
8728     return rtl::OUString::createFromAscii( "ScTableSheetObj" );
8729 }
8730 
8731 sal_Bool SAL_CALL ScTableSheetObj::supportsService( const rtl::OUString& rServiceName )
8732                                                     throw(uno::RuntimeException)
8733 {
8734     String aServiceStr( rServiceName );
8735     return aServiceStr.EqualsAscii( SCSPREADSHEET_SERVICE ) ||
8736            aServiceStr.EqualsAscii( SCSHEETCELLRANGE_SERVICE ) ||
8737            aServiceStr.EqualsAscii( SCCELLRANGE_SERVICE ) ||
8738            aServiceStr.EqualsAscii( SCCELLPROPERTIES_SERVICE ) ||
8739            aServiceStr.EqualsAscii( SCCHARPROPERTIES_SERVICE ) ||
8740            aServiceStr.EqualsAscii( SCPARAPROPERTIES_SERVICE ) ||
8741            aServiceStr.EqualsAscii( SCLINKTARGET_SERVICE );
8742 }
8743 
8744 uno::Sequence<rtl::OUString> SAL_CALL ScTableSheetObj::getSupportedServiceNames()
8745                                                     throw(uno::RuntimeException)
8746 {
8747     uno::Sequence<rtl::OUString> aRet(7);
8748     rtl::OUString* pArray = aRet.getArray();
8749     pArray[0] = rtl::OUString::createFromAscii( SCSPREADSHEET_SERVICE );
8750     pArray[1] = rtl::OUString::createFromAscii( SCSHEETCELLRANGE_SERVICE );
8751     pArray[2] = rtl::OUString::createFromAscii( SCCELLRANGE_SERVICE );
8752     pArray[3] = rtl::OUString::createFromAscii( SCCELLPROPERTIES_SERVICE );
8753     pArray[4] = rtl::OUString::createFromAscii( SCCHARPROPERTIES_SERVICE );
8754     pArray[5] = rtl::OUString::createFromAscii( SCPARAPROPERTIES_SERVICE );
8755     pArray[6] = rtl::OUString::createFromAscii( SCLINKTARGET_SERVICE );
8756     return aRet;
8757 }
8758 
8759 // XUnoTunnel
8760 
8761 sal_Int64 SAL_CALL ScTableSheetObj::getSomething(
8762                 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
8763 {
8764     if ( rId.getLength() == 16 &&
8765           0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
8766                                     rId.getConstArray(), 16 ) )
8767     {
8768         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
8769     }
8770 
8771     return ScCellRangeObj::getSomething( rId );
8772 }
8773 
8774 // static
8775 const uno::Sequence<sal_Int8>& ScTableSheetObj::getUnoTunnelId()
8776 {
8777     static uno::Sequence<sal_Int8> * pSeq = 0;
8778     if( !pSeq )
8779     {
8780         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
8781         if( !pSeq )
8782         {
8783             static uno::Sequence< sal_Int8 > aSeq( 16 );
8784             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
8785             pSeq = &aSeq;
8786         }
8787     }
8788     return *pSeq;
8789 }
8790 
8791 // static
8792 ScTableSheetObj* ScTableSheetObj::getImplementation( const uno::Reference<uno::XInterface> xObj )
8793 {
8794     ScTableSheetObj* pRet = NULL;
8795     uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
8796     if (xUT.is())
8797         pRet = reinterpret_cast<ScTableSheetObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
8798     return pRet;
8799 }
8800 
8801 //------------------------------------------------------------------------
8802 
8803 ScTableColumnObj::ScTableColumnObj( ScDocShell* pDocSh, SCCOL nCol, SCTAB nTab ) :
8804     ScCellRangeObj( pDocSh, ScRange(nCol,0,nTab, nCol,MAXROW,nTab) ),
8805     pColPropSet(lcl_GetColumnPropertySet())
8806 {
8807 }
8808 
8809 ScTableColumnObj::~ScTableColumnObj()
8810 {
8811 }
8812 
8813 uno::Any SAL_CALL ScTableColumnObj::queryInterface( const uno::Type& rType ) throw(uno::RuntimeException)
8814 {
8815     SC_QUERYINTERFACE( container::XNamed )
8816 
8817     return ScCellRangeObj::queryInterface( rType );
8818 }
8819 
8820 void SAL_CALL ScTableColumnObj::acquire() throw()
8821 {
8822     ScCellRangeObj::acquire();
8823 }
8824 
8825 void SAL_CALL ScTableColumnObj::release() throw()
8826 {
8827     ScCellRangeObj::release();
8828 }
8829 
8830 uno::Sequence<uno::Type> SAL_CALL ScTableColumnObj::getTypes() throw(uno::RuntimeException)
8831 {
8832     static uno::Sequence<uno::Type> aTypes;
8833     if ( aTypes.getLength() == 0 )
8834     {
8835         uno::Sequence<uno::Type> aParentTypes(ScCellRangeObj::getTypes());
8836         long nParentLen = aParentTypes.getLength();
8837         const uno::Type* pParentPtr = aParentTypes.getConstArray();
8838 
8839         aTypes.realloc( nParentLen + 1 );
8840         uno::Type* pPtr = aTypes.getArray();
8841         pPtr[nParentLen + 0] = getCppuType((const uno::Reference<container::XNamed>*)0);
8842 
8843         for (long i=0; i<nParentLen; i++)
8844             pPtr[i] = pParentPtr[i];                // parent types first
8845     }
8846     return aTypes;
8847 }
8848 
8849 uno::Sequence<sal_Int8> SAL_CALL ScTableColumnObj::getImplementationId() throw(uno::RuntimeException)
8850 {
8851     static uno::Sequence< sal_Int8 > aId;
8852     if( aId.getLength() == 0 )
8853     {
8854         aId.realloc( 16 );
8855         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
8856     }
8857     return aId;
8858 }
8859 
8860 // XNamed
8861 
8862 rtl::OUString SAL_CALL ScTableColumnObj::getName() throw(uno::RuntimeException)
8863 {
8864     ScUnoGuard aGuard;
8865 
8866     const ScRange& rRange = GetRange();
8867     DBG_ASSERT(rRange.aStart.Col() == rRange.aEnd.Col(), "too many columns");
8868     SCCOL nCol = rRange.aStart.Col();
8869 
8870     return ScColToAlpha( nCol );        // from global.hxx
8871 }
8872 
8873 void SAL_CALL ScTableColumnObj::setName( const rtl::OUString& /* aNewName */ )
8874                                                 throw(uno::RuntimeException)
8875 {
8876     ScUnoGuard aGuard;
8877     throw uno::RuntimeException();      // read-only
8878 }
8879 
8880 // XPropertySet erweitert fuer Spalten-Properties
8881 
8882 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnObj::getPropertySetInfo()
8883                                                         throw(uno::RuntimeException)
8884 {
8885     ScUnoGuard aGuard;
8886     static uno::Reference<beans::XPropertySetInfo> aRef(
8887         new SfxItemPropertySetInfo( pColPropSet->getPropertyMap() ));
8888     return aRef;
8889 }
8890 
8891 void ScTableColumnObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
8892                                 throw(lang::IllegalArgumentException, uno::RuntimeException)
8893 {
8894     if ( pEntry )
8895     {
8896         if ( IsScItemWid( pEntry->nWID ) )
8897         {
8898             //  for Item WIDs, call ScCellRangesBase directly
8899             ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
8900             return;
8901         }
8902 
8903         //  own properties
8904 
8905         ScDocShell* pDocSh = GetDocShell();
8906         if (!pDocSh)
8907             return;                                                 //! Exception oder so?
8908         const ScRange& rRange = GetRange();
8909         DBG_ASSERT(rRange.aStart.Col() == rRange.aEnd.Col(), "zuviele Spalten");
8910         SCCOL nCol = rRange.aStart.Col();
8911         SCTAB nTab = rRange.aStart.Tab();
8912         ScDocFunc aFunc(*pDocSh);
8913 
8914         SCCOLROW nColArr[2];
8915         nColArr[0] = nColArr[1] = nCol;
8916 
8917         if ( pEntry->nWID == SC_WID_UNO_CELLWID )
8918         {
8919             sal_Int32 nNewWidth = 0;
8920             if ( aValue >>= nNewWidth )
8921             {
8922                 //  property is 1/100mm, column width is twips
8923                 nNewWidth = HMMToTwips(nNewWidth);
8924                 aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, SC_SIZE_ORIGINAL,
8925                                         (sal_uInt16)nNewWidth, sal_True, sal_True );
8926             }
8927         }
8928         else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
8929         {
8930             sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8931             ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
8932             aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab, eMode, 0, sal_True, sal_True );
8933             //  SC_SIZE_DIRECT mit Groesse 0 blendet aus
8934         }
8935         else if ( pEntry->nWID == SC_WID_UNO_OWIDTH )
8936         {
8937             sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8938             if (bOpt)
8939                 aFunc.SetWidthOrHeight( sal_True, 1, nColArr, nTab,
8940                                         SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, sal_True, sal_True );
8941             // sal_False bei Spalten momentan ohne Auswirkung
8942         }
8943         else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE || pEntry->nWID == SC_WID_UNO_MANPAGE )
8944         {
8945             sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8946             if (bSet)
8947                 aFunc.InsertPageBreak( sal_True, rRange.aStart, sal_True, sal_True, sal_True );
8948             else
8949                 aFunc.RemovePageBreak( sal_True, rRange.aStart, sal_True, sal_True, sal_True );
8950         }
8951         else
8952             ScCellRangeObj::SetOnePropertyValue(pEntry, aValue);        // base class, no Item WID
8953     }
8954 }
8955 
8956 void ScTableColumnObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
8957                                             uno::Any& rAny )
8958                                                 throw(uno::RuntimeException)
8959 {
8960     if ( pEntry )
8961     {
8962         ScDocShell* pDocSh = GetDocShell();
8963         if (!pDocSh)
8964             throw uno::RuntimeException();
8965 
8966         ScDocument* pDoc = pDocSh->GetDocument();
8967         const ScRange& rRange = GetRange();
8968         DBG_ASSERT(rRange.aStart.Col() == rRange.aEnd.Col(), "zuviele Spalten");
8969         SCCOL nCol = rRange.aStart.Col();
8970         SCTAB nTab = rRange.aStart.Tab();
8971 
8972         if ( pEntry->nWID == SC_WID_UNO_CELLWID )
8973         {
8974             // for hidden column, return original height
8975             sal_uInt16 nWidth = pDoc->GetOriginalWidth( nCol, nTab );
8976             //  property is 1/100mm, column width is twips
8977             nWidth = (sal_uInt16) TwipsToHMM(nWidth);
8978             rAny <<= (sal_Int32)( nWidth );
8979         }
8980         else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
8981         {
8982             SCCOL nDummy;
8983             bool bHidden = pDoc->ColHidden(nCol, nTab, nDummy);
8984             ScUnoHelpFunctions::SetBoolInAny( rAny, !bHidden );
8985         }
8986         else if ( pEntry->nWID == SC_WID_UNO_OWIDTH )
8987         {
8988             //! momentan immer gesetzt ??!?!
8989             sal_Bool bOpt = !(pDoc->GetColFlags( nCol, nTab ) & CR_MANUALSIZE);
8990             ScUnoHelpFunctions::SetBoolInAny( rAny, bOpt );
8991         }
8992         else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE )
8993         {
8994             ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
8995             ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
8996         }
8997         else if ( pEntry->nWID == SC_WID_UNO_MANPAGE )
8998         {
8999             ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab);
9000             ScUnoHelpFunctions::SetBoolInAny(rAny, (nBreak & BREAK_MANUAL));
9001         }
9002         else
9003             ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
9004     }
9005 }
9006 
9007 const SfxItemPropertyMap* ScTableColumnObj::GetItemPropertyMap()
9008 {
9009     return pColPropSet->getPropertyMap();
9010 }
9011 
9012 //------------------------------------------------------------------------
9013 
9014 ScTableRowObj::ScTableRowObj(ScDocShell* pDocSh, SCROW nRow, SCTAB nTab) :
9015     ScCellRangeObj( pDocSh, ScRange(0,nRow,nTab, MAXCOL,nRow,nTab) ),
9016     pRowPropSet(lcl_GetRowPropertySet())
9017 {
9018 }
9019 
9020 ScTableRowObj::~ScTableRowObj()
9021 {
9022 }
9023 
9024 // XPropertySet erweitert fuer Zeilen-Properties
9025 
9026 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowObj::getPropertySetInfo()
9027                                                         throw(uno::RuntimeException)
9028 {
9029     ScUnoGuard aGuard;
9030     static uno::Reference<beans::XPropertySetInfo> aRef(
9031         new SfxItemPropertySetInfo( pRowPropSet->getPropertyMap() ));
9032     return aRef;
9033 }
9034 
9035 void ScTableRowObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry, const uno::Any& aValue )
9036                                 throw(lang::IllegalArgumentException, uno::RuntimeException)
9037 {
9038     if ( pEntry )
9039     {
9040         if ( IsScItemWid( pEntry->nWID ) )
9041         {
9042             //  for Item WIDs, call ScCellRangesBase directly
9043             ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
9044             return;
9045         }
9046 
9047         //  own properties
9048 
9049         ScDocShell* pDocSh = GetDocShell();
9050         if (!pDocSh)
9051             return;                                                 //! Exception oder so?
9052         ScDocument* pDoc = pDocSh->GetDocument();
9053         const ScRange& rRange = GetRange();
9054         DBG_ASSERT(rRange.aStart.Row() == rRange.aEnd.Row(), "zuviele Zeilen");
9055         SCROW nRow = rRange.aStart.Row();
9056         SCTAB nTab = rRange.aStart.Tab();
9057         ScDocFunc aFunc(*pDocSh);
9058 
9059         SCCOLROW nRowArr[2];
9060         nRowArr[0] = nRowArr[1] = nRow;
9061 
9062         if ( pEntry->nWID == SC_WID_UNO_CELLHGT )
9063         {
9064             sal_Int32 nNewHeight = 0;
9065             if ( aValue >>= nNewHeight )
9066             {
9067                 //  property is 1/100mm, row height is twips
9068                 nNewHeight = HMMToTwips(nNewHeight);
9069                 aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_ORIGINAL,
9070                                         (sal_uInt16)nNewHeight, sal_True, sal_True );
9071             }
9072         }
9073         else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
9074         {
9075             sal_Bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
9076             ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
9077             aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, eMode, 0, sal_True, sal_True );
9078             //  SC_SIZE_DIRECT mit Groesse 0 blendet aus
9079         }
9080         else if ( pEntry->nWID == SC_WID_UNO_CELLFILT )
9081         {
9082             sal_Bool bFil = ScUnoHelpFunctions::GetBoolFromAny( aValue );
9083 //          ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
9084 //          aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, eMode, 0, sal_True, sal_True );
9085             //  SC_SIZE_DIRECT mit Groesse 0 blendet aus
9086             pDoc->SetRowFiltered(nRow, nRow, nTab, bFil);
9087         }
9088         else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT )
9089         {
9090             sal_Bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
9091             if (bOpt)
9092                 aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, sal_True, sal_True );
9093             else
9094             {
9095                 //  set current height again manually
9096                 sal_uInt16 nHeight = pDoc->GetOriginalHeight( nRow, nTab );
9097                 aFunc.SetWidthOrHeight( sal_False, 1, nRowArr, nTab, SC_SIZE_ORIGINAL, nHeight, sal_True, sal_True );
9098             }
9099         }
9100         else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE || pEntry->nWID == SC_WID_UNO_MANPAGE )
9101         {
9102             sal_Bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
9103             if (bSet)
9104                 aFunc.InsertPageBreak( sal_False, rRange.aStart, sal_True, sal_True, sal_True );
9105             else
9106                 aFunc.RemovePageBreak( sal_False, rRange.aStart, sal_True, sal_True, sal_True );
9107         }
9108         else
9109             ScCellRangeObj::SetOnePropertyValue(pEntry, aValue);        // base class, no Item WID
9110     }
9111 }
9112 
9113 void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntry,
9114                                         uno::Any& rAny )
9115                                                 throw(uno::RuntimeException)
9116 {
9117     if ( pEntry )
9118     {
9119         ScDocShell* pDocSh = GetDocShell();
9120         if (!pDocSh)
9121             throw uno::RuntimeException();
9122         ScDocument* pDoc = pDocSh->GetDocument();
9123         const ScRange& rRange = GetRange();
9124         DBG_ASSERT(rRange.aStart.Row() == rRange.aEnd.Row(), "zuviele Zeilen");
9125         SCROW nRow = rRange.aStart.Row();
9126         SCTAB nTab = rRange.aStart.Tab();
9127 
9128         if ( pEntry->nWID == SC_WID_UNO_CELLHGT )
9129         {
9130             // for hidden row, return original height
9131             sal_uInt16 nHeight = pDoc->GetOriginalHeight( nRow, nTab );
9132             //  property is 1/100mm, row height is twips
9133             nHeight = (sal_uInt16) TwipsToHMM(nHeight);
9134             rAny <<= (sal_Int32)( nHeight );
9135         }
9136         else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
9137         {
9138             SCROW nDummy;
9139             bool bHidden = pDoc->RowHidden(nRow, nTab, nDummy);
9140             ScUnoHelpFunctions::SetBoolInAny( rAny, !bHidden );
9141         }
9142         else if ( pEntry->nWID == SC_WID_UNO_CELLFILT )
9143         {
9144             bool bVis = pDoc->RowFiltered(nRow, nTab);
9145             ScUnoHelpFunctions::SetBoolInAny( rAny, bVis );
9146         }
9147         else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT )
9148         {
9149             sal_Bool bOpt = !(pDoc->GetRowFlags( nRow, nTab ) & CR_MANUALSIZE);
9150             ScUnoHelpFunctions::SetBoolInAny( rAny, bOpt );
9151         }
9152         else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE )
9153         {
9154             ScBreakType nBreak = pDoc->HasRowBreak(nRow, nTab);
9155             ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
9156         }
9157         else if ( pEntry->nWID == SC_WID_UNO_MANPAGE )
9158         {
9159             ScBreakType nBreak = (pDoc->HasRowBreak(nRow, nTab) & BREAK_MANUAL);
9160             ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak );
9161         }
9162         else
9163             ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
9164     }
9165 }
9166 
9167 const SfxItemPropertyMap* ScTableRowObj::GetItemPropertyMap()
9168 {
9169     return pRowPropSet->getPropertyMap();
9170 }
9171 
9172 //------------------------------------------------------------------------
9173 
9174 ScCellsObj::ScCellsObj(ScDocShell* pDocSh, const ScRangeList& rR) :
9175     pDocShell( pDocSh ),
9176     aRanges( rR )
9177 {
9178     pDocShell->GetDocument()->AddUnoObject(*this);
9179 }
9180 
9181 ScCellsObj::~ScCellsObj()
9182 {
9183     if (pDocShell)
9184         pDocShell->GetDocument()->RemoveUnoObject(*this);
9185 }
9186 
9187 void ScCellsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
9188 {
9189     if ( rHint.ISA( ScUpdateRefHint ) )
9190     {
9191         const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
9192         aRanges.UpdateReference( rRef.GetMode(), pDocShell->GetDocument(), rRef.GetRange(),
9193                                         rRef.GetDx(), rRef.GetDy(), rRef.GetDz() );
9194     }
9195     else if ( rHint.ISA( SfxSimpleHint ) &&
9196             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
9197     {
9198         pDocShell = NULL;       // ungueltig geworden
9199     }
9200 }
9201 
9202 // XEnumerationAccess
9203 
9204 uno::Reference<container::XEnumeration> SAL_CALL ScCellsObj::createEnumeration()
9205                                                     throw(uno::RuntimeException)
9206 {
9207     ScUnoGuard aGuard;
9208     if (pDocShell)
9209         return new ScCellsEnumeration( pDocShell, aRanges );
9210     return NULL;
9211 }
9212 
9213 uno::Type SAL_CALL ScCellsObj::getElementType() throw(uno::RuntimeException)
9214 {
9215     ScUnoGuard aGuard;
9216     return getCppuType((uno::Reference<table::XCell>*)0);
9217 }
9218 
9219 sal_Bool SAL_CALL ScCellsObj::hasElements() throw(uno::RuntimeException)
9220 {
9221     ScUnoGuard aGuard;
9222     sal_Bool bHas = sal_False;
9223     if ( pDocShell )
9224     {
9225         //! schneller selber testen?
9226 
9227         uno::Reference<container::XEnumeration> xEnum(new ScCellsEnumeration( pDocShell, aRanges ));
9228         bHas = xEnum->hasMoreElements();
9229     }
9230     return bHas;
9231 }
9232 
9233 //------------------------------------------------------------------------
9234 
9235 ScCellsEnumeration::ScCellsEnumeration(ScDocShell* pDocSh, const ScRangeList& rR) :
9236     pDocShell( pDocSh ),
9237     aRanges( rR ),
9238     pMark( NULL ),
9239     bAtEnd( sal_False )
9240 {
9241     ScDocument* pDoc = pDocShell->GetDocument();
9242     pDoc->AddUnoObject(*this);
9243 
9244     if ( aRanges.Count() == 0 )
9245         bAtEnd = sal_True;
9246     else
9247     {
9248         SCTAB nTab = 0;
9249         const ScRange* pFirst = aRanges.GetObject(0);
9250         if (pFirst)
9251             nTab = pFirst->aStart.Tab();
9252         aPos = ScAddress(0,0,nTab);
9253         CheckPos_Impl();                    // aPos auf erste passende Zelle setzen
9254     }
9255 }
9256 
9257 void ScCellsEnumeration::CheckPos_Impl()
9258 {
9259     if (pDocShell)
9260     {
9261         sal_Bool bFound = sal_False;
9262         ScDocument* pDoc = pDocShell->GetDocument();
9263         ScBaseCell* pCell = pDoc->GetCell(aPos);
9264         if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
9265         {
9266             if (!pMark)
9267             {
9268                 pMark = new ScMarkData;
9269                 pMark->MarkFromRangeList( aRanges, sal_False );
9270                 pMark->MarkToMulti();   // needed for GetNextMarkedCell
9271             }
9272             bFound = pMark->IsCellMarked( aPos.Col(), aPos.Row() );
9273         }
9274         if (!bFound)
9275             Advance_Impl();
9276     }
9277 }
9278 
9279 ScCellsEnumeration::~ScCellsEnumeration()
9280 {
9281     if (pDocShell)
9282         pDocShell->GetDocument()->RemoveUnoObject(*this);
9283     delete pMark;
9284 }
9285 
9286 void ScCellsEnumeration::Advance_Impl()
9287 {
9288     DBG_ASSERT(!bAtEnd,"zuviel Advance_Impl");
9289     if (!pMark)
9290     {
9291         pMark = new ScMarkData;
9292         pMark->MarkFromRangeList( aRanges, sal_False );
9293         pMark->MarkToMulti();   // needed for GetNextMarkedCell
9294     }
9295 
9296     SCCOL nCol = aPos.Col();
9297     SCROW nRow = aPos.Row();
9298     SCTAB nTab = aPos.Tab();
9299     sal_Bool bFound = pDocShell->GetDocument()->GetNextMarkedCell( nCol, nRow, nTab, *pMark );
9300     if (bFound)
9301         aPos.Set( nCol, nRow, nTab );
9302     else
9303         bAtEnd = sal_True;      // kommt nix mehr
9304 }
9305 
9306 void ScCellsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
9307 {
9308     if ( rHint.ISA( ScUpdateRefHint ) )
9309     {
9310         if (pDocShell)
9311         {
9312             const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
9313             aRanges.UpdateReference( rRef.GetMode(), pDocShell->GetDocument(), rRef.GetRange(),
9314                                             rRef.GetDx(), rRef.GetDy(), rRef.GetDz() );
9315 
9316             delete pMark;       // aus verschobenen Bereichen neu erzeugen
9317             pMark = NULL;
9318 
9319             if (!bAtEnd)        // aPos anpassen
9320             {
9321                 ScRangeList aNew;
9322                 aNew.Append(ScRange(aPos));
9323                 aNew.UpdateReference( rRef.GetMode(), pDocShell->GetDocument(), rRef.GetRange(),
9324                                         rRef.GetDx(), rRef.GetDy(), rRef.GetDz() );
9325                 if (aNew.Count()==1)
9326                 {
9327                     aPos = aNew.GetObject(0)->aStart;
9328                     CheckPos_Impl();
9329                 }
9330             }
9331         }
9332     }
9333     else if ( rHint.ISA( SfxSimpleHint ) &&
9334             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
9335     {
9336         pDocShell = NULL;       // ungueltig geworden
9337     }
9338 }
9339 
9340 // XEnumeration
9341 
9342 sal_Bool SAL_CALL ScCellsEnumeration::hasMoreElements() throw(uno::RuntimeException)
9343 {
9344     ScUnoGuard aGuard;
9345     return !bAtEnd;
9346 }
9347 
9348 uno::Any SAL_CALL ScCellsEnumeration::nextElement() throw(container::NoSuchElementException,
9349                                         lang::WrappedTargetException, uno::RuntimeException)
9350 {
9351     ScUnoGuard aGuard;
9352     if (pDocShell && !bAtEnd)
9353     {
9354         // Interface-Typ muss zu ScCellsObj::getElementType passen
9355 
9356         ScAddress aTempPos(aPos);
9357         Advance_Impl();
9358         return uno::makeAny(uno::Reference<table::XCell>(new ScCellObj( pDocShell, aTempPos )));
9359     }
9360 
9361     throw container::NoSuchElementException();      // no more elements
9362 //    return uno::Any();
9363 }
9364 
9365 //------------------------------------------------------------------------
9366 
9367 ScCellFormatsObj::ScCellFormatsObj(ScDocShell* pDocSh, const ScRange& rRange) :
9368     pDocShell( pDocSh ),
9369     aTotalRange( rRange )
9370 {
9371     ScDocument* pDoc = pDocShell->GetDocument();
9372     pDoc->AddUnoObject(*this);
9373 
9374     DBG_ASSERT( aTotalRange.aStart.Tab() == aTotalRange.aEnd.Tab(), "unterschiedliche Tabellen" );
9375 }
9376 
9377 ScCellFormatsObj::~ScCellFormatsObj()
9378 {
9379     if (pDocShell)
9380         pDocShell->GetDocument()->RemoveUnoObject(*this);
9381 }
9382 
9383 void ScCellFormatsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
9384 {
9385     if ( rHint.ISA( ScUpdateRefHint ) )
9386     {
9387         //! aTotalRange...
9388     }
9389     else if ( rHint.ISA( SfxSimpleHint ) &&
9390             ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
9391     {
9392         pDocShell = NULL;       // ungueltig geworden
9393     }
9394 }
9395 
9396 ScCellRangeObj* ScCellFormatsObj::GetObjectByIndex_Impl(long nIndex) const
9397 {
9398     //! direkt auf die AttrArrays zugreifen !!!!
9399 
9400     ScCellRangeObj* pRet = NULL;
9401     if (pDocShell)
9402     {
9403         ScDocument* pDoc = pDocShell->GetDocument();
9404         long nPos = 0;
9405         ScAttrRectIterator aIter( pDoc, aTotalRange.aStart.Tab(),
9406                                     aTotalRange.aStart.Col(), aTotalRange.aStart.Row(),
9407                                     aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() );
9408         SCCOL nCol1, nCol2;
9409         SCROW nRow1, nRow2;
9410         while ( aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
9411         {
9412             if ( nPos == nIndex )
9413             {
9414                 SCTAB nTab = aTotalRange.aStart.Tab();
9415                 ScRange aNext( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
9416 
9417                 if ( aNext.aStart == aNext.aEnd )
9418                     pRet = new ScCellObj( pDocShell, aNext.aStart );
9419                 else
9420                     pRet = new ScCellRangeObj( pDocShell, aNext );
9421             }
9422             ++nPos;
9423         }
9424     }
9425     return pRet;
9426 }
9427 
9428 // XIndexAccess
9429 
9430 sal_Int32 SAL_CALL ScCellFormatsObj::getCount() throw(uno::RuntimeException)
9431 {
9432     ScUnoGuard aGuard;
9433 
9434     //! direkt auf die AttrArrays zugreifen !!!!
9435 
9436     long nCount = 0;
9437     if (pDocShell)
9438     {
9439         ScDocument* pDoc = pDocShell->GetDocument();
9440         ScAttrRectIterator aIter( pDoc, aTotalRange.aStart.Tab(),
9441                                     aTotalRange.aStart.Col(), aTotalRange.aStart.Row(),
9442                                     aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() );
9443         SCCOL nCol1, nCol2;
9444         SCROW nRow1, nRow2;
9445         while ( aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
9446             ++nCount;
9447     }
9448     return nCount;
9449 }
9450 
9451 uno::Any SAL_CALL ScCellFormatsObj::getByIndex( sal_Int32 nIndex )
9452                             throw(lang::IndexOutOfBoundsException,
9453                                     lang::WrappedTargetException, uno::RuntimeException)
9454 {
9455     ScUnoGuard aGuard;
9456 
9457     uno::Reference<table::XCellRange> xRange(GetObjectByIndex_Impl(nIndex));
9458     if (xRange.is())
9459         return uno::makeAny(xRange);
9460     else
9461         throw lang::IndexOutOfBoundsException();
9462 //    return uno::Any();
9463 }
9464 
9465 uno::Type SAL_CALL ScCellFormatsObj::getElementType() throw(uno::RuntimeException)
9466 {
9467     ScUnoGuard aGuard;
9468     return getCppuType((uno::Reference<table::XCellRange>*)0);
9469 }
9470 
9471 sal_Bool SAL_CALL ScCellFormatsObj::hasElements() throw(uno::RuntimeException)
9472 {
9473     ScUnoGuard aGuard;
9474     return ( getCount() != 0 );     //! immer groesser 0 ??
9475 }
9476 
9477 // XEnumerationAccess
9478 
9479 uno::Reference<container::XEnumeration> SAL_CALL ScCellFormatsObj::createEnumeration()
9480                                                     throw(uno::RuntimeException)
9481 {
9482     ScUnoGuard aGuard;
9483     if (pDocShell)
9484         return new ScCellFormatsEnumeration( pDocShell, aTotalRange );
9485     return NULL;
9486 }
9487 
9488 //------------------------------------------------------------------------
9489 
9490 ScCellFormatsEnumeration::ScCellFormatsEnumeration(ScDocShell* pDocSh, const ScRange& rRange) :
9491     pDocShell( pDocSh ),
9492     nTab( rRange.aStart.Tab() ),
9493     pIter( NULL ),
9494     bAtEnd( sal_False ),
9495     bDirty( sal_False )
9496 {
9497     ScDocument* pDoc = pDocShell->GetDocument();
9498     pDoc->AddUnoObject(*this);
9499 
9500     DBG_ASSERT( rRange.aStart.Tab() == rRange.aEnd.Tab(),
9501                 "CellFormatsEnumeration: unterschiedliche Tabellen" );
9502 
9503     pIter = new ScAttrRectIterator( pDoc, nTab,
9504                                     rRange.aStart.Col(), rRange.aStart.Row(),
9505                                     rRange.aEnd.Col(), rRange.aEnd.Row() );
9506     Advance_Impl();
9507 }
9508 
9509 ScCellFormatsEnumeration::~ScCellFormatsEnumeration()
9510 {
9511     if (pDocShell)
9512         pDocShell->GetDocument()->RemoveUnoObject(*this);
9513     delete pIter;
9514 }
9515 
9516 void ScCellFormatsEnumeration::Advance_Impl()
9517 {
9518     DBG_ASSERT(!bAtEnd,"zuviel Advance_Impl");
9519 
9520     if ( pIter )
9521     {
9522         if ( bDirty )
9523         {
9524             pIter->DataChanged();   // AttrArray-Index neu suchen
9525             bDirty = sal_False;
9526         }
9527 
9528         SCCOL nCol1, nCol2;
9529         SCROW nRow1, nRow2;
9530         if ( pIter->GetNext( nCol1, nCol2, nRow1, nRow2 ) )
9531             aNext = ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
9532         else
9533             bAtEnd = sal_True;      // kommt nix mehr
9534     }
9535     else
9536         bAtEnd = sal_True;          // Dok weggekommen oder so
9537 }
9538 
9539 ScCellRangeObj* ScCellFormatsEnumeration::NextObject_Impl()
9540 {
9541     ScCellRangeObj* pRet = NULL;
9542     if (pDocShell && !bAtEnd)
9543     {
9544         if ( aNext.aStart == aNext.aEnd )
9545             pRet = new ScCellObj( pDocShell, aNext.aStart );
9546         else
9547             pRet = new ScCellRangeObj( pDocShell, aNext );
9548         Advance_Impl();
9549     }
9550     return pRet;
9551 }
9552 
9553 void ScCellFormatsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
9554 {
9555     if ( rHint.ISA( ScUpdateRefHint ) )
9556     {
9557         //! und nun ???
9558     }
9559     else if ( rHint.ISA( SfxSimpleHint ) )
9560     {
9561         sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
9562         if ( nId == SFX_HINT_DYING )
9563         {
9564             pDocShell = NULL;                       // ungueltig geworden
9565             delete pIter;
9566             pIter = NULL;
9567         }
9568         else if ( nId == SFX_HINT_DATACHANGED )
9569         {
9570             bDirty = sal_True;          // AttrArray-Index evtl. ungueltig geworden
9571         }
9572     }
9573 }
9574 
9575 // XEnumeration
9576 
9577 sal_Bool SAL_CALL ScCellFormatsEnumeration::hasMoreElements() throw(uno::RuntimeException)
9578 {
9579     ScUnoGuard aGuard;
9580     return !bAtEnd;
9581 }
9582 
9583 uno::Any SAL_CALL ScCellFormatsEnumeration::nextElement() throw(container::NoSuchElementException,
9584                                         lang::WrappedTargetException, uno::RuntimeException)
9585 {
9586     ScUnoGuard aGuard;
9587 
9588     if ( bAtEnd || !pDocShell )
9589         throw container::NoSuchElementException();      // no more elements
9590 
9591     // Interface-Typ muss zu ScCellFormatsObj::getElementType passen
9592 
9593     return uno::makeAny(uno::Reference<table::XCellRange> (NextObject_Impl()));
9594 }
9595 
9596 //------------------------------------------------------------------------
9597 
9598 ScUniqueCellFormatsObj::ScUniqueCellFormatsObj(ScDocShell* pDocSh, const ScRange& rRange) :
9599     pDocShell( pDocSh ),
9600     aTotalRange( rRange ),
9601     aRangeLists()
9602 {
9603     pDocShell->GetDocument()->AddUnoObject(*this);
9604 
9605     DBG_ASSERT( aTotalRange.aStart.Tab() == aTotalRange.aEnd.Tab(), "unterschiedliche Tabellen" );
9606 
9607     GetObjects_Impl();
9608 }
9609 
9610 ScUniqueCellFormatsObj::~ScUniqueCellFormatsObj()
9611 {
9612     if (pDocShell)
9613         pDocShell->GetDocument()->RemoveUnoObject(*this);
9614 }
9615 
9616 void ScUniqueCellFormatsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
9617 {
9618     if ( rHint.ISA( ScUpdateRefHint ) )
9619     {
9620         //! aTotalRange...
9621     }
9622     else if ( rHint.ISA( SfxSimpleHint ) )
9623     {
9624         sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
9625         if ( nId == SFX_HINT_DYING )
9626             pDocShell = NULL;                       // ungueltig geworden
9627     }
9628 }
9629 
9630 //
9631 //  Fill the list of formats from the document
9632 //
9633 
9634 // hash code to access the range lists by ScPatternAttr pointer
9635 struct ScPatternHashCode
9636 {
9637     size_t operator()( const ScPatternAttr* pPattern ) const
9638     {
9639         return reinterpret_cast<size_t>(pPattern);
9640     }
9641 };
9642 
9643 // Hash map to find a range by its start row
9644 typedef ::std::hash_map< SCROW, ScRange > ScRowRangeHashMap;
9645 
9646 typedef ::std::vector<ScRange> ScRangeVector;
9647 
9648 // Hash map entry.
9649 // The Join method depends on the column-wise order of ScAttrRectIterator
9650 class ScUniqueFormatsEntry
9651 {
9652     enum EntryState { STATE_EMPTY, STATE_SINGLE, STATE_COMPLEX };
9653 
9654     EntryState          eState;
9655     ScRange             aSingleRange;
9656     ScRowRangeHashMap   aJoinedRanges;      // "active" ranges to be merged
9657     ScRangeVector       aCompletedRanges;   // ranges that will no longer be touched
9658     ScRangeListRef      aReturnRanges;      // result as ScRangeList for further use
9659 
9660 public:
9661                         ScUniqueFormatsEntry() : eState( STATE_EMPTY ) {}
9662                         ScUniqueFormatsEntry( const ScUniqueFormatsEntry& r ) :
9663                             eState( r.eState ),
9664                             aSingleRange( r.aSingleRange ),
9665                             aJoinedRanges( r.aJoinedRanges ),
9666                             aCompletedRanges( r.aCompletedRanges ),
9667                             aReturnRanges( r.aReturnRanges ) {}
9668                         ~ScUniqueFormatsEntry() {}
9669 
9670     void                Join( const ScRange& rNewRange );
9671     const ScRangeList&  GetRanges();
9672     void                Clear() { aReturnRanges.Clear(); }  // aJoinedRanges and aCompletedRanges are cleared in GetRanges
9673 };
9674 
9675 void ScUniqueFormatsEntry::Join( const ScRange& rNewRange )
9676 {
9677     // Special-case handling for single range
9678 
9679     if ( eState == STATE_EMPTY )
9680     {
9681         aSingleRange = rNewRange;
9682         eState = STATE_SINGLE;
9683         return;
9684     }
9685     if ( eState == STATE_SINGLE )
9686     {
9687         if ( aSingleRange.aStart.Row() == rNewRange.aStart.Row() &&
9688              aSingleRange.aEnd.Row() == rNewRange.aEnd.Row() &&
9689              aSingleRange.aEnd.Col() + 1 == rNewRange.aStart.Col() )
9690         {
9691             aSingleRange.aEnd.SetCol( rNewRange.aEnd.Col() );
9692             return;     // still a single range
9693         }
9694 
9695         SCROW nSingleRow = aSingleRange.aStart.Row();
9696         aJoinedRanges.insert( ScRowRangeHashMap::value_type( nSingleRow, aSingleRange ) );
9697         eState = STATE_COMPLEX;
9698         // continue normally
9699     }
9700 
9701     // This is called in the order of ScAttrRectIterator results.
9702     // rNewRange can only be joined with an existing entry if it's the same rows, starting in the next column.
9703     // If the old entry for the start row extends to a different end row, or ends in a different column, it
9704     // can be moved to aCompletedRanges because it can't be joined with following iterator results.
9705     // Everything happens within one sheet, so Tab can be ignored.
9706 
9707     SCROW nStartRow = rNewRange.aStart.Row();
9708     ScRowRangeHashMap::iterator aIter( aJoinedRanges.find( nStartRow ) );       // find the active entry for the start row
9709     if ( aIter != aJoinedRanges.end() )
9710     {
9711         ScRange& rOldRange = aIter->second;
9712         if ( rOldRange.aEnd.Row() == rNewRange.aEnd.Row() &&
9713              rOldRange.aEnd.Col() + 1 == rNewRange.aStart.Col() )
9714         {
9715             // extend existing range
9716             rOldRange.aEnd.SetCol( rNewRange.aEnd.Col() );
9717         }
9718         else
9719         {
9720             // move old range to aCompletedRanges, keep rNewRange for joining
9721             aCompletedRanges.push_back( rOldRange );
9722             rOldRange = rNewRange;  // replace in hash map
9723         }
9724     }
9725     else
9726     {
9727         // keep rNewRange for joining
9728         aJoinedRanges.insert( ScRowRangeHashMap::value_type( nStartRow, rNewRange ) );
9729     }
9730 }
9731 
9732 const ScRangeList& ScUniqueFormatsEntry::GetRanges()
9733 {
9734     if ( eState == STATE_SINGLE )
9735     {
9736         aReturnRanges = new ScRangeList;
9737         aReturnRanges->Append( aSingleRange );
9738         return *aReturnRanges;
9739     }
9740 
9741     // move remaining entries from aJoinedRanges to aCompletedRanges
9742 
9743     ScRowRangeHashMap::const_iterator aJoinedEnd = aJoinedRanges.end();
9744     for ( ScRowRangeHashMap::const_iterator aJoinedIter = aJoinedRanges.begin(); aJoinedIter != aJoinedEnd; ++aJoinedIter )
9745         aCompletedRanges.push_back( aJoinedIter->second );
9746     aJoinedRanges.clear();
9747 
9748     // sort all ranges for a predictable API result
9749 
9750     std::sort( aCompletedRanges.begin(), aCompletedRanges.end() );
9751 
9752     // fill and return ScRangeList
9753 
9754     aReturnRanges = new ScRangeList;
9755     ScRangeVector::const_iterator aCompEnd( aCompletedRanges.end() );
9756     for ( ScRangeVector::const_iterator aCompIter( aCompletedRanges.begin() ); aCompIter != aCompEnd; ++aCompIter )
9757         aReturnRanges->Append( *aCompIter );
9758     aCompletedRanges.clear();
9759 
9760     return *aReturnRanges;
9761 }
9762 
9763 typedef ::std::hash_map< const ScPatternAttr*, ScUniqueFormatsEntry, ScPatternHashCode > ScUniqueFormatsHashMap;
9764 
9765 // function object to sort the range lists by start of first range
9766 struct ScUniqueFormatsOrder
9767 {
9768     bool operator()( const ScRangeList& rList1, const ScRangeList& rList2 ) const
9769     {
9770         // all range lists have at least one entry
9771         DBG_ASSERT( rList1.Count() > 0 && rList2.Count() > 0, "ScUniqueFormatsOrder: empty list" );
9772 
9773         // compare start positions using ScAddress comparison operator
9774         return ( rList1.GetObject(0)->aStart < rList2.GetObject(0)->aStart );
9775     }
9776 };
9777 
9778 void ScUniqueCellFormatsObj::GetObjects_Impl()
9779 {
9780     if (pDocShell)
9781     {
9782         ScDocument* pDoc = pDocShell->GetDocument();
9783         SCTAB nTab = aTotalRange.aStart.Tab();
9784         ScAttrRectIterator aIter( pDoc, nTab,
9785                                     aTotalRange.aStart.Col(), aTotalRange.aStart.Row(),
9786                                     aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() );
9787         SCCOL nCol1, nCol2;
9788         SCROW nRow1, nRow2;
9789 
9790         // Collect the ranges for each format in a hash map, to avoid nested loops
9791 
9792         ScUniqueFormatsHashMap aHashMap;
9793         while (aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
9794         {
9795             ScRange aRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
9796             const ScPatternAttr* pPattern = pDoc->GetPattern(nCol1, nRow1, nTab);
9797             aHashMap[pPattern].Join( aRange );
9798         }
9799 
9800         // Fill the vector aRangeLists with the range lists from the hash map
9801 
9802         aRangeLists.reserve( aHashMap.size() );
9803         ScUniqueFormatsHashMap::iterator aMapIter( aHashMap.begin() );
9804         ScUniqueFormatsHashMap::iterator aMapEnd( aHashMap.end() );
9805         while ( aMapIter != aMapEnd )
9806         {
9807             ScUniqueFormatsEntry& rEntry = aMapIter->second;
9808             const ScRangeList& rRanges = rEntry.GetRanges();
9809             aRangeLists.push_back( rRanges );       // copy ScRangeList
9810             rEntry.Clear();                         // free memory, don't hold both copies of all ranges
9811             ++aMapIter;
9812         }
9813 
9814         // Sort the vector by first range's start position, to avoid random shuffling
9815         // due to using the ScPatterAttr pointers
9816 
9817         ScUniqueFormatsOrder aComp;
9818         ::std::sort( aRangeLists.begin(), aRangeLists.end(), aComp );
9819     }
9820 }
9821 
9822 // XIndexAccess
9823 
9824 sal_Int32 SAL_CALL ScUniqueCellFormatsObj::getCount() throw(uno::RuntimeException)
9825 {
9826     ScUnoGuard aGuard;
9827 
9828     return aRangeLists.size();
9829 }
9830 
9831 uno::Any SAL_CALL ScUniqueCellFormatsObj::getByIndex( sal_Int32 nIndex )
9832                             throw(lang::IndexOutOfBoundsException,
9833                                     lang::WrappedTargetException, uno::RuntimeException)
9834 {
9835     ScUnoGuard aGuard;
9836 
9837     if(static_cast<sal_uInt32>(nIndex) < aRangeLists.size())
9838         return uno::makeAny(uno::Reference<sheet::XSheetCellRangeContainer>(new ScCellRangesObj(pDocShell, aRangeLists[nIndex])));
9839     else
9840         throw lang::IndexOutOfBoundsException();
9841 //    return uno::Any();
9842 }
9843 
9844 uno::Type SAL_CALL ScUniqueCellFormatsObj::getElementType() throw(uno::RuntimeException)
9845 {
9846     ScUnoGuard aGuard;
9847     return getCppuType((uno::Reference<sheet::XSheetCellRangeContainer>*)0);
9848 }
9849 
9850 sal_Bool SAL_CALL ScUniqueCellFormatsObj::hasElements() throw(uno::RuntimeException)
9851 {
9852     ScUnoGuard aGuard;
9853     return ( aRangeLists.size() != 0 );
9854 }
9855 
9856 // XEnumerationAccess
9857 
9858 uno::Reference<container::XEnumeration> SAL_CALL ScUniqueCellFormatsObj::createEnumeration()
9859                                                     throw(uno::RuntimeException)
9860 {
9861     ScUnoGuard aGuard;
9862     if (pDocShell)
9863         return new ScUniqueCellFormatsEnumeration( pDocShell, aRangeLists );
9864     return NULL;
9865 }
9866 
9867 //------------------------------------------------------------------------
9868 
9869 ScUniqueCellFormatsEnumeration::ScUniqueCellFormatsEnumeration(ScDocShell* pDocSh, const ScMyRangeLists& rRangeLists) :
9870     aRangeLists(rRangeLists),
9871     pDocShell( pDocSh ),
9872     nCurrentPosition(0)
9873 {
9874     pDocShell->GetDocument()->AddUnoObject(*this);
9875 }
9876 
9877 ScUniqueCellFormatsEnumeration::~ScUniqueCellFormatsEnumeration()
9878 {
9879     if (pDocShell)
9880         pDocShell->GetDocument()->RemoveUnoObject(*this);
9881 }
9882 
9883 void ScUniqueCellFormatsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
9884 {
9885     if ( rHint.ISA( ScUpdateRefHint ) )
9886     {
9887         //! und nun ???
9888     }
9889     else if ( rHint.ISA( SfxSimpleHint ) )
9890     {
9891         sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
9892         if ( nId == SFX_HINT_DYING )
9893             pDocShell = NULL;                       // ungueltig geworden
9894     }
9895 }
9896 
9897 // XEnumeration
9898 
9899 sal_Bool SAL_CALL ScUniqueCellFormatsEnumeration::hasMoreElements() throw(uno::RuntimeException)
9900 {
9901     ScUnoGuard aGuard;
9902     return static_cast<sal_uInt32>(nCurrentPosition) < aRangeLists.size();
9903 }
9904 
9905 uno::Any SAL_CALL ScUniqueCellFormatsEnumeration::nextElement() throw(container::NoSuchElementException,
9906                                         lang::WrappedTargetException, uno::RuntimeException)
9907 {
9908     ScUnoGuard aGuard;
9909 
9910     if ( !hasMoreElements() || !pDocShell )
9911         throw container::NoSuchElementException();      // no more elements
9912 
9913     // Interface-Typ muss zu ScCellFormatsObj::getElementType passen
9914 
9915     return uno::makeAny(uno::Reference<sheet::XSheetCellRangeContainer>(new ScCellRangesObj(pDocShell, aRangeLists[nCurrentPosition++])));
9916 }
9917 
9918 
9919