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