revert between 56095 -> 55830 in arch
[AROS.git] / workbench / classes / zune / nlist / nlist_mcc / NList_func2.c
blob8293e816714aadc60522bb8d6648b2c60783de79
1 /***************************************************************************
3 NList.mcc - New List MUI Custom Class
4 Registered MUI class, Serial Number: 1d51 0x9d510030 to 0x9d5100A0
5 0x9d5100C0 to 0x9d5100FF
7 Copyright (C) 1996-2001 by Gilles Masson
8 Copyright (C) 2001-2014 NList Open Source Team
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.
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.
20 NList classes Support Site: http://www.sf.net/projects/nlist-classes
22 $Id$
24 ***************************************************************************/
26 #include <stdlib.h>
28 #include <clib/alib_protos.h>
29 #include <proto/exec.h>
30 #include <proto/intuition.h>
32 #include "private.h"
34 #include "NList_func.h"
36 static ULONG NL_List_Move(struct NLData *data,LONG from,LONG to);
38 LONG NL_GetSelects(struct NLData *data, LONG ent)
40 LONG selects = 0L;
42 if (data->multiselect && data->EntriesArray[ent]->Wrap && !(data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine))
44 LONG bitpos = 1L,ent1 = ent + data->EntriesArray[ent]->dnum;
45 BOOL sel = FALSE;
47 while ((ent < data->NList_Entries) && (ent < ent1))
49 if (data->EntriesArray[ent]->Select != TE_Select_None)
51 selects |= bitpos;
52 sel = TRUE;
54 else
55 sel = FALSE;
57 bitpos = bitpos << 1;
58 ent++;
61 while (sel && (bitpos & 0x0000FFFF))
63 selects |= bitpos;
64 bitpos = bitpos << 1;
67 if (sel)
68 selects |= 0xFFFF8000;
69 else
70 selects &= 0x00007FFF;
73 return (selects);
77 //$$$ARRAY+
78 BOOL NL_InsertTmpLine(struct NLData *data,LONG pos)
80 LONG newpos, ent, ent1, maxent;
82 newpos = pos;
83 maxent = data->NList_Entries + 1;
85 if (maxent >= data->LastEntry)
87 struct TypeEntry **newentries = NULL;
88 LONG le = ((maxent << 1) + 0x00FFL) & ~0x000FL;
90 if((newentries = AllocVecPooled(data->Pool, sizeof(struct TypeEntry *) * (le + 1))) != NULL)
92 struct TypeEntry *newentry = NULL;
94 if ((data->NList_First >= pos) && (data->NList_First < data->NList_Entries-1))
95 data->NList_First++;
97 data->LastEntry = le;
98 ent = 0;
99 ent1 = 0;
101 { LONG de = newpos - ent1;
102 if ((maxent - ent) < de)
103 de = maxent - ent;
104 NL_Move(&newentries[ent],&data->EntriesArray[ent1],de,ent);
105 ent += de;
106 ent1 += de;
109 if((newentry = AllocTypeEntry()) != NULL)
111 newentries[ent] = newentry;
113 newentry->Entry = 0;
114 newentry->Select = 0;
115 newentry->Wrap = TE_Wrap_TmpLine;
116 newentry->PixLen = -1;
117 newentry->pos = 0;
118 newentry->len = -2;
119 newentry->style = 0;
120 newentry->dnum = 1;
121 newentry->entpos = ent;
122 ent++;
124 { LONG de = data->NList_Entries - ent1;
125 if ((maxent - ent) < de)
126 de = maxent - ent;
127 NL_Move(&newentries[ent],&data->EntriesArray[ent1],de,ent);
128 ent += de;
131 newentries[ent] = NULL;
132 if (data->EntriesArray)
133 FreeVecPooled(data->Pool, data->EntriesArray);
134 data->EntriesArray = newentries;
135 data->NList_Entries = ent;
136 if ((newpos >= data->NList_AffFirst) || data->NList_EntryValueDependent)
138 NL_SegChanged(data,newpos,data->NList_Entries);
139 data->do_draw = TRUE;
141 else
143 data->NList_AffFirst += 1;
144 data->do_draw = TRUE;
146 if ((data->NList_Active >= newpos) && (data->NList_Active < data->NList_Entries))
148 set_Active(data->NList_Active + 1);
149 NL_Changed(data,data->NList_Active);
151 UnSelectCharSel(data,FALSE);
152 return (TRUE);
155 FreeVecPooled(data->Pool, newentries);
156 return (FALSE);
159 else if (data->EntriesArray)
161 struct TypeEntry *newentry = NULL;
163 if ((data->NList_First >= pos) && (data->NList_First < data->NList_Entries-1))
164 data->NList_First++;
166 ent = data->NList_Entries;
167 NL_MoveD(&data->EntriesArray[ent+1],&data->EntriesArray[ent],ent-newpos,ent+1);
168 ent = newpos;
170 if((newentry = AllocTypeEntry()) != NULL)
172 data->EntriesArray[ent] = newentry;
174 newentry->Entry = 0;
175 newentry->Select = 0;
176 newentry->Wrap = TE_Wrap_TmpLine;
177 newentry->PixLen = -1;
178 newentry->pos = 0;
179 newentry->len = -2;
180 newentry->style = 0;
181 newentry->dnum = 1;
182 newentry->entpos = ent;
183 data->NList_Entries += 1;
185 if ((newpos >= data->NList_AffFirst) || data->NList_EntryValueDependent)
187 NL_SegChanged(data,newpos,data->NList_Entries);
188 data->do_draw = TRUE;
190 else
192 data->NList_AffFirst += 1;
193 data->do_draw = TRUE;
196 if ((data->NList_Active >= newpos) && (data->NList_Active < data->NList_Entries))
198 set_Active(data->NList_Active + 1);
199 NL_Changed(data,data->NList_Active);
202 UnSelectCharSel(data,FALSE);
204 return (TRUE);
207 return (FALSE);
211 //$$$ARRAY+
212 void NL_DeleteTmpLine(struct NLData *data,LONG pos)
214 LONG ent = pos;
216 if((ent >= 0) && (ent < data->NList_Entries) && data->EntriesArray && (data->LastEntry > 0) &&
217 (data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine))
219 if((data->NList_First >= pos) && (data->NList_First > 0))
220 data->NList_First--;
221 data->NList_Entries -= 1;
223 if((ent >= data->NList_AffFirst) || data->NList_EntryValueDependent)
225 NL_SegChanged(data,ent,data->NList_Entries + 1);
226 data->do_draw = TRUE;
228 else
230 data->NList_AffFirst--;
231 data->do_draw = TRUE;
234 if(data->NList_Active == ent)
236 DO_NOTIFY(NTF_Active | NTF_L_Active);
237 if(data->NList_MultiSelect == MUIV_NList_MultiSelect_None)
239 if(ent+1 <= data->NList_Entries)
241 if(data->EntriesArray[ent+1]->Select == TE_Select_None)
242 SELECT(ent+1,TE_Select_Line);
243 data->lastselected = ent;
244 data->lastactived = ent;
246 else if(ent-1 >= 0)
248 SELECT(ent-1,TE_Select_Line);
249 data->lastselected = ent-1;
250 data->lastactived = ent-1;
254 else if(data->NList_Active > ent)
256 set_Active(data->NList_Active - 1);
258 if(data->NList_Active >= data->NList_Entries)
260 set_Active(data->NList_Entries - 1);
263 FreeTypeEntry(data->EntriesArray[ent]);
264 NL_Move(&data->EntriesArray[ent],&data->EntriesArray[ent+1],data->NList_Entries-ent,ent);
265 ent = data->NList_Entries;
267 data->EntriesArray[ent] = NULL;
269 UnSelectCharSel(data,FALSE);
274 struct sort_entry
275 { LONG ent;
276 struct NLData *data;
280 static int NL_SortCompar(struct NLData *data,LONG ent1,LONG ent2)
282 LONG result = 0;
283 LONG e1 = ent1;
284 LONG e2 = ent2;
286 if (data->EntriesArray[ent1]->Wrap & TE_Wrap_TmpLine)
287 ent1 -= data->EntriesArray[ent1]->dnum;
288 if (data->EntriesArray[ent2]->Wrap & TE_Wrap_TmpLine)
289 ent2 -= data->EntriesArray[ent2]->dnum;
291 if(ent1 != ent2)
293 result = (LONG)DoMethod(data->this, MUIM_NList_Compare, data->EntriesArray[ent1]->Entry, data->EntriesArray[ent2]->Entry, data->NList_SortType, data->NList_SortType2);
294 if(result == 0)
295 result = ent1 - ent2;
297 else
298 result = e1 - e2;
300 return (int)result;
304 /*int sort_compar(const void *e1, const void *e2)*/
305 static int sort_compar(struct sort_entry *e1, struct sort_entry *e2)
307 return NL_SortCompar(e1->data,e1->ent,e2->ent);
311 //$$$ARRAY+
312 //fent = first entry
313 //lent = last entry
314 static ULONG NL_List_SortPart(struct NLData *data,LONG fent,LONG lent)
316 LONG ent, ent1, numfollow, numexch, has_changed;
317 struct sort_entry *entry = NULL;
318 struct TypeEntry *newentry;
320 ENTER();
322 data->display_ptr = NULL;
323 has_changed = FALSE;
325 lent++;
327 if((entry = (struct sort_entry *)AllocVecPooled(data->Pool, sizeof(struct sort_entry) * (lent-fent))) != NULL)
329 for (ent = fent; ent < lent; ent++)
331 entry[ent-fent].ent = ent;
332 entry[ent-fent].data = data;
335 //D(DBF_ALWAYS, "qsort started.");
336 qsort(entry, (size_t) (lent-fent), (size_t) sizeof(struct sort_entry), (int (*)()) &sort_compar);
337 //D(DBF_ALWAYS, "qsort ended.");
339 ent1 = numfollow = numexch = 0;
341 for (ent = fent; ent < lent; ent++)
343 ent1 = entry[ent-fent].ent;
344 while (ent1 < ent) /* find a ent1 not already done */
346 ent1 = entry[ent1-fent].ent;
347 numfollow++;
348 if(numfollow > lent) break;
351 if (ent1 > ent) /* exchange them */
353 /* DO EXCHANGE */
354 newentry = data->EntriesArray[ent];
355 data->EntriesArray[ent] = data->EntriesArray[ent1];
356 data->EntriesArray[ent1] = newentry;
357 data->EntriesArray[ent]->entpos = ent;
358 data->EntriesArray[ent1]->entpos = ent1;
360 NL_Changed(data,ent);
361 NL_Changed(data,ent1);
363 if (data->NList_Active == ent)
364 set_Active(ent1);
365 else if (data->NList_Active == ent1)
366 set_Active(ent);
368 if (data->NList_LastInserted == ent)
370 /* sba: was data->NList_LastInserted--; */
371 data->NList_LastInserted = ent1;
372 DO_NOTIFY(NTF_Insert);
373 } else
374 if (data->NList_LastInserted == ent1)
376 /* sba: was data->NList_LastInserted++; */
377 data->NList_LastInserted = ent;
378 DO_NOTIFY(NTF_Insert);
380 has_changed = TRUE;
381 data->moves = FALSE;
383 entry[ent-fent].ent = ent1; /* redirect old current where it is now */
384 numexch++;
388 //D(DBF_ALWAYS, "qsort stat: %ld exchanges, %ld follows.",numexch,numfollow);
390 FreeVecPooled(data->Pool, entry);
393 RETURN(has_changed);
394 return ((ULONG)has_changed);
398 ULONG NL_List_Sort(struct NLData *data)
400 LONG has_changed;
402 has_changed = NL_List_SortPart(data,0,data->NList_Entries-1);
404 if (has_changed || data->do_wwrap)
406 data->sorted = TRUE;
407 Make_Active_Visible;
408 UnSelectCharSel(data,FALSE);
409 if (has_changed)
410 { DO_NOTIFY(NTF_Select | NTF_LV_Select);
412 if (data->do_wwrap)
413 NL_DoWrapAll(data,TRUE,FALSE);
414 data->do_updatesb = TRUE;
415 REDRAW;
418 /* do_notifies(NTF_AllChanges|NTF_MinMax);*/
419 return ((ULONG)has_changed);
423 //$$$ARRAY+
424 static ULONG NL_List_SortMore(struct NLData *data,LONG newpos)
426 LONG has_changed=0,fent,ment,lent;
427 int comp;
428 struct TypeEntry *newentry;
430 if (newpos < data->NList_Entries-1)
431 has_changed = NL_List_SortPart(data,newpos,data->NList_Entries-1);
432 fent = 0;
434 while (newpos < data->NList_Entries)
436 lent = newpos;
437 while (fent < lent)
438 { ment = (fent+lent)/2;
439 comp = NL_SortCompar(data,newpos,ment);
440 if (comp < 0)
441 lent = ment;
442 else
443 fent = ment+1;
445 if (lent < newpos)
446 { /* move newpos to lent */
447 newentry = data->EntriesArray[newpos];
449 NL_MoveD(&data->EntriesArray[newpos+1],&data->EntriesArray[newpos],newpos-lent,newpos+1);
451 data->EntriesArray[lent] = newentry;
452 data->EntriesArray[lent]->entpos = lent;
455 if ((data->NList_Active >= lent) && (data->NList_Active < newpos))
457 set_Active(data->NList_Active + 1);
459 else if (data->NList_Active == newpos)
461 set_Active(lent);
463 NL_SegChanged(data,lent,newpos);
464 data->NList_LastInserted = lent;
465 DO_NOTIFY(NTF_Insert);
467 newpos++;
470 if (has_changed || data->do_wwrap)
472 data->sorted = TRUE;
473 Make_Active_Visible;
474 UnSelectCharSel(data,FALSE);
475 if (has_changed)
476 { DO_NOTIFY(NTF_Select | NTF_LV_Select);
478 if (data->do_wwrap)
479 NL_DoWrapAll(data,TRUE,FALSE);
480 data->do_updatesb = TRUE;
481 REDRAW;
483 return ((ULONG)has_changed);
487 //$$$ARRAY+
488 ULONG NL_List_Insert(struct NLData *data,APTR *entries,LONG count,LONG pos,LONG wrapcol,LONG align,ULONG flags)
490 BOOL success = FALSE;
491 LONG newpos,count2;
492 BOOL is_string = FALSE;
493 char *string;
495 STARTCLOCK(DBF_ALWAYS);
496 wrapcol &= TE_Wrap_TmpMask;
497 if (wrapcol)
499 LONG wrapcol2 = 1;
501 while (wrapcol2 < TE_Wrap_TmpLine)
503 if (wrapcol & wrapcol2)
504 break;
505 wrapcol2 = wrapcol2 << 1;
507 wrapcol = wrapcol2 & TE_Wrap_TmpMask;
510 if (entries)
512 LONG ent, ent1, ent2, ent3, maxent, nlentries;
514 //D(bug( "Inserting %ld entries at position %ld\n", count, pos ));
516 data->display_ptr = NULL;
517 if (count == -1)
519 count = 0;
520 while (entries[count] != NULL)
521 count++;
523 else if (count == -2)
525 is_string = TRUE;
526 count = 1;
527 string = (char *) entries;
528 while (string[0] != '\0')
530 if ((string[0] == '\n') || (string[0] == '\r')) count++;
531 if ((string[0] == '\r') && (string[1] == '\n')) string++;
532 string++;
534 string = (char *) entries;
536 else if (count > 0)
538 newpos = 0;
539 while (newpos < count)
541 if (entries[newpos] == NULL) count--;
542 newpos++;
546 if (count > 0)
548 maxent = count + data->NList_Entries;
549 count2 = 0;
551 switch (pos)
553 case MUIV_NList_Insert_Top:
554 newpos = 0;
555 break;
556 case MUIV_NList_Insert_Bottom:
557 newpos = data->NList_Entries;
558 break;
559 case MUIV_NList_Insert_Active:
560 if ((data->NList_Active >= 0) && (data->NList_Active < data->NList_Entries))
561 newpos = data->NList_Active;
562 else
563 newpos = data->NList_Entries;
564 break;
565 case MUIV_NList_Insert_Sorted:
566 default:
567 if ((pos >= 0) && (pos < data->NList_Entries))
568 newpos = pos;
569 else
570 newpos = data->NList_Entries;
571 break;
574 if ((newpos >= 0) && (newpos < data->NList_Entries) && (data->EntriesArray[newpos]->Wrap & TE_Wrap_TmpLine))
575 newpos -= data->EntriesArray[newpos]->dnum;
576 data->moves = FALSE;
578 if (maxent >= data->LastEntry)
580 struct TypeEntry **newentries = NULL,**oldentries = data->EntriesArray;
581 LONG le = ((maxent << 1) + 0x00FFL) & ~0x000FL;
583 if((newentries = AllocVecPooled(data->Pool, sizeof(struct TypeEntry *) * (le + 1))) != NULL)
585 struct TypeEntry *newentry = NULL;
587 //D(bug( "Allocating new entry array at 0x%08lx with %ld entries.\n", newentries, le+1 ));
589 data->EntriesArray = newentries;
590 nlentries = data->NList_Entries;
591 data->NList_Entries += count;
592 DO_NOTIFY(NTF_Entries|NTF_MinMax);
593 data->LastEntry = le;
594 ent = 0;
595 ent1 = 0;
596 ent3 = ent2 = 0;
598 if (is_string)
599 entries = (APTR *)(void*)&string;
600 else
602 while (!entries[ent2])
603 ent2++;
607 LONG de = newpos - ent1;
609 if ((maxent - ent) < de)
610 de = maxent - ent;
612 if(de != 0)
614 D(DBF_ALWAYS, "Moving %ld old entries to new array (from %ld to %ld)", de, ent1, ent);
615 NL_Move(&data->EntriesArray[ent], &oldentries[ent1], de, ent);
617 ent += de;
618 ent1 += de;
622 while ((ent < maxent) && (ent3 < count))
624 if((newentry = AllocTypeEntry()) != NULL)
626 data->EntriesArray[ent] = newentry;
628 newentry->Entry = (APTR) DoMethod(data->this, MUIM_NList_Construct, entries[ent2], data->Pool);
630 if (newentry->Entry)
632 newentry->Select = TE_Select_None;
633 newentry->Wrap = wrapcol;
634 newentry->PixLen = -1;
635 newentry->pos = 0;
636 newentry->len = -1;
637 newentry->style = align;
638 newentry->dnum = 1;
639 newentry->entpos = ent;
640 data->NList_LastInserted = ent;
641 if(isFlagClear(flags, MUIV_NList_Insert_Flag_Raw))
642 NL_SetColsAdd(data,ent,FALSE);
643 ent++;
645 else
646 count2++;
648 if (is_string)
650 while ((string[0] != '\0') && (string[0] != '\n') && (string[0] != '\r'))
651 string++;
652 if ((string[0] == '\r') && (string[1] == '\n'))
653 { string++; string++; }
654 else if ((string[0] == '\n') ||(string[0] == '\r'))
655 string++;
656 entries = (APTR *)(void*)&string;
658 else
660 ent2++;
661 while (!entries[ent2])
662 ent2++;
664 ent3++;
669 LONG de = nlentries - ent1;
671 if ((maxent - ent) < de)
672 de = maxent - ent;
674 if(de != 0)
676 D(DBF_ALWAYS, "Moving %ld old entries to new array (from %ld to %ld)", de, ent1, ent);
677 NL_Move(&data->EntriesArray[ent], &oldentries[ent1], de, ent);
679 ent += de;
683 DO_NOTIFY(NTF_Insert);
685 //D(bug( "Deleting pointer in entry %ld.\n", ent ));
687 data->EntriesArray[ent] = NULL;
688 if(oldentries != NULL)
689 FreeVecPooled(data->Pool, oldentries);
691 if(data->NList_Entries != ent)
693 DO_NOTIFY(NTF_Entries|NTF_MinMax);
696 data->NList_Entries = ent;
697 count -= count2;
699 /* TODO: This stuff here can be merged with the stuff below */
700 GetNImage_End(data);
701 GetNImage_Sizes(data);
702 if (count > 0)
704 if ((newpos >= data->NList_AffFirst) || data->NList_EntryValueDependent)
705 NL_SegChanged(data,newpos,data->NList_Entries);
706 else
707 data->NList_AffFirst += count;
709 if ((data->NList_Active >= newpos) && (data->NList_Active < data->NList_Entries))
711 set_Active(data->NList_Active + count);
712 NL_Changed(data,data->NList_Active);
715 UnSelectCharSel(data,FALSE);
716 if (wrapcol)
717 data->do_wwrap = TRUE;
718 if (pos == MUIV_NList_Insert_Sorted)
720 BOOL needs_redraw;
722 NL_SetCols(data);
724 /* NL_List_SortXXX returns wheather sorting has changed anything
725 * and redraws the entries. If sorting hasn't changed anything
726 * we still have to redraw the list, because there are new entries
727 * in the list */
728 if (data->sorted)
729 needs_redraw = !NL_List_SortMore(data,newpos);
730 else
731 needs_redraw = !NL_List_Sort(data);
733 if (needs_redraw)
735 REDRAW;
738 else
740 Make_Active_Visible;
741 data->do_updatesb = TRUE;
742 data->sorted = FALSE;
743 REDRAW;
745 /* do_notifies(NTF_AllChanges|NTF_MinMax);*/
746 success = TRUE;
750 else if (data->EntriesArray)
752 struct TypeEntry *newentry = NULL;
754 ent = data->NList_Entries;
755 nlentries = data->NList_Entries;
756 data->NList_Entries += count;
757 DO_NOTIFY(NTF_Entries|NTF_MinMax);
759 D(DBF_ALWAYS, "Moving %ld entries (from %ld to %ld)", ent-newpos, ent, ent+count);
760 NL_MoveD(&data->EntriesArray[ent+count], &data->EntriesArray[ent], ent-newpos, ent+count);
762 ent = newpos;
763 ent3 = ent2 = 0;
765 if (is_string)
766 entries = (APTR *)(void*)&string;
767 else
769 while (!entries[ent2])
770 ent2++;
773 while ((ent < data->LastEntry) && (ent3 < count))
775 if((newentry = AllocTypeEntry()) != NULL)
777 data->EntriesArray[ent] = newentry;
779 newentry->Entry = (APTR) DoMethod(data->this, MUIM_NList_Construct, entries[ent2], data->Pool);
781 if (newentry->Entry)
783 newentry->Select = TE_Select_None;
784 newentry->Wrap = wrapcol;
785 newentry->PixLen = -1;
786 newentry->pos = 0;
787 newentry->len = -1;
788 newentry->style = align;
789 newentry->dnum = 1;
790 newentry->entpos = ent;
791 data->NList_LastInserted = ent;
792 if(isFlagClear(flags, MUIV_NList_Insert_Flag_Raw))
793 NL_SetColsAdd(data,ent,FALSE);
794 ent++;
796 else
797 count2++;
799 if (is_string)
801 while ((string[0] != '\0') && (string[0] != '\n') && (string[0] != '\r'))
802 string++;
803 if ((string[0] == '\r') && (string[1] == '\n'))
804 { string++; string++; }
805 else if ((string[0] == '\n') ||(string[0] == '\r'))
806 string++;
807 entries = (APTR *)(void*)&string;
809 else
811 ent2++;
812 while (!entries[ent2])
813 ent2++;
815 ent3++;
819 data->NList_Entries -= count2;
820 count -= count2;
821 if (count2)
823 D(DBF_ALWAYS, "Moving %ld entries (from %ld to %ld)", data->NList_Entries-ent, ent+count2, ent);
824 NL_Move(&data->EntriesArray[ent], &data->EntriesArray[ent+count2], data->NList_Entries-ent, ent);
827 DO_NOTIFY(NTF_Insert);
829 GetNImage_End(data);
830 GetNImage_Sizes(data);
832 if (count > 0)
834 if ((newpos >= data->NList_AffFirst) || data->NList_EntryValueDependent)
835 NL_SegChanged(data,newpos,data->NList_Entries);
836 else
837 data->NList_AffFirst += count;
839 if ((data->NList_Active >= newpos) && (data->NList_Active < data->NList_Entries))
841 set_Active(data->NList_Active + count);
842 NL_Changed(data,data->NList_Active);
844 UnSelectCharSel(data,FALSE);
845 if (wrapcol)
846 data->do_wwrap = TRUE;
848 if (pos == MUIV_NList_Insert_Sorted)
850 int needs_redraw;
852 NL_SetCols(data);
854 /* NL_List_SortXXX returns wheather sorting has changed anything
855 * and redraws the entries. If sorting hasn't changed anything
856 * we still have to redraw the list, because there are new entries
857 * in the list */
858 if (data->sorted)
859 needs_redraw = !NL_List_SortMore(data,newpos);
860 else
861 needs_redraw = !NL_List_Sort(data);
863 if (needs_redraw)
865 REDRAW;
867 } else
869 Make_Active_Visible;
870 data->do_updatesb = TRUE;
871 data->sorted = FALSE;
872 REDRAW;
874 /* do_notifies(NTF_AllChanges|NTF_MinMax);*/
875 success = TRUE;
880 STOPCLOCK(DBF_ALWAYS, "insert");
882 return success;
886 ULONG NL_List_Replace(struct NLData *data,APTR entry,LONG pos,LONG wrapcol,LONG align)
888 ULONG result = FALSE;
889 LONG ent;
891 ENTER();
893 wrapcol &= TE_Wrap_TmpMask;
894 if (wrapcol != 0)
896 LONG wrapcol2 = 1;
898 while(wrapcol2 < TE_Wrap_TmpLine)
900 if(wrapcol & wrapcol2)
901 break;
903 wrapcol2 = wrapcol2 << 1;
905 wrapcol = wrapcol2 & TE_Wrap_TmpMask;
908 switch (pos)
910 case MUIV_NList_Insert_Top:
912 ent = 0;
914 break;
916 case MUIV_NList_Insert_Bottom:
918 ent = data->NList_Entries-1;
920 break;
922 case MUIV_NList_Insert_Active:
924 // make sure there is an active element
925 if(data->NList_Active >= 0 && data->NList_Active < data->NList_Entries)
927 ent = data->NList_Active;
929 else
931 // let the replacement fail if there is no active element
932 ent = -1;
935 break;
937 case MUIV_NList_Insert_Sorted:
938 default:
940 // make sure the position is valid
941 if(pos >= 0 && pos < data->NList_Entries)
943 ent = pos;
945 else
947 // let the replacement fail if the position is invalid
948 ent = -1;
951 break;
954 SHOWVALUE(DBF_ALWAYS, ent);
956 if(ent >= 0 && ent < data->NList_Entries && (data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine))
957 ent -= data->EntriesArray[ent]->dnum;
959 if(entry != NULL && ent >= 0 && ent < data->NList_Entries)
961 // duplicate the given entry
962 entry = (APTR)DoMethod(data->this, MUIM_NList_Construct, entry, data->Pool);
964 if(entry != NULL)
966 data->display_ptr = NULL;
967 NL_SetColsRem(data,ent);
969 if(data->EntriesArray[ent]->Wrap && !(data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine) && data->EntriesArray[ent]->len >= 0)
970 data->EntriesArray[ent]->pos = (WORD) NL_GetSelects(data,ent);
971 else
972 data->EntriesArray[ent]->pos = 0;
974 /* I don't understand this line but... ;) */
975 if(!(data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine))
976 DoMethod(data->this, MUIM_NList_Destruct, data->EntriesArray[ent]->Entry, data->Pool);
978 data->EntriesArray[ent]->Entry = entry;
979 data->EntriesArray[ent]->Wrap = wrapcol;
980 data->EntriesArray[ent]->PixLen = -1;
981 data->EntriesArray[ent]->len = -1;
982 data->EntriesArray[ent]->style = align;
983 data->EntriesArray[ent]->dnum = 1;
984 data->EntriesArray[ent]->entpos = ent;
985 data->NList_LastInserted = ent;
986 DO_NOTIFY(NTF_Insert);
987 NL_SetColsAdd(data,ent,TRUE);
988 NL_Changed(data,ent);
989 UnSelectCharSel(data,FALSE);
991 if(wrapcol != 0)
992 data->do_wwrap = TRUE;
994 data->do_updatesb = TRUE;
995 data->sorted = FALSE;
997 REDRAW;
999 result = TRUE;
1001 else
1002 result = NL_List_Remove(data,ent);
1005 RETURN(result);
1006 return result;
1010 //$$$ARRAY+
1011 ULONG NL_List_Clear(struct NLData *data)
1013 LONG ent = data->NList_Entries - 1;
1015 STARTCLOCK(DBF_ALWAYS);
1016 DONE_NOTIFY(NTF_Select | NTF_LV_Select);
1017 data->display_ptr = NULL;
1018 NL_SetColsRem(data,-2);
1020 STARTCLOCK(DBF_ALWAYS);
1021 if(data->EntriesArray)
1023 struct TypeEntry **entries = data->EntriesArray;
1024 BOOL notifySelect = FALSE;
1026 while(ent >= 0)
1028 struct TypeEntry *entry = *entries;
1030 if(entry->Select != TE_Select_None)
1031 notifySelect = TRUE;
1033 if(isFlagClear(entry->Wrap, TE_Wrap_TmpLine))
1034 DoMethod(data->this, MUIM_NList_Destruct, entry->Entry, data->Pool);
1036 FreeTypeEntry(entry);
1037 ent--;
1038 entries++;
1041 FreeVecPooled(data->Pool, data->EntriesArray);
1043 if(notifySelect == TRUE)
1045 DO_NOTIFY(NTF_Select | NTF_LV_Select);
1048 STOPCLOCK(DBF_ALWAYS, "destruct");
1050 data->EntriesArray = NULL;
1051 data->LastEntry = 0;
1053 if(data->NList_Entries != 0)
1055 DO_NOTIFY(NTF_Entries|NTF_MinMax);
1056 data->NList_Entries = 0;
1059 if(data->NList_First != 0)
1061 DO_NOTIFY(NTF_First);
1062 data->NList_First = 0;
1065 set_Active(MUIV_NList_Active_Off);
1066 data->NList_Horiz_First = 0;
1067 // Reset the amount of visible lines only if the list is not "quiet".
1068 // It will be recalculated as soon as the "quiet" state ends.
1069 // This makes it possible to perform a centered jump to a certain
1070 // entry while the "quiet" state is active.
1071 if(data->NList_Quiet == 0)
1072 data->NList_Visible = 0;
1073 data->NList_LastInserted = -1;
1074 data->Title_PixLen = -1;
1075 data->NList_DropMark = 0;
1076 data->sorted = FALSE;
1078 data->lastselected = MUIV_NList_Active_Off;
1079 data->lastactived = MUIV_NList_Active_Off;
1080 UnSelectCharSel(data,FALSE);
1081 NL_SetColsAdd(data,-1,TRUE);
1082 data->do_parse = data->do_setcols = data->do_updatesb = data->do_wwrap = TRUE;
1083 data->moves = FALSE;
1084 REDRAW_ALL;
1085 /* do_notifies(NTF_AllChanges|NTF_MinMax);*/
1086 STOPCLOCK(DBF_ALWAYS, "clear");
1088 return (TRUE);
1092 //$$$ARRAY+
1093 ULONG NL_List_Remove(struct NLData *data,LONG pos)
1095 LONG ent,ent2,skip,nlentries;
1096 if (pos == MUIV_NList_Remove_First)
1097 ent = 0;
1098 else if (pos == MUIV_NList_Remove_Last)
1099 ent = data->NList_Entries - 1;
1100 else if (pos == MUIV_NList_Remove_Active)
1101 ent = data->NList_Active;
1102 else if (pos == MUIV_NList_Remove_Selected)
1103 { ent2 = 0;
1104 while ((ent2 < data->NList_Entries) && (data->EntriesArray[ent2]->Select == TE_Select_None))
1105 ent2++;
1106 ent = ent2;
1108 else
1109 ent = pos;
1110 if ((ent >= 0) && (ent < data->NList_Entries) && (data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine))
1111 ent -= data->EntriesArray[ent]->dnum;
1112 if ((ent >= 0) && (ent < data->NList_Entries) && data->EntriesArray && (data->LastEntry > 0))
1114 BYTE select;
1115 data->display_ptr = NULL;
1116 data->moves = FALSE;
1118 ent2 = ent + data->EntriesArray[ent]->dnum;
1120 if (data->NList_Entries <= 1)
1121 return NL_List_Clear(data);
1123 skip = FALSE;
1124 nlentries = data->NList_Entries;
1127 { nlentries -= 1;
1129 if (data->EntriesArray[ent]->Wrap)
1130 data->do_wwrap = TRUE;
1132 NL_SetColsRem(data,ent);
1134 if (!(data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine))
1135 DoMethod(data->this, MUIM_NList_Destruct, data->EntriesArray[ent]->Entry, data->Pool);
1137 DONE_NOTIFY(NTF_Select | NTF_LV_Select);
1139 select = data->EntriesArray[ent]->Select;
1140 if (data->EntriesArray[ent]->Select != TE_Select_None)
1142 DO_NOTIFY(NTF_Select | NTF_LV_Select);
1145 if ((ent >= data->NList_AffFirst) || data->NList_EntryValueDependent)
1147 NL_SegChanged(data,ent,nlentries + 1);
1149 else
1150 data->NList_AffFirst--;
1152 if (data->NList_Active == ent)
1154 DO_NOTIFY(NTF_Active | NTF_L_Active);
1156 if (data->NList_MultiSelect == MUIV_NList_MultiSelect_None)
1158 if (ent+1 <= nlentries)
1160 if (data->EntriesArray[ent+1]->Select == TE_Select_None)
1161 skip = TRUE;
1162 SELECT(ent+1,TE_Select_Line);
1163 data->lastselected = ent;
1164 data->lastactived = ent;
1166 else if (ent-1 >= 0)
1167 { SELECT(ent-1,TE_Select_Line);
1168 data->lastselected = ent-1;
1169 data->lastactived = ent-1;
1172 else
1174 if ((ent+1 <= nlentries) &&
1175 (select == TE_Select_Line) &&
1176 (data->EntriesArray[ent+1]->Select == TE_Select_None))
1178 if (data->EntriesArray[ent+1]->Select == TE_Select_None)
1179 skip = TRUE;
1180 SELECT(ent+1,TE_Select_Line);
1181 data->lastselected = ent;
1182 data->lastactived = ent;
1184 else if ((ent-1 >= 0) &&
1185 (select == TE_Select_Line) &&
1186 (data->EntriesArray[ent-1]->Select == TE_Select_None))
1188 SELECT(ent-1,TE_Select_Line);
1189 data->lastselected = ent-1;
1190 data->lastactived = ent-1;
1194 else if (data->NList_Active > ent)
1196 set_Active(data->NList_Active - 1);
1198 if (data->NList_Active >= nlentries)
1200 set_Active(nlentries - 1);
1203 FreeTypeEntry(data->EntriesArray[ent]);
1205 NL_Move(&data->EntriesArray[ent],&data->EntriesArray[ent+1],nlentries-ent,ent);
1206 ent = nlentries;
1208 data->EntriesArray[ent] = NULL;
1210 if (pos == MUIV_NList_Remove_Selected)
1212 if (skip)
1213 ent = ent2;
1214 else
1215 ent = ent2 - 1;
1216 skip = FALSE;
1217 while ((ent < nlentries) && (data->EntriesArray[ent]->Select == TE_Select_None))
1218 ent++;
1219 if ((ent >= 0) && (ent < nlentries))
1221 if (data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine)
1222 ent -= data->EntriesArray[ent]->dnum;
1223 ent2 = ent + data->EntriesArray[ent]->dnum;
1226 } while ((pos == MUIV_NList_Remove_Selected) && (ent < nlentries));
1228 if (data->NList_Entries != nlentries)
1230 DO_NOTIFY(NTF_Entries|NTF_MinMax);
1233 data->NList_Entries = nlentries;
1234 if (data->NList_Entries <= 0)
1235 return NL_List_Clear(data);
1238 if (data->NList_Entries < ((data->LastEntry/2) & ~0x000FL))
1239 maxent = (data->LastEntry/2) & ~0x000FL;
1241 if ((maxent > 0) && (newentries = AllocVecPooled(data->Pool, sizeof(struct TypeEntry *) * (maxent + 1))))
1242 { LONG ent1 = 0;
1243 data->LastEntry = maxent;
1244 maxent = 0;
1246 NL_Move(&newentries[ent1],&data->EntriesArray[ent1],data->NList_Entries-ent1,ent1);
1247 ent1 = data->NList_Entries;
1249 newentries[ent1] = NULL;
1250 if (data->EntriesArray)
1251 FreeVecPooled(data->Pool, data->EntriesArray);
1252 data->EntriesArray = newentries;
1256 if ((data->NList_First > 0) && (data->NList_First + data->NList_Visible >= data->NList_Entries))
1258 data->NList_First = data->NList_Entries - data->NList_Visible;
1259 if (data->NList_First < 0)
1260 data->NList_First = 0;
1261 DO_NOTIFY(NTF_First);
1263 UnSelectCharSel(data,FALSE);
1264 Make_Active_Visible;
1265 data->do_updatesb = TRUE;
1266 REDRAW;
1267 /* do_notifies(NTF_AllChanges|NTF_MinMax);*/
1269 return (TRUE);
1271 return (FALSE);
1275 ULONG NL_List_Exchange(struct NLData *data,LONG pos1,LONG pos2)
1277 LONG ent1, ent2;
1278 switch (pos1)
1280 case MUIV_NList_Exchange_Top:
1281 ent1 = 0;
1282 break;
1283 case MUIV_NList_Exchange_Bottom:
1284 ent1 = data->NList_Entries - 1;
1285 break;
1286 case MUIV_NList_Exchange_Active:
1287 ent1 = data->NList_Active;
1288 break;
1289 default:
1290 ent1 = pos1;
1291 break;
1293 if ((ent1 >= 0) && (ent1 < data->NList_Entries) && (data->EntriesArray[ent1]->Wrap & TE_Wrap_TmpLine))
1294 ent1 -= data->EntriesArray[ent1]->dnum;
1295 if ((ent1 >= 0) && (ent1 < data->NList_Entries))
1297 switch (pos2)
1299 case MUIV_NList_Exchange_Top:
1300 ent2 = 0;
1301 break;
1302 case MUIV_NList_Exchange_Bottom:
1303 ent2 = data->NList_Entries - 1;
1304 break;
1305 case MUIV_NList_Exchange_Active:
1306 ent2 = data->NList_Active;
1307 break;
1308 case MUIV_NList_Exchange_Next:
1309 ent2 = ent1 + 1;
1310 break;
1311 case MUIV_NList_Exchange_Previous:
1312 ent2 = ent1 - 1;
1313 break;
1314 default:
1315 ent2 = pos2;
1316 break;
1318 if ((ent2 >= 0) && (ent2 < data->NList_Entries) && (data->EntriesArray[ent2]->Wrap & TE_Wrap_TmpLine))
1319 ent2 -= data->EntriesArray[ent2]->dnum;
1320 if ((ent2 >= 0) && (ent2 < data->NList_Entries) && (ent1 != ent2))
1322 struct TypeEntry *newentry;
1324 data->display_ptr = NULL;
1326 newentry = data->EntriesArray[ent1];
1327 if (data->EntriesArray[ent1]->Wrap && !(data->EntriesArray[ent1]->Wrap & TE_Wrap_TmpLine) && (data->EntriesArray[ent1]->len >= 0))
1329 newentry->pos = (WORD) NL_GetSelects(data,ent1);
1330 newentry->len = -1;
1331 data->do_wwrap = TRUE;
1334 data->EntriesArray[ent1] = data->EntriesArray[ent2];
1335 data->EntriesArray[ent1]->entpos = ent1;
1336 if (data->EntriesArray[ent2]->Wrap && !(data->EntriesArray[ent2]->Wrap & TE_Wrap_TmpLine) && (data->EntriesArray[ent2]->len >= 0))
1338 data->EntriesArray[ent1]->pos = (WORD) NL_GetSelects(data,ent2);
1339 data->EntriesArray[ent1]->len = -1;
1340 data->do_wwrap = TRUE;
1343 data->EntriesArray[ent2] = newentry;
1344 data->EntriesArray[ent2]->entpos = ent2;
1346 if (data->NList_Active == ent1)
1348 set_Active(ent2);
1350 else if (data->NList_Active == ent2)
1352 set_Active(ent1);
1354 if ((ent1 >= data->NList_First) && (ent1 < data->NList_First+data->NList_Visible))
1355 NL_Changed(data,ent1);
1356 if ((ent2 >= data->NList_First) && (ent2 < data->NList_First+data->NList_Visible))
1357 NL_Changed(data,ent2);
1358 UnSelectCharSel(data,FALSE);
1359 Make_Active_Visible;
1360 NL_DoWrapAll(data,FALSE,FALSE);
1361 data->do_updatesb = TRUE;
1362 data->sorted = FALSE;
1363 REDRAW;
1364 /* do_notifies(NTF_AllChanges|NTF_MinMax);*/
1365 return (TRUE);
1368 return (FALSE);
1372 //$$$ARRAY+
1373 static ULONG NL_List_Move_Selected(struct NLData *data, LONG to)
1375 LONG num_sel = 0;
1376 long first,last,ent,ent2,ent3,act,act2,dest;
1377 struct TypeEntry **EntriesArray;
1379 ENTER();
1381 first = last = -1;
1382 if (!data->NList_TypeSelect)
1384 ent = 0;
1385 while (ent < data->NList_Entries)
1387 if (data->EntriesArray[ent]->Select != TE_Select_None)
1389 if (data->EntriesArray[ent]->Wrap)
1391 if (data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine)
1392 ent -= data->EntriesArray[ent]->dnum;
1393 if (data->EntriesArray[ent]->Wrap && (data->EntriesArray[ent]->len >= 0))
1395 data->EntriesArray[ent]->pos = (WORD) NL_GetSelects(data,ent);
1396 data->EntriesArray[ent]->len = -1;
1397 data->do_wwrap = TRUE;
1399 if (first == -1)
1400 first = ent;
1401 ent2 = ent;
1402 last = ent + data->EntriesArray[ent]->dnum;
1403 data->EntriesArray[ent]->Select = TE_Select_Line;
1404 num_sel++;
1405 ent++;
1406 while ((ent < data->NList_Entries) && (ent < last) && (data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine))
1408 data->EntriesArray[ent]->Select = TE_Select_Line;
1409 data->EntriesArray[ent]->dnum = ent - ent2;
1410 num_sel++;
1411 ent++;
1413 data->EntriesArray[ent2]->dnum = ent - ent2;
1414 last = ent - 1;
1416 else
1418 if (first == -1)
1419 first = ent;
1420 last = ent;
1421 num_sel++;
1422 ent++;
1425 else
1426 ent++;
1429 else
1431 first = data->sel_pt[data->min_sel].ent;
1432 last = data->sel_pt[data->max_sel].ent;
1433 if ((data->sel_pt[data->max_sel].column == 0) && (data->sel_pt[data->max_sel].xoffset == PMIN))
1434 last--;
1435 if ((first >= 0) && (first < data->NList_Entries) && (data->EntriesArray[first]->Wrap & TE_Wrap_TmpLine))
1436 first -= data->EntriesArray[first]->dnum;
1437 if ((last >= 0) && (last < data->NList_Entries) && (data->EntriesArray[last]->Wrap & TE_Wrap_TmpLine))
1438 { last -= data->EntriesArray[last]->dnum;
1439 if ((last >= 0) && (last < data->NList_Entries))
1440 last += data->EntriesArray[last]->dnum - 1;
1442 if ((first >= 0) && (first < data->NList_Entries) && (last >= 0) && (last < data->NList_Entries) && (first <= last))
1443 num_sel = last - first + 1;
1446 if (num_sel <= 0)
1448 RETURN(TRUE);
1449 return TRUE;
1451 else if (num_sel == 1)
1453 ULONG res;
1455 // we have to decrease 'to' by one if 'to > last' (user moves item down)
1456 // because NL_List_Move() expects the indices to prepared the same
1457 // way like List.mui is expecting it.
1458 if(to > last)
1459 to--;
1461 res = NL_List_Move(data, last, to);
1463 RETURN(res);
1464 return res;
1466 else
1468 switch (to)
1470 case MUIV_NList_Move_Top:
1471 dest = 0;
1472 break;
1473 case MUIV_NList_Move_Bottom:
1474 dest = data->NList_Entries;
1475 break;
1476 case MUIV_NList_Move_Active:
1477 dest = data->NList_Active;
1478 break;
1479 default:
1480 dest = to;
1481 if ((dest < 0) || (dest > data->NList_Entries))
1482 dest = data->NList_Entries;
1483 break;
1485 if ((dest >= 0) && (dest < data->NList_Entries) && (data->EntriesArray[dest]->Wrap & TE_Wrap_TmpLine))
1486 dest -= data->EntriesArray[dest]->dnum;
1488 if ((last-first+1 == num_sel) && (first <= dest) && (dest <= last+1))
1490 if (data->do_wwrap)
1492 NL_DoWrapAll(data,FALSE,FALSE);
1493 REDRAW;
1496 RETURN(TRUE);
1497 return TRUE;
1499 else if((EntriesArray = (struct TypeEntry **)AllocVecPooled(data->Pool, sizeof(struct TypeEntry *)*num_sel)) != NULL)
1501 data->display_ptr = NULL;
1502 ent = ent2 = first;
1503 ent3 = 0;
1504 act = data->NList_Active;
1505 act2 = MUIV_NList_Active_Off;
1507 while (ent < data->NList_Entries)
1509 if ((!data->NList_TypeSelect && (data->EntriesArray[ent]->Select != TE_Select_None)) ||
1510 (data->NList_TypeSelect && (ent >= first) && (ent <= last)))
1512 if (dest > ent2)
1513 dest--;
1514 if (data->NList_Active == ent)
1515 act2 = ent3;
1516 else if (act > ent2)
1517 act--;
1518 EntriesArray[ent3] = data->EntriesArray[ent];
1519 EntriesArray[ent3]->entpos = ent3;
1520 ent3++;
1522 else
1524 data->EntriesArray[ent2] = data->EntriesArray[ent];
1525 data->EntriesArray[ent2]->entpos = ent2;
1526 if (data->EntriesArray[ent]->Wrap && !(data->EntriesArray[ent]->Wrap & TE_Wrap_TmpLine) && (data->EntriesArray[ent]->len >= 0))
1528 data->EntriesArray[ent2]->pos = (WORD) NL_GetSelects(data,ent);
1529 data->EntriesArray[ent2]->len = -1;
1530 data->do_wwrap = TRUE;
1532 ent2++;
1534 ent++;
1536 if (act2 >= 0)
1538 set_Active(dest + act2);
1540 else if (act >= dest)
1542 set_Active(act + ent3);
1544 else
1546 set_Active(act);
1548 data->NList_LastInserted = dest;
1549 DO_NOTIFY(NTF_Insert);
1550 ent2--;
1551 while (ent2 >= dest)
1553 data->EntriesArray[ent2+ent3] = data->EntriesArray[ent2];
1554 data->EntriesArray[ent2+ent3]->entpos = ent2+ent3;
1555 if (data->EntriesArray[ent2]->Wrap && !(data->EntriesArray[ent2]->Wrap & TE_Wrap_TmpLine) && (data->EntriesArray[ent2]->len >= 0))
1557 data->EntriesArray[ent2+ent3]->pos = (WORD) NL_GetSelects(data,ent2);
1558 data->EntriesArray[ent2+ent3]->len = -1;
1559 data->do_wwrap = TRUE;
1561 ent2--;
1563 ent2++;
1565 NL_Move(&data->EntriesArray[ent2],&EntriesArray[0],ent3,ent2);
1566 FreeVecPooled(data->Pool, EntriesArray);
1568 if (dest < first)
1569 first = dest;
1570 if (dest+ent3 > last)
1571 last = dest+ent3;
1573 NL_SegChanged(data,first,last);
1574 UnSelectCharSel(data,FALSE);
1575 Make_Active_Visible;
1576 NL_DoWrapAll(data,FALSE,FALSE);
1577 data->do_updatesb = TRUE;
1578 REDRAW;
1579 /* do_notifies(NTF_AllChanges|NTF_MinMax);*/
1581 RETURN(TRUE);
1582 return TRUE;
1584 else if (data->do_wwrap)
1586 NL_DoWrapAll(data,FALSE,FALSE);
1587 REDRAW;
1591 RETURN(FALSE);
1592 return FALSE;
1596 //$$$ARRAY+
1597 static ULONG NL_List_Move(struct NLData *data,LONG from,LONG to)
1599 LONG ent1, ent2;
1601 if(from == MUIV_NList_Move_Selected)
1602 return NL_List_Move_Selected(data, to);
1604 switch(from)
1606 case MUIV_NList_Move_Top:
1607 ent1 = 0;
1608 break;
1610 case MUIV_NList_Move_Bottom:
1611 ent1 = data->NList_Entries - 1;
1612 break;
1614 case MUIV_NList_Move_Active:
1615 ent1 = data->NList_Active;
1616 break;
1618 default:
1619 ent1 = from;
1620 break;
1623 if(ent1 >= 0 && ent1 < data->NList_Entries && isFlagSet(data->EntriesArray[ent1]->Wrap, TE_Wrap_TmpLine))
1624 ent1 -= data->EntriesArray[ent1]->dnum;
1626 if(ent1 >= 0 && ent1 < data->NList_Entries)
1628 switch(to)
1630 case MUIV_NList_Move_Top:
1631 ent2 = 0;
1632 break;
1634 case MUIV_NList_Move_Bottom:
1635 ent2 = data->NList_Entries - 1;
1636 break;
1638 case MUIV_NList_Move_Active:
1639 ent2 = data->NList_Active;
1640 break;
1642 case MUIV_NList_Move_Next:
1643 ent2 = ent1 + 1;
1644 break;
1646 case MUIV_NList_Move_Previous:
1647 ent2 = ent1 - 1;
1648 break;
1650 default:
1651 ent2 = to;
1652 break;
1655 if(ent2 >= 0 && ent2 < data->NList_Entries && isFlagSet(data->EntriesArray[ent2]->Wrap, TE_Wrap_TmpLine))
1656 ent2 -= data->EntriesArray[ent2]->dnum;
1658 if(ent2 >= 0 && ent2 < data->NList_Entries && ent1 != ent2)
1660 struct TypeEntry *newentry;
1662 data->display_ptr = NULL;
1664 if(ent1 < ent2)
1666 if(data->EntriesArray[ent2]->Wrap != 0 && isFlagClear(data->EntriesArray[ent2]->Wrap, TE_Wrap_TmpLine))
1667 ent2 += (data->EntriesArray[ent2]->dnum - 1);
1669 newentry = data->EntriesArray[ent1];
1671 if(data->EntriesArray[ent1]->Wrap != 0 && isFlagClear(data->EntriesArray[ent1]->Wrap, TE_Wrap_TmpLine) && data->EntriesArray[ent1]->len >= 0)
1673 newentry->pos = (WORD)NL_GetSelects(data, ent1);
1674 newentry->len = -1;
1675 data->do_wwrap = TRUE;
1678 NL_Move(&data->EntriesArray[ent1], &data->EntriesArray[ent1+1], ent2-ent1, ent1);
1680 data->EntriesArray[ent2] = newentry;
1681 data->EntriesArray[ent2]->entpos = ent2;
1683 if(data->NList_Active > ent1 && data->NList_Active <= ent2)
1685 set_Active(data->NList_Active - 1);
1687 else if(data->NList_Active == ent1)
1689 set_Active(ent2);
1691 NL_SegChanged(data, ent1, ent2);
1692 data->NList_LastInserted = ent2;
1693 DO_NOTIFY(NTF_Insert);
1695 else
1697 newentry = data->EntriesArray[ent1];
1699 if(data->EntriesArray[ent1]->Wrap != 0 && isFlagClear(data->EntriesArray[ent1]->Wrap, TE_Wrap_TmpLine) && data->EntriesArray[ent1]->len >= 0)
1701 newentry->pos = (WORD)NL_GetSelects(data, ent1);
1702 newentry->len = -1;
1703 data->do_wwrap = TRUE;
1706 NL_MoveD(&data->EntriesArray[ent1+1], &data->EntriesArray[ent1], ent1-ent2, ent1+1);
1708 data->EntriesArray[ent2] = newentry;
1709 data->EntriesArray[ent2]->entpos = ent2;
1711 if(data->NList_Active >= ent2 && data->NList_Active < ent1)
1713 set_Active(data->NList_Active + 1);
1715 else if(data->NList_Active == ent1)
1717 set_Active(ent2);
1719 NL_SegChanged(data,ent2,ent1);
1720 data->NList_LastInserted = ent2;
1721 DO_NOTIFY(NTF_Insert);
1723 data->sorted = FALSE;
1724 UnSelectCharSel(data, FALSE);
1725 Make_Active_Visible;
1726 NL_DoWrapAll(data, FALSE, FALSE);
1727 data->do_updatesb = TRUE;
1728 REDRAW;
1729 /* do_notifies(NTF_AllChanges|NTF_MinMax);*/
1730 return (TRUE);
1733 return (FALSE);
1738 IPTR mNL_List_Sort(struct IClass *cl, Object *obj, UNUSED struct MUIP_NList_Sort *msg)
1740 struct NLData *data = INST_DATA(cl,obj);
1741 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1742 return (NL_List_Sort(data));
1746 IPTR mNL_List_Sort2(struct IClass *cl,Object *obj,struct MUIP_NList_Sort2 *msg)
1748 struct NLData *data = INST_DATA(cl,obj);
1749 if ((msg->sort_type_add) && ((data->NList_SortType & ~MUIV_NList_SortTypeAdd_Mask) == (ULONG)msg->sort_type))
1750 data->NList_SortType += msg->sort_type_add;
1751 else
1752 data->NList_SortType = msg->sort_type;
1753 set(obj,MUIA_NList_SortType,data->NList_SortType);
1754 return (NL_List_Sort(data));
1758 IPTR mNL_List_Sort3(struct IClass *cl,Object *obj,struct MUIP_NList_Sort3 *msg)
1760 struct NLData *data = INST_DATA(cl,obj);
1761 if (msg->which == MUIV_NList_Sort3_SortType_2)
1763 if ((msg->sort_type_add) && ((data->NList_SortType2 & ~MUIV_NList_SortTypeAdd_Mask) == (ULONG)msg->sort_type))
1764 data->NList_SortType2 += msg->sort_type_add;
1765 else
1766 data->NList_SortType2 = msg->sort_type;
1767 set(obj,MUIA_NList_SortType2,data->NList_SortType2);
1769 else
1771 if ((msg->sort_type_add) && ((data->NList_SortType & ~MUIV_NList_SortTypeAdd_Mask) == (ULONG)msg->sort_type))
1772 data->NList_SortType += msg->sort_type_add;
1773 else
1774 data->NList_SortType = msg->sort_type;
1775 if (msg->which == MUIV_NList_Sort3_SortType_1)
1776 { set(obj,MUIA_NList_SortType,data->NList_SortType);
1778 else
1779 { data->NList_SortType2 = data->NList_SortType;
1780 set(obj,MUIA_NList_SortType,data->NList_SortType);
1781 set(obj,MUIA_NList_SortType2,data->NList_SortType2);
1784 return (NL_List_Sort(data));
1788 IPTR mNL_List_Insert(struct IClass *cl,Object *obj,struct MUIP_NList_Insert *msg)
1790 struct NLData *data = INST_DATA(cl,obj);
1791 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1792 return (NL_List_Insert(data,msg->entries,msg->count,msg->pos,NOWRAP,ALIGN_LEFT,msg->flags));
1796 IPTR mNL_List_InsertSingle(struct IClass *cl,Object *obj,struct MUIP_NList_InsertSingle *msg)
1798 struct NLData *data = INST_DATA(cl,obj);
1799 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1800 if (msg->entry)
1801 return (NL_List_Insert(data,&(msg->entry),1,msg->pos,NOWRAP,ALIGN_LEFT,0));
1802 return (0);
1806 IPTR mNL_List_InsertWrap(struct IClass *cl,Object *obj,struct MUIP_NList_InsertWrap *msg)
1808 struct NLData *data = INST_DATA(cl,obj);
1809 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1810 return (NL_List_Insert(data,msg->entries,msg->count,msg->pos,msg->wrapcol,msg->align & ALIGN_MASK,msg->flags));
1814 IPTR mNL_List_InsertSingleWrap(struct IClass *cl,Object *obj,struct MUIP_NList_InsertSingleWrap *msg)
1816 struct NLData *data = INST_DATA(cl,obj);
1817 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1818 if (msg->entry)
1819 return (NL_List_Insert(data,&(msg->entry),1,msg->pos,msg->wrapcol,msg->align & ALIGN_MASK,0));
1820 return (0);
1824 IPTR mNL_List_ReplaceSingle(struct IClass *cl,Object *obj,struct MUIP_NList_ReplaceSingle *msg)
1826 struct NLData *data = INST_DATA(cl,obj);
1827 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1828 return (NL_List_Replace(data,msg->entry,msg->pos,msg->wrapcol,msg->align & ALIGN_MASK));
1832 IPTR mNL_List_Exchange(struct IClass *cl,Object *obj,struct MUIP_NList_Exchange *msg)
1834 struct NLData *data = INST_DATA(cl,obj);
1835 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1836 return (NL_List_Exchange(data,msg->pos1,msg->pos2));
1840 IPTR mNL_List_Move(struct IClass *cl,Object *obj,struct MUIP_NList_Move *msg)
1842 struct NLData *data = INST_DATA(cl,obj);
1843 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1844 return (NL_List_Move(data,msg->from,msg->to));
1848 IPTR mNL_List_Clear(struct IClass *cl, Object *obj, UNUSED struct MUIP_NList_Clear *msg)
1850 struct NLData *data = INST_DATA(cl,obj);
1851 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1852 return (NL_List_Clear(data));
1856 IPTR mNL_List_Remove(struct IClass *cl,Object *obj,struct MUIP_NList_Remove *msg)
1858 struct NLData *data = INST_DATA(cl,obj);
1859 /*DoSuperMethodA(cl,obj,(Msg) msg);*/
1860 return (NL_List_Remove(data,msg->pos));
1865 #define DROPMARK_NONE -1
1866 #define DROPMARK_START -2
1870 IPTR mNL_DragQuery(struct IClass *cl,Object *obj,struct MUIP_DragQuery *msg)
1872 struct NLData *data = INST_DATA(cl,obj);
1873 if (data->NList_Disabled)
1875 /*D(bug("%lx| 1 DragQuery_Refuse\n",obj));*/
1876 return (MUIV_DragQuery_Refuse);
1878 if ((msg->obj==obj) && (data->NList_DragSortable))
1880 /*D(bug("%lx| 3 DragQuery_Accept\n",obj));*/
1881 return(MUIV_DragQuery_Accept);
1883 /*D(bug("%lx| 3 DragQuery_Refuse\n",obj));*/
1884 return(MUIV_DragQuery_Refuse);
1888 IPTR mNL_DragBegin(struct IClass *cl,Object *obj,struct MUIP_DragBegin *msg)
1890 struct NLData *data = INST_DATA(cl,obj);
1891 data->NList_DropMark = DROPMARK_START;
1892 if (data->NList_Disabled)
1893 return (0);
1894 if ((data->NList_ShowDropMarks || (msg->obj==obj)) && (data->NList_Entries > 0))
1895 return(0);
1896 return(DoSuperMethodA(cl,obj,(Msg) msg));
1900 IPTR mNL_DragReport(struct IClass *cl,Object *obj,struct MUIP_DragReport *msg)
1902 struct NLData *data = INST_DATA(cl,obj);
1903 LONG mdy,type,lyl = DROPMARK_NONE;
1905 if (data->NList_Disabled)
1907 /*D(bug("%lx| 1 DragReport_Abort\n",obj));*/
1908 return (MUIV_DragReport_Abort);
1910 data->dropping = TRUE;
1911 if (msg->update)
1912 { LONG drawnum = -1,erasenum = -1;
1913 if (data->markdraw && (data->markdrawnum >= 0))
1914 drawnum = data->markdrawnum;
1915 if (data->markerase && (data->markerasenum >= 0) && (data->markerasenum != drawnum))
1916 erasenum = data->markerasenum;
1917 if ((drawnum >= 0) || (erasenum >= 0))
1918 { if ((DoMethod(obj,MUIM_NList_DropEntryDrawErase, data->marktype,drawnum, erasenum) != MUIM_NList_DropEntryDrawErase) &&
1919 (drawnum >= 0))
1920 NL_Changed(data,drawnum);
1922 data->display_ptr = NULL;
1923 data->parse_column = -1;
1924 REDRAW_FORCE;
1925 if (data->NList_SerMouseFix)
1926 return(MUIV_DragReport_Continue);
1927 else
1928 return(MUIV_DragReport_Lock);
1930 else if ((msg->x >= _left(obj)) && (msg->x <= _right(obj)))
1931 { type = MUIV_NList_DropType_Above;
1932 if (data->NList_DropMark == DROPMARK_START)
1933 { data->NList_DropMark = DROPMARK_NONE;
1934 if (data->markdrawnum == (LONG)MUIM_NList_Trigger)
1935 data->markdrawnum = 0;
1936 else if ((msg->x > data->mleft+6) && (msg->x < data->mright-6))
1937 { if (msg->y < data->vpos+4)
1938 lyl = 0;
1939 else if (msg->y > data->mbottom-4)
1940 lyl = data->NList_Entries;
1943 if (lyl < 0)
1944 { LONG ly = (msg->y - data->vpos);
1945 /*lyl = (ly + data->vinc/2) / data->vinc + data->NList_First;*/
1946 lyl = ly / data->vinc + data->NList_First;
1947 if ((ly % data->vinc) >= (data->vinc / 2))
1948 type = MUIV_NList_DropType_Below;
1949 if (lyl >= data->NList_First + data->NList_Visible)
1950 { if (msg->y > data->mbottom+40)
1951 lyl = data->NList_First + data->NList_Visible + 7;
1952 else if (msg->y > data->mbottom+24)
1953 lyl = data->NList_First + data->NList_Visible + 3;
1954 else if (msg->y > data->mbottom+8)
1955 lyl = data->NList_First + data->NList_Visible + 1;
1956 else
1957 lyl = data->NList_First + data->NList_Visible;
1959 if ((ly < 0) || (lyl < data->NList_First))
1960 { if (msg->y < data->vpos-40)
1961 lyl = data->NList_First - 8;
1962 else if (msg->y < data->vpos-24)
1963 lyl = data->NList_First - 4;
1964 else if (msg->y < data->vpos-8)
1965 lyl = data->NList_First - 2;
1966 else
1967 lyl = data->NList_First - 1;
1968 if (lyl < 0)
1969 lyl = 0;
1972 if (data->NList_Entries == 0)
1973 { lyl = 0;
1974 type = MUIV_NList_DropType_Above;
1976 else if (lyl >= data->NList_Entries)
1977 { lyl = data->NList_Entries - 1;
1978 type = MUIV_NList_DropType_Below;
1980 mdy = data->vpos + (data->vinc * (lyl - data->NList_First));
1981 DoMethod(obj,MUIM_NList_DropType, &lyl,&type, data->mleft,data->mright,
1982 mdy,mdy+data->vinc-1, msg->x,msg->y);
1983 if ((type & MUIV_NList_DropType_Mask) == MUIV_NList_DropType_Below)
1984 { lyl++;
1985 type = (type & ~MUIV_NList_DropType_Mask) | MUIV_NList_DropType_Above;
1987 if (data->NList_Entries == 0)
1988 { lyl = 0;
1989 type = (type & ~MUIV_NList_DropType_Mask) | MUIV_NList_DropType_Above;
1991 else if (lyl >= data->NList_Entries)
1992 { lyl = data->NList_Entries - 1;
1993 type = (type & ~MUIV_NList_DropType_Mask) | MUIV_NList_DropType_Below;
1996 if ((data->NList_DropMark != lyl) || (type != data->marktype))
1997 { if (data->NList_DropMark >= 0)
1998 data->markerase = TRUE;
1999 data->markdraw = TRUE;
2000 if (lyl >= -1)
2001 data->NList_DropMark = lyl;
2002 if (data->NList_DropMark >= 0)
2004 if (data->NList_DropMark < data->NList_First)
2005 { data->NList_First = data->NList_DropMark;
2006 DO_NOTIFY(NTF_First);
2008 if (data->NList_DropMark >= data->NList_First + data->NList_Visible)
2009 { data->NList_First = data->NList_DropMark - data->NList_Visible + 1;
2010 DO_NOTIFY(NTF_First);
2012 if (data->NList_First < 0)
2013 { data->NList_First = 0;
2014 DO_NOTIFY(NTF_First);
2016 data->markdrawnum = data->NList_DropMark;
2017 data->marktype = type;
2018 if ((data->NList_ShowDropMarks || (msg->obj==obj)) && (data->NList_Entries > 0))
2019 return(MUIV_DragReport_Refresh);
2020 else
2021 { data->markerase = FALSE;
2022 data->markdraw = FALSE;
2023 if (data->NList_First != data->NList_AffFirst)
2024 return(MUIV_DragReport_Refresh);
2027 else if (data->markerase)
2028 { data->markdraw = FALSE;
2029 if ((data->NList_ShowDropMarks || (msg->obj==obj)) && (data->NList_Entries > 0))
2030 return(MUIV_DragReport_Refresh);
2033 if (data->NList_SerMouseFix)
2034 return(MUIV_DragReport_Continue);
2035 else
2036 return(MUIV_DragReport_Lock);
2038 /*D(bug("%lx| 2 DragReport_Abort\n",obj));*/
2039 return(MUIV_DragReport_Abort);
2043 IPTR mNL_DragFinish(struct IClass *cl,Object *obj,struct MUIP_DragFinish *msg)
2045 struct NLData *data = INST_DATA(cl,obj);
2046 if (data->NList_DropMark == DROPMARK_START)
2047 data->NList_DropMark = DROPMARK_NONE;
2048 if (data->NList_Disabled)
2049 return (0);
2050 if ((data->NList_ShowDropMarks || (msg->obj==obj)) && (data->NList_Entries > 0))
2051 { if (data->NList_DropMark >= 0)
2052 { data->markdraw = FALSE;
2053 data->markerase = TRUE;
2054 if (data->markerase && (data->markerasenum >= 0))
2055 DoMethod(obj,MUIM_NList_DropEntryDrawErase, 0,-1,data->markerasenum);
2056 data->display_ptr = NULL;
2057 data->parse_column = -1;
2058 REDRAW_FORCE;
2060 data->dropping = FALSE;
2061 return(0);
2063 data->dropping = FALSE;
2064 return(DoSuperMethodA(cl,obj,(Msg) msg));
2068 IPTR mNL_DragDrop(struct IClass *cl,Object *obj,struct MUIP_DragDrop *msg)
2070 struct NLData *data = INST_DATA(cl,obj);
2071 LONG ent = data->NList_DropMark;
2072 IPTR result = 0;
2074 ENTER();
2076 if(data->NList_Disabled == FALSE)
2078 if(data->NList_DragSortable && (msg->obj==obj) && (ent >= 0) && (data->marktype & MUIV_NList_DropType_Mask))
2080 LONG li;
2081 LONG res;
2083 if((data->marktype & MUIV_NList_DropType_Mask) == MUIV_NList_DropType_Below)
2084 ent++;
2086 li = data->NList_LastInserted;
2087 data->NList_LastInserted = -1;
2088 res = NL_List_Move_Selected(data,ent);
2090 if(data->NList_LastInserted >= 0)
2091 DO_NOTIFY(NTF_DragSortInsert);
2092 else
2093 data->NList_LastInserted = li;
2095 result = res;
2099 RETURN(result);
2100 return result;
2104 IPTR mNL_DropType(UNUSED struct IClass *cl, UNUSED Object *obj, UNUSED struct MUIP_NList_DropType *msg)
2106 /*struct NLData *data = INST_DATA(cl,obj);*/
2107 return(0);
2110 IPTR mNL_DropEntryDrawErase(UNUSED struct IClass *cl, UNUSED Object *obj, UNUSED struct MUIP_NList_DropEntryDrawErase *msg)
2112 /*struct NLData *data = INST_DATA(cl,obj);*/
2113 return(MUIM_NList_DropEntryDrawErase);