Version 7.5.1.1, tag libreoffice-7.5.1.1
[LibreOffice.git] / sc / source / filter / html / htmlimp.cxx
blob12e98a9ef0189796e5be10953ad5f78dcdd52c70
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <scitems.hxx>
21 #include <osl/diagnose.h>
22 #include <unotools/charclass.hxx>
24 #include <editeng/lrspitem.hxx>
25 #include <editeng/paperinf.hxx>
26 #include <editeng/sizeitem.hxx>
27 #include <editeng/ulspitem.hxx>
28 #include <editeng/boxitem.hxx>
29 #include <vcl/svapp.hxx>
30 #include <o3tl/string_view.hxx>
32 #include <htmlimp.hxx>
33 #include <htmlpars.hxx>
34 #include <filter.hxx>
35 #include <global.hxx>
36 #include <document.hxx>
37 #include <editutil.hxx>
38 #include <stlpool.hxx>
39 #include <stlsheet.hxx>
40 #include <refdata.hxx>
41 #include <rangenam.hxx>
42 #include <attrib.hxx>
43 #include <ftools.hxx>
44 #include <tokenarray.hxx>
46 ErrCode ScFormatFilterPluginImpl::ScImportHTML( SvStream &rStream, const OUString& rBaseURL, ScDocument *pDoc,
47 ScRange& rRange, double nOutputFactor, bool bCalcWidthHeight, SvNumberFormatter* pFormatter,
48 bool bConvertDate )
50 ScHTMLImport aImp( pDoc, rBaseURL, rRange, bCalcWidthHeight );
51 ErrCode nErr = aImp.Read( rStream, rBaseURL );
52 ScRange aR = aImp.GetRange();
53 rRange.aEnd = aR.aEnd;
54 aImp.WriteToDocument( true, nOutputFactor, pFormatter, bConvertDate );
55 return nErr;
58 std::unique_ptr<ScEEAbsImport> ScFormatFilterPluginImpl::CreateHTMLImport( ScDocument* pDocP, const OUString& rBaseURL, const ScRange& rRange )
60 return std::make_unique<ScHTMLImport>( pDocP, rBaseURL, rRange, true/*bCalcWidthHeight*/ );
63 ScHTMLImport::ScHTMLImport( ScDocument* pDocP, const OUString& rBaseURL, const ScRange& rRange, bool bCalcWidthHeight ) :
64 ScEEImport( pDocP, rRange )
66 Size aPageSize;
67 OutputDevice* pDefaultDev = Application::GetDefaultDevice();
68 const OUString& aPageStyle = mpDoc->GetPageStyle( rRange.aStart.Tab() );
69 ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>(mpDoc->
70 GetStyleSheetPool()->Find( aPageStyle, SfxStyleFamily::Page ));
71 if ( pStyleSheet )
73 const SfxItemSet& rSet = pStyleSheet->GetItemSet();
74 const SvxLRSpaceItem* pLRItem = &rSet.Get( ATTR_LRSPACE );
75 tools::Long nLeftMargin = pLRItem->GetLeft();
76 tools::Long nRightMargin = pLRItem->GetRight();
77 const SvxULSpaceItem* pULItem = &rSet.Get( ATTR_ULSPACE );
78 tools::Long nTopMargin = pULItem->GetUpper();
79 tools::Long nBottomMargin = pULItem->GetLower();
80 aPageSize = rSet.Get(ATTR_PAGE_SIZE).GetSize();
81 if ( !aPageSize.Width() || !aPageSize.Height() )
83 OSL_FAIL("PageSize Null ?!?!?");
84 aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
86 aPageSize.AdjustWidth( -(nLeftMargin + nRightMargin) );
87 aPageSize.AdjustHeight( -(nTopMargin + nBottomMargin) );
88 aPageSize = pDefaultDev->LogicToPixel( aPageSize, MapMode( MapUnit::MapTwip ) );
90 else
92 OSL_FAIL("no StyleSheet?!?");
93 aPageSize = pDefaultDev->LogicToPixel(
94 SvxPaperInfo::GetPaperSize( PAPER_A4 ), MapMode( MapUnit::MapTwip ) );
96 if( bCalcWidthHeight )
97 mpParser.reset( new ScHTMLLayoutParser( mpEngine.get(), rBaseURL, aPageSize, pDocP ));
98 else
99 mpParser.reset( new ScHTMLQueryParser( mpEngine.get(), pDocP ));
102 void ScHTMLImport::InsertRangeName( ScDocument& rDoc, const OUString& rName, const ScRange& rRange )
104 ScComplexRefData aRefData;
105 aRefData.InitRange( rRange );
106 aRefData.Ref1.SetFlag3D( true );
107 aRefData.Ref2.SetFlag3D( aRefData.Ref2.Tab() != aRefData.Ref1.Tab() );
108 ScTokenArray aTokArray(rDoc);
109 aTokArray.AddDoubleReference( aRefData );
110 ScRangeData* pRangeData = new ScRangeData( rDoc, rName, aTokArray );
111 rDoc.GetRangeName()->insert( pRangeData );
114 void ScHTMLImport::WriteToDocument(
115 bool bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate )
117 ScEEImport::WriteToDocument( bSizeColsRows, nOutputFactor, pFormatter, bConvertDate );
119 const ScHTMLParser* pParser = static_cast<ScHTMLParser*>(mpParser.get());
120 const ScHTMLTable* pGlobTable = pParser->GetGlobalTable();
121 if( !pGlobTable )
122 return;
124 // set cell borders for HTML table cells
125 pGlobTable->ApplyCellBorders( mpDoc, maRange.aStart );
127 // correct cell borders for merged cells
128 for ( size_t i = 0, n = pParser->ListSize(); i < n; ++i )
130 const ScEEParseEntry* pEntry = pParser->ListEntry( i );
131 if( (pEntry->nColOverlap > 1) || (pEntry->nRowOverlap > 1) )
133 SCTAB nTab = maRange.aStart.Tab();
134 const ScMergeAttr* pItem = mpDoc->GetAttr( pEntry->nCol, pEntry->nRow, nTab, ATTR_MERGE );
135 if( pItem->IsMerged() )
137 SCCOL nColMerge = pItem->GetColMerge();
138 SCROW nRowMerge = pItem->GetRowMerge();
140 const SvxBoxItem* pToItem = mpDoc->GetAttr( pEntry->nCol, pEntry->nRow, nTab, ATTR_BORDER );
141 SvxBoxItem aNewItem( *pToItem );
142 if( nColMerge > 1 )
144 const SvxBoxItem* pFromItem =
145 mpDoc->GetAttr( pEntry->nCol + nColMerge - 1, pEntry->nRow, nTab, ATTR_BORDER );
146 aNewItem.SetLine( pFromItem->GetLine( SvxBoxItemLine::RIGHT ), SvxBoxItemLine::RIGHT );
148 if( nRowMerge > 1 )
150 const SvxBoxItem* pFromItem =
151 mpDoc->GetAttr( pEntry->nCol, pEntry->nRow + nRowMerge - 1, nTab, ATTR_BORDER );
152 aNewItem.SetLine( pFromItem->GetLine( SvxBoxItemLine::BOTTOM ), SvxBoxItemLine::BOTTOM );
154 mpDoc->ApplyAttr( pEntry->nCol, pEntry->nRow, nTab, aNewItem );
159 // create ranges for HTML tables
160 // 1 - entire document
161 ScRange aNewRange( maRange.aStart );
162 aNewRange.aEnd.IncCol( static_cast<SCCOL>(pGlobTable->GetDocSize( tdCol )) - 1 );
163 aNewRange.aEnd.IncRow( pGlobTable->GetDocSize( tdRow ) - 1 );
164 InsertRangeName( *mpDoc, ScfTools::GetHTMLDocName(), aNewRange );
166 // 2 - all tables
167 InsertRangeName( *mpDoc, ScfTools::GetHTMLTablesName(), ScRange( maRange.aStart ) );
169 // 3 - single tables
170 SCCOL nColDiff = maRange.aStart.Col();
171 SCROW nRowDiff = maRange.aStart.Row();
172 SCTAB nTabDiff = maRange.aStart.Tab();
174 ScHTMLTable* pTable = nullptr;
175 ScHTMLTableId nTableId = SC_HTML_GLOBAL_TABLE;
176 ScRange aErrorRange( ScAddress::UNINITIALIZED );
177 while( (pTable = pGlobTable->FindNestedTable( ++nTableId )) != nullptr )
179 pTable->GetDocRange( aNewRange );
180 if (!aNewRange.Move( nColDiff, nRowDiff, nTabDiff, aErrorRange, *mpDoc ))
182 assert(!"can't move");
184 // insert table number as name
185 OUStringBuffer aName(ScfTools::GetNameFromHTMLIndex(nTableId));
186 // insert table id as name
187 if (!pTable->GetTableName().isEmpty())
188 aName.append(" - " + pTable->GetTableName());
189 // insert table caption as name
190 if (!pTable->GetTableCaption().isEmpty())
191 aName.append(" - " + pTable->GetTableCaption());
192 const OUString sName(aName.makeStringAndClear());
193 if (!mpDoc->GetRangeName()->findByUpperName(ScGlobal::getCharClass().uppercase(sName)))
194 InsertRangeName(*mpDoc, sName, aNewRange);
198 OUString ScFormatFilterPluginImpl::GetHTMLRangeNameList( ScDocument& rDoc, const OUString& rOrigName )
200 return ScHTMLImport::GetHTMLRangeNameList( rDoc, rOrigName );
203 OUString ScHTMLImport::GetHTMLRangeNameList( const ScDocument& rDoc, std::u16string_view rOrigName )
205 if (rOrigName.empty())
206 return OUString();
208 OUString aNewName;
209 ScRangeName* pRangeNames = rDoc.GetRangeName();
210 ScRangeList aRangeList;
211 sal_Int32 nStringIx = 0;
214 OUString aToken( o3tl::getToken(rOrigName, 0, ';', nStringIx ) );
215 if( pRangeNames && ScfTools::IsHTMLTablesName( aToken ) )
216 { // build list with all HTML tables
217 sal_uLong nIndex = 1;
218 for(;;)
220 aToken = ScfTools::GetNameFromHTMLIndex( nIndex++ );
221 const ScRangeData* pRangeData = pRangeNames->findByUpperName(ScGlobal::getCharClass().uppercase(aToken));
222 if (!pRangeData)
223 break;
224 ScRange aRange;
225 if( pRangeData->IsReference( aRange ) && !aRangeList.Contains( aRange ) )
227 aNewName = ScGlobal::addToken(aNewName, aToken, ';');
228 aRangeList.push_back( aRange );
232 else
233 aNewName = ScGlobal::addToken(aNewName, aToken, ';');
235 while (nStringIx>0);
236 return aNewName;
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */