Hint added.
[AROS.git] / workbench / utilities / MultiView / misc.c
blobf0e093af9c52ee13826e261abfacb061a13908a7
1 /*
2 Copyright © 1995-2016, 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 );
20 static void SetItemChecked( ULONG msgid, BOOL state );
22 /*********************************************************************************************/
24 #ifdef __AROS__
25 /* NOTE: AROS uses '%id' for IPTR arrays */
26 static const char internal_about_tmpl[] = "%s %id.%id (%s)\n%s %s\n\n%s %s\n%s %s\n%s %s";
27 #else
28 static const char internal_about_tmpl[] = "%s %ld.%ld (%s)\n%s %s\n\n%s %s\n%s %s\n%s %s";
29 #endif
31 /*********************************************************************************************/
33 struct NewMenu nm[] =
35 {NM_TITLE, (STRPTR)MSG_MEN_PROJECT }, /* 0 */
36 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_OPEN },
37 {NM_ITEM, NM_BARLABEL },
38 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_SAVEAS },
39 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_SAVEAS_IFF },
40 {NM_ITEM, NM_BARLABEL },
41 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_PRINT },
42 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_ABOUT },
43 {NM_ITEM, NM_BARLABEL },
44 {NM_ITEM, (STRPTR)MSG_MEN_PROJECT_QUIT },
45 {NM_TITLE, (STRPTR)MSG_MEN_EDIT }, /* 1 */
46 {NM_ITEM, (STRPTR)MSG_MEN_EDIT_MARK },
47 {NM_ITEM, (STRPTR)MSG_MEN_EDIT_COPY },
48 {NM_ITEM, NM_BARLABEL },
49 {NM_ITEM, (STRPTR)MSG_MEN_EDIT_SELECTALL },
50 {NM_ITEM, (STRPTR)MSG_MEN_EDIT_CLEARSELECTED },
51 {NM_TITLE, (STRPTR)MSG_MEN_WINDOW }, /* 2 */
52 {NM_ITEM, (STRPTR)MSG_MEN_WINDOW_SEPSCREEN , 0, CHECKIT | MENUTOGGLE },
53 {NM_ITEM, NM_BARLABEL },
54 {NM_ITEM, (STRPTR)MSG_MEN_WINDOW_MINIMIZE },
55 {NM_ITEM, (STRPTR)MSG_MEN_WINDOW_NORMAL },
56 {NM_ITEM, (STRPTR)MSG_MEN_WINDOW_MAXIMIZE },
57 {NM_TITLE, (STRPTR)MSG_MEN_SETTINGS }, /* 3 */
58 {NM_ITEM, (STRPTR)MSG_MEN_SETTINGS_SAVEDEF },
59 {NM_END}
62 struct NewMenu nmpict[] =
64 {NM_TITLE, (STRPTR)MSG_MEN_PICT },
65 {NM_ITEM, (STRPTR)MSG_MEN_PICT_ZOOM_IN },
66 {NM_ITEM, (STRPTR)MSG_MEN_PICT_ZOOM_OUT },
67 {NM_ITEM, (STRPTR)MSG_MEN_PICT_RESET },
68 {NM_ITEM, NM_BARLABEL },
69 {NM_ITEM, (STRPTR)MSG_MEN_PICT_FIT_WIN , 0, CHECKIT | MENUTOGGLE },
70 {NM_ITEM, (STRPTR)MSG_MEN_PICT_KEEP_ASPECT , 0, CHECKIT | MENUTOGGLE },
71 {NM_ITEM, NM_BARLABEL },
72 {NM_ITEM, (STRPTR)MSG_MEN_PICT_FORCE_MAP , 0, CHECKIT | MENUTOGGLE },
73 {NM_ITEM, (STRPTR)MSG_MEN_PICT_DITHER , 0, CHECKIT | MENUTOGGLE | CHECKED },
74 {NM_END}
77 struct NewMenu nmtext[] =
79 {NM_TITLE, (STRPTR)MSG_MEN_TEXT },
80 {NM_ITEM, (STRPTR)MSG_MEN_TEXT_WORDWRAP , 0, CHECKIT | MENUTOGGLE },
81 {NM_ITEM, (STRPTR)MSG_MEN_TEXT_SEARCH },
82 {NM_ITEM, (STRPTR)MSG_MEN_TEXT_SEARCH_PREV },
83 {NM_ITEM, (STRPTR)MSG_MEN_TEXT_SEARCH_NEXT },
84 {NM_END}
87 /*********************************************************************************************/
89 static struct MenuItem * FindMenuItem( struct Menu *menu, ULONG msgid )
91 struct MenuItem *item;
93 while( menu )
95 if( (IPTR)GTMENU_USERDATA(menu) == msgid )
96 return (struct MenuItem *)menu;
97 item = menu->FirstItem;
98 while( item )
100 if( (IPTR)GTMENUITEM_USERDATA(item) == msgid )
101 return item;
102 item = item->NextItem;
104 menu = menu->NextMenu;
106 return NULL;
109 /*********************************************************************************************/
111 static void ChangeItemState( ULONG msgid, BOOL state )
113 struct MenuItem *item;
115 item = FindMenuItem(menus, msgid);
116 if (item)
118 if (state) item->Flags |= ITEMENABLED; else item->Flags &= ~ITEMENABLED;
122 /*********************************************************************************************/
124 static void SetItemChecked( ULONG msgid, BOOL state )
126 struct MenuItem *item;
128 item = FindMenuItem(menus, msgid);
129 if (item)
131 if (state) item->Flags |= CHECKED; else item->Flags &= ~CHECKED;
135 /*********************************************************************************************/
137 void InitMenus(struct NewMenu *newm)
139 struct NewMenu *actnm;
141 for(actnm = newm; actnm->nm_Type != NM_END; actnm++)
143 if (actnm->nm_Label != NM_BARLABEL)
145 ULONG id = (IPTR)actnm->nm_Label;
146 CONST_STRPTR str = MSG(id);
148 if (actnm->nm_Type == NM_TITLE)
150 actnm->nm_Label = str;
151 } else {
152 actnm->nm_Label = str + 2;
153 if (str[0] != ' ') actnm->nm_CommKey = str;
155 actnm->nm_UserData = (APTR)(IPTR)id;
157 } /* if (actnm->nm_Label != NM_BARLABEL) */
159 } /* for(actnm = nm; nm->nm_Type != NM_END; nm++) */
163 /*********************************************************************************************/
165 struct Menu * MakeMenus(struct NewMenu *newm)
167 struct Menu *menu;
168 struct TagItem menu_tags[] =
170 {GTMN_NewLookMenus, TRUE},
171 {TAG_DONE }
174 menu = CreateMenusA(newm, NULL);
175 if (!menu) Cleanup(MSG(MSG_CANT_CREATE_MENUS));
177 if (!LayoutMenusA(menu, vi, menu_tags))
179 FreeMenus(menu);
180 Cleanup(MSG(MSG_CANT_CREATE_MENUS));
182 return menu;
185 /*********************************************************************************************/
187 void KillMenus(void)
189 if (win) ClearMenuStrip(win);
190 if (menus) FreeMenus(menus);
191 if (pictmenus) FreeMenus(pictmenus);
192 if (textmenus) FreeMenus(textmenus);
194 menus = NULL;
195 pictmenus = NULL;
196 textmenus = NULL;
199 /*********************************************************************************************/
201 void SetMenuFlags(void)
203 struct Menu *menu;
204 struct MenuItem *item;
205 IPTR val;
206 BOOL ret;
208 if (win) ClearMenuStrip(win);
210 ChangeItemState( MSG_MEN_PROJECT_SAVEAS, dto_supports_write );
211 ChangeItemState( MSG_MEN_PROJECT_SAVEAS_IFF, dto_supports_write_iff );
212 ChangeItemState( MSG_MEN_PROJECT_PRINT, dto_supports_print );
213 ChangeItemState( MSG_MEN_EDIT_COPY, dto_supports_copy );
214 ChangeItemState( MSG_MEN_EDIT_SELECTALL, dto_supports_selectall );
215 ChangeItemState( MSG_MEN_EDIT_CLEARSELECTED, dto_supports_clearselected );
217 item = FindMenuItem(menus, MSG_MEN_SETTINGS); /* Search last menu, then append dt group dependent menu */
218 menu = (struct Menu *)item;
219 if (menu)
221 if (dto_subclass_gid == GID_PICTURE)
223 D(bug("Multiview: is picture.datatype\n"));
224 menu->NextMenu = pictmenus;
225 SetItemChecked( MSG_MEN_PICT_FIT_WIN, pdt_fit_win );
226 SetItemChecked( MSG_MEN_PICT_KEEP_ASPECT, pdt_keep_aspect );
227 SetItemChecked( MSG_MEN_PICT_FORCE_MAP, pdt_force_map );
228 SetItemChecked( MSG_MEN_PICT_DITHER, pdt_pict_dither );
230 else if (dto_subclass_gid == GID_TEXT)
232 D(bug("Multiview: is text.datatype\n"));
233 menu->NextMenu = textmenus;
234 ret = GetDTAttrs(dto, TDTA_WordWrap, (IPTR)&val, TAG_DONE);
235 item = FindMenuItem(menus, MSG_MEN_TEXT_WORDWRAP);
236 if (ret && item)
238 if (val) item->Flags |= CHECKED; else item->Flags &= ~CHECKED;
240 SetItemChecked( MSG_MEN_TEXT_WORDWRAP, tdt_text_wordwrap );
241 ChangeItemState( MSG_MEN_TEXT_WORDWRAP, ret );
242 ChangeItemState( MSG_MEN_TEXT_SEARCH, dto_supports_search );
243 ChangeItemState( MSG_MEN_TEXT_SEARCH_PREV, dto_supports_search_prev );
244 ChangeItemState( MSG_MEN_TEXT_SEARCH_NEXT, dto_supports_search_next );
246 else
248 D(bug("Multiview: is unknown datatype\n"));
249 menu->NextMenu = NULL;
254 struct TagItem menu_tags[] =
256 {GTMN_NewLookMenus, TRUE},
257 {TAG_DONE }
260 LayoutMenusA(menus, vi, menu_tags);
263 if (win) SetMenuStrip(win, menus);
266 /*********************************************************************************************/
268 STRPTR GetFileName(ULONG msgtextid)
270 static UBYTE pathbuffer[300];
271 static UBYTE filebuffer[300];
272 struct FileRequester *req;
273 STRPTR filepart, retval = NULL;
275 AslBase = OpenLibrary("asl.library", 39);
276 if (AslBase)
278 filebuffer[299] = 0;
279 pathbuffer[299] = 0;
281 strncpy(filebuffer, FilePart(filenamebuffer), 299);
282 strncpy(pathbuffer, filenamebuffer, 299);
283 filepart = FilePart(pathbuffer);
284 *filepart = 0;
286 req = AllocAslRequestTags(ASL_FileRequest, ASLFR_TitleText , (IPTR)MSG(msgtextid),
287 ASLFR_DoPatterns , TRUE ,
288 ASLFR_InitialPattern, "~(#?.info)" ,
289 ASLFR_InitialDrawer , (IPTR)pathbuffer ,
290 ASLFR_InitialFile , (IPTR)filebuffer ,
291 ASLFR_Window , (IPTR)win ,
292 TAG_DONE);
293 if (req)
295 if (AslRequest(req, NULL))
297 strncpy(filebuffer, req->fr_Drawer, 299);
298 AddPart(filebuffer, req->fr_File, 299);
300 retval = filebuffer;
302 } /* if (AslRequest(req, NULL) */
304 FreeAslRequest(req);
306 } /* if (req) */
308 CloseLibrary(AslBase);
310 } /* if (AslBase) */
312 return retval;
315 /*********************************************************************************************/
317 static struct Library * FindClassBase(CONST_STRPTR className)
319 struct Library *lib;
321 Forbid();
322 lib = (struct Library *)FindName(&SysBase->LibList, className);
323 Permit();
325 return lib;
328 static struct IClass *FindClassSuper(struct IClass *baseClass)
330 struct IClass *tmp = baseClass->cl_Super;
332 while ((tmp->cl_Super != NULL) &&
333 (strncmp(tmp->cl_Super->cl_ID, "datatypesclass", 14)))
335 tmp = tmp->cl_Super;
338 return tmp;
341 static char *versToStr(char *version)
343 UBYTE stringBuff[100];
344 char *tmp;
345 STRPTR sp;
346 WORD i = 0;
348 for(sp = version;
349 (*sp != 0) && ((*sp < '0') || (*sp > '9'));
350 sp++)
353 while ((*sp != 0) && (*sp != '\r') && (*sp != '\n') && (*(sp-1) !=')') && (i < 99))
355 stringBuff[i++] = *sp++;
357 stringBuff[i] = '\0';
359 tmp = AllocVec(i + 1, MEMF_ANY);
360 CopyMem(stringBuff, tmp, i + 1);
362 return tmp;
365 void About(void)
367 struct Library *tmpBase;
368 struct IClass *clSuper;
369 struct DataType *dt = NULL;
370 struct EasyStruct es;
371 struct DTClassInfo *classInfo;
372 char *fmtTemplate;
373 int count = 12, tmplLen;
374 IPTR *abouttxt;
375 WORD i = 0;
377 tmplLen = strlen(internal_about_tmpl);
379 if ((classInfo = FindClassInfo(dto_subclass_gid)) != NULL)
381 i += classInfo->templen + 1;
382 count += classInfo->entries;
385 fmtTemplate = AllocVec(tmplLen + i + 1, MEMF_ANY);
386 CopyMem(internal_about_tmpl, fmtTemplate, tmplLen + 1);
387 if (classInfo)
389 fmtTemplate[tmplLen++] = '\n';
390 classInfo->aboutTemplate(&fmtTemplate[tmplLen]);
392 es.es_TextFormat = fmtTemplate;
394 abouttxt = AllocVec(count * sizeof(IPTR), MEMF_ANY);
396 GetAttr(DTA_Name, dto, (IPTR *)&abouttxt[6]);
397 if (abouttxt[6])
398 abouttxt[6] = (IPTR)FilePart((CONST_STRPTR)abouttxt[6]);
400 if (GetDTAttrs(dto, DTA_DataType, (IPTR)&dt, TAG_DONE))
402 if (dt)
404 abouttxt[7] = (IPTR) GetDTString(dt->dtn_Header->dth_GroupID);
405 abouttxt[6] = (IPTR) dt->dtn_Header->dth_Name;
409 if (!abouttxt[7]) abouttxt[7] = (IPTR)"";
410 if (!abouttxt[6]) abouttxt[6] = (IPTR)"";
412 /* display version info about datatypes.library */
413 abouttxt[5] = (IPTR) versToStr(DataTypesBase->lib_IdString);
415 /* display version info about datatype object's class */
416 if ((tmpBase = FindClassBase(OCLASS(dto)->cl_ID)) != NULL)
418 abouttxt[8] = (IPTR) tmpBase->lib_Node.ln_Name;
419 abouttxt[9] = (IPTR) versToStr(tmpBase->lib_IdString);
422 /* display version info about datatype object's superclass */
423 if ((clSuper = FindClassSuper(OCLASS(dto))) != NULL)
425 if ((tmpBase = FindClassBase(clSuper->cl_ID)) != NULL)
427 abouttxt[10] = (IPTR) tmpBase->lib_Node.ln_Name;
428 abouttxt[11] = (IPTR) versToStr(tmpBase->lib_IdString);
432 es.es_StructSize = sizeof(es);
433 es.es_Flags = 0;
434 es.es_Title = MSG(MSG_ABOUT_TITLE);
435 es.es_GadgetFormat = MSG(MSG_CONTINUE);
437 abouttxt[0] = (IPTR) es.es_Title;
438 abouttxt[1] = VERSION;
439 abouttxt[2] = REVISION;
440 abouttxt[3] = (IPTR) DATESTR;
441 abouttxt[4] = (IPTR)DataTypesBase->lib_Node.ln_Name;
443 if (classInfo)
444 classInfo->aboutFunc(dto, (char **)&abouttxt[12]);
446 EasyRequestArgs(win, &es, NULL, (RAWARG)abouttxt);
448 if (classInfo)
449 classInfo->aboutDispose((char **)&abouttxt[12]);
451 FreeVec(fmtTemplate);
452 FreeVec((APTR)abouttxt[5]);
453 FreeVec((APTR)abouttxt[9]);
454 FreeVec((APTR)abouttxt[11]);
455 FreeVec(abouttxt);
458 /*********************************************************************************************/
460 ULONG DoTrigger(ULONG what)
462 struct dtTrigger msg;
464 msg.MethodID = DTM_TRIGGER;
465 msg.dtt_GInfo = NULL;
466 msg.dtt_Function = what;
467 msg.dtt_Data = NULL;
469 return DoDTMethodA(dto, win, NULL, (Msg)&msg);
472 /*********************************************************************************************/
474 ULONG DoWriteMethod(STRPTR name, ULONG mode)
476 struct dtWrite msg;
477 BPTR fh;
478 ULONG retval;
480 fh = BNULL;
481 if (name)
483 fh = Open( name, MODE_NEWFILE );
484 if (!fh)
486 D(bug("Multiview: Cannot open %s\n", name));
487 OutputMessage(MSG(MSG_SAVE_FAILED));
488 return FALSE;
494 msg.MethodID = DTM_WRITE;
495 msg.dtw_GInfo = NULL;
496 msg.dtw_FileHandle = fh;
497 msg.dtw_Mode = mode;
498 msg.dtw_AttrList = NULL;
500 D(bug("Multiview: Saving %s mode %ld\n", name ? name : (STRPTR)"[nothing]", mode));
501 retval = DoDTMethodA(dto, win, NULL, (Msg)&msg);
502 if (fh)
504 Close( fh );
505 if( !retval )
507 D(bug("Multiview: Error during write !\n"));
508 OutputMessage(MSG(MSG_SAVE_FAILED));
511 return retval;
514 /*********************************************************************************************/
516 ULONG DoPrintMethod(VOID)
518 struct dtPrint msg;
519 struct MsgPort *mp;
520 struct IORequest *pio;
521 ULONG retval = PDERR_CANCEL;
523 if ((mp = CreateMsgPort())) {
524 if ((pio = CreateIORequest(mp, sizeof(union printerIO)))) {
525 if (0 == OpenDevice("printer.device", 0, pio, 0)) {
526 ULONG IDCMPFlags;
528 msg.MethodID = DTM_PRINT;
529 msg.dtp_GInfo = NULL;
530 msg.dtp_PIO = (union printerIO *)pio;
531 msg.dtp_AttrList = NULL;
532 D(bug("Multiview: Printing...\n"));
534 /* We're not using PrintDTObjectA() here at this
535 * time, because we don't plan on waiting for the
536 * IDCMP_IDCMPUPDATE (DTA_PrinterStatus) message.
538 * So we just use the busy pointer while printing.
540 IDCMPFlags = win->IDCMPFlags;
541 ModifyIDCMP(win, 0);
542 SetWindowPointer(win, WA_BusyPointer, TRUE);
543 retval = DoDTMethodA(dto, win, NULL, (Msg)&msg);
544 ModifyIDCMP(win, IDCMPFlags);
545 ClearPointer(win);
547 CloseDevice(pio);
549 DeleteIORequest(pio);
551 DeleteMsgPort(mp);
554 return retval;
557 /*********************************************************************************************/
559 ULONG DoLayout(ULONG initial)
561 ULONG res;
562 struct gpLayout msg;
564 D(bug("=> erase\n"));
565 EraseRect(win->RPort, win->BorderLeft,
566 win->BorderTop,
567 win->Width - 1 - win->BorderRight,
568 win->Height - 1 - win->BorderBottom);
570 #if 1
571 msg.MethodID = GM_LAYOUT;
572 msg.gpl_GInfo = NULL;
573 msg.gpl_Initial = initial;
575 #if 0
576 D(bug("=> doasynclayout libcall\n"));
577 res = DoAsyncLayout(dto, &msg);
578 #else
579 D(bug("=> GM_Layout method\n"));
580 res = DoDTMethodA(dto, win, 0, (Msg)&msg);
581 #endif
582 D(bug("layout result %ld\n", res));
583 return res;
584 #else
585 RemoveDTObject(win, dto);
586 AddDTObject(win, NULL, dto, -1);
587 #endif
590 /*********************************************************************************************/
592 ULONG DoScaleMethod(ULONG xsize, ULONG ysize, BOOL aspect)
594 #ifdef __GNUC__
595 struct pdtScale msg;
597 D(bug(" scale width %d height %d\n", xsize, ysize));
598 msg.MethodID = PDTM_SCALE;
599 msg.ps_NewWidth = xsize;
600 msg.ps_NewHeight = ysize;
601 msg.ps_Flags = aspect ? PScale_KeepAspect : 0;
602 // D(bug("- method %08lx newwidth %ld newheight %ld flags %08lx\n", msg.MethodID, msg.ps_NewWidth, msg.ps_NewHeight, msg.ps_Flags));
604 return DoMethodA(dto, (Msg)&msg);
605 #else
606 return 0;
607 #endif
610 /*********************************************************************************************/
612 void DoZoom(WORD zoomer)
614 UWORD curwidth, curheight;
616 if (zoomer > 0)
618 curwidth = pdt_origwidth * zoomer;
619 curheight = pdt_origheight * zoomer;
621 else
623 curwidth = pdt_origwidth / -zoomer;
624 curheight = pdt_origheight / -zoomer;
626 D(bug(" zoom %d width %d height %d\n", zoomer, curwidth, curheight));
627 DoScaleMethod(curwidth, curheight, 0);
628 DoLayout(TRUE);
631 /*********************************************************************************************/