home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / tollmanager3.lha / toolmanager3 / ToolManagerSrc.lha / ToolManager / Source / Prefs / entrylist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-22  |  12.6 KB  |  466 lines

  1. /*
  2.  * entrylist.c  V3.0
  3.  *
  4.  * Class for TM dock entries list
  5.  *
  6.  * Copyright (C) 1990-97 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local data */
  19. static const char EmptyString[] = "";
  20. static const char *TextColumnExec;
  21. static const char *TextColumnImage;
  22. static const char *TextColumnSound;
  23.  
  24. /* EntryList class instance data */
  25. struct EntryListClassData {
  26.  struct Hook elcd_Construct;
  27. };
  28. #define TYPED_INST_DATA(cl, o) ((struct EntryListClassData *) INST_DATA((cl), (o)))
  29.  
  30. /* EntryList class construct function */
  31. #undef  DEBUGFUNCTION
  32. #define DEBUGFUNCTION EntryListClassConstruct
  33. __geta4 static ULONG EntryListClassConstruct(__a0 struct Hook *h,
  34.                                              __a1 struct DockEntry *de)
  35. {
  36.  /* Duplicate dock entry */
  37.  return((ULONG) CopyDockEntry(de, (Object *) h->h_Data));
  38. }
  39.  
  40. /* EntryList class destruct function */
  41. #undef  DEBUGFUNCTION
  42. #define DEBUGFUNCTION EntryListClassDestruct
  43. __geta4 static void EntryListClassDestruct(__a1 struct DockEntry *de)
  44. {
  45.  /* Free dock entry */
  46.  FreeDockEntry(de);
  47. }
  48.  
  49. /* EntryList class display function */
  50. #undef  DEBUGFUNCTION
  51. #define DEBUGFUNCTION EntryListClassDisplay
  52. __geta4 static void EntryListClassDisplay(__a1 struct DockEntry *de,
  53.                                           __a2 const char **array)
  54. {
  55.  /* Entry valid? */
  56.  if (de) {
  57.  
  58.   /* Yes, get object names. Get Exec object name */
  59.   if (de->de_Exec)
  60.    GetAttr(TMA_Name, de->de_Exec->ad_Object,  (ULONG *) array++);
  61.   else
  62.    *array++ = EmptyString;
  63.  
  64.   /* Get Image object name */
  65.   if (de->de_Image)
  66.    GetAttr(TMA_Name, de->de_Image->ad_Object, (ULONG *) array++);
  67.   else
  68.    *array++ = EmptyString;
  69.  
  70.   /* Get Sound object name */
  71.   if (de->de_Sound)
  72.    GetAttr(TMA_Name, de->de_Sound->ad_Object, (ULONG *) array);
  73.   else
  74.    *array = EmptyString;
  75.  
  76.  } else {
  77.  
  78.   /* No, create title column */
  79.   *array++ = TextColumnExec;
  80.   *array++ = TextColumnImage;
  81.   *array   = TextColumnSound;
  82.  }
  83. }
  84.  
  85. /* Hooks */
  86. static const struct Hook DestructHook = {
  87.  {NULL, NULL}, (void *) EntryListClassDestruct, NULL, NULL
  88. };
  89. static const struct Hook DisplayHook = {
  90.  {NULL, NULL}, (void *) EntryListClassDisplay, NULL, NULL
  91. };
  92.  
  93. /* EntryList class method: OM_NEW */
  94. #undef  DEBUGFUNCTION
  95. #define DEBUGFUNCTION EntryListClassNew
  96. static ULONG EntryListClassNew(Class *cl, Object *obj, struct opSet *ops)
  97. {
  98.  ENTRYLIST_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  99.                 PrintTagList(ops->ops_AttrList)))
  100.  
  101.  /* Create object */
  102.  if (obj = (Object *) DoSuperNew(cl, obj,
  103.                                  MUIA_List_DestructHook, &DestructHook,
  104.                                  MUIA_List_DisplayHook,  &DisplayHook,
  105.                                  MUIA_List_Format,       "BAR,BAR,",
  106.                                  MUIA_List_DragSortable, TRUE,
  107.                                  MUIA_List_Title,        TRUE,
  108.                                  TAG_MORE,               ops->ops_AttrList)) {
  109.   struct EntryListClassData *elcd = TYPED_INST_DATA(cl, obj);
  110.   struct DockEntry          *de   = (struct DockEntry *)
  111.                                      GetHead((struct MinList *)
  112.                                               GetTagData(TMA_Entries, NULL,
  113.                                                          ops->ops_AttrList));
  114.  
  115.   /* Initialize construct hook */
  116.   elcd->elcd_Construct.h_Entry = (void *) EntryListClassConstruct;
  117.   elcd->elcd_Construct.h_Data  = obj;
  118.  
  119.   /* Set construct hook */
  120.   SetAttrs(obj, MUIA_List_ConstructHook, &elcd->elcd_Construct, TAG_DONE);
  121.  
  122.   /* For each dock entry */
  123.   while (de) {
  124.  
  125.    /* Insert entry */
  126.    DoMethod(obj, MUIM_List_InsertSingle, de, MUIV_List_Insert_Bottom);
  127.  
  128.    /* Next entry */
  129.    de = (struct DockEntry *) GetSucc((struct MinNode *) de);
  130.   }
  131.  }
  132.  
  133.  ENTRYLIST_LOG(LOG1(Result, "0x%08lx", obj))
  134.  
  135.  /* Return pointer to created object */
  136.  return((ULONG) obj);
  137. }
  138.  
  139. /* EntryList class method: MUIM_DragQuery */
  140. #undef  DEBUGFUNCTION
  141. #define DEBUGFUNCTION EntryListClassDragQuery
  142. static ULONG EntryListClassDragQuery(Class *cl, Object *obj,
  143.                                      struct MUIP_DragQuery *mpdq)
  144. {
  145.  ULONG rc = MUIV_DragQuery_Accept;
  146.  
  147. #if DEBUG_VERY_NOISY
  148.  /* This just generates too much debug output... */
  149.  ENTRYLIST_LOG(LOG2(Arguments, "Object 0x%08lx Source 0x%08lx", obj,
  150.                     mpdq->obj))
  151. #endif
  152.  
  153.  /* Is source our list? */
  154.  if (mpdq->obj != obj) {
  155.   Object *active;
  156.   ULONG   type   = TMOBJTYPES;
  157.  
  158.   /* No, get active entry */
  159.   if (GetAttr(TMA_Active, mpdq->obj, (ULONG *) &active))
  160.  
  161.    /* Get type of object */
  162.    GetAttr(TMA_Type, active, &type);
  163.  
  164.   /* Check type, only Exec, Image and Sound objects are accepted */
  165.   if (type > TMOBJTYPE_SOUND) rc = MUIV_DragQuery_Refuse;
  166.  }
  167.  
  168.  return(rc);
  169. }
  170.  
  171. /* EntryList class method: MUIM_DragDrop */
  172. #undef  DEBUGFUNCTION
  173. #define DEBUGFUNCTION EntryListClassDragDrop
  174. static ULONG EntryListClassDragDrop(Class *cl, Object *obj,
  175.                                     struct MUIP_DragDrop *mpdd)
  176. {
  177.  /* Is source our list? */
  178.  if (obj == mpdd->obj)
  179.  
  180.   /* Yes, call SuperClass */
  181.   DoSuperMethodA(cl, obj, (Msg) mpdd);
  182.  
  183.  else {
  184.   Object           *active;
  185.   ULONG             type;
  186.   ULONG             entry;
  187.   struct DockEntry *de;
  188.  
  189.   /* No, get active entry */
  190.   GetAttr(TMA_Active, mpdd->obj, (ULONG *) &active);
  191.  
  192.   ENTRYLIST_LOG(LOG1(Object, "0x%08lx", active))
  193.  
  194.   /* Get type of object */
  195.   GetAttr(TMA_Type, active, &type);
  196.  
  197.   ENTRYLIST_LOG(LOG1(Type, "%ld", type))
  198.  
  199.   /* Get drop mark */
  200.   GetAttr(MUIA_List_DropMark, obj, &entry);
  201.  
  202.   ENTRYLIST_LOG(LOG1(Drop Mark, "%ld", entry))
  203.  
  204.   /* Get entry corresponding to drop mark */
  205.   DoMethod(obj, MUIM_List_GetEntry, entry, &de);
  206.  
  207.   /* Entry valid? */
  208.   if (de) {
  209.  
  210.    ENTRYLIST_LOG(LOG1(Dock Entry, "0x%08lx", de))
  211.  
  212.    /* Which type? */
  213.    switch (type) {
  214.     case TMOBJTYPE_EXEC:
  215.      /* Detach old Exec object */
  216.      if (de->de_Exec) DoMethod(de->de_Exec->ad_Object, TMM_Detach,
  217.                                de->de_Exec);
  218.  
  219.      /* Attach new Exec object */
  220.      de->de_Exec = (struct AttachData *) DoMethod(active, TMM_Attach, obj);
  221.      break;
  222.  
  223.     case TMOBJTYPE_IMAGE:
  224.      /* Detach old Image object */
  225.      if (de->de_Image) DoMethod(de->de_Image->ad_Object, TMM_Detach,
  226.                                 de->de_Image);
  227.  
  228.      /* Attach new Image object */
  229.      de->de_Image = (struct AttachData *) DoMethod(active, TMM_Attach, obj);
  230.      break;
  231.  
  232.     case TMOBJTYPE_SOUND:
  233.      /* Detach old Sound object */
  234.      if (de->de_Sound) DoMethod(de->de_Sound->ad_Object, TMM_Detach,
  235.                                 de->de_Sound);
  236.  
  237.      /* Attach new Sound object */
  238.      de->de_Sound = (struct AttachData *) DoMethod(active, TMM_Attach, obj);
  239.      break;
  240.    }
  241.  
  242.    /* Redraw entry */
  243.    DoMethod(obj, MUIM_List_Redraw, entry);
  244.  
  245.   } else {
  246.    struct DockEntry  de;
  247.    struct AttachData ad;
  248.  
  249.    /* Initialize dummy entry */
  250.    de.de_Exec  = NULL;
  251.    de.de_Image = NULL;
  252.    de.de_Sound = NULL;
  253.  
  254.    /* Initialize dummy attach data */
  255.    ad.ad_Object = active;
  256.  
  257.    /* Set dummy attach data to correct type */
  258.    switch (type) {
  259.     case TMOBJTYPE_EXEC:  de.de_Exec  = &ad; break;
  260.     case TMOBJTYPE_IMAGE: de.de_Image = &ad; break;
  261.     case TMOBJTYPE_SOUND: de.de_Sound = &ad; break;
  262.    }
  263.  
  264.    /* Insert "dummy" entry (it will be duplicated!) */
  265.    DoMethod(obj, MUIM_List_InsertSingle, &de, MUIV_List_Insert_Bottom);
  266.  
  267.    ENTRYLIST_LOG(LOG0(Creating new entry))
  268.   }
  269.  }
  270.  
  271.  /* Return 1 to indicate that the method is implemented */
  272.  return(1);
  273. }
  274.  
  275. /* EntryList class method: TMM_Notify */
  276. #undef  DEBUGFUNCTION
  277. #define DEBUGFUNCTION EntryListClassNotify
  278. static ULONG EntryListClassNotify(Class *cl, Object *obj,
  279.                                   struct TMP_Notify *tmpn)
  280. {
  281.  ENTRYLIST_LOG(LOG1(Type, "0x%08lx", tmpn->tmpn_Data->ad_Object))
  282.  
  283.  /* Object deleted? */
  284.  if (tmpn->tmpn_Data->ad_Object == NULL) {
  285.   int               i  = 0;
  286.   struct DockEntry *de;
  287.  
  288.   /* For each entry in list */
  289.   do {
  290.  
  291.    /* Get next entry */
  292.    DoMethod(obj, MUIM_List_GetEntry, i++, &de);
  293.  
  294.    ENTRYLIST_LOG(LOG1(Next entry, "0x%08lx", de))
  295.  
  296.    /* Try to remove attached object. Leave loop if object found */
  297.    if (de && RemoveDockEntryAttach(de, tmpn->tmpn_Data)) break;
  298.  
  299.   } while (de);
  300.  }
  301.  
  302.  /* Redraw list */
  303.  DoMethod(obj, MUIM_List_Redraw, MUIV_List_Redraw_All);
  304.  
  305.  /* Return 1 to indicate that the method is implemented */
  306.  return(1);
  307. }
  308.  
  309. /* EntryList class method: TMM_WBArg */
  310. #undef  DEBUGFUNCTION
  311. #define DEBUGFUNCTION EntryListClassWBArg
  312. static ULONG EntryListClassWBArg(Class *cl, Object *obj,
  313.                                  struct TMP_WBArg *tmpwa)
  314. {
  315.  Object *exec;
  316.  ULONG  rc    = 0;
  317.  
  318.  ENTRYLIST_LOG(LOG1(WBArg, "0x%08lx", tmpwa->tmpwa_Argument))
  319.  
  320.  /* Create exec object from WBArg */
  321.  if (exec = (Object *) DoMethodA(tmpwa->tmpwa_Lists[TMOBJTYPE_EXEC],
  322.                                  (Msg) tmpwa)) {
  323.   Object *image;
  324.  
  325.   ENTRYLIST_LOG(LOG1(Exec, "0x%08lx", exec))
  326.  
  327.   /* Create image object from WBArg */
  328.   if (image = (Object *) DoMethodA(tmpwa->tmpwa_Lists[TMOBJTYPE_IMAGE],
  329.                                    (Msg) tmpwa)) {
  330.    struct DockEntry  de;
  331.    struct AttachData ead;
  332.    struct AttachData iad;
  333.  
  334.    ENTRYLIST_LOG(LOG1(Image, "0x%08lx", image))
  335.  
  336.    /* Initialize dummy entry */
  337.    de.de_Exec  = &ead;
  338.    de.de_Image = &iad;
  339.    de.de_Sound = NULL;
  340.  
  341.    /* Initialize dummy attach data */
  342.    ead.ad_Object = exec;
  343.    iad.ad_Object = image;
  344.  
  345.    /* Insert "dummy" entry (it will be duplicated!) */
  346.    DoMethod(obj, MUIM_List_InsertSingle, &de, MUIV_List_Insert_Bottom);
  347.  
  348.    /* Return 1 to indicate success */
  349.    rc = 1;
  350.   }
  351.  }
  352.  
  353.  ENTRYLIST_LOG(LOG1(Result, "0x%08lx", rc))
  354.  
  355.  return(rc);
  356. }
  357.  
  358. /* EntryList class method: TMM_Column */
  359. #undef  DEBUGFUNCTION
  360. #define DEBUGFUNCTION EntryListClassColumn
  361. static ULONG EntryListClassColumn(Class *cl, Object *obj,
  362.                                   struct TMP_Column *tmpc)
  363. {
  364.  struct DockEntry  *de;
  365.  struct AttachData *ad = NULL;
  366.  
  367.  ENTRYLIST_LOG(LOG1(Column, "%ld", tmpc->tmpc_Column))
  368.  
  369.  /* Get active entry from list*/
  370.  DoMethod(obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &de);
  371.  
  372.  ENTRYLIST_LOG(LOG1(Entry, "0x%08lx", de))
  373.  
  374.  /* Select object to edit */
  375.  switch (tmpc->tmpc_Column) {
  376.   case 0: ad = de->de_Exec;  break;
  377.   case 1: ad = de->de_Image; break;
  378.   case 2: ad = de->de_Sound; break;
  379.  }
  380.  
  381.  ENTRYLIST_LOG(LOG1(Attach data, "0x%08lx", ad))
  382.  
  383.  /* Call edit method on the object */
  384.  if (ad) DoMethod(ad->ad_Object, TMM_Edit, NULL);
  385.  
  386.  /* Return 1 to indicate that the method is implemented */
  387.  return(1);
  388. }
  389.  
  390. /* EntryList class method dispatcher */
  391. #undef  DEBUGFUNCTION
  392. #define DEBUGFUNCTION EntryListClassDispatcher
  393. __geta4 static ULONG EntryListClassDispatcher(__a0 Class *cl, __a2 Object *obj,
  394.                                               __a1 Msg msg)
  395. {
  396.  ULONG rc;
  397.  
  398. #if DEBUG_VERY_NOISY
  399.  /* This just generates too much debug output... */
  400.  ENTRYLIST_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  401.                     cl, obj, msg))
  402. #endif
  403.  
  404.  switch(msg->MethodID) {
  405.   /* BOOPSI methods */
  406.   case OM_NEW:
  407.    rc = EntryListClassNew(cl, obj, (struct opSet *) msg);
  408.    break;
  409.  
  410.   /* MUI methods */
  411.   case MUIM_DragQuery:
  412.    rc = EntryListClassDragQuery(cl, obj, (struct MUIP_DragQuery *) msg);
  413.    break;
  414.  
  415.   case MUIM_DragDrop:
  416.    rc = EntryListClassDragDrop(cl, obj, (struct MUIP_DragDrop *) msg);
  417.    break;
  418.  
  419.   /* TM methods */
  420.   case TMM_Notify:
  421.    rc = EntryListClassNotify(cl, obj, (struct TMP_Notify *) msg);
  422.    break;
  423.  
  424.   case TMM_WBArg:
  425.    rc = EntryListClassWBArg(cl, obj, (struct TMP_WBArg *) msg);
  426.    break;
  427.  
  428.   case TMM_Column:
  429.    rc = EntryListClassColumn(cl, obj, (struct TMP_Column *) msg);
  430.    break;
  431.  
  432.   /* Unknown method -> delegate to SuperClass */
  433.   default:
  434.    rc = DoSuperMethodA(cl, obj, msg);
  435.    break;
  436.  }
  437.  
  438.  return(rc);
  439. }
  440.  
  441. /* Create EntryList class */
  442. #undef  DEBUGFUNCTION
  443. #define DEBUGFUNCTION CreateEntryListClass
  444. struct MUI_CustomClass *CreateEntryListClass(void)
  445. {
  446.  struct MUI_CustomClass *rc;
  447.  
  448.  /* Create class */
  449.  if (rc = MUI_CreateCustomClass(NULL, MUIC_List, NULL,
  450.                                 sizeof(struct EntryListClassData),
  451.                                 EntryListClassDispatcher)) {
  452.  
  453.   /* Localize strings */
  454.   TextColumnExec  = TranslateString(LOCALE_TEXT_ENTRYLIST_COLUMN_EXEC_STR,
  455.                                     LOCALE_TEXT_ENTRYLIST_COLUMN_EXEC);
  456.   TextColumnImage = TranslateString(LOCALE_TEXT_ENTRYLIST_COLUMN_IMAGE_STR,
  457.                                     LOCALE_TEXT_ENTRYLIST_COLUMN_IMAGE);
  458.   TextColumnSound = TranslateString(LOCALE_TEXT_ENTRYLIST_COLUMN_SOUND_STR,
  459.                                     LOCALE_TEXT_ENTRYLIST_COLUMN_SOUND);
  460.  }
  461.  
  462.  ENTRYLIST_LOG(LOG1(Result, "0x%08lx", rc))
  463.  
  464.  return(rc);
  465. }
  466.