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