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"
45 FltError
ScFormatFilterPluginImpl::ScImportHTML( SvStream
&rStream
, const OUString
& rBaseURL
, ScDocument
*pDoc
,
46 ScRange
& rRange
, double nOutputFactor
, bool bCalcWidthHeight
, SvNumberFormatter
* pFormatter
,
49 ScHTMLImport
aImp( pDoc
, rBaseURL
, rRange
, bCalcWidthHeight
);
50 FltError nErr
= (FltError
) aImp
.Read( rStream
, rBaseURL
);
51 ScRange aR
= aImp
.GetRange();
52 rRange
.aEnd
= aR
.aEnd
;
53 aImp
.WriteToDocument( true, nOutputFactor
, pFormatter
, bConvertDate
);
57 ScEEAbsImport
*ScFormatFilterPluginImpl::CreateHTMLImport( ScDocument
* pDocP
, const OUString
& rBaseURL
, const ScRange
& rRange
, bool bCalcWidthHeight
)
59 return new ScHTMLImport( pDocP
, rBaseURL
, rRange
, bCalcWidthHeight
);
62 ScHTMLImport::ScHTMLImport( ScDocument
* pDocP
, const OUString
& rBaseURL
, const ScRange
& rRange
, bool bCalcWidthHeight
) :
63 ScEEImport( pDocP
, rRange
)
66 OutputDevice
* pDefaultDev
= Application::GetDefaultDevice();
67 const OUString
& aPageStyle
= mpDoc
->GetPageStyle( rRange
.aStart
.Tab() );
68 ScStyleSheet
* pStyleSheet
= static_cast<ScStyleSheet
*>(mpDoc
->
69 GetStyleSheetPool()->Find( aPageStyle
, SFX_STYLE_FAMILY_PAGE
));
72 const SfxItemSet
& rSet
= pStyleSheet
->GetItemSet();
73 const SvxLRSpaceItem
* pLRItem
= static_cast<const SvxLRSpaceItem
*>( &rSet
.Get( ATTR_LRSPACE
) );
74 long nLeftMargin
= pLRItem
->GetLeft();
75 long nRightMargin
= pLRItem
->GetRight();
76 const SvxULSpaceItem
* pULItem
= static_cast<const SvxULSpaceItem
*>( &rSet
.Get( ATTR_ULSPACE
) );
77 long nTopMargin
= pULItem
->GetUpper();
78 long nBottomMargin
= pULItem
->GetLower();
79 aPageSize
= static_cast<const SvxSizeItem
&>(rSet
.Get(ATTR_PAGE_SIZE
)).GetSize();
80 if ( !aPageSize
.Width() || !aPageSize
.Height() )
82 OSL_FAIL("PageSize Null ?!?!?");
83 aPageSize
= SvxPaperInfo::GetPaperSize( PAPER_A4
);
85 aPageSize
.Width() -= nLeftMargin
+ nRightMargin
;
86 aPageSize
.Height() -= nTopMargin
+ nBottomMargin
;
87 aPageSize
= pDefaultDev
->LogicToPixel( aPageSize
, MapMode( MAP_TWIP
) );
91 OSL_FAIL("no StyleSheet?!?");
92 aPageSize
= pDefaultDev
->LogicToPixel(
93 SvxPaperInfo::GetPaperSize( PAPER_A4
), MapMode( MAP_TWIP
) );
95 if( bCalcWidthHeight
)
96 mpParser
= new ScHTMLLayoutParser( mpEngine
, rBaseURL
, aPageSize
, pDocP
);
98 mpParser
= new ScHTMLQueryParser( mpEngine
, pDocP
);
101 ScHTMLImport::~ScHTMLImport()
103 // Ordering is important, otherwise we get an error in some other Dtor!
104 // OK, as ScEEImport is the Base Class
105 delete static_cast<ScHTMLParser
*>(mpParser
); // before EditEngine!
108 void ScHTMLImport::InsertRangeName( ScDocument
* pDoc
, const OUString
& rName
, const ScRange
& rRange
)
110 ScComplexRefData aRefData
;
111 aRefData
.InitRange( rRange
);
112 ScTokenArray aTokArray
;
113 aTokArray
.AddDoubleReference( aRefData
);
114 ScRangeData
* pRangeData
= new ScRangeData( pDoc
, rName
, aTokArray
);
115 pDoc
->GetRangeName()->insert( pRangeData
);
118 void ScHTMLImport::WriteToDocument(
119 bool bSizeColsRows
, double nOutputFactor
, SvNumberFormatter
* pFormatter
, bool bConvertDate
)
121 ScEEImport::WriteToDocument( bSizeColsRows
, nOutputFactor
, pFormatter
, bConvertDate
);
123 const ScHTMLParser
* pParser
= GetParser();
124 const ScHTMLTable
* pGlobTable
= pParser
->GetGlobalTable();
128 // set cell borders for HTML table cells
129 pGlobTable
->ApplyCellBorders( mpDoc
, maRange
.aStart
);
131 // correct cell borders for merged cells
132 for ( size_t i
= 0, n
= pParser
->ListSize(); i
< n
; ++i
)
134 const ScEEParseEntry
* pEntry
= pParser
->ListEntry( i
);
135 if( (pEntry
->nColOverlap
> 1) || (pEntry
->nRowOverlap
> 1) )
137 SCTAB nTab
= maRange
.aStart
.Tab();
138 const ScMergeAttr
* pItem
= static_cast<const ScMergeAttr
*>( mpDoc
->GetAttr( pEntry
->nCol
, pEntry
->nRow
, nTab
, ATTR_MERGE
) );
139 if( pItem
->IsMerged() )
141 SCCOL nColMerge
= pItem
->GetColMerge();
142 SCROW nRowMerge
= pItem
->GetRowMerge();
144 const SvxBoxItem
* pToItem
= static_cast<const SvxBoxItem
*>(
145 mpDoc
->GetAttr( pEntry
->nCol
, pEntry
->nRow
, nTab
, ATTR_BORDER
) );
146 SvxBoxItem
aNewItem( *pToItem
);
149 const SvxBoxItem
* pFromItem
= static_cast<const SvxBoxItem
*>(
150 mpDoc
->GetAttr( pEntry
->nCol
+ nColMerge
- 1, pEntry
->nRow
, nTab
, ATTR_BORDER
) );
151 aNewItem
.SetLine( pFromItem
->GetLine( SvxBoxItemLine::RIGHT
), SvxBoxItemLine::RIGHT
);
155 const SvxBoxItem
* pFromItem
= static_cast<const SvxBoxItem
*>(
156 mpDoc
->GetAttr( pEntry
->nCol
, pEntry
->nRow
+ nRowMerge
- 1, nTab
, ATTR_BORDER
) );
157 aNewItem
.SetLine( pFromItem
->GetLine( SvxBoxItemLine::BOTTOM
), SvxBoxItemLine::BOTTOM
);
159 mpDoc
->ApplyAttr( pEntry
->nCol
, pEntry
->nRow
, nTab
, aNewItem
);
164 // create ranges for HTML tables
165 // 1 - entire document
166 ScRange
aNewRange( maRange
.aStart
);
167 aNewRange
.aEnd
.IncCol( static_cast<SCsCOL
>(pGlobTable
->GetDocSize( tdCol
)) - 1 );
168 aNewRange
.aEnd
.IncRow( pGlobTable
->GetDocSize( tdRow
) - 1 );
169 InsertRangeName( mpDoc
, ScfTools::GetHTMLDocName(), aNewRange
);
172 InsertRangeName( mpDoc
, ScfTools::GetHTMLTablesName(), ScRange( maRange
.aStart
) );
175 SCsCOL nColDiff
= (SCsCOL
)maRange
.aStart
.Col();
176 SCsROW nRowDiff
= (SCsROW
)maRange
.aStart
.Row();
177 SCsTAB nTabDiff
= (SCsTAB
)maRange
.aStart
.Tab();
179 ScHTMLTable
* pTable
= NULL
;
180 ScHTMLTableId nTableId
= SC_HTML_GLOBAL_TABLE
;
181 while( (pTable
= pGlobTable
->FindNestedTable( ++nTableId
)) != 0 )
183 pTable
->GetDocRange( aNewRange
);
184 aNewRange
.Move( nColDiff
, nRowDiff
, nTabDiff
);
185 // insert table number as name
186 InsertRangeName( mpDoc
, ScfTools::GetNameFromHTMLIndex( nTableId
), aNewRange
);
187 // insert table id as name
188 if (!pTable
->GetTableName().isEmpty())
190 OUString
aName( ScfTools::GetNameFromHTMLName( pTable
->GetTableName() ) );
191 if (!mpDoc
->GetRangeName()->findByUpperName(ScGlobal::pCharClass
->uppercase(aName
)))
192 InsertRangeName( mpDoc
, aName
, aNewRange
);
197 OUString
ScFormatFilterPluginImpl::GetHTMLRangeNameList( ScDocument
* pDoc
, const OUString
& rOrigName
)
199 return ScHTMLImport::GetHTMLRangeNameList( pDoc
, rOrigName
);
202 OUString
ScHTMLImport::GetHTMLRangeNameList( ScDocument
* pDoc
, const OUString
& rOrigName
)
204 OSL_ENSURE( pDoc
, "ScHTMLImport::GetHTMLRangeNameList - missing document" );
207 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
208 ScRangeList aRangeList
;
209 sal_Int32 nTokenCnt
= comphelper::string::getTokenCount(rOrigName
, ';');
210 sal_Int32 nStringIx
= 0;
211 for( sal_Int32 nToken
= 0; nToken
< nTokenCnt
; nToken
++ )
213 OUString
aToken( rOrigName
.getToken( 0, ';', nStringIx
) );
214 if( pRangeNames
&& ScfTools::IsHTMLTablesName( aToken
) )
215 { // build list with all HTML tables
216 sal_uLong nIndex
= 1;
220 aToken
= ScfTools::GetNameFromHTMLIndex( nIndex
++ );
221 const ScRangeData
* pRangeData
= pRangeNames
->findByUpperName(ScGlobal::pCharClass
->uppercase(aToken
));
225 if( pRangeData
->IsReference( aRange
) && !aRangeList
.In( aRange
) )
227 aNewName
= ScGlobal::addToken(aNewName
, aToken
, ';');
228 aRangeList
.Append( aRange
);
236 aNewName
= ScGlobal::addToken(aNewName
, aToken
, ';');
241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */