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