#if !NO_SCCS_STRINGS
static char sccs_clipbord_c[] = "@(#)clipbord.c	128.1 1/20/93 19:38:57";
#endif /* NO_SCCS_STRINGS */
/***********************************************************************\

   (c) Copyright 1991 by Lotus Development Corporation
   All Rights Reserved

   Module:  clipbord.c

   Description:  Add-in application that supports copying and pasting
   a cell to and from a clipboard.  The user is presented with two menu
   choices.  If the user selects COPY, the characteristics of the current
   cell are placed on the clipboard.  If the user selects PASTE and the
   clipboard is filled, the current cell assumes the contents of the
   clipboard.

\***********************************************************************/

#define  LPI_MAIN_MODULE

#define  USE_REGISTER
#define  USE_CELL
#define  USE_RANGE
#define  USE_INPUT
#define  USE_UTILITY

#include "lpixport.h"
#include "clipbord.h"

/* structure to hold a Cell's attributes */

struct CellD {
   lmbcs   Contents[LPI_CL_CELL_BUFLEN];
   lbool   Protection;
   lbool   Highlight;
   lbool   ColorNegative;
   lbool   Parentheses;
   lushort LabelPrefix;
   lushort FormatType;
   lushort FormatPlaces;
   lbool   Status;
};
typedef struct CellD CellDescription;
CellDescription theClipboard;

/* utility function that sounds an error tone */

lsshort clipbord_bell ()
{
   return (LpiUtBeep(BELL_FREQUENCY,BELL_DURATION));
}

/* main function */

LpiMain(clipbord_m)
{
   lsshort      retval, theMenuItem;
   lushort      apperr;
   LpiMenuType  theMenu;
   LpiCellType  theCell;
   
   /* construct clipboard menu */

   retval = LpiMnuConstruct(&theMenu,clipbord_theMenuArray,MENU_ITEMS);
   if (retval != LPI_SUCCESS) return;

   /* post clipboard menu */

   retval = LpiMnuInput(theMenu,&theMenuItem);
   if (retval != LPI_SUCCESS) {
      LpiMnuDestroy(&theMenu);
      return;
   }

   /* process menu selection */

   switch (theMenuItem) {

      case MENU_COPY:

         /* construct current cell */
         retval = LpiClConstructCurrent(&theCell);
         if (retval != LPI_SUCCESS) {
            LpiMnuDestroy(&theMenu);
            return;
         }

         /* get cell contents */
         retval = LpiClGetContents(theCell, theClipboard.Contents);
         if (retval != LPI_SUCCESS) {
            LpiMnuDestroy(&theMenu);
            LpiClDestroy(&theCell);
            return;
         }

         /* get cell protection state */
         retval = LpiClGetProtection(theCell, &theClipboard.Protection);
         if (retval != LPI_SUCCESS) {
            LpiMnuDestroy(&theMenu);
            LpiClDestroy(&theCell);
            return;
         }

         /* get cell highlight state */
         retval = LpiClGetHighlight(theCell, &theClipboard.Highlight);
         if (retval != LPI_SUCCESS) {
            LpiMnuDestroy(&theMenu);
            LpiClDestroy(&theCell);
            return;
         }

         /* get cell color negative state */
         retval = LpiClGetColorNegative(theCell, &theClipboard.ColorNegative);
         if (retval != LPI_SUCCESS) {
            LpiMnuDestroy(&theMenu);
            LpiClDestroy(&theCell);
            return;
         }

         /* get cell parentheses state */
         retval = LpiClGetParentheses(theCell, &theClipboard.Parentheses);
         if (retval != LPI_SUCCESS) {
            LpiMnuDestroy(&theMenu);
            LpiClDestroy(&theCell);
            return;
         }

         /* get cell label prefix type */
         retval = LpiClGetLabelPrefix(theCell, &theClipboard.LabelPrefix);
         if (retval != LPI_SUCCESS) {
            LpiMnuDestroy(&theMenu);
            LpiClDestroy(&theCell);
            return;
         }

         /* get cell format type */
         retval = LpiClGetFormatPlaces(theCell, &theClipboard.FormatType,
                                       &theClipboard.FormatPlaces);
         if (retval != LPI_SUCCESS) {
            LpiMnuDestroy(&theMenu);
            LpiClDestroy(&theCell);
            return;
         }

         /* destroy cell and set clipboard flag to filled */   
         LpiClDestroy(&theCell);
         theClipboard.Status = CLIPBOARD_FILLED;
         break;

      case MENU_PASTE:

         /* test if anything on the clipboard */
         if (theClipboard.Status) {

            /* construct current cell */
            retval = LpiClConstructCurrent(&theCell);
            if (retval != LPI_SUCCESS) {
               LpiMnuDestroy(&theMenu);
               return;
            }

            /* set cell contents */
            retval = LpiClSetContents(theCell, theClipboard.Contents, &apperr);
            if (retval != LPI_SUCCESS) {
               LpiMnuDestroy(&theMenu);
               LpiClDestroy(&theCell);
               return;
            }

            /* set cell protection state */
            retval = LpiClSetProtection(theCell, theClipboard.Protection, &apperr);
            if (retval != LPI_SUCCESS) {
               LpiMnuDestroy(&theMenu);
               LpiClDestroy(&theCell);
               return;
            }

            /* set cell highlight state */
            retval = LpiClSetHighlight(theCell, theClipboard.Highlight, &apperr);
            if (retval != LPI_SUCCESS) {
               LpiMnuDestroy(&theMenu);
               LpiClDestroy(&theCell);
               return;
            }
   
            /* set cell color negative state */
            retval = LpiClSetColorNegative(theCell, theClipboard.ColorNegative,
                                           &apperr);
            if (retval != LPI_SUCCESS) {
               LpiMnuDestroy(&theMenu);
               LpiClDestroy(&theCell);
               return;
            }

            /* set cell parentheses state */
            retval = LpiClSetParentheses(theCell, theClipboard.Parentheses,
                                           &apperr);
            if (retval != LPI_SUCCESS) {
               LpiMnuDestroy(&theMenu);
               LpiClDestroy(&theCell);
               return;
            }

            /* set cell label prefix type */
            retval = LpiClSetLabelPrefix(theCell, theClipboard.LabelPrefix);
            if (retval != LPI_SUCCESS) {
               LpiMnuDestroy(&theMenu);
               LpiClDestroy(&theCell);
               return;
            }
   
            /* set cell format type */
            retval = LpiClSetFormatPlaces(theCell, theClipboard.FormatType,
                                 (lulong)theClipboard.FormatPlaces, &apperr);
            if (retval != LPI_SUCCESS) {
               LpiMnuDestroy(&theMenu);
               LpiClDestroy(&theCell);
               return;
            }

            /* destroy cell and set clipboard flag to filled */   
            LpiClDestroy(&theCell);
         }
         else {

            /* clipboard empty */

            clipbord_bell();
         }
         break;

      default:
         break;
   }
   /* destroy mneu */
   LpiMnuDestroy(&theMenu);
}

/************************************************************************\

   The following function, LpiBind, is called when 1-2-3 loads our add-in.
   Use this function to perform any setup, such as allocating memory,
   opening files, etc.

\************************************************************************/

LpiBind(clipbord_b)
{
   /* Start loading pointers to used modules */

   LPI_SETUP_LOAD;

   if (LPI_LOAD_INPUT   != LPI_SUCCESS) LpiSignal (LPI_FAILURE);
   if (LPI_LOAD_CELL    != LPI_SUCCESS) LpiSignal (LPI_FAILURE);
   if (LPI_LOAD_RANGE   != LPI_SUCCESS) LpiSignal (LPI_FAILURE);
   if (LPI_LOAD_UTILITY != LPI_SUCCESS) LpiSignal (LPI_FAILURE);

   /* initially empty clipboard  */
   theClipboard.Status = CLIPBOARD_EMPTY;

   LpiSignal (LPI_SUCCESS);
}

/************************************************************************\

   The following function, LpiUnbind, is called when 1-2-3 unloads our
   add-in.  This function simply executes the macro LPI_UNBIND and signals
   no errors.  Use this function to perform any cleanup such, as
   deallocating memory you allocated in LpiBind, closing opened files, etc.

/************************************************************************/

LpiUnbind(clipbord_u)
{
   LPI_UNLOAD;                                    /* macro for cleanup */

   LpiSignal (LPI_SUCCESS);                       /* indicate no errors */
}

