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