Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / utilities / MultiView / misc.c
blobde59159f39d2d14e69ac88a010a505c34b3afd48
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*********************************************************************************************/
8 #include "global.h"
9 #include "version.h"
11 #include <string.h>
13 #include "compilerspecific.h"
14 #include "debug.h"
16 /*********************************************************************************************/
18 static struct MenuItem * FindMenuItem( struct Menu *menu, ULONG msgid );
19 static void ChangeItemState( ULONG msgid, BOOL state );
21 /*********************************************************************************************/
23 struct NewMenu nm[] =
25 {NM_TITLE, (STRPTR)MSG_MEN_PROJECT }, /* 0 */
26 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_OPEN },
27 {NM_ITEM, NM_BARLABEL },
28 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_SAVEAS },
29 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_SAVEAS_IFF },
30 {NM_ITEM, NM_BARLABEL },
31 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_PRINT },
32 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_ABOUT },
33 {NM_ITEM, NM_BARLABEL },
34 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_QUIT },
35 {NM_TITLE, (STRPTR)MSG_MEN_EDIT }, /* 1 */
36 {NM_ITEM, (STRPTR)MSG_MEN_EDIT_MARK },
37 {NM_ITEM, (STRPTR)MSG_MEN_EDIT_COPY },
38 {NM_ITEM, NM_BARLABEL },
39 {NM_ITEM, (STRPTR)MSG_MEN_EDIT_SELECTALL },
40 {NM_ITEM, (STRPTR)MSG_MEN_EDIT_CLEARSELECTED },
41 {NM_TITLE, (STRPTR)MSG_MEN_WINDOW }, /* 2 */
42 {NM_ITEM, (STRPTR)MSG_MEN_WINDOW_SEPSCREEN , 0, CHECKIT | MENUTOGGLE },
43 {NM_ITEM, NM_BARLABEL },
44 {NM_ITEM, (STRPTR)MSG_MEN_WINDOW_MINIMIZE },
45 {NM_ITEM, (STRPTR)MSG_MEN_WINDOW_NORMAL },
46 {NM_ITEM, (STRPTR)MSG_MEN_WINDOW_MAXIMIZE },
47 {NM_TITLE, (STRPTR)MSG_MEN_SETTINGS }, /* 3 */
48 {NM_ITEM, (STRPTR)MSG_MEN_SETTINGS_SAVEDEF },
49 {NM_END}
52 struct NewMenu nmpict[] =
54 {NM_TITLE, (STRPTR)MSG_MEN_PICT },
55 {NM_ITEM, (STRPTR)MSG_MEN_PICT_ZOOM_IN },
56 {NM_ITEM, (STRPTR)MSG_MEN_PICT_ZOOM_OUT },
57 {NM_ITEM, (STRPTR)MSG_MEN_PICT_RESET },
58 {NM_ITEM, NM_BARLABEL },
59 {NM_ITEM, (STRPTR)MSG_MEN_PICT_FIT_WIN , 0, CHECKIT | MENUTOGGLE },
60 {NM_ITEM, (STRPTR)MSG_MEN_PICT_KEEP_ASPECT , 0, CHECKIT | MENUTOGGLE },
61 {NM_ITEM, NM_BARLABEL },
62 {NM_ITEM, (STRPTR)MSG_MEN_PICT_FORCE_MAP , 0, CHECKIT | MENUTOGGLE },
63 {NM_ITEM, (STRPTR)MSG_MEN_PICT_DITHER , 0, CHECKIT | MENUTOGGLE | CHECKED },
64 {NM_END}
67 struct NewMenu nmtext[] =
69 {NM_TITLE, (STRPTR)MSG_MEN_TEXT },
70 {NM_ITEM, (STRPTR)MSG_MEN_TEXT_WORDWRAP , 0, CHECKIT | MENUTOGGLE },
71 {NM_ITEM, (STRPTR)MSG_MEN_TEXT_SEARCH },
72 {NM_ITEM, (STRPTR)MSG_MEN_TEXT_SEARCH_PREV },
73 {NM_ITEM, (STRPTR)MSG_MEN_TEXT_SEARCH_NEXT },
74 {NM_END}
77 /*********************************************************************************************/
79 static struct MenuItem * FindMenuItem( struct Menu *menu, ULONG msgid )
81 struct MenuItem *item;
83 while( menu )
85 if( (ULONG)GTMENU_USERDATA(menu) == msgid )
86 return (struct MenuItem *)menu;
87 item = menu->FirstItem;
88 while( item )
90 if( (ULONG)GTMENUITEM_USERDATA(item) == msgid )
91 return item;
92 item = item->NextItem;
94 menu = menu->NextMenu;
96 return NULL;
99 /*********************************************************************************************/
101 static void ChangeItemState( ULONG msgid, BOOL state )
103 struct MenuItem *item;
105 item = FindMenuItem(menus, msgid);
106 if (item)
108 if (state) item->Flags |= ITEMENABLED; else item->Flags &= ~ITEMENABLED;
112 /*********************************************************************************************/
114 void InitMenus(struct NewMenu *newm)
116 struct NewMenu *actnm;
118 for(actnm = newm; actnm->nm_Type != NM_END; actnm++)
120 if (actnm->nm_Label != NM_BARLABEL)
122 ULONG id = (ULONG)actnm->nm_Label;
123 CONST_STRPTR str = MSG(id);
125 if (actnm->nm_Type == NM_TITLE)
127 actnm->nm_Label = str;
128 } else {
129 actnm->nm_Label = str + 2;
130 if (str[0] != ' ') actnm->nm_CommKey = str;
132 actnm->nm_UserData = (APTR)id;
134 } /* if (actnm->nm_Label != NM_BARLABEL) */
136 } /* for(actnm = nm; nm->nm_Type != NM_END; nm++) */
140 /*********************************************************************************************/
142 struct Menu * MakeMenus(struct NewMenu *newm)
144 struct Menu *menu;
145 struct TagItem menu_tags[] =
147 {GTMN_NewLookMenus, TRUE},
148 {TAG_DONE }
151 menu = CreateMenusA(newm, NULL);
152 if (!menu) Cleanup(MSG(MSG_CANT_CREATE_MENUS));
154 if (!LayoutMenusA(menu, vi, menu_tags))
156 FreeMenus(menu);
157 Cleanup(MSG(MSG_CANT_CREATE_MENUS));
159 return menu;
162 /*********************************************************************************************/
164 void KillMenus(void)
166 if (win) ClearMenuStrip(win);
167 if (menus) FreeMenus(menus);
168 if (pictmenus) FreeMenus(pictmenus);
169 if (textmenus) FreeMenus(textmenus);
171 menus = NULL;
172 pictmenus = NULL;
173 textmenus = NULL;
176 /*********************************************************************************************/
178 void SetMenuFlags(void)
180 struct Menu *menu;
181 struct MenuItem *item;
182 IPTR val;
183 BOOL ret;
185 if (win) ClearMenuStrip(win);
187 ChangeItemState( MSG_MEN_PROJECT_SAVEAS, dto_supports_write );
188 ChangeItemState( MSG_MEN_PROJECT_SAVEAS_IFF, dto_supports_write_iff );
189 ChangeItemState( MSG_MEN_PROJECT_PRINT, dto_supports_print );
190 ChangeItemState( MSG_MEN_EDIT_COPY, dto_supports_copy );
191 ChangeItemState( MSG_MEN_EDIT_SELECTALL, dto_supports_selectall );
192 ChangeItemState( MSG_MEN_EDIT_CLEARSELECTED, dto_supports_clearselected );
194 item = FindMenuItem(menus, MSG_MEN_SETTINGS); /* Search last menu, then append dt group dependent menu */
195 menu = (struct Menu *)item;
196 if (menu)
198 if (dto_subclass_gid == GID_PICTURE)
200 D(bug("Multiview: is picture.datatype\n"));
201 menu->NextMenu = pictmenus;
203 else if (dto_subclass_gid == GID_TEXT)
205 D(bug("Multiview: is text.datatype\n"));
206 menu->NextMenu = textmenus;
207 ret = GetDTAttrs(dto, TDTA_WordWrap, (IPTR)&val, TAG_DONE);
208 item = FindMenuItem(menus, MSG_MEN_TEXT_WORDWRAP);
209 if (ret && item)
211 if (val) item->Flags |= CHECKED; else item->Flags &= ~CHECKED;
213 ChangeItemState( MSG_MEN_TEXT_WORDWRAP, ret );
214 ChangeItemState( MSG_MEN_TEXT_SEARCH, dto_supports_search );
215 ChangeItemState( MSG_MEN_TEXT_SEARCH_PREV, dto_supports_search_prev );
216 ChangeItemState( MSG_MEN_TEXT_SEARCH_NEXT, dto_supports_search_next );
218 else
220 D(bug("Multiview: is unknown datatype\n"));
221 menu->NextMenu = NULL;
226 struct TagItem menu_tags[] =
228 {GTMN_NewLookMenus, TRUE},
229 {TAG_DONE }
232 LayoutMenusA(menus, vi, menu_tags);
235 if (win) SetMenuStrip(win, menus);
238 /*********************************************************************************************/
240 STRPTR GetFileName(ULONG msgtextid)
242 static UBYTE pathbuffer[300];
243 static UBYTE filebuffer[300];
244 struct FileRequester *req;
245 STRPTR filepart, retval = NULL;
247 AslBase = OpenLibrary("asl.library", 39);
248 if (AslBase)
250 filebuffer[299] = 0;
251 pathbuffer[299] = 0;
253 strncpy(filebuffer, FilePart(filenamebuffer), 299);
254 strncpy(pathbuffer, filenamebuffer, 299);
255 filepart = FilePart(pathbuffer);
256 *filepart = 0;
258 req = AllocAslRequestTags(ASL_FileRequest, ASLFR_TitleText , (IPTR)MSG(msgtextid),
259 ASLFR_DoPatterns , TRUE ,
260 ASLFR_InitialFile , (IPTR)filebuffer ,
261 ASLFR_InitialDrawer, (IPTR)pathbuffer ,
262 ASLFR_Window , (IPTR)win ,
263 TAG_DONE);
264 if (req)
266 if (AslRequest(req, NULL))
268 strncpy(filebuffer, req->fr_Drawer, 299);
269 AddPart(filebuffer, req->fr_File, 299);
271 retval = filebuffer;
273 } /* if (AslRequest(req, NULL) */
275 FreeAslRequest(req);
277 } /* if (req) */
279 CloseLibrary(AslBase);
281 } /* if (AslBase) */
283 return retval;
286 /*********************************************************************************************/
288 void About(void)
290 struct DataType *dt = NULL;
291 struct EasyStruct es;
292 STRPTR gid_string = NULL;
293 STRPTR name_string = NULL;
294 STRPTR sp;
295 WORD i;
296 UBYTE dtver_string[100];
298 if (GetDTAttrs(dto, DTA_DataType, (IPTR)&dt, TAG_DONE))
300 if (dt)
302 gid_string = GetDTString(dt->dtn_Header->dth_GroupID);
303 name_string = dt->dtn_Header->dth_Name;
307 if (!gid_string) gid_string = "";
308 if (!name_string) name_string = "";
310 for(sp = DataTypesBase->lib_IdString;
311 (*sp != 0) && ((*sp < '0') || (*sp > '9'));
312 sp++)
316 i = 0;
317 while ((*sp != 0) && (*sp != '\r') && (*sp != '\n') && (i < 99))
319 dtver_string[i++] = *sp++;
321 dtver_string[i++] = '\0';
323 es.es_StructSize = sizeof(es);
324 es.es_Flags = 0;
325 es.es_Title = MSG(MSG_ABOUT_TITLE);
326 es.es_TextFormat = MSG(MSG_ABOUT);
327 es.es_GadgetFormat = MSG(MSG_CONTINUE);
329 EasyRequest(win, &es, NULL, (IPTR)VERSION,
330 (IPTR)REVISION,
331 (IPTR)DATESTR,
332 (IPTR)dtver_string,
333 (IPTR)name_string,
334 (IPTR)gid_string);
338 /*********************************************************************************************/
340 ULONG DoTrigger(ULONG what)
342 struct dtTrigger msg;
344 msg.MethodID = DTM_TRIGGER;
345 msg.dtt_GInfo = NULL;
346 msg.dtt_Function = what;
347 msg.dtt_Data = NULL;
349 return DoDTMethodA(dto, win, NULL, (Msg)&msg);
352 /*********************************************************************************************/
354 ULONG DoWriteMethod(STRPTR name, ULONG mode)
356 struct dtWrite msg;
357 BPTR fh;
358 ULONG retval;
360 fh = NULL;
361 if (name)
363 fh = Open( name, MODE_NEWFILE );
364 if (!fh)
366 D(bug("Multiview: Cannot open %s\n", name));
367 OutputMessage(MSG(MSG_SAVE_FAILED));
368 return FALSE;
374 msg.MethodID = DTM_WRITE;
375 msg.dtw_GInfo = NULL;
376 msg.dtw_FileHandle = fh;
377 msg.dtw_Mode = mode;
378 msg.dtw_AttrList = NULL;
380 D(bug("Multiview: Saving %s mode %ld\n", name ? name : (STRPTR)"[nothing]", mode));
381 retval = DoDTMethodA(dto, win, NULL, (Msg)&msg);
382 if (fh)
384 Close( fh );
385 if( !retval )
387 D(bug("Multiview: Error during write !\n"));
388 OutputMessage(MSG(MSG_SAVE_FAILED));
391 return retval;
394 /*********************************************************************************************/
396 ULONG DoLayout(ULONG initial)
398 ULONG res;
399 struct gpLayout msg;
401 D(bug("=> erase\n"));
402 EraseRect(win->RPort, win->BorderLeft,
403 win->BorderTop,
404 win->Width - 1 - win->BorderRight,
405 win->Height - 1 - win->BorderBottom);
407 #if 1
408 msg.MethodID = GM_LAYOUT;
409 msg.gpl_GInfo = NULL;
410 msg.gpl_Initial = initial;
412 #if 0
413 D(bug("=> doasynclayout libcall\n"));
414 res = DoAsyncLayout(dto, &msg);
415 #else
416 D(bug("=> GM_Layout method\n"));
417 res = DoDTMethodA(dto, win, 0, (Msg)&msg);
418 #endif
419 D(bug("layout result %ld\n", res));
420 return res;
421 #else
422 RemoveDTObject(win, dto);
423 AddDTObject(win, NULL, dto, -1);
424 #endif
427 /*********************************************************************************************/
429 ULONG DoScaleMethod(ULONG xsize, ULONG ysize, BOOL aspect)
431 struct pdtScale msg;
433 D(bug(" scale width %d height %d\n", xsize, ysize));
434 msg.MethodID = PDTM_SCALE;
435 msg.ps_NewWidth = xsize;
436 msg.ps_NewHeight = ysize;
437 msg.ps_Flags = aspect ? PScale_KeepAspect : 0;
438 // D(bug("- method %08lx newwidth %ld newheight %ld flags %08lx\n", msg.MethodID, msg.ps_NewWidth, msg.ps_NewHeight, msg.ps_Flags));
440 return DoMethodA(dto, (Msg)&msg);
443 /*********************************************************************************************/
445 void DoZoom(WORD zoomer)
447 UWORD curwidth, curheight;
449 if (zoomer > 0)
451 curwidth = pdt_origwidth * zoomer;
452 curheight = pdt_origheight * zoomer;
454 else
456 curwidth = pdt_origwidth / -zoomer;
457 curheight = pdt_origheight / -zoomer;
459 D(bug(" zoom %d width %d height %d\n", zoomer, curwidth, curheight));
460 DoScaleMethod(curwidth, curheight, 0);
461 DoLayout(TRUE);
464 /*********************************************************************************************/