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.getType(); 1333 if (eType == CELLTYPE_FORMULA) 1334 { 1335 ScFormulaCell* pForm = aCell.getFormula(); 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.getEditText(); 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 3661 for (size_t nR = 0, nCount = aNewRanges.size(); nR<nCount; ++nR) 3662 { 3663 ScRange const & rRange = aNewRanges[ nR]; 3664 ScCellIterator aIter(rDoc, rRange); 3665 for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) 3666 { 3667 if (aIter.getType() != CELLTYPE_FORMULA) 3668 continue; 3669 3670 ScDetectiveRefIter aRefIter(rDoc, aIter.getFormulaCell()); 3671 ScRange aRefRange; 3672 while ( aRefIter.GetNextRef( aRefRange) ) 3673 { 3674 if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aRefRange ) ) 3675 bFound = true; 3676 aMarkData.SetMultiMarkArea(aRefRange); 3677 } 3678 } 3679 } 3680 3681 aMarkData.FillRangeListWithMarks( &aNewRanges, true ); 3682 } 3683 while ( bRecursive && bFound ); 3684 3685 return new ScCellRangesObj( pDocShell, aNewRanges ); 3686 } 3687 3688 return nullptr; 3689 } 3690 3691 uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryDependents( 3692 sal_Bool bRecursive ) 3693 { 3694 SolarMutexGuard aGuard; 3695 if ( pDocShell ) 3696 { 3697 ScDocument& rDoc = pDocShell->GetDocument(); 3698 3699 ScRangeList aNewRanges(aRanges); 3700 bool bFound; 3701 do 3702 { 3703 bFound = false; 3704 3705 // aMarkData uses aNewRanges, not aRanges, so GetMarkData can't be used 3706 ScMarkData aMarkData(rDoc.GetSheetLimits()); 3707 aMarkData.MarkFromRangeList( aNewRanges, false ); 3708 3709 SCTAB nTab = lcl_FirstTab(aNewRanges); //! all tables 3710 3711 ScCellIterator aCellIter( rDoc, ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab) ); 3712 for (bool bHasCell = aCellIter.first(); bHasCell; bHasCell = aCellIter.next()) 3713 { 3714 if (aCellIter.getType() != CELLTYPE_FORMULA) 3715 continue; 3716 3717 bool bMark = false; 3718 ScDetectiveRefIter aIter(rDoc, aCellIter.getFormulaCell()); 3719 ScRange aRefRange; 3720 while ( aIter.GetNextRef( aRefRange) && !bMark ) 3721 { 3722 size_t nRangesCount = aNewRanges.size(); 3723 for (size_t nR = 0; nR < nRangesCount; ++nR) 3724 { 3725 ScRange const & rRange = aNewRanges[ nR ]; 3726 if (rRange.Intersects(aRefRange)) 3727 { 3728 bMark = true; // depending on part of Range 3729 break; 3730 } 3731 } 3732 } 3733 if (bMark) 3734 { 3735 ScRange aCellRange(aCellIter.GetPos()); 3736 if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aCellRange ) ) 3737 bFound = true; 3738 aMarkData.SetMultiMarkArea(aCellRange); 3739 } 3740 } 3741 3742 aMarkData.FillRangeListWithMarks( &aNewRanges, true ); 3743 } 3744 while ( bRecursive && bFound ); 3745 3746 return new ScCellRangesObj( pDocShell, aNewRanges ); 3747 } 3748 3749 return nullptr; 3750 } 3751 3752 // XSearchable 3753 3754 uno::Reference<util::XSearchDescriptor> SAL_CALL ScCellRangesBase::createSearchDescriptor() 3755 { 3756 return new ScCellSearchObj; 3757 } 3758 3759 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangesBase::findAll( 3760 const uno::Reference<util::XSearchDescriptor>& xDesc ) 3761 { 3762 SolarMutexGuard aGuard; 3763 // should we return Null if nothing is found(?) 3764 uno::Reference<container::XIndexAccess> xRet; 3765 if ( pDocShell && xDesc.is() ) 3766 { 3767 ScCellSearchObj* pSearch = comphelper::getFromUnoTunnel<ScCellSearchObj>( xDesc ); 3768 if (pSearch) 3769 { 3770 SvxSearchItem* pSearchItem = pSearch->GetSearchItem(); 3771 if (pSearchItem) 3772 { 3773 ScDocument& rDoc = pDocShell->GetDocument(); 3774 pSearchItem->SetCommand( SvxSearchCmd::FIND_ALL ); 3775 // always only within this object 3776 pSearchItem->SetSelection( !lcl_WholeSheet(rDoc, aRanges) ); 3777 3778 ScMarkData aMark(*GetMarkData()); 3779 3780 OUString aDummyUndo; 3781 ScRangeList aMatchedRanges; 3782 SCCOL nCol = 0; 3783 SCROW nRow = 0; 3784 SCTAB nTab = 0; 3785 bool bFound = rDoc.SearchAndReplace( 3786 *pSearchItem, nCol, nRow, nTab, aMark, aMatchedRanges, aDummyUndo); 3787 if (bFound) 3788 { 3789 // on findAll always CellRanges no matter how much has been found 3790 xRet.set(new ScCellRangesObj( pDocShell, aMatchedRanges )); 3791 } 3792 } 3793 } 3794 } 3795 return xRet; 3796 } 3797 3798 uno::Reference<uno::XInterface> ScCellRangesBase::Find_Impl( 3799 const uno::Reference<util::XSearchDescriptor>& xDesc, 3800 const ScAddress* pLastPos ) 3801 { 3802 uno::Reference<uno::XInterface> xRet; 3803 if ( pDocShell && xDesc.is() ) 3804 { 3805 ScCellSearchObj* pSearch = comphelper::getFromUnoTunnel<ScCellSearchObj>( xDesc ); 3806 if (pSearch) 3807 { 3808 SvxSearchItem* pSearchItem = pSearch->GetSearchItem(); 3809 if (pSearchItem) 3810 { 3811 ScDocument& rDoc = pDocShell->GetDocument(); 3812 pSearchItem->SetCommand( SvxSearchCmd::FIND ); 3813 // only always in this object 3814 pSearchItem->SetSelection( !lcl_WholeSheet(rDoc, aRanges) ); 3815 3816 ScMarkData aMark(*GetMarkData()); 3817 3818 SCCOL nCol; 3819 SCROW nRow; 3820 SCTAB nTab; 3821 if (pLastPos) 3822 pLastPos->GetVars( nCol, nRow, nTab ); 3823 else 3824 { 3825 nTab = lcl_FirstTab(aRanges); //! multiple sheets? 3826 rDoc.GetSearchAndReplaceStart( *pSearchItem, nCol, nRow ); 3827 } 3828 3829 OUString aDummyUndo; 3830 ScRangeList aMatchedRanges; 3831 bool bFound = rDoc.SearchAndReplace( 3832 *pSearchItem, nCol, nRow, nTab, aMark, aMatchedRanges, aDummyUndo); 3833 if (bFound) 3834 { 3835 ScAddress aFoundPos( nCol, nRow, nTab ); 3836 xRet.set(static_cast<cppu::OWeakObject*>(new ScCellObj( pDocShell, aFoundPos ))); 3837 } 3838 } 3839 } 3840 } 3841 return xRet; 3842 } 3843 3844 uno::Reference<uno::XInterface> SAL_CALL ScCellRangesBase::findFirst( 3845 const uno::Reference<util::XSearchDescriptor>& xDesc ) 3846 { 3847 SolarMutexGuard aGuard; 3848 return Find_Impl( xDesc, nullptr ); 3849 } 3850 3851 uno::Reference<uno::XInterface> SAL_CALL ScCellRangesBase::findNext( 3852 const uno::Reference<uno::XInterface>& xStartAt, 3853 const uno::Reference<util::XSearchDescriptor >& xDesc ) 3854 { 3855 SolarMutexGuard aGuard; 3856 if ( xStartAt.is() ) 3857 { 3858 ScCellRangesBase* pRangesImp = comphelper::getFromUnoTunnel<ScCellRangesBase>( xStartAt ); 3859 if ( pRangesImp && pRangesImp->GetDocShell() == pDocShell ) 3860 { 3861 const ScRangeList& rStartRanges = pRangesImp->GetRangeList(); 3862 if ( rStartRanges.size() == 1 ) 3863 { 3864 ScAddress aStartPos = rStartRanges[ 0 ].aStart; 3865 return Find_Impl( xDesc, &aStartPos ); 3866 } 3867 } 3868 } 3869 return nullptr; 3870 } 3871 3872 // XReplaceable 3873 3874 uno::Reference<util::XReplaceDescriptor> SAL_CALL ScCellRangesBase::createReplaceDescriptor() 3875 { 3876 return new ScCellSearchObj; 3877 } 3878 3879 sal_Int32 SAL_CALL ScCellRangesBase::replaceAll( const uno::Reference<util::XSearchDescriptor>& xDesc ) 3880 { 3881 SolarMutexGuard aGuard; 3882 sal_uInt64 nReplaced = 0; 3883 if ( pDocShell && xDesc.is() ) 3884 { 3885 ScCellSearchObj* pSearch = comphelper::getFromUnoTunnel<ScCellSearchObj>( xDesc ); 3886 if (pSearch) 3887 { 3888 SvxSearchItem* pSearchItem = pSearch->GetSearchItem(); 3889 if (pSearchItem) 3890 { 3891 ScDocument& rDoc = pDocShell->GetDocument(); 3892 bool bUndo(rDoc.IsUndoEnabled()); 3893 pSearchItem->SetCommand( SvxSearchCmd::REPLACE_ALL ); 3894 // only always in this object 3895 pSearchItem->SetSelection( !lcl_WholeSheet(rDoc, aRanges) ); 3896 3897 ScMarkData aMark(*GetMarkData()); 3898 3899 SCTAB nTabCount = rDoc.GetTableCount(); 3900 bool bProtected = !pDocShell->IsEditable(); 3901 for (const auto& rTab : aMark) 3902 { 3903 if (rTab >= nTabCount) 3904 break; 3905 if ( rDoc.IsTabProtected(rTab) ) 3906 bProtected = true; 3907 } 3908 if (bProtected) 3909 { 3910 //! Exception, or what? 3911 } 3912 else 3913 { 3914 SCTAB nTab = aMark.GetFirstSelected(); // do not use if SearchAndReplace 3915 SCCOL nCol = 0; 3916 SCROW nRow = 0; 3917 3918 OUString aUndoStr; 3919 ScDocumentUniquePtr pUndoDoc; 3920 if (bUndo) 3921 { 3922 pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO )); 3923 pUndoDoc->InitUndo( rDoc, nTab, nTab ); 3924 } 3925 for (const auto& rTab : aMark) 3926 { 3927 if (rTab >= nTabCount) 3928 break; 3929 if (rTab != nTab && bUndo) 3930 pUndoDoc->AddUndoTab( rTab, rTab ); 3931 } 3932 std::unique_ptr<ScMarkData> pUndoMark; 3933 if (bUndo) 3934 pUndoMark.reset(new ScMarkData(aMark)); 3935 3936 bool bFound = false; 3937 if (bUndo) 3938 { 3939 ScRangeList aMatchedRanges; 3940 bFound = rDoc.SearchAndReplace( 3941 *pSearchItem, nCol, nRow, nTab, aMark, aMatchedRanges, aUndoStr, pUndoDoc.get() ); 3942 } 3943 if (bFound) 3944 { 3945 nReplaced = pUndoDoc->GetCellCount(); 3946 3947 pDocShell->GetUndoManager()->AddUndoAction( 3948 std::make_unique<ScUndoReplace>( pDocShell, *pUndoMark, nCol, nRow, nTab, 3949 aUndoStr, std::move(pUndoDoc), pSearchItem ) ); 3950 3951 pDocShell->PostPaintGridAll(); 3952 pDocShell->SetDocumentModified(); 3953 } 3954 } 3955 } 3956 } 3957 } 3958 return nReplaced; 3959 } 3960 3961 // XUnoTunnel 3962 3963 UNO3_GETIMPLEMENTATION_IMPL(ScCellRangesBase); 3964 3965 ScCellRangesObj::ScCellRangesObj(ScDocShell* pDocSh, const ScRangeList& rR) 3966 : ScCellRangesBase(pDocSh, rR) 3967 { 3968 } 3969 3970 ScCellRangesObj::~ScCellRangesObj() 3971 { 3972 } 3973 3974 void ScCellRangesObj::RefChanged() 3975 { 3976 ScCellRangesBase::RefChanged(); 3977 } 3978 3979 uno::Any SAL_CALL ScCellRangesObj::queryInterface( const uno::Type& rType ) 3980 { 3981 SC_QUERYINTERFACE( sheet::XSheetCellRangeContainer ) 3982 SC_QUERYINTERFACE( sheet::XSheetCellRanges ) 3983 SC_QUERYINTERFACE( container::XIndexAccess ) 3984 SC_QUERY_MULTIPLE( container::XElementAccess, container::XIndexAccess ) 3985 SC_QUERYINTERFACE( container::XEnumerationAccess ) 3986 SC_QUERYINTERFACE( container::XNameContainer ) 3987 SC_QUERYINTERFACE( container::XNameReplace ) 3988 SC_QUERYINTERFACE( container::XNameAccess ) 3989 3990 return ScCellRangesBase::queryInterface( rType ); 3991 } 3992 3993 void SAL_CALL ScCellRangesObj::acquire() noexcept 3994 { 3995 ScCellRangesBase::acquire(); 3996 } 3997 3998 void SAL_CALL ScCellRangesObj::release() noexcept 3999 { 4000 ScCellRangesBase::release(); 4001 } 4002 4003 uno::Sequence<uno::Type> SAL_CALL ScCellRangesObj::getTypes() 4004 { 4005 static const uno::Sequence<uno::Type> aTypes = comphelper::concatSequences( 4006 ScCellRangesBase::getTypes(), 4007 uno::Sequence<uno::Type> 4008 { 4009 cppu::UnoType<sheet::XSheetCellRangeContainer>::get(), 4010 cppu::UnoType<container::XNameContainer>::get(), 4011 cppu::UnoType<container::XEnumerationAccess>::get() 4012 } ); 4013 return aTypes; 4014 } 4015 4016 uno::Sequence<sal_Int8> SAL_CALL ScCellRangesObj::getImplementationId() 4017 { 4018 return css::uno::Sequence<sal_Int8>(); 4019 } 4020 4021 // XCellRanges 4022 4023 rtl::Reference<ScCellRangeObj> ScCellRangesObj::GetObjectByIndex_Impl(sal_Int32 nIndex) const 4024 { 4025 ScDocShell* pDocSh = GetDocShell(); 4026 const ScRangeList& rRanges = GetRangeList(); 4027 if ( pDocSh && nIndex >= 0 && nIndex < sal::static_int_cast<sal_Int32>(rRanges.size()) ) 4028 { 4029 ScRange const & rRange = rRanges[ nIndex ]; 4030 if ( rRange.aStart == rRange.aEnd ) 4031 return new ScCellObj( pDocSh, rRange.aStart ); 4032 else 4033 return new ScCellRangeObj( pDocSh, rRange ); 4034 } 4035 4036 return nullptr; // no DocShell or wrong index 4037 } 4038 4039 uno::Sequence<table::CellRangeAddress> SAL_CALL ScCellRangesObj::getRangeAddresses() 4040 { 4041 SolarMutexGuard aGuard; 4042 ScDocShell* pDocSh = GetDocShell(); 4043 const ScRangeList& rRanges = GetRangeList(); 4044 size_t nCount = rRanges.size(); 4045 if ( pDocSh && nCount ) 4046 { 4047 table::CellRangeAddress aRangeAddress; 4048 uno::Sequence<table::CellRangeAddress> aSeq(nCount); 4049 table::CellRangeAddress* pAry = aSeq.getArray(); 4050 for ( size_t i=0; i < nCount; i++) 4051 { 4052 ScUnoConversion::FillApiRange( aRangeAddress, rRanges[ i ] ); 4053 pAry[i] = aRangeAddress; 4054 } 4055 return aSeq; 4056 } 4057 4058 return {}; // can be empty 4059 } 4060 4061 uno::Reference<container::XEnumerationAccess> SAL_CALL ScCellRangesObj::getCells() 4062 { 4063 SolarMutexGuard aGuard; 4064 4065 // getCells with empty range list is possible (no exception), 4066 // the resulting enumeration just has no elements 4067 // (same behaviour as a valid range with no cells) 4068 // This is handled in ScCellsEnumeration ctor. 4069 4070 const ScRangeList& rRanges = GetRangeList(); 4071 ScDocShell* pDocSh = GetDocShell(); 4072 if (pDocSh) 4073 return new ScCellsObj( pDocSh, rRanges ); 4074 return nullptr; 4075 } 4076 4077 OUString SAL_CALL ScCellRangesObj::getRangeAddressesAsString() 4078 { 4079 SolarMutexGuard aGuard; 4080 OUString aString; 4081 ScDocShell* pDocSh = GetDocShell(); 4082 const ScRangeList& rRanges = GetRangeList(); 4083 if (pDocSh) 4084 rRanges.Format( aString, ScRefFlags::VALID | ScRefFlags::TAB_3D, pDocSh->GetDocument() ); 4085 return aString; 4086 } 4087 4088 // XSheetCellRangeContainer 4089 4090 void SAL_CALL ScCellRangesObj::addRangeAddress( const table::CellRangeAddress& rRange, 4091 sal_Bool bMergeRanges ) 4092 { 4093 SolarMutexGuard aGuard; 4094 ScRange aRange(static_cast<SCCOL>(rRange.StartColumn), 4095 static_cast<SCROW>(rRange.StartRow), 4096 static_cast<SCTAB>(rRange.Sheet), 4097 static_cast<SCCOL>(rRange.EndColumn), 4098 static_cast<SCROW>(rRange.EndRow), 4099 static_cast<SCTAB>(rRange.Sheet)); 4100 AddRange(aRange, bMergeRanges); 4101 } 4102 4103 static void lcl_RemoveNamedEntry( std::vector<ScCellRangesObj::ScNamedEntry>& rNamedEntries, const ScRange& rRange ) 4104 { 4105 sal_uInt16 nCount = rNamedEntries.size(); 4106 for ( sal_uInt16 n=nCount; n--; ) 4107 if ( rNamedEntries[n].GetRange() == rRange ) 4108 rNamedEntries.erase( rNamedEntries.begin() + n ); 4109 } 4110 4111 void SAL_CALL ScCellRangesObj::removeRangeAddress( const table::CellRangeAddress& rRange ) 4112 { 4113 SolarMutexGuard aGuard; 4114 const ScRangeList& rRanges = GetRangeList(); 4115 4116 ScRangeList aSheetRanges; 4117 ScRangeList aNotSheetRanges; 4118 for (size_t i = 0; i < rRanges.size(); ++i) 4119 { 4120 if (rRanges[ i].aStart.Tab() == rRange.Sheet) 4121 { 4122 aSheetRanges.push_back( rRanges[ i ] ); 4123 } 4124 else 4125 { 4126 aNotSheetRanges.push_back( rRanges[ i ] ); 4127 } 4128 } 4129 ScMarkData aMarkData(GetDocument()->GetSheetLimits()); 4130 aMarkData.MarkFromRangeList( aSheetRanges, false ); 4131 ScRange aRange(static_cast<SCCOL>(rRange.StartColumn), 4132 static_cast<SCROW>(rRange.StartRow), 4133 static_cast<SCTAB>(rRange.Sheet), 4134 static_cast<SCCOL>(rRange.EndColumn), 4135 static_cast<SCROW>(rRange.EndRow), 4136 static_cast<SCTAB>(rRange.Sheet)); 4137 if (aMarkData.GetTableSelect( aRange.aStart.Tab() )) 4138 { 4139 aMarkData.MarkToMulti(); 4140 if (!aMarkData.IsAllMarked( aRange ) ) 4141 throw container::NoSuchElementException(); 4142 4143 aMarkData.SetMultiMarkArea( aRange, false ); 4144 lcl_RemoveNamedEntry(m_aNamedEntries, aRange); 4145 4146 } 4147 SetNewRanges(aNotSheetRanges); 4148 ScRangeList aNew; 4149 aMarkData.FillRangeListWithMarks( &aNew, false ); 4150 for ( size_t j = 0; j < aNew.size(); ++j) 4151 { 4152 AddRange(aNew[ j ], false); 4153 } 4154 } 4155 4156 void SAL_CALL ScCellRangesObj::addRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRanges, 4157 sal_Bool bMergeRanges ) 4158 { 4159 SolarMutexGuard aGuard; 4160 for (const table::CellRangeAddress& rRange : rRanges) 4161 { 4162 ScRange aRange(static_cast<SCCOL>(rRange.StartColumn), 4163 static_cast<SCROW>(rRange.StartRow), 4164 static_cast<SCTAB>(rRange.Sheet), 4165 static_cast<SCCOL>(rRange.EndColumn), 4166 static_cast<SCROW>(rRange.EndRow), 4167 static_cast<SCTAB>(rRange.Sheet)); 4168 AddRange(aRange, bMergeRanges); 4169 } 4170 } 4171 4172 void SAL_CALL ScCellRangesObj::removeRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRangeSeq ) 4173 { 4174 // use sometimes a better/faster implementation 4175 for (const table::CellRangeAddress& rRange : rRangeSeq) 4176 { 4177 removeRangeAddress(rRange); 4178 } 4179 } 4180 4181 // XNameContainer 4182 4183 static void lcl_RemoveNamedEntry( std::vector<ScCellRangesObj::ScNamedEntry>& rNamedEntries, std::u16string_view rName ) 4184 { 4185 sal_uInt16 nCount = rNamedEntries.size(); 4186 for ( sal_uInt16 n=nCount; n--; ) 4187 if ( rNamedEntries[n].GetName() == rName ) 4188 rNamedEntries.erase( rNamedEntries.begin() + n ); 4189 } 4190 4191 void SAL_CALL ScCellRangesObj::insertByName( const OUString& aName, const uno::Any& aElement ) 4192 { 4193 SolarMutexGuard aGuard; 4194 ScDocShell* pDocSh = GetDocShell(); 4195 bool bDone = false; 4196 4197 //! Type of aElement can be some specific interface instead of XInterface 4198 4199 uno::Reference<uno::XInterface> xInterface(aElement, uno::UNO_QUERY); 4200 if ( pDocSh && xInterface.is() ) 4201 { 4202 ScCellRangesBase* pRangesImp = comphelper::getFromUnoTunnel<ScCellRangesBase>( xInterface ); 4203 if ( pRangesImp && pRangesImp->GetDocShell() == pDocSh ) 4204 { 4205 // if explicit name is given and already existing, throw exception 4206 4207 if ( !aName.isEmpty() ) 4208 { 4209 size_t nNamedCount = m_aNamedEntries.size(); 4210 for (size_t n = 0; n < nNamedCount; n++) 4211 { 4212 if (m_aNamedEntries[n].GetName() == aName) 4213 throw container::ElementExistException(); 4214 } 4215 } 4216 4217 ScRangeList aNew(GetRangeList()); 4218 const ScRangeList& rAddRanges = pRangesImp->GetRangeList(); 4219 size_t nAddCount = rAddRanges.size(); 4220 for ( size_t i = 0; i < nAddCount; i++ ) 4221 aNew.Join( rAddRanges[ i ] ); 4222 SetNewRanges(aNew); 4223 bDone = true; 4224 4225 if ( !aName.isEmpty() && nAddCount == 1 ) 4226 { 4227 // if a name is given, also insert into list of named entries 4228 // (only possible for a single range) 4229 // name is not in m_aNamedEntries (tested above) 4230 m_aNamedEntries.emplace_back( ScNamedEntry{aName, rAddRanges[ 0 ]} ); 4231 } 4232 } 4233 } 4234 4235 if (!bDone) 4236 { 4237 // invalid element - double names are handled above 4238 throw lang::IllegalArgumentException(); 4239 } 4240 } 4241 4242 static bool lcl_FindRangeByName( const ScRangeList& rRanges, ScDocShell* pDocSh, 4243 std::u16string_view rName, size_t& rIndex ) 4244 { 4245 if (pDocSh) 4246 { 4247 OUString aRangeStr; 4248 ScDocument& rDoc = pDocSh->GetDocument(); 4249 for ( size_t i = 0, nCount = rRanges.size(); i < nCount; i++ ) 4250 { 4251 aRangeStr = rRanges[ i ].Format(rDoc, ScRefFlags::VALID | ScRefFlags::TAB_3D); 4252 if ( aRangeStr == rName ) 4253 { 4254 rIndex = i; 4255 return true; 4256 } 4257 } 4258 } 4259 return false; 4260 } 4261 4262 static bool lcl_FindRangeOrEntry( const std::vector<ScCellRangesObj::ScNamedEntry>& rNamedEntries, 4263 const ScRangeList& rRanges, ScDocShell* pDocSh, 4264 const OUString& rName, ScRange& rFound ) 4265 { 4266 // exact range in list? 4267 4268 size_t nIndex = 0; 4269 if ( lcl_FindRangeByName( rRanges, pDocSh, rName, nIndex ) ) 4270 { 4271 rFound = rRanges[ nIndex ]; 4272 return true; 4273 } 4274 4275 // range contained in selection? (sheet must be specified) 4276 4277 ScRange aCellRange; 4278 ScRefFlags nParse = aCellRange.ParseAny( rName, pDocSh->GetDocument() ); 4279 if ( (nParse & ( ScRefFlags::VALID | ScRefFlags::TAB_3D )) 4280 == ( ScRefFlags::VALID | ScRefFlags::TAB_3D )) 4281 { 4282 ScMarkData aMarkData(pDocSh->GetDocument().GetSheetLimits()); 4283 aMarkData.MarkFromRangeList( rRanges, false ); 4284 if ( aMarkData.IsAllMarked( aCellRange ) ) 4285 { 4286 rFound = aCellRange; 4287 return true; 4288 } 4289 } 4290 4291 // named entry in this object? 4292 4293 for (const auto & rNamedEntry : rNamedEntries) 4294 if ( rNamedEntry.GetName() == rName ) 4295 { 4296 // test if named entry is contained in rRanges 4297 4298 const ScRange& rComp = rNamedEntry.GetRange(); 4299 ScMarkData aMarkData(pDocSh->GetDocument().GetSheetLimits()); 4300 aMarkData.MarkFromRangeList( rRanges, false ); 4301 if ( aMarkData.IsAllMarked( rComp ) ) 4302 { 4303 rFound = rComp; 4304 return true; 4305 } 4306 } 4307 4308 return false; // not found 4309 } 4310 4311 void SAL_CALL ScCellRangesObj::removeByName( const OUString& aName ) 4312 { 4313 SolarMutexGuard aGuard; 4314 bool bDone = false; 4315 ScDocShell* pDocSh = GetDocShell(); 4316 const ScRangeList& rRanges = GetRangeList(); 4317 size_t nIndex = 0; 4318 if ( lcl_FindRangeByName( rRanges, pDocSh, aName, nIndex ) ) 4319 { 4320 // skip a single range 4321 ScRangeList aNew; 4322 for ( size_t i = 0, nCount = rRanges.size(); i < nCount; i++ ) 4323 if (i != nIndex) 4324 aNew.push_back( rRanges[ i ] ); 4325 SetNewRanges(aNew); 4326 bDone = true; 4327 } 4328 else if (pDocSh) 4329 { 4330 // deselect any ranges (parsed or named entry) 4331 ScRangeList aDiff; 4332 bool bValid = ( aDiff.Parse( aName, pDocSh->GetDocument() ) & ScRefFlags::VALID ) 4333 == ScRefFlags::VALID; 4334 if (!bValid) 4335 { 4336 sal_uInt16 nCount = m_aNamedEntries.size(); 4337 for (sal_uInt16 n=0; n<nCount && !bValid; n++) 4338 if (m_aNamedEntries[n].GetName() == aName) 4339 { 4340 aDiff.RemoveAll(); 4341 aDiff.push_back(m_aNamedEntries[n].GetRange()); 4342 bValid = true; 4343 } 4344 } 4345 if ( bValid ) 4346 { 4347 ScMarkData aMarkData(GetDocument()->GetSheetLimits()); 4348 aMarkData.MarkFromRangeList( rRanges, false ); 4349 4350 for ( size_t i = 0, nDiffCount = aDiff.size(); i < nDiffCount; i++ ) 4351 { 4352 ScRange const & rDiffRange = aDiff[ i ]; 4353 if (aMarkData.GetTableSelect( rDiffRange.aStart.Tab() )) 4354 aMarkData.SetMultiMarkArea( rDiffRange, false ); 4355 } 4356 4357 ScRangeList aNew; 4358 aMarkData.FillRangeListWithMarks( &aNew, false ); 4359 SetNewRanges(aNew); 4360 4361 bDone = true; //! error if range was not selected before? 4362 } 4363 } 4364 4365 if (!m_aNamedEntries.empty()) 4366 lcl_RemoveNamedEntry(m_aNamedEntries, aName); 4367 4368 if (!bDone) 4369 throw container::NoSuchElementException(); // not found 4370 } 4371 4372 // XNameReplace 4373 4374 void SAL_CALL ScCellRangesObj::replaceByName( const OUString& aName, const uno::Any& aElement ) 4375 { 4376 SolarMutexGuard aGuard; 4377 //! combine? 4378 removeByName( aName ); 4379 insertByName( aName, aElement ); 4380 } 4381 4382 // XNameAccess 4383 4384 uno::Any SAL_CALL ScCellRangesObj::getByName( const OUString& aName ) 4385 { 4386 SolarMutexGuard aGuard; 4387 uno::Any aRet; 4388 4389 ScDocShell* pDocSh = GetDocShell(); 4390 const ScRangeList& rRanges = GetRangeList(); 4391 ScRange aRange; 4392 if (!lcl_FindRangeOrEntry(m_aNamedEntries, rRanges, 4393 pDocSh, aName, aRange)) 4394 throw container::NoSuchElementException(); 4395 4396 uno::Reference<table::XCellRange> xRange; 4397 if ( aRange.aStart == aRange.aEnd ) 4398 xRange.set(new ScCellObj( pDocSh, aRange.aStart )); 4399 else 4400 xRange.set(new ScCellRangeObj( pDocSh, aRange )); 4401 aRet <<= xRange; 4402 4403 return aRet; 4404 } 4405 4406 static bool lcl_FindEntryName( const std::vector<ScCellRangesObj::ScNamedEntry>& rNamedEntries, 4407 const ScRange& rRange, OUString& rName ) 4408 { 4409 sal_uInt16 nCount = rNamedEntries.size(); 4410 for (sal_uInt16 i=0; i<nCount; i++) 4411 if (rNamedEntries[i].GetRange() == rRange) 4412 { 4413 rName = rNamedEntries[i].GetName(); 4414 return true; 4415 } 4416 return false; 4417 } 4418 4419 uno::Sequence<OUString> SAL_CALL ScCellRangesObj::getElementNames() 4420 { 4421 SolarMutexGuard aGuard; 4422 4423 ScDocShell* pDocSh = GetDocShell(); 4424 const ScRangeList& rRanges = GetRangeList(); 4425 if (pDocSh) 4426 { 4427 OUString aRangeStr; 4428 ScDocument& rDoc = pDocSh->GetDocument(); 4429 size_t nCount = rRanges.size(); 4430 4431 uno::Sequence<OUString> aSeq(nCount); 4432 OUString* pAry = aSeq.getArray(); 4433 for (size_t i=0; i < nCount; i++) 4434 { 4435 // use given name if for exactly this range, otherwise just format 4436 ScRange const & rRange = rRanges[ i ]; 4437 if (m_aNamedEntries.empty() || 4438 !lcl_FindEntryName(m_aNamedEntries, rRange, aRangeStr)) 4439 { 4440 aRangeStr = rRange.Format(rDoc, ScRefFlags::VALID | ScRefFlags::TAB_3D); 4441 } 4442 pAry[i] = aRangeStr; 4443 } 4444 return aSeq; 4445 } 4446 return {}; 4447 } 4448 4449 sal_Bool SAL_CALL ScCellRangesObj::hasByName( const OUString& aName ) 4450 { 4451 SolarMutexGuard aGuard; 4452 ScDocShell* pDocSh = GetDocShell(); 4453 const ScRangeList& rRanges = GetRangeList(); 4454 ScRange aRange; 4455 return lcl_FindRangeOrEntry(m_aNamedEntries, rRanges, pDocSh, 4456 aName, aRange); 4457 } 4458 4459 // XEnumerationAccess 4460 4461 uno::Reference<container::XEnumeration> SAL_CALL ScCellRangesObj::createEnumeration() 4462 { 4463 SolarMutexGuard aGuard; 4464 return new ScIndexEnumeration(this, "com.sun.star.sheet.SheetCellRangesEnumeration"); 4465 } 4466 4467 // XIndexAccess 4468 4469 sal_Int32 SAL_CALL ScCellRangesObj::getCount() 4470 { 4471 SolarMutexGuard aGuard; 4472 const ScRangeList& rRanges = GetRangeList(); 4473 return rRanges.size(); 4474 } 4475 4476 uno::Any SAL_CALL ScCellRangesObj::getByIndex( sal_Int32 nIndex ) 4477 { 4478 SolarMutexGuard aGuard; 4479 uno::Reference<table::XCellRange> xRange(GetObjectByIndex_Impl(nIndex)); 4480 if (!xRange.is()) 4481 throw lang::IndexOutOfBoundsException(); 4482 4483 return uno::Any(xRange); 4484 4485 } 4486 4487 uno::Type SAL_CALL ScCellRangesObj::getElementType() 4488 { 4489 return cppu::UnoType<table::XCellRange>::get(); 4490 } 4491 4492 sal_Bool SAL_CALL ScCellRangesObj::hasElements() 4493 { 4494 SolarMutexGuard aGuard; 4495 const ScRangeList& rRanges = GetRangeList(); 4496 return !rRanges.empty(); 4497 } 4498 4499 // XServiceInfo 4500 OUString SAL_CALL ScCellRangesObj::getImplementationName() 4501 { 4502 return "ScCellRangesObj"; 4503 } 4504 4505 sal_Bool SAL_CALL ScCellRangesObj::supportsService( const OUString& rServiceName ) 4506 { 4507 return cppu::supportsService(this, rServiceName); 4508 } 4509 4510 uno::Sequence<OUString> SAL_CALL ScCellRangesObj::getSupportedServiceNames() 4511 { 4512 return {SCSHEETCELLRANGES_SERVICE, 4513 SCCELLPROPERTIES_SERVICE, 4514 SCCHARPROPERTIES_SERVICE, 4515 SCPARAPROPERTIES_SERVICE}; 4516 } 4517 4518 uno::Reference<table::XCellRange> ScCellRangeObj::CreateRangeFromDoc( const ScDocument& rDoc, const ScRange& rR ) 4519 { 4520 SfxObjectShell* pObjSh = rDoc.GetDocumentShell(); 4521 if ( auto pDocShell = dynamic_cast<ScDocShell*>( pObjSh) ) 4522 return new ScCellRangeObj( pDocShell, rR ); 4523 return nullptr; 4524 } 4525 4526 ScCellRangeObj::ScCellRangeObj(ScDocShell* pDocSh, const ScRange& rR) : 4527 ScCellRangesBase( pDocSh, rR ), 4528 pRangePropSet( lcl_GetRangePropertySet() ), 4529 aRange( rR ) 4530 { 4531 aRange.PutInOrder(); // beginning / end correct 4532 } 4533 4534 ScCellRangeObj::~ScCellRangeObj() 4535 { 4536 } 4537 4538 void ScCellRangeObj::RefChanged() 4539 { 4540 ScCellRangesBase::RefChanged(); 4541 4542 const ScRangeList& rRanges = GetRangeList(); 4543 OSL_ENSURE(rRanges.size() == 1, "What ranges ?!?!"); 4544 if ( !rRanges.empty() ) 4545 { 4546 const ScRange & rFirst = rRanges[0]; 4547 aRange = rFirst; 4548 aRange.PutInOrder(); 4549 } 4550 } 4551 4552 uno::Any SAL_CALL ScCellRangeObj::queryInterface( const uno::Type& rType ) 4553 { 4554 SC_QUERYINTERFACE( sheet::XCellRangeAddressable ) 4555 SC_QUERYINTERFACE( table::XCellRange ) 4556 SC_QUERYINTERFACE( sheet::XSheetCellRange ) 4557 SC_QUERYINTERFACE( sheet::XArrayFormulaRange ) 4558 SC_QUERYINTERFACE( sheet::XArrayFormulaTokens ) 4559 SC_QUERYINTERFACE( sheet::XCellRangeData ) 4560 SC_QUERYINTERFACE( sheet::XCellRangeFormula ) 4561 SC_QUERYINTERFACE( sheet::XMultipleOperation ) 4562 SC_QUERYINTERFACE( util::XMergeable ) 4563 SC_QUERYINTERFACE( sheet::XCellSeries ) 4564 SC_QUERYINTERFACE( table::XAutoFormattable ) 4565 SC_QUERYINTERFACE( util::XSortable ) 4566 SC_QUERYINTERFACE( sheet::XSheetFilterableEx ) 4567 SC_QUERYINTERFACE( sheet::XSheetFilterable ) 4568 SC_QUERYINTERFACE( sheet::XSubTotalCalculatable ) 4569 SC_QUERYINTERFACE( table::XColumnRowRange ) 4570 SC_QUERYINTERFACE( util::XImportable ) 4571 SC_QUERYINTERFACE( sheet::XCellFormatRangesSupplier ) 4572 SC_QUERYINTERFACE( sheet::XUniqueCellFormatRangesSupplier ) 4573 4574 return ScCellRangesBase::queryInterface( rType ); 4575 } 4576 4577 void SAL_CALL ScCellRangeObj::acquire() noexcept 4578 { 4579 ScCellRangesBase::acquire(); 4580 } 4581 4582 void SAL_CALL ScCellRangeObj::release() noexcept 4583 { 4584 ScCellRangesBase::release(); 4585 } 4586 4587 uno::Sequence<uno::Type> SAL_CALL ScCellRangeObj::getTypes() 4588 { 4589 static const uno::Sequence<uno::Type> aTypes = comphelper::concatSequences( 4590 ScCellRangesBase::getTypes(), 4591 uno::Sequence<uno::Type> 4592 { 4593 cppu::UnoType<sheet::XCellRangeAddressable>::get(), 4594 cppu::UnoType<sheet::XSheetCellRange>::get(), 4595 cppu::UnoType<sheet::XArrayFormulaRange>::get(), 4596 cppu::UnoType<sheet::XArrayFormulaTokens>::get(), 4597 cppu::UnoType<sheet::XCellRangeData>::get(), 4598 cppu::UnoType<sheet::XCellRangeFormula>::get(), 4599 cppu::UnoType<sheet::XMultipleOperation>::get(), 4600 cppu::UnoType<util::XMergeable>::get(), 4601 cppu::UnoType<sheet::XCellSeries>::get(), 4602 cppu::UnoType<table::XAutoFormattable>::get(), 4603 cppu::UnoType<util::XSortable>::get(), 4604 cppu::UnoType<sheet::XSheetFilterableEx>::get(), 4605 cppu::UnoType<sheet::XSubTotalCalculatable>::get(), 4606 cppu::UnoType<table::XColumnRowRange>::get(), 4607 cppu::UnoType<util::XImportable>::get(), 4608 cppu::UnoType<sheet::XCellFormatRangesSupplier>::get(), 4609 cppu::UnoType<sheet::XUniqueCellFormatRangesSupplier>::get() 4610 } ); 4611 return aTypes; 4612 } 4613 4614 uno::Sequence<sal_Int8> SAL_CALL ScCellRangeObj::getImplementationId() 4615 { 4616 return css::uno::Sequence<sal_Int8>(); 4617 } 4618 4619 // XCellRange 4620 4621 // ColumnCount / RowCount vanished 4622 //! are used in Writer for tables ??? 4623 4624 uno::Reference<table::XCell> ScCellRangeObj::GetCellByPosition_Impl( 4625 sal_Int32 nColumn, sal_Int32 nRow ) 4626 { 4627 ScDocShell* pDocSh = GetDocShell(); 4628 if (!pDocSh) 4629 throw uno::RuntimeException(); 4630 4631 if ( nColumn >= 0 && nRow >= 0 ) 4632 { 4633 sal_Int32 nPosX = aRange.aStart.Col() + nColumn; 4634 sal_Int32 nPosY = aRange.aStart.Row() + nRow; 4635 4636 if ( nPosX <= aRange.aEnd.Col() && nPosY <= aRange.aEnd.Row() ) 4637 { 4638 ScAddress aNew( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), aRange.aStart.Tab() ); 4639 return new ScCellObj( pDocSh, aNew ); 4640 } 4641 } 4642 4643 throw lang::IndexOutOfBoundsException(); 4644 } 4645 4646 uno::Reference<table::XCell> SAL_CALL ScCellRangeObj::getCellByPosition( 4647 sal_Int32 nColumn, sal_Int32 nRow ) 4648 { 4649 SolarMutexGuard aGuard; 4650 4651 return GetCellByPosition_Impl(nColumn, nRow); 4652 } 4653 4654 uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByPosition( 4655 sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) 4656 { 4657 SolarMutexGuard aGuard; 4658 4659 ScDocShell* pDocSh = GetDocShell(); 4660 if (!pDocSh) 4661 throw uno::RuntimeException(); 4662 4663 if ( nLeft >= 0 && nTop >= 0 && nRight >= 0 && nBottom >= 0 ) 4664 { 4665 sal_Int32 nStartX = aRange.aStart.Col() + nLeft; 4666 sal_Int32 nStartY = aRange.aStart.Row() + nTop; 4667 sal_Int32 nEndX = aRange.aStart.Col() + nRight; 4668 sal_Int32 nEndY = aRange.aStart.Row() + nBottom; 4669 4670 if ( nStartX <= nEndX && nEndX <= aRange.aEnd.Col() && 4671 nStartY <= nEndY && nEndY <= aRange.aEnd.Row() ) 4672 { 4673 ScRange aNew( static_cast<SCCOL>(nStartX), static_cast<SCROW>(nStartY), aRange.aStart.Tab(), 4674 static_cast<SCCOL>(nEndX), static_cast<SCROW>(nEndY), aRange.aEnd.Tab() ); 4675 return new ScCellRangeObj( pDocSh, aNew ); 4676 } 4677 } 4678 4679 throw lang::IndexOutOfBoundsException(); 4680 } 4681 4682 uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByName( 4683 const OUString& aName ) 4684 { 4685 return getCellRangeByName( aName, ScAddress::detailsOOOa1 ); 4686 } 4687 4688 uno::Reference<table::XCellRange> ScCellRangeObj::getCellRangeByName( 4689 const OUString& aName, const ScAddress::Details& rDetails ) 4690 { 4691 // name refers to the whole document (with the range's table as default), 4692 // valid only if the range is within this range 4693 4694 SolarMutexGuard aGuard; 4695 ScDocShell* pDocSh = GetDocShell(); 4696 if ( pDocSh ) 4697 { 4698 ScDocument& rDoc = pDocSh->GetDocument(); 4699 SCTAB nTab = aRange.aStart.Tab(); 4700 4701 ScRange aCellRange; 4702 bool bFound = false; 4703 ScRefFlags nParse = aCellRange.ParseAny( aName, rDoc, rDetails ); 4704 if ( nParse & ScRefFlags::VALID ) 4705 { 4706 if ( !(nParse & ScRefFlags::TAB_3D) ) // no sheet specified -> this sheet 4707 { 4708 aCellRange.aStart.SetTab(nTab); 4709 aCellRange.aEnd.SetTab(nTab); 4710 } 4711 bFound = true; 4712 } 4713 else 4714 { 4715 if ( ScRangeUtil::MakeRangeFromName( aName, rDoc, nTab, aCellRange, RUTL_NAMES, rDetails) || 4716 ScRangeUtil::MakeRangeFromName( aName, rDoc, nTab, aCellRange, RUTL_DBASE, rDetails)) 4717 bFound = true; 4718 } 4719 4720 if (bFound) // valid only if within this object's range 4721 { 4722 if (!aRange.Contains(aCellRange)) 4723 bFound = false; 4724 } 4725 4726 if (bFound) 4727 { 4728 if ( aCellRange.aStart == aCellRange.aEnd ) 4729 return new ScCellObj( pDocSh, aCellRange.aStart ); 4730 else 4731 return new ScCellRangeObj( pDocSh, aCellRange ); 4732 } 4733 } 4734 4735 throw uno::RuntimeException(); 4736 } 4737 4738 // XColumnRowRange 4739 4740 uno::Reference<table::XTableColumns> SAL_CALL ScCellRangeObj::getColumns() 4741 { 4742 SolarMutexGuard aGuard; 4743 ScDocShell* pDocSh = GetDocShell(); 4744 if (pDocSh) 4745 return new ScTableColumnsObj( pDocSh, aRange.aStart.Tab(), 4746 aRange.aStart.Col(), aRange.aEnd.Col() ); 4747 4748 OSL_FAIL("Document invalid"); 4749 return nullptr; 4750 } 4751 4752 uno::Reference<table::XTableRows> SAL_CALL ScCellRangeObj::getRows() 4753 { 4754 SolarMutexGuard aGuard; 4755 ScDocShell* pDocSh = GetDocShell(); 4756 if (pDocSh) 4757 return new ScTableRowsObj( pDocSh, aRange.aStart.Tab(), 4758 aRange.aStart.Row(), aRange.aEnd.Row() ); 4759 4760 OSL_FAIL("Document invalid"); 4761 return nullptr; 4762 } 4763 4764 // XAddressableCellRange 4765 4766 table::CellRangeAddress SAL_CALL ScCellRangeObj::getRangeAddress() 4767 { 4768 SolarMutexGuard aGuard; 4769 table::CellRangeAddress aRet; 4770 ScUnoConversion::FillApiRange( aRet, aRange ); 4771 return aRet; 4772 } 4773 4774 // XSheetCellRange 4775 4776 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScCellRangeObj::getSpreadsheet() 4777 { 4778 SolarMutexGuard aGuard; 4779 ScDocShell* pDocSh = GetDocShell(); 4780 if (pDocSh) 4781 return new ScTableSheetObj( pDocSh, aRange.aStart.Tab() ); 4782 4783 OSL_FAIL("Document invalid"); 4784 return nullptr; 4785 } 4786 4787 // XArrayFormulaRange 4788 4789 OUString SAL_CALL ScCellRangeObj::getArrayFormula() 4790 { 4791 SolarMutexGuard aGuard; 4792 4793 // Matrix formula if clearly part of a matrix (so when start and end of 4794 // the block belong to the same matrix) else empty string. 4795 4796 ScDocShell* pDocSh = GetDocShell(); 4797 if (!pDocSh) 4798 return OUString(); 4799 4800 ScDocument& rDoc = pDocSh->GetDocument(); 4801 ScRefCellValue aCell1(rDoc, aRange.aStart); 4802 ScRefCellValue aCell2(rDoc, aRange.aEnd); 4803 if (aCell1.getType() == CELLTYPE_FORMULA && aCell2.getType() == CELLTYPE_FORMULA) 4804 { 4805 const ScFormulaCell* pFCell1 = aCell1.getFormula(); 4806 const ScFormulaCell* pFCell2 = aCell2.getFormula(); 4807 ScAddress aStart1; 4808 ScAddress aStart2; 4809 if (pFCell1->GetMatrixOrigin(rDoc, aStart1) && pFCell2->GetMatrixOrigin(rDoc, aStart2)) 4810 { 4811 if (aStart1 == aStart2) // both the same matrix 4812 return pFCell1->GetFormula(); // it doesn't matter from which cell 4813 } 4814 } 4815 return OUString(); 4816 } 4817 4818 void ScCellRangeObj::SetArrayFormula_Impl(const OUString& rFormula, 4819 const formula::FormulaGrammar::Grammar eGrammar) 4820 { 4821 ScDocShell* pDocSh = GetDocShell(); 4822 if (!pDocSh) 4823 return; 4824 4825 if ( !rFormula.isEmpty() ) 4826 { 4827 if ( comphelper::getFromUnoTunnel<ScTableSheetObj>( static_cast<cppu::OWeakObject*>(this) ) ) 4828 { 4829 // don't set array formula for sheet object 4830 throw uno::RuntimeException(); 4831 } 4832 4833 pDocSh->GetDocFunc().EnterMatrix( aRange, nullptr, nullptr, rFormula, true, true, OUString()/*rFormulaNmsp*/, eGrammar ); 4834 } 4835 else 4836 { 4837 // empty string -> erase array formula 4838 ScMarkData aMark(GetDocument()->GetSheetLimits()); 4839 aMark.SetMarkArea( aRange ); 4840 aMark.SelectTable( aRange.aStart.Tab(), true ); 4841 pDocSh->GetDocFunc().DeleteContents( aMark, InsertDeleteFlags::CONTENTS, true, true ); 4842 } 4843 } 4844 4845 void SAL_CALL ScCellRangeObj::setArrayFormula( const OUString& aFormula ) 4846 { 4847 SolarMutexGuard aGuard; 4848 // GRAM_API for API compatibility. 4849 SetArrayFormula_Impl( aFormula, formula::FormulaGrammar::GRAM_API); 4850 } 4851 4852 // XArrayFormulaTokens 4853 uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellRangeObj::getArrayTokens() 4854 { 4855 SolarMutexGuard aGuard; 4856 4857 // same cell logic as in getArrayFormula 4858 4859 uno::Sequence<sheet::FormulaToken> aSequence; 4860 ScDocShell* pDocSh = GetDocShell(); 4861 if (!pDocSh) 4862 return aSequence; 4863 4864 ScDocument& rDoc = pDocSh->GetDocument(); 4865 ScRefCellValue aCell1(rDoc, aRange.aStart); 4866 ScRefCellValue aCell2(rDoc, aRange.aEnd); 4867 if (aCell1.getType() == CELLTYPE_FORMULA && aCell2.getType() == CELLTYPE_FORMULA) 4868 { 4869 const ScFormulaCell* pFCell1 = aCell1.getFormula(); 4870 const ScFormulaCell* pFCell2 = aCell2.getFormula(); 4871 ScAddress aStart1; 4872 ScAddress aStart2; 4873 if (pFCell1->GetMatrixOrigin(rDoc, aStart1) && pFCell2->GetMatrixOrigin(rDoc, aStart2)) 4874 { 4875 if (aStart1 == aStart2) 4876 { 4877 const ScTokenArray* pTokenArray = pFCell1->GetCode(); 4878 if (pTokenArray) 4879 ScTokenConversion::ConvertToTokenSequence(rDoc, aSequence, *pTokenArray); 4880 } 4881 } 4882 } 4883 4884 return aSequence; 4885 } 4886 4887 void SAL_CALL ScCellRangeObj::setArrayTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) 4888 { 4889 SolarMutexGuard aGuard; 4890 ScDocShell* pDocSh = GetDocShell(); 4891 if ( !pDocSh ) 4892 return; 4893 4894 if ( rTokens.hasElements() ) 4895 { 4896 if ( comphelper::getFromUnoTunnel<ScTableSheetObj>( static_cast<cppu::OWeakObject*>(this) ) ) 4897 { 4898 throw uno::RuntimeException(); 4899 } 4900 4901 ScDocument& rDoc = pDocSh->GetDocument(); 4902 ScTokenArray aTokenArray(rDoc); 4903 (void)ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens ); 4904 4905 // Actually GRAM_API is a don't-care here because of the token 4906 // array being set, it fits with other API compatibility grammars 4907 // though. 4908 pDocSh->GetDocFunc().EnterMatrix( aRange, nullptr, &aTokenArray, OUString(), true, true, OUString(), formula::FormulaGrammar::GRAM_API ); 4909 } 4910 else 4911 { 4912 // empty sequence -> erase array formula 4913 ScMarkData aMark(pDocSh->GetDocument().GetSheetLimits()); 4914 aMark.SetMarkArea( aRange ); 4915 aMark.SelectTable( aRange.aStart.Tab(), true ); 4916 pDocSh->GetDocFunc().DeleteContents( aMark, InsertDeleteFlags::CONTENTS, true, true ); 4917 } 4918 } 4919 4920 // XCellRangeData 4921 4922 uno::Sequence< uno::Sequence<uno::Any> > SAL_CALL ScCellRangeObj::getDataArray() 4923 { 4924 SolarMutexGuard aGuard; 4925 4926 if ( comphelper::getFromUnoTunnel<ScTableSheetObj>( static_cast<cppu::OWeakObject*>(this) ) ) 4927 { 4928 // don't create a data array for the sheet 4929 throw uno::RuntimeException(); 4930 } 4931 4932 ScDocShell* pDocSh = GetDocShell(); 4933 if (pDocSh) 4934 { 4935 uno::Any aAny; 4936 // bAllowNV = TRUE: errors as void 4937 if ( ScRangeToSequence::FillMixedArray( aAny, pDocSh->GetDocument(), aRange, true ) ) 4938 { 4939 uno::Sequence< uno::Sequence<uno::Any> > aSeq; 4940 if ( aAny >>= aSeq ) 4941 return aSeq; // success 4942 } 4943 } 4944 4945 throw uno::RuntimeException(); // no other exceptions specified 4946 } 4947 4948 void SAL_CALL ScCellRangeObj::setDataArray( 4949 const uno::Sequence< uno::Sequence<uno::Any> >& aArray ) 4950 { 4951 SolarMutexGuard aGuard; 4952 4953 bool bDone = false; 4954 ScDocShell* pDocSh = GetDocShell(); 4955 if (pDocSh) 4956 { 4957 //! move lcl_PutDataArray to docfunc? 4958 bDone = lcl_PutDataArray( *pDocSh, aRange, aArray ); 4959 } 4960 4961 if (!bDone) 4962 throw uno::RuntimeException(); // no other exceptions specified 4963 } 4964 4965 // XCellRangeFormula 4966 4967 uno::Sequence< uno::Sequence<OUString> > SAL_CALL ScCellRangeObj::getFormulaArray() 4968 { 4969 SolarMutexGuard aGuard; 4970 4971 if ( comphelper::getFromUnoTunnel<ScTableSheetObj>( static_cast<cppu::OWeakObject*>(this) ) ) 4972 { 4973 // don't create a data array for the sheet 4974 throw uno::RuntimeException(); 4975 } 4976 4977 ScDocShell* pDocSh = GetDocShell(); 4978 if (pDocSh) 4979 { 4980 SCCOL nStartCol = aRange.aStart.Col(); 4981 SCROW nStartRow = aRange.aStart.Row(); 4982 SCCOL nEndCol = aRange.aEnd.Col(); 4983 SCROW nEndRow = aRange.aEnd.Row(); 4984 SCCOL nColCount = nEndCol + 1 - nStartCol; 4985 SCROW nRowCount = nEndRow + 1 - nStartRow; 4986 SCTAB nTab = aRange.aStart.Tab(); 4987 4988 uno::Sequence< uno::Sequence<OUString> > aRowSeq( nRowCount ); 4989 uno::Sequence<OUString>* pRowAry = aRowSeq.getArray(); 4990 for (SCROW nRowIndex = 0; nRowIndex < nRowCount; nRowIndex++) 4991 { 4992 uno::Sequence<OUString> aColSeq( nColCount ); 4993 OUString* pColAry = aColSeq.getArray(); 4994 for (SCCOL nColIndex = 0; nColIndex < nColCount; nColIndex++) 4995 pColAry[nColIndex] = lcl_GetInputString( pDocSh->GetDocument(), 4996 ScAddress( nStartCol+nColIndex, nStartRow+nRowIndex, nTab ), true ); 4997 4998 pRowAry[nRowIndex] = aColSeq; 4999 } 5000 5001 return aRowSeq; 5002 } 5003 5004 throw uno::RuntimeException(); // no other exceptions specified 5005 } 5006 5007 void SAL_CALL ScCellRangeObj::setFormulaArray( 5008 const uno::Sequence< uno::Sequence<OUString> >& aArray ) 5009 { 5010 SolarMutexGuard aGuard; 5011 5012 bool bDone = false; 5013 ScDocShell* pDocSh = GetDocShell(); 5014 if (pDocSh) 5015 { 5016 ScExternalRefManager::ApiGuard aExtRefGuard(pDocSh->GetDocument()); 5017 5018 // GRAM_API for API compatibility. 5019 bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray, formula::FormulaGrammar::GRAM_API ); 5020 } 5021 5022 if (!bDone) 5023 throw uno::RuntimeException(); // no other exceptions specified 5024 } 5025 5026 // XMultipleOperation 5027 5028 void SAL_CALL ScCellRangeObj::setTableOperation( const table::CellRangeAddress& aFormulaRange, 5029 sheet::TableOperationMode nMode, 5030 const table::CellAddress& aColumnCell, 5031 const table::CellAddress& aRowCell ) 5032 { 5033 SolarMutexGuard aGuard; 5034 ScDocShell* pDocSh = GetDocShell(); 5035 if (!pDocSh) 5036 return; 5037 5038 bool bError = false; 5039 ScTabOpParam aParam; 5040 aParam.aRefFormulaCell = ScRefAddress( static_cast<SCCOL>(aFormulaRange.StartColumn), 5041 static_cast<SCROW>(aFormulaRange.StartRow), aFormulaRange.Sheet ); 5042 aParam.aRefFormulaEnd = ScRefAddress( static_cast<SCCOL>(aFormulaRange.EndColumn), 5043 static_cast<SCROW>(aFormulaRange.EndRow), aFormulaRange.Sheet ); 5044 aParam.aRefRowCell = ScRefAddress( static_cast<SCCOL>(aRowCell.Column), 5045 static_cast<SCROW>(aRowCell.Row), aRowCell.Sheet ); 5046 aParam.aRefColCell = ScRefAddress( static_cast<SCCOL>(aColumnCell.Column), 5047 static_cast<SCROW>(aColumnCell.Row), aColumnCell.Sheet ); 5048 5049 switch (nMode) 5050 { 5051 case sheet::TableOperationMode_COLUMN: 5052 aParam.meMode = ScTabOpParam::Column; 5053 break; 5054 case sheet::TableOperationMode_ROW: 5055 aParam.meMode = ScTabOpParam::Row; 5056 break; 5057 case sheet::TableOperationMode_BOTH: 5058 aParam.meMode = ScTabOpParam::Both; 5059 break; 5060 default: 5061 bError = true; 5062 } 5063 5064 if (!bError) 5065 pDocSh->GetDocFunc().TabOp( aRange, nullptr, aParam, true, true ); 5066 } 5067 5068 // XMergeable 5069 5070 void SAL_CALL ScCellRangeObj::merge( sal_Bool bMerge ) 5071 { 5072 SolarMutexGuard aGuard; 5073 ScDocShell* pDocSh = GetDocShell(); 5074 if ( !pDocSh ) 5075 return; 5076 5077 ScCellMergeOption aMergeOption( 5078 aRange.aStart.Col(), aRange.aStart.Row(), 5079 aRange.aEnd.Col(), aRange.aEnd.Row(), false); 5080 aMergeOption.maTabs.insert(aRange.aStart.Tab()); 5081 if ( bMerge ) 5082 pDocSh->GetDocFunc().MergeCells( aMergeOption, false, true, true ); 5083 else 5084 pDocSh->GetDocFunc().UnmergeCells( aMergeOption, true, nullptr ); 5085 5086 //! Catch error? 5087 } 5088 5089 sal_Bool SAL_CALL ScCellRangeObj::getIsMerged() 5090 { 5091 SolarMutexGuard aGuard; 5092 ScDocShell* pDocSh = GetDocShell(); 5093 return pDocSh && pDocSh->GetDocument().HasAttrib( aRange, HasAttrFlags::Merged ); 5094 } 5095 5096 // XCellSeries 5097 5098 void SAL_CALL ScCellRangeObj::fillSeries( sheet::FillDirection nFillDirection, 5099 sheet::FillMode nFillMode, sheet::FillDateMode nFillDateMode, 5100 double fStep, double fEndValue ) 5101 { 5102 SolarMutexGuard aGuard; 5103 ScDocShell* pDocSh = GetDocShell(); 5104 if ( !pDocSh ) 5105 return; 5106 5107 bool bError = false; 5108 5109 FillDir eDir = FILL_TO_BOTTOM; 5110 switch (nFillDirection) 5111 { 5112 case sheet::FillDirection_TO_BOTTOM: 5113 eDir = FILL_TO_BOTTOM; 5114 break; 5115 case sheet::FillDirection_TO_RIGHT: 5116 eDir = FILL_TO_RIGHT; 5117 break; 5118 case sheet::FillDirection_TO_TOP: 5119 eDir = FILL_TO_TOP; 5120 break; 5121 case sheet::FillDirection_TO_LEFT: 5122 eDir = FILL_TO_LEFT; 5123 break; 5124 default: 5125 bError = true; 5126 } 5127 5128 FillCmd eCmd = FILL_SIMPLE; 5129 switch ( nFillMode ) 5130 { 5131 case sheet::FillMode_SIMPLE: 5132 eCmd = FILL_SIMPLE; 5133 break; 5134 case sheet::FillMode_LINEAR: 5135 eCmd = FILL_LINEAR; 5136 break; 5137 case sheet::FillMode_GROWTH: 5138 eCmd = FILL_GROWTH; 5139 break; 5140 case sheet::FillMode_DATE: 5141 eCmd = FILL_DATE; 5142 break; 5143 case sheet::FillMode_AUTO: 5144 eCmd = FILL_AUTO; 5145 break; 5146 default: 5147 bError = true; 5148 } 5149 5150 FillDateCmd eDateCmd = FILL_DAY; 5151 switch ( nFillDateMode ) 5152 { 5153 case sheet::FillDateMode_FILL_DATE_DAY: 5154 eDateCmd = FILL_DAY; 5155 break; 5156 case sheet::FillDateMode_FILL_DATE_WEEKDAY: 5157 eDateCmd = FILL_WEEKDAY; 5158 break; 5159 case sheet::FillDateMode_FILL_DATE_MONTH: 5160 eDateCmd = FILL_MONTH; 5161 break; 5162 case sheet::FillDateMode_FILL_DATE_YEAR: 5163 eDateCmd = FILL_YEAR; 5164 break; 5165 default: 5166 bError = true; 5167 } 5168 5169 if (!bError) 5170 pDocSh->GetDocFunc().FillSeries( aRange, nullptr, eDir, eCmd, eDateCmd, 5171 MAXDOUBLE, fStep, fEndValue, true ); 5172 } 5173 5174 void SAL_CALL ScCellRangeObj::fillAuto( sheet::FillDirection nFillDirection, 5175 sal_Int32 nSourceCount ) 5176 { 5177 SolarMutexGuard aGuard; 5178 ScDocShell* pDocSh = GetDocShell(); 5179 if ( !(pDocSh && nSourceCount) ) 5180 return; 5181 5182 ScRange aSourceRange(aRange); 5183 SCCOLROW nCount = 0; // "Dest-Count" 5184 FillDir eDir = FILL_TO_BOTTOM; 5185 bool bError = false; 5186 switch (nFillDirection) 5187 { 5188 case sheet::FillDirection_TO_BOTTOM: 5189 aSourceRange.aEnd.SetRow( static_cast<SCROW>( aSourceRange.aStart.Row() + nSourceCount - 1 ) ); 5190 nCount = aRange.aEnd.Row() - aSourceRange.aEnd.Row(); 5191 eDir = FILL_TO_BOTTOM; 5192 break; 5193 case sheet::FillDirection_TO_RIGHT: 5194 aSourceRange.aEnd.SetCol( static_cast<SCCOL>( aSourceRange.aStart.Col() + nSourceCount - 1 ) ); 5195 nCount = aRange.aEnd.Col() - aSourceRange.aEnd.Col(); 5196 eDir = FILL_TO_RIGHT; 5197 break; 5198 case sheet::FillDirection_TO_TOP: 5199 aSourceRange.aStart.SetRow( static_cast<SCROW>( aSourceRange.aEnd.Row() - nSourceCount + 1 ) ); 5200 nCount = aSourceRange.aStart.Row() - aRange.aStart.Row(); 5201 eDir = FILL_TO_TOP; 5202 break; 5203 case sheet::FillDirection_TO_LEFT: 5204 aSourceRange.aStart.SetCol( static_cast<SCCOL>( aSourceRange.aEnd.Col() - nSourceCount + 1 ) ); 5205 nCount = aSourceRange.aStart.Col() - aRange.aStart.Col(); 5206 eDir = FILL_TO_LEFT; 5207 break; 5208 default: 5209 bError = true; 5210 } 5211 const ScDocument& rDoc = pDocSh->GetDocument(); 5212 if (nCount < 0 || nCount > rDoc.MaxRow()) // overflow 5213 bError = true; 5214 5215 if (!bError) 5216 pDocSh->GetDocFunc().FillAuto( aSourceRange, nullptr, eDir, nCount, true ); 5217 } 5218 5219 // XAutoFormattable 5220 5221 void SAL_CALL ScCellRangeObj::autoFormat( const OUString& aName ) 5222 { 5223 SolarMutexGuard aGuard; 5224 ScDocShell* pDocSh = GetDocShell(); 5225 if ( pDocSh ) 5226 { 5227 ScAutoFormat* pAutoFormat = ScGlobal::GetOrCreateAutoFormat(); 5228 ScAutoFormat::const_iterator it = pAutoFormat->find(aName); 5229 if (it == pAutoFormat->end()) 5230 throw lang::IllegalArgumentException(); 5231 5232 ScAutoFormat::const_iterator itBeg = pAutoFormat->begin(); 5233 size_t nIndex = std::distance(itBeg, it); 5234 pDocSh->GetDocFunc().AutoFormat(aRange, nullptr, nIndex, true); 5235 5236 } 5237 } 5238 5239 // XSortable 5240 5241 uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createSortDescriptor() 5242 { 5243 SolarMutexGuard aGuard; 5244 ScSortParam aParam; 5245 ScDocShell* pDocSh = GetDocShell(); 5246 if ( pDocSh ) 5247 { 5248 // create DB-Area only during execution; API always the exact area 5249 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark ); 5250 if (pData) 5251 { 5252 pData->GetSortParam(aParam); 5253 5254 // SortDescriptor contains the counted fields inside the area 5255 ScRange aDBRange; 5256 pData->GetArea(aDBRange); 5257 SCCOLROW nFieldStart = aParam.bByRow ? 5258 static_cast<SCCOLROW>(aDBRange.aStart.Col()) : 5259 static_cast<SCCOLROW>(aDBRange.aStart.Row()); 5260 for (sal_uInt16 i=0; i<aParam.GetSortKeyCount(); i++) 5261 if ( aParam.maKeyState[i].bDoSort && aParam.maKeyState[i].nField >= nFieldStart ) 5262 aParam.maKeyState[i].nField -= nFieldStart; 5263 } 5264 } 5265 5266 uno::Sequence<beans::PropertyValue> aSeq( ScSortDescriptor::GetPropertyCount() ); 5267 ScSortDescriptor::FillProperties( aSeq, aParam ); 5268 return aSeq; 5269 } 5270 5271 void SAL_CALL ScCellRangeObj::sort( const uno::Sequence<beans::PropertyValue>& aDescriptor ) 5272 { 5273 SolarMutexGuard aGuard; 5274 ScDocShell* pDocSh = GetDocShell(); 5275 if (!pDocSh) 5276 return; 5277 5278 sal_uInt16 i; 5279 ScSortParam aParam; 5280 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area 5281 if (pData) 5282 { 5283 // get old settings if not everything is set anew 5284 pData->GetSortParam(aParam); 5285 SCCOLROW nOldStart = aParam.bByRow ? 5286 static_cast<SCCOLROW>(aRange.aStart.Col()) : 5287 static_cast<SCCOLROW>(aRange.aStart.Row()); 5288 for (i=0; i<aParam.GetSortKeyCount(); i++) 5289 if ( aParam.maKeyState[i].bDoSort && aParam.maKeyState[i].nField >= nOldStart ) 5290 aParam.maKeyState[i].nField -= nOldStart; 5291 } 5292 5293 ScSortDescriptor::FillSortParam( aParam, aDescriptor ); 5294 5295 // SortDescriptor contains the counted fields inside the area 5296 // ByRow can be changed during execution of FillSortParam 5297 SCCOLROW nFieldStart = aParam.bByRow ? 5298 static_cast<SCCOLROW>(aRange.aStart.Col()) : 5299 static_cast<SCCOLROW>(aRange.aStart.Row()); 5300 SCCOLROW nFieldEnd = aParam.bByRow ? 5301 static_cast<SCCOLROW>(aRange.aEnd.Col()) : 5302 static_cast<SCCOLROW>(aRange.aEnd.Row()); 5303 for (i=0; i<aParam.GetSortKeyCount(); i++) 5304 { 5305 aParam.maKeyState[i].nField += nFieldStart; 5306 // tdf#103632 - sanity check poorly behaved macros. 5307 if (aParam.maKeyState[i].nField > nFieldEnd) 5308 aParam.maKeyState[i].nField = nFieldEnd; 5309 } 5310 5311 SCTAB nTab = aRange.aStart.Tab(); 5312 aParam.nCol1 = aRange.aStart.Col(); 5313 aParam.nRow1 = aRange.aStart.Row(); 5314 aParam.nCol2 = aRange.aEnd.Col(); 5315 aParam.nRow2 = aRange.aEnd.Row(); 5316 5317 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area 5318 5319 ScDBDocFunc aFunc(*pDocSh); // area must be created 5320 (void)aFunc.Sort( nTab, aParam, true, true, true ); 5321 } 5322 5323 // XFilterable 5324 5325 uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFilterDescriptor( 5326 sal_Bool bEmpty ) 5327 { 5328 SolarMutexGuard aGuard; 5329 ScDocShell* pDocSh = GetDocShell(); 5330 rtl::Reference<ScFilterDescriptor> pNew = new ScFilterDescriptor(pDocSh); 5331 if ( !bEmpty && pDocSh ) 5332 { 5333 // create DB-Area only during execution; API always the exact area 5334 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark ); 5335 if (pData) 5336 { 5337 ScQueryParam aParam; 5338 pData->GetQueryParam(aParam); 5339 // FilterDescriptor contains the counted fields inside the area 5340 ScRange aDBRange; 5341 pData->GetArea(aDBRange); 5342 SCCOLROW nFieldStart = aParam.bByRow ? 5343 static_cast<SCCOLROW>(aDBRange.aStart.Col()) : 5344 static_cast<SCCOLROW>(aDBRange.aStart.Row()); 5345 SCSIZE nCount = aParam.GetEntryCount(); 5346 for (SCSIZE i=0; i<nCount; i++) 5347 { 5348 ScQueryEntry& rEntry = aParam.GetEntry(i); 5349 if (rEntry.bDoQuery && rEntry.nField >= nFieldStart) 5350 rEntry.nField -= nFieldStart; 5351 } 5352 pNew->SetParam(aParam); 5353 } 5354 } 5355 return pNew; 5356 } 5357 5358 void SAL_CALL ScCellRangeObj::filter( const uno::Reference<sheet::XSheetFilterDescriptor>& xDescriptor ) 5359 { 5360 SolarMutexGuard aGuard; 5361 5362 if (!xDescriptor.is()) return; 5363 5364 // This could be theoretically an unknown object, so only use the 5365 // public XSheetFilterDescriptor interface to copy the data into a 5366 // ScFilterDescriptor object: 5367 //! if it already a ScFilterDescriptor is, direct via getImplementation? 5368 5369 ScDocShell* pDocSh = GetDocShell(); 5370 rtl::Reference<ScFilterDescriptor> xImpl(new ScFilterDescriptor(pDocSh)); 5371 uno::Reference< sheet::XSheetFilterDescriptor2 > xDescriptor2( xDescriptor, uno::UNO_QUERY ); 5372 if ( xDescriptor2.is() ) 5373 { 5374 xImpl->setFilterFields2( xDescriptor2->getFilterFields2() ); 5375 } 5376 else 5377 { 5378 xImpl->setFilterFields( xDescriptor->getFilterFields() ); 5379 } 5380 // the rest are now properties... 5381 5382 uno::Reference<beans::XPropertySet> xPropSet( xDescriptor, uno::UNO_QUERY ); 5383 if (xPropSet.is()) 5384 lcl_CopyProperties(*xImpl, *xPropSet); 5385 5386 if (!pDocSh) 5387 return; 5388 5389 ScQueryParam aParam = xImpl->GetParam(); 5390 // FilterDescriptor contains the counted fields inside the area 5391 SCCOLROW nFieldStart = aParam.bByRow ? 5392 static_cast<SCCOLROW>(aRange.aStart.Col()) : 5393 static_cast<SCCOLROW>(aRange.aStart.Row()); 5394 SCSIZE nCount = aParam.GetEntryCount(); 5395 svl::SharedStringPool& rPool = pDocSh->GetDocument().GetSharedStringPool(); 5396 for (SCSIZE i=0; i<nCount; i++) 5397 { 5398 ScQueryEntry& rEntry = aParam.GetEntry(i); 5399 if (rEntry.bDoQuery) 5400 { 5401 rEntry.nField += nFieldStart; 5402 // dialog always shows the string -> must match the value 5403 ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems(); 5404 rItems.resize(1); 5405 ScQueryEntry::Item& rItem = rItems.front(); 5406 if (rItem.meType != ScQueryEntry::ByString) 5407 { 5408 OUString aStr; 5409 pDocSh->GetDocument().GetFormatTable()->GetInputLineString(rItem.mfVal, 0, aStr); 5410 rItem.maString = rPool.intern(aStr); 5411 } 5412 } 5413 } 5414 5415 SCTAB nTab = aRange.aStart.Tab(); 5416 aParam.nCol1 = aRange.aStart.Col(); 5417 aParam.nRow1 = aRange.aStart.Row(); 5418 aParam.nCol2 = aRange.aEnd.Col(); 5419 aParam.nRow2 = aRange.aEnd.Row(); 5420 5421 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area 5422 5423 //! keep source range in filter descriptor 5424 //! if created by createFilterDescriptorByObject ??? 5425 5426 ScDBDocFunc aFunc(*pDocSh); 5427 aFunc.Query( nTab, aParam, nullptr, true, true ); // area must be created 5428 } 5429 5430 //! get/setAutoFilter as properties!!! 5431 5432 // XAdvancedFilterSource 5433 5434 uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScCellRangeObj::createFilterDescriptorByObject( 5435 const uno::Reference<sheet::XSheetFilterable>& xObject ) 5436 { 5437 SolarMutexGuard aGuard; 5438 5439 // this here is not the area, which will be filtered, instead the area 5440 // with the query 5441 5442 uno::Reference<sheet::XCellRangeAddressable> xAddr( xObject, uno::UNO_QUERY ); 5443 5444 ScDocShell* pDocSh = GetDocShell(); 5445 if ( !pDocSh || !xAddr.is() ) 5446 { 5447 OSL_FAIL("no document or no area"); 5448 return nullptr; 5449 } 5450 5451 //! check if xObject is in the same document 5452 5453 rtl::Reference<ScFilterDescriptor> pNew(new ScFilterDescriptor(pDocSh)); //! instead from object? 5454 5455 ScQueryParam aParam = pNew->GetParam(); 5456 aParam.bHasHeader = true; 5457 5458 table::CellRangeAddress aDataAddress(xAddr->getRangeAddress()); 5459 aParam.nCol1 = static_cast<SCCOL>(aDataAddress.StartColumn); 5460 aParam.nRow1 = static_cast<SCROW>(aDataAddress.StartRow); 5461 aParam.nCol2 = static_cast<SCCOL>(aDataAddress.EndColumn); 5462 aParam.nRow2 = static_cast<SCROW>(aDataAddress.EndRow); 5463 aParam.nTab = aDataAddress.Sheet; 5464 5465 ScDocument& rDoc = pDocSh->GetDocument(); 5466 if (!rDoc.CreateQueryParam(aRange, aParam)) 5467 return nullptr; 5468 5469 // FilterDescriptor contains the counted fields inside the area 5470 SCCOLROW nFieldStart = aParam.bByRow ? 5471 static_cast<SCCOLROW>(aDataAddress.StartColumn) : 5472 static_cast<SCCOLROW>(aDataAddress.StartRow); 5473 SCSIZE nCount = aParam.GetEntryCount(); 5474 for (SCSIZE i=0; i<nCount; i++) 5475 { 5476 ScQueryEntry& rEntry = aParam.GetEntry(i); 5477 if (rEntry.bDoQuery && rEntry.nField >= nFieldStart) 5478 rEntry.nField -= nFieldStart; 5479 } 5480 5481 pNew->SetParam( aParam ); 5482 return pNew; 5483 } 5484 5485 // XSubTotalSource 5486 5487 uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL ScCellRangeObj::createSubTotalDescriptor( 5488 sal_Bool bEmpty ) 5489 { 5490 SolarMutexGuard aGuard; 5491 rtl::Reference<ScSubTotalDescriptor> pNew = new ScSubTotalDescriptor; 5492 ScDocShell* pDocSh = GetDocShell(); 5493 if ( !bEmpty && pDocSh ) 5494 { 5495 // create DB-Area only during execution; API always the exact area 5496 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark ); 5497 if (pData) 5498 { 5499 ScSubTotalParam aParam; 5500 pData->GetSubTotalParam(aParam); 5501 // SubTotalDescriptor contains the counted fields inside the area 5502 ScRange aDBRange; 5503 pData->GetArea(aDBRange); 5504 SCCOL nFieldStart = aDBRange.aStart.Col(); 5505 for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) 5506 { 5507 if ( aParam.bGroupActive[i] ) 5508 { 5509 if ( aParam.nField[i] >= nFieldStart ) 5510 aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] - nFieldStart ); 5511 for (SCCOL j=0; j<aParam.nSubTotals[i]; j++) 5512 if ( aParam.pSubTotals[i][j] >= nFieldStart ) 5513 aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] - nFieldStart ); 5514 } 5515 } 5516 pNew->SetParam(aParam); 5517 } 5518 } 5519 return pNew; 5520 } 5521 5522 void SAL_CALL ScCellRangeObj::applySubTotals( 5523 const uno::Reference<sheet::XSubTotalDescriptor>& xDescriptor, 5524 sal_Bool bReplace) 5525 { 5526 SolarMutexGuard aGuard; 5527 5528 if (!xDescriptor.is()) return; 5529 5530 ScDocShell* pDocSh = GetDocShell(); 5531 ScSubTotalDescriptorBase* pImp = 5532 comphelper::getFromUnoTunnel<ScSubTotalDescriptorBase>( xDescriptor ); 5533 5534 if (!(pDocSh && pImp)) 5535 return; 5536 5537 ScSubTotalParam aParam; 5538 pImp->GetData(aParam); // virtual method of base class 5539 5540 // SubTotalDescriptor contains the counted fields inside the area 5541 SCCOL nFieldStart = aRange.aStart.Col(); 5542 for (sal_uInt16 i=0; i<MAXSUBTOTAL; i++) 5543 { 5544 if ( aParam.bGroupActive[i] ) 5545 { 5546 aParam.nField[i] = sal::static_int_cast<SCCOL>( aParam.nField[i] + nFieldStart ); 5547 for (SCCOL j=0; j<aParam.nSubTotals[i]; j++) 5548 aParam.pSubTotals[i][j] = sal::static_int_cast<SCCOL>( aParam.pSubTotals[i][j] + nFieldStart ); 5549 } 5550 } 5551 5552 aParam.bReplace = bReplace; 5553 5554 SCTAB nTab = aRange.aStart.Tab(); 5555 aParam.nCol1 = aRange.aStart.Col(); 5556 aParam.nRow1 = aRange.aStart.Row(); 5557 aParam.nCol2 = aRange.aEnd.Col(); 5558 aParam.nRow2 = aRange.aEnd.Row(); 5559 5560 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area 5561 5562 ScDBDocFunc aFunc(*pDocSh); 5563 aFunc.DoSubTotals( nTab, aParam, true, true ); // area must be created 5564 } 5565 5566 void SAL_CALL ScCellRangeObj::removeSubTotals() 5567 { 5568 SolarMutexGuard aGuard; 5569 5570 ScDocShell* pDocSh = GetDocShell(); 5571 if (!pDocSh) 5572 return; 5573 5574 ScSubTotalParam aParam; 5575 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark ); 5576 if (pData) 5577 pData->GetSubTotalParam(aParam); // also keep field entries during remove 5578 5579 aParam.bRemoveOnly = true; 5580 5581 SCTAB nTab = aRange.aStart.Tab(); 5582 aParam.nCol1 = aRange.aStart.Col(); 5583 aParam.nRow1 = aRange.aStart.Row(); 5584 aParam.nCol2 = aRange.aEnd.Col(); 5585 aParam.nRow2 = aRange.aEnd.Row(); 5586 5587 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area 5588 5589 ScDBDocFunc aFunc(*pDocSh); 5590 aFunc.DoSubTotals( nTab, aParam, true, true ); // are must be created 5591 } 5592 5593 uno::Sequence<beans::PropertyValue> SAL_CALL ScCellRangeObj::createImportDescriptor( sal_Bool bEmpty ) 5594 { 5595 SolarMutexGuard aGuard; 5596 ScImportParam aParam; 5597 ScDocShell* pDocSh = GetDocShell(); 5598 if ( !bEmpty && pDocSh ) 5599 { 5600 // create DB-Area only during execution; API always the exact area 5601 ScDBData* pData = pDocSh->GetDBData( aRange, SC_DB_OLD, ScGetDBSelection::ForceMark ); 5602 if (pData) 5603 pData->GetImportParam(aParam); 5604 } 5605 5606 uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() ); 5607 ScImportDescriptor::FillProperties( aSeq, aParam ); 5608 return aSeq; 5609 } 5610 5611 void SAL_CALL ScCellRangeObj::doImport( const uno::Sequence<beans::PropertyValue>& aDescriptor ) 5612 { 5613 SolarMutexGuard aGuard; 5614 ScDocShell* pDocSh = GetDocShell(); 5615 if (!pDocSh) 5616 return; 5617 5618 ScImportParam aParam; 5619 ScImportDescriptor::FillImportParam( aParam, aDescriptor ); 5620 5621 SCTAB nTab = aRange.aStart.Tab(); 5622 aParam.nCol1 = aRange.aStart.Col(); 5623 aParam.nRow1 = aRange.aStart.Row(); 5624 aParam.nCol2 = aRange.aEnd.Col(); 5625 aParam.nRow2 = aRange.aEnd.Row(); 5626 5627 //! TODO: could we get passed a valid result set by any means? 5628 5629 pDocSh->GetDBData( aRange, SC_DB_MAKE, ScGetDBSelection::ForceMark ); // if needed create area 5630 5631 ScDBDocFunc aFunc(*pDocSh); // are must be created 5632 aFunc.DoImport( nTab, aParam, nullptr ); //! Api-Flag as parameter 5633 } 5634 5635 // XCellFormatRangesSupplier 5636 5637 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangeObj::getCellFormatRanges() 5638 { 5639 SolarMutexGuard aGuard; 5640 ScDocShell* pDocSh = GetDocShell(); 5641 if ( pDocSh ) 5642 return new ScCellFormatsObj( pDocSh, aRange ); 5643 return nullptr; 5644 } 5645 5646 // XUniqueCellFormatRangesSupplier 5647 5648 uno::Reference<container::XIndexAccess> SAL_CALL ScCellRangeObj::getUniqueCellFormatRanges() 5649 { 5650 SolarMutexGuard aGuard; 5651 ScDocShell* pDocSh = GetDocShell(); 5652 if ( pDocSh ) 5653 return new ScUniqueCellFormatsObj( pDocSh, aRange ); 5654 return nullptr; 5655 } 5656 5657 // XPropertySet extended for Range-Properties 5658 5659 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellRangeObj::getPropertySetInfo() 5660 { 5661 SolarMutexGuard aGuard; 5662 static uno::Reference<beans::XPropertySetInfo> aRef( 5663 new SfxItemPropertySetInfo( pRangePropSet->getPropertyMap() )); 5664 return aRef; 5665 } 5666 5667 void ScCellRangeObj::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue ) 5668 { 5669 // Range has only Position and Size in addition to ScCellRangesBase, both are ReadOnly 5670 // -> nothing to do here 5671 5672 ScCellRangesBase::SetOnePropertyValue( pEntry, aValue ); 5673 } 5674 5675 void ScCellRangeObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny ) 5676 { 5677 if ( !pEntry ) 5678 return; 5679 5680 if ( pEntry->nWID == SC_WID_UNO_POS ) 5681 { 5682 ScDocShell* pDocSh = GetDocShell(); 5683 if (pDocSh) 5684 { 5685 // GetMMRect converts using HMM_PER_TWIPS, like the DrawingLayer 5686 tools::Rectangle aMMRect(pDocSh->GetDocument().GetMMRect( 5687 aRange.aStart.Col(), aRange.aStart.Row(), 5688 aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() )); 5689 awt::Point aPos( aMMRect.Left(), aMMRect.Top() ); 5690 rAny <<= aPos; 5691 } 5692 } 5693 else if ( pEntry->nWID == SC_WID_UNO_SIZE ) 5694 { 5695 ScDocShell* pDocSh = GetDocShell(); 5696 if (pDocSh) 5697 { 5698 // GetMMRect converts using HMM_PER_TWIPS, like the DrawingLayer 5699 tools::Rectangle aMMRect = pDocSh->GetDocument().GetMMRect( 5700 aRange.aStart.Col(), aRange.aStart.Row(), 5701 aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ); 5702 Size aSize(aMMRect.GetSize()); 5703 awt::Size aAwtSize( aSize.Width(), aSize.Height() ); 5704 rAny <<= aAwtSize; 5705 } 5706 } 5707 else 5708 ScCellRangesBase::GetOnePropertyValue( pEntry, rAny ); 5709 } 5710 5711 const SfxItemPropertyMap& ScCellRangeObj::GetItemPropertyMap() 5712 { 5713 return pRangePropSet->getPropertyMap(); 5714 } 5715 5716 // XServiceInfo 5717 5718 OUString SAL_CALL ScCellRangeObj::getImplementationName() 5719 { 5720 return "ScCellRangeObj"; 5721 } 5722 5723 sal_Bool SAL_CALL ScCellRangeObj::supportsService( const OUString& rServiceName ) 5724 { 5725 return cppu::supportsService(this, rServiceName); 5726 } 5727 5728 uno::Sequence<OUString> SAL_CALL ScCellRangeObj::getSupportedServiceNames() 5729 { 5730 return {SCSHEETCELLRANGE_SERVICE, 5731 SCCELLRANGE_SERVICE, 5732 SCCELLPROPERTIES_SERVICE, 5733 SCCHARPROPERTIES_SERVICE, 5734 SCPARAPROPERTIES_SERVICE}; 5735 } 5736 5737 const SvxItemPropertySet* ScCellObj::GetEditPropertySet() 5738 { 5739 return lcl_GetEditPropertySet(); 5740 } 5741 5742 const SfxItemPropertyMap& ScCellObj::GetCellPropertyMap() 5743 { 5744 return lcl_GetCellPropertySet()->getPropertyMap(); 5745 } 5746 5747 ScCellObj::ScCellObj(ScDocShell* pDocSh, const ScAddress& rP) : 5748 ScCellRangeObj( pDocSh, ScRange(rP,rP) ), 5749 pCellPropSet( lcl_GetCellPropertySet() ), 5750 aCellPos( rP ), 5751 nActionLockCount( 0 ) 5752 { 5753 // pUnoText is allocated on demand (GetUnoText) 5754 // can't be aggregated because getString/setString is handled here 5755 } 5756 5757 SvxUnoText& ScCellObj::GetUnoText() 5758 { 5759 if (!mxUnoText.is()) 5760 { 5761 mxUnoText.set(new ScCellTextObj(GetDocShell(), aCellPos)); 5762 if (nActionLockCount) 5763 { 5764 ScCellEditSource* pEditSource = 5765 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource()); 5766 if (pEditSource) 5767 pEditSource->SetDoUpdateData(false); 5768 } 5769 } 5770 return *mxUnoText; 5771 } 5772 5773 ScCellObj::~ScCellObj() 5774 { 5775 } 5776 5777 void ScCellObj::RefChanged() 5778 { 5779 ScCellRangeObj::RefChanged(); 5780 5781 const ScRangeList& rRanges = GetRangeList(); 5782 OSL_ENSURE(rRanges.size() == 1, "What ranges ?!?!"); 5783 if ( !rRanges.empty() ) 5784 { 5785 aCellPos = rRanges[ 0 ].aStart; 5786 } 5787 } 5788 5789 uno::Any SAL_CALL ScCellObj::queryInterface( const uno::Type& rType ) 5790 { 5791 SC_QUERYINTERFACE( table::XCell ) 5792 SC_QUERYINTERFACE( table::XCell2 ) 5793 SC_QUERYINTERFACE( sheet::XFormulaTokens ) 5794 SC_QUERYINTERFACE( sheet::XCellAddressable ) 5795 SC_QUERYINTERFACE( text::XText ) 5796 SC_QUERYINTERFACE( text::XSimpleText ) 5797 SC_QUERYINTERFACE( text::XTextRange ) 5798 SC_QUERYINTERFACE( container::XEnumerationAccess ) 5799 SC_QUERYINTERFACE( container::XElementAccess ) 5800 SC_QUERYINTERFACE( sheet::XSheetAnnotationAnchor ) 5801 SC_QUERYINTERFACE( text::XTextFieldsSupplier ) 5802 SC_QUERYINTERFACE( document::XActionLockable ) 5803 5804 return ScCellRangeObj::queryInterface( rType ); 5805 } 5806 5807 void SAL_CALL ScCellObj::acquire() noexcept 5808 { 5809 ScCellRangeObj::acquire(); 5810 } 5811 5812 void SAL_CALL ScCellObj::release() noexcept 5813 { 5814 ScCellRangeObj::release(); 5815 } 5816 5817 uno::Sequence<uno::Type> SAL_CALL ScCellObj::getTypes() 5818 { 5819 static const uno::Sequence<uno::Type> aTypes = comphelper::concatSequences( 5820 ScCellRangeObj::getTypes(), 5821 uno::Sequence<uno::Type> 5822 { 5823 cppu::UnoType<table::XCell>::get(), 5824 cppu::UnoType<sheet::XCellAddressable>::get(), 5825 cppu::UnoType<text::XText>::get(), 5826 cppu::UnoType<container::XEnumerationAccess>::get(), 5827 cppu::UnoType<sheet::XSheetAnnotationAnchor>::get(), 5828 cppu::UnoType<text::XTextFieldsSupplier>::get(), 5829 cppu::UnoType<document::XActionLockable>::get(), 5830 cppu::UnoType<sheet::XFormulaTokens>::get(), 5831 cppu::UnoType<table::XCell2>::get() 5832 } ); 5833 return aTypes; 5834 } 5835 5836 uno::Sequence<sal_Int8> SAL_CALL ScCellObj::getImplementationId() 5837 { 5838 return css::uno::Sequence<sal_Int8>(); 5839 } 5840 5841 // helper methods 5842 5843 OUString ScCellObj::GetInputString_Impl(bool bEnglish) const // for getFormula / FormulaLocal 5844 { 5845 if (GetDocShell()) 5846 return lcl_GetInputString( GetDocShell()->GetDocument(), aCellPos, bEnglish ); 5847 return OUString(); 5848 } 5849 5850 OUString ScCellObj::GetOutputString_Impl() const 5851 { 5852 ScDocShell* pDocSh = GetDocShell(); 5853 OUString aVal; 5854 if ( pDocSh ) 5855 { 5856 ScDocument& rDoc = pDocSh->GetDocument(); 5857 ScRefCellValue aCell(rDoc, aCellPos); 5858 5859 aVal = ScCellFormat::GetOutputString(rDoc, aCellPos, aCell); 5860 } 5861 return aVal; 5862 } 5863 5864 void ScCellObj::SetString_Impl(const OUString& rString, bool bInterpret, bool bEnglish) 5865 { 5866 ScDocShell* pDocSh = GetDocShell(); 5867 if ( pDocSh ) 5868 { 5869 // GRAM_API for API compatibility. 5870 (void)pDocSh->GetDocFunc().SetCellText( 5871 aCellPos, rString, bInterpret, bEnglish, true, formula::FormulaGrammar::GRAM_API ); 5872 } 5873 } 5874 5875 double ScCellObj::GetValue_Impl() const 5876 { 5877 ScDocShell* pDocSh = GetDocShell(); 5878 if ( pDocSh ) 5879 return pDocSh->GetDocument().GetValue( aCellPos ); 5880 5881 return 0.0; 5882 } 5883 5884 void ScCellObj::SetValue_Impl(double fValue) 5885 { 5886 ScDocShell* pDocSh = GetDocShell(); 5887 if ( pDocSh ) 5888 pDocSh->GetDocFunc().SetValueCell(aCellPos, fValue, false); 5889 } 5890 5891 // only for XML import 5892 5893 void ScCellObj::InputEnglishString( const OUString& rText ) 5894 { 5895 // This is like a mixture of setFormula and property FormulaLocal: 5896 // The cell's number format is checked for "text", a new cell format may be set, 5897 // but all parsing is in English. 5898 5899 ScDocShell* pDocSh = GetDocShell(); 5900 if (!pDocSh) 5901 return; 5902 5903 ScDocument& rDoc = pDocSh->GetDocument(); 5904 SvNumberFormatter* pFormatter = rDoc.GetFormatTable(); 5905 sal_uInt32 nOldFormat = rDoc.GetNumberFormat( aCellPos ); 5906 if (pFormatter->GetType(nOldFormat) == SvNumFormatType::TEXT) 5907 { 5908 SetString_Impl(rText, false, false); // text cell 5909 return; 5910 } 5911 5912 ScDocFunc &rFunc = pDocSh->GetDocFunc(); 5913 5914 ScInputStringType aRes = 5915 ScStringUtil::parseInputString(*pFormatter, rText, LANGUAGE_ENGLISH_US); 5916 5917 if (aRes.meType != ScInputStringType::Unknown) 5918 { 5919 if ((nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && aRes.mnFormatType != SvNumFormatType::ALL) 5920 { 5921 // apply a format for the recognized type and the old format's language 5922 sal_uInt32 nNewFormat = ScGlobal::GetStandardFormat(*pFormatter, nOldFormat, aRes.mnFormatType); 5923 if (nNewFormat != nOldFormat) 5924 { 5925 ScPatternAttr aPattern( rDoc.GetPool() ); 5926 aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) ); 5927 // ATTR_LANGUAGE_FORMAT remains unchanged 5928 rFunc.ApplyAttributes( *GetMarkData(), aPattern, true ); 5929 } 5930 } 5931 } 5932 switch (aRes.meType) 5933 { 5934 case ScInputStringType::Formula: 5935 rFunc.SetFormulaCell( 5936 aCellPos, 5937 new ScFormulaCell(rDoc, aCellPos, aRes.maText, formula::FormulaGrammar::GRAM_API), 5938 false); 5939 break; 5940 case ScInputStringType::Number: 5941 rFunc.SetValueCell(aCellPos, aRes.mfValue, false); 5942 break; 5943 case ScInputStringType::Text: 5944 rFunc.SetStringOrEditCell(aCellPos, aRes.maText, false); 5945 break; 5946 default: 5947 SetString_Impl(rText, false, false); // probably empty string 5948 } 5949 } 5950 5951 // XText 5952 5953 uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursor() 5954 { 5955 SolarMutexGuard aGuard; 5956 return new ScCellTextCursor( *this ); 5957 } 5958 5959 uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursorByRange( 5960 const uno::Reference<text::XTextRange>& aTextPosition ) 5961 { 5962 SolarMutexGuard aGuard; 5963 rtl::Reference<SvxUnoTextCursor> pCursor = new ScCellTextCursor( *this ); 5964 5965 SvxUnoTextRangeBase* pRange = comphelper::getFromUnoTunnel<SvxUnoTextRangeBase>( aTextPosition ); 5966 if(pRange) 5967 pCursor->SetSelection( pRange->GetSelection() ); 5968 else 5969 { 5970 ScCellTextCursor* pOther = comphelper::getFromUnoTunnel<ScCellTextCursor>( aTextPosition ); 5971 if(!pOther) 5972 throw uno::RuntimeException(); 5973 5974 pCursor->SetSelection( pOther->GetSelection() ); 5975 5976 } 5977 5978 return pCursor; 5979 } 5980 5981 OUString SAL_CALL ScCellObj::getString() 5982 { 5983 SolarMutexGuard aGuard; 5984 return GetOutputString_Impl(); 5985 } 5986 5987 void SAL_CALL ScCellObj::setString( const OUString& aText ) 5988 { 5989 SolarMutexGuard aGuard; 5990 SetString_Impl(aText, false, false); // always text 5991 5992 // don't create pUnoText here if not there 5993 if (mxUnoText.is()) 5994 mxUnoText->SetSelection(ESelection( 0,0, 0,aText.getLength() )); 5995 } 5996 5997 void SAL_CALL ScCellObj::insertString( const uno::Reference<text::XTextRange>& xRange, 5998 const OUString& aString, sal_Bool bAbsorb ) 5999 { 6000 // special handling for ScCellTextCursor is no longer needed, 6001 // SvxUnoText::insertString checks for SvxUnoTextRangeBase instead of SvxUnoTextRange 6002 6003 SolarMutexGuard aGuard; 6004 GetUnoText().insertString(xRange, aString, bAbsorb); 6005 } 6006 6007 void SAL_CALL ScCellObj::insertControlCharacter( const uno::Reference<text::XTextRange>& xRange, 6008 sal_Int16 nControlCharacter, sal_Bool bAbsorb ) 6009 { 6010 SolarMutexGuard aGuard; 6011 GetUnoText().insertControlCharacter(xRange, nControlCharacter, bAbsorb); 6012 } 6013 6014 void SAL_CALL ScCellObj::insertTextContent( const uno::Reference<text::XTextRange >& xRange, 6015 const uno::Reference<text::XTextContent >& xContent, 6016 sal_Bool bAbsorb ) 6017 { 6018 SolarMutexGuard aGuard; 6019 ScDocShell* pDocSh = GetDocShell(); 6020 if ( pDocSh && xContent.is() ) 6021 { 6022 ScEditFieldObj* pCellField = comphelper::getFromUnoTunnel<ScEditFieldObj>(xContent); 6023 SvxUnoTextRangeBase* pTextRange = comphelper::getFromUnoTunnel<ScCellTextCursor>( xRange ); 6024 6025 if ( pCellField && !pCellField->IsInserted() && pTextRange ) 6026 { 6027 SvxEditSource* pEditSource = pTextRange->GetEditSource(); 6028 ESelection aSelection(pTextRange->GetSelection()); 6029 6030 if (!bAbsorb) 6031 { 6032 // do not replace -> append 6033 aSelection.Adjust(); 6034 aSelection.nStartPara = aSelection.nEndPara; 6035 aSelection.nStartPos = aSelection.nEndPos; 6036 } 6037 6038 if (pCellField->GetFieldType() == text::textfield::Type::TABLE) 6039 pCellField->setPropertyValue(SC_UNONAME_TABLEPOS, uno::Any(sal_Int32(aCellPos.Tab()))); 6040 6041 SvxFieldItem aItem = pCellField->CreateFieldItem(); 6042 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder(); 6043 pForwarder->QuickInsertField( aItem, aSelection ); 6044 pEditSource->UpdateData(); 6045 6046 // new selection: a digit 6047 aSelection.Adjust(); 6048 aSelection.nEndPara = aSelection.nStartPara; 6049 aSelection.nEndPos = aSelection.nStartPos + 1; 6050 uno::Reference<text::XTextRange> xParent(this); 6051 pCellField->InitDoc( 6052 xParent, std::make_unique<ScCellEditSource>(pDocSh, aCellPos), aSelection); 6053 6054 // for bAbsorb=FALSE, the new selection must be behind the inserted content 6055 // (the xml filter relies on this) 6056 if (!bAbsorb) 6057 aSelection.nStartPos = aSelection.nEndPos; 6058 6059 pTextRange->SetSelection( aSelection ); 6060 6061 return; 6062 } 6063 } 6064 GetUnoText().insertTextContent(xRange, xContent, bAbsorb); 6065 } 6066 6067 void SAL_CALL ScCellObj::removeTextContent( const uno::Reference<text::XTextContent>& xContent ) 6068 { 6069 SolarMutexGuard aGuard; 6070 if ( xContent.is() ) 6071 { 6072 ScEditFieldObj* pCellField = comphelper::getFromUnoTunnel<ScEditFieldObj>(xContent); 6073 if ( pCellField && pCellField->IsInserted() ) 6074 { 6075 //! Check if field is in this cell 6076 pCellField->DeleteField(); 6077 return; 6078 } 6079 } 6080 GetUnoText().removeTextContent(xContent); 6081 } 6082 6083 uno::Reference<text::XText> SAL_CALL ScCellObj::getText() 6084 { 6085 return this; 6086 } 6087 6088 uno::Reference<text::XTextRange> SAL_CALL ScCellObj::getStart() 6089 { 6090 SolarMutexGuard aGuard; 6091 return GetUnoText().getStart(); 6092 } 6093 6094 uno::Reference<text::XTextRange> SAL_CALL ScCellObj::getEnd() 6095 { 6096 SolarMutexGuard aGuard; 6097 return GetUnoText().getEnd(); 6098 } 6099 6100 uno::Reference<container::XEnumeration> SAL_CALL ScCellObj::createEnumeration() 6101 { 6102 SolarMutexGuard aGuard; 6103 return GetUnoText().createEnumeration(); 6104 } 6105 6106 uno::Type SAL_CALL ScCellObj::getElementType() 6107 { 6108 SolarMutexGuard aGuard; 6109 return GetUnoText().getElementType(); 6110 } 6111 6112 sal_Bool SAL_CALL ScCellObj::hasElements() 6113 { 6114 SolarMutexGuard aGuard; 6115 return GetUnoText().hasElements(); 6116 } 6117 6118 // XCell 6119 6120 OUString SAL_CALL ScCellObj::getFormula() 6121 { 6122 SolarMutexGuard aGuard; 6123 return GetInputString_Impl( true /* English */ ); 6124 } 6125 6126 void SAL_CALL ScCellObj::setFormula( const OUString& aFormula ) 6127 { 6128 SolarMutexGuard aGuard; 6129 SetString_Impl(aFormula, true, true); // Interpret as English 6130 } 6131 6132 double SAL_CALL ScCellObj::getValue() 6133 { 6134 SolarMutexGuard aGuard; 6135 return GetValue_Impl(); 6136 } 6137 6138 void SAL_CALL ScCellObj::setValue( double nValue ) 6139 { 6140 SolarMutexGuard aGuard; 6141 SetValue_Impl(nValue); 6142 } 6143 6144 void SAL_CALL ScCellObj::setFormulaString( const OUString& aFormula) 6145 { 6146 SolarMutexGuard aGuard; 6147 ScDocShell *pDocSh = GetDocShell(); 6148 if( pDocSh ) 6149 { 6150 ScFormulaCell* pCell = new ScFormulaCell( pDocSh->GetDocument(), aCellPos ); 6151 pCell->SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE ); 6152 pDocSh->GetDocFunc().SetFormulaCell(aCellPos, pCell, false); 6153 } 6154 } 6155 void SAL_CALL ScCellObj::setFormulaResult( double nValue ) 6156 { 6157 SolarMutexGuard aGuard; 6158 ScDocShell* pDocSh = GetDocShell(); 6159 if (pDocSh) 6160 { 6161 ScRefCellValue aCell(pDocSh->GetDocument(), aCellPos); 6162 if (aCell.getType() == CELLTYPE_FORMULA) 6163 { 6164 ScFormulaCell* pCell = aCell.getFormula(); 6165 pCell->SetHybridDouble( nValue ); 6166 pCell->ResetDirty(); 6167 pCell->SetChanged(false); 6168 } 6169 } 6170 } 6171 6172 table::CellContentType SAL_CALL ScCellObj::getType() 6173 { 6174 SolarMutexGuard aGuard; 6175 table::CellContentType eRet = table::CellContentType_EMPTY; 6176 ScDocShell* pDocSh = GetDocShell(); 6177 if (pDocSh) 6178 { 6179 CellType eCalcType = pDocSh->GetDocument().GetCellType( aCellPos ); 6180 switch (eCalcType) 6181 { 6182 case CELLTYPE_VALUE: 6183 eRet = table::CellContentType_VALUE; 6184 break; 6185 case CELLTYPE_STRING: 6186 case CELLTYPE_EDIT: 6187 eRet = table::CellContentType_TEXT; 6188 break; 6189 case CELLTYPE_FORMULA: 6190 eRet = table::CellContentType_FORMULA; 6191 break; 6192 default: 6193 eRet = table::CellContentType_EMPTY; 6194 } 6195 } 6196 else 6197 { 6198 OSL_FAIL("no DocShell"); //! Exception or so? 6199 } 6200 6201 return eRet; 6202 } 6203 6204 sal_Int32 ScCellObj::GetResultType_Impl() const 6205 { 6206 SolarMutexGuard aGuard; 6207 sal_Int32 eRet = sheet::FormulaResult::STRING; 6208 ScDocShell* pDocSh = GetDocShell(); 6209 if (pDocSh) 6210 { 6211 if (pDocSh->GetDocument().GetCellType(aCellPos) == CELLTYPE_FORMULA) 6212 { 6213 ScFormulaCell* pFCell = pDocSh->GetDocument().GetFormulaCell(aCellPos); 6214 if (!pFCell) 6215 { 6216 // should throw instead of default string? 6217 } 6218 else if (pFCell->GetErrCode() != FormulaError::NONE ) 6219 { 6220 eRet = sheet::FormulaResult::ERROR; 6221 } 6222 else if (pFCell->IsValue()) 6223 { 6224 eRet = sheet::FormulaResult::VALUE; 6225 } 6226 else 6227 { 6228 eRet = sheet::FormulaResult::STRING; 6229 } 6230 } 6231 } 6232 else 6233 { 6234 OSL_FAIL("no DocShell"); 6235 } 6236 6237 return eRet; 6238 } 6239 6240 table::CellContentType ScCellObj::GetContentType_Impl() 6241 { 6242 ScDocShell* pDocSh = GetDocShell(); 6243 if ( pDocSh ) 6244 { 6245 ScRefCellValue aCell(pDocSh->GetDocument(), aCellPos); 6246 if (aCell.getType() == CELLTYPE_FORMULA) 6247 { 6248 bool bValue = aCell.getFormula()->IsValue(); 6249 return bValue ? table::CellContentType_VALUE : table::CellContentType_TEXT; 6250 } 6251 } 6252 return getType(); 6253 } 6254 6255 sal_Int32 SAL_CALL ScCellObj::getError() 6256 { 6257 SolarMutexGuard aGuard; 6258 ScDocShell* pDocSh = GetDocShell(); 6259 if (!pDocSh) 6260 { 6261 OSL_FAIL("no DocShell"); //! Exception or so? 6262 return 0; 6263 } 6264 6265 FormulaError nError = FormulaError::NONE; 6266 ScRefCellValue aCell(pDocSh->GetDocument(), aCellPos); 6267 if (aCell.getType() == CELLTYPE_FORMULA) 6268 nError = aCell.getFormula()->GetErrCode(); 6269 6270 return static_cast<sal_Int32>(nError); 6271 } 6272 6273 // XFormulaTokens 6274 6275 uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellObj::getTokens() 6276 { 6277 SolarMutexGuard aGuard; 6278 uno::Sequence<sheet::FormulaToken> aSequence; 6279 ScDocShell* pDocSh = GetDocShell(); 6280 if (!pDocSh) 6281 return aSequence; 6282 6283 ScDocument& rDoc = pDocSh->GetDocument(); 6284 ScRefCellValue aCell(rDoc, aCellPos); 6285 if (aCell.getType() == CELLTYPE_FORMULA) 6286 { 6287 ScTokenArray* pTokenArray = aCell.getFormula()->GetCode(); 6288 if (pTokenArray) 6289 ScTokenConversion::ConvertToTokenSequence(rDoc, aSequence, *pTokenArray); 6290 } 6291 return aSequence; 6292 } 6293 6294 void SAL_CALL ScCellObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) 6295 { 6296 SolarMutexGuard aGuard; 6297 ScDocShell* pDocSh = GetDocShell(); 6298 if ( pDocSh ) 6299 { 6300 ScDocument& rDoc = pDocSh->GetDocument(); 6301 ScTokenArray aTokenArray(rDoc); 6302 (void)ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, rTokens ); 6303 6304 ScFormulaCell* pNewCell = new ScFormulaCell(rDoc, aCellPos, aTokenArray); 6305 (void)pDocSh->GetDocFunc().SetFormulaCell(aCellPos, pNewCell, false); 6306 } 6307 } 6308 6309 // XCellAddressable 6310 6311 table::CellAddress SAL_CALL ScCellObj::getCellAddress() 6312 { 6313 SolarMutexGuard aGuard; 6314 table::CellAddress aAdr; 6315 aAdr.Sheet = aCellPos.Tab(); 6316 aAdr.Column = aCellPos.Col(); 6317 aAdr.Row = aCellPos.Row(); 6318 return aAdr; 6319 } 6320 6321 // XSheetAnnotationAnchor 6322 6323 uno::Reference<sheet::XSheetAnnotation> SAL_CALL ScCellObj::getAnnotation() 6324 { 6325 SolarMutexGuard aGuard; 6326 ScDocShell* pDocSh = GetDocShell(); 6327 if ( pDocSh ) 6328 return new ScAnnotationObj( pDocSh, aCellPos ); 6329 6330 OSL_FAIL("getAnnotation without DocShell"); 6331 return nullptr; 6332 } 6333 6334 // XFieldTypesSupplier 6335 6336 uno::Reference<container::XEnumerationAccess> SAL_CALL ScCellObj::getTextFields() 6337 { 6338 SolarMutexGuard aGuard; 6339 ScDocShell* pDocSh = GetDocShell(); 6340 if ( pDocSh ) 6341 { 6342 uno::Reference<text::XTextRange> xContent(this); 6343 return new ScCellFieldsObj(xContent, pDocSh, aCellPos); 6344 } 6345 6346 return nullptr; 6347 } 6348 6349 uno::Reference<container::XNameAccess> SAL_CALL ScCellObj::getTextFieldMasters() 6350 { 6351 // there is no such thing in Calc (?) 6352 return nullptr; 6353 } 6354 6355 // XPropertySet extended for Cell-Properties 6356 6357 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScCellObj::getPropertySetInfo() 6358 { 6359 SolarMutexGuard aGuard; 6360 static uno::Reference<beans::XPropertySetInfo> aRef( 6361 new SfxItemPropertySetInfo( pCellPropSet->getPropertyMap() )); 6362 return aRef; 6363 } 6364 6365 void ScCellObj::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue ) 6366 { 6367 if ( !pEntry ) 6368 return; 6369 6370 if ( pEntry->nWID == SC_WID_UNO_FORMLOC ) 6371 { 6372 OUString aStrVal; 6373 aValue >>= aStrVal; 6374 SetString_Impl(aStrVal, true, false); // interpret locally 6375 } 6376 else if ( pEntry->nWID == SC_WID_UNO_FORMRT || pEntry->nWID == SC_WID_UNO_FORMRT2 6377 || pEntry->nWID == SC_WID_UNO_CELLCONTENTTYPE ) 6378 { 6379 // Read-Only 6380 //! Exception or so... 6381 } 6382 else 6383 ScCellRangeObj::SetOnePropertyValue( pEntry, aValue ); 6384 } 6385 6386 void ScCellObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny ) 6387 { 6388 if ( !pEntry ) 6389 return; 6390 6391 if ( pEntry->nWID == SC_WID_UNO_FORMLOC ) 6392 { 6393 // sal_False = local 6394 rAny <<= GetInputString_Impl(false); 6395 } 6396 else if ( pEntry->nWID == SC_WID_UNO_FORMRT2 ) 6397 { 6398 sal_Int32 eType = GetResultType_Impl(); 6399 rAny <<= eType; 6400 } 6401 else if ( pEntry->nWID == SC_WID_UNO_CELLCONTENTTYPE || pEntry->nWID == SC_WID_UNO_FORMRT ) 6402 { 6403 table::CellContentType eType = GetContentType_Impl(); 6404 rAny <<= eType; 6405 } 6406 else 6407 ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); 6408 } 6409 6410 const SfxItemPropertyMap& ScCellObj::GetItemPropertyMap() 6411 { 6412 return pCellPropSet->getPropertyMap(); 6413 } 6414 6415 // XServiceInfo 6416 6417 OUString SAL_CALL ScCellObj::getImplementationName() 6418 { 6419 return "ScCellObj"; 6420 } 6421 6422 sal_Bool SAL_CALL ScCellObj::supportsService( const OUString& rServiceName ) 6423 { 6424 return cppu::supportsService(this, rServiceName); 6425 } 6426 6427 uno::Sequence<OUString> SAL_CALL ScCellObj::getSupportedServiceNames() 6428 { 6429 return {SCSHEETCELL_SERVICE, 6430 SCCELL_SERVICE, 6431 SCCELLPROPERTIES_SERVICE, 6432 SCCHARPROPERTIES_SERVICE, 6433 SCPARAPROPERTIES_SERVICE, 6434 SCSHEETCELLRANGE_SERVICE, 6435 SCCELLRANGE_SERVICE}; 6436 } 6437 6438 // XActionLockable 6439 6440 sal_Bool SAL_CALL ScCellObj::isActionLocked() 6441 { 6442 SolarMutexGuard aGuard; 6443 return nActionLockCount != 0; 6444 } 6445 6446 void SAL_CALL ScCellObj::addActionLock() 6447 { 6448 SolarMutexGuard aGuard; 6449 if (!nActionLockCount) 6450 { 6451 if (mxUnoText.is()) 6452 { 6453 ScCellEditSource* pEditSource = 6454 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource()); 6455 if (pEditSource) 6456 pEditSource->SetDoUpdateData(false); 6457 } 6458 } 6459 nActionLockCount++; 6460 } 6461 6462 void SAL_CALL ScCellObj::removeActionLock() 6463 { 6464 SolarMutexGuard aGuard; 6465 if (nActionLockCount <= 0) 6466 return; 6467 6468 nActionLockCount--; 6469 if (nActionLockCount) 6470 return; 6471 6472 if (mxUnoText.is()) 6473 { 6474 ScCellEditSource* pEditSource = 6475 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource()); 6476 if (pEditSource) 6477 { 6478 pEditSource->SetDoUpdateData(true); 6479 if (pEditSource->IsDirty()) 6480 pEditSource->UpdateData(); 6481 } 6482 } 6483 } 6484 6485 void SAL_CALL ScCellObj::setActionLocks( sal_Int16 nLock ) 6486 { 6487 SolarMutexGuard aGuard; 6488 if (mxUnoText.is()) 6489 { 6490 ScCellEditSource* pEditSource = 6491 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource()); 6492 if (pEditSource) 6493 { 6494 pEditSource->SetDoUpdateData(nLock == 0); 6495 if ((nActionLockCount > 0) && (nLock == 0) && pEditSource->IsDirty()) 6496 pEditSource->UpdateData(); 6497 } 6498 } 6499 nActionLockCount = nLock; 6500 } 6501 6502 sal_Int16 SAL_CALL ScCellObj::resetActionLocks() 6503 { 6504 SolarMutexGuard aGuard; 6505 sal_uInt16 nRet(nActionLockCount); 6506 if (mxUnoText.is()) 6507 { 6508 ScCellEditSource* pEditSource = 6509 static_cast<ScCellEditSource*> (mxUnoText->GetEditSource()); 6510 if (pEditSource) 6511 { 6512 pEditSource->SetDoUpdateData(true); 6513 if (pEditSource->IsDirty()) 6514 pEditSource->UpdateData(); 6515 } 6516 } 6517 nActionLockCount = 0; 6518 return nRet; 6519 } 6520 6521 static ScRange MaxDocRange(ScDocShell* pDocSh, SCTAB nTab) 6522 { 6523 const SCCOL nMaxcol = pDocSh ? pDocSh->GetDocument().MaxCol() : MAXCOL; 6524 const SCROW nMaxRow = pDocSh ? pDocSh->GetDocument().MaxRow() : MAXROW; 6525 return ScRange(0, 0, nTab, nMaxcol, nMaxRow, nTab); 6526 } 6527 6528 ScTableSheetObj::ScTableSheetObj( ScDocShell* pDocSh, SCTAB nTab ) : 6529 ScCellRangeObj( pDocSh, MaxDocRange(pDocSh, nTab) ), 6530 pSheetPropSet(lcl_GetSheetPropertySet()) 6531 { 6532 } 6533 6534 ScTableSheetObj::~ScTableSheetObj() 6535 { 6536 } 6537 6538 void ScTableSheetObj::InitInsertSheet(ScDocShell* pDocSh, SCTAB nTab) 6539 { 6540 ScDocument& rDoc = pDocSh->GetDocument(); 6541 InitInsertRange( pDocSh, ScRange(0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab) ); 6542 } 6543 6544 uno::Any SAL_CALL ScTableSheetObj::queryInterface( const uno::Type& rType ) 6545 { 6546 SC_QUERYINTERFACE( sheet::XSpreadsheet ) 6547 SC_QUERYINTERFACE( container::XNamed ) 6548 SC_QUERYINTERFACE( sheet::XSheetPageBreak ) 6549 SC_QUERYINTERFACE( sheet::XCellRangeMovement ) 6550 SC_QUERYINTERFACE( table::XTableChartsSupplier ) 6551 SC_QUERYINTERFACE( sheet::XDataPilotTablesSupplier ) 6552 SC_QUERYINTERFACE( sheet::XScenariosSupplier ) 6553 SC_QUERYINTERFACE( sheet::XSheetAnnotationsSupplier ) 6554 SC_QUERYINTERFACE( drawing::XDrawPageSupplier ) 6555 SC_QUERYINTERFACE( sheet::XPrintAreas ) 6556 SC_QUERYINTERFACE( sheet::XSheetAuditing ) 6557 SC_QUERYINTERFACE( sheet::XSheetOutline ) 6558 SC_QUERYINTERFACE( util::XProtectable ) 6559 SC_QUERYINTERFACE( sheet::XScenario ) 6560 SC_QUERYINTERFACE( sheet::XScenarioEnhanced ) 6561 SC_QUERYINTERFACE( sheet::XSheetLinkable ) 6562 SC_QUERYINTERFACE( sheet::XExternalSheetName ) 6563 SC_QUERYINTERFACE( document::XEventsSupplier ) 6564 SC_QUERYINTERFACE( table::XTablePivotChartsSupplier ) 6565 6566 return ScCellRangeObj::queryInterface( rType ); 6567 } 6568 6569 void SAL_CALL ScTableSheetObj::acquire() noexcept 6570 { 6571 ScCellRangeObj::acquire(); 6572 } 6573 6574 void SAL_CALL ScTableSheetObj::release() noexcept 6575 { 6576 ScCellRangeObj::release(); 6577 } 6578 6579 uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() 6580 { 6581 static const uno::Sequence<uno::Type> aTypes = comphelper::concatSequences( 6582 ScCellRangeObj::getTypes(), 6583 uno::Sequence<uno::Type> 6584 { 6585 cppu::UnoType<sheet::XSpreadsheet>::get(), 6586 cppu::UnoType<container::XNamed>::get(), 6587 cppu::UnoType<sheet::XSheetPageBreak>::get(), 6588 cppu::UnoType<sheet::XCellRangeMovement>::get(), 6589 cppu::UnoType<table::XTableChartsSupplier>::get(), 6590 cppu::UnoType<sheet::XDataPilotTablesSupplier>::get(), 6591 cppu::UnoType<sheet::XScenariosSupplier>::get(), 6592 cppu::UnoType<sheet::XSheetAnnotationsSupplier>::get(), 6593 cppu::UnoType<drawing::XDrawPageSupplier>::get(), 6594 cppu::UnoType<sheet::XPrintAreas>::get(), 6595 cppu::UnoType<sheet::XSheetAuditing>::get(), 6596 cppu::UnoType<sheet::XSheetOutline>::get(), 6597 cppu::UnoType<util::XProtectable>::get(), 6598 cppu::UnoType<sheet::XScenario>::get(), 6599 cppu::UnoType<sheet::XScenarioEnhanced>::get(), 6600 cppu::UnoType<sheet::XSheetLinkable>::get(), 6601 cppu::UnoType<sheet::XExternalSheetName>::get(), 6602 cppu::UnoType<document::XEventsSupplier>::get(), 6603 cppu::UnoType<table::XTablePivotChartsSupplier>::get() 6604 } ); 6605 return aTypes; 6606 } 6607 6608 uno::Sequence<sal_Int8> SAL_CALL ScTableSheetObj::getImplementationId() 6609 { 6610 return css::uno::Sequence<sal_Int8>(); 6611 } 6612 6613 // Helper functions 6614 6615 SCTAB ScTableSheetObj::GetTab_Impl() const 6616 { 6617 const ScRangeList& rRanges = GetRangeList(); 6618 OSL_ENSURE(rRanges.size() == 1, "What ranges ?!?!"); 6619 if ( !rRanges.empty() ) 6620 { 6621 return rRanges[ 0 ].aStart.Tab(); 6622 } 6623 return 0; 6624 } 6625 6626 // former XSheet 6627 6628 uno::Reference<table::XTableCharts> SAL_CALL ScTableSheetObj::getCharts() 6629 { 6630 SolarMutexGuard aGuard; 6631 ScDocShell* pDocSh = GetDocShell(); 6632 if ( pDocSh ) 6633 return new ScChartsObj( pDocSh, GetTab_Impl() ); 6634 6635 OSL_FAIL("no document"); 6636 return nullptr; 6637 } 6638 6639 uno::Reference<table::XTablePivotCharts> SAL_CALL ScTableSheetObj::getPivotCharts() 6640 { 6641 SolarMutexGuard aGuard; 6642 ScDocShell* pDocSh = GetDocShell(); 6643 if (pDocSh) 6644 return new sc::TablePivotCharts(pDocSh, GetTab_Impl()); 6645 6646 OSL_FAIL("no document"); 6647 return nullptr; 6648 } 6649 6650 uno::Reference<sheet::XDataPilotTables> SAL_CALL ScTableSheetObj::getDataPilotTables() 6651 { 6652 SolarMutexGuard aGuard; 6653 ScDocShell* pDocSh = GetDocShell(); 6654 if ( pDocSh ) 6655 return new ScDataPilotTablesObj(*pDocSh, GetTab_Impl()); 6656 6657 OSL_FAIL("no document"); 6658 return nullptr; 6659 } 6660 6661 uno::Reference<sheet::XScenarios> SAL_CALL ScTableSheetObj::getScenarios() 6662 { 6663 SolarMutexGuard aGuard; 6664 ScDocShell* pDocSh = GetDocShell(); 6665 6666 if ( pDocSh ) 6667 return new ScScenariosObj( pDocSh, GetTab_Impl() ); 6668 6669 OSL_FAIL("no document"); 6670 return nullptr; 6671 } 6672 6673 uno::Reference<sheet::XSheetAnnotations> SAL_CALL ScTableSheetObj::getAnnotations() 6674 { 6675 SolarMutexGuard aGuard; 6676 ScDocShell* pDocSh = GetDocShell(); 6677 6678 if ( pDocSh ) 6679 return new ScAnnotationsObj( pDocSh, GetTab_Impl() ); 6680 6681 OSL_FAIL("no document"); 6682 return nullptr; 6683 } 6684 6685 uno::Reference<table::XCellRange> SAL_CALL ScTableSheetObj::getCellRangeByName( 6686 const OUString& rRange ) 6687 { 6688 SolarMutexGuard aGuard; 6689 return ScCellRangeObj::getCellRangeByName( rRange ); 6690 } 6691 6692 uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursor() 6693 { 6694 SolarMutexGuard aGuard; 6695 ScDocShell* pDocSh = GetDocShell(); 6696 if ( pDocSh ) 6697 { 6698 //! single cell or whole table?????? 6699 const ScDocument& rDoc = pDocSh->GetDocument(); 6700 SCTAB nTab = GetTab_Impl(); 6701 return new ScCellCursorObj( pDocSh, ScRange( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab ) ); 6702 } 6703 return nullptr; 6704 } 6705 6706 uno::Reference<sheet::XSheetCellCursor> SAL_CALL ScTableSheetObj::createCursorByRange( 6707 const uno::Reference<sheet::XSheetCellRange>& xCellRange ) 6708 { 6709 SolarMutexGuard aGuard; 6710 ScDocShell* pDocSh = GetDocShell(); 6711 if ( pDocSh && xCellRange.is() ) 6712 { 6713 ScCellRangesBase* pRangesImp = comphelper::getFromUnoTunnel<ScCellRangesBase>( xCellRange ); 6714 if (pRangesImp) 6715 { 6716 const ScRangeList& rRanges = pRangesImp->GetRangeList(); 6717 SAL_WARN_IF( rRanges.size() != 1, "sc", "ScTableSheetObj::createCursorByRange: Range? Ranges?"); 6718 if (rRanges.empty()) 6719 return nullptr; 6720 return new ScCellCursorObj( pDocSh, rRanges[ 0 ] ); 6721 } 6722 } 6723 return nullptr; 6724 } 6725 6726 // XSheetCellRange 6727 6728 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScTableSheetObj::getSpreadsheet() 6729 { 6730 return this; //!??? 6731 } 6732 6733 // XCellRange 6734 6735 uno::Reference<table::XCell> SAL_CALL ScTableSheetObj::getCellByPosition( 6736 sal_Int32 nColumn, sal_Int32 nRow ) 6737 { 6738 SolarMutexGuard aGuard; 6739 return ScCellRangeObj::GetCellByPosition_Impl(nColumn, nRow); 6740 } 6741 6742 uno::Reference<table::XCellRange> SAL_CALL ScTableSheetObj::getCellRangeByPosition( 6743 sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nRight, sal_Int32 nBottom ) 6744 { 6745 SolarMutexGuard aGuard; 6746 return ScCellRangeObj::getCellRangeByPosition(nLeft,nTop,nRight,nBottom); 6747 } 6748 6749 uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getColumnPageBreaks() 6750 { 6751 SolarMutexGuard aGuard; 6752 ScDocShell* pDocSh = GetDocShell(); 6753 if ( pDocSh ) 6754 { 6755 ScDocument& rDoc = pDocSh->GetDocument(); 6756 SCTAB nTab = GetTab_Impl(); 6757 6758 Size aSize(rDoc.GetPageSize( nTab )); 6759 if (aSize.Width() && aSize.Height()) // effective size already set? 6760 rDoc.UpdatePageBreaks( nTab ); 6761 else 6762 { 6763 // update breaks like in ScDocShell::PageStyleModified: 6764 ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ); 6765 aPrintFunc.UpdatePages(); 6766 } 6767 6768 SCCOL nCount = 0; 6769 for (SCCOL nCol : rDoc.GetColumnsRange(nTab, 0, rDoc.MaxCol())) 6770 if (rDoc.HasColBreak(nCol, nTab) != ScBreakType::NONE) 6771 ++nCount; 6772 6773 sheet::TablePageBreakData aData; 6774 uno::Sequence<sheet::TablePageBreakData> aSeq(nCount); 6775 sheet::TablePageBreakData* pAry = aSeq.getArray(); 6776 sal_uInt16 nPos = 0; 6777 for (SCCOL nCol : rDoc.GetColumnsRange(nTab, 0, rDoc.MaxCol())) 6778 { 6779 ScBreakType nBreak = rDoc.HasColBreak(nCol, nTab); 6780 if (nBreak != ScBreakType::NONE) 6781 { 6782 aData.Position = nCol; 6783 aData.ManualBreak = bool(nBreak & ScBreakType::Manual); 6784 pAry[nPos] = aData; 6785 ++nPos; 6786 } 6787 } 6788 return aSeq; 6789 } 6790 return {}; 6791 } 6792 6793 uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getRowPageBreaks() 6794 { 6795 SolarMutexGuard aGuard; 6796 ScDocShell* pDocSh = GetDocShell(); 6797 if ( pDocSh ) 6798 { 6799 ScDocument& rDoc = pDocSh->GetDocument(); 6800 SCTAB nTab = GetTab_Impl(); 6801 6802 Size aSize(rDoc.GetPageSize( nTab )); 6803 if (aSize.Width() && aSize.Height()) // effective size already set? 6804 rDoc.UpdatePageBreaks( nTab ); 6805 else 6806 { 6807 // update breaks like in ScDocShell::PageStyleModified: 6808 ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ); 6809 aPrintFunc.UpdatePages(); 6810 } 6811 return rDoc.GetRowBreakData(nTab); 6812 } 6813 return {}; 6814 } 6815 6816 void SAL_CALL ScTableSheetObj::removeAllManualPageBreaks() 6817 { 6818 SolarMutexGuard aGuard; 6819 ScDocShell* pDocSh = GetDocShell(); 6820 if ( !pDocSh ) 6821 return; 6822 6823 //! DocFunc function, also for ScViewFunc::RemoveManualBreaks 6824 6825 ScDocument& rDoc = pDocSh->GetDocument(); 6826 bool bUndo (rDoc.IsUndoEnabled()); 6827 SCTAB nTab = GetTab_Impl(); 6828 6829 if (bUndo) 6830 { 6831 ScDocumentUniquePtr pUndoDoc(new ScDocument( SCDOCMODE_UNDO )); 6832 pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true ); 6833 rDoc.CopyToDocument(0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, InsertDeleteFlags::NONE, false, *pUndoDoc); 6834 pDocSh->GetUndoManager()->AddUndoAction( 6835 std::make_unique<ScUndoRemoveBreaks>( pDocSh, nTab, std::move(pUndoDoc) ) ); 6836 } 6837 6838 rDoc.RemoveManualBreaks(nTab); 6839 rDoc.UpdatePageBreaks(nTab); 6840 6841 //? UpdatePageBreakData( sal_True ); 6842 pDocSh->SetDocumentModified(); 6843 pDocSh->PostPaint(ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab), PaintPartFlags::Grid); 6844 } 6845 6846 // XNamed 6847 6848 OUString SAL_CALL ScTableSheetObj::getName() 6849 { 6850 SolarMutexGuard aGuard; 6851 OUString aName; 6852 ScDocShell* pDocSh = GetDocShell(); 6853 if ( pDocSh ) 6854 pDocSh->GetDocument().GetName( GetTab_Impl(), aName ); 6855 return aName; 6856 } 6857 6858 void SAL_CALL ScTableSheetObj::setName( const OUString& aNewName ) 6859 { 6860 SolarMutexGuard aGuard; 6861 ScDocShell* pDocSh = GetDocShell(); 6862 if ( pDocSh ) 6863 { 6864 pDocSh->GetDocFunc().RenameTable( GetTab_Impl(), aNewName, true, true ); 6865 } 6866 } 6867 6868 // XDrawPageSupplier 6869 6870 uno::Reference<drawing::XDrawPage> SAL_CALL ScTableSheetObj::getDrawPage() 6871 { 6872 SolarMutexGuard aGuard; 6873 ScDocShell* pDocSh = GetDocShell(); 6874 if ( pDocSh ) 6875 { 6876 ScDrawLayer* pDrawLayer = pDocSh->MakeDrawLayer(); 6877 OSL_ENSURE(pDrawLayer,"Cannot create Draw-Layer"); 6878 6879 SCTAB nTab = GetTab_Impl(); 6880 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); 6881 OSL_ENSURE(pPage,"Draw-Page not found"); 6882 if (pPage) 6883 return uno::Reference<drawing::XDrawPage> (pPage->getUnoPage(), uno::UNO_QUERY); 6884 6885 // The DrawPage object will register itself as a Listener at SdrModel 6886 // and should receive all action from there 6887 } 6888 return nullptr; 6889 } 6890 6891 // XCellMovement 6892 6893 void SAL_CALL ScTableSheetObj::insertCells( const table::CellRangeAddress& rRangeAddress, 6894 sheet::CellInsertMode nMode ) 6895 { 6896 SolarMutexGuard aGuard; 6897 ScDocShell* pDocSh = GetDocShell(); 6898 if ( !pDocSh ) 6899 return; 6900 6901 bool bDo = true; 6902 InsCellCmd eCmd = INS_NONE; 6903 switch (nMode) 6904 { 6905 case sheet::CellInsertMode_NONE: bDo = false; break; 6906 case sheet::CellInsertMode_DOWN: eCmd = INS_CELLSDOWN; break; 6907 case sheet::CellInsertMode_RIGHT: eCmd = INS_CELLSRIGHT; break; 6908 case sheet::CellInsertMode_ROWS: eCmd = INS_INSROWS_BEFORE; break; 6909 case sheet::CellInsertMode_COLUMNS: eCmd = INS_INSCOLS_BEFORE; break; 6910 default: 6911 OSL_FAIL("insertCells: wrong mode"); 6912 bDo = false; 6913 } 6914 6915 if (bDo) 6916 { 6917 OSL_ENSURE( rRangeAddress.Sheet == GetTab_Impl(), "wrong table in CellRangeAddress" ); 6918 ScRange aScRange; 6919 ScUnoConversion::FillScRange( aScRange, rRangeAddress ); 6920 (void)pDocSh->GetDocFunc().InsertCells( aScRange, nullptr, eCmd, true, true ); 6921 } 6922 } 6923 6924 void SAL_CALL ScTableSheetObj::removeRange( const table::CellRangeAddress& rRangeAddress, 6925 sheet::CellDeleteMode nMode ) 6926 { 6927 SolarMutexGuard aGuard; 6928 ScDocShell* pDocSh = GetDocShell(); 6929 if ( !pDocSh ) 6930 return; 6931 6932 bool bDo = true; 6933 DelCellCmd eCmd = DelCellCmd::NONE; 6934 switch (nMode) 6935 { 6936 case sheet::CellDeleteMode_NONE: bDo = false; break; 6937 case sheet::CellDeleteMode_UP: eCmd = DelCellCmd::CellsUp; break; 6938 case sheet::CellDeleteMode_LEFT: eCmd = DelCellCmd::CellsLeft; break; 6939 case sheet::CellDeleteMode_ROWS: eCmd = DelCellCmd::Rows; break; 6940 case sheet::CellDeleteMode_COLUMNS: eCmd = DelCellCmd::Cols; break; 6941 default: 6942 OSL_FAIL("deleteCells: wrong mode"); 6943 bDo = false; 6944 } 6945 6946 if (bDo) 6947 { 6948 OSL_ENSURE( rRangeAddress.Sheet == GetTab_Impl(), "wrong table in CellRangeAddress" ); 6949 ScRange aScRange; 6950 ScUnoConversion::FillScRange( aScRange, rRangeAddress ); 6951 (void)pDocSh->GetDocFunc().DeleteCells( aScRange, nullptr, eCmd, true ); 6952 } 6953 } 6954 6955 void SAL_CALL ScTableSheetObj::moveRange( const table::CellAddress& aDestination, 6956 const table::CellRangeAddress& aSource ) 6957 { 6958 SolarMutexGuard aGuard; 6959 ScDocShell* pDocSh = GetDocShell(); 6960 if ( pDocSh ) 6961 { 6962 OSL_ENSURE( aSource.Sheet == GetTab_Impl(), "wrong table in CellRangeAddress" ); 6963 ScRange aSourceRange; 6964 ScUnoConversion::FillScRange( aSourceRange, aSource ); 6965 ScAddress aDestPos( static_cast<SCCOL>(aDestination.Column), static_cast<SCROW>(aDestination.Row), aDestination.Sheet ); 6966 (void)pDocSh->GetDocFunc().MoveBlock( aSourceRange, aDestPos, true, true, true, true ); 6967 } 6968 } 6969 6970 void SAL_CALL ScTableSheetObj::copyRange( const table::CellAddress& aDestination, 6971 const table::CellRangeAddress& aSource ) 6972 { 6973 SolarMutexGuard aGuard; 6974 ScDocShell* pDocSh = GetDocShell(); 6975 if ( pDocSh ) 6976 { 6977 OSL_ENSURE( aSource.Sheet == GetTab_Impl(), "wrong table in CellRangeAddress" ); 6978 ScRange aSourceRange; 6979 ScUnoConversion::FillScRange( aSourceRange, aSource ); 6980 ScAddress aDestPos( static_cast<SCCOL>(aDestination.Column), static_cast<SCROW>(aDestination.Row), aDestination.Sheet ); 6981 (void)pDocSh->GetDocFunc().MoveBlock( aSourceRange, aDestPos, false, true, true, true ); 6982 } 6983 } 6984 6985 // XPrintAreas 6986 6987 void ScTableSheetObj::PrintAreaUndo_Impl( std::unique_ptr<ScPrintRangeSaver> pOldRanges ) 6988 { 6989 // page break and undo 6990 ScDocShell* pDocSh = GetDocShell(); 6991 6992 if(!pDocSh) 6993 return; 6994 6995 ScDocument& rDoc = pDocSh->GetDocument(); 6996 const bool bUndo(rDoc.IsUndoEnabled()); 6997 const SCTAB nTab(GetTab_Impl()); 6998 6999 if(bUndo) 7000 { 7001 pDocSh->GetUndoManager()->AddUndoAction( 7002 std::make_unique<ScUndoPrintRange>( 7003 pDocSh, 7004 nTab, 7005 std::move(pOldRanges), 7006 rDoc.CreatePrintRangeSaver())); // create new ranges 7007 } 7008 7009 ScPrintFunc(pDocSh, pDocSh->GetPrinter(), nTab).UpdatePages(); 7010 SfxBindings* pBindings = pDocSh->GetViewBindings(); 7011 7012 if(pBindings) 7013 { 7014 pBindings->Invalidate(SID_DELETE_PRINTAREA); 7015 } 7016 7017 pDocSh->SetDocumentModified(); 7018 } 7019 7020 uno::Sequence<table::CellRangeAddress> SAL_CALL ScTableSheetObj::getPrintAreas() 7021 { 7022 SolarMutexGuard aGuard; 7023 ScDocShell* pDocSh = GetDocShell(); 7024 if ( pDocSh ) 7025 { 7026 ScDocument& rDoc = pDocSh->GetDocument(); 7027 SCTAB nTab = GetTab_Impl(); 7028 sal_uInt16 nCount = rDoc.GetPrintRangeCount( nTab ); 7029 7030 table::CellRangeAddress aRangeAddress; 7031 uno::Sequence<table::CellRangeAddress> aSeq(nCount); 7032 table::CellRangeAddress* pAry = aSeq.getArray(); 7033 for (sal_uInt16 i=0; i<nCount; i++) 7034 { 7035 const ScRange* pRange = rDoc.GetPrintRange( nTab, i ); 7036 OSL_ENSURE(pRange,"where is the printing area"); 7037 if (pRange) 7038 { 7039 ScUnoConversion::FillApiRange( aRangeAddress, *pRange ); 7040 aRangeAddress.Sheet = nTab; // core does not care about sheet index 7041 pAry[i] = aRangeAddress; 7042 } 7043 } 7044 return aSeq; 7045 } 7046 return uno::Sequence<table::CellRangeAddress>(); 7047 } 7048 7049 void SAL_CALL ScTableSheetObj::setPrintAreas( 7050 const uno::Sequence<table::CellRangeAddress>& aPrintAreas ) 7051 { 7052 SolarMutexGuard aGuard; 7053 ScDocShell* pDocSh = GetDocShell(); 7054 if ( !pDocSh ) 7055 return; 7056 7057 std::unique_ptr<ScPrintRangeSaver> pOldRanges; 7058 ScDocument& rDoc = pDocSh->GetDocument(); 7059 SCTAB nTab = GetTab_Impl(); 7060 7061 if ( rDoc.IsUndoEnabled() ) 7062 pOldRanges = rDoc.CreatePrintRangeSaver(); 7063 7064 sal_uInt16 nCount = static_cast<sal_uInt16>(aPrintAreas.getLength()); 7065 rDoc.ClearPrintRanges( nTab ); 7066 if (nCount) 7067 { 7068 ScRange aPrintRange; 7069 for (const table::CellRangeAddress& rPrintArea : aPrintAreas) 7070 { 7071 ScUnoConversion::FillScRange( aPrintRange, rPrintArea ); 7072 rDoc.AddPrintRange( nTab, aPrintRange ); 7073 } 7074 } 7075 7076 if ( rDoc.IsUndoEnabled() ) 7077 PrintAreaUndo_Impl( std::move(pOldRanges) ); // Undo, Page Breaks, Modified etc. 7078 } 7079 7080 sal_Bool SAL_CALL ScTableSheetObj::getPrintTitleColumns() 7081 { 7082 SolarMutexGuard aGuard; 7083 ScDocShell* pDocSh = GetDocShell(); 7084 if ( pDocSh ) 7085 { 7086 ScDocument& rDoc = pDocSh->GetDocument(); 7087 SCTAB nTab = GetTab_Impl(); 7088 return rDoc.GetRepeatColRange(nTab).has_value(); 7089 } 7090 return false; 7091 } 7092 7093 void SAL_CALL ScTableSheetObj::setPrintTitleColumns( sal_Bool bPrintTitleColumns ) 7094 { 7095 SolarMutexGuard aGuard; 7096 ScDocShell* pDocSh = GetDocShell(); 7097 if ( !pDocSh ) 7098 return; 7099 7100 ScDocument& rDoc = pDocSh->GetDocument(); 7101 SCTAB nTab = GetTab_Impl(); 7102 7103 std::unique_ptr<ScPrintRangeSaver> pOldRanges = rDoc.CreatePrintRangeSaver(); 7104 7105 if ( bPrintTitleColumns ) 7106 { 7107 if ( !rDoc.GetRepeatColRange( nTab ) ) // do not change existing area 7108 { 7109 rDoc.SetRepeatColRange( nTab, ScRange( 0, 0, nTab, 0, 0, nTab ) ); // enable 7110 } 7111 } 7112 else 7113 rDoc.SetRepeatColRange( nTab, std::nullopt ); // disable 7114 7115 PrintAreaUndo_Impl( std::move(pOldRanges) ); // undo, page break, modified etc. 7116 7117 //! save last set area during switch off and recreate during switch on ??? 7118 } 7119 7120 table::CellRangeAddress SAL_CALL ScTableSheetObj::getTitleColumns() 7121 { 7122 SolarMutexGuard aGuard; 7123 table::CellRangeAddress aRet; 7124 ScDocShell* pDocSh = GetDocShell(); 7125 if ( pDocSh ) 7126 { 7127 ScDocument& rDoc = pDocSh->GetDocument(); 7128 SCTAB nTab = GetTab_Impl(); 7129 std::optional<ScRange> oRange = rDoc.GetRepeatColRange(nTab); 7130 if (oRange) 7131 { 7132 ScUnoConversion::FillApiRange( aRet, *oRange ); 7133 aRet.Sheet = nTab; // core does not care about sheet index 7134 } 7135 } 7136 return aRet; 7137 } 7138 7139 void SAL_CALL ScTableSheetObj::setTitleColumns( const table::CellRangeAddress& aTitleColumns ) 7140 { 7141 SolarMutexGuard aGuard; 7142 ScDocShell* pDocSh = GetDocShell(); 7143 if ( !pDocSh ) 7144 return; 7145 7146 ScDocument& rDoc = pDocSh->GetDocument(); 7147 SCTAB nTab = GetTab_Impl(); 7148 7149 std::unique_ptr<ScPrintRangeSaver> pOldRanges = rDoc.CreatePrintRangeSaver(); 7150 7151 ScRange aNew; 7152 ScUnoConversion::FillScRange( aNew, aTitleColumns ); 7153 rDoc.SetRepeatColRange( nTab, std::move(aNew) ); // also always enable 7154 7155 PrintAreaUndo_Impl( std::move(pOldRanges) ); // undo, page breaks, modified etc. 7156 } 7157 7158 sal_Bool SAL_CALL ScTableSheetObj::getPrintTitleRows() 7159 { 7160 SolarMutexGuard aGuard; 7161 ScDocShell* pDocSh = GetDocShell(); 7162 if ( pDocSh ) 7163 { 7164 ScDocument& rDoc = pDocSh->GetDocument(); 7165 SCTAB nTab = GetTab_Impl(); 7166 return rDoc.GetRepeatRowRange(nTab).has_value(); 7167 } 7168 return false; 7169 } 7170 7171 void SAL_CALL ScTableSheetObj::setPrintTitleRows( sal_Bool bPrintTitleRows ) 7172 { 7173 SolarMutexGuard aGuard; 7174 ScDocShell* pDocSh = GetDocShell(); 7175 if ( !pDocSh ) 7176 return; 7177 7178 ScDocument& rDoc = pDocSh->GetDocument(); 7179 SCTAB nTab = GetTab_Impl(); 7180 7181 std::unique_ptr<ScPrintRangeSaver> pOldRanges = rDoc.CreatePrintRangeSaver(); 7182 7183 if ( bPrintTitleRows ) 7184 { 7185 if ( !rDoc.GetRepeatRowRange( nTab ) ) // do not change existing area 7186 { 7187 rDoc.SetRepeatRowRange( nTab, ScRange(0, 0, nTab, 0, 0, nTab) ); // enable 7188 } 7189 } 7190 else 7191 rDoc.SetRepeatRowRange( nTab, std::nullopt ); // disable 7192 7193 PrintAreaUndo_Impl( std::move(pOldRanges) ); // undo, page breaks, modified etc. 7194 7195 //! save last set area during switch off and recreate during switch on ??? 7196 } 7197 7198 table::CellRangeAddress SAL_CALL ScTableSheetObj::getTitleRows() 7199 { 7200 SolarMutexGuard aGuard; 7201 table::CellRangeAddress aRet; 7202 ScDocShell* pDocSh = GetDocShell(); 7203 if ( pDocSh ) 7204 { 7205 ScDocument& rDoc = pDocSh->GetDocument(); 7206 SCTAB nTab = GetTab_Impl(); 7207 std::optional<ScRange> oRange = rDoc.GetRepeatRowRange(nTab); 7208 if (oRange) 7209 { 7210 ScUnoConversion::FillApiRange( aRet, *oRange ); 7211 aRet.Sheet = nTab; // core does not care about sheet index 7212 } 7213 } 7214 return aRet; 7215 } 7216 7217 void SAL_CALL ScTableSheetObj::setTitleRows( const table::CellRangeAddress& aTitleRows ) 7218 { 7219 SolarMutexGuard aGuard; 7220 ScDocShell* pDocSh = GetDocShell(); 7221 if ( !pDocSh ) 7222 return; 7223 7224 ScDocument& rDoc = pDocSh->GetDocument(); 7225 SCTAB nTab = GetTab_Impl(); 7226 7227 std::unique_ptr<ScPrintRangeSaver> pOldRanges = rDoc.CreatePrintRangeSaver(); 7228 7229 ScRange aNew; 7230 ScUnoConversion::FillScRange( aNew, aTitleRows ); 7231 rDoc.SetRepeatRowRange( nTab, std::move(aNew) ); // also always enable 7232 7233 PrintAreaUndo_Impl( std::move(pOldRanges) ); // Undo, page breaks, modified etc. 7234 } 7235 7236 // XSheetLinkable 7237 7238 sheet::SheetLinkMode SAL_CALL ScTableSheetObj::getLinkMode() 7239 { 7240 SolarMutexGuard aGuard; 7241 sheet::SheetLinkMode eRet = sheet::SheetLinkMode_NONE; 7242 ScDocShell* pDocSh = GetDocShell(); 7243 if ( pDocSh ) 7244 { 7245 ScLinkMode nMode = pDocSh->GetDocument().GetLinkMode( GetTab_Impl() ); 7246 if ( nMode == ScLinkMode::NORMAL ) 7247 eRet = sheet::SheetLinkMode_NORMAL; 7248 else if ( nMode == ScLinkMode::VALUE ) 7249 eRet = sheet::SheetLinkMode_VALUE; 7250 } 7251 return eRet; 7252 } 7253 7254 void SAL_CALL ScTableSheetObj::setLinkMode( sheet::SheetLinkMode nLinkMode ) 7255 { 7256 SolarMutexGuard aGuard; 7257 7258 //! search for filter and options in old link 7259 7260 OUString aUrl(getLinkUrl()); 7261 OUString aSheet(getLinkSheetName()); 7262 7263 link( aUrl, aSheet, "", "", nLinkMode ); 7264 } 7265 7266 OUString SAL_CALL ScTableSheetObj::getLinkUrl() 7267 { 7268 SolarMutexGuard aGuard; 7269 OUString aFile; 7270 ScDocShell* pDocSh = GetDocShell(); 7271 if ( pDocSh ) 7272 aFile = pDocSh->GetDocument().GetLinkDoc( GetTab_Impl() ); 7273 return aFile; 7274 } 7275 7276 void SAL_CALL ScTableSheetObj::setLinkUrl( const OUString& aLinkUrl ) 7277 { 7278 SolarMutexGuard aGuard; 7279 7280 //! search for filter and options in old link 7281 7282 sheet::SheetLinkMode eMode = getLinkMode(); 7283 OUString aSheet(getLinkSheetName()); 7284 7285 link( aLinkUrl, aSheet, "", "", eMode ); 7286 } 7287 7288 OUString SAL_CALL ScTableSheetObj::getLinkSheetName() 7289 { 7290 SolarMutexGuard aGuard; 7291 OUString aSheet; 7292 ScDocShell* pDocSh = GetDocShell(); 7293 if ( pDocSh ) 7294 aSheet = pDocSh->GetDocument().GetLinkTab( GetTab_Impl() ); 7295 return aSheet; 7296 } 7297 7298 void SAL_CALL ScTableSheetObj::setLinkSheetName( const OUString& aLinkSheetName ) 7299 { 7300 SolarMutexGuard aGuard; 7301 7302 //! search for filter and options in old link 7303 7304 sheet::SheetLinkMode eMode = getLinkMode(); 7305 OUString aUrl(getLinkUrl()); 7306 7307 link( aUrl, aLinkSheetName, "", "", eMode ); 7308 } 7309 7310 void SAL_CALL ScTableSheetObj::link( const OUString& aUrl, const OUString& aSheetName, 7311 const OUString& aFilterName, const OUString& aFilterOptions, 7312 sheet::SheetLinkMode nMode ) 7313 { 7314 SolarMutexGuard aGuard; 7315 ScDocShell* pDocSh = GetDocShell(); 7316 if ( !pDocSh ) 7317 return; 7318 7319 ScDocument& rDoc = pDocSh->GetDocument(); 7320 SCTAB nTab = GetTab_Impl(); 7321 7322 OUString aFileString = aUrl; 7323 OUString aFilterString = aFilterName; 7324 OUString aOptString = aFilterOptions; 7325 7326 aFileString = ScGlobal::GetAbsDocName( aFileString, pDocSh ); 7327 if (aFilterString.isEmpty()) 7328 ScDocumentLoader::GetFilterName( aFileString, aFilterString, aOptString, true, false ); 7329 7330 // remove application prefix from filter name here, so the filter options 7331 // aren't reset when the filter name is changed in ScTableLink::DataChanged 7332 ScDocumentLoader::RemoveAppPrefix( aFilterString ); 7333 7334 ScLinkMode nLinkMode = ScLinkMode::NONE; 7335 if ( nMode == sheet::SheetLinkMode_NORMAL ) 7336 nLinkMode = ScLinkMode::NORMAL; 7337 else if ( nMode == sheet::SheetLinkMode_VALUE ) 7338 nLinkMode = ScLinkMode::VALUE; 7339 7340 rDoc.SetLink( nTab, nLinkMode, aFileString, aFilterString, aOptString, aSheetName, 0/*nRefresh*/ ); 7341 7342 pDocSh->UpdateLinks(); // if needed add or delete link 7343 SfxBindings* pBindings = pDocSh->GetViewBindings(); 7344 if (pBindings) 7345 pBindings->Invalidate(SID_LINKS); 7346 7347 //! undo of link data on the table 7348 7349 if ( !(nLinkMode != ScLinkMode::NONE && rDoc.IsExecuteLinkEnabled()) ) // update link 7350 return; 7351 7352 // Always update link also if already exists 7353 //! update only on the affected table??? 7354 7355 sfx2::LinkManager* pLinkManager = rDoc.GetLinkManager(); 7356 sal_uInt16 nCount = pLinkManager->GetLinks().size(); 7357 for ( sal_uInt16 i=0; i<nCount; i++ ) 7358 { 7359 ::sfx2::SvBaseLink* pBase = pLinkManager->GetLinks()[i].get(); 7360 if (auto pTabLink = dynamic_cast<ScTableLink*>( pBase)) 7361 { 7362 if ( aFileString == pTabLink->GetFileName() ) 7363 pTabLink->Update(); // include Paint&Undo 7364 7365 //! The file name should only exists once (?) 7366 } 7367 } 7368 7369 //! notify ScSheetLinkObj objects!!! 7370 } 7371 7372 // XSheetAuditing 7373 7374 sal_Bool SAL_CALL ScTableSheetObj::hideDependents( const table::CellAddress& aPosition ) 7375 { 7376 SolarMutexGuard aGuard; 7377 ScDocShell* pDocSh = GetDocShell(); 7378 if ( pDocSh ) 7379 { 7380 SCTAB nTab = GetTab_Impl(); 7381 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" ); 7382 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab ); 7383 return pDocSh->GetDocFunc().DetectiveDelSucc( aPos ); 7384 } 7385 return false; 7386 } 7387 7388 sal_Bool SAL_CALL ScTableSheetObj::hidePrecedents( const table::CellAddress& aPosition ) 7389 { 7390 SolarMutexGuard aGuard; 7391 ScDocShell* pDocSh = GetDocShell(); 7392 if ( pDocSh ) 7393 { 7394 SCTAB nTab = GetTab_Impl(); 7395 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" ); 7396 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab ); 7397 return pDocSh->GetDocFunc().DetectiveDelPred( aPos ); 7398 } 7399 return false; 7400 } 7401 7402 sal_Bool SAL_CALL ScTableSheetObj::showDependents( const table::CellAddress& aPosition ) 7403 { 7404 SolarMutexGuard aGuard; 7405 ScDocShell* pDocSh = GetDocShell(); 7406 if ( pDocSh ) 7407 { 7408 SCTAB nTab = GetTab_Impl(); 7409 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" ); 7410 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab ); 7411 return pDocSh->GetDocFunc().DetectiveAddSucc( aPos ); 7412 } 7413 return false; 7414 } 7415 7416 sal_Bool SAL_CALL ScTableSheetObj::showPrecedents( const table::CellAddress& aPosition ) 7417 { 7418 SolarMutexGuard aGuard; 7419 ScDocShell* pDocSh = GetDocShell(); 7420 if ( pDocSh ) 7421 { 7422 SCTAB nTab = GetTab_Impl(); 7423 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" ); 7424 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab ); 7425 return pDocSh->GetDocFunc().DetectiveAddPred( aPos ); 7426 } 7427 return false; 7428 } 7429 7430 sal_Bool SAL_CALL ScTableSheetObj::showErrors( const table::CellAddress& aPosition ) 7431 { 7432 SolarMutexGuard aGuard; 7433 ScDocShell* pDocSh = GetDocShell(); 7434 if ( pDocSh ) 7435 { 7436 SCTAB nTab = GetTab_Impl(); 7437 OSL_ENSURE( aPosition.Sheet == nTab, "wrong table in CellAddress" ); 7438 ScAddress aPos( static_cast<SCCOL>(aPosition.Column), static_cast<SCROW>(aPosition.Row), nTab ); 7439 return pDocSh->GetDocFunc().DetectiveAddError( aPos ); 7440 } 7441 return false; 7442 } 7443 7444 sal_Bool SAL_CALL ScTableSheetObj::showInvalid() 7445 { 7446 SolarMutexGuard aGuard; 7447 ScDocShell* pDocSh = GetDocShell(); 7448 if ( pDocSh ) 7449 return pDocSh->GetDocFunc().DetectiveMarkInvalid( GetTab_Impl() ); 7450 return false; 7451 } 7452 7453 void SAL_CALL ScTableSheetObj::clearArrows() 7454 { 7455 SolarMutexGuard aGuard; 7456 ScDocShell* pDocSh = GetDocShell(); 7457 if ( pDocSh ) 7458 pDocSh->GetDocFunc().DetectiveDelAll( GetTab_Impl() ); 7459 } 7460 7461 // XSheetOutline 7462 7463 void SAL_CALL ScTableSheetObj::group( const table::CellRangeAddress& rGroupRange, 7464 table::TableOrientation nOrientation ) 7465 { 7466 SolarMutexGuard aGuard; 7467 ScDocShell* pDocSh = GetDocShell(); 7468 if ( pDocSh ) 7469 { 7470 bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS ); 7471 ScRange aGroupRange; 7472 ScUnoConversion::FillScRange( aGroupRange, rGroupRange ); 7473 ScOutlineDocFunc aFunc(*pDocSh); 7474 aFunc.MakeOutline( aGroupRange, bColumns, true, true ); 7475 } 7476 } 7477 7478 void SAL_CALL ScTableSheetObj::ungroup( const table::CellRangeAddress& rGroupRange, 7479 table::TableOrientation nOrientation ) 7480 { 7481 SolarMutexGuard aGuard; 7482 ScDocShell* pDocSh = GetDocShell(); 7483 if ( pDocSh ) 7484 { 7485 bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS ); 7486 ScRange aGroupRange; 7487 ScUnoConversion::FillScRange( aGroupRange, rGroupRange ); 7488 ScOutlineDocFunc aFunc(*pDocSh); 7489 aFunc.RemoveOutline( aGroupRange, bColumns, true, true ); 7490 } 7491 } 7492 7493 void SAL_CALL ScTableSheetObj::autoOutline( const table::CellRangeAddress& rCellRange ) 7494 { 7495 SolarMutexGuard aGuard; 7496 ScDocShell* pDocSh = GetDocShell(); 7497 if ( pDocSh ) 7498 { 7499 ScRange aFormulaRange; 7500 ScUnoConversion::FillScRange( aFormulaRange, rCellRange ); 7501 ScOutlineDocFunc aFunc(*pDocSh); 7502 aFunc.AutoOutline( aFormulaRange, true ); 7503 } 7504 } 7505 7506 void SAL_CALL ScTableSheetObj::clearOutline() 7507 { 7508 SolarMutexGuard aGuard; 7509 ScDocShell* pDocSh = GetDocShell(); 7510 if ( pDocSh ) 7511 { 7512 SCTAB nTab = GetTab_Impl(); 7513 ScOutlineDocFunc aFunc(*pDocSh); 7514 aFunc.RemoveAllOutlines( nTab, true ); 7515 } 7516 } 7517 7518 void SAL_CALL ScTableSheetObj::hideDetail( const table::CellRangeAddress& rCellRange ) 7519 { 7520 SolarMutexGuard aGuard; 7521 ScDocShell* pDocSh = GetDocShell(); 7522 if ( pDocSh ) 7523 { 7524 ScRange aMarkRange; 7525 ScUnoConversion::FillScRange( aMarkRange, rCellRange ); 7526 ScOutlineDocFunc aFunc(*pDocSh); 7527 aFunc.HideMarkedOutlines( aMarkRange, true ); 7528 } 7529 } 7530 7531 void SAL_CALL ScTableSheetObj::showDetail( const table::CellRangeAddress& rCellRange ) 7532 { 7533 SolarMutexGuard aGuard; 7534 ScDocShell* pDocSh = GetDocShell(); 7535 if ( pDocSh ) 7536 { 7537 ScRange aMarkRange; 7538 ScUnoConversion::FillScRange( aMarkRange, rCellRange ); 7539 ScOutlineDocFunc aFunc(*pDocSh); 7540 aFunc.ShowMarkedOutlines( aMarkRange, true ); 7541 } 7542 } 7543 7544 void SAL_CALL ScTableSheetObj::showLevel( sal_Int16 nLevel, table::TableOrientation nOrientation ) 7545 { 7546 SolarMutexGuard aGuard; 7547 ScDocShell* pDocSh = GetDocShell(); 7548 if ( pDocSh ) 7549 { 7550 bool bColumns = ( nOrientation == table::TableOrientation_COLUMNS ); 7551 SCTAB nTab = GetTab_Impl(); 7552 ScOutlineDocFunc aFunc(*pDocSh); 7553 aFunc.SelectLevel( nTab, bColumns, nLevel, true, true ); 7554 } 7555 } 7556 7557 // XProtectable 7558 7559 void SAL_CALL ScTableSheetObj::protect( const OUString& aPassword ) 7560 { 7561 SolarMutexGuard aGuard; 7562 ScDocShell* pDocSh = GetDocShell(); 7563 // #i108245# if already protected, don't change anything 7564 if ( pDocSh && !pDocSh->GetDocument().IsTabProtected( GetTab_Impl() ) ) 7565 { 7566 pDocSh->GetDocFunc().Protect( GetTab_Impl(), aPassword ); 7567 } 7568 } 7569 7570 void SAL_CALL ScTableSheetObj::unprotect( const OUString& aPassword ) 7571 { 7572 SolarMutexGuard aGuard; 7573 ScDocShell* pDocSh = GetDocShell(); 7574 if ( pDocSh ) 7575 { 7576 bool bDone = pDocSh->GetDocFunc().Unprotect( GetTab_Impl(), aPassword, true ); 7577 if (!bDone) 7578 throw lang::IllegalArgumentException(); 7579 } 7580 } 7581 7582 sal_Bool SAL_CALL ScTableSheetObj::isProtected() 7583 { 7584 SolarMutexGuard aGuard; 7585 ScDocShell* pDocSh = GetDocShell(); 7586 if ( pDocSh ) 7587 return pDocSh->GetDocument().IsTabProtected( GetTab_Impl() ); 7588 7589 OSL_FAIL("no DocShell"); //! Exception or so? 7590 return false; 7591 } 7592 7593 // XScenario 7594 7595 sal_Bool SAL_CALL ScTableSheetObj::getIsScenario() 7596 { 7597 SolarMutexGuard aGuard; 7598 ScDocShell* pDocSh = GetDocShell(); 7599 if ( pDocSh ) 7600 return pDocSh->GetDocument().IsScenario( GetTab_Impl() ); 7601 7602 return false; 7603 } 7604 7605 OUString SAL_CALL ScTableSheetObj::getScenarioComment() 7606 { 7607 SolarMutexGuard aGuard; 7608 ScDocShell* pDocSh = GetDocShell(); 7609 if ( pDocSh ) 7610 { 7611 OUString aComment; 7612 Color aColor; 7613 ScScenarioFlags nFlags; 7614 pDocSh->GetDocument().GetScenarioData( GetTab_Impl(), aComment, aColor, nFlags ); 7615 return aComment; 7616 } 7617 return OUString(); 7618 } 7619 7620 void SAL_CALL ScTableSheetObj::setScenarioComment( const OUString& aScenarioComment ) 7621 { 7622 SolarMutexGuard aGuard; 7623 ScDocShell* pDocSh = GetDocShell(); 7624 if ( !pDocSh ) 7625 return; 7626 7627 ScDocument& rDoc = pDocSh->GetDocument(); 7628 SCTAB nTab = GetTab_Impl(); 7629 7630 OUString aName; 7631 OUString aComment; 7632 Color aColor; 7633 ScScenarioFlags nFlags; 7634 rDoc.GetName( nTab, aName ); 7635 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags ); 7636 7637 aComment = aScenarioComment; 7638 7639 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 7640 } 7641 7642 void SAL_CALL ScTableSheetObj::addRanges( const uno::Sequence<table::CellRangeAddress>& rScenRanges ) 7643 { 7644 SolarMutexGuard aGuard; 7645 ScDocShell* pDocSh = GetDocShell(); 7646 if ( !pDocSh ) 7647 return; 7648 7649 ScDocument& rDoc = pDocSh->GetDocument(); 7650 SCTAB nTab = GetTab_Impl(); 7651 7652 if (!rDoc.IsScenario(nTab)) 7653 return; 7654 7655 ScMarkData aMarkData(rDoc.GetSheetLimits()); 7656 aMarkData.SelectTable( nTab, true ); 7657 7658 for (const table::CellRangeAddress& rRange : rScenRanges) 7659 { 7660 OSL_ENSURE( rRange.Sheet == nTab, "addRanges with wrong Tab" ); 7661 ScRange aOneRange( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), nTab, 7662 static_cast<SCCOL>(rRange.EndColumn), static_cast<SCROW>(rRange.EndRow), nTab ); 7663 7664 aMarkData.SetMultiMarkArea( aOneRange ); 7665 } 7666 7667 // Scenario ranges are tagged with attribute 7668 ScPatternAttr aPattern( rDoc.GetPool() ); 7669 aPattern.GetItemSet().Put( ScMergeFlagAttr( ScMF::Scenario ) ); 7670 aPattern.GetItemSet().Put( ScProtectionAttr( true ) ); 7671 pDocSh->GetDocFunc().ApplyAttributes( aMarkData, aPattern, true ); 7672 } 7673 7674 void SAL_CALL ScTableSheetObj::apply() 7675 { 7676 SolarMutexGuard aGuard; 7677 ScDocShell* pDocSh = GetDocShell(); 7678 if ( !pDocSh ) 7679 return; 7680 7681 ScDocument& rDoc = pDocSh->GetDocument(); 7682 SCTAB nTab = GetTab_Impl(); 7683 OUString aName; 7684 rDoc.GetName( nTab, aName ); // scenario name 7685 7686 SCTAB nDestTab = nTab; 7687 while ( nDestTab > 0 && rDoc.IsScenario(nDestTab) ) 7688 --nDestTab; 7689 7690 if ( !rDoc.IsScenario(nDestTab) ) 7691 pDocSh->UseScenario( nDestTab, aName ); 7692 7693 //! otherwise error or so 7694 } 7695 7696 // XScenarioEnhanced 7697 7698 uno::Sequence< table::CellRangeAddress > SAL_CALL ScTableSheetObj::getRanges( ) 7699 { 7700 SolarMutexGuard aGuard; 7701 ScDocShell* pDocSh = GetDocShell(); 7702 if ( pDocSh ) 7703 { 7704 ScDocument& rDoc = pDocSh->GetDocument(); 7705 SCTAB nTab = GetTab_Impl(); 7706 const ScRangeList* pRangeList = rDoc.GetScenarioRanges(nTab); 7707 if (pRangeList) 7708 { 7709 size_t nCount = pRangeList->size(); 7710 uno::Sequence< table::CellRangeAddress > aRetRanges( nCount ); 7711 table::CellRangeAddress* pAry = aRetRanges.getArray(); 7712 for( size_t nIndex = 0; nIndex < nCount; nIndex++ ) 7713 { 7714 const ScRange & rRange = (*pRangeList)[nIndex]; 7715 pAry->StartColumn = rRange.aStart.Col(); 7716 pAry->StartRow = rRange.aStart.Row(); 7717 pAry->EndColumn = rRange.aEnd.Col(); 7718 pAry->EndRow = rRange.aEnd.Row(); 7719 pAry->Sheet = rRange.aStart.Tab(); 7720 ++pAry; 7721 } 7722 return aRetRanges; 7723 } 7724 } 7725 return uno::Sequence< table::CellRangeAddress > (); 7726 } 7727 7728 // XExternalSheetName 7729 7730 void ScTableSheetObj::setExternalName( const OUString& aUrl, const OUString& aSheetName ) 7731 { 7732 SolarMutexGuard aGuard; 7733 ScDocShell* pDocSh = GetDocShell(); 7734 if ( pDocSh ) 7735 { 7736 ScDocument& rDoc = pDocSh->GetDocument(); 7737 const SCTAB nTab = GetTab_Impl(); 7738 const OUString aAbsDocName( ScGlobal::GetAbsDocName( aUrl, pDocSh ) ); 7739 const OUString aDocTabName( ScGlobal::GetDocTabName( aAbsDocName, aSheetName ) ); 7740 if ( !rDoc.RenameTab( nTab, aDocTabName, true /*bExternalDocument*/ ) ) 7741 { 7742 throw container::ElementExistException( OUString(), *this ); 7743 } 7744 } 7745 } 7746 7747 // XEventsSupplier 7748 7749 uno::Reference<container::XNameReplace> SAL_CALL ScTableSheetObj::getEvents() 7750 { 7751 SolarMutexGuard aGuard; 7752 ScDocShell* pDocSh = GetDocShell(); 7753 if ( pDocSh ) 7754 return new ScSheetEventsObj( pDocSh, GetTab_Impl() ); 7755 7756 return nullptr; 7757 } 7758 7759 // XPropertySet extended for Sheet-Properties 7760 7761 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableSheetObj::getPropertySetInfo() 7762 { 7763 SolarMutexGuard aGuard; 7764 static uno::Reference<beans::XPropertySetInfo> aRef( 7765 new SfxItemPropertySetInfo( pSheetPropSet->getPropertyMap() )); 7766 return aRef; 7767 } 7768 7769 void ScTableSheetObj::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue ) 7770 { 7771 if ( !pEntry ) 7772 return; 7773 7774 if ( IsScItemWid( pEntry->nWID ) ) 7775 { 7776 // for Item WIDs, call ScCellRangesBase directly 7777 ScCellRangesBase::SetOnePropertyValue(pEntry, aValue); 7778 return; 7779 } 7780 7781 // own properties 7782 7783 ScDocShell* pDocSh = GetDocShell(); 7784 if (!pDocSh) 7785 return; //! Exception or so? 7786 ScDocument& rDoc = pDocSh->GetDocument(); 7787 SCTAB nTab = GetTab_Impl(); 7788 ScDocFunc &rFunc = pDocSh->GetDocFunc(); 7789 7790 if ( pEntry->nWID == SC_WID_UNO_PAGESTL ) 7791 { 7792 OUString aStrVal; 7793 aValue >>= aStrVal; 7794 OUString aNewStr(ScStyleNameConversion::ProgrammaticToDisplayName( 7795 aStrVal, SfxStyleFamily::Page )); 7796 7797 //! Undo? (also if SID_STYLE_APPLY on View) 7798 7799 if ( rDoc.GetPageStyle( nTab ) != aNewStr ) 7800 { 7801 rDoc.SetPageStyle( nTab, aNewStr ); 7802 if (!rDoc.IsImportingXML()) 7803 { 7804 ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages(); 7805 7806 SfxBindings* pBindings = pDocSh->GetViewBindings(); 7807 if (pBindings) 7808 { 7809 pBindings->Invalidate( SID_STYLE_FAMILY4 ); 7810 pBindings->Invalidate( SID_STATUS_PAGESTYLE ); 7811 pBindings->Invalidate( FID_RESET_PRINTZOOM ); 7812 pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT ); 7813 pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT ); 7814 } 7815 } 7816 pDocSh->SetDocumentModified(); 7817 } 7818 } 7819 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) 7820 { 7821 bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 7822 rFunc.SetTableVisible( nTab, bVis, true ); 7823 } 7824 else if ( pEntry->nWID == SC_WID_UNO_ISACTIVE ) 7825 { 7826 if (rDoc.IsScenario(nTab)) 7827 rDoc.SetActiveScenario( nTab, ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); 7828 } 7829 else if ( pEntry->nWID == SC_WID_UNO_BORDCOL ) 7830 { 7831 if (rDoc.IsScenario(nTab)) 7832 { 7833 Color aColor; 7834 if (aValue >>= aColor) 7835 { 7836 OUString aName; 7837 OUString aComment; 7838 ScScenarioFlags nFlags; 7839 Color aTmp; 7840 rDoc.GetName( nTab, aName ); 7841 rDoc.GetScenarioData( nTab, aComment, aTmp, nFlags ); 7842 7843 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 7844 } 7845 } 7846 } 7847 else if ( pEntry->nWID == SC_WID_UNO_PROTECT ) 7848 { 7849 if (rDoc.IsScenario(nTab)) 7850 { 7851 OUString aName; 7852 OUString aComment; 7853 Color aColor; 7854 ScScenarioFlags nFlags; 7855 rDoc.GetName( nTab, aName ); 7856 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags ); 7857 bool bModify(false); 7858 7859 if (ScUnoHelpFunctions::GetBoolFromAny( aValue )) 7860 { 7861 if (!(nFlags & ScScenarioFlags::Protected)) 7862 { 7863 nFlags |= ScScenarioFlags::Protected; 7864 bModify = true; 7865 } 7866 } 7867 else 7868 { 7869 if (nFlags & ScScenarioFlags::Protected) 7870 { 7871 nFlags &= ~ScScenarioFlags::Protected; 7872 bModify = true; 7873 } 7874 } 7875 7876 if (bModify) 7877 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 7878 } 7879 } 7880 else if ( pEntry->nWID == SC_WID_UNO_SHOWBORD ) 7881 { 7882 if (rDoc.IsScenario(nTab)) 7883 { 7884 OUString aName; 7885 OUString aComment; 7886 Color aColor; 7887 ScScenarioFlags nFlags; 7888 rDoc.GetName( nTab, aName ); 7889 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags ); 7890 bool bModify(false); 7891 7892 if (ScUnoHelpFunctions::GetBoolFromAny( aValue )) 7893 { 7894 if (!(nFlags & ScScenarioFlags::ShowFrame)) 7895 { 7896 nFlags |= ScScenarioFlags::ShowFrame; 7897 bModify = true; 7898 } 7899 } 7900 else 7901 { 7902 if (nFlags & ScScenarioFlags::ShowFrame) 7903 { 7904 nFlags &= ~ScScenarioFlags::ShowFrame; 7905 bModify = true; 7906 } 7907 } 7908 7909 if (bModify) 7910 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 7911 } 7912 } 7913 else if ( pEntry->nWID == SC_WID_UNO_PRINTBORD ) 7914 { 7915 if (rDoc.IsScenario(nTab)) 7916 { 7917 OUString aName; 7918 OUString aComment; 7919 Color aColor; 7920 ScScenarioFlags nFlags; 7921 rDoc.GetName( nTab, aName ); 7922 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags ); 7923 bool bModify(false); 7924 7925 if (ScUnoHelpFunctions::GetBoolFromAny( aValue )) 7926 { 7927 if (!(nFlags & ScScenarioFlags::PrintFrame)) 7928 { 7929 nFlags |= ScScenarioFlags::PrintFrame; 7930 bModify = true; 7931 } 7932 } 7933 else 7934 { 7935 if (nFlags & ScScenarioFlags::PrintFrame) 7936 { 7937 nFlags &= ~ScScenarioFlags::PrintFrame; 7938 bModify = true; 7939 } 7940 } 7941 7942 if (bModify) 7943 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 7944 } 7945 } 7946 else if ( pEntry->nWID == SC_WID_UNO_COPYBACK ) 7947 { 7948 if (rDoc.IsScenario(nTab)) 7949 { 7950 OUString aName; 7951 OUString aComment; 7952 Color aColor; 7953 ScScenarioFlags nFlags; 7954 rDoc.GetName( nTab, aName ); 7955 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags ); 7956 bool bModify(false); 7957 7958 if (ScUnoHelpFunctions::GetBoolFromAny( aValue )) 7959 { 7960 if (!(nFlags & ScScenarioFlags::TwoWay)) 7961 { 7962 nFlags |= ScScenarioFlags::TwoWay; 7963 bModify = true; 7964 } 7965 } 7966 else 7967 { 7968 if (nFlags & ScScenarioFlags::TwoWay) 7969 { 7970 nFlags &= ~ScScenarioFlags::TwoWay; 7971 bModify = true; 7972 } 7973 } 7974 7975 if (bModify) 7976 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 7977 } 7978 } 7979 else if ( pEntry->nWID == SC_WID_UNO_COPYSTYL ) 7980 { 7981 if (rDoc.IsScenario(nTab)) 7982 { 7983 OUString aName; 7984 OUString aComment; 7985 Color aColor; 7986 ScScenarioFlags nFlags; 7987 rDoc.GetName( nTab, aName ); 7988 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags ); 7989 bool bModify(false); 7990 7991 if (ScUnoHelpFunctions::GetBoolFromAny( aValue )) 7992 { 7993 if (!(nFlags & ScScenarioFlags::Attrib)) 7994 { 7995 nFlags |= ScScenarioFlags::Attrib; 7996 bModify = true; 7997 } 7998 } 7999 else 8000 { 8001 if (nFlags & ScScenarioFlags::Attrib) 8002 { 8003 nFlags &= ~ScScenarioFlags::Attrib; 8004 bModify = true; 8005 } 8006 } 8007 8008 if (bModify) 8009 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 8010 } 8011 } 8012 else if ( pEntry->nWID == SC_WID_UNO_COPYFORM ) 8013 { 8014 if (rDoc.IsScenario(nTab)) 8015 { 8016 OUString aName; 8017 OUString aComment; 8018 Color aColor; 8019 ScScenarioFlags nFlags; 8020 rDoc.GetName( nTab, aName ); 8021 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags ); 8022 bool bModify(false); 8023 8024 if (ScUnoHelpFunctions::GetBoolFromAny( aValue )) 8025 { 8026 if (nFlags & ScScenarioFlags::Value) 8027 { 8028 nFlags &= ~ScScenarioFlags::Value; 8029 bModify = true; 8030 } 8031 } 8032 else 8033 { 8034 if (!(nFlags & ScScenarioFlags::Value)) 8035 { 8036 nFlags |= ScScenarioFlags::Value; 8037 bModify = true; 8038 } 8039 } 8040 8041 if (bModify) 8042 pDocSh->ModifyScenario( nTab, aName, aComment, aColor, nFlags ); 8043 } 8044 } 8045 else if ( pEntry->nWID == SC_WID_UNO_TABLAYOUT ) 8046 { 8047 sal_Int16 nValue = 0; 8048 if (aValue >>= nValue) 8049 { 8050 if (nValue == css::text::WritingMode2::RL_TB) 8051 rFunc.SetLayoutRTL(nTab, true); 8052 else 8053 rFunc.SetLayoutRTL(nTab, false); 8054 } 8055 } 8056 else if ( pEntry->nWID == SC_WID_UNO_AUTOPRINT ) 8057 { 8058 bool bAutoPrint = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 8059 if (bAutoPrint) 8060 rDoc.SetPrintEntireSheet( nTab ); // clears all print ranges 8061 else 8062 { 8063 if (rDoc.IsPrintEntireSheet( nTab )) 8064 rDoc.ClearPrintRanges( nTab ); // if this flag is true, there are no PrintRanges, so Clear clears only the flag. 8065 } 8066 } 8067 else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR ) 8068 { 8069 Color aColor = COL_AUTO; 8070 if ( aValue >>= aColor ) 8071 { 8072 if ( rDoc.GetTabBgColor( nTab ) != aColor ) 8073 rFunc.SetTabBgColor( nTab, aColor, true, true ); 8074 } 8075 } 8076 else if ( pEntry->nWID == SC_WID_UNO_CODENAME ) 8077 { 8078 OUString aCodeName; 8079 if (aValue >>= aCodeName) 8080 { 8081 pDocSh->GetDocument().SetCodeName( GetTab_Impl(), aCodeName ); 8082 } 8083 } 8084 else if (pEntry->nWID == SC_WID_UNO_CONDFORMAT) 8085 { 8086 uno::Reference<sheet::XConditionalFormats> xCondFormat; 8087 if (aValue >>= xCondFormat) 8088 { 8089 // how to set the format correctly 8090 } 8091 } 8092 else 8093 ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID 8094 } 8095 8096 void ScTableSheetObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, 8097 uno::Any& rAny ) 8098 { 8099 if ( !pEntry ) 8100 return; 8101 8102 ScDocShell* pDocSh = GetDocShell(); 8103 if (!pDocSh) 8104 throw uno::RuntimeException(); 8105 ScDocument& rDoc = pDocSh->GetDocument(); 8106 SCTAB nTab = GetTab_Impl(); 8107 8108 if ( pEntry->nWID == SC_WID_UNO_NAMES ) 8109 { 8110 rAny <<= uno::Reference<sheet::XNamedRanges>(new ScLocalNamedRangesObj(pDocSh, this)); 8111 } 8112 else if ( pEntry->nWID == SC_WID_UNO_PAGESTL ) 8113 { 8114 rAny <<= ScStyleNameConversion::DisplayToProgrammaticName( 8115 rDoc.GetPageStyle( nTab ), SfxStyleFamily::Page ); 8116 } 8117 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) 8118 { 8119 bool bVis = rDoc.IsVisible( nTab ); 8120 rAny <<= bVis; 8121 } 8122 else if ( pEntry->nWID == SC_WID_UNO_LINKDISPBIT ) 8123 { 8124 // no target bitmaps for individual entries (would be all equal) 8125 // ScLinkTargetTypeObj::SetLinkTargetBitmap( aAny, SC_LINKTARGETTYPE_SHEET ); 8126 } 8127 else if ( pEntry->nWID == SC_WID_UNO_LINKDISPNAME ) 8128 { 8129 // LinkDisplayName for hyperlink dialog 8130 rAny <<= getName(); // sheet name 8131 } 8132 else if ( pEntry->nWID == SC_WID_UNO_ISACTIVE ) 8133 { 8134 if (rDoc.IsScenario(nTab)) 8135 rAny <<= rDoc.IsActiveScenario( nTab ); 8136 } 8137 else if ( pEntry->nWID == SC_WID_UNO_BORDCOL ) 8138 { 8139 if (rDoc.IsScenario(nTab)) 8140 { 8141 OUString aComment; 8142 Color aColor; 8143 ScScenarioFlags nFlags; 8144 rDoc.GetScenarioData( nTab, aComment, aColor, nFlags ); 8145 8146 rAny <<= aColor; 8147 } 8148 } 8149 else if ( pEntry->nWID == SC_WID_UNO_PROTECT ) 8150 { 8151 if (rDoc.IsScenario(nTab)) 8152 { 8153 ScScenarioFlags nFlags; 8154 rDoc.GetScenarioFlags(nTab, nFlags); 8155 8156 rAny <<= ((nFlags & ScScenarioFlags::Protected) != ScScenarioFlags::NONE); 8157 } 8158 } 8159 else if ( pEntry->nWID == SC_WID_UNO_SHOWBORD ) 8160 { 8161 if (rDoc.IsScenario(nTab)) 8162 { 8163 ScScenarioFlags nFlags; 8164 rDoc.GetScenarioFlags(nTab, nFlags); 8165 8166 rAny <<= ((nFlags & ScScenarioFlags::ShowFrame) != ScScenarioFlags::NONE); 8167 } 8168 } 8169 else if ( pEntry->nWID == SC_WID_UNO_PRINTBORD ) 8170 { 8171 if (rDoc.IsScenario(nTab)) 8172 { 8173 ScScenarioFlags nFlags; 8174 rDoc.GetScenarioFlags(nTab, nFlags); 8175 8176 rAny <<= ((nFlags & ScScenarioFlags::PrintFrame) != ScScenarioFlags::NONE); 8177 } 8178 } 8179 else if ( pEntry->nWID == SC_WID_UNO_COPYBACK ) 8180 { 8181 if (rDoc.IsScenario(nTab)) 8182 { 8183 ScScenarioFlags nFlags; 8184 rDoc.GetScenarioFlags(nTab, nFlags); 8185 8186 rAny <<= ((nFlags & ScScenarioFlags::TwoWay) != ScScenarioFlags::NONE); 8187 } 8188 } 8189 else if ( pEntry->nWID == SC_WID_UNO_COPYSTYL ) 8190 { 8191 if (rDoc.IsScenario(nTab)) 8192 { 8193 ScScenarioFlags nFlags; 8194 rDoc.GetScenarioFlags(nTab, nFlags); 8195 8196 rAny <<= ((nFlags & ScScenarioFlags::Attrib) != ScScenarioFlags::NONE); 8197 } 8198 } 8199 else if ( pEntry->nWID == SC_WID_UNO_COPYFORM ) 8200 { 8201 if (rDoc.IsScenario(nTab)) 8202 { 8203 ScScenarioFlags nFlags; 8204 rDoc.GetScenarioFlags(nTab, nFlags); 8205 8206 rAny <<= !(nFlags & ScScenarioFlags::Value); 8207 } 8208 } 8209 else if ( pEntry->nWID == SC_WID_UNO_TABLAYOUT ) 8210 { 8211 if (rDoc.IsLayoutRTL(nTab)) 8212 rAny <<= sal_Int16(css::text::WritingMode2::RL_TB); 8213 else 8214 rAny <<= sal_Int16(css::text::WritingMode2::LR_TB); 8215 } 8216 else if ( pEntry->nWID == SC_WID_UNO_AUTOPRINT ) 8217 { 8218 bool bAutoPrint = rDoc.IsPrintEntireSheet( nTab ); 8219 rAny <<= bAutoPrint; 8220 } 8221 else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR ) 8222 { 8223 rAny <<= rDoc.GetTabBgColor(nTab); 8224 } 8225 else if ( pEntry->nWID == SC_WID_UNO_CODENAME ) 8226 { 8227 OUString aCodeName; 8228 pDocSh->GetDocument().GetCodeName(GetTab_Impl(), aCodeName); 8229 rAny <<= aCodeName; 8230 } 8231 else if (pEntry->nWID == SC_WID_UNO_CONDFORMAT) 8232 { 8233 rAny <<= uno::Reference<sheet::XConditionalFormats>(new ScCondFormatsObj(pDocSh, nTab)); 8234 } 8235 else 8236 ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); 8237 } 8238 8239 const SfxItemPropertyMap& ScTableSheetObj::GetItemPropertyMap() 8240 { 8241 return pSheetPropSet->getPropertyMap(); 8242 } 8243 8244 // XServiceInfo 8245 8246 OUString SAL_CALL ScTableSheetObj::getImplementationName() 8247 { 8248 return "ScTableSheetObj"; 8249 } 8250 8251 sal_Bool SAL_CALL ScTableSheetObj::supportsService( const OUString& rServiceName ) 8252 { 8253 return cppu::supportsService(this, rServiceName); 8254 } 8255 8256 uno::Sequence<OUString> SAL_CALL ScTableSheetObj::getSupportedServiceNames() 8257 { 8258 return {SCSPREADSHEET_SERVICE, 8259 SCSHEETCELLRANGE_SERVICE, 8260 SCCELLRANGE_SERVICE, 8261 SCCELLPROPERTIES_SERVICE, 8262 SCCHARPROPERTIES_SERVICE, 8263 SCPARAPROPERTIES_SERVICE, 8264 SCLINKTARGET_SERVICE}; 8265 } 8266 8267 // XUnoTunnel 8268 8269 UNO3_GETIMPLEMENTATION2_IMPL(ScTableSheetObj, ScCellRangeObj); 8270 8271 ScTableColumnObj::ScTableColumnObj( ScDocShell* pDocSh, SCCOL nCol, SCTAB nTab ) : 8272 ScCellRangeObj( pDocSh, ScRange(nCol,0,nTab, nCol, pDocSh->GetDocument().MaxRow(),nTab) ), 8273 pColPropSet(lcl_GetColumnPropertySet()) 8274 { 8275 } 8276 8277 ScTableColumnObj::~ScTableColumnObj() 8278 { 8279 } 8280 8281 uno::Any SAL_CALL ScTableColumnObj::queryInterface( const uno::Type& rType ) 8282 { 8283 SC_QUERYINTERFACE( container::XNamed ) 8284 8285 return ScCellRangeObj::queryInterface( rType ); 8286 } 8287 8288 void SAL_CALL ScTableColumnObj::acquire() noexcept 8289 { 8290 ScCellRangeObj::acquire(); 8291 } 8292 8293 void SAL_CALL ScTableColumnObj::release() noexcept 8294 { 8295 ScCellRangeObj::release(); 8296 } 8297 8298 uno::Sequence<uno::Type> SAL_CALL ScTableColumnObj::getTypes() 8299 { 8300 return comphelper::concatSequences( 8301 ScCellRangeObj::getTypes(), 8302 uno::Sequence<uno::Type> { cppu::UnoType<container::XNamed>::get() } ); 8303 } 8304 8305 uno::Sequence<sal_Int8> SAL_CALL ScTableColumnObj::getImplementationId() 8306 { 8307 return css::uno::Sequence<sal_Int8>(); 8308 } 8309 8310 // XNamed 8311 8312 OUString SAL_CALL ScTableColumnObj::getName() 8313 { 8314 SolarMutexGuard aGuard; 8315 8316 const ScRange& rRange = GetRange(); 8317 OSL_ENSURE(rRange.aStart.Col() == rRange.aEnd.Col(), "too many columns"); 8318 SCCOL nCol = rRange.aStart.Col(); 8319 8320 return ScColToAlpha( nCol ); // from global.hxx 8321 } 8322 8323 void SAL_CALL ScTableColumnObj::setName( const OUString& /* aNewName */ ) 8324 { 8325 throw uno::RuntimeException(); // read-only 8326 } 8327 8328 // XPropertySet extended for Column-Properties 8329 8330 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableColumnObj::getPropertySetInfo() 8331 { 8332 SolarMutexGuard aGuard; 8333 static uno::Reference<beans::XPropertySetInfo> aRef( 8334 new SfxItemPropertySetInfo( pColPropSet->getPropertyMap() )); 8335 return aRef; 8336 } 8337 8338 void ScTableColumnObj::SetOnePropertyValue(const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue) 8339 { 8340 if ( !pEntry ) 8341 return; 8342 8343 if ( IsScItemWid( pEntry->nWID ) ) 8344 { 8345 // for Item WIDs, call ScCellRangesBase directly 8346 ScCellRangesBase::SetOnePropertyValue(pEntry, aValue); 8347 return; 8348 } 8349 8350 // own properties 8351 8352 ScDocShell* pDocSh = GetDocShell(); 8353 if (!pDocSh) 8354 return; //! Exception or so? 8355 const ScRange& rRange = GetRange(); 8356 OSL_ENSURE(rRange.aStart.Col() == rRange.aEnd.Col(), "Too many columns"); 8357 SCCOL nCol = rRange.aStart.Col(); 8358 SCTAB nTab = rRange.aStart.Tab(); 8359 ScDocFunc &rFunc = pDocSh->GetDocFunc(); 8360 8361 std::vector<sc::ColRowSpan> aColArr(1, sc::ColRowSpan(nCol,nCol)); 8362 8363 if ( pEntry->nWID == SC_WID_UNO_CELLWID ) 8364 { 8365 sal_Int32 nNewWidth = 0; 8366 if ( aValue >>= nNewWidth ) 8367 { 8368 // property is 1/100mm, column width is twips 8369 nNewWidth = o3tl::toTwips(nNewWidth, o3tl::Length::mm100); 8370 rFunc.SetWidthOrHeight( 8371 true, aColArr, nTab, SC_SIZE_ORIGINAL, nNewWidth, true, true); 8372 } 8373 } 8374 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) 8375 { 8376 bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 8377 ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT; 8378 rFunc.SetWidthOrHeight(true, aColArr, nTab, eMode, 0, true, true); 8379 // SC_SIZE_DIRECT with size 0 will hide 8380 } 8381 else if ( pEntry->nWID == SC_WID_UNO_OWIDTH ) 8382 { 8383 bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 8384 if (bOpt) 8385 rFunc.SetWidthOrHeight( 8386 true, aColArr, nTab, SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH, true, true); 8387 // sal_False on columns currently without effect 8388 } 8389 else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE || pEntry->nWID == SC_WID_UNO_MANPAGE ) 8390 { 8391 bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 8392 if (bSet) 8393 rFunc.InsertPageBreak( true, rRange.aStart, true, true ); 8394 else 8395 rFunc.RemovePageBreak( true, rRange.aStart, true, true ); 8396 } 8397 else 8398 ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID 8399 } 8400 8401 void ScTableColumnObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny ) 8402 { 8403 if ( !pEntry ) 8404 return; 8405 8406 ScDocShell* pDocSh = GetDocShell(); 8407 if (!pDocSh) 8408 throw uno::RuntimeException(); 8409 8410 ScDocument& rDoc = pDocSh->GetDocument(); 8411 const ScRange& rRange = GetRange(); 8412 OSL_ENSURE(rRange.aStart.Col() == rRange.aEnd.Col(), "too many columns"); 8413 SCCOL nCol = rRange.aStart.Col(); 8414 SCTAB nTab = rRange.aStart.Tab(); 8415 8416 if ( pEntry->nWID == SC_WID_UNO_CELLWID ) 8417 { 8418 // for hidden column, return original height 8419 sal_uInt16 nWidth = rDoc.GetOriginalWidth( nCol, nTab ); 8420 // property is 1/100mm, column width is twips 8421 nWidth = static_cast<sal_uInt16>(convertTwipToMm100(nWidth)); 8422 rAny <<= static_cast<sal_Int32>(nWidth); 8423 } 8424 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) 8425 { 8426 bool bHidden = rDoc.ColHidden(nCol, nTab); 8427 rAny <<= !bHidden; 8428 } 8429 else if ( pEntry->nWID == SC_WID_UNO_OWIDTH ) 8430 { 8431 //! at the moment always set ??!?! 8432 bool bOpt = !(rDoc.GetColFlags( nCol, nTab ) & CRFlags::ManualSize); 8433 rAny <<= bOpt; 8434 } 8435 else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE ) 8436 { 8437 ScBreakType nBreak = rDoc.HasColBreak(nCol, nTab); 8438 rAny <<= nBreak != ScBreakType::NONE; 8439 } 8440 else if ( pEntry->nWID == SC_WID_UNO_MANPAGE ) 8441 { 8442 ScBreakType nBreak = rDoc.HasColBreak(nCol, nTab); 8443 rAny <<= bool(nBreak & ScBreakType::Manual); 8444 } 8445 else 8446 ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); 8447 } 8448 8449 const SfxItemPropertyMap& ScTableColumnObj::GetItemPropertyMap() 8450 { 8451 return pColPropSet->getPropertyMap(); 8452 } 8453 8454 ScTableRowObj::ScTableRowObj(ScDocShell* pDocSh, SCROW nRow, SCTAB nTab) : 8455 ScCellRangeObj( pDocSh, ScRange(0,nRow,nTab, pDocSh->GetDocument().MaxCol(),nRow,nTab) ), 8456 pRowPropSet(lcl_GetRowPropertySet()) 8457 { 8458 } 8459 8460 ScTableRowObj::~ScTableRowObj() 8461 { 8462 } 8463 8464 // XPropertySet extended for Row-Properties 8465 8466 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableRowObj::getPropertySetInfo() 8467 { 8468 SolarMutexGuard aGuard; 8469 static uno::Reference<beans::XPropertySetInfo> aRef( 8470 new SfxItemPropertySetInfo( pRowPropSet->getPropertyMap() )); 8471 return aRef; 8472 } 8473 8474 void ScTableRowObj::SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const uno::Any& aValue ) 8475 { 8476 if ( !pEntry ) 8477 return; 8478 8479 if ( IsScItemWid( pEntry->nWID ) ) 8480 { 8481 // for Item WIDs, call ScCellRangesBase directly 8482 ScCellRangesBase::SetOnePropertyValue(pEntry, aValue); 8483 return; 8484 } 8485 8486 // own properties 8487 8488 ScDocShell* pDocSh = GetDocShell(); 8489 if (!pDocSh) 8490 return; //! Exception or so? 8491 ScDocument& rDoc = pDocSh->GetDocument(); 8492 const ScRange& rRange = GetRange(); 8493 OSL_ENSURE(rRange.aStart.Row() == rRange.aEnd.Row(), "too many rows"); 8494 SCROW nRow = rRange.aStart.Row(); 8495 SCTAB nTab = rRange.aStart.Tab(); 8496 ScDocFunc &rFunc = pDocSh->GetDocFunc(); 8497 8498 std::vector<sc::ColRowSpan> aRowArr(1, sc::ColRowSpan(nRow,nRow)); 8499 8500 if ( pEntry->nWID == SC_WID_UNO_CELLHGT ) 8501 { 8502 sal_Int32 nNewHeight = 0; 8503 if ( aValue >>= nNewHeight ) 8504 { 8505 // property is 1/100mm, row height is twips 8506 nNewHeight = o3tl::toTwips(nNewHeight, o3tl::Length::mm100); 8507 rFunc.SetWidthOrHeight( 8508 false, aRowArr, nTab, SC_SIZE_ORIGINAL, nNewHeight, true, true); 8509 } 8510 } 8511 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) 8512 { 8513 bool bVis = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 8514 ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT; 8515 rFunc.SetWidthOrHeight(false, aRowArr, nTab, eMode, 0, true, true); 8516 // SC_SIZE_DIRECT with size zero will hide 8517 } 8518 else if ( pEntry->nWID == SC_WID_UNO_CELLFILT ) 8519 { 8520 bool bFil = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 8521 // SC_SIZE_DIRECT with size zero will hide 8522 rDoc.SetRowFiltered(nRow, nRow, nTab, bFil); 8523 } 8524 else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT ) 8525 { 8526 bool bOpt = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 8527 if (bOpt) 8528 rFunc.SetWidthOrHeight(false, aRowArr, nTab, SC_SIZE_OPTIMAL, 0, true, true); 8529 else 8530 { 8531 // set current height again manually 8532 sal_uInt16 nHeight = rDoc.GetOriginalHeight( nRow, nTab ); 8533 rFunc.SetWidthOrHeight(false, aRowArr, nTab, SC_SIZE_ORIGINAL, nHeight, true, true); 8534 } 8535 } 8536 else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE || pEntry->nWID == SC_WID_UNO_MANPAGE ) 8537 { 8538 bool bSet = ScUnoHelpFunctions::GetBoolFromAny( aValue ); 8539 if (bSet) 8540 rFunc.InsertPageBreak( false, rRange.aStart, true, true ); 8541 else 8542 rFunc.RemovePageBreak( false, rRange.aStart, true, true ); 8543 } 8544 else 8545 ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID 8546 } 8547 8548 void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, uno::Any& rAny ) 8549 { 8550 if ( !pEntry ) 8551 return; 8552 8553 ScDocShell* pDocSh = GetDocShell(); 8554 if (!pDocSh) 8555 throw uno::RuntimeException(); 8556 ScDocument& rDoc = pDocSh->GetDocument(); 8557 const ScRange& rRange = GetRange(); 8558 OSL_ENSURE(rRange.aStart.Row() == rRange.aEnd.Row(), "too many rows"); 8559 SCROW nRow = rRange.aStart.Row(); 8560 SCTAB nTab = rRange.aStart.Tab(); 8561 8562 if ( pEntry->nWID == SC_WID_UNO_CELLHGT ) 8563 { 8564 // for hidden row, return original height 8565 sal_uInt16 nHeight = rDoc.GetOriginalHeight( nRow, nTab ); 8566 // property is 1/100mm, row height is twips 8567 nHeight = static_cast<sal_uInt16>(convertTwipToMm100(nHeight)); 8568 rAny <<= static_cast<sal_Int32>(nHeight); 8569 } 8570 else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) 8571 { 8572 bool bHidden = rDoc.RowHidden(nRow, nTab); 8573 rAny <<= !bHidden; 8574 } 8575 else if ( pEntry->nWID == SC_WID_UNO_CELLFILT ) 8576 { 8577 bool bVis = rDoc.RowFiltered(nRow, nTab); 8578 rAny <<= bVis; 8579 } 8580 else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT ) 8581 { 8582 bool bOpt = !(rDoc.GetRowFlags( nRow, nTab ) & CRFlags::ManualSize); 8583 rAny <<= bOpt; 8584 } 8585 else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE ) 8586 { 8587 ScBreakType nBreak = rDoc.HasRowBreak(nRow, nTab); 8588 rAny <<= (nBreak != ScBreakType::NONE); 8589 } 8590 else if ( pEntry->nWID == SC_WID_UNO_MANPAGE ) 8591 { 8592 bool bBreak(rDoc.HasRowBreak(nRow, nTab) & ScBreakType::Manual); 8593 rAny <<= bBreak; 8594 } 8595 else 8596 ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); 8597 } 8598 8599 const SfxItemPropertyMap& ScTableRowObj::GetItemPropertyMap() 8600 { 8601 return pRowPropSet->getPropertyMap(); 8602 } 8603 8604 ScCellsObj::ScCellsObj(ScDocShell* pDocSh, const ScRangeList& rR) : 8605 pDocShell( pDocSh ), 8606 aRanges( rR ) 8607 { 8608 pDocShell->GetDocument().AddUnoObject(*this); 8609 } 8610 8611 ScCellsObj::~ScCellsObj() 8612 { 8613 SolarMutexGuard g; 8614 8615 if (pDocShell) 8616 pDocShell->GetDocument().RemoveUnoObject(*this); 8617 } 8618 8619 void ScCellsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 8620 { 8621 if ( auto pRefHint = dynamic_cast<const ScUpdateRefHint*>(&rHint) ) 8622 { 8623 aRanges.UpdateReference( pRefHint->GetMode(), &pDocShell->GetDocument(), pRefHint->GetRange(), 8624 pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() ); 8625 } 8626 else if ( rHint.GetId() == SfxHintId::Dying ) 8627 { 8628 pDocShell = nullptr; 8629 } 8630 } 8631 8632 // XEnumerationAccess 8633 8634 uno::Reference<container::XEnumeration> SAL_CALL ScCellsObj::createEnumeration() 8635 { 8636 SolarMutexGuard aGuard; 8637 if (pDocShell) 8638 return new ScCellsEnumeration( pDocShell, aRanges ); 8639 return nullptr; 8640 } 8641 8642 uno::Type SAL_CALL ScCellsObj::getElementType() 8643 { 8644 return cppu::UnoType<table::XCell>::get(); 8645 } 8646 8647 sal_Bool SAL_CALL ScCellsObj::hasElements() 8648 { 8649 SolarMutexGuard aGuard; 8650 bool bHas = false; 8651 if ( pDocShell ) 8652 { 8653 //! faster if test ourself? 8654 8655 uno::Reference<container::XEnumeration> xEnum(new ScCellsEnumeration( pDocShell, aRanges )); 8656 bHas = xEnum->hasMoreElements(); 8657 } 8658 return bHas; 8659 } 8660 8661 ScCellsEnumeration::ScCellsEnumeration(ScDocShell* pDocSh, const ScRangeList& rR) : 8662 pDocShell( pDocSh ), 8663 aRanges( rR ), 8664 bAtEnd( false ) 8665 { 8666 ScDocument& rDoc = pDocShell->GetDocument(); 8667 rDoc.AddUnoObject(*this); 8668 8669 if ( aRanges.empty() ) 8670 bAtEnd = true; 8671 else 8672 { 8673 SCTAB nTab = aRanges[ 0 ].aStart.Tab(); 8674 aPos = ScAddress(0,0,nTab); 8675 CheckPos_Impl(); // set aPos on first matching cell 8676 } 8677 } 8678 8679 void ScCellsEnumeration::CheckPos_Impl() 8680 { 8681 if (!pDocShell) 8682 return; 8683 8684 bool bFound = false; 8685 ScDocument& rDoc = pDocShell->GetDocument(); 8686 ScRefCellValue aCell(rDoc, aPos); 8687 if (!aCell.isEmpty()) 8688 { 8689 if (!pMark) 8690 { 8691 pMark.reset( new ScMarkData(rDoc.GetSheetLimits()) ); 8692 pMark->MarkFromRangeList(aRanges, false); 8693 pMark->MarkToMulti(); // needed for GetNextMarkedCell 8694 } 8695 bFound = pMark->IsCellMarked(aPos.Col(), aPos.Row()); 8696 } 8697 if (!bFound) 8698 Advance_Impl(); 8699 } 8700 8701 ScCellsEnumeration::~ScCellsEnumeration() 8702 { 8703 SolarMutexGuard g; 8704 8705 if (pDocShell) 8706 pDocShell->GetDocument().RemoveUnoObject(*this); 8707 pMark.reset(); 8708 } 8709 8710 void ScCellsEnumeration::Advance_Impl() 8711 { 8712 OSL_ENSURE(!bAtEnd,"too much Advance_Impl"); 8713 if (!pMark) 8714 { 8715 pMark.reset( new ScMarkData(pDocShell->GetDocument().GetSheetLimits()) ); 8716 pMark->MarkFromRangeList( aRanges, false ); 8717 pMark->MarkToMulti(); // needed for GetNextMarkedCell 8718 } 8719 8720 SCCOL nCol = aPos.Col(); 8721 SCROW nRow = aPos.Row(); 8722 SCTAB nTab = aPos.Tab(); 8723 bool bFound = pDocShell->GetDocument().GetNextMarkedCell( nCol, nRow, nTab, *pMark ); 8724 if (bFound) 8725 aPos.Set( nCol, nRow, nTab ); 8726 else 8727 bAtEnd = true; // nothing will follow 8728 } 8729 8730 void ScCellsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint ) 8731 { 8732 const ScUpdateRefHint* pRefHint = dynamic_cast<const ScUpdateRefHint*>(&rHint); 8733 if ( pRefHint ) 8734 { 8735 if (pDocShell) 8736 { 8737 aRanges.UpdateReference( pRefHint->GetMode(), &pDocShell->GetDocument(), pRefHint->GetRange(), 8738 pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() ); 8739 8740 pMark.reset(); // recreate from moved area 8741 8742 if (!bAtEnd) // adjust aPos 8743 { 8744 ScRangeList aNew { ScRange(aPos) }; 8745 aNew.UpdateReference( pRefHint->GetMode(), &pDocShell->GetDocument(), pRefHint->GetRange(), 8746 pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() ); 8747 if (aNew.size()==1) 8748 { 8749 aPos = aNew[ 0 ].aStart; 8750 CheckPos_Impl(); 8751 } 8752 } 8753 } 8754 } 8755 else if ( rHint.GetId() == SfxHintId::Dying ) 8756 { 8757 pDocShell = nullptr; 8758 } 8759 } 8760 8761 // XEnumeration 8762 8763 sal_Bool SAL_CALL ScCellsEnumeration::hasMoreElements() 8764 { 8765 SolarMutexGuard aGuard; 8766 return !bAtEnd; 8767 } 8768 8769 uno::Any SAL_CALL ScCellsEnumeration::nextElement() 8770 { 8771 SolarMutexGuard aGuard; 8772 if (pDocShell && !bAtEnd) 8773 { 8774 // interface must match ScCellsObj::getElementType 8775 8776 ScAddress aTempPos(aPos); 8777 Advance_Impl(); 8778 return uno::Any(uno::Reference<table::XCell>(new ScCellObj( pDocShell, aTempPos ))); 8779 } 8780 8781 throw container::NoSuchElementException(); // no more elements 8782 } 8783 8784 ScCellFormatsObj::ScCellFormatsObj(ScDocShell* pDocSh, const ScRange& rRange) : 8785 pDocShell( pDocSh ), 8786 aTotalRange( rRange ) 8787 { 8788 ScDocument& rDoc = pDocShell->GetDocument(); 8789 rDoc.AddUnoObject(*this); 8790 8791 OSL_ENSURE( aTotalRange.aStart.Tab() == aTotalRange.aEnd.Tab(), "different tables" ); 8792 } 8793 8794 ScCellFormatsObj::~ScCellFormatsObj() 8795 { 8796 SolarMutexGuard g; 8797 8798 if (pDocShell) 8799 pDocShell->GetDocument().RemoveUnoObject(*this); 8800 } 8801 8802 void ScCellFormatsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 8803 { 8804 if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) ) 8805 { 8806 //! aTotalRange... 8807 } 8808 else if ( rHint.GetId() == SfxHintId::Dying ) 8809 { 8810 pDocShell = nullptr; 8811 } 8812 } 8813 8814 rtl::Reference<ScCellRangeObj> ScCellFormatsObj::GetObjectByIndex_Impl(tools::Long nIndex) const 8815 { 8816 //! access the AttrArrays directly !!!! 8817 8818 if (pDocShell) 8819 { 8820 ScDocument& rDoc = pDocShell->GetDocument(); 8821 tools::Long nPos = 0; 8822 ScAttrRectIterator aIter( rDoc, aTotalRange.aStart.Tab(), 8823 aTotalRange.aStart.Col(), aTotalRange.aStart.Row(), 8824 aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() ); 8825 SCCOL nCol1, nCol2; 8826 SCROW nRow1, nRow2; 8827 while ( aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) ) 8828 { 8829 if ( nPos == nIndex ) 8830 { 8831 SCTAB nTab = aTotalRange.aStart.Tab(); 8832 ScRange aNext( nCol1, nRow1, nTab, nCol2, nRow2, nTab ); 8833 8834 if ( aNext.aStart == aNext.aEnd ) 8835 return new ScCellObj( pDocShell, aNext.aStart ); 8836 else 8837 return new ScCellRangeObj( pDocShell, aNext ); 8838 } 8839 ++nPos; 8840 } 8841 } 8842 return {}; 8843 } 8844 8845 // XIndexAccess 8846 8847 sal_Int32 SAL_CALL ScCellFormatsObj::getCount() 8848 { 8849 SolarMutexGuard aGuard; 8850 8851 //! access the AttrArrays directly !!!! 8852 8853 tools::Long nCount = 0; 8854 if (pDocShell) 8855 { 8856 ScDocument& rDoc = pDocShell->GetDocument(); 8857 ScAttrRectIterator aIter( rDoc, aTotalRange.aStart.Tab(), 8858 aTotalRange.aStart.Col(), aTotalRange.aStart.Row(), 8859 aTotalRange.aEnd.Col(), aTotalRange.aEnd.Row() ); 8860 SCCOL nCol1, nCol2; 8861 SCROW nRow1, nRow2; 8862 while ( aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) ) 8863 ++nCount; 8864 } 8865 return nCount; 8866 } 8867 8868 uno::Any SAL_CALL ScCellFormatsObj::getByIndex( sal_Int32 nIndex ) 8869 { 8870 SolarMutexGuard aGuard; 8871 8872 uno::Reference<table::XCellRange> xRange(GetObjectByIndex_Impl(nIndex)); 8873 if (!xRange.is()) 8874 throw lang::IndexOutOfBoundsException(); 8875 8876 return uno::Any(xRange); 8877 8878 } 8879 8880 uno::Type SAL_CALL ScCellFormatsObj::getElementType() 8881 { 8882 return cppu::UnoType<table::XCellRange>::get(); 8883 } 8884 8885 sal_Bool SAL_CALL ScCellFormatsObj::hasElements() 8886 { 8887 SolarMutexGuard aGuard; 8888 return ( getCount() != 0 ); //! always greater then zero ?? 8889 } 8890 8891 // XEnumerationAccess 8892 8893 uno::Reference<container::XEnumeration> SAL_CALL ScCellFormatsObj::createEnumeration() 8894 { 8895 SolarMutexGuard aGuard; 8896 if (pDocShell) 8897 return new ScCellFormatsEnumeration( pDocShell, aTotalRange ); 8898 return nullptr; 8899 } 8900 8901 ScCellFormatsEnumeration::ScCellFormatsEnumeration(ScDocShell* pDocSh, const ScRange& rRange) : 8902 pDocShell( pDocSh ), 8903 nTab( rRange.aStart.Tab() ), 8904 bAtEnd( false ), 8905 bDirty( false ) 8906 { 8907 ScDocument& rDoc = pDocShell->GetDocument(); 8908 rDoc.AddUnoObject(*this); 8909 8910 OSL_ENSURE( rRange.aStart.Tab() == rRange.aEnd.Tab(), 8911 "CellFormatsEnumeration: different tables" ); 8912 8913 pIter.reset( new ScAttrRectIterator( rDoc, nTab, 8914 rRange.aStart.Col(), rRange.aStart.Row(), 8915 rRange.aEnd.Col(), rRange.aEnd.Row() ) ); 8916 Advance_Impl(); 8917 } 8918 8919 ScCellFormatsEnumeration::~ScCellFormatsEnumeration() 8920 { 8921 SolarMutexGuard g; 8922 8923 if (pDocShell) 8924 pDocShell->GetDocument().RemoveUnoObject(*this); 8925 } 8926 8927 void ScCellFormatsEnumeration::Advance_Impl() 8928 { 8929 OSL_ENSURE(!bAtEnd,"too many Advance_Impl"); 8930 8931 if ( pIter ) 8932 { 8933 if ( bDirty ) 8934 { 8935 pIter->DataChanged(); // new search for AttrArray-Index 8936 bDirty = false; 8937 } 8938 8939 SCCOL nCol1, nCol2; 8940 SCROW nRow1, nRow2; 8941 if ( pIter->GetNext( nCol1, nCol2, nRow1, nRow2 ) ) 8942 aNext = ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab ); 8943 else 8944 bAtEnd = true; 8945 } 8946 else 8947 bAtEnd = true; // document vanished or so 8948 } 8949 8950 rtl::Reference<ScCellRangeObj> ScCellFormatsEnumeration::NextObject_Impl() 8951 { 8952 rtl::Reference<ScCellRangeObj> pRet; 8953 if (pDocShell && !bAtEnd) 8954 { 8955 if ( aNext.aStart == aNext.aEnd ) 8956 pRet = new ScCellObj( pDocShell, aNext.aStart ); 8957 else 8958 pRet = new ScCellRangeObj( pDocShell, aNext ); 8959 Advance_Impl(); 8960 } 8961 return pRet; 8962 } 8963 8964 void ScCellFormatsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint ) 8965 { 8966 if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) ) 8967 { 8968 //! and now??? 8969 } 8970 else 8971 { 8972 const SfxHintId nId = rHint.GetId(); 8973 if ( nId == SfxHintId::Dying ) 8974 { 8975 pDocShell = nullptr; 8976 pIter.reset(); 8977 } 8978 else if ( nId == SfxHintId::DataChanged ) 8979 { 8980 bDirty = true; // AttrArray-Index possibly invalid 8981 } 8982 } 8983 } 8984 8985 // XEnumeration 8986 8987 sal_Bool SAL_CALL ScCellFormatsEnumeration::hasMoreElements() 8988 { 8989 SolarMutexGuard aGuard; 8990 return !bAtEnd; 8991 } 8992 8993 uno::Any SAL_CALL ScCellFormatsEnumeration::nextElement() 8994 { 8995 SolarMutexGuard aGuard; 8996 8997 if ( bAtEnd || !pDocShell ) 8998 throw container::NoSuchElementException(); // no more elements 8999 9000 // interface must match ScCellFormatsObj::getElementType 9001 9002 return uno::Any(uno::Reference<table::XCellRange> (NextObject_Impl())); 9003 } 9004 9005 ScUniqueCellFormatsObj::~ScUniqueCellFormatsObj() 9006 { 9007 SolarMutexGuard g; 9008 9009 if (pDocShell) 9010 pDocShell->GetDocument().RemoveUnoObject(*this); 9011 } 9012 9013 void ScUniqueCellFormatsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) 9014 { 9015 if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) ) 9016 { 9017 //! aTotalRange... 9018 } 9019 else 9020 { 9021 if ( rHint.GetId() == SfxHintId::Dying ) 9022 pDocShell = nullptr; 9023 } 9024 } 9025 9026 // Fill the list of formats from the document 9027 9028 namespace { 9029 9030 // hash code to access the range lists by ScPatternAttr pointer 9031 struct ScPatternHashCode 9032 { 9033 size_t operator()( const ScPatternAttr* pPattern ) const 9034 { 9035 return reinterpret_cast<size_t>(pPattern); 9036 } 9037 }; 9038 9039 } 9040 9041 // Hash map to find a range by its start row 9042 typedef std::unordered_map< SCROW, ScRange > ScRowRangeHashMap; 9043 9044 namespace { 9045 9046 // Hash map entry. 9047 // The Join method depends on the column-wise order of ScAttrRectIterator 9048 class ScUniqueFormatsEntry 9049 { 9050 enum EntryState { STATE_EMPTY, STATE_SINGLE, STATE_COMPLEX }; 9051 9052 EntryState eState; 9053 ScRange aSingleRange; 9054 ScRowRangeHashMap aJoinedRanges; // "active" ranges to be merged 9055 std::vector<ScRange> aCompletedRanges; // ranges that will no longer be touched 9056 ScRangeListRef aReturnRanges; // result as ScRangeList for further use 9057 9058 public: 9059 ScUniqueFormatsEntry() : eState( STATE_EMPTY ) {} 9060 9061 void Join( const ScRange& rNewRange ); 9062 const ScRangeList& GetRanges(); 9063 void Clear() { aReturnRanges.clear(); } // aJoinedRanges and aCompletedRanges are cleared in GetRanges 9064 }; 9065 9066 } 9067 9068 void ScUniqueFormatsEntry::Join( const ScRange& rNewRange ) 9069 { 9070 // Special-case handling for single range 9071 9072 if ( eState == STATE_EMPTY ) 9073 { 9074 aSingleRange = rNewRange; 9075 eState = STATE_SINGLE; 9076 return; 9077 } 9078 if ( eState == STATE_SINGLE ) 9079 { 9080 if ( aSingleRange.aStart.Row() == rNewRange.aStart.Row() && 9081 aSingleRange.aEnd.Row() == rNewRange.aEnd.Row() && 9082 aSingleRange.aEnd.Col() + 1 == rNewRange.aStart.Col() ) 9083 { 9084 aSingleRange.aEnd.SetCol( rNewRange.aEnd.Col() ); 9085 return; // still a single range 9086 } 9087 9088 SCROW nSingleRow = aSingleRange.aStart.Row(); 9089 aJoinedRanges.emplace( nSingleRow, aSingleRange ); 9090 eState = STATE_COMPLEX; 9091 // continue normally 9092 } 9093 9094 // This is called in the order of ScAttrRectIterator results. 9095 // rNewRange can only be joined with an existing entry if it's the same rows, starting in the next column. 9096 // If the old entry for the start row extends to a different end row, or ends in a different column, it 9097 // can be moved to aCompletedRanges because it can't be joined with following iterator results. 9098 // Everything happens within one sheet, so Tab can be ignored. 9099 9100 SCROW nStartRow = rNewRange.aStart.Row(); 9101 ScRowRangeHashMap::iterator aIter( aJoinedRanges.find( nStartRow ) ); // find the active entry for the start row 9102 if ( aIter != aJoinedRanges.end() ) 9103 { 9104 ScRange& rOldRange = aIter->second; 9105 if ( rOldRange.aEnd.Row() == rNewRange.aEnd.Row() && 9106 rOldRange.aEnd.Col() + 1 == rNewRange.aStart.Col() ) 9107 { 9108 // extend existing range 9109 rOldRange.aEnd.SetCol( rNewRange.aEnd.Col() ); 9110 } 9111 else 9112 { 9113 // move old range to aCompletedRanges, keep rNewRange for joining 9114 aCompletedRanges.push_back( rOldRange ); 9115 rOldRange = rNewRange; // replace in hash map 9116 } 9117 } 9118 else 9119 { 9120 // keep rNewRange for joining 9121 aJoinedRanges.emplace( nStartRow, rNewRange ); 9122 } 9123 } 9124 9125 const ScRangeList& ScUniqueFormatsEntry::GetRanges() 9126 { 9127 if ( eState == STATE_SINGLE ) 9128 { 9129 aReturnRanges = new ScRangeList( aSingleRange ); 9130 return *aReturnRanges; 9131 } 9132 9133 // move remaining entries from aJoinedRanges to aCompletedRanges 9134 9135 for ( const auto& rEntry : aJoinedRanges ) 9136 aCompletedRanges.push_back( rEntry.second ); 9137 aJoinedRanges.clear(); 9138 9139 // sort all ranges for a predictable API result 9140 9141 std::sort( aCompletedRanges.begin(), aCompletedRanges.end() ); 9142 9143 // fill and return ScRangeList 9144 9145 aReturnRanges = new ScRangeList; 9146 aReturnRanges->insert( aReturnRanges->end(), aCompletedRanges.begin(), aCompletedRanges.end() ); 9147 aCompletedRanges.clear(); 9148 9149 return *aReturnRanges; 9150 } 9151 9152 namespace { 9153 9154 // function object to sort the range lists by start of first range 9155 struct ScUniqueFormatsOrder 9156 { 9157 bool operator()( const ScRangeList& rList1, const ScRangeList& rList2 ) const 9158 { 9159 // all range lists have at least one entry 9160 OSL_ENSURE( !rList1.empty() && !rList2.empty(), "ScUniqueFormatsOrder: empty list" ); 9161 9162 // compare start positions using ScAddress comparison operator 9163 return ( rList1[ 0 ].aStart < rList2[ 0 ].aStart ); 9164 } 9165 }; 9166 9167 } 9168 9169 ScUniqueCellFormatsObj::ScUniqueCellFormatsObj(ScDocShell* pDocSh, const ScRange& rTotalRange) : 9170 pDocShell( pDocSh ) 9171 { 9172 pDocShell->GetDocument().AddUnoObject(*this); 9173 9174 OSL_ENSURE( rTotalRange.aStart.Tab() == rTotalRange.aEnd.Tab(), "different tables" ); 9175 9176 ScDocument& rDoc = pDocShell->GetDocument(); 9177 SCTAB nTab = rTotalRange.aStart.Tab(); 9178 ScAttrRectIterator aIter( rDoc, nTab, 9179 rTotalRange.aStart.Col(), rTotalRange.aStart.Row(), 9180 rTotalRange.aEnd.Col(), rTotalRange.aEnd.Row() ); 9181 SCCOL nCol1, nCol2; 9182 SCROW nRow1, nRow2; 9183 9184 // Collect the ranges for each format in a hash map, to avoid nested loops 9185 9186 std::unordered_map< const ScPatternAttr*, ScUniqueFormatsEntry, ScPatternHashCode > aHashMap; 9187 while (aIter.GetNext( nCol1, nCol2, nRow1, nRow2 ) ) 9188 { 9189 ScRange aRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab ); 9190 const ScPatternAttr* pPattern = rDoc.GetPattern(nCol1, nRow1, nTab); 9191 aHashMap[pPattern].Join( aRange ); 9192 } 9193 9194 // Fill the vector aRangeLists with the range lists from the hash map 9195 9196 aRangeLists.reserve( aHashMap.size() ); 9197 for ( auto& rMapEntry : aHashMap ) 9198 { 9199 ScUniqueFormatsEntry& rEntry = rMapEntry.second; 9200 const ScRangeList& rRanges = rEntry.GetRanges(); 9201 aRangeLists.push_back( rRanges ); // copy ScRangeList 9202 rEntry.Clear(); // free memory, don't hold both copies of all ranges 9203 } 9204 9205 // Sort the vector by first range's start position, to avoid random shuffling 9206 // due to using the ScPatterAttr pointers 9207 9208 ::std::sort( aRangeLists.begin(), aRangeLists.end(), ScUniqueFormatsOrder() ); 9209 } 9210 9211 9212 // XIndexAccess 9213 9214 sal_Int32 SAL_CALL ScUniqueCellFormatsObj::getCount() 9215 { 9216 SolarMutexGuard aGuard; 9217 9218 return aRangeLists.size(); 9219 } 9220 9221 uno::Any SAL_CALL ScUniqueCellFormatsObj::getByIndex( sal_Int32 nIndex ) 9222 { 9223 SolarMutexGuard aGuard; 9224 9225 if(o3tl::make_unsigned(nIndex) >= aRangeLists.size()) 9226 throw lang::IndexOutOfBoundsException(); 9227 9228 return uno::Any(uno::Reference<sheet::XSheetCellRangeContainer>(new ScCellRangesObj(pDocShell, aRangeLists[nIndex]))); 9229 9230 } 9231 9232 uno::Type SAL_CALL ScUniqueCellFormatsObj::getElementType() 9233 { 9234 return cppu::UnoType<sheet::XSheetCellRangeContainer>::get(); 9235 } 9236 9237 sal_Bool SAL_CALL ScUniqueCellFormatsObj::hasElements() 9238 { 9239 SolarMutexGuard aGuard; 9240 return ( !aRangeLists.empty() ); 9241 } 9242 9243 // XEnumerationAccess 9244 9245 uno::Reference<container::XEnumeration> SAL_CALL ScUniqueCellFormatsObj::createEnumeration() 9246 { 9247 SolarMutexGuard aGuard; 9248 if (pDocShell) 9249 return new ScUniqueCellFormatsEnumeration( pDocShell, std::vector(aRangeLists) ); 9250 return nullptr; 9251 } 9252 9253 ScUniqueCellFormatsEnumeration::ScUniqueCellFormatsEnumeration(ScDocShell* pDocSh, std::vector<ScRangeList>&& rRangeLists) : 9254 aRangeLists(std::move(rRangeLists)), 9255 pDocShell( pDocSh ), 9256 nCurrentPosition(0) 9257 { 9258 pDocShell->GetDocument().AddUnoObject(*this); 9259 } 9260 9261 ScUniqueCellFormatsEnumeration::~ScUniqueCellFormatsEnumeration() 9262 { 9263 SolarMutexGuard g; 9264 9265 if (pDocShell) 9266 pDocShell->GetDocument().RemoveUnoObject(*this); 9267 } 9268 9269 void ScUniqueCellFormatsEnumeration::Notify( SfxBroadcaster&, const SfxHint& rHint ) 9270 { 9271 if ( dynamic_cast<const ScUpdateRefHint*>(&rHint) ) 9272 { 9273 //! and now ??? 9274 } 9275 else 9276 { 9277 if ( rHint.GetId() == SfxHintId::Dying ) 9278 pDocShell = nullptr; 9279 } 9280 } 9281 9282 // XEnumeration 9283 9284 sal_Bool SAL_CALL ScUniqueCellFormatsEnumeration::hasMoreElements() 9285 { 9286 SolarMutexGuard aGuard; 9287 return o3tl::make_unsigned(nCurrentPosition) < aRangeLists.size(); 9288 } 9289 9290 uno::Any SAL_CALL ScUniqueCellFormatsEnumeration::nextElement() 9291 { 9292 SolarMutexGuard aGuard; 9293 9294 if ( !hasMoreElements() || !pDocShell ) 9295 throw container::NoSuchElementException(); // no more elements 9296 9297 // interface type must match ScCellFormatsObj::getElementType 9298 9299 return uno::Any(uno::Reference<sheet::XSheetCellRangeContainer>(new ScCellRangesObj(pDocShell, aRangeLists[nCurrentPosition++]))); 9300 } 9301 9302 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 9303
