1 /* AbiWord
2  * Copyright (C) 1998 AbiSource, Inc.
3  * Copyright (C) 2003 Martin Sevior <msevior@physics.unimelb.edu.au>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301 USA.
19  */
20 
21 
22 #include "ie_imp_PasteListener.h"
23 #include "pp_AttrProp.h"
24 #include "pf_Frag.h"
25 #include "pf_Frag_Strux.h"
26 #include "px_CR_FmtMark.h"
27 #include "px_CR_FmtMarkChange.h"
28 #include "px_CR_Object.h"
29 #include "px_CR_ObjectChange.h"
30 #include "px_CR_Span.h"
31 #include "px_CR_SpanChange.h"
32 #include "px_CR_Strux.h"
33 #include "px_CR_StruxChange.h"
34 
35 /*!
36  * This nifty little class allows all importers to also be used for pasting
37  * into the document.
38  * The idea is that we create a dummy document which we import to as usual
39  * with the impoters.
40  * After the Dummy document is completed we do a PD_Document::tellListener on
41  * it with this class as the listner class.
42  * This class translates all the populate().... and populateStrux()...
43  * methods into insertSpan(..) insertStrux(...) methods at the current
44  * insertion point.
45  *
46  * Hey presto we have pasted into the current document. Pretty cool eh?
47  */
IE_Imp_PasteListener(PD_Document * pDocToPaste,PT_DocPosition insPoint,PD_Document * pSourceDoc)48 IE_Imp_PasteListener::IE_Imp_PasteListener(PD_Document * pDocToPaste, PT_DocPosition insPoint, PD_Document * pSourceDoc) :
49 	m_pPasteDocument(pDocToPaste),
50 	m_insPoint(insPoint),
51 	m_bFirstSection(true),
52 	m_bFirstBlock(true),
53 	m_pSourceDoc(pSourceDoc)
54 {
55 }
populate(fl_ContainerLayout *,const PX_ChangeRecord * pcr)56 bool  IE_Imp_PasteListener::populate(fl_ContainerLayout* /* sfh */,
57 					 const PX_ChangeRecord * pcr)
58 {
59 	PT_AttrPropIndex indexAP = pcr->getIndexAP();
60 	const PP_AttrProp* pAP = NULL;
61 	UT_DEBUGMSG(("SEVIOR: Doing Populate Section in PasteListener \n"));
62 	const char ** atts = NULL;
63 	const char ** props = NULL;
64 	if (m_pSourceDoc->getAttrProp(indexAP, &pAP) && pAP)
65 	{
66 		atts = pAP->getAttributes();
67 		props = pAP->getProperties();
68 	}
69 	else
70 	{
71 		return false;
72 	}
73 
74 	switch (pcr->getType())
75 	{
76 	case PX_ChangeRecord::PXT_InsertSpan:
77 	{
78 		const PX_ChangeRecord_Span * pcrs = static_cast<const PX_ChangeRecord_Span *>(pcr);
79 		UT_uint32 len = pcrs->getLength();
80 
81 		PT_BufIndex bi = pcrs->getBufIndex();
82 		const UT_UCSChar* pChars = 	m_pSourceDoc->getPointer(bi);
83 		PP_AttrProp* pfAP = const_cast<PP_AttrProp *>(pAP);
84 		m_pPasteDocument->insertSpan(m_insPoint,pChars,len,pfAP);
85 		m_insPoint += len;
86 		return true;
87 	}
88 
89 	case PX_ChangeRecord::PXT_InsertObject:
90 	{
91 		const PX_ChangeRecord_Object * pcro = static_cast<const PX_ChangeRecord_Object *>(pcr);
92 		m_pPasteDocument->insertObject(m_insPoint,pcro->getObjectType(),atts,props);
93 		m_insPoint++;
94 		return true;
95 	}
96 
97 	case PX_ChangeRecord::PXT_InsertFmtMark:
98 	{
99 		m_pPasteDocument->changeSpanFmt(PTC_SetExactly,m_insPoint,m_insPoint,atts,props);
100 		return true;
101 	}
102 	default:
103 		UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
104 		return false;
105 	}
106 	return true;
107 }
108 
populateStrux(pf_Frag_Strux * sdh,const PX_ChangeRecord * pcr,fl_ContainerLayout **)109 bool  IE_Imp_PasteListener::populateStrux(pf_Frag_Strux* sdh,
110 									  const PX_ChangeRecord * pcr,
111 										  fl_ContainerLayout* * /* psfh */)
112 {
113 //
114 // TODO graphics in struxes
115 // TODO UID stuff
116 //
117 	UT_ASSERT(pcr->getType() == PX_ChangeRecord::PXT_InsertStrux);
118 	const PX_ChangeRecord_Strux * pcrx = static_cast<const PX_ChangeRecord_Strux *> (pcr);
119 	PT_AttrPropIndex indexAP = pcr->getIndexAP();
120 	const PP_AttrProp* pAP = NULL;
121 	UT_DEBUGMSG(("SEVIOR: Doing Populate Strux in PasteListener \n"));
122 	const char ** atts = NULL;
123 	const char ** props = NULL;
124 	if (m_pSourceDoc->getAttrProp(indexAP, &pAP) && pAP)
125 	{
126 		atts = pAP->getAttributes();
127 		props = pAP->getProperties();
128 	}
129 	else
130 	{
131 		return false;
132 	}
133 	switch (pcrx->getStruxType())
134 	{
135 	case PTX_Section:
136 	{
137 		if(m_bFirstSection)
138 		{
139 //
140 // Every doc has a first section. Now is good time to extract all the
141 // data items from the source document and stuff them into pasted doc
142 //
143 // Now these can be found via the properties of the spans and strux's
144 //
145 			PD_DataItemHandle pHandle = NULL;
146 			std::string mimeType;
147 			const char * szName= NULL;
148 			const UT_ByteBuf * pBuf = NULL;
149 			UT_sint32 k = 0;
150 			while(m_pSourceDoc->enumDataItems(k,&pHandle,&szName,&pBuf,&mimeType))
151 			{
152 				m_pPasteDocument->createDataItem(szName,false,pBuf,mimeType,&pHandle);
153 				k++;
154 			}
155 			m_bFirstSection = false;
156 			if (sdh->getNext() && (sdh->getNext()->getType() == pf_Frag::PFT_Strux) &&
157 			    (static_cast<pf_Frag_Strux*>(sdh->getNext())->getStruxType() != PTX_Block))
158 			{
159 			    // The second frag is not a PXT_Block (it is probably a PTX_SectionTable)
160 			    // The first block encountered needs to be inserted in the piece table
161 			    m_bFirstBlock = false;
162 			}
163 			return true;
164 		}
165 		//
166 		// We don't actually paste in a section though. Since a paste
167 		// is not meant to insert a section break
168 		//
169 		//m_pPasteDocument->insertStrux(m_insPoint,PTX_Section,atts,props);
170 		// m_insPoint++;
171 		return true;
172 	}
173 	case PTX_SectionFootnote:
174 	{
175 		m_pPasteDocument->insertStrux(m_insPoint,PTX_SectionFootnote,atts,props);
176 		m_insPoint++;
177 		return true;
178 	}
179 	case PTX_SectionEndnote:
180 	{
181 		m_pPasteDocument->insertStrux(m_insPoint,PTX_SectionEndnote,atts,props);
182 		m_insPoint++;
183 		return true;
184 	}
185 
186 	case PTX_EndFootnote:
187 	{
188 		m_pPasteDocument->insertStrux(m_insPoint,PTX_EndFootnote,atts,props);
189 		m_insPoint++;
190 		return true;
191 	}
192 	case PTX_EndEndnote:
193 	{
194 		m_pPasteDocument->insertStrux(m_insPoint,PTX_EndEndnote,atts,props);
195 		m_insPoint++;
196 		return true;
197 	}
198 	case PTX_SectionTOC:
199 	{
200 		m_pPasteDocument->insertStrux(m_insPoint,PTX_SectionTOC,atts,props);
201 		m_insPoint++;
202 		return true;
203 	}
204 
205 	case PTX_EndTOC:
206 	{
207 		m_pPasteDocument->insertStrux(m_insPoint,PTX_EndTOC,atts,props);
208 		m_insPoint++;
209 		return true;
210 	}
211 	case PTX_SectionHdrFtr:
212 	{
213 		m_pPasteDocument->insertStrux(m_insPoint,PTX_SectionHdrFtr,atts,props);
214 		m_insPoint++;
215 		return true;
216 	}
217 
218 	case PTX_Block:
219 	{
220 		if(m_bFirstBlock)
221 		{
222 			m_bFirstBlock = false;
223 			return true;
224 		}
225 		m_pPasteDocument->insertStrux(m_insPoint,PTX_Block,atts,props);
226 		m_insPoint++;
227 		return true;
228 	}
229 	case PTX_SectionTable:
230 	{
231 		m_pPasteDocument->insertStrux(m_insPoint,PTX_SectionTable,atts,props);
232 		m_insPoint++;
233 		return true;
234 	}
235 	case PTX_SectionFrame:
236 	{
237 		m_pPasteDocument->insertStrux(m_insPoint,PTX_SectionFrame,atts,props);
238 		m_insPoint++;
239 		return true;
240 	}
241 	case PTX_EndFrame:
242 	{
243 		m_pPasteDocument->insertStrux(m_insPoint,PTX_EndFrame,atts,props);
244 		m_insPoint++;
245 		return true;
246 	}
247 	case PTX_SectionCell:
248 	{
249 		m_pPasteDocument->insertStrux(m_insPoint,PTX_SectionCell,atts,props);
250 		m_insPoint++;
251 		return true;
252 	}
253 	case PTX_EndTable:
254 	{
255 		m_pPasteDocument->insertStrux(m_insPoint,PTX_EndTable,atts,props);
256 		m_insPoint++;
257 		return true;
258 	}
259 	case PTX_EndCell:
260 	{
261 		m_pPasteDocument->insertStrux(m_insPoint,PTX_EndCell,atts,props);
262 		m_insPoint++;
263 		return true;
264 	}
265 	default:
266 	{
267 		m_pPasteDocument->insertStrux(m_insPoint,pcrx->getStruxType(),atts,props);
268 		m_insPoint++;
269 		UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
270 		return true;
271 	}
272 	}
273 
274 	return true;
275 }
276 
getDoc(void) const277 PD_Document * IE_Imp_PasteListener::getDoc(void) const
278 {
279 	return m_pPasteDocument;
280 }
281 
282