tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / unoobj / cellsuno.cxx
blob5bacf8a856b8021b11622a1c710ac8c8e3593e32
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <scitems.hxx>
21 #include <editeng/eeitem.hxx>
22 #include <o3tl/safeint.hxx>
23 #include <svx/svdpool.hxx>
25 #include <utility>
26 #include <vcl/svapp.hxx>
27 #include <svx/algitem.hxx>
28 #include <editeng/borderline.hxx>
29 #include <editeng/boxitem.hxx>
30 #include <editeng/editeng.hxx>
31 #include <editeng/flditem.hxx>
32 #include <editeng/editobj.hxx>
33 #include <editeng/unoipset.hxx>
34 #include <editeng/langitem.hxx>
35 #include <sfx2/linkmgr.hxx>
36 #include <svl/numformat.hxx>
37 #include <svl/srchitem.hxx>
38 #include <svl/sharedstringpool.hxx>
39 #include <svx/unomid.hxx>
40 #include <editeng/unoprnms.hxx>
41 #include <editeng/unotext.hxx>
42 #include <svx/svdpage.hxx>
43 #include <sfx2/bindings.hxx>
44 #include <svl/zforlist.hxx>
45 #include <svl/zformat.hxx>
46 #include <cppuhelper/supportsservice.hxx>
47 #include <float.h>
48 #include <cppuhelper/queryinterface.hxx>
49 #include <comphelper/diagnose_ex.hxx>
50 #include <tools/UnitConversion.hxx>
52 #include <com/sun/star/awt/XBitmap.hpp>
53 #include <com/sun/star/util/CellProtection.hpp>
54 #include <com/sun/star/table/CellHoriJustify.hpp>
55 #include <com/sun/star/table/CellOrientation.hpp>
56 #include <com/sun/star/table/ShadowFormat.hpp>
57 #include <com/sun/star/table/TableBorder.hpp>
58 #include <com/sun/star/table/TableBorder2.hpp>
59 #include <com/sun/star/sheet/CellFlags.hpp>
60 #include <com/sun/star/sheet/FormulaResult.hpp>
61 #include <com/sun/star/beans/PropertyAttribute.hpp>
62 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
63 #include <com/sun/star/lang/Locale.hpp>
64 #include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
65 #include <com/sun/star/beans/SetPropertyTolerantFailed.hpp>
66 #include <com/sun/star/text/WritingMode2.hpp>
67 #include <com/sun/star/text/textfield/Type.hpp>
68 #include <com/sun/star/sheet/XConditionalFormats.hpp>
69 #include <com/sun/star/sheet/XSolverSettings.hpp>
71 #include <autoform.hxx>
72 #include <cellvalue.hxx>
73 #include <cellmergeoption.hxx>
74 #include <cellsuno.hxx>
75 #include <cursuno.hxx>
76 #include <textuno.hxx>
77 #include <editsrc.hxx>
78 #include <notesuno.hxx>
79 #include <fielduno.hxx>
80 #include <docuno.hxx>
81 #include <datauno.hxx>
82 #include <dapiuno.hxx>
83 #include <chartuno.hxx>
84 #include <fmtuno.hxx>
85 #include <miscuno.hxx>
86 #include <convuno.hxx>
87 #include <srchuno.hxx>
88 #include <nameuno.hxx>
89 #include <targuno.hxx>
90 #include <tokenuno.hxx>
91 #include <eventuno.hxx>
92 #include <docsh.hxx>
93 #include <markdata.hxx>
94 #include <patattr.hxx>
95 #include <docpool.hxx>
96 #include <docfunc.hxx>
97 #include <dbdocfun.hxx>
98 #include <olinefun.hxx>
99 #include <hints.hxx>
100 #include <formulacell.hxx>
101 #include <undotab.hxx>
102 #include <undoblk.hxx>
103 #include <stlsheet.hxx>
104 #include <dbdata.hxx>
105 #include <attrib.hxx>
106 #include <chartarr.hxx>
107 #include <chartlis.hxx>
108 #include <drwlayer.hxx>
109 #include <printfun.hxx>
110 #include <prnsave.hxx>
111 #include <tablink.hxx>
112 #include <dociter.hxx>
113 #include <rangeutl.hxx>
114 #include <conditio.hxx>
115 #include <validat.hxx>
116 #include <sc.hrc>
117 #include <cellform.hxx>
118 #include <globstr.hrc>
119 #include <scresid.hxx>
120 #include <unonames.hxx>
121 #include <styleuno.hxx>
122 #include <rangeseq.hxx>
123 #include <unowids.hxx>
124 #include <paramisc.hxx>
125 #include <queryentry.hxx>
126 #include <formula/errorcodes.hxx>
127 #include <unoreflist.hxx>
128 #include <formula/grammar.hxx>
129 #include <editeng/escapementitem.hxx>
130 #include <stringutil.hxx>
131 #include <formulaiter.hxx>
132 #include <tokenarray.hxx>
133 #include <stylehelper.hxx>
134 #include <dputil.hxx>
135 #include <sortparam.hxx>
136 #include <condformatuno.hxx>
137 #include <TablePivotCharts.hxx>
138 #include <table.hxx>
139 #include <refundo.hxx>
140 #include <columnspanset.hxx>
141 #include <CommonProperties.hxx>
142 #include <solveruno.hxx>
144 #include <memory>
146 using namespace com::sun::star;
148 // The names in the maps must be sorted according to strcmp!
149 //! Instead of Which-ID 0 use special IDs and do not compare via names!
151 // Left/Right/Top/BottomBorder are mapped directly to the core items,
152 // not collected/applied to the borders of a range -> ATTR_BORDER can be used directly
154 static const SfxItemPropertySet* lcl_GetCellsPropertySet()
156 static const SfxItemPropertyMapEntry aCellsPropertyMap_Impl[] =
158 { SC_UNONAME_ABSNAME, SC_WID_UNO_ABSNAME, cppu::UnoType<OUString>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
159 { SC_UNONAME_ASIANVERT,ATTR_VERTICAL_ASIAN,cppu::UnoType<bool>::get(), 0, 0 },
160 CELL_BORDER_PROPERTIES
161 CELL_BACKGROUND_COLOR_PROPERTIES
162 { SC_UNONAME_CELLPRO, ATTR_PROTECTION, cppu::UnoType<util::CellProtection>::get(), 0, 0 },
163 { SC_UNONAME_CELLSTYL, SC_WID_UNO_CELLSTYL,cppu::UnoType<OUString>::get(), 0, 0 },
164 CHAR_COLOR_PROPERTIES
165 { SC_UNONAME_COUTL, ATTR_FONT_CONTOUR, cppu::UnoType<bool>::get(), 0, 0 },
166 { SC_UNONAME_CCROSS, ATTR_FONT_CROSSEDOUT,cppu::UnoType<bool>::get(), 0, MID_CROSSED_OUT },
167 { SC_UNONAME_CEMPHAS, ATTR_FONT_EMPHASISMARK,cppu::UnoType<sal_Int16>::get(), 0, MID_EMPHASIS },
168 { SC_UNONAME_CFONT, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
169 { SC_UNONAME_CFCHARS, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
170 { SC_UNO_CJK_CFCHARS, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
171 { SC_UNO_CTL_CFCHARS, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
172 { SC_UNONAME_CFFAMIL, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
173 { SC_UNO_CJK_CFFAMIL, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
174 { SC_UNO_CTL_CFFAMIL, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
175 { SC_UNONAME_CFNAME, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
176 { SC_UNO_CJK_CFNAME, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
177 { SC_UNO_CTL_CFNAME, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
178 { SC_UNONAME_CFPITCH, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
179 { SC_UNO_CJK_CFPITCH, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
180 { SC_UNO_CTL_CFPITCH, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
181 { SC_UNONAME_CFSTYLE, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
182 { SC_UNO_CJK_CFSTYLE, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
183 { SC_UNO_CTL_CFSTYLE, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
184 { SC_UNONAME_CHEIGHT, ATTR_FONT_HEIGHT, cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
185 { SC_UNO_CJK_CHEIGHT, ATTR_CJK_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
186 { SC_UNO_CTL_CHEIGHT, ATTR_CTL_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
187 { SC_UNONAME_CLOCAL, ATTR_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
188 { SC_UNO_CJK_CLOCAL, ATTR_CJK_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
189 { SC_UNO_CTL_CLOCAL, ATTR_CTL_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
190 { SC_UNONAME_COVER, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
191 { SC_UNONAME_COVRLCOL, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
192 { SC_UNONAME_COVRLHAS, ATTR_FONT_OVERLINE, cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
193 { SC_UNONAME_CPOST, ATTR_FONT_POSTURE, cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
194 { SC_UNO_CJK_CPOST, ATTR_CJK_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
195 { SC_UNO_CTL_CPOST, ATTR_CTL_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
196 { SC_UNONAME_CRELIEF, ATTR_FONT_RELIEF, cppu::UnoType<sal_Int16>::get(), 0, MID_RELIEF },
197 { SC_UNONAME_CSHADD, ATTR_FONT_SHADOWED, cppu::UnoType<bool>::get(), 0, 0 },
198 { SC_UNONAME_CSTRIKE, ATTR_FONT_CROSSEDOUT,cppu::UnoType<sal_Int16>::get(), 0, MID_CROSS_OUT },
199 { SC_UNONAME_CUNDER, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
200 { SC_UNONAME_CUNDLCOL, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
201 { SC_UNONAME_CUNDLHAS, ATTR_FONT_UNDERLINE,cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
202 { SC_UNONAME_CWEIGHT, ATTR_FONT_WEIGHT, cppu::UnoType<float>::get(), 0, MID_WEIGHT },
203 { SC_UNO_CJK_CWEIGHT, ATTR_CJK_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
204 { SC_UNO_CTL_CWEIGHT, ATTR_CTL_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
205 { SC_UNONAME_CWORDMOD, ATTR_FONT_WORDLINE, cppu::UnoType<bool>::get(), 0, 0 },
206 { SC_UNONAME_CHCOLHDR, SC_WID_UNO_CHCOLHDR,cppu::UnoType<bool>::get(), 0, 0 },
207 { SC_UNONAME_CHROWHDR, SC_WID_UNO_CHROWHDR,cppu::UnoType<bool>::get(), 0, 0 },
208 { SC_UNONAME_CONDFMT, SC_WID_UNO_CONDFMT, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
209 { SC_UNONAME_CONDLOC, SC_WID_UNO_CONDLOC, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
210 { SC_UNONAME_CONDXML, SC_WID_UNO_CONDXML, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
211 { SC_UNONAME_DIAGONAL_BLTR, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
212 { SC_UNONAME_DIAGONAL_BLTR2, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
213 { SC_UNONAME_DIAGONAL_TLBR, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
214 { SC_UNONAME_DIAGONAL_TLBR2, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
215 { SC_UNONAME_CELLHJUS, ATTR_HOR_JUSTIFY, cppu::UnoType<table::CellHoriJustify>::get(), 0, MID_HORJUST_HORJUST },
216 { SC_UNONAME_CELLHJUS_METHOD, ATTR_HOR_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
217 { SC_UNONAME_CELLTRAN, ATTR_BACKGROUND, cppu::UnoType<bool>::get(), 0, MID_GRAPHIC_TRANSPARENT },
218 { SC_UNONAME_WRAP, ATTR_LINEBREAK, cppu::UnoType<bool>::get(), 0, 0 },
219 { SC_UNONAME_NUMFMT, ATTR_VALUE_FORMAT, cppu::UnoType<sal_Int32>::get(), 0, 0 },
220 { SC_UNONAME_NUMRULES, SC_WID_UNO_NUMRULES,cppu::UnoType<container::XIndexReplace>::get(), 0, 0 },
221 { SC_UNONAME_CELLORI, ATTR_STACKED, cppu::UnoType<table::CellOrientation>::get(), 0, 0 },
222 { SC_UNONAME_PADJUST, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
223 { SC_UNONAME_PBMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
224 { SC_UNONAME_PINDENT, ATTR_INDENT, cppu::UnoType<sal_Int16>::get(), 0, 0 }, //! CONVERT_TWIPS
225 { SC_UNONAME_PISCHDIST,ATTR_SCRIPTSPACE, cppu::UnoType<bool>::get(), 0, 0 },
226 { SC_UNONAME_PISFORBID,ATTR_FORBIDDEN_RULES,cppu::UnoType<bool>::get(), 0, 0 },
227 { SC_UNONAME_PISHANG, ATTR_HANGPUNCTUATION,cppu::UnoType<bool>::get(), 0, 0 },
228 { SC_UNONAME_PISHYPHEN,ATTR_HYPHENATE, cppu::UnoType<bool>::get(), 0, 0 },
229 { SC_UNONAME_PLASTADJ, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
230 { SC_UNONAME_PLMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
231 { SC_UNONAME_PRMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
232 { SC_UNONAME_PTMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
233 { SC_UNONAME_ROTANG, ATTR_ROTATE_VALUE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
234 { SC_UNONAME_ROTREF, ATTR_ROTATE_MODE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
235 { SC_UNONAME_SHADOW, ATTR_SHADOW, cppu::UnoType<table::ShadowFormat>::get(), 0, 0 | CONVERT_TWIPS },
236 { SC_UNONAME_SHRINK_TO_FIT, ATTR_SHRINKTOFIT, cppu::UnoType<bool>::get(), 0, 0 },
237 { SC_UNONAME_TBLBORD, SC_WID_UNO_TBLBORD, cppu::UnoType<table::TableBorder>::get(), 0, 0 | CONVERT_TWIPS },
238 { SC_UNONAME_TBLBORD2, SC_WID_UNO_TBLBORD2, cppu::UnoType<table::TableBorder2>::get(), 0, 0 | CONVERT_TWIPS },
239 { SC_UNONAME_USERDEF, ATTR_USERDEF, cppu::UnoType<container::XNameContainer>::get(), 0, 0 },
240 { SC_UNONAME_VALIDAT, SC_WID_UNO_VALIDAT, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
241 { SC_UNONAME_VALILOC, SC_WID_UNO_VALILOC, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
242 { SC_UNONAME_VALIXML, SC_WID_UNO_VALIXML, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
243 { SC_UNONAME_CELLVJUS, ATTR_VER_JUSTIFY, cppu::UnoType<sal_Int32>::get(), 0, 0 },
244 { SC_UNONAME_CELLVJUS_METHOD, ATTR_VER_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
245 { SC_UNONAME_WRITING, ATTR_WRITINGDIR, cppu::UnoType<sal_Int16>::get(), 0, 0 },
246 { SC_UNONAME_HYPERLINK, ATTR_HYPERLINK, cppu::UnoType<OUString>::get(), 0, 0 },
247 { SC_UNONAME_FORMATID, SC_WID_UNO_FORMATID, cppu::UnoType<sal_uInt64>::get(), 0, 0 },
249 static SfxItemPropertySet aCellsPropertySet( aCellsPropertyMap_Impl );
250 return &aCellsPropertySet;
253 // CellRange contains all entries from Cells, plus its own entries
254 // with Which-ID 0 (those are needed only for getPropertySetInfo).
256 static const SfxItemPropertySet* lcl_GetRangePropertySet()
258 static const SfxItemPropertyMapEntry aRangePropertyMap_Impl[] =
260 { SC_UNONAME_ABSNAME, SC_WID_UNO_ABSNAME, cppu::UnoType<OUString>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
261 { SC_UNONAME_ASIANVERT,ATTR_VERTICAL_ASIAN,cppu::UnoType<bool>::get(), 0, 0 },
262 CELL_BORDER_PROPERTIES
263 CELL_BACKGROUND_COLOR_PROPERTIES
264 { SC_UNONAME_CELLPRO, ATTR_PROTECTION, cppu::UnoType<util::CellProtection>::get(), 0, 0 },
265 { SC_UNONAME_CELLSTYL, SC_WID_UNO_CELLSTYL,cppu::UnoType<OUString>::get(), 0, 0 },
266 CHAR_COLOR_PROPERTIES
267 { SC_UNONAME_COUTL, ATTR_FONT_CONTOUR, cppu::UnoType<bool>::get(), 0, 0 },
268 { SC_UNONAME_CCROSS, ATTR_FONT_CROSSEDOUT,cppu::UnoType<bool>::get(), 0, MID_CROSSED_OUT },
269 { SC_UNONAME_CEMPHAS, ATTR_FONT_EMPHASISMARK,cppu::UnoType<sal_Int16>::get(), 0, MID_EMPHASIS },
270 { SC_UNONAME_CFONT, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
271 { SC_UNONAME_CFCHARS, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
272 { SC_UNO_CJK_CFCHARS, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
273 { SC_UNO_CTL_CFCHARS, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
274 { SC_UNONAME_CFFAMIL, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
275 { SC_UNO_CJK_CFFAMIL, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
276 { SC_UNO_CTL_CFFAMIL, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
277 { SC_UNONAME_CFNAME, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
278 { SC_UNO_CJK_CFNAME, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
279 { SC_UNO_CTL_CFNAME, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
280 { SC_UNONAME_CFPITCH, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
281 { SC_UNO_CJK_CFPITCH, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
282 { SC_UNO_CTL_CFPITCH, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
283 { SC_UNONAME_CFSTYLE, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
284 { SC_UNO_CJK_CFSTYLE, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
285 { SC_UNO_CTL_CFSTYLE, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
286 { SC_UNONAME_CHEIGHT, ATTR_FONT_HEIGHT, cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
287 { SC_UNO_CJK_CHEIGHT, ATTR_CJK_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
288 { SC_UNO_CTL_CHEIGHT, ATTR_CTL_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
289 { SC_UNONAME_CLOCAL, ATTR_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
290 { SC_UNO_CJK_CLOCAL, ATTR_CJK_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
291 { SC_UNO_CTL_CLOCAL, ATTR_CTL_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
292 { SC_UNONAME_COVER, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
293 { SC_UNONAME_COVRLCOL, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
294 { SC_UNONAME_COVRLHAS, ATTR_FONT_OVERLINE, cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
295 { SC_UNONAME_CPOST, ATTR_FONT_POSTURE, cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
296 { SC_UNO_CJK_CPOST, ATTR_CJK_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
297 { SC_UNO_CTL_CPOST, ATTR_CTL_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
298 { SC_UNONAME_CRELIEF, ATTR_FONT_RELIEF, cppu::UnoType<sal_Int16>::get(), 0, MID_RELIEF },
299 { SC_UNONAME_CSHADD, ATTR_FONT_SHADOWED, cppu::UnoType<bool>::get(), 0, 0 },
300 { SC_UNONAME_CSTRIKE, ATTR_FONT_CROSSEDOUT,cppu::UnoType<sal_Int16>::get(), 0, MID_CROSS_OUT },
301 { SC_UNONAME_CUNDER, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
302 { SC_UNONAME_CUNDLCOL, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
303 { SC_UNONAME_CUNDLHAS, ATTR_FONT_UNDERLINE,cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
304 { SC_UNONAME_CWEIGHT, ATTR_FONT_WEIGHT, cppu::UnoType<float>::get(), 0, MID_WEIGHT },
305 { SC_UNO_CJK_CWEIGHT, ATTR_CJK_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
306 { SC_UNO_CTL_CWEIGHT, ATTR_CTL_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
307 { SC_UNONAME_CWORDMOD, ATTR_FONT_WORDLINE, cppu::UnoType<bool>::get(), 0, 0 },
308 { SC_UNONAME_CHCOLHDR, SC_WID_UNO_CHCOLHDR,cppu::UnoType<bool>::get(), 0, 0 },
309 { SC_UNONAME_CHROWHDR, SC_WID_UNO_CHROWHDR,cppu::UnoType<bool>::get(), 0, 0 },
310 { SC_UNONAME_CONDFMT, SC_WID_UNO_CONDFMT, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
311 { SC_UNONAME_CONDLOC, SC_WID_UNO_CONDLOC, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
312 { SC_UNONAME_CONDXML, SC_WID_UNO_CONDXML, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
313 { SC_UNONAME_DIAGONAL_BLTR, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
314 { SC_UNONAME_DIAGONAL_BLTR2, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
315 { SC_UNONAME_DIAGONAL_TLBR, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
316 { SC_UNONAME_DIAGONAL_TLBR2, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
317 { SC_UNONAME_CELLHJUS, ATTR_HOR_JUSTIFY, cppu::UnoType<table::CellHoriJustify>::get(), 0, MID_HORJUST_HORJUST },
318 { SC_UNONAME_CELLHJUS_METHOD, ATTR_HOR_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
319 { SC_UNONAME_CELLTRAN, ATTR_BACKGROUND, cppu::UnoType<bool>::get(), 0, MID_GRAPHIC_TRANSPARENT },
320 { SC_UNONAME_WRAP, ATTR_LINEBREAK, cppu::UnoType<bool>::get(), 0, 0 },
321 { SC_UNONAME_NUMFMT, ATTR_VALUE_FORMAT, cppu::UnoType<sal_Int32>::get(), 0, 0 },
322 { SC_UNONAME_NUMRULES, SC_WID_UNO_NUMRULES,cppu::UnoType<container::XIndexReplace>::get(), 0, 0 },
323 { SC_UNONAME_CELLORI, ATTR_STACKED, cppu::UnoType<table::CellOrientation>::get(), 0, 0 },
324 { SC_UNONAME_PADJUST, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
325 { SC_UNONAME_PBMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
326 { SC_UNONAME_PINDENT, ATTR_INDENT, cppu::UnoType<sal_Int16>::get(), 0, 0 }, //! CONVERT_TWIPS
327 { SC_UNONAME_PISCHDIST,ATTR_SCRIPTSPACE, cppu::UnoType<bool>::get(), 0, 0 },
328 { SC_UNONAME_PISFORBID,ATTR_FORBIDDEN_RULES,cppu::UnoType<bool>::get(), 0, 0 },
329 { SC_UNONAME_PISHANG, ATTR_HANGPUNCTUATION,cppu::UnoType<bool>::get(), 0, 0 },
330 { SC_UNONAME_PISHYPHEN,ATTR_HYPHENATE, cppu::UnoType<bool>::get(), 0, 0 },
331 { SC_UNONAME_PLASTADJ, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
332 { SC_UNONAME_PLMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
333 { SC_UNONAME_PRMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
334 { SC_UNONAME_PTMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
335 { SC_UNONAME_POS, SC_WID_UNO_POS, cppu::UnoType<awt::Point>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
336 { SC_UNONAME_ROTANG, ATTR_ROTATE_VALUE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
337 { SC_UNONAME_ROTREF, ATTR_ROTATE_MODE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
338 { SC_UNONAME_SHADOW, ATTR_SHADOW, cppu::UnoType<table::ShadowFormat>::get(), 0, 0 | CONVERT_TWIPS },
339 { SC_UNONAME_SHRINK_TO_FIT, ATTR_SHRINKTOFIT, cppu::UnoType<bool>::get(), 0, 0 },
340 { SC_UNONAME_SIZE, SC_WID_UNO_SIZE, cppu::UnoType<awt::Size>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
341 { SC_UNONAME_TBLBORD, SC_WID_UNO_TBLBORD, cppu::UnoType<table::TableBorder>::get(), 0, 0 | CONVERT_TWIPS },
342 { SC_UNONAME_TBLBORD2, SC_WID_UNO_TBLBORD2, cppu::UnoType<table::TableBorder2>::get(), 0, 0 | CONVERT_TWIPS },
343 { SC_UNONAME_USERDEF, ATTR_USERDEF, cppu::UnoType<container::XNameContainer>::get(), 0, 0 },
344 { SC_UNONAME_VALIDAT, SC_WID_UNO_VALIDAT, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
345 { SC_UNONAME_VALILOC, SC_WID_UNO_VALILOC, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
346 { SC_UNONAME_VALIXML, SC_WID_UNO_VALIXML, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
347 { SC_UNONAME_CELLVJUS, ATTR_VER_JUSTIFY, cppu::UnoType<sal_Int32>::get(), 0, 0 },
348 { SC_UNONAME_CELLVJUS_METHOD, ATTR_VER_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
349 { SC_UNONAME_WRITING, ATTR_WRITINGDIR, cppu::UnoType<sal_Int16>::get(), 0, 0 },
350 { SC_UNONAME_FORMATID, SC_WID_UNO_FORMATID, cppu::UnoType<sal_uInt64>::get(), 0, 0 },
352 static SfxItemPropertySet aRangePropertySet( aRangePropertyMap_Impl );
353 return &aRangePropertySet;
356 // Cell contains entries from CellRange, plus its own entries
357 // with Which-ID 0 (those are needed only for getPropertySetInfo).
359 static const SfxItemPropertySet* lcl_GetCellPropertySet()
361 static const SfxItemPropertyMapEntry aCellPropertyMap_Impl[] =
363 { SC_UNONAME_ABSNAME, SC_WID_UNO_ABSNAME, cppu::UnoType<OUString>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
364 { SC_UNONAME_ASIANVERT,ATTR_VERTICAL_ASIAN,cppu::UnoType<bool>::get(), 0, 0 },
365 CELL_BORDER_PROPERTIES
366 CELL_BACKGROUND_COLOR_PROPERTIES
367 { SC_UNONAME_CELLPRO, ATTR_PROTECTION, cppu::UnoType<util::CellProtection>::get(), 0, 0 },
368 { SC_UNONAME_CELLSTYL, SC_WID_UNO_CELLSTYL,cppu::UnoType<OUString>::get(), 0, 0 },
369 CHAR_COLOR_PROPERTIES
370 { SC_UNONAME_COUTL, ATTR_FONT_CONTOUR, cppu::UnoType<bool>::get(), 0, 0 },
371 { SC_UNONAME_CCROSS, ATTR_FONT_CROSSEDOUT,cppu::UnoType<bool>::get(), 0, MID_CROSSED_OUT },
372 { SC_UNONAME_CEMPHAS, ATTR_FONT_EMPHASISMARK,cppu::UnoType<sal_Int16>::get(), 0, MID_EMPHASIS },
373 { SC_UNONAME_CFONT, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
374 { SC_UNONAME_CFCHARS, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
375 { SC_UNO_CJK_CFCHARS, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
376 { SC_UNO_CTL_CFCHARS, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
377 { SC_UNONAME_CFFAMIL, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
378 { SC_UNO_CJK_CFFAMIL, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
379 { SC_UNO_CTL_CFFAMIL, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
380 { SC_UNONAME_CFNAME, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
381 { SC_UNO_CJK_CFNAME, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
382 { SC_UNO_CTL_CFNAME, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
383 { SC_UNONAME_CFPITCH, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
384 { SC_UNO_CJK_CFPITCH, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
385 { SC_UNO_CTL_CFPITCH, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
386 { SC_UNONAME_CFSTYLE, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
387 { SC_UNO_CJK_CFSTYLE, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
388 { SC_UNO_CTL_CFSTYLE, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
389 { SC_UNONAME_CHEIGHT, ATTR_FONT_HEIGHT, cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
390 { SC_UNO_CJK_CHEIGHT, ATTR_CJK_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
391 { SC_UNO_CTL_CHEIGHT, ATTR_CTL_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
392 { SC_UNONAME_CLOCAL, ATTR_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
393 { SC_UNO_CJK_CLOCAL, ATTR_CJK_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
394 { SC_UNO_CTL_CLOCAL, ATTR_CTL_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
395 { SC_UNONAME_COVER, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
396 { SC_UNONAME_COVRLCOL, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
397 { SC_UNONAME_COVRLHAS, ATTR_FONT_OVERLINE, cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
398 { SC_UNONAME_CPOST, ATTR_FONT_POSTURE, cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
399 { SC_UNO_CJK_CPOST, ATTR_CJK_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
400 { SC_UNO_CTL_CPOST, ATTR_CTL_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
401 { SC_UNONAME_CRELIEF, ATTR_FONT_RELIEF, cppu::UnoType<sal_Int16>::get(), 0, MID_RELIEF },
402 { SC_UNONAME_CSHADD, ATTR_FONT_SHADOWED, cppu::UnoType<bool>::get(), 0, 0 },
403 { SC_UNONAME_CSTRIKE, ATTR_FONT_CROSSEDOUT,cppu::UnoType<sal_Int16>::get(), 0, MID_CROSS_OUT },
404 { SC_UNONAME_CUNDER, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
405 { SC_UNONAME_CUNDLCOL, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
406 { SC_UNONAME_CUNDLHAS, ATTR_FONT_UNDERLINE,cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
407 { SC_UNONAME_CWEIGHT, ATTR_FONT_WEIGHT, cppu::UnoType<float>::get(), 0, MID_WEIGHT },
408 { SC_UNO_CJK_CWEIGHT, ATTR_CJK_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
409 { SC_UNO_CTL_CWEIGHT, ATTR_CTL_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
410 { SC_UNONAME_CWORDMOD, ATTR_FONT_WORDLINE, cppu::UnoType<bool>::get(), 0, 0 },
411 { SC_UNONAME_CHCOLHDR, SC_WID_UNO_CHCOLHDR,cppu::UnoType<bool>::get(), 0, 0 },
412 { SC_UNONAME_CHROWHDR, SC_WID_UNO_CHROWHDR,cppu::UnoType<bool>::get(), 0, 0 },
413 { SC_UNONAME_CONDFMT, SC_WID_UNO_CONDFMT, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
414 { SC_UNONAME_CONDLOC, SC_WID_UNO_CONDLOC, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
415 { SC_UNONAME_CONDXML, SC_WID_UNO_CONDXML, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
416 { SC_UNONAME_DIAGONAL_BLTR, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
417 { SC_UNONAME_DIAGONAL_BLTR2, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
418 { SC_UNONAME_DIAGONAL_TLBR, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
419 { SC_UNONAME_DIAGONAL_TLBR2, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
420 { SC_UNONAME_FORMLOC, SC_WID_UNO_FORMLOC, cppu::UnoType<OUString>::get(), 0, 0 },
421 { SC_UNONAME_FORMRT, SC_WID_UNO_FORMRT, cppu::UnoType<table::CellContentType>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
422 { SC_UNONAME_CELLCONTENTTYPE, SC_WID_UNO_CELLCONTENTTYPE, cppu::UnoType<table::CellContentType>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
423 { SC_UNONAME_FORMRT2, SC_WID_UNO_FORMRT2, cppu::UnoType<sal_Int32>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
424 { SC_UNONAME_CELLHJUS, ATTR_HOR_JUSTIFY, cppu::UnoType<table::CellHoriJustify>::get(), 0, MID_HORJUST_HORJUST },
425 { SC_UNONAME_CELLHJUS_METHOD, ATTR_HOR_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
426 { SC_UNONAME_CELLTRAN, ATTR_BACKGROUND, cppu::UnoType<bool>::get(), 0, MID_GRAPHIC_TRANSPARENT },
427 { SC_UNONAME_WRAP, ATTR_LINEBREAK, cppu::UnoType<bool>::get(), 0, 0 },
428 { SC_UNONAME_NUMFMT, ATTR_VALUE_FORMAT, cppu::UnoType<sal_Int32>::get(), 0, 0 },
429 { SC_UNONAME_NUMRULES, SC_WID_UNO_NUMRULES,cppu::UnoType<container::XIndexReplace>::get(), 0, 0 },
430 { SC_UNONAME_CELLORI, ATTR_STACKED, cppu::UnoType<table::CellOrientation>::get(), 0, 0 },
431 { SC_UNONAME_PADJUST, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
432 { SC_UNONAME_PBMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
433 { SC_UNONAME_PINDENT, ATTR_INDENT, cppu::UnoType<sal_Int16>::get(), 0, 0 }, //! CONVERT_TWIPS
434 { SC_UNONAME_PISCHDIST,ATTR_SCRIPTSPACE, cppu::UnoType<bool>::get(), 0, 0 },
435 { SC_UNONAME_PISFORBID,ATTR_FORBIDDEN_RULES,cppu::UnoType<bool>::get(), 0, 0 },
436 { SC_UNONAME_PISHANG, ATTR_HANGPUNCTUATION,cppu::UnoType<bool>::get(), 0, 0 },
437 { SC_UNONAME_PISHYPHEN,ATTR_HYPHENATE, cppu::UnoType<bool>::get(), 0, 0 },
438 { SC_UNONAME_PLASTADJ, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
439 { SC_UNONAME_PLMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
440 { SC_UNONAME_PRMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
441 { SC_UNONAME_PTMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
442 { SC_UNONAME_POS, SC_WID_UNO_POS, cppu::UnoType<awt::Point>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
443 { SC_UNONAME_ROTANG, ATTR_ROTATE_VALUE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
444 { SC_UNONAME_ROTREF, ATTR_ROTATE_MODE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
445 { SC_UNONAME_SHADOW, ATTR_SHADOW, cppu::UnoType<table::ShadowFormat>::get(), 0, 0 | CONVERT_TWIPS },
446 { SC_UNONAME_SHRINK_TO_FIT, ATTR_SHRINKTOFIT, cppu::UnoType<bool>::get(), 0, 0 },
447 { SC_UNONAME_SIZE, SC_WID_UNO_SIZE, cppu::UnoType<awt::Size>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
448 { SC_UNONAME_TBLBORD, SC_WID_UNO_TBLBORD, cppu::UnoType<table::TableBorder>::get(), 0, 0 | CONVERT_TWIPS },
449 { SC_UNONAME_TBLBORD2, SC_WID_UNO_TBLBORD2, cppu::UnoType<table::TableBorder2>::get(), 0, 0 | CONVERT_TWIPS },
450 { SC_UNONAME_USERDEF, ATTR_USERDEF, cppu::UnoType<container::XNameContainer>::get(), 0, 0 },
451 { SC_UNONAME_VALIDAT, SC_WID_UNO_VALIDAT, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
452 { SC_UNONAME_VALILOC, SC_WID_UNO_VALILOC, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
453 { SC_UNONAME_VALIXML, SC_WID_UNO_VALIXML, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
454 { SC_UNONAME_CELLVJUS, ATTR_VER_JUSTIFY, cppu::UnoType<sal_Int32>::get(), 0, 0 },
455 { SC_UNONAME_CELLVJUS_METHOD, ATTR_VER_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
456 { SC_UNONAME_WRITING, ATTR_WRITINGDIR, cppu::UnoType<sal_Int16>::get(), 0, 0 },
457 { UNO_NAME_EDIT_CHAR_ESCAPEMENT, EE_CHAR_ESCAPEMENT, cppu::UnoType<sal_Int32>::get(), 0, 0 },
458 { SC_UNONAME_HYPERLINK, ATTR_HYPERLINK, cppu::UnoType<OUString>::get(), 0, 0 },
459 { SC_UNONAME_FORMATID, SC_WID_UNO_FORMATID, cppu::UnoType<sal_uInt64>::get(), 0, 0 },
461 static SfxItemPropertySet aCellPropertySet( aCellPropertyMap_Impl );
462 return &aCellPropertySet;
465 // Column and Row contain all entries from CellRange, plus its own entries
466 // with Which-ID 0 (those are needed only for getPropertySetInfo).
468 static const SfxItemPropertySet* lcl_GetColumnPropertySet()
470 static const SfxItemPropertyMapEntry aColumnPropertyMap_Impl[] =
472 { SC_UNONAME_ABSNAME, SC_WID_UNO_ABSNAME, cppu::UnoType<OUString>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
473 { SC_UNONAME_ASIANVERT,ATTR_VERTICAL_ASIAN,cppu::UnoType<bool>::get(), 0, 0 },
474 CELL_BORDER_PROPERTIES
475 CELL_BACKGROUND_COLOR_PROPERTIES
476 { SC_UNONAME_CELLPRO, ATTR_PROTECTION, cppu::UnoType<util::CellProtection>::get(), 0, 0 },
477 { SC_UNONAME_CELLSTYL, SC_WID_UNO_CELLSTYL,cppu::UnoType<OUString>::get(), 0, 0 },
478 CHAR_COLOR_PROPERTIES
479 { SC_UNONAME_COUTL, ATTR_FONT_CONTOUR, cppu::UnoType<bool>::get(), 0, 0 },
480 { SC_UNONAME_CCROSS, ATTR_FONT_CROSSEDOUT,cppu::UnoType<bool>::get(), 0, MID_CROSSED_OUT },
481 { SC_UNONAME_CEMPHAS, ATTR_FONT_EMPHASISMARK,cppu::UnoType<sal_Int16>::get(), 0, MID_EMPHASIS },
482 { SC_UNONAME_CFONT, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
483 { SC_UNONAME_CFCHARS, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
484 { SC_UNO_CJK_CFCHARS, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
485 { SC_UNO_CTL_CFCHARS, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
486 { SC_UNONAME_CFFAMIL, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
487 { SC_UNO_CJK_CFFAMIL, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
488 { SC_UNO_CTL_CFFAMIL, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
489 { SC_UNONAME_CFNAME, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
490 { SC_UNO_CJK_CFNAME, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
491 { SC_UNO_CTL_CFNAME, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
492 { SC_UNONAME_CFPITCH, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
493 { SC_UNO_CJK_CFPITCH, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
494 { SC_UNO_CTL_CFPITCH, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
495 { SC_UNONAME_CFSTYLE, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
496 { SC_UNO_CJK_CFSTYLE, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
497 { SC_UNO_CTL_CFSTYLE, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
498 { SC_UNONAME_CHEIGHT, ATTR_FONT_HEIGHT, cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
499 { SC_UNO_CJK_CHEIGHT, ATTR_CJK_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
500 { SC_UNO_CTL_CHEIGHT, ATTR_CTL_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
501 { SC_UNONAME_CLOCAL, ATTR_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
502 { SC_UNO_CJK_CLOCAL, ATTR_CJK_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
503 { SC_UNO_CTL_CLOCAL, ATTR_CTL_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
504 { SC_UNONAME_COVER, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
505 { SC_UNONAME_COVRLCOL, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
506 { SC_UNONAME_COVRLHAS, ATTR_FONT_OVERLINE, cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
507 { SC_UNONAME_CPOST, ATTR_FONT_POSTURE, cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
508 { SC_UNO_CJK_CPOST, ATTR_CJK_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
509 { SC_UNO_CTL_CPOST, ATTR_CTL_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
510 { SC_UNONAME_CRELIEF, ATTR_FONT_RELIEF, cppu::UnoType<sal_Int16>::get(), 0, MID_RELIEF },
511 { SC_UNONAME_CSHADD, ATTR_FONT_SHADOWED, cppu::UnoType<bool>::get(), 0, 0 },
512 { SC_UNONAME_CSTRIKE, ATTR_FONT_CROSSEDOUT,cppu::UnoType<sal_Int16>::get(), 0, MID_CROSS_OUT },
513 { SC_UNONAME_CUNDER, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
514 { SC_UNONAME_CUNDLCOL, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
515 { SC_UNONAME_CUNDLHAS, ATTR_FONT_UNDERLINE,cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
516 { SC_UNONAME_CWEIGHT, ATTR_FONT_WEIGHT, cppu::UnoType<float>::get(), 0, MID_WEIGHT },
517 { SC_UNO_CJK_CWEIGHT, ATTR_CJK_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
518 { SC_UNO_CTL_CWEIGHT, ATTR_CTL_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
519 { SC_UNONAME_CWORDMOD, ATTR_FONT_WORDLINE, cppu::UnoType<bool>::get(), 0, 0 },
520 { SC_UNONAME_CHCOLHDR, SC_WID_UNO_CHCOLHDR,cppu::UnoType<bool>::get(), 0, 0 },
521 { SC_UNONAME_CHROWHDR, SC_WID_UNO_CHROWHDR,cppu::UnoType<bool>::get(), 0, 0 },
522 { SC_UNONAME_CONDFMT, SC_WID_UNO_CONDFMT, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
523 { SC_UNONAME_CONDLOC, SC_WID_UNO_CONDLOC, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
524 { SC_UNONAME_CONDXML, SC_WID_UNO_CONDXML, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
525 { SC_UNONAME_DIAGONAL_BLTR, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
526 { SC_UNONAME_DIAGONAL_BLTR2, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
527 { SC_UNONAME_DIAGONAL_TLBR, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
528 { SC_UNONAME_DIAGONAL_TLBR2, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
529 { SC_UNONAME_CELLHJUS, ATTR_HOR_JUSTIFY, cppu::UnoType<table::CellHoriJustify>::get(), 0, MID_HORJUST_HORJUST },
530 { SC_UNONAME_CELLHJUS_METHOD, ATTR_HOR_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
531 { SC_UNONAME_CELLTRAN, ATTR_BACKGROUND, cppu::UnoType<bool>::get(), 0, MID_GRAPHIC_TRANSPARENT },
532 { SC_UNONAME_MANPAGE, SC_WID_UNO_MANPAGE, cppu::UnoType<bool>::get(), 0, 0 },
533 { SC_UNONAME_NEWPAGE, SC_WID_UNO_NEWPAGE, cppu::UnoType<bool>::get(), 0, 0 },
534 { SC_UNONAME_WRAP, ATTR_LINEBREAK, cppu::UnoType<bool>::get(), 0, 0 },
535 { SC_UNONAME_CELLVIS, SC_WID_UNO_CELLVIS, cppu::UnoType<bool>::get(), 0, 0 },
536 { SC_UNONAME_NUMFMT, ATTR_VALUE_FORMAT, cppu::UnoType<sal_Int32>::get(), 0, 0 },
537 { SC_UNONAME_NUMRULES, SC_WID_UNO_NUMRULES,cppu::UnoType<container::XIndexReplace>::get(), 0, 0 },
538 { SC_UNONAME_OWIDTH, SC_WID_UNO_OWIDTH, cppu::UnoType<bool>::get(), 0, 0 },
539 { SC_UNONAME_CELLORI, ATTR_STACKED, cppu::UnoType<table::CellOrientation>::get(), 0, 0 },
540 { SC_UNONAME_PADJUST, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
541 { SC_UNONAME_PBMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
542 { SC_UNONAME_PINDENT, ATTR_INDENT, cppu::UnoType<sal_Int16>::get(), 0, 0 }, //! CONVERT_TWIPS
543 { SC_UNONAME_PISCHDIST,ATTR_SCRIPTSPACE, cppu::UnoType<bool>::get(), 0, 0 },
544 { SC_UNONAME_PISFORBID,ATTR_FORBIDDEN_RULES,cppu::UnoType<bool>::get(), 0, 0 },
545 { SC_UNONAME_PISHANG, ATTR_HANGPUNCTUATION,cppu::UnoType<bool>::get(), 0, 0 },
546 { SC_UNONAME_PISHYPHEN,ATTR_HYPHENATE, cppu::UnoType<bool>::get(), 0, 0 },
547 { SC_UNONAME_PLASTADJ, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
548 { SC_UNONAME_PLMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
549 { SC_UNONAME_PRMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
550 { SC_UNONAME_PTMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
551 { SC_UNONAME_POS, SC_WID_UNO_POS, cppu::UnoType<awt::Point>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
552 { SC_UNONAME_ROTANG, ATTR_ROTATE_VALUE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
553 { SC_UNONAME_ROTREF, ATTR_ROTATE_MODE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
554 { SC_UNONAME_SHADOW, ATTR_SHADOW, cppu::UnoType<table::ShadowFormat>::get(), 0, 0 | CONVERT_TWIPS },
555 { SC_UNONAME_SHRINK_TO_FIT, ATTR_SHRINKTOFIT, cppu::UnoType<bool>::get(), 0, 0 },
556 { SC_UNONAME_SIZE, SC_WID_UNO_SIZE, cppu::UnoType<awt::Size>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
557 { SC_UNONAME_TBLBORD, SC_WID_UNO_TBLBORD, cppu::UnoType<table::TableBorder>::get(), 0, 0 | CONVERT_TWIPS },
558 { SC_UNONAME_TBLBORD2, SC_WID_UNO_TBLBORD2, cppu::UnoType<table::TableBorder2>::get(), 0, 0 | CONVERT_TWIPS },
559 { SC_UNONAME_USERDEF, ATTR_USERDEF, cppu::UnoType<container::XNameContainer>::get(), 0, 0 },
560 { SC_UNONAME_VALIDAT, SC_WID_UNO_VALIDAT, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
561 { SC_UNONAME_VALILOC, SC_WID_UNO_VALILOC, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
562 { SC_UNONAME_VALIXML, SC_WID_UNO_VALIXML, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
563 { SC_UNONAME_CELLVJUS, ATTR_VER_JUSTIFY, cppu::UnoType<sal_Int32>::get(), 0, 0 },
564 { SC_UNONAME_CELLVJUS_METHOD, ATTR_VER_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
565 { SC_UNONAME_CELLWID, SC_WID_UNO_CELLWID, cppu::UnoType<sal_Int32>::get(), 0, 0 },
566 { SC_UNONAME_WRITING, ATTR_WRITINGDIR, cppu::UnoType<sal_Int16>::get(), 0, 0 },
568 static SfxItemPropertySet aColumnPropertySet( aColumnPropertyMap_Impl );
569 return &aColumnPropertySet;
572 static const SfxItemPropertySet* lcl_GetRowPropertySet()
574 static const SfxItemPropertyMapEntry aRowPropertyMap_Impl[] =
576 { SC_UNONAME_ABSNAME, SC_WID_UNO_ABSNAME, cppu::UnoType<OUString>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
577 { SC_UNONAME_ASIANVERT,ATTR_VERTICAL_ASIAN,cppu::UnoType<bool>::get(), 0, 0 },
578 CELL_BORDER_PROPERTIES
579 CELL_BACKGROUND_COLOR_PROPERTIES
580 { SC_UNONAME_CELLPRO, ATTR_PROTECTION, cppu::UnoType<util::CellProtection>::get(), 0, 0 },
581 { SC_UNONAME_CELLSTYL, SC_WID_UNO_CELLSTYL,cppu::UnoType<OUString>::get(), 0, 0 },
582 CHAR_COLOR_PROPERTIES
583 { SC_UNONAME_COUTL, ATTR_FONT_CONTOUR, cppu::UnoType<bool>::get(), 0, 0 },
584 { SC_UNONAME_CCROSS, ATTR_FONT_CROSSEDOUT,cppu::UnoType<bool>::get(), 0, MID_CROSSED_OUT },
585 { SC_UNONAME_CEMPHAS, ATTR_FONT_EMPHASISMARK,cppu::UnoType<sal_Int16>::get(), 0, MID_EMPHASIS },
586 { SC_UNONAME_CFONT, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
587 { SC_UNONAME_CFCHARS, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
588 { SC_UNO_CJK_CFCHARS, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
589 { SC_UNO_CTL_CFCHARS, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
590 { SC_UNONAME_CFFAMIL, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
591 { SC_UNO_CJK_CFFAMIL, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
592 { SC_UNO_CTL_CFFAMIL, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
593 { SC_UNONAME_CFNAME, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
594 { SC_UNO_CJK_CFNAME, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
595 { SC_UNO_CTL_CFNAME, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
596 { SC_UNONAME_CFPITCH, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
597 { SC_UNO_CJK_CFPITCH, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
598 { SC_UNO_CTL_CFPITCH, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
599 { SC_UNONAME_CFSTYLE, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
600 { SC_UNO_CJK_CFSTYLE, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
601 { SC_UNO_CTL_CFSTYLE, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
602 { SC_UNONAME_CHEIGHT, ATTR_FONT_HEIGHT, cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
603 { SC_UNO_CJK_CHEIGHT, ATTR_CJK_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
604 { SC_UNO_CTL_CHEIGHT, ATTR_CTL_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
605 { SC_UNONAME_CLOCAL, ATTR_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
606 { SC_UNO_CJK_CLOCAL, ATTR_CJK_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
607 { SC_UNO_CTL_CLOCAL, ATTR_CTL_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
608 { SC_UNONAME_COVER, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
609 { SC_UNONAME_COVRLCOL, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
610 { SC_UNONAME_COVRLHAS, ATTR_FONT_OVERLINE, cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
611 { SC_UNONAME_CPOST, ATTR_FONT_POSTURE, cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
612 { SC_UNO_CJK_CPOST, ATTR_CJK_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
613 { SC_UNO_CTL_CPOST, ATTR_CTL_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
614 { SC_UNONAME_CRELIEF, ATTR_FONT_RELIEF, cppu::UnoType<sal_Int16>::get(), 0, MID_RELIEF },
615 { SC_UNONAME_CSHADD, ATTR_FONT_SHADOWED, cppu::UnoType<bool>::get(), 0, 0 },
616 { SC_UNONAME_CSTRIKE, ATTR_FONT_CROSSEDOUT,cppu::UnoType<sal_Int16>::get(), 0, MID_CROSS_OUT },
617 { SC_UNONAME_CUNDER, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
618 { SC_UNONAME_CUNDLCOL, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
619 { SC_UNONAME_CUNDLHAS, ATTR_FONT_UNDERLINE,cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
620 { SC_UNONAME_CWEIGHT, ATTR_FONT_WEIGHT, cppu::UnoType<float>::get(), 0, MID_WEIGHT },
621 { SC_UNO_CJK_CWEIGHT, ATTR_CJK_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
622 { SC_UNO_CTL_CWEIGHT, ATTR_CTL_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
623 { SC_UNONAME_CWORDMOD, ATTR_FONT_WORDLINE, cppu::UnoType<bool>::get(), 0, 0 },
624 { SC_UNONAME_CHCOLHDR, SC_WID_UNO_CHCOLHDR,cppu::UnoType<bool>::get(), 0, 0 },
625 { SC_UNONAME_CHROWHDR, SC_WID_UNO_CHROWHDR,cppu::UnoType<bool>::get(), 0, 0 },
626 { SC_UNONAME_CONDFMT, SC_WID_UNO_CONDFMT, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
627 { SC_UNONAME_CONDLOC, SC_WID_UNO_CONDLOC, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
628 { SC_UNONAME_CONDXML, SC_WID_UNO_CONDXML, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
629 { SC_UNONAME_DIAGONAL_BLTR, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
630 { SC_UNONAME_DIAGONAL_BLTR2, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
631 { SC_UNONAME_DIAGONAL_TLBR, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
632 { SC_UNONAME_DIAGONAL_TLBR2, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
633 { SC_UNONAME_CELLHGT, SC_WID_UNO_CELLHGT, cppu::UnoType<sal_Int32>::get(), 0, 0 },
634 { SC_UNONAME_CELLHJUS, ATTR_HOR_JUSTIFY, cppu::UnoType<table::CellHoriJustify>::get(), 0, MID_HORJUST_HORJUST },
635 { SC_UNONAME_CELLHJUS_METHOD, ATTR_HOR_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
636 { SC_UNONAME_CELLTRAN, ATTR_BACKGROUND, cppu::UnoType<bool>::get(), 0, MID_GRAPHIC_TRANSPARENT },
637 { SC_UNONAME_CELLFILT, SC_WID_UNO_CELLFILT,cppu::UnoType<bool>::get(), 0, 0 },
638 { SC_UNONAME_MANPAGE, SC_WID_UNO_MANPAGE, cppu::UnoType<bool>::get(), 0, 0 },
639 { SC_UNONAME_NEWPAGE, SC_WID_UNO_NEWPAGE, cppu::UnoType<bool>::get(), 0, 0 },
640 { SC_UNONAME_WRAP, ATTR_LINEBREAK, cppu::UnoType<bool>::get(), 0, 0 },
641 { SC_UNONAME_CELLVIS, SC_WID_UNO_CELLVIS, cppu::UnoType<bool>::get(), 0, 0 },
642 { SC_UNONAME_NUMFMT, ATTR_VALUE_FORMAT, cppu::UnoType<sal_Int32>::get(), 0, 0 },
643 { SC_UNONAME_NUMRULES, SC_WID_UNO_NUMRULES,cppu::UnoType<container::XIndexReplace>::get(), 0, 0 },
644 { SC_UNONAME_OHEIGHT, SC_WID_UNO_OHEIGHT, cppu::UnoType<bool>::get(), 0, 0 },
645 { SC_UNONAME_CELLORI, ATTR_STACKED, cppu::UnoType<table::CellOrientation>::get(), 0, 0 },
646 { SC_UNONAME_PADJUST, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
647 { SC_UNONAME_PBMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
648 { SC_UNONAME_PINDENT, ATTR_INDENT, cppu::UnoType<sal_Int16>::get(), 0, 0 }, //! CONVERT_TWIPS
649 { SC_UNONAME_PISCHDIST,ATTR_SCRIPTSPACE, cppu::UnoType<bool>::get(), 0, 0 },
650 { SC_UNONAME_PISFORBID,ATTR_FORBIDDEN_RULES,cppu::UnoType<bool>::get(), 0, 0 },
651 { SC_UNONAME_PISHANG, ATTR_HANGPUNCTUATION,cppu::UnoType<bool>::get(), 0, 0 },
652 { SC_UNONAME_PISHYPHEN,ATTR_HYPHENATE, cppu::UnoType<bool>::get(), 0, 0 },
653 { SC_UNONAME_PLASTADJ, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
654 { SC_UNONAME_PLMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
655 { SC_UNONAME_PRMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
656 { SC_UNONAME_PTMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
657 { SC_UNONAME_POS, SC_WID_UNO_POS, cppu::UnoType<awt::Point>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
658 { SC_UNONAME_ROTANG, ATTR_ROTATE_VALUE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
659 { SC_UNONAME_ROTREF, ATTR_ROTATE_MODE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
660 { SC_UNONAME_SHADOW, ATTR_SHADOW, cppu::UnoType<table::ShadowFormat>::get(), 0, 0 | CONVERT_TWIPS },
661 { SC_UNONAME_SHRINK_TO_FIT, ATTR_SHRINKTOFIT, cppu::UnoType<bool>::get(), 0, 0 },
662 { SC_UNONAME_SIZE, SC_WID_UNO_SIZE, cppu::UnoType<awt::Size>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
663 { SC_UNONAME_TBLBORD, SC_WID_UNO_TBLBORD, cppu::UnoType<table::TableBorder>::get(), 0, 0 | CONVERT_TWIPS },
664 { SC_UNONAME_TBLBORD2, SC_WID_UNO_TBLBORD2, cppu::UnoType<table::TableBorder2>::get(), 0, 0 | CONVERT_TWIPS },
665 { SC_UNONAME_USERDEF, ATTR_USERDEF, cppu::UnoType<container::XNameContainer>::get(), 0, 0 },
666 { SC_UNONAME_VALIDAT, SC_WID_UNO_VALIDAT, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
667 { SC_UNONAME_VALILOC, SC_WID_UNO_VALILOC, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
668 { SC_UNONAME_VALIXML, SC_WID_UNO_VALIXML, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
669 { SC_UNONAME_CELLVJUS, ATTR_VER_JUSTIFY, cppu::UnoType<sal_Int32>::get(), 0, 0 },
670 { SC_UNONAME_CELLVJUS_METHOD, ATTR_VER_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
671 { SC_UNONAME_WRITING, ATTR_WRITINGDIR, cppu::UnoType<sal_Int16>::get(), 0, 0 },
673 static SfxItemPropertySet aRowPropertySet( aRowPropertyMap_Impl );
674 return &aRowPropertySet;
677 static const SfxItemPropertySet* lcl_GetSheetPropertySet()
679 static const SfxItemPropertyMapEntry aSheetPropertyMap_Impl[] =
681 { SC_UNONAME_ABSNAME, SC_WID_UNO_ABSNAME, cppu::UnoType<OUString>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
682 { SC_UNONAME_ASIANVERT,ATTR_VERTICAL_ASIAN,cppu::UnoType<bool>::get(), 0, 0 },
683 { SC_UNONAME_AUTOPRINT,SC_WID_UNO_AUTOPRINT,cppu::UnoType<bool>::get(), 0, 0 },
684 { SC_UNONAME_BORDCOL, SC_WID_UNO_BORDCOL, cppu::UnoType<sal_Int32>::get(), 0, 0 },
685 CELL_BORDER_PROPERTIES
686 CELL_BACKGROUND_COLOR_PROPERTIES
687 { SC_UNONAME_CELLPRO, ATTR_PROTECTION, cppu::UnoType<util::CellProtection>::get(), 0, 0 },
688 { SC_UNONAME_CELLSTYL, SC_WID_UNO_CELLSTYL,cppu::UnoType<OUString>::get(), 0, 0 },
689 CHAR_COLOR_PROPERTIES
690 { SC_UNONAME_COUTL, ATTR_FONT_CONTOUR, cppu::UnoType<bool>::get(), 0, 0 },
691 { SC_UNONAME_CCROSS, ATTR_FONT_CROSSEDOUT,cppu::UnoType<bool>::get(), 0, MID_CROSSED_OUT },
692 { SC_UNONAME_CEMPHAS, ATTR_FONT_EMPHASISMARK,cppu::UnoType<sal_Int16>::get(), 0, MID_EMPHASIS },
693 { SC_UNONAME_CFONT, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
694 { SC_UNONAME_CFCHARS, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
695 { SC_UNO_CJK_CFCHARS, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
696 { SC_UNO_CTL_CFCHARS, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_CHAR_SET },
697 { SC_UNONAME_CFFAMIL, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
698 { SC_UNO_CJK_CFFAMIL, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
699 { SC_UNO_CTL_CFFAMIL, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_FAMILY },
700 { SC_UNONAME_CFNAME, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
701 { SC_UNO_CJK_CFNAME, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
702 { SC_UNO_CTL_CFNAME, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_FAMILY_NAME },
703 { SC_UNONAME_CFPITCH, ATTR_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
704 { SC_UNO_CJK_CFPITCH, ATTR_CJK_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
705 { SC_UNO_CTL_CFPITCH, ATTR_CTL_FONT, cppu::UnoType<sal_Int16>::get(), 0, MID_FONT_PITCH },
706 { SC_UNONAME_CFSTYLE, ATTR_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
707 { SC_UNO_CJK_CFSTYLE, ATTR_CJK_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
708 { SC_UNO_CTL_CFSTYLE, ATTR_CTL_FONT, cppu::UnoType<OUString>::get(), 0, MID_FONT_STYLE_NAME },
709 { SC_UNONAME_CHEIGHT, ATTR_FONT_HEIGHT, cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
710 { SC_UNO_CJK_CHEIGHT, ATTR_CJK_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
711 { SC_UNO_CTL_CHEIGHT, ATTR_CTL_FONT_HEIGHT,cppu::UnoType<float>::get(), 0, MID_FONTHEIGHT | CONVERT_TWIPS },
712 { SC_UNONAME_CLOCAL, ATTR_FONT_LANGUAGE, cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
713 { SC_UNO_CJK_CLOCAL, ATTR_CJK_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
714 { SC_UNO_CTL_CLOCAL, ATTR_CTL_FONT_LANGUAGE,cppu::UnoType<lang::Locale>::get(), 0, MID_LANG_LOCALE },
715 { SC_UNONAME_COVER, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
716 { SC_UNONAME_COVRLCOL, ATTR_FONT_OVERLINE, cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
717 { SC_UNONAME_COVRLHAS, ATTR_FONT_OVERLINE, cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
718 { SC_UNONAME_CPOST, ATTR_FONT_POSTURE, cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
719 { SC_UNO_CJK_CPOST, ATTR_CJK_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
720 { SC_UNO_CTL_CPOST, ATTR_CTL_FONT_POSTURE,cppu::UnoType<awt::FontSlant>::get(), 0, MID_POSTURE },
721 { SC_UNONAME_CRELIEF, ATTR_FONT_RELIEF, cppu::UnoType<sal_Int16>::get(), 0, MID_RELIEF },
722 { SC_UNONAME_CSHADD, ATTR_FONT_SHADOWED, cppu::UnoType<bool>::get(), 0, 0 },
723 { SC_UNONAME_CSTRIKE, ATTR_FONT_CROSSEDOUT,cppu::UnoType<sal_Int16>::get(), 0, MID_CROSS_OUT },
724 { SC_UNONAME_CUNDER, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int16>::get(), 0, MID_TL_STYLE },
725 { SC_UNONAME_CUNDLCOL, ATTR_FONT_UNDERLINE,cppu::UnoType<sal_Int32>::get(), 0, MID_TL_COLOR },
726 { SC_UNONAME_CUNDLHAS, ATTR_FONT_UNDERLINE,cppu::UnoType<bool>::get(), 0, MID_TL_HASCOLOR },
727 { SC_UNONAME_CWEIGHT, ATTR_FONT_WEIGHT, cppu::UnoType<float>::get(), 0, MID_WEIGHT },
728 { SC_UNO_CJK_CWEIGHT, ATTR_CJK_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
729 { SC_UNO_CTL_CWEIGHT, ATTR_CTL_FONT_WEIGHT,cppu::UnoType<float>::get(), 0, MID_WEIGHT },
730 { SC_UNONAME_CWORDMOD, ATTR_FONT_WORDLINE, cppu::UnoType<bool>::get(), 0, 0 },
731 { SC_UNONAME_CHCOLHDR, SC_WID_UNO_CHCOLHDR,cppu::UnoType<bool>::get(), 0, 0 },
732 { SC_UNONAME_CHROWHDR, SC_WID_UNO_CHROWHDR,cppu::UnoType<bool>::get(), 0, 0 },
733 { SC_UNONAME_CONDFMT, SC_WID_UNO_CONDFMT, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
734 { SC_UNONAME_CONDLOC, SC_WID_UNO_CONDLOC, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
735 { SC_UNONAME_CONDXML, SC_WID_UNO_CONDXML, cppu::UnoType<sheet::XSheetConditionalEntries>::get(), 0, 0 },
736 { SC_UNONAME_COPYBACK, SC_WID_UNO_COPYBACK,cppu::UnoType<bool>::get(), 0, 0 },
737 { SC_UNONAME_COPYFORM, SC_WID_UNO_COPYFORM,cppu::UnoType<bool>::get(), 0, 0 },
738 { SC_UNONAME_COPYSTYL, SC_WID_UNO_COPYSTYL,cppu::UnoType<bool>::get(), 0, 0 },
739 { SC_UNONAME_DIAGONAL_BLTR, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
740 { SC_UNONAME_DIAGONAL_BLTR2, ATTR_BORDER_BLTR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
741 { SC_UNONAME_DIAGONAL_TLBR, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine>::get(), 0, 0 | CONVERT_TWIPS },
742 { SC_UNONAME_DIAGONAL_TLBR2, ATTR_BORDER_TLBR, ::cppu::UnoType<table::BorderLine2>::get(), 0, 0 | CONVERT_TWIPS },
743 { SC_UNONAME_CELLHJUS, ATTR_HOR_JUSTIFY, cppu::UnoType<table::CellHoriJustify>::get(), 0, MID_HORJUST_HORJUST },
744 { SC_UNONAME_CELLHJUS_METHOD, ATTR_HOR_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
745 { SC_UNONAME_ISACTIVE, SC_WID_UNO_ISACTIVE,cppu::UnoType<bool>::get(), 0, 0 },
746 { SC_UNONAME_CELLTRAN, ATTR_BACKGROUND, cppu::UnoType<bool>::get(), 0, MID_GRAPHIC_TRANSPARENT },
747 { SC_UNONAME_WRAP, ATTR_LINEBREAK, cppu::UnoType<bool>::get(), 0, 0 },
748 { SC_UNONAME_CELLVIS, SC_WID_UNO_CELLVIS, cppu::UnoType<bool>::get(), 0, 0 },
749 { SC_UNO_LINKDISPBIT, SC_WID_UNO_LINKDISPBIT,cppu::UnoType<awt::XBitmap>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
750 { SC_UNO_LINKDISPNAME, SC_WID_UNO_LINKDISPNAME,cppu::UnoType<OUString>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
751 { SC_UNONAME_NUMFMT, ATTR_VALUE_FORMAT, cppu::UnoType<sal_Int32>::get(), 0, 0 },
752 { SC_UNONAME_NUMRULES, SC_WID_UNO_NUMRULES,cppu::UnoType<container::XIndexReplace>::get(), 0, 0 },
753 { SC_UNONAME_CELLORI, ATTR_STACKED, cppu::UnoType<table::CellOrientation>::get(), 0, 0 },
754 { SC_UNONAME_PAGESTL, SC_WID_UNO_PAGESTL, cppu::UnoType<OUString>::get(), 0, 0 },
755 { SC_UNONAME_PADJUST, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
756 { SC_UNONAME_PBMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_LO_MARGIN | CONVERT_TWIPS },
757 { SC_UNONAME_PINDENT, ATTR_INDENT, cppu::UnoType<sal_Int16>::get(), 0, 0 }, //! CONVERT_TWIPS
758 { SC_UNONAME_PISCHDIST,ATTR_SCRIPTSPACE, cppu::UnoType<bool>::get(), 0, 0 },
759 { SC_UNONAME_PISFORBID,ATTR_FORBIDDEN_RULES,cppu::UnoType<bool>::get(), 0, 0 },
760 { SC_UNONAME_PISHANG, ATTR_HANGPUNCTUATION,cppu::UnoType<bool>::get(), 0, 0 },
761 { SC_UNONAME_PISHYPHEN,ATTR_HYPHENATE, cppu::UnoType<bool>::get(), 0, 0 },
762 { SC_UNONAME_PLASTADJ, ATTR_HOR_JUSTIFY, ::cppu::UnoType<sal_Int16>::get(), 0, MID_HORJUST_ADJUST },
763 { SC_UNONAME_PLMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_L_MARGIN | CONVERT_TWIPS },
764 { SC_UNONAME_PRMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_R_MARGIN | CONVERT_TWIPS },
765 { SC_UNONAME_PTMARGIN, ATTR_MARGIN, cppu::UnoType<sal_Int32>::get(), 0, MID_MARGIN_UP_MARGIN | CONVERT_TWIPS },
766 { SC_UNONAME_POS, SC_WID_UNO_POS, cppu::UnoType<awt::Point>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
767 { SC_UNONAME_PRINTBORD,SC_WID_UNO_PRINTBORD,cppu::UnoType<bool>::get(), 0, 0 },
768 { SC_UNONAME_PROTECT, SC_WID_UNO_PROTECT, cppu::UnoType<bool>::get(), 0, 0 },
769 { SC_UNONAME_ROTANG, ATTR_ROTATE_VALUE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
770 { SC_UNONAME_ROTREF, ATTR_ROTATE_MODE, cppu::UnoType<sal_Int32>::get(), 0, 0 },
771 { SC_UNONAME_SHADOW, ATTR_SHADOW, cppu::UnoType<table::ShadowFormat>::get(), 0, 0 | CONVERT_TWIPS },
772 { SC_UNONAME_SHOWBORD, SC_WID_UNO_SHOWBORD,cppu::UnoType<bool>::get(), 0, 0 },
773 { SC_UNONAME_SHRINK_TO_FIT, ATTR_SHRINKTOFIT, cppu::UnoType<bool>::get(), 0, 0 },
774 { SC_UNONAME_SIZE, SC_WID_UNO_SIZE, cppu::UnoType<awt::Size>::get(), 0 | beans::PropertyAttribute::READONLY, 0 },
775 { SC_UNONAME_TBLBORD, SC_WID_UNO_TBLBORD, cppu::UnoType<table::TableBorder>::get(), 0, 0 | CONVERT_TWIPS },
776 { SC_UNONAME_TBLBORD2, SC_WID_UNO_TBLBORD2, cppu::UnoType<table::TableBorder2>::get(), 0, 0 | CONVERT_TWIPS },
777 { SC_UNONAME_TABLAYOUT,SC_WID_UNO_TABLAYOUT,cppu::UnoType<sal_Int16>::get(), 0, 0 },
778 { SC_UNONAME_CONDFORMAT, SC_WID_UNO_CONDFORMAT, cppu::UnoType<sheet::XConditionalFormats>::get(), 0, 0},
779 { SC_UNONAME_USERDEF, ATTR_USERDEF, cppu::UnoType<container::XNameContainer>::get(), 0, 0 },
780 { SC_UNONAME_VALIDAT, SC_WID_UNO_VALIDAT, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
781 { SC_UNONAME_VALILOC, SC_WID_UNO_VALILOC, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
782 { SC_UNONAME_VALIXML, SC_WID_UNO_VALIXML, cppu::UnoType<beans::XPropertySet>::get(), 0, 0 },
783 { SC_UNONAME_CELLVJUS, ATTR_VER_JUSTIFY, cppu::UnoType<sal_Int32>::get(), 0, 0 },
784 { SC_UNONAME_CELLVJUS_METHOD, ATTR_VER_JUSTIFY_METHOD, ::cppu::UnoType<sal_Int32>::get(), 0, 0 },
785 { SC_UNONAME_WRITING, ATTR_WRITINGDIR, cppu::UnoType<sal_Int16>::get(), 0, 0 },
786 { SC_UNONAME_TABCOLOR, SC_WID_UNO_TABCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0 },
787 { SC_UNO_CODENAME, SC_WID_UNO_CODENAME, cppu::UnoType<OUString>::get(), 0, 0},
788 { SC_UNO_NAMEDRANGES, SC_WID_UNO_NAMES, cppu::UnoType<sheet::XNamedRanges>::get(), 0, 0 },
789 { SC_UNO_SOLVERSETTINGS, SC_WID_UNO_SOLVERSETTINGS, cppu::UnoType<sheet::XSolverSettings>::get(), 0, 0 },
790 { SC_UNONAME_TOTALBELOW, SC_WID_UNO_TOTALBELOW, cppu::UnoType<bool>::get(), 0, 0 },
792 static SfxItemPropertySet aSheetPropertySet( aSheetPropertyMap_Impl );
793 return &aSheetPropertySet;
796 static std::span<const SfxItemPropertyMapEntry> lcl_GetEditPropertyMap()
798 static const SfxItemPropertyMapEntry aEditPropertyMap_Impl[] =
800 SVX_UNOEDIT_CHAR_PROPERTIES,
801 SVX_UNOEDIT_FONT_PROPERTIES,
802 SVX_UNOEDIT_PARA_PROPERTIES,
803 SVX_UNOEDIT_NUMBERING_PROPERTY, // for completeness of service ParagraphProperties
804 { SC_UNONAME_TEXTUSER, EE_CHAR_XMLATTRIBS, cppu::UnoType<container::XNameContainer>::get(), 0, 0},
805 { SC_UNONAME_USERDEF, EE_PARA_XMLATTRIBS, cppu::UnoType<container::XNameContainer>::get(), 0, 0},
807 return aEditPropertyMap_Impl;
809 static const SvxItemPropertySet* lcl_GetEditPropertySet()
811 static SvxItemPropertySet aEditPropertySet( lcl_GetEditPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool() );
812 return &aEditPropertySet;
815 constexpr OUString SCCHARPROPERTIES_SERVICE = u"com.sun.star.style.CharacterProperties"_ustr;
816 constexpr OUString SCPARAPROPERTIES_SERVICE = u"com.sun.star.style.ParagraphProperties"_ustr;
817 constexpr OUString SCCELLPROPERTIES_SERVICE = u"com.sun.star.table.CellProperties"_ustr;
818 constexpr OUString SCCELLRANGE_SERVICE = u"com.sun.star.table.CellRange"_ustr;
819 constexpr OUString SCCELL_SERVICE = u"com.sun.star.table.Cell"_ustr;
820 constexpr OUString SCSHEETCELLRANGES_SERVICE = u"com.sun.star.sheet.SheetCellRanges"_ustr;
821 constexpr OUString SCSHEETCELLRANGE_SERVICE = u"com.sun.star.sheet.SheetCellRange"_ustr;
822 constexpr OUString SCSPREADSHEET_SERVICE = u"com.sun.star.sheet.Spreadsheet"_ustr;
823 constexpr OUString SCSHEETCELL_SERVICE = u"com.sun.star.sheet.SheetCell"_ustr;
825 SC_SIMPLE_SERVICE_INFO( ScCellFormatsEnumeration, u"ScCellFormatsEnumeration"_ustr, u"com.sun.star.sheet.CellFormatRangesEnumeration"_ustr )
826 SC_SIMPLE_SERVICE_INFO( ScCellFormatsObj, u"ScCellFormatsObj"_ustr, u"com.sun.star.sheet.CellFormatRanges"_ustr )
827 SC_SIMPLE_SERVICE_INFO( ScUniqueCellFormatsEnumeration, u"ScUniqueCellFormatsEnumeration"_ustr, u"com.sun.star.sheet.UniqueCellFormatRangesEnumeration"_ustr )
828 SC_SIMPLE_SERVICE_INFO( ScUniqueCellFormatsObj, u"ScUniqueCellFormatsObj"_ustr, u"com.sun.star.sheet.UniqueCellFormatRanges"_ustr )
829 SC_SIMPLE_SERVICE_INFO( ScCellRangesBase, u"ScCellRangesBase"_ustr, u"stardiv.unknown"_ustr )
830 SC_SIMPLE_SERVICE_INFO( ScCellsEnumeration, u"ScCellsEnumeration"_ustr, u"com.sun.star.sheet.CellsEnumeration"_ustr )
831 SC_SIMPLE_SERVICE_INFO( ScCellsObj, u"ScCellsObj"_ustr, u"com.sun.star.sheet.Cells"_ustr )
832 SC_SIMPLE_SERVICE_INFO( ScTableColumnObj, u"ScTableColumnObj"_ustr, u"com.sun.star.table.TableColumn"_ustr )
833 SC_SIMPLE_SERVICE_INFO( ScTableRowObj, u"ScTableRowObj"_ustr, u"com.sun.star.table.TableRow"_ustr )
835 //! move ScLinkListener into another file !!!
837 ScLinkListener::~ScLinkListener()
841 void ScLinkListener::Notify( const SfxHint& rHint )
843 aLink.Call( rHint );
846 static void lcl_CopyProperties( beans::XPropertySet& rDest, beans::XPropertySet& rSource )
848 uno::Reference<beans::XPropertySetInfo> xInfo(rSource.getPropertySetInfo());
849 if (xInfo.is())
851 const uno::Sequence<beans::Property> aSeq(xInfo->getProperties());
852 for (const beans::Property& rProp : aSeq)
854 OUString aName(rProp.Name);
855 rDest.setPropertyValue( aName, rSource.getPropertyValue( aName ) );
860 static SCTAB lcl_FirstTab( const ScRangeList& rRanges )
862 if (rRanges.empty())
863 throw std::out_of_range("empty range");
864 const ScRange & rFirst = rRanges[0];
865 return rFirst.aStart.Tab();
868 static bool lcl_WholeSheet( const ScDocument& rDoc, const ScRangeList& rRanges )
870 if ( rRanges.size() == 1 )
872 const ScRange & rRange = rRanges[0];
873 if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == rDoc.MaxCol() &&
874 rRange.aStart.Row() == 0 && rRange.aEnd.Row() == rDoc.MaxRow() )
875 return true;
877 return false;
880 namespace {
881 template<typename BorderLineType>
882 const ::editeng::SvxBorderLine* lcl_getBorderLine(
883 ::editeng::SvxBorderLine& rLine, const BorderLineType& rStruct )
885 // Convert from 1/100mm to Twips.
886 if (!SvxBoxItem::LineToSvxLine( rStruct, rLine, true))
887 return nullptr;
889 if ( rLine.GetOutWidth() || rLine.GetInWidth() || rLine.GetDistance() )
890 return &rLine;
891 else
892 return nullptr;
896 const ::editeng::SvxBorderLine* ScHelperFunctions::GetBorderLine(
897 ::editeng::SvxBorderLine& rLine, const table::BorderLine& rStruct )
899 return lcl_getBorderLine( rLine, rStruct);
902 const ::editeng::SvxBorderLine* ScHelperFunctions::GetBorderLine(
903 ::editeng::SvxBorderLine& rLine, const table::BorderLine2& rStruct )
905 return lcl_getBorderLine( rLine, rStruct);
908 namespace {
909 template<typename TableBorderType>
910 void lcl_fillBoxItems( SvxBoxItem& rOuter, SvxBoxInfoItem& rInner, const TableBorderType& rBorder )
912 ::editeng::SvxBorderLine aLine;
913 rOuter.SetAllDistances(o3tl::toTwips(rBorder.Distance, o3tl::Length::mm100));
914 rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.TopLine ), SvxBoxItemLine::TOP );
915 rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.BottomLine ), SvxBoxItemLine::BOTTOM );
916 rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.LeftLine ), SvxBoxItemLine::LEFT );
917 rOuter.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.RightLine ), SvxBoxItemLine::RIGHT );
918 rInner.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.HorizontalLine ), SvxBoxInfoItemLine::HORI );
919 rInner.SetLine( ScHelperFunctions::GetBorderLine( aLine, rBorder.VerticalLine ), SvxBoxInfoItemLine::VERT );
920 rInner.SetValid( SvxBoxInfoItemValidFlags::TOP, rBorder.IsTopLineValid );
921 rInner.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, rBorder.IsBottomLineValid );
922 rInner.SetValid( SvxBoxInfoItemValidFlags::LEFT, rBorder.IsLeftLineValid );
923 rInner.SetValid( SvxBoxInfoItemValidFlags::RIGHT, rBorder.IsRightLineValid );
924 rInner.SetValid( SvxBoxInfoItemValidFlags::HORI, rBorder.IsHorizontalLineValid );
925 rInner.SetValid( SvxBoxInfoItemValidFlags::VERT, rBorder.IsVerticalLineValid );
926 rInner.SetValid( SvxBoxInfoItemValidFlags::DISTANCE, rBorder.IsDistanceValid );
927 rInner.SetTable( true );
931 void ScHelperFunctions::FillBoxItems( SvxBoxItem& rOuter, SvxBoxInfoItem& rInner, const table::TableBorder& rBorder )
933 lcl_fillBoxItems( rOuter, rInner, rBorder);
936 void ScHelperFunctions::FillBoxItems( SvxBoxItem& rOuter, SvxBoxInfoItem& rInner, const table::TableBorder2& rBorder )
938 lcl_fillBoxItems( rOuter, rInner, rBorder);
941 void ScHelperFunctions::FillBorderLine( table::BorderLine& rStruct, const ::editeng::SvxBorderLine* pLine )
943 // Convert from Twips to 1/100mm.
944 rStruct = SvxBoxItem::SvxLineToLine( pLine, true);
947 void ScHelperFunctions::FillBorderLine( table::BorderLine2& rStruct, const ::editeng::SvxBorderLine* pLine )
949 rStruct = SvxBoxItem::SvxLineToLine( pLine, true);
952 namespace {
953 template<typename TableBorderItem>
954 void lcl_fillTableBorder( TableBorderItem& rBorder, const SvxBoxItem& rOuter, const SvxBoxInfoItem& rInner,
955 bool bInvalidateHorVerDist )
957 ScHelperFunctions::FillBorderLine( rBorder.TopLine, rOuter.GetTop() );
958 ScHelperFunctions::FillBorderLine( rBorder.BottomLine, rOuter.GetBottom() );
959 ScHelperFunctions::FillBorderLine( rBorder.LeftLine, rOuter.GetLeft() );
960 ScHelperFunctions::FillBorderLine( rBorder.RightLine, rOuter.GetRight() );
961 ScHelperFunctions::FillBorderLine( rBorder.HorizontalLine, rInner.GetHori() );
962 ScHelperFunctions::FillBorderLine( rBorder.VerticalLine, rInner.GetVert() );
964 rBorder.Distance = rOuter.GetSmallestDistance();
965 rBorder.IsTopLineValid = rInner.IsValid(SvxBoxInfoItemValidFlags::TOP);
966 rBorder.IsBottomLineValid = rInner.IsValid(SvxBoxInfoItemValidFlags::BOTTOM);
967 rBorder.IsLeftLineValid = rInner.IsValid(SvxBoxInfoItemValidFlags::LEFT);
968 rBorder.IsRightLineValid = rInner.IsValid(SvxBoxInfoItemValidFlags::RIGHT);
969 rBorder.IsHorizontalLineValid = !bInvalidateHorVerDist && rInner.IsValid(SvxBoxInfoItemValidFlags::HORI);
970 rBorder.IsVerticalLineValid = !bInvalidateHorVerDist && rInner.IsValid(SvxBoxInfoItemValidFlags::VERT);
971 rBorder.IsDistanceValid = !bInvalidateHorVerDist && rInner.IsValid(SvxBoxInfoItemValidFlags::DISTANCE);
975 void ScHelperFunctions::AssignTableBorderToAny( uno::Any& rAny,
976 const SvxBoxItem& rOuter, const SvxBoxInfoItem& rInner, bool bInvalidateHorVerDist )
978 table::TableBorder aBorder;
979 lcl_fillTableBorder( aBorder, rOuter, rInner, bInvalidateHorVerDist);
980 rAny <<= aBorder;
983 void ScHelperFunctions::AssignTableBorder2ToAny( uno::Any& rAny,
984 const SvxBoxItem& rOuter, const SvxBoxInfoItem& rInner, bool bInvalidateHorVerDist )
986 table::TableBorder2 aBorder;
987 lcl_fillTableBorder( aBorder, rOuter, rInner, bInvalidateHorVerDist);
988 rAny <<= aBorder;
991 //! move lcl_ApplyBorder to docfunc !
993 void ScHelperFunctions::ApplyBorder( ScDocShell* pDocShell, const ScRangeList& rRanges,
994 const SvxBoxItem& rOuter, const SvxBoxInfoItem& rInner )
996 ScDocument& rDoc = pDocShell->GetDocument();
997 bool bUndo(rDoc.IsUndoEnabled());
998 ScDocumentUniquePtr pUndoDoc;
999 if (bUndo)
1000 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1001 size_t nCount = rRanges.size();
1002 for (size_t i = 0; i < nCount; ++i)
1004 ScRange const & rRange = rRanges[ i ];
1005 SCTAB nTab = rRange.aStart.Tab();
1007 if (bUndo)
1009 if ( i==0 )
1010 pUndoDoc->InitUndo( rDoc, nTab, nTab );
1011 else
1012 pUndoDoc->AddUndoTab( nTab, nTab );
1013 rDoc.CopyToDocument(rRange, InsertDeleteFlags::ATTRIB, false, *pUndoDoc);
1016 ScMarkData aMark(rDoc.GetSheetLimits());
1017 aMark.SetMarkArea( rRange );
1018 aMark.SelectTable( nTab, true );
1020 rDoc.ApplySelectionFrame(aMark, rOuter, &rInner);
1021 // don't need RowHeight if there is only a border
1024 if (bUndo)
1026 pDocShell->GetUndoManager()->AddUndoAction(
1027 std::make_unique<ScUndoBorder>( pDocShell, rRanges, std::move(pUndoDoc), rOuter, rInner ) );
1030 for (size_t i = 0; i < nCount; ++i )
1031 pDocShell->PostPaint( rRanges[ i ], PaintPartFlags::Grid, SC_PF_LINES | SC_PF_TESTMERGE );
1033 pDocShell->SetDocumentModified();
1036 //! move lcl_PutDataArray to docfunc?
1037 //! merge loop with ScFunctionAccess::callFunction
1039 static bool lcl_PutDataArray( ScDocShell& rDocShell, const ScRange& rRange,
1040 const uno::Sequence< uno::Sequence<uno::Any> >& aData )
1042 ScDocument& rDoc = rDocShell.GetDocument();
1043 ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
1044 SCTAB nTab = rRange.aStart.Tab();
1045 SCCOL nStartCol = rRange.aStart.Col();
1046 SCROW nStartRow = rRange.aStart.Row();
1047 SCCOL nEndCol = rRange.aEnd.Col();
1048 SCROW nEndRow = rRange.aEnd.Row();
1049 bool bUndo(rDoc.IsUndoEnabled());
1051 if ( !rDoc.IsBlockEditable( nTab, nStartCol,nStartRow, nEndCol,nEndRow ) )
1053 //! error message
1054 return false;
1057 sal_Int32 nCols = 0;
1058 sal_Int32 nRows = aData.getLength();
1059 if ( nRows )
1060 nCols = aData[0].getLength();
1062 if ( nCols != nEndCol-nStartCol+1 || nRows != nEndRow-nStartRow+1 )
1064 //! error message?
1065 return false;
1068 ScDocumentUniquePtr pUndoDoc;
1069 if ( bUndo )
1071 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1072 pUndoDoc->InitUndo( rDoc, nTab, nTab );
1073 rDoc.CopyToDocument(rRange, InsertDeleteFlags::CONTENTS|InsertDeleteFlags::NOCAPTIONS, false, *pUndoDoc);
1076 rDoc.DeleteAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, InsertDeleteFlags::CONTENTS );
1078 bool bError = false;
1079 SCROW nDocRow = nStartRow;
1080 for (const uno::Sequence<uno::Any>& rColSeq : aData)
1082 if ( rColSeq.getLength() == nCols )
1084 SCCOL nDocCol = nStartCol;
1085 for (const uno::Any& rElement : rColSeq)
1087 ScAddress aPos(nDocCol, nDocRow, nTab);
1089 switch( rElement.getValueTypeClass() )
1091 case uno::TypeClass_VOID:
1093 // void = "no value"
1094 rDoc.SetError( nDocCol, nDocRow, nTab, FormulaError::NotAvailable );
1096 break;
1098 // #87871# accept integer types because Basic passes a floating point
1099 // variable as byte, short or long if it's an integer number.
1100 case uno::TypeClass_BYTE:
1101 case uno::TypeClass_SHORT:
1102 case uno::TypeClass_UNSIGNED_SHORT:
1103 case uno::TypeClass_LONG:
1104 case uno::TypeClass_UNSIGNED_LONG:
1105 case uno::TypeClass_FLOAT:
1106 case uno::TypeClass_DOUBLE:
1108 double fVal(0.0);
1109 rElement >>= fVal;
1110 rDoc.SetValue(aPos, fVal);
1112 break;
1114 case uno::TypeClass_STRING:
1116 OUString aUStr;
1117 rElement >>= aUStr;
1118 if ( !aUStr.isEmpty() )
1120 // tdf#146454 - check for a multiline string since setting an edit
1121 // or string cell is in magnitudes slower than setting a plain string
1122 if (ScStringUtil::isMultiline(aUStr))
1124 rEngine.SetTextCurrentDefaults(aUStr);
1125 rDoc.SetEditText(aPos, rEngine.CreateTextObject());
1127 else
1129 ScSetStringParam aParam;
1130 aParam.setTextInput();
1131 rDoc.SetString(aPos, aUStr, &aParam);
1135 break;
1137 // accept Sequence<FormulaToken> for formula cells
1138 case uno::TypeClass_SEQUENCE:
1140 uno::Sequence< sheet::FormulaToken > aTokens;
1141 if ( rElement >>= aTokens )
1143 ScTokenArray aTokenArray(rDoc);
1144 ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, aTokens );
1145 rDoc.SetFormula(aPos, aTokenArray);
1147 else
1148 bError = true;
1150 break;
1152 default:
1153 bError = true; // invalid type
1155 ++nDocCol;
1158 else
1159 bError = true; // wrong size
1161 ++nDocRow;
1164 bool bHeight = rDocShell.AdjustRowHeight( nStartRow, nEndRow, nTab );
1166 if ( pUndoDoc )
1168 ScMarkData aDestMark(rDoc.GetSheetLimits());
1169 aDestMark.SelectOneTable( nTab );
1170 rDocShell.GetUndoManager()->AddUndoAction(
1171 std::make_unique<ScUndoPaste>(
1172 &rDocShell, ScRange(nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab),
1173 aDestMark, std::move(pUndoDoc), nullptr, InsertDeleteFlags::CONTENTS, nullptr, false));
1176 if (!bHeight)
1177 rDocShell.PostPaint( rRange, PaintPartFlags::Grid ); // AdjustRowHeight may have painted already
1179 rDocShell.SetDocumentModified();
1181 return !bError;
1184 static bool lcl_PutFormulaArray( ScDocShell& rDocShell, const ScRange& rRange,
1185 const uno::Sequence< uno::Sequence<OUString> >& aData,
1186 const formula::FormulaGrammar::Grammar eGrammar )
1188 ScDocument& rDoc = rDocShell.GetDocument();
1189 SCTAB nTab = rRange.aStart.Tab();
1190 SCCOL nStartCol = rRange.aStart.Col();
1191 SCROW nStartRow = rRange.aStart.Row();
1192 SCCOL nEndCol = rRange.aEnd.Col();
1193 SCROW nEndRow = rRange.aEnd.Row();
1194 bool bUndo(rDoc.IsUndoEnabled());
1196 if ( !rDoc.IsBlockEditable( nTab, nStartCol,nStartRow, nEndCol,nEndRow ) )
1198 //! error message
1199 return false;
1202 sal_Int32 nCols = 0;
1203 sal_Int32 nRows = aData.getLength();
1204 if ( nRows )
1205 nCols = aData[0].getLength();
1207 if ( nCols != nEndCol-nStartCol+1 || nRows != nEndRow-nStartRow+1 )
1209 //! error message?
1210 return false;
1213 ScDocumentUniquePtr pUndoDoc;
1214 if ( bUndo )
1216 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1217 pUndoDoc->InitUndo( rDoc, nTab, nTab );
1218 rDoc.CopyToDocument(rRange, InsertDeleteFlags::CONTENTS, false, *pUndoDoc);
1221 rDoc.DeleteAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, InsertDeleteFlags::CONTENTS );
1223 bool bError = false;
1224 SCROW nDocRow = nStartRow;
1225 for (const uno::Sequence<OUString>& rColSeq : aData)
1227 if ( rColSeq.getLength() == nCols )
1229 SCCOL nDocCol = nStartCol;
1230 for (const OUString& aText : rColSeq)
1232 ScAddress aPos( nDocCol, nDocRow, nTab );
1234 ScInputStringType aRes =
1235 ScStringUtil::parseInputString(
1236 rDoc.GetNonThreadedContext(), aText, LANGUAGE_ENGLISH_US);
1237 switch (aRes.meType)
1239 case ScInputStringType::Formula:
1240 rDoc.SetFormula(aPos, aRes.maText, eGrammar);
1241 break;
1242 case ScInputStringType::Number:
1243 rDoc.SetValue(aPos, aRes.mfValue);
1244 break;
1245 case ScInputStringType::Text:
1246 rDoc.SetTextCell(aPos, aRes.maText);
1247 break;
1248 default:
1252 ++nDocCol;
1255 else
1256 bError = true; // wrong size
1258 ++nDocRow;
1261 bool bHeight = rDocShell.AdjustRowHeight( nStartRow, nEndRow, nTab );
1263 if ( pUndoDoc )
1265 ScMarkData aDestMark(rDoc.GetSheetLimits());
1266 aDestMark.SelectOneTable( nTab );
1267 rDocShell.GetUndoManager()->AddUndoAction(
1268 std::make_unique<ScUndoPaste>( &rDocShell,
1269 ScRange(nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab), aDestMark,
1270 std::move(pUndoDoc), nullptr, InsertDeleteFlags::CONTENTS, nullptr, false));
1273 if (!bHeight)
1274 rDocShell.PostPaint( rRange, PaintPartFlags::Grid ); // AdjustRowHeight may have painted already
1276 rDocShell.SetDocumentModified();
1278 return !bError;
1281 // used in ScCellRangeObj::getFormulaArray and ScCellObj::GetInputString_Impl
1282 static OUString lcl_GetInputString( ScDocument& rDoc, const ScAddress& rPos, bool bEnglish )
1284 ScRefCellValue aCell(rDoc, rPos);
1285 if (aCell.isEmpty())
1286 return OUString();
1288 OUString aVal;
1290 CellType eType = aCell.getType();
1291 if (eType == CELLTYPE_FORMULA)
1293 ScFormulaCell* pForm = aCell.getFormula();
1294 return pForm->GetFormula( formula::FormulaGrammar::mapAPItoGrammar( bEnglish, false));
1297 // use an InterpreterContext, possibly with a different formatter, to uniformly use
1298 // ScCellFormat::GetInputString everywhere
1299 ScInterpreterContextGetterGuard aContextGetterGuard(rDoc, bEnglish ? ScGlobal::GetEnglishFormatter()
1300 : rDoc.GetFormatTable());
1301 ScInterpreterContext* pInterpreterContext = aContextGetterGuard.GetInterpreterContext();
1303 // Since the English formatter was constructed with
1304 // LANGUAGE_ENGLISH_US the "General" format has index key 0,
1305 // we don't have to query.
1306 sal_uInt32 nNumFmt = bEnglish ? 0 : rDoc.GetNumberFormat(ScRange(rPos));
1308 if (eType == CELLTYPE_EDIT)
1310 // GetString on EditCell turns breaks into spaces,
1311 // but we need the breaks here
1312 const EditTextObject* pData = aCell.getEditText();
1313 if (pData)
1315 EditEngine& rEngine = rDoc.GetEditEngine();
1316 rEngine.SetText(*pData);
1317 aVal = rEngine.GetText();
1320 else
1321 aVal = ScCellFormat::GetInputString(aCell, nNumFmt, pInterpreterContext, rDoc);
1323 // if applicable, prepend ' like in ScTabViewShell::UpdateInputHandler
1324 if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
1326 double fDummy;
1327 OUString aTempString = aVal;
1328 bool bIsNumberFormat(pInterpreterContext->NFIsNumberFormat(aTempString, nNumFmt, fDummy));
1329 if ( bIsNumberFormat )
1330 aTempString = "'" + aTempString;
1331 else if ( aTempString.startsWith("'") )
1333 // if the string starts with a "'", add another one because setFormula
1334 // strips one (like text input, except for "text" number formats)
1335 if ( bEnglish || ( pInterpreterContext->NFGetType(nNumFmt) != SvNumFormatType::TEXT ) )
1336 aTempString = "'" + aTempString;
1338 aVal = aTempString;
1341 return aVal;
1344 ScCellRangesBase::ScCellRangesBase(ScDocShell* pDocSh, const ScRange& rR) :
1345 pPropSet(lcl_GetCellsPropertySet()),
1346 pDocShell( pDocSh ),
1347 nObjectId( 0 ),
1348 bChartColAsHdr( false ),
1349 bChartRowAsHdr( false ),
1350 bCursorOnly( false ),
1351 bGotDataChangedHint( false ),
1352 aValueListeners( 0 )
1354 ScRange aCellRange(rR);
1355 aCellRange.PutInOrder();
1356 aRanges.push_back( aCellRange );
1358 if (pDocShell) // Null if created with createInstance
1360 ScDocument& rDoc = pDocShell->GetDocument();
1361 rDoc.AddUnoObject(*this);
1362 nObjectId = rDoc.GetNewUnoId();
1366 ScCellRangesBase::ScCellRangesBase(ScDocShell* pDocSh, ScRangeList aR) :
1367 pPropSet(lcl_GetCellsPropertySet()),
1368 pDocShell( pDocSh ),
1369 aRanges(std::move( aR )),
1370 nObjectId( 0 ),
1371 bChartColAsHdr( false ),
1372 bChartRowAsHdr( false ),
1373 bCursorOnly( false ),
1374 bGotDataChangedHint( false ),
1375 aValueListeners( 0 )
1377 if (pDocShell) // Null if created with createInstance
1379 ScDocument& rDoc = pDocShell->GetDocument();
1380 rDoc.AddUnoObject(*this);
1381 nObjectId = rDoc.GetNewUnoId();
1385 ScCellRangesBase::~ScCellRangesBase()
1387 SolarMutexGuard g;
1389 // call RemoveUnoObject first, so no notification can happen
1390 // during ForgetCurrentAttrs
1392 if (pDocShell)
1393 pDocShell->GetDocument().RemoveUnoObject(*this);
1395 ForgetCurrentAttrs();
1396 ForgetMarkData();
1398 pValueListener.reset();
1400 //! unregister XChartDataChangeEventListener ??
1401 //! (ChartCollection will then hold this object as well!)
1404 void ScCellRangesBase::ForgetCurrentAttrs()
1406 pCurrentFlat.reset();
1407 pCurrentDeep.reset();
1408 moCurrentDataSet.reset();
1409 moNoDfltCurrentDataSet.reset();
1411 // #i62483# pMarkData can remain unchanged, is deleted only if the range changes (RefChanged)
1414 void ScCellRangesBase::ForgetMarkData()
1416 pMarkData.reset();
1419 const ScPatternAttr* ScCellRangesBase::GetCurrentAttrsFlat()
1421 // get and cache direct cell attributes for this object's range
1423 if ( !pCurrentFlat && pDocShell )
1425 ScDocument& rDoc = pDocShell->GetDocument();
1426 pCurrentFlat = rDoc.CreateSelectionPattern( *GetMarkData(), false );
1428 return pCurrentFlat.get();
1431 const ScPatternAttr* ScCellRangesBase::GetCurrentAttrsDeep()
1433 // get and cache cell attributes (incl. styles) for this object's range
1435 if ( !pCurrentDeep && pDocShell )
1437 ScDocument& rDoc = pDocShell->GetDocument();
1438 pCurrentDeep = rDoc.CreateSelectionPattern( *GetMarkData() );
1440 return pCurrentDeep.get();
1443 SfxItemSet* ScCellRangesBase::GetCurrentDataSet(bool bNoDflt)
1445 if(!moCurrentDataSet)
1447 const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
1448 if ( pPattern )
1450 // replace Dontcare with Default, so that we always have a reflection
1451 moCurrentDataSet.emplace( pPattern->GetItemSet() );
1452 moNoDfltCurrentDataSet.emplace( pPattern->GetItemSet() );
1453 moCurrentDataSet->ClearInvalidItems();
1456 if (bNoDflt)
1458 if (moNoDfltCurrentDataSet)
1459 return &*moNoDfltCurrentDataSet;
1461 else
1463 if (moCurrentDataSet)
1464 return &*moCurrentDataSet;
1466 return nullptr;
1469 const ScMarkData* ScCellRangesBase::GetMarkData()
1471 if (!pMarkData)
1473 pMarkData.reset( new ScMarkData(GetDocument()->GetSheetLimits(), aRanges) );
1475 return pMarkData.get();
1478 void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
1480 const SfxHintId nId = rHint.GetId();
1481 if ( nId == SfxHintId::Dying )
1483 // if the document dies, must reset to avoid crash in dtor!
1484 ForgetCurrentAttrs();
1485 pDocShell = nullptr; // invalid
1487 // fdo#72695: if UNO object is already dead, don't revive it with event
1488 if ( m_refCount > 0 && !aValueListeners.empty() )
1490 // dispose listeners
1492 lang::EventObject aEvent;
1493 aEvent.Source = getXWeak();
1494 for (uno::Reference<util::XModifyListener> & xValueListener : aValueListeners)
1495 xValueListener->disposing( aEvent );
1497 aValueListeners.clear();
1499 // The listeners can't have the last ref to this, as it's still held
1500 // by the DocShell.
1503 else if ( nId == SfxHintId::DataChanged )
1505 // document content changed -> forget cached attributes
1506 ForgetCurrentAttrs();
1508 if ( bGotDataChangedHint && pDocShell )
1510 // This object was notified of content changes, so one call
1511 // for each listener is generated now.
1512 // The calls can't be executed directly because the document's
1513 // UNO broadcaster list must not be modified.
1514 // Instead, add to the document's list of listener calls,
1515 // which will be executed directly after the broadcast of
1516 // SfxHintId::DataChanged.
1518 lang::EventObject aEvent;
1519 aEvent.Source = getXWeak();
1521 // the EventObject holds a Ref to this object until after the listener calls
1523 ScDocument& rDoc = pDocShell->GetDocument();
1524 for (const uno::Reference<util::XModifyListener> & xValueListener : aValueListeners)
1525 rDoc.AddUnoListenerCall( xValueListener, aEvent );
1527 bGotDataChangedHint = false;
1530 else if ( nId == SfxHintId::ScCalcAll )
1532 // broadcast from DoHardRecalc - set bGotDataChangedHint
1533 // (SfxHintId::DataChanged follows separately)
1535 if ( !aValueListeners.empty() )
1536 bGotDataChangedHint = true;
1538 else if ( rHint.GetId() == SfxHintId::ScUpdateRef )
1540 auto pRefHint = static_cast<const ScUpdateRefHint*>(&rHint);
1541 ScDocument& rDoc = pDocShell->GetDocument();
1542 std::unique_ptr<ScRangeList> pUndoRanges;
1543 if ( rDoc.HasUnoRefUndo() )
1544 pUndoRanges.reset(new ScRangeList( aRanges ));
1546 if ( aRanges.UpdateReference( pRefHint->GetMode(), &rDoc, pRefHint->GetRange(),
1547 pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() ) )
1549 if ( pRefHint->GetMode() == URM_INSDEL
1550 && aRanges.size() == 1
1551 && dynamic_cast<ScTableSheetObj*>(this)
1554 // #101755#; the range size of a sheet does not change
1555 ScRange & rR = aRanges.front();
1556 rR.aStart.SetCol(0);
1557 rR.aStart.SetRow(0);
1558 rR.aEnd.SetCol(rDoc.MaxCol());
1559 rR.aEnd.SetRow(rDoc.MaxRow());
1561 RefChanged();
1563 // any change of the range address is broadcast to value (modify) listeners
1564 if ( !aValueListeners.empty() )
1565 bGotDataChangedHint = true;
1567 if ( pUndoRanges )
1568 rDoc.AddUnoRefChange( nObjectId, *pUndoRanges );
1571 else if ( rHint.GetId() == SfxHintId::ScUnoRefUndo )
1573 auto pUndoHint = static_cast<const ScUnoRefUndoHint*>(&rHint);
1574 if ( pUndoHint->GetObjectId() == nObjectId )
1576 // restore ranges from hint
1578 aRanges = pUndoHint->GetRanges();
1580 RefChanged();
1581 if ( !aValueListeners.empty() )
1582 bGotDataChangedHint = true; // need to broadcast the undo, too
1587 void ScCellRangesBase::RefChanged()
1589 //! adjust XChartDataChangeEventListener
1591 if ( pValueListener && !aValueListeners.empty() )
1593 pValueListener->EndListeningAll();
1595 ScDocument& rDoc = pDocShell->GetDocument();
1596 for ( size_t i = 0, nCount = aRanges.size(); i < nCount; ++i )
1597 rDoc.StartListeningArea( aRanges[ i ], false, pValueListener.get() );
1600 ForgetCurrentAttrs();
1601 ForgetMarkData();
1604 ScDocument* ScCellRangesBase::GetDocument() const
1606 if (pDocShell)
1607 return &pDocShell->GetDocument();
1608 else
1609 return nullptr;
1612 void ScCellRangesBase::InitInsertRange(ScDocShell* pDocSh, const ScRange& rR)
1614 if ( pDocShell || !pDocSh )
1615 return;
1617 pDocShell = pDocSh;
1619 ScRange aCellRange(rR);
1620 aCellRange.PutInOrder();
1621 aRanges.RemoveAll();
1622 aRanges.push_back( aCellRange );
1624 pDocShell->GetDocument().AddUnoObject(*this);
1626 RefChanged(); // adjust range in range object
1629 void ScCellRangesBase::AddRange(const ScRange& rRange, const bool bMergeRanges)
1631 if (bMergeRanges)
1632 aRanges.Join(rRange);
1633 else
1634 aRanges.push_back(rRange);
1635 RefChanged();
1638 void ScCellRangesBase::SetNewRange(const ScRange& rNew)
1640 ScRange aCellRange(rNew);
1641 aCellRange.PutInOrder();
1643 aRanges.RemoveAll();
1644 aRanges.push_back( aCellRange );
1645 RefChanged();
1648 void ScCellRangesBase::SetNewRanges(const ScRangeList& rNew)
1650 aRanges = rNew;
1651 RefChanged();
1654 void ScCellRangesBase::SetCursorOnly( bool bSet )
1656 // set for a selection object that is created from the cursor position
1657 // without anything selected (may contain several sheets)
1659 bCursorOnly = bSet;
1662 void ScCellRangesBase::PaintGridRanges_Impl( )
1664 for (size_t i = 0, nCount = aRanges.size(); i < nCount; ++i)
1665 pDocShell->PostPaint( aRanges[ i ], PaintPartFlags::Grid );
1668 // XSheetOperation
1670 double SAL_CALL ScCellRangesBase::computeFunction( sheet::GeneralFunction nFunction )
1672 SolarMutexGuard aGuard;
1673 ScMarkData aMark(*GetMarkData());
1674 aMark.MarkToSimple();
1675 if (!aMark.IsMarked())
1676 aMark.SetMarkNegative(true); // so we can enter dummy position
1678 ScAddress aDummy; // if not marked, ignored if it is negative
1679 double fVal;
1680 ScSubTotalFunc eFunc = ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(nFunction));
1681 ScDocument& rDoc = pDocShell->GetDocument();
1682 if ( !rDoc.GetSelectionFunction( eFunc, aDummy, aMark, fVal ) )
1684 throw uno::RuntimeException(); //! own exception?
1687 return fVal;
1690 void SAL_CALL ScCellRangesBase::clearContents( sal_Int32 nContentFlags )
1692 SolarMutexGuard aGuard;
1693 if ( !aRanges.empty() )
1695 // only for clearContents: EDITATTR is only used if no contents are deleted
1696 InsertDeleteFlags nDelFlags = static_cast<InsertDeleteFlags>(nContentFlags) & InsertDeleteFlags::ALL;
1697 if ( ( nDelFlags & InsertDeleteFlags::EDITATTR ) && ( nDelFlags & InsertDeleteFlags::CONTENTS ) == InsertDeleteFlags::NONE )
1698 nDelFlags |= InsertDeleteFlags::EDITATTR;
1700 pDocShell->GetDocFunc().DeleteContents( *GetMarkData(), nDelFlags, true, true );
1702 // otherwise nothing to do
1705 // XPropertyState
1707 const SfxItemPropertyMap& ScCellRangesBase::GetItemPropertyMap()
1709 return pPropSet->getPropertyMap();
1712 static void lcl_GetPropertyWhich( const SfxItemPropertyMapEntry* pEntry,
1713 sal_uInt16& rItemWhich )
1715 // Which-ID of the affected items also when the item can't handle
1716 // the property by itself
1717 if ( !pEntry )
1718 return;
1720 if ( IsScItemWid( pEntry->nWID ) )
1721 rItemWhich = pEntry->nWID;
1722 else
1723 switch ( pEntry->nWID )
1725 case SC_WID_UNO_TBLBORD:
1726 case SC_WID_UNO_TBLBORD2:
1727 rItemWhich = ATTR_BORDER;
1728 break;
1729 case SC_WID_UNO_CONDFMT:
1730 case SC_WID_UNO_CONDLOC:
1731 case SC_WID_UNO_CONDXML:
1732 rItemWhich = ATTR_CONDITIONAL;
1733 break;
1734 case SC_WID_UNO_VALIDAT:
1735 case SC_WID_UNO_VALILOC:
1736 case SC_WID_UNO_VALIXML:
1737 rItemWhich = ATTR_VALIDDATA;
1738 break;
1743 beans::PropertyState ScCellRangesBase::GetOnePropertyState( sal_uInt16 nItemWhich, const SfxItemPropertyMapEntry* pEntry )
1745 beans::PropertyState eRet = beans::PropertyState_DIRECT_VALUE;
1746 if ( nItemWhich ) // item wid (from map or special case)
1748 // For items that contain several properties (like background),
1749 // "ambiguous" is returned too often here
1751 // for PropertyState, don't look at styles
1752 const ScPatternAttr* pPattern = GetCurrentAttrsFlat();
1753 if ( pPattern )
1755 SfxItemState eState = pPattern->GetItemSet().GetItemState( nItemWhich, false );
1757 if ( nItemWhich == ATTR_VALUE_FORMAT && eState == SfxItemState::DEFAULT )
1758 eState = pPattern->GetItemSet().GetItemState( ATTR_LANGUAGE_FORMAT, false );
1760 if ( eState == SfxItemState::SET )
1761 eRet = beans::PropertyState_DIRECT_VALUE;
1762 else if ( eState == SfxItemState::DEFAULT )
1763 eRet = beans::PropertyState_DEFAULT_VALUE;
1764 else if ( eState == SfxItemState::INVALID )
1765 eRet = beans::PropertyState_AMBIGUOUS_VALUE;
1766 else
1768 OSL_FAIL("unknown ItemState");
1772 else if ( pEntry )
1774 if ( pEntry->nWID == SC_WID_UNO_CHCOLHDR || pEntry->nWID == SC_WID_UNO_CHROWHDR || pEntry->nWID == SC_WID_UNO_ABSNAME )
1775 eRet = beans::PropertyState_DIRECT_VALUE;
1776 else if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
1778 // a style is always set, there's no default state
1779 const ScStyleSheet* pStyle = pDocShell->GetDocument().GetSelectionStyle(*GetMarkData());
1780 if (pStyle)
1781 eRet = beans::PropertyState_DIRECT_VALUE;
1782 else
1783 eRet = beans::PropertyState_AMBIGUOUS_VALUE;
1785 else if ( pEntry->nWID == SC_WID_UNO_NUMRULES )
1786 eRet = beans::PropertyState_DEFAULT_VALUE; // numbering rules are always default
1788 return eRet;
1791 beans::PropertyState SAL_CALL ScCellRangesBase::getPropertyState( const OUString& aPropertyName )
1793 SolarMutexGuard aGuard;
1794 if ( aRanges.empty() )
1795 throw uno::RuntimeException();
1797 const SfxItemPropertyMap& rMap = GetItemPropertyMap(); // from derived class
1798 sal_uInt16 nItemWhich = 0;
1799 const SfxItemPropertyMapEntry* pEntry = rMap.getByName( aPropertyName );
1800 lcl_GetPropertyWhich( pEntry, nItemWhich );
1801 return GetOnePropertyState( nItemWhich, pEntry );
1804 uno::Sequence<beans::PropertyState> SAL_CALL ScCellRangesBase::getPropertyStates(
1805 const uno::Sequence<OUString>& aPropertyNames )
1807 SolarMutexGuard aGuard;
1809 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
1811 uno::Sequence<beans::PropertyState> aRet(aPropertyNames.getLength());
1812 std::transform(aPropertyNames.begin(), aPropertyNames.end(), aRet.getArray(),
1813 [this, &rPropertyMap](const auto& rName) -> beans::PropertyState {
1814 sal_uInt16 nItemWhich = 0;
1815 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( rName );
1816 lcl_GetPropertyWhich( pEntry, nItemWhich );
1817 return GetOnePropertyState(nItemWhich, pEntry);
1819 return aRet;
1822 void SAL_CALL ScCellRangesBase::setPropertyToDefault( const OUString& aPropertyName )
1824 SolarMutexGuard aGuard;
1825 if ( !pDocShell )
1826 return;
1828 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
1829 sal_uInt16 nItemWhich = 0;
1830 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( aPropertyName );
1831 lcl_GetPropertyWhich( pEntry, nItemWhich );
1832 if ( nItemWhich ) // item wid (from map or special case)
1834 if ( !aRanges.empty() ) // empty = nothing to do
1836 //! for items that have multiple properties (e.g. background)
1837 //! too much will be reset
1838 //! for ATTR_ROTATE_VALUE, reset ATTR_ORIENTATION as well?
1840 sal_uInt16 aWIDs[3];
1841 aWIDs[0] = nItemWhich;
1842 if ( nItemWhich == ATTR_VALUE_FORMAT )
1844 aWIDs[1] = ATTR_LANGUAGE_FORMAT; // language for number formats
1845 aWIDs[2] = 0;
1847 else
1848 aWIDs[1] = 0;
1849 pDocShell->GetDocFunc().ClearItems( *GetMarkData(), aWIDs, true );
1852 else if ( pEntry )
1854 if ( pEntry->nWID == SC_WID_UNO_CHCOLHDR )
1855 bChartColAsHdr = false;
1856 else if ( pEntry->nWID == SC_WID_UNO_CHROWHDR )
1857 bChartRowAsHdr = false;
1858 else if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
1860 OUString aStyleName( ScResId( STR_STYLENAME_STANDARD ) );
1861 pDocShell->GetDocFunc().ApplyStyle( *GetMarkData(), aStyleName, true );
1866 uno::Any SAL_CALL ScCellRangesBase::getPropertyDefault( const OUString& aPropertyName )
1868 //! bundle with getPropertyValue
1870 SolarMutexGuard aGuard;
1871 uno::Any aAny;
1873 if ( pDocShell )
1875 ScDocument& rDoc = pDocShell->GetDocument();
1876 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
1877 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( aPropertyName );
1878 if ( pEntry )
1880 if ( IsScItemWid( pEntry->nWID ) )
1882 const ScPatternAttr* pPattern(&rDoc.getCellAttributeHelper().getDefaultCellAttribute());
1883 if ( pPattern )
1885 const SfxItemSet& rSet = pPattern->GetItemSet();
1887 switch ( pEntry->nWID ) // for item-specific handling
1889 case ATTR_VALUE_FORMAT:
1890 // default has no language set
1891 aAny <<= static_cast<sal_Int32>( static_cast<const SfxUInt32Item&>(rSet.Get(pEntry->nWID)).GetValue() );
1892 break;
1893 case ATTR_INDENT:
1894 aAny <<= static_cast<sal_Int16>( convertTwipToMm100(static_cast<const ScIndentItem&>(
1895 rSet.Get(pEntry->nWID)).GetValue()) );
1896 break;
1897 default:
1898 pPropSet->getPropertyValue(aPropertyName, rSet, aAny);
1902 else
1903 switch ( pEntry->nWID )
1905 case SC_WID_UNO_CHCOLHDR:
1906 case SC_WID_UNO_CHROWHDR:
1907 aAny <<= false;
1908 break;
1909 case SC_WID_UNO_CELLSTYL:
1910 aAny <<= ScStyleNameConversion::DisplayToProgrammaticName(
1911 ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para );
1912 break;
1913 case SC_WID_UNO_TBLBORD:
1914 case SC_WID_UNO_TBLBORD2:
1916 const ScPatternAttr* pPattern(&rDoc.getCellAttributeHelper().getDefaultCellAttribute());
1917 if ( pPattern )
1919 if (pEntry->nWID == SC_WID_UNO_TBLBORD2)
1920 ScHelperFunctions::AssignTableBorder2ToAny( aAny,
1921 pPattern->GetItem(ATTR_BORDER),
1922 pPattern->GetItem(ATTR_BORDER_INNER) );
1923 else
1924 ScHelperFunctions::AssignTableBorderToAny( aAny,
1925 pPattern->GetItem(ATTR_BORDER),
1926 pPattern->GetItem(ATTR_BORDER_INNER) );
1929 break;
1930 case SC_WID_UNO_CONDFMT:
1931 case SC_WID_UNO_CONDLOC:
1932 case SC_WID_UNO_CONDXML:
1934 bool bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
1935 bool bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
1936 formula::FormulaGrammar::Grammar eGrammar = (bXML ?
1937 rDoc.GetStorageGrammar() :
1938 formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
1940 aAny <<= uno::Reference<sheet::XSheetConditionalEntries>(
1941 new ScTableConditionalFormat( &rDoc, 0, aRanges[0].aStart.Tab(), eGrammar ));
1943 break;
1944 case SC_WID_UNO_VALIDAT:
1945 case SC_WID_UNO_VALILOC:
1946 case SC_WID_UNO_VALIXML:
1948 bool bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
1949 bool bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
1950 formula::FormulaGrammar::Grammar eGrammar = (bXML ?
1951 rDoc.GetStorageGrammar() :
1952 formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
1954 aAny <<= uno::Reference<beans::XPropertySet>(
1955 new ScTableValidationObj( rDoc, 0, eGrammar ));
1957 break;
1958 case SC_WID_UNO_NUMRULES:
1960 aAny <<= ScStyleObj::CreateEmptyNumberingRules();
1962 break;
1967 return aAny;
1970 // XPropertySet
1972 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellRangesBase::getPropertySetInfo()
1974 SolarMutexGuard aGuard;
1975 static uno::Reference<beans::XPropertySetInfo> aRef(
1976 new SfxItemPropertySetInfo( pPropSet->getPropertyMap() ));
1977 return aRef;
1980 static void lcl_SetCellProperty( const SfxItemPropertyMapEntry& rEntry, const uno::Any& rValue,
1981 ScPatternAttr& rPattern, const ScDocument &rDoc,
1982 sal_uInt16& rFirstItemId, sal_uInt16& rSecondItemId )
1984 rFirstItemId = rEntry.nWID;
1985 rSecondItemId = 0;
1987 SfxItemSet& rSet = rPattern.GetItemSet();
1988 switch ( rEntry.nWID )
1990 case ATTR_VALUE_FORMAT:
1992 // language for number formats
1993 SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
1994 sal_uLong nOldFormat = rSet.Get( ATTR_VALUE_FORMAT ).GetValue();
1995 LanguageType eOldLang = rSet.Get( ATTR_LANGUAGE_FORMAT ).GetLanguage();
1996 nOldFormat = pFormatter->GetFormatForLanguageIfBuiltIn( nOldFormat, eOldLang );
1998 sal_Int32 nIntVal = 0;
1999 if ( !(rValue >>= nIntVal) )
2000 throw lang::IllegalArgumentException();
2002 sal_uLong nNewFormat = static_cast<sal_uLong>(nIntVal);
2003 rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
2005 const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
2006 LanguageType eNewLang =
2007 pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
2008 if ( eNewLang != eOldLang && eNewLang != LANGUAGE_DONTKNOW )
2010 rSet.Put( SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
2012 // if only language is changed,
2013 // don't touch number format attribute
2014 sal_uLong nNewMod = nNewFormat % SV_COUNTRY_LANGUAGE_OFFSET;
2015 if ( nNewMod == ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) &&
2016 nNewMod <= SV_MAX_COUNT_STANDARD_FORMATS )
2018 rFirstItemId = 0; // don't use ATTR_VALUE_FORMAT value
2021 rSecondItemId = ATTR_LANGUAGE_FORMAT;
2025 break;
2026 case ATTR_INDENT:
2028 sal_Int16 nIntVal = 0;
2029 if ( !(rValue >>= nIntVal) )
2030 throw lang::IllegalArgumentException();
2032 rSet.Put(ScIndentItem(o3tl::toTwips(nIntVal, o3tl::Length::mm100)));
2035 break;
2036 case ATTR_ROTATE_VALUE:
2038 sal_Int32 nRotVal = 0;
2039 if ( !(rValue >>= nRotVal) )
2040 throw lang::IllegalArgumentException();
2042 // stored value is always between 0 and 360 deg.
2043 nRotVal %= 36000;
2044 if ( nRotVal < 0 )
2045 nRotVal += 36000;
2047 rSet.Put( ScRotateValueItem( Degree100(nRotVal) ) );
2050 break;
2051 case ATTR_STACKED:
2053 table::CellOrientation eOrient;
2054 if( rValue >>= eOrient )
2056 switch( eOrient )
2058 case table::CellOrientation_STANDARD:
2059 rSet.Put( ScVerticalStackCell( false ) );
2060 break;
2061 case table::CellOrientation_TOPBOTTOM:
2062 rSet.Put( ScVerticalStackCell( false ) );
2063 rSet.Put( ScRotateValueItem( 27000_deg100 ) );
2064 rSecondItemId = ATTR_ROTATE_VALUE;
2065 break;
2066 case table::CellOrientation_BOTTOMTOP:
2067 rSet.Put( ScVerticalStackCell( false ) );
2068 rSet.Put( ScRotateValueItem( 9000_deg100 ) );
2069 rSecondItemId = ATTR_ROTATE_VALUE;
2070 break;
2071 case table::CellOrientation_STACKED:
2072 rSet.Put( ScVerticalStackCell( true ) );
2073 break;
2074 default:
2076 // added to avoid warnings
2081 break;
2082 default:
2084 SfxItemPropertySet::setPropertyValue(rEntry, rValue, rSet);
2089 void SAL_CALL ScCellRangesBase::setPropertyValue(
2090 const OUString& aPropertyName, const uno::Any& aValue )
2092 SolarMutexGuard aGuard;
2094 if ( !pDocShell || aRanges.empty() )
2095 throw uno::RuntimeException();
2097 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
2098 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( aPropertyName );
2099 if ( !pEntry )
2100 throw beans::UnknownPropertyException(aPropertyName);
2102 SetOnePropertyValue( pEntry, aValue );
2105 void ScCellRangesBase::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue )
2107 if ( !pEntry )
2108 return;
2110 if ( IsScItemWid( pEntry->nWID ) )
2112 if ( !aRanges.empty() ) // empty = nothing to do
2114 ScDocument& rDoc = pDocShell->GetDocument();
2116 // For parts of compound items with multiple properties (e.g. background)
2117 // the old item has to be first fetched from the document.
2118 //! But we can't recognize this case here
2119 //! -> an extra flag in PropertyMap entry, or something like that???
2120 //! fetch the item directly from its position in the range?
2121 // ClearInvalidItems, so that in any case we have an item with the correct type
2123 ScPatternAttr aPattern( *GetCurrentAttrsDeep() );
2124 SfxItemSet& rSet = aPattern.GetItemSet();
2125 rSet.ClearInvalidItems();
2127 sal_uInt16 nFirstItem, nSecondItem;
2128 lcl_SetCellProperty( *pEntry, aValue, aPattern, rDoc, nFirstItem, nSecondItem );
2130 for (sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; nWhich++)
2131 if ( nWhich != nFirstItem && nWhich != nSecondItem )
2132 rSet.ClearItem(nWhich);
2134 pDocShell->GetDocFunc().ApplyAttributes( *GetMarkData(), aPattern, true );
2137 else // implemented here
2138 switch ( pEntry->nWID )
2140 case EE_CHAR_ESCAPEMENT: // Specifically for xlsx import
2142 sal_Int32 nValue = 0;
2143 aValue >>= nValue;
2144 if (nValue)
2146 for (size_t i = 0, n = aRanges.size(); i < n; ++i)
2148 ScRange const & rRange = aRanges[i];
2150 /* TODO: Iterate through the range */
2151 ScAddress aAddr = rRange.aStart;
2152 ScDocument& rDoc = pDocShell->GetDocument();
2153 ScRefCellValue aCell(rDoc, aAddr);
2155 OUString aStr = aCell.getString(&rDoc);
2156 EditEngine aEngine( rDoc.GetEnginePool() );
2157 aEngine.SetEditTextObjectPool(rDoc.GetEditPool());
2159 /* EE_CHAR_ESCAPEMENT seems to be set on the cell _only_ when
2160 * there are no other attribs for the cell.
2161 * So, it is safe to overwrite the complete attribute set.
2162 * If there is a need - getting CellType and processing
2163 * the attributes could be considered.
2165 SfxItemSet aAttr = aEngine.GetEmptyItemSet();
2166 aEngine.SetText(aStr);
2167 if( nValue < 0 ) // Subscript
2168 aAttr.Put( SvxEscapementItem( SvxEscapement::Subscript, EE_CHAR_ESCAPEMENT ) );
2169 else // Superscript
2170 aAttr.Put( SvxEscapementItem( SvxEscapement::Superscript, EE_CHAR_ESCAPEMENT ) );
2171 aEngine.QuickSetAttribs(aAttr, ESelection(0, 0, 0, aStr.getLength()));
2173 // The cell will own the text object instance.
2174 rDoc.SetEditText(aRanges[0].aStart, aEngine.CreateTextObject());
2178 break;
2179 case SC_WID_UNO_CHCOLHDR:
2180 // chart header flags are set for this object, not stored with document
2181 bChartColAsHdr = ScUnoHelpFunctions::GetBoolFromAny( aValue );
2182 break;
2183 case SC_WID_UNO_CHROWHDR:
2184 bChartRowAsHdr = ScUnoHelpFunctions::GetBoolFromAny( aValue );
2185 break;
2186 case SC_WID_UNO_CELLSTYL:
2188 OUString aStrVal;
2189 aValue >>= aStrVal;
2190 OUString aString(ScStyleNameConversion::ProgrammaticToDisplayName(
2191 aStrVal, SfxStyleFamily::Para ));
2192 pDocShell->GetDocFunc().ApplyStyle( *GetMarkData(), aString, true );
2194 break;
2195 case SC_WID_UNO_TBLBORD:
2197 table::TableBorder aBorder;
2198 if ( !aRanges.empty() && ( aValue >>= aBorder ) ) // empty = nothing to do
2200 SvxBoxItem aOuter(ATTR_BORDER);
2201 SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
2202 ScHelperFunctions::FillBoxItems( aOuter, aInner, aBorder );
2204 ScHelperFunctions::ApplyBorder( pDocShell, aRanges, aOuter, aInner ); //! docfunc
2207 break;
2208 case SC_WID_UNO_TBLBORD2:
2210 table::TableBorder2 aBorder2;
2211 if ( !aRanges.empty() && ( aValue >>= aBorder2 ) ) // empty = nothing to do
2213 SvxBoxItem aOuter(ATTR_BORDER);
2214 SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
2215 ScHelperFunctions::FillBoxItems( aOuter, aInner, aBorder2 );
2217 ScHelperFunctions::ApplyBorder( pDocShell, aRanges, aOuter, aInner ); //! docfunc
2220 break;
2221 case SC_WID_UNO_CONDFMT:
2222 case SC_WID_UNO_CONDLOC:
2223 case SC_WID_UNO_CONDXML:
2225 uno::Reference<sheet::XSheetConditionalEntries> xInterface(aValue, uno::UNO_QUERY);
2226 if ( !aRanges.empty() && xInterface.is() ) // empty = nothing to do
2228 ScTableConditionalFormat* pFormat =
2229 dynamic_cast<ScTableConditionalFormat*>( xInterface.get() );
2230 if (pFormat)
2232 ScDocument& rDoc = pDocShell->GetDocument();
2233 bool bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
2234 bool bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
2235 formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2236 formula::FormulaGrammar::GRAM_UNSPECIFIED :
2237 formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2239 SCTAB nTab = aRanges.front().aStart.Tab();
2240 // To remove conditional formats for all cells in aRanges we need to:
2241 // Remove conditional format data from cells' attributes
2242 rDoc.RemoveCondFormatData( aRanges, nTab, 0 );
2243 // And also remove ranges from conditional formats list
2244 for (size_t i = 0; i < aRanges.size(); ++i)
2246 rDoc.GetCondFormList( aRanges[i].aStart.Tab() )->DeleteArea(
2247 aRanges[i].aStart.Col(), aRanges[i].aStart.Row(),
2248 aRanges[i].aEnd.Col(), aRanges[i].aEnd.Row() );
2251 // Then we can apply new conditional format if there is one
2252 if (pFormat->getCount())
2254 auto pNew = std::make_unique<ScConditionalFormat>( 0, &rDoc ); // Index will be set on inserting
2255 pFormat->FillFormat( *pNew, rDoc, eGrammar );
2256 pNew->SetRange( aRanges );
2257 pDocShell->GetDocFunc().ReplaceConditionalFormat( 0, std::move(pNew), nTab, aRanges );
2260 // and repaint
2261 for (size_t i = 0; i < aRanges.size(); ++i)
2262 pDocShell->PostPaint(aRanges[i], PaintPartFlags::Grid);
2263 pDocShell->SetDocumentModified();
2267 break;
2268 case SC_WID_UNO_VALIDAT:
2269 case SC_WID_UNO_VALILOC:
2270 case SC_WID_UNO_VALIXML:
2272 uno::Reference<beans::XPropertySet> xInterface(aValue, uno::UNO_QUERY);
2273 if ( !aRanges.empty() && xInterface.is() ) // empty = nothing to do
2275 ScTableValidationObj* pValidObj =
2276 dynamic_cast<ScTableValidationObj*>( xInterface.get() );
2277 if (pValidObj)
2279 ScDocument& rDoc = pDocShell->GetDocument();
2280 bool bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
2281 bool bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
2282 formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2283 formula::FormulaGrammar::GRAM_UNSPECIFIED :
2284 formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2286 std::unique_ptr<ScValidationData> pNewData(
2287 pValidObj->CreateValidationData( rDoc, eGrammar ));
2288 sal_uInt32 nIndex = rDoc.AddValidationEntry( *pNewData );
2289 pNewData.reset();
2291 ScPatternAttr aPattern(rDoc.getCellAttributeHelper());
2292 aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nIndex ) );
2293 pDocShell->GetDocFunc().ApplyAttributes( *GetMarkData(), aPattern, true );
2297 break;
2298 // SC_WID_UNO_NUMRULES is ignored...
2302 uno::Any SAL_CALL ScCellRangesBase::getPropertyValue( const OUString& aPropertyName )
2304 SolarMutexGuard aGuard;
2306 if ( !pDocShell || aRanges.empty() )
2307 throw uno::RuntimeException();
2309 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
2310 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( aPropertyName );
2311 if ( !pEntry )
2312 throw beans::UnknownPropertyException(aPropertyName);
2314 uno::Any aAny;
2315 GetOnePropertyValue( pEntry, aAny );
2316 return aAny;
2319 void ScCellRangesBase::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny )
2321 if ( !pEntry )
2322 return;
2324 if ( IsScItemWid( pEntry->nWID ) )
2326 SfxItemSet* pDataSet = GetCurrentDataSet();
2327 if ( pDataSet )
2329 switch ( pEntry->nWID ) // for special handling of items
2331 case ATTR_VALUE_FORMAT:
2333 ScDocument& rDoc = pDocShell->GetDocument();
2335 sal_uLong nOldFormat =
2336 pDataSet->Get( ATTR_VALUE_FORMAT ).GetValue();
2337 LanguageType eOldLang =
2338 pDataSet->Get( ATTR_LANGUAGE_FORMAT ).GetLanguage();
2339 nOldFormat = rDoc.GetFormatTable()->
2340 GetFormatForLanguageIfBuiltIn( nOldFormat, eOldLang );
2341 rAny <<= static_cast<sal_Int32>(nOldFormat);
2343 break;
2344 case ATTR_INDENT:
2345 rAny <<= static_cast<sal_Int16>( convertTwipToMm100(static_cast<const ScIndentItem&>(
2346 pDataSet->Get(pEntry->nWID)).GetValue()) );
2347 break;
2348 case ATTR_STACKED:
2350 Degree100 nRot = pDataSet->Get(ATTR_ROTATE_VALUE).GetValue();
2351 bool bStacked = static_cast<const ScVerticalStackCell&>(pDataSet->Get(pEntry->nWID)).GetValue();
2352 SvxOrientationItem( nRot, bStacked, TypedWhichId<SvxOrientationItem>(0) ).QueryValue( rAny );
2354 break;
2355 default:
2356 SfxItemPropertySet::getPropertyValue(*pEntry, *pDataSet, rAny);
2360 else // implemented here
2361 switch ( pEntry->nWID )
2363 case SC_WID_UNO_CHCOLHDR:
2364 rAny <<= bChartColAsHdr;
2365 break;
2366 case SC_WID_UNO_CHROWHDR:
2367 rAny <<= bChartRowAsHdr;
2368 break;
2369 case SC_WID_UNO_CELLSTYL:
2371 OUString aStyleName;
2372 const ScStyleSheet* pStyle = pDocShell->GetDocument().GetSelectionStyle(*GetMarkData());
2373 if (pStyle)
2374 aStyleName = pStyle->GetName();
2375 rAny <<= ScStyleNameConversion::DisplayToProgrammaticName(
2376 aStyleName, SfxStyleFamily::Para );
2378 break;
2379 case SC_WID_UNO_TBLBORD:
2380 case SC_WID_UNO_TBLBORD2:
2382 //! loop through all ranges
2383 if ( !aRanges.empty() )
2385 const ScRange & rFirst = aRanges[ 0 ];
2386 SvxBoxItem aOuter(ATTR_BORDER);
2387 SvxBoxInfoItem aInner(ATTR_BORDER_INNER);
2389 ScDocument& rDoc = pDocShell->GetDocument();
2390 ScMarkData aMark(rDoc.GetSheetLimits());
2391 aMark.SetMarkArea( rFirst );
2392 aMark.SelectTable( rFirst.aStart.Tab(), true );
2393 rDoc.GetSelectionFrame( aMark, aOuter, aInner );
2395 if (pEntry->nWID == SC_WID_UNO_TBLBORD2)
2396 ScHelperFunctions::AssignTableBorder2ToAny( rAny, aOuter, aInner);
2397 else
2398 ScHelperFunctions::AssignTableBorderToAny( rAny, aOuter, aInner);
2401 break;
2402 case SC_WID_UNO_CONDFMT:
2403 case SC_WID_UNO_CONDLOC:
2404 case SC_WID_UNO_CONDXML:
2406 const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
2407 if ( pPattern )
2409 ScDocument& rDoc = pDocShell->GetDocument();
2410 bool bEnglish = ( pEntry->nWID != SC_WID_UNO_CONDLOC );
2411 bool bXML = ( pEntry->nWID == SC_WID_UNO_CONDXML );
2412 formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2413 rDoc.GetStorageGrammar() :
2414 formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2415 const ScCondFormatIndexes& rIndex =
2416 pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData();
2417 sal_uLong nIndex = 0;
2418 if(!rIndex.empty())
2419 nIndex = rIndex[0];
2420 rAny <<= uno::Reference<sheet::XSheetConditionalEntries>(
2421 new ScTableConditionalFormat( &rDoc, nIndex, aRanges.front().aStart.Tab(), eGrammar ));
2424 break;
2425 case SC_WID_UNO_VALIDAT:
2426 case SC_WID_UNO_VALILOC:
2427 case SC_WID_UNO_VALIXML:
2429 const ScPatternAttr* pPattern = GetCurrentAttrsDeep();
2430 if ( pPattern )
2432 ScDocument& rDoc = pDocShell->GetDocument();
2433 bool bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC );
2434 bool bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML );
2435 formula::FormulaGrammar::Grammar eGrammar = (bXML ?
2436 rDoc.GetStorageGrammar() :
2437 formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML));
2438 sal_uLong nIndex =
2439 pPattern->GetItem(ATTR_VALIDDATA).GetValue();
2440 rAny <<= uno::Reference<beans::XPropertySet>(
2441 new ScTableValidationObj( rDoc, nIndex, eGrammar ));
2444 break;
2445 case SC_WID_UNO_NUMRULES:
2447 // always return empty numbering rules object
2448 rAny <<= ScStyleObj::CreateEmptyNumberingRules();
2450 break;
2451 case SC_WID_UNO_ABSNAME:
2453 OUString sRet;
2454 aRanges.Format(sRet, ScRefFlags::RANGE_ABS_3D, pDocShell->GetDocument());
2455 rAny <<= sRet;
2457 break;
2458 case SC_WID_UNO_FORMATID:
2460 const ScPatternAttr* pPattern = GetCurrentAttrsFlat();
2461 rAny <<= pPattern->GetPAKey();
2463 break;
2467 void SAL_CALL ScCellRangesBase::addPropertyChangeListener( const OUString& /* aPropertyName */,
2468 const uno::Reference<beans::XPropertyChangeListener>& /* aListener */)
2470 SolarMutexGuard aGuard;
2471 if ( aRanges.empty() )
2472 throw uno::RuntimeException();
2474 OSL_FAIL("not implemented");
2477 void SAL_CALL ScCellRangesBase::removePropertyChangeListener( const OUString& /* aPropertyName */,
2478 const uno::Reference<beans::XPropertyChangeListener>& /* aListener */)
2480 SolarMutexGuard aGuard;
2481 if ( aRanges.empty() )
2482 throw uno::RuntimeException();
2484 OSL_FAIL("not implemented");
2487 void SAL_CALL ScCellRangesBase::addVetoableChangeListener( const OUString&,
2488 const uno::Reference<beans::XVetoableChangeListener>&)
2490 OSL_FAIL("not implemented");
2493 void SAL_CALL ScCellRangesBase::removeVetoableChangeListener( const OUString&,
2494 const uno::Reference<beans::XVetoableChangeListener>&)
2496 OSL_FAIL("not implemented");
2499 // XMultiPropertySet
2501 void SAL_CALL ScCellRangesBase::setPropertyValues( const uno::Sequence< OUString >& aPropertyNames,
2502 const uno::Sequence< uno::Any >& aValues )
2504 SolarMutexGuard aGuard;
2506 sal_Int32 nCount(aPropertyNames.getLength());
2507 sal_Int32 nValues(aValues.getLength());
2508 if (nCount != nValues)
2509 throw lang::IllegalArgumentException();
2511 if ( !(pDocShell && nCount) )
2512 return;
2514 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
2515 const OUString* pNames = aPropertyNames.getConstArray();
2516 const uno::Any* pValues = aValues.getConstArray();
2518 std::unique_ptr<const SfxItemPropertyMapEntry*[]> pEntryArray(new const SfxItemPropertyMapEntry*[nCount]);
2520 sal_Int32 i;
2521 for(i = 0; i < nCount; i++)
2523 // first loop: find all properties in map, but handle only CellStyle
2524 // (CellStyle must be set before any other cell properties)
2526 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( pNames[i] );
2527 pEntryArray[i] = pEntry;
2528 if (pEntry)
2530 if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
2534 SetOnePropertyValue( pEntry, pValues[i] );
2536 catch ( lang::IllegalArgumentException& )
2538 TOOLS_WARN_EXCEPTION( "sc", "exception when setting cell style"); // not supposed to happen
2544 ScDocument& rDoc = pDocShell->GetDocument();
2545 std::unique_ptr<ScPatternAttr> pOldPattern;
2546 std::unique_ptr<ScPatternAttr> pNewPattern;
2548 for(i = 0; i < nCount; i++)
2550 // second loop: handle other properties
2552 const SfxItemPropertyMapEntry* pEntry = pEntryArray[i];
2553 if ( pEntry )
2555 if ( IsScItemWid( pEntry->nWID ) ) // can be handled by SfxItemPropertySet
2557 if ( !pOldPattern )
2559 pOldPattern.reset(new ScPatternAttr( *GetCurrentAttrsDeep() ));
2560 pOldPattern->GetItemSet().ClearInvalidItems();
2561 pNewPattern.reset(new ScPatternAttr(rDoc.getCellAttributeHelper()));
2564 // collect items in pNewPattern, apply with one call after the loop
2566 sal_uInt16 nFirstItem, nSecondItem;
2567 lcl_SetCellProperty( *pEntry, pValues[i], *pOldPattern, rDoc, nFirstItem, nSecondItem );
2569 // put only affected items into new set
2570 if ( nFirstItem )
2571 pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nFirstItem ) );
2572 if ( nSecondItem )
2573 pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nSecondItem ) );
2575 else if ( pEntry->nWID != SC_WID_UNO_CELLSTYL ) // CellStyle is handled above
2577 // call virtual method to set a single property
2578 SetOnePropertyValue( pEntry, pValues[i] );
2583 if ( pNewPattern && !aRanges.empty() )
2584 pDocShell->GetDocFunc().ApplyAttributes( *GetMarkData(), *pNewPattern, true );
2587 uno::Sequence<uno::Any> SAL_CALL ScCellRangesBase::getPropertyValues(
2588 const uno::Sequence< OUString >& aPropertyNames )
2590 SolarMutexGuard aGuard;
2592 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
2594 uno::Sequence<uno::Any> aRet(aPropertyNames.getLength());
2595 uno::Any* pProperties = aRet.getArray();
2596 for(sal_Int32 i = 0; i < aPropertyNames.getLength(); i++)
2598 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( aPropertyNames[i] );
2599 GetOnePropertyValue( pEntry, pProperties[i] );
2601 return aRet;
2604 void SAL_CALL ScCellRangesBase::addPropertiesChangeListener( const uno::Sequence< OUString >& /* aPropertyNames */,
2605 const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
2607 OSL_FAIL("not implemented");
2610 void SAL_CALL ScCellRangesBase::removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
2612 OSL_FAIL("not implemented");
2615 void SAL_CALL ScCellRangesBase::firePropertiesChangeEvent( const uno::Sequence< OUString >& /* aPropertyNames */,
2616 const uno::Reference< beans::XPropertiesChangeListener >& /* xListener */ )
2618 OSL_FAIL("not implemented");
2621 IMPL_LINK( ScCellRangesBase, ValueListenerHdl, const SfxHint&, rHint, void )
2623 if ( pDocShell && (rHint.GetId() == SfxHintId::ScDataChanged))
2625 // This may be called several times for a single change, if several formulas
2626 // in the range are notified. So only a flag is set that is checked when
2627 // SfxHintId::DataChanged is received.
2629 bGotDataChangedHint = true;
2633 // XTolerantMultiPropertySet
2634 uno::Sequence< beans::SetPropertyTolerantFailed > SAL_CALL ScCellRangesBase::setPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames,
2635 const uno::Sequence< uno::Any >& aValues )
2637 SolarMutexGuard aGuard;
2639 sal_Int32 nCount(aPropertyNames.getLength());
2640 sal_Int32 nValues(aValues.getLength());
2641 if (nCount != nValues)
2642 throw lang::IllegalArgumentException();
2644 if ( pDocShell && nCount )
2646 uno::Sequence < beans::SetPropertyTolerantFailed > aReturns(nCount);
2647 beans::SetPropertyTolerantFailed* pReturns = aReturns.getArray();
2649 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
2650 const OUString* pNames = aPropertyNames.getConstArray();
2651 const uno::Any* pValues = aValues.getConstArray();
2653 std::unique_ptr<const SfxItemPropertyMapEntry*[]> pMapArray(new const SfxItemPropertyMapEntry*[nCount]);
2655 sal_Int32 i;
2656 for(i = 0; i < nCount; i++)
2658 // first loop: find all properties in map, but handle only CellStyle
2659 // (CellStyle must be set before any other cell properties)
2661 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( pNames[i] );
2662 pMapArray[i] = pEntry;
2663 if (pEntry)
2665 if ( pEntry->nWID == SC_WID_UNO_CELLSTYL )
2669 SetOnePropertyValue( pEntry, pValues[i] );
2671 catch ( lang::IllegalArgumentException& )
2673 TOOLS_WARN_EXCEPTION( "sc", "exception when setting cell style"); // not supposed to happen
2679 ScDocument& rDoc = pDocShell->GetDocument();
2680 std::unique_ptr<ScPatternAttr> pOldPattern;
2681 std::unique_ptr<ScPatternAttr> pNewPattern;
2683 sal_Int32 nFailed(0);
2684 for(i = 0; i < nCount; i++)
2686 // second loop: handle other properties
2688 const SfxItemPropertyMapEntry* pEntry = pMapArray[i];
2689 if ( pEntry && ((pEntry->nFlags & beans::PropertyAttribute::READONLY) == 0))
2691 if ( IsScItemWid( pEntry->nWID ) ) // can be handled by SfxItemPropertySet
2693 if ( !pOldPattern )
2695 pOldPattern.reset(new ScPatternAttr( *GetCurrentAttrsDeep() ));
2696 pOldPattern->GetItemSet().ClearInvalidItems();
2697 pNewPattern.reset(new ScPatternAttr(rDoc.getCellAttributeHelper()));
2700 // collect items in pNewPattern, apply with one call after the loop
2703 sal_uInt16 nFirstItem, nSecondItem;
2704 lcl_SetCellProperty( *pEntry, pValues[i], *pOldPattern, rDoc, nFirstItem, nSecondItem );
2706 // put only affected items into new set
2707 if ( nFirstItem )
2708 pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nFirstItem ) );
2709 if ( nSecondItem )
2710 pNewPattern->GetItemSet().Put( pOldPattern->GetItemSet().Get( nSecondItem ) );
2712 catch ( lang::IllegalArgumentException& )
2714 pReturns[nFailed].Name = pNames[i];
2715 pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
2718 else if ( pEntry->nWID != SC_WID_UNO_CELLSTYL ) // CellStyle is handled above
2720 // call virtual method to set a single property
2723 SetOnePropertyValue( pEntry, pValues[i] );
2725 catch ( lang::IllegalArgumentException& )
2727 pReturns[nFailed].Name = pNames[i];
2728 pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::ILLEGAL_ARGUMENT;
2732 else
2734 pReturns[nFailed].Name = pNames[i];
2735 if (pEntry)
2736 pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::PROPERTY_VETO;
2737 else
2738 pReturns[nFailed++].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
2742 if ( pNewPattern && !aRanges.empty() )
2743 pDocShell->GetDocFunc().ApplyAttributes( *GetMarkData(), *pNewPattern, true );
2745 aReturns.realloc(nFailed);
2747 return aReturns;
2749 return uno::Sequence < beans::SetPropertyTolerantFailed >();
2752 uno::Sequence< beans::GetPropertyTolerantResult > SAL_CALL ScCellRangesBase::getPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames )
2754 SolarMutexGuard aGuard;
2756 sal_Int32 nCount(aPropertyNames.getLength());
2757 uno::Sequence < beans::GetPropertyTolerantResult > aReturns(nCount);
2758 beans::GetPropertyTolerantResult* pReturns = aReturns.getArray();
2760 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
2762 for(sal_Int32 i = 0; i < nCount; i++)
2764 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( aPropertyNames[i] );
2765 if (!pEntry)
2767 pReturns[i].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
2769 else
2771 sal_uInt16 nItemWhich = 0;
2772 lcl_GetPropertyWhich( pEntry, nItemWhich );
2773 pReturns[i].State = GetOnePropertyState( nItemWhich, pEntry );
2774 GetOnePropertyValue( pEntry, pReturns[i].Value );
2775 pReturns[i].Result = beans::TolerantPropertySetResultType::SUCCESS;
2778 return aReturns;
2781 uno::Sequence< beans::GetDirectPropertyTolerantResult > SAL_CALL ScCellRangesBase::getDirectPropertyValuesTolerant( const uno::Sequence< OUString >& aPropertyNames )
2783 SolarMutexGuard aGuard;
2785 sal_Int32 nCount(aPropertyNames.getLength());
2786 uno::Sequence < beans::GetDirectPropertyTolerantResult > aReturns(nCount);
2787 beans::GetDirectPropertyTolerantResult* pReturns = aReturns.getArray();
2789 const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class
2791 sal_Int32 j = 0;
2792 for(sal_Int32 i = 0; i < nCount; i++)
2794 const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( aPropertyNames[i] );
2795 if (!pEntry)
2797 pReturns[i].Result = beans::TolerantPropertySetResultType::UNKNOWN_PROPERTY;
2799 else
2801 sal_uInt16 nItemWhich = 0;
2802 lcl_GetPropertyWhich( pEntry, nItemWhich );
2803 pReturns[j].State = GetOnePropertyState( nItemWhich, pEntry );
2804 if (pReturns[j].State == beans::PropertyState_DIRECT_VALUE)
2806 GetOnePropertyValue( pEntry, pReturns[j].Value );
2807 pReturns[j].Result = beans::TolerantPropertySetResultType::SUCCESS;
2808 pReturns[j].Name = aPropertyNames[i];
2809 ++j;
2813 if (j < nCount)
2814 aReturns.realloc(j);
2815 return aReturns;
2818 // XIndent
2820 void SAL_CALL ScCellRangesBase::decrementIndent()
2822 SolarMutexGuard aGuard;
2823 if ( pDocShell && !aRanges.empty() )
2825 //#97041#; put only MultiMarked ScMarkData in ChangeIndent
2826 ScMarkData aMarkData(*GetMarkData());
2827 aMarkData.MarkToMulti();
2828 pDocShell->GetDocFunc().ChangeIndent( aMarkData, false, true );
2832 void SAL_CALL ScCellRangesBase::incrementIndent()
2834 SolarMutexGuard aGuard;
2835 if ( pDocShell && !aRanges.empty() )
2837 //#97041#; put only MultiMarked ScMarkData in ChangeIndent
2838 ScMarkData aMarkData(*GetMarkData());
2839 aMarkData.MarkToMulti();
2840 pDocShell->GetDocFunc().ChangeIndent( aMarkData, true, true );
2844 // XChartData
2846 std::unique_ptr<ScMemChart> ScCellRangesBase::CreateMemChart_Impl() const
2848 if ( pDocShell && !aRanges.empty() )
2850 ScRangeListRef xChartRanges;
2851 if ( aRanges.size() == 1 )
2853 // set useful table limit (only occupied data area)
2854 // (only here - Listeners are registered for the whole area)
2855 //! check immediately if a ScTableSheetObj?
2857 const ScDocument & rDoc = pDocShell->GetDocument();
2858 const ScRange & rRange = aRanges[0];
2859 if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == rDoc.MaxCol() &&
2860 rRange.aStart.Row() == 0 && rRange.aEnd.Row() == rDoc.MaxRow() )
2862 SCTAB nTab = rRange.aStart.Tab();
2864 SCCOL nStartX;
2865 SCROW nStartY; // Get start
2866 if (!pDocShell->GetDocument().GetDataStart( nTab, nStartX, nStartY ))
2868 nStartX = 0;
2869 nStartY = 0;
2872 SCCOL nEndX;
2873 SCROW nEndY; // Get end
2874 if (!pDocShell->GetDocument().GetTableArea( nTab, nEndX, nEndY ))
2876 nEndX = 0;
2877 nEndY = 0;
2880 xChartRanges = new ScRangeList( ScRange( nStartX, nStartY, nTab, nEndX, nEndY, nTab ) );
2883 if (!xChartRanges.is()) // otherwise take Ranges directly
2884 xChartRanges = new ScRangeList(aRanges);
2885 ScChartArray aArr( pDocShell->GetDocument(), xChartRanges );
2887 // RowAsHdr = ColHeaders and vice versa
2888 aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr );
2890 return aArr.CreateMemChart();
2892 return nullptr;
2895 uno::Sequence< uno::Sequence<double> > SAL_CALL ScCellRangesBase::getData()
2897 SolarMutexGuard aGuard;
2898 std::unique_ptr<ScMemChart> pMemChart(CreateMemChart_Impl());
2899 if ( pMemChart )
2901 sal_Int32 nColCount = pMemChart->GetColCount();
2902 sal_Int32 nRowCount = static_cast<sal_Int32>(pMemChart->GetRowCount());
2904 uno::Sequence< uno::Sequence<double> > aRowSeq( nRowCount );
2905 uno::Sequence<double>* pRowAry = aRowSeq.getArray();
2906 for (sal_Int32 nRow = 0; nRow < nRowCount; nRow++)
2908 uno::Sequence<double> aColSeq( nColCount );
2909 double* pColAry = aColSeq.getArray();
2910 for (sal_Int32 nCol = 0; nCol < nColCount; nCol++)
2911 pColAry[nCol] = pMemChart->GetData( nCol, nRow );
2913 pRowAry[nRow] = std::move(aColSeq);
2916 return aRowSeq;
2919 return {};
2922 ScRangeListRef ScCellRangesBase::GetLimitedChartRanges_Impl( sal_Int32 nDataColumns, sal_Int32 nDataRows ) const
2924 if ( aRanges.size() == 1 )
2926 const ScDocument & rDoc = pDocShell->GetDocument();
2927 const ScRange & rRange = aRanges[0];
2928 if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == rDoc.MaxCol() &&
2929 rRange.aStart.Row() == 0 && rRange.aEnd.Row() == rDoc.MaxRow() )
2931 // if aRanges is a complete sheet, limit to given size
2933 SCTAB nTab = rRange.aStart.Tab();
2935 sal_Int32 nEndColumn = nDataColumns - 1 + ( bChartColAsHdr ? 1 : 0 );
2936 if ( nEndColumn < 0 )
2937 nEndColumn = 0;
2938 if ( nEndColumn > rDoc.MaxCol() )
2939 nEndColumn = rDoc.MaxCol();
2941 sal_Int32 nEndRow = nDataRows - 1 + ( bChartRowAsHdr ? 1 : 0 );
2942 if ( nEndRow < 0 )
2943 nEndRow = 0;
2944 if ( nEndRow > rDoc.MaxRow() )
2945 nEndRow = rDoc.MaxRow();
2947 ScRangeListRef xChartRanges = new ScRangeList( ScRange( 0, 0, nTab, static_cast<SCCOL>(nEndColumn), static_cast<SCROW>(nEndRow), nTab ) );
2948 return xChartRanges;
2952 return new ScRangeList(aRanges); // as-is
2955 void SAL_CALL ScCellRangesBase::setData( const uno::Sequence< uno::Sequence<double> >& aData )
2957 SolarMutexGuard aGuard;
2958 bool bDone = false;
2959 sal_Int32 nRowCount = aData.getLength();
2960 sal_Int32 nColCount = nRowCount ? aData[0].getLength() : 0;
2961 ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( nColCount, nRowCount );
2962 if ( pDocShell && xChartRanges.is() )
2964 ScDocument& rDoc = pDocShell->GetDocument();
2965 ScChartArray aArr( rDoc, xChartRanges );
2966 aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr ); // RowAsHdr = ColHeaders
2967 const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
2968 if (pPosMap)
2970 if ( pPosMap->GetColCount() == static_cast<SCCOL>(nColCount) &&
2971 pPosMap->GetRowCount() == static_cast<SCROW>(nRowCount) )
2973 for (sal_Int32 nRow=0; nRow<nRowCount; nRow++)
2975 const uno::Sequence<double>& rRowSeq = aData[nRow];
2976 const double* pArray = rRowSeq.getConstArray();
2977 nColCount = rRowSeq.getLength();
2978 for (sal_Int32 nCol=0; nCol<nColCount; nCol++)
2980 const ScAddress* pPos = pPosMap->GetPosition(
2981 sal::static_int_cast<SCCOL>(nCol),
2982 sal::static_int_cast<SCROW>(nRow) );
2983 if (pPos)
2985 double fVal = pArray[nCol];
2986 if ( fVal == DBL_MIN )
2987 rDoc.SetEmptyCell(*pPos);
2988 else
2989 rDoc.SetValue(*pPos, pArray[nCol]);
2994 //! undo
2995 PaintGridRanges_Impl();
2996 pDocShell->SetDocumentModified();
2997 ForceChartListener_Impl(); // call listeners for this object synchronously
2998 bDone = true;
3003 if (!bDone)
3004 throw uno::RuntimeException();
3007 uno::Sequence<OUString> SAL_CALL ScCellRangesBase::getRowDescriptions()
3009 SolarMutexGuard aGuard;
3010 std::unique_ptr<ScMemChart> pMemChart(CreateMemChart_Impl());
3011 if ( pMemChart )
3013 sal_Int32 nRowCount = static_cast<sal_Int32>(pMemChart->GetRowCount());
3014 uno::Sequence<OUString> aSeq( nRowCount );
3015 OUString* pAry = aSeq.getArray();
3016 for (sal_Int32 nRow = 0; nRow < nRowCount; nRow++)
3017 pAry[nRow] = pMemChart->GetRowText(nRow);
3019 return aSeq;
3021 return {};
3024 void SAL_CALL ScCellRangesBase::setRowDescriptions(
3025 const uno::Sequence<OUString>& aRowDescriptions )
3027 SolarMutexGuard aGuard;
3028 bool bDone = false;
3029 if ( bChartColAsHdr )
3031 sal_Int32 nRowCount = aRowDescriptions.getLength();
3032 ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( 1, nRowCount );
3033 if ( pDocShell && xChartRanges.is() )
3035 ScDocument& rDoc = pDocShell->GetDocument();
3036 ScChartArray aArr( rDoc, xChartRanges );
3037 aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr ); // RowAsHdr = ColHeaders
3038 const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
3039 if (pPosMap)
3041 if ( pPosMap->GetRowCount() == static_cast<SCROW>(nRowCount) )
3043 const OUString* pArray = aRowDescriptions.getConstArray();
3044 for (sal_Int32 nRow=0; nRow<nRowCount; nRow++)
3046 const ScAddress* pPos = pPosMap->GetRowHeaderPosition(
3047 static_cast<SCSIZE>(nRow) );
3048 if (pPos)
3050 const OUString& aStr = pArray[nRow];
3051 if (aStr.isEmpty())
3052 rDoc.SetEmptyCell(*pPos);
3053 else
3055 ScSetStringParam aParam;
3056 aParam.setTextInput();
3057 rDoc.SetString(*pPos, aStr, &aParam);
3062 //! undo
3063 PaintGridRanges_Impl();
3064 pDocShell->SetDocumentModified();
3065 ForceChartListener_Impl(); // call listeners for this object synchronously
3066 bDone = true;
3072 if (!bDone)
3073 throw uno::RuntimeException();
3076 uno::Sequence<OUString> SAL_CALL ScCellRangesBase::getColumnDescriptions()
3078 SolarMutexGuard aGuard;
3079 std::unique_ptr<ScMemChart> pMemChart(CreateMemChart_Impl());
3080 if ( pMemChart )
3082 sal_Int32 nColCount = pMemChart->GetColCount();
3083 uno::Sequence<OUString> aSeq( nColCount );
3084 OUString* pAry = aSeq.getArray();
3085 for (sal_Int32 nCol = 0; nCol < nColCount; nCol++)
3086 pAry[nCol] = pMemChart->GetColText(nCol);
3088 return aSeq;
3090 return {};
3093 void SAL_CALL ScCellRangesBase::setColumnDescriptions(
3094 const uno::Sequence<OUString>& aColumnDescriptions )
3096 SolarMutexGuard aGuard;
3097 bool bDone = false;
3098 if ( bChartRowAsHdr )
3100 sal_Int32 nColCount = aColumnDescriptions.getLength();
3101 ScRangeListRef xChartRanges = GetLimitedChartRanges_Impl( nColCount, 1 );
3102 if ( pDocShell && xChartRanges.is() )
3104 ScDocument& rDoc = pDocShell->GetDocument();
3105 ScChartArray aArr( rDoc, xChartRanges );
3106 aArr.SetHeaders( bChartRowAsHdr, bChartColAsHdr ); // RowAsHdr = ColHeaders
3107 const ScChartPositionMap* pPosMap = aArr.GetPositionMap();
3108 if (pPosMap)
3110 if ( pPosMap->GetColCount() == static_cast<SCCOL>(nColCount) )
3112 const OUString* pArray = aColumnDescriptions.getConstArray();
3113 for (sal_Int32 nCol=0; nCol<nColCount; nCol++)
3115 const ScAddress* pPos = pPosMap->GetColHeaderPosition(
3116 sal::static_int_cast<SCCOL>(nCol) );
3117 if (pPos)
3119 const OUString& aStr = pArray[nCol];
3120 if (aStr.isEmpty())
3121 rDoc.SetEmptyCell(*pPos);
3122 else
3124 ScSetStringParam aParam;
3125 aParam.setTextInput();
3126 rDoc.SetString(*pPos, aStr, &aParam);
3131 //! undo
3132 PaintGridRanges_Impl();
3133 pDocShell->SetDocumentModified();
3134 ForceChartListener_Impl(); // call listeners for this object synchronously
3135 bDone = true;
3141 if (!bDone)
3142 throw uno::RuntimeException();
3145 void ScCellRangesBase::ForceChartListener_Impl()
3147 // call Update immediately so the caller to setData etc. can
3148 // recognize the listener call
3150 if (!pDocShell)
3151 return;
3153 ScChartListenerCollection* pColl = pDocShell->GetDocument().GetChartListenerCollection();
3154 if (!pColl)
3155 return;
3157 ScChartListenerCollection::ListenersType& rListeners = pColl->getListeners();
3158 for (auto const& it : rListeners)
3160 ScChartListener *const p = it.second.get();
3161 assert(p);
3162 if (p->GetUnoSource() == static_cast<chart::XChartData*>(this) && p->IsDirty())
3163 p->Update();
3167 void SAL_CALL ScCellRangesBase::addChartDataChangeEventListener( const uno::Reference<
3168 chart::XChartDataChangeEventListener >& aListener )
3170 SolarMutexGuard aGuard;
3171 if ( !pDocShell || aRanges.empty() )
3172 return;
3174 //! test for duplicates ?
3176 ScDocument& rDoc = pDocShell->GetDocument();
3177 ScRangeListRef aRangesRef( new ScRangeList(aRanges) );
3178 ScChartListenerCollection* pColl = rDoc.GetChartListenerCollection();
3179 OUString aName = pColl->getUniqueName(u"__Uno");
3180 if (aName.isEmpty())
3181 // failed to create unique name.
3182 return;
3184 ScChartListener* pListener = new ScChartListener( aName, rDoc, aRangesRef );
3185 pListener->SetUno( aListener, this );
3186 pColl->insert( pListener );
3187 pListener->StartListeningTo();
3190 void SAL_CALL ScCellRangesBase::removeChartDataChangeEventListener( const uno::Reference<
3191 chart::XChartDataChangeEventListener >& aListener )
3193 SolarMutexGuard aGuard;
3194 if ( pDocShell && !aRanges.empty() )
3196 ScDocument& rDoc = pDocShell->GetDocument();
3197 ScChartListenerCollection* pColl = rDoc.GetChartListenerCollection();
3198 pColl->FreeUno( aListener, this );
3202 double SAL_CALL ScCellRangesBase::getNotANumber()
3204 // use DBL_MIN in ScChartArray, because Chart wants it so
3205 return DBL_MIN;
3208 sal_Bool SAL_CALL ScCellRangesBase::isNotANumber( double nNumber )
3210 // use DBL_MIN in ScChartArray, because Chart wants it so
3211 return (nNumber == DBL_MIN);
3214 // XModifyBroadcaster
3216 void SAL_CALL ScCellRangesBase::addModifyListener(const uno::Reference<util::XModifyListener>& aListener)
3218 SolarMutexGuard aGuard;
3219 if ( aRanges.empty() )
3220 throw uno::RuntimeException();
3222 aValueListeners.emplace_back( aListener );
3224 if ( aValueListeners.size() == 1 )
3226 if (!pValueListener)
3227 pValueListener.reset( new ScLinkListener( LINK( this, ScCellRangesBase, ValueListenerHdl ) ) );
3229 ScDocument& rDoc = pDocShell->GetDocument();
3230 for ( size_t i = 0, nCount = aRanges.size(); i < nCount; i++)
3231 rDoc.StartListeningArea( aRanges[ i ], false, pValueListener.get() );
3233 acquire(); // don't lose this object (one ref for all listeners)
3237 void SAL_CALL ScCellRangesBase::removeModifyListener( const uno::Reference<util::XModifyListener>& aListener )
3240 SolarMutexGuard aGuard;
3241 if ( aRanges.empty() )
3242 throw uno::RuntimeException();
3244 rtl::Reference<ScCellRangesBase> xSelfHold(this); // in case the listeners have the last ref
3246 sal_uInt16 nCount = aValueListeners.size();
3247 for ( sal_uInt16 n=nCount; n--; )
3249 uno::Reference<util::XModifyListener>& rObj = aValueListeners[n];
3250 if ( rObj == aListener )
3252 aValueListeners.erase( aValueListeners.begin() + n );
3254 if ( aValueListeners.empty() )
3256 if (pValueListener)
3257 pValueListener->EndListeningAll();
3259 release(); // release the ref for the listeners
3262 break;
3267 // XCellRangesQuery
3269 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryVisibleCells()
3271 SolarMutexGuard aGuard;
3272 if (pDocShell)
3274 //! Separate for all tables, if markings separated per table
3275 SCTAB nTab = lcl_FirstTab(aRanges);
3277 ScMarkData aMarkData(*GetMarkData());
3279 ScDocument& rDoc = pDocShell->GetDocument();
3280 SCCOL nCol = 0, nLastCol;
3281 while (nCol <= rDoc.MaxCol())
3283 if (rDoc.ColHidden(nCol, nTab, nullptr, &nLastCol))
3284 // hidden columns. Deselect them.
3285 aMarkData.SetMultiMarkArea(ScRange(nCol, 0, nTab, nLastCol, rDoc.MaxRow(), nTab), false);
3287 nCol = nLastCol + 1;
3290 SCROW nRow = 0, nLastRow;
3291 while (nRow <= rDoc.MaxRow())
3293 if (rDoc.RowHidden(nRow, nTab, nullptr, &nLastRow))
3294 // These rows are hidden. Deselect them.
3295 aMarkData.SetMultiMarkArea(ScRange(0, nRow, nTab, rDoc.MaxCol(), nLastRow, nTab), false);
3297 nRow = nLastRow + 1;
3300 ScRangeList aNewRanges;
3301 aMarkData.FillRangeListWithMarks( &aNewRanges, false );
3302 return new ScCellRangesObj( pDocShell, aNewRanges );
3305 return nullptr;
3308 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryEmptyCells()
3310 SolarMutexGuard aGuard;
3311 if (pDocShell)
3313 ScDocument& rDoc = pDocShell->GetDocument();
3315 ScMarkData aMarkData(*GetMarkData());
3317 // mark occupied cells
3318 for (size_t i = 0, nCount = aRanges.size(); i < nCount; ++i)
3320 ScRange const & rRange = aRanges[ i ];
3322 ScCellIterator aIter(rDoc, rRange);
3323 for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
3325 // notes count as non-empty
3326 if (!aIter.isEmpty())
3327 aMarkData.SetMultiMarkArea(ScRange(aIter.GetPos()), false);
3331 ScRangeList aNewRanges;
3332 // IsMultiMarked is not enough (will not be reset during deselecting)
3333 //if (aMarkData.HasAnyMultiMarks()) // #i20044# should be set for all empty range
3334 aMarkData.FillRangeListWithMarks( &aNewRanges, false );
3336 return new ScCellRangesObj( pDocShell, aNewRanges ); // aNewRanges can be empty
3339 return nullptr;
3342 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryContentCells(
3343 sal_Int16 nContentFlags )
3345 SolarMutexGuard aGuard;
3346 if (pDocShell)
3348 ScDocument& rDoc = pDocShell->GetDocument();
3350 ScMarkData aMarkData(rDoc.GetSheetLimits());
3352 // select matching cells
3353 for ( size_t i = 0, nCount = aRanges.size(); i < nCount; ++i )
3355 ScRange const & rRange = aRanges[ i ];
3357 ScCellIterator aIter(rDoc, rRange);
3358 for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
3360 bool bAdd = false;
3361 switch (aIter.getType())
3363 case CELLTYPE_STRING:
3364 if ( nContentFlags & sheet::CellFlags::STRING )
3365 bAdd = true;
3366 break;
3367 case CELLTYPE_EDIT:
3368 if ( (nContentFlags & sheet::CellFlags::STRING) || (nContentFlags & sheet::CellFlags::FORMATTED) )
3369 bAdd = true;
3370 break;
3371 case CELLTYPE_FORMULA:
3372 if ( nContentFlags & sheet::CellFlags::FORMULA )
3373 bAdd = true;
3374 break;
3375 case CELLTYPE_VALUE:
3376 if ( (nContentFlags & (sheet::CellFlags::VALUE|sheet::CellFlags::DATETIME))
3377 == (sheet::CellFlags::VALUE|sheet::CellFlags::DATETIME) )
3378 bAdd = true;
3379 else
3381 // date/time identification
3383 sal_uLong nIndex = static_cast<sal_uLong>(rDoc.GetAttr(
3384 aIter.GetPos(), ATTR_VALUE_FORMAT)->GetValue());
3385 SvNumFormatType nTyp = rDoc.GetFormatTable()->GetType(nIndex);
3386 if ((nTyp == SvNumFormatType::DATE) || (nTyp == SvNumFormatType::TIME) ||
3387 (nTyp == SvNumFormatType::DATETIME))
3389 if ( nContentFlags & sheet::CellFlags::DATETIME )
3390 bAdd = true;
3392 else
3394 if ( nContentFlags & sheet::CellFlags::VALUE )
3395 bAdd = true;
3398 break;
3399 default:
3401 // added to avoid warnings
3405 if (bAdd)
3406 aMarkData.SetMultiMarkArea(ScRange(aIter.GetPos()));
3410 if (nContentFlags & sheet::CellFlags::ANNOTATION)
3412 std::vector<sc::NoteEntry> aNotes;
3413 rDoc.GetNotesInRange(aRanges, aNotes);
3415 for (const auto& i : aNotes)
3417 aMarkData.SetMultiMarkArea(ScRange(i.maPos));
3421 ScRangeList aNewRanges;
3422 if (aMarkData.IsMultiMarked())
3423 aMarkData.FillRangeListWithMarks( &aNewRanges, false );
3425 return new ScCellRangesObj( pDocShell, aNewRanges ); // aNewRanges can be empty
3428 return nullptr;
3431 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryFormulaCells(
3432 sal_Int32 nResultFlags )
3434 SolarMutexGuard aGuard;
3435 if (pDocShell)
3437 ScDocument& rDoc = pDocShell->GetDocument();
3439 ScMarkData aMarkData(rDoc.GetSheetLimits());
3441 // select matching cells
3442 for ( size_t i = 0, nCount = aRanges.size(); i < nCount; ++i )
3444 ScRange const & rRange = aRanges[ i ];
3446 ScCellIterator aIter(rDoc, rRange);
3447 for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
3449 if (aIter.getType() == CELLTYPE_FORMULA)
3451 ScFormulaCell* pFCell = aIter.getFormulaCell();
3452 bool bAdd = false;
3453 if (pFCell->GetErrCode() != FormulaError::NONE)
3455 if ( nResultFlags & sheet::FormulaResult::ERROR )
3456 bAdd = true;
3458 else if (pFCell->IsValue())
3460 if ( nResultFlags & sheet::FormulaResult::VALUE )
3461 bAdd = true;
3463 else // String
3465 if ( nResultFlags & sheet::FormulaResult::STRING )
3466 bAdd = true;
3469 if (bAdd)
3470 aMarkData.SetMultiMarkArea(ScRange(aIter.GetPos()));
3475 ScRangeList aNewRanges;
3476 if (aMarkData.IsMultiMarked())
3477 aMarkData.FillRangeListWithMarks( &aNewRanges, false );
3479 return new ScCellRangesObj( pDocShell, aNewRanges ); // aNewRanges can be empty
3482 return nullptr;
3485 uno::Reference<sheet::XSheetCellRanges> ScCellRangesBase::QueryDifferences_Impl(
3486 const table::CellAddress& aCompare, bool bColumnDiff)
3488 if (pDocShell)
3490 size_t nRangeCount = aRanges.size();
3491 size_t i;
3492 ScDocument& rDoc = pDocShell->GetDocument();
3493 ScMarkData aMarkData(rDoc.GetSheetLimits());
3495 SCCOLROW nCmpPos = bColumnDiff ? static_cast<SCCOLROW>(aCompare.Row) : static_cast<SCCOLROW>(aCompare.Column);
3497 // first select everything, where at all something is in the comparison column
3498 // (in the second step the selection is cancelled for equal cells)
3500 SCTAB nTab = lcl_FirstTab(aRanges); //! for all tables, if markings per table
3501 ScRange aCmpRange, aCellRange;
3502 if (bColumnDiff)
3503 aCmpRange = ScRange( 0,nCmpPos,nTab, rDoc.MaxCol(),nCmpPos,nTab );
3504 else
3505 aCmpRange = ScRange( static_cast<SCCOL>(nCmpPos),0,nTab, static_cast<SCCOL>(nCmpPos),rDoc.MaxRow(),nTab );
3506 ScCellIterator aCmpIter(rDoc, aCmpRange);
3507 for (bool bHasCell = aCmpIter.first(); bHasCell; bHasCell = aCmpIter.next())
3509 SCCOLROW nCellPos = bColumnDiff ? static_cast<SCCOLROW>(aCmpIter.GetPos().Col()) : static_cast<SCCOLROW>(aCmpIter.GetPos().Row());
3510 if (bColumnDiff)
3511 aCellRange = ScRange( static_cast<SCCOL>(nCellPos),0,nTab,
3512 static_cast<SCCOL>(nCellPos),rDoc.MaxRow(),nTab );
3513 else
3514 aCellRange = ScRange( 0,nCellPos,nTab, rDoc.MaxCol(),nCellPos,nTab );
3516 for (i=0; i<nRangeCount; i++)
3518 ScRange aRange( aRanges[ i ] );
3519 if ( aRange.Intersects( aCellRange ) )
3521 if (bColumnDiff)
3523 aRange.aStart.SetCol(static_cast<SCCOL>(nCellPos));
3524 aRange.aEnd.SetCol(static_cast<SCCOL>(nCellPos));
3526 else
3528 aRange.aStart.SetRow(nCellPos);
3529 aRange.aEnd.SetRow(nCellPos);
3531 aMarkData.SetMultiMarkArea( aRange );
3536 // compare all not empty cells with the comparison column and accordingly
3537 // select or cancel
3539 ScAddress aCmpAddr;
3540 for (i=0; i<nRangeCount; i++)
3542 ScRange const & rRange = aRanges[ i ];
3544 ScCellIterator aIter( rDoc, rRange );
3545 for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
3547 if (bColumnDiff)
3548 aCmpAddr = ScAddress( aIter.GetPos().Col(), nCmpPos, aIter.GetPos().Tab() );
3549 else
3550 aCmpAddr = ScAddress( static_cast<SCCOL>(nCmpPos), aIter.GetPos().Row(), aIter.GetPos().Tab() );
3552 ScRange aOneRange(aIter.GetPos());
3553 if (!aIter.equalsWithoutFormat(aCmpAddr))
3554 aMarkData.SetMultiMarkArea( aOneRange );
3555 else
3556 aMarkData.SetMultiMarkArea( aOneRange, false ); // deselect
3560 ScRangeList aNewRanges;
3561 if (aMarkData.IsMultiMarked())
3562 aMarkData.FillRangeListWithMarks( &aNewRanges, false );
3564 return new ScCellRangesObj( pDocShell, aNewRanges ); // aNewRanges can be empty
3566 return nullptr;
3569 uno::Reference<sheet::XSheetCellRanges > SAL_CALL ScCellRangesBase::queryColumnDifferences(
3570 const table::CellAddress& aCompare )
3572 SolarMutexGuard aGuard;
3573 return QueryDifferences_Impl( aCompare, true );
3576 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryRowDifferences(
3577 const table::CellAddress& aCompare )
3579 SolarMutexGuard aGuard;
3580 return QueryDifferences_Impl( aCompare, false );
3583 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryIntersection(
3584 const table::CellRangeAddress& aRange )
3586 SolarMutexGuard aGuard;
3587 ScRange aMask( static_cast<SCCOL>(aRange.StartColumn), static_cast<SCROW>(aRange.StartRow), aRange.Sheet,
3588 static_cast<SCCOL>(aRange.EndColumn), static_cast<SCROW>(aRange.EndRow), aRange.Sheet );
3590 ScRangeList aNew;
3591 for ( size_t i = 0, nCount = aRanges.size(); i < nCount; ++i )
3593 ScRange aTemp( aRanges[ i ] );
3594 if ( aTemp.Intersects( aMask ) )
3595 aNew.Join( ScRange( std::max( aTemp.aStart.Col(), aMask.aStart.Col() ),
3596 std::max( aTemp.aStart.Row(), aMask.aStart.Row() ),
3597 std::max( aTemp.aStart.Tab(), aMask.aStart.Tab() ),
3598 std::min( aTemp.aEnd.Col(), aMask.aEnd.Col() ),
3599 std::min( aTemp.aEnd.Row(), aMask.aEnd.Row() ),
3600 std::min( aTemp.aEnd.Tab(), aMask.aEnd.Tab() ) ) );
3603 return new ScCellRangesObj( pDocShell, aNew ); // can be empty
3606 // XFormulaQuery
3608 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryPrecedents(
3609 sal_Bool bRecursive )
3611 SolarMutexGuard aGuard;
3612 if ( pDocShell )
3614 ScDocument& rDoc = pDocShell->GetDocument();
3616 ScRangeList aNewRanges(aRanges);
3617 bool bFound;
3620 bFound = false;
3622 // aMarkData uses aNewRanges, not aRanges, so GetMarkData can't be used
3623 ScMarkData aMarkData(rDoc.GetSheetLimits());
3624 aMarkData.MarkFromRangeList( aNewRanges, false );
3626 for (size_t nR = 0, nCount = aNewRanges.size(); nR<nCount; ++nR)
3628 ScRange const & rRange = aNewRanges[ nR];
3629 ScCellIterator aIter(rDoc, rRange);
3630 for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
3632 if (aIter.getType() != CELLTYPE_FORMULA)
3633 continue;
3635 ScDetectiveRefIter aRefIter(rDoc, aIter.getFormulaCell());
3636 ScRange aRefRange;
3637 while ( aRefIter.GetNextRef( aRefRange) )
3639 if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aRefRange ) )
3640 bFound = true;
3641 aMarkData.SetMultiMarkArea(aRefRange);
3646 aMarkData.FillRangeListWithMarks( &aNewRanges, true );
3648 while ( bRecursive && bFound );
3650 return new ScCellRangesObj( pDocShell, aNewRanges );
3653 return nullptr;
3656 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryDependents(
3657 sal_Bool bRecursive )
3659 SolarMutexGuard aGuard;
3660 if ( pDocShell )
3662 ScDocument& rDoc = pDocShell->GetDocument();
3664 ScRangeList aNewRanges(aRanges);
3665 bool bFound;
3668 bFound = false;
3670 // aMarkData uses aNewRanges, not aRanges, so GetMarkData can't be used
3671 ScMarkData aMarkData(rDoc.GetSheetLimits());
3672 aMarkData.MarkFromRangeList( aNewRanges, false );
3674 SCTAB nTab = lcl_FirstTab(aNewRanges); //! all tables
3676 ScCellIterator aCellIter( rDoc, ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab) );
3677 for (bool bHasCell = aCellIter.first(); bHasCell; bHasCell = aCellIter.next())
3679 if (aCellIter.getType() != CELLTYPE_FORMULA)
3680 continue;
3682 bool bMark = false;
3683 ScDetectiveRefIter aIter(rDoc, aCellIter.getFormulaCell());
3684 ScRange aRefRange;
3685 while ( aIter.GetNextRef( aRefRange) && !bMark )
3687 size_t nRangesCount = aNewRanges.size();
3688 for (size_t nR = 0; nR < nRangesCount; ++nR)
3690 ScRange const & rRange = aNewRanges[ nR ];
3691 if (rRange.Intersects(aRefRange))
3693 bMark = true; // depending on part of Range
3694 break;
3698 if (bMark)
3700 ScRange aCellRange(aCellIter.GetPos());
3701 if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aCellRange ) )
3702 bFound = true;
3703 aMarkData.SetMultiMarkArea(aCellRange);
3707 aMarkData.FillRangeListWithMarks( &aNewRanges, true );
3709 while ( bRecursive && bFound );
3711 return new ScCellRangesObj( pDocShell, aNewRanges );
3714 return nullptr;
3717 // XSearchable
3719 uno::Reference<util::XSearchDescriptor> SAL_CALL ScCellRangesBase::createSearchDescriptor()
3721 return new ScCellSearchObj;
3724 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangesBase::findAll(
3725 const uno::Reference<util::XSearchDescriptor>& xDesc )
3727 SolarMutexGuard aGuard;
3728 // should we return Null if nothing is found(?)
3729 uno::Reference<container::XIndexAccess> xRet;
3730 if ( pDocShell && xDesc.is() )
3732 ScCellSearchObj* pSearch = dynamic_cast<ScCellSearchObj*>( xDesc.get() );
3733 if (pSearch)
3735 SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
3736 if (pSearchItem)
3738 ScDocument& rDoc = pDocShell->GetDocument();
3739 pSearchItem->SetCommand( SvxSearchCmd::FIND_ALL );
3740 // always only within this object
3741 pSearchItem->SetSelection( !lcl_WholeSheet(rDoc, aRanges) );
3743 ScMarkData aMark(*GetMarkData());
3745 OUString aDummyUndo;
3746 ScRangeList aMatchedRanges;
3747 SCCOL nCol = 0;
3748 SCROW nRow = 0;
3749 SCTAB nTab = 0;
3750 bool bMatchedRangesWereClamped = false;
3751 bool bFound = rDoc.SearchAndReplace(
3752 *pSearchItem, nCol, nRow, nTab, aMark, aMatchedRanges, aDummyUndo, nullptr, bMatchedRangesWereClamped);
3753 if (bFound)
3755 // on findAll always CellRanges no matter how much has been found
3756 xRet.set(new ScCellRangesObj( pDocShell, aMatchedRanges ));
3761 return xRet;
3764 uno::Reference<uno::XInterface> ScCellRangesBase::Find_Impl(
3765 const uno::Reference<util::XSearchDescriptor>& xDesc,
3766 const ScAddress* pLastPos )
3768 uno::Reference<uno::XInterface> xRet;
3769 if ( pDocShell && xDesc.is() )
3771 ScCellSearchObj* pSearch = dynamic_cast<ScCellSearchObj*>( xDesc.get() );
3772 if (pSearch)
3774 SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
3775 if (pSearchItem)
3777 ScDocument& rDoc = pDocShell->GetDocument();
3778 pSearchItem->SetCommand( SvxSearchCmd::FIND );
3779 // only always in this object
3780 pSearchItem->SetSelection( !lcl_WholeSheet(rDoc, aRanges) );
3782 ScMarkData aMark(*GetMarkData());
3784 SCCOL nCol;
3785 SCROW nRow;
3786 SCTAB nTab;
3787 if (pLastPos)
3788 pLastPos->GetVars( nCol, nRow, nTab );
3789 else
3791 nTab = lcl_FirstTab(aRanges); //! multiple sheets?
3792 rDoc.GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
3795 OUString aDummyUndo;
3796 ScRangeList aMatchedRanges;
3797 bool bMatchedRangesWereClamped;
3798 bool bFound = rDoc.SearchAndReplace(
3799 *pSearchItem, nCol, nRow, nTab, aMark, aMatchedRanges, aDummyUndo, nullptr, bMatchedRangesWereClamped);
3800 if (bFound)
3802 ScAddress aFoundPos( nCol, nRow, nTab );
3803 xRet.set(cppu::getXWeak(new ScCellObj( pDocShell, aFoundPos )));
3808 return xRet;
3811 uno::Reference<uno::XInterface> SAL_CALL ScCellRangesBase::findFirst(
3812 const uno::Reference<util::XSearchDescriptor>& xDesc )
3814 SolarMutexGuard aGuard;
3815 return Find_Impl( xDesc, nullptr );
3818 uno::Reference<uno::XInterface> SAL_CALL ScCellRangesBase::findNext(
3819 const uno::Reference<uno::XInterface>& xStartAt,
3820 const uno::Reference<util::XSearchDescriptor >& xDesc )
3822 SolarMutexGuard aGuard;
3823 if ( xStartAt.is() )
3825 ScCellRangesBase* pRangesImp = dynamic_cast<ScCellRangesBase*>( xStartAt.get() );
3826 if ( pRangesImp && pRangesImp->GetDocShell() == pDocShell )
3828 const ScRangeList& rStartRanges = pRangesImp->GetRangeList();
3829 if ( rStartRanges.size() == 1 )
3831 ScAddress aStartPos = rStartRanges[ 0 ].aStart;
3832 return Find_Impl( xDesc, &aStartPos );
3836 return nullptr;
3839 // XReplaceable
3841 uno::Reference<util::XReplaceDescriptor> SAL_CALL ScCellRangesBase::createReplaceDescriptor()
3843 return new ScCellSearchObj;
3846 sal_Int32 SAL_CALL ScCellRangesBase::replaceAll( const uno::Reference<util::XSearchDescriptor>& xDesc )
3848 SolarMutexGuard aGuard;
3849 sal_uInt64 nReplaced = 0;
3850 if ( pDocShell && xDesc.is() )
3852 ScCellSearchObj* pSearch = dynamic_cast<ScCellSearchObj*>( xDesc.get() );
3853 if (pSearch)
3855 SvxSearchItem* pSearchItem = pSearch->GetSearchItem();
3856 if (pSearchItem)
3858 ScDocument& rDoc = pDocShell->GetDocument();
3859 bool bUndo(rDoc.IsUndoEnabled());
3860 pSearchItem->SetCommand( SvxSearchCmd::REPLACE_ALL );
3861 // only always in this object
3862 pSearchItem->SetSelection( !lcl_WholeSheet(rDoc, aRanges) );
3864 ScMarkData aMark(*GetMarkData());
3866 SCTAB nTabCount = rDoc.GetTableCount();
3867 bool bProtected = !pDocShell->IsEditable();
3868 for (const auto& rTab : aMark)
3870 if (rTab >= nTabCount)
3871 break;
3872 if ( rDoc.IsTabProtected(rTab) )
3873 bProtected = true;
3875 if (bProtected)
3877 //! Exception, or what?
3879 else
3881 SCTAB nTab = aMark.GetFirstSelected(); // do not use if SearchAndReplace
3882 SCCOL nCol = 0;
3883 SCROW nRow = 0;
3885 OUString aUndoStr;
3886 ScDocumentUniquePtr pUndoDoc;
3887 if (bUndo)
3889 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
3890 pUndoDoc->InitUndo( rDoc, nTab, nTab );
3892 for (const auto& rTab : aMark)
3894 if (rTab >= nTabCount)
3895 break;
3896 if (rTab != nTab && bUndo)
3897 pUndoDoc->AddUndoTab( rTab, rTab );
3899 std::unique_ptr<ScMarkData> pUndoMark;
3900 if (bUndo)
3901 pUndoMark.reset(new ScMarkData(aMark));
3903 bool bFound = false;
3904 if (bUndo)
3906 ScRangeList aMatchedRanges;
3907 bool bMatchedRangesWereClamped;
3908 bFound = rDoc.SearchAndReplace(
3909 *pSearchItem, nCol, nRow, nTab, aMark, aMatchedRanges, aUndoStr, pUndoDoc.get(), bMatchedRangesWereClamped );
3911 if (bFound)
3913 nReplaced = pUndoDoc->GetCellCount();
3915 pDocShell->GetUndoManager()->AddUndoAction(
3916 std::make_unique<ScUndoReplace>( pDocShell, *pUndoMark, nCol, nRow, nTab,
3917 aUndoStr, std::move(pUndoDoc), pSearchItem ) );
3919 pDocShell->PostPaintGridAll();
3920 pDocShell->SetDocumentModified();
3926 return nReplaced;
3929 ScCellRangesObj::ScCellRangesObj(ScDocShell* pDocSh, const ScRangeList& rR)
3930 : ScCellRangesObj_BASE(pDocSh, rR)
3934 ScCellRangesObj::~ScCellRangesObj()
3938 void ScCellRangesObj::RefChanged()
3940 ScCellRangesBase::RefChanged();
3943 // XCellRanges
3945 rtl::Reference<ScCellRangeObj> ScCellRangesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const
3947 ScDocShell* pDocSh = GetDocShell();
3948 const ScRangeList& rRanges = GetRangeList();
3949 if ( pDocSh && nIndex >= 0 && nIndex < sal::static_int_cast<sal_Int32>(rRanges.size()) )
3951 ScRange const & rRange = rRanges[ nIndex ];
3952 if ( rRange.aStart == rRange.aEnd )
3953 return new ScCellObj( pDocSh, rRange.aStart );
3954 else
3955 return new ScCellRangeObj( pDocSh, rRange );
3958 return nullptr; // no DocShell or wrong index
3961 uno::Sequence<table::CellRangeAddress> SAL_CALL ScCellRangesObj::getRangeAddresses()
3963 SolarMutexGuard aGuard;
3964 ScDocShell* pDocSh = GetDocShell();
3965 const ScRangeList& rRanges = GetRangeList();
3966 size_t nCount = rRanges.size();
3967 if ( pDocSh && nCount )
3969 table::CellRangeAddress aRangeAddress;
3970 uno::Sequence<table::CellRangeAddress> aSeq(nCount);
3971 table::CellRangeAddress* pAry = aSeq.getArray();
3972 for ( size_t i=0; i < nCount; i++)
3974 ScUnoConversion::FillApiRange( aRangeAddress, rRanges[ i ] );
3975 pAry[i] = aRangeAddress;
3977 return aSeq;
3980 return {}; // can be empty
3983 uno::Reference<container::XEnumerationAccess> SAL_CALL ScCellRangesObj::getCells()
3985 SolarMutexGuard aGuard;
3987 // getCells with empty range list is possible (no exception),
3988 // the resulting enumeration just has no elements
3989 // (same behaviour as a valid range with no cells)
3990 // This is handled in ScCellsEnumeration ctor.
3992 const ScRangeList& rRanges = GetRangeList();
3993 ScDocShell* pDocSh = GetDocShell();
3994 if (pDocSh)
3995 return new ScCellsObj( pDocSh, rRanges );
3996 return nullptr;
3999 OUString SAL_CALL ScCellRangesObj::getRangeAddressesAsString()
4001 SolarMutexGuard aGuard;
4002 OUString aString;
4003 ScDocShell* pDocSh = GetDocShell();
4004 const ScRangeList& rRanges = GetRangeList();
4005 if (pDocSh)
4006 rRanges.Format( aString, ScRefFlags::VALID | ScRefFlags::TAB_3D, pDocSh->GetDocument() );
4007 return aString;
4010 // XSheetCellRangeContainer
4012 void SAL_CALL ScCellRangesObj::addRangeAddress( const table::CellRangeAddress& rRange,
4013 sal_Bool bMergeRanges )
4015 SolarMutexGuard aGuard;
4016 ScRange aRange(static_cast<SCCOL>(rRange.StartColumn),
4017 static_cast<SCROW>(rRange.StartRow),
4018 static_cast<SCTAB>(rRange.Sheet),
4019 static_cast<SCCOL>(rRange.EndColumn),
4020 static_cast<SCROW>(rRange.EndRow),
4021 static_cast<SCTAB>(rRange.Sheet));
4022 AddRange(aRange, bMergeRanges);
4025 static void lcl_RemoveNamedEntry( std::vector<ScCellRangesObj::ScNamedEntry>& rNamedEntries, const ScRange& rRange )
4027 sal_uInt16 nCount = rNamedEntries.size();
4028 for ( sal_uInt16 n=nCount; n--; )
4029 if ( rNamedEntries[n].GetRange() == rRange )
4030 rNamedEntries.erase( rNamedEntries.begin() + n );
4033 void SAL_CALL ScCellRangesObj::removeRangeAddress( const table::CellRangeAddress& rRange )
4035 SolarMutexGuard aGuard;
4036 const ScRangeList& rRanges = GetRangeList();
4038 ScRangeList aSheetRanges;
4039 ScRangeList aNotSheetRanges;
4040 for (size_t i = 0; i < rRanges.size(); ++i)
4042 if (rRanges[ i].aStart.Tab() == rRange.Sheet)
4044 aSheetRanges.push_back( rRanges[ i ] );
4046 else
4048 aNotSheetRanges.push_back( rRanges[ i ] );
4051 ScMarkData aMarkData(GetDocument()->GetSheetLimits());
4052 aMarkData.MarkFromRangeList( aSheetRanges, false );
4053 ScRange aRange(static_cast<SCCOL>(rRange.StartColumn),
4054 static_cast<SCROW>(rRange.StartRow),
4055 static_cast<SCTAB>(rRange.Sheet),
4056 static_cast<SCCOL>(rRange.EndColumn),
4057 static_cast<SCROW>(rRange.EndRow),
4058 static_cast<SCTAB>(rRange.Sheet));
4059 if (aMarkData.GetTableSelect( aRange.aStart.Tab() ))
4061 aMarkData.MarkToMulti();
4062 if (!aMarkData.IsAllMarked( aRange ) )
4063 throw container::NoSuchElementException();
4065 aMarkData.SetMultiMarkArea( aRange, false );
4066 lcl_RemoveNamedEntry(m_aNamedEntries, aRange);
4069 SetNewRanges(aNotSheetRanges);
4070 ScRangeList aNew;
4071 aMarkData.FillRangeListWithMarks( &aNew, false );
4072 for ( size_t j = 0; j < aNew.size(); ++j)
4074 AddRange(aNew[ j ], false);
4078 void SAL_CALL ScCellRangesObj::addRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRanges,
4079 sal_Bool bMergeRanges )
4081 SolarMutexGuard aGuard;
4082 for (const table::CellRangeAddress& rRange : rRanges)
4084 ScRange aRange(static_cast<SCCOL>(rRange.StartColumn),
4085 static_cast<SCROW>(rRange.StartRow),
4086 static_cast<SCTAB>(rRange.Sheet),
4087 static_cast<SCCOL>(rRange.EndColumn),
4088 static_cast<SCROW>(rRange.EndRow),
4089 static_cast<SCTAB>(rRange.Sheet));
4090 AddRange(aRange, bMergeRanges);
4094 void SAL_CALL ScCellRangesObj::removeRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRangeSeq )
4096 // use sometimes a better/faster implementation
4097 for (const table::CellRangeAddress& rRange : rRangeSeq)
4099 removeRangeAddress(rRange);
4103 // XNameContainer
4105 static void lcl_RemoveNamedEntry( std::vector<ScCellRangesObj::ScNamedEntry>& rNamedEntries, std::u16string_view rName )
4107 sal_uInt16 nCount = rNamedEntries.size();
4108 for ( sal_uInt16 n=nCount; n--; )
4109 if ( rNamedEntries[n].GetName() == rName )
4110 rNamedEntries.erase( rNamedEntries.begin() + n );
4113 void SAL_CALL ScCellRangesObj::insertByName( const OUString& aName, const uno::Any& aElement )
4115 SolarMutexGuard aGuard;
4116 ScDocShell* pDocSh = GetDocShell();
4117 bool bDone = false;
4119 //! Type of aElement can be some specific interface instead of XInterface
4121 uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY);
4122 if ( pDocSh && xInterface.is() )
4124 ScCellRangesBase* pRangesImp = dynamic_cast<ScCellRangesBase*>( xInterface.get() );
4125 if ( pRangesImp && pRangesImp->GetDocShell() == pDocSh )
4127 // if explicit name is given and already existing, throw exception
4129 if ( !aName.isEmpty() )
4131 size_t nNamedCount = m_aNamedEntries.size();
4132 for (size_t n = 0; n < nNamedCount; n++)
4134 if (m_aNamedEntries[n].GetName() == aName)
4135 throw container::ElementExistException();
4139 ScRangeList aNew(GetRangeList());
4140 const ScRangeList& rAddRanges = pRangesImp->GetRangeList();
4141 size_t nAddCount = rAddRanges.size();
4142 for ( size_t i = 0; i < nAddCount; i++ )
4143 aNew.Join( rAddRanges[ i ] );
4144 SetNewRanges(aNew);
4145 bDone = true;
4147 if ( !aName.isEmpty() && nAddCount == 1 )
4149 // if a name is given, also insert into list of named entries
4150 // (only possible for a single range)
4151 // name is not in m_aNamedEntries (tested above)
4152 m_aNamedEntries.emplace_back( ScNamedEntry{aName, rAddRanges[ 0 ]} );
4157 if (!bDone)
4159 // invalid element - double names are handled above
4160 throw lang::IllegalArgumentException();
4164 static bool lcl_FindRangeByName( const ScRangeList& rRanges, ScDocShell* pDocSh,
4165 std::u16string_view rName, size_t& rIndex )
4167 if (pDocSh)
4169 OUString aRangeStr;
4170 ScDocument& rDoc = pDocSh->GetDocument();
4171 for ( size_t i = 0, nCount = rRanges.size(); i < nCount; i++ )
4173 aRangeStr = rRanges[ i ].Format(rDoc, ScRefFlags::VALID | ScRefFlags::TAB_3D);
4174 if ( aRangeStr == rName )
4176 rIndex = i;
4177 return true;
4181 return false;
4184 static bool lcl_FindRangeOrEntry( const std::vector<ScCellRangesObj::ScNamedEntry>& rNamedEntries,
4185 const ScRangeList& rRanges, ScDocShell* pDocSh,
4186 const OUString& rName, ScRange& rFound )
4188 // exact range in list?
4190 size_t nIndex = 0;
4191 if ( lcl_FindRangeByName( rRanges, pDocSh, rName, nIndex ) )
4193 rFound = rRanges[ nIndex ];
4194 return true;
4197 // range contained in selection? (sheet must be specified)
4199 ScRange aCellRange;
4200 ScRefFlags nParse = aCellRange.ParseAny( rName, pDocSh->GetDocument() );
4201 if ( (nParse & ( ScRefFlags::VALID | ScRefFlags::TAB_3D ))
4202 == ( ScRefFlags::VALID | ScRefFlags::TAB_3D ))
4204 ScMarkData aMarkData(pDocSh->GetDocument().GetSheetLimits());
4205 aMarkData.MarkFromRangeList( rRanges, false );
4206 if ( aMarkData.IsAllMarked( aCellRange ) )
4208 rFound = aCellRange;
4209 return true;
4213 // named entry in this object?
4215 for (const auto & rNamedEntry : rNamedEntries)
4216 if ( rNamedEntry.GetName() == rName )
4218 // test if named entry is contained in rRanges
4220 const ScRange& rComp = rNamedEntry.GetRange();
4221 ScMarkData aMarkData(pDocSh->GetDocument().GetSheetLimits());
4222 aMarkData.MarkFromRangeList( rRanges, false );
4223 if ( aMarkData.IsAllMarked( rComp ) )
4225 rFound = rComp;
4226 return true;
4230 return false; // not found
4233 void SAL_CALL ScCellRangesObj::removeByName( const OUString& aName )
4235 SolarMutexGuard aGuard;
4236 bool bDone = false;
4237 ScDocShell* pDocSh = GetDocShell();
4238 const ScRangeList& rRanges = GetRangeList();
4239 size_t nIndex = 0;
4240 if ( lcl_FindRangeByName( rRanges, pDocSh, aName, nIndex ) )
4242 // skip a single range
4243 ScRangeList aNew;
4244 for ( size_t i = 0, nCount = rRanges.size(); i < nCount; i++ )
4245 if (i != nIndex)
4246 aNew.push_back( rRanges[ i ] );
4247 SetNewRanges(aNew);
4248 bDone = true;
4250 else if (pDocSh)
4252 // deselect any ranges (parsed or named entry)
4253 ScRangeList aDiff;
4254 bool bValid = ( aDiff.Parse( aName, pDocSh->GetDocument() ) & ScRefFlags::VALID )
4255 == ScRefFlags::VALID;
4256 if (!bValid)
4258 sal_uInt16 nCount = m_aNamedEntries.size();
4259 for (sal_uInt16 n=0; n<nCount && !bValid; n++)
4260 if (m_aNamedEntries[n].GetName() == aName)
4262 aDiff.RemoveAll();
4263 aDiff.push_back(m_aNamedEntries[n].GetRange());
4264 bValid = true;
4267 if ( bValid )
4269 ScMarkData aMarkData(GetDocument()->GetSheetLimits());
4270 aMarkData.MarkFromRangeList( rRanges, false );
4272 for ( size_t i = 0, nDiffCount = aDiff.size(); i < nDiffCount; i++ )
4274 ScRange const & rDiffRange = aDiff[ i ];
4275 if (aMarkData.GetTableSelect( rDiffRange.aStart.Tab() ))
4276 aMarkData.SetMultiMarkArea( rDiffRange, false );
4279 ScRangeList aNew;
4280 aMarkData.FillRangeListWithMarks( &aNew, false );
4281 SetNewRanges(aNew);
4283 bDone = true; //! error if range was not selected before?
4287 if (!m_aNamedEntries.empty())
4288 lcl_RemoveNamedEntry(m_aNamedEntries, aName);
4290 if (!bDone)
4291 throw container::NoSuchElementException(); // not found
4294 // XNameReplace
4296 void SAL_CALL ScCellRangesObj::replaceByName( const OUString& aName, const uno::Any& aElement )
4298 SolarMutexGuard aGuard;
4299 //! combine?
4300 removeByName( aName );
4301 insertByName( aName, aElement );
4304 // XNameAccess
4306 uno::Any SAL_CALL ScCellRangesObj::getByName( const OUString& aName )
4308 SolarMutexGuard aGuard;
4309 uno::Any aRet;
4311 ScDocShell* pDocSh = GetDocShell();
4312 const ScRangeList& rRanges = GetRangeList();
4313 ScRange aRange;
4314 if (!lcl_FindRangeOrEntry(m_aNamedEntries, rRanges,
4315 pDocSh, aName, aRange))
4316 throw container::NoSuchElementException();
4318 uno::Reference<table::XCellRange> xRange;
4319 if ( aRange.aStart == aRange.aEnd )
4320 xRange.set(new ScCellObj( pDocSh, aRange.aStart ));
4321 else
4322 xRange.set(new ScCellRangeObj( pDocSh, aRange ));
4323 aRet <<= xRange;
4325 return aRet;
4328 static bool lcl_FindEntryName( const std::vector<ScCellRangesObj::ScNamedEntry>& rNamedEntries,
4329 const ScRange& rRange, OUString& rName )
4331 sal_uInt16 nCount = rNamedEntries.size();
4332 for (sal_uInt16 i=0; i<nCount; i++)
4333 if (rNamedEntries[i].GetRange() == rRange)
4335 rName = rNamedEntries[i].GetName();
4336 return true;
4338 return false;
4341 uno::Sequence<OUString> SAL_CALL ScCellRangesObj::getElementNames()
4343 SolarMutexGuard aGuard;
4345 ScDocShell* pDocSh = GetDocShell();
4346 const ScRangeList& rRanges = GetRangeList();
4347 if (pDocSh)
4349 OUString aRangeStr;
4350 ScDocument& rDoc = pDocSh->GetDocument();
4351 size_t nCount = rRanges.size();
4353 uno::Sequence<OUString> aSeq(nCount);
4354 OUString* pAry = aSeq.getArray();
4355 for (size_t i=0; i < nCount; i++)
4357 // use given name if for exactly this range, otherwise just format
4358 ScRange const & rRange = rRanges[ i ];
4359 if (m_aNamedEntries.empty() ||
4360 !lcl_FindEntryName(m_aNamedEntries, rRange, aRangeStr))
4362 aRangeStr = rRange.Format(rDoc, ScRefFlags::VALID | ScRefFlags::TAB_3D);
4364 pAry[i] = aRangeStr;
4366 return aSeq;
4368 return {};
4371 sal_Bool SAL_CALL ScCellRangesObj::hasByName( const OUString& aName )
4373 SolarMutexGuard aGuard;
4374 ScDocShell* pDocSh = GetDocShell();
4375 const ScRangeList& rRanges = GetRangeList();
4376 ScRange aRange;
4377 return lcl_FindRangeOrEntry(m_aNamedEntries, rRanges, pDocSh,
4378 aName, aRange);
4381 // XEnumerationAccess
4383 uno::Reference<container::XEnumeration> SAL_CALL ScCellRangesObj::createEnumeration()
4385 SolarMutexGuard aGuard;
4386 return new ScIndexEnumeration(this, u"com.sun.star.sheet.SheetCellRangesEnumeration"_ustr);
4389 // XIndexAccess
4391 sal_Int32 SAL_CALL ScCellRangesObj::getCount()
4393 SolarMutexGuard aGuard;
4394 const ScRangeList& rRanges = GetRangeList();
4395 return rRanges.size();
4398 uno::Any SAL_CALL ScCellRangesObj::getByIndex( sal_Int32 nIndex )
4400 SolarMutexGuard aGuard;
4401 uno::Reference<table::XCellRange> xRange(GetObjectByIndex_Impl(nIndex));
4402 if (!xRange.is())
4403 throw lang::IndexOutOfBoundsException();
4405 return uno::Any(xRange);
4409 uno::Type SAL_CALL ScCellRangesObj::getElementType()
4411 return cppu::UnoType<table::XCellRange>::get();
4414 sal_Bool SAL_CALL ScCellRangesObj::hasElements()
4416 SolarMutexGuard aGuard;
4417 const ScRangeList& rRanges = GetRangeList();
4418 return !rRanges.empty();
4421 // XServiceInfo
4422 OUString SAL_CALL ScCellRangesObj::getImplementationName()
4424 return u"ScCellRangesObj"_ustr;
4427 sal_Bool SAL_CALL ScCellRangesObj::supportsService( const OUString& rServiceName )
4429 return cppu::supportsService(this, rServiceName);
4432 uno::Sequence<OUString> SAL_CALL ScCellRangesObj::getSupportedServiceNames()
4434 return {SCSHEETCELLRANGES_SERVICE,
4435 SCCELLPROPERTIES_SERVICE,
4436 SCCHARPROPERTIES_SERVICE,
4437 SCPARAPROPERTIES_SERVICE};
4440 uno::Reference<table::XCellRange> ScCellRangeObj::CreateRangeFromDoc( const ScDocument& rDoc, const ScRange& rR )
4442 if ( ScDocShell* pDocShell = rDoc.GetDocumentShell() )
4443 return new ScCellRangeObj( pDocShell, rR );
4444 return nullptr;
4447 ScCellRangeObj::ScCellRangeObj(ScDocShell* pDocSh, const ScRange& rR) :
4448 ScCellRangeObj_BASE( pDocSh, rR ),
4449 pRangePropSet( lcl_GetRangePropertySet() ),
4450 aRange( rR )
4452 aRange.PutInOrder(); // beginning / end correct
4455 ScCellRangeObj::~ScCellRangeObj()
4459 void ScCellRangeObj::RefChanged()
4461 ScCellRangesBase::RefChanged();
4463 const ScRangeList& rRanges = GetRangeList();
4464 OSL_ENSURE(rRanges.size() == 1, "What ranges ?!?!");
4465 if ( !rRanges.empty() )
4467 const ScRange & rFirst = rRanges[0];
4468 aRange = rFirst;
4469 aRange.PutInOrder();
4473 // XCellRange
4475 // ColumnCount / RowCount vanished
4476 //! are used in Writer for tables ???
4478 uno::Reference<table::XCell> ScCellRangeObj::GetCellByPosition_Impl(
4479 sal_Int32 nColumn, sal_Int32 nRow )
4481 ScDocShell* pDocSh = GetDocShell();
4482 if (!pDocSh)
4483 throw uno::RuntimeException();
4485 if ( nColumn >= 0 && nRow >= 0 )
4487 sal_Int32 nPosX = aRange.aStart.Col() + nColumn;
4488 sal_Int32 nPosY = aRange.aStart.Row() + nRow;
4490 if ( nPosX <= aRange.aEnd.Col() && nPosY <= aRange.aEnd.Row() )
4492 ScAddress aNew( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), aRange.aStart.Tab() );
4493 return new ScCellObj( pDocSh, aNew );
4497 throw lang::IndexOutOfBoundsException();
4500 uno::Reference<table::XCell> SAL_CALL ScCellRangeObj::getCellByPosition(
4501 sal_Int32 nColumn, sal_Int32 nRow )
4503 SolarMutexGuard aGuard;
4505 return GetCellByPosition_Impl(nColumn, nRow);
4508 uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByPosition(
4509 sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
4511 SolarMutexGuard aGuard;
4513 ScDocShell* pDocSh = GetDocShell();
4514 if (!pDocSh)
4515 throw uno::RuntimeException();
4517 if ( nLeft >= 0 && nTop >= 0 && nRight >= 0 && nBottom >= 0 )
4519 sal_Int32 nStartX = aRange.aStart.Col() + nLeft;
4520 sal_Int32 nStartY = aRange.aStart.Row() + nTop;
4521 sal_Int32 nEndX = aRange.aStart.Col() + nRight;
4522 sal_Int32 nEndY = aRange.aStart.Row() + nBottom;
4524 if ( nStartX <= nEndX && nEndX <= aRange.aEnd.Col() &&
4525 nStartY <= nEndY && nEndY <= aRange.aEnd.Row() )
4527 ScRange aNew( static_cast<SCCOL>(nStartX), static_cast<SCROW>(nStartY), aRange.aStart.Tab(),
4528 static_cast<SCCOL>(nEndX), static_cast<SCROW>(nEndY), aRange.aEnd.Tab() );
4529 return new ScCellRangeObj( pDocSh, aNew );
4533 throw lang::IndexOutOfBoundsException();
4536 uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByName(
4537 const OUString& aName )
4539 return getCellRangeByName( aName, ScAddress::detailsOOOa1 );
4542 uno::Reference<table::XCellRange> ScCellRangeObj::getCellRangeByName(
4543 const OUString& aName, const ScAddress::Details& rDetails )
4545 // name refers to the whole document (with the range's table as default),
4546 // valid only if the range is within this range
4548 SolarMutexGuard aGuard;
4549 ScDocShell* pDocSh = GetDocShell();
4550 if ( pDocSh )
4552 ScDocument& rDoc = pDocSh->GetDocument();
4553 SCTAB nTab = aRange.aStart.Tab();
4555 ScRange aCellRange;
4556 bool bFound = false;
4557 ScRefFlags nParse = aCellRange.ParseAny( aName, rDoc, rDetails );
4558 if ( nParse & ScRefFlags::VALID )
4560 if ( !(nParse & ScRefFlags::TAB_3D) ) // no sheet specified -> this sheet
4562 aCellRange.aStart.SetTab(nTab);
4563 aCellRange.aEnd.SetTab(nTab);
4565 bFound = true;
4567 else
4569 if ( ScRangeUtil::MakeRangeFromName( aName, rDoc, nTab, aCellRange, RUTL_NAMES, rDetails) ||
4570 ScRangeUtil::MakeRangeFromName( aName, rDoc, nTab, aCellRange, RUTL_DBASE, rDetails))
4571 bFound = true;
4574 if (bFound) // valid only if within this object's range
4576 if (!aRange.Contains(aCellRange))
4577 bFound = false;
4580 if (bFound)
4582 if ( aCellRange.aStart == aCellRange.aEnd )
4583 return new ScCellObj( pDocSh, aCellRange.aStart );
4584 else
4585 return new ScCellRangeObj( pDocSh, aCellRange );
4589 throw uno::RuntimeException();
4592 // XColumnRowRange
4594 uno::Reference<table::XTableColumns> SAL_CALL ScCellRangeObj::getColumns()
4596 SolarMutexGuard aGuard;
4597 ScDocShell* pDocSh = GetDocShell();
4598 if (pDocSh)
4599 return new ScTableColumnsObj( pDocSh, aRange.aStart.Tab(),
4600 aRange.aStart.Col(), aRange.aEnd.Col() );
4602 OSL_FAIL("Document invalid");
4603 return nullptr;
4606 uno::Reference<table::XTableRows> SAL_CALL ScCellRangeObj::getRows()
4608 SolarMutexGuard aGuard;
4609 ScDocShell* pDocSh = GetDocShell();
4610 if (pDocSh)
4611 return new ScTableRowsObj( pDocSh, aRange.aStart.Tab(),
4612 aRange.aStart.Row(), aRange.aEnd.Row() );
4614 OSL_FAIL("Document invalid");
4615 return nullptr;
4618 // XAddressableCellRange
4620 table::CellRangeAddress SAL_CALL ScCellRangeObj::getRangeAddress()
4622 SolarMutexGuard aGuard;
4623 table::CellRangeAddress aRet;
4624 ScUnoConversion::FillApiRange( aRet, aRange );
4625 return aRet;
4628 // XSheetCellRange
4630 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScCellRangeObj::getSpreadsheet()
4632 SolarMutexGuard aGuard;
4633 ScDocShell* pDocSh = GetDocShell();
4634 if (pDocSh)
4635 return new ScTableSheetObj( pDocSh, aRange.aStart.Tab() );
4637 OSL_FAIL("Document invalid");
4638 return nullptr;
4641 // XArrayFormulaRange
4643 OUString SAL_CALL ScCellRangeObj::getArrayFormula()
4645 SolarMutexGuard aGuard;
4647 // Matrix formula if clearly part of a matrix (so when start and end of
4648 // the block belong to the same matrix) else empty string.
4650 ScDocShell* pDocSh = GetDocShell();
4651 if (!pDocSh)
4652 return OUString();
4654 ScDocument& rDoc = pDocSh->GetDocument();
4655 ScRefCellValue aCell1(rDoc, aRange.aStart);
4656 ScRefCellValue aCell2(rDoc, aRange.aEnd);
4657 if (aCell1.getType() == CELLTYPE_FORMULA && aCell2.getType() == CELLTYPE_FORMULA)
4659 const ScFormulaCell* pFCell1 = aCell1.getFormula();
4660 const ScFormulaCell* pFCell2 = aCell2.getFormula();
4661 ScAddress aStart1;
4662 ScAddress aStart2;
4663 if (pFCell1->GetMatrixOrigin(rDoc, aStart1) && pFCell2->GetMatrixOrigin(rDoc, aStart2))
4665 if (aStart1 == aStart2) // both the same matrix
4666 return pFCell1->GetFormula(); // it doesn't matter from which cell
4669 return OUString();
4672 void ScCellRangeObj::SetArrayFormula_Impl(const OUString& rFormula,
4673 const formula::FormulaGrammar::Grammar eGrammar)
4675 ScDocShell* pDocSh = GetDocShell();
4676 if (!pDocSh)
4677 return;
4679 if ( !rFormula.isEmpty() )
4681 if ( dynamic_cast<ScTableSheetObj*>( this ) )
4683 // don't set array formula for sheet object
4684 throw uno::RuntimeException();
4687 pDocSh->GetDocFunc().EnterMatrix( aRange, nullptr, nullptr, rFormula, true, true, OUString()/*rFormulaNmsp*/, eGrammar );
4689 else
4691 // empty string -> erase array formula
4692 ScMarkData aMark(GetDocument()->GetSheetLimits());
4693 aMark.SetMarkArea( aRange );
4694 aMark.SelectTable( aRange.aStart.Tab(), true );
4695 pDocSh->GetDocFunc().DeleteContents( aMark, InsertDeleteFlags::CONTENTS, true, true );
4699 void SAL_CALL ScCellRangeObj::setArrayFormula( const OUString& aFormula )
4701 SolarMutexGuard aGuard;
4702 // GRAM_API for API compatibility.
4703 SetArrayFormula_Impl( aFormula, formula::FormulaGrammar::GRAM_API);
4706 // XArrayFormulaTokens
4707 uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellRangeObj::getArrayTokens()
4709 SolarMutexGuard aGuard;
4711 // same cell logic as in getArrayFormula
4713 uno::Sequence<sheet::FormulaToken> aSequence;
4714 ScDocShell* pDocSh = GetDocShell();
4715 if (!pDocSh)
4716 return aSequence;
4718 ScDocument& rDoc = pDocSh->GetDocument();
4719 ScRefCellValue aCell1(rDoc, aRange.aStart);
4720 ScRefCellValue aCell2(rDoc, aRange.aEnd);
4721 if (aCell1.getType() == CELLTYPE_FORMULA && aCell2.getType() == CELLTYPE_FORMULA)
4723 const ScFormulaCell* pFCell1 = aCell1.getFormula();
4724 const ScFormulaCell* pFCell2 = aCell2.getFormula();
4725 ScAddress aStart1;
4726 ScAddress aStart2;
4727 if (pFCell1->GetMatrixOrigin(rDoc, aStart1) && pFCell2->GetMatrixOrigin(rDoc, aStart2))
4729 if (aStart1 == aStart2)
4731 const ScTokenArray* pTokenArray = pFCell1->GetCode();
4732 if (pTokenArray)
4733 ScTokenConversion::ConvertToTokenSequence(rDoc, aSequence, *pTokenArray);
4738 return aSequence;
4741 void SAL_CALL ScCellRangeObj::setArrayTokens( const uno::Sequence<sheet::FormulaToken>& rTokens )
4743 SolarMutexGuard aGuard;
4744 ScDocShell* pDocSh = GetDocShell();
4745 if ( !pDocSh )
4746 return;
4748 if ( rTokens.hasElements() )
4750 if ( dynamic_cast<ScTableSheetObj*>( this ) )
4752 throw uno::RuntimeException();
4755 ScDocument& rDoc = pDocSh->GetDocument();
4756 ScTokenArray aTokenArray(rDoc);
4757 (void)ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
4759 // Actually GRAM_API is a don't-care here because of the token
4760 // array being set, it fits with other API compatibility grammars
4761 // though.
4762 pDocSh->GetDocFunc().EnterMatrix( aRange, nullptr, &aTokenArray, OUString(), true, true, OUString(), formula::FormulaGrammar::GRAM_API );
4764 else
4766 // empty sequence -> erase array formula
4767 ScMarkData aMark(pDocSh->GetDocument().GetSheetLimits());
4768 aMark.SetMarkArea( aRange );
4769 aMark.SelectTable( aRange.aStart.Tab(), true );
4770 pDocSh->GetDocFunc().DeleteContents( aMark, InsertDeleteFlags::CONTENTS, true, true );
4774 // XCellRangeData
4776 uno::Sequence< uno::Sequence<uno::Any> > SAL_CALL ScCellRangeObj::getDataArray()
4778 SolarMutexGuard aGuard;
4780 if ( dynamic_cast<ScTableSheetObj*>( this ) )
4782 // don't create a data array for the sheet
4783 throw uno::RuntimeException();
4786 ScDocShell* pDocSh = GetDocShell();
4787 if (pDocSh)
4789 uno::Any aAny;
4790 // bAllowNV = TRUE: errors as void
4791 if ( ScRangeToSequence::FillMixedArray( aAny, pDocSh->GetDocument(), aRange, true ) )
4793 uno::Sequence< uno::Sequence<uno::Any> > aSeq;
4794 if ( aAny >>= aSeq )
4795 return aSeq; // success
4799 throw uno::RuntimeException(); // no other exceptions specified
4802 void SAL_CALL ScCellRangeObj::setDataArray(
4803 const uno::Sequence< uno::Sequence<uno::Any> >& aArray )
4805 SolarMutexGuard aGuard;
4807 bool bDone = false;
4808 ScDocShell* pDocSh = GetDocShell();
4809 if (pDocSh)
4811 //! move lcl_PutDataArray to docfunc?
4812 bDone = lcl_PutDataArray( *pDocSh, aRange, aArray );
4815 if (!bDone)
4816 throw uno::RuntimeException(); // no other exceptions specified
4819 // XCellRangeFormula
4821 uno::Sequence< uno::Sequence<OUString> > SAL_CALL ScCellRangeObj::getFormulaArray()
4823 SolarMutexGuard aGuard;
4825 if ( dynamic_cast<ScTableSheetObj*>( this ) )
4827 // don't create a data array for the sheet
4828 throw uno::RuntimeException();
4831 ScDocShell* pDocSh = GetDocShell();
4832 if (pDocSh)
4834 SCCOL nStartCol = aRange.aStart.Col();
4835 SCROW nStartRow = aRange.aStart.Row();
4836 SCCOL nEndCol = aRange.aEnd.Col();
4837 SCROW nEndRow = aRange.aEnd.Row();
4838 SCCOL nColCount = nEndCol + 1 - nStartCol;
4839 SCROW nRowCount = nEndRow + 1 - nStartRow;
4840 SCTAB nTab = aRange.aStart.Tab();
4842 uno::Sequence< uno::Sequence<OUString> > aRowSeq( nRowCount );
4843 uno::Sequence<OUString>* pRowAry = aRowSeq.getArray();
4844 for (SCROW nRowIndex = 0; nRowIndex < nRowCount; nRowIndex++)
4846 uno::Sequence<OUString> aColSeq( nColCount );
4847 OUString* pColAry = aColSeq.getArray();
4848 for (SCCOL nColIndex = 0; nColIndex < nColCount; nColIndex++)
4849 pColAry[nColIndex] = lcl_GetInputString( pDocSh->GetDocument(),
4850 ScAddress( nStartCol+nColIndex, nStartRow+nRowIndex, nTab ), true );
4852 pRowAry[nRowIndex] = std::move(aColSeq);
4855 return aRowSeq;
4858 throw uno::RuntimeException(); // no other exceptions specified
4861 void SAL_CALL ScCellRangeObj::setFormulaArray(
4862 const uno::Sequence< uno::Sequence<OUString> >& aArray )
4864 SolarMutexGuard aGuard;
4866 bool bDone = false;
4867 ScDocShell* pDocSh = GetDocShell();
4868 if (pDocSh)
4870 ScExternalRefManager::ApiGuard aExtRefGuard(pDocSh->GetDocument());
4872 // GRAM_API for API compatibility.
4873 bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray, formula::FormulaGrammar::GRAM_API );
4876 if (!bDone)
4877 throw uno::RuntimeException(); // no other exceptions specified
4880 // XMultipleOperation
4882 void SAL_CALL ScCellRangeObj::setTableOperation( const table::CellRangeAddress& aFormulaRange,
4883 sheet::TableOperationMode nMode,
4884 const table::CellAddress& aColumnCell,
4885 const table::CellAddress& aRowCell )
4887 SolarMutexGuard aGuard;
4888 ScDocShell* pDocSh = GetDocShell();
4889 if (!pDocSh)
4890 return;
4892 bool bError = false;
4893 ScTabOpParam aParam;
4894 aParam.aRefFormulaCell = ScRefAddress( static_cast<SCCOL>(aFormulaRange.StartColumn),
4895 static_cast<SCROW>(aFormulaRange.StartRow), aFormulaRange.Sheet );
4896 aParam.aRefFormulaEnd = ScRefAddress( static_cast<SCCOL>(aFormulaRange.EndColumn),
4897 static_cast<SCROW>(aFormulaRange.EndRow), aFormulaRange.Sheet );
4898 aParam.aRefRowCell = ScRefAddress( static_cast<SCCOL>(aRowCell.Column),
4899 static_cast<SCROW>(aRowCell.Row), aRowCell.Sheet );
4900 aParam.aRefColCell = ScRefAddress( static_cast<SCCOL>(aColumnCell.Column),
4901 static_cast<SCROW>(aColumnCell.Row), aColumnCell.Sheet );
4903 switch (nMode)
4905 case sheet::TableOperationMode_COLUMN:
4906 aParam.meMode = ScTabOpParam::Column;
4907 break;
4908 case sheet::TableOperationMode_ROW:
4909 aParam.meMode = ScTabOpParam::Row;
4910 break;
4911 case sheet::TableOperationMode_BOTH:
4912 aParam.meMode = ScTabOpParam::Both;
4913 break;
4914 default:
4915 bError = true;
4918 if (!bError)
4919 pDocSh->GetDocFunc().TabOp( aRange, nullptr, aParam, true, true );
4922 // XMergeable
4924 void SAL_CALL ScCellRangeObj::merge( sal_Bool bMerge )
4926 SolarMutexGuard aGuard;
4927 ScDocShell* pDocSh = GetDocShell();
4928 if ( !pDocSh )
4929 return;
4931 ScCellMergeOption aMergeOption(
4932 aRange.aStart.Col(), aRange.aStart.Row(),
4933 aRange.aEnd.Col(), aRange.aEnd.Row(), false);
4934 aMergeOption.maTabs.insert(aRange.aStart.Tab());
4935 if ( bMerge )
4936 pDocSh->GetDocFunc().MergeCells( aMergeOption, false, true, true );
4937 else
4938 pDocSh->GetDocFunc().UnmergeCells( aMergeOption, true, nullptr );
4940 //! Catch error?
4943 sal_Bool SAL_CALL ScCellRangeObj::getIsMerged()
4945 SolarMutexGuard aGuard;
4946 ScDocShell* pDocSh = GetDocShell();
4947 return pDocSh && pDocSh->GetDocument().HasAttrib( aRange, HasAttrFlags::Merged );
4950 // XCellSeries
4952 void SAL_CALL ScCellRangeObj::fillSeries( sheet::FillDirection nFillDirection,
4953 sheet::FillMode nFillMode, sheet::FillDateMode nFillDateMode,
4954 double fStep, double fEndValue )
4956 SolarMutexGuard aGuard;
4957 ScDocShell* pDocSh = GetDocShell();
4958 if ( !pDocSh )
4959 return;
4961 bool bError = false;
4963 FillDir eDir = FILL_TO_BOTTOM;
4964 switch (nFillDirection)
4966 case sheet::FillDirection_TO_BOTTOM:
4967 eDir = FILL_TO_BOTTOM;
4968 break;
4969 case sheet::FillDirection_TO_RIGHT:
4970 eDir = FILL_TO_RIGHT;
4971 break;
4972 case sheet::FillDirection_TO_TOP:
4973 eDir = FILL_TO_TOP;
4974 break;
4975 case sheet::FillDirection_TO_LEFT:
4976 eDir = FILL_TO_LEFT;
4977 break;
4978 default:
4979 bError = true;
4982 FillCmd eCmd = FILL_SIMPLE;
4983 switch ( nFillMode )
4985 case sheet::FillMode_SIMPLE:
4986 eCmd = FILL_SIMPLE;
4987 break;
4988 case sheet::FillMode_LINEAR:
4989 eCmd = FILL_LINEAR;
4990 break;
4991 case sheet::FillMode_GROWTH:
4992 eCmd = FILL_GROWTH;
4993 break;
4994 case sheet::FillMode_DATE:
4995 eCmd = FILL_DATE;
4996 break;
4997 case sheet::FillMode_AUTO:
4998 eCmd = FILL_AUTO;
4999 break;
5000 default:
5001 bError = true;
5004 FillDateCmd eDateCmd = FILL_DAY;
5005 switch ( nFillDateMode )
5007 case sheet::FillDateMode_FILL_DATE_DAY:
5008 eDateCmd = FILL_DAY;
5009 break;
5010 case sheet::FillDateMode_FILL_DATE_WEEKDAY:
5011 eDateCmd = FILL_WEEKDAY;
5012 break;
5013 case sheet::FillDateMode_FILL_DATE_MONTH:
5014 eDateCmd = FILL_MONTH;
5015 break;
5016 case sheet::FillDateMode_FILL_DATE_YEAR:
5017 eDateCmd = FILL_YEAR;
5018 break;
5019 default:
5020 bError = true;
5023 if (!bError)
5024 pDocSh->GetDocFunc().FillSeries( aRange, nullptr, eDir, eCmd, eDateCmd,
5025 MAXDOUBLE, fStep, fEndValue, true );
5028 void SAL_CALL ScCellRangeObj::fillAuto( sheet::FillDirection nFillDirection,
5029 sal_Int32 nSourceCount )
5031 SolarMutexGuard aGuard;
5032 ScDocShell* pDocSh = GetDocShell();
5033 if ( !(pDocSh && nSourceCount) )
5034 return;
5036 ScRange aSourceRange(aRange);
5037 SCCOLROW nCount = 0; // "Dest-Count"
5038 FillDir eDir = FILL_TO_BOTTOM;
5039 bool bError = false;
5040 switch (nFillDirection)
5042 case sheet::FillDirection_TO_BOTTOM:
5043 aSourceRange.aEnd.SetRow( static_cast<SCROW>( aSourceRange.aStart.Row() + nSourceCount - 1 ) );
5044 nCount = aRange.aEnd.Row() - aSourceRange.aEnd.Row();
5045 eDir = FILL_TO_BOTTOM;
5046 break;
5047 case sheet::FillDirection_TO_RIGHT:
5048 aSourceRange.aEnd.SetCol( static_cast<SCCOL>( aSourceRange.aStart.Col() + nSourceCount - 1 ) );
5049 nCount = aRange.aEnd.Col() - aSourceRange.aEnd.Col();
5050 eDir = FILL_TO_RIGHT;
5051 break;
5052 case sheet::FillDirection_TO_TOP:
5053 aSourceRange.aStart.SetRow( static_cast<SCROW>( aSourceRange.aEnd.Row() - nSourceCount + 1 ) );
5054 nCount = aSourceRange.aStart.Row() - aRange.aStart.Row();
5055 eDir = FILL_TO_TOP;
5056 break;
5057 case sheet::FillDirection_TO_LEFT:
5058 aSourceRange.aStart.SetCol( static_cast<SCCOL>( aSourceRange.aEnd.Col() - nSourceCount + 1 ) );
5059 nCount = aSourceRange.aStart.Col() - aRange.aStart.Col();
5060 eDir = FILL_TO_LEFT;
5061 break;
5062 default:
5063 bError = true;
5065 const ScDocument& rDoc = pDocSh->GetDocument();
5066 if (nCount < 0 || nCount > rDoc.MaxRow()) // overflow
5067 bError = true;
5069 if (!bError)
5070 pDocSh->GetDocFunc().FillAuto( aSourceRange, nullptr, eDir, nCount, true );
5073 // XAutoFormattable
5075 void SAL_CALL ScCellRangeObj::autoFormat( const OUString& aName )
5077 SolarMutexGuard aGuard;
5078 ScDocShell* pDocSh = GetDocShell();
5079 if ( pDocSh )
5081 ScAutoFormat* pAutoFormat = ScGlobal::GetOrCreateAutoFormat();
5082 ScAutoFormat::const_iterator it = pAutoFormat->find(aName);
5083 if (it == pAutoFormat->end())
5084 throw lang::IllegalArgumentException();
5086 ScAutoFormat::const_iterator itBeg = pAutoFormat->begin();
5087 size_t nIndex = std::distance(itBeg, it);
5088 pDocSh->GetDocFunc().AutoFormat(aRange, nullptr, nIndex, true);
5093 // XSortable
5095 uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createSortDescriptor()
5097 SolarMutexGuard aGuard;
5098 ScSortParam aParam;
5099 ScDocShell* pDocSh = GetDocShell();
5100 if ( pDocSh )
5102 // create DB-Area only during execution; API always the exact area
5103 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark );
5104 if (pData)
5106 pData->GetSortParam(aParam);
5108 // SortDescriptor contains the counted fields inside the area
5109 ScRange aDBRange;
5110 pData->GetArea(aDBRange);
5111 SCCOLROW nFieldStart = aParam.bByRow ?
5112 static_cast<SCCOLROW>(aDBRange.aStart.Col()) :
5113 static_cast<SCCOLROW>(aDBRange.aStart.Row());
5114 for (sal_uInt16 i=0; i<aParam.GetSortKeyCount(); i++)
5115 if ( aParam.maKeyState[i].bDoSort && aParam.maKeyState[i].nField >= nFieldStart )
5116 aParam.maKeyState[i].nField -= nFieldStart;
5120 uno::Sequence<beans::PropertyValue> aSeq( ScSortDescriptor::GetPropertyCount() );
5121 ScSortDescriptor::FillProperties( aSeq, aParam );
5122 return aSeq;
5125 void SAL_CALL ScCellRangeObj::sort( const uno::Sequence<beans::PropertyValue>& aDescriptor )
5127 SolarMutexGuard aGuard;
5128 ScDocShell* pDocSh = GetDocShell();
5129 if (!pDocSh)
5130 return;
5132 sal_uInt16 i;
5133 ScSortParam aParam;
5134 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area
5135 if (pData)
5137 // get old settings if not everything is set anew
5138 pData->GetSortParam(aParam);
5139 SCCOLROW nOldStart = aParam.bByRow ?
5140 static_cast<SCCOLROW>(aRange.aStart.Col()) :
5141 static_cast<SCCOLROW>(aRange.aStart.Row());
5142 for (i=0; i<aParam.GetSortKeyCount(); i++)
5143 if ( aParam.maKeyState[i].bDoSort && aParam.maKeyState[i].nField >= nOldStart )
5144 aParam.maKeyState[i].nField -= nOldStart;
5147 ScSortDescriptor::FillSortParam( aParam, aDescriptor );
5149 // SortDescriptor contains the counted fields inside the area
5150 // ByRow can be changed during execution of FillSortParam
5151 SCCOLROW nFieldStart = aParam.bByRow ?
5152 static_cast<SCCOLROW>(aRange.aStart.Col()) :
5153 static_cast<SCCOLROW>(aRange.aStart.Row());
5154 SCCOLROW nFieldEnd = aParam.bByRow ?
5155 static_cast<SCCOLROW>(aRange.aEnd.Col()) :
5156 static_cast<SCCOLROW>(aRange.aEnd.Row());
5157 for (i=0; i<aParam.GetSortKeyCount(); i++)
5159 aParam.maKeyState[i].nField += nFieldStart;
5160 // tdf#103632 - sanity check poorly behaved macros.
5161 if (aParam.maKeyState[i].nField > nFieldEnd)
5162 aParam.maKeyState[i].nField = nFieldEnd;
5165 SCTAB nTab = aRange.aStart.Tab();
5166 aParam.nCol1 = aRange.aStart.Col();
5167 aParam.nRow1 = aRange.aStart.Row();
5168 aParam.nCol2 = aRange.aEnd.Col();
5169 aParam.nRow2 = aRange.aEnd.Row();
5171 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area
5173 ScDBDocFunc aFunc(*pDocSh); // area must be created
5174 (void)aFunc.Sort( nTab, aParam, true, true, true );
5177 // XFilterable
5179 uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFilterDescriptor(
5180 sal_Bool bEmpty )
5182 SolarMutexGuard aGuard;
5183 ScDocShell* pDocSh = GetDocShell();
5184 rtl::Reference<ScFilterDescriptor> pNew = new ScFilterDescriptor(pDocSh);
5185 if ( !bEmpty && pDocSh )
5187 // create DB-Area only during execution; API always the exact area
5188 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark );
5189 if (pData)
5191 ScQueryParam aParam;
5192 pData->GetQueryParam(aParam);
5193 // FilterDescriptor contains the counted fields inside the area
5194 ScRange aDBRange;
5195 pData->GetArea(aDBRange);
5196 SCCOLROW nFieldStart = aParam.bByRow ?
5197 static_cast<SCCOLROW>(aDBRange.aStart.Col()) :
5198 static_cast<SCCOLROW>(aDBRange.aStart.Row());
5199 SCSIZE nCount = aParam.GetEntryCount();
5200 for (SCSIZE i=0; i<nCount; i++)
5202 ScQueryEntry& rEntry = aParam.GetEntry(i);
5203 if (rEntry.bDoQuery && rEntry.nField >= nFieldStart)
5204 rEntry.nField -= nFieldStart;
5206 pNew->SetParam(aParam);
5209 return pNew;
5212 void SAL_CALL ScCellRangeObj::filter( const uno::Reference<sheet::XSheetFilterDescriptor>& xDescriptor )
5214 SolarMutexGuard aGuard;
5216 if (!xDescriptor.is()) return;
5218 // This could be theoretically an unknown object, so only use the
5219 // public XSheetFilterDescriptor interface to copy the data into a
5220 // ScFilterDescriptor object:
5221 //! if it already a ScFilterDescriptor is, direct via getImplementation?
5223 ScDocShell* pDocSh = GetDocShell();
5224 rtl::Reference<ScFilterDescriptor> xImpl(new ScFilterDescriptor(pDocSh));
5225 uno::Reference< sheet::XSheetFilterDescriptor2 > xDescriptor2( xDescriptor, uno::UNO_QUERY );
5226 if ( xDescriptor2.is() )
5228 xImpl->setFilterFields2( xDescriptor2->getFilterFields2() );
5230 else
5232 xImpl->setFilterFields( xDescriptor->getFilterFields() );
5234 // the rest are now properties...
5236 uno::Reference<beans::XPropertySet> xPropSet( xDescriptor, uno::UNO_QUERY );
5237 if (xPropSet.is())
5238 lcl_CopyProperties(*xImpl, *xPropSet);
5240 if (!pDocSh)
5241 return;
5243 ScQueryParam aParam = xImpl->GetParam();
5244 // FilterDescriptor contains the counted fields inside the area
5245 SCCOLROW nFieldStart = aParam.bByRow ?
5246 static_cast<SCCOLROW>(aRange.aStart.Col()) :
5247 static_cast<SCCOLROW>(aRange.aStart.Row());
5248 SCSIZE nCount = aParam.GetEntryCount();
5249 svl::SharedStringPool& rPool = pDocSh->GetDocument().GetSharedStringPool();
5250 for (SCSIZE i=0; i<nCount; i++)
5252 ScQueryEntry& rEntry = aParam.GetEntry(i);
5253 if (rEntry.bDoQuery)
5255 rEntry.nField += nFieldStart;
5256 // dialog always shows the string -> must match the value
5257 ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
5258 rItems.resize(1);
5259 ScQueryEntry::Item& rItem = rItems.front();
5260 if (rItem.meType != ScQueryEntry::ByString)
5262 OUString aStr = pDocSh->GetDocument().GetFormatTable()->GetInputLineString(rItem.mfVal, 0);
5263 rItem.maString = rPool.intern(aStr);
5268 SCTAB nTab = aRange.aStart.Tab();
5269 aParam.nCol1 = aRange.aStart.Col();
5270 aParam.nRow1 = aRange.aStart.Row();
5271 aParam.nCol2 = aRange.aEnd.Col();
5272 aParam.nRow2 = aRange.aEnd.Row();
5274 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area
5276 //! keep source range in filter descriptor
5277 //! if created by createFilterDescriptorByObject ???
5279 ScDBDocFunc aFunc(*pDocSh);
5280 aFunc.Query( nTab, aParam, nullptr, true, true ); // area must be created
5283 //! get/setAutoFilter as properties!!!
5285 // XAdvancedFilterSource
5287 uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFilterDescriptorByObject(
5288 const uno::Reference<sheet::XSheetFilterable>& xObject )
5290 SolarMutexGuard aGuard;
5292 // this here is not the area, which will be filtered, instead the area
5293 // with the query
5295 uno::Reference<sheet::XCellRangeAddressable> xAddr( xObject, uno::UNO_QUERY );
5297 ScDocShell* pDocSh = GetDocShell();
5298 if ( !pDocSh || !xAddr.is() )
5300 OSL_FAIL("no document or no area");
5301 return nullptr;
5304 //! check if xObject is in the same document
5306 rtl::Reference<ScFilterDescriptor> pNew(new ScFilterDescriptor(pDocSh)); //! instead from object?
5308 ScQueryParam aParam = pNew->GetParam();
5309 aParam.bHasHeader = true;
5311 table::CellRangeAddress aDataAddress(xAddr->getRangeAddress());
5312 aParam.nCol1 = static_cast<SCCOL>(aDataAddress.StartColumn);
5313 aParam.nRow1 = static_cast<SCROW>(aDataAddress.StartRow);
5314 aParam.nCol2 = static_cast<SCCOL>(aDataAddress.EndColumn);
5315 aParam.nRow2 = static_cast<SCROW>(aDataAddress.EndRow);
5316 aParam.nTab = aDataAddress.Sheet;
5318 ScDocument& rDoc = pDocSh->GetDocument();
5319 if (!rDoc.CreateQueryParam(aRange, aParam))
5320 return nullptr;
5322 // FilterDescriptor contains the counted fields inside the area
5323 SCCOLROW nFieldStart = aParam.bByRow ?
5324 static_cast<SCCOLROW>(aDataAddress.StartColumn) :
5325 static_cast<SCCOLROW>(aDataAddress.StartRow);
5326 SCSIZE nCount = aParam.GetEntryCount();
5327 for (SCSIZE i=0; i<nCount; i++)
5329 ScQueryEntry& rEntry = aParam.GetEntry(i);
5330 if (rEntry.bDoQuery && rEntry.nField >= nFieldStart)
5331 rEntry.nField -= nFieldStart;
5334 pNew->SetParam( aParam );
5335 return pNew;
5338 // XSubTotalSource
5340 uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL ScCellRangeObj::createSubTotalDescriptor(
5341 sal_Bool bEmpty )
5343 SolarMutexGuard aGuard;
5344 rtl::Reference<ScSubTotalDescriptor> pNew = new ScSubTotalDescriptor;
5345 ScDocShell* pDocSh = GetDocShell();
5346 if ( !bEmpty && pDocSh )
5348 // create DB-Area only during execution; API always the exact area
5349 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark );
5350 if (pData)
5352 ScSubTotalParam aParam;
5353 pData->GetSubTotalParam(aParam);
5354 // SubTotalDescriptor contains the counted fields inside the area
5355 ScRange aDBRange;
5356 pData->GetArea(aDBRange);
5357 SCCOL nFieldStart = aDBRange.aStart.Col();
5358 for (auto& group : aParam.aGroups)
5360 if (group.bActive)
5362 if (group.nField >= nFieldStart)
5363 group.nField -= nFieldStart;
5364 for (SCCOL j = 0; j < group.nSubTotals; j++)
5365 if (group.col(j) >= nFieldStart)
5366 group.col(j) -= nFieldStart;
5369 pNew->SetParam(aParam);
5372 return pNew;
5375 void SAL_CALL ScCellRangeObj::applySubTotals(
5376 const uno::Reference<sheet::XSubTotalDescriptor>& xDescriptor,
5377 sal_Bool bReplace)
5379 SolarMutexGuard aGuard;
5381 if (!xDescriptor.is()) return;
5383 ScDocShell* pDocSh = GetDocShell();
5384 ScSubTotalDescriptorBase* pImp =
5385 dynamic_cast<ScSubTotalDescriptorBase*>( xDescriptor.get() );
5387 if (!(pDocSh && pImp))
5388 return;
5390 ScSubTotalParam aParam;
5391 pImp->GetData(aParam); // virtual method of base class
5393 // SubTotalDescriptor contains the counted fields inside the area
5394 SCCOL nFieldStart = aRange.aStart.Col();
5395 for (auto& group : aParam.aGroups)
5397 if (group.bActive)
5399 group.nField += nFieldStart;
5400 for (SCCOL j = 0; j < group.nSubTotals; j++)
5401 group.col(j) += nFieldStart;
5405 aParam.bReplace = bReplace;
5407 SCTAB nTab = aRange.aStart.Tab();
5408 aParam.nCol1 = aRange.aStart.Col();
5409 aParam.nRow1 = aRange.aStart.Row();
5410 aParam.nCol2 = aRange.aEnd.Col();
5411 aParam.nRow2 = aRange.aEnd.Row();
5413 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area
5415 ScDBDocFunc aFunc(*pDocSh);
5416 aFunc.DoSubTotals( nTab, aParam, true, true ); // area must be created
5419 void SAL_CALL ScCellRangeObj::removeSubTotals()
5421 SolarMutexGuard aGuard;
5423 ScDocShell* pDocSh = GetDocShell();
5424 if (!pDocSh)
5425 return;
5427 ScSubTotalParam aParam;
5428 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark );
5429 if (pData)
5430 pData->GetSubTotalParam(aParam); // also keep field entries during remove
5432 aParam.bRemoveOnly = true;
5434 SCTAB nTab = aRange.aStart.Tab();
5435 aParam.nCol1 = aRange.aStart.Col();
5436 aParam.nRow1 = aRange.aStart.Row();
5437 aParam.nCol2 = aRange.aEnd.Col();
5438 aParam.nRow2 = aRange.aEnd.Row();
5440 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area
5442 ScDBDocFunc aFunc(*pDocSh);
5443 aFunc.DoSubTotals( nTab, aParam, true, true ); // are must be created
5446 uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createImportDescriptor( sal_Bool bEmpty )
5448 SolarMutexGuard aGuard;
5449 ScImportParam aParam;
5450 ScDocShell* pDocSh = GetDocShell();
5451 if ( !bEmpty && pDocSh )
5453 // create DB-Area only during execution; API always the exact area
5454 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark );
5455 if (pData)
5456 pData->GetImportParam(aParam);
5459 uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
5460 ScImportDescriptor::FillProperties( aSeq, aParam );
5461 return aSeq;
5464 void SAL_CALL ScCellRangeObj::doImport( const uno::Sequence<beans::PropertyValue>& aDescriptor )
5466 SolarMutexGuard aGuard;
5467 ScDocShell* pDocSh = GetDocShell();
5468 if (!pDocSh)
5469 return;
5471 ScImportParam aParam;
5472 ScImportDescriptor::FillImportParam( aParam, aDescriptor );
5474 SCTAB nTab = aRange.aStart.Tab();
5475 aParam.nCol1 = aRange.aStart.Col();
5476 aParam.nRow1 = aRange.aStart.Row();
5477 aParam.nCol2 = aRange.aEnd.Col();
5478 aParam.nRow2 = aRange.aEnd.Row();
5480 //! TODO: could we get passed a valid result set by any means?
5482 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area
5484 ScDBDocFunc aFunc(*pDocSh); // are must be created
5485 aFunc.DoImport( nTab, aParam, nullptr ); //! Api-Flag as parameter
5488 // XCellFormatRangesSupplier
5490 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangeObj::getCellFormatRanges()
5492 SolarMutexGuard aGuard;
5493 ScDocShell* pDocSh = GetDocShell();
5494 if ( pDocSh )
5495 return new ScCellFormatsObj( pDocSh, aRange );
5496 return nullptr;
5499 // XUniqueCellFormatRangesSupplier
5501 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangeObj::getUniqueCellFormatRanges()
5503 SolarMutexGuard aGuard;
5504 ScDocShell* pDocSh = GetDocShell();
5505 if ( pDocSh )
5506 return new ScUniqueCellFormatsObj( pDocSh, aRange );
5507 return nullptr;
5510 // XPropertySet extended for Range-Properties
5512 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellRangeObj::getPropertySetInfo()
5514 SolarMutexGuard aGuard;
5515 static uno::Reference<beans::XPropertySetInfo> aRef(
5516 new SfxItemPropertySetInfo( pRangePropSet->getPropertyMap() ));
5517 return aRef;
5520 void ScCellRangeObj::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue )
5522 // Range has only Position and Size in addition to ScCellRangesBase, both are ReadOnly
5523 // -> nothing to do here
5525 ScCellRangesBase::SetOnePropertyValue( pEntry, aValue );
5528 void ScCellRangeObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny )
5530 if ( !pEntry )
5531 return;
5533 if ( pEntry->nWID == SC_WID_UNO_POS )
5535 ScDocShell* pDocSh = GetDocShell();
5536 if (pDocSh)
5538 // GetMMRect converts using HMM_PER_TWIPS, like the DrawingLayer
5539 tools::Rectangle aMMRect(pDocSh->GetDocument().GetMMRect(
5540 aRange.aStart.Col(), aRange.aStart.Row(),
5541 aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ));
5542 awt::Point aPos( aMMRect.Left(), aMMRect.Top() );
5543 rAny <<= aPos;
5546 else if ( pEntry->nWID == SC_WID_UNO_SIZE )
5548 ScDocShell* pDocSh = GetDocShell();
5549 if (pDocSh)
5551 // GetMMRect converts using HMM_PER_TWIPS, like the DrawingLayer
5552 tools::Rectangle aMMRect = pDocSh->GetDocument().GetMMRect(
5553 aRange.aStart.Col(), aRange.aStart.Row(),
5554 aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() );
5555 Size aSize(aMMRect.GetSize());
5556 awt::Size aAwtSize( aSize.Width(), aSize.Height() );
5557 rAny <<= aAwtSize;
5560 else
5561 ScCellRangesBase::GetOnePropertyValue( pEntry, rAny );
5564 const SfxItemPropertyMap& ScCellRangeObj::GetItemPropertyMap()
5566 return pRangePropSet->getPropertyMap();
5569 // XServiceInfo
5571 OUString SAL_CALL ScCellRangeObj::getImplementationName()
5573 return u"ScCellRangeObj"_ustr;
5576 sal_Bool SAL_CALL ScCellRangeObj::supportsService( const OUString& rServiceName )
5578 return cppu::supportsService(this, rServiceName);
5581 uno::Sequence<OUString> SAL_CALL ScCellRangeObj::getSupportedServiceNames()
5583 return {SCSHEETCELLRANGE_SERVICE,
5584 SCCELLRANGE_SERVICE,
5585 SCCELLPROPERTIES_SERVICE,
5586 SCCHARPROPERTIES_SERVICE,
5587 SCPARAPROPERTIES_SERVICE};
5590 const SvxItemPropertySet* ScCellObj::GetEditPropertySet()
5592 return lcl_GetEditPropertySet();
5595 const SfxItemPropertyMap& ScCellObj::GetCellPropertyMap()
5597 return lcl_GetCellPropertySet()->getPropertyMap();
5600 ScCellObj::ScCellObj(ScDocShell* pDocSh, const ScAddress& rP) :
5601 ScCellObj_BASE( pDocSh, ScRange(rP,rP) ),
5602 pCellPropSet( lcl_GetCellPropertySet() ),
5603 aCellPos( rP ),
5604 nActionLockCount( 0 )
5606 // pUnoText is allocated on demand (GetUnoText)
5607 // can't be aggregated because getString/setString is handled here
5610 SvxUnoText& ScCellObj::GetUnoText()
5612 if (!mxUnoText.is())
5614 mxUnoText.set(new ScCellTextObj(GetDocShell(), aCellPos));
5615 if (nActionLockCount)
5617 ScCellEditSource* pEditSource =
5618 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource());
5619 if (pEditSource)
5620 pEditSource->SetDoUpdateData(false);
5623 return *mxUnoText;
5626 ScCellObj::~ScCellObj()
5630 void ScCellObj::RefChanged()
5632 ScCellRangeObj::RefChanged();
5634 const ScRangeList& rRanges = GetRangeList();
5635 OSL_ENSURE(rRanges.size() == 1, "What ranges ?!?!");
5636 if ( !rRanges.empty() )
5638 aCellPos = rRanges[ 0 ].aStart;
5642 // helper methods
5644 OUString ScCellObj::GetInputString_Impl(bool bEnglish) const // for getFormula / FormulaLocal
5646 if (GetDocShell())
5647 return lcl_GetInputString( GetDocShell()->GetDocument(), aCellPos, bEnglish );
5648 return OUString();
5651 OUString ScCellObj::GetOutputString_Impl() const
5653 ScDocShell* pDocSh = GetDocShell();
5654 OUString aVal;
5655 if ( pDocSh )
5657 ScDocument& rDoc = pDocSh->GetDocument();
5658 ScRefCellValue aCell(rDoc, aCellPos);
5660 aVal = ScCellFormat::GetOutputString(rDoc, aCellPos, aCell);
5662 return aVal;
5665 void ScCellObj::SetString_Impl(const OUString& rString, bool bInterpret, bool bEnglish)
5667 ScDocShell* pDocSh = GetDocShell();
5668 if ( pDocSh )
5670 // GRAM_API for API compatibility.
5671 (void)pDocSh->GetDocFunc().SetCellText(
5672 aCellPos, rString, bInterpret, bEnglish, true, formula::FormulaGrammar::GRAM_API );
5676 double ScCellObj::GetValue_Impl() const
5678 ScDocShell* pDocSh = GetDocShell();
5679 if ( pDocSh )
5680 return pDocSh->GetDocument().GetValue( aCellPos );
5682 return 0.0;
5685 void ScCellObj::SetValue_Impl(double fValue)
5687 ScDocShell* pDocSh = GetDocShell();
5688 if ( pDocSh )
5689 pDocSh->GetDocFunc().SetValueCell(aCellPos, fValue, false);
5692 // only for XML import
5694 void ScCellObj::InputEnglishString( const OUString& rText )
5696 // This is like a mixture of setFormula and property FormulaLocal:
5697 // The cell's number format is checked for "text", a new cell format may be set,
5698 // but all parsing is in English.
5700 ScDocShell* pDocSh = GetDocShell();
5701 if (!pDocSh)
5702 return;
5704 ScDocument& rDoc = pDocSh->GetDocument();
5705 ScInterpreterContext& rContext = rDoc.GetNonThreadedContext();
5706 sal_uInt32 nOldFormat = rDoc.GetNumberFormat( ScRange(aCellPos) );
5707 if (rContext.NFGetType(nOldFormat) == SvNumFormatType::TEXT)
5709 SetString_Impl(rText, false, false); // text cell
5710 return;
5713 ScDocFunc &rFunc = pDocSh->GetDocFunc();
5715 ScInputStringType aRes =
5716 ScStringUtil::parseInputString(rContext, rText, LANGUAGE_ENGLISH_US);
5718 if (aRes.meType != ScInputStringType::Unknown)
5720 if ((nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && aRes.mnFormatType != SvNumFormatType::ALL)
5722 // apply a format for the recognized type and the old format's language
5723 sal_uInt32 nNewFormat = ScGlobal::GetStandardFormat(rContext, nOldFormat, aRes.mnFormatType);
5724 if (nNewFormat != nOldFormat)
5726 ScPatternAttr aPattern(rDoc.getCellAttributeHelper());
5727 aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
5728 // ATTR_LANGUAGE_FORMAT remains unchanged
5729 rFunc.ApplyAttributes( *GetMarkData(), aPattern, true );
5733 switch (aRes.meType)
5735 case ScInputStringType::Formula:
5736 rFunc.SetFormulaCell(
5737 aCellPos,
5738 new ScFormulaCell(rDoc, aCellPos, aRes.maText, formula::FormulaGrammar::GRAM_API),
5739 false);
5740 break;
5741 case ScInputStringType::Number:
5742 rFunc.SetValueCell(aCellPos, aRes.mfValue, false);
5743 break;
5744 case ScInputStringType::Text:
5745 rFunc.SetStringOrEditCell(aCellPos, aRes.maText, false);
5746 break;
5747 default:
5748 SetString_Impl(rText, false, false); // probably empty string
5752 // XText
5754 uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursor()
5756 SolarMutexGuard aGuard;
5757 return new ScCellTextCursor( *this );
5760 uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursorByRange(
5761 const uno::Reference<text::XTextRange>& aTextPosition )
5763 SolarMutexGuard aGuard;
5764 rtl::Reference<SvxUnoTextCursor> pCursor = new ScCellTextCursor( *this );
5766 SvxUnoTextRangeBase* pRange = comphelper::getFromUnoTunnel<SvxUnoTextRangeBase>( aTextPosition );
5767 if(pRange)
5768 pCursor->SetSelection( pRange->GetSelection() );
5769 else
5771 ScCellTextCursor* pOther = comphelper::getFromUnoTunnel<ScCellTextCursor>( aTextPosition );
5772 if(!pOther)
5773 throw uno::RuntimeException();
5775 pCursor->SetSelection( pOther->GetSelection() );
5779 return pCursor;
5782 OUString SAL_CALL ScCellObj::getString()
5784 SolarMutexGuard aGuard;
5785 return GetOutputString_Impl();
5788 void SAL_CALL ScCellObj::setString( const OUString& aText )
5790 SolarMutexGuard aGuard;
5791 SetString_Impl(aText, false, false); // always text
5793 // don't create pUnoText here if not there
5794 if (mxUnoText.is())
5795 mxUnoText->SetSelection(ESelection( 0,0, 0,aText.getLength() ));
5798 void SAL_CALL ScCellObj::insertString( const uno::Reference<text::XTextRange>& xRange,
5799 const OUString& aString, sal_Bool bAbsorb )
5801 // special handling for ScCellTextCursor is no longer needed,
5802 // SvxUnoText::insertString checks for SvxUnoTextRangeBase instead of SvxUnoTextRange
5804 SolarMutexGuard aGuard;
5805 GetUnoText().insertString(xRange, aString, bAbsorb);
5808 void SAL_CALL ScCellObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange,
5809 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
5811 SolarMutexGuard aGuard;
5812 GetUnoText().insertControlCharacter(xRange, nControlCharacter, bAbsorb);
5815 void SAL_CALL ScCellObj::insertTextContent( const uno::Reference<text::XTextRange >& xRange,
5816 const uno::Reference<text::XTextContent >& xContent,
5817 sal_Bool bAbsorb )
5819 SolarMutexGuard aGuard;
5820 ScDocShell* pDocSh = GetDocShell();
5821 if ( pDocSh && xContent.is() )
5823 ScEditFieldObj* pCellField = dynamic_cast<ScEditFieldObj*>(xContent.get());
5824 SvxUnoTextRangeBase* pTextRange = comphelper::getFromUnoTunnel<ScCellTextCursor>( xRange );
5826 if ( pCellField && !pCellField->IsInserted() && pTextRange )
5828 SvxEditSource* pEditSource = pTextRange->GetEditSource();
5829 ESelection aSelection(pTextRange->GetSelection());
5831 if (!bAbsorb)
5833 // do not replace -> append
5834 aSelection.Adjust();
5835 aSelection.CollapseToEnd();
5838 if (pCellField->GetFieldType() == text::textfield::Type::TABLE)
5839 pCellField->setPropertyValue(SC_UNONAME_TABLEPOS, uno::Any(sal_Int32(aCellPos.Tab())));
5841 SvxFieldItem aItem = pCellField->CreateFieldItem();
5842 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
5843 pForwarder->QuickInsertField( aItem, aSelection );
5844 pEditSource->UpdateData();
5846 // new selection: a digit
5847 aSelection.Adjust();
5848 aSelection.end.nPara = aSelection.start.nPara;
5849 aSelection.end.nIndex = aSelection.start.nIndex + 1;
5850 uno::Reference<text::XTextRange> xParent(this);
5851 pCellField->InitDoc(
5852 xParent, std::make_unique<ScCellEditSource>(pDocSh, aCellPos), aSelection);
5854 // for bAbsorb=FALSE, the new selection must be behind the inserted content
5855 // (the xml filter relies on this)
5856 if (!bAbsorb)
5857 aSelection.start.nIndex = aSelection.end.nIndex;
5859 pTextRange->SetSelection( aSelection );
5861 return;
5864 GetUnoText().insertTextContent(xRange, xContent, bAbsorb);
5867 void SAL_CALL ScCellObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent )
5869 SolarMutexGuard aGuard;
5870 if ( xContent.is() )
5872 ScEditFieldObj* pCellField = dynamic_cast<ScEditFieldObj*>(xContent.get());
5873 if ( pCellField && pCellField->IsInserted() )
5875 //! Check if field is in this cell
5876 pCellField->DeleteField();
5877 return;
5880 GetUnoText().removeTextContent(xContent);
5883 uno::Reference<text::XText> SAL_CALL ScCellObj::getText()
5885 return this;
5888 uno::Reference<text::XTextRange> SAL_CALL ScCellObj::getStart()
5890 SolarMutexGuard aGuard;
5891 return GetUnoText().getStart();
5894 uno::Reference<text::XTextRange> SAL_CALL ScCellObj::getEnd()
5896 SolarMutexGuard aGuard;
5897 return GetUnoText().getEnd();
5900 uno::Reference<container::XEnumeration> SAL_CALL ScCellObj::createEnumeration()
5902 SolarMutexGuard aGuard;
5903 return GetUnoText().createEnumeration();
5906 uno::Type SAL_CALL ScCellObj::getElementType()
5908 SolarMutexGuard aGuard;
5909 return GetUnoText().getElementType();
5912 sal_Bool SAL_CALL ScCellObj::hasElements()
5914 SolarMutexGuard aGuard;
5915 return GetUnoText().hasElements();
5918 // XCell
5920 OUString SAL_CALL ScCellObj::getFormula()
5922 SolarMutexGuard aGuard;
5923 return GetInputString_Impl( true /* English */ );
5926 void SAL_CALL ScCellObj::setFormula( const OUString& aFormula )
5928 SolarMutexGuard aGuard;
5929 SetString_Impl(aFormula, true, true); // Interpret as English
5932 double SAL_CALL ScCellObj::getValue()
5934 SolarMutexGuard aGuard;
5935 return GetValue_Impl();
5938 void SAL_CALL ScCellObj::setValue( double nValue )
5940 SolarMutexGuard aGuard;
5941 SetValue_Impl(nValue);
5944 void SAL_CALL ScCellObj::setFormulaString( const OUString& aFormula)
5946 SolarMutexGuard aGuard;
5947 ScDocShell *pDocSh = GetDocShell();
5948 if( pDocSh )
5950 ScFormulaCell* pCell = new ScFormulaCell( pDocSh->GetDocument(), aCellPos );
5951 pCell->SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE );
5952 pDocSh->GetDocFunc().SetFormulaCell(aCellPos, pCell, false);
5955 void SAL_CALL ScCellObj::setFormulaResult( double nValue )
5957 SolarMutexGuard aGuard;
5958 ScDocShell* pDocSh = GetDocShell();
5959 if (pDocSh)
5961 ScRefCellValue aCell(pDocSh->GetDocument(), aCellPos);
5962 if (aCell.getType() == CELLTYPE_FORMULA)
5964 ScFormulaCell* pCell = aCell.getFormula();
5965 pCell->SetHybridDouble( nValue );
5966 pCell->ResetDirty();
5967 pCell->SetChanged(false);
5972 table::CellContentType SAL_CALL ScCellObj::getType()
5974 SolarMutexGuard aGuard;
5975 table::CellContentType eRet = table::CellContentType_EMPTY;
5976 ScDocShell* pDocSh = GetDocShell();
5977 if (pDocSh)
5979 CellType eCalcType = pDocSh->GetDocument().GetCellType( aCellPos );
5980 switch (eCalcType)
5982 case CELLTYPE_VALUE:
5983 eRet = table::CellContentType_VALUE;
5984 break;
5985 case CELLTYPE_STRING:
5986 case CELLTYPE_EDIT:
5987 eRet = table::CellContentType_TEXT;
5988 break;
5989 case CELLTYPE_FORMULA:
5990 eRet = table::CellContentType_FORMULA;
5991 break;
5992 default:
5993 eRet = table::CellContentType_EMPTY;
5996 else
5998 OSL_FAIL("no DocShell"); //! Exception or so?
6001 return eRet;
6004 sal_Int32 ScCellObj::GetResultType_Impl() const
6006 SolarMutexGuard aGuard;
6007 sal_Int32 eRet = sheet::FormulaResult::STRING;
6008 ScDocShell* pDocSh = GetDocShell();
6009 if (pDocSh)
6011 if (pDocSh->GetDocument().GetCellType(aCellPos) == CELLTYPE_FORMULA)
6013 ScFormulaCell* pFCell = pDocSh->GetDocument().GetFormulaCell(aCellPos);
6014 if (!pFCell)
6016 // should throw instead of default string?
6018 else if (pFCell->GetErrCode() != FormulaError::NONE )
6020 eRet = sheet::FormulaResult::ERROR;
6022 else if (pFCell->IsValue())
6024 eRet = sheet::FormulaResult::VALUE;
6026 else
6028 eRet = sheet::FormulaResult::STRING;
6032 else
6034 OSL_FAIL("no DocShell");
6037 return eRet;
6040 table::CellContentType ScCellObj::GetContentType_Impl()
6042 ScDocShell* pDocSh = GetDocShell();
6043 if ( pDocSh )
6045 ScRefCellValue aCell(pDocSh->GetDocument(), aCellPos);
6046 if (aCell.getType() == CELLTYPE_FORMULA)
6048 bool bValue = aCell.getFormula()->IsValue();
6049 return bValue ? table::CellContentType_VALUE : table::CellContentType_TEXT;
6052 return getType();
6055 sal_Int32 SAL_CALL ScCellObj::getError()
6057 SolarMutexGuard aGuard;
6058 ScDocShell* pDocSh = GetDocShell();
6059 if (!pDocSh)
6061 OSL_FAIL("no DocShell"); //! Exception or so?
6062 return 0;
6065 FormulaError nError = FormulaError::NONE;
6066 ScRefCellValue aCell(pDocSh->GetDocument(), aCellPos);
6067 if (aCell.getType() == CELLTYPE_FORMULA)
6068 nError = aCell.getFormula()->GetErrCode();
6070 return static_cast<sal_Int32>(nError);
6073 // XFormulaTokens
6075 uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellObj::getTokens()
6077 SolarMutexGuard aGuard;
6078 uno::Sequence<sheet::FormulaToken> aSequence;
6079 ScDocShell* pDocSh = GetDocShell();
6080 if (!pDocSh)
6081 return aSequence;
6083 ScDocument& rDoc = pDocSh->GetDocument();
6084 ScRefCellValue aCell(rDoc, aCellPos);
6085 if (aCell.getType() == CELLTYPE_FORMULA)
6087 ScTokenArray* pTokenArray = aCell.getFormula()->GetCode();
6088 if (pTokenArray)
6089 ScTokenConversion::ConvertToTokenSequence(rDoc, aSequence, *pTokenArray);
6091 return aSequence;
6094 void SAL_CALL ScCellObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens )
6096 SolarMutexGuard aGuard;
6097 ScDocShell* pDocSh = GetDocShell();
6098 if ( pDocSh )
6100 ScDocument& rDoc = pDocSh->GetDocument();
6101 ScTokenArray aTokenArray(rDoc);
6102 (void)ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens );
6104 ScFormulaCell* pNewCell = new ScFormulaCell(rDoc, aCellPos, aTokenArray);
6105 (void)pDocSh->GetDocFunc().SetFormulaCell(aCellPos, pNewCell, false);
6109 // XCellAddressable
6111 table::CellAddress SAL_CALL ScCellObj::getCellAddress()
6113 SolarMutexGuard aGuard;
6114 table::CellAddress aAdr;
6115 aAdr.Sheet = aCellPos.Tab();
6116 aAdr.Column = aCellPos.Col();
6117 aAdr.Row = aCellPos.Row();
6118 return aAdr;
6121 // XSheetAnnotationAnchor
6123 uno::Reference<sheet::XSheetAnnotation> SAL_CALL ScCellObj::getAnnotation()
6125 SolarMutexGuard aGuard;
6126 ScDocShell* pDocSh = GetDocShell();
6127 if ( pDocSh )
6128 return new ScAnnotationObj( pDocSh, aCellPos );
6130 OSL_FAIL("getAnnotation without DocShell");
6131 return nullptr;
6134 // XFieldTypesSupplier
6136 uno::Reference<container::XEnumerationAccess> SAL_CALL ScCellObj::getTextFields()
6138 SolarMutexGuard aGuard;
6139 ScDocShell* pDocSh = GetDocShell();
6140 if ( pDocSh )
6142 uno::Reference<text::XTextRange> xContent(this);
6143 return new ScCellFieldsObj(xContent, pDocSh, aCellPos);
6146 return nullptr;
6149 uno::Reference<container::XNameAccess> SAL_CALL ScCellObj::getTextFieldMasters()
6151 // there is no such thing in Calc (?)
6152 return nullptr;
6155 // XPropertySet extended for Cell-Properties
6157 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellObj::getPropertySetInfo()
6159 SolarMutexGuard aGuard;
6160 static uno::Reference<beans::XPropertySetInfo> aRef(
6161 new SfxItemPropertySetInfo( pCellPropSet->getPropertyMap() ));
6162 return aRef;
6165 void ScCellObj::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue )
6167 if ( !pEntry )
6168 return;
6170 if ( pEntry->nWID == SC_WID_UNO_FORMLOC )
6172 OUString aStrVal;
6173 aValue >>= aStrVal;
6174 SetString_Impl(aStrVal, true, false); // interpret locally
6176 else if ( pEntry->nWID == SC_WID_UNO_FORMRT || pEntry->nWID == SC_WID_UNO_FORMRT2
6177 || pEntry->nWID == SC_WID_UNO_CELLCONTENTTYPE )
6179 // Read-Only
6180 //! Exception or so...
6182 else
6183 ScCellRangeObj::SetOnePropertyValue( pEntry, aValue );
6186 void ScCellObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny )
6188 if ( !pEntry )
6189 return;
6191 if ( pEntry->nWID == SC_WID_UNO_FORMLOC )
6193 // sal_False = local
6194 rAny <<= GetInputString_Impl(false);
6196 else if ( pEntry->nWID == SC_WID_UNO_FORMRT2 )
6198 sal_Int32 eType = GetResultType_Impl();
6199 rAny <<= eType;
6201 else if ( pEntry->nWID == SC_WID_UNO_CELLCONTENTTYPE || pEntry->nWID == SC_WID_UNO_FORMRT )
6203 table::CellContentType eType = GetContentType_Impl();
6204 rAny <<= eType;
6206 else
6207 ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
6210 const SfxItemPropertyMap& ScCellObj::GetItemPropertyMap()
6212 return pCellPropSet->getPropertyMap();
6215 // XServiceInfo
6217 OUString SAL_CALL ScCellObj::getImplementationName()
6219 return u"ScCellObj"_ustr;
6222 sal_Bool SAL_CALL ScCellObj::supportsService( const OUString& rServiceName )
6224 return cppu::supportsService(this, rServiceName);
6227 uno::Sequence<OUString> SAL_CALL ScCellObj::getSupportedServiceNames()
6229 return {SCSHEETCELL_SERVICE,
6230 SCCELL_SERVICE,
6231 SCCELLPROPERTIES_SERVICE,
6232 SCCHARPROPERTIES_SERVICE,
6233 SCPARAPROPERTIES_SERVICE,
6234 SCSHEETCELLRANGE_SERVICE,
6235 SCCELLRANGE_SERVICE};
6238 // XActionLockable
6240 sal_Bool SAL_CALL ScCellObj::isActionLocked()
6242 SolarMutexGuard aGuard;
6243 return nActionLockCount != 0;
6246 void SAL_CALL ScCellObj::addActionLock()
6248 SolarMutexGuard aGuard;
6249 if (!nActionLockCount)
6251 if (mxUnoText.is())
6253 ScCellEditSource* pEditSource =
6254 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource());
6255 if (pEditSource)
6256 pEditSource->SetDoUpdateData(false);
6259 nActionLockCount++;
6262 void SAL_CALL ScCellObj::removeActionLock()
6264 SolarMutexGuard aGuard;
6265 if (nActionLockCount <= 0)
6266 return;
6268 nActionLockCount--;
6269 if (nActionLockCount)
6270 return;
6272 if (mxUnoText.is())
6274 ScCellEditSource* pEditSource =
6275 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource());
6276 if (pEditSource)
6278 pEditSource->SetDoUpdateData(true);
6279 if (pEditSource->IsDirty())
6280 pEditSource->UpdateData();
6285 void SAL_CALL ScCellObj::setActionLocks( sal_Int16 nLock )
6287 SolarMutexGuard aGuard;
6288 if (mxUnoText.is())
6290 ScCellEditSource* pEditSource =
6291 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource());
6292 if (pEditSource)
6294 pEditSource->SetDoUpdateData(nLock == 0);
6295 if ((nActionLockCount > 0) && (nLock == 0) && pEditSource->IsDirty())
6296 pEditSource->UpdateData();
6299 nActionLockCount = nLock;
6302 sal_Int16 SAL_CALL ScCellObj::resetActionLocks()
6304 SolarMutexGuard aGuard;
6305 sal_uInt16 nRet(nActionLockCount);
6306 if (mxUnoText.is())
6308 ScCellEditSource* pEditSource =
6309 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource());
6310 if (pEditSource)
6312 pEditSource->SetDoUpdateData(true);
6313 if (pEditSource->IsDirty())
6314 pEditSource->UpdateData();
6317 nActionLockCount = 0;
6318 return nRet;
6321 static ScRange MaxDocRange(ScDocShell* pDocSh, SCTAB nTab)
6323 const SCCOL nMaxcol = pDocSh ? pDocSh->GetDocument().MaxCol() : MAXCOL;
6324 const SCROW nMaxRow = pDocSh ? pDocSh->GetDocument().MaxRow() : MAXROW;
6325 return ScRange(0, 0, nTab, nMaxcol, nMaxRow, nTab);
6328 ScTableSheetObj::ScTableSheetObj( ScDocShell* pDocSh, SCTAB nTab ) :
6329 ScTableSheetObj_BASE( pDocSh, MaxDocRange(pDocSh, nTab) ),
6330 pSheetPropSet(lcl_GetSheetPropertySet())
6334 ScTableSheetObj::~ScTableSheetObj()
6338 void ScTableSheetObj::InitInsertSheet(ScDocShell* pDocSh, SCTAB nTab)
6340 ScDocument& rDoc = pDocSh->GetDocument();
6341 InitInsertRange( pDocSh, ScRange(0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab) );
6344 // Helper functions
6346 SCTAB ScTableSheetObj::GetTab_Impl() const
6348 const ScRangeList& rRanges = GetRangeList();
6349 OSL_ENSURE(rRanges.size() == 1, "What ranges ?!?!");
6350 if ( !rRanges.empty() )
6352 return rRanges[ 0 ].aStart.Tab();
6354 return 0;
6357 // former XSheet
6359 uno::Reference<table::XTableCharts> SAL_CALL ScTableSheetObj::getCharts()
6361 SolarMutexGuard aGuard;
6362 ScDocShell* pDocSh = GetDocShell();
6363 if ( pDocSh )
6364 return new ScChartsObj( pDocSh, GetTab_Impl() );
6366 OSL_FAIL("no document");
6367 return nullptr;
6370 uno::Reference<table::XTablePivotCharts> SAL_CALL ScTableSheetObj::getPivotCharts()
6372 SolarMutexGuard aGuard;
6373 ScDocShell* pDocSh = GetDocShell();
6374 if (pDocSh)
6375 return new sc::TablePivotCharts(pDocSh, GetTab_Impl());
6377 OSL_FAIL("no document");
6378 return nullptr;
6381 uno::Reference<sheet::XDataPilotTables> SAL_CALL ScTableSheetObj::getDataPilotTables()
6383 SolarMutexGuard aGuard;
6384 ScDocShell* pDocSh = GetDocShell();
6385 if ( pDocSh )
6386 return new ScDataPilotTablesObj(*pDocSh, GetTab_Impl());
6388 OSL_FAIL("no document");
6389 return nullptr;
6392 uno::Reference<sheet::XScenarios> SAL_CALL ScTableSheetObj::getScenarios()
6394 SolarMutexGuard aGuard;
6395 ScDocShell* pDocSh = GetDocShell();
6397 if ( pDocSh )
6398 return new ScScenariosObj( pDocSh, GetTab_Impl() );
6400 OSL_FAIL("no document");
6401 return nullptr;
6404 uno::Reference<sheet::XSheetAnnotations> SAL_CALL ScTableSheetObj::getAnnotations()
6406 SolarMutexGuard aGuard;
6407 ScDocShell* pDocSh = GetDocShell();
6409 if ( pDocSh )
6410 return new ScAnnotationsObj( pDocSh, GetTab_Impl() );
6412 OSL_FAIL("no document");
6413 return nullptr;
6416 uno::Reference<table::XCellRange> SAL_CALL ScTableSheetObj::getCellRangeByName(
6417 const OUString& rRange )
6419 SolarMutexGuard aGuard;
6420 return ScCellRangeObj::getCellRangeByName( rRange );
6423 uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursor()
6425 SolarMutexGuard aGuard;
6426 ScDocShell* pDocSh = GetDocShell();
6427 if ( pDocSh )
6429 //! single cell or whole table??????
6430 const ScDocument& rDoc = pDocSh->GetDocument();
6431 SCTAB nTab = GetTab_Impl();
6432 return new ScCellCursorObj( pDocSh, ScRange( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab ) );
6434 return nullptr;
6437 uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursorByRange(
6438 const uno::Reference<sheet::XSheetCellRange>& xCellRange )
6440 SolarMutexGuard aGuard;
6441 ScDocShell* pDocSh = GetDocShell();
6442 if ( pDocSh && xCellRange.is() )
6444 ScCellRangesBase* pRangesImp = dynamic_cast<ScCellRangesBase*>( xCellRange.get() );
6445 if (pRangesImp)
6447 const ScRangeList& rRanges = pRangesImp->GetRangeList();
6448 SAL_WARN_IF( rRanges.size() != 1, "sc", "ScTableSheetObj::createCursorByRange: Range? Ranges?");
6449 if (rRanges.empty())
6450 return nullptr;
6451 return new ScCellCursorObj( pDocSh, rRanges[ 0 ] );
6454 return nullptr;
6457 // XSheetCellRange
6459 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScTableSheetObj::getSpreadsheet()
6461 return this; //!???
6464 // XCellRange
6466 uno::Reference<table::XCell> SAL_CALL ScTableSheetObj::getCellByPosition(
6467 sal_Int32 nColumn, sal_Int32 nRow )
6469 SolarMutexGuard aGuard;
6470 return ScCellRangeObj::GetCellByPosition_Impl(nColumn, nRow);
6473 uno::Reference<table::XCellRange> SAL_CALL ScTableSheetObj::getCellRangeByPosition(
6474 sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom )
6476 SolarMutexGuard aGuard;
6477 return ScCellRangeObj::getCellRangeByPosition(nLeft,nTop,nRight,nBottom);
6480 uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getColumnPageBreaks()
6482 SolarMutexGuard aGuard;
6483 ScDocShell* pDocSh = GetDocShell();
6484 if ( pDocSh )
6486 ScDocument& rDoc = pDocSh->GetDocument();
6487 SCTAB nTab = GetTab_Impl();
6489 Size aSize(rDoc.GetPageSize( nTab ));
6490 if (aSize.Width() && aSize.Height()) // effective size already set?
6491 rDoc.UpdatePageBreaks( nTab );
6492 else
6494 // update breaks like in ScDocShell::PageStyleModified:
6495 ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab );
6496 aPrintFunc.UpdatePages();
6499 SCCOL nCount = 0;
6500 for (SCCOL nCol : rDoc.GetColumnsRange(nTab, 0, rDoc.MaxCol()))
6501 if (rDoc.HasColBreak(nCol, nTab) != ScBreakType::NONE)
6502 ++nCount;
6504 sheet::TablePageBreakData aData;
6505 uno::Sequence<sheet::TablePageBreakData> aSeq(nCount);
6506 sheet::TablePageBreakData* pAry = aSeq.getArray();
6507 sal_uInt16 nPos = 0;
6508 for (SCCOL nCol : rDoc.GetColumnsRange(nTab, 0, rDoc.MaxCol()))
6510 ScBreakType nBreak = rDoc.HasColBreak(nCol, nTab);
6511 if (nBreak != ScBreakType::NONE)
6513 aData.Position = nCol;
6514 aData.ManualBreak = bool(nBreak & ScBreakType::Manual);
6515 pAry[nPos] = aData;
6516 ++nPos;
6519 return aSeq;
6521 return {};
6524 uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getRowPageBreaks()
6526 SolarMutexGuard aGuard;
6527 ScDocShell* pDocSh = GetDocShell();
6528 if ( pDocSh )
6530 ScDocument& rDoc = pDocSh->GetDocument();
6531 SCTAB nTab = GetTab_Impl();
6533 Size aSize(rDoc.GetPageSize( nTab ));
6534 if (aSize.Width() && aSize.Height()) // effective size already set?
6535 rDoc.UpdatePageBreaks( nTab );
6536 else
6538 // update breaks like in ScDocShell::PageStyleModified:
6539 ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab );
6540 aPrintFunc.UpdatePages();
6542 return rDoc.GetRowBreakData(nTab);
6544 return {};
6547 void SAL_CALL ScTableSheetObj::removeAllManualPageBreaks()
6549 SolarMutexGuard aGuard;
6550 ScDocShell* pDocSh = GetDocShell();
6551 if ( !pDocSh )
6552 return;
6554 //! DocFunc function, also for ScViewFunc::RemoveManualBreaks
6556 ScDocument& rDoc = pDocSh->GetDocument();
6557 bool bUndo (rDoc.IsUndoEnabled());
6558 SCTAB nTab = GetTab_Impl();
6560 if (bUndo)
6562 ScDocumentUniquePtr pUndoDoc(new ScDocument( SCDOCMODE_UNDO ));
6563 pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true );
6564 rDoc.CopyToDocument(0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
6565 pDocSh->GetUndoManager()->AddUndoAction(
6566 std::make_unique<ScUndoRemoveBreaks>( pDocSh, nTab, std::move(pUndoDoc) ) );
6569 rDoc.RemoveManualBreaks(nTab);
6570 rDoc.UpdatePageBreaks(nTab);
6572 //? UpdatePageBreakData( sal_True );
6573 pDocSh->SetDocumentModified();
6574 pDocSh->PostPaint(ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab), PaintPartFlags::Grid);
6577 // XNamed
6579 OUString SAL_CALL ScTableSheetObj::getName()
6581 SolarMutexGuard aGuard;
6582 OUString aName;
6583 ScDocShell* pDocSh = GetDocShell();
6584 if ( pDocSh )
6585 pDocSh->GetDocument().GetName( GetTab_Impl(), aName );
6586 return aName;
6589 void SAL_CALL ScTableSheetObj::setName( const OUString& aNewName )
6591 SolarMutexGuard aGuard;
6592 ScDocShell* pDocSh = GetDocShell();
6593 if ( pDocSh )
6595 pDocSh->GetDocFunc().RenameTable( GetTab_Impl(), aNewName, true, true );
6599 // XDrawPageSupplier
6601 uno::Reference<drawing::XDrawPage> SAL_CALL ScTableSheetObj::getDrawPage()
6603 SolarMutexGuard aGuard;
6604 ScDocShell* pDocSh = GetDocShell();
6605 if ( pDocSh )
6607 ScDrawLayer* pDrawLayer = pDocSh->MakeDrawLayer();
6608 OSL_ENSURE(pDrawLayer,"Cannot create Draw-Layer");
6610 SCTAB nTab = GetTab_Impl();
6611 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
6612 OSL_ENSURE(pPage,"Draw-Page not found");
6613 if (pPage)
6614 return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY);
6616 // The DrawPage object will register itself as a Listener at SdrModel
6617 // and should receive all action from there
6619 return nullptr;
6622 // XCellMovement
6624 void SAL_CALL ScTableSheetObj::insertCells( const table::CellRangeAddress& rRangeAddress,
6625 sheet::CellInsertMode nMode )
6627 SolarMutexGuard aGuard;
6628 ScDocShell* pDocSh = GetDocShell();
6629 if ( !pDocSh )
6630 return;
6632 bool bDo = true;
6633 InsCellCmd eCmd = INS_NONE;
6634 switch (nMode)
6636 case sheet::CellInsertMode_NONE: bDo = false; break;
6637 case sheet::CellInsertMode_DOWN: eCmd = INS_CELLSDOWN; break;
6638 case sheet::CellInsertMode_RIGHT: eCmd = INS_CELLSRIGHT; break;
6639 case sheet::CellInsertMode_ROWS: eCmd = INS_INSROWS_BEFORE; break;
6640 case sheet::CellInsertMode_COLUMNS: eCmd = INS_INSCOLS_BEFORE; break;
6641 default:
6642 OSL_FAIL("insertCells: wrong mode");
6643 bDo = false;
6646 if (bDo)
6648 OSL_ENSURE( rRangeAddress.Sheet == GetTab_Impl(), "wrong table in CellRangeAddress" );
6649 ScRange aScRange;
6650 ScUnoConversion::FillScRange( aScRange, rRangeAddress );
6651 (void)pDocSh->GetDocFunc().InsertCells( aScRange, nullptr, eCmd, true, true );
6655 void SAL_CALL ScTableSheetObj::removeRange( const table::CellRangeAddress& rRangeAddress,
6656 sheet::CellDeleteMode nMode )
6658 SolarMutexGuard aGuard;
6659 ScDocShell* pDocSh = GetDocShell();
6660 if ( !pDocSh )
6661 return;
6663 bool bDo = true;
6664 DelCellCmd eCmd = DelCellCmd::NONE;
6665 switch (nMode)
6667 case sheet::CellDeleteMode_NONE: bDo = false; break;
6668 case sheet::CellDeleteMode_UP: eCmd = DelCellCmd::CellsUp; break;
6669 case sheet::CellDeleteMode_LEFT: eCmd = DelCellCmd::CellsLeft; break;
6670 case sheet::CellDeleteMode_ROWS: eCmd = DelCellCmd::Rows; break;
6671 case sheet::CellDeleteMode_COLUMNS: eCmd = DelCellCmd::Cols; break;
6672 default:
6673 OSL_FAIL("deleteCells: wrong mode");
6674 bDo = false;
6677 if (bDo)
6679 OSL_ENSURE( rRangeAddress.Sheet == GetTab_Impl(), "wrong table in CellRangeAddress" );
6680 ScRange aScRange;
6681 ScUnoConversion::FillScRange( aScRange, rRangeAddress );
6682 (void)pDocSh->GetDocFunc().DeleteCells( aScRange, nullptr, eCmd, true );
6686 void SAL_CALL ScTableSheetObj::moveRange( const table::CellAddress& aDestination,
6687 const table::CellRangeAddress& aSource )
6689 SolarMutexGuard aGuard;
6690 ScDocShell* pDocSh = GetDocShell();
6691 if ( pDocSh )
6693 OSL_ENSURE( aSource.Sheet == GetTab_Impl(), "wrong table in CellRangeAddress" );
6694 ScRange aSourceRange;
6695 ScUnoConversion::FillScRange( aSourceRange, aSource );
6696 ScAddress aDestPos( static_cast<SCCOL>(aDestination.Column), static_cast<SCROW>(aDestination.Row), aDestination.Sheet );
6697 (void)pDocSh->GetDocFunc().MoveBlock( aSourceRange, aDestPos, true, true, true, true );
6701 void SAL_CALL ScTableSheetObj::copyRange( const table::CellAddress& aDestination,
6702 const table::CellRangeAddress& aSource )
6704 SolarMutexGuard aGuard;
6705 ScDocShell* pDocSh = GetDocShell();
6706 if ( pDocSh )
6708 OSL_ENSURE( aSource.Sheet == GetTab_Impl(), "wrong table in CellRangeAddress" );
6709 ScRange aSourceRange;
6710 ScUnoConversion::FillScRange( aSourceRange, aSource );
6711 ScAddress aDestPos( static_cast<SCCOL>(aDestination.Column), static_cast<SCROW>(aDestination.Row), aDestination.Sheet );
6712 (void)pDocSh->GetDocFunc().MoveBlock( aSourceRange, aDestPos, false, true, true, true );
6716 // XPrintAreas
6718 void ScTableSheetObj::PrintAreaUndo_Impl( std::unique_ptr<ScPrintRangeSaver> pOldRanges )
6720 // page break and undo
6721 ScDocShell* pDocSh = GetDocShell();
6723 if(!pDocSh)
6724 return;
6726 ScDocument& rDoc = pDocSh->GetDocument();
6727 const bool bUndo(rDoc.IsUndoEnabled());
6728 const SCTAB nTab(GetTab_Impl());
6730 if(bUndo)
6732 pDocSh->GetUndoManager()->AddUndoAction(
6733 std::make_unique<ScUndoPrintRange>(
6734 pDocSh,
6735 nTab,
6736 std::move(pOldRanges),
6737 rDoc.CreatePrintRangeSaver())); // create new ranges
6740 ScPrintFunc(pDocSh, pDocSh->GetPrinter(), nTab).UpdatePages();
6741 SfxBindings* pBindings = pDocSh->GetViewBindings();
6743 if(pBindings)
6745 pBindings->Invalidate(SID_DELETE_PRINTAREA);
6748 pDocSh->SetDocumentModified();
6751 uno::Sequence<table::CellRangeAddress> SAL_CALL ScTableSheetObj::getPrintAreas()
6753 SolarMutexGuard aGuard;
6754 ScDocShell* pDocSh = GetDocShell();
6755 if ( pDocSh )
6757 ScDocument& rDoc = pDocSh->GetDocument();
6758 SCTAB nTab = GetTab_Impl();
6759 sal_uInt16 nCount = rDoc.GetPrintRangeCount( nTab );
6761 table::CellRangeAddress aRangeAddress;
6762 uno::Sequence<table::CellRangeAddress> aSeq(nCount);
6763 table::CellRangeAddress* pAry = aSeq.getArray();
6764 for (sal_uInt16 i=0; i<nCount; i++)
6766 const ScRange* pRange = rDoc.GetPrintRange( nTab, i );
6767 OSL_ENSURE(pRange,"where is the printing area");
6768 if (pRange)
6770 ScUnoConversion::FillApiRange( aRangeAddress, *pRange );
6771 aRangeAddress.Sheet = nTab; // core does not care about sheet index
6772 pAry[i] = aRangeAddress;
6775 return aSeq;
6777 return uno::Sequence<table::CellRangeAddress>();
6780 void SAL_CALL ScTableSheetObj::setPrintAreas(
6781 const uno::Sequence<table::CellRangeAddress>& aPrintAreas )
6783 SolarMutexGuard aGuard;
6784 ScDocShell* pDocSh = GetDocShell();
6785 if ( !pDocSh )
6786 return;
6788 std::unique_ptr<ScPrintRangeSaver> pOldRanges;
6789 ScDocument& rDoc = pDocSh->GetDocument();
6790 SCTAB nTab = GetTab_Impl();
6792 if ( rDoc.IsUndoEnabled() )
6793 pOldRanges = rDoc.CreatePrintRangeSaver();
6795 sal_uInt16 nCount = static_cast<sal_uInt16>(aPrintAreas.getLength());
6796 rDoc.ClearPrintRanges( nTab );
6797 if (nCount)
6799 ScRange aPrintRange;
6800 for (const table::CellRangeAddress& rPrintArea : aPrintAreas)
6802 ScUnoConversion::FillScRange( aPrintRange, rPrintArea );
6803 rDoc.AddPrintRange( nTab, aPrintRange );
6807 if ( rDoc.IsUndoEnabled() )
6808 PrintAreaUndo_Impl( std::move(pOldRanges) ); // Undo, Page Breaks, Modified etc.
6811 sal_Bool SAL_CALL ScTableSheetObj::getPrintTitleColumns()
6813 SolarMutexGuard aGuard;
6814 ScDocShell* pDocSh = GetDocShell();
6815 if ( pDocSh )
6817 ScDocument& rDoc = pDocSh->GetDocument();
6818 SCTAB nTab = GetTab_Impl();
6819 return rDoc.GetRepeatColRange(nTab).has_value();
6821 return false;
6824 void SAL_CALL ScTableSheetObj::setPrintTitleColumns( sal_Bool bPrintTitleColumns )
6826 SolarMutexGuard aGuard;
6827 ScDocShell* pDocSh = GetDocShell();
6828 if ( !pDocSh )
6829 return;
6831 ScDocument& rDoc = pDocSh->GetDocument();
6832 SCTAB nTab = GetTab_Impl();
6834 std::unique_ptr<ScPrintRangeSaver> pOldRanges = rDoc.CreatePrintRangeSaver();
6836 if ( bPrintTitleColumns )
6838 if ( !rDoc.GetRepeatColRange( nTab ) ) // do not change existing area
6840 rDoc.SetRepeatColRange( nTab, ScRange( 0, 0, nTab, 0, 0, nTab ) ); // enable
6843 else
6844 rDoc.SetRepeatColRange( nTab, std::nullopt ); // disable
6846 PrintAreaUndo_Impl( std::move(pOldRanges) ); // undo, page break, modified etc.
6848 //! save last set area during switch off and recreate during switch on ???
6851 table::CellRangeAddress SAL_CALL ScTableSheetObj::getTitleColumns()
6853 SolarMutexGuard aGuard;
6854 table::CellRangeAddress aRet;
6855 ScDocShell* pDocSh = GetDocShell();
6856 if ( pDocSh )
6858 ScDocument& rDoc = pDocSh->GetDocument();
6859 SCTAB nTab = GetTab_Impl();
6860 std::optional<ScRange> oRange = rDoc.GetRepeatColRange(nTab);
6861 if (oRange)
6863 ScUnoConversion::FillApiRange( aRet, *oRange );
6864 aRet.Sheet = nTab; // core does not care about sheet index
6867 return aRet;
6870 void SAL_CALL ScTableSheetObj::setTitleColumns( const table::CellRangeAddress& aTitleColumns )
6872 SolarMutexGuard aGuard;
6873 ScDocShell* pDocSh = GetDocShell();
6874 if ( !pDocSh )
6875 return;
6877 ScDocument& rDoc = pDocSh->GetDocument();
6878 SCTAB nTab = GetTab_Impl();
6880 std::unique_ptr<ScPrintRangeSaver> pOldRanges = rDoc.CreatePrintRangeSaver();
6882 ScRange aNew;
6883 ScUnoConversion::FillScRange( aNew, aTitleColumns );
6884 rDoc.SetRepeatColRange( nTab, std::move(aNew) ); // also always enable
6886 PrintAreaUndo_Impl( std::move(pOldRanges) ); // undo, page breaks, modified etc.
6889 sal_Bool SAL_CALL ScTableSheetObj::getPrintTitleRows()
6891 SolarMutexGuard aGuard;
6892 ScDocShell* pDocSh = GetDocShell();
6893 if ( pDocSh )
6895 ScDocument& rDoc = pDocSh->GetDocument();
6896 SCTAB nTab = GetTab_Impl();
6897 return rDoc.GetRepeatRowRange(nTab).has_value();
6899 return false;
6902 void SAL_CALL ScTableSheetObj::setPrintTitleRows( sal_Bool bPrintTitleRows )
6904 SolarMutexGuard aGuard;
6905 ScDocShell* pDocSh = GetDocShell();
6906 if ( !pDocSh )
6907 return;
6909 ScDocument& rDoc = pDocSh->GetDocument();
6910 SCTAB nTab = GetTab_Impl();
6912 std::unique_ptr<ScPrintRangeSaver> pOldRanges = rDoc.CreatePrintRangeSaver();
6914 if ( bPrintTitleRows )
6916 if ( !rDoc.GetRepeatRowRange( nTab ) ) // do not change existing area
6918 rDoc.SetRepeatRowRange( nTab, ScRange(0, 0, nTab, 0, 0, nTab) ); // enable
6921 else
6922 rDoc.SetRepeatRowRange( nTab, std::nullopt ); // disable
6924 PrintAreaUndo_Impl( std::move(pOldRanges) ); // undo, page breaks, modified etc.
6926 //! save last set area during switch off and recreate during switch on ???
6929 table::CellRangeAddress SAL_CALL ScTableSheetObj::getTitleRows()
6931 SolarMutexGuard aGuard;
6932 table::CellRangeAddress aRet;
6933 ScDocShell* pDocSh = GetDocShell();
6934 if ( pDocSh )
6936 ScDocument& rDoc = pDocSh->GetDocument();
6937 SCTAB nTab = GetTab_Impl();
6938 std::optional<ScRange> oRange = rDoc.GetRepeatRowRange(nTab);
6939 if (oRange)
6941 ScUnoConversion::FillApiRange( aRet, *oRange );
6942 aRet.Sheet = nTab; // core does not care about sheet index
6945 return aRet;
6948 void SAL_CALL ScTableSheetObj::setTitleRows( const table::CellRangeAddress& aTitleRows )
6950 SolarMutexGuard aGuard;
6951 ScDocShell* pDocSh = GetDocShell();
6952 if ( !pDocSh )
6953 return;
6955 ScDocument& rDoc = pDocSh->GetDocument();
6956 SCTAB nTab = GetTab_Impl();
6958 std::unique_ptr<ScPrintRangeSaver> pOldRanges = rDoc.CreatePrintRangeSaver();
6960 ScRange aNew;
6961 ScUnoConversion::FillScRange( aNew, aTitleRows );
6962 rDoc.SetRepeatRowRange( nTab, std::move(aNew) ); // also always enable
6964 PrintAreaUndo_Impl( std::move(pOldRanges) ); // Undo, page breaks, modified etc.
6967 // XSheetLinkable
6969 sheet::SheetLinkMode SAL_CALL ScTableSheetObj::getLinkMode()
6971 SolarMutexGuard aGuard;
6972 sheet::SheetLinkMode eRet = sheet::SheetLinkMode_NONE;
6973 ScDocShell* pDocSh = GetDocShell();
6974 if ( pDocSh )
6976 ScLinkMode nMode = pDocSh->GetDocument().GetLinkMode( GetTab_Impl() );
6977 if ( nMode == ScLinkMode::NORMAL )
6978 eRet = sheet::SheetLinkMode_NORMAL;
6979 else if ( nMode == ScLinkMode::VALUE )
6980 eRet = sheet::SheetLinkMode_VALUE;
6982 return eRet;
6985 void SAL_CALL ScTableSheetObj::setLinkMode( sheet::SheetLinkMode nLinkMode )
6987 SolarMutexGuard aGuard;
6989 //! search for filter and options in old link
6991 OUString aUrl(getLinkUrl());
6992 OUString aSheet(getLinkSheetName());
6994 link( aUrl, aSheet, u""_ustr, u""_ustr, nLinkMode );
6997 OUString SAL_CALL ScTableSheetObj::getLinkUrl()
6999 SolarMutexGuard aGuard;
7000 OUString aFile;
7001 ScDocShell* pDocSh = GetDocShell();
7002 if ( pDocSh )
7003 aFile = pDocSh->GetDocument().GetLinkDoc( GetTab_Impl() );
7004 return aFile;
7007 void SAL_CALL ScTableSheetObj::setLinkUrl( const OUString& aLinkUrl )
7009 SolarMutexGuard aGuard;
7011 //! search for filter and options in old link
7013 sheet::SheetLinkMode eMode = getLinkMode();
7014 OUString aSheet(getLinkSheetName());
7016 link( aLinkUrl, aSheet, u""_ustr, u""_ustr, eMode );
7019 OUString SAL_CALL ScTableSheetObj::getLinkSheetName()
7021 SolarMutexGuard aGuard;
7022 OUString aSheet;
7023 ScDocShell* pDocSh = GetDocShell();
7024 if ( pDocSh )
7025 aSheet = pDocSh->GetDocument().GetLinkTab( GetTab_Impl() );
7026 return aSheet;
7029 void SAL_CALL ScTableSheetObj::setLinkSheetName( const OUString& aLinkSheetName )
7031 SolarMutexGuard aGuard;
7033 //! search for filter and options in old link
7035 sheet::SheetLinkMode eMode = getLinkMode();
7036 OUString aUrl(getLinkUrl());
7038 link( aUrl, aLinkSheetName, u""_ustr, u""_ustr, eMode );
7041 void SAL_CALL ScTableSheetObj::link( const OUString& aUrl, const OUString& aSheetName,
7042 const OUString& aFilterName, const OUString& aFilterOptions,
7043 sheet::SheetLinkMode nMode )
7045 SolarMutexGuard aGuard;
7046 ScDocShell* pDocSh = GetDocShell();
7047 if ( !pDocSh )
7048 return;
7050 ScDocument& rDoc = pDocSh->GetDocument();
7051 SCTAB nTab = GetTab_Impl();
7053 OUString aFileString = aUrl;
7054 OUString aFilterString = aFilterName;
7055 OUString aOptString = aFilterOptions;
7057 aFileString = ScGlobal::GetAbsDocName( aFileString, pDocSh );
7058 if (aFilterString.isEmpty())
7059 ScDocumentLoader::GetFilterName( aFileString, aFilterString, aOptString, true, false );
7061 // remove application prefix from filter name here, so the filter options
7062 // aren't reset when the filter name is changed in ScTableLink::DataChanged
7063 ScDocumentLoader::RemoveAppPrefix( aFilterString );
7065 ScLinkMode nLinkMode = ScLinkMode::NONE;
7066 if ( nMode == sheet::SheetLinkMode_NORMAL )
7067 nLinkMode = ScLinkMode::NORMAL;
7068 else if ( nMode == sheet::SheetLinkMode_VALUE )
7069 nLinkMode = ScLinkMode::VALUE;
7071 rDoc.SetLink( nTab, nLinkMode, aFileString, aFilterString, aOptString, aSheetName, 0/*nRefresh*/ );
7073 pDocSh->UpdateLinks(); // if needed add or delete link
7074 SfxBindings* pBindings = pDocSh->GetViewBindings();
7075 if (pBindings)
7076 pBindings->Invalidate(SID_LINKS);
7078 //! undo of link data on the table
7080 if ( !(nLinkMode != ScLinkMode::NONE && rDoc.IsExecuteLinkEnabled()) ) // update link
7081 return;
7083 // Always update link also if already exists
7084 //! update only on the affected table???
7086 sfx2::LinkManager* pLinkManager = rDoc.GetLinkManager();
7087 sal_uInt16 nCount = pLinkManager->GetLinks().size();
7088 for ( sal_uInt16 i=0; i<nCount; i++ )
7090 ::sfx2::SvBaseLink* pBase = pLinkManager->GetLinks()[i].get();
7091 if (auto pTabLink = dynamic_cast<ScTableLink*>( pBase))
7093 if ( aFileString == pTabLink->GetFileName() )
7094 pTabLink->Update(); // include Paint&Undo
7096 //! The file name should only exists once (?)
7100 //! notify ScSheetLinkObj objects!!!
7103 // XSheetAuditing
7105 sal_Bool SAL_CALL ScTableSheetObj::hideDependents( const table::CellAddress& aPosition )
7107 SolarMutexGuard aGuard;
7108 ScDocShell* pDocSh = GetDocShell();
7109 if ( pDocSh )
7111 SCTAB nTab = GetTab_Impl();
7112 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" );
7113 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab );
7114 return pDocSh->GetDocFunc().DetectiveDelSucc( aPos );
7116 return false;
7119 sal_Bool SAL_CALL ScTableSheetObj::hidePrecedents( const table::CellAddress& aPosition )
7121 SolarMutexGuard aGuard;
7122 ScDocShell* pDocSh = GetDocShell();
7123 if ( pDocSh )
7125 SCTAB nTab = GetTab_Impl();
7126 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" );
7127 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab );
7128 return pDocSh->GetDocFunc().DetectiveDelPred( aPos );
7130 return false;
7133 sal_Bool SAL_CALL ScTableSheetObj::showDependents( const table::CellAddress& aPosition )
7135 SolarMutexGuard aGuard;
7136 ScDocShell* pDocSh = GetDocShell();
7137 if ( pDocSh )
7139 SCTAB nTab = GetTab_Impl();
7140 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" );
7141 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab );
7142 return pDocSh->GetDocFunc().DetectiveAddSucc( aPos );
7144 return false;
7147 sal_Bool SAL_CALL ScTableSheetObj::showPrecedents( const table::CellAddress& aPosition )
7149 SolarMutexGuard aGuard;
7150 ScDocShell* pDocSh = GetDocShell();
7151 if ( pDocSh )
7153 SCTAB nTab = GetTab_Impl();
7154 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" );
7155 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab );
7156 return pDocSh->GetDocFunc().DetectiveAddPred( aPos );
7158 return false;
7161 sal_Bool SAL_CALL ScTableSheetObj::showErrors( const table::CellAddress& aPosition )
7163 SolarMutexGuard aGuard;
7164 ScDocShell* pDocSh = GetDocShell();
7165 if ( pDocSh )
7167 SCTAB nTab = GetTab_Impl();
7168 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" );
7169 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab );
7170 return pDocSh->GetDocFunc().DetectiveAddError( aPos );
7172 return false;
7175 sal_Bool SAL_CALL ScTableSheetObj::showInvalid()
7177 SolarMutexGuard aGuard;
7178 ScDocShell* pDocSh = GetDocShell();
7179 if ( pDocSh )
7180 return pDocSh->GetDocFunc().DetectiveMarkInvalid( GetTab_Impl() );
7181 return false;
7184 void SAL_CALL ScTableSheetObj::clearArrows()
7186 SolarMutexGuard aGuard;
7187 ScDocShell* pDocSh = GetDocShell();
7188 if ( pDocSh )
7189 pDocSh->GetDocFunc().DetectiveDelAll( GetTab_Impl() );
7192 // XSheetOutline
7194 void SAL_CALL ScTableSheetObj::group( const table::CellRangeAddress& rGroupRange,
7195 table::TableOrientation nOrientation )
7197 SolarMutexGuard aGuard;
7198 ScDocShell* pDocSh = GetDocShell();
7199 if ( pDocSh )
7201 bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
7202 ScRange aGroupRange;
7203 ScUnoConversion::FillScRange( aGroupRange, rGroupRange );
7204 ScOutlineDocFunc aFunc(*pDocSh);
7205 aFunc.MakeOutline( aGroupRange, bColumns, true, true );
7209 void SAL_CALL ScTableSheetObj::ungroup( const table::CellRangeAddress& rGroupRange,
7210 table::TableOrientation nOrientation )
7212 SolarMutexGuard aGuard;
7213 ScDocShell* pDocSh = GetDocShell();
7214 if ( pDocSh )
7216 bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
7217 ScRange aGroupRange;
7218 ScUnoConversion::FillScRange( aGroupRange, rGroupRange );
7219 ScOutlineDocFunc aFunc(*pDocSh);
7220 aFunc.RemoveOutline( aGroupRange, bColumns, true, true );
7224 void SAL_CALL ScTableSheetObj::autoOutline( const table::CellRangeAddress& rCellRange )
7226 SolarMutexGuard aGuard;
7227 ScDocShell* pDocSh = GetDocShell();
7228 if ( pDocSh )
7230 ScRange aFormulaRange;
7231 ScUnoConversion::FillScRange( aFormulaRange, rCellRange );
7232 ScOutlineDocFunc aFunc(*pDocSh);
7233 aFunc.AutoOutline( aFormulaRange, true );
7237 void SAL_CALL ScTableSheetObj::clearOutline()
7239 SolarMutexGuard aGuard;
7240 ScDocShell* pDocSh = GetDocShell();
7241 if ( pDocSh )
7243 SCTAB nTab = GetTab_Impl();
7244 ScOutlineDocFunc aFunc(*pDocSh);
7245 aFunc.RemoveAllOutlines( nTab, true );
7249 void SAL_CALL ScTableSheetObj::hideDetail( const table::CellRangeAddress& rCellRange )
7251 SolarMutexGuard aGuard;
7252 ScDocShell* pDocSh = GetDocShell();
7253 if ( pDocSh )
7255 ScRange aMarkRange;
7256 ScUnoConversion::FillScRange( aMarkRange, rCellRange );
7257 ScOutlineDocFunc aFunc(*pDocSh);
7258 aFunc.HideMarkedOutlines( aMarkRange, true );
7262 void SAL_CALL ScTableSheetObj::showDetail( const table::CellRangeAddress& rCellRange )
7264 SolarMutexGuard aGuard;
7265 ScDocShell* pDocSh = GetDocShell();
7266 if ( pDocSh )
7268 ScRange aMarkRange;
7269 ScUnoConversion::FillScRange( aMarkRange, rCellRange );
7270 ScOutlineDocFunc aFunc(*pDocSh);
7271 aFunc.ShowMarkedOutlines( aMarkRange, true );
7275 void SAL_CALL ScTableSheetObj::showLevel( sal_Int16 nLevel, table::TableOrientation nOrientation )
7277 SolarMutexGuard aGuard;
7278 ScDocShell* pDocSh = GetDocShell();
7279 if ( pDocSh )
7281 bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS );
7282 SCTAB nTab = GetTab_Impl();
7283 ScOutlineDocFunc aFunc(*pDocSh);
7284 aFunc.SelectLevel( nTab, bColumns, nLevel, true, true );
7288 // XProtectable
7290 void SAL_CALL ScTableSheetObj::protect( const OUString& aPassword )
7292 SolarMutexGuard aGuard;
7293 ScDocShell* pDocSh = GetDocShell();
7294 // #i108245# if already protected, don't change anything
7295 if ( pDocSh && !pDocSh->GetDocument().IsTabProtected( GetTab_Impl() ) )
7297 pDocSh->GetDocFunc().Protect( GetTab_Impl(), aPassword );
7301 void SAL_CALL ScTableSheetObj::unprotect( const OUString& aPassword )
7303 SolarMutexGuard aGuard;
7304 ScDocShell* pDocSh = GetDocShell();
7305 if ( pDocSh )
7307 bool bDone = pDocSh->GetDocFunc().Unprotect( GetTab_Impl(), aPassword, true );
7308 if (!bDone)
7309 throw lang::IllegalArgumentException();
7313 sal_Bool SAL_CALL ScTableSheetObj::isProtected()
7315 SolarMutexGuard aGuard;
7316 ScDocShell* pDocSh = GetDocShell();
7317 if ( pDocSh )
7318 return pDocSh->GetDocument().IsTabProtected( GetTab_Impl() );
7320 OSL_FAIL("no DocShell"); //! Exception or so?
7321 return false;
7324 // XScenario
7326 sal_Bool SAL_CALL ScTableSheetObj::getIsScenario()
7328 SolarMutexGuard aGuard;
7329 ScDocShell* pDocSh = GetDocShell();
7330 if ( pDocSh )
7331 return pDocSh->GetDocument().IsScenario( GetTab_Impl() );
7333 return false;
7336 OUString SAL_CALL ScTableSheetObj::getScenarioComment()
7338 SolarMutexGuard aGuard;
7339 ScDocShell* pDocSh = GetDocShell();
7340 if ( pDocSh )
7342 OUString aComment;
7343 Color aColor;
7344 ScScenarioFlags nFlags;
7345 pDocSh->GetDocument().GetScenarioData( GetTab_Impl(), aComment, aColor, nFlags );
7346 return aComment;
7348 return OUString();
7351 void SAL_CALL ScTableSheetObj::setScenarioComment( const OUString& aScenarioComment )
7353 SolarMutexGuard aGuard;
7354 ScDocShell* pDocSh = GetDocShell();
7355 if ( !pDocSh )
7356 return;
7358 ScDocument& rDoc = pDocSh->GetDocument();
7359 SCTAB nTab = GetTab_Impl();
7361 OUString aName;
7362 OUString aComment;
7363 Color aColor;
7364 ScScenarioFlags nFlags;
7365 rDoc.GetName( nTab, aName );
7366 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags );
7368 aComment = aScenarioComment;
7370 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
7373 void SAL_CALL ScTableSheetObj::addRanges( const uno::Sequence<table::CellRangeAddress>& rScenRanges )
7375 SolarMutexGuard aGuard;
7376 ScDocShell* pDocSh = GetDocShell();
7377 if ( !pDocSh )
7378 return;
7380 ScDocument& rDoc = pDocSh->GetDocument();
7381 SCTAB nTab = GetTab_Impl();
7383 if (!rDoc.IsScenario(nTab))
7384 return;
7386 ScMarkData aMarkData(rDoc.GetSheetLimits());
7387 aMarkData.SelectTable( nTab, true );
7389 for (const table::CellRangeAddress& rRange : rScenRanges)
7391 OSL_ENSURE( rRange.Sheet == nTab, "addRanges with wrong Tab" );
7392 ScRange aOneRange( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), nTab,
7393 static_cast<SCCOL>(rRange.EndColumn), static_cast<SCROW>(rRange.EndRow), nTab );
7395 aMarkData.SetMultiMarkArea( aOneRange );
7398 // Scenario ranges are tagged with attribute
7399 ScPatternAttr aPattern(rDoc.getCellAttributeHelper());
7400 aPattern.GetItemSet().Put( ScMergeFlagAttr( ScMF::Scenario ) );
7401 aPattern.GetItemSet().Put( ScProtectionAttr( true ) );
7402 pDocSh->GetDocFunc().ApplyAttributes( aMarkData, aPattern, true );
7405 void SAL_CALL ScTableSheetObj::apply()
7407 SolarMutexGuard aGuard;
7408 ScDocShell* pDocSh = GetDocShell();
7409 if ( !pDocSh )
7410 return;
7412 ScDocument& rDoc = pDocSh->GetDocument();
7413 SCTAB nTab = GetTab_Impl();
7414 OUString aName;
7415 rDoc.GetName( nTab, aName ); // scenario name
7417 SCTAB nDestTab = nTab;
7418 while ( nDestTab > 0 && rDoc.IsScenario(nDestTab) )
7419 --nDestTab;
7421 if ( !rDoc.IsScenario(nDestTab) )
7422 pDocSh->UseScenario( nDestTab, aName );
7424 //! otherwise error or so
7427 // XScenarioEnhanced
7429 uno::Sequence< table::CellRangeAddress > SAL_CALL ScTableSheetObj::getRanges( )
7431 SolarMutexGuard aGuard;
7432 ScDocShell* pDocSh = GetDocShell();
7433 if ( pDocSh )
7435 ScDocument& rDoc = pDocSh->GetDocument();
7436 SCTAB nTab = GetTab_Impl();
7437 const ScRangeList* pRangeList = rDoc.GetScenarioRanges(nTab);
7438 if (pRangeList)
7440 size_t nCount = pRangeList->size();
7441 uno::Sequence< table::CellRangeAddress > aRetRanges( nCount );
7442 table::CellRangeAddress* pAry = aRetRanges.getArray();
7443 for( size_t nIndex = 0; nIndex < nCount; nIndex++ )
7445 const ScRange & rRange = (*pRangeList)[nIndex];
7446 pAry->StartColumn = rRange.aStart.Col();
7447 pAry->StartRow = rRange.aStart.Row();
7448 pAry->EndColumn = rRange.aEnd.Col();
7449 pAry->EndRow = rRange.aEnd.Row();
7450 pAry->Sheet = rRange.aStart.Tab();
7451 ++pAry;
7453 return aRetRanges;
7456 return uno::Sequence< table::CellRangeAddress > ();
7459 // XExternalSheetName
7461 void ScTableSheetObj::setExternalName( const OUString& aUrl, const OUString& aSheetName )
7463 SolarMutexGuard aGuard;
7464 ScDocShell* pDocSh = GetDocShell();
7465 if ( pDocSh )
7467 ScDocument& rDoc = pDocSh->GetDocument();
7468 const SCTAB nTab = GetTab_Impl();
7469 const OUString aAbsDocName( ScGlobal::GetAbsDocName( aUrl, pDocSh ) );
7470 const OUString aDocTabName( ScGlobal::GetDocTabName( aAbsDocName, aSheetName ) );
7471 if ( !rDoc.RenameTab( nTab, aDocTabName, true /*bExternalDocument*/ ) )
7473 throw container::ElementExistException( OUString(), *this );
7478 // XEventsSupplier
7480 uno::Reference<container::XNameReplace> SAL_CALL ScTableSheetObj::getEvents()
7482 SolarMutexGuard aGuard;
7483 ScDocShell* pDocSh = GetDocShell();
7484 if ( pDocSh )
7485 return new ScSheetEventsObj( pDocSh, GetTab_Impl() );
7487 return nullptr;
7490 // XPropertySet extended for Sheet-Properties
7492 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableSheetObj::getPropertySetInfo()
7494 SolarMutexGuard aGuard;
7495 static uno::Reference<beans::XPropertySetInfo> aRef(
7496 new SfxItemPropertySetInfo( pSheetPropSet->getPropertyMap() ));
7497 return aRef;
7500 void ScTableSheetObj::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue )
7502 if ( !pEntry )
7503 return;
7505 if ( IsScItemWid( pEntry->nWID ) )
7507 // for Item WIDs, call ScCellRangesBase directly
7508 ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
7509 return;
7512 // own properties
7514 ScDocShell* pDocSh = GetDocShell();
7515 if (!pDocSh)
7516 return; //! Exception or so?
7517 ScDocument& rDoc = pDocSh->GetDocument();
7518 SCTAB nTab = GetTab_Impl();
7519 ScDocFunc &rFunc = pDocSh->GetDocFunc();
7521 if ( pEntry->nWID == SC_WID_UNO_PAGESTL )
7523 OUString aStrVal;
7524 aValue >>= aStrVal;
7525 OUString aNewStr(ScStyleNameConversion::ProgrammaticToDisplayName(
7526 aStrVal, SfxStyleFamily::Page ));
7528 //! Undo? (also if SID_STYLE_APPLY on View)
7530 if ( rDoc.GetPageStyle( nTab ) != aNewStr )
7532 rDoc.SetPageStyle( nTab, aNewStr );
7533 if (!rDoc.IsImportingXML())
7535 ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
7537 SfxBindings* pBindings = pDocSh->GetViewBindings();
7538 if (pBindings)
7540 pBindings->Invalidate( SID_STYLE_FAMILY4 );
7541 pBindings->Invalidate( SID_STATUS_PAGESTYLE );
7542 pBindings->Invalidate( FID_RESET_PRINTZOOM );
7543 pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
7544 pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
7547 pDocSh->SetDocumentModified();
7550 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
7552 bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
7553 rFunc.SetTableVisible( nTab, bVis, true );
7555 else if ( pEntry->nWID == SC_WID_UNO_ISACTIVE )
7557 if (rDoc.IsScenario(nTab))
7558 rDoc.SetActiveScenario( nTab, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
7560 else if ( pEntry->nWID == SC_WID_UNO_BORDCOL )
7562 if (rDoc.IsScenario(nTab))
7564 Color aColor;
7565 if (aValue >>= aColor)
7567 OUString aName;
7568 OUString aComment;
7569 ScScenarioFlags nFlags;
7570 Color aTmp;
7571 rDoc.GetName( nTab, aName );
7572 rDoc.GetScenarioData( nTab, aComment, aTmp, nFlags );
7574 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
7578 else if ( pEntry->nWID == SC_WID_UNO_PROTECT )
7580 if (rDoc.IsScenario(nTab))
7582 OUString aName;
7583 OUString aComment;
7584 Color aColor;
7585 ScScenarioFlags nFlags;
7586 rDoc.GetName( nTab, aName );
7587 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags );
7588 bool bModify(false);
7590 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
7592 if (!(nFlags & ScScenarioFlags::Protected))
7594 nFlags |= ScScenarioFlags::Protected;
7595 bModify = true;
7598 else
7600 if (nFlags & ScScenarioFlags::Protected)
7602 nFlags &= ~ScScenarioFlags::Protected;
7603 bModify = true;
7607 if (bModify)
7608 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
7611 else if ( pEntry->nWID == SC_WID_UNO_SHOWBORD )
7613 if (rDoc.IsScenario(nTab))
7615 OUString aName;
7616 OUString aComment;
7617 Color aColor;
7618 ScScenarioFlags nFlags;
7619 rDoc.GetName( nTab, aName );
7620 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags );
7621 bool bModify(false);
7623 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
7625 if (!(nFlags & ScScenarioFlags::ShowFrame))
7627 nFlags |= ScScenarioFlags::ShowFrame;
7628 bModify = true;
7631 else
7633 if (nFlags & ScScenarioFlags::ShowFrame)
7635 nFlags &= ~ScScenarioFlags::ShowFrame;
7636 bModify = true;
7640 if (bModify)
7641 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
7644 else if ( pEntry->nWID == SC_WID_UNO_PRINTBORD )
7646 if (rDoc.IsScenario(nTab))
7648 OUString aName;
7649 OUString aComment;
7650 Color aColor;
7651 ScScenarioFlags nFlags;
7652 rDoc.GetName( nTab, aName );
7653 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags );
7654 bool bModify(false);
7656 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
7658 if (!(nFlags & ScScenarioFlags::PrintFrame))
7660 nFlags |= ScScenarioFlags::PrintFrame;
7661 bModify = true;
7664 else
7666 if (nFlags & ScScenarioFlags::PrintFrame)
7668 nFlags &= ~ScScenarioFlags::PrintFrame;
7669 bModify = true;
7673 if (bModify)
7674 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
7677 else if ( pEntry->nWID == SC_WID_UNO_COPYBACK )
7679 if (rDoc.IsScenario(nTab))
7681 OUString aName;
7682 OUString aComment;
7683 Color aColor;
7684 ScScenarioFlags nFlags;
7685 rDoc.GetName( nTab, aName );
7686 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags );
7687 bool bModify(false);
7689 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
7691 if (!(nFlags & ScScenarioFlags::TwoWay))
7693 nFlags |= ScScenarioFlags::TwoWay;
7694 bModify = true;
7697 else
7699 if (nFlags & ScScenarioFlags::TwoWay)
7701 nFlags &= ~ScScenarioFlags::TwoWay;
7702 bModify = true;
7706 if (bModify)
7707 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
7710 else if ( pEntry->nWID == SC_WID_UNO_COPYSTYL )
7712 if (rDoc.IsScenario(nTab))
7714 OUString aName;
7715 OUString aComment;
7716 Color aColor;
7717 ScScenarioFlags nFlags;
7718 rDoc.GetName( nTab, aName );
7719 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags );
7720 bool bModify(false);
7722 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
7724 if (!(nFlags & ScScenarioFlags::Attrib))
7726 nFlags |= ScScenarioFlags::Attrib;
7727 bModify = true;
7730 else
7732 if (nFlags & ScScenarioFlags::Attrib)
7734 nFlags &= ~ScScenarioFlags::Attrib;
7735 bModify = true;
7739 if (bModify)
7740 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
7743 else if ( pEntry->nWID == SC_WID_UNO_COPYFORM )
7745 if (rDoc.IsScenario(nTab))
7747 OUString aName;
7748 OUString aComment;
7749 Color aColor;
7750 ScScenarioFlags nFlags;
7751 rDoc.GetName( nTab, aName );
7752 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags );
7753 bool bModify(false);
7755 if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
7757 if (nFlags & ScScenarioFlags::Value)
7759 nFlags &= ~ScScenarioFlags::Value;
7760 bModify = true;
7763 else
7765 if (!(nFlags & ScScenarioFlags::Value))
7767 nFlags |= ScScenarioFlags::Value;
7768 bModify = true;
7772 if (bModify)
7773 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags );
7776 else if ( pEntry->nWID == SC_WID_UNO_TABLAYOUT )
7778 sal_Int16 nValue = 0;
7779 if (aValue >>= nValue)
7781 if (nValue == css::text::WritingMode2::RL_TB)
7782 rFunc.SetLayoutRTL(nTab, true);
7783 else
7784 rFunc.SetLayoutRTL(nTab, false);
7787 else if ( pEntry->nWID == SC_WID_UNO_AUTOPRINT )
7789 bool bAutoPrint = ScUnoHelpFunctions::GetBoolFromAny( aValue );
7790 if (bAutoPrint)
7791 rDoc.SetPrintEntireSheet( nTab ); // clears all print ranges
7792 else
7794 if (rDoc.IsPrintEntireSheet( nTab ))
7795 rDoc.ClearPrintRanges( nTab ); // if this flag is true, there are no PrintRanges, so Clear clears only the flag.
7798 else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR )
7800 Color aColor = COL_AUTO;
7801 if ( aValue >>= aColor )
7803 if ( rDoc.GetTabBgColor( nTab ) != aColor )
7804 rFunc.SetTabBgColor( nTab, aColor, true, true );
7807 else if ( pEntry->nWID == SC_WID_UNO_CODENAME )
7809 OUString aCodeName;
7810 if (aValue >>= aCodeName)
7812 pDocSh->GetDocument().SetCodeName( GetTab_Impl(), aCodeName );
7815 else if (pEntry->nWID == SC_WID_UNO_CONDFORMAT)
7817 uno::Reference<sheet::XConditionalFormats> xCondFormat;
7818 if (aValue >>= xCondFormat)
7820 // how to set the format correctly
7823 else if (pEntry->nWID == SC_WID_UNO_TOTALBELOW)
7825 bool bTotalsRowBelow = ScUnoHelpFunctions::GetBoolFromAny(aValue);
7826 rDoc.SetTotalsRowBelow(nTab, bTotalsRowBelow);
7828 else
7829 ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID
7832 void ScTableSheetObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry,
7833 uno::Any& rAny )
7835 if ( !pEntry )
7836 return;
7838 ScDocShell* pDocSh = GetDocShell();
7839 if (!pDocSh)
7840 throw uno::RuntimeException();
7841 ScDocument& rDoc = pDocSh->GetDocument();
7842 SCTAB nTab = GetTab_Impl();
7844 if ( pEntry->nWID == SC_WID_UNO_NAMES )
7846 rAny <<= uno::Reference<sheet::XNamedRanges>(new ScLocalNamedRangesObj(pDocSh, this));
7848 else if ( pEntry->nWID == SC_WID_UNO_PAGESTL )
7850 rAny <<= ScStyleNameConversion::DisplayToProgrammaticName(
7851 rDoc.GetPageStyle( nTab ), SfxStyleFamily::Page );
7853 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
7855 bool bVis = rDoc.IsVisible( nTab );
7856 rAny <<= bVis;
7858 else if ( pEntry->nWID == SC_WID_UNO_LINKDISPBIT )
7860 // no target bitmaps for individual entries (would be all equal)
7861 // ScLinkTargetTypeObj::SetLinkTargetBitmap( aAny, SC_LINKTARGETTYPE_SHEET );
7863 else if ( pEntry->nWID == SC_WID_UNO_LINKDISPNAME )
7865 // LinkDisplayName for hyperlink dialog
7866 rAny <<= getName(); // sheet name
7868 else if ( pEntry->nWID == SC_WID_UNO_ISACTIVE )
7870 if (rDoc.IsScenario(nTab))
7871 rAny <<= rDoc.IsActiveScenario( nTab );
7873 else if ( pEntry->nWID == SC_WID_UNO_BORDCOL )
7875 if (rDoc.IsScenario(nTab))
7877 OUString aComment;
7878 Color aColor;
7879 ScScenarioFlags nFlags;
7880 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags );
7882 rAny <<= aColor;
7885 else if ( pEntry->nWID == SC_WID_UNO_PROTECT )
7887 if (rDoc.IsScenario(nTab))
7889 ScScenarioFlags nFlags;
7890 rDoc.GetScenarioFlags(nTab, nFlags);
7892 rAny <<= ((nFlags & ScScenarioFlags::Protected) != ScScenarioFlags::NONE);
7895 else if ( pEntry->nWID == SC_WID_UNO_SHOWBORD )
7897 if (rDoc.IsScenario(nTab))
7899 ScScenarioFlags nFlags;
7900 rDoc.GetScenarioFlags(nTab, nFlags);
7902 rAny <<= ((nFlags & ScScenarioFlags::ShowFrame) != ScScenarioFlags::NONE);
7905 else if ( pEntry->nWID == SC_WID_UNO_PRINTBORD )
7907 if (rDoc.IsScenario(nTab))
7909 ScScenarioFlags nFlags;
7910 rDoc.GetScenarioFlags(nTab, nFlags);
7912 rAny <<= ((nFlags & ScScenarioFlags::PrintFrame) != ScScenarioFlags::NONE);
7915 else if ( pEntry->nWID == SC_WID_UNO_COPYBACK )
7917 if (rDoc.IsScenario(nTab))
7919 ScScenarioFlags nFlags;
7920 rDoc.GetScenarioFlags(nTab, nFlags);
7922 rAny <<= ((nFlags & ScScenarioFlags::TwoWay) != ScScenarioFlags::NONE);
7925 else if ( pEntry->nWID == SC_WID_UNO_COPYSTYL )
7927 if (rDoc.IsScenario(nTab))
7929 ScScenarioFlags nFlags;
7930 rDoc.GetScenarioFlags(nTab, nFlags);
7932 rAny <<= ((nFlags & ScScenarioFlags::Attrib) != ScScenarioFlags::NONE);
7935 else if ( pEntry->nWID == SC_WID_UNO_COPYFORM )
7937 if (rDoc.IsScenario(nTab))
7939 ScScenarioFlags nFlags;
7940 rDoc.GetScenarioFlags(nTab, nFlags);
7942 rAny <<= !(nFlags & ScScenarioFlags::Value);
7945 else if ( pEntry->nWID == SC_WID_UNO_TABLAYOUT )
7947 if (rDoc.IsLayoutRTL(nTab))
7948 rAny <<= sal_Int16(css::text::WritingMode2::RL_TB);
7949 else
7950 rAny <<= sal_Int16(css::text::WritingMode2::LR_TB);
7952 else if ( pEntry->nWID == SC_WID_UNO_AUTOPRINT )
7954 bool bAutoPrint = rDoc.IsPrintEntireSheet( nTab );
7955 rAny <<= bAutoPrint;
7957 else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR )
7959 rAny <<= rDoc.GetTabBgColor(nTab);
7961 else if ( pEntry->nWID == SC_WID_UNO_CODENAME )
7963 OUString aCodeName;
7964 pDocSh->GetDocument().GetCodeName(GetTab_Impl(), aCodeName);
7965 rAny <<= aCodeName;
7967 else if (pEntry->nWID == SC_WID_UNO_CONDFORMAT)
7969 rAny <<= uno::Reference<sheet::XConditionalFormats>(new ScCondFormatsObj(pDocSh, nTab));
7971 else if (pEntry->nWID == SC_WID_UNO_SOLVERSETTINGS)
7973 rAny <<= uno::Reference<sheet::XSolverSettings>(new ScSolverSettings(pDocSh, this));
7975 else
7976 ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
7979 const SfxItemPropertyMap& ScTableSheetObj::GetItemPropertyMap()
7981 return pSheetPropSet->getPropertyMap();
7984 // XServiceInfo
7986 OUString SAL_CALL ScTableSheetObj::getImplementationName()
7988 return u"ScTableSheetObj"_ustr;
7991 sal_Bool SAL_CALL ScTableSheetObj::supportsService( const OUString& rServiceName )
7993 return cppu::supportsService(this, rServiceName);
7996 uno::Sequence<OUString> SAL_CALL ScTableSheetObj::getSupportedServiceNames()
7998 return {SCSPREADSHEET_SERVICE,
7999 SCSHEETCELLRANGE_SERVICE,
8000 SCCELLRANGE_SERVICE,
8001 SCCELLPROPERTIES_SERVICE,
8002 SCCHARPROPERTIES_SERVICE,
8003 SCPARAPROPERTIES_SERVICE,
8004 SCLINKTARGET_SERVICE};
8007 ScTableColumnObj::ScTableColumnObj( ScDocShell* pDocSh, SCCOL nCol, SCTAB nTab ) :
8008 ScTableColumnObj_BASE( pDocSh, ScRange(nCol,0,nTab, nCol, pDocSh->GetDocument().MaxRow(),nTab) ),
8009 pColPropSet(lcl_GetColumnPropertySet())
8013 ScTableColumnObj::~ScTableColumnObj()
8017 // XNamed
8019 OUString SAL_CALL ScTableColumnObj::getName()
8021 SolarMutexGuard aGuard;
8023 const ScRange& rRange = GetRange();
8024 OSL_ENSURE(rRange.aStart.Col() == rRange.aEnd.Col(), "too many columns");
8025 SCCOL nCol = rRange.aStart.Col();
8027 return ScColToAlpha( nCol ); // from global.hxx
8030 void SAL_CALL ScTableColumnObj::setName( const OUString& /* aNewName */ )
8032 throw uno::RuntimeException(); // read-only
8035 // XPropertySet extended for Column-Properties
8037 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnObj::getPropertySetInfo()
8039 SolarMutexGuard aGuard;
8040 static uno::Reference<beans::XPropertySetInfo> aRef(
8041 new SfxItemPropertySetInfo( pColPropSet->getPropertyMap() ));
8042 return aRef;
8045 void ScTableColumnObj::SetOnePropertyValue(const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue)
8047 if ( !pEntry )
8048 return;
8050 if ( IsScItemWid( pEntry->nWID ) )
8052 // for Item WIDs, call ScCellRangesBase directly
8053 ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
8054 return;
8057 // own properties
8059 ScDocShell* pDocSh = GetDocShell();
8060 if (!pDocSh)
8061 return; //! Exception or so?
8062 const ScRange& rRange = GetRange();
8063 OSL_ENSURE(rRange.aStart.Col() == rRange.aEnd.Col(), "Too many columns");
8064 SCCOL nCol = rRange.aStart.Col();
8065 SCTAB nTab = rRange.aStart.Tab();
8066 ScDocFunc &rFunc = pDocSh->GetDocFunc();
8068 std::vector<sc::ColRowSpan> aColArr(1, sc::ColRowSpan(nCol,nCol));
8070 if ( pEntry->nWID == SC_WID_UNO_CELLWID )
8072 sal_Int32 nNewWidth = 0;
8073 if ( aValue >>= nNewWidth )
8075 // property is 1/100mm, column width is twips
8076 nNewWidth = o3tl::toTwips(nNewWidth, o3tl::Length::mm100);
8077 rFunc.SetWidthOrHeight(
8078 true, aColArr, nTab, SC_SIZE_ORIGINAL, nNewWidth, true, true);
8081 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
8083 bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8084 ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
8085 rFunc.SetWidthOrHeight(true, aColArr, nTab, eMode, 0, true, true);
8086 // SC_SIZE_DIRECT with size 0 will hide
8088 else if ( pEntry->nWID == SC_WID_UNO_OWIDTH )
8090 bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8091 if (bOpt)
8092 rFunc.SetWidthOrHeight(
8093 true, aColArr, nTab, SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, true, true);
8094 // sal_False on columns currently without effect
8096 else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE || pEntry->nWID == SC_WID_UNO_MANPAGE )
8098 bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8099 if (bSet)
8100 rFunc.InsertPageBreak( true, rRange.aStart, true, true );
8101 else
8102 rFunc.RemovePageBreak( true, rRange.aStart, true, true );
8104 else
8105 ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID
8108 void ScTableColumnObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny )
8110 if ( !pEntry )
8111 return;
8113 ScDocShell* pDocSh = GetDocShell();
8114 if (!pDocSh)
8115 throw uno::RuntimeException();
8117 ScDocument& rDoc = pDocSh->GetDocument();
8118 const ScRange& rRange = GetRange();
8119 OSL_ENSURE(rRange.aStart.Col() == rRange.aEnd.Col(), "too many columns");
8120 SCCOL nCol = rRange.aStart.Col();
8121 SCTAB nTab = rRange.aStart.Tab();
8123 if ( pEntry->nWID == SC_WID_UNO_CELLWID )
8125 // for hidden column, return original height
8126 sal_uInt16 nWidth = rDoc.GetOriginalWidth( nCol, nTab );
8127 // property is 1/100mm, column width is twips
8128 rAny <<= static_cast<sal_Int32>(convertTwipToMm100(nWidth));
8130 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
8132 bool bHidden = rDoc.ColHidden(nCol, nTab);
8133 rAny <<= !bHidden;
8135 else if ( pEntry->nWID == SC_WID_UNO_OWIDTH )
8137 //! at the moment always set ??!?!
8138 bool bOpt = !(rDoc.GetColFlags( nCol, nTab ) & CRFlags::ManualSize);
8139 rAny <<= bOpt;
8141 else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE )
8143 ScBreakType nBreak = rDoc.HasColBreak(nCol, nTab);
8144 rAny <<= nBreak != ScBreakType::NONE;
8146 else if ( pEntry->nWID == SC_WID_UNO_MANPAGE )
8148 ScBreakType nBreak = rDoc.HasColBreak(nCol, nTab);
8149 rAny <<= bool(nBreak & ScBreakType::Manual);
8151 else
8152 ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
8155 const SfxItemPropertyMap& ScTableColumnObj::GetItemPropertyMap()
8157 return pColPropSet->getPropertyMap();
8160 ScTableRowObj::ScTableRowObj(ScDocShell* pDocSh, SCROW nRow, SCTAB nTab) :
8161 ScCellRangeObj( pDocSh, ScRange(0,nRow,nTab, pDocSh->GetDocument().MaxCol(),nRow,nTab) ),
8162 pRowPropSet(lcl_GetRowPropertySet())
8166 ScTableRowObj::~ScTableRowObj()
8170 // XPropertySet extended for Row-Properties
8172 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowObj::getPropertySetInfo()
8174 SolarMutexGuard aGuard;
8175 static uno::Reference<beans::XPropertySetInfo> aRef(
8176 new SfxItemPropertySetInfo( pRowPropSet->getPropertyMap() ));
8177 return aRef;
8180 void ScTableRowObj::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue )
8182 if ( !pEntry )
8183 return;
8185 if ( IsScItemWid( pEntry->nWID ) )
8187 // for Item WIDs, call ScCellRangesBase directly
8188 ScCellRangesBase::SetOnePropertyValue(pEntry, aValue);
8189 return;
8192 // own properties
8194 ScDocShell* pDocSh = GetDocShell();
8195 if (!pDocSh)
8196 return; //! Exception or so?
8197 ScDocument& rDoc = pDocSh->GetDocument();
8198 const ScRange& rRange = GetRange();
8199 OSL_ENSURE(rRange.aStart.Row() == rRange.aEnd.Row(), "too many rows");
8200 SCROW nRow = rRange.aStart.Row();
8201 SCTAB nTab = rRange.aStart.Tab();
8202 ScDocFunc &rFunc = pDocSh->GetDocFunc();
8204 std::vector<sc::ColRowSpan> aRowArr(1, sc::ColRowSpan(nRow,nRow));
8206 if ( pEntry->nWID == SC_WID_UNO_CELLHGT )
8208 sal_Int32 nNewHeight = 0;
8209 if ( aValue >>= nNewHeight )
8211 // property is 1/100mm, row height is twips
8212 nNewHeight = o3tl::toTwips(nNewHeight, o3tl::Length::mm100);
8213 rFunc.SetWidthOrHeight(
8214 false, aRowArr, nTab, SC_SIZE_ORIGINAL, nNewHeight, true, true);
8217 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
8219 bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8220 ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
8221 rFunc.SetWidthOrHeight(false, aRowArr, nTab, eMode, 0, true, true);
8222 // SC_SIZE_DIRECT with size zero will hide
8224 else if ( pEntry->nWID == SC_WID_UNO_CELLFILT )
8226 bool bFil = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8227 // SC_SIZE_DIRECT with size zero will hide
8228 rDoc.SetRowFiltered(nRow, nRow, nTab, bFil);
8230 else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT )
8232 bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8233 if (bOpt)
8234 rFunc.SetWidthOrHeight(false, aRowArr, nTab, SC_SIZE_OPTIMAL, 0, true, true);
8235 else
8237 // set current height again manually
8238 sal_uInt16 nHeight = rDoc.GetOriginalHeight( nRow, nTab );
8239 rFunc.SetWidthOrHeight(false, aRowArr, nTab, SC_SIZE_ORIGINAL, nHeight, true, true);
8242 else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE || pEntry->nWID == SC_WID_UNO_MANPAGE )
8244 bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue );
8245 if (bSet)
8246 rFunc.InsertPageBreak( false, rRange.aStart, true, true );
8247 else
8248 rFunc.RemovePageBreak( false, rRange.aStart, true, true );
8250 else
8251 ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID
8254 void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny )
8256 if ( !pEntry )
8257 return;
8259 ScDocShell* pDocSh = GetDocShell();
8260 if (!pDocSh)
8261 throw uno::RuntimeException();
8262 ScDocument& rDoc = pDocSh->GetDocument();
8263 const ScRange& rRange = GetRange();
8264 OSL_ENSURE(rRange.aStart.Row() == rRange.aEnd.Row(), "too many rows");
8265 SCROW nRow = rRange.aStart.Row();
8266 SCTAB nTab = rRange.aStart.Tab();
8268 if ( pEntry->nWID == SC_WID_UNO_CELLHGT )
8270 // for hidden row, return original height
8271 sal_uInt16 nHeight = rDoc.GetOriginalHeight( nRow, nTab );
8272 // property is 1/100mm, row height is twips
8273 rAny <<= static_cast<sal_Int32>(convertTwipToMm100(nHeight));
8275 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS )
8277 bool bHidden = rDoc.RowHidden(nRow, nTab);
8278 rAny <<= !bHidden;
8280 else if ( pEntry->nWID == SC_WID_UNO_CELLFILT )
8282 bool bVis = rDoc.RowFiltered(nRow, nTab);
8283 rAny <<= bVis;
8285 else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT )
8287 bool bOpt = !(rDoc.GetRowFlags( nRow, nTab ) & CRFlags::ManualSize);
8288 rAny <<= bOpt;
8290 else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE )
8292 ScBreakType nBreak = rDoc.HasRowBreak(nRow, nTab);
8293 rAny <<= (nBreak != ScBreakType::NONE);
8295 else if ( pEntry->nWID == SC_WID_UNO_MANPAGE )
8297 bool bBreak(rDoc.HasRowBreak(nRow, nTab) & ScBreakType::Manual);
8298 rAny <<= bBreak;
8300 else
8301 ScCellRangeObj::GetOnePropertyValue(pEntry, rAny);
8304 const SfxItemPropertyMap& ScTableRowObj::GetItemPropertyMap()
8306 return pRowPropSet->getPropertyMap();
8309 ScCellsObj::ScCellsObj(ScDocShell* pDocSh, ScRangeList aR) :
8310 pDocShell( pDocSh ),
8311 aRanges(std::move( aR ))
8313 pDocShell->GetDocument().AddUnoObject(*this);
8316 ScCellsObj::~ScCellsObj()
8318 SolarMutexGuard g;
8320 if (pDocShell)
8321 pDocShell->GetDocument().RemoveUnoObject(*this);
8324 void ScCellsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
8326 if ( rHint.GetId() == SfxHintId::ScUpdateRef )
8328 auto pRefHint = static_cast<const ScUpdateRefHint*>(&rHint);
8329 aRanges.UpdateReference( pRefHint->GetMode(), &pDocShell->GetDocument(), pRefHint->GetRange(),
8330 pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() );
8332 else if ( rHint.GetId() == SfxHintId::Dying )
8334 pDocShell = nullptr;
8338 // XEnumerationAccess
8340 uno::Reference<container::XEnumeration> SAL_CALL ScCellsObj::createEnumeration()
8342 SolarMutexGuard aGuard;
8343 if (pDocShell)
8344 return new ScCellsEnumeration( pDocShell, aRanges );
8345 return nullptr;
8348 uno::Type SAL_CALL ScCellsObj::getElementType()
8350 return cppu::UnoType<table::XCell>::get();
8353 sal_Bool SAL_CALL ScCellsObj::hasElements()
8355 SolarMutexGuard aGuard;
8356 bool bHas = false;
8357 if ( pDocShell )
8359 //! faster if test ourself?
8361 uno::Reference<container::XEnumeration> xEnum(new ScCellsEnumeration( pDocShell, aRanges ));
8362 bHas = xEnum->hasMoreElements();
8364 return bHas;
8367 ScCellsEnumeration::ScCellsEnumeration(ScDocShell* pDocSh, ScRangeList aR) :
8368 pDocShell( pDocSh ),
8369 aRanges(std::move( aR )),
8370 bAtEnd( false )
8372 ScDocument& rDoc = pDocShell->GetDocument();
8373 rDoc.AddUnoObject(*this);
8375 if ( aRanges.empty() )
8376 bAtEnd = true;
8377 else
8379 SCTAB nTab = aRanges[ 0 ].aStart.Tab();
8380 aPos = ScAddress(0,0,nTab);
8381 CheckPos_Impl(); // set aPos on first matching cell
8385 void ScCellsEnumeration::CheckPos_Impl()
8387 if (!pDocShell)
8388 return;
8390 bool bFound = false;
8391 ScDocument& rDoc = pDocShell->GetDocument();
8392 ScRefCellValue aCell(rDoc, aPos);
8393 if (!aCell.isEmpty())
8395 if (!pMark)
8397 pMark.reset( new ScMarkData(rDoc.GetSheetLimits()) );
8398 pMark->MarkFromRangeList(aRanges, false);
8399 pMark->MarkToMulti(); // needed for GetNextMarkedCell
8401 bFound = pMark->IsCellMarked(aPos.Col(), aPos.Row());
8403 if (!bFound)
8404 Advance_Impl();
8407 ScCellsEnumeration::~ScCellsEnumeration()
8409 SolarMutexGuard g;
8411 if (pDocShell)
8412 pDocShell->GetDocument().RemoveUnoObject(*this);
8413 pMark.reset();
8416 void ScCellsEnumeration::Advance_Impl()
8418 OSL_ENSURE(!bAtEnd,"too much Advance_Impl");
8419 if (!pMark)
8421 pMark.reset( new ScMarkData(pDocShell->GetDocument().GetSheetLimits()) );
8422 pMark->MarkFromRangeList( aRanges, false );
8423 pMark->MarkToMulti(); // needed for GetNextMarkedCell
8426 SCCOL nCol = aPos.Col();
8427 SCROW nRow = aPos.Row();
8428 SCTAB nTab = aPos.Tab();
8429 bool bFound = pDocShell->GetDocument().GetNextMarkedCell( nCol, nRow, nTab, *pMark );
8430 if (bFound)
8431 aPos.Set( nCol, nRow, nTab );
8432 else
8433 bAtEnd = true; // nothing will follow
8436 void ScCellsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
8438 if ( rHint.GetId() == SfxHintId::ScUpdateRef )
8440 const ScUpdateRefHint* pRefHint = static_cast<const ScUpdateRefHint*>(&rHint);
8441 if (pDocShell)
8443 aRanges.UpdateReference( pRefHint->GetMode(), &pDocShell->GetDocument(), pRefHint->GetRange(),
8444 pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() );
8446 pMark.reset(); // recreate from moved area
8448 if (!bAtEnd) // adjust aPos
8450 ScRangeList aNew { ScRange(aPos) };
8451 aNew.UpdateReference( pRefHint->GetMode(), &pDocShell->GetDocument(), pRefHint->GetRange(),
8452 pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() );
8453 if (aNew.size()==1)
8455 aPos = aNew[ 0 ].aStart;
8456 CheckPos_Impl();
8461 else if ( rHint.GetId() == SfxHintId::Dying )
8463 pDocShell = nullptr;
8467 // XEnumeration
8469 sal_Bool SAL_CALL ScCellsEnumeration::hasMoreElements()
8471 SolarMutexGuard aGuard;
8472 return !bAtEnd;
8475 uno::Any SAL_CALL ScCellsEnumeration::nextElement()
8477 SolarMutexGuard aGuard;
8478 if (pDocShell && !bAtEnd)
8480 // interface must match ScCellsObj::getElementType
8482 ScAddress aTempPos(aPos);
8483 Advance_Impl();
8484 return uno::Any(uno::Reference<table::XCell>(new ScCellObj( pDocShell, aTempPos )));
8487 throw container::NoSuchElementException(); // no more elements
8490 ScCellFormatsObj::ScCellFormatsObj(ScDocShell* pDocSh, const ScRange& rRange) :
8491 pDocShell( pDocSh ),
8492 aTotalRange( rRange )
8494 ScDocument& rDoc = pDocShell->GetDocument();
8495 rDoc.AddUnoObject(*this);
8497 OSL_ENSURE( aTotalRange.aStart.Tab() == aTotalRange.aEnd.Tab(), "different tables" );
8500 ScCellFormatsObj::~ScCellFormatsObj()
8502 SolarMutexGuard g;
8504 if (pDocShell)
8505 pDocShell->GetDocument().RemoveUnoObject(*this);
8508 void ScCellFormatsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
8510 if ( rHint.GetId() == SfxHintId::ScUpdateRef )
8512 //! aTotalRange...
8514 else if ( rHint.GetId() == SfxHintId::Dying )
8516 pDocShell = nullptr;
8520 rtl::Reference<ScCellRangeObj> ScCellFormatsObj::GetObjectByIndex_Impl(tools::Long nIndex) const
8522 //! access the AttrArrays directly !!!!
8524 if (pDocShell)
8526 ScDocument& rDoc = pDocShell->GetDocument();
8527 tools::Long nPos = 0;
8528 ScAttrRectIterator aIter( rDoc, aTotalRange.aStart.Tab(),
8529 aTotalRange.aStart.Col(), aTotalRange.aStart.Row(),
8530 aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() );
8531 SCCOL nCol1, nCol2;
8532 SCROW nRow1, nRow2;
8533 while ( aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
8535 if ( nPos == nIndex )
8537 SCTAB nTab = aTotalRange.aStart.Tab();
8538 ScRange aNext( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
8540 if ( aNext.aStart == aNext.aEnd )
8541 return new ScCellObj( pDocShell, aNext.aStart );
8542 else
8543 return new ScCellRangeObj( pDocShell, aNext );
8545 ++nPos;
8548 return {};
8551 // XIndexAccess
8553 sal_Int32 SAL_CALL ScCellFormatsObj::getCount()
8555 SolarMutexGuard aGuard;
8557 //! access the AttrArrays directly !!!!
8559 tools::Long nCount = 0;
8560 if (pDocShell)
8562 ScDocument& rDoc = pDocShell->GetDocument();
8563 ScAttrRectIterator aIter( rDoc, aTotalRange.aStart.Tab(),
8564 aTotalRange.aStart.Col(), aTotalRange.aStart.Row(),
8565 aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() );
8566 SCCOL nCol1, nCol2;
8567 SCROW nRow1, nRow2;
8568 while ( aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
8569 ++nCount;
8571 return nCount;
8574 uno::Any SAL_CALL ScCellFormatsObj::getByIndex( sal_Int32 nIndex )
8576 SolarMutexGuard aGuard;
8578 uno::Reference<table::XCellRange> xRange(GetObjectByIndex_Impl(nIndex));
8579 if (!xRange.is())
8580 throw lang::IndexOutOfBoundsException();
8582 return uno::Any(xRange);
8586 uno::Type SAL_CALL ScCellFormatsObj::getElementType()
8588 return cppu::UnoType<table::XCellRange>::get();
8591 sal_Bool SAL_CALL ScCellFormatsObj::hasElements()
8593 SolarMutexGuard aGuard;
8594 return ( getCount() != 0 ); //! always greater than zero ??
8597 // XEnumerationAccess
8599 uno::Reference<container::XEnumeration> SAL_CALL ScCellFormatsObj::createEnumeration()
8601 SolarMutexGuard aGuard;
8602 if (pDocShell)
8603 return new ScCellFormatsEnumeration( pDocShell, aTotalRange );
8604 return nullptr;
8607 ScCellFormatsEnumeration::ScCellFormatsEnumeration(ScDocShell* pDocSh, const ScRange& rRange) :
8608 pDocShell( pDocSh ),
8609 nTab( rRange.aStart.Tab() ),
8610 bAtEnd( false ),
8611 bDirty( false )
8613 ScDocument& rDoc = pDocShell->GetDocument();
8614 rDoc.AddUnoObject(*this);
8616 OSL_ENSURE( rRange.aStart.Tab() == rRange.aEnd.Tab(),
8617 "CellFormatsEnumeration: different tables" );
8619 pIter.reset( new ScAttrRectIterator( rDoc, nTab,
8620 rRange.aStart.Col(), rRange.aStart.Row(),
8621 rRange.aEnd.Col(), rRange.aEnd.Row() ) );
8622 Advance_Impl();
8625 ScCellFormatsEnumeration::~ScCellFormatsEnumeration()
8627 SolarMutexGuard g;
8629 if (pDocShell)
8630 pDocShell->GetDocument().RemoveUnoObject(*this);
8633 void ScCellFormatsEnumeration::Advance_Impl()
8635 OSL_ENSURE(!bAtEnd,"too many Advance_Impl");
8637 if ( pIter )
8639 if ( bDirty )
8641 pIter->DataChanged(); // new search for AttrArray-Index
8642 bDirty = false;
8645 SCCOL nCol1, nCol2;
8646 SCROW nRow1, nRow2;
8647 if ( pIter->GetNext( nCol1, nCol2, nRow1, nRow2 ) )
8648 aNext = ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
8649 else
8650 bAtEnd = true;
8652 else
8653 bAtEnd = true; // document vanished or so
8656 rtl::Reference<ScCellRangeObj> ScCellFormatsEnumeration::NextObject_Impl()
8658 rtl::Reference<ScCellRangeObj> pRet;
8659 if (pDocShell && !bAtEnd)
8661 if ( aNext.aStart == aNext.aEnd )
8662 pRet = new ScCellObj( pDocShell, aNext.aStart );
8663 else
8664 pRet = new ScCellRangeObj( pDocShell, aNext );
8665 Advance_Impl();
8667 return pRet;
8670 void ScCellFormatsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
8672 if ( rHint.GetId() == SfxHintId::ScUpdateRef )
8674 //! and now???
8676 else
8678 const SfxHintId nId = rHint.GetId();
8679 if ( nId == SfxHintId::Dying )
8681 pDocShell = nullptr;
8682 pIter.reset();
8684 else if ( nId == SfxHintId::DataChanged )
8686 bDirty = true; // AttrArray-Index possibly invalid
8691 // XEnumeration
8693 sal_Bool SAL_CALL ScCellFormatsEnumeration::hasMoreElements()
8695 SolarMutexGuard aGuard;
8696 return !bAtEnd;
8699 uno::Any SAL_CALL ScCellFormatsEnumeration::nextElement()
8701 SolarMutexGuard aGuard;
8703 if ( bAtEnd || !pDocShell )
8704 throw container::NoSuchElementException(); // no more elements
8706 // interface must match ScCellFormatsObj::getElementType
8708 return uno::Any(uno::Reference<table::XCellRange> (NextObject_Impl()));
8711 ScUniqueCellFormatsObj::~ScUniqueCellFormatsObj()
8713 SolarMutexGuard g;
8715 if (pDocShell)
8716 pDocShell->GetDocument().RemoveUnoObject(*this);
8719 void ScUniqueCellFormatsObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
8721 if ( rHint.GetId() == SfxHintId::ScUpdateRef )
8723 //! aTotalRange...
8725 else
8727 if ( rHint.GetId() == SfxHintId::Dying )
8728 pDocShell = nullptr;
8732 // Fill the list of formats from the document
8734 namespace {
8736 // hash code to access the range lists by ScPatternAttr pointer
8737 struct ScPatternHashCode
8739 size_t operator()( const ScPatternAttr* pPattern ) const
8741 return reinterpret_cast<size_t>(pPattern);
8747 // Hash map to find a range by its start row
8748 typedef std::unordered_map< SCROW, ScRange > ScRowRangeHashMap;
8750 namespace {
8752 // Hash map entry.
8753 // The Join method depends on the column-wise order of ScAttrRectIterator
8754 class ScUniqueFormatsEntry
8756 enum EntryState { STATE_EMPTY, STATE_SINGLE, STATE_COMPLEX };
8758 EntryState eState;
8759 ScRange aSingleRange;
8760 ScRowRangeHashMap aJoinedRanges; // "active" ranges to be merged
8761 std::vector<ScRange> aCompletedRanges; // ranges that will no longer be touched
8762 ScRangeListRef aReturnRanges; // result as ScRangeList for further use
8764 public:
8765 ScUniqueFormatsEntry() : eState( STATE_EMPTY ) {}
8767 void Join( const ScRange& rNewRange );
8768 const ScRangeList& GetRanges();
8769 void Clear() { aReturnRanges.clear(); } // aJoinedRanges and aCompletedRanges are cleared in GetRanges
8774 void ScUniqueFormatsEntry::Join( const ScRange& rNewRange )
8776 // Special-case handling for single range
8778 if ( eState == STATE_EMPTY )
8780 aSingleRange = rNewRange;
8781 eState = STATE_SINGLE;
8782 return;
8784 if ( eState == STATE_SINGLE )
8786 if ( aSingleRange.aStart.Row() == rNewRange.aStart.Row() &&
8787 aSingleRange.aEnd.Row() == rNewRange.aEnd.Row() &&
8788 aSingleRange.aEnd.Col() + 1 == rNewRange.aStart.Col() )
8790 aSingleRange.aEnd.SetCol( rNewRange.aEnd.Col() );
8791 return; // still a single range
8794 SCROW nSingleRow = aSingleRange.aStart.Row();
8795 aJoinedRanges.emplace( nSingleRow, aSingleRange );
8796 eState = STATE_COMPLEX;
8797 // continue normally
8800 // This is called in the order of ScAttrRectIterator results.
8801 // rNewRange can only be joined with an existing entry if it's the same rows, starting in the next column.
8802 // If the old entry for the start row extends to a different end row, or ends in a different column, it
8803 // can be moved to aCompletedRanges because it can't be joined with following iterator results.
8804 // Everything happens within one sheet, so Tab can be ignored.
8806 SCROW nStartRow = rNewRange.aStart.Row();
8807 ScRowRangeHashMap::iterator aIter( aJoinedRanges.find( nStartRow ) ); // find the active entry for the start row
8808 if ( aIter != aJoinedRanges.end() )
8810 ScRange& rOldRange = aIter->second;
8811 if ( rOldRange.aEnd.Row() == rNewRange.aEnd.Row() &&
8812 rOldRange.aEnd.Col() + 1 == rNewRange.aStart.Col() )
8814 // extend existing range
8815 rOldRange.aEnd.SetCol( rNewRange.aEnd.Col() );
8817 else
8819 // move old range to aCompletedRanges, keep rNewRange for joining
8820 aCompletedRanges.push_back( rOldRange );
8821 rOldRange = rNewRange; // replace in hash map
8824 else
8826 // keep rNewRange for joining
8827 aJoinedRanges.emplace( nStartRow, rNewRange );
8831 const ScRangeList& ScUniqueFormatsEntry::GetRanges()
8833 if ( eState == STATE_SINGLE )
8835 aReturnRanges = new ScRangeList( aSingleRange );
8836 return *aReturnRanges;
8839 // move remaining entries from aJoinedRanges to aCompletedRanges
8841 for ( const auto& rEntry : aJoinedRanges )
8842 aCompletedRanges.push_back( rEntry.second );
8843 aJoinedRanges.clear();
8845 // sort all ranges for a predictable API result
8847 std::sort( aCompletedRanges.begin(), aCompletedRanges.end() );
8849 // fill and return ScRangeList
8851 aReturnRanges = new ScRangeList;
8852 aReturnRanges->insert( aReturnRanges->end(), aCompletedRanges.begin(), aCompletedRanges.end() );
8853 aCompletedRanges.clear();
8855 return *aReturnRanges;
8858 namespace {
8860 // function object to sort the range lists by start of first range
8861 struct ScUniqueFormatsOrder
8863 bool operator()( const ScRangeList& rList1, const ScRangeList& rList2 ) const
8865 // all range lists have at least one entry
8866 OSL_ENSURE( !rList1.empty() && !rList2.empty(), "ScUniqueFormatsOrder: empty list" );
8868 // compare start positions using ScAddress comparison operator
8869 return ( rList1[ 0 ].aStart < rList2[ 0 ].aStart );
8875 ScUniqueCellFormatsObj::ScUniqueCellFormatsObj(ScDocShell* pDocSh, const ScRange& rTotalRange) :
8876 pDocShell( pDocSh )
8878 pDocShell->GetDocument().AddUnoObject(*this);
8880 OSL_ENSURE( rTotalRange.aStart.Tab() == rTotalRange.aEnd.Tab(), "different tables" );
8882 ScDocument& rDoc = pDocShell->GetDocument();
8883 SCTAB nTab = rTotalRange.aStart.Tab();
8884 ScAttrRectIterator aIter( rDoc, nTab,
8885 rTotalRange.aStart.Col(), rTotalRange.aStart.Row(),
8886 rTotalRange.aEnd.Col(), rTotalRange.aEnd.Row() );
8887 SCCOL nCol1, nCol2;
8888 SCROW nRow1, nRow2;
8890 // Collect the ranges for each format in a hash map, to avoid nested loops
8892 std::unordered_map< const ScPatternAttr*, ScUniqueFormatsEntry, ScPatternHashCode > aHashMap;
8893 while (aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) )
8895 ScRange aRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
8896 const ScPatternAttr* pPattern = rDoc.GetPattern(nCol1, nRow1, nTab);
8897 aHashMap[pPattern].Join( aRange );
8900 // Fill the vector aRangeLists with the range lists from the hash map
8902 aRangeLists.reserve( aHashMap.size() );
8903 for ( auto& rMapEntry : aHashMap )
8905 ScUniqueFormatsEntry& rEntry = rMapEntry.second;
8906 const ScRangeList& rRanges = rEntry.GetRanges();
8907 aRangeLists.push_back( rRanges ); // copy ScRangeList
8908 rEntry.Clear(); // free memory, don't hold both copies of all ranges
8911 // Sort the vector by first range's start position, to avoid random shuffling
8912 // due to using the ScPatterAttr pointers
8914 ::std::sort( aRangeLists.begin(), aRangeLists.end(), ScUniqueFormatsOrder() );
8918 // XIndexAccess
8920 sal_Int32 SAL_CALL ScUniqueCellFormatsObj::getCount()
8922 SolarMutexGuard aGuard;
8924 return aRangeLists.size();
8927 uno::Any SAL_CALL ScUniqueCellFormatsObj::getByIndex( sal_Int32 nIndex )
8929 SolarMutexGuard aGuard;
8931 if(o3tl::make_unsigned(nIndex) >= aRangeLists.size())
8932 throw lang::IndexOutOfBoundsException();
8934 return uno::Any(uno::Reference<sheet::XSheetCellRangeContainer>(new ScCellRangesObj(pDocShell, aRangeLists[nIndex])));
8938 uno::Type SAL_CALL ScUniqueCellFormatsObj::getElementType()
8940 return cppu::UnoType<sheet::XSheetCellRangeContainer>::get();
8943 sal_Bool SAL_CALL ScUniqueCellFormatsObj::hasElements()
8945 SolarMutexGuard aGuard;
8946 return ( !aRangeLists.empty() );
8949 // XEnumerationAccess
8951 uno::Reference<container::XEnumeration> SAL_CALL ScUniqueCellFormatsObj::createEnumeration()
8953 SolarMutexGuard aGuard;
8954 if (pDocShell)
8955 return new ScUniqueCellFormatsEnumeration( pDocShell, std::vector(aRangeLists) );
8956 return nullptr;
8959 ScUniqueCellFormatsEnumeration::ScUniqueCellFormatsEnumeration(ScDocShell* pDocSh, std::vector<ScRangeList>&& rRangeLists) :
8960 aRangeLists(std::move(rRangeLists)),
8961 pDocShell( pDocSh ),
8962 nCurrentPosition(0)
8964 pDocShell->GetDocument().AddUnoObject(*this);
8967 ScUniqueCellFormatsEnumeration::~ScUniqueCellFormatsEnumeration()
8969 SolarMutexGuard g;
8971 if (pDocShell)
8972 pDocShell->GetDocument().RemoveUnoObject(*this);
8975 void ScUniqueCellFormatsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint )
8977 if ( rHint.GetId() == SfxHintId::ScUpdateRef )
8979 //! and now ???
8981 else
8983 if ( rHint.GetId() == SfxHintId::Dying )
8984 pDocShell = nullptr;
8988 // XEnumeration
8990 sal_Bool SAL_CALL ScUniqueCellFormatsEnumeration::hasMoreElements()
8992 SolarMutexGuard aGuard;
8993 return o3tl::make_unsigned(nCurrentPosition) < aRangeLists.size();
8996 uno::Any SAL_CALL ScUniqueCellFormatsEnumeration::nextElement()
8998 SolarMutexGuard aGuard;
9000 if ( !hasMoreElements() || !pDocShell )
9001 throw container::NoSuchElementException(); // no more elements
9003 // interface type must match ScCellFormatsObj::getElementType
9005 return uno::Any(uno::Reference<sheet::XSheetCellRangeContainer>(new ScCellRangesObj(pDocShell, aRangeLists[nCurrentPosition++])));
9008 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */