File: observers.xml

package info (click to toggle)
pdfedit 0.4.1-2
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 15,032 kB
  • ctags: 21,708
  • sloc: cpp: 185,471; xml: 8,824; yacc: 1,178; ansic: 666; perl: 664; makefile: 636; sh: 371; lisp: 51
file content (127 lines) | stat: -rw-r--r-- 5,320 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<sect1 id="observers_in_cobjects">
<title>Observers in cobjects</title>
<para>
  Generic observer mechanism described in <xref linkend="general_utils_observers"/> 
  is used in our cobject implementation. <classname>IProperty</classname> base class implements
  <classname>IObserverHandler</classname> interface and so all its descendants are responsible
  for notifying about changes (see <xref linkend="kernel_part_cobjects"/>. 
</para>
<para>
	All cobjects provides <classname>BasicChangeContext</classname> which contains previous value
  of changed one. Because complex types can add and remove its elements,
  special behaviour is specified. New value given as mandatory parameter
  of notify method may be <classname>CNull</classname> if element is deleted from comlex type.
  Old value in the context may also <classname>CNull</classname> if element was added. It is
  imposible to have both of them <classname>CNull</classname>.
</para>
</sect1>

<sect1 id="observers_in_cpdf">
<title>Observers in CPdf</title>
<para>
  CPdf class as PDF file maintainer uses observers for synchronization
  of structures which may be changed in two ways. This may occure
  because all attributes can be accesible through properties (cobjects)
  and also special objects provided by CPdf - CPage for page
  manipulation, COutline for outlines manipulation and so on. Special
  objects keeps logic of concrete entities and manipulates with cobject
  in that way. Property part is without any logic and enables making
  changes which are not covered by special objects. This advantage and
  extensibility is payed by additional synchronization. 
  <note>Property tree doesn't know the way how it was changed.</note>
</para>

<sect2 id="page_tree_synchronization">
<title>Page tree synchronization</title>
<para>
     Page tree, as mentiont above, can be changed from property site of 
	 view by making changes directly to the <xref linkend="page_tree"/> 
	 or by CPdf using 
<programlisting>
	CPdf::insertPage
	Cpdf::removePage
</programlisting>
     methods. Second way is safer, because all necessary workaround are 
     done correctly here which is not guaranteed by property site, where 
     any kind of data can be supplied.
</para>
<para>
	Synchronization is guarantied by 3 internal
	<footnote>
	<para>
		Classes are internal because they need access to CPdf internals, such as
		pageList and protected methods for page tree and page list
		consolidation.
	</para>
	</footnote>
	classes which implements <classname>IObserver</classname> interface. 
	To make their logic easier, each observer is specialized for one 
	type of change. So that we have
	<itemizedlist>
		<listitem>
			<classname>PageTreeRootObserver</classname> - which is registered on
			Pages entry in <xref linkend="document_catalog"/>. If this 
			value changes, we have to throw away and invalidate all pages
			which were returned until now.
		</listitem>
		<listitem>
			<classname>PageTreeNodeObserver</classname> - which is registered on
			all intermediate nodes. If any of node's dictionary is changed,
			checks whether it is entry which may affect page tree (Kids, Count
			or Parent properties are added, removed, or their value is changed).
			it has to invalidate all subtree of this node.
		</listitem>
		<listitem>
			<classname>PageTreeKidsObserver</classname> - which is registered on
			all elements of intermediate node's Kids array. If any of this 
			element changes its value (they all should be referencies to Pages 
			or Page dictionary), original node has to be invalidated and also 
			its children if it is intermediate node.
		</listitem>
	</itemizedlist>
	Whenever Kids array changes and as a result subtree of intermediate node is
	changed, Count entry in node's dictionary has to be changed too and
	propagated to the page tree root. 
</para>
<para>
	All this stuff is implemented by <classname>consolidatePageTree</classname>
	and <classname>consolidatePageList</classname> methods in CPdf. For more
	implementation details, please see doxygen documentation.
</para>
</sect2>
</sect1>

<sect1 id="observer_cpage">
	<title>Observers in CPage</title>
	<sect2 id="observer_for_annotation">
		<title>Observer for annotation</title>
		<para>
			CPage stores all CAnnotation instance from its Annots array in 
			internal <classname>annotStorage</classname>. User can change
			annotatations with <classname>addAnnotation</classname> or
			<classname>delAnnotation</classname> methods but also by changing
			Annots array directly. 
		</para>
		<para>
			To prevent from problems with inconsistency, CPage instance
			registers <classname>AnnotsArrayWatchDog</classname> observer
			implementation on Annots array and all its members (because they are
			referencies and someone may change reference value to target which
			is not annotation dictionary). Whenever this array changes,
			observer will force to reload annotStorage (see doxygen
			documentation for more precise information because they are out of
			scope of this documentation).
		</para>
	</sect2>
</sect1>

<!--
<sect1 id="kernel_part_ccontentstream_observers">
	<title>Observers in CContentStream</title>
	<para>
		Content stream object uses observer TODO Jozo - describe Observer
		implementation - maybe some image whould be good 
	</para>
</sect1>
-->