LibreOffice Module sc (master)  1
excelfilter.cxx
Go to the documentation of this file.
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 <excelfilter.hxx>
21 
22 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
23 #include <osl/diagnose.h>
24 #include <sal/log.hxx>
25 
26 #include <excelvbaproject.hxx>
27 #include <stylesbuffer.hxx>
28 #include <themebuffer.hxx>
29 #include <workbookfragment.hxx>
30 #include <xestream.hxx>
31 
32 #include <addressconverter.hxx>
33 #include <document.hxx>
34 #include <docsh.hxx>
35 #include <scerrors.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/weld.hxx>
38 #include <svtools/sfxecode.hxx>
39 #include <svtools/ehdl.hxx>
40 #include <tools/urlobj.hxx>
41 #include <tools/diagnose_ex.h>
42 
43 namespace oox::xls {
44 
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::sheet;
47 using namespace ::com::sun::star::uno;
48 using namespace ::oox::core;
49 
50 using ::oox::drawingml::table::TableStyleListPtr;
51 
53  XmlFilterBase( rxContext ),
54  mpBookGlob( nullptr )
55 {
56 }
57 
59 {
60  OSL_ENSURE( !mpBookGlob, "ExcelFilter::~ExcelFilter - workbook data not cleared" );
61 }
62 
64 {
65  mpBookGlob = &rBookGlob;
66 }
67 
69 {
70  OSL_ENSURE( mpBookGlob, "ExcelFilter::getWorkbookGlobals - missing workbook data" );
71  return *mpBookGlob;
72 }
73 
75 {
76  mpBookGlob = nullptr;
77 }
78 
80 {
81  /* To activate the XLSX/XLSB dumper, insert the full path to the file
82  file:///<path-to-oox-module>/source/dump/xlsbdumper.ini
83  into the environment variable OOO_XLSBDUMPER and start the office with
84  this variable (nonpro only). */
85  //OOX_DUMP_FILE( ::oox::dump::xlsb::Dumper );
86 
87  OUString aWorkbookPath = getFragmentPathFromFirstTypeFromOfficeDoc( u"officeDocument" );
88  if( aWorkbookPath.isEmpty() )
89  return false;
90 
91  try
92  {
93  try
94  {
96  }
97  catch( const Exception& )
98  {
99  TOOLS_WARN_EXCEPTION("sc", "exception when importing document properties");
100  }
101  catch( ... )
102  {
103  SAL_WARN("sc", "exception when importing document properties");
104  }
105  /* Construct the WorkbookGlobals object referred to by every instance of
106  the class WorkbookHelper, and execute the import filter by constructing
107  an instance of WorkbookFragment and loading the file. */
109  if (xBookGlob)
110  {
111  rtl::Reference<FragmentHandler> xWorkbookFragment( new WorkbookFragment(*xBookGlob, aWorkbookPath));
112 
113  const WorkbookFragment* pWF = static_cast<const WorkbookFragment*>(xWorkbookFragment.get());
114  const ScDocument& rDoc = pWF->getScDocument();
115  if (ScDocShell* pDocSh = static_cast<ScDocShell*>(rDoc.GetDocumentShell()))
116  pDocSh->SetInitialLinkUpdate( pDocSh->GetMedium());
117 
118  bool bRet = importFragment( xWorkbookFragment);
119  if (bRet)
120  {
121  const AddressConverter& rAC = pWF->getAddressConverter();
122  if (rAC.isTabOverflow() || rAC.isColOverflow() || rAC.isRowOverflow())
123  {
124  if (rDoc.IsUserInteractionEnabled())
125  {
126  // Show data loss warning.
127 
132  nullptr, RID_ERRCTX);
133 
134  OUString aWarning;
135  aContext.GetString( ERRCODE_NONE.MakeWarning(), aWarning);
136  aWarning += ":\n";
137 
138  OUString aMsg;
139  if (rAC.isTabOverflow())
140  {
142  aWarning += aMsg;
143  }
144  if (rAC.isColOverflow())
145  {
146  if (!aMsg.isEmpty())
147  aWarning += "\n";
149  aWarning += aMsg;
150  }
151  if (rAC.isRowOverflow())
152  {
153  if (!aMsg.isEmpty())
154  aWarning += "\n";
156  aWarning += aMsg;
157  }
158 
159  /* XXX displaying a dialog here is ugly and should
160  * rather happen at UI level instead of at the filter
161  * level, but it seems there's no way to transport
162  * detailed information other than returning true or
163  * false at this point? */
164 
165  std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
166  VclMessageType::Warning, VclButtonsType::Ok,
167  aWarning));
168  xWarn->run();
169  }
170  }
171  }
172  return bRet;
173  }
174  }
175  catch (...)
176  {
177  }
178 
179  return false;
180 }
181 
183 {
184  return false;
185 }
186 
187 const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const
188 {
190 }
191 
193 {
194  return nullptr;
195 }
196 
198 {
199  return TableStyleListPtr();
200 }
201 
203 {
205 }
206 
208 {
210 }
211 
213 {
214  return new ExcelGraphicHelper( getWorkbookGlobals() );
215 }
216 
218 {
219  return new ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
220 }
221 
222 sal_Bool SAL_CALL ExcelFilter::filter( const css::uno::Sequence< css::beans::PropertyValue >& rDescriptor )
223 {
224  if ( XmlFilterBase::filter( rDescriptor ) )
225  return true;
226 
227  if ( isExportFilter() )
228  {
229  bool bExportVBA = exportVBA();
230  Reference< XExporter > xExporter(
231  new XclExpXmlStream( getComponentContext(), bExportVBA, isExportTemplate() ) );
232 
233  Reference< XComponent > xDocument = getModel();
234  Reference< XFilter > xFilter( xExporter, UNO_QUERY );
235 
236  if ( xFilter.is() )
237  {
238  xExporter->setSourceDocument( xDocument );
239  if ( xFilter->filter( rDescriptor ) )
240  return true;
241  }
242  }
243 
244  return false;
245 }
246 
248 {
249  return "com.sun.star.comp.oox.xls.ExcelFilter";
250 }
251 
252 } // namespace oox::xls
253 
254 
255 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
256 com_sun_star_comp_oox_xls_ExcelFilter_get_implementation(css::uno::XComponentContext* context,
257  css::uno::Sequence<css::uno::Any> const &)
258 {
259  return cppu::acquire(new oox::xls::ExcelFilter(context));
260 }
261 
262 
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Helper class to provide access to global workbook data.
void registerWorkbookGlobals(WorkbookGlobals &rBookGlob)
Definition: excelfilter.cxx:63
bool exportVBA() const
URL aURL
oox::drawingml::chart::ChartConverter * getChartConverter() const
Returns the chart object converter.
virtual bool exportDocument() noexcept override
static weld::Window * GetActiveDialogParent()
Definition: docsh.cxx:3071
SC_DLLPUBLIC bool IsUserInteractionEnabled() const
Definition: document.hxx:1546
std::shared_ptr< TableStyleList > TableStyleListPtr
virtual ::oox::ole::VbaProject * implCreateVbaProject() const override
bool importFragment(const rtl::Reference< FragmentHandler > &rxHandler)
bool isExportTemplate() const
virtual ::oox::drawingml::table::TableStyleListPtr getTableStyles() override
virtual GraphicHelper * implCreateGraphicHelper() const override
bool isExportFilter() const
static bool GetErrorString(ErrCode nId, OUString &rStr)
void useInternalChartDataTable(bool bInternal)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define ERRCTX_SFX_OPENDOC
virtual bool importDocument() override
Definition: excelfilter.cxx:79
Special implementation of the VBA project for the Excel filters.
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
virtual ::oox::drawingml::chart::ChartConverter * getChartConverter() override
Relative character height if escaped.
WorkbookGlobals & getWorkbookGlobals() const
Definition: excelfilter.cxx:68
float u
unsigned char sal_Bool
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
std::shared_ptr< WorkbookGlobals > WorkbookGlobalsRef
virtual ::oox::vml::Drawing * getVmlDrawing() override
virtual OUString SAL_CALL getImplementationName() override
const css::uno::Reference< css::frame::XModel > & getModel() const
SVT_DLLPUBLIC const ErrMsgCode RID_ERRCTX[]
const OUString & getFileUrl() const
static WorkbookGlobalsRef constructGlobals(ExcelFilter &rFilter)
void unregisterWorkbookGlobals()
Definition: excelfilter.cxx:74
virtual ~ExcelFilter() override
Definition: excelfilter.cxx:58
Converter for cell addresses and cell ranges for OOXML and BIFF filters.
virtual void useInternalChartDataTable(bool bInternal) override
#define ERRCODE_NONE
#define SCWARN_IMPORT_SHEET_OVERFLOW
Definition: scerrors.hxx:64
#define SCWARN_IMPORT_ROW_OVERFLOW
Definition: scerrors.hxx:62
#define SCWARN_IMPORT_COLUMN_OVERFLOW
Definition: scerrors.hxx:63
OUString getFragmentPathFromFirstTypeFromOfficeDoc(std::u16string_view rPart)
WorkbookGlobals * mpBookGlob
Definition: excelfilter.hxx:56
ExcelFilter(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
Definition: excelfilter.cxx:52
ThemeBuffer & getTheme() const
Returns the office theme object read from the theme substorage.
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1057
#define SAL_WARN(area, stream)
virtual const ::oox::drawingml::Theme * getCurrentTheme() const override
virtual sal_Bool SAL_CALL filter(const css::uno::Sequence< css::beans::PropertyValue > &rDescriptor) override
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_oox_xls_ExcelFilter_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
bool GetString(ErrCode nErrId, OUString &rStr) override
AddressConverter & getAddressConverter() const
Returns the converter for string to cell address/range conversion.