reenabled swaptest. quake should now load data and start on big endian architectures...
[AROS-Contrib.git] / vpdf / application.c
blobc05e6ce67ec0d338f01e8e06f0f6ae4c44aa17e7
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 static 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 = (Object *) DoSuperNew(cl, obj,
181 MUIA_Application_Menustrip, (IPTR) (menu[0] = MenustripObject,
182 MUIA_Family_Child, (IPTR) (MenuObject,
183 MUIA_Menu_Title, (IPTR) LOCSTR(MSG_MENU_PROJECT),
184 MUIA_Family_Child, (IPTR) (menu[MEN_WINDOW_NEW] =
185 CreateMenuitem(LOCSTR(MSG_MENU_NEWWIN), "N")),
186 MUIA_Family_Child, (IPTR) (menu[MEN_TAB_NEW] =
187 CreateMenuitem(LOCSTR(MSG_MENU_NEWTAB), "T")),
189 MUIA_Family_Child, (IPTR) (menu[MEN_OPEN_URL] =
190 CreateMenuitem(LOCSTR(MSG_MENU_URL), "T")),
192 MUIA_Family_Child, (IPTR) (menu[MEN_OPEN_FILE] =
193 CreateMenuitem(LOCSTR(MSG_MENU_FILE), 0)),
194 MUIA_Family_Child, (IPTR) (menu[MEN_OPEN_RECENT] =
195 CreateMenuitem(LOCSTR(MSG_MENU_RECENT), 0)),
196 MUIA_Family_Child, (IPTR) (menu[MEN_PRINT] =
197 CreateMenuitem(LOCSTR(MSG_MENU_PRINT), "P")),
198 MUIA_Family_Child, (IPTR) CreateMenuitem(NM_BARLABEL, NULL),
199 MUIA_Family_Child, (IPTR) (menu[MEN_ABOUT] =
200 CreateMenuitem(LOCSTR(MSG_MENU_ABOUT), "?")),
201 MUIA_Family_Child, (IPTR) CreateMenuitem(NM_BARLABEL, NULL),
202 MUIA_Family_Child, (IPTR) (menu[MEN_QUIT] =
203 CreateMenuitem(LOCSTR(MSG_MENU_QUIT), "Q")),
204 End),
205 MUIA_Family_Child, (IPTR) (MenuObject,
206 MUIA_Menu_Title, (IPTR) LOCSTR(MSG_MENU_EDIT),
207 MUIA_Family_Child, (IPTR) (menu[MEN_EDIT_COPY] =
208 CreateMenuitem(LOCSTR(MSG_MENU_COPY), "C")),
209 End),
210 MUIA_Family_Child, (IPTR) (MenuObject,
211 MUIA_Menu_Title, (IPTR) LOCSTR(MSG_MENU_WINDOWS),
212 MUIA_Family_Child, (IPTR) (menu[MEN_WINDOWS_LOG] =
213 CreateMenuitem(LOCSTR(MSG_MENU_LOG), 0)),
214 End),
215 MUIA_Family_Child, (IPTR) (MenuObject,
216 MUIA_Menu_Title, (IPTR) LOCSTR(MSG_MENU_SETTINGS),
217 MUIA_Family_Child, (IPTR) (menu[MEN_SETTINGS_SETTINGS] =
218 CreateMenuitem(LOCSTR(MSG_MENU_SETTINGS_SETTINGS), 0)),
219 MUIA_Family_Child, (IPTR) (menu[MEN_SETTINGS_SAVESETTINGS] =
220 CreateMenuitem(LOCSTR(MSG_MENU_SETTINGS_SAVE), 0)),
221 MUIA_Family_Child, (IPTR) (menu[MEN_SETTINGS_MUI] =
222 CreateMenuitem(LOCSTR(MSG_MENU_SETTINGS_MUI), 0)),
223 End),
224 End),
226 #if !defined(__AROS__)
227 MUIA_Application_Commands, &rexxcommands,
228 #endif
229 MUIA_Application_Window, (IPTR) (settingswin = WindowObject,
230 MUIA_Window_Title, (IPTR) "VPDF ยท Settings",
231 MUIA_Window_Width, MUIV_Window_Width_Screen(30),
232 MUIA_Window_Height, MUIV_Window_Height_Screen(40),
233 MUIA_Window_ID, MAKE_ID('V', 'P', 'S', 'T'),
234 MUIA_Window_RootObject, (IPTR) (VGroup,
235 Child, (IPTR) (settings = VPDFSettingsObject,
236 MUIA_Frame, MUIV_Frame_Group,
237 End),
238 Child, (IPTR) (HGroup,
239 Child, (IPTR) (btnSave = SimpleButton(LOCSTR(MSG_SAVE))),
240 Child, (IPTR) (btnUse = SimpleButton(LOCSTR(MSG_USE))),
241 //Child, SimpleButton("_Test"),
242 Child, (IPTR) HSpace(0),
243 Child, (IPTR) (btnCancel = SimpleButton(LOCSTR(MSG_CANCEL))),
244 End),
245 End),
246 End),
247 MUIA_Application_Window, printerwin = VPDFPrinterObject, End,
249 TAG_MORE, INITTAGS);
251 if (obj != NULL)
253 GETDATA;
254 int i;
255 memset(data, 0, sizeof(struct Data));
256 data->settings = settings;
257 data->printer = printerwin;
259 /* spawn document renderer common for all views */
260 data->renderer = RendererObject, End;
262 /* TODO: make some separate singleton for reqs? */
263 reqInit("");
265 /* menu notifications */
266 DoMethod((Object *)menu[MEN_ABOUT], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 1, MUIM_VPDF_About);
267 DoMethod((Object *)menu[MEN_QUIT], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
268 DoMethod((Object *)menu[MEN_TAB_NEW], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 2, MUIM_VPDF_CreateTab, 0);
269 DoMethod((Object *)menu[MEN_WINDOW_NEW], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 1, MUIM_VPDF_CreateWindow);
270 DoMethod((Object *)menu[MEN_OPEN_FILE], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 4, MUIM_VPDF_OpenFile, 0, NULL, MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty);
271 DoMethod((Object *)menu[MEN_SETTINGS_SETTINGS], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,settingswin, 3, MUIM_Set, MUIA_Window_Open, TRUE);
272 DoMethod((Object *)menu[MEN_SETTINGS_SAVESETTINGS], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,settingswin, 1, MUIM_VPDFSettings_Save);
273 DoMethod((Object *)menu[MEN_SETTINGS_MUI], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 2, MUIM_Application_OpenConfigWindow, 0);
274 DoMethod((Object *)menu[MEN_PRINT], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 1, MUIM_VPDF_PrintDocument);
275 DoMethod((Object *)menu[MEN_WINDOWS_LOG], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 3, MUIM_VPDF_LogMessage, 0, NULL);
276 DoMethod((Object *)menu[MEN_EDIT_COPY], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,obj, 1, MUIM_VPDF_SelectionCopy);
279 DoMethod(settingswin, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, settingswin, 3, MUIM_Set, MUIA_Window_Open, FALSE);
280 DoMethod(btnCancel, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_VPDF_SettingsCancel);
281 DoMethod(btnSave, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_VPDF_SettingsSave);
282 DoMethod(btnUse, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, MUIM_VPDF_SettingsUse);
284 DoMethod(printerwin, MUIM_Notify, MUIA_Window_Open, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_VPDF_Locked, MUIV_TriggerValue);
286 set(printerwin, MUIA_VPDFPrinter_PSName, xget(_app(obj), MUIA_VPDFSettings_PSName));
287 DoMethod(printerwin, MUIM_Notify, MUIA_VPDFPrinter_PSName, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_VPDFSettings_PSName, MUIV_TriggerValue);
288 set(printerwin, MUIA_VPDFPrinter_PrintingMode, xget(_app(obj), MUIA_VPDFSettings_PrintingMode));
289 DoMethod(printerwin, MUIM_Notify, MUIA_VPDFPrinter_PrintingMode, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_VPDFSettings_PrintingMode, MUIV_TriggerValue);
290 set(printerwin, MUIA_VPDFPrinter_PSMode, xget(_app(obj), MUIA_VPDFSettings_PSMode));
291 DoMethod(printerwin, MUIM_Notify, MUIA_VPDFPrinter_PSMode, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_VPDFSettings_PSMode, MUIV_TriggerValue);
295 return (IPTR)obj;
298 DEFDISP
300 GETDATA;
302 /* always 'use' settings. even if not modified */
303 DoMethod(data->settings, MUIM_VPDFSettings_Use);
305 /* delete all windows first as they might be using renderer object.
306 * skip settings window so all windows which save to settings have last chance now. */
309 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
310 Object *winobj_state = (Object*)winlist->lh_Head;
311 Object *winobj;
312 while((winobj = NextObject(&winobj_state)))
314 set(winobj, MUIA_Window_Open, FALSE);
315 if (winobj != data->settings)
317 DoMethod(obj, OM_REMMEMBER, winobj);
318 MUI_DisposeObject(winobj);
323 /* dispose renderer and the rest */
325 MUI_DisposeObject(data->renderer);
326 reqEnd();
328 return DOSUPER;
331 static void setuprecent(Object *obj, struct Data *data);
333 DEFMMETHOD(VPDF_OpenFile)
335 GETDATA;
336 char *filename = msg->filename;
337 int mode = msg->mode;
338 Object *window = (Object*)DoMethod(obj, MUIM_VPDF_FindWindowByID, msg->windowid == 0 ? MUIV_VPDF_FindWindowByID_Active : msg->windowid);
340 if (window == NULL)
342 window = (Object*)DoMethod(obj, MUIM_VPDF_CreateWindow);
343 mode = MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty;
346 if (filename == NULL)
348 filename = (char*)DoMethod(_app(obj), MUIM_VPDF_RequestFile,
349 MUIV_VPDF_RequestFile_Load,
350 NULL,
351 NULL,
352 NULL);
354 if (filename == NULL)
355 return FALSE;
358 if (window != NULL)
360 if (DoMethod(window, MUIM_VPDFWindow_OpenFile, filename, mode))
362 /* add to history */
363 int i;
364 int dupe = FALSE;
366 for(i=0; i<MAXRECENT && data->recent[i] != NULL && *data->recent[i] != '\0' && dupe == FALSE; i++)
367 dupe = 0 == stricmp(data->recent[i], filename);
369 if (dupe == FALSE)
371 free(data->recent[MAXRECENT-1]);
372 for(i=MAXRECENT-1;i>=1; i--)
373 data->recent[i] = data->recent[i-1];
375 data->recent[0] = strdup(filename);
376 setuprecent(obj, data);
381 return TRUE;
384 DEFMMETHOD(VPDF_OpenRecentFile)
386 GETDATA;
387 if (data->recent[msg->idx] != NULL && *data->recent[msg->idx] != '\0')
389 return DoMethod(obj, MUIM_VPDF_OpenFile, msg->windowid, data->recent[msg->idx], MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty);
391 //KPrintF("Open recent file %s\n", data->recent[msg->idx]);
393 return FALSE;
396 DEFMMETHOD(VPDF_CreateTab)
398 Object *window = (Object*)DoMethod(obj, MUIM_VPDF_FindWindowByID, msg->windowid == 0 ? MUIV_VPDF_FindWindowByID_Active : msg->windowid);
400 if (window != NULL)
402 return DoMethod(window, MUIM_VPDFWindow_CreateTab);
405 return (ULONG)-1;
408 DEFMMETHOD(VPDF_CreateWindow)
410 GETDATA;
411 Object *refwindow = (Object*)DoMethod(obj, MUIM_VPDF_FindActiveWindow);
412 Object *window = VPDFWindowObject,
413 MUIA_VPDFWindow_ID, ++data->windowid,
414 MUIA_Window_ID, MAKE_ID('V','P', 'W','O'), /* this is going to be nullified for all non-active windows */
415 MUIA_Window_LeftEdge, 20,
416 MUIA_Window_TopEdge, 20,
417 MUIA_Window_RefWindow, (IPTR) refwindow,
418 MUIA_Window_OverrideStoredPosition, refwindow != NULL ? TRUE : FALSE,
419 End;
421 if (window != NULL)
423 int id = xget(window, MUIA_VPDFWindow_ID);
424 DoMethod(obj, OM_ADDMEMBER, window);
425 DoMethod(window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, obj, 2, MUIM_VPDF_CloseWindow, id);
426 DoMethod(window, MUIM_Notify, MUIA_Window_Activate, TRUE, obj, 2, MUIM_VPDF_NewActiveWindow, window);
427 set(window, MUIA_Window_Open, TRUE);
430 return (ULONG)window;
433 DEFMMETHOD(VPDF_HandleAppMessage)
435 struct AppMessage *amsg = msg->appmessage;
436 struct WBArg *ap = amsg->am_ArgList;
437 char buf[1024];
439 NameFromLock(ap->wa_Lock,buf,sizeof(buf));
440 AddPart(buf,ap->wa_Name,sizeof(buf));
442 if (strMatch(buf, "#?.pdf"))
443 DoMethod(obj, MUIM_VPDF_OpenFile, msg->windowid, buf, MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty);
445 return 0;
448 /// Helper Functions (requesters)
450 M_HOOK(AslRefresh, struct FileRequester *req,struct IntuiMessage *imsg)
452 if (imsg->Class==IDCMP_REFRESHWINDOW)
453 DoMethod(req->fr_UserData,MUIM_Application_CheckRefresh);
456 static struct FileRequester *reqLoad = NULL;
457 static struct FileRequester *reqSave = NULL;
459 static void reqInit(char *path)
461 char *dir = strdup(path);
462 char *file = FilePart(path);
463 char *fPart = PathPart(dir);
465 if (fPart)
466 dir[ fPart - dir ] = 0;
468 reqSave = MUI_AllocAslRequestTags(ASL_FileRequest,
469 ASLFR_TitleText , "Save image...",
470 ASLFR_InitialPattern, "",
471 ASLFR_DoSaveMode , TRUE,
472 ASLFR_InitialDrawer , dir,
473 ASLFR_InitialFile , file,
474 ASLFR_DoPatterns , TRUE,
475 ASLFR_RejectIcons , TRUE,
476 TAG_DONE);
478 reqLoad = MUI_AllocAslRequestTags(ASL_FileRequest,
479 ASLFR_TitleText , "Load image...",
480 ASLFR_InitialPattern, "",
481 ASLFR_DoSaveMode , FALSE,
482 ASLFR_InitialDrawer , dir,
483 ASLFR_InitialFile , file,
484 ASLFR_DoPatterns , TRUE,
485 ASLFR_RejectIcons , TRUE,
486 TAG_DONE);
488 free(dir);
491 static void reqEnd(void)
493 if (reqSave)
494 MUI_FreeAslRequest(reqSave);
495 if (reqLoad)
496 MUI_FreeAslRequest(reqLoad);
499 DEFMMETHOD(VPDF_RequestFile)
501 static char buf[1024];
502 char *res = NULL;
503 struct FileRequester *req;
504 Object *window = (Object*)DoMethod(obj, MUIM_VPDF_FindActiveWindow);
506 if (msg->mode & MUIV_VPDF_RequestFile_Load)
507 req = reqLoad;
508 else
509 req = reqSave;
511 if (req != NULL)
513 char *title = NULL;
515 set(obj, MUIA_Application_Sleep, TRUE);
517 /* will extract directory path first */
519 buf[ 0 ] = 0;
521 if (msg->initialdir != NULL)
522 stccpy(buf, msg->initialdir, sizeof(buf));
523 else if (msg->initialpath != NULL)
525 stccpy(buf, msg->initialpath, sizeof(buf));
526 buf[ (int)PathPart(buf) - (int)&buf[ 0 ] ] = 0;
529 /* setup proper title */
531 if (msg->mode & MUIV_VPDF_RequestFile_DirectoryOnly)
532 title = (STRPTR) LOCSTR( MSG_REQ_DRAWER );
533 else if (msg->mode & MUIV_VPDF_RequestFile_Load)
534 title = (STRPTR) LOCSTR( MSG_REQ_OPEN );
535 else if (msg->mode & MUIV_VPDF_RequestFile_Save)
536 title = (STRPTR) LOCSTR( MSG_REQ_SAVE );
538 if (MUI_AslRequestTags(req,
539 title != NULL ? ASLFR_TitleText : TAG_IGNORE, title,
540 ASLFR_UserData, obj,
541 ASLFR_IntuiMsgFunc, &AslRefreshHook,
542 ASLFR_PrivateIDCMP, FALSE,
543 buf[ 0 ] ? ASLFR_InitialDrawer : TAG_IGNORE, buf,
544 ASLFR_InitialFile, msg->initialfile ? msg->initialfile : msg->initialpath ? (char*)FilePart(msg->initialpath) : (char*)"",
545 ASLFR_DrawersOnly, msg->mode & MUIV_VPDF_RequestFile_DirectoryOnly,
546 ASLFR_Window, window != 0 ? xget(window, MUIA_Window_Window) : 0,
547 TAG_DONE))
549 if (*req->fr_File)
551 res = buf;
552 stccpy(buf, req->fr_Drawer, sizeof(buf));
553 if (!(msg->mode & MUIV_VPDF_RequestFile_DirectoryOnly))
554 AddPart(buf, req->fr_File, sizeof(buf));
556 else if (*req->fr_Drawer && (msg->mode & MUIV_VPDF_RequestFile_DirectoryOnly))
558 res = buf;
559 stccpy(buf, req->fr_Drawer, sizeof(buf));
563 set(obj, MUIA_Application_Sleep, FALSE);
566 return (ULONG)res;
570 ////
572 static void setuprecent(Object *obj, struct Data *data)
574 #if defined(__AROS__)
575 #define MUIM_Menustrip_Popup (MUIB_MUI|0x00420e76) /* MUI: V20 */
576 #define MUIM_Menustrip_ExitChange (MUIB_MUI|0x0042ce4d) /* MUI: V20 */
577 #define MUIM_Menustrip_InitChange (MUIB_MUI|0x0042dcd9) /* MUI: V20 */
578 // FIXME: AROS
579 #endif
580 int i;
581 Object *o;
582 DoMethod((Object *)menu[MEN_OPEN_RECENT] , MUIM_Menustrip_InitChange);
584 /* cleanup recents */
585 while((o = (Object *)DoMethod((Object *)menu[MEN_OPEN_RECENT], MUIM_Family_GetChild, MUIV_Family_GetChild_First)))
587 DoMethod((Object *)menu[MEN_OPEN_RECENT], MUIM_Family_Remove, o);
588 MUI_DisposeObject(o);
591 for(i=0; i<MAXRECENT && data->recent[i] != NULL && *data->recent[i] != '\0'; i++)
593 menu[MEN_OPEN_RECENT0-i] = MenuitemObject,
594 MUIA_Menuitem_Title, (IPTR)data->recent[i],
595 MUIA_Menuitem_CopyStrings, TRUE,
596 End;
597 DoMethod((Object *)menu[MEN_OPEN_RECENT0-i], MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime, obj, 3, MUIM_VPDF_OpenRecentFile, 0, i);
598 DoMethod((Object *)menu[MEN_OPEN_RECENT], MUIM_Family_AddTail, menu[MEN_OPEN_RECENT0-i]);
601 DoMethod((Object *)menu[MEN_OPEN_RECENT], MUIM_Menustrip_ExitChange);
604 /* this method finds window which was last activated, not currently active one! */
606 DEFMMETHOD(VPDF_FindActiveWindow)
608 GETDATA;
609 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
610 Object *winobj_state = (Object*)winlist->lh_Head;
611 Object *winobj;
612 ULONG v;
614 while((winobj = NextObject(&winobj_state)))
616 //if (xget(winobj, MUIA_Window_Activate))
617 if (xget(winobj, MUIA_Window_ID) != 0 && get(winobj, MUIA_VPDFWindow_ID, &v))
618 return (IPTR) winobj;
621 return 0;
624 DEFMMETHOD(VPDF_FindWindowByID)
626 GETDATA;
628 if (msg->windowid == MUIV_VPDF_FindWindowByID_Active)
630 return DoMethod(obj, MUIM_VPDF_FindActiveWindow);
632 else
634 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
635 Object *winobj_state = (Object*)winlist->lh_Head;
636 Object *winobj;
637 while((winobj = NextObject(&winobj_state)))
639 /* validate if it's document view window */
640 int v;
641 if (get(winobj, MUIA_VPDFWindow_ID, &v) == FALSE)
642 continue;
644 if (msg->windowid == MUIV_VPDF_FindWindowByID_First)
645 return (IPTR) winobj;
646 else if (msg->windowid == xget(winobj, MUIA_VPDFWindow_ID))
647 return (IPTR) winobj;
651 return 0;
654 DEFMMETHOD(VPDF_CloseWindow)
656 Object *window = (Object*)DoMethod(obj, MUIM_VPDF_FindWindowByID, msg->windowid == 0 ? MUIV_VPDF_FindWindowByID_Active : msg->windowid);
658 if (window != NULL)
660 set(window, MUIA_Window_Open, FALSE);
661 DoMethod(obj, OM_REMMEMBER, window);
662 DoMethod(obj, MUIM_Application_PushMethod, window, 1, OM_DISPOSE);
664 if (DoMethod(obj, MUIM_VPDF_FindWindowByID, MUIV_VPDF_FindWindowByID_First) == 0)
665 DoMethod(obj, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
667 return TRUE;
669 return FALSE;
672 DEFMMETHOD(Export)
674 GETDATA;
675 int i;
677 for(i=0; i<MAXRECENT && data->recent[i] != NULL && *data->recent[i] != '\0'; i++)
680 DoMethod(msg->dataspace, MUIM_Dataspace_Add, data->recent[i], strlen(data->recent[i]) + 1, ID_VPDF_RECENT0 + i);
682 return DOSUPER;
685 DEFMMETHOD(Import)
687 GETDATA;
688 int i, j;
690 for(i=0, j=0; i<MAXRECENT; i++)
692 char *recent = (char*)DoMethod(msg->dataspace, MUIM_Dataspace_Find, ID_VPDF_RECENT0 + i);
693 if (recent != NULL)
695 BPTR lock;
696 struct Process *theProc = (struct Process *)FindTask(NULL);
697 struct Window *oldWindowPtr = theProc->pr_WindowPtr;
698 theProc->pr_WindowPtr = (APTR)(-1L);
700 if (lock = Lock(recent, ACCESS_READ))
702 data->recent[j] = strdup(recent);
703 j++;
704 UnLock(lock);
706 theProc->pr_WindowPtr = oldWindowPtr;
710 setuprecent(obj, data);
712 return DOSUPER;
715 DEFGET
717 GETDATA;
718 ULONG v;
720 switch (msg->opg_AttrID)
722 case MUIA_VPDF_Renderer:
723 *(ULONG*)msg->opg_Storage = (ULONG)data->renderer;
724 return TRUE;
727 /* check for settings attribute */
729 if (msg->opg_AttrID > MUIA_VPDFSettings_First && msg->opg_AttrID < MUIA_VPDFSettings_Last)
731 if (get(data->settings, msg->opg_AttrID, &v))
733 *(ULONG*)msg->opg_Storage = v;
734 return TRUE;
738 /* */
740 return DOSUPER;
743 DEFSET
745 GETDATA;
747 FORTAG(INITTAGS)
749 case MUIA_VPDF_Locked:
751 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
752 Object *winobj_state = (Object*)winlist->lh_Head;
753 Object *winobj;
754 while((winobj = NextObject(&winobj_state)))
756 /* validate if it's document view window */
757 int v;
758 if (get(winobj, MUIA_VPDFWindow_ID, &v) == FALSE)
759 continue;
761 set(winobj, MUIA_Window_Sleep, tag->ti_Data);
764 break;
766 default:
767 /* check for settings attribute */
769 if (tag->ti_Tag > MUIA_VPDFSettings_First && tag->ti_Tag < MUIA_VPDFSettings_Last)
771 set(data->settings, tag->ti_Tag, tag->ti_Data);
774 NEXTTAG
776 return DOSUPER;
779 DEFMMETHOD(VPDF_LogMessage)
781 GETDATA;
783 if (data->logger == NULL)
785 data->loggerwin = WindowObject,
786 MUIA_Window_Title, (IPTR) "VPDF ยท Log",
787 MUIA_Window_Width, MUIV_Window_Width_Screen(30),
788 MUIA_Window_Height, MUIV_Window_Height_Screen(10),
789 MUIA_Window_RootObject,
790 (IPTR) (data->logger = LoggerObject, End),
791 End;
793 if (data->loggerwin != NULL)
795 DoMethod(obj, OM_ADDMEMBER, data->loggerwin);
796 DoMethod(data->loggerwin, MUIM_Notify, MUIA_Window_CloseRequest, MUIV_EveryTime, data->loggerwin, 3, MUIM_Set, MUIA_Window_Open, FALSE);
800 if (data->logger != NULL)
802 if (msg->message == NULL || xget(_app(obj), MUIA_VPDFSettings_OpenLog))
803 set(data->loggerwin, MUIA_Window_Open, TRUE);
806 if (data->logger != NULL && msg->message != NULL)
808 DoMethod(data->logger, MUIM_Logger_LogMessage, msg->severity, msg->message);
810 /* message is always strdupped() so dispose it here. logger has to make a copy! */
811 free(msg->message);
814 return 0;
817 DEFMMETHOD(VPDF_NewActiveWindow)
819 /* only setup window id for active window so it will be used when the application is restarted*/
821 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
822 Object *winobj_state = (Object*)winlist->lh_Head;
823 Object *winobj;
824 while((winobj = NextObject(&winobj_state)))
826 /* validate if it's document view window */
827 int v;
828 if (get(winobj, MUIA_VPDFWindow_ID, &v) == FALSE)
829 continue;
831 set(winobj, MUIA_Window_ID, winobj == msg->window ? MAKE_ID('V','P', 'W','O') : 0);
834 return 0;
837 DEFMMETHOD(VPDF_SettingsCancel)
839 GETDATA;
840 DoMethod(data->settings, MUIM_VPDFSettings_Cancel);
841 set(_win(data->settings), MUIA_Window_Open, FALSE);
842 return 0;
846 DEFMMETHOD(VPDF_SettingsUse)
848 GETDATA;
849 DoMethod(obj, MUIM_VPDF_SettingsApply, DoMethod(data->settings, MUIM_VPDFSettings_Use));
850 return 0;
854 DEFMMETHOD(VPDF_SettingsSave)
856 GETDATA;
857 DoMethod(obj, MUIM_VPDF_SettingsApply, DoMethod(data->settings, MUIM_VPDFSettings_Save));
858 return 0;
861 DEFMMETHOD(VPDF_SettingsApply)
863 GETDATA;
864 set(_win(data->settings), MUIA_Window_Open, FALSE);
865 return 0;
868 DEFMMETHOD(VPDF_About)
870 GETDATA;
872 if (data->aboutbox == NULL)
874 data->aboutbox = AboutboxObject,
875 MUIA_Aboutbox_Credits, (IPTR) __credits,
876 End;
878 DoMethod(obj, OM_ADDMEMBER, data->aboutbox);
881 if (data->aboutbox != NULL)
882 set(data->aboutbox, MUIA_Window_Open, TRUE);
884 return 0;
887 DEFMMETHOD(VPDF_PrintDocument)
889 GETDATA;
890 Object *activewindow = (Object*)DoMethod(obj, MUIM_VPDF_FindActiveWindow);
892 if (activewindow != NULL)
894 void *doc = (void*)xget(activewindow, MUIA_VPDFWindow_PDFDocument);
895 if (doc != NULL)
896 DoMethod(data->printer, MUIM_VPDFPrinter_PrintDocument, doc);
898 return TRUE;
901 DEFMMETHOD(DragDrop)
903 GETDATA;
904 int v;
906 /* check if it was title object */
908 if (_parent(msg->obj) != NULL && get(_parent(msg->obj), MUIA_VPDFTitle_IsTitle, &v))
910 struct List *winlist = (struct List*)xget(obj, MUIA_Application_WindowList);
911 int ownwindow = FALSE;
913 if (xget(_parent(msg->obj), MUIA_Group_ChildCount) <= 1)
914 return DOSUPER;
916 if (winlist != NULL)
918 Object *winobj_state = (Object*)winlist->lh_Head;
919 Object *winobj;
920 while((winobj = NextObject(&winobj_state)))
922 /* validate if it's document view window */
923 int v;
924 if (get(winobj, MUIA_VPDFWindow_ID, &v))
926 if (msg->x > xget(winobj, MUIA_Window_LeftEdge) && msg->x < xget(winobj, MUIA_Window_LeftEdge) + xget(winobj, MUIA_Window_Width)
927 && msg->y > xget(winobj, MUIA_Window_TopEdge) && msg->y < xget(winobj, MUIA_Window_TopEdge) + xget(winobj, MUIA_Window_Height))
929 ownwindow = TRUE;
931 break;
937 /* detach document from window (create new and add the document) */
939 if (ownwindow == FALSE)
941 Object *oldwindow = _win(msg->obj);
942 Object *newwindow = (Object*)DoMethod(obj, MUIM_VPDF_CreateWindow);
944 if (newwindow != NULL)
946 struct MUIP_VPDFWindow_DetachView msg;
947 msg.MethodID = MUIM_VPDFWindow_DetachView;
948 msg.tabind = MUIV_VPDFWindow_DetachView_Active;
950 if (DoMethodA(oldwindow, &msg))
953 DoMethod(newwindow, MUIM_VPDFWindow_AttachView, MUIV_VPDFWindow_AttachView_CurrentTabIfEmpty, msg.docview, msg.title);
959 return DOSUPER;
962 /* rexx handling */
964 static LONG Rexx(void)
966 #if defined(__AROS__)
967 kprintf("[Rexx] not implemented\n");
968 // FIXME: AROS
969 #else
970 struct Hook *h = (struct Hook*)(APTR)REG_A0;
971 Object *obj = (Object*)REG_A2;
972 IPTR *params = (IPTR*)REG_A1;
974 switch ((ULONG)h->h_Data)
976 case REXX_ABOUT:
977 break;
979 case REXX_OPEN:
981 char *file = (char*)*params;
982 ULONG newtab = params[1];
984 char *ftemp = file;
985 while(*ftemp != '\0')
987 if(*ftemp == '\\')
988 *ftemp = ' ';
989 ftemp++;
992 DoMethod(obj, MUIM_VPDF_OpenFile, 0, file, newtab ? MUIV_VPDFWindow_OpenFile_CurrentTab : MUIV_VPDFWindow_OpenFile_CurrentTabIfEmpty);
993 break;
996 case REXX_SAVE:
997 break;
999 case REXX_APPTOFRONT:
1000 break;
1002 #endif
1003 return 0;
1006 DEFMMETHOD(VPDF_SelectionCopy)
1008 GETDATA;
1009 Object *activewindow = (Object*)DoMethod(obj, MUIM_VPDF_FindActiveWindow);
1011 if (activewindow != NULL)
1013 Object *documentview = (Object*)xget(activewindow, MUIA_VPDFWindow_ActiveDocumentView);
1014 if (documentview != NULL)
1016 DoMethod(documentview, MUIM_DocumentView_SelectionCopy);
1020 return TRUE;
1022 /* */
1024 BEGINMTABLE
1025 DECNEW
1026 DECDISP
1027 DECGET
1028 DECSET
1029 DECMMETHOD(Import)
1030 DECMMETHOD(Export)
1031 DECMMETHOD(DragDrop)
1032 DECMMETHOD(VPDF_OpenFile)
1033 DECMMETHOD(VPDF_CreateTab)
1034 DECMMETHOD(VPDF_CreateWindow)
1035 DECMMETHOD(VPDF_HandleAppMessage)
1036 DECMMETHOD(VPDF_RequestFile)
1037 DECMMETHOD(VPDF_OpenRecentFile)
1038 DECMMETHOD(VPDF_FindActiveWindow)
1039 DECMMETHOD(VPDF_FindWindowByID)
1040 DECMMETHOD(VPDF_CloseWindow)
1041 DECMMETHOD(VPDF_LogMessage)
1042 DECMMETHOD(VPDF_NewActiveWindow)
1043 DECMMETHOD(VPDF_SettingsCancel)
1044 DECMMETHOD(VPDF_SettingsSave)
1045 DECMMETHOD(VPDF_SettingsUse)
1046 DECMMETHOD(VPDF_SettingsApply)
1047 DECMMETHOD(VPDF_About)
1048 DECMMETHOD(VPDF_PrintDocument)
1049 DECMMETHOD(VPDF_SelectionCopy)
1050 ENDMTABLE
1052 DECSUBCLASS_NC(MUIC_Application, VPDFClass)