home *** CD-ROM | disk | FTP | other *** search
- /*
- * This program will create new text for a specified menu item.
- * The new text will reside in a node linked on to the UserData
- * field of the window it resides in.
- *
- * Problem: the new text will never be de-allocated unless by
- * this program (ie it stays around and waits for the window to
- * close). Or by another program that looks at the window->UserData
- * field. Use the RESTORE program I've included with this one to
- * unlink the new menuitems before closing the window.
- *
- * ((c)) 1987, John Russell. Unlimited distribution, but donations to
- * starving programmers welcome.
- *
- */
-
- #include "intuition/intuition.h"
- #include "stdio.h"
- #include "exec/memory.h"
-
- char *name = "John Russell";
- char *address = "5 Alderdice Place";
- char *province = "St. John's, Newfoundland, Canada";
- char *postal_code = "A1B 2P8";
- char *phone = "(709) 726-7847";
-
- void copy();
- char *gets(); /* I couldn't seem to get this to "clip" properly */
-
- struct IntuitionBase *IntuitionBase;
-
- struct node {
- struct node *next; /* link to next node */
- char text[46]; /* buffer for menu text */
- char *old_text; /* save location for program's pointer */
- short old_item_width; /* save location for hitbox width */
- struct MenuItem *altered; /* pointer to menuitem we alter */
- } *node,*ptr,*findnode();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- struct Window *window;
- struct Screen *screen;
- struct MenuItem *item;
- struct Menu *menu,*main_menu;
- int x,text;
- short width;
- char line_buf[100]; /* buffer for gets() to handle too-long strings */
-
- text = argc-1; /* *argv[text] == text to assign */
-
- if ((IntuitionBase=(struct IntuitionBase *)
- OpenLibrary("intuition.library",0L))==NULL) {
- puts("Where is Intuition gone???\n");
- exit(0);
- }
-
- /* print instructions if wrong number of arguments */
-
- if ((argc > 6) || (argc < 5)) {
- puts("Usage: menutext <window> <menunum> <itemnum>\n\
- [ <subitemnum> ] <new_text | \"-ask\">");
- puts("\nEG - menutext FooBar 1 4 testing\n\
- menutext VT100 2 1 3 high_speed\n\
- menutext Notepad 1 1 -ask");
- exit(0);
- }
-
- Forbid();
-
- screen = IntuitionBase->FirstScreen; /* address of Workbench screen structure */
-
- while (screen) { /* do all screens */
-
- window = screen->FirstWindow;
-
- while (window) { /* do all windows */
-
- if (compare(argv[1],window->Title)==0) { /* search for name */
-
- x=atoi(argv[2]); /* menu # */
- menu = window->MenuStrip;
- main_menu = menu; /* main menu of window for SetMenuStrip */
-
- while (--x > 0) { /* scan menu list */
- if ((menu = menu->NextMenu) == NULL)
- goto quit;
- }
-
- x = atoi(argv[3]); /* item # */
- item = menu->FirstItem;
- submenu:
- while (--x > 0) { /* scan item list */
- if ((item = item->NextItem) == NULL)
- goto quit;
- }
-
- if (argc==6) { /* descend into sub-menu? */
- argc=0;
- item=item->SubItem;
- x=atoi(argv[4]); /* sub-item # */
- goto submenu;
- }
-
- ClearMenuStrip(window); /* disable menu structure */
-
- /*
- * First check to see if this menu item has already been redefined, by
- * scanning the list from window->UserData. If it has, do no node creation
- * or re-linking, just copy the text over the node's old text.
- *
- * If this is the first time the menu item has received new text, create
- * a new node, record which menu item is being altered, and preserve a
- * pointer to the original text used by the program, so we can undo all
- * of this later. Also record how wide the original hitbox was for future
- * reference.
- *
- * A new hitbox width is created if a new, longer string is put into the
- * menu. If a keyboard shortcut exists for that item, the hitbox is widened
- * to take that into account.
- *
- */
-
- if ( (node = findnode(window,item)) == NULL) {
-
- node = (struct node *)
- AllocMem(sizeof(struct node),MEMF_CHIP|MEMF_CLEAR);
- node->next = window->UserData; /* insert in first place */
- window->UserData = node; /* link into window structure */
- node->altered = item;
- node->old_text = item->ItemFill->IText; /* save old text */
- node->old_item_width = item->Width; /* save old width */
- item->ItemFill->IText = node->text; /* change menu itself */
-
- }
-
- if (compare(argv[text],"-ask")) {
- copy(argv[text],node->text); /* special strncpy() */
- }
- else {
- printf("Enter new menu text: ");
- gets(line_buf,45); /* "45" ignored? seems that way */
- copy(line_buf,node->text);
- }
-
- /* alter width if necessary, so you don't have long menutexts with very */
- /* short complemented or boxed areas. font-size is fixed at 8 because */
- /* the "TextAttr" structure is not in the Intuition manual, and the RKM */
- /* is not handy. */
-
- width = ((length(node->text)) * 8) +
- (item->Flags & COMMSEQ ? COMMWIDTH : 0);
-
- if (width > node->old_item_width) {
- item->Width = width; /* don't shorten, just lengthen */
- }
-
- /* debugging info left in. This program, although it works fine, can be */
- /* (and will be) revised extensively. */
-
- ptr = window->UserData;
-
- printf("Replacing menutext \"%s\" with \"%s\"\n\n",
- node->old_text,node->text);
-
- printf("Current changed definitions:\n");
-
- while (ptr) {
- printf("\tOld text: %s\n\tNew text: %s\n\n",
- ptr->old_text,ptr->text);
- ptr = ptr->next;
- }
-
- SetMenuStrip(window,main_menu); /* give it back */
- }
- window = window->NextWindow;
- }
- screen = screen->NextScreen;
- }
-
- quit:
- Permit();
- CloseLibrary(IntuitionBase);
-
- }
-
- compare(string1,string2) /* if spaces in windowname, only check first word */
- char *string1,*string2;
- {
- while ((*string1 != '\0') && (*string1 != ' ')) {
- if (*string1++ != *string2++) /* space and null both end conditions */
- return(1);
- }
- return(0); /* return weird values like strcmp() */
- }
-
- void copy(string1,string2) /* modified strncpy */
- char *string1,*string2;
- {
- int count = 44; /* (44 + space + null) will fill available buffer */
-
- while ((*string1 != '\0') && count) {
- *string2++ = *string1++;
- count--;
- }
- *string2++ = ' '; /* always end string with space + null */
- *string2++ = '\0'; /* otherwise menus with shortcuts are messy */
- }
-
- struct node *findnode(window,item) /* does item already have attached node? */
- struct Window *window;
- struct MenuItem *item;
- {
- struct node *ptr;
-
- ptr = window->UserData;
-
- while (ptr) {
- if (ptr->altered == item) /* if desired item already redefined */
- return(ptr); /* this is the node to use */
-
- ptr = ptr->next;
- }
-
- return(NULL); /* search failed, send message to create and link node */
- }
-
- length(string) /* I hate (and don't really trust) std C string functions */
- char *string;
- {
- int x=0;
-
- while (*string++)
- x++;
-
- return(x);
- }
-
-