xref: /aoo4110/main/sc/source/filter/html/htmlimp.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 
29 //------------------------------------------------------------------------
30 
31 #include "scitems.hxx"
32 #include <editeng/eeitem.hxx>
33 
34 #include <editeng/lrspitem.hxx>
35 #include <editeng/paperinf.hxx>
36 #include <editeng/sizeitem.hxx>
37 #include <editeng/ulspitem.hxx>
38 #include <editeng/boxitem.hxx>
39 #include <vcl/svapp.hxx>
40 
41 #include "htmlimp.hxx"
42 #include "htmlpars.hxx"
43 #include "filter.hxx"
44 #include "global.hxx"
45 #include "document.hxx"
46 #include "editutil.hxx"
47 #include "stlpool.hxx"
48 #include "stlsheet.hxx"
49 #include "compiler.hxx"
50 #include "rangenam.hxx"
51 #include "attrib.hxx"
52 #include "ftools.hxx"
53 #include "tokenarray.hxx"
54 
55 
56 //------------------------------------------------------------------------
57 
ScImportHTML(SvStream & rStream,const String & rBaseURL,ScDocument * pDoc,ScRange & rRange,double nOutputFactor,sal_Bool bCalcWidthHeight,SvNumberFormatter * pFormatter,bool bConvertDate)58 FltError ScFormatFilterPluginImpl::ScImportHTML( SvStream &rStream, const String& rBaseURL, ScDocument *pDoc,
59 		ScRange& rRange, double nOutputFactor, sal_Bool bCalcWidthHeight, SvNumberFormatter* pFormatter,
60         bool bConvertDate )
61 {
62     ScHTMLImport aImp( pDoc, rBaseURL, rRange, bCalcWidthHeight );
63     FltError nErr = (FltError) aImp.Read( rStream, rBaseURL );
64 	ScRange aR = aImp.GetRange();
65 	rRange.aEnd = aR.aEnd;
66 	aImp.WriteToDocument( sal_True, nOutputFactor, pFormatter, bConvertDate );
67 	return nErr;
68 }
69 
CreateHTMLImport(ScDocument * pDocP,const String & rBaseURL,const ScRange & rRange,sal_Bool bCalcWidthHeight)70 ScEEAbsImport *ScFormatFilterPluginImpl::CreateHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, sal_Bool bCalcWidthHeight )
71 {
72     return new ScHTMLImport( pDocP, rBaseURL, rRange, bCalcWidthHeight );
73 }
74 
ScHTMLImport(ScDocument * pDocP,const String & rBaseURL,const ScRange & rRange,sal_Bool bCalcWidthHeight)75 ScHTMLImport::ScHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, sal_Bool bCalcWidthHeight ) :
76 	ScEEImport( pDocP, rRange )
77 {
78 	Size aPageSize;
79 	OutputDevice* pDefaultDev = Application::GetDefaultDevice();
80     const String& aPageStyle = mpDoc->GetPageStyle( rRange.aStart.Tab() );
81     ScStyleSheet* pStyleSheet = (ScStyleSheet*)mpDoc->
82 		GetStyleSheetPool()->Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
83 	if ( pStyleSheet )
84 	{
85 		const SfxItemSet& rSet = pStyleSheet->GetItemSet();
86 		const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &rSet.Get( ATTR_LRSPACE );
87 		long nLeftMargin   = pLRItem->GetLeft();
88 		long nRightMargin  = pLRItem->GetRight();
89 		const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &rSet.Get( ATTR_ULSPACE );
90 		long nTopMargin    = pULItem->GetUpper();
91 		long nBottomMargin = pULItem->GetLower();
92 		aPageSize = ((const SvxSizeItem&) rSet.Get(ATTR_PAGE_SIZE)).GetSize();
93 		if ( !aPageSize.Width() || !aPageSize.Height() )
94 		{
95 			DBG_ERRORFILE("PageSize Null ?!?!?");
96 			aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
97 		}
98 		aPageSize.Width() -= nLeftMargin + nRightMargin;
99 		aPageSize.Height() -= nTopMargin + nBottomMargin;
100 		aPageSize = pDefaultDev->LogicToPixel( aPageSize, MapMode( MAP_TWIP ) );
101 	}
102 	else
103 	{
104 		DBG_ERRORFILE("kein StyleSheet?!?");
105 		aPageSize = pDefaultDev->LogicToPixel(
106 			SvxPaperInfo::GetPaperSize( PAPER_A4 ), MapMode( MAP_TWIP ) );
107 	}
108     if( bCalcWidthHeight )
109         mpParser = new ScHTMLLayoutParser( mpEngine, rBaseURL, aPageSize, pDocP );
110     else
111         mpParser = new ScHTMLQueryParser( mpEngine, pDocP );
112 }
113 
114 
~ScHTMLImport()115 ScHTMLImport::~ScHTMLImport()
116 {
117 	// Reihenfolge wichtig, sonst knallt's irgendwann irgendwo in irgendeinem Dtor!
118 	// Ist gewaehrleistet, da ScEEImport Basisklasse ist
119     delete (ScHTMLParser*) mpParser;        // vor EditEngine!
120 }
121 
122 
InsertRangeName(ScDocument * pDoc,const String & rName,const ScRange & rRange)123 void ScHTMLImport::InsertRangeName( ScDocument* pDoc, const String& rName, const ScRange& rRange )
124 {
125 	ScComplexRefData aRefData;
126 	aRefData.InitRange( rRange );
127 	ScTokenArray aTokArray;
128 	aTokArray.AddDoubleReference( aRefData );
129 	ScRangeData* pRangeData = new ScRangeData( pDoc, rName, aTokArray );
130 	if( !pDoc->GetRangeName()->Insert( pRangeData ) )
131 		delete pRangeData;
132 }
133 
WriteToDocument(sal_Bool bSizeColsRows,double nOutputFactor,SvNumberFormatter * pFormatter,bool bConvertDate)134 void ScHTMLImport::WriteToDocument(
135     sal_Bool bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate )
136 {
137 	ScEEImport::WriteToDocument( bSizeColsRows, nOutputFactor, pFormatter, bConvertDate );
138 
139     const ScHTMLParser* pParser = GetParser();
140     const ScHTMLTable* pGlobTable = pParser->GetGlobalTable();
141     if( !pGlobTable )
142 		return;
143 
144 	// set cell borders for HTML table cells
145     pGlobTable->ApplyCellBorders( mpDoc, maRange.aStart );
146 
147 	// correct cell borders for merged cells
148 	for ( ScEEParseEntry* pEntry = pParser->First(); pEntry; pEntry = pParser->Next() )
149 	{
150 		if( (pEntry->nColOverlap > 1) || (pEntry->nRowOverlap > 1) )
151 		{
152             SCTAB nTab = maRange.aStart.Tab();
153             const ScMergeAttr* pItem = (ScMergeAttr*) mpDoc->GetAttr( pEntry->nCol, pEntry->nRow, nTab, ATTR_MERGE );
154 			if( pItem->IsMerged() )
155 			{
156 				SCCOL nColMerge = pItem->GetColMerge();
157 				SCROW nRowMerge = pItem->GetRowMerge();
158 
159 				const SvxBoxItem* pToItem = (const SvxBoxItem*)
160                     mpDoc->GetAttr( pEntry->nCol, pEntry->nRow, nTab, ATTR_BORDER );
161 				SvxBoxItem aNewItem( *pToItem );
162 				if( nColMerge > 1 )
163 				{
164 					const SvxBoxItem* pFromItem = (const SvxBoxItem*)
165                         mpDoc->GetAttr( pEntry->nCol + nColMerge - 1, pEntry->nRow, nTab, ATTR_BORDER );
166 					aNewItem.SetLine( pFromItem->GetLine( BOX_LINE_RIGHT ), BOX_LINE_RIGHT );
167 				}
168 				if( nRowMerge > 1 )
169 				{
170 					const SvxBoxItem* pFromItem = (const SvxBoxItem*)
171                         mpDoc->GetAttr( pEntry->nCol, pEntry->nRow + nRowMerge - 1, nTab, ATTR_BORDER );
172 					aNewItem.SetLine( pFromItem->GetLine( BOX_LINE_BOTTOM ), BOX_LINE_BOTTOM );
173 				}
174                 mpDoc->ApplyAttr( pEntry->nCol, pEntry->nRow, nTab, aNewItem );
175 			}
176 		}
177 	}
178 
179 	// create ranges for HTML tables
180  	// 1 - entire document
181     ScRange aNewRange( maRange.aStart );
182     aNewRange.aEnd.IncCol( static_cast<SCsCOL>(pGlobTable->GetDocSize( tdCol )) - 1 );
183     aNewRange.aEnd.IncRow( pGlobTable->GetDocSize( tdRow ) - 1 );
184     InsertRangeName( mpDoc, ScfTools::GetHTMLDocName(), aNewRange );
185 
186 	// 2 - all tables
187     InsertRangeName( mpDoc, ScfTools::GetHTMLTablesName(), ScRange( maRange.aStart ) );
188 
189 	// 3 - single tables
190     SCsCOL nColDiff = (SCsCOL)maRange.aStart.Col();
191     SCsROW nRowDiff = (SCsROW)maRange.aStart.Row();
192     SCsTAB nTabDiff = (SCsTAB)maRange.aStart.Tab();
193 
194     ScHTMLTable* pTable = NULL;
195     ScHTMLTableId nTableId = SC_HTML_GLOBAL_TABLE;
196     while( (pTable = pGlobTable->FindNestedTable( ++nTableId )) != 0 )
197 	{
198         pTable->GetDocRange( aNewRange );
199 		aNewRange.Move( nColDiff, nRowDiff, nTabDiff );
200 		// insert table number as name
201         InsertRangeName( mpDoc, ScfTools::GetNameFromHTMLIndex( nTableId ), aNewRange );
202 		// insert table id as name
203 		if( pTable->GetTableName().Len() )
204 		{
205             String aName( ScfTools::GetNameFromHTMLName( pTable->GetTableName() ) );
206 			sal_uInt16 nPos;
207             if( !mpDoc->GetRangeName()->SearchName( aName, nPos ) )
208                 InsertRangeName( mpDoc, aName, aNewRange );
209 		}
210 	}
211 }
212 
GetHTMLRangeNameList(ScDocument * pDoc,const String & rOrigName)213 String ScFormatFilterPluginImpl::GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName )
214 {
215     return ScHTMLImport::GetHTMLRangeNameList( pDoc, rOrigName );
216 }
217 
GetHTMLRangeNameList(ScDocument * pDoc,const String & rOrigName)218 String ScHTMLImport::GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName )
219 {
220 	DBG_ASSERT( pDoc, "ScHTMLImport::GetHTMLRangeNameList - missing document" );
221 
222 	String aNewName;
223 	ScRangeName* pRangeNames = pDoc->GetRangeName();
224 	ScRangeList aRangeList;
225 	xub_StrLen nTokenCnt = rOrigName.GetTokenCount( ';' );
226 	xub_StrLen nStringIx = 0;
227 	for( xub_StrLen nToken = 0; nToken < nTokenCnt; nToken++ )
228 	{
229 		String aToken( rOrigName.GetToken( 0, ';', nStringIx ) );
230         if( pRangeNames && ScfTools::IsHTMLTablesName( aToken ) )
231 		{	// build list with all HTML tables
232 			sal_uLong nIndex = 1;
233 			sal_uInt16 nPos;
234 			sal_Bool bLoop = sal_True;
235 			while( bLoop )
236 			{
237                 aToken = ScfTools::GetNameFromHTMLIndex( nIndex++ );
238 				bLoop = pRangeNames->SearchName( aToken, nPos );
239 				if( bLoop )
240 				{
241 					const ScRangeData* pRangeData = (*pRangeNames)[ nPos ];
242 					ScRange aRange;
243 					if( pRangeData && pRangeData->IsReference( aRange ) && !aRangeList.In( aRange ) )
244 					{
245                         ScGlobal::AddToken( aNewName, aToken, ';' );
246 						aRangeList.Append( aRange );
247 					}
248 				}
249 			}
250 		}
251 		else
252             ScGlobal::AddToken( aNewName, aToken, ';' );
253 	}
254 	return aNewName;
255 }
256 
257