home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
- ***********************************************************************
- ** **
- ** Menucure.c **
- ** **
- ** Historique Nom Description **
- ** ---------- ------------ ---------------------------------- **
- ** 06-05-88 Eric Le Saux Version originale **
- ** Jean Pepin **
- ** **
- ***********************************************************************
- *********************************************************************/
-
- /*********************************************************************
- ***********************************************************************
- ** **
- ** Club Amiga Montréal (CAM) **
- ** C.P. 195 STATION "N" **
- ** Montréal (Québec) **
- ** H2X 3M2, CANADA **
- ** **
- ** Je veux être propagé comme un virus ! **
- ** **
- ** DOMAINE PUBLIC - Distribution non-commerciale **
- ** PUBLIC DOMAIN - Freely redistributable **
- ** **
- ***********************************************************************
- *********************************************************************/
-
- #include <Menucure.h>
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Comparaisons de chaînes de caractères avec wildcards.
- **
- ** Certains titres d'écrans et de fenêtres ont des parties variantes,
- ** pour les reconnaître, on permet l'usage de certaines wildcards.
- **
- ** '?' pour empecher la comparaison
- ** '#' pour arreter la comparaison
- **
- ** Retourne TRUE quand les chaînes sont identiques.
- */
-
- BOOL StrCmp (S1, S2)
- STRPTR S1, S2;
- {
- FOREVER
- {
- if ( (*S1 != '\0') && (*S1 != '\0') )
- {
- if ( (*S1 != '?') && (*S2 != '?') )
- {
- if ( (*S1 == '#') || (*S2 == '#') ) return (TRUE);
-
- if (*S1 != *S2) return (FALSE);
- }
- }
- else return (*S1 == *S2);
-
- S1++;
- S2++;
- }
-
- return (*(S1-1) == *(S2-1));
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Copie d'une chaîne de caractères dans une autre.
- **
- ** N est la taille du buffer S1, incluant le terminateur '\0'.
- ** On copie jusqu'à N-1 caractères de S2 vers S1.
- **
- ** Si S2 est trop grande, l'avant-dernier caractère a être mis dans S1
- ** est celui de troncation : '#'.
- **
- */
-
- void StrNCpy (S1, S2, N)
- UBYTE *S1, *S2;
- SHORT N;
- {
- while ( --N && (*S1++ = *S2++) );
-
- if (!N)
- {
- *S1 = '\0';
- *(S1-1)='#';
- }
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Calcule le nombre d'occurences d'un caractère dans un fichier
- **
- */
-
- SHORT Occurences (Fichier, Car)
- FILE *Fichier;
- UBYTE Car;
- {
- LONG Pos;
- SHORT C;
- SHORT N = 0;
-
- Pos = ftell (Fichier);
-
- while ( (C=getc(Fichier)) != EOF ) if ( C == SEP ) N++;
-
- fseek (Fichier, Pos, 0);
-
- return (N);
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Modification de la largeur d'un menu et de ses items.
- **
- */
-
- void ChangeLargeur(Item, LargeurFonte, LargeurEcran)
- struct MenuItem * Item;
- SHORT LargeurFonte;
- SHORT LargeurEcran;
- {
- struct MenuItem * Ptr = Item;
- SHORT Max = 0, L;
- SHORT LargeurTotale;
- SHORT CoteGauche = Item->LeftEdge;
- BOOL Commandes = FALSE;
- BOOL CheckMarks = FALSE;
-
- while (Ptr)
- {
- if ( (L=strlen(((IT *)Ptr->ItemFill)->IText)) > Max )
- Max = L;
- if (Ptr->Flags & COMMSEQ) Commandes = TRUE;
- if (Ptr->Flags & CHECKIT) CheckMarks = TRUE;
- Ptr = Ptr->NextItem;
- }
-
- LargeurTotale = LargeurFonte * Max;
- if (Commandes) LargeurTotale += COMWIDTH;
- if (CheckMarks) LargeurTotale += COMWIDTH/2;
-
- if ( (L=CoteGauche+LargeurTotale+20) > LargeurEcran )
- CoteGauche -= (L-LargeurEcran);
-
- Ptr = Item;
-
- while (Ptr)
- {
- Ptr->LeftEdge = CoteGauche;
- Ptr->Width = LargeurTotale;
- Ptr = Ptr->NextItem;
- }
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Modification de menus
- **
- */
-
- void ChangeMenus (Table, N)
-
- struct TableCom *Table;
- SHORT N;
-
- {
- struct Screen * Ecran;
- struct Window * Fenetre;
- struct Menu * Menu;
- struct Menu * BandeMenu;
- struct MenuItem * Item;
- struct MenuItem * SubItem;
- ULONG Lock;
-
-
- Lock = LockIBase (0L);
-
- Ecran = PREMIER_ECRAN;
-
- while (Ecran)
- {
- if (StrCmp(Ecran->Title,Table->NomEcran))
- {
- Fenetre = Ecran->FirstWindow;
-
- while (Fenetre)
- {
- if (StrCmp(Fenetre->Title,Table->NomFenetre))
- {
- BandeMenu = Menu = Fenetre->MenuStrip;
-
- ClearMenuStrip (Fenetre);
-
- while (Menu)
- {
- if (StrCmp(Menu->MenuName,Table->NomMenu))
- {
- Item = Menu->FirstItem;
-
- while (Item && ( (Item->Flags & ITEMTEXT) || (Item->SubItem) ) )
- {
- if (StrCmp (((IT *)Item->ItemFill)->IText,Table->NomItem))
- {
- if (Table->NomSubItem[0]) /* s'il y a un sous-item */
- {
- SubItem = Item->SubItem;
-
- while (SubItem && (SubItem->Flags & ITEMTEXT) )
- {
- if (StrCmp (((IT *)SubItem->ItemFill)->IText,Table->NomSubItem))
- {
- SubItem->Command = Table->Commande;
-
- if (Table->Commande != NOCOM)
- {
- if ( ! (SubItem->Flags & COMMSEQ) )
- {
- SubItem->Flags |= COMMSEQ;
- ChangeLargeur (Item->SubItem,
- Fenetre->RPort->Font->tf_XSize,
- Ecran->Width);
- }
- }
- else if (SubItem->Flags & COMMSEQ)
- {
- SubItem->Flags &= ~COMMSEQ;
- ChangeLargeur (Item->SubItem,
- Fenetre->RPort->Font->tf_XSize,
- Ecran->Width);
- }
-
- Table->Modifie = TRUE;
- }
-
- SubItem = SubItem->NextItem;
- Table++;
- }
- }
- else /* Item */
- {
- Item->Command = Table->Commande;
-
- if (Table->Commande != NOCOM)
- {
- if ( ! (Item->Flags & COMMSEQ) )
- {
- Item->Flags |= COMMSEQ;
- ChangeLargeur (Menu->FirstItem,
- Fenetre->RPort->Font->tf_XSize,
- Ecran->Width);
- }
- }
- else if (Item->Flags & COMMSEQ)
- {
- Item->Flags &= ~COMMSEQ;
- ChangeLargeur (Menu->FirstItem,
- Fenetre->RPort->Font->tf_XSize,
- Ecran->Width);
- }
-
- Table->Modifie = TRUE;
- Table++;
- }
- }
-
- Item = Item->NextItem;
- }
- }
-
- Menu = Menu->NextMenu;
- }
-
- SetMenuStrip (Fenetre, BandeMenu);
- }
-
- Fenetre = Fenetre->NextWindow;
- }
- }
-
- Ecran = Ecran->NextScreen;
- }
-
- UnlockIBase (Lock);
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Lecture de la prochaine string dans le fichier
- **
- ** TRUE si le séparateur attendu est rencontré.
- */
-
- BOOL LectureString (Fichier, StrPtr)
- FILE *Fichier;
- STRPTR StrPtr;
- {
- STRPTR Ptr = StrPtr;
- SHORT Car;
- SHORT N = 0;
-
- while ( ((Car=getc(Fichier)) != EOF) && (Car != SEP) && (N<(MAX-1)) )
- {
- *Ptr++ = Car;
- N++;
- }
-
- if (Car == EOF) return (FALSE);
- if ( (Car == SEP) || (N == (MAX-1)) ) *Ptr = '\0';
-
- return (TRUE);
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Allocation de la table des menus
- **
- */
-
- LONG AlloueTable (Table, NbMenus)
- struct TableCom **Table;
- SHORT NbMenus;
- {
- LONG BytesRequises;
-
- BytesRequises = NbMenus * sizeof (struct TableCom);
-
- *Table = AllocMem (BytesRequises, MEMF_PUBLIC|MEMF_CLEAR);
-
- return (BytesRequises);
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Lecture des menus à partir du fichier passé en paramètre
- **
- */
-
- void LectureMenus (Fichier, CLI)
- FILE *Fichier;
- BOOL CLI;
- {
- struct TableCom *Table;
- SHORT Car;
- SHORT NbMenus;
- LONG Taille;
- SHORT N, M;
-
- /*** Allocation de la table des menus ***/
-
- if ( ! (NbMenus = Occurences (Fichier,SEP) / 6 ) ) return;
-
- if ( ! (Taille = AlloueTable (&Table,NbMenus)) )
- {
- if (CLI) printf (ERRMEM);
- else DisplayBeep (NULL);
-
- return;
- }
-
- /*** Lecture du fichier ***/
-
- for (N=0; N<NbMenus; N++)
- {
- while ( ((Car=getc(Fichier)) != EOF) && (Car != SEP) );
-
- if (Car == EOF) break;
-
- if (!LectureString(Fichier,Table[N].NomEcran)) break;
- if (!LectureString(Fichier,Table[N].NomFenetre)) break;
- if (!LectureString(Fichier,Table[N].NomMenu)) break;
- if (!LectureString(Fichier,Table[N].NomItem)) break;
- if (!LectureString(Fichier,Table[N].NomSubItem)) break;
-
- Table[N].Commande = getc(Fichier);
-
- Table[N].Modifie = FALSE;
- }
-
- /*** Application de la table ***/
-
- ChangeMenus (Table, N);
-
- /*** Messages d'erreurs pour les menus non-modifiés ***/
-
- for (M=0; M<N; M++)
- if (!Table[M].Modifie)
- if (CLI)
- {
- printf ("%s->%s->%s->%s->%s non-modifié pour '%c'\n",
- Table[M].NomEcran, Table[M].NomFenetre,
- Table[M].NomMenu, Table[M].NomItem,
- Table[M].NomSubItem, Table[M].Commande);
- }
- else
- {
- DisplayBeep (NULL);
- }
-
- /*** Déallocation de la table des menus ***/
-
- FreeMem (Table, Taille);
-
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Affichage des menus
- **
- ** Deux passes : la première pour compter le nb de menus à enregistrer,
- ** la deuxième pour les enregistrer.
- **
- ** Retourne FALSE s'il a manqué de mémoire pour la table.
- */
-
- BOOL AfficheMenus (Fichier, CLI)
- FILE * Fichier;
- BOOL CLI;
- {
- struct Screen * Ecran;
- struct Window * Fenetre;
- struct Menu * Menu;
- struct MenuItem * Item;
- struct MenuItem * SubItem;
- ULONG Lock;
- SHORT Passe;
- SHORT NbMenus = 0;
- struct TableCom * Table;
- struct TableCom * Ptr;
- struct TableCom * Ptr2;
- LONG Taille;
-
-
- /*** Création de la table de menus ***/
-
- Lock = LockIBase (0L); /* Accès sécuritaire à IntuitionBase */
-
- for (Passe=0; Passe<2; Passe++)
- {
-
- if (Passe==1)
- {
- if (!NbMenus) /* Impossible à partir du WB */
- {
- printf (ERRNBMENUS);
-
- UnlockIBase (Lock);
- return (FALSE);
- }
-
- if ( ! (Taille = AlloueTable (&Table,NbMenus)) )
- {
- if (CLI) printf (ERRMEM);
- else DisplayBeep (NULL);
-
- UnlockIBase (Lock);
- return (FALSE);
- }
-
- Ptr2 = Ptr = Table;
- }
-
- Ecran = PREMIER_ECRAN;
-
- while (Ecran)
- {
- Fenetre = Ecran->FirstWindow;
-
- while (Fenetre)
- {
- Menu = Fenetre->MenuStrip;
-
- while (Menu)
- {
- Item = Menu->FirstItem;
-
- while (Item)
- {
- SubItem = Item->SubItem;
-
- if (SubItem) while (SubItem)
- {
- if (SubItem->Flags & ITEMTEXT)
- {
- if (Passe==1)
- {
- StrNCpy (Ptr->NomEcran,Ecran->Title,MAX);
- StrNCpy (Ptr->NomFenetre,Fenetre->Title,MAX);
- StrNCpy (Ptr->NomMenu,Menu->MenuName,MAX);
- StrNCpy (Ptr->NomItem,((IT *)Item->ItemFill)->IText,MAX);
- StrNCpy (Ptr->NomSubItem,((IT *)SubItem->ItemFill)->IText,MAX);
- Ptr->Commande = (SubItem->Flags & COMMSEQ)?SubItem->Command:NOCOM;
- Ptr++;
- }
- else NbMenus++;
- }
-
- SubItem = SubItem->NextItem;
- }
- else
- {
- if (Item->Flags & ITEMTEXT)
- {
- if (Passe==1)
- {
- StrNCpy (Ptr->NomEcran,Ecran->Title,MAX);
- StrNCpy (Ptr->NomFenetre,Fenetre->Title,MAX);
- StrNCpy (Ptr->NomMenu,Menu->MenuName,MAX);
- StrNCpy (Ptr->NomItem,((IT *)Item->ItemFill)->IText,MAX);
- Ptr->NomSubItem[0] = '\0';
- Ptr->Commande = (Item->Flags & COMMSEQ)?Item->Command:NOCOM;
- Ptr++;
- }
-
- else NbMenus++;
- }
- }
-
- Item = Item->NextItem;
- }
-
- Menu = Menu->NextMenu;
- }
-
- Fenetre = Fenetre->NextWindow;
- }
-
- Ecran = Ecran->NextScreen;
- }
- }
-
- UnlockIBase (Lock); /* On repermet l'accès à IntuitionBase */
-
-
- /*** Envoi de la table dans le fichier ***/
-
- while (Ptr2 < Ptr)
- {
- fprintf (Fichier, "¹%s¹%s¹%s¹%s¹%s¹%c\n",
- Ptr2->NomEcran,
- Ptr2->NomFenetre,
- Ptr2->NomMenu,
- Ptr2->NomItem,
- Ptr2->NomSubItem,
- Ptr2->Commande
- );
- Ptr2++;
- }
-
-
- /*** Déallocation de la table des menus ***/
-
- FreeMem (Table, Taille);
-
- return (TRUE);
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Création d'une liste de menus exécutable du WB
- **
- */
-
- void CreeWBListe (NomOutil)
- UBYTE *NomOutil;
- {
- FILE * Fichier;
- SHORT NbBytes;
- BOOL Resultat;
-
- /*** On écrit le fichier de données ***/
-
- Fichier = fopen (NOM_DATA, "w");
- if (!Fichier) return;
- Resultat = AfficheMenus (Fichier, FALSE);
- fclose (Fichier);
- if (!Resultat) unlink (NOM_DATA);
-
- /*** On crée son .info ***/
-
- Fichier = fopen (NOM_DATA_INFO, "w");
- if (!Fichier) return;
-
- for (NbBytes=0; NbBytes<LONGUEUR_INFO; NbBytes++)
- putc (DataInfo[NbBytes], Fichier);
-
- fprintf (Fichier, "%c%s", (UBYTE)strlen(NomOutil), NomOutil);
-
- fclose (Fichier);
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Lectures des menus passés en paramètres du WB
- **
- ** S'il n'y a pas d'argument, l'usager veut que l'on crée une liste
- ** des menus des fenêtres actuellement ouvertes.
- */
-
- void WBArguments (WBMsg)
- struct WBStartup *WBMsg;
- {
- struct WBArg *Arg = WBMsg->sm_ArgList;
- SHORT NbArgs;
- FILE *Fichier;
- UBYTE *NomOutil = (UBYTE *) Arg->wa_Name;
-
- Arg++; /* On saute l'outil lui-même */
-
- if (WBMsg->sm_NumArgs==1)
- CreeWBListe (NomOutil);
- else
- for (NbArgs=1; NbArgs<WBMsg->sm_NumArgs; NbArgs++)
- {
- Fichier = fopen (Arg->wa_Name, "r");
- if (Fichier)
- {
- LectureMenus (Fichier, FALSE);
- fclose (Fichier);
- }
- Arg++;
- }
- }
-
-
- /*********************************************************************
- ***********************************************************************
- **
- ** Programme principal
- **
- ** Workbench:
- ** Outil : crée un fichier de menus NOM_DATA avec icône.
- ** Projet(s) : applique les menus du(des) projet(s).
- ** CLI:
- ** 1> Menucure ; crée un fichier de menus NOM_DATA.
- ** 1> Menucure Fichier ; applique les menus du Fichier.
- ** 1> Menucure -f Fichier ; crée un fichier de menus Fichier.
- */
-
- main (argc, argv)
- SHORT argc;
- STRPTR argv[];
- {
- FILE *Fichier;
- BOOL Resultat;
-
- IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 33L);
- if (!IntuitionBase)
- {
- if (argc) printf ("Nécessite intuition.library v33 et +\n");
- exit (0);
- }
-
- if (argv[1] == '?') argc = 10; /* force l'aide */
-
- switch (argc)
- {
- case 0 : WBArguments (WBenchMsg);
- break;
-
- case 1 : Fichier = fopen (NOM_DATA, "w");
- if (Fichier)
- {
- Resultat = AfficheMenus (Fichier, TRUE);
- fclose (Fichier);
- if (Resultat)
- printf ("Fichier %s créé par défaut\n", NOM_DATA);
- else
- unlink (NOM_DATA);
- }
- else
- {
- printf ("Ne peut ouvrir le fichier de sortie\n");
- }
- break;
-
- case 3 : if ( *(argv[1]+1) == 'f' )
- {
- Fichier = fopen (argv[2], "w");
- if (Fichier)
- {
- Resultat = AfficheMenus (Fichier, TRUE);
- fclose (Fichier);
- if (!Resultat) unlink (argv[2]);
- }
- else
- {
- printf ("Ne peut ouvrir '%s'\n", argv[2]);
- }
- break;
- }
- else
- {
- printf ("Option inconnue.\n");
- }
-
- /** L'option 2 après 3, sinon on exécute le else de ce dernier ***/
-
- case 2 : if ( *argv[1] != '?' )
- {
- Fichier = fopen (argv[1], "r");
- if (!Fichier)
- {
- printf ("Fichier '%s' introuvable\n", argv[1]);
- break;
- }
- LectureMenus (Fichier, TRUE);
- fclose (Fichier);
- break;
- }
- /* Sinon il va aboutir dans le default: */
-
- default:
- printf ("\n== Club Amiga Montréal ==\n");
- printf ("Eric Le Saux & Jean Pepin\n");
- printf ("\nUSAGE\n\n");
- printf (" %s ; crée le fichier de menus '%s'\n", argv[0], NOM_DATA);
- printf (" %s Fichier ; applique les menus de 'Fichier'\n", argv[0]);
- printf (" %s -f Fichier ; crée un fichier de menus 'Fichier'\n\n", argv[0]);
- break;
- }
-
- CloseLibrary (IntuitionBase);
- }
-