1279 lines
38 KiB
C
1279 lines
38 KiB
C
/************************************************************/
|
||
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
||
/************************************************************/
|
||
|
||
/* edit.c -- MW editing routines */
|
||
|
||
#define NOVIRTUALKEYCODES
|
||
#define NOCTLMGR
|
||
#define NOWINMESSAGES
|
||
#define NOWINSTYLES
|
||
#define NOCLIPBOARD
|
||
#define NOGDICAPMASKS
|
||
#define NOSYSMETRICS
|
||
#define NOMENUS
|
||
#define NOKEYSTATE
|
||
#define NORASTEROPS
|
||
#define NOSYSCOMMANDS
|
||
#define NOSHOWWINDOW
|
||
#define NOCOLOR
|
||
//#define NOATOM
|
||
#define NOBITMAP
|
||
#define NOICON
|
||
#define NOBRUSH
|
||
#define NOCREATESTRUCT
|
||
#define NOMB
|
||
#define NOMSG
|
||
#define NOOPENFILE
|
||
#define NOPEN
|
||
#define NOPOINT
|
||
#define NOREGION
|
||
#define NOSCROLL
|
||
#define NOSOUND
|
||
#define NOWH
|
||
#define NOWINOFFSETS
|
||
#define NOWNDCLASS
|
||
#define NOCOMM
|
||
#include <windows.h>
|
||
|
||
#include "mw.h"
|
||
#include "cmddefs.h"
|
||
#include "docdefs.h"
|
||
#include "filedefs.h"
|
||
#include "propdefs.h"
|
||
#include "fkpdefs.h"
|
||
#include "debug.h"
|
||
#include "wwdefs.h"
|
||
#include "dispdefs.h"
|
||
#include "editdefs.h"
|
||
#include "str.h"
|
||
#include "prmdefs.h"
|
||
#include "printdef.h"
|
||
#include "fontdefs.h"
|
||
#if defined(OLE)
|
||
#include "obj.h"
|
||
#endif
|
||
|
||
/* E X T E R N A L S */
|
||
extern int vfOutOfMemory;
|
||
extern struct DOD (**hpdocdod)[];
|
||
extern typeCP vcpFirstSectCache;
|
||
extern struct UAB vuab;
|
||
extern typeCP cpMinCur;
|
||
extern typeCP cpMacCur;
|
||
extern struct SEL selCur;
|
||
extern int docCur;
|
||
extern struct WWD rgwwd[];
|
||
extern int wwMac;
|
||
extern int wwCur;
|
||
extern typeCP vcpLimSectCache;
|
||
/*extern int idstrUndoBase;*/
|
||
extern int docScrap;
|
||
extern int docUndo;
|
||
extern int vfSeeSel;
|
||
extern struct PAP vpapAbs;
|
||
extern int vfPictSel;
|
||
extern int ferror;
|
||
|
||
/* the following used to be defined here */
|
||
extern typeCP vcpFirstParaCache;
|
||
extern typeCP vcpLimParaCache;
|
||
/* this is a global parameter to AdjustCp; if false, no invalidation will
|
||
take place */
|
||
extern BOOL vfInvalid;
|
||
|
||
#ifdef ENABLE
|
||
extern struct SEL selRulerSprm;
|
||
#endif
|
||
|
||
extern int docRulerSprm;
|
||
extern struct EDL *vpedlAdjustCp;
|
||
|
||
struct PCD *PpcdOpen();
|
||
|
||
|
||
|
||
|
||
/* R E P L A C E */
|
||
Replace(doc, cp, dcp, fn, fc, dfc)
|
||
int doc, fn;
|
||
typeCP cp, dcp;
|
||
typeFC fc, dfc;
|
||
{ /* Replace cp through (cp+dcp-1) in doc by fc through (fc+dfc-1) in fn */
|
||
|
||
if (ferror) return;
|
||
#ifdef ENABLE
|
||
if (docRulerSprm != docNil) ClearRulerSprm();
|
||
#endif
|
||
/* if (fn == fnNil) we are infact deleting text by replacing text
|
||
with nil. Thus, the memory space check is unnecessary.*/
|
||
#ifdef BOGUS /* No longer have cwHeapFree available */
|
||
if ((fn != fnNil) && (cwHeapFree < 3 * cpcdMaxIncr * cwPCD))
|
||
{
|
||
#ifdef DEBUG
|
||
ErrorWithMsg(IDPMTNoMemory, " edit#1");
|
||
#else
|
||
Error(IDPMTNoMemory);
|
||
#endif
|
||
return;
|
||
}
|
||
#else
|
||
if (vfOutOfMemory)
|
||
{
|
||
ferror = 1;
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
if (dcp != cp0)
|
||
{
|
||
AdjParas(doc, cp, doc, cp, dcp, fTrue); /* Check for del EOL */
|
||
DelFtns(doc, cp, cp + dcp); /* Delete any footnotes */
|
||
}
|
||
|
||
Repl1(doc, cp, dcp, fn, fc, dfc);
|
||
if (ferror)
|
||
return;
|
||
AdjustCp(doc, cp, dcp, dfc);
|
||
|
||
/* Special kludge for graphics paragraphs */
|
||
if (dfc != dcp)
|
||
CheckGraphic(doc, cp + dfc);
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
/* C H E C K G R A P H I C */
|
||
CheckGraphic(doc, cp)
|
||
int doc; typeCP cp;
|
||
{
|
||
#if defined(OLE)
|
||
extern BOOL bNoEol;
|
||
#endif
|
||
|
||
#ifdef CASHMERE /* No docBuffer in MEMO */
|
||
extern int docBuffer; /* Don't need extra paragraph mark in txb document */
|
||
if (cp == ((**hpdocdod)[doc]).cpMac || doc == docBuffer)
|
||
return;
|
||
#else
|
||
if (cp == ((**hpdocdod)[doc]).cpMac)
|
||
return;
|
||
CachePara(doc, cp);
|
||
/* !!! this has a bug. There are cases when you don't want to insert
|
||
EOL. Ex1: place cursor in front of bitmap and press
|
||
backspace. Ex2: OleSaveObjectToDoc deletes an object and
|
||
insert new one (Eol gets inserted too). (4.10.91) v-dougk
|
||
*/
|
||
if (vpapAbs.fGraphics && vcpFirstParaCache != cp)
|
||
#if defined(OLE)
|
||
if (!bNoEol)
|
||
#endif
|
||
InsertEolInsert(doc, cp);
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
|
||
int IpcdSplit(hpctb, cp)
|
||
struct PCTB **hpctb;
|
||
typeCP cp;
|
||
{ /* Ensure cp is the beginning of a piece. Return index of that piece.
|
||
return ipcdNil on error (extern int ferror will be set in that case) */
|
||
register struct PCD *ppcd = &(**hpctb).rgpcd[IpcdFromCp(*hpctb, cp)];
|
||
typeCP dcp = cp - ppcd->cpMin;
|
||
|
||
if (dcp != cp0)
|
||
{
|
||
ppcd = PpcdOpen(hpctb, ppcd + 1, 1); /* Insert a new piece */
|
||
if (ppcd == NULL)
|
||
return ipcdNil;
|
||
ppcd->cpMin = cp;
|
||
ppcd->fn = (ppcd - 1)->fn;
|
||
ppcd->fc = (ppcd - 1)->fc + dcp;
|
||
ppcd->prm = (ppcd - 1)->prm;
|
||
ppcd->fNoParaLast = (ppcd - 1)->fNoParaLast;
|
||
}
|
||
/* NOTE CASTS: For piece tables with rgpcd > 32Kbytes */
|
||
/* return ppcd - (*hpctb)->rgpcd; */
|
||
|
||
return ((unsigned)ppcd - (unsigned)((*hpctb)->rgpcd)) / sizeof (struct PCD);
|
||
}
|
||
|
||
|
||
|
||
|
||
/* P P C D O P E N */
|
||
struct PCD *PpcdOpen(hpctb, ppcd, cpcd)
|
||
struct PCTB **hpctb;
|
||
struct PCD *ppcd;
|
||
int cpcd;
|
||
{ /* Insert or delete cpcd pieces */
|
||
register struct PCTB *ppctb = *hpctb;
|
||
|
||
/* NOTE CASTS: For piece tables with rgpcd > 32Kbytes */
|
||
/* int ipcd = ppcd - ppctb->rgpcd; */
|
||
int ipcd = ((unsigned)ppcd - (unsigned)(ppctb->rgpcd)) / sizeof (struct PCD);
|
||
int ipcdMac, ipcdMax;
|
||
|
||
ipcdMac = ppctb->ipcdMac + cpcd;
|
||
ipcdMax = ppctb->ipcdMax;
|
||
|
||
if (cpcd > 0)
|
||
{ /* Inserting pieces; check for pctb too small */
|
||
if (ipcdMac > ipcdMax)
|
||
{ /* Enlarge piece table */
|
||
int cpcdIncr = umin(cpcdMaxIncr, ipcdMac / cpcdChunk);
|
||
|
||
if (!FChngSizeH((int **) hpctb, (int) (cwPCTBInit + cwPCD *
|
||
((ipcdMax = ipcdMac + cpcdIncr) - cpcdInit)), false))
|
||
{
|
||
#ifdef DEBUG
|
||
ErrorWithMsg(IDPMTNoMemory, " edit#3");
|
||
#else
|
||
Error(IDPMTNoMemory);
|
||
#endif
|
||
return (struct PCD *)NULL;
|
||
}
|
||
|
||
/* Successfully expanded piece table */
|
||
|
||
ppctb = *hpctb;
|
||
ppcd = &ppctb->rgpcd [ipcd];
|
||
ppctb->ipcdMax = ipcdMax;
|
||
}
|
||
ppctb->ipcdMac = ipcdMac;
|
||
blt(ppcd, ppcd + cpcd, cwPCD * (ipcdMac - (ipcd + cpcd)));
|
||
}
|
||
else if (cpcd < 0)
|
||
{ /* Deleting pieces; check for pctb obscenely large */
|
||
ppctb->ipcdMac = ipcdMac;
|
||
blt(ppcd - cpcd, ppcd, cwPCD * (ipcdMac - ipcd));
|
||
if (ipcdMax > cpcdInit && ipcdMac * 2 < ipcdMax)
|
||
{ /* Shrink piece table */
|
||
#ifdef DEBUG
|
||
int f =
|
||
#endif
|
||
FChngSizeH((int **) hpctb, (int) (cwPCTBInit + cwPCD *
|
||
((ppctb->ipcdMax = umax(cpcdInit,
|
||
ipcdMac + ipcdMac / cpcdChunk)) - cpcdInit)), true);
|
||
|
||
Assert( f );
|
||
|
||
return &(**hpctb).rgpcd[ipcd];
|
||
}
|
||
}
|
||
return ppcd;
|
||
}
|
||
|
||
|
||
|
||
|
||
/* R E P L 1 */
|
||
/* core of replace except for checking and Adjust */
|
||
Repl1(doc, cp, dcp, fn, fc, dfc)
|
||
int doc, fn;
|
||
typeCP cp, dcp;
|
||
typeFC fc, dfc;
|
||
{ /* Replace pieces with an optional new piece */
|
||
struct PCTB **hpctb;
|
||
int ipcdFirst;
|
||
int cpcd;
|
||
typeCP dcpAdj = dfc - dcp;
|
||
register struct PCD *ppcd;
|
||
struct PCD *ppcdMac;
|
||
struct PCTB *ppctb;
|
||
struct PCD *ppcdPrev;
|
||
struct PCD *ppcdLim=NULL;
|
||
|
||
hpctb = (**hpdocdod)[doc].hpctb;
|
||
ipcdFirst = IpcdSplit(hpctb, cp);
|
||
|
||
if (dcp == cp0)
|
||
cpcd = 0;
|
||
else
|
||
cpcd = IpcdSplit( hpctb, cp + dcp ) - ipcdFirst;
|
||
|
||
if (ferror)
|
||
return;
|
||
|
||
ppctb = *hpctb;
|
||
ppcdPrev = &ppctb->rgpcd[ipcdFirst - 1];
|
||
|
||
if ( dfc == fc0 ||
|
||
(ipcdFirst > 0 && ppcdPrev->fn == fn && bPRMNIL(ppcdPrev->prm) &&
|
||
ppcdPrev->fc + (cp - ppcdPrev->cpMin) == fc) ||
|
||
((ppcdLim=ppcdPrev + (cpcd + 1))->fn == fn &&
|
||
bPRMNIL(ppcdLim->prm) && (ppcdLim->fc == fc + dfc)))
|
||
{ /* Cases: (1) No insertion,
|
||
(2) Insertion is appended to previous piece
|
||
(3) Insertion is prepended to this piece */
|
||
|
||
ppcd = PpcdOpen( hpctb, ppcdPrev + 1, -cpcd );
|
||
if (ppcd == NULL)
|
||
return;
|
||
|
||
if (dfc != fc0)
|
||
{ /* Cases 2 & 3 */
|
||
if (ppcdLim != NULL)
|
||
/* Case 3 */
|
||
(ppcd++)->fc = fc;
|
||
|
||
/* If extending, say we might have inserted EOL */
|
||
(ppcd - 1)->fNoParaLast = false;
|
||
}
|
||
}
|
||
else
|
||
{ /* Insertion */
|
||
ppcd = PpcdOpen( hpctb, ppcdPrev + 1, 1 - cpcd );
|
||
if (ppcd == NULL)
|
||
return;
|
||
ppcd->cpMin = cp;
|
||
ppcd->fn = fn;
|
||
ppcd->fc = fc;
|
||
SETPRMNIL(ppcd->prm);
|
||
ppcd->fNoParaLast = false; /* Don't know yet */
|
||
++ppcd;
|
||
}
|
||
ppcdMac = &(*hpctb)->rgpcd[(*hpctb)->ipcdMac];
|
||
if (dcpAdj !=0)
|
||
while (ppcd < ppcdMac)
|
||
(ppcd++)->cpMin += dcpAdj;
|
||
}
|
||
|
||
|
||
|
||
|
||
/* A D J U S T C P */
|
||
/* note global parameter vfInvalid */
|
||
/* sets global vpedlAdjustCp to pedl of line containing cpFirst, if any */
|
||
AdjustCp(doc, cpFirst, dcpDel, dcpIns)
|
||
int doc;
|
||
typeCP cpFirst, dcpDel, dcpIns;
|
||
{
|
||
/* Adjust all cp references in doc to conform to the deletion of
|
||
dcpDel chars and the insertion of dcpIns chars at cpFirst.
|
||
Mark display lines (dl's) dirty for all lines in all windows
|
||
displaying doc that are affected by the insertion & deletion
|
||
*/
|
||
extern int vdocBitmapCache;
|
||
extern typeCP vcpBitmapCache;
|
||
int ww;
|
||
typeCP cpLim = cpFirst + dcpDel;
|
||
typeCP dcpAdj = dcpIns - dcpDel;
|
||
#ifdef DEBUG
|
||
Scribble(2,'A');
|
||
#endif
|
||
|
||
{ /* Range in which pdod belongs in a register */
|
||
register struct DOD *pdod = &(**hpdocdod)[doc];
|
||
|
||
#ifdef STYLES
|
||
/* If inserting or deleting in style sheet, invalidates rest of doc */
|
||
if (pdod->dty == dtySsht && dcpAdj != cp0)
|
||
cpLim = pdod->cpMac;
|
||
#endif
|
||
pdod->cpMac += dcpAdj;
|
||
/* Change for sand to support separate footnote windows: Make sure that edit
|
||
was within the current cpMacCur */
|
||
/* note <= (CS) */
|
||
if (doc == docCur && cpFirst <= cpMacCur)
|
||
cpMacCur += dcpAdj;
|
||
|
||
#ifdef STYLES
|
||
if (dcpAdj != cp0 && pdod->dty != dtySsht)
|
||
#else
|
||
if (dcpAdj != cp0)
|
||
#endif
|
||
{
|
||
#ifdef FOOTNOTES
|
||
if (pdod->hfntb != 0)
|
||
{ /* Adjust footnotes */
|
||
struct FNTB *pfntb = *pdod->hfntb;
|
||
int cfnd = pfntb->cfnd;
|
||
struct FND *pfnd = &pfntb->rgfnd[cfnd];
|
||
AdjRg(pfnd, cchFND, bcpRefFND, cfnd, cpFirst, dcpAdj);
|
||
AdjRg(pfnd, cchFND, bcpFtnFND, cfnd, cpFirst + 1, dcpAdj);
|
||
}
|
||
#endif
|
||
#ifdef CASHMERE
|
||
if (pdod->hsetb != 0)
|
||
{ /* Adjust sections */
|
||
struct SETB *psetb = *pdod->hsetb;
|
||
int csed = psetb->csed;
|
||
AdjRg(&psetb->rgsed[csed], cchSED, bcpSED, csed, cpFirst + 1,
|
||
dcpAdj);
|
||
}
|
||
#endif
|
||
if (pdod->dty == dtyNormal && pdod->hpgtb != 0)
|
||
{ /* Adjust page table */
|
||
struct PGTB *ppgtb = *pdod->hpgtb;
|
||
int cpgd = ppgtb->cpgd;
|
||
AdjRg(&ppgtb->rgpgd[cpgd], cchPGD, bcpPGD, cpgd, cpFirst + 1,
|
||
dcpAdj);
|
||
}
|
||
}
|
||
|
||
#ifdef ENABLE
|
||
/* invalidate selection which contains the sprm Ruler1. When AdjustCp is
|
||
called in behalf of DragTabs, this invalidation will be undone by the caller
|
||
*/
|
||
if (doc == docRulerSprm && cpFirst >= selRulerSprm.cpFirst)
|
||
docRulerSprm = docNil;
|
||
#endif
|
||
} /* End of pdod belongs in a register */
|
||
|
||
/* Adjust or invalidate bitmap cache as appropriate */
|
||
|
||
if (doc == vdocBitmapCache)
|
||
{
|
||
if (vcpBitmapCache >= cpFirst)
|
||
{
|
||
if (vcpBitmapCache < cpFirst + dcpDel)
|
||
FreeBitmapCache();
|
||
else
|
||
vcpBitmapCache += dcpAdj;
|
||
}
|
||
}
|
||
|
||
for (ww = 0; ww < wwMac; ww++)
|
||
{
|
||
register struct WWD *pwwd;
|
||
if ((pwwd = &rgwwd[ww])->doc == doc)
|
||
{ /* This window may be affected */
|
||
int dlFirst = 0;
|
||
int dlLim = pwwd->dlMac;
|
||
struct EDL *pedlFirst;
|
||
struct EDL *pedlLast;
|
||
register struct EDL *pedl;
|
||
typeCP cpFirstWw = pwwd->cpFirst;
|
||
struct SEL *psel = (ww == wwCur) ? &selCur : &pwwd->sel;
|
||
|
||
if (pwwd->cpMac >= cpLim)
|
||
{
|
||
pwwd->cpMac += dcpAdj;
|
||
if (pwwd->cpMin > cpLim || pwwd->cpMac < pwwd->cpMin)
|
||
{
|
||
pwwd->cpMin += dcpAdj;
|
||
if (ww == wwCur)
|
||
cpMinCur = pwwd->cpMin;
|
||
}
|
||
}
|
||
|
||
#ifndef BOGUSCS
|
||
if (dcpAdj != cp0 && psel->cpLim >= cpFirst)
|
||
#else
|
||
if (dcpAdj != cp0 && psel->cpLim > cpFirst)
|
||
#endif
|
||
{ /* Adjust selection */
|
||
if (psel->cpFirst >= cpLim)
|
||
{ /* Whole sel is after edit */
|
||
psel->cpFirst += dcpAdj;
|
||
psel->cpLim += dcpAdj;
|
||
}
|
||
else
|
||
{ /* Part of sel is in edit */
|
||
typeCP cpLimNew = (dcpIns == 0) ?
|
||
CpFirstSty( cpFirst, styChar ) :
|
||
cpFirst + dcpIns;
|
||
#ifdef BOGUSCS
|
||
if (ww == wwCur)
|
||
TurnOffSel();
|
||
#endif
|
||
psel->cpFirst = cpFirst;
|
||
psel->cpLim = cpLimNew;
|
||
}
|
||
}
|
||
|
||
pedlFirst = &(**(pwwd->hdndl))[0];
|
||
pedl = pedlLast = &pedlFirst[ dlLim - 1];
|
||
|
||
while (pedl >= pedlFirst && (pedl->cpMin > cpLim
|
||
/* || (dcpAdj < 0 && pedl->cpMin == cpLim) */))
|
||
{ /* Adjust dl's after edit */
|
||
pedl->cpMin += dcpAdj;
|
||
pedl--;
|
||
}
|
||
|
||
/* Invalidate dl's containing edit */
|
||
while (pedl >= pedlFirst && (pedl->cpMin + pedl->dcpMac > cpFirst ||
|
||
(pedl->cpMin + pedl->dcpMac == cpFirst && pedl->fIchCpIncr)))
|
||
{
|
||
if (vfInvalid)
|
||
pedl->fValid = false;
|
||
if (ww == wwCur) vpedlAdjustCp = pedl;
|
||
pedl--;
|
||
}
|
||
|
||
if (pedl == pedlLast)
|
||
continue; /* Entire edit below ww */
|
||
|
||
if (vfInvalid)
|
||
pwwd->fDirty = fTrue; /* Say ww needs updating */
|
||
|
||
if (pedl < pedlFirst)
|
||
{ /* Check for possible cpFirstWw change */
|
||
if (cpFirstWw > cpLim) /* Edit above ww */
|
||
pwwd->cpFirst = cpFirstWw + dcpAdj;
|
||
else if (cpFirstWw + pwwd->dcpDepend > cpFirst)
|
||
/* Edit includes hot spot at top of ww */
|
||
{
|
||
if (cpFirst + dcpIns < cpFirstWw)
|
||
{
|
||
pwwd->cpFirst = cpFirst;
|
||
pwwd->ichCpFirst = 0;
|
||
}
|
||
}
|
||
else /* Edit doesn't affect cpFirstWw */
|
||
continue;
|
||
|
||
pwwd->fCpBad = true; /* Say cpFirst inaccurate */
|
||
DirtyCache(cpFirst); /* Say cache inaccurate */
|
||
}
|
||
else do
|
||
{ /* Invalidate previous line if necessary */
|
||
if (pedl->cpMin + pedl->dcpMac + pedl->dcpDepend > cpFirst)
|
||
{
|
||
pedl->fValid = fFalse;
|
||
pwwd->fDirty = fTrue;
|
||
}
|
||
else
|
||
break;
|
||
} while (pedl-- > pedlFirst);
|
||
}
|
||
} /* end for */
|
||
|
||
#if defined(OLE)
|
||
ObjAdjustCps(doc,cpLim,dcpAdj);
|
||
#endif
|
||
|
||
InvalidateCaches(doc);
|
||
Scribble(2,' ');
|
||
}
|
||
|
||
|
||
|
||
|
||
ReplaceCps(docDest, cpDel, dcpDel, docSrc, cpIns, dcpIns)
|
||
int docDest, docSrc;
|
||
typeCP cpDel, dcpDel, cpIns, dcpIns;
|
||
{ /* General replace routine */
|
||
/* Replace dcpDel cp's starting at cpDel in docDest with
|
||
dcpIns cp's starting at cpIns in docSrc. */
|
||
register struct PCTB **hpctbDest;
|
||
struct PCTB **hpctbSrc;
|
||
int ipcdFirst, ipcdLim, ipcdInsFirst, ipcdInsLast;
|
||
register struct PCD *ppcdDest;
|
||
struct PCD *ppcdIns, *ppcdMac;
|
||
typeCP dcpFile, dcpAdj;
|
||
int cpcd;
|
||
|
||
if (ferror) return;
|
||
#ifdef ENABLE
|
||
if (docRulerSprm != docNil) ClearRulerSprm();
|
||
#endif
|
||
|
||
if (dcpIns == cp0) /* This is just too easy . . . */
|
||
{
|
||
Replace(docDest, cpDel, dcpDel, fnNil, fc0, fc0);
|
||
return;
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
Assert(docDest != docSrc);
|
||
#endif /* DEBUG */
|
||
|
||
/* Keep the heap handles, because IpcdSplit & PpcdOpen move heap */
|
||
hpctbDest = (**hpdocdod)[docDest].hpctb;
|
||
hpctbSrc = (**hpdocdod)[docSrc].hpctb;
|
||
|
||
/* Get the first and last pieces for insertion */
|
||
ipcdInsFirst = IpcdFromCp(*hpctbSrc, cpIns);
|
||
ipcdInsLast = IpcdFromCp(*hpctbSrc, cpIns + dcpIns - 1);
|
||
|
||
#ifdef BOGUS /* No longer have cwHeapFree */
|
||
if (cwHeapFree < (ipcdInsLast - ipcdInsFirst + cpcdMaxIncr + 1) * cwPCD + 10)
|
||
{
|
||
#ifdef DEBUG
|
||
ErrorWithMsg(IDPMTNoMemory, " edit#2");
|
||
#else
|
||
Error(IDPMTNoMemory);
|
||
#endif
|
||
return;
|
||
}
|
||
#else
|
||
if (vfOutOfMemory)
|
||
{
|
||
ferror = TRUE;
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
if (docDest == docCur)
|
||
HideSel(); /* Take down sel before we mess with cp's */
|
||
|
||
if (dcpDel != cp0)
|
||
{ /* Check for deleting EOL */
|
||
AdjParas(docDest, cpDel, docDest, cpDel, dcpDel, fTrue);
|
||
DelFtns(docDest, cpDel, cpDel + dcpDel); /* Remove footnotes */
|
||
}
|
||
|
||
if (dcpIns != cp0)
|
||
AdjParas(docDest, cpDel, docSrc, cpIns, dcpIns, fFalse);
|
||
|
||
/* Get the limiting pieces for deletion (indices because hp moves ) */
|
||
ipcdFirst = IpcdSplit(hpctbDest, cpDel);
|
||
ipcdLim = (dcpDel == cp0) ? ipcdFirst : IpcdSplit(hpctbDest, cpDel + dcpDel);
|
||
if (ferror)
|
||
return;
|
||
|
||
/* Adjust pctb size; get pointer to the first new piece, ppcdDest, and to the
|
||
first piece we are inserting. No more heap movement! */
|
||
ppcdDest = PpcdOpen(hpctbDest, &(**hpctbDest).rgpcd[ipcdFirst],
|
||
ipcdFirst - ipcdLim + ipcdInsLast - ipcdInsFirst + 1);
|
||
ppcdIns = &(**hpctbSrc).rgpcd[ipcdInsFirst];
|
||
|
||
if (ferror)
|
||
/* Ran out of memory expanding piece table */
|
||
return;
|
||
|
||
/* Fill first new piece */
|
||
blt(ppcdIns, ppcdDest, cwPCD);
|
||
ppcdDest->cpMin = cpDel;
|
||
ppcdDest->fc += (cpIns - ppcdIns->cpMin);
|
||
|
||
dcpFile = cpDel - cpIns;
|
||
dcpAdj = dcpIns - dcpDel;
|
||
|
||
/* Fill in rest of inserted pieces */
|
||
if ((cpcd = ipcdInsLast - ipcdInsFirst) != 0)
|
||
{
|
||
blt((ppcdIns + 1), (ppcdDest + 1), cwPCD * cpcd);
|
||
while (cpcd--)
|
||
(++ppcdDest)->cpMin += dcpFile;
|
||
}
|
||
|
||
/* Adjust rest of pieces in destination doc */
|
||
ppcdMac = &(**hpctbDest).rgpcd[(**hpctbDest).ipcdMac];
|
||
while (++ppcdDest < ppcdMac)
|
||
ppcdDest->cpMin += dcpAdj;
|
||
#ifdef DEBUG
|
||
/* ShowDocPcd("From ReplaceCps: ", docDest); */
|
||
#endif
|
||
|
||
/* And inform anyone else who cares */
|
||
AdjustCp(docDest, cpDel, dcpDel, dcpIns);
|
||
/* Copy any footnotes along with their reference marks */
|
||
|
||
#ifdef FOOTNOTES
|
||
{
|
||
/* If there are any footnotes call AddFtns */
|
||
struct FNTB **hfntbSrc;
|
||
if ((hfntbSrc = HfntbGet(docSrc)) != 0)
|
||
AddFtns(docDest, cpDel, docSrc, cpIns, cpIns + dcpIns, hfntbSrc);
|
||
}
|
||
#endif /* FOOTNOTES */
|
||
|
||
#ifdef CASHMERE
|
||
{
|
||
/* If there are any sections call AddSects */
|
||
struct SETB **hsetbSrc;
|
||
if ((hsetbSrc = HsetbGet(docSrc)) != 0)
|
||
AddSects(docDest, cpDel, docSrc, cpIns, cpIns + dcpIns, hsetbSrc);
|
||
}
|
||
#endif
|
||
|
||
/* Special kludge for graphics paragraphs */
|
||
if (dcpIns != dcpDel)
|
||
CheckGraphic(docDest, cpDel + dcpIns);
|
||
|
||
if (dcpIns != cp0)
|
||
{
|
||
/* may have to merge in font tables */
|
||
MergeFfntb(docSrc, docDest, cpDel, cpDel + dcpIns);
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
/* ShowDocPcd("From ReplaceCps End: ", docDest); */
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
|
||
/* A D J P A R A S */
|
||
AdjParas(docDest, cpDest, docSrc, cpFirstSrc, dcpLimSrc, fDel)
|
||
int docDest, docSrc, fDel;
|
||
typeCP cpDest, cpFirstSrc, dcpLimSrc;
|
||
{ /* Mark display lines showing the section/paragraph containing cpDest
|
||
in docDest as invalid if the range cpFirstSrc through cpLimSrc-1
|
||
in docSrc contains end-of-section/end-of-paragraph marks */
|
||
|
||
|
||
typeCP cpFirstPara, cpFirstSect;
|
||
typeCP cpLimSrc = cpFirstSrc + dcpLimSrc;
|
||
|
||
#ifdef CASHMERE /* In WRITE, the document is one big section */
|
||
CacheSect(docSrc, cpFirstSrc);
|
||
if (cpLimSrc >= vcpLimSectCache)
|
||
{ /* Sel includes sect mark */
|
||
typeCP dcp;
|
||
CacheSect(docDest, cpDest);
|
||
dcp = cpDest - vcpFirstSectCache;
|
||
AdjustCp(docDest, vcpFirstSectCache, dcp, dcp);
|
||
}
|
||
#endif
|
||
|
||
CachePara(docSrc, cpFirstSrc);
|
||
if (cpLimSrc >= vcpLimParaCache)
|
||
{ /* Diddling with a para return */
|
||
typeCP dcp, cpLim;
|
||
typeCP cpMacT = (**hpdocdod)[docDest].cpMac;
|
||
typeCP cpFirst;
|
||
|
||
if ((cpDest == cpMacT) && (cpMacT != cp0))
|
||
{
|
||
CachePara(docDest, cpDest-1);
|
||
cpLim = cpMacT + 1;
|
||
}
|
||
else
|
||
{
|
||
CachePara(docDest, cpLim = cpDest);
|
||
}
|
||
cpFirst = vcpFirstParaCache;
|
||
/* invalidate at least from cpFirst to cpLim */
|
||
|
||
/* cpFirst is start of disturbed para in destination doc */
|
||
/* next few lines check for effect of the edit on the semi-paragraph after
|
||
the last paragraph mark in the document.
|
||
Note: cpLimSrc is redefined as the point of insertion if !fDel.
|
||
If fDel, Src and Dest documents are the same.
|
||
*/
|
||
if (!fDel)
|
||
cpLimSrc = cpFirstSrc;
|
||
if (cpLimSrc <= cpMacT)
|
||
{
|
||
/* if a paragraph exists at the end of the disturbance, is it the last
|
||
semi-paragraph? */
|
||
CachePara(docDest, cpLimSrc);
|
||
if (vcpLimParaCache > cpMacT)
|
||
/* yes, extend invalidation over the semi-para */
|
||
cpLim = cpMacT + 1;
|
||
}
|
||
else
|
||
cpLim = cpMacT + 1;
|
||
dcp = cpLim - cpFirst;
|
||
AdjustCp(docDest, cpFirst, dcp, dcp);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
int IcpSearch(cp, rgfoo, cchFoo, bcp, ifooLim)
|
||
typeCP cp;
|
||
CHAR rgfoo[];
|
||
unsigned cchFoo;
|
||
unsigned bcp;
|
||
unsigned ifooLim;
|
||
{ /* Binary search a table for cp; return index of 1st >= cp */
|
||
unsigned ifooMin = 0;
|
||
|
||
while (ifooMin + 1 < ifooLim)
|
||
{
|
||
int ifooGuess = (ifooMin + ifooLim - 1) >> 1;
|
||
typeCP cpGuess;
|
||
if ((cpGuess = *(typeCP *) &rgfoo[cchFoo * ifooGuess + bcp]) < cp)
|
||
ifooMin = ifooGuess + 1;
|
||
else if (cpGuess > cp)
|
||
ifooLim = ifooGuess + 1;
|
||
else
|
||
return ifooGuess;
|
||
}
|
||
return ifooMin;
|
||
} /* end of I c p S e a r c h */
|
||
|
||
|
||
|
||
|
||
|
||
DelFtns(doc, cpFirst, cpLim)
|
||
typeCP cpFirst, cpLim;
|
||
int doc;
|
||
{ /* Delete all footnote text corresponding to refs in [cpFirst:cpLim) */
|
||
/* Also delete SED's for section marks. */
|
||
struct FNTB **hfntb;
|
||
|
||
struct SETB **hsetb;
|
||
|
||
struct PGTB **hpgtb;
|
||
|
||
struct DOD *pdod;
|
||
|
||
#ifdef FOOTNOTES
|
||
if ((hfntb = HfntbGet(doc)) != 0)
|
||
RemoveDelFtnText(doc, cpFirst, cpLim, hfntb);
|
||
#endif /* FOOTNOTES */
|
||
|
||
#ifdef CASHMERE
|
||
if ((hsetb = HsetbGet(doc)) != 0)
|
||
RemoveDelSeds(doc, cpFirst, cpLim, hsetb);
|
||
#endif
|
||
|
||
pdod = &(**hpdocdod)[doc];
|
||
if (pdod->dty == dtyNormal && (hpgtb = pdod->hpgtb) != 0)
|
||
RemoveDelPgd(doc, cpFirst, cpLim, hpgtb);
|
||
|
||
}
|
||
|
||
|
||
|
||
AdjRg(pfoo, cchFoo, bcp, ccp, cp, dcpAdj)
|
||
register CHAR *pfoo;
|
||
int cchFoo, bcp, ccp;
|
||
typeCP cp, dcpAdj;
|
||
{ /* Adjust cp's in an array */
|
||
pfoo += bcp;
|
||
while (ccp-- && *(typeCP *)((pfoo -= cchFoo)) >= cp)
|
||
*(typeCP *)(pfoo) += dcpAdj;
|
||
}
|
||
|
||
|
||
|
||
|
||
DeleteSel()
|
||
{ /* Delete a selection */
|
||
typeCP cpFirst;
|
||
typeCP cpLim;
|
||
typeCP dcp;
|
||
|
||
cpFirst = selCur.cpFirst;
|
||
cpLim = selCur.cpLim;
|
||
|
||
NoUndo(); /* We don't want any combining of adjacents for this operation */
|
||
SetUndo(uacDelNS, docCur, cpFirst, dcp = cpLim - cpFirst,
|
||
docNil, cpNil, cp0, 0);
|
||
Replace(docCur, cpFirst, dcp, fnNil, fc0, fc0);
|
||
vfSeeSel = true;
|
||
vfPictSel = false;
|
||
return ferror;
|
||
}
|
||
|
||
|
||
|
||
|
||
FWriteOk( fwc )
|
||
int fwc;
|
||
{ /* Test whether the edit operation specified by fwc is acceptable.
|
||
Assume the operation is to be performed on selCur in docCur.
|
||
Return TRUE if the operation is acceptable; FALSE otherwise */
|
||
extern int vfOutOfMemory;
|
||
|
||
return !vfOutOfMemory;
|
||
}
|
||
|
||
|
||
|
||
|
||
/* S E T U N D O */
|
||
SetUndo(uac, doc, cp, dcp, doc2, cp2, dcp2, itxb)
|
||
int uac, doc, doc2;
|
||
typeCP cp, dcp, cp2, dcp2;
|
||
short itxb;
|
||
{/* Set up the UNDO structure, vuab, in response to an editing operation */
|
||
struct DOD *pdod, *pdodUndo;
|
||
|
||
/* Group delete operations together with adjacent deletes or replaces */
|
||
/* WRITE needs the replace case since AlphaMode is treated as a big */
|
||
/* replace operation */
|
||
|
||
if (uac == uacDelNS && doc == vuab.doc)
|
||
{
|
||
if ((vuab.uac == uacDelNS) || (vuab.uac == uacReplNS))
|
||
{
|
||
typeCP cpUndoAdd;
|
||
|
||
if (cp == vuab.cp)
|
||
{
|
||
cpUndoAdd = CpMacText( docUndo );
|
||
goto UndoAdd;
|
||
}
|
||
else if (cp + dcp == vuab.cp)
|
||
{
|
||
cpUndoAdd = cp0;
|
||
UndoAdd: ReplaceCps( docUndo, cpUndoAdd, cp0, doc, cp, dcp );
|
||
if (vuab.uac == uacDelNS)
|
||
vuab.dcp += dcp;
|
||
else
|
||
vuab.dcp2 += dcp;
|
||
goto SURet;
|
||
}
|
||
else if (vuab.uac == uacReplNS && cp == vuab.cp + vuab.dcp)
|
||
{ /* Special case for combining insertions --
|
||
do not start a new undo operation if a null
|
||
deletion is done at the end of an existing replace */
|
||
if (dcp == cp0)
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Group insertions together with adjacent ins's and replaces */
|
||
|
||
if (uac == uacInsert && doc == vuab.doc)
|
||
{/* check for adjacent inserts */
|
||
/* Because we can be popped out of Alpha Mode so easily
|
||
in WRITE, we try to be smarter about combining adjacent
|
||
insert operations */
|
||
if (vuab.uac == uacInsert || vuab.uac == uacReplNS)
|
||
{
|
||
if (cp == vuab.cp + vuab.dcp)
|
||
{
|
||
vuab.dcp += dcp;
|
||
goto SURet;
|
||
}
|
||
}
|
||
else if (cp == vuab.cp)
|
||
switch(vuab.uac)
|
||
{
|
||
default:
|
||
break;
|
||
case uacDelNS:
|
||
vuab.dcp2 = vuab.dcp;
|
||
vuab.uac = uacReplNS;
|
||
goto repl;
|
||
case uacDelBuf:
|
||
vuab.uac = uacReplBuf;
|
||
goto repl;
|
||
case uacDelScrap:
|
||
vuab.uac = uacReplScrap;
|
||
repl:
|
||
vuab.dcp = dcp;
|
||
SetUndoMenuStr(IDSTRUndoEdit);
|
||
goto SURet;
|
||
}
|
||
}
|
||
|
||
#ifndef CASHMERE
|
||
/* The use of vuab.itxb is a kludge to determine if the undo block is
|
||
for a ruler change or an undone ruler change. */
|
||
if (uac == uacRulerChange && vuab.uac == uacRulerChange && doc ==
|
||
vuab.doc && cp == vuab.cp && vuab.itxb == 0)
|
||
{
|
||
/* The undo action block for the ruler change is already set. */
|
||
vuab.dcp = CpMax(dcp, vuab.dcp);
|
||
goto SURet;
|
||
}
|
||
#endif /* not CASHMERE */
|
||
|
||
vuab.doc = doc;
|
||
vuab.cp = cp;
|
||
vuab.dcp = dcp;
|
||
vuab.doc2 = doc2;
|
||
vuab.cp2 = cp2;
|
||
vuab.dcp2 = dcp2;
|
||
vuab.itxb = itxb;
|
||
/*idstrUndoBase = IDSTRUndoBase;*/
|
||
switch (vuab.uac = uac)
|
||
{ /* Save deleted text if necessary */
|
||
default:
|
||
SetUndoMenuStr(IDSTRUndoEdit);
|
||
break;
|
||
case uacDelScrap:
|
||
case uacReplScrap:
|
||
/* Two-level edit; save scrap */
|
||
{
|
||
extern int vfOwnClipboard;
|
||
|
||
if ( vfOwnClipboard )
|
||
{
|
||
ClobberDoc( docUndo, docScrap, cp0,
|
||
CpMacText( docScrap ) );
|
||
}
|
||
else
|
||
ClobberDoc(docUndo, docNil, cp0, cp0);
|
||
|
||
SetUndoMenuStr(IDSTRUndoEdit);
|
||
/* SetUndoMenuStr(uac == uacDelScrap ? IDSTRUndoCut :*/
|
||
/* IDSTRUndoPaste);*/
|
||
break;
|
||
}
|
||
case uacDelNS:
|
||
/* One-level edit; save deleted text */
|
||
ClobberDoc(docUndo, doc, cp, dcp);
|
||
SetUndoMenuStr(IDSTRUndoEdit);
|
||
/* SetUndoMenuStr(IDSTRUndoCut);*/
|
||
break;
|
||
case uacReplNS:
|
||
/* One-level edit; save deleted text */
|
||
ClobberDoc(docUndo, doc, cp, dcp2);
|
||
SetUndoMenuStr(IDSTRUndoEdit);
|
||
/* SetUndoMenuStr(IDSTRUndoPaste);*/
|
||
break;
|
||
case uacPictSel:
|
||
ClobberDoc(docUndo, doc, cp, dcp);
|
||
SetUndoMenuStr(IDSTRUndoEdit);
|
||
/* SetUndoMenuStr(IDSTRUndoPict);*/
|
||
break;
|
||
case uacChLook:
|
||
case uacChLookSect:
|
||
SetUndoMenuStr(IDSTRUndoLook);
|
||
break;
|
||
|
||
#ifndef CASHMERE
|
||
case uacFormatTabs:
|
||
ClobberDoc(docUndo, doc, cp, dcp);
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
break;
|
||
case uacRepaginate:
|
||
case uacFormatSection:
|
||
ClobberDoc(docUndo, doc, cp, dcp);
|
||
if ((**hpdocdod)[doc].hpgtb)
|
||
{ /* copy page table over if there is one */
|
||
int cw = cwPgtbBase + (**(**hpdocdod)[doc].hpgtb).cpgdMax * cwPGD;
|
||
CopyHeapTableHandle(hpdocdod,
|
||
(sizeof(struct DOD) * doc) + BStructMember(DOD, hpgtb),
|
||
(sizeof(struct DOD) * docUndo) + BStructMember(DOD, hpgtb),
|
||
cw);
|
||
}
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
break;
|
||
case uacRulerChange:
|
||
ClobberDoc(docUndo, doc, cp, dcp2);
|
||
SetUndoMenuStr(IDSTRUndoLook);
|
||
/* SetUndoMenuStr(IDSTRUndoRuler);*/
|
||
break;
|
||
#endif /* not CASHMERE */
|
||
|
||
#ifdef UPDATE_UNDO
|
||
#if defined(OLE)
|
||
case uacObjUpdate:
|
||
ClobberDoc(docUndo, docNil, cp0, cp0);
|
||
SetUndoMenuStr(IDSTRObjUndo);
|
||
break;
|
||
#endif
|
||
#endif
|
||
}
|
||
|
||
if (doc != docNil)
|
||
{
|
||
pdod = &(**hpdocdod)[doc];
|
||
pdodUndo = &(**hpdocdod)[docUndo];
|
||
pdodUndo->fDirty = pdod->fDirty;
|
||
pdodUndo->fFormatted = pdod->fFormatted;
|
||
if (uac != uacReplScrap)
|
||
/* If SetUndo is called with uacReplScrap, = COPY SCRAP */
|
||
pdod->fDirty = true;
|
||
}
|
||
#ifdef BOGUSCS
|
||
if (uac == uacMove)
|
||
CheckMove();
|
||
#endif
|
||
SURet:
|
||
if (ferror) NoUndo();
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
/* C L O B B E R D O C */
|
||
ClobberDoc(docDest, docSrc, cp, dcp)
|
||
int docDest, docSrc;
|
||
typeCP cp, dcp;
|
||
{ /* Replace contents of docDest with docSrc[cp:dcp] */
|
||
|
||
extern int docScrap;
|
||
extern int vfOwnClipboard;
|
||
struct FFNTB **hffntb;
|
||
struct SEP **hsep;
|
||
struct TBD (**hgtbd)[];
|
||
|
||
register int bdodDest=sizeof(struct DOD)*docDest;
|
||
register int bdodSrc=sizeof(struct DOD)*docSrc;
|
||
|
||
#define dodDest (*((struct DOD *)(((CHAR *)(*hpdocdod))+bdodDest)))
|
||
#define dodSrc (*((struct DOD *)(((CHAR *)(*hpdocdod))+bdodSrc)))
|
||
|
||
/* clear out dest doc's font table - it will get a copy of source's */
|
||
hffntb = HffntbGet(docDest);
|
||
dodDest.hffntb = 0;
|
||
|
||
/* this does nothing if hffntb is NULL (5.15.91) v-dougk */
|
||
FreeFfntb(hffntb);
|
||
|
||
SmashDocFce(docDest); /* font cache entries can't refer to it by doc
|
||
any more */
|
||
|
||
/* this does nothing (code stubbed out) (5.15.91) v-dougk */
|
||
ZeroFtns(docDest); /* So ReplaceCps doesn't worry about them */
|
||
|
||
ReplaceCps(docDest, cp0, dodDest.cpMac, docSrc, cp, dcp);
|
||
|
||
/* Copy section properties and tab table, both of which are
|
||
document properties in MEMO */
|
||
CopyHeapTableHandle( hpdocdod,
|
||
((docSrc == docNil) ? -1 :
|
||
bdodSrc + BStructMember( DOD, hsep )),
|
||
bdodDest + BStructMember( DOD, hsep ),
|
||
cwSEP );
|
||
CopyHeapTableHandle( hpdocdod,
|
||
((docSrc == docNil) ? -1 :
|
||
bdodSrc + BStructMember( DOD, hgtbd )),
|
||
bdodDest + BStructMember( DOD, hgtbd ),
|
||
cwTBD * itbdMax );
|
||
}
|
||
|
||
|
||
|
||
|
||
CopyHeapTableHandle( hBase, bhSrc, bhDest, cwHandle )
|
||
CHAR **hBase;
|
||
register int bhSrc;
|
||
register int bhDest;
|
||
int cwHandle;
|
||
{ /* Copy cwHandle words of contents from a handle located at
|
||
offset (in bytes) bhSrc from the beginning of heap object
|
||
hBase to a handle located at bhDest from the same base. If the
|
||
destination handle is non-NULL, free it first.
|
||
If bhSrc is negative, free the destination, but do not copy */
|
||
|
||
int **hT;
|
||
|
||
#define hSrc (*((int ***) ((*hBase)+bhSrc)))
|
||
#define hDest (*((int ***) ((*hBase)+bhDest)))
|
||
|
||
if (hDest != NULL)
|
||
{
|
||
FreeH( hDest );
|
||
hDest = NULL;
|
||
}
|
||
|
||
if ( (bhSrc >= 0) && (hSrc != NULL) &&
|
||
!FNoHeap( hT = (int **)HAllocate( cwHandle )))
|
||
{
|
||
blt( *hSrc, *hT, cwHandle );
|
||
hDest = hT;
|
||
}
|
||
|
||
#undef hSrc
|
||
#undef hDest
|
||
}
|
||
|
||
|
||
|
||
ZeroFtns(doc)
|
||
{ /* Remove all footnote & section references from doc */
|
||
struct FNTB **hfntb;
|
||
struct SETB **hsetb;
|
||
|
||
#ifdef FOOTNOTES
|
||
if ((hfntb = HfntbGet(doc)) != 0)
|
||
{
|
||
FreeH(hfntb);
|
||
(**hpdocdod)[doc].hfntb = 0;
|
||
}
|
||
#endif /* FOOTNOTES */
|
||
#ifdef CASHMERE
|
||
if ((hsetb = HsetbGet(doc)) != 0)
|
||
{
|
||
FreeH(hsetb);
|
||
(**hpdocdod)[doc].hsetb = 0;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
fnClearEdit(int nInsertingOver)
|
||
|
||
{ /* CLEAR command entry point: Delete the current selection */
|
||
|
||
/**
|
||
NOTE: as of this comment, this is used:
|
||
1) when typing over a selection (AlphaMode() in insert.c)
|
||
2) when Pasting over a selection (fnPasteEdit in clipboard.c)
|
||
3) when pressing the delete key
|
||
4) for InsertObject (obj3.c)
|
||
5) for DragDrop (obj3.c)
|
||
6) Clear header/footer (running.c)
|
||
|
||
A similar sequence occurs when cutting to the clipboard
|
||
(fnCutEdit in clipbord.c).
|
||
|
||
Also see copying to clipboard (fnCopyEdit in clipbord.c).
|
||
|
||
(8.29.91) v-dougk
|
||
**/
|
||
|
||
if (!FWriteOk( fwcDelete ))
|
||
return TRUE;
|
||
|
||
if (selCur.cpFirst < selCur.cpLim)
|
||
{
|
||
#if defined(OLE)
|
||
|
||
/* this'll prevent us from deleting open embeds */
|
||
if (!ObjDeletionOK(nInsertingOver))
|
||
return TRUE;
|
||
|
||
/* close open links */
|
||
ObjEnumInRange(docCur,selCur.cpFirst,selCur.cpLim,ObjCloseObjectInDoc);
|
||
#endif
|
||
|
||
return DeleteSel();
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
|
||
MergeFfntb(docSrc, docDest, cpMin, cpLim)
|
||
/* determines if the two docs font tables differ to the extent that we need
|
||
to apply a mapping sprm to the specified cp's */
|
||
|
||
int docSrc, docDest;
|
||
typeCP cpMin, cpLim;
|
||
{
|
||
struct FFNTB **hffntb;
|
||
int cftcDiffer, ftc, iffn;
|
||
struct FFN *pffn;
|
||
CHAR rgbSprm[2 + 256];
|
||
CHAR rgbFfn[ibFfnMax];
|
||
|
||
hffntb = HffntbGet(docSrc);
|
||
if (hffntb != 0)
|
||
{
|
||
cftcDiffer = 0;
|
||
for (iffn = 0; iffn < (*hffntb)->iffnMac; iffn++)
|
||
{
|
||
pffn = *(*hffntb)->mpftchffn[iffn];
|
||
bltbyte(pffn, rgbFfn, CbFromPffn(pffn));
|
||
ftc = FtcChkDocFfn(docDest, rgbFfn);
|
||
if (ftc != iffn)
|
||
cftcDiffer++;
|
||
rgbSprm[2+iffn] = ftc;
|
||
if (ftc == ftcNil)
|
||
/* we're stuck! */
|
||
return;
|
||
}
|
||
|
||
if (cftcDiffer == 0)
|
||
/* new font table is a superset, & all the old font table's
|
||
ftc's matched exactly - no need to do anything */
|
||
return;
|
||
|
||
rgbSprm[0] = sprmCMapFtc;
|
||
rgbSprm[1] = (*hffntb)->iffnMac;
|
||
|
||
/* here goes - apply the mapping */
|
||
AddSprmCps(rgbSprm, docDest, cpMin, cpLim);
|
||
}
|
||
}
|
||
|
||
|