1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <comphelper/string.hxx>
22 #include <editeng/eeitem.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>
31 #include "htmlimp.hxx"
32 #include "htmlpars.hxx"
35 #include "document.hxx"
36 #include "editutil.hxx"
37 #include "stlpool.hxx"
38 #include "stlsheet.hxx"
39 #include "compiler.hxx"
40 #include "rangenam.hxx"
43 #include "tokenarray.hxx"
46 //------------------------------------------------------------------------
48 FltError
ScFormatFilterPluginImpl::ScImportHTML( SvStream
&rStream
, const String
& rBaseURL
, ScDocument
*pDoc
,
49 ScRange
& rRange
, double nOutputFactor
, bool bCalcWidthHeight
, SvNumberFormatter
* pFormatter
,
52 ScHTMLImport
aImp( pDoc
, rBaseURL
, rRange
, bCalcWidthHeight
);
53 FltError nErr
= (FltError
) aImp
.Read( rStream
, rBaseURL
);
54 ScRange aR
= aImp
.GetRange();
55 rRange
.aEnd
= aR
.aEnd
;
56 aImp
.WriteToDocument( true, nOutputFactor
, pFormatter
, bConvertDate
);
60 ScEEAbsImport
*ScFormatFilterPluginImpl::CreateHTMLImport( ScDocument
* pDocP
, const String
& rBaseURL
, const ScRange
& rRange
, bool bCalcWidthHeight
)
62 return new ScHTMLImport( pDocP
, rBaseURL
, rRange
, bCalcWidthHeight
);
65 ScHTMLImport::ScHTMLImport( ScDocument
* pDocP
, const String
& rBaseURL
, const ScRange
& rRange
, bool bCalcWidthHeight
) :
66 ScEEImport( pDocP
, rRange
)
69 OutputDevice
* pDefaultDev
= Application::GetDefaultDevice();
70 const String
& aPageStyle
= mpDoc
->GetPageStyle( rRange
.aStart
.Tab() );
71 ScStyleSheet
* pStyleSheet
= (ScStyleSheet
*)mpDoc
->
72 GetStyleSheetPool()->Find( aPageStyle
, SFX_STYLE_FAMILY_PAGE
);
75 const SfxItemSet
& rSet
= pStyleSheet
->GetItemSet();
76 const SvxLRSpaceItem
* pLRItem
= (const SvxLRSpaceItem
*) &rSet
.Get( ATTR_LRSPACE
);
77 long nLeftMargin
= pLRItem
->GetLeft();
78 long nRightMargin
= pLRItem
->GetRight();
79 const SvxULSpaceItem
* pULItem
= (const SvxULSpaceItem
*) &rSet
.Get( ATTR_ULSPACE
);
80 long nTopMargin
= pULItem
->GetUpper();
81 long nBottomMargin
= pULItem
->GetLower();
82 aPageSize
= ((const SvxSizeItem
&) rSet
.Get(ATTR_PAGE_SIZE
)).GetSize();
83 if ( !aPageSize
.Width() || !aPageSize
.Height() )
85 OSL_FAIL("PageSize Null ?!?!?");
86 aPageSize
= SvxPaperInfo::GetPaperSize( PAPER_A4
);
88 aPageSize
.Width() -= nLeftMargin
+ nRightMargin
;
89 aPageSize
.Height() -= nTopMargin
+ nBottomMargin
;
90 aPageSize
= pDefaultDev
->LogicToPixel( aPageSize
, MapMode( MAP_TWIP
) );
94 OSL_FAIL("no StyleSheet?!?");
95 aPageSize
= pDefaultDev
->LogicToPixel(
96 SvxPaperInfo::GetPaperSize( PAPER_A4
), MapMode( MAP_TWIP
) );
98 if( bCalcWidthHeight
)
99 mpParser
= new ScHTMLLayoutParser( mpEngine
, rBaseURL
, aPageSize
, pDocP
);
101 mpParser
= new ScHTMLQueryParser( mpEngine
, pDocP
);
105 ScHTMLImport::~ScHTMLImport()
107 // Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
108 // Ist gewaehrleistet, da ScEEImport Basisklasse ist
109 delete (ScHTMLParser
*) mpParser
; // vor EditEngine!
113 void ScHTMLImport::InsertRangeName( ScDocument
* pDoc
, const String
& rName
, const ScRange
& rRange
)
115 ScComplexRefData aRefData
;
116 aRefData
.InitRange( rRange
);
117 ScTokenArray aTokArray
;
118 aTokArray
.AddDoubleReference( aRefData
);
119 ScRangeData
* pRangeData
= new ScRangeData( pDoc
, rName
, aTokArray
);
120 pDoc
->GetRangeName()->insert( pRangeData
);
123 void ScHTMLImport::WriteToDocument(
124 bool bSizeColsRows
, double nOutputFactor
, SvNumberFormatter
* pFormatter
, bool bConvertDate
)
126 ScEEImport::WriteToDocument( bSizeColsRows
, nOutputFactor
, pFormatter
, bConvertDate
);
128 const ScHTMLParser
* pParser
= GetParser();
129 const ScHTMLTable
* pGlobTable
= pParser
->GetGlobalTable();
133 // set cell borders for HTML table cells
134 pGlobTable
->ApplyCellBorders( mpDoc
, maRange
.aStart
);
136 // correct cell borders for merged cells
137 for ( size_t i
= 0, n
= pParser
->ListSize(); i
< n
; ++i
)
139 const ScEEParseEntry
* pEntry
= pParser
->ListEntry( i
);
140 if( (pEntry
->nColOverlap
> 1) || (pEntry
->nRowOverlap
> 1) )
142 SCTAB nTab
= maRange
.aStart
.Tab();
143 const ScMergeAttr
* pItem
= (ScMergeAttr
*) mpDoc
->GetAttr( pEntry
->nCol
, pEntry
->nRow
, nTab
, ATTR_MERGE
);
144 if( pItem
->IsMerged() )
146 SCCOL nColMerge
= pItem
->GetColMerge();
147 SCROW nRowMerge
= pItem
->GetRowMerge();
149 const SvxBoxItem
* pToItem
= (const SvxBoxItem
*)
150 mpDoc
->GetAttr( pEntry
->nCol
, pEntry
->nRow
, nTab
, ATTR_BORDER
);
151 SvxBoxItem
aNewItem( *pToItem
);
154 const SvxBoxItem
* pFromItem
= (const SvxBoxItem
*)
155 mpDoc
->GetAttr( pEntry
->nCol
+ nColMerge
- 1, pEntry
->nRow
, nTab
, ATTR_BORDER
);
156 aNewItem
.SetLine( pFromItem
->GetLine( BOX_LINE_RIGHT
), BOX_LINE_RIGHT
);
160 const SvxBoxItem
* pFromItem
= (const SvxBoxItem
*)
161 mpDoc
->GetAttr( pEntry
->nCol
, pEntry
->nRow
+ nRowMerge
- 1, nTab
, ATTR_BORDER
);
162 aNewItem
.SetLine( pFromItem
->GetLine( BOX_LINE_BOTTOM
), BOX_LINE_BOTTOM
);
164 mpDoc
->ApplyAttr( pEntry
->nCol
, pEntry
->nRow
, nTab
, aNewItem
);
169 // create ranges for HTML tables
170 // 1 - entire document
171 ScRange
aNewRange( maRange
.aStart
);
172 aNewRange
.aEnd
.IncCol( static_cast<SCsCOL
>(pGlobTable
->GetDocSize( tdCol
)) - 1 );
173 aNewRange
.aEnd
.IncRow( pGlobTable
->GetDocSize( tdRow
) - 1 );
174 InsertRangeName( mpDoc
, ScfTools::GetHTMLDocName(), aNewRange
);
177 InsertRangeName( mpDoc
, ScfTools::GetHTMLTablesName(), ScRange( maRange
.aStart
) );
180 SCsCOL nColDiff
= (SCsCOL
)maRange
.aStart
.Col();
181 SCsROW nRowDiff
= (SCsROW
)maRange
.aStart
.Row();
182 SCsTAB nTabDiff
= (SCsTAB
)maRange
.aStart
.Tab();
184 ScHTMLTable
* pTable
= NULL
;
185 ScHTMLTableId nTableId
= SC_HTML_GLOBAL_TABLE
;
186 while( (pTable
= pGlobTable
->FindNestedTable( ++nTableId
)) != 0 )
188 pTable
->GetDocRange( aNewRange
);
189 aNewRange
.Move( nColDiff
, nRowDiff
, nTabDiff
);
190 // insert table number as name
191 InsertRangeName( mpDoc
, ScfTools::GetNameFromHTMLIndex( nTableId
), aNewRange
);
192 // insert table id as name
193 if (!pTable
->GetTableName().isEmpty())
195 String
aName( ScfTools::GetNameFromHTMLName( pTable
->GetTableName() ) );
196 if (!mpDoc
->GetRangeName()->findByUpperName(ScGlobal::pCharClass
->uppercase(aName
)))
197 InsertRangeName( mpDoc
, aName
, aNewRange
);
202 String
ScFormatFilterPluginImpl::GetHTMLRangeNameList( ScDocument
* pDoc
, const String
& rOrigName
)
204 return ScHTMLImport::GetHTMLRangeNameList( pDoc
, rOrigName
);
207 String
ScHTMLImport::GetHTMLRangeNameList( ScDocument
* pDoc
, const String
& rOrigName
)
209 OSL_ENSURE( pDoc
, "ScHTMLImport::GetHTMLRangeNameList - missing document" );
212 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
213 ScRangeList aRangeList
;
214 xub_StrLen nTokenCnt
= comphelper::string::getTokenCount(rOrigName
, ';');
215 sal_Int32 nStringIx
= 0;
216 for( xub_StrLen nToken
= 0; nToken
< nTokenCnt
; nToken
++ )
218 String
aToken( rOrigName
.GetToken( 0, ';', nStringIx
) );
219 if( pRangeNames
&& ScfTools::IsHTMLTablesName( aToken
) )
220 { // build list with all HTML tables
221 sal_uLong nIndex
= 1;
225 aToken
= ScfTools::GetNameFromHTMLIndex( nIndex
++ );
226 const ScRangeData
* pRangeData
= pRangeNames
->findByUpperName(ScGlobal::pCharClass
->uppercase(aToken
));
230 if( pRangeData
->IsReference( aRange
) && !aRangeList
.In( aRange
) )
232 aNewName
= ScGlobal::addToken(aNewName
, aToken
, ';');
233 aRangeList
.Append( aRange
);
241 aNewName
= ScGlobal::addToken(aNewName
, aToken
, ';');
246 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */