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( "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  bool bRet = importFragment( xWorkbookFragment);
113  if (bRet)
114  {
115  const WorkbookFragment* pWF = static_cast<const WorkbookFragment*>(xWorkbookFragment.get());
116  const AddressConverter& rAC = pWF->getAddressConverter();
117  if (rAC.isTabOverflow() || rAC.isColOverflow() || rAC.isRowOverflow())
118  {
119  const ScDocument& rDoc = pWF->getScDocument();
120  if (rDoc.IsUserInteractionEnabled())
121  {
122  // Show data loss warning.
123 
128  nullptr, RID_ERRCTX);
129 
130  OUString aWarning;
131  aContext.GetString( ERRCODE_NONE.MakeWarning(), aWarning);
132  aWarning += ":\n";
133 
134  OUString aMsg;
135  if (rAC.isTabOverflow())
136  {
138  aWarning += aMsg;
139  }
140  if (rAC.isColOverflow())
141  {
142  if (!aMsg.isEmpty())
143  aWarning += "\n";
145  aWarning += aMsg;
146  }
147  if (rAC.isRowOverflow())
148  {
149  if (!aMsg.isEmpty())
150  aWarning += "\n";
152  aWarning += aMsg;
153  }
154 
155  /* XXX displaying a dialog here is ugly and should
156  * rather happen at UI level instead of at the filter
157  * level, but it seems there's no way to transport
158  * detailed information other than returning true or
159  * false at this point? */
160 
161  std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
162  VclMessageType::Warning, VclButtonsType::Ok,
163  aWarning));
164  xWarn->run();
165  }
166  }
167  }
168  return bRet;
169  }
170  }
171  catch (...)
172  {
173  }
174 
175  return false;
176 }
177 
179 {
180  return false;
181 }
182 
183 const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const
184 {
186 }
187 
189 {
190  return nullptr;
191 }
192 
194 {
195  return TableStyleListPtr();
196 }
197 
199 {
201 }
202 
204 {
206 }
207 
209 {
210  return new ExcelGraphicHelper( getWorkbookGlobals() );
211 }
212 
214 {
215  return new ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
216 }
217 
218 sal_Bool SAL_CALL ExcelFilter::filter( const css::uno::Sequence< css::beans::PropertyValue >& rDescriptor )
219 {
220  if ( XmlFilterBase::filter( rDescriptor ) )
221  return true;
222 
223  if ( isExportFilter() )
224  {
225  bool bExportVBA = exportVBA();
226  Reference< XExporter > xExporter(
227  new XclExpXmlStream( getComponentContext(), bExportVBA, isExportTemplate() ) );
228 
229  Reference< XComponent > xDocument = getModel();
230  Reference< XFilter > xFilter( xExporter, UNO_QUERY );
231 
232  if ( xFilter.is() )
233  {
234  xExporter->setSourceDocument( xDocument );
235  if ( xFilter->filter( rDescriptor ) )
236  return true;
237  }
238  }
239 
240  return false;
241 }
242 
244 {
245  return "com.sun.star.comp.oox.xls.ExcelFilter";
246 }
247 
248 } // namespace oox::xls
249 
250 
251 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
252 com_sun_star_comp_oox_xls_ExcelFilter_get_implementation(css::uno::XComponentContext* context,
253  css::uno::Sequence<css::uno::Any> const &)
254 {
255  return cppu::acquire(new oox::xls::ExcelFilter(context));
256 }
257 
258 
259 /* 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
OUString getFragmentPathFromFirstTypeFromOfficeDoc(const OUString &rPart)
oox::drawingml::chart::ChartConverter * getChartConverter() const
Returns the chart object converter.
static weld::Window * GetActiveDialogParent()
Definition: docsh.cxx:2949
SC_DLLPUBLIC bool IsUserInteractionEnabled() const
Definition: document.hxx:1542
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
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:65
#define SCWARN_IMPORT_ROW_OVERFLOW
Definition: scerrors.hxx:63
#define SCWARN_IMPORT_COLUMN_OVERFLOW
Definition: scerrors.hxx:64
virtual bool exportDocument() override
WorkbookGlobals * mpBookGlob
Definition: excelfilter.hxx:57
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.
#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.