4 * BGUI Tree List View class
6 * (C) Copyright 1999 Manuel Lemos.
7 * (C) Copyright 1996-1999 Nick Christie.
11 * Revision 42.2 2004/06/16 20:16:49 verhaegs
12 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
14 * Revision 42.1 2000/05/15 19:29:08 stegerg
15 * replacements for REG macro
17 * Revision 42.0 2000/05/09 22:21:45 mlemos
18 * Bumped to revision 42.0 before handing BGUI to AROS team
20 * Revision 41.11 2000/05/09 20:35:31 mlemos
21 * Bumped to revision 41.11
23 * Revision 1.2 2000/05/09 20:00:30 mlemos
24 * Merged with the branch Manuel_Lemos_fixes.
26 * Revision 1.1.2.2 1999/05/31 01:12:51 mlemos
27 * Made the method functions take the arguments in the apropriate registers.
29 * Revision 1.1.2.1 1999/02/21 04:07:44 mlemos
30 * Nick Christie sources.
36 /************************************************************************
37 *********************** TREEVIEW CLASS: INSERT ************************
38 ************************************************************************/
40 /************************************************************************
41 ****************************** INCLUDES *******************************
42 ************************************************************************/
44 #include "TreeViewPrivate.h"
47 /************************************************************************
48 ************************** LOCAL DEFINITIONS **************************
49 ************************************************************************/
52 /************************************************************************
53 ************************* EXTERNAL REFERENCES *************************
54 ************************************************************************/
57 * Functions from TVUtil are listed in TVUtil.h
60 /************************************************************************
61 ***************************** PROTOTYPES ******************************
62 ************************************************************************/
65 /************************************************************************
66 ***************************** LOCAL DATA ******************************
67 ************************************************************************/
70 /************************************************************************
71 ***************************** TV_INSERT() *****************************
72 *************************************************************************
73 * Insert a new entry into the treeview. In the message structure for
74 * this method, the user includes the entry to insert, a relation entry
75 * to serve as reference for the insertion position, a code to indicate
76 * what kind of relationship there should be between the new entry and
77 * the relation, plus some flags to expand the new node, select it, etc.
78 * This method returns non-zero if successful, zero on failure.
80 * Special values allowed for the relation entry are:
81 * TV_ROOT to represent the root of the tree (a dummy entry).
82 * TV_SELECTED for the (first) currently selected entry.
84 * If the relation entry is TV_SELECTED, but no entry is currently
85 * selected, the entry is not inserted and zero is returned.
87 * Permitted values for the relationship code are as follows:
88 * TVW_CHILD_FIRST first child of relation
89 * TVW_CHILD_LAST last child of relation
90 * TVW_CHILD_SORTED child of relation, sorted
91 * TVW_SIBLING_FIRST first sibling of relation
92 * TVW_SIBLING_LAST last sibling of relation
93 * TVW_SIBLING_NEXT next sibling of relation
94 * TVW_SIBLING_PREV prev. sibling of relation
95 * TVW_SIBLING_SORTED sibling of relation, sorted
97 * If the relation entry is TV_ROOT, only the TVW_CHILD_??? codes are
100 * Permitted bits for the flags parameter are:
101 * TVF_SELECT select entry
102 * TVF_MULTISELECT multi-select entry (with TVF_SELECT)
103 * TVF_MAKEVISIBLE make entry visible
104 * TVF_EXPAND expand entry
106 * The new entry will be displayed in the treeview only if all its parents
107 * are expanded, or a flag such as TVF_SELECT is used. In that case,
108 * parents will be expanded as required to bring the new entry into view
111 *************************************************************************/
113 METHOD(TV_Insert
, struct tvInsert
*, tvi
)
116 TNPTR tn
,prevtn
= NULL
,par
,tr
,sr
= NULL
;
118 ULONG rc
,tvflags
,lvflags
,pos
;
120 TV_DebugDumpMethod((Msg
) tvi
);
122 tv
= (TVData
*) INST_DATA(cl
,obj
);
129 * Set expanded flag if requested
132 if (tvi
->tvi_Flags
& TVF_EXPAND
)
133 tvflags
|= TNF_EXPANDED
;
136 * Allocate a new node for the entry and initialise it's child list.
139 if ((tn
= TV_AllocTreeNode(tv
,tvi
->tvi_Entry
,tvflags
)))
142 * Locate the treenode corresponding to the relation entry,
143 * which may be TV_SELECTED for the first selected entry.
149 if (tvi
->tvi_Relation
== TV_ROOT
)
152 * Relation is the dummy root node, only TVWS_CHILD_? permitted
155 if ((tvi
->tvi_Where
& TVWC_MASK
) == TVWC_CHILD
)
156 tr
= &tv
->tv_RootNode
;
158 else if (tvi
->tvi_Relation
== TV_SELECTED
)
159 /* relation is the first selected entry */
160 tr
= (TNPTR
) DoMethod(tv
->tv_Listview
,LVM_FIRSTENTRY
,NULL
,LVGEF_SELECTED
);
161 else if (tvi
->tvi_Flags
& TVF_INTERNAL
)
162 /* internal reference, already a TreeNode ptr */
163 tr
= tvi
->tvi_Relation
;
165 /* a user's entry: find its TreeNode */
166 tr
= TV_FindTreeNode(RootList(tv
),tvi
->tvi_Relation
);
170 if ((tvi
->tvi_Where
& TVWC_MASK
) == TVWC_CHILD
)
171 par
= tr
; /* parent is relation */
172 else if ((tvi
->tvi_Where
& TVWC_MASK
) == TVWC_SIB
)
173 par
= ParentOf(tr
); /* parent is relation's parent */
175 par
= NULL
; /* no other category allowed */
179 list
= ChildListOf(par
);
182 switch(tvi
->tvi_Where
& TVWS_MASK
)
184 case TVWS_FIRST
: /* first child/sibling of relation */
189 case TVWS_LAST
: /* last child/sibling of relation */
190 prevtn
= LastChildIn(list
);
191 sr
= TV_LastDisplayedChild(par
);
194 case TVWS_NEXT
: /* next sibling of relation */
195 if ((tvi
->tvi_Where
& TVWC_MASK
) == TVWC_SIB
)
198 sr
= TV_LastDisplayedChild(prevtn
);
204 case TVWS_PREV
: /* prev. sibling of relation */
205 if ((tvi
->tvi_Where
& TVWC_MASK
) == TVWC_SIB
)
207 prevtn
= PrevSiblingOf(tr
);
208 sr
= prevtn
? prevtn
: par
;
214 case TVWS_SORT
: /* sorted child/sibling of relation */
215 prevtn
= TV_SortedPrev(tv
,list
,tn
);
216 sr
= prevtn
? TV_LastDisplayedChild(prevtn
) : par
;
219 default: /* no other tvi_Where allowed */
223 } /* end switch(tvi->tvi_Where & TVWS_MASK) */
227 if (TV_IsDisplayed(prevtn
? prevtn
: par
))
228 pos
= TV_TreeNodeToIndex(tv
,sr
) + 1;
231 } /* endif got parent */
233 } /* endif found relation */
235 if (list
) /* passed all tests above */
238 * Add the new entry to the child list of the parent node
239 * (the rootlist if there is no parent) and bump up the total
240 * count of entries. If the new entry has a parent, put in
241 * the link to the parent and increment the parent's child count.
244 Insert(list
,(NODEPTR
) tn
,(NODEPTR
) prevtn
);
250 par
->tn_NumChildren
++;
254 * If we have a position for the entry in the listview,
255 * and the parent is either expanded, or the root entry,
256 * insert the entry in the listview.
259 if ((pos
!= ~0) && (!par
|| IsExpanded(par
)))
260 rc
= DoMethod(tv
->tv_Listview
,LVM_INSERTSINGLE
,tvi
->tvi_GInfo
,
265 * If tv_NoLeafImage is set, and this new entry is the
266 * first child of its parent, we need to refresh the
267 * parent as the image will be applicable.
270 if (tv
->tv_NoLeafImage
&& par
&& (par
->tn_NumChildren
== 1))
271 DoMethod(obj
,TVM_REFRESH
,tvi
->tvi_GInfo
);
276 if (rc
) /* new entry added to listview */
279 * User wants us to make the new entry visible?
282 if (tvi
->tvi_Flags
& TVF_MAKEVISIBLE
)
283 DoMethod(obj
,TVM_VISIBLE
,tvi
->tvi_GInfo
,tn
,
284 TVW_ENTRY
,TVF_INTERNAL
);
286 * User wants us to select the new entry, as well?
289 if (tvi
->tvi_Flags
& TVF_SELECT
)
290 DoMethod(obj
,TVM_SELECT
,tvi
->tvi_GInfo
,tn
,TVW_ENTRY
,
291 TVF_INTERNAL
|(tvi
->tvi_Flags
& TVF_MULTISELECT
));
293 else /* failed to add to listview */
295 Remove((NODEPTR
) tn
);
296 TV_FreeTreeNode(tv
,tn
);
299 par
->tn_NumChildren
--;
302 } /* endif got list */
304 TV_FreeTreeNode(tv
,tn
);
306 } /* endif alloctreenode */