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