/* * saveas.c * Copyright (C) 1998-2001 A.J. van Os; Released under GPL * * Description: * Functions to save the results as a textfile or a drawfile */ #include #include #include "DeskLib:Menu.h" #include "DeskLib:Save.h" #include "DeskLib:Template.h" #include "DeskLib:Window.h" #include "drawfile.h" #include "antiword.h" /* The window handle of the save window */ static window_handle tSaveWindow = 0; /* Xfer_send box fields */ #define DRAG_SPRITE 3 #define OK_BUTTON 0 #define CANCEL_BUTTON (-1) #define FILENAME_ICON 2 /* * saveas - a wrapper around Save_InitSaveWindowhandler */ static void saveas(int iFileType, char *szOutfile, size_t tEstSize, save_filesaver save_function, void *pvReference) { TRACE_MSG("saveas"); if (tSaveWindow == 0) { tSaveWindow = Window_Create("xfer_send", template_TITLEMIN); } Icon_SetText(tSaveWindow, FILENAME_ICON, szOutfile); Window_Show(tSaveWindow, open_UNDERPOINTER); (void)Save_InitSaveWindowHandler(tSaveWindow, FALSE, TRUE, TRUE, DRAG_SPRITE, OK_BUTTON, CANCEL_BUTTON, FILENAME_ICON, save_function, NULL, NULL, tEstSize, iFileType, pvReference); } /* end of saveas */ static BOOL bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename) { if (fwrite(pvBytes, sizeof(char), tSize, pFile) != tSize) { werr(0, "I can't write to '%s'", szFilename); return FALSE; } return TRUE; } /* end of bWrite2File */ /* * bText2File - Save the generated draw file to a Text file */ static BOOL bText2File(char *szFilename, void *pvHandle) { FILE *pFile; diagram_type *pDiag; drawfile_object *pObj; drawfile_text *pText; const char *pcTmp; int iToGo, iX, iYtopPrev, iHeight, iLines; BOOL bFirst, bIndent, bSuccess; TRACE_MSG("bText2File"); fail(szFilename == NULL || szFilename[0] == '\0'); fail(pvHandle == NULL); DBG_MSG(szFilename); pDiag = (diagram_type *)pvHandle; pFile = fopen(szFilename, "w"); if (pFile == NULL) { werr(0, "I can't open '%s' for writing", szFilename); return FALSE; } bFirst = TRUE; iYtopPrev = 0; iHeight = (int)lWord2DrawUnits20(DEFAULT_FONT_SIZE); bSuccess = TRUE; fail(pDiag->tInfo.length < offsetof(drawfile_diagram, objects)); iToGo = pDiag->tInfo.length - offsetof(drawfile_diagram, objects); DBG_DEC(iToGo); pcTmp = (const char *)pDiag->tInfo.data + offsetof(drawfile_diagram, objects); while (iToGo > 0 && bSuccess) { pObj = (drawfile_object *)pcTmp; switch (pObj->type) { case drawfile_TYPE_TEXT: pText = &pObj->data.text; /* Compute the number of lines */ iLines = (iYtopPrev - pText->bbox.max.y + iHeight / 2) / iHeight; DBG_DEC_C(iLines < 0, iYtopPrev); DBG_DEC_C(iLines < 0, pText->bbox.max.y); fail(iLines < 0); bIndent = iLines > 0 || bFirst; bFirst = FALSE; /* Print the newlines */ while (iLines > 0 && bSuccess) { bSuccess = bWrite2File("\n", 1, pFile, szFilename); iLines--; } /* Print the indentation */ if (bIndent && bSuccess) { for (iX = Drawfile_ScreenToDraw(8); iX <= pText->bbox.min.x && bSuccess; iX += Drawfile_ScreenToDraw(16)) { bSuccess = bWrite2File(" ", 1, pFile, szFilename); } } if (!bSuccess) { break; } /* Print the text object */ bSuccess = bWrite2File(pText->text, strlen(pText->text), pFile, szFilename); /* Setup for the next object */ iYtopPrev = pText->bbox.max.y; iHeight = pText->bbox.max.y - pText->bbox.min.y; break; case drawfile_TYPE_FONT_TABLE: case drawfile_TYPE_PATH: case drawfile_TYPE_SPRITE: case drawfile_TYPE_JPEG: /* These are not relevant in a textfile */ break; default: DBG_DEC(pObj->type); bSuccess = FALSE; break; } pcTmp += pObj->size; iToGo -= pObj->size; } DBG_DEC_C(iToGo != 0, iToGo); if (bSuccess) { bSuccess = bWrite2File("\n", 1, pFile, szFilename); } (void)fclose(pFile); if (bSuccess) { vSetFiletype(szFilename, FILETYPE_TEXT); } else { (void)remove(szFilename); werr(0, "Unable to save textfile '%s'", szFilename); } return bSuccess; } /* end of bText2File */ /* * bSaveTextfile - save the diagram as a text file */ BOOL bSaveTextfile(event_pollblock *pEvent, void *pvReference) { diagram_type *pDiag; size_t tRecLen, tNbrRecs, tEstSize; TRACE_MSG("bSaveTextfile"); fail(pEvent == NULL); fail(pvReference == NULL); pDiag = (diagram_type *)pvReference; switch (pEvent->type) { case event_SEND: /* From a menu */ fail(pEvent->data.message.header.action != message_MENUWARN); if (menu_currentopen != pDiag->pSaveMenu || pEvent->data.message.data.menuwarn.selection[0] != SAVEMENU_SAVETEXT) { return FALSE; } break; case event_KEY: /* From a key short cut */ if (pEvent->data.key.caret.window != pDiag->tMainWindow) { return FALSE; } break; default: DBG_DEC(pEvent->type); return FALSE; } tRecLen = sizeof(drawfile_text) + DEFAULT_SCREEN_WIDTH * 2 / 3; tNbrRecs = pDiag->tInfo.length / tRecLen + 1; tEstSize = tNbrRecs * DEFAULT_SCREEN_WIDTH * 2 / 3; DBG_DEC(tEstSize); saveas(FILETYPE_TEXT, "WordText", tEstSize, bText2File, pDiag); return TRUE; } /* end of bSaveTextfile */ /* * bDraw2File - Save the generated draw file to a Draw file * * Remark: This is not a simple copy action. The origin of the * coordinates (0,0) must move from the top-left corner to the * bottom-left corner. */ static BOOL bDraw2File(char *szFilename, void *pvHandle) { FILE *pFile; diagram_type *pDiagram; wimp_box *pBbox; drawfile_object *pObj; drawfile_text *pText; drawfile_path *pPath; drawfile_sprite *pSprite; drawfile_jpeg *pJpeg; int *piPath; char *pcTmp; int iYadd, iToGo, iSize; BOOL bSuccess; TRACE_MSG("bDraw2File"); fail(szFilename == NULL || szFilename[0] == '\0'); fail(pvHandle == NULL); NO_DBG_MSG(szFilename); pDiagram = (diagram_type *)pvHandle; pFile = fopen(szFilename, "wb"); if (pFile == NULL) { werr(0, "I can't open '%s' for writing", szFilename); return FALSE; } iToGo = pDiagram->tInfo.length; DBG_DEC(iToGo); pcTmp = pDiagram->tInfo.data; bSuccess = bWrite2File(pcTmp, offsetof(drawfile_diagram, bbox), pFile, szFilename); if (bSuccess) { pcTmp += offsetof(drawfile_diagram, bbox); iToGo -= offsetof(drawfile_diagram, bbox); pBbox = (wimp_box *)pcTmp; iYadd = -pBbox->min.y; pBbox->min.y += iYadd; pBbox->max.y += iYadd; bSuccess = bWrite2File(pcTmp, sizeof(*pBbox), pFile, szFilename); iToGo -= sizeof(*pBbox); DBG_DEC(iToGo); pcTmp += sizeof(*pBbox); } else { iYadd = 0; } while (iToGo > 0 && bSuccess) { pObj = (drawfile_object *)pcTmp; iSize = pObj->size; switch (pObj->type) { case drawfile_TYPE_FONT_TABLE: bSuccess = bWrite2File(pcTmp, iSize, pFile, szFilename); pcTmp += iSize; iToGo -= iSize; break; case drawfile_TYPE_TEXT: pText = &pObj->data.text; /* First correct the coordinates */ pText->bbox.min.y += iYadd; pText->bbox.max.y += iYadd; pText->base.y += iYadd; /* Now write the information to file */ bSuccess = bWrite2File(pcTmp, iSize, pFile, szFilename); pcTmp += pObj->size; iToGo -= pObj->size; break; case drawfile_TYPE_PATH: pPath = &pObj->data.path; /* First correct the coordinates */ pPath->bbox.min.y += iYadd; pPath->bbox.max.y += iYadd; /* Now write the information to file */ bSuccess = bWrite2File(pPath, sizeof(*pPath), pFile, szFilename); pcTmp += sizeof(*pPath); iSize = pObj->size - sizeof(*pPath); fail(iSize < 14 * sizeof(int)); /* Second correct the path coordinates */ piPath = xmalloc(iSize); memcpy(piPath, pcTmp, iSize); piPath[ 2] += iYadd; piPath[ 5] += iYadd; piPath[ 8] += iYadd; piPath[11] += iYadd; if (bSuccess) { bSuccess = bWrite2File(piPath, iSize, pFile, szFilename); pcTmp += iSize; } piPath = xfree(piPath); iToGo -= pObj->size; break; case drawfile_TYPE_SPRITE: pSprite = &pObj->data.sprite; /* First correct the coordinates */ pSprite->bbox.min.y += iYadd; pSprite->bbox.max.y += iYadd; /* Now write the information to file */ bSuccess = bWrite2File(pcTmp, iSize, pFile, szFilename); pcTmp += pObj->size; iToGo -= pObj->size; break; case drawfile_TYPE_JPEG: pJpeg = &pObj->data.jpeg; /* First correct the coordinates */ pJpeg->bbox.min.y += iYadd; pJpeg->bbox.max.y += iYadd; pJpeg->trfm.entries[2][1] += iYadd; /* Now write the information to file */ bSuccess = bWrite2File(pcTmp, iSize, pFile, szFilename); pcTmp += pObj->size; iToGo -= pObj->size; break; default: DBG_DEC(pObj->type); bSuccess = FALSE; break; } } DBG_DEC_C(iToGo != 0, iToGo); (void)fclose(pFile); if (bSuccess) { vSetFiletype(szFilename, FILETYPE_DRAW); } else { (void)remove(szFilename); werr(0, "Unable to save drawfile '%s'", szFilename); } return bSuccess; } /* end of bDraw2File */ /* * bSaveDrawfile - save the diagram as a draw file */ BOOL bSaveDrawfile(event_pollblock *pEvent, void *pvReference) { diagram_type *pDiag; size_t tEstSize; TRACE_MSG("bSaveDrawfile"); fail(pEvent == NULL); fail(pvReference == NULL); pDiag = (diagram_type *)pvReference; switch (pEvent->type) { case event_SEND: /* From a menu */ fail(pEvent->data.message.header.action != message_MENUWARN); if (menu_currentopen != pDiag->pSaveMenu || pEvent->data.message.data.menuwarn.selection[0] != SAVEMENU_SAVEDRAW) { return FALSE; } break; case event_KEY: /* From a key short cut */ if (pEvent->data.key.caret.window != pDiag->tMainWindow) { return FALSE; } break; default: DBG_DEC(pEvent->type); return FALSE; } tEstSize = pDiag->tInfo.length; DBG_DEC(tEstSize); saveas(FILETYPE_DRAW, "WordDraw", tEstSize, bDraw2File, pDiag); return TRUE; } /* end of bSaveDrawfile */