/*
* 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 <stdio.h>
#include <string.h>
#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 */
|