Moving to main tree, needed by SysExplorer
[aros:aros.git] / AROS / workbench / classes / zune / nlist / nlist_mcc / NList_mcc.c
1 /***************************************************************************
2
3  NList.mcc - New List MUI Custom Class
4  Registered MUI class, Serial Number: 1d51 0x9d510030 to 0x9d5100A0
5                                            0x9d5100C0 to 0x9d5100FF
6
7  Copyright (C) 1996-2001 by Gilles Masson
8  Copyright (C) 2001-2005 by NList Open Source Team
9
10  This library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU Lesser General Public
12  License as published by the Free Software Foundation; either
13  version 2.1 of the License, or (at your option) any later version.
14
15  This library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  Lesser General Public License for more details.
19
20  NList classes Support Site:  http://www.sf.net/projects/nlist-classes
21
22  $Id$
23
24 ***************************************************************************/
25
26 #include <string.h>
27 #include <stdlib.h>
28
29 #include <dos/dosextens.h>
30 #include <clib/alib_protos.h>
31
32 #ifndef NO_INLINE_STDARG
33 #define NO_INLINE_STDARG
34 #endif
35
36 #include <proto/muimaster.h>
37 #include <proto/diskfont.h>
38 #include <proto/graphics.h>
39 #include <proto/utility.h>
40 #include <proto/exec.h>
41 #include <proto/intuition.h>
42
43 #include "private.h"
44
45 #include "NList_func.h"
46 #include "NList_grp.h"
47
48 #include "NListviews_mcp.h"
49
50 /* IO macros */
51 /*
52  *#define IO_SIGBIT(req)  ((LONG)(((struct IORequest *)req)->io_Message.mn_ReplyPort->mp_SigBit))
53  *#define IO_SIGMASK(req) ((LONG)(1L<<IO_SIGBIT(req)))
54  */
55
56
57 DEFAULT_KEYS_ARRAY
58
59 #define INIT_PEN(attr,var_dest,test_init) \
60   { \
61     var_dest = -1; \
62     if((tag = FindTagItem(attr, msg->ops_AttrList))) \
63     { \
64       test_init = tag->ti_Data; \
65     } \
66     else \
67       test_init = FALSE; \
68   }
69
70 #define INIT_BG(attr,var_dest,test_init) \
71   { \
72     var_dest = -1; \
73     if((tag = FindTagItem(attr, msg->ops_AttrList))) \
74     { \
75       var_dest = tag->ti_Data; \
76       test_init = TRUE; \
77     } \
78     else \
79       test_init = FALSE; \
80   }
81
82
83 #define LOAD_PEN(test,var_dest,cfg_attr,defaultval) \
84   { \
85     if (!test) \
86     { \
87       IPTR ptrd; \
88       if (DoMethod(obj, MUIM_GetConfigItem, cfg_attr, &ptrd)) \
89         obtain_pen(obj, &(var_dest), (struct MUI_PenSpec *)ptrd); \
90       else \
91         obtain_pen(obj, &(var_dest), (struct MUI_PenSpec *)(defaultval)); \
92     } \
93     else \
94       obtain_pen(obj, &(var_dest), (struct MUI_PenSpec *)(test)); \
95   }
96
97 #define LOAD_BG(test,var_dest,cfg_attr,defaultval) \
98   { \
99     if (!test) \
100     { \
101       IPTR ptrd; \
102       if (DoMethod(obj, MUIM_GetConfigItem, cfg_attr, &ptrd)) \
103         var_dest = ptrd; \
104       else \
105         var_dest = (IPTR)(defaultval); \
106     } \
107   }
108
109
110 HOOKPROTONH(NL_ConstructFunc_String, APTR, APTR pool, char *str)
111 {
112   char *new;
113   LONG len = 0;
114
115   while(str[len] != '\0' && str[len] != '\n' && str[len] != '\r' )
116   {
117     len++;
118   }
119
120   if((new = (char *)AllocVecPooled(pool, len+1)) != NULL)
121   {
122     memcpy(new, str, len*sizeof(char));
123     new[len] = '\0'; // we have to terminate with a \0
124   }
125
126   return((APTR)new);
127 }
128 MakeHook(NL_ConstructHook_String, NL_ConstructFunc_String);
129
130 HOOKPROTONH(NL_DestructFunc_String, void, APTR pool, char *entry)
131 {
132   FreeVecPooled(pool, entry);
133 }
134 MakeHook(NL_DestructHook_String, NL_DestructFunc_String);
135
136 HOOKPROTONHNO(NL_LayoutFuncNList, ULONG, struct MUI_LayoutMsg *lm)
137 {
138   switch (lm->lm_Type)
139   {
140     case MUILM_MINMAX:
141     {
142       lm->lm_MinMax.MinWidth  = 1;
143       lm->lm_MinMax.DefWidth  = 1;
144       lm->lm_MinMax.MaxWidth  = 1;
145       lm->lm_MinMax.MinHeight = 1;
146       lm->lm_MinMax.DefHeight = 1;
147       lm->lm_MinMax.MaxHeight = 1;
148
149       return(0);
150       //return (MUILM_UNKNOWN);
151     }
152     break;
153
154     case MUILM_LAYOUT:
155     {
156       Object *cstate = (Object *)lm->lm_Children->mlh_Head;
157       Object *child;
158       LONG mw,mh;
159
160       while((child = NextObject(&cstate)))
161       {
162         mw = (LONG) _defwidth(child);
163         mh = (LONG) _defheight(child);
164
165         if(!MUI_Layout(child,lm->lm_Layout.Width+MUI_MAXMAX,lm->lm_Layout.Height+MUI_MAXMAX,mw,mh,0))
166         {
167           /*return(FALSE);*/
168         }
169       }
170
171       return(TRUE);
172     }
173     break;
174   }
175
176   return(MUILM_UNKNOWN);
177 }
178 MakeStaticHook(NL_LayoutHookNList, NL_LayoutFuncNList);
179
180 HOOKPROTONHNO(NL_LayoutFuncGroup, ULONG, struct MUI_LayoutMsg *lm)
181 {
182   switch (lm->lm_Type)
183   {
184     case MUILM_MINMAX:
185     {
186       lm->lm_MinMax.MinWidth  = 2;
187       lm->lm_MinMax.DefWidth  = 20;
188       lm->lm_MinMax.MaxWidth  = MUI_MAXMAX+100;
189       lm->lm_MinMax.MinHeight = 2;
190       lm->lm_MinMax.DefHeight = 20+100;
191       lm->lm_MinMax.MaxHeight = MUI_MAXMAX+100;
192
193       return(0);
194       //return (MUILM_UNKNOWN);
195     }
196     break;
197
198     case MUILM_LAYOUT:
199     {
200       Object *cstate = (Object *)lm->lm_Children->mlh_Head;
201       Object *child;
202       LONG mw,mh;
203
204       while((child = NextObject(&cstate)))
205       {
206         mw = (LONG) _defwidth(child);
207         mh = (LONG) _defheight(child);
208
209         if (!MUI_Layout(child,0,0,mw,mh,0))
210         {
211           /*return(FALSE);*/
212         }
213       }
214       return(TRUE);
215     }
216     break;
217   }
218
219   return(MUILM_UNKNOWN);
220 }
221 MakeStaticHook(NL_LayoutHookGroup, NL_LayoutFuncGroup);
222
223
224 void release_pen(Object *obj, ULONG *pen)
225 {
226   if(*pen != (ULONG)-1)
227   {
228     MUI_ReleasePen(muiRenderInfo(obj), *pen);
229     *pen = (ULONG)-1;
230   }
231 }
232
233
234 void obtain_pen(Object *obj, ULONG *pen, struct MUI_PenSpec *ps)
235 {
236   release_pen(obj, pen);
237   *pen = MUI_ObtainPen(muiRenderInfo(obj), ps, 0);
238 }
239
240 #if !defined(__MORPHOS__)
241 #ifdef __AROS__
242 static __attribute__ ((noinline)) Object * VARARGS68K DoSuperNew(struct IClass *cl, Object *obj, Tag tag1, ...)
243 {
244     AROS_SLOWSTACKTAGS_PRE_AS(tag1, Object *)
245     retval = (Object *)DoSuperMethod(cl, obj, OM_NEW, AROS_SLOWSTACKTAGS_ARG(tag1), NULL);
246     AROS_SLOWSTACKTAGS_POST
247 }
248 #else
249 static Object * VARARGS68K DoSuperNew(struct IClass *cl, Object *obj, ...)
250 {
251   Object *rc;
252   VA_LIST args;
253
254   ENTER();
255
256   VA_START(args, obj);
257   rc = (Object *)DoSuperMethod(cl, obj, OM_NEW, VA_ARG(args, ULONG), NULL);
258   VA_END(args);
259
260   RETURN(rc);
261   return rc;
262 }
263 #endif
264 #endif // !__MORPHOS__
265
266 IPTR mNL_New(struct IClass *cl,Object *obj,struct opSet *msg)
267 {
268     struct NLData *data;
269   //$$$$Sensei: msg->ops_AttrList is changed to taglist EVERYWHERE in OM_NEW!!!
270   // It should speed up a bit.
271     struct TagItem    *tag;
272     struct TagItem    *taglist    = msg->ops_AttrList;
273   LONG DragType = MUIV_NList_DragType_None;
274   LONG DragSortable = FALSE; /*FALSE*/
275   LONG Draggable = FALSE;    /*FALSE*/
276   LONG Dropable = TRUE;      /*TRUE*/
277   LONG dropable = TRUE;      /*TRUE*/
278   STRPTR ShortHelp = NULL;   // RHP: Added for Special ShortHelp
279   APTR img_tr,grp;
280   const char *img_name = "noimage";
281
282   if((tag = FindTagItem(MUIA_ShortHelp, taglist)))
283     ShortHelp = (STRPTR)tag->ti_Data;
284
285   if((tag = FindTagItem(MUIA_FixHeightTxt, taglist)))
286     tag->ti_Tag = TAG_IGNORE;
287
288   if((tag = FindTagItem(MUIA_FixWidthTxt, taglist)))
289     tag->ti_Tag = TAG_IGNORE;
290
291   if((tag = FindTagItem(MUIA_Draggable, taglist)))
292   {
293     Draggable = tag->ti_Data;
294     tag->ti_Tag = TAG_IGNORE;
295   }
296
297   if((tag = FindTagItem(MUIA_Dropable, taglist)))
298   {
299     Dropable = dropable = tag->ti_Data;
300     tag->ti_Tag = TAG_IGNORE;
301   }
302
303   if((tag = FindTagItem(MUIA_NList_DragSortable, taglist)) ||
304      (tag = FindTagItem(MUIA_List_DragSortable, taglist)))
305   {
306     DragSortable = tag->ti_Data;
307     tag->ti_Tag = TAG_IGNORE;
308   }
309
310   if((tag = FindTagItem(MUIA_NList_DragType, taglist)) ||
311      (tag = FindTagItem(MUIA_Listview_DragType, taglist)))
312   {
313     DragType = tag->ti_Data;
314     tag->ti_Tag = TAG_IGNORE;
315   }
316
317   if((DragType != MUIV_NList_DragType_None) || DragSortable)
318     Draggable = TRUE;
319   else if (Draggable)
320     DragType = MUIV_NList_DragType_Default;
321   else
322   {
323     DragType = MUIV_NList_DragType_None;
324     DragSortable = FALSE;
325   }
326
327   if(DragSortable)
328     dropable = TRUE;
329
330   obj = (Object *) DoSuperNew(cl,obj,
331     MUIA_Group_LayoutHook, &NL_LayoutHookNList,
332     MUIA_FillArea, FALSE,
333     MUIA_Dropable, dropable,
334     NoFrame,
335       Child, grp = NewObject(NGR_Class->mcc_Class,NULL,
336         MUIA_Group_LayoutHook, &NL_LayoutHookGroup,
337         MUIA_FillArea, FALSE,
338         NoFrame,
339         Child, img_tr = MUI_NewObject(MUIC_Image,
340           MUIA_FillArea,FALSE,
341           MUIA_Image_Spec,img_name,
342 /*
343  *         MUIA_Image_FontMatch, TRUE,
344  *         MUIA_Font, Topaz_8,
345  *         MUIA_Image_State, IDS_NORMAL,
346  */
347         End,
348         /*Child, HVSpace,*/
349       End,
350     TAG_MORE, taglist
351   );
352
353
354   if(obj == NULL || (data = INST_DATA(cl, obj)) == NULL)
355     return(0);
356
357   data->this = obj;
358   data->nlistviewobj = NULL;
359   data->listviewobj = NULL;
360   data->scrollersobj = NULL;
361   data->SETUP = FALSE;
362   data->SHOW = FALSE;
363   data->DRAW = 0;
364   data->ncl = cl;
365   data->ocl = OCLASS(obj);
366   data->rp = NULL;
367   data->NL_Group = grp;
368
369   data->NList_Title = NULL;
370   data->NList_TitleSeparator = TRUE;
371   data->NList_TitleMark = MUIV_NList_TitleMark_None;
372   data->NList_TitleMark2 = MUIV_NList_TitleMark2_None;
373   data->NList_IgnoreSpecialChars = NULL;
374   data->NList_LastInserted = -1;
375   data->NList_Quiet = 0;
376   data->NList_AffActive = MUIV_NList_Active_Off;
377   data->NList_Active = MUIV_NList_Active_Off;
378   data->NList_Smooth = DEFAULT_SMOOTHSCROLL;
379   data->VertPropObject = NULL;
380   data->NList_AffFirst = 0;
381   data->NList_AffFirst_Incr = 0;
382   data->NList_First = 0;
383   data->NList_First_Incr = 0;
384   data->NList_Visible = 50000;
385   data->NList_Entries = 0;
386   data->NList_Prop_First = 0;
387   data->NList_Prop_First_Prec = 0;
388   data->NList_Prop_First_Real = 0;
389   data->NList_Prop_Add = 0;
390   data->NList_Prop_Wait = 2;
391   data->NList_Prop_Visible = 0;
392   data->NList_Prop_Entries = 0;
393   data->NList_Horiz_AffFirst = 0;
394   data->NList_Horiz_First = 0;
395   data->NList_Horiz_Visible = 0;
396   data->NList_Horiz_Entries = 0;
397   data->old_prop_visible = -1;
398   data->old_prop_entries = -1;
399   data->old_prop_delta = -1;
400   data->old_horiz_visible = -1;
401   data->old_horiz_entries = -1;
402   data->old_horiz_delta = -1;
403   data->NList_MultiSelect = MUIV_NList_MultiSelect_None;
404   data->NList_Input = TRUE;
405   data->NList_DefaultObjectOnClick = TRUE;
406   data->NList_ActiveObjectOnClick = FALSE;
407   data->NList_KeepActive = 0;
408   data->NList_MakeActive = 0;
409   data->NList_AutoVisible = FALSE;
410   data->NList_Font = 0;
411   data->NList_DragType = DragType;
412   data->NList_Dropable = Dropable;
413   data->NList_DragColOnly = -1;
414   data->NList_DragSortable = DragSortable;
415   data->NList_DropMark = -1;
416   data->NList_SortType = MUIV_NList_SortType_None;
417   data->NList_SortType2 = MUIV_NList_SortType_None;
418   data->NList_ButtonClick = -1;
419   data->NList_SerMouseFix = DEFAULT_SERMOUSEFIX;
420   data->NList_Keys = default_keys;
421   data->NList_ShortHelp = ShortHelp; // RHP: Added for Special ShortHelp
422   data->Wheel_Keys = NULL;
423   data->pushtrigger = 0;
424   data->marktype = 0;
425   data->NList_ShowDropMarks = TRUE;
426   data->NImage2 = NULL;
427   data->NImage.NImgObj = img_tr;
428   data->NImage.ImgName = (char *)img_name;
429   data->NImage.next = NULL;
430   data->multiselect = MUIV_NList_MultiSelect_None;
431   data->multisel_qualifier = 0;
432   data->drag_qualifier = 0;
433   data->InUseFont = NULL;
434   data->badrport = FALSE;
435   data->moves = FALSE;
436   data->multiclick = 0;
437   data->multiclickalone = 0;
438   data->click_line = -2;
439   data->click_x = 0;
440   data->click_y = 0;
441   data->NList_SelectChange = FALSE;
442   data->EntriesArray = NULL;
443   data->LastEntry = 0;
444   data->vpos = 1;
445   data->voff = 1;
446   data->vinc = 1;
447   data->addvinc = 1;
448   data->hpos = 1;
449   data->adding_member = 0;
450   data->format_chge = 1;
451   data->do_draw_all = TRUE;
452   data->do_draw_title = TRUE;
453   data->do_draw_active = TRUE;
454   data->do_draw = TRUE;
455   data->do_parse = TRUE;
456   data->do_setcols = TRUE;
457   data->do_updatesb = TRUE;
458   data->do_wwrap = TRUE;
459   data->force_wwrap = FALSE;
460   data->do_images = TRUE;
461   data->nodraw = 1;
462   data->drawsuper = FALSE;
463   data->dropping = FALSE;
464   data->markdraw = FALSE;
465   data->markerase = FALSE;
466   data->markdrawnum = -1;
467   data->markerasenum = -1;
468   data->NumIntuiTick = 0;
469   data->sorted = FALSE;
470   data->selectmode = TE_Select_Line;
471   data->first_change = LONG_MAX;
472   data->last_change = LONG_MIN;
473   data->lastselected = MUIV_NList_Active_Off;
474   data->lastactived = MUIV_NList_Active_Off;
475   data->selectskiped = FALSE;
476   data->NList_ListBackGround = -1;
477   data->actbackground = -1;
478   data->NList_CompareHook = NULL;
479   data->NList_ConstructHook = NULL;
480   data->NList_DestructHook = NULL;
481   data->NList_DisplayHook = NULL;
482   data->NList_MultiTestHook = NULL;
483   data->NList_CopyEntryToClipHook = NULL;
484   data->NList_CopyColumnToClipHook = NULL;
485   data->NList_CompareHook2 = FALSE;
486   data->NList_ConstructHook2 = FALSE;
487   data->NList_DestructHook2 = FALSE;
488   data->NList_DisplayHook2 = FALSE;
489   data->NList_CopyEntryToClipHook2 = FALSE;
490   data->NList_CopyColumnToClipHook2 = FALSE;
491 /*
492   data->NList_Pool = NULL;
493   data->NList_PoolPuddleSize = 2008;
494   data->NList_PoolThreshSize = 1024;
495 */
496   data->NList_MinLineHeight = 5;
497   data->MinImageHeight = 5;
498   data->NList_AdjustHeight = 0;
499   data->NList_AdjustWidth = 0;
500   data->NList_SourceArray = 0;
501   data->NList_DefClickColumn = 0;
502   data->NList_AutoCopyToClip = TRUE;
503   data->NList_AutoClip = TRUE;
504   data->NList_UseImages = NULL;
505   data->NList_TabSize = 8;
506   data->NList_SkipChars = NULL;
507   data->NList_WordSelectChars = NULL;
508   data->NList_EntryValueDependent = FALSE;
509   data->NList_DragLines = DEFAULT_DRAGLINES;
510   data->NList_WheelStep = DEFAULT_WHEELSTEP;
511   data->NList_WheelFast = DEFAULT_WHEELFAST;
512   data->NList_WheelMMB = DEFAULT_WHEELMMB;
513   data->NList_PrivateData = NULL;
514   data->NList_ContextMenu = data->ContextMenu = data->ContextMenuOn = MUIV_NList_ContextMenu_Default;
515   data->ListCompatibility = FALSE;
516   data->NList_Disabled = FALSE;
517   data->MenuObj = NULL;
518   data->LastImage = 0;
519   data->DragRPort = NULL;
520   data->cols = NULL;
521   data->Title_PixLen = -1;
522   data->numcols = 0;
523   data->numcols2 = 0;
524   data->column[0] = -1;
525   data->aff_infos = NULL;
526   data->numaff_infos = 0;
527   data->spacesize = 6;
528   data->tabsize = data->spacesize * data->NList_TabSize;
529 //  data->NList_Pool_Given = FALSE;
530   data->NList_TypeSelect = MUIV_NList_TypeSelect_Line;
531   data->min_sel = 1;
532   data->max_sel = 1;
533   data->sel_pt[0].ent = -1;
534   data->sel_pt[1].ent = -1;
535   data->minx_change_entry = -1;
536   data->maxx_change_entry = -1;
537   data->drag_border = FALSE;
538   data->ScrollBarsPos = -4;
539   data->ScrollBars = 0;
540   data->ScrollBarsOld = 0;
541   data->ScrollBarsTime = 0;
542   data->display_ptr = NULL;
543   data->Notify = 0;
544   data->DoNotify = 0;
545   data->Notifying = 0;
546   data->TitleClick = -1;
547   data->TitleClick2 = -1;
548   data->NList_ForcePen = MUIV_NList_ForcePen_Default;
549   data->ForcePen = DEFAULT_FORCEPEN;
550   data->UpdatingScrollbars = FALSE;
551   data->UpdateScrollersRedrawn = FALSE;
552   data->drawall_bits = 0;
553   data->drawall_dobit = 0;
554   data->refreshing = FALSE;
555   data->VirtGroup = NULL;
556   data->VirtGroup2 = NULL;
557   data->VirtClass = NULL;
558   data->NList_ColWidthDrag = DEFAULT_CWD;
559   data->NList_PartialCol = DEFAULT_PARTIALCOL;
560   data->NList_PartialChar = DEFAULT_PARTIALCHAR;
561   data->NList_List_Select = MUIV_NList_Select_List;
562   data->NList_MinColSortable = 1;
563   data->NList_Imports = MUIV_NList_Imports_Active | MUIV_NList_Imports_First | MUIV_NList_Imports_Cols;
564   data->NList_Exports = MUIV_NList_Exports_Active | MUIV_NList_Exports_First | MUIV_NList_Exports_Cols;
565   data->affover = -1; // RHP: Added for Shorthelp
566   data->affbutton = -1;
567   data->affbuttonline = -1;
568   data->affbuttoncol = -1;
569   data->affbuttonstate = 0;
570   data->storebutton = TRUE;
571   data->SizePointerObj = NULL;
572   data->MovePointerObj = NULL;
573   data->NList_SelectPointer = DEFAULT_SELECTPOINTER;
574   data->SelectPointerObj = NULL;
575   data->activeCustomPointer = PT_NONE;
576   data->MOUSE_MOVE = FALSE;
577   data->pad1 = -1;
578   data->pad2 = TRUE;
579   data->isActiveObject = FALSE;
580   data->NList_KeyUpFocus = NULL;
581   data->NList_KeyDownFocus = NULL;
582   data->NList_KeyLeftFocus = NULL;
583   data->NList_KeyRightFocus = NULL;
584
585 /*D(bug("%lx|NEW 1 \n",obj));*/
586
587   //$$$Sensei: major rewrite memory handling. PuddleSize and ThreshSize takes memory, nothing else.
588   /* User pool was specified passed? */
589   if(( tag = FindTagItem( MUIA_NList_Pool, taglist ) ) ||
590      ( tag = FindTagItem( MUIA_List_Pool, taglist ) ) )
591   {
592     data->Pool = (APTR)tag->ti_Data;
593   }
594   else
595   {
596     ULONG puddleSize = GetTagData(MUIA_NList_PoolPuddleSize, GetTagData(MUIA_List_PoolPuddleSize, MUIV_NList_PoolPuddleSize_Default, taglist), taglist);
597     ULONG threshold = GetTagData(MUIA_NList_PoolThreshSize, GetTagData(MUIA_List_PoolThreshSize, MUIV_NList_PoolThreshSize_Default, taglist), taglist);
598
599     /* Create internal pool using specified parameters or default one. */
600     #if defined(__amigaos4__)
601     data->Pool = AllocSysObjectTags(ASOT_MEMPOOL, ASOPOOL_MFlags, MEMF_SHARED,
602                                                   ASOPOOL_Puddle, puddleSize,
603                                                   ASOPOOL_Threshold, threshold,
604                                                   ASOPOOL_Name, "NList.mcc pool",
605                                                   TAG_DONE);
606     #else
607     data->Pool = CreatePool(MEMF_ANY, puddleSize, threshold);
608     #endif
609
610     data->PoolInternal = data->Pool;
611   }
612
613   #if defined(__amigaos4__)
614   // for OS4 we create an ItemPool
615   data->EntryPool = AllocSysObjectTags(ASOT_ITEMPOOL, ASOITEM_MFlags, MEMF_SHARED,
616                                                       ASOITEM_ItemSize, sizeof(struct TypeEntry),
617                                                       ASOITEM_BatchSize, 1024,
618                                                       ASOITEM_GCPolicy, ITEMGC_AFTERCOUNT,
619                                                       TAG_DONE);
620   #else
621   // all other systems use a standard pool with puddle size and threshold set appropriately
622   data->EntryPool = CreatePool(MEMF_ANY, sizeof(struct TypeEntry) * 1024, sizeof(struct TypeEntry) * 1024);
623   #endif
624
625   // are pools available?
626   if(data->Pool == NULL || data->EntryPool == NULL)
627   {
628     CoerceMethod(cl, obj, OM_DISPOSE);
629     return(0);
630   }
631
632   if ((tag = FindTagItem(MUIA_NList_ConstructHook, taglist)) ||
633       (tag = FindTagItem(MUIA_List_ConstructHook, taglist)))
634   {
635     if (tag->ti_Data == (ULONG)MUIV_NList_ConstructHook_String)
636       data->NList_ConstructHook = (struct Hook *) &NL_ConstructHook_String;
637     else
638       data->NList_ConstructHook = (struct Hook *) tag->ti_Data;
639   }
640   if ((tag = FindTagItem(MUIA_NList_DestructHook, taglist)) ||
641       (tag = FindTagItem(MUIA_List_DestructHook, taglist)))
642   {
643     if (tag->ti_Data == (ULONG)MUIV_NList_DestructHook_String)
644       data->NList_DestructHook = (struct Hook *) &NL_DestructHook_String;
645     else
646       data->NList_DestructHook = (struct Hook *) tag->ti_Data;
647   }
648
649   if((tag = FindTagItem(MUIA_NList_ListCompatibility, taglist)))
650     data->ListCompatibility = TRUE;
651   else
652     data->ListCompatibility = FALSE;
653
654   if((tag = FindTagItem(MUIA_Disabled, taglist)))
655     data->NList_Disabled = 1;
656   else
657     data->NList_Disabled = FALSE;
658
659   if((tag = FindTagItem(MUIA_NList_CompareHook, taglist)) ||
660      (tag = FindTagItem(MUIA_List_CompareHook, taglist)))
661   {
662     data->NList_CompareHook = (struct Hook *) tag->ti_Data;
663   }
664
665   if((tag = FindTagItem(MUIA_NList_DisplayHook, taglist)) ||
666      (tag = FindTagItem(MUIA_List_DisplayHook, taglist)))
667   {
668     data->NList_DisplayHook = (struct Hook *) tag->ti_Data;
669   }
670
671   if((tag = FindTagItem(MUIA_NList_MultiTestHook, taglist)) ||
672      (tag = FindTagItem(MUIA_List_MultiTestHook, taglist)))
673   {
674     data->NList_MultiTestHook = (struct Hook *) tag->ti_Data;
675   }
676
677   if((tag = FindTagItem(MUIA_NList_CopyEntryToClipHook, taglist)))
678     data->NList_CopyEntryToClipHook = (struct Hook *) tag->ti_Data;
679
680   if((tag = FindTagItem(MUIA_NList_CopyColumnToClipHook, taglist)))
681     data->NList_CopyColumnToClipHook = (struct Hook *) tag->ti_Data;
682
683   if((tag = FindTagItem(MUIA_NList_ConstructHook2, taglist)))
684   {
685     data->NList_ConstructHook = (struct Hook *) tag->ti_Data;
686     data->NList_ConstructHook2 = TRUE;
687   }
688
689   if((tag = FindTagItem(MUIA_NList_DestructHook2, taglist)))
690   {
691     data->NList_DestructHook = (struct Hook *) tag->ti_Data;
692     data->NList_DestructHook2 = TRUE;
693   }
694
695   if((tag = FindTagItem(MUIA_NList_CompareHook2, taglist)))
696   {
697     data->NList_CompareHook = (struct Hook *) tag->ti_Data;
698     data->NList_CompareHook2 = TRUE;
699   }
700
701   if((tag = FindTagItem(MUIA_NList_DisplayHook2, taglist)))
702   {
703     data->NList_DisplayHook = (struct Hook *) tag->ti_Data;
704     data->NList_DisplayHook2 = TRUE;
705   }
706
707   if((tag = FindTagItem(MUIA_NList_CopyEntryToClipHook2, taglist)))
708   {
709     data->NList_CopyEntryToClipHook = (struct Hook *) tag->ti_Data;
710     data->NList_CopyEntryToClipHook2 = TRUE;
711   }
712
713   if((tag = FindTagItem(MUIA_NList_CopyColumnToClipHook2, taglist)))
714   {
715     data->NList_CopyColumnToClipHook = (struct Hook *) tag->ti_Data;
716     data->NList_CopyColumnToClipHook2 = TRUE;
717   }
718
719   if((tag = FindTagItem(MUICFG_NList_ForcePen, taglist)))
720     data->NList_ForcePen = (LONG) tag->ti_Data;
721
722   if((tag = FindTagItem(MUIA_NList_Format, taglist)) ||
723      (tag = FindTagItem(MUIA_List_Format, taglist)))
724   {
725     data->NList_Format = (char *) tag->ti_Data;
726     if (!NL_Read_Format(data,(char *) tag->ti_Data,(tag->ti_Tag == MUIA_List_Format)))
727     {
728       CoerceMethod(cl, obj, OM_DISPOSE);
729       return(0);
730     }
731   }
732   else
733   {
734     data->NList_Format = NULL;
735     if (!NL_Read_Format(data, (char *)"",FALSE))
736     {
737       CoerceMethod(cl, obj, OM_DISPOSE);
738       return(0);
739     }
740   }
741
742   if (!NeedAffInfo(data,AFFINFOS_START_MAX))
743   {
744     CoerceMethod(cl, obj, OM_DISPOSE);
745     return(0);
746   }
747 /*D(bug("%lx|NEW 5 \n",obj));*/
748
749   if ((tag = FindTagItem(MUIA_NList_Input, taglist)) ||
750       (tag = FindTagItem(MUIA_Listview_Input, taglist)))
751     data->NList_Input = tag->ti_Data;
752
753   if(!FindTagItem(MUIA_Frame, taglist))
754   {
755     if (data->NList_Input)
756     {
757       nnset(obj,MUIA_Frame, MUIV_Frame_InputList);
758     }
759     else
760     {
761       nnset(obj,MUIA_Frame, MUIV_Frame_ReadList);
762     }
763   }
764
765   if((tag = FindTagItem(MUIA_ContextMenu, taglist)))
766   {
767     data->NList_ContextMenu = data->ContextMenu = data->ContextMenuOn = tag->ti_Data;
768   }
769   else
770     notdoset(obj,MUIA_ContextMenu,data->ContextMenu);
771
772   if((tag = FindTagItem(MUIA_Font, taglist)))
773     data->NList_Font = tag->ti_Data;
774   else if (!data->ListCompatibility)
775     data->NList_Font = MUIV_NList_Font;
776   else
777     data->NList_Font = MUIV_Font_List;
778
779   if((tag = FindTagItem(MUIA_NList_AutoCopyToClip, taglist)))
780     data->NList_AutoCopyToClip = (LONG) tag->ti_Data;
781
782   if((tag = FindTagItem(MUIA_NList_AutoClip, taglist)))
783     data->NList_AutoClip = (BOOL)tag->ti_Data;
784
785   if((tag = FindTagItem(MUIA_NList_TabSize, taglist)))
786     data->NList_TabSize = (LONG) tag->ti_Data;
787
788   if((tag = FindTagItem(MUIA_NList_SkipChars, taglist)))
789     data->NList_SkipChars = (char *) tag->ti_Data;
790
791   if((tag = FindTagItem(MUIA_NList_WordSelectChars, taglist)))
792     data->NList_WordSelectChars = (char *) tag->ti_Data;
793
794   if((tag = FindTagItem(MUIA_NList_EntryValueDependent, taglist)))
795     data->NList_EntryValueDependent = (LONG) tag->ti_Data;
796
797   if((tag = FindTagItem(MUIA_NList_PrivateData, taglist)))
798     data->NList_PrivateData = (APTR) tag->ti_Data;
799
800   if((tag = FindTagItem(MUIA_NList_Title, taglist)) ||
801      (tag = FindTagItem(MUIA_List_Title, taglist)))
802   {
803     data->NList_Title = (char *) tag->ti_Data;
804   }
805
806   if((tag = FindTagItem(MUIA_NList_TitleSeparator, taglist)))
807     data->NList_TitleSeparator = (LONG) tag->ti_Data;
808
809   if((tag = FindTagItem(MUIA_NList_TitleClick, taglist)))
810     WANT_NOTIFY(NTF_TitleClick);
811
812   if((tag = FindTagItem(MUIA_NList_TitleClick2, taglist)))
813     WANT_NOTIFY(NTF_TitleClick2);
814
815   if((tag = FindTagItem(MUIA_NList_MultiSelect, taglist)) ||
816      (tag = FindTagItem(MUIA_Listview_MultiSelect, taglist)))
817   {
818     data->multiselect = data->NList_MultiSelect = (LONG) tag->ti_Data;
819   }
820
821   if((tag = FindTagItem(MUIA_NList_DefaultObjectOnClick, taglist)))
822     data->NList_DefaultObjectOnClick = (LONG) tag->ti_Data;
823
824   if((tag = FindTagItem(MUIA_NList_ActiveObjectOnClick, taglist)))
825   {
826     data->NList_ActiveObjectOnClick = (BOOL)tag->ti_Data;
827     if(data->NList_ActiveObjectOnClick)
828     {
829       // disable that the object will automatically get a border when
830       // the ActiveObjectOnClick option is active
831       _flags(obj) |= (1<<7);
832     }
833   }
834
835   if((tag = FindTagItem(MUIA_NList_MinLineHeight, taglist)))
836     data->NList_MinLineHeight = (LONG) tag->ti_Data;
837
838   if((tag = FindTagItem(MUIA_List_MinLineHeight, taglist)))
839     data->NList_MinLineHeight = (LONG) tag->ti_Data;
840
841   if((tag = FindTagItem(MUIA_NList_TypeSelect, taglist)))
842     data->NList_TypeSelect = (LONG) tag->ti_Data;
843
844   if((tag = FindTagItem(MUIA_NList_AutoVisible, taglist)) ||
845      (tag = FindTagItem(MUIA_List_AutoVisible, taglist)))
846   {
847     data->NList_AutoVisible = (LONG) tag->ti_Data;
848   }
849
850   if((tag = FindTagItem(MUIA_NList_DefClickColumn, taglist)) ||
851      (tag = FindTagItem(MUIA_Listview_DefClickColumn, taglist)))
852   {
853     data->NList_DefClickColumn = (LONG) tag->ti_Data;
854   }
855
856   if((tag = FindTagItem(MUIA_NList_ShowDropMarks, taglist)) ||
857      (tag = FindTagItem(MUIA_List_ShowDropMarks, taglist)))
858   {
859     data->NList_ShowDropMarks = (LONG) tag->ti_Data;
860   }
861
862   if((tag = FindTagItem(MUIA_NList_DragColOnly, taglist)))
863     data->NList_DragColOnly = (LONG) tag->ti_Data;
864
865   if((tag = FindTagItem(MUIA_NList_SortType, taglist)))
866     data->NList_SortType = (LONG) tag->ti_Data;
867
868   if((tag = FindTagItem(MUIA_NList_SortType2, taglist)))
869     data->NList_SortType2 = (LONG) tag->ti_Data;
870
871   if((tag = FindTagItem(MUIA_NList_MinColSortable, taglist)))
872     data->NList_MinColSortable = (LONG) tag->ti_Data;
873
874   if((tag = FindTagItem(MUIA_NList_Imports, taglist)))
875     data->NList_Imports = (LONG) tag->ti_Data;
876
877   if((tag = FindTagItem(MUIA_NList_Exports, taglist)))
878     data->NList_Exports = (LONG) tag->ti_Data;
879
880   if((tag = FindTagItem(MUIA_NList_TitleMark, taglist)))
881     data->NList_TitleMark = (LONG) tag->ti_Data;
882
883   if((tag = FindTagItem(MUIA_NList_TitleMark2, taglist)))
884     data->NList_TitleMark2 = (LONG) tag->ti_Data;
885
886   if((tag = FindTagItem(MUIA_NList_Columns, taglist)))
887     NL_Columns(data,(BYTE *) tag->ti_Data);
888
889   if((tag = FindTagItem(MUIA_NList_KeyUpFocus, taglist)))
890     data->NList_KeyUpFocus = (Object *)tag->ti_Data;
891
892   if((tag = FindTagItem(MUIA_NList_KeyDownFocus, taglist)))
893     data->NList_KeyDownFocus = (Object *)tag->ti_Data;
894
895   if((tag = FindTagItem(MUIA_NList_KeyLeftFocus, taglist)))
896     data->NList_KeyLeftFocus = (Object *)tag->ti_Data;
897
898   if((tag = FindTagItem(MUIA_NList_KeyRightFocus, taglist)))
899     data->NList_KeyRightFocus = (Object *)tag->ti_Data;
900
901   if (data->NList_DragSortable)
902     data->NList_ShowDropMarks = TRUE;
903
904 /*D(bug("%lx|NEW 6 \n",obj));*/
905
906   INIT_PEN(MUIA_NList_TitlePen,   data->NList_TitlePen,   data->Pen_Title_init);
907   INIT_PEN(MUIA_NList_ListPen,    data->NList_ListPen,    data->Pen_List_init);
908   INIT_PEN(MUIA_NList_SelectPen,  data->NList_SelectPen,  data->Pen_Select_init);
909   INIT_PEN(MUIA_NList_CursorPen,  data->NList_CursorPen,  data->Pen_Cursor_init);
910   INIT_PEN(MUIA_NList_UnselCurPen,data->NList_UnselCurPen,data->Pen_UnselCur_init);
911   INIT_PEN(MUIA_NList_InactivePen,data->NList_InactivePen,data->Pen_Inactive_init);
912
913   INIT_BG(MUIA_NList_TitleBackground,   data->NList_TitleBackGround,   data->BG_Title_init);
914   INIT_BG(MUIA_Background,              data->NList_ListBackGround,    data->BG_List_init);
915   if (!data->BG_List_init)
916     INIT_BG(MUIA_NList_ListBackground,  data->NList_ListBackGround,    data->BG_List_init);
917   INIT_BG(MUIA_NList_SelectBackground,  data->NList_SelectBackground,  data->BG_Select_init);
918   INIT_BG(MUIA_NList_CursorBackground,  data->NList_CursorBackground,  data->BG_Cursor_init);
919   INIT_BG(MUIA_NList_UnselCurBackground,data->NList_UnselCurBackground,data->BG_UnselCur_init);
920   INIT_BG(MUIA_NList_InactiveBackground,data->NList_InactiveBackground,data->BG_Inactive_init);
921
922 /*
923  *   for (tags=((struct opSet *)msg)->ops_AttrList;tag=NextTagItem(&tags);)
924  *   { switch (tag->ti_Tag)
925  *     { case MYATTR_PEN:
926  *         if (tag->ti_Data)
927  *           data->penspec = *((struct MUI_PenSpec *)tag->ti_Data);
928  *         break;
929  *     }
930  *   }
931  */
932
933 /*D(bug("%lx|NEW 7 \n",obj));*/
934   if((tag = FindTagItem(MUIA_NList_AdjustHeight, taglist)))
935   {
936     if (tag->ti_Data)
937       data->NList_AdjustHeight = -1;
938   }
939
940   if((tag = FindTagItem(MUIA_NList_AdjustWidth, taglist)))
941   {
942     if (tag->ti_Data)
943       data->NList_AdjustWidth = -1;
944   }
945
946   if((tag = FindTagItem(MUIA_NList_SourceInsert, taglist)) && tag->ti_Data)
947   {
948     struct MUIP_NList_InsertWrap *ins = (struct MUIP_NList_InsertWrap *) tag->ti_Data;
949
950     NL_List_Insert(data,ins->entries,ins->count,ins->pos,ins->wrapcol,ins->align & ALIGN_MASK,0);
951
952     if(data->NList_Entries > 0)
953       data->NList_SourceArray = 1;
954
955     if((tag = FindTagItem(MUIA_NList_First, taglist)))
956       NL_List_First(data,(long) tag->ti_Data,tag);
957
958     if((tag = FindTagItem(MUIA_NList_Active, taglist)))
959       NL_List_Active(data,(long) tag->ti_Data,tag,MUIV_NList_Select_None,FALSE,0);
960   }
961   else if((tag = FindTagItem(MUIA_NList_SourceString, taglist)) && tag->ti_Data)
962   {
963     NL_List_Insert(data,(APTR *) tag->ti_Data,-2,MUIV_NList_Insert_Bottom,0,0,0);
964
965     if(data->NList_Entries > 0)
966       data->NList_SourceArray = 1;
967
968     if((tag = FindTagItem(MUIA_NList_First, taglist)))
969       NL_List_First(data,(long) tag->ti_Data,tag);
970
971     if((tag = FindTagItem(MUIA_NList_Active, taglist)))
972       NL_List_Active(data,(long) tag->ti_Data,tag,MUIV_NList_Select_None,FALSE,0);
973   }
974   else if((tag = FindTagItem(MUIA_NList_SourceArray, taglist)) ||
975           (tag = FindTagItem(MUIA_List_SourceArray, taglist)))
976   {
977     NL_List_Insert(data,(APTR *) tag->ti_Data,-1,MUIV_NList_Insert_Bottom,0,0,0);
978
979     if(data->NList_Entries > 0)
980       data->NList_SourceArray = 1;
981
982     if((tag = FindTagItem(MUIA_NList_First, taglist)))
983       NL_List_First(data,(long) tag->ti_Data,tag);
984
985     if((tag = FindTagItem(MUIA_NList_Active, taglist)))
986       NL_List_Active(data,(long) tag->ti_Data,tag,MUIV_NList_Select_None,FALSE,0);
987   }
988
989   if((tag = FindTagItem(MUIA_NList_IgnoreSpecialChars, taglist)))
990     data->NList_IgnoreSpecialChars = (const char *)tag->ti_Data;
991
992   data->ihnode.ihn_Object  = obj;
993   data->ihnode.ihn_Millis  = 30;
994   data->ihnode.ihn_Method  = MUIM_NList_Trigger;
995   data->ihnode.ihn_Flags   = MUIIHNF_TIMER;
996
997   set(obj,MUIA_FillArea,(LONG) FALSE);
998
999 /*D(bug("%lx|NEW 9 \n",obj));*/
1000
1001   return((IPTR)obj);
1002 }
1003
1004
1005 IPTR mNL_Dispose(struct IClass *cl,Object *obj,Msg msg)
1006 {
1007   register struct NLData *data;
1008   data = INST_DATA(cl,obj);
1009
1010 /*D(bug("%lx|mNL_Dispose() 1 \n",obj));*/
1011
1012   data->NList_Quiet = 1;
1013   data->SETUP = 3;
1014
1015   NL_List_Clear(data);
1016
1017   data->format_chge = data->do_draw_all = data->do_draw_title = data->do_draw_active = data->do_draw = FALSE;
1018   data->do_parse = data->do_images = data->do_setcols = data->do_updatesb = data->do_wwrap = data->force_wwrap = FALSE;
1019   data->Notify = data->DoNotify = data->Notifying = 0;
1020
1021   if (data->MenuObj)
1022   {
1023     MUI_DisposeObject(data->MenuObj);
1024     data->MenuObj = NULL;
1025   }
1026
1027   DeleteNImages2(data);
1028
1029   DeleteNImages(data);
1030
1031   if (data->NList_UseImages)
1032     FreeVecPooled(data->Pool, data->NList_UseImages);
1033
1034   data->NList_UseImages = NULL;
1035   data->LastImage = 0;
1036
1037   FreeAffInfo(data);
1038
1039   NL_Free_Format(data);
1040
1041   if(data->EntryPool != NULL)
1042   {
1043     #if defined(__amigaos4__)
1044     FreeSysObject(ASOT_ITEMPOOL, data->EntryPool);
1045     #else
1046     DeletePool(data->EntryPool);
1047     #endif
1048   }
1049
1050   if(data->PoolInternal != NULL)
1051   {
1052     #if defined(__amigaos4__)
1053     FreeSysObject(ASOT_MEMPOOL, data->PoolInternal);
1054     #else
1055     DeletePool(data->PoolInternal);
1056     #endif
1057   }
1058
1059   return(DoSuperMethodA(cl,obj,msg));
1060
1061 }
1062
1063
1064
1065 IPTR mNL_Setup(struct IClass *cl,Object *obj,struct MUIP_Setup *msg)
1066 {
1067   struct NLData *data = INST_DATA(cl,obj);
1068   LONG ent;
1069   Object *o;
1070
1071 /*D(bug("%lx|mNL_Setup() 1 \n",obj));*/
1072
1073   data->DRAW = 0;
1074   data->SETUP = FALSE;
1075
1076   if (data->NList_Disabled)
1077     data->NList_Disabled = 1;
1078
1079   if (data->NList_AdjustWidth)
1080     data->NList_AdjustWidth = -1;
1081
1082   GetImages(data);
1083
1084   data->SETUP = TRUE;
1085
1086 /*  data->MinImageHeight = 5;*/
1087   data->display_ptr = NULL;
1088   if (data->NList_Font && !data->InUseFont)
1089   {
1090     char *fontname = NULL;
1091     IPTR fonttmp = data->NList_Font;
1092
1093     if (data->NList_Font == MUIV_NList_Font)
1094     {
1095       fonttmp = MUIV_Font_List;
1096       DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_Font, &fontname);
1097     }
1098     else if (data->NList_Font == MUIV_NList_Font_Little)
1099     {
1100       fonttmp = MUIV_Font_Tiny;
1101       DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_Font_Little, &fontname);
1102     }
1103     else if (data->NList_Font == MUIV_NList_Font_Fixed)
1104     {
1105       fonttmp = MUIV_Font_Fixed;
1106       DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_Font_Fixed, &fontname);
1107     }
1108     if (fontname && *fontname)
1109     {
1110       struct TextAttr myta;
1111       LONG fsize = 8;
1112       int pp=0;
1113       char fname[32];
1114       while ((fontname[pp] != '/') && (fontname[pp] != '\0'))
1115       { if (pp < 42)
1116           fname[pp] = fontname[pp];
1117         pp++;
1118       }
1119       if (fontname[pp] != '\0')
1120         fsize = atol(&fontname[pp+1]);
1121       fname[pp++]='.'; fname[pp++]='f'; fname[pp++]='o'; fname[pp++]='n'; fname[pp++]='t'; fname[pp++]='\0';
1122       myta.ta_Name = fname;
1123       myta.ta_YSize = fsize;
1124       myta.ta_Style = 0;
1125       myta.ta_Flags = 0;
1126       data->InUseFont = OpenDiskFont(&myta);
1127     }
1128     if (data->InUseFont)
1129     {
1130       notdoset(obj,MUIA_Font,data->InUseFont);
1131       /*_font(obj) = data->InUseFont;*/
1132     }
1133     else
1134     {
1135       notdoset(obj,MUIA_Font,fonttmp);
1136     }
1137     NL_SetColsRem(data,-2);
1138   }
1139
1140   if (!(DoSuperMethodA(cl,obj,(Msg) msg)))
1141   {
1142     if (data->InUseFont)
1143     {
1144       notdoset(obj,MUIA_Font,0L);
1145       CloseFont(data->InUseFont);
1146       data->InUseFont = NULL;
1147     }
1148     return(FALSE);
1149   }
1150
1151   data->rp = NULL;
1152
1153   data->nodraw = 0;
1154
1155   if (data->NList_MinLineHeight <= 0)
1156     data->addvinc = -data->NList_MinLineHeight;
1157   else
1158   {
1159     LONG *ptrd;
1160     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_VertInc, &ptrd))
1161       data->addvinc = *ptrd;
1162     else
1163       data->addvinc = DEFAULT_VERT_INC;
1164   }
1165
1166   {
1167     LONG *ptrd;
1168     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_ColWidthDrag, &ptrd))
1169       data->NList_ColWidthDrag = *ptrd;
1170     else
1171       data->NList_ColWidthDrag = DEFAULT_CWD;
1172   }
1173
1174   {
1175     LONG *ptrd;
1176     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_PartialCol, &ptrd))
1177       data->NList_PartialCol = *ptrd;
1178     else
1179       data->NList_PartialCol = DEFAULT_PARTIALCOL;
1180   }
1181
1182   {
1183     LONG *ptrd;
1184     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_PartialChar, &ptrd))
1185       data->NList_PartialChar = *ptrd;
1186     else
1187       data->NList_PartialChar = DEFAULT_PARTIALCHAR;
1188   }
1189
1190   {
1191     LONG *ptrd;
1192     data->NList_List_Select = MUIV_NList_Select_List;
1193     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_List_Select, &ptrd))
1194     { if (!*ptrd)
1195         data->NList_List_Select = MUIV_NList_Select_None;
1196     }
1197   }
1198
1199   {
1200     LONG *ptrd;
1201     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_SerMouseFix, &ptrd))
1202       data->NList_SerMouseFix = *ptrd;
1203     else
1204       data->NList_SerMouseFix = DEFAULT_SERMOUSEFIX;
1205   }
1206
1207   {
1208     LONG *ptrd;
1209     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_DragLines, &ptrd))
1210       data->NList_DragLines = *ptrd + 1;
1211     else
1212       data->NList_DragLines = DEFAULT_DRAGLINES;
1213   }
1214
1215   {
1216     LONG *ptrd;
1217     if(DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_WheelStep, &ptrd))
1218       data->NList_WheelStep = *ptrd;
1219     else
1220       data->NList_WheelStep = DEFAULT_WHEELSTEP;
1221   }
1222
1223   {
1224     LONG *ptrd;
1225
1226     if(DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_WheelFast, &ptrd))
1227       data->NList_WheelFast = *ptrd;
1228     else
1229       data->NList_WheelFast = DEFAULT_WHEELFAST;
1230   }
1231
1232   {
1233     LONG *ptrd;
1234     data->NList_WheelMMB = DEFAULT_WHEELMMB;
1235
1236     if(DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_WheelMMB, &ptrd))
1237     {
1238       if(*ptrd != 0)
1239         data->NList_WheelMMB = TRUE;
1240       else
1241         data->NList_WheelMMB = FALSE;
1242     }
1243   }
1244
1245   {
1246     LONG *ptrd;
1247     data->NList_SelectPointer = DEFAULT_SELECTPOINTER;
1248     if(DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_SelectPointer, &ptrd))
1249     {
1250       if(*ptrd != 0)
1251         data->NList_SelectPointer = TRUE;
1252       else
1253         data->NList_SelectPointer = FALSE;
1254     }
1255   }
1256
1257   // determine our parent NListview object
1258   data->nlistviewobj = NULL;
1259   o = obj;
1260   while((o = (Object *)xget(o, MUIA_Parent)) != NULL)
1261   {
1262     // check if the parent object return ourself as its NList object
1263     // this one will be our parent NListview object
1264     if((Object *)xget(o, MUIA_NListview_NList) == obj)
1265     {
1266       data->nlistviewobj = o;
1267       D(DBF_STARTUP, "found parent NListview object %08lx", data->nlistviewobj);
1268       break;
1269     }
1270   }
1271
1272   // now we try to see if the parent listview object is
1273   // an NListview or a plain Listview.mui object so that we
1274   // can set the listviewobj pointer accordingly
1275   data->listviewobj = NULL;
1276   o = obj;
1277   while((o = (Object *)xget(o, MUIA_Parent)))
1278   {
1279     Object *tagobj;
1280
1281     if((tagobj = (Object *)xget(o, MUIA_Listview_List)) != NULL)
1282     {
1283       if(tagobj == obj && (Object *)xget(o, MUIA_NListview_NList) == NULL)
1284       {
1285         SIPTR tagval;
1286
1287         data->listviewobj = o;
1288         WANT_NOTIFY(NTF_LV_Select);
1289         WANT_NOTIFY(NTF_LV_Doubleclick);
1290         WANT_NOTIFY(NTF_L_Active);
1291         WANT_NOTIFY(NTF_Entries);
1292
1293         // check if we have a DragType attribute or not
1294         if(GetAttr(MUIA_Listview_DragType, data->listviewobj, (IPTR *)&tagval) != FALSE)
1295           data->NList_DragType = tagval;
1296
1297         // in case this is MUI 3.8 we can query more detailed information
1298         // by directly accessing the raw instance data of the Listview.mui
1299         // object. Puh, what a hack!
1300         if(MUIMasterBase->lib_Version <= 19 && data->pad2)
1301         {
1302           struct IClass *lcl,*lcl1,*lcl2,*lcl3,*lcl4;
1303           UBYTE *ldata = ((UBYTE *) o) + 178;
1304           lcl = lcl1 = lcl2 = lcl3 = lcl4 = OCLASS(o);
1305
1306           while (lcl->cl_Super)     /* when loop is finished : */
1307           { lcl4 = lcl3;            /*  Listview  */
1308             lcl3 = lcl2;            /*  Group     */
1309             lcl2 = lcl1;            /*  Area      */
1310             lcl1 = lcl;             /*  Notify    */
1311             lcl = lcl->cl_Super;    /*  rootclass */
1312           }
1313
1314           if (lcl4->cl_InstSize == 68)  /* data size of Listview.mui class in 3.8 */
1315           {
1316             data->multiselect = data->NList_MultiSelect = (LONG) ldata[43];
1317             data->NList_Input = (LONG) ldata[65];
1318             ldata[40] = ldata[41] = ldata[42] = ldata[43] = 0;
1319             ldata[64] = ldata[65] = 0;
1320           }
1321         }
1322       }
1323       break;
1324     }
1325   }
1326
1327   if (data->NList_DragType == MUIV_NList_DragType_Default)
1328   { LONG *ptrd;
1329     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_DragType, &ptrd))
1330       data->drag_type = *ptrd;
1331     else
1332       data->drag_type = MUIV_NList_DragType_Immediate;
1333   }
1334   else
1335     data->drag_type = data->NList_DragType;
1336
1337   if ((data->NList_DragSortable) && (data->drag_type == MUIV_NList_DragType_None))
1338   { LONG *ptrd;
1339     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_DragType, &ptrd))
1340       data->drag_type = *ptrd;
1341     else
1342       data->drag_type = MUIV_NList_DragType_Immediate;
1343   }
1344
1345 /*
1346   { LONG *ptrd;
1347     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_DragQualifier, &ptrd))
1348       data->drag_qualifier = *ptrd;
1349     else
1350       data->drag_qualifier = 0;
1351   }
1352 */
1353
1354   { LONG *ptrd;
1355
1356     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_Smooth, &ptrd))
1357       data->NList_Smooth = *ptrd;
1358     else
1359       data->NList_Smooth = DEFAULT_SMOOTHSCROLL;
1360
1361     if (data->VertPropObject)
1362     { if (data->NList_Smooth)
1363         set(data->VertPropObject,MUIA_Prop_DoSmooth, TRUE);
1364       else
1365         set(data->VertPropObject,MUIA_Prop_DoSmooth, FALSE);
1366     }
1367   }
1368
1369   {
1370     LONG *ptrd;
1371
1372     if (data->NList_Keys && (data->NList_Keys != default_keys))
1373     {
1374       FreeVecPooled(data->Pool, data->NList_Keys);
1375       data->NList_Keys = default_keys;
1376     }
1377
1378     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_Keys, &ptrd))
1379     {
1380       struct KeyBinding *keys = (struct KeyBinding *) ptrd;
1381       LONG nk = 0;
1382
1383       while (keys[nk].kb_KeyTag)
1384         nk++;
1385
1386       if((data->NList_Keys = AllocVecPooled(data->Pool, sizeof(struct KeyBinding) * (nk + 1))) != NULL)
1387       {
1388         while (nk >= 0)
1389         {
1390           data->NList_Keys[nk] = keys[nk];
1391           nk--;
1392         }
1393       }
1394       else
1395         data->NList_Keys = default_keys;
1396     }
1397     else
1398       data->NList_Keys = default_keys;
1399   }
1400
1401   LOAD_PEN(data->Pen_Title_init,   data->NList_TitlePen,   MUICFG_NList_Pen_Title,   DEFAULT_PEN_TITLE);
1402   LOAD_PEN(data->Pen_List_init,    data->NList_ListPen,    MUICFG_NList_Pen_List,    DEFAULT_PEN_LIST);
1403   LOAD_PEN(data->Pen_Select_init,  data->NList_SelectPen,  MUICFG_NList_Pen_Select,  DEFAULT_PEN_SELECT);
1404   LOAD_PEN(data->Pen_Cursor_init,  data->NList_CursorPen,  MUICFG_NList_Pen_Cursor,  DEFAULT_PEN_CURSOR);
1405   LOAD_PEN(data->Pen_UnselCur_init,data->NList_UnselCurPen,MUICFG_NList_Pen_UnselCur,DEFAULT_PEN_UNSELCUR);
1406   LOAD_PEN(data->Pen_Inactive_init,data->NList_InactivePen,MUICFG_NList_Pen_Inactive,DEFAULT_PEN_INACTIVE);
1407
1408   LOAD_BG(data->BG_Title_init,   data->NList_TitleBackGround,   MUICFG_NList_BG_Title,   DEFAULT_BG_TITLE);
1409   LOAD_BG(data->BG_List_init,    data->NList_ListBackGround,    MUICFG_NList_BG_List,    DEFAULT_BG_LIST);
1410   LOAD_BG(data->BG_Select_init,  data->NList_SelectBackground,  MUICFG_NList_BG_Select,  DEFAULT_BG_SELECT);
1411   LOAD_BG(data->BG_Cursor_init,  data->NList_CursorBackground,  MUICFG_NList_BG_Cursor,  DEFAULT_BG_CURSOR);
1412   LOAD_BG(data->BG_UnselCur_init,data->NList_UnselCurBackground,MUICFG_NList_BG_UnselCur,DEFAULT_BG_UNSELCUR);
1413   LOAD_BG(data->BG_Inactive_init,data->NList_InactiveBackground,MUICFG_NList_BG_Inactive,DEFAULT_BG_INACTIVE);
1414
1415   if (data->NList_ForcePen == MUIV_NList_ForcePen_Default)
1416   {
1417     LONG *ptrd, fpen = MUIV_NList_ForcePen_Off;
1418     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_ForcePen, &ptrd))
1419       fpen = *ptrd;
1420     data->ForcePen = (LONG) fpen;
1421   }
1422   else
1423     data->ForcePen = data->NList_ForcePen;
1424
1425   for(ent = 0;ent < data->NList_Entries;ent++)
1426     data->EntriesArray[ent]->PixLen = -1;
1427
1428   data->actbackground = -1;
1429
1430   if (data->NList_SourceArray)
1431     data->NList_SourceArray = 2;
1432
1433   data->multiselect = data->NList_MultiSelect;
1434   data->multisel_qualifier = 0;
1435   { LONG *multisel;
1436     LONG mult = MUIV_NList_MultiSelect_Shifted;
1437     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_MultiSelect, &multisel))
1438       mult = *multisel;
1439     if (data->NList_MultiSelect == MUIV_NList_MultiSelect_Default)
1440       data->multiselect = mult & 0x0007;
1441     if ((mult & MUIV_NList_MultiSelect_MMB_On) == MUIV_NList_MultiSelect_MMB_On)
1442       data->multisel_qualifier = IEQUALIFIER_MIDBUTTON;
1443   }
1444
1445   if (data->NList_ContextMenu == (LONG)MUIV_NList_ContextMenu_Default)
1446   {
1447     LONG *ptrd;
1448     data->ContextMenu = MUIV_NList_ContextMenu_Always;
1449     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_Menu, &ptrd))
1450     {
1451       switch (*ptrd)
1452       { case MUIV_NList_ContextMenu_TopOnly :
1453         case MUIV_NList_ContextMenu_Always :
1454         case MUIV_NList_ContextMenu_Never :
1455           data->ContextMenu = *ptrd;
1456           break;
1457       }
1458     }
1459   }
1460
1461   /* Use centered text lines? */
1462   {
1463     LONG *vert;
1464
1465     data->NList_VerticalCenteredText = DEFAULT_VCENTERED;
1466     if (DoMethod(obj, MUIM_GetConfigItem, MUICFG_NList_VCenteredLines, &vert))
1467       data->NList_VerticalCenteredText = *vert;
1468   }
1469
1470   if (data->ContextMenu != data->ContextMenuOn)
1471   {
1472     if (/*(((data->ContextMenu & 0x9d510030) == 0x9d510030) && (data->numcols <= 1)) ||*/ /* sba: Contextmenu problem: Disabled */
1473         (data->ContextMenu == (LONG)MUIV_NList_ContextMenu_Never))
1474       notdoset(obj,MUIA_ContextMenu,NULL);
1475     else
1476       notdoset(obj,MUIA_ContextMenu,data->ContextMenu);
1477   }
1478
1479   data->ScrollBarsPos = -2;
1480   data->ScrollBars = 0;
1481   data->ScrollBarsTime = -1;
1482
1483   NL_CreateImages(data);
1484
1485   data->drawsuper = NULL;
1486   data->format_chge = 1;
1487   data->do_draw_all = data->do_draw_title = data->do_draw = TRUE;
1488   data->do_parse = data->do_setcols = data->do_updatesb = data->do_wwrap = TRUE;
1489   /*data->force_wwrap = TRUE;*/
1490   data->badrport = FALSE;
1491   data->refreshing = FALSE;
1492
1493   data->first_change = LONG_MAX;
1494   data->last_change = LONG_MIN;
1495
1496   data->adjustbar = -1;
1497   data->adjustbar_old = -1;
1498
1499   Make_Active_Visible;
1500
1501   {
1502     Object *o = obj;
1503
1504     data->VirtGroup = NULL;
1505     data->VirtGroup2 = NULL;
1506
1507     while((o = (Object *)xget(o, MUIA_Parent)))
1508     {
1509       IPTR val;
1510
1511       // check if the class "knows" the Virtgroup_Left and
1512       // Virtgroup_Top attributes
1513       if(GetAttr(MUIA_Virtgroup_Left, o, &val) != FALSE &&
1514          GetAttr(MUIA_Virtgroup_Top, o, &val) != FALSE)
1515       {
1516         data->VirtGroup = o;
1517
1518         if (!data->VirtClass)
1519         {
1520           o = MUI_NewObject(MUIC_Virtgroup,Child, MUI_NewObject(MUIC_Rectangle, TAG_DONE), TAG_DONE);
1521
1522           if (o)
1523           {
1524             data->VirtClass = OCLASS(o);
1525             MUI_DisposeObject(o);
1526           }
1527         }
1528         break;
1529       }
1530     }
1531     data->VirtGroup2 = data->VirtGroup;
1532   }
1533
1534   // setup our custom selection pointer
1535   SetupCustomPointers(data);
1536
1537 /*  MUI_RequestIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_INTUITICKS|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW);*/
1538 /*  MUI_RequestIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_INTUITICKS);*/
1539
1540   data->MOUSE_MOVE = FALSE;
1541 /*  data->ehnode.ehn_Events = (IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_INTUITICKS|IDCMP_MOUSEMOVE);*/
1542   data->ehnode.ehn_Events = (IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_INTUITICKS|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW);
1543   data->ehnode.ehn_Priority = 1;
1544   data->ehnode.ehn_Flags = MUI_EHF_GUIMODE;
1545   data->ehnode.ehn_Object = obj;
1546   data->ehnode.ehn_Class  = cl;
1547
1548   // add IDCMP_EXTENDEDMOUSE for OS4 wheelmouse support
1549   #if defined(__amigaos4__)
1550   data->ehnode.ehn_Events |= IDCMP_EXTENDEDMOUSE;
1551   #endif
1552
1553   DoMethod(_win(obj),MUIM_Window_AddEventHandler, &data->ehnode);
1554
1555   DoMethod(_app(obj),MUIM_Application_AddInputHandler,&data->ihnode);
1556
1557 /*  GetNImage_Sizes(data);*/
1558
1559   data->pad2 = FALSE;
1560
1561 /*D(bug("%lx|mNL_Setup() 2 \n",obj));*/
1562
1563   return(TRUE);
1564 }
1565
1566 IPTR mNL_Cleanup(struct IClass *cl,Object *obj,struct MUIP_Cleanup *msg)
1567 {
1568   register struct NLData *data = INST_DATA(cl,obj);
1569   IPTR retval;
1570
1571 /*D(bug("%lx|mNL_Cleanup() 1 \n",obj));*/
1572
1573   data = INST_DATA(cl,obj);
1574
1575   data->nodraw = 1;
1576   data->DRAW = 0;
1577
1578   // cleanup our custom mouse pointers
1579   CleanupCustomPointers(data);
1580
1581   DoMethod(_app(obj),MUIM_Application_RemInputHandler,&data->ihnode);
1582
1583   DoMethod(_win(obj),MUIM_Window_RemEventHandler, &data->ehnode);
1584
1585 /*  MUI_RejectIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_INTUITICKS|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW);*/
1586 /*  MUI_RejectIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_INTUITICKS);*/
1587
1588   data->NList_Quiet++;
1589   data->VirtGroup = NULL;
1590
1591   // forget that this object has received a MUIM_Setup
1592   // this must be done before calling NL_DeleteImages(), because that function
1593   // will try to relayout the group data->NL_Group, which is not a very wise
1594   // thing to do while we a cleaning up ourselves.
1595   data->SETUP = FALSE;
1596
1597   NL_DeleteImages(data);
1598
1599   if (data->NList_Keys && (data->NList_Keys != default_keys))
1600   {
1601     FreeVecPooled(data->Pool, data->NList_Keys);
1602     data->NList_Keys = default_keys;
1603   }
1604
1605   release_pen(obj, &data->NList_TitlePen);
1606   release_pen(obj, &data->NList_ListPen);
1607   release_pen(obj, &data->NList_SelectPen);
1608   release_pen(obj, &data->NList_CursorPen);
1609   release_pen(obj, &data->NList_UnselCurPen);
1610
1611   retval = DoSuperMethodA(cl,obj,(Msg) msg);
1612
1613   if (data->InUseFont)
1614   {
1615     notdoset(obj,MUIA_Font,0L);
1616     CloseFont(data->InUseFont);
1617     data->InUseFont = NULL;
1618   }
1619
1620   data->voff = 1;
1621
1622   data->rp = NULL;
1623   data->badrport = FALSE;
1624   data->UpdateScrollersRedrawn = FALSE;
1625
1626   data->NList_Quiet--;
1627
1628 /*D(bug("%lx|mNL_Cleanup() 2 \n",obj));*/
1629
1630   return (retval);
1631 }