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