874 lines
28 KiB
C
874 lines
28 KiB
C
/************************************************************/
|
||
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
||
/************************************************************/
|
||
|
||
/* NOTE: the routines in this file are not written in a manner which minimizes
|
||
code space. It is anticipated that these routines will be swappable
|
||
and that a reasonable optimizer will be used when compiling the code */
|
||
|
||
#define NOCLIPBOARD
|
||
#define NOGDICAPMASKS
|
||
#define NOCTLMGR
|
||
#define NOVIRTUALKEYCODES
|
||
#define NOWINMESSAGES
|
||
#define NOWINSTYLES
|
||
#define NOSYSMETRICS
|
||
#define NOMENUS
|
||
#define NOKEYSTATE
|
||
//#define NOGDI
|
||
#define NORASTEROPS
|
||
#define NOSYSCOMMANDS
|
||
#define NOSHOWWINDOW
|
||
#define NOCOLOR
|
||
//#define NOATOM
|
||
#define NOBITMAP
|
||
#define NOICON
|
||
#define NOBRUSH
|
||
#define NOCREATESTRUCT
|
||
#define NOMB
|
||
#define NOFONT
|
||
#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 "docdefs.h"
|
||
#include "editdefs.h"
|
||
#include "cmddefs.h"
|
||
#include "str.h"
|
||
#include "txb.h"
|
||
#include "ch.h"
|
||
#include "code.h"
|
||
#include "wwdefs.h"
|
||
#include "printdef.h"
|
||
#if defined(OLE)
|
||
#include "obj.h"
|
||
#endif
|
||
|
||
#ifndef CASHMERE
|
||
#include "propdefs.h"
|
||
#endif /* not CASHMERE */
|
||
|
||
struct UAB vuab;
|
||
|
||
#ifdef ENABLE
|
||
VAL rgvalAgain[ivalMax];
|
||
#endif
|
||
|
||
extern struct WWD *pwwdCur;
|
||
extern typeCP cpMacCur;
|
||
extern typeCP cpMinCur;
|
||
extern int vfSeeSel;
|
||
extern int docMac;
|
||
extern int docCur;
|
||
extern int docScrap;
|
||
extern int docUndo;
|
||
extern int docBuffer;
|
||
extern int vdocPageCache;
|
||
extern struct DOD (**hpdocdod)[];
|
||
extern struct SEL selCur;
|
||
extern CHAR (**hszReplace)[];
|
||
extern struct TXB (**hgtxb)[];
|
||
/*extern int idstrUndoBase;*/
|
||
extern int vfPictSel;
|
||
extern int ferror;
|
||
extern int docMode;
|
||
extern int vfOwnClipboard; /* Whether this instance owns the clip contents */
|
||
|
||
#ifndef CASHMERE
|
||
extern int vdocSectCache;
|
||
#endif /* not CASHMERE */
|
||
|
||
|
||
fnUndoEdit()
|
||
{
|
||
extern HCURSOR vhcIBeam;
|
||
StartLongOp();
|
||
CmdUndo();
|
||
EndLongOp(vhcIBeam);
|
||
}
|
||
|
||
|
||
/*
|
||
The routines in this file implement the "undo" and "again" features in
|
||
Multi-Tool Word. The basic idea is that whenever an editing operation is
|
||
about to be done, the global structure "vuab" will be updated to contain
|
||
information sufficient to undo or repeat that operation. The structure
|
||
(defined in editdefs.h, declared in this file) looks like this:
|
||
struct UAB
|
||
{ UNDO Action Block
|
||
int uac; UNDO Action Code (see cmddefs.h)
|
||
int doc;
|
||
typeCP cp;
|
||
typeCP dcp;
|
||
int doc2;
|
||
typeCP cp2;
|
||
typeCP dcp2;
|
||
short itxb;
|
||
};
|
||
Setting up this structure is taken care of by "SetUndo()" which does a lot
|
||
of plugging in of values and a couple pseudo-smart things. These smartish
|
||
things are:
|
||
a) If an insert is made and the last operation was a delete
|
||
the two are combined into one "replace" operation.
|
||
This means that undo-ing and again-ing apply to the replace and
|
||
not just the insertion.
|
||
|
||
b) When needed (see the code for details) the undo buffer (docUndo)
|
||
is filled with any text that needs preservation for future
|
||
undo-ing or again-ing. The main example of this is storing away
|
||
the old value of the scrap when an operation is about to clobber
|
||
the scrap.
|
||
|
||
Here is a list of the various uac values and what info is stored
|
||
other info may be clobbered by the process.
|
||
are defined in cmddefs.h. Note that none of the "undo" codes
|
||
(those starting with "uacU...") should be set outside of CmdUndo(),
|
||
since they may assume things like contents of docUndo which could
|
||
be wrong.
|
||
Note: This list store information used by the again and undo commands.
|
||
Other info may be clobbered by the process.
|
||
|
||
uacNil No action stored.
|
||
uacInsert
|
||
doc = document text was inserted into
|
||
cp = location at which text was inserted
|
||
dcp = length of inserted text
|
||
uacUInsert
|
||
doc = document from which text was removed (un-inserted)
|
||
cp = location at which text was removed
|
||
docUndo = text which was removed
|
||
uacReplNS
|
||
doc = document in which replacement occurred
|
||
cp = location at which replacement occurred
|
||
dcp = length of inserted text
|
||
dcp2 = length of deleted text
|
||
docUndo = deleted text
|
||
uacUReplNS
|
||
doc = document in which replace occrred
|
||
cp = location of the replace
|
||
dcp = length of re-inserted text
|
||
dcp2 = length of un-inserted text
|
||
docUndo = un-inserted text
|
||
uacReplGlobal
|
||
uacChLook
|
||
uacChLookSect
|
||
uacFormatChar
|
||
uacFormatPara
|
||
uacFormatSection
|
||
uacGalFormatChar
|
||
uacGalFormatPara
|
||
uacGalFormatSection
|
||
uacFormatCStyle
|
||
uacFormatPStyle
|
||
uacFormatSStyle
|
||
uacFormatRHText
|
||
uacLookCharMouse
|
||
uacLookParaMouse
|
||
uacClearAllTab
|
||
uacFormatTabs
|
||
uacClearTab
|
||
uacOvertype
|
||
Similar to uacReplNS except that they are agained differently.
|
||
uacDelNS
|
||
doc = document from which text was deleted
|
||
cp = location at which text was deleted
|
||
dcp = length of deleted text
|
||
docUndo = deleted text
|
||
uacUDelNS
|
||
doc = document in which text was re-inserted
|
||
cp = location at which text was re-inserted
|
||
dcp = length of re-inserted text
|
||
uacMove
|
||
doc = document from which text was deleted
|
||
cp = location at which text was deleted
|
||
dcp = length of deleted text
|
||
(also serves as length of inserted text)
|
||
doc2 = document in which text was inserted
|
||
cp2 = location at which text was inserted
|
||
uacDelScrap
|
||
doc = document from which text was deleted
|
||
cp = location at which text was deleted
|
||
dcp = length of deleted text
|
||
docUndo = old contents of scrap
|
||
uacUDelScrap
|
||
doc = document in which text was re-inserted
|
||
cp = location at which text was re-inserted
|
||
dcp = length of re-inserted text
|
||
uacReplScrap
|
||
doc = document in which replacement occurred
|
||
cp = location at which replacement occurred
|
||
dcp = length of inserted text
|
||
docUndo = old contents of scrap
|
||
uacUReplScrap
|
||
doc = document in which replacement was undone
|
||
cp = location at which replacement was undone
|
||
dcp = length of re-inserted text
|
||
docUndo = deleted text (was originally inserted)
|
||
uacDelBuf
|
||
doc = document from which text was deleted
|
||
cp = location at which text was deleted
|
||
cp2 = location in docBuffer of old contents of buffer
|
||
dcp2 = size of old contents of buffer
|
||
itxb = index of buffer in question
|
||
uacUDelBuf
|
||
doc = document in which text was re-inserted
|
||
cp = location of re-insertion
|
||
dcp = amount of text re-inserted
|
||
itxb = index of buffer involved
|
||
uacReplBuf
|
||
doc = document in which replace took place
|
||
cp = location of replace
|
||
dcp = length of inserted text
|
||
cp2 = location of old buffer contents in docBuffer
|
||
dcp2 = length of old buffer contents
|
||
itxb = index of buffer involved
|
||
uacUReplBuf
|
||
doc = document in which original replace took place
|
||
cp = location of replace
|
||
dcp = length of text which was restored in document
|
||
itxb = index of buffer involved
|
||
docUndo = un-inserted text
|
||
uacCopyBuf
|
||
cp = location of old buffer contents in docBuffer
|
||
dcp = length of old buffer contents
|
||
itxb = index of buffer involved
|
||
uacUCopyBuf
|
||
cp = location of undone buffer contents in docBuffer
|
||
dcp = length of undone buffer contents
|
||
itxb = index of buffer involved
|
||
*/
|
||
|
||
|
||
CmdUndo()
|
||
{ /* UNDO */
|
||
typeCP dcpT,cpT,dcpT2;
|
||
int docT;
|
||
int f;
|
||
struct DOD *pdod, *pdodUndo;
|
||
int uac;
|
||
|
||
#ifndef CASHMERE
|
||
struct SEP **hsep;
|
||
struct TBD (**hgtbd)[];
|
||
struct PGTB **hpgtb;
|
||
struct PGTB **hpgtbUndo;
|
||
struct PGTB **hpgtbT;
|
||
|
||
BOOL near FCopyPgtb(int, struct PGTB ***);
|
||
#endif /* not CASHMERE */
|
||
|
||
TurnOffSel();
|
||
ClearInsertLine();
|
||
switch (uac = vuab.uac)
|
||
{
|
||
struct TXB *ptxb;
|
||
default:/* case uacNil: */
|
||
Assert(false); /* Won't get here cause menu should be greyed */
|
||
return;
|
||
case uacInsert:
|
||
case uacInsertFtn:
|
||
case uacUDelNS:
|
||
ClobberDoc(docUndo, vuab.doc, vuab.cp, vuab.dcp);
|
||
Replace(vuab.doc, vuab.cp, vuab.dcp, fnNil, fc0, fc0);
|
||
dcpT = cp0;
|
||
vuab.uac = (uac == uacUDelNS) ? uacDelNS : uacUInsert;
|
||
/* idstrUndoBase = uac == uacUDelNS ? IDSTRUndoBase : IDSTRUndoRedo;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
if (uac == uacInsertFtn)
|
||
TrashAllWws(); /* Simple, but effective */
|
||
break;
|
||
case uacUInsert:
|
||
case uacDelNS:
|
||
ReplaceCps(vuab.doc, vuab.cp, cp0, docUndo, cp0, dcpT = vuab.dcp);
|
||
vuab.uac = (uac == uacUInsert) ? uacInsert : uacUDelNS;
|
||
/* idstrUndoBase = uac == uacUInsert ? IDSTRUndoBase : IDSTRUndoRedo;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
break;
|
||
|
||
case uacDelScrap: /* UNDO CUT */
|
||
if ( !vfOwnClipboard )
|
||
ferror = TRUE;
|
||
else
|
||
{
|
||
ReplaceCps(vuab.doc, vuab.cp, cp0, docScrap, cp0,
|
||
dcpT = CpMacText(docScrap));
|
||
vuab.uac = uacUDelScrap;
|
||
/* idstrUndoBase = IDSTRUndoRedo;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
ClobberDoc( docScrap, docUndo, cp0, CpMacText( docUndo ) );
|
||
ChangeClipboard();
|
||
}
|
||
break;
|
||
|
||
case uacUDelScrap: /* REDO CUT */
|
||
ClobberDoc( docUndo, docScrap, cp0, CpMacText( docScrap ) );
|
||
/* idstrUndoBase = IDSTRUndoBase;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
vuab.uac = uacDelScrap;
|
||
|
||
ClobberDoc(docScrap, vuab.doc, vuab.cp, vuab.dcp);
|
||
Replace(vuab.doc, vuab.cp, vuab.dcp, fnNil, fc0, fc0);
|
||
ChangeClipboard();
|
||
|
||
dcpT = 0;
|
||
break;
|
||
case uacReplScrap: /* UNDO COPY */
|
||
if (!vfOwnClipboard)
|
||
ferror = TRUE;
|
||
else
|
||
{
|
||
dcpT = CpMacText(docScrap);
|
||
ReplaceCps(vuab.doc, vuab.cp + vuab.dcp, cp0,
|
||
docScrap, cp0, dcpT);
|
||
|
||
ClobberDoc( docScrap, docUndo, cp0, CpMacText( docUndo ) );
|
||
|
||
/* idstrUndoBase = IDSTRUndoRedo;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
vuab.uac = uacUReplScrap;
|
||
|
||
ClobberDoc(docUndo, vuab.doc, vuab.cp, vuab.dcp);
|
||
Replace(vuab.doc, vuab.cp, vuab.dcp, fnNil, fc0, fc0);
|
||
vuab.dcp = dcpT;
|
||
ChangeClipboard();
|
||
}
|
||
break;
|
||
case uacUReplScrap: /* REDO COPY */
|
||
dcpT = CpMacText(docUndo);
|
||
ReplaceCps(vuab.doc, vuab.cp + vuab.dcp, cp0,
|
||
docUndo, cp0, dcpT);
|
||
|
||
ClobberDoc( docUndo, docScrap, cp0, CpMacText( docScrap ));
|
||
/* idstrUndoBase = IDSTRUndoBase;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
vuab.uac = uacReplScrap;
|
||
|
||
ClobberDoc(docScrap, vuab.doc, vuab.cp, vuab.dcp);
|
||
Replace(vuab.doc, vuab.cp, vuab.dcp, fnNil, fc0, fc0);
|
||
vuab.dcp = dcpT;
|
||
|
||
ChangeClipboard();
|
||
break;
|
||
#ifdef DEBUG
|
||
case uacUCopyBuf:
|
||
case uacCopyBuf:
|
||
case uacUReplBuf:
|
||
case uacReplBuf:
|
||
case uacUDelBuf:
|
||
case uacDelBuf:
|
||
|
||
Assert( FALSE ); /* No buffers in MEMO */
|
||
#ifdef ENABLE
|
||
DoUndoTxb(); /* Moved to txb.c */
|
||
#endif
|
||
break;
|
||
#endif /* DEBUG */
|
||
case uacMove:
|
||
if (!FMoveText(vuab.doc2, vuab.cp2, vuab.dcp, vuab.doc, &vuab.cp, fFalse))
|
||
return;
|
||
dcpT = vuab.dcp;
|
||
cpT = vuab.cp;
|
||
vuab.cp = vuab.cp2;
|
||
vuab.cp2 = cpT;
|
||
docT = vuab.doc;
|
||
vuab.doc = vuab.doc2;
|
||
vuab.doc2 = docT;
|
||
CheckMove();
|
||
break;
|
||
case uacUReplNS:
|
||
case uacChLook:
|
||
case uacChLookSect:
|
||
case uacReplNS:
|
||
case uacFormatChar:
|
||
case uacFormatPara:
|
||
case uacGalFormatChar:
|
||
case uacGalFormatPara:
|
||
case uacGalFormatSection:
|
||
case uacReplGlobal:
|
||
case uacFormatCStyle:
|
||
case uacFormatPStyle:
|
||
case uacFormatSStyle:
|
||
case uacFormatRHText:
|
||
case uacLookCharMouse:
|
||
case uacLookParaMouse:
|
||
case uacClearAllTab:
|
||
case uacClearTab:
|
||
case uacOvertype:
|
||
|
||
#ifdef CASHMERE
|
||
case uacFormatTabs:
|
||
case uacFormatSection:
|
||
#endif /* CASHMERE */
|
||
|
||
#ifdef BOGUS
|
||
/* Must do insertion first, in front, in case footnote */
|
||
/* if (uac == uacOvertype)
|
||
vuab.dcp2 = CpMin(vuab.dcp, vuab.dcp2);*/
|
||
dcpT = vuab.dcp2;
|
||
ReplaceCps(vuab.doc, vuab.cp, cp0, docUndo, cp0, dcpT);
|
||
ClobberDoc(docUndo, vuab.doc, vuab.cp + dcpT, vuab.dcp);
|
||
Replace(vuab.doc, vuab.cp + dcpT, vuab.dcp, fnNil, fc0, fc0);
|
||
vuab.dcp2 = vuab.dcp;
|
||
vuab.dcp = dcpT;
|
||
if(uac == uacReplNS)
|
||
vuab.uac = uacUReplNS;
|
||
else if(uac == uacUReplNS)
|
||
vuab.uac = uacReplNS;
|
||
/* idstrUndoBase = uac != uacUReplNS ? IDSTRUndoRedo : IDSTRUndoBase;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
break;
|
||
#endif
|
||
case uacReplPic:
|
||
case uacUReplPic:
|
||
case uacPictSel:
|
||
dcpT = uac != uacPictSel ? vuab.dcp2 : vuab.dcp;
|
||
ReplaceCps(docUndo, dcpT, cp0, vuab.doc, vuab.cp, vuab.dcp);
|
||
ReplaceCps(vuab.doc, vuab.cp, vuab.dcp, docUndo, cp0, dcpT);
|
||
Replace(docUndo, cp0, dcpT, fnNil, fc0, fc0);
|
||
if (uac != uacPictSel)
|
||
{
|
||
vuab.dcp2 = vuab.dcp;
|
||
vuab.dcp = dcpT;
|
||
}
|
||
if (uac == uacPictSel)
|
||
{
|
||
dcpT = (**hpdocdod)[vuab.doc].cpMac - vuab.cp;
|
||
AdjustCp(vuab.doc, vuab.cp, dcpT, dcpT);
|
||
}
|
||
if(uac == uacReplPic)
|
||
vuab.uac = uacUReplPic;
|
||
else if(uac == uacUReplPic)
|
||
vuab.uac = uacReplPic;
|
||
else if(uac == uacReplNS)
|
||
vuab.uac = uacUReplNS;
|
||
else if(uac == uacUReplNS)
|
||
vuab.uac = uacReplNS;
|
||
/* switch(uac) */
|
||
/* { */
|
||
/* case uacUReplPic: */
|
||
/* case uacUReplNS: */
|
||
/* idstrUndoBase = IDSTRUndoBase; */
|
||
/* break; */
|
||
/* case uacReplPic: */
|
||
/* case uacReplNS: */
|
||
/* idstrUndoBase = IDSTRUndoRedo; */
|
||
/* break; */
|
||
/* default: */
|
||
/* idstrUndoBase = (idstrUndoBase == */
|
||
/* IDSTRUndoRedo) ? IDSTRUndoBase : IDSTRUndoRedo;*/
|
||
/* break; */
|
||
/* } */
|
||
/*--- idstrUndoBase = (uac != uacUReplPic && uac != uacUReplNS) ?
|
||
IDSTRUndoRedo : IDSTRUndoBase;---*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
Select( CpFirstSty( selCur.cpFirst, styChar ),
|
||
CpLastStyChar( selCur.cpLim ) );
|
||
break;
|
||
|
||
#ifndef CASHMERE
|
||
case uacRepaginate:
|
||
/* Make a copy of the document's page table. */
|
||
if (!FCopyPgtb(vuab.doc, &hpgtb) || !FCopyPgtb(docUndo, &hpgtbUndo))
|
||
{
|
||
break;
|
||
}
|
||
|
||
/* Swap the contents of the entire document with docUndo. */
|
||
dcpT = CpMacText(vuab.doc);
|
||
dcpT2 = CpMacText(docUndo);
|
||
ReplaceCps(docUndo, dcpT2, cp0, vuab.doc, cp0, dcpT);
|
||
ReplaceCps(vuab.doc, cp0, dcpT, docUndo, cp0, dcpT2);
|
||
Replace(docUndo, cp0, dcpT2, fnNil, fc0, fc0);
|
||
|
||
/* Swap the page tables of the two documents. */
|
||
if ((hpgtbT = (**hpdocdod)[vuab.doc].hpgtb) != NULL)
|
||
{
|
||
FreeH(hpgtbT);
|
||
}
|
||
(**hpdocdod)[vuab.doc].hpgtb = hpgtbUndo;
|
||
if ((hpgtbT = (**hpdocdod)[docUndo].hpgtb) != NULL)
|
||
{
|
||
FreeH(hpgtbT);
|
||
}
|
||
(**hpdocdod)[docUndo].hpgtb = hpgtb;
|
||
vdocPageCache = docNil;
|
||
break;
|
||
case uacFormatSection:
|
||
pdod = &(**hpdocdod)[vuab.doc];
|
||
pdodUndo = &(**hpdocdod)[docUndo];
|
||
hsep = pdod->hsep;
|
||
pdod->hsep = pdodUndo->hsep;
|
||
pdodUndo->hsep = hsep;
|
||
hpgtb = pdod->hpgtb;
|
||
pdod->hpgtb = pdodUndo->hpgtb;
|
||
pdodUndo->hpgtb = hpgtb;
|
||
/* idstrUndoBase = (idstrUndoBase == IDSTRUndoRedo) ? IDSTRUndoBase :*/
|
||
/* IDSTRUndoRedo;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
vdocSectCache = vdocPageCache = docMode = docNil;
|
||
TrashAllWws();
|
||
break;
|
||
case uacRulerChange:
|
||
ReplaceCps(docUndo, vuab.dcp2, cp0, vuab.doc, vuab.cp, vuab.dcp);
|
||
ReplaceCps(vuab.doc, vuab.cp, vuab.dcp, docUndo, cp0, vuab.dcp2);
|
||
Replace(docUndo, cp0, vuab.dcp2, fnNil, fc0, fc0);
|
||
dcpT = vuab.dcp;
|
||
vuab.dcp = vuab.dcp2;
|
||
vuab.dcp2 = dcpT;
|
||
|
||
/* This is a kludge to indicate that this is an undone ruler change.
|
||
*/
|
||
vuab.itxb = 1 - vuab.itxb;
|
||
case uacFormatTabs:
|
||
pdod = &(**hpdocdod)[vuab.doc];
|
||
pdodUndo = &(**hpdocdod)[docUndo];
|
||
hgtbd = pdod->hgtbd;
|
||
pdod->hgtbd = pdodUndo->hgtbd;
|
||
pdodUndo->hgtbd = hgtbd;
|
||
/* idstrUndoBase = (idstrUndoBase == IDSTRUndoRedo) ? IDSTRUndoBase :*/
|
||
/* IDSTRUndoRedo;*/
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
TrashAllWws();
|
||
break;
|
||
#endif /* not CASHMERE */
|
||
|
||
#if UPDATE_UNDO
|
||
#if defined(OLE)
|
||
case uacObjUpdate:
|
||
case uacUObjUpdate:
|
||
ObjDoUpdateUndo(vuab.doc,vuab.cp);
|
||
if (uac == uacObjUpdate)
|
||
{
|
||
vuab.uac = uacUObjUpdate;
|
||
SetUndoMenuStr(IDSTRUndoBase);
|
||
}
|
||
break;
|
||
#endif
|
||
#endif
|
||
}
|
||
if (ferror)
|
||
NoUndo();
|
||
pdod = &(**hpdocdod)[vuab.doc];
|
||
pdodUndo = &(**hpdocdod)[docUndo];
|
||
f = pdod->fDirty;
|
||
pdod->fDirty = pdodUndo->fDirty;
|
||
pdodUndo->fDirty = f;
|
||
f = pdod->fFormatted;
|
||
pdod->fFormatted = pdodUndo->fFormatted;
|
||
pdodUndo->fFormatted = f;
|
||
|
||
#ifdef CASHMERE
|
||
if (uac != uacMove
|
||
#else /* not CASHMERE */
|
||
if (uac != uacMove && uac != uacFormatTabs && uac != uacFormatSection &&
|
||
uac != uacRulerChange
|
||
#endif /* not CASHMERE */
|
||
|
||
&& docCur != docNil && vuab.doc == docCur && vuab.cp >= cpMinCur &&
|
||
vuab.cp + dcpT <= cpMacCur)
|
||
{
|
||
if (uac == uacPictSel)
|
||
{
|
||
Select(vuab.cp, CpLimSty(vuab.cp, styPara));
|
||
vfPictSel = true;
|
||
}
|
||
else
|
||
#ifdef BOGUS
|
||
Select( vuab.cp,
|
||
(dcpT == cp0) ? CpLastStyChar( vuab.cp ) :
|
||
vuab.cp + dcpT );
|
||
#endif
|
||
Select( vuab.cp, vuab.cp + dcpT );
|
||
vfSeeSel = true;
|
||
}
|
||
}
|
||
|
||
|
||
BOOL near FCopyPgtb(doc, phpgtb)
|
||
int doc;
|
||
struct PGTB ***phpgtb;
|
||
{
|
||
/* This sets *phpgtb to a copy of the page table associated with doc. FALSE
|
||
is returned iff an error occurs in creating the copy of the page table. */
|
||
|
||
struct PGTB **hpgtbT;
|
||
|
||
if ((hpgtbT = (**hpdocdod)[doc].hpgtb) == NULL)
|
||
{
|
||
*phpgtb = NULL;
|
||
}
|
||
else
|
||
{
|
||
int cwpgtb = cwPgtbBase + (**hpgtbT).cpgdMax * cwPGD;
|
||
|
||
if (FNoHeap(*phpgtb = (struct PGTB **)HAllocate(cwpgtb)))
|
||
{
|
||
return (FALSE);
|
||
}
|
||
blt(*hpgtbT, **phpgtb, cwpgtb);
|
||
}
|
||
return (TRUE);
|
||
}
|
||
|
||
|
||
#ifdef CASHMERE /* No Repeat-last-command in MEMO */
|
||
CmdAgain()
|
||
{ /* use the undo action block to repeat a command */
|
||
int uac;
|
||
typeCP dcpT;
|
||
typeCP cpFirst;
|
||
typeCP cpLim;
|
||
typeCP dcp;
|
||
struct DOD *pdod, *pdodUndo;
|
||
|
||
/* First check error conditions; this may change selCur */
|
||
switch (uac = vuab.uac)
|
||
{
|
||
case uacReplBuf:
|
||
case uacUReplBuf:
|
||
case uacDelBuf:
|
||
case uacUDelBuf:
|
||
case uacUDelNS:
|
||
case uacDelNS:
|
||
case uacUDelScrap:
|
||
case uacDelScrap:
|
||
case uacUReplNS:
|
||
case uacOvertype:
|
||
case uacReplNS:
|
||
case uacReplGlobal:
|
||
case uacReplScrap:
|
||
case uacUReplScrap:
|
||
/* Ensure OK to delete here */
|
||
if (!FWriteOk(fwcDelete))
|
||
return;
|
||
break;
|
||
case uacUCopyBuf:
|
||
case uacCopyBuf:
|
||
if (false)
|
||
return;
|
||
break;
|
||
case uacUInsert:
|
||
case uacInsert:
|
||
if (!FWriteOk(fwcInsert))
|
||
return;
|
||
break;
|
||
case uacMove:
|
||
/* Ensure OK to edit here */
|
||
if (!FWriteOk(fwcInsert))
|
||
return;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
/* Now set up cp's and dispatch */
|
||
cpFirst = selCur.cpFirst;
|
||
cpLim = selCur.cpLim;
|
||
dcp = cpLim - cpFirst;
|
||
switch (uac = vuab.uac)
|
||
{
|
||
struct TXB *ptxb;
|
||
default:
|
||
/* case uacNil: */
|
||
_beep();
|
||
return;
|
||
#ifdef ENABLE /* NO GLOSSARY IN MEMO */
|
||
case uacReplBuf:
|
||
case uacUReplBuf:
|
||
case uacDelBuf:
|
||
case uacUDelBuf:
|
||
case uacUCopyBuf:
|
||
case uacCopyBuf:
|
||
DoAgainTxb(dcp, cpFirst);
|
||
break;
|
||
#endif /* ENABLE */
|
||
case uacUInsert:
|
||
ReplaceCps(docCur, cpFirst, cp0, docUndo, cp0, vuab.dcp);
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
Select(cpFirst+vuab.dcp, CpLastStyChar(cpFirst+vuab.dcp));
|
||
vuab.uac = uacInsert;
|
||
break;
|
||
case uacInsert:
|
||
ClobberDoc(docUndo, vuab.doc, vuab.cp, vuab.dcp);
|
||
ReplaceCps(docCur, cpFirst, cp0, docUndo, cp0, vuab.dcp);
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
Select(cpFirst+vuab.dcp, CpLastStyChar(cpFirst+vuab.dcp));
|
||
break;
|
||
case uacUDelNS:
|
||
case uacDelNS:
|
||
ClobberDoc(docUndo, docCur, cpFirst, dcp);
|
||
Replace(docCur, cpFirst, dcp, fnNil, fc0, fc0);
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
vuab.dcp = dcp;
|
||
vuab.uac = uacDelNS;
|
||
Select(cpFirst,CpLastStyChar(cpFirst));
|
||
break;
|
||
case uacUDelScrap:
|
||
case uacDelScrap:
|
||
ClobberDoc(docUndo,docScrap,cp0,CpMacText(docScrap));
|
||
ClobberDoc(docScrap, docCur, cpFirst, dcp);
|
||
Replace(docCur, cpFirst, dcp, fnNil, fc0, fc0);
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
vuab.dcp = dcp;
|
||
vuab.uac = uacDelScrap;
|
||
Select(cpFirst, CpLastStyChar(cpFirst));
|
||
break;
|
||
case uacUReplNS:
|
||
vuab.dcp2 = vuab.dcp;
|
||
ReplaceCps(docCur, cpLim, cp0, docUndo, cp0,
|
||
vuab.dcp = CpMacText(docUndo));
|
||
ClobberDoc(docUndo, docCur, cpFirst, dcp);
|
||
Replace(docCur, cpFirst, dcp, fnNil, fc0, fc0);
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
Select(cpFirst+vuab.dcp, CpLastStyChar(cpFirst + vuab.dcp));
|
||
vuab.uac = uacReplNS;
|
||
break;
|
||
case uacOvertype:
|
||
/* for this one vuab.cp2 is the DCP of how much was actually
|
||
inserted */
|
||
vuab.dcp = vuab.cp2;
|
||
/* fall through...*/
|
||
case uacReplNS:
|
||
ClobberDoc(docUndo, vuab.doc, vuab.cp, vuab.dcp);
|
||
ReplaceCps(docCur, cpLim, cp0, docUndo, cp0, vuab.dcp);
|
||
ClobberDoc(docUndo, docCur, cpFirst, dcp);
|
||
Replace(docCur, cpFirst, dcp, fnNil, fc0, fc0);
|
||
dcpT = vuab.dcp;
|
||
vuab.dcp2 = dcp;
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
vuab.uac = uacReplNS;
|
||
if (ferror) /* the operation (cmd "a") could not be completed
|
||
due to out of memory */
|
||
NoUndo();
|
||
else
|
||
Select(cpFirst+vuab.dcp, CpLastStyChar(cpFirst + dcpT));
|
||
break;
|
||
case uacChLook:
|
||
case uacChLookSect:
|
||
#ifdef ENABLE /* ChLook stuff is not hooked up yet */
|
||
|
||
DoChLook(chAgain,0);
|
||
#endif
|
||
break;
|
||
case uacReplGlobal:
|
||
ClobberDoc(docUndo, docCur, cpFirst, dcp);
|
||
Replace(docCur, cpFirst, dcp, fnNil, fc0, fc0);
|
||
vuab.dcp2 = dcp;
|
||
dcp = (typeCP)(CchSz(**hszReplace) - 1);
|
||
InsertRgch(docCur, cpFirst, **hszReplace, dcp, 0, 0);
|
||
vuab.dcp = dcp;
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
Select(cpFirst+vuab.dcp, CpLastStyChar(cpFirst + vuab.dcp));
|
||
vuab.uac = uacReplNS;
|
||
break;
|
||
case uacReplScrap:
|
||
ClobberDoc(docUndo, vuab.doc, vuab.cp, vuab.dcp);
|
||
ReplaceCps(docCur, cpLim, cp0, docUndo, cp0, vuab.dcp);
|
||
ClobberDoc(docUndo,docScrap,cp0,CpMacText(docScrap));
|
||
ClobberDoc(docScrap, docCur, cpFirst, dcp);
|
||
Replace(docCur, cpFirst, dcp, fnNil, fc0, fc0);
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
Select(cpFirst+vuab.dcp, CpLastStyChar(cpFirst + vuab.dcp));
|
||
break;
|
||
#ifdef ENABLE /* Not used in SAND */
|
||
case uacFormatCStyle:
|
||
DoFormatCStyle(rgvalAgain);
|
||
break;
|
||
case uacFormatPStyle:
|
||
DoFormatPStyle(rgvalAgain);
|
||
break;
|
||
case uacFormatSStyle:
|
||
DoFormatSStyle(rgvalAgain);
|
||
break;
|
||
#endif /* ENABLE */
|
||
#ifdef ENABLE /* Not hooked up yet */
|
||
case uacLookCharMouse:
|
||
AgainLookCharMouse();
|
||
break;
|
||
case uacLookParaMouse:
|
||
AgainLookParaMouse();
|
||
break;
|
||
#endif /* ENABLE */
|
||
#ifdef ENABLE /* Not used in SAND */
|
||
case uacClearTab:
|
||
DoClearTab(true);
|
||
vuab.uac = uac;
|
||
break;
|
||
case uacClearAllTab:
|
||
CmdClearAllTab();
|
||
vuab.uac = uac;
|
||
break;
|
||
#endif /* ENABLE */
|
||
#ifdef ENABLE /* Formatting menu stuff is not hooked up yet */
|
||
case uacFormatTabs:
|
||
DoFormatTabs(true);
|
||
vuab.uac = uac;
|
||
break;
|
||
case uacFormatRHText:
|
||
DoFormatRHText(rgvalAgain);
|
||
break;
|
||
case uacFormatChar:
|
||
DoFormatChar(rgvalAgain);
|
||
break;
|
||
case uacFormatPara:
|
||
DoFormatPara(rgvalAgain);
|
||
break;
|
||
case uacFormatSection:
|
||
DoFormatSection(rgvalAgain);
|
||
break;
|
||
#endif /* ENABLE */
|
||
#ifdef STYLES
|
||
case uacGalFormatChar:
|
||
DoGalFormatChar(rgvalAgain);
|
||
break;
|
||
case uacGalFormatPara:
|
||
DoGalFormatPara(rgvalAgain);
|
||
break;
|
||
case uacGalFormatSection:
|
||
DoGalFormatSection(rgvalAgain);
|
||
break;
|
||
#endif /* STYLES */
|
||
case uacUReplScrap:
|
||
ReplaceCps(docCur, cpLim, cp0, docUndo, cp0,
|
||
vuab.dcp = CpMacText(docUndo));
|
||
ClobberDoc(docUndo,docScrap,cp0,CpMacText(docScrap));
|
||
ClobberDoc(docScrap, docCur, cpFirst, dcp);
|
||
Replace(docCur, cpFirst, dcp, fnNil, fc0, fc0);
|
||
vuab.doc = docCur;
|
||
vuab.cp = cpFirst;
|
||
Select(cpFirst+vuab.dcp, CpLastStyChar(cpFirst + vuab.dcp));
|
||
vuab.uac = uacReplScrap;
|
||
break;
|
||
case uacMove:
|
||
if (!FMoveText(vuab.doc2, vuab.cp2, vuab.dcp, docCur, &cpFirst, fFalse))
|
||
return;
|
||
vuab.cp = vuab.cp2;
|
||
vuab.cp2 = cpFirst;
|
||
vuab.doc = vuab.doc2;
|
||
vuab.doc2 = docCur;
|
||
CheckMove();
|
||
break;
|
||
}
|
||
vfSeeSel = true;
|
||
}
|
||
#endif /* CASHMERE */
|
||
|
||
|