home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-22 | 49.6 KB | 1,705 lines | [TEXT/MPS ] |
- /*
- File: DraftWn.cpp
-
- Contains: Implementation of the DraftWin and DraftInfoRec classes
-
- Owned by: Eric House
-
- Copyright: © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <53> 11/2/95 eeh 1282521: save and restore port in ::Drafts
- <52> 10/18/95 eeh 1293420: wrap TRY around callbacks
- <51> 4/10/95 NP 1287722: Change signature of
- ODSession::GetUserName.
- <50> 9/29/95 eeh 1287262: fix constant
- <49> 9/13/95 TÇ 1249149 FB2: Memory leak/crash fixes
- <48> 9/12/95 DM 1280020 FB1 part trans dlg mem leaks
- <47> 9/12/95 eeh 1230007: atTopLeft -> atNone
- <46> 9/8/95 TÇ 1252120 FB1: New documents saved w/ StdFile
- & trashed if closed w/o saving
- <45> 9/8/95 TÇ 1281096 FB2:Many constants in ODTypesB
- without kOD prefix!
- <44> 9/8/95 TÇ 1282092 FB2: Shell must check nil after SOM
- new
- <43> 9/7/95 EL 1281410, 1279985: DeleteSelectedDraft will
- close and open the draft above it if it is
- open, and rename all the windows for draft
- above the seletected draft.
- <42> 9/5/95 TÇ FBs: 1266428, 1274419, 1274421, 1274423,
- 1274429, 1274435 Fixed the Shell to handle
- multiple documents in a process. Needed for
- CyberDog.
- <41> 8/25/95 eeh 1230007: cleanup/proofing
- <40> 8/25/95 eeh 1230007: mondo changes (incomplete)
- <39> 8/22/95 eeh 1230007: use tempobjs for exception safety
- <38> 8/16/95 eeh 1248265: close dialog on mousedown not *up
- <37> 8/3/95 eeh 1229960: use CheckKeyScriptChangeFilterProc
- and DialogScriptData
- <36> 7/21/95 eeh 1236744: add CheckDeleteKeyFilterProc;
- 1263063: call SetPlatformClipboard
- <35> 7/18/95 eeh 1222282: deal with enter key etc. in
- DraftDlgFilterProc
- <34> 7/18/95 eeh 1222282 (partial): add DeleteDlgFilterProc,
- arrow keys etc.
- <33> 6/25/95 TÇ 1242642 BB: Turn on ODDebug warning if
- refcount is wrong in
- ODRefCntObjectsomUninit.
- <32> 6/20/95 eeh 1259193: don't return kDraftWinOpen if
- selection empty
- <31> 5/26/95 RR #1251403: Multithreading naming support
- <30> 5/25/95 jpa Fixed 'for' loop for ANSI compliance.
- [1253324] GetScript --> GetScriptVariable.
- [1241078]
- <29> 5/22/95 eeh 1245226: disable non-roman scripts if roman
- text
- <28> 5/20/95 eeh 1245226: call SetupDialogForAppScript
- <27> 5/18/95 eeh 1236414: disable Delete and Save Draft
- buttons for r/o files
- <26> 5/12/95 eeh 1239830: call ODHaveFreeSpace
- <25> 5/10/95 eeh 1215536: remove DraftInfoRec representing
- current draft
- <24> 5/4/95 eeh 1232095: factor out DeleteSelectedDraft
- <23> 5/1/95 TÇ 1234420 StdTypIO functions should not
- return default values
- <22> 4/24/95 eeh 1228013: always draw vertical scroll bar
- <21> 4/14/95 TÇ #1235279 BB: InfoUtil & StdTypIO functions
- should take Environment* and SU* when
- possible
- <20> 4/10/95 EL 1215536: creation date of draft should be
- creation date of next draft property.
- 1236414: There is no temporary draft for
- read only document.
- <19> 4/7/95 EL Use ODGetTime_TProp for document exchange.
- <18> 4/7/95 eeh 1236464: TRY around document->AcquireDraft
- <17> 3/24/95 eeh 1229961, 1215528: change callbacks to use
- IText*
- <16> 3/15/95 eeh 1193824: move drawing routines to
- useritemproc
- <15> 3/8/95 eeh 1180986: setwtitle -> SetWTitle
- <14> 3/6/95 jpa Use dialog utilities (ODGetNewDialog,
- ODDialogFilterProc) to make dlogs movable.
- [1218957] Also don't leave rsrc fork
- active.
- <13> 2/20/95 TÇ #1210979 BB: 5-$ Bugs need to be evaluated
- and removed from Shell
- <12> 1/26/95 eeh 1214080: OpenDoc really uses kODMacIText,
- not kODIntlText.
- <11> 1/12/95 jpa Don't use obsolete Toolbox names. [1211211]
- <10> 12/20/94 VL 1195012: Make Storage calls be
- marshallable.
- <9> 12/19/94 eeh 1192626: remove "current" draft; fix button
- hiliting; nuke horizontal scroll bar, etc.
- <8> 9/26/94 TÇ #1188566 Removing Drafts
- <7> 9/23/94 VL 1155579, 1184272: Use StorUtil to
- create/get container and its file.
- <6> 8/29/94 TÇ #1183567 StdTypIO routine implementation &
- fixup
- <5> 8/12/94 NP 1180762-Correct usage of GetUserName.
- Correctly dipose of IText after using.
- <4> 7/27/94 eeh use ODSetITextProp and ODGetITextProp
- (fixed Draft dialog garbage)
- <3> 7/23/94 TÇ #include "DraftWLD.h"
- <2> 7/18/94 TÇ changed include of PtFrInfo.h to StTypIO.h
- <1> 6/27/94 TÇ first checked in
- <0> 6/27/94 SV SOMverted
- <10> 5/10/94 TÇ #1162405 Removed explicit ASLM dependency
- for using resources
- <9> 5/9/94 MB #1162181: Changes necessary to install MMM.
- <8> 5/3/94 eeh bug #1155857: incorporate LDEF; remove
- hard-coded number limits
- <7> 4/1/94 TÇ #1154941: Get OpenDoc source to actually
- compile for PowerPC
- <6> 3/31/94 eeh bug #1153999: use XMPG/SetITextProp,
- different PStrToIntl.
- <5> 3/28/94 CG 1153547: Use new method
- ODSession::GetUserName instead of
- calling system directly.
- <4> 3/24/94 eeh bug #1153053: Changes for PPC nativity (or
- is it nativeness...?)
- <3> 3/18/94 CC Value type of user property changed from
- kXMPAppleTEXT to kODASCIIText (but should
- be international text!). (1151636)
- <2> 3/1/94 JA Made local fns static.
- <12> 2/7/94 JA Utilities.h --> XMPUtils.h
- <11> 2/7/94 TÇ more fixes to compile with PPC Headers
- <10> 2/4/94 TÇ fixes to compile with PPC Universal headers
- <9> 1/28/94 TÇ bug fixes & implemented double click = open
- <8> 1/25/94 NP TÇ: implemented
- <7> 1/20/94 TÇ got rid of warnings
- <6> 1/14/94 TÇ added skeleton code from HI to show dialogs
- <5> 1/13/94 TÇ reworked and added some code for latest
- round of HI changes
- <3> 8/24/93 TÇ removed code made obsolete by HI Changes
- <2> 8/19/93 TÇ fixed some stuff
- <1> 7/14/93 TÇ first checked in
-
- To Do:
- In Progress:
-
- */
-
-
- #ifndef _DRAFTWLD_
- #include "DraftWLD.h"
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef _DRAFTWN_
- #include "DraftWn.h"
- #endif
-
- #ifndef _TEMPOBJ_
- #include "TempObj.h"
- #endif
-
- #ifndef _USERSRCM_
- #include <UseRsrcM.h>
- #endif
-
- #ifndef SOM_ODDocument_xh
- #include <Document.xh>
- #endif
-
- #ifndef SOM_ODContainer_xh
- #include <ODCtr.xh>
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- #ifndef SOM_ODWindowIterator_xh
- #include <WinIter.xh>
- #endif
-
- #ifndef SOM_ODWindow_xh
- #include <Window.xh>
- #endif
-
- #ifndef _DOCUTILS_
- #include <DocUtils.h>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODClipboard_xh
- #include <Clipbd.xh>
- #endif
-
- #ifndef SOM_ODStorageUnitView_xh
- #include <SUView.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef _ODMEMORY_
- #include <ODMemory.h>
- #endif
-
- #ifndef _PLFMFILE_
- #include <PlfmFile.h>
- #endif
-
- #ifndef _DLOGUTIL_
- #include <DlogUtil.h>
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef __TIME_H__
- #include <Time.h>
- #endif
-
- #ifndef _PASCLSTR_
- #include <PasclStr.h>
- #endif
-
- #ifndef _ISOSTR_
- #include <ISOStr.h>
- #endif
-
- #ifndef _ITEXT_
- #include <IText.h>
- #endif
-
- #ifndef __SCRIPT__
- #include <script.h>
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __LISTS__
- #include <Lists.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifdef __SC__
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
- #else
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
- #endif
-
- #ifndef __ICONS__
- #include <Icons.h>
- #endif
-
- #ifndef _ODMEMORY_
- #include <ODMemory.h>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef _STDTYPIO_
- #include <StdTypIO.h>
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #pragma segment DraftWindow
-
- //==============================================================================
- // Constants
- //==============================================================================
-
- #define tenPt 10
- #define kNoExpandClick -1
- #define kNoRowHilited -1
-
-
- #define no_ictb_exists false /* try using an ictb resource instead of code */
-
- #define kXMPNewLineChar '\n'
-
- #define kDraftsActiveControl 0
-
- // macros for passing info about default button behavior. Currently involves
- // setting the low-order bit in the listhandle, which on the mac *should*
- // always be clear. A cleaner implementation might be advised....
-
- #define CREATEISSET(self) (((DraftWindow*)(self))->CreateIsSet())
- #define GETLISTHANDLE(self) (((DraftWindow*)(self))->GetListHandle())
- #define GETLISTRECT(self, rectPtr) \
- (((DraftWindow*)(self))->GetListRect((rectPtr)))
- #define SETREADYTOCLOSE(self) \
- (((DraftWindow*)(self))->SetReadyToClose(kODTrue))
- #define CLEARREADYTOCLOSE(self) \
- (((DraftWindow*)(self))->SetReadyToClose(kODFalse))
- #define READYTOCLOSESET(self) \
- (((DraftWindow*)(self))->ReadyToClose())
- #define kNumColumns 4
- #define kCommentsColumnIndex 3
-
- const short kControlActive = 0;
-
- //==============================================================================
- // Scalar Types
- //==============================================================================
-
- //==============================================================================
- // Local Classes
- //==============================================================================
-
- //==============================================================================
- // Function Prototypes
- //==============================================================================
-
- static void DrawDWUserStrings( struct DraftLDEFCallbackInfo *callbackInfo,
- ODSShort row, const Rect* listItemRect );
- static DraftInfoRec* GetNthRow( DraftInfoRec* from, short whichRow );
- static void ContractList( FullDraftInfoRec* dir, ListHandle listH, short parentRowNum );
- static void ExpandList( FullDraftInfoRec* dir, ListHandle listH, DialogPtr dialog,
- short parentRowNum );
- static void AddRows( ListHandle listH, short startIndex, short numToAdd );
- static FullDraftInfoRec* FirstSelectedRow( DraftInfoRec* from );
- static TEHandle ITextToTERec( ODIText* iText, Rect* bothRects );
- static pascal void DrawBlackBoxItem(DialogPtr dlog, short theItem);
- static pascal ODBoolean CheckDeleteKeyFilterProc( DialogPtr dialog, EventRecord *event,
- short *itemHit);
- static pascal ODBoolean CheckKeyScriptFirstFilterProc( DialogPtr dialog, EventRecord *event,
- short *itemHit);
- static pascal ODBoolean DraftDlgFilterProc( DialogPtr dialog, EventRecord *event,
- short *itemHit );
- static void SetButtonStates( DialogPtr dlog, ODBoolean hasWriteAccess,
- Boolean hasContent );
- static void SetRows( DraftInfoRec* dir, short startRow, ODBoolean newValue,
- ListHandle listH );
-
- //==============================================================================
- // DraftWindow
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // Creation
- //------------------------------------------------------------------------------
-
- DraftWindow::DraftWindow()
- {
- fDraft = kODNULL;
- fDocument = kODNULL;
- fDraftInfo = kODNULL;
- fSelectedDraft = kODNULL;
- fSelectedDraftNumber = 0;
- // fExpandClickRow = kNoExpandClick;
- // fHilitedRow = kODNULL; // clear in Drafts() instead.
- }
-
- void DraftWindow::InitDraftWindow(Environment* ev, ODDraft* draft)
- {
- fDraft = draft;
- fDocument = draft->GetDocument(ev);
- fListH = kODNULL;
- fCreateSet = kODFalse;
- fReadyToClose = kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // Destruction
- //------------------------------------------------------------------------------
-
- DraftWindow::~DraftWindow()
- {
- ODReleaseObject(somGetGlobalEnvironment(),fSelectedDraft);
- // dispose of DraftInfoRecs and collection
- ODDeleteObject(fDraftInfo);
- }
-
-
- //------------------------------------------------------------------------------
- // Dialog
- //------------------------------------------------------------------------------
-
- ListHandle DraftWindow::MakeAList(DialogPtr dlg, ODSShort* numLines,
- long refcon )
- {
- Rect itemRect, boundsRect;
- Handle itemH;
- short scratchKind;
-
- /* create a scrolling list */
-
- GetDialogItem(dlg, kDraftsListUserItem, &scratchKind, &itemH, &itemRect);
- itemRect.top -= 1;
- itemRect.left -= 1;
- SetRect(&boundsRect, 0, 0, 1, 0); /* one column list, 0 row count for now */
-
- FontInfo scriptAppFontInfo;
- GetFontInfo(&scriptAppFontInfo);
- ODSShort cellHeight = scriptAppFontInfo.ascent +
- scriptAppFontInfo.descent + scriptAppFontInfo.leading;
- *numLines = (itemRect.bottom - itemRect.top) / cellHeight;
-
- fListRect = itemRect;
- fListRect.bottom -= 1;
- itemRect.right -= 15;
-
- InsetRect(&itemRect, 1, 1); /* leave room for the frame */
-
- /* use the Application Font for the list items (cell size) */
- long scriptAppFontSize = GetScriptVariable(smSystemScript,smScriptAppFondSize);
- TextFont(HiWord(scriptAppFontSize));
- TextSize(LoWord(scriptAppFontSize)); /* make look larger; icons will force this to be right once they're added */
-
- (LoWord(scriptAppFontSize) < tenPt) ? TextSize(tenPt) : TextSize(LoWord(scriptAppFontSize));
-
- Point cellSize;
- SetPt(&cellSize, 500, cellHeight);
-
- /* now get the real desired font size */
- long scriptSmallFontSize = GetScriptVariable(smSystemScript,smScriptSmallFondSize);
- (LoWord(scriptSmallFontSize) < tenPt) ? TextSize(tenPt) : TextSize(LoWord(scriptSmallFontSize));
-
- Handle myHandle;
- ListHandle listH;
- { CUsingLibraryResources r;
- myHandle = Get1Resource('LDEF',kDraftWinLDEFID);
- THROW_IF_NULL(myHandle);
- ListDefUPP LDEFUPP = NewListDefProc(DRAFTWINDOWLDEF);
- (*(ListDefUPP*)&((*myHandle)[kDraftWinLDEFAddrOffset])) = LDEFUPP;
- /* This above code written from suggestion in NIM:PPC System Software 1-35,1-36 */
-
- listH = LNew(&itemRect, &boundsRect, cellSize, kDraftWinLDEFID, dlg,
- kODFalse, kODFalse, kODFalse, kODTrue);
- }
-
- if (listH != nil)
- { /* list was created */
- (*listH)->refCon = refcon ;
- /* resize list rectangle to only display whole cells */
- itemRect.bottom -= (((short) (itemRect.bottom - itemRect.top)) % cellSize.v);
- LSize(itemRect.right - itemRect.left, itemRect.bottom - itemRect.top, listH);
- itemRect.right += 15; /* add room for scroll bar */
- SetDialogItem(dlg, kDraftsListUserItem, scratchKind, itemH, &itemRect);
-
- // (*listH)->selFlags = lNoNilHilite;
- // (*listH)->selFlags = (lOnlyOne | lNoNilHilite);
-
- LSetDrawingMode(kODFalse, listH);
-
- LDelRow(0, 0, listH); /* delete everything in the list */
- AddRows( listH, 0, this->CountDrafts() );
-
- LAutoScroll(listH);
- LUpdate(dlg->visRgn, listH);
- (*listH)->lastClick = *(Cell*)0L;
- if ( fDraftInfo )
- this->SetHilite( fDraftInfo, 0 );
- // LSetDrawingMode(kODTrue, listH);
- }
- return listH;
- } // DraftWindow::MakeAList
-
- #if ODDebug
- void DraftWindow::CheckConsistency()
- {
- if ( !fDraftInfo )
- return;
-
- DraftInfoRec* dir = fDraftInfo;
- short fullEntryCount = 0;
- short dummyEntryCount = 0;
- FullDraftInfoRec* fdir = kODNULL;
- WASSERT( dir->GetComment() );
- ODBoolean somethingExpanded = kODFalse;
- ODBoolean foundHilite = kODFalse;
- while ( dir )
- {
- if ( dir->GetDIRType() == kDIRTypeFull )
- {
- ++fullEntryCount;
- fdir = (FullDraftInfoRec*)dir;
- if ( fdir->ShouldHilite() )
- {
- WASSERT( !foundHilite );
- foundHilite = kODTrue;
- }
- if ( fdir->IsExpanded() )
- {
- somethingExpanded = kODTrue;
- WASSERT( fdir->GetCachedComment() != kODNULL );
- WASSERT( fdir->GetComment() != kODNULL );
- WASSERT( fdir->Next() != kODNULL );
- WASSERT( fdir->Next()->GetDIRType() != kDIRTypeFull );
- }
- else
- {
- WASSERT( fdir->GetCachedComment() == kODNULL );
- WASSERT( fdir->GetComment() != kODNULL );
- }
- }
- else
- {
- ++dummyEntryCount;
- DummyDraftInfoRec* ddir = (DummyDraftInfoRec*)dir;
- WASSERT( ddir->GetCommentOwner() );
- WASSERT( ddir->GetCommentOwner() == fdir );
- WASSERT( ddir->ShouldHilite() == fdir->ShouldHilite() );
- }
- dir = dir->Next();
- }
- if ( !somethingExpanded )
- WASSERT( fullEntryCount == (*fListH)->dataBounds.bottom);
- else
- WASSERT( fullEntryCount+dummyEntryCount == (*fListH)->dataBounds.bottom);
- WASSERT( foundHilite );
- WASSERT( fullEntryCount == this->CountDrafts() );
- }
- #endif
-
- DraftWinAction DraftWindow::Drafts(Environment* ev, ODDraft* draft,
- DraftWinAction prevAction, ODBoolean hasWriteAccess )
- {
- // show the dialog/create the window and modally respond
- // to events until dismissed
-
- short itemKind,itemHit;
- Rect scratchRect;
- Handle scratchHandle;
-
- // worst case app heap memory usage between here and when the
- // delete confirmation draft is up is 6448 bytes. So I'm
- // padding to 10000 to be safe.
- // <eeh> need to reconsider now that comments expand?
-
- if ( !ODHaveFreeSpace( 10000, 0, kODTrue) )
- return kDraftWinLowMemAbort;
-
- if ( draft != kODNULL )
- fDraft = draft;
-
- /// read and construct DraftInfo
- fHilitedRow = kODNULL; // clear this each time reopen dialog
- fDraftInfo = this->InternalizeHistory(ev);
-
- GrafPort* savePort;
- GetPort(&savePort);
-
- TempODStorageUnit draftProps = fDraft->AcquireDraftProperties(ev);
- ODSession *session = draftProps->GetSession(ev);
- DialogPtr dlg;
- {CUsingLibraryResources r;
- dlg = ODGetNewDialog(ev,kDraftsDlgID,session,kODFalse);
- }
- THROW_IF_NULL(dlg);
- SetPort(dlg);
-
- PlatformFile* file = GetPlatformFileFromContainer(ev,
- fDraft->GetDocument(ev)->GetContainer(ev));
- Str255 dWinName;
- ODName* fileName = file->GetName();
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
- // DMc: ensure that string is deleted:
- TempODString tempString = (char*) GetITextString(fileName, (StringPtr)kODNULL);
- ConstStr255Param csp = (ConstStr255Param) (char*) tempString;
- ReplaceIntoString( kDraftsWnTitleResID,
- csp, kODNULL,
- dWinName);
- EndUsingLibraryResources(savedRefNum);
- DisposeIText(fileName);
-
- SetWTitle(dlg,(StringPtr)dWinName);
- ODDeleteObject(file);
-
- DialogPeek dlgPeek;
- #if no_ictb_exists
- /* use the script's small font for the static text */
- scriptSmallFontSize = GetScript(smSystemScript,smScriptSmallFondSize);
- TextFont(HiWord(scriptSmallFontSize));
- (LoWord(scriptSmallFontSize) < tenPt) ?
- TextSize(tenPt) : TextSize(LoWord(scriptSmallFontSize));
- TextFace(bold);
-
- /* WARNING: remember to set the font, face and size for update events */
- dlgPeek = (DialogPeek) dlg;
- (**(dlgPeek->textH)).txFont = HiWord(scriptSmallFontSize);
- if (((**(dlgPeek->textH)).txSize = LoWord(scriptSmallFontSize)) < tenPt)
- (**(dlgPeek->textH)).txSize = tenPt;
- // (**(dlgPeek->textH)).txFace = bold;
- #endif
-
- UserItemUPP drawBoxItemUPP; // dialogs.h
- drawBoxItemUPP = NewUserItemProc(DrawBlackBoxItem);
-
- /* A horizontal line needs to be drawn above the list rectangle */
- GetDialogItem(dlg, kDraftsHorizRectUserItem, &itemKind,
- &scratchHandle, &scratchRect);
- SetDialogItem(dlg, kDraftsHorizRectUserItem, itemKind,
- (Handle)drawBoxItemUPP, &scratchRect);
-
- /* A rectangle needs to be drawn around the list column titles */
- GetDialogItem(dlg, kDraftsHeaderRectUserItem, &itemKind,
- &scratchHandle, &scratchRect);
- SetDialogItem(dlg, kDraftsHeaderRectUserItem, itemKind,
- (Handle)drawBoxItemUPP, &scratchRect);
-
- if ( hasWriteAccess )
- {
- GetDialogItem(dlg, kDraftsCreateUserItem, &itemKind,
- &scratchHandle, &scratchRect);
- SetDialogItem(dlg, kDraftsCreateUserItem, itemKind,
- (Handle)drawBoxItemUPP, &scratchRect);
- }
- else // set up to draw box around create button
- {
- GetDialogItem(dlg, kDraftsCreateBtn, &itemKind, &scratchHandle,
- &scratchRect);
- HiliteControl( (ControlHandle)scratchHandle, 255 ); // disable create
- }
-
- GetDialogItem(dlg, kDraftsDoneUserItem, &itemKind,
- &scratchHandle, &scratchRect);
- SetDialogItem(dlg, kDraftsDoneUserItem, itemKind,
- (Handle)drawBoxItemUPP, &scratchRect);
-
- GetDialogItem(dlg, kDraftsListUserItem, &itemKind,
- &scratchHandle, &scratchRect);
- SetDialogItem(dlg, kDraftsListUserItem, itemKind,
- (Handle)drawBoxItemUPP, &scratchRect);
-
- /* create a scrolling list of draft information */
- DraftLDEFCallbackInfo hc ;
- hc.dialog = dlg;
- hc.dir = fDraftInfo ;
- hc.stringsProc = DrawDWUserStrings ;
-
-
- GetDialogItem(dlg, kDraftsCreatorStaticTxt, &itemKind, &scratchHandle,
- &scratchRect);
- hc.rectEnds[0].right = scratchRect.right;
- hc.rectEnds[0].left = scratchRect.left;
- GetDialogItem(dlg, kDraftsDraftStaticTxt, &itemKind, &scratchHandle,
- &scratchRect);
- hc.rectEnds[1].right = scratchRect.right;
- hc.rectEnds[1].left = scratchRect.left;
- GetDialogItem(dlg, kDraftsCreatedStaticTxt, &itemKind, &scratchHandle,
- &scratchRect);
- hc.rectEnds[2].right = scratchRect.right;
- hc.rectEnds[2].left = scratchRect.left;
- GetDialogItem(dlg, kDraftsCommentStaticTxt, &itemKind, &scratchHandle,
- &scratchRect);
- hc.rectEnds[3].right = scratchRect.right;
- hc.rectEnds[3].left = scratchRect.left;
-
- GetDialogItem(dlg, kDraftsArrowStaticTxt, &itemKind, &scratchHandle,
- &scratchRect);
- hc.arrowEnds.right = scratchRect.right;
- hc.arrowEnds.left = scratchRect.left;
-
- fCreateSet = (prevAction == kDraftWinNone) && hasWriteAccess;
-
- session->GetClipboard(ev)->SetPlatformClipboard( ev, kODNULL );
-
- ODSShort numLines;
- ListHandle listH = fListH = this->MakeAList(dlg, &numLines, (long)&hc );
- ((WindowPeek)dlg)->refCon = (long)this;
- dlgPeek = (DialogPeek) dlg;
- UpdateDialog( dlg,(dlgPeek->window).port.visRgn);
- ShowWindow(dlg);
-
- // <eeh> does this work?
- LSetDrawingMode(kODTrue, listH);
-
- DraftWinAction dWinAction = kDraftWinNone;
- ODUseCommandKeyStringsResource( kDraftsCmdKeyStrs );
- ModalFilterUPP modalFilter = NewModalFilterProc(CheckDeleteKeyFilterProc);
- SetButtonStates( dlg, hasWriteAccess, fDraftInfo != kODNULL );
- while (dWinAction == kDraftWinNone)
- {
- #if ODDebug
- this->CheckConsistency();
- #endif
- ODUseCommandKeyStringsResource( kDraftsCmdKeyStrs );
- BeginUsingLibraryResources(savedRefNum); // for the cmd key str#
- ModalDialog( modalFilter, &itemHit );
- EndUsingLibraryResources(savedRefNum);
-
- switch (itemHit)
- {
- case kODUpArrowItem:
- case kODPageUpArrowItem:
- case kODHomeArrowItem:
- case kODDownArrowItem:
- case kODPageDownArrowItem:
- case kODEndArrowItem:
- // ArrowKeyScrollList( itemHit, listH, numLines,
- // this->CountDrafts()-1 );
- break;
-
- case kDraftsDoneBtn:
- dWinAction = kDraftWinDone;
- break;
-
- case kDraftsCreateBtn:
- LActivate(kODFalse,listH);
- if (this->CreateDraft(ev))
- dWinAction = kDraftWinCreate;
- LActivate(kODTrue,listH);
- ShowWindow(dlg);
- break;
-
- case kDraftsListUserItem:
- continue;
-
- case kDraftsDeleteBtn:
- case kDraftsOpenBtn:
- WASSERT( fDraftInfo );
- FullDraftInfoRec* selDraftInfoRec =
- FirstSelectedRow( fDraftInfo );
-
- WASSERT(selDraftInfoRec);
- ODReleaseObject(ev,fSelectedDraft);
- WASSERT(selDraftInfoRec->GetDIRType() == kDIRTypeFull);
- fSelectedDraft = selDraftInfoRec->Draft();
- fSelectedDraft->Acquire(ev);
- fSelectedDraftNumber = selDraftInfoRec->Number();
-
- if (itemHit == kDraftsDeleteBtn)
- {
- LActivate(kODFalse,listH);
- if (this->RemoveSelectedDrafts(ev))
- dWinAction = kDraftWinDelete;
- LActivate(kODTrue,listH);
- ShowWindow(dlg);
- }
- else
- {
- dWinAction = kDraftWinOpen;
- }
- break;
- default:
- break;
- }
- UpdateDialog(dlg,(dlgPeek->window).port.visRgn);
- }
-
- if (listH != kODNULL)
- {
- CUsingLibraryResources r;
- // Release LDEF and the UPP it points to after deleting the list:
- Handle ldef = (**listH).listDefProc;
- LDispose(listH);
- DisposeRoutineDescriptor(
- (*(ListDefUPP*)&((*ldef)[kDraftWinLDEFAddrOffset])) );
- ReleaseResource(ldef);
- }
-
- DisposeRoutineDescriptor(modalFilter);
- DisposeRoutineDescriptor(drawBoxItemUPP);
-
- DisposeDialog(dlg);
- SetPort(savePort);
-
- // dispose of DraftInfoRecs and collection
- ODDeleteObject(fDraftInfo);
-
- if (dWinAction == kDraftWinCreate)
- {
- ODReleaseObject(ev,fSelectedDraft);
- fSelectedDraftNumber = 0;
- }
-
- return dWinAction;
- } // DraftWindow::Drafts
-
- void DraftWindow::DeleteSelectedDraft(Environment* ev, ODSession* session)
- {
- WASSERT(fSelectedDraft);
- if (fSelectedDraft == fDraft)
- ; // can't delete current draft, this shouldn't happen!
- else if (fSelectedDraft->GetRefCount(ev)>1)
- {
- // When the exceptionalert code becomes a utility, call it
- // here. That allow us to not THROW an error, which we don't
- // want to do because there's no code to catch it in places
- // where cleanup must be done.
-
- WARN( "kODErrOutstandingDraft: trying to delete open draft." );
- SysBeep( 2 );
- }
- else
- {
- ODDraft* fromDraft =
- fDocument->AcquireDraft(ev,kODDPReadOnly,kODNULL, /* -- TÇ: $$$$$ Don't know if this is a true leak */
- fSelectedDraft, kODPosFirstAbove,kODFalse);
- ODBoolean openDraftAbove = kODFalse;
- // if draft just above selected draft is open, close and open it again
- // otherwise the window would be pointing to the wrong draft
- ODWindowState* windowState = session->GetWindowState(ev);
- if (windowState->GetRootWindowCount(ev, fromDraft)) {
- ODCloseDraft(ev, session, fromDraft);
- openDraftAbove = kODTrue;
- }
- fDocument->SaveToAPrevDraft(ev,fromDraft,fSelectedDraft);
- fDocument->CollapseDrafts(ev,fromDraft,fSelectedDraft); // Releases fSelectedDraft
-
- // open the selected draft again, this is now what was the draft just above it
- if (openDraftAbove != kODFalse)
- ODOpenDraft(ev, session, fSelectedDraft);
-
- // rename any open window in the drafts above
- TempODDraft topDraft = fDocument->AcquireDraft(ev,kODDPReadOnly,kODNULL,kODNULL,kODPosTop,kODFalse);
- TempODDraft nextDraft = fDocument->AcquireDraft(ev,kODDPReadOnly,kODNULL,
- fSelectedDraft, kODPosFirstAbove,kODFalse);
- while (ODObjectsAreEqual(ev, nextDraft, topDraft) == kODFalse) {
- windowState->SetDefaultWindowTitles(ev, nextDraft);
- nextDraft = fDocument->AcquireDraft(ev,kODDPReadOnly,kODNULL, nextDraft, kODPosFirstAbove,kODTrue);
- }
-
- fSelectedDraft = kODNULL;
- fSelectedDraftNumber = 0;
- }
- }
-
- //------------------------------------------------------------------------------
- // InternalizeHistory
- //------------------------------------------------------------------------------
-
- FullDraftInfoRec* DraftWindow::InternalizeHistory(Environment* ev)
- {
- ODDocument* document = fDraft->GetDocument(ev);
- TempODDraft prevDraft = kODNULL;
- TempODDraft bottomDraft = document->AcquireBaseDraft(ev,kODDPReadOnly);
- FullDraftInfoRec* aDraftInfoRec;
-
- if (HAS_WRITE_ACCESS(fDraft->GetPermissions(ev)))
- {
- WASSERT(document->Exists(ev, 0, fDraft, kODPosFirstBelow));
-
- prevDraft = document->AcquireDraft(ev,kODDPReadOnly,kODNULL,fDraft,
- kODPosFirstBelow,kODFalse);
- }
- else
- {
- prevDraft = fDraft;
- prevDraft->Acquire(ev);
- }
-
- FullDraftInfoRec* firstInfoRec = kODNULL;
- if ( prevDraft != bottomDraft )
- {
- ODULong curDraftNumber = 1;
- for ( ; ; )
- {
- // $$$$$ <eeh> each draft gets aquired twice: here and in InitDraftInfoRec
- prevDraft = document->AcquireDraft( ev, kODDPReadOnly, kODNULL,
- prevDraft, kODPosFirstBelow, kODTrue );
-
- FullDraftInfoRec* newDIR = new FullDraftInfoRec;
- newDIR->InitDraftInfoRec(ev, prevDraft);
-
- if ( firstInfoRec )
- {
- aDraftInfoRec->SetNext(newDIR);
- aDraftInfoRec = newDIR;
- }
- else
- {
- aDraftInfoRec = newDIR;
- firstInfoRec = aDraftInfoRec;
- }
- if ( prevDraft == bottomDraft )
- break;
- ++curDraftNumber;
- }
-
- ODScriptCode script = FontToScript( GetSysFont() );
- ODLangCode lang = GetScriptVariable( script, smScriptLang );
-
- for (aDraftInfoRec = firstInfoRec; aDraftInfoRec!=kODNULL;
- aDraftInfoRec =
- (FullDraftInfoRec*)((DraftInfoRec*)aDraftInfoRec)->Next())
- {
- aDraftInfoRec->SetNumber( curDraftNumber-- );
- Str255 numberStr;
- NumToString( aDraftInfoRec->Number(), numberStr);
- aDraftInfoRec->SetNumberString( CreateIText( script, lang, numberStr ));
- }
- }
-
- return firstInfoRec;
- }
-
- void DraftWindow::DraftSaved(Environment* ev, ODDraft* draft)
- {
- ODTime savedTimeDate;
- time((time_t *)(&savedTimeDate));
- TempODStorageUnit su = draft->AcquireDraftProperties(ev);
- ODSetTime_TProp(ev, su, kODPropDraftSavedDate, kODTime_T, savedTimeDate);
- }
-
- ODSShort DraftWindow::CountDrafts()
- {
- DraftInfoRec* dir = fDraftInfo;
- ODSShort result;
- for ( result = 0; dir; dir = dir->Next() )
- if ( dir->GetDIRType() == kDIRTypeFull )
- ++result;
- return result;
- }
-
- ODBoolean DraftWindow::CreateDraft(Environment* ev)
- {
- short itemHit,itemKind;
- Handle itemHandle;
- Rect scratchRect;
- DialogPtr dlg;
- Str255 aS255;
- ODBoolean result;
- GrafPort* savePort;
-
- TempODStorageUnit su = fDraft->AcquireDraftProperties(ev);
- ODSession *session = su->GetSession(ev);
-
- GetPort(&savePort);
- { CUsingLibraryResources r;
- dlg = ODGetNewDialog(ev,kCreateDraftsDlgID,session);
- }
- THROW_IF_NULL(dlg);
- SetPort(dlg);
-
- SetDialogDefaultItem(dlg, kCreateDraftsCreateBtn);
- SetDialogCancelItem(dlg, kCreateDraftsCancelBtn);
-
- GetDialogItem(dlg, kCreateDraftsNameEditTxt, &itemKind,
- &itemHandle, &scratchRect);
- ODIText userName;
- session->GetUserName(ev, &userName);
- Str255 userNamePStr ;
- IntlToPStr(&userName, userNamePStr);
- SetDialogItemText(itemHandle,userNamePStr);
- DisposeITextStruct(userName);
-
- /* make the Comments edit text field active: (0, 0) = beginning of text */
- SelectDialogItemText(dlg, kCreateDraftsCommentsEditTxt, 0, 0);
-
- /* get the draft # dynamically and add to static text… */
- ODULong num = fDraftInfo?fDraftInfo->Number() + 1 : 1;
- NumToString( num, aS255 );
-
- // This acts to replace the "^0" in static text item 8 with the
- // number of the draft. Since item 8 is the only static text item
- // in the dialog we don't have to say which one. I guess....
- ParamText(aS255,"\p","\p","\p");
-
- DialogScriptData dsd;
- ODUseDialogScriptData( &dsd, dlg );
-
- ShowWindow(dlg);
-
- ModalFilterUPP modalFilter =
- NewModalFilterProc(CheckKeyScriptFirstFilterProc);
-
- ODUseCommandKeyStringsResource( kDraftsCreateCmdKeyStrs );
- do {
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum); // for the cmd key str#
- ModalDialog( modalFilter, &itemHit );
-
- EndUsingLibraryResources(savedRefNum);
- switch(itemHit)
- {
- case kCreateDraftsNameEditTxt:
- break;
- case kCreateDraftsCommentsEditTxt:
- break;
- }
- } while ((itemHit != kCreateDraftsCreateBtn) &&
- (itemHit != kCreateDraftsCancelBtn));
-
- DisposeRoutineDescriptor(modalFilter);
-
- result = (itemHit == kCreateDraftsCreateBtn);
- if (result)
- {
- Str255 aStr255;
-
- // update Name
- GetDialogItem(dlg, kCreateDraftsNameEditTxt, &itemHit,
- &itemHandle, &scratchRect);
- GetDialogItemText(itemHandle,aStr255);
- TempODIText name = CreateIText( dsd.Script(), dsd.Language(),
- (StringPtr)aStr255 );
- ODSetITextProp( ev, su, kODPropModUser, kODMacIText, name);
-
- // update Comments. Note that it's now possible to display long ones
- // and that therefore we want to allow them bigger than 255.
- GetDialogItem(dlg, kCreateDraftsCommentsEditTxt, &itemHit, &itemHandle,
- &scratchRect);
- ODSize strLen = GetHandleSize(itemHandle);
- TempODIText comments = CreateIText( dsd.Script(), dsd.Language(),
- (ODUByte*)*itemHandle, strLen );
- ODSetITextProp( ev, su, kODPropDraftComment, kODMacIText, comments);
- }
- DisposeDialog(dlg);
- SetPort(savePort);
- return result;
- } // CreateDraft()
-
-
- ODBoolean DraftWindow::RemoveSelectedDrafts(Environment* ev)
- {
- short itemHit;
- DialogPtr dlg;
- Str255 aS255,aS2552;
- GrafPort* savePort;
-
- GetPort(&savePort);
- {
- TempODStorageUnit draftProps = fDraft->AcquireDraftProperties(ev);
- ODSession *session = draftProps->GetSession(ev);
- CUsingLibraryResources r;
- dlg = ODGetNewDialog( ev, kDeleteDraftsDlogID, session );
- }
- THROW_IF_NULL(dlg);
- SetPort(dlg);
-
- SetDialogDefaultItem(dlg, kDeleteDraftsCancelBtn);
- SetDialogCancelItem(dlg, kDeleteDraftsCancelBtn);
-
- PlatformFile* file = GetPlatformFileFromContainer(ev,
- fDraft->GetDocument(ev)->GetContainer(ev));
-
- file->GetAsciiName((char*)aS255,255);
- ODDeleteObject(file);
- CToPascalString((char*)aS255);
- NumToString( fSelectedDraftNumber, aS2552 );
- ParamText(aS2552,aS255,"\p","\p");
-
- ShowWindow(dlg);
- ModalFilterUPP modalFilter = NewModalFilterProc( CheckDeleteKeyFilterProc );
-
- do {
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum); // for the cmd key str#
- ModalDialog( modalFilter, &itemHit );
- EndUsingLibraryResources(savedRefNum);
- } while ((itemHit != kDeleteDraftsCancelBtn) &&
- (itemHit != kDeleteDraftsDeleteBtn));
-
- DisposeRoutineDescriptor(modalFilter);
- DisposeDialog(dlg);
- SetPort(savePort);
-
- return itemHit == kDeleteDraftsDeleteBtn;
- }
-
- void DraftWindow::SetHilite( DraftInfoRec* from, short whichRow )
- {
- if ( fHilitedRow != kODNULL )
- SetRows( fHilitedRow, 0, kODFalse, fListH );
- SetRows( from, whichRow, kODTrue, fListH );
- fHilitedRow = (FullDraftInfoRec*)GetNthRow( from, whichRow );
- }
-
- void DraftWindow::Print()
- {
- }
-
- //==============================================================================
- // DraftInfoRec
- //==============================================================================
-
- DraftInfoRec::DraftInfoRec()
- {
- fDIRType = kDIRTypeUnknown;
- // fFirst = kODNULL;
- fNext = kODNULL;
- fComment = kODNULL;
- }
-
- //==============================================================================
- // DummyDraftInfoRec
- //==============================================================================
-
- DummyDraftInfoRec::DummyDraftInfoRec()
- {
- this->SetDIRType( kDIRTypeDummy );
- this->SetShouldHilite( kODFalse );
-
- // fPartialComment = kODNULL;
- fCommentOwner = kODNULL;
- }
-
- //==============================================================================
- // FullDraftInfoRec
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // Creation
- //------------------------------------------------------------------------------
-
- FullDraftInfoRec::FullDraftInfoRec()
- {
- this->SetDIRType( kDIRTypeFull );
- this->SetShouldHilite( kODFalse );
-
- fDraft = kODNULL;
- fDraftProperties = kODNULL;
- fDraftID = kODNULL;
- fDraftNumber = 0;
- fDraftNumberString = kODNULL;
- fSaved = kODNULL;
- fSavedString = kODNULL;
- fCachedComment = kODNULL;
- fModifiedBy = kODNULL;
- fCanExpand = kODFalse;
- }
-
- void FullDraftInfoRec::InitDraftInfoRec(Environment* ev, ODDraft* draft )
- {
- draft->Acquire(ev);
- fDraft = draft;
- fDraftProperties = draft->AcquireDraftProperties(ev);
- fDraftID = draft->GetID(ev);
-
- fModifiedBy = ODGetITextProp( ev, fDraftProperties,
- kODPropModUser, kODMacIText, kODNULL);
-
- fSaved = ODGetTime_TProp(ev, fDraftProperties, kODPropDraftSavedDate,
- kODTime_T);
-
- Str255 dateString;
- IUDateString( fSaved, shortDate, dateString );
- Str255 timeString;
- IUTimeString( fSaved, kODFalse, timeString );
-
- Str255 dateTimeString;
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
- ReplaceIntoString( kDraftsWnDateSpaceResID, dateString,
- timeString, dateTimeString );
- EndUsingLibraryResources(savedRefNum);
- ODScriptCode script = GetScriptManagerVariable(smSysScript);
- ODLangCode lang = GetScriptVariable(script, smScriptLang);
- fSavedString = CreateIText( script, lang, dateTimeString );
-
- ODIText* comment = ODGetITextProp( ev, fDraftProperties,
- kODPropDraftComment, kODMacIText, kODNULL );
- WASSERT( comment );
- this->SetComment( comment );
- }
-
-
- //------------------------------------------------------------------------------
- // Destruction
- //------------------------------------------------------------------------------
-
- DraftInfoRec::~DraftInfoRec()
- {
- ODDeleteObject(fNext);
- DisposeIText(fComment);
- }
-
- #if ODDebug
- DummyDraftInfoRec::~DummyDraftInfoRec()
- {
- WASSERT( this->GetDIRType() == kDIRTypeDummy);
- }
- #endif
-
- FullDraftInfoRec::~FullDraftInfoRec()
- {
- WASSERT( this->GetDIRType() == kDIRTypeFull);
- Environment* ev = somGetGlobalEnvironment();
-
- ODReleaseObject(ev,fDraftProperties);
- ODReleaseObject(ev,fDraft);
-
- DisposeIText(fDraftNumberString);
- DisposeIText(fSavedString);
- DisposeIText(fModifiedBy);
- DisposeIText(fCachedComment);
- }
-
- //------------------------------------------------------------------------------
- // filter procs
- //------------------------------------------------------------------------------
-
- static pascal ODBoolean DraftDlgFilterProc( DialogPtr dialog, EventRecord *event,
- short *itemHit )
- {
- Rect itemRect;
- short itemType;
- Handle itemHandle;
- long refcon = ((WindowPeek)dialog)->refCon;
- DraftWindow* self = (DraftWindow*)refcon;
- ListHandle listH = self->GetListHandle();
- ODBoolean result = kODFalse;
-
- if (event->what == mouseUp)
- {
- if ( READYTOCLOSESET( refcon ) )
- {
- *itemHit = kDraftsOpenBtn;
- result = kODTrue;
- }
- }
- else if (event->what == mouseDown)
- {
- GetDialogItem(dialog, kDraftsListUserItem, &itemType, &itemHandle, &itemRect);
- Point mpt = event->where;
- SetPort(dialog);
- GlobalToLocal(&mpt);
- if ( PtInRect(mpt, &itemRect) )
- {
- if ( LClick( mpt, event->modifiers, listH ) )
- {
- WASSERT( !READYTOCLOSESET( refcon ) );
- SETREADYTOCLOSE( refcon );
- }
- else if ( self->ProcessMousedownInList( dialog, listH, mpt ) )
- InvalRect( &itemRect );
- *itemHit = kDraftsListUserItem;
- result = kODTrue;
- }
- }
- // <eeh> autoKey too?
- else if ( (event->what == keyDown) && !CREATEISSET(refcon) )
- {
- // the "done" button is shown as the default though it is item
- // #2, so we need to override the ODArrowKeyFilterProc's behavior.
- char key = event->message & charCodeMask;
- if ( (key == kEnterKey) || (key ==kReturnKey) )
- {
- FlashButtonItem( dialog, kDraftsDoneBtn );
- *itemHit = kDraftsDoneBtn;
- result = kODTrue;
- }
- }
-
- return result || ODArrowKeyFilterProc( dialog, event, itemHit );
- }
-
- static pascal ODBoolean CheckKeyScriptFirstFilterProc( DialogPtr dialog,
- EventRecord *event, short *itemHit)
- {
- // pass to the next filter proc. This one just changes state, never
- // consuming the event.
- return CheckKeyScriptChangeFilterProc( dialog, event, itemHit )
- || ODButtonKeyFilterProc( dialog, event, itemHit );
- }
-
- static DraftInfoRec* GetNthRow( DraftInfoRec* from, short whichRow )
- {
- WASSERT( from );
- WASSERT( whichRow >= 0 );
- while ( whichRow-- )
- {
- from = from->Next();
- WASSERT( from );
- }
- return from;
- }
-
- static void SetRows( DraftInfoRec* dir, short startRow, ODBoolean newValue,
- ListHandle listH )
- {
- dir = GetNthRow( dir, startRow );
- WASSERT(dir);
- WASSERT( dir->GetDIRType() == kDIRTypeFull );
- dir->SetShouldHilite( newValue );
- Cell cell;
- cell.h = 0;
- cell.v = startRow;
- while ( ((dir = dir->Next()) != NULL) && dir->GetDIRType() == kDIRTypeDummy )
- {
- dir->SetShouldHilite( newValue );
- ++cell.v;
- }
- }
-
- static FullDraftInfoRec* FirstSelectedRow( DraftInfoRec* from )
- {
- while ( from && !from->ShouldHilite() )
- from = (FullDraftInfoRec*)from->Next();
-
- WASSERT( from );
- WASSERT( from->GetDIRType() == kDIRTypeFull );
- return (FullDraftInfoRec*)from;
- }
-
- static pascal void OutlineButton(Rect *theBox, DialogPtr dlog)
- {
- GrafPtr oldPort;
- GetPort( &oldPort );
- SetPort( dlog );
-
- PenState curPen;
- GetPenState( &curPen );
- PenNormal();
- PenSize( 3, 3 );
- FrameRoundRect( theBox, 16, 16 );
-
- SetPenState( &curPen );
- SetPort( oldPort );
- }
-
- static pascal void DrawBlackBoxItem(DialogPtr dlog, short theItem)
- {
- Rect boxRect;
- Handle scratchHandle;
- short scratchKind;
-
- GetDialogItem(dlog, theItem, &scratchKind, &scratchHandle, &boxRect);
- switch ( theItem )
- {
- case kDraftsHorizRectUserItem:
- case kDraftsHeaderRectUserItem:
- DrawItemFrame(dlog,theItem);
- break;
- case kDraftsCreateUserItem:
- case kDraftsDoneUserItem:
- ODBoolean createIsDefault = CREATEISSET(((WindowPeek)dlog)->refCon);
- if ( createIsDefault && theItem == kDraftsCreateUserItem)
- OutlineButton(&boxRect, dlog);
- else if ( !createIsDefault && theItem == kDraftsDoneUserItem)
- OutlineButton(&boxRect, dlog);
- break;
- case kDraftsListUserItem:
- LUpdate(dlog->visRgn, GETLISTHANDLE(((WindowPeek)dlog)->refCon));
- Rect listRect;
- GETLISTRECT( ((WindowPeek)dlog)->refCon, &listRect );
- FrameRect( &listRect );
- break;
- }
- }
-
- static void ContractList( FullDraftInfoRec* dir, ListHandle listH, short parentRowNum )
- {
- WASSERT( dir );
- WASSERT( dir->GetDIRType() == kDIRTypeFull );
-
- DisposeIText( dir->GetComment() );
- dir->UncacheComment();
-
- // Patch around the dummy entries and dispose them. Remember that
- // ~DraftInfoRec deletes fNext recursively, so clip the list free
- // at both ends before deleting.
-
- DummyDraftInfoRec* findNextFull = (DummyDraftInfoRec*)dir->Next();
- WASSERT(findNextFull);
- DummyDraftInfoRec* rememberPrev = kODNULL;
- short removedCount = 0;
- while ( findNextFull && (findNextFull->GetDIRType() != kDIRTypeFull) )
- {
- rememberPrev = findNextFull;
- findNextFull = (DummyDraftInfoRec*)findNextFull->Next();
- ++removedCount;
- }
- WASSERT( rememberPrev );
- rememberPrev->SetNext( kODNULL );
- delete dir->Next(); // this is the head of the list
-
- dir->SetNext( findNextFull );
-
- LDelRow( removedCount, parentRowNum, listH );
- }
-
- static TEHandle ITextToTERec( ODIText* iText, Rect* bothRects )
- {
- TEHandle hTE = TENew( bothRects, bothRects );
-
- short newFont = GetScriptVariable( GetITextScriptCode(iText),
- smScriptAppFond );
- (*hTE)->txFont = newFont;
- TESetText( GetITextPtr( iText ), GetITextStringLength(iText), hTE );
- return hTE;
- }
-
- static void ExpandList( FullDraftInfoRec* dir, ListHandle listH, DialogPtr dialog,
- short parentRowNum )
- {
- WASSERT(dir);
- WASSERT(dir->GetDIRType() == kDIRTypeFull);
-
- // Get the text of the comment, figure out how many lines it'll require
- // not truncated, and create dummy DraftInfoRecs each of them holding
- // one line. TE will calculate line breaks based on a rect given,
- // so use the left and right fields from the comments column.
- // REMEMBER that the first line goes in the existing "parent" entry.
-
- Rect itemRect;
- short ignoreType;
- Handle ignoreHandle;
- GetDialogItem( dialog, kDraftsCommentStaticTxt, &ignoreType, &ignoreHandle,
- &itemRect );
- itemRect.top = 0;
- itemRect.bottom = 0x7fff; // why be shy?
- itemRect.right -= 1; // make TE linewrap same as our trunc function
-
- ODIText* iText = dir->GetComment();
- // save off the truncatable comment for when we're contracted
- dir->CacheComment();
-
- TEHandle teh = ITextToTERec( iText, &itemRect );
-
- HLock( (Handle)teh );
- HLock( (*teh)->hText );
- char* currentLine = *(*teh)->hText;
- short* curLineStart = (*teh)->lineStarts;
- WASSERT( *curLineStart == 0 );
- ODScriptCode script = GetITextScriptCode( iText );
- ODLangCode lang = GetITextLangCode( iText );
-
- FullDraftInfoRec* savedNext = (FullDraftInfoRec*)dir->Next();
- DraftInfoRec* currentParent = dir;
- ODBoolean hiliteState = dir->ShouldHilite();
-
- short numLines = (*teh)->nLines;
- LSetDrawingMode(kODFalse, listH); /* turn list drawing off */
- AddRows( listH, parentRowNum, numLines-1 );
- LSetDrawingMode(kODTrue, listH); /* turn list drawing off */
- for ( short i = 0 ;i < numLines; ++i )
- {
- ODUByte* thisLine = (ODUByte*)¤tLine[*curLineStart++];
- ODUByte* nextLine = (ODUByte*)¤tLine[*curLineStart];
- ODSize len = nextLine - thisLine;
- ODIText* partialComment = CreateIText( script, lang, thisLine, len );
-
- if ( i == 0 )
- {
- dir->SetComment( partialComment );
- }
- else
- {
- DummyDraftInfoRec* newDummy = new DummyDraftInfoRec;
- newDummy->SetComment( partialComment );
- newDummy->SetCommentOwner( dir );
- newDummy->SetShouldHilite( hiliteState );
-
- currentParent->SetNext(newDummy);
- currentParent = newDummy;
- }
- }
-
- TEDispose( teh );
- currentParent->SetNext(savedNext);
- }
-
- ODBoolean DraftWindow::ProcessMousedownInList( DialogPtr dialog,
- ListHandle listH, Point mpt )
- {
- // get last cell clicked in, but
- // ignore it if the cell doesn't exist (why is this necessary?)
- Cell lastClick = LLastClick( listH );
- if ( (lastClick.v) == -1 ||
- (lastClick.v >= (*listH)->dataBounds.bottom) )
- return kODFalse;
-
- ODBoolean result = kODFalse;
-
- DraftInfoRec* dir = GetNthRow( fDraftInfo, lastClick.v );
- WASSERT( dir );
-
- if ( dir->GetDIRType() == kDIRTypeDummy )
- {
- DraftInfoRec* parent =
- ((DummyDraftInfoRec*)dir)->GetCommentOwner();
- ODBoolean isHilited = dir->ShouldHilite();
- WASSERT( isHilited == parent->ShouldHilite() );
- if ( !isHilited )
- {
- this->SetHilite( parent, 0 );
- result = kODTrue;
- }
- return result;
- }
-
- Rect scratchRect;
- short itemType;
- Handle ignore;
- GetDialogItem(dialog, kDraftsArrowStaticTxt, &itemType,
- &ignore, &scratchRect);
- ODBoolean inGrowColumn = (mpt.h > scratchRect.left)
- && (mpt.h < scratchRect.right);
-
- if ( inGrowColumn && ((FullDraftInfoRec*)dir)->CanExpand() )
- {
- if ( ((FullDraftInfoRec*)dir)->IsExpanded() )
- ContractList( (FullDraftInfoRec*)dir, listH, lastClick.v );
- else
- ExpandList( (FullDraftInfoRec*)dir, listH, dialog, lastClick.v );
- result = kODTrue;
- }
- else if ( !dir->ShouldHilite() )
- {
- this->SetHilite( dir, 0 );
- result = kODTrue;
- }
- return result;
- }
-
-
- static pascal ODBoolean CheckDeleteKeyFilterProc( DialogPtr dialog, EventRecord *event,
- short *itemHit)
- {
- ODBoolean result = kODFalse;
- ODBoolean isDraftsDlog = ((WindowPeek)dialog)->refCon != 0;
-
- if (event->what == keyDown)
- {
- const char kDeleteButton = 0x08;
- char key = event->message & charCodeMask;
- if ( key == kDeleteButton )
- {
- if ( isDraftsDlog )
- {
- *itemHit = kDraftsDeleteBtn;
- result = kODTrue;
- }
- else
- {
- *itemHit = kDeleteDraftsDeleteBtn;
- result = kODTrue;
- }
- }
- }
- if ( result )
- FlashButtonItem( dialog, *itemHit );
- else
- {
- if ( isDraftsDlog )
- result = DraftDlgFilterProc( dialog, event, itemHit );
- else
- result = ODDialogFilterProc( dialog, event, itemHit );
- }
-
- return result;
- }
-
- static void SetButtonStates( DialogPtr dlog, ODBoolean hasWriteAccess,
- Boolean hasContent )
- {
- short openHiliteState = hasContent? kDraftsActiveControl : 255;
- short deleteHiliteState
- = hasContent && hasWriteAccess? kDraftsActiveControl : 255;
-
- short ignoreT;
- ControlHandle control;
- Rect ignoreR;
-
- GetDialogItem( dlog, kDraftsDeleteBtn, &ignoreT,
- (Handle*)&control, &ignoreR );
- HiliteControl( control, deleteHiliteState);
- SetControlReference( control, deleteHiliteState );
-
- GetDialogItem( dlog, kDraftsOpenBtn, &ignoreT, (Handle*)&control,
- &ignoreR );
- HiliteControl( control, openHiliteState );
- SetControlReference( control, openHiliteState );
- }
-
- static void AddRows( ListHandle listH, short startIndex, short numToAdd )
- {
- char aByte = 'a' ;
- Cell newCell;
- newCell.h = 0;
- short finalIndex = startIndex + numToAdd;
- while ( startIndex < finalIndex )
- {
- LAddRow(1, startIndex, listH);
- newCell.v = startIndex++;
- LSetCell( &aByte, 1, newCell, listH );
- }
- }
-
- //------------------------------------------------------------------------------
- // Callback to let LDEF communicate with DraftWindow
- //------------------------------------------------------------------------------
-
- void DrawDWUserStrings( struct DraftLDEFCallbackInfo *callbackInfo,
- ODSShort row, const Rect* listItemRect)
- {
- DraftInfoRec *dir = callbackInfo->dir ;
- WASSERT(dir);
-
- TRY // much of what follows can't throw, but some of it can, so I'm
- // making this thing cover nearly all of the routine. The overhead
- // is paid but once anyway.
-
- dir = GetNthRow( dir, row );
- WASSERT( dir );
-
- DialogPtr dlog = callbackInfo->dialog;
- Rect localRect;
- localRect.top = listItemRect->top;
- localRect.bottom = listItemRect->bottom;
-
- ODIText* fourStrings[kNumColumns];
- fourStrings[kCommentsColumnIndex] = dir->GetComment();
- ODBoolean isFullType = dir->GetDIRType() == kDIRTypeFull;
- if ( isFullType )
- {
- fourStrings[0] = ((FullDraftInfoRec*)dir)->GetModifiedBy();
- fourStrings[1] = ((FullDraftInfoRec*)dir)->GetNumberString();
- fourStrings[2] = ((FullDraftInfoRec*)dir)->GetCreated();
- }
- else
- {
- WASSERT(dir->GetDIRType() == kDIRTypeDummy);
- fourStrings[0] = fourStrings[1] = fourStrings[2] = kODNULL;
- }
-
- // Determination whether a comment is too long to be drawn in a single
- // line is done lazily: it's put off until now, where the DrawITextInDlogBox
- // function get the necessary information as part of its job. So now, in
- // addition to drawing the strings, we need to save off that information.
-
- ODBoolean truncatedThisComment = kODFalse; // default values
- ODBoolean mayWantToTruncate;
- for ( short index = 0; index < kNumColumns; ++index )
- {
- localRect.left = callbackInfo->rectEnds[index].left;
- localRect.right = callbackInfo->rectEnds[index].right;
- if ( fourStrings[index] )
- {
- // don't try to truncate if guaranteed short enough already. This fixes
- // TextEdit's ignoring of training spaces when calculating line breaks.
- // If this is a dummy record, we *know* that the comment will fit; otherwise
- // check if this is an expanded full record's comments column, in which
- // case we've already clipped the comments to fit.
- mayWantToTruncate = isFullType &&
- ((index != kCommentsColumnIndex)
- || !(((FullDraftInfoRec*)dir)->IsExpanded()));
- ODBoolean truncatedThisColumn =
- DrawITextInDlogBox( fourStrings[index],
- &localRect, dlog, mayWantToTruncate );
- if ( index == kCommentsColumnIndex )
- truncatedThisComment =
- truncatedThisComment || truncatedThisColumn;
- }
- }
- if ( truncatedThisComment )
- {
- WASSERT( dir->GetDIRType() == kDIRTypeFull );
- WASSERT( ((FullDraftInfoRec*)dir)->IsExpanded() == kODFalse );
- // record that this entry has a too-long comment
- ((FullDraftInfoRec*)dir)->SetCanExpand();
- }
-
- // now decide whether we need to draw the expansion icon and draw
- // the right one.
-
- if ( isFullType && ((FullDraftInfoRec*)dir)->CanExpand() )
- {
- localRect.left = callbackInfo->arrowEnds.left;
- localRect.right = callbackInfo->arrowEnds.right;
-
- ODSLong savedRefNum;
- BeginUsingLibraryResources(savedRefNum);
- OSErr err = PlotIconID( &localRect, atNone, ttNone,
- ((FullDraftInfoRec*)dir)->IsExpanded() ?
- kDWOpenTriangleResID : kDWClosedTriangleResID );
- EndUsingLibraryResources(savedRefNum);
- }
-
- // finally, hilite if this record is [part of] the selection
- if ( dir->ShouldHilite() )
- {
- short oldPenMode = dlog->pnMode;
- PenMode( hilitetransfermode );
- PaintRect( listItemRect ) ;
- PenMode( oldPenMode );
- }
-
- CATCH_ALL
- WARN( "ignoring error in DrawDWUserStrings" );
- ENDTRY
- }
-
-
-
-
-