File:  [Public] / Amaya / amaya / HTMLbook.c
Revision 1.2: download - view: text, annotated - select for diffs
Wed Mar 19 17:13:26 1997 UTC (27 years, 3 months ago) by cvs
Branches: MAIN
CVS tags: HEAD
Allow Amaya to control the print through API functions
Irene

/*
 *
 *  (c) COPYRIGHT MIT and INRIA, 1996.
 *  Please first read the full copyright statement in file COPYRIGHT.
 *
 */

/*
 * Initialization functions and button functions of Amaya application.
 *
 * Authors: V. Quint, I. Vatton
 */


/* Included headerfiles */
#define THOT_EXPORT
#include "amaya.h"
#include "print.h"

#define NumFormPrint       1
#define NumMenuOptions     2
#define NumMenuPaperFormat 3
#define NumMenuSupport     4
#define NumZonePrinterName 5
#define PRINT_MAX_REF	   6

/* Thot printer variables */
static int              PaperPrint;
static int              ManualFeed;
static int              PageSize;
static char             PSdir[MAX_PATH];
static char             pPrinter[MAX_PATH];
static Document		docPrint;
static boolean		numberLinks;
static boolean		withToC;
static int              basePrint;

#include "init_f.h"
#include "HTMLactions_f.h"
#include "HTMLbook_f.h"
#include "HTMLedit_f.h"


/*----------------------------------------------------------------------
  SetInternalLinks
  Associate a InternalLink attribute with all anchor (A) elements of the
  document which designate another anchor in the same document.
  InternalLink is a Thot reference attribute that links a source and a
  target anchor and that allows P schemas to display and print cross-references
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void             SetInternalLinks (Document document)
#else
static void             SetInternalLinks (document)
Document                document;
#endif
{
   Element	        root, el;
   Element		link, target;
   ElementType		elType;
   Attribute		HrefAttr, IntLinkAttr;
   AttributeType	attrType;
   int			length;
   char			*text;


   root = TtaGetMainRoot (document);
   elType = TtaGetElementType (root);
   elType.ElTypeNum = HTML_EL_BODY;
   el = TtaSearchTypedElement (elType, SearchForward, root);

   elType.ElTypeNum = HTML_EL_Anchor;
   attrType.AttrSSchema = elType.ElSSchema;
   /* looks for all anchors in the document */
   link = el;
   while (link != NULL)
     {
       link = TtaSearchTypedElement (elType, SearchForward, link);
       if (link != NULL)
	 /* an anchor has been found */
	 {
	 attrType.AttrTypeNum = HTML_ATTR_HREF_;
         HrefAttr = TtaGetAttribute (link, attrType);
         if (HrefAttr != NULL)
	   /* this anchor has an HREF attribute */
	   {
	   length = TtaGetTextAttributeLength (HrefAttr);
	   text = TtaGetMemory (length + 1);
	   TtaGiveTextAttributeValue (HrefAttr, text, &length);
	   if (text[0] == '#')
	      /* it'a an internal link. Attach an attribute InternalLink to */
	      /* the link, if this attribute does not exist yet */
	      {
	        attrType.AttrTypeNum = HTML_ATTR_InternalLink;
		IntLinkAttr = TtaGetAttribute (link, attrType);
		if (IntLinkAttr == NULL)
		   {
		     IntLinkAttr = TtaNewAttribute (attrType);
		     TtaAttachAttribute (link, IntLinkAttr, document);
		   }
		/* looks for the target element */
		target = SearchNAMEattribute (document, &text[1], NULL);
		if (target != NULL)
		   /* set the Thot link */
		   TtaSetAttributeReference (IntLinkAttr, link, document,
					     target, document);
	      }
	   TtaFreeMemory (text);
	   }
	 }
     }
}


/*----------------------------------------------------------------------
   CallbackImage manage returns of Picture form.                   
  ----------------------------------------------------------------------*/
#ifdef __STDC__
void                CallbackPrint (int ref, int typedata, char *data)
#else  /* __STDC__ */
void                CallbackPrint (ref, typedata, data)
int                 ref;
int                 typedata;
char               *data;

#endif /* __STDC__ */
{
  int                 val;

  val = (int) data;
  switch (ref - basePrint)
    {
    case NumFormPrint:
      TtaDestroyDialogue (basePrint+NumFormPrint);
      switch (val)
	{
	case 1:
	  /* confirms the paper print option */
	  /* the other options are not taken into account without this
	     confirmation */
	  TtaSetPrintParameter (PP_Destination, PaperPrint);
	  TtaSetPrintParameter (PP_ManualFeed, ManualFeed);
	  TtaSetPrintParameter (PP_PaperSize, PageSize);
	  TtaSetPrintCommand (pPrinter);
	  TtaSetPsFile (PSdir);
	  if (numberLinks)
	    SetInternalLinks (docPrint);		
	  if (withToC)
	    TtaPrint (docPrint, "Formatted_view Table_of_contents");
	  else
	    TtaPrint (docPrint, "Formatted_view");
	  break;
	case 0:
	  PaperPrint = TtaGetPrintParameter (PP_Destination);
	  ManualFeed = TtaGetPrintParameter (PP_ManualFeed);
	  PageSize = TtaGetPrintParameter (PP_PaperSize);	  
	  TtaGetPrintCommand (pPrinter);
	  TtaGetPsFile (PSdir);
	  break;
	default:
	  break;
	}
      break;
    case NumMenuOptions:
      switch (val)
	{
	case 0:
	  /* Manual feed option */
	  if (ManualFeed == PP_ON)
	    ManualFeed = PP_OFF;
	  else
	    ManualFeed = PP_ON;
	  break;
	case 1:
	  /* Toc option */
	  withToC = !withToC;
	  break;
	case 2:
	  /* Manual feed option */
	  numberLinks = !numberLinks;
	  break;
	  break;
	}
      break;
    case NumMenuPaperFormat:
      /* page size submenu */
      switch (val)
	{
	case 0:
	  PageSize = PP_A4;
	  break;
	case 1:
	  PageSize = PP_US;
	  break;
	}
      break;
    case NumMenuSupport:
      /* paper print/save PostScript submenu */
      switch (val)
	{
	case 0:
	  if (PaperPrint == PP_PS)
	    {
	      PaperPrint = PP_PRINTER;
	      TtaSetTextForm (basePrint+NumZonePrinterName, pPrinter);
	    }
	  break;
	case 1:
	  if (PaperPrint == PP_PRINTER)
	    {
	      PaperPrint = PP_PS;
	      TtaSetTextForm (basePrint+NumZonePrinterName, PSdir);
	    }
	  break;
	}
      break;
    case NumZonePrinterName:
      if (data[0] != '\0')
	if (PaperPrint == PP_PRINTER)
	  /* text capture zone for the printer name */
	  strncpy (pPrinter, data, MAX_PATH);
	else
	  /* text capture zone for the name of the PostScript file */
	  strncpy (PSdir, data, MAX_PATH);
      break;
    }
}

/*----------------------------------------------------------------------
  ----------------------------------------------------------------------*/
#ifdef __STDC__
void                InitPrint (void)
#else  /* __STDC__ */
void                InitPrint ()
#endif /* __STDC__ */
{
  char *ptr;

   basePrint = TtaSetCallback (CallbackPrint, PRINT_MAX_REF);
   docPrint = 0;

   /* init printer variables */
   /* read default printer variable */
   ptr = TtaGetEnvString ("THOTPRINT");
   if (ptr == NULL)
     strcpy (pPrinter, "");
   else
     strcpy (pPrinter, ptr);

   PageSize = PP_A4;
   PaperPrint = PP_PRINTER;
   ManualFeed = PP_OFF;
   TtaSetPrintParameter (PP_Destination, PaperPrint);
   TtaSetPrintParameter (PP_ManualFeed, ManualFeed);
   TtaSetPrintParameter (PP_PaperSize, PageSize);
   TtaSetPrintCommand (pPrinter);
   numberLinks = FALSE;
   withToC = FALSE;
}

/*----------------------------------------------------------------------
  ----------------------------------------------------------------------*/
#ifdef __STDC__
void                SetupAndPrint (Document document, View view)
#else
void                SetupAndPrint (document, view)
Document            document;
View                view;

#endif
{
   char             bufMenu[MAX_LENGTH];
   char            *ptr, suffix[MAX_LENGTH];
   int              i, lg;

   /* Print form */
   if (docPrint != document)
     {
       /* initialize print parameters */
       docPrint = document;

       /* read default tmpdir variable */
       if (ptr != NULL && TtaCheckDirectory (ptr))
	 {
	   strcpy(PSdir,ptr);
	   lg = strlen(PSdir);
	   if (PSdir[lg - 1] == DIR_SEP)
	     PSdir[--lg] = '\0';
	 }
       else
	 {
#ifdef _WINDOWS
	   strcpy (PSdir,"C:\\TEMP");
#else  /* !_WINDOWS */
	   strcpy (PSdir,"/tmp");
#endif /* !_WINDOWS */
	   lg = strlen (PSdir);
	 }
       strcpy (bufMenu, TtaGetDocumentName (document));
       ExtractSuffix (bufMenu, suffix);
       sprintf (&PSdir[lg], "/%s.ps", bufMenu);
       TtaSetPsFile (PSdir);
     }

   TtaNewSheet (basePrint+NumFormPrint, TtaGetViewFrame (document, view), 
		TtaGetMessage (LIB, TMSG_LIB_PRINT),
	   1, TtaGetMessage (LIB, TMSG_LIB_CONFIRM), FALSE, 2, 'L', D_CANCEL);
   i = 0;
   sprintf (&bufMenu[i], "%s%s", "T", TtaGetMessage (LIB, TMSG_MANUAL_FEED));
   i += strlen (&bufMenu[i]) + 1;
   sprintf (&bufMenu[i], "%s%s", "T", TtaGetMessage (AMAYA, AM_PRINT_TOC));
   i += strlen (&bufMenu[i]) + 1;
   sprintf (&bufMenu[i], "%s%s", "T", TtaGetMessage (AMAYA, AM_NUMBERED_LINKS));
   TtaNewToggleMenu (basePrint+NumMenuOptions, basePrint+NumFormPrint,
		TtaGetMessage (LIB, TMSG_OPTIONS), 3, bufMenu, NULL, FALSE);
   if (ManualFeed == PP_ON)
      TtaSetToggleMenu (basePrint+NumMenuOptions, 0, TRUE);
   if (withToC)
      TtaSetToggleMenu (basePrint+NumMenuOptions, 1, TRUE);
   if (numberLinks)
      TtaSetToggleMenu (basePrint+NumMenuOptions, 2, TRUE);

   /* Paper format submenu */
   i = 0;
   sprintf (&bufMenu[i], "%s%s", "B", TtaGetMessage (LIB, TMSG_A4));
   i += strlen (&bufMenu[i]) + 1;
   sprintf (&bufMenu[i], "%s%s", "B", TtaGetMessage (LIB, TMSG_US));
   TtaNewSubmenu (basePrint+NumMenuPaperFormat, basePrint+NumFormPrint, 0,
	     TtaGetMessage (LIB, TMSG_PAPER_SIZE), 2, bufMenu, NULL, FALSE);
   if (PageSize == PP_US)
      TtaSetMenuForm (basePrint+NumMenuPaperFormat, 1);
   else
      TtaSetMenuForm (basePrint+NumMenuPaperFormat, 0);

   /* Print to paper/ Print to file submenu */
   i = 0;
   sprintf (&bufMenu[i], "%s%s", "B", TtaGetMessage (LIB, TMSG_PRINTER));
   i += strlen (&bufMenu[i]) + 1;
   sprintf (&bufMenu[i], "%s%s", "B", TtaGetMessage (LIB, TMSG_PS_FILE));
   TtaNewSubmenu (basePrint+NumMenuSupport, basePrint+NumFormPrint, 0,
                  TtaGetMessage (LIB, TMSG_OUTPUT), 2, bufMenu, NULL, TRUE);
   /* text capture zone for the printer name */
   TtaNewTextForm (basePrint+NumZonePrinterName, basePrint+NumFormPrint, NULL, 30, 1, FALSE);

   /* initialization of the PaperPrint selector */
   if (PaperPrint == PP_PRINTER)
     {
	TtaSetMenuForm (basePrint+NumMenuSupport, 0);
	TtaSetTextForm (basePrint+NumZonePrinterName, pPrinter);
     }
   else
     {
	TtaSetMenuForm (basePrint+NumMenuSupport, 1);
	TtaSetTextForm (basePrint+NumZonePrinterName, PSdir);
     }

   /* activates the Print form */
   TtaShowDialogue (basePrint+NumFormPrint, FALSE);
}

/*----------------------------------------------------------------------
  SectionNumbering
  Execute the "Section Numbering" command
  ----------------------------------------------------------------------*/
#ifdef __STDC__
void                SectionNumbering (Document document, View view)
#else
void                SectionNumbering (document, view)
Document            document;
View                view;
#endif
{
   ChangeAttrOnRoot (document, HTML_ATTR_SectionNumbering);
}

/*----------------------------------------------------------------------
  UpdateURLsInSubtree
  Update NAMEs and URLs in subtree of el element, to take into account
  the move from one document to another.
  If a NAME attribute already exists in the new document, it is changed
  to avoid duplicate names.
  Transform the HREF and SRC attribute to make them independent from their
  former base.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         UpdateURLsInSubtree (NotifyElement *event, Element el)
#else
static void         UpdateURLsInSubtree (event, el)
NotifyElement      *event;
Element             el;
#endif
{
Element             nextEl;

  event->element = el;
  ElementPasted (event);
  nextEl = TtaGetFirstChild (el);
  while (nextEl != NULL)
    {
      UpdateURLsInSubtree (event, nextEl);
      TtaNextSibling (&nextEl);
    }
}


/*----------------------------------------------------------------------
  MoveDocumentBody
  Copy the elements contained in the BODY of document sourceDoc to the
  position of element *el in document destDoc.
  Delete the element containing *el and all its empty ancestors.
  If deleteTree is TRUE, copied elements are deleted from the source
  document.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         MoveDocumentBody (Element *el, Document destDoc,
				      Document sourceDoc, boolean deleteTree)
#else
static void         MoveDocumentBody (el, destDoc, sourceDoc, deleteTree)
Element            *el;
Document           destDoc;
Document           sourceDoc;
boolean            deleteTree;
#endif
{
   Element	   root, body, ancestor, elem, firstInserted,
		   lastInserted, srce, copy, old, parent, sibling;
   ElementType	   elType;
   NotifyElement   event;

   firstInserted = NULL;
   /* get the BODY element of source document */
   root = TtaGetMainRoot (sourceDoc);
   elType = TtaGetElementType (root);
   elType.ElTypeNum = HTML_EL_BODY;
   body = TtaSearchTypedElement (elType, SearchForward, root);
   if (body != NULL)
     {
     /* get elem, the ancestor of *el which is a child of a DIV or BODY
	element in the destination document. The copied elements will be
	inserted just before this element. */
     elem = *el;
     do
	{
        ancestor = TtaGetParent (elem);
	if (ancestor != NULL);
	   {
	   elType = TtaGetElementType (ancestor);
	   if (elType.ElTypeNum == HTML_EL_BODY ||
	       elType.ElTypeNum == HTML_EL_Division)
	      ancestor = NULL;
	   else
	      elem = ancestor;
	   }
	}
     while (ancestor != NULL);
     parent = TtaGetParent (elem);
     
     /* do copy */
     lastInserted = NULL;
     srce = TtaGetFirstChild (body);
     while (srce != NULL)
	{
	copy = TtaCopyTree (srce, sourceDoc, destDoc, parent);
	if (copy != NULL)
	   {
	   if (lastInserted == NULL)
	      /* this is the first copied element. Insert it before elem */
	      {
	      TtaInsertSibling (copy, elem, TRUE, destDoc);
	      firstInserted = copy;
	      }
	   else
	      /* insert the new copied element after the element previously
		 copied */
	      TtaInsertSibling (copy, lastInserted, FALSE, destDoc);
	   lastInserted = copy;
	   /* update the NAMEs and URLs in the copied element */
	   event.document = destDoc;
	   event.position = sourceDoc;
	   UpdateURLsInSubtree(&event, copy);
	   }
	/* get the next element in the source document */
	old = srce;
	TtaNextSibling (&srce);
	if (deleteTree)
	  TtaDeleteTree (old, sourceDoc);
	}

     /* delete the element(s) containing the link to the copied document */
     /* delete the parent element of *el and all empty ancestors */
     elem = TtaGetParent (*el);
     do
	{
	sibling = elem;
        TtaNextSibling (&sibling);
	if (sibling == NULL)
	   {
	   sibling = elem;
	   TtaPreviousSibling (&sibling);
	   if (sibling == NULL)
	      elem = TtaGetParent (elem);
	   }
	}
     while (sibling == NULL);
     TtaDeleteTree (elem, destDoc);
     /* return the address of the first copied element */
     *el = firstInserted;
     }
}

/*----------------------------------------------------------------------
  GetIncludedDocuments
  Look forward, starting from element el, for a link (A) with attribute
  REL="chapter" and replace that link by the contents of the target document.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static Element      GetIncludedDocuments (Element el, Document document)
#else
static Element      GetIncludedDocuments (el, document)
Element		    el;
Document            document;
#endif
{
   Element		link, next;
   Attribute		RelAttr, HrefAttr;
   AttributeType	attrType;
   int			length;
   char			*text, *ptr;
   Document		includedDocument, newdoc;

   attrType.AttrSSchema = TtaGetDocumentSSchema (document);
   attrType.AttrTypeNum = HTML_ATTR_REL;
   link = el;
   RelAttr = NULL;
   /* looks for an anchor having an attribute REL="chapter" */
   while (link != NULL && RelAttr == NULL)
     {
       TtaSearchAttribute (attrType, SearchForward, link, &link, &RelAttr);
       if (link != NULL && RelAttr != NULL)
	 {
	   length = TtaGetTextAttributeLength (RelAttr);
	   text = TtaGetMemory (length + 1);
	   TtaGiveTextAttributeValue (RelAttr, text, &length);
	   if (strcasecmp (text, "chapter"))
	     RelAttr = NULL;
	   TtaFreeMemory (text);
	 }
     }

   if (RelAttr != NULL && link != NULL)
     /* a link with attribute REL="Chapter" has been found */
     {
       next = link;
       attrType.AttrTypeNum = HTML_ATTR_HREF_;
       HrefAttr = TtaGetAttribute (link, attrType);
       if (HrefAttr != NULL)
	 /* this link has an attribute HREF */
	 {
	   length = TtaGetTextAttributeLength (HrefAttr);
	   text = TtaGetMemory (length + 1);
	   TtaGiveTextAttributeValue (HrefAttr, text, &length);
	   /* ignore links to a particular position within a document */
	   ptr = strrchr (text, '#');
	   if (ptr == NULL)
	     /* this link designate the whole document */
	     {
	       /* create a new document and loads the target document */
	       includedDocument = TtaNewDocument ("HTML", "tmp");
	       newdoc = GetHTMLDocument (text, NULL, includedDocument,
					 document, DC_TRUE);
	       if (newdoc != 0 && newdoc != document)
		   /* it's not the document itself */
		   /* copy the target document at the position of the link */
		   MoveDocumentBody (&next, document, newdoc,
				     newdoc == includedDocument);
	       FreeDocumentResource (includedDocument);
	       TtaCloseDocument (includedDocument);
	     }
	   TtaFreeMemory (text);
	 }
       return (next);
     }
   return (NULL);
}


/*----------------------------------------------------------------------
  MakeBook
  Replace all links in a document which have an attribute REL="chapter"
  by the corresponding target document.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
void                MakeBook (Document document, View view)
#else
void                MakeBook (document, view)
Document            document;
View                view;
#endif
{
   Element	    root, body, el;
   ElementType	    elType;

   root = TtaGetMainRoot (document);
   elType = TtaGetElementType (root);
   elType.ElTypeNum = HTML_EL_BODY;
   body = TtaSearchTypedElement (elType, SearchForward, root);
   TtaSetDocumentModified (document);
   el = body;
   while (el != NULL)
      el = GetIncludedDocuments (el, document);
}


#ifdef R_HTML
/*----------------------------------------------------------------------
  ----------------------------------------------------------------------*/
#ifdef __STDC__
static void         LoadEntity (Document document, char *text)
#else
static void         LoadEntity (document, text)
Document            document;
char               *text;
#endif
{
  Document          includedDocument;
  Attribute	    attr;
  AttributeType	    attrType;
  Element           el, includedEl;
  ElementType	    elType;
  int               length;

  /* create the temporary document */
  includedDocument = TtaNewDocument ("HTML", "tmp");
  /* read the temporary document */
  includedDocument = GetHTMLDocument (text, NULL, includedDocument, document, DC_TRUE);
  
  if (includedDocument != 0)
    {
      /* To do: Seach entity in the table */
      /* locate the entity in the document */
      el = TtaGetMainRoot (document);
      elType = TtaGetElementType (el);
      elType.ElTypeNum = HTML_EL_Entity;
      /* TtaSearchElementByLabel (label, el); */
      el = TtaSearchTypedElement (elType, SearchForward, el);
      /* keep the entity name to know where to insert the sub-tree */
      attrType.AttrSSchema = TtaGetDocumentSSchema (document);
      attrType.AttrTypeNum = HTML_ATTR_entity_name;
      attr = TtaGetAttribute (el, attrType);
      if (attr != NULL)
	{
	  length = TtaGetTextAttributeLength (attr);
	  text = TtaGetMemory (length + 1);
	  TtaGiveTextAttributeValue (attr, text, &length);
	}
      /* To do: translate the entity name into element type
	 and search this first element type in included document */
      includedEl = TtaGetMainRoot (includedDocument);
      elType = TtaGetElementType (includedEl);
      elType.ElTypeNum = HTML_EL_TEXT_UNIT;
      includedEl = TtaSearchTypedElement (elType, SearchForward, includedEl);
      /* remove Entity */
      /* To do: insert sub-trees */
      FreeDocumentResource (includedDocument);
      TtaCloseDocument (includedDocument);
    }
}
#endif /* R_HTML */


/*----------------------------------------------------------------------
  ----------------------------------------------------------------------*/
#ifdef __STDC__
void                RealTimeHTML (Document document, View view)
#else
void                RealTimeHTML (document, view)
Document            document;
View                view;
#endif
{
#ifdef R_HTML
  Element	    root, el;
  ElementType	    elType;

  root = TtaGetMainRoot (document);
  elType = TtaGetElementType (root);
  elType.ElTypeNum = HTML_EL_Entity;
  el = TtaSearchTypedElement (elType, SearchForward, root);
  if (el != NULL)
    {
      /* document contains entities */
      /* To do -> build table of entities */

      /* simulate reception of different entities */
      LoadEntity (document, "0/0");
      LoadEntity (document, "0/1");
    }
#endif /* R_HTML */
}

Webmaster