1 /* AbiWord
2 * Copyright (C) 1998 AbiSource, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA.
18 */
19
20 // change-object-related routines for piece table.
21
22 #include "ut_types.h"
23 #include "ut_misc.h"
24 #include "ut_assert.h"
25 #include "ut_debugmsg.h"
26 #include "ut_growbuf.h"
27 #include "pt_PieceTable.h"
28 #include "pf_Frag.h"
29 #include "pf_Frag_Object.h"
30 #include "pf_Fragments.h"
31 #include "px_ChangeRecord.h"
32 #include "px_CR_Object.h"
33 #include "px_CR_ObjectChange.h"
34 #include "fd_Field.h"
35
36 #define SETP(p,v) do { if (p) (*(p)) = (v); } while (0)
37
38 /****************************************************************/
39 /****************************************************************/
40
changeObjectFormatNoUpdate(PTChangeFmt ptc,pf_Frag_Object * pfo,const gchar ** attributes,const gchar ** properties)41 bool pt_PieceTable::changeObjectFormatNoUpdate(PTChangeFmt ptc ,pf_Frag_Object * pfo, const gchar ** attributes, const gchar ** properties)
42 {
43 PT_AttrPropIndex indexNewAP;
44 PT_AttrPropIndex indexOldAP = pfo->getIndexAP();
45 bool bMerged = m_varset.mergeAP(ptc,indexOldAP,attributes,properties,&indexNewAP,getDocument());
46 UT_UNUSED(bMerged);
47 UT_ASSERT_HARMLESS(bMerged);
48
49 if (indexOldAP == indexNewAP) // the requested change will have no effect on this fragment.
50 {
51 return true;
52 }
53 // actually apply the format change.
54
55 pfo->setIndexAP(indexNewAP);
56 return true;
57 }
58
_fmtChangeObjectWithNotify(PTChangeFmt ptc,pf_Frag_Object * pfo,UT_uint32 fragOffset,PT_DocPosition dpos,UT_uint32 length,const gchar ** attributes,const gchar ** properties,pf_Frag_Strux * pfs,pf_Frag ** ppfNewEnd,UT_uint32 * pfragOffsetNewEnd,bool bRevisionDelete)59 bool pt_PieceTable::_fmtChangeObjectWithNotify(PTChangeFmt ptc,
60 pf_Frag_Object * pfo, UT_uint32 fragOffset,
61 PT_DocPosition dpos,
62 UT_uint32 length,
63 const gchar ** attributes,
64 const gchar ** properties,
65 pf_Frag_Strux * pfs,
66 pf_Frag ** ppfNewEnd,
67 UT_uint32 * pfragOffsetNewEnd,
68 bool bRevisionDelete)
69 {
70 // apply a span-level change to the given object.
71 // create a change record for this change and put it in the history.
72
73 UT_return_val_if_fail (length == pfo->getLength(), false);
74 UT_return_val_if_fail (fragOffset == 0, false);
75
76 PT_AttrPropIndex indexNewAP;
77 PT_AttrPropIndex indexOldAP = pfo->getIndexAP();
78 bool bMerged = m_varset.mergeAP(ptc,indexOldAP,attributes,properties,&indexNewAP,getDocument());
79 UT_UNUSED(bMerged);
80 UT_ASSERT_HARMLESS(bMerged);
81
82 if (indexOldAP == indexNewAP) // the requested change will have no effect on this fragment.
83 {
84 SETP(ppfNewEnd, pfo->getNext());
85 SETP(pfragOffsetNewEnd, 0);
86 return true;
87 }
88
89 PT_BlockOffset blockOffset = _computeBlockOffset(pfs,pfo) + fragOffset;
90
91 // we do this before the actual change because various fields that
92 // we need may be blown away during the change. we then notify all
93 // listeners of the change.
94
95 PX_ChangeRecord_ObjectChange * pcr
96 = new PX_ChangeRecord_ObjectChange(PX_ChangeRecord::PXT_ChangeObject,
97 dpos, indexOldAP,indexNewAP,
98 pfo->getObjectType(),blockOffset,bRevisionDelete);
99 UT_return_val_if_fail (pcr, false);
100
101 // apply the change to this fragment
102
103 _fmtChangeObject(pfo,indexNewAP,ppfNewEnd,pfragOffsetNewEnd);
104
105 // add record to history. we do not attempt to coalesce these.
106 m_history.addChangeRecord(pcr);
107 m_pDocument->notifyListeners(pfs,pcr);
108
109 return true;
110 }
111
_fmtChangeObject(pf_Frag_Object * pfo,PT_AttrPropIndex indexNewAP,pf_Frag ** ppfNewEnd,UT_uint32 * pfragOffsetNewEnd)112 bool pt_PieceTable::_fmtChangeObject(pf_Frag_Object * pfo,
113 PT_AttrPropIndex indexNewAP,
114 pf_Frag ** ppfNewEnd,
115 UT_uint32 * pfragOffsetNewEnd)
116 {
117 // actually apply the format change.
118
119 pfo->setIndexAP(indexNewAP);
120 // if (pfo->getField()) pfo->getField()->update();
121 SETP(ppfNewEnd, pfo->getNext());
122 SETP(pfragOffsetNewEnd, 0);
123 return true;
124 }
125
126
127