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