1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2
3 /* AbiWord
4 * Copyright (C) 1998 AbiSource, Inc.
5 * Copyright (C) 2003 Martin Sevior (msevior@physics.unimelb.edu.au>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include "ut_types.h"
27 #include "ut_string.h"
28
29 #include "ap_Prefs.h"
30 #include "fl_SectionLayout.h"
31 #include "fl_FrameLayout.h"
32 #include "fl_Layout.h"
33 #include "fl_DocLayout.h"
34 #include "fl_BlockLayout.h"
35 #include "fb_LineBreaker.h"
36 #include "fp_Page.h"
37 #include "fp_Line.h"
38 #include "fp_Column.h"
39 #include "fp_FrameContainer.h"
40 #include "fp_ContainerObject.h"
41 #include "pd_Document.h"
42 #include "pp_AttrProp.h"
43 #include "gr_Graphics.h"
44 #include "pp_Property.h"
45 #include "px_ChangeRecord.h"
46 #include "px_CR_Object.h"
47 #include "px_CR_ObjectChange.h"
48 #include "px_CR_Span.h"
49 #include "px_CR_SpanChange.h"
50 #include "px_CR_Strux.h"
51 #include "px_CR_StruxChange.h"
52 #include "px_CR_Glob.h"
53 #include "fp_Run.h"
54 #include "ut_debugmsg.h"
55 #include "ut_assert.h"
56 #include "ut_units.h"
57 #include "fv_FrameEdit.h"
58 #include "ut_png.h"
59 #include "ut_bytebuf.h"
60 #include "fg_GraphicRaster.h"
61 #include "fg_GraphicVector.h"
62 #include "fv_View.h"
63
64 static void s_border_properties (const gchar * border_color, const gchar * border_style, const gchar * border_width,
65 const gchar * color, PP_PropertyMap::Line & line);
66
67 static void s_background_properties (const gchar * pszBgStyle, const gchar * pszBgColor,
68 const gchar * pszBackgroundColor,
69 PP_PropertyMap::Background & background);
70
71
fl_FrameLayout(FL_DocLayout * pLayout,pf_Frag_Strux * sdh,PT_AttrPropIndex indexAP,fl_ContainerLayout * pMyContainerLayout)72 fl_FrameLayout::fl_FrameLayout(FL_DocLayout* pLayout,
73 pf_Frag_Strux* sdh,
74 PT_AttrPropIndex indexAP,
75 fl_ContainerLayout * pMyContainerLayout)
76 : fl_SectionLayout(pLayout,
77 sdh,
78 indexAP,
79 FL_SECTION_FRAME,
80 FL_CONTAINER_FRAME,
81 PTX_SectionFrame,
82 pMyContainerLayout),
83 m_iFrameType(FL_FRAME_TEXTBOX_TYPE),
84 m_iFramePositionTo(FL_FRAME_POSITIONED_TO_BLOCK),
85 m_bNeedsRebuild(false),
86 m_bNeedsFormat(true),
87 m_bIsOnPage(false),
88 m_bHasEndFrame(false),
89 m_iWidth(0),
90 m_iHeight(0),
91 m_iXpos(0),
92 m_iYpos(0),
93 m_iXpad(0),
94 m_iYpad(0),
95 m_iXColumn(0),
96 m_iYColumn(0),
97 m_iXPage(0),
98 m_iYPage(0),
99 m_iBoundingSpace(0),
100 m_iFrameWrapMode(FL_FRAME_ABOVE_TEXT),
101 m_bIsTightWrap(false),
102 m_iPrefPage(-1),
103 m_iPrefColumn(0),
104 m_bExpandHeight(false),
105 m_iMinHeight(0),
106 m_pParentContainer(NULL)
107 {
108 }
109
~fl_FrameLayout()110 fl_FrameLayout::~fl_FrameLayout()
111 {
112 // NB: be careful about the order of these
113 UT_DEBUGMSG(("Deleting Framelayout %p \n",this));
114 _purgeLayout();
115 fp_FrameContainer * pFC = static_cast<fp_FrameContainer *>(getFirstContainer());
116 while(pFC)
117 {
118 fp_FrameContainer * pNext = static_cast<fp_FrameContainer *>(pFC->getNext());
119 if(pFC == static_cast<fp_FrameContainer *>(getLastContainer()))
120 {
121 pNext = NULL;
122 }
123 delete pFC;
124 pFC = pNext;
125 }
126
127 setFirstContainer(NULL);
128 setLastContainer(NULL);
129 //
130 // Remove pointers to this if they exist
131 //
132 if(getDocLayout() && getDocLayout()->getView())
133 {
134 FV_FrameEdit * pFE = getDocLayout()->getView()->getFrameEdit();
135 if(pFE->getFrameLayout() == this)
136 {
137 pFE->setMode(FV_FrameEdit_NOT_ACTIVE);
138 }
139 }
140 }
141
142 /*!
143 * This loads all the properties of the container found in the piecetable
144 * into the physical frame container
145 */
setContainerProperties(void)146 void fl_FrameLayout::setContainerProperties(void)
147 {
148 fp_FrameContainer * pFrame = static_cast<fp_FrameContainer *>(getLastContainer());
149 if(pFrame == NULL)
150 {
151 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
152 return;
153 }
154 pFrame->setBackground(m_background );
155 pFrame->setBottomStyle(m_lineBottom );
156 pFrame->setTopStyle(m_lineTop );
157 pFrame->setLeftStyle(m_lineLeft );
158 pFrame->setRightStyle(m_lineRight );
159 pFrame->setXpad(m_iXpad);
160 pFrame->setYpad(m_iYpad);
161 pFrame->setTightWrapping(m_bIsTightWrap);
162 if(FL_FRAME_BELOW_TEXT == m_iFrameWrapMode)
163 {
164 pFrame->setAbove(false);
165 }
166 else if(FL_FRAME_WRAPPED_TO_RIGHT == m_iFrameWrapMode)
167 {
168 pFrame->setRightWrapped(true);
169 }
170 else if(FL_FRAME_WRAPPED_TO_LEFT == m_iFrameWrapMode)
171 {
172 pFrame->setLeftWrapped(true);
173 }
174 else if(FL_FRAME_WRAPPED_TOPBOT == m_iFrameWrapMode)
175 {
176 pFrame->setTopBot(true);
177 }
178 //
179 // Now do the image for this frame.
180 //
181 if(m_pGraphicImage)
182 {
183 if(m_pImageImage == NULL)
184 {
185 const PP_AttrProp * pAP = NULL;
186 getAP(pAP);
187 GR_Graphics * pG = getDocLayout()->getGraphics();
188 UT_sint32 iWidth = pG->tlu(100);
189 UT_sint32 iHeight = pG->tlu(100);
190 if(m_pGraphicImage->getType() == FGT_Raster)
191 {
192 iWidth = pG->tlu(m_pGraphicImage->getWidth());
193 iHeight = pG->tlu(m_pGraphicImage->getHeight());
194 }
195 GR_Image * pImage = m_pGraphicImage->generateImage(pG,pAP,iWidth,iHeight);
196 m_iDocImageWidth = pFrame->getFullWidth();
197 m_iDocImageHeight = pFrame->getFullHeight();
198 m_iGraphicTick = getDocLayout()->getGraphicTick();
199 UT_Rect rec(0,0,pFrame->getFullWidth(),pFrame->getFullHeight());
200 if(rec.width < pG->tlu(3))
201 {
202 rec.width = pG->tlu(3);
203 }
204 if(rec.height < pG->tlu(3))
205 {
206 rec.height = pG->tlu(3);
207 }
208 if(pImage)
209 {
210 pImage->scaleImageTo(pG,rec);
211 }
212 m_pImageImage = pImage;
213 }
214 pFrame->getFillType().setImagePointer(&m_pGraphicImage,&m_pImageImage);
215 }
216 if(m_iFrameWrapMode >= FL_FRAME_WRAPPED_TO_RIGHT)
217 {
218 //
219 // Set text wrapping around frame
220 //
221 pFrame->setWrapping(true);
222 }
223 pFrame->setPreferedPageNo(m_iPrefPage);
224 pFrame->setPreferedColumnNo(m_iPrefColumn);
225 }
226
getBoundingSpace(void) const227 UT_sint32 fl_FrameLayout::getBoundingSpace(void) const
228 {
229 return m_iBoundingSpace;
230 }
231
232 /*!
233 * Returns the position in the document of the PTX_SectionFrame strux
234 */
getDocPosition(void)235 PT_DocPosition fl_FrameLayout::getDocPosition(void)
236 {
237 pf_Frag_Strux* sdh = getStruxDocHandle();
238 return m_pLayout->getDocument()->getStruxPosition(sdh);
239 }
240
241 /*!
242 * This method returns the length of the Frame. This is such that
243 * getDocPosition() + getLength() is one value beyond the the EndFrame
244 * strux
245 */
getLength(void)246 UT_uint32 fl_FrameLayout::getLength(void)
247 {
248 PT_DocPosition startPos = getDocPosition();
249 pf_Frag_Strux* sdhEnd = NULL;
250 pf_Frag_Strux* sdhStart = getStruxDocHandle();
251 UT_DebugOnly<bool> bres;
252 bres = m_pLayout->getDocument()->getNextStruxOfType(sdhStart,PTX_EndFrame,&sdhEnd);
253 UT_ASSERT(bres && sdhEnd);
254 if(sdhEnd == NULL)
255 {
256 return 1;
257 }
258 PT_DocPosition endPos = m_pLayout->getDocument()->getStruxPosition(sdhEnd);
259 UT_uint32 length = static_cast<UT_uint32>(endPos - startPos + 1);
260 return length;
261 }
262
263
264 /*!
265 * This code actually inserts a block AFTER the frame in the docsectionlayout
266 * Code copied from tablelayout
267 */
insertBlockAfter(fl_ContainerLayout *,const PX_ChangeRecord_Strux * pcrx,pf_Frag_Strux * sdh,PL_ListenerId lid,void (* pfnBindHandles)(pf_Frag_Strux * sdhNew,PL_ListenerId lid,fl_ContainerLayout * sfhNew))268 bool fl_FrameLayout::insertBlockAfter(fl_ContainerLayout* /*pLBlock*/,
269 const PX_ChangeRecord_Strux * pcrx,
270 pf_Frag_Strux* sdh,
271 PL_ListenerId lid,
272 void (* pfnBindHandles)(pf_Frag_Strux* sdhNew,
273 PL_ListenerId lid,
274 fl_ContainerLayout* sfhNew))
275 {
276
277 UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_InsertStrux);
278 UT_ASSERT(pcrx->getStruxType()==PTX_Block);
279
280 fl_ContainerLayout * pNewCL = NULL;
281 fl_ContainerLayout * pMyCL = myContainingLayout();
282 pNewCL = pMyCL->insert(sdh,this,pcrx->getIndexAP(), FL_CONTAINER_BLOCK);
283 fl_BlockLayout * pBlock = static_cast<fl_BlockLayout *>(pNewCL);
284 //
285 // Set the sectionlayout of this frame to that of the block since it is that scope
286 //
287 pBlock->setSectionLayout(static_cast<fl_SectionLayout *>(myContainingLayout()));
288 pNewCL->setContainingLayout(myContainingLayout());
289
290 // Must call the bind function to complete the exchange of handles
291 // with the document (piece table) *** before *** anything tries
292 // to call down into the document (like all of the view
293 // listeners).
294
295 fl_ContainerLayout* sfhNew = pNewCL;
296 pfnBindHandles(sdh,lid,sfhNew);
297 //
298 // increment the insertion point in the view.
299 //
300 FV_View* pView = m_pLayout->getView();
301 if (pView && (pView->isActive() || pView->isPreview()))
302 {
303 pView->setPoint(pcrx->getPosition() + fl_BLOCK_STRUX_OFFSET);
304 }
305 else if(pView && pView->getPoint() > pcrx->getPosition())
306 {
307 pView->setPoint(pView->getPoint() + fl_BLOCK_STRUX_OFFSET);
308 }
309 if(pView)
310 pView->updateCarets(pcrx->getPosition(),1);
311 return true;
312 }
313
bl_doclistener_insertEndFrame(fl_ContainerLayout *,const PX_ChangeRecord_Strux * pcrx,pf_Frag_Strux * sdh,PL_ListenerId lid,void (* pfnBindHandles)(pf_Frag_Strux * sdhNew,PL_ListenerId lid,fl_ContainerLayout * sfhNew))314 bool fl_FrameLayout::bl_doclistener_insertEndFrame(fl_ContainerLayout*,
315 const PX_ChangeRecord_Strux * pcrx,
316 pf_Frag_Strux* sdh,
317 PL_ListenerId lid,
318 void (* pfnBindHandles)(pf_Frag_Strux* sdhNew,
319 PL_ListenerId lid,
320 fl_ContainerLayout* sfhNew))
321 {
322 // The endFrame strux actually needs a format handle to to this Frame layout.
323 // so we bind to this layout. We also set a pointer to keep track of the endFrame strux.
324
325
326 fl_ContainerLayout* sfhNew = this;
327 pfnBindHandles(sdh,lid,sfhNew);
328 setEndStruxDocHandle(sdh);
329
330
331 //
332 // increment the insertion point in the view.
333 //
334 FV_View* pView = m_pLayout->getView();
335 if (pView && (pView->isActive() || pView->isPreview()))
336 {
337 pView->setPoint(pcrx->getPosition() + fl_BLOCK_STRUX_OFFSET);
338 }
339 else if(pView && pView->getPoint() > pcrx->getPosition())
340 {
341 pView->setPoint(pView->getPoint() + fl_BLOCK_STRUX_OFFSET);
342 }
343 if(pView)
344 pView->updateCarets(pcrx->getPosition(),1);
345 m_bHasEndFrame = true;
346 return true;
347 }
348
349
350 /*!
351 * This signals an incomplete frame section.
352 */
doclistener_deleteEndFrame(const PX_ChangeRecord_Strux *)353 bool fl_FrameLayout::doclistener_deleteEndFrame( const PX_ChangeRecord_Strux * /*pcrx*/)
354 {
355 m_bHasEndFrame = false;
356 return true;
357 }
358
359
getSectionLayout(void) const360 fl_SectionLayout * fl_FrameLayout::getSectionLayout(void) const
361 {
362 fl_ContainerLayout * pDSL = myContainingLayout();
363 while(pDSL)
364 {
365 if(pDSL->getContainerType() == FL_CONTAINER_DOCSECTION)
366 {
367 return static_cast<fl_SectionLayout *>(pDSL);
368 }
369 pDSL = pDSL->myContainingLayout();
370 }
371 return NULL;
372 }
373
374
doclistener_changeStrux(const PX_ChangeRecord_StruxChange * pcrxc)375 bool fl_FrameLayout::doclistener_changeStrux(const PX_ChangeRecord_StruxChange * pcrxc)
376 {
377 UT_ASSERT(pcrxc->getType()==PX_ChangeRecord::PXT_ChangeStrux);
378 fp_FrameContainer * pFrameC = static_cast<fp_FrameContainer *>(getFirstContainer());
379 UT_GenericVector<fl_ContainerLayout *> AllLayouts;
380 AllLayouts.clear();
381 fp_Page * pPage = NULL;
382 UT_sint32 i = 0;
383 if(pFrameC)
384 {
385 pPage = pFrameC->getPage();
386 if (pPage)
387 {
388 pPage->getAllLayouts(AllLayouts);
389 for(i=0; i< AllLayouts.getItemCount();i++)
390 {
391 fl_ContainerLayout * pCL = AllLayouts.getNthItem(i);
392 pCL->collapse();
393 }
394 }
395 }
396 setAttrPropIndex(pcrxc->getIndexAP());
397 collapse();
398 lookupProperties();
399 format();
400 for(i=0; i< AllLayouts.getItemCount();i++)
401 {
402 fl_ContainerLayout * pCL = AllLayouts.getNthItem(i);
403 pCL->format();
404 xxx_UT_DEBUGMSG(("Format block %x \n",pBL));
405 pCL->markAllRunsDirty();
406 }
407 getDocSectionLayout()->markAllRunsDirty();
408 return true;
409 }
410
411
recalculateFields(UT_uint32 iUpdateCount)412 bool fl_FrameLayout::recalculateFields(UT_uint32 iUpdateCount)
413 {
414 // ingnore frames in normal view mode
415 FV_View * pView = getDocLayout()->getView();
416 GR_Graphics * pG = getDocLayout()->getGraphics();
417 UT_return_val_if_fail( pView && pG, false );
418
419 bool bResult = false;
420 fl_ContainerLayout* pBL = getFirstLayout();
421 while (pBL)
422 {
423 bResult = pBL->recalculateFields(iUpdateCount) || bResult;
424 pBL = pBL->getNext();
425 }
426 return bResult;
427 }
428
429
markAllRunsDirty(void)430 void fl_FrameLayout::markAllRunsDirty(void)
431 {
432 fl_ContainerLayout* pCL = getFirstLayout();
433 while (pCL)
434 {
435 pCL->markAllRunsDirty();
436 pCL = pCL->getNext();
437 }
438 }
439
updateLayout(bool)440 void fl_FrameLayout::updateLayout(bool /*bDoAll*/)
441 {
442 // ingnore frames in normal view mode
443 FV_View * pView = getDocLayout()->getView();
444 GR_Graphics * pG = getDocLayout()->getGraphics();
445 UT_return_if_fail( pView && pG);
446
447 xxx_UT_DEBUGMSG(("UpdsateLayout in in framelayout \n"));
448 if(needsReformat())
449 {
450 format();
451 }
452 m_vecFormatLayout.clear();
453 fl_ContainerLayout* pBL = getFirstLayout();
454 while (pBL)
455 {
456 if (pBL->needsReformat())
457 {
458 pBL->format();
459 }
460
461 pBL = pBL->getNext();
462 }
463 }
464
redrawUpdate(void)465 void fl_FrameLayout::redrawUpdate(void)
466 {
467 fl_ContainerLayout* pBL = getFirstLayout();
468 while (pBL)
469 {
470 if (pBL->needsRedraw())
471 {
472 pBL->redrawUpdate();
473 }
474
475 pBL = pBL->getNext();
476 }
477 }
478
479
doclistener_deleteStrux(const PX_ChangeRecord_Strux * pcrx)480 bool fl_FrameLayout::doclistener_deleteStrux(const PX_ChangeRecord_Strux * pcrx)
481 {
482 UT_UNUSED(pcrx);
483 UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_DeleteStrux);
484 #if 0
485 fp_FrameContainer * pFrameC = getFirstContainer();
486 if(pFrameC && pFrameC->getPage())
487 {
488 pFrameC->getPage()->markDirtyOverlappingRuns(pFrameC);
489 }
490 #endif
491 fp_FrameContainer * pFrameC = static_cast<fp_FrameContainer *>(getFirstContainer());
492 UT_GenericVector<fl_BlockLayout *> vecBlocks;
493 pFrameC->getBlocksAroundFrame(vecBlocks);
494 UT_sint32 i = 0;
495 for(i=0; i< vecBlocks.getItemCount();i++)
496 {
497 fl_BlockLayout * pBL = vecBlocks.getNthItem(i);
498 pBL->collapse();
499 xxx_UT_DEBUGMSG(("Collapse block %x \n",pBL));
500 }
501
502 //
503 // Remove all remaining structures
504 //
505 collapse();
506 myContainingLayout()->remove(this);
507 UT_DEBUGMSG(("Unlinking frame Layout %p \n",this));
508 //
509 // Remove from the list of frames in the previous block
510 //
511 fl_ContainerLayout * pCL = getParentContainer();
512 fl_BlockLayout * pBL = NULL;
513 if(pCL)
514 {
515 if(!pCL->removeFrame(this))
516 {
517 UT_DEBUGMSG(("Whoops! Frame not found in container %p\n",pCL));
518 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
519 }
520 }
521 for(i=0; i< vecBlocks.getItemCount();i++)
522 {
523 pBL = vecBlocks.getNthItem(i);
524 pBL->format();
525 xxx_UT_DEBUGMSG(("Format block %p\n",pBL));
526 }
527
528 delete this; // TODO whoa! this construct is VERY dangerous.
529
530 return true;
531 }
532
533
534 /*!
535 * This method removes all layout structures contained by this layout
536 * structure.
537 */
_purgeLayout(void)538 void fl_FrameLayout::_purgeLayout(void)
539 {
540 UT_DEBUGMSG(("FrameLayout: purge \n"));
541 fl_ContainerLayout * pCL = getFirstLayout();
542 while(pCL)
543 {
544 fl_ContainerLayout * pNext = pCL->getNext();
545 delete pCL;
546 pCL = pNext;
547 }
548 }
549
550
551 /*!
552 * This method creates a new footnote with its properties initially set
553 * from the Attributes/properties of this Layout
554 */
_createFrameContainer(void)555 void fl_FrameLayout::_createFrameContainer(void)
556 {
557 lookupProperties();
558 fp_FrameContainer * pFrameContainer = new fp_FrameContainer(static_cast<fl_SectionLayout *>(this));
559 setFirstContainer(pFrameContainer);
560 setLastContainer(pFrameContainer);
561 pFrameContainer->setWidth(m_iWidth);
562 pFrameContainer->setHeight(m_iHeight);
563 // Now do Frame image
564
565 const PP_AttrProp* pSectionAP = NULL;
566 // This is a real NO-NO: must *always* call getAP()
567 // m_pLayout->getDocument()->getAttrProp(m_apIndex, &pSectionAP);
568 getAP(pSectionAP);
569
570 const gchar * pszDataID = NULL;
571 pSectionAP->getAttribute(PT_STRUX_IMAGE_DATAID, (const gchar *&)pszDataID);
572 DELETEP(m_pGraphicImage);
573 DELETEP(m_pImageImage);
574 //
575 // Set the image size from the full width
576 //
577 setImageWidth(pFrameContainer->getFullWidth());
578 setImageHeight(pFrameContainer->getFullHeight());
579 if(pszDataID && *pszDataID)
580 {
581 UT_DEBUGMSG(("!!!Found image of file %s \n",pszDataID));
582 m_pGraphicImage = FG_Graphic::createFromStrux(this);
583 }
584
585 setContainerProperties();
586 }
587
588 /*!
589 Create a new Frame container.
590 \param If pPrevFrame is non-null place the new cell after this in the linked
591 list, otherwise just append it to the end.
592 \return The newly created Frame container
593 */
getNewContainer(fp_Container *)594 fp_Container* fl_FrameLayout::getNewContainer(fp_Container *)
595 {
596 UT_DEBUGMSG(("creating new Frame container\n"));
597 _createFrameContainer();
598 m_bIsOnPage = false;
599 return static_cast<fp_Container *>(getLastContainer());
600 }
601
_insertFrameContainer(fp_Container *)602 void fl_FrameLayout::_insertFrameContainer(fp_Container * /*pNewFC*/)
603 {
604
605 // This is all done fl_BlockLayout::setFramesOnPage
606
607 }
608
609
miniFormat(void)610 void fl_FrameLayout::miniFormat(void)
611 {
612 // ingnore frames in normal view mode
613 FV_View * pView = getDocLayout()->getView();
614 GR_Graphics * pG = getDocLayout()->getGraphics();
615 UT_return_if_fail( pView && pG );
616
617 fl_ContainerLayout* pBL = getFirstLayout();
618
619 while (pBL)
620 {
621 pBL->format();
622 pBL = pBL->getNext();
623 }
624 fp_FrameContainer * pFrame = static_cast<fp_FrameContainer *>(getFirstContainer());
625 pFrame->layout();
626 pFrame->getFillType().setWidthHeight(getDocLayout()->getGraphics(),pFrame->getFullWidth(),pFrame->getFullHeight(),false);
627 m_bNeedsFormat = false;
628 m_bNeedsReformat = false;
629 }
630
format(void)631 void fl_FrameLayout::format(void)
632 {
633 // ingnore frames in normal view mode
634 FV_View * pView = getDocLayout()->getView();
635 GR_Graphics * pG = getDocLayout()->getGraphics();
636 UT_return_if_fail( pView && pG );
637
638 xxx_UT_DEBUGMSG(("SEVIOR: Formatting first container is %x \n",getFirstContainer()));
639 if(isHidden() > FP_VISIBLE)
640 {
641 xxx_UT_DEBUGMSG(("Don't format FRAME coz I'm hidden! \n"));
642 return;
643 }
644
645 if(getFirstContainer() == NULL)
646 {
647 getNewContainer();
648 }
649 fl_ContainerLayout* pBL2 = getFirstLayout();
650 while (pBL2)
651 {
652 pBL2->format();
653 UT_sint32 count = 0;
654 while(pBL2->getLastContainer() == NULL || pBL2->getFirstContainer()==NULL)
655 {
656 UT_DEBUGMSG(("Error formatting a block try again \n"));
657 count = count + 1;
658 pBL2->format();
659 if(count > 3)
660 {
661 UT_DEBUGMSG(("Give up trying to format. Hope for the best :-( \n"));
662 break;
663 }
664 }
665 pBL2 = pBL2->getNext();
666 }
667 static_cast<fp_FrameContainer *>(getFirstContainer())->layout();
668 bool bPlacedOnPage = false;
669 if(!m_bIsOnPage && !(getDocLayout()->isLayoutFilling()))
670 {
671 //
672 // Place it on the correct page.
673 //
674 fl_ContainerLayout * pCL = getParentContainer();
675 if((!pCL) || pCL->getContainerType() != FL_CONTAINER_BLOCK)
676 {
677 UT_DEBUGMSG(("No BlockLayout or wrong layout associated with this frame! \n"));
678 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
679 return;
680 }
681 fl_BlockLayout * pBL = NULL;
682 pBL = static_cast<fl_BlockLayout *>(pCL);
683 UT_sint32 count = pBL->getNumFrames();
684 UT_sint32 i = 0;
685 for(i=0; i<count; i++)
686 {
687 fl_FrameLayout * pFL = pBL->getNthFrameLayout(i);
688 if(pFL == this)
689 {
690 break;
691 }
692 }
693 if(count == i)
694 {
695 UT_DEBUGMSG(("BlockLayout does not contain this frame! \n"));
696 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
697 return;
698 }
699 if(!pBL->isCollapsed())
700 {
701 m_bIsOnPage = pBL->setFramesOnPage(NULL);
702 if(!m_bIsOnPage)
703 {
704 setNeedsReformat(this);
705 }
706 }
707 if(m_bIsOnPage)
708 bPlacedOnPage = true;
709 }
710 m_bNeedsFormat = m_bIsOnPage;
711 m_bNeedsReformat = m_bIsOnPage;
712 if(!m_bIsOnPage)
713 {
714 setNeedsReformat(this);
715 }
716 if(!m_bIsOnPage)
717 {
718 return;
719 }
720 if(bPlacedOnPage)
721 {
722 fl_DocSectionLayout * pDSL = getDocSectionLayout();
723 fp_FrameContainer * pFC = static_cast<fp_FrameContainer *>(getFirstContainer());
724 if(pFC)
725 {
726 pDSL->setNeedsSectionBreak(true,pFC->getPage());
727 }
728 }
729 }
730
setNeedsReformat(fl_ContainerLayout *,UT_uint32)731 void fl_FrameLayout::setNeedsReformat(fl_ContainerLayout * /*pCL*/,UT_uint32 /*offset*/)
732 {
733 m_bNeedsReformat = true;
734 myContainingLayout()->setNeedsReformat(this);
735 }
736 /*!
737 this function is only to be called by fl_ContainerLayout::lookupProperties()
738 all other code must call lookupProperties() instead
739 */
_lookupProperties(const PP_AttrProp * pSectionAP)740 void fl_FrameLayout::_lookupProperties(const PP_AttrProp* pSectionAP)
741 {
742 UT_return_if_fail(pSectionAP);
743
744 FV_View * pView = getDocLayout()->getView();
745 GR_Graphics * pG = getDocLayout()->getGraphics();
746 UT_return_if_fail( pView && pG );
747
748 const gchar *pszFrameType = NULL;
749 const gchar *pszPositionTo = NULL;
750 const gchar *pszWrapMode = NULL;
751 const gchar *pszXpos = NULL;
752 const gchar *pszYpos = NULL;
753 const gchar *pszColXpos = NULL;
754 const gchar *pszColYpos = NULL;
755 const gchar *pszPageXpos = NULL;
756 const gchar *pszPageYpos = NULL;
757 const gchar *pszWidth = NULL;
758 const gchar *pszHeight = NULL;
759 const gchar *pszXpad = NULL;
760 const gchar *pszYpad = NULL;
761
762 const gchar * pszColor = NULL;
763 const gchar * pszBorderColor = NULL;
764 const gchar * pszBorderStyle = NULL;
765 const gchar * pszBorderWidth = NULL;
766
767 const gchar * pszBoundingSpace = NULL;
768 const gchar * pszTightWrapped = NULL;
769 const gchar * pszPrefPage = NULL;
770 const gchar * pszPrefColumn = NULL;
771
772 const gchar * pszExpandHeight = NULL;
773 const gchar * pszPercentWidth = NULL;
774 const gchar * pszMinHeight = NULL;
775 // Frame Type
776
777 if(!pSectionAP || !pSectionAP->getProperty("frame-type",pszFrameType))
778 {
779 m_iFrameType = FL_FRAME_TEXTBOX_TYPE;
780 }
781 else if(strcmp(pszFrameType,"textbox") == 0)
782 {
783 m_iFrameType = FL_FRAME_TEXTBOX_TYPE;
784 }
785 else if(strcmp(pszFrameType,"image") == 0)
786 {
787 m_iFrameType = FL_FRAME_WRAPPER_IMAGE;
788 }
789 else
790 {
791 UT_DEBUGMSG(("Unknown Frame Type %s \n",pszFrameType));
792 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
793 m_iFrameType = FL_FRAME_TEXTBOX_TYPE;
794 }
795
796 // Position-to
797
798 if((!pSectionAP || !pSectionAP->getProperty("position-to",pszPositionTo)))
799 {
800 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
801 }
802 else if(strcmp(pszPositionTo,"block-above-text") == 0)
803 {
804 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
805 }
806 else if(strcmp(pszPositionTo,"column-above-text") == 0)
807 {
808 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_COLUMN;
809 }
810 else if(strcmp(pszPositionTo,"page-above-text") == 0)
811 {
812 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_PAGE;
813 }
814 else
815 {
816 UT_DEBUGMSG(("Unknown Position to %s \n",pszPositionTo));
817 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
818 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
819 }
820
821
822 // wrap-mode
823
824 if(!pSectionAP || !pSectionAP->getProperty("wrap-mode",pszWrapMode))
825 {
826 m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
827 }
828 else if(strcmp(pszWrapMode,"above-text") == 0)
829 {
830 m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
831 }
832 else if(strcmp(pszWrapMode,"below-text") == 0)
833 {
834 m_iFrameWrapMode = FL_FRAME_BELOW_TEXT;
835 }
836 else if(strcmp(pszWrapMode,"wrapped-to-right") == 0)
837 {
838 m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_RIGHT;
839 }
840 else if(strcmp(pszWrapMode,"wrapped-to-left") == 0)
841 {
842 m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_LEFT;
843 }
844 else if(strcmp(pszWrapMode,"wrapped-both") == 0)
845 {
846 m_iFrameWrapMode = FL_FRAME_WRAPPED_BOTH_SIDES;
847 }
848 else if(strcmp(pszWrapMode,"wrapped-topbot") == 0)
849 {
850 m_iFrameWrapMode = FL_FRAME_WRAPPED_TOPBOT;
851 }
852 else
853 {
854 UT_DEBUGMSG(("Unknown wrap-mode %s \n",pszWrapMode));
855 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
856 m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
857 }
858 //
859 // Wrap type
860 //
861 if(!pSectionAP || !pSectionAP->getProperty("tight-wrap",pszTightWrapped))
862 {
863 m_bIsTightWrap = false;
864 }
865 else if(strcmp(pszTightWrapped,"1") == 0)
866 {
867 m_bIsTightWrap = true;
868 }
869 else
870 {
871 m_bIsTightWrap = false;
872 }
873
874 // Xpos
875
876 if(!pSectionAP || !pSectionAP->getProperty("xpos",pszXpos))
877 {
878 m_iXpos = 0;
879 }
880 else
881 {
882 m_iXpos = UT_convertToLogicalUnits(pszXpos);
883 }
884 UT_DEBUGMSG(("xpos for frame is %s \n",pszXpos));
885 // Ypos
886
887 if(!pSectionAP || !pSectionAP->getProperty("ypos",pszYpos))
888 {
889 m_iYpos = 0;
890 }
891 else
892 {
893 m_iYpos = UT_convertToLogicalUnits(pszYpos);
894 }
895 UT_DEBUGMSG(("ypos for frame is %s \n",pszYpos));
896
897 // ColXpos
898
899 if(!pSectionAP || !pSectionAP->getProperty("frame-col-xpos",pszColXpos))
900 {
901 m_iXColumn = 0;
902 }
903 else
904 {
905 m_iXColumn = UT_convertToLogicalUnits(pszColXpos);
906 }
907 UT_DEBUGMSG(("ColXpos for frame is %s \n",pszColXpos));
908 // colYpos
909
910 if(!pSectionAP || !pSectionAP->getProperty("frame-col-ypos",pszColYpos))
911 {
912 m_iYColumn = 0;
913 }
914 else
915 {
916 m_iYColumn = UT_convertToLogicalUnits(pszColYpos);
917 }
918 UT_DEBUGMSG(("ColYpos for frame is %s units %d \n",pszColYpos,m_iYColumn));
919
920
921 // PageXpos
922
923 if(!pSectionAP || !pSectionAP->getProperty("frame-page-xpos",pszPageXpos))
924 {
925 m_iXPage = 0;
926 }
927 else
928 {
929 m_iXPage = UT_convertToLogicalUnits(pszPageXpos);
930 }
931 UT_DEBUGMSG(("PageXpos for frame is %s units %d \n",pszPageXpos,m_iXPage));
932 // PageYpos
933
934 if(!pSectionAP || !pSectionAP->getProperty("frame-page-ypos",pszPageYpos))
935 {
936 m_iYPage = 0;
937 }
938 else
939 {
940 m_iYPage = UT_convertToLogicalUnits(pszPageYpos);
941 }
942 UT_DEBUGMSG(("PageYpos for frame is %s units %d \n",pszPageYpos,m_iYPage));
943
944
945 // Width
946
947 if(!pSectionAP || !pSectionAP->getProperty("frame-width",pszWidth))
948 {
949 m_iWidth = UT_convertToLogicalUnits("1.0in");
950 }
951 else
952 {
953 m_iWidth = UT_convertToLogicalUnits(pszWidth);
954 }
955 if(m_iWidth < m_pLayout->getGraphics()->tlu(2))
956 {
957 m_iWidth = m_pLayout->getGraphics()->tlu(2);
958 }
959 UT_DEBUGMSG(("Width %s \n",pszWidth));
960 // Height
961
962 if(!pSectionAP || !pSectionAP->getProperty("frame-height",pszHeight))
963 {
964 m_iHeight = UT_convertToLogicalUnits("1.0in");
965 }
966 else
967 {
968 m_iHeight = UT_convertToLogicalUnits(pszHeight);
969 }
970 if(m_iHeight < m_pLayout->getGraphics()->tlu(2))
971 {
972 m_iHeight = m_pLayout->getGraphics()->tlu(2);
973 }
974 m_iMinHeight = m_iHeight;
975 UT_DEBUGMSG(("Height %s \n",pszHeight));
976
977 // Xpadding
978
979
980 if(!pSectionAP || !pSectionAP->getProperty("xpad",pszXpad))
981 {
982 m_iXpad = UT_convertToLogicalUnits("0.03in");
983 }
984 else
985 {
986 m_iXpad = UT_convertToLogicalUnits(pszXpad);
987 }
988
989
990 // Ypadding
991
992
993 if(!pSectionAP || !pSectionAP->getProperty("ypad",pszYpad))
994 {
995 m_iYpad = UT_convertToLogicalUnits("0.03in");
996 }
997 else
998 {
999 m_iYpad = UT_convertToLogicalUnits(pszYpad);
1000 }
1001
1002
1003 /* Frame-border properties:
1004 */
1005
1006 pSectionAP->getProperty ("color", pszColor);
1007
1008 pSectionAP->getProperty ("bot-color",pszBorderColor);
1009 pSectionAP->getProperty ("bot-style",pszBorderStyle);
1010 pSectionAP->getProperty ("bot-thickness",pszBorderWidth);
1011
1012 s_border_properties (pszBorderColor, pszBorderStyle, pszBorderWidth, pszColor, m_lineBottom);
1013
1014 pszBorderColor = NULL;
1015 pszBorderStyle = NULL;
1016 pszBorderWidth = NULL;
1017
1018 pSectionAP->getProperty ("left-color", pszBorderColor);
1019 pSectionAP->getProperty ("left-style", pszBorderStyle);
1020 pSectionAP->getProperty ("left-thickness", pszBorderWidth);
1021
1022 s_border_properties (pszBorderColor, pszBorderStyle, pszBorderWidth, pszColor, m_lineLeft);
1023
1024 pszBorderColor = NULL;
1025 pszBorderStyle = NULL;
1026 pszBorderWidth = NULL;
1027
1028 pSectionAP->getProperty ("right-color",pszBorderColor);
1029 pSectionAP->getProperty ("right-style",pszBorderStyle);
1030 pSectionAP->getProperty ("right-thickness", pszBorderWidth);
1031
1032 s_border_properties (pszBorderColor, pszBorderStyle, pszBorderWidth, pszColor, m_lineRight);
1033
1034 pszBorderColor = NULL;
1035 pszBorderStyle = NULL;
1036 pszBorderWidth = NULL;
1037
1038 pSectionAP->getProperty ("top-color", pszBorderColor);
1039 pSectionAP->getProperty ("top-style", pszBorderStyle);
1040 pSectionAP->getProperty ("top-thickness",pszBorderWidth);
1041
1042 s_border_properties (pszBorderColor, pszBorderStyle, pszBorderWidth, pszColor, m_lineTop);
1043
1044 /* Frame fill
1045 */
1046 m_background.reset ();
1047
1048 const gchar * pszBgStyle = NULL;
1049 const gchar * pszBgColor = NULL;
1050 const gchar * pszBackgroundColor = NULL;
1051
1052 pSectionAP->getProperty ("bg-style", pszBgStyle);
1053 pSectionAP->getProperty ("bgcolor", pszBgColor);
1054 pSectionAP->getProperty ("background-color", pszBackgroundColor);
1055
1056 s_background_properties (pszBgStyle, pszBgColor, pszBackgroundColor, m_background);
1057
1058 //
1059 // Bounding Space
1060 //
1061 if(!pSectionAP || !pSectionAP->getProperty("bounding-space",pszBoundingSpace))
1062 {
1063 m_iBoundingSpace = UT_convertToLogicalUnits("0.05in");
1064 }
1065 else
1066 {
1067 m_iBoundingSpace = UT_convertToLogicalUnits(pszBoundingSpace);
1068 }
1069 //
1070 // Preferred Page
1071 //
1072 if(!pSectionAP || !pSectionAP->getProperty("frame-pref-page",pszPrefPage))
1073 {
1074 m_iPrefPage = -1;
1075 }
1076 else
1077 {
1078 if(pszPrefPage && *pszPrefPage != 0)
1079 m_iPrefPage = atoi(pszPrefPage);
1080 else
1081 m_iPrefPage = -1;
1082 }
1083 //
1084 // Preferred column
1085 //
1086 if(!pSectionAP || !pSectionAP->getProperty("frame-pref-column",pszPrefColumn))
1087 {
1088 m_iPrefColumn = 0;
1089 }
1090 else
1091 {
1092 if(pszPrefColumn && *pszPrefColumn != 0)
1093 m_iPrefColumn = atoi(pszPrefColumn);
1094 else
1095 m_iPrefColumn = -1;
1096 }
1097 //
1098 // Percent Width
1099 //
1100 if(pSectionAP && pSectionAP->getProperty("frame-rel-width",pszPercentWidth))
1101 {
1102 if(pszPercentWidth && (m_iWidth <= (m_pLayout->getGraphics()->tlu(2)+3)))
1103 {
1104 double frac_width = UT_convertFraction(pszPercentWidth);
1105 fl_DocSectionLayout * pDSL = getDocSectionLayout();
1106 m_iWidth = frac_width*pDSL->getActualColumnWidth();
1107 }
1108 }
1109
1110 //
1111 // Min Height
1112 //
1113 if(pSectionAP && pSectionAP->getProperty("frame-min-height",pszMinHeight))
1114 {
1115 if(pszMinHeight)
1116 {
1117 m_iMinHeight = UT_convertToLogicalUnits(pszMinHeight);
1118 m_bExpandHeight = true;
1119 }
1120 }
1121
1122 //
1123 // Expandable Height
1124 //
1125 if(pSectionAP && pSectionAP->getProperty("frame-expand-height",pszExpandHeight))
1126 {
1127 m_iMinHeight = m_iHeight;
1128 m_bExpandHeight = true;
1129 }
1130
1131 //
1132 // left/right aligned
1133 //
1134 const char * pszAlign = NULL;
1135 if(pSectionAP && pSectionAP->getProperty("frame-horiz-align",pszAlign))
1136 {
1137 if(pszAlign && (strcmp(pszAlign,"right") == 0) && (m_iXpos == 0))
1138 {
1139 fl_DocSectionLayout * pDSL = getDocSectionLayout();
1140 m_iXpos = pDSL->getActualColumnWidth() - m_iWidth;
1141 }
1142 }
1143
1144 }
1145
_lookupMarginProperties(const PP_AttrProp * pSectionAP)1146 void fl_FrameLayout::_lookupMarginProperties(const PP_AttrProp* pSectionAP)
1147 {
1148
1149 UT_return_if_fail(pSectionAP);
1150 FV_View * pView = getDocLayout()->getView();
1151 GR_Graphics * pG = getDocLayout()->getGraphics();
1152 UT_return_if_fail( pView && pG );
1153
1154 UT_sint32 iFramePositionTo = m_iFramePositionTo;
1155 FL_FrameWrapMode iFrameWrapMode = m_iFrameWrapMode;
1156 bool bIsTightWrap = m_bIsTightWrap;
1157 UT_sint32 iXpos = m_iXpos;
1158 UT_sint32 iYpos = m_iYpos;
1159 UT_sint32 iXColumn = m_iXColumn;
1160 UT_sint32 iYColumn = m_iYColumn;
1161 UT_sint32 iXPage = m_iXPage;
1162 UT_sint32 iYPage = m_iYPage;
1163
1164
1165 if(pView->getViewMode() == VIEW_NORMAL && !pG->queryProperties(GR_Graphics::DGP_PAPER))
1166 {
1167 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
1168 m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_RIGHT;
1169 m_bIsTightWrap = false;
1170 m_iXpos = 0;
1171 m_iYpos = 0;
1172 m_iXColumn = 0;
1173 m_iYColumn = 0;
1174 m_iXPage = 0;
1175 m_iYPage = 0;
1176 }
1177 else
1178 {
1179 const gchar *pszPositionTo = NULL;
1180 const gchar *pszWrapMode = NULL;
1181 const gchar *pszXpos = NULL;
1182 const gchar *pszYpos = NULL;
1183 const gchar *pszColXpos = NULL;
1184 const gchar *pszColYpos = NULL;
1185 const gchar *pszPageXpos = NULL;
1186 const gchar *pszPageYpos = NULL;
1187 const gchar * pszTightWrapped = NULL;
1188
1189
1190 // Position-to
1191
1192 if(!pSectionAP || !pSectionAP->getProperty("position-to",pszPositionTo))
1193 {
1194 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
1195 }
1196 else if(strcmp(pszPositionTo,"block-above-text") == 0)
1197 {
1198 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
1199 }
1200 else if(strcmp(pszPositionTo,"column-above-text") == 0)
1201 {
1202 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_COLUMN;
1203 }
1204 else if(strcmp(pszPositionTo,"page-above-text") == 0)
1205 {
1206 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_PAGE;
1207 }
1208 else
1209 {
1210 UT_DEBUGMSG(("Unknown Position to %s \n",pszPositionTo));
1211 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
1212 m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
1213 }
1214
1215
1216 // wrap-mode
1217
1218 if(!pSectionAP || !pSectionAP->getProperty("wrap-mode",pszWrapMode))
1219 {
1220 m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
1221 }
1222 else if(strcmp(pszWrapMode,"above-text") == 0)
1223 {
1224 m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
1225 }
1226 else if(strcmp(pszWrapMode,"below-text") == 0)
1227 {
1228 m_iFrameWrapMode = FL_FRAME_BELOW_TEXT;
1229 }
1230 else if(strcmp(pszWrapMode,"wrapped-to-right") == 0)
1231 {
1232 m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_RIGHT;
1233 }
1234 else if(strcmp(pszWrapMode,"wrapped-to-left") == 0)
1235 {
1236 m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_LEFT;
1237 }
1238 else if(strcmp(pszWrapMode,"wrapped-both") == 0)
1239 {
1240 m_iFrameWrapMode = FL_FRAME_WRAPPED_BOTH_SIDES;
1241 }
1242 else if(strcmp(pszWrapMode,"wrapped-topbot") == 0)
1243 {
1244 m_iFrameWrapMode = FL_FRAME_WRAPPED_TOPBOT;
1245 }
1246 else
1247 {
1248 UT_DEBUGMSG(("Unknown wrap-mode %s \n",pszWrapMode));
1249 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
1250 m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
1251 }
1252 //
1253 // Wrap type
1254 //
1255 if(!pSectionAP || !pSectionAP->getProperty("tight-wrap",pszTightWrapped))
1256 {
1257 m_bIsTightWrap = false;
1258 }
1259 else if(strcmp(pszTightWrapped,"1") == 0)
1260 {
1261 m_bIsTightWrap = true;
1262 }
1263 else
1264 {
1265 m_bIsTightWrap = false;
1266 }
1267
1268 // Xpos
1269
1270 if(!pSectionAP || !pSectionAP->getProperty("xpos",pszXpos))
1271 {
1272 m_iXpos = 0;
1273 }
1274 else
1275 {
1276 m_iXpos = UT_convertToLogicalUnits(pszXpos);
1277 }
1278 UT_DEBUGMSG(("xpos for frame is %s \n",pszXpos));
1279 // Ypos
1280
1281 if(!pSectionAP || !pSectionAP->getProperty("ypos",pszYpos))
1282 {
1283 m_iYpos = 0;
1284 }
1285 else
1286 {
1287 m_iYpos = UT_convertToLogicalUnits(pszYpos);
1288 }
1289 UT_DEBUGMSG(("ypos for frame is %s \n",pszYpos));
1290
1291 // ColXpos
1292
1293 if(!pSectionAP || !pSectionAP->getProperty("frame-col-xpos",pszColXpos))
1294 {
1295 m_iXColumn = 0;
1296 }
1297 else
1298 {
1299 m_iXColumn = UT_convertToLogicalUnits(pszColXpos);
1300 }
1301 UT_DEBUGMSG(("ColXpos for frame is %s \n",pszColXpos));
1302 // colYpos
1303
1304 if(!pSectionAP || !pSectionAP->getProperty("frame-col-ypos",pszColYpos))
1305 {
1306 m_iYColumn = 0;
1307 }
1308 else
1309 {
1310 m_iYColumn = UT_convertToLogicalUnits(pszColYpos);
1311 }
1312 UT_DEBUGMSG(("ColYpos for frame is %s units %d \n",pszColYpos,m_iYColumn));
1313
1314
1315 // PageXpos
1316
1317 if(!pSectionAP || !pSectionAP->getProperty("frame-page-xpos",pszPageXpos))
1318 {
1319 m_iXPage = 0;
1320 }
1321 else
1322 {
1323 m_iXPage = UT_convertToLogicalUnits(pszPageXpos);
1324 }
1325 UT_DEBUGMSG(("PageXpos for frame is %s \n",pszPageXpos));
1326 // PageYpos
1327
1328 if(!pSectionAP || !pSectionAP->getProperty("frame-page-ypos",pszPageYpos))
1329 {
1330 m_iYPage = 0;
1331 }
1332 else
1333 {
1334 m_iYPage = UT_convertToLogicalUnits(pszPageYpos);
1335 }
1336 UT_DEBUGMSG(("PageYpos for frame is %s units %d \n",pszColYpos,m_iYPage));
1337
1338 }
1339
1340 fl_ContainerLayout* pCL = getFirstLayout();
1341 while (pCL)
1342 {
1343 pCL->lookupMarginProperties();
1344 pCL = pCL->getNext();
1345 }
1346
1347 if(iFramePositionTo != m_iFramePositionTo || iFrameWrapMode != m_iFrameWrapMode ||
1348 bIsTightWrap != m_bIsTightWrap || iXpos != m_iXpos || iYpos != m_iYpos ||
1349 iXColumn != m_iXColumn || iYColumn != m_iYColumn || iXPage != m_iXPage ||
1350 iYPage != m_iYPage)
1351 {
1352 collapse();
1353 }
1354 }
1355
localCollapse(void)1356 void fl_FrameLayout::localCollapse(void)
1357 {
1358 // ClearScreen on our Cell. One Cell per layout.
1359 fp_FrameContainer *pFC = static_cast<fp_FrameContainer *>(getFirstContainer());
1360 if (pFC)
1361 {
1362 pFC->clearScreen();
1363 }
1364
1365 // get rid of all the layout information for every containerLayout
1366 fl_ContainerLayout* pCL = getFirstLayout();
1367 while (pCL)
1368 {
1369 pCL->collapse();
1370 pCL = pCL->getNext();
1371 }
1372 m_bNeedsReformat = true;
1373 }
1374
collapse(void)1375 void fl_FrameLayout::collapse(void)
1376 {
1377 FV_View * pView = getDocLayout()->getView();
1378 if(pView)
1379 {
1380 if(pView->getFrameEdit()->getFrameLayout() == this)
1381 {
1382 pView->getFrameEdit()->setMode(FV_FrameEdit_NOT_ACTIVE);
1383 }
1384 }
1385 localCollapse();
1386 fp_FrameContainer *pFC = static_cast<fp_FrameContainer *>(getFirstContainer());
1387 if (pFC)
1388 {
1389 //
1390 // Remove it from the page.
1391 //
1392 if(pFC->getPage())
1393 {
1394 pFC->getPage()->removeFrameContainer(pFC);
1395 pFC->setPage(NULL);
1396 }
1397 //
1398 // remove it from the linked list.
1399 //
1400 fp_FrameContainer * pPrev = static_cast<fp_FrameContainer *>(pFC->getPrev());
1401 if(pPrev)
1402 {
1403 pPrev->setNext(pFC->getNext());
1404 }
1405 if(pFC->getNext())
1406 {
1407 pFC->getNext()->setPrev(pPrev);
1408 }
1409 delete pFC;
1410 }
1411 setFirstContainer(NULL);
1412 setLastContainer(NULL);
1413 }
1414
1415 // Frame Background
1416
s_background_properties(const gchar * pszBgStyle,const gchar * pszBgColor,const gchar * pszBackgroundColor,PP_PropertyMap::Background & background)1417 static void s_background_properties (const gchar * pszBgStyle, const gchar * pszBgColor,
1418 const gchar * pszBackgroundColor,
1419 PP_PropertyMap::Background & background)
1420 {
1421 if (pszBgStyle)
1422 {
1423 if (strcmp (pszBgStyle, "0") == 0)
1424 {
1425 background.m_t_background = PP_PropertyMap::background_none;
1426 }
1427 else if (strcmp (pszBgStyle, "1") == 0)
1428 {
1429 if (pszBgColor)
1430 {
1431 background.m_t_background = PP_PropertyMap::background_type (pszBgColor);
1432 if (background.m_t_background == PP_PropertyMap::background_solid)
1433 UT_parseColor (pszBgColor, background.m_color);
1434 }
1435
1436 }
1437 }
1438
1439 if (pszBackgroundColor)
1440 {
1441 background.m_t_background = PP_PropertyMap::background_type (pszBackgroundColor);
1442 if (background.m_t_background == PP_PropertyMap::background_solid)
1443 UT_parseColor (pszBackgroundColor, background.m_color);
1444 }
1445 }
1446
s_border_properties(const gchar * border_color,const gchar * border_style,const gchar * border_width,const gchar * color,PP_PropertyMap::Line & line)1447 static void s_border_properties (const gchar * border_color, const gchar * border_style, const gchar * border_width,
1448 const gchar * color, PP_PropertyMap::Line & line)
1449 {
1450 /* frame-border properties:
1451 *
1452 * (1) color - defaults to value of "color" property
1453 * (2) line-style - defaults to solid (in contrast to "none" in CSS)
1454 * (3) thickness - defaults to 1 layout unit (??, vs "medium" in CSS)
1455 */
1456 line.reset ();
1457
1458 PP_PropertyMap::TypeColor t_border_color = PP_PropertyMap::color_type (border_color);
1459 if (t_border_color)
1460 {
1461 line.m_t_color = t_border_color;
1462 if (t_border_color == PP_PropertyMap::color_color)
1463 UT_parseColor (border_color, line.m_color);
1464 }
1465 else if (color)
1466 {
1467 PP_PropertyMap::TypeColor t_color = PP_PropertyMap::color_type (color);
1468
1469 line.m_t_color = t_color;
1470 if (t_color == PP_PropertyMap::color_color)
1471 UT_parseColor (color, line.m_color);
1472 }
1473
1474 line.m_t_linestyle = PP_PropertyMap::linestyle_type (border_style);
1475 if (!line.m_t_linestyle)
1476 line.m_t_linestyle = PP_PropertyMap::linestyle_solid;
1477
1478 line.m_t_thickness = PP_PropertyMap::thickness_type (border_width);
1479 if (line.m_t_thickness == PP_PropertyMap::thickness_length)
1480 {
1481 if (UT_determineDimension (border_width, (UT_Dimension)-1) == DIM_PX)
1482 {
1483 double thickness = UT_LAYOUT_RESOLUTION * UT_convertDimensionless (border_width);
1484 line.m_thickness = static_cast<UT_sint32>(thickness / UT_PAPER_UNITS_PER_INCH);
1485 }
1486 else
1487 line.m_thickness = UT_convertToLogicalUnits (border_width);
1488
1489 if (!line.m_thickness)
1490 {
1491 double thickness = UT_LAYOUT_RESOLUTION;
1492 line.m_thickness = static_cast<UT_sint32>(thickness / UT_PAPER_UNITS_PER_INCH);
1493 }
1494 }
1495 else // ??
1496 {
1497 double thickness = UT_LAYOUT_RESOLUTION;
1498 line.m_thickness = static_cast<UT_sint32>(thickness / UT_PAPER_UNITS_PER_INCH);
1499 }
1500 }
1501
1502