don't use NULL or cast NULL where appropriate.
[AROS-Contrib.git] / vpdf / application.c
blobafd92939dd49071cba0232d7f4b0de8b0232020f
2 #if defined(__AROS__)
3 #define MUIMASTER_YES_INLINE_STDARG
4 #endif
6 /// System includes
7 #define AROS_ALMOST_COMPATIBLE
8 #include <proto/muimaster.h>
9 #include <libraries/mui.h>
11 #include <libraries/asl.h>
12 #include <workbench/workbench.h>
14 #include <proto/exec.h>
15 #include <intuition/intuition.h>
16 #include <graphics/gfx.h>
17 #include <exec/libraries.h>
18 #include <proto/graphics.h>
19 #include <proto/intuition.h>
20 #include <proto/icon.h>
21 #include <dos/dos.h>
22 #include <proto/dos.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <math.h>
28 #include <memory.h>
30 #include <proto/alib.h>
31 #include <proto/utility.h>
33 #include <proto/datatypes.h>
34 #include <proto/dtclass.h>
35 #include <datatypes/pictureclass.h>
36 #include <devices/rawkeycodes.h>
38 #include <libraries/gadtools.h>
40 #if defined(__AROS__)
41 #include <clib/arossupport_protos.h>
42 #endif
44 #if defined(__MORPHOS__)
45 #include <emul/emulregs.h>
46 #include <emul/emulinterface.h>
47 #endif
48 ////
50 #include <private/vapor/vapor.h>
51 #include "util.h"
52 #include "poppler.h"
53 #include "application.h"
54 #include "window.h"
55 #include "logger.h"
56 #include "locale.h"
57 #include "settings.h"
58 #include "printer.h"
59 #include "system/functions.h"
61 #include "mcc/documentview_class.h"
62 #include "mcc/toolbar_class.h"
63 #include "mcc/renderer_class.h"
64 #include "mcc/title_class.h"
66 #include <mui/Aboutbox_mcc.h>
68 #define MAXRECENT 10
70 struct Data
72 Object *renderer;
73 Object *menu;
74 int windowid;
75 Object *logger;
76 Object *loggerwin;
77 Object *settings;
78 Object *printer;
79 char *recent[MAXRECENT];
80 Object *aboutbox;
83 /* MEnu description */
85 enum
87 MEN_PROJECT = 1,
88 MEN_ABOUT, MEN_OPEN_FILE, MEN_OPEN_URL, MEN_TAB_NEW, MEN_TAB_CLOSE, MEN_WINDOW_NEW, MEN_WINDOW_CLOSE,
89 MEN_OPEN_RECENT,
90 MEN_PRINT,
91 MEN_QUIT,
92 MEN_EDIT, MEN_EDIT_COPY,
93 MEN_WINDOWS, MEN_WINDOWS_LOG,
94 MEN_SETTINGS, MEN_SETTINGS_SETTINGS, MEN_SETTINGS_SAVESETTINGS, MEN_SETTINGS_MUI,
95 MEN_OPEN_RECENT0 = 100 /* keep it last*/
98 Object menu[MEN_OPEN_RECENT0+1];
100 /* rexx handling */
102 #define REXXHOOK(name, param) static const struct Hook name = { { NULL, NULL }, (HOOKFUNC)&RexxEmul, NULL, (APTR)(param) }
104 enum
106 REXX_ABOUT,
107 REXX_SAVE,
108 REXX_OPEN,
109 REXX_APPTOFRONT
112 #if defined(__MORPHOS__)
113 // FIXME: AROS doesn't support REXX in MUI but AmigaOS4 does
114 static LONG Rexx(void);
115 static const struct EmulLibEntry RexxEmul = { TRAP_LIB, 0, (void (*)())&Rexx };
116 REXXHOOK(RexxHookAbout, REXX_ABOUT);
117 REXXHOOK(RexxHookSave, REXX_SAVE);
118 REXXHOOK(RexxHookOpen, REXX_OPEN);
119 REXXHOOK(RexxHookAppToFront, REXX_APPTOFRONT);
121 static const struct MUI_Command rexxcommands[] =
123 { "ABOUT", NULL, 0, (struct Hook *)&RexxHookAbout},
124 { "SAVE", NULL, 0, (struct Hook *)&RexxHookSave },
125 { "OPEN", "FILE/K,NEWTAB/S", 2, (struct Hook *)&RexxHookOpen },
126 { "APPTOFRONT", "APPTOFRONT/S", 1, (struct Hook *)&RexxHookAppToFront },
127 { NULL, NULL, 0, NULL }
129 #endif
131 /* credits */
133 static CONST_STRPTR __credits =
134 "\33b%p\33n\n"
135 "\tMichal 'kiero' Wozniak\n\n"
136 "\33b%W\33n\n"
137 "\twozniak_m@interia.pl\n\n"
138 "\33b%P\33n\n"
139 "\tMichal Zukowski\n\n"
140 "\33b%§\33n\n"
141 "\tVPDF uses following libraries:\n"
142 "\tPoppler (http://www.poppler.freedesktop.org)\n"
143 "\tXPDF (http://www.foolabs.com/xpdf/)\n"
144 "\tFreeType (http://www.freetype.org)\n\n"
145 "\tThis software is based in part on the work of the\n"
146 "\tIndependent JPEG Group"
150 /* */
152 static void reqInit(char *path);
153 static void reqEnd(void);
156 Object *CreateMenuitem(CONST_STRPTR text, CONST_STRPTR shortcut)
158 Object *obj;
159 if(shortcut)
161 obj = MUI_NewObject(MUIC_Menuitem,
162 MUIA_Menuitem_Title , text,
163 MUIA_Menuitem_Shortcut , shortcut,
164 TAG_END);
166 else
168 obj = MUI_NewObject(MUIC_Menuitem,
169 MUIA_Menuitem_Title , text,
170 TAG_END);
172 return obj;
175 DEFNEW
177 Object *settings, *settingswin, *printerwin;
178 Object *btnSave, *btnUse, *btnCancel;
180 obj = DoSuperNew(cl, obj,
181 MUIA_Application_Menustrip, menu[0] = MenustripObject,
182 MUIA_Family_Child, MenuObject,
183 MUIA_Menu_Title, LOCSTR(MSG_MENU_PROJECT),
184 MUIA_Family_Child, menu[MEN_WINDOW_NEW] = CreateMenuitem(LOCSTR(MSG_MENU_NEWWIN), "N"),
185 MUIA_Family_Child, menu[MEN_TAB_NEW] = CreateMenuitem(LOCSTR(MSG_MENU_NEWTAB), "T"),
187 MUIA_Family_Child, menu[MEN_OPEN_URL] = CreateMenuitem(LOCSTR(MSG_MENU_URL), "T"),
189 MUIA_Family_Child, menu[MEN_OPEN_FILE] = CreateMenuitem(LOCSTR(MSG_MENU_FILE), 0),
190 MUIA_Family_Child, menu[MEN_OPEN_RECENT] = CreateMenuitem(LOCSTR(MSG_MENU_RECENT), 0),
191 MUIA_Family_Child, menu[MEN_PRINT] = CreateMenuitem(LOCSTR(MSG_MENU_PRINT), "P"),
192 MUIA_Family_Child, CreateMenuitem(NM_BARLABEL, NULL),
193 MUIA_Family_Child, menu[MEN_ABOUT] = CreateMenuitem(LOCSTR(MSG_MENU_ABOUT), "?"),
194 MUIA_Family_Child, CreateMenuitem(NM_BARLABEL, NULL),
195 MUIA_Family_Child, menu[MEN_QUIT] = CreateMenuitem(LOCSTR(MSG_MENU_QUIT), "Q"),
196 End,
197 MUIA_Family_Child, MenuObject,
198 MUIA_Menu_Title, LOCSTR(MSG_MENU_EDIT),
199 MUIA_Family_Child, menu[MEN_EDIT_COPY] = CreateMenuitem(LOCSTR(MSG_MENU_COPY), "C"),
200 End,
201 MUIA_Family_Child, MenuObject,
202 MUIA_Menu_Title, LOCSTR(MSG_MENU_WINDOWS),
203 MUIA_Family_Child, menu[MEN_WINDOWS_LOG] = CreateMenuitem(LOCSTR(MSG_MENU_LOG), 0),
204 End,
205 MUIA_Family_Child, MenuObject,
206 MUIA_Menu_Title, LOCSTR(MSG_MENU_SETTINGS),
207 MUIA_Family_Child, menu[MEN_SETTINGS_SETTINGS] =
208 CreateMenuitem(LOCSTR(MSG_MENU_SETTINGS_SETTINGS), 0),
209 MUIA_Family_Child, menu[MEN_SETTINGS_SAVESETTINGS] =
210 CreateMenuitem(LOCSTR(MSG_MENU_SETTINGS_SAVE), 0),
211 MUIA_Family_Child, menu[MEN_SETTINGS_MUI] =
212 CreateMenuitem(LOCSTR(MSG_MENU_SETTINGS_MUI), 0),
213 End,
215 End,
218 #if !defined(__AROS__)
219 MUIA_Application_Commands, &rexxcommands,
220 #endif
221 MUIA_Application_Window, settingswin = WindowObject,
222 MUIA_Window_Title,"VPDF · Setttings",
223 MUIA_Window_Width, MUIV_Window_Width_Screen(30),
224 MUIA_Window_Height, MUIV_Window_Height_Screen(40),
225 MUIA_Window_ID, MAKE_ID('V', 'P', 'S', 'T'),
226 MUIA_Window_RootObject, VGroup,
227 Child, settings = VPDFSettingsObject,
228 MUIA_Frame, MUIV_Frame_Group,
229 End,
230 Child, HGroup,
231 Child, btnSave = SimpleButton(LOCSTR(MSG_SAVE)),
232 Child, btnUse = SimpleButton(LOCSTR(MSG_USE)),
233 //Child, SimpleButton("_Test"),
234 Child, HSpace(0),
235 Child, btnCancel = SimpleButton(LOCSTR(MSG_CANCEL)),
236 End,
237 End,
238 End,
239 MUIA_Application_Window, printerwin = VPDFPrinterObject, End,
241 TAG_MORE, INITTAGS);
243 if (obj != NULL)
245 GETDATA;
246 int i;
247 memset(data, 0, sizeof(struct Data));
248 data->settings = settings;
249 data->printer = printerwin;
251 /* spawn document renderer common for all views */
252 data->renderer = RendererObject, End;
254 /* TODO: make some separate singleton for reqs? */
255 reqInit("");
257 /* menu notifications */
258 DoMethod(menu[MEN_ABOUT], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 1, MUIM_VPDF_About);
259 DoMethod(menu[MEN_QUIT], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
260 DoMethod(menu[MEN_TAB_NEW], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 2, MUIM_VPDF_CreateTab, 0);
261 DoMethod(menu[MEN_WINDOW_NEW], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 1, MUIM_VPDF_CreateWindow);
262 DoMethod(menu[MEN_OPEN_FILE], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 4, MUIM_VPDF_OpenFile, 0, NULL, MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty);
263 DoMethod(menu[MEN_SETTINGS_SETTINGS], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,settingswin, 3, MUIM_Set, MUIA_Window_Open, TRUE);
264 DoMethod(menu[MEN_SETTINGS_SAVESETTINGS], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,settingswin, 1, MUIM_VPDFSettings_Save);
265 DoMethod(menu[MEN_SETTINGS_MUI], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 2, MUIM_Application_OpenConfigWindow, 0);
266 DoMethod(menu[MEN_PRINT], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 1, MUIM_VPDF_PrintDocument);
267 DoMethod(menu[MEN_WINDOWS_LOG], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 3, MUIM_VPDF_LogMessage, 0, NULL);
268 DoMethod(menu[MEN_EDIT_COPY], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 1, MUIM_VPDF_SelectionCopy);
271 DoMethod(settingswin, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, settingswin, 3, MUIM_Set, MUIA_Window_Open, FALSE);
272 DoMethod(btnCancel, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_VPDF_SettingsCancel);
273 DoMethod(btnSave, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_VPDF_SettingsSave);
274 DoMethod(btnUse, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_VPDF_SettingsUse);
276 DoMethod(printerwin, MUIM_Notify, MUIA_Window_Open, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_VPDF_Locked, MUIV_TriggerValue);
278 set(printerwin, MUIA_VPDFPrinter_PSName, xget(_app(obj), MUIA_VPDFSettings_PSName));
279 DoMethod(printerwin, MUIM_Notify, MUIA_VPDFPrinter_PSName, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_VPDFSettings_PSName, MUIV_TriggerValue);
280 set(printerwin, MUIA_VPDFPrinter_PrintingMode, xget(_app(obj), MUIA_VPDFSettings_PrintingMode));
281 DoMethod(printerwin, MUIM_Notify, MUIA_VPDFPrinter_PrintingMode, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_VPDFSettings_PrintingMode, MUIV_TriggerValue);
282 set(printerwin, MUIA_VPDFPrinter_PSMode, xget(_app(obj), MUIA_VPDFSettings_PSMode));
283 DoMethod(printerwin, MUIM_Notify, MUIA_VPDFPrinter_PSMode, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_VPDFSettings_PSMode, MUIV_TriggerValue);
287 return (ULONG)obj;
290 DEFDISP
292 GETDATA;
294 /* always 'use' settings. even if not modified */
295 DoMethod(data->settings, MUIM_VPDFSettings_Use);
297 /* delete all windows first as they might be using renderer object.
298 * skip settings window so all windows which save to settings have last chance now. */
301 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
302 Object *winobj_state = (Object*)winlist->lh_Head;
303 Object *winobj;
304 while((winobj = NextObject(&winobj_state)))
306 set(winobj, MUIA_Window_Open, FALSE);
307 if (winobj != data->settings)
309 DoMethod(obj, OM_REMMEMBER, winobj);
310 MUI_DisposeObject(winobj);
315 /* dispose renderer and the rest */
317 MUI_DisposeObject(data->renderer);
318 reqEnd();
320 return DOSUPER;
323 static void setuprecent(Object *obj, struct Data *data);
325 DEFMMETHOD(VPDF_OpenFile)
327 GETDATA;
328 char *filename = msg->filename;
329 int mode = msg->mode;
330 Object *window = (Object*)DoMethod(obj, MUIM_VPDF_FindWindowByID, msg->windowid == 0 ? MUIV_VPDF_FindWindowByID_Active : msg->windowid);
332 if (window == NULL)
334 window = (Object*)DoMethod(obj, MUIM_VPDF_CreateWindow);
335 mode = MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty;
338 if (filename == NULL)
340 filename = (char*)DoMethod(_app(obj), MUIM_VPDF_RequestFile,
341 MUIV_VPDF_RequestFile_Load,
342 NULL,
343 NULL,
344 NULL);
346 if (filename == NULL)
347 return FALSE;
350 if (window != NULL)
352 if (DoMethod(window, MUIM_VPDFWindow_OpenFile, filename, mode))
354 /* add to history */
355 int i;
356 int dupe = FALSE;
358 for(i=0; i<MAXRECENT && data->recent[i] != NULL && *data->recent[i] != '\0' && dupe == FALSE; i++)
359 dupe = 0 == stricmp(data->recent[i], filename);
361 if (dupe == FALSE)
363 free(data->recent[MAXRECENT-1]);
364 for(i=MAXRECENT-1;i>=1; i--)
365 data->recent[i] = data->recent[i-1];
367 data->recent[0] = strdup(filename);
368 setuprecent(obj, data);
373 return TRUE;
376 DEFMMETHOD(VPDF_OpenRecentFile)
378 GETDATA;
379 if (data->recent[msg->idx] != NULL && *data->recent[msg->idx] != '\0')
381 return DoMethod(obj, MUIM_VPDF_OpenFile, msg->windowid, data->recent[msg->idx], MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty);
383 //KPrintF("Open recent file %s\n", data->recent[msg->idx]);
385 return FALSE;
388 DEFMMETHOD(VPDF_CreateTab)
390 Object *window = (Object*)DoMethod(obj, MUIM_VPDF_FindWindowByID, msg->windowid == 0 ? MUIV_VPDF_FindWindowByID_Active : msg->windowid);
392 if (window != NULL)
394 return DoMethod(window, MUIM_VPDFWindow_CreateTab);
397 return (ULONG)-1;
400 DEFMMETHOD(VPDF_CreateWindow)
402 GETDATA;
403 Object *refwindow = DoMethod(obj, MUIM_VPDF_FindActiveWindow);
404 Object *window = VPDFWindowObject,
405 MUIA_VPDFWindow_ID, ++data->windowid,
406 MUIA_Window_ID, MAKE_ID('V','P', 'W','O'), /* this is going to be nullified for all non-active windows */
407 MUIA_Window_LeftEdge, 20,
408 MUIA_Window_TopEdge, 20,
409 MUIA_Window_RefWindow, refwindow,
410 MUIA_Window_OverrideStoredPosition, refwindow != NULL ? TRUE : FALSE,
411 End;
413 if (window != NULL)
415 int id = xget(window, MUIA_VPDFWindow_ID);
416 DoMethod(obj, OM_ADDMEMBER, window);
417 DoMethod(window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, obj, 2, MUIM_VPDF_CloseWindow, id);
418 DoMethod(window, MUIM_Notify, MUIA_Window_Activate, TRUE, obj, 2, MUIM_VPDF_NewActiveWindow, window);
419 set(window, MUIA_Window_Open, TRUE);
422 return (ULONG)window;
425 DEFMMETHOD(VPDF_HandleAppMessage)
427 struct AppMessage *amsg = msg->appmessage;
428 struct WBArg *ap = amsg->am_ArgList;
429 char buf[1024];
431 NameFromLock(ap->wa_Lock,buf,sizeof(buf));
432 AddPart(buf,ap->wa_Name,sizeof(buf));
434 if (strMatch(buf, "#?.pdf"))
435 DoMethod(obj, MUIM_VPDF_OpenFile, msg->windowid, buf, MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty);
437 return 0;
440 /// Helper Functions (requesters)
442 M_HOOK(AslRefresh, struct FileRequester *req,struct IntuiMessage *imsg)
444 if (imsg->Class==IDCMP_REFRESHWINDOW)
445 DoMethod(req->fr_UserData,MUIM_Application_CheckRefresh);
448 static struct FileRequester *reqLoad = NULL;
449 static struct FileRequester *reqSave = NULL;
451 static void reqInit(char *path)
453 char *dir = strdup(path);
454 char *file = FilePart(path);
455 char *fPart = PathPart(dir);
457 if (fPart)
458 dir[ fPart - dir ] = 0;
460 reqSave = MUI_AllocAslRequestTags(ASL_FileRequest,
461 ASLFR_TitleText , "Save image...",
462 ASLFR_InitialPattern, "",
463 ASLFR_DoSaveMode , TRUE,
464 ASLFR_InitialDrawer , dir,
465 ASLFR_InitialFile , file,
466 ASLFR_DoPatterns , TRUE,
467 ASLFR_RejectIcons , TRUE,
468 TAG_DONE);
470 reqLoad = MUI_AllocAslRequestTags(ASL_FileRequest,
471 ASLFR_TitleText , "Load image...",
472 ASLFR_InitialPattern, "",
473 ASLFR_DoSaveMode , FALSE,
474 ASLFR_InitialDrawer , dir,
475 ASLFR_InitialFile , file,
476 ASLFR_DoPatterns , TRUE,
477 ASLFR_RejectIcons , TRUE,
478 TAG_DONE);
480 free(dir);
483 static void reqEnd(void)
485 if (reqSave)
486 MUI_FreeAslRequest(reqSave);
487 if (reqLoad)
488 MUI_FreeAslRequest(reqLoad);
491 DEFMMETHOD(VPDF_RequestFile)
493 static char buf[1024];
494 char *res = NULL;
495 struct FileRequester *req;
496 Object *window = (Object*)DoMethod(obj, MUIM_VPDF_FindActiveWindow);
498 if (msg->mode & MUIV_VPDF_RequestFile_Load)
499 req = reqLoad;
500 else
501 req = reqSave;
503 if (req != NULL)
505 char *title = NULL;
507 set(obj, MUIA_Application_Sleep, TRUE);
509 /* will extract directory path first */
511 buf[ 0 ] = 0;
513 if (msg->initialdir != NULL)
514 stccpy(buf, msg->initialdir, sizeof(buf));
515 else if (msg->initialpath != NULL)
517 stccpy(buf, msg->initialpath, sizeof(buf));
518 buf[ (int)PathPart(buf) - (int)&buf[ 0 ] ] = 0;
521 /* setup proper title */
523 if (msg->mode & MUIV_VPDF_RequestFile_DirectoryOnly)
524 title = LOCSTR( MSG_REQ_DRAWER );
525 else if (msg->mode & MUIV_VPDF_RequestFile_Load)
526 title = LOCSTR( MSG_REQ_OPEN );
527 else if (msg->mode & MUIV_VPDF_RequestFile_Save)
528 title = LOCSTR( MSG_REQ_SAVE );
530 if (MUI_AslRequestTags(req,
531 title != NULL ? ASLFR_TitleText : TAG_IGNORE, title,
532 ASLFR_UserData, obj,
533 ASLFR_IntuiMsgFunc, &AslRefreshHook,
534 ASLFR_PrivateIDCMP, FALSE,
535 buf[ 0 ] ? ASLFR_InitialDrawer : TAG_IGNORE, buf,
536 ASLFR_InitialFile, msg->initialfile ? msg->initialfile : msg->initialpath ? (char*)FilePart(msg->initialpath) : (char*)"",
537 ASLFR_DrawersOnly, msg->mode & MUIV_VPDF_RequestFile_DirectoryOnly,
538 ASLFR_Window, window != NULL ? xget(window, MUIA_Window_Window) : NULL,
539 TAG_DONE))
541 if (*req->fr_File)
543 res = buf;
544 stccpy(buf, req->fr_Drawer, sizeof(buf));
545 if (!(msg->mode & MUIV_VPDF_RequestFile_DirectoryOnly))
546 AddPart(buf, req->fr_File, sizeof(buf));
548 else if (*req->fr_Drawer && (msg->mode & MUIV_VPDF_RequestFile_DirectoryOnly))
550 res = buf;
551 stccpy(buf, req->fr_Drawer, sizeof(buf));
555 set(obj, MUIA_Application_Sleep, FALSE);
558 return (ULONG)res;
562 ////
564 static void setuprecent(Object *obj, struct Data *data)
566 #if defined(__AROS__)
567 kprintf("[setuprecent] not implemented\n");
568 // FIXME: AROS
569 #else
570 int i;
571 Object *o;
572 DoMethod(menu[MEN_OPEN_RECENT] , MUIM_Menustrip_InitChange);
574 /* cleanup recents */
575 while((o = (Object*)DoMethod(menu[MEN_OPEN_RECENT], MUIM_Family_GetChild, MUIV_Family_GetChild_First)))
577 DoMethod(menu[MEN_OPEN_RECENT], MUIM_Family_Remove, o);
578 MUI_DisposeObject(o);
581 for(i=0; i<MAXRECENT && data->recent[i] != NULL && *data->recent[i] != '\0'; i++)
583 menu[MEN_OPEN_RECENT0-i] = MenuitemObject,
584 MUIA_Menuitem_Title, data->recent[i],
585 MUIA_Menuitem_CopyStrings, TRUE,
586 End;
587 DoMethod(menu[MEN_OPEN_RECENT0-i], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 3, MUIM_VPDF_OpenRecentFile, 0, i);
588 DoMethod(menu[MEN_OPEN_RECENT], MUIM_Family_AddTail, menu[MEN_OPEN_RECENT0-i]);
591 DoMethod(menu[MEN_OPEN_RECENT], MUIM_Menustrip_ExitChange);
592 #endif
595 /* this method finds window which was last activated, not currently active one! */
597 DEFMMETHOD(VPDF_FindActiveWindow)
599 GETDATA;
600 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
601 Object *winobj_state = (Object*)winlist->lh_Head;
602 Object *winobj;
603 ULONG v;
605 while((winobj = NextObject(&winobj_state)))
607 //if (xget(winobj, MUIA_Window_Activate))
608 if (xget(winobj, MUIA_Window_ID) != 0 && get(winobj, MUIA_VPDFWindow_ID, &v))
609 return winobj;
612 return 0;
615 DEFMMETHOD(VPDF_FindWindowByID)
617 GETDATA;
619 if (msg->windowid == MUIV_VPDF_FindWindowByID_Active)
621 return DoMethod(obj, MUIM_VPDF_FindActiveWindow);
623 else
625 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
626 Object *winobj_state = (Object*)winlist->lh_Head;
627 Object *winobj;
628 while((winobj = NextObject(&winobj_state)))
630 /* validate if it's document view window */
631 int v;
632 if (get(winobj, MUIA_VPDFWindow_ID, &v) == FALSE)
633 continue;
635 if (msg->windowid == MUIV_VPDF_FindWindowByID_First)
636 return winobj;
637 else if (msg->windowid == xget(winobj, MUIA_VPDFWindow_ID))
638 return winobj;
642 return 0;
645 DEFMMETHOD(VPDF_CloseWindow)
647 Object *window = (Object*)DoMethod(obj, MUIM_VPDF_FindWindowByID, msg->windowid == 0 ? MUIV_VPDF_FindWindowByID_Active : msg->windowid);
649 if (window != NULL)
651 set(window, MUIA_Window_Open, FALSE);
652 DoMethod(obj, OM_REMMEMBER, window);
653 MUI_DisposeObject(window);
655 if (DoMethod(obj, MUIM_VPDF_FindWindowByID, MUIV_VPDF_FindWindowByID_First) == NULL)
656 DoMethod(obj, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
658 return TRUE;
660 return FALSE;
663 DEFMMETHOD(Export)
665 GETDATA;
666 int i;
668 for(i=0; i<MAXRECENT && data->recent[i] != NULL && *data->recent[i] != '\0'; i++)
671 DoMethod(msg->dataspace, MUIM_Dataspace_Add, data->recent[i], strlen(data->recent[i]) + 1, ID_VPDF_RECENT0 + i);
673 return DOSUPER;
676 DEFMMETHOD(Import)
678 GETDATA;
679 int i, j;
681 for(i=0, j=0; i<MAXRECENT; i++)
683 char *recent = (char*)DoMethod(msg->dataspace, MUIM_Dataspace_Find, ID_VPDF_RECENT0 + i);
684 if (recent != NULL)
686 BPTR *lock;
687 struct Process *theProc = (struct Process *)FindTask(NULL);
688 struct Window *oldWindowPtr = theProc->pr_WindowPtr;
689 theProc->pr_WindowPtr = (APTR)(-1L);
691 if (lock = Lock(recent, ACCESS_READ))
693 data->recent[j] = strdup(recent);
694 j++;
695 UnLock(lock);
697 theProc->pr_WindowPtr = oldWindowPtr;
701 setuprecent(obj, data);
703 return DOSUPER;
706 DEFGET
708 GETDATA;
709 ULONG v;
711 switch (msg->opg_AttrID)
713 case MUIA_VPDF_Renderer:
714 *(ULONG*)msg->opg_Storage = (ULONG)data->renderer;
715 return TRUE;
718 /* check for settings attribute */
720 if (msg->opg_AttrID > MUIA_VPDFSettings_First && msg->opg_AttrID < MUIA_VPDFSettings_Last)
722 if (get(data->settings, msg->opg_AttrID, &v))
724 *(ULONG*)msg->opg_Storage = v;
725 return TRUE;
729 /* */
731 return DOSUPER;
734 DEFSET
736 GETDATA;
738 FORTAG(INITTAGS)
740 case MUIA_VPDF_Locked:
742 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
743 Object *winobj_state = (Object*)winlist->lh_Head;
744 Object *winobj;
745 while((winobj = NextObject(&winobj_state)))
747 /* validate if it's document view window */
748 int v;
749 if (get(winobj, MUIA_VPDFWindow_ID, &v) == FALSE)
750 continue;
752 set(winobj, MUIA_Window_Sleep, tag->ti_Data);
755 break;
757 default:
758 /* check for settings attribute */
760 if (tag->ti_Tag > MUIA_VPDFSettings_First && tag->ti_Tag < MUIA_VPDFSettings_Last)
762 set(data->settings, tag->ti_Tag, tag->ti_Data);
765 NEXTTAG
767 return DOSUPER;
770 DEFMMETHOD(VPDF_LogMessage)
772 GETDATA;
774 if (data->logger == NULL)
776 data->loggerwin = WindowObject,
777 MUIA_Window_Title,"VPDF · Log",
778 MUIA_Window_Width, MUIV_Window_Width_Screen(30),
779 MUIA_Window_Height, MUIV_Window_Height_Screen(10),
780 MUIA_Window_RootObject,
781 data->logger = LoggerObject, End,
782 End;
784 if (data->loggerwin != NULL)
786 DoMethod(obj, OM_ADDMEMBER, data->loggerwin);
787 DoMethod(data->loggerwin, MUIM_Notify, MUIA_Window_CloseRequest, MUIV_EveryTime, data->loggerwin, 3, MUIM_Set, MUIA_Window_Open, FALSE);
791 if (data->logger != NULL)
793 if (msg->message == NULL || xget(_app(obj), MUIA_VPDFSettings_OpenLog))
794 set(data->loggerwin, MUIA_Window_Open, TRUE);
797 if (data->logger != NULL && msg->message != NULL)
799 DoMethod(data->logger, MUIM_Logger_LogMessage, msg->severity, msg->message);
801 /* message is always strdupped() so dispose it here. logger has to make a copy! */
802 free(msg->message);
805 return 0;
808 DEFMMETHOD(VPDF_NewActiveWindow)
810 /* only setup window id for active window so it will be used when the application is restarted*/
812 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
813 Object *winobj_state = (Object*)winlist->lh_Head;
814 Object *winobj;
815 while((winobj = NextObject(&winobj_state)))
817 /* validate if it's document view window */
818 int v;
819 if (get(winobj, MUIA_VPDFWindow_ID, &v) == FALSE)
820 continue;
822 set(winobj, MUIA_Window_ID, winobj == msg->window ? MAKE_ID('V','P', 'W','O') : 0);
825 return 0;
828 DEFMMETHOD(VPDF_SettingsCancel)
830 GETDATA;
831 DoMethod(data->settings, MUIM_VPDFSettings_Cancel);
832 set(_win(data->settings), MUIA_Window_Open, FALSE);
833 return 0;
837 DEFMMETHOD(VPDF_SettingsUse)
839 GETDATA;
840 DoMethod(obj, MUIM_VPDF_SettingsApply, DoMethod(data->settings, MUIM_VPDFSettings_Use));
841 return 0;
845 DEFMMETHOD(VPDF_SettingsSave)
847 GETDATA;
848 DoMethod(obj, MUIM_VPDF_SettingsApply, DoMethod(data->settings, MUIM_VPDFSettings_Save));
849 return 0;
852 DEFMMETHOD(VPDF_SettingsApply)
854 GETDATA;
855 set(_win(data->settings), MUIA_Window_Open, FALSE);
856 return 0;
859 DEFMMETHOD(VPDF_About)
861 GETDATA;
863 if (data->aboutbox == NULL)
865 data->aboutbox = AboutboxObject,
866 MUIA_Aboutbox_Credits, __credits,
867 End;
869 DoMethod(obj, OM_ADDMEMBER, data->aboutbox);
872 if (data->aboutbox != NULL)
873 set(data->aboutbox, MUIA_Window_Open, TRUE);
875 return 0;
878 DEFMMETHOD(VPDF_PrintDocument)
880 GETDATA;
881 Object *activewindow = (Object*)DoMethod(obj, MUIM_VPDF_FindActiveWindow);
883 if (activewindow != NULL)
885 void *doc = (void*)xget(activewindow, MUIA_VPDFWindow_PDFDocument);
886 if (doc != NULL)
887 DoMethod(data->printer, MUIM_VPDFPrinter_PrintDocument, doc);
889 return TRUE;
892 DEFMMETHOD(DragDrop)
894 GETDATA;
895 int v;
897 /* check if it was title object */
899 if (_parent(msg->obj) != NULL && get(_parent(msg->obj), MUIA_VPDFTitle_IsTitle, &v))
901 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
902 int ownwindow = FALSE;
904 if (xget(_parent(msg->obj), MUIA_Group_ChildCount) <= 1)
905 return DOSUPER;
907 if (winlist != NULL)
909 Object *winobj_state = (Object*)winlist->lh_Head;
910 Object *winobj;
911 while((winobj = NextObject(&winobj_state)))
913 /* validate if it's document view window */
914 int v;
915 if (get(winobj, MUIA_VPDFWindow_ID, &v))
917 if (msg->x > xget(winobj, MUIA_Window_LeftEdge) && msg->x < xget(winobj, MUIA_Window_LeftEdge) + xget(winobj, MUIA_Window_Width)
918 && msg->y > xget(winobj, MUIA_Window_TopEdge) && msg->y < xget(winobj, MUIA_Window_TopEdge) + xget(winobj, MUIA_Window_Height))
920 ownwindow = TRUE;
922 break;
928 /* detach document from window (create new and add the document) */
930 if (ownwindow == FALSE)
932 Object *oldwindow = _win(msg->obj);
933 Object *newwindow = (Object*)DoMethod(obj, MUIM_VPDF_CreateWindow);
935 if (newwindow != NULL)
937 struct MUIP_VPDFWindow_DetachView msg;
938 msg.MethodID = MUIM_VPDFWindow_DetachView;
939 msg.tabind = MUIV_VPDFWindow_DetachView_Active;
941 if (DoMethodA(oldwindow, &msg))
944 DoMethod(newwindow, MUIM_VPDFWindow_AttachView, MUIV_VPDFWindow_AttachView_CurrentTabIfEmpty, msg.docview, msg.title);
950 return DOSUPER;
953 /* rexx handling */
955 static LONG Rexx(void)
957 #if defined(__AROS__)
958 kprintf("[Rexx] not implemented\n");
959 // FIXME: AROS
960 #else
961 struct Hook *h = (struct Hook*)(APTR)REG_A0;
962 Object *obj = (Object*)REG_A2;
963 IPTR *params = (IPTR*)REG_A1;
965 switch ((ULONG)h->h_Data)
967 case REXX_ABOUT:
968 break;
970 case REXX_OPEN:
972 char *file = (char*)*params;
973 ULONG newtab = params[1];
975 char *ftemp = file;
976 while(*ftemp != '\0')
978 if(*ftemp == '\\')
979 *ftemp = ' ';
980 ftemp++;
983 DoMethod(obj, MUIM_VPDF_OpenFile, 0, file, newtab ? MUIV_VPDFWindow_OpenFile_CurrentTab : MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty);
984 break;
987 case REXX_SAVE:
988 break;
990 case REXX_APPTOFRONT:
991 break;
993 #endif
994 return 0;
997 DEFMMETHOD(VPDF_SelectionCopy)
999 GETDATA;
1000 Object *activewindow = (Object*)DoMethod(obj, MUIM_VPDF_FindActiveWindow);
1002 if (activewindow != NULL)
1004 Object *documentview = (Object*)xget(activewindow, MUIA_VPDFWindow_ActiveDocumentView);
1005 if (documentview != NULL)
1007 DoMethod(documentview, MUIM_DocumentView_SelectionCopy);
1011 return TRUE;
1013 /* */
1015 BEGINMTABLE
1016 DECNEW
1017 DECDISP
1018 DECGET
1019 DECSET
1020 DECMMETHOD(Import)
1021 DECMMETHOD(Export)
1022 DECMMETHOD(DragDrop)
1023 DECMMETHOD(VPDF_OpenFile)
1024 DECMMETHOD(VPDF_CreateTab)
1025 DECMMETHOD(VPDF_CreateWindow)
1026 DECMMETHOD(VPDF_HandleAppMessage)
1027 DECMMETHOD(VPDF_RequestFile)
1028 DECMMETHOD(VPDF_OpenRecentFile)
1029 DECMMETHOD(VPDF_FindActiveWindow)
1030 DECMMETHOD(VPDF_FindWindowByID)
1031 DECMMETHOD(VPDF_CloseWindow)
1032 DECMMETHOD(VPDF_LogMessage)
1033 DECMMETHOD(VPDF_NewActiveWindow)
1034 DECMMETHOD(VPDF_SettingsCancel)
1035 DECMMETHOD(VPDF_SettingsSave)
1036 DECMMETHOD(VPDF_SettingsUse)
1037 DECMMETHOD(VPDF_SettingsApply)
1038 DECMMETHOD(VPDF_About)
1039 DECMMETHOD(VPDF_PrintDocument)
1040 DECMMETHOD(VPDF_SelectionCopy)
1041 ENDMTABLE
1043 DECSUBCLASS_NC(MUIC_Application, VPDFClass)