diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/oleutest/letest/outline/outldoc.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/oleutest/letest/outline/outldoc.c')
-rw-r--r-- | private/oleutest/letest/outline/outldoc.c | 3247 |
1 files changed, 3247 insertions, 0 deletions
diff --git a/private/oleutest/letest/outline/outldoc.c b/private/oleutest/letest/outline/outldoc.c new file mode 100644 index 000000000..8e36101f0 --- /dev/null +++ b/private/oleutest/letest/outline/outldoc.c @@ -0,0 +1,3247 @@ +/************************************************************************* +** +** OLE 2 Sample Code +** +** outldoc.c +** +** This file contains OutlineDoc functions. +** +** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved +** +*************************************************************************/ + +#include "outline.h" + +#if !defined( OLE_VERSION ) +#include <commdlg.h> +#endif + + +OLEDBGDATA + +extern LPOUTLINEAPP g_lpApp; + +// REVIEW: should use string resource for messages +char ErrMsgDocWnd[] = "Can't create Document Window!"; +char ErrMsgFormatNotSupported[] = "Clipboard format not supported!"; +char MsgSaveFile[] = "Save existing file ?"; +char ErrMsgSaving[] = "Error in saving file!"; +char ErrMsgOpening[] = "Error in opening file!"; +char ErrMsgFormat[] = "Improper file format!"; +char ErrOutOfMemory[] = "Error: out of memory!"; +static char ErrMsgPrint[] = "Printing Error!"; + +static BOOL fCancelPrint; // TRUE if the user has canceled the print job +static HWND hWndPDlg; // Handle to the cancel print dialog + + +/* OutlineDoc_Init + * --------------- + * + * Initialize the fields of a new OutlineDoc object. The object is initially + * not associated with a file or an (Untitled) document. This function sets + * the docInitType to DOCTYPE_UNKNOWN. After calling this function the + * caller should call: + * 1. OutlineDoc_InitNewFile to set the OutlineDoc to (Untitled) + * 2. OutlineDoc_LoadFromFile to associate the OutlineDoc with a file. + * This function creates a new window for the document. + * + * NOTE: the window is initially created with a NIL size. it must be + * sized and positioned by the caller. also the document is initially + * created invisible. the caller must call OutlineDoc_ShowWindow + * after sizing it to make the document window visible. + */ +BOOL OutlineDoc_Init(LPOUTLINEDOC lpOutlineDoc, BOOL fDataTransferDoc) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + +#if defined( INPLACE_CNTR ) + lpOutlineDoc->m_hWndDoc = CreateWindow( + DOCWNDCLASS, // Window class name + NULL, // Window's title + + /* OLE2NOTE: an in-place contanier MUST use + ** WS_CLIPCHILDREN window style for the window + ** that it uses as the parent for the server's + ** in-place active window so that its + ** painting does NOT interfere with the painting + ** of the server's in-place active child window. + */ + + WS_CLIPCHILDREN | WS_CLIPSIBLINGS | + WS_CHILDWINDOW, + 0, 0, + 0, 0, + lpOutlineApp->m_hWndApp,// Parent window's handle + (HMENU)1, // child window id + lpOutlineApp->m_hInst, // Instance of window + NULL); // Create struct for WM_CREATE + +#else + + lpOutlineDoc->m_hWndDoc = CreateWindow( + DOCWNDCLASS, // Window class name + NULL, // Window's title + WS_CHILDWINDOW, + 0, 0, + 0, 0, + lpOutlineApp->m_hWndApp,// Parent window's handle + (HMENU)1, // child window id + lpOutlineApp->m_hInst, // Instance of window + NULL); // Create struct for WM_CREATE +#endif + + if(! lpOutlineDoc->m_hWndDoc) { + OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgDocWnd); + return FALSE; + } + + SetWindowLong(lpOutlineDoc->m_hWndDoc, 0, (LONG) lpOutlineDoc); + + if (! LineList_Init(&lpOutlineDoc->m_LineList, lpOutlineDoc)) + return FALSE; + + lpOutlineDoc->m_lpNameTable = OutlineDoc_CreateNameTable(lpOutlineDoc); + if (! lpOutlineDoc->m_lpNameTable ) + return FALSE; + + lpOutlineDoc->m_docInitType = DOCTYPE_UNKNOWN; + lpOutlineDoc->m_cfSaveFormat = lpOutlineApp->m_cfOutline; + lpOutlineDoc->m_szFileName[0] = '\0'; + lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName; + lpOutlineDoc->m_fDataTransferDoc = fDataTransferDoc; + lpOutlineDoc->m_uCurrentZoom = IDM_V_ZOOM_100; + lpOutlineDoc->m_scale.dwSxN = (DWORD) 1; + lpOutlineDoc->m_scale.dwSxD = (DWORD) 1; + lpOutlineDoc->m_scale.dwSyN = (DWORD) 1; + lpOutlineDoc->m_scale.dwSyD = (DWORD) 1; + lpOutlineDoc->m_uCurrentMargin = IDM_V_SETMARGIN_0; + lpOutlineDoc->m_nLeftMargin = 0; + lpOutlineDoc->m_nRightMargin = 0; + lpOutlineDoc->m_nDisableDraw = 0; + OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE); + +#if defined( USE_HEADING ) + if (! fDataTransferDoc) { + if (!Heading_Create((LPHEADING)&lpOutlineDoc->m_heading, + lpOutlineDoc->m_hWndDoc, lpOutlineApp->m_hInst)) { + return FALSE; + + } + } +#endif // USE_HEADING + +#if defined( USE_FRAMETOOLS ) + if (! fDataTransferDoc) { + lpOutlineDoc->m_lpFrameTools = OutlineApp_GetFrameTools(lpOutlineApp); + FrameTools_AssociateDoc( + lpOutlineDoc->m_lpFrameTools, + lpOutlineDoc + ); + } +#endif // USE_FRAMETOOLS + +#if defined( OLE_VERSION ) + /* OLE2NOTE: perform initialization required for OLE */ + if (! OleDoc_Init((LPOLEDOC)lpOutlineDoc, fDataTransferDoc)) + return FALSE; +#endif // OLE_VERSION + + return TRUE; +} + + +/* OutlineDoc_InitNewFile + * ---------------------- + * + * Initialize the OutlineDoc object to be a new (Untitled) document. + * This function sets the docInitType to DOCTYPE_NEW. + */ +BOOL OutlineDoc_InitNewFile(LPOUTLINEDOC lpOutlineDoc) +{ +#if defined( OLE_VERSION ) + // OLE2NOTE: call OLE version of this function instead + return OleDoc_InitNewFile((LPOLEDOC)lpOutlineDoc); + +#else + + OleDbgAssert(lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN); + + // set file name to untitled + // REVIEW: should load from string resource + lstrcpy(lpOutlineDoc->m_szFileName, UNTITLED); + lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName; + lpOutlineDoc->m_docInitType = DOCTYPE_NEW; + + if (! lpOutlineDoc->m_fDataTransferDoc) + OutlineDoc_SetTitle(lpOutlineDoc, FALSE /*fMakeUpperCase*/); + + return TRUE; + +#endif // BASE OUTLINE VERSION +} + + +/* OutlineDoc_CreateNameTable + * -------------------------- + * + * Allocate a new NameTable of the appropriate type. Each document has + * a NameTable and a LineList. + * OutlineDoc --> creates standard OutlineNameTable type name tables. + * ServerDoc --> creates enhanced SeverNameTable type name tables. + * + * Returns lpNameTable for successful, NULL if error. + */ +LPOUTLINENAMETABLE OutlineDoc_CreateNameTable(LPOUTLINEDOC lpOutlineDoc) +{ + LPOUTLINENAMETABLE lpOutlineNameTable; + + lpOutlineNameTable = (LPOUTLINENAMETABLE)New( + (DWORD)sizeof(OUTLINENAMETABLE) + ); + + OleDbgAssertSz(lpOutlineNameTable != NULL,"Error allocating NameTable"); + if (lpOutlineNameTable == NULL) + return NULL; + + // initialize new NameTable + if (! OutlineNameTable_Init(lpOutlineNameTable, lpOutlineDoc) ) + goto error; + + return lpOutlineNameTable; + +error: + if (lpOutlineNameTable) + Delete(lpOutlineNameTable); + return NULL; +} + + +/* OutlineDoc_ClearCommand + * ----------------------- + * + * Delete selection in list box by calling OutlineDoc_Delete + */ +void OutlineDoc_ClearCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + int i; + int nNumSel; + LINERANGE lrSel; + + nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel); + + OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE ); + for(i = 0; i < nNumSel; i++) + OutlineDoc_DeleteLine(lpOutlineDoc, lrSel.m_nStartLine); + + OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE ); + + LineList_RecalcMaxLineWidthInHimetric(lpLL, 0); +} + + +/* OutlineDoc_CutCommand + * --------------------- + * + * Cut selection to clipboard + */ +void OutlineDoc_CutCommand(LPOUTLINEDOC lpOutlineDoc) +{ + OutlineDoc_CopyCommand(lpOutlineDoc); + OutlineDoc_ClearCommand(lpOutlineDoc); +} + + +/* OutlineDoc_CopyCommand + * ---------------------- + * Copy selection to clipboard. + * Post to the clipboard the formats that the app can render. + * the actual data is not rendered at this time. using the + * delayed rendering technique, Windows will send the clipboard + * owner window either a WM_RENDERALLFORMATS or a WM_RENDERFORMAT + * message when the actual data is requested. + * + * OLE2NOTE: the normal delayed rendering technique where Windows + * sends the clipboard owner window either a WM_RENDERALLFORMATS or + * a WM_RENDERFORMAT message when the actual data is requested is + * NOT exposed to the app calling OleSetClipboard. OLE internally + * creates its own window as the clipboard owner and thus our app + * will NOT get these WM_RENDER messages. + */ +void OutlineDoc_CopyCommand(LPOUTLINEDOC lpSrcOutlineDoc) +{ +#if defined( OLE_VERSION ) + // Call OLE version of this function instead + OleDoc_CopyCommand((LPOLEDOC)lpSrcOutlineDoc); + +#else + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPOUTLINEDOC lpClipboardDoc; + + OpenClipboard(lpSrcOutlineDoc->m_hWndDoc); + EmptyClipboard(); + + /* squirrel away a copy of the current selection to the ClipboardDoc */ + lpClipboardDoc = OutlineDoc_CreateDataTransferDoc(lpSrcOutlineDoc); + + if (! lpClipboardDoc) + return; // Error: could not create DataTransferDoc + + lpOutlineApp->m_lpClipboardDoc = (LPOUTLINEDOC)lpClipboardDoc; + + SetClipboardData(lpOutlineApp->m_cfOutline, NULL); + SetClipboardData(CF_TEXT, NULL); + + CloseClipboard(); + +#endif // ! OLE_VERSION +} + + +/* OutlineDoc_ClearAllLines + * ------------------------ + * + * Delete all lines in the document. + */ +void OutlineDoc_ClearAllLines(LPOUTLINEDOC lpOutlineDoc) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + int i; + + for(i = 0; i < lpLL->m_nNumLines; i++) + OutlineDoc_DeleteLine(lpOutlineDoc, 0); + + LineList_RecalcMaxLineWidthInHimetric(lpLL, 0); +} + + +/* OutlineDoc_CreateDataTransferDoc + * -------------------------------- + * + * Create a document to be use to transfer data (either via a + * drag/drop operation of the clipboard). Copy the selection of the + * source doc to the data transfer document. A data transfer document is + * the same as a document that is created by the user except that it is + * NOT made visible to the user. it is specially used to hold a copy of + * data that the user should not be able to change. + * + * OLE2NOTE: in the OLE version the data transfer document is used + * specifically to provide an IDataObject* that renders the data copied. + */ +LPOUTLINEDOC OutlineDoc_CreateDataTransferDoc(LPOUTLINEDOC lpSrcOutlineDoc) +{ +#if defined( OLE_VERSION ) + // Call OLE version of this function instead + return OleDoc_CreateDataTransferDoc((LPOLEDOC)lpSrcOutlineDoc); + +#else + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPOUTLINEDOC lpDestOutlineDoc; + LPLINELIST lpSrcLL = &lpSrcOutlineDoc->m_LineList; + LINERANGE lrSel; + int nCopied; + + lpDestOutlineDoc = OutlineApp_CreateDoc(lpOutlineApp, TRUE); + if (! lpDestOutlineDoc) return NULL; + + // set the ClipboardDoc to an (Untitled) doc. + if (! OutlineDoc_InitNewFile(lpDestOutlineDoc)) + goto error; + + LineList_GetSel(lpSrcLL, (LPLINERANGE)&lrSel); + nCopied = LineList_CopySelToDoc( + lpSrcLL, + (LPLINERANGE)&lrSel, + lpDestOutlineDoc + ); + + return lpDestOutlineDoc; + +error: + if (lpDestOutlineDoc) + OutlineDoc_Destroy(lpDestOutlineDoc); + + return NULL; + +#endif // ! OLE_VERSION +} + + +/* OutlineDoc_PasteCommand + * ----------------------- + * + * Paste lines from clipboard + */ +void OutlineDoc_PasteCommand(LPOUTLINEDOC lpOutlineDoc) +{ +#if defined( OLE_VERSION ) + // Call OLE version of this function instead + OleDoc_PasteCommand((LPOLEDOC)lpOutlineDoc); + +#else + + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList; + int nIndex; + int nCount; + HGLOBAL hData; + LINERANGE lrSel; + UINT uFormat; + + if (LineList_GetCount(lpLL) == 0) + nIndex = -1; // pasting to empty list + else + nIndex=LineList_GetFocusLineIndex(lpLL); + + OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE ); + + OpenClipboard(lpOutlineDoc->m_hWndDoc); + + uFormat = 0; + while(uFormat = EnumClipboardFormats(uFormat)) { + if(uFormat == lpOutlineApp->m_cfOutline) { + hData = GetClipboardData(lpOutlineApp->m_cfOutline); + nCount = OutlineDoc_PasteOutlineData(lpOutlineDoc, hData, nIndex); + break; + } + if(uFormat == CF_TEXT) { + hData = GetClipboardData(CF_TEXT); + nCount = OutlineDoc_PasteTextData(lpOutlineDoc, hData, nIndex); + break; + } + } + + lrSel.m_nStartLine = nIndex + nCount; + lrSel.m_nEndLine = nIndex + 1; + LineList_SetSel(lpLL, &lrSel); + OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE ); + + CloseClipboard(); + +#endif // ! OLE_VERSION +} + + +/* OutlineDoc_PasteOutlineData + * --------------------------- + * + * Put an array of Line Objects (stored in hOutline) into the document + * + * Return the number of items added + */ +int OutlineDoc_PasteOutlineData(LPOUTLINEDOC lpOutlineDoc, HGLOBAL hOutline, int nStartIndex) +{ + int nCount; + int i; + LPTEXTLINE arrLine; + + nCount = (int) GlobalSize(hOutline) / sizeof(TEXTLINE); + arrLine = (LPTEXTLINE)GlobalLock(hOutline); + if (!arrLine) + return 0; + + for(i = 0; i < nCount; i++) + Line_CopyToDoc((LPLINE)&arrLine[i], lpOutlineDoc, nStartIndex+i); + + GlobalUnlock(hOutline); + + return nCount; +} + + +/* OutlineDoc_PasteTextData + * ------------------------ + * + * Build Line Objects from the strings (separated by '\n') in hText + * and put them into the document + */ +int OutlineDoc_PasteTextData(LPOUTLINEDOC lpOutlineDoc, HGLOBAL hText, int nStartIndex) +{ + LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList; + HDC hDC; + LPSTR lpszText; + LPSTR lpszEnd; + LPTEXTLINE lpLine; + int nLineCount; + int i; + UINT nTab; + char szBuf[MAXSTRLEN+1]; + + lpszText=(LPSTR)GlobalLock(hText); + if(!lpszText) + return 0; + + lpszEnd = lpszText + lstrlen(lpszText); + nLineCount=0; + + while(*lpszText && (lpszText<lpszEnd)) { + + // count the tab level + nTab = 0; + while((*lpszText == '\t') && (lpszText<lpszEnd)) { + nTab++; + lpszText++; + } + + // collect the text string character by character + for(i=0; (i<MAXSTRLEN) && (lpszText<lpszEnd); i++) { + if ((! *lpszText) || (*lpszText == '\n')) + break; + szBuf[i] = *lpszText++; + } + szBuf[i] = 0; + lpszText++; + if ((i > 0) && (szBuf[i-1] == '\r')) + szBuf[i-1] = 0; // remove carriage return at the end + + hDC = LineList_GetDC(lpLL); + lpLine = TextLine_Create(hDC, nTab, szBuf); + LineList_ReleaseDC(lpLL, hDC); + + OutlineDoc_AddLine( + lpOutlineDoc, + (LPLINE)lpLine, + nStartIndex + nLineCount + ); + nLineCount++; + + } + + GlobalUnlock(hText); + + return nLineCount; +} + + +/* OutlineDoc_AddTextLineCommand + * ----------------------------- + * + * Add a new text line following the current focus line. + */ +void OutlineDoc_AddTextLineCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + HDC hDC; + int nIndex = LineList_GetFocusLineIndex(lpLL); + char szBuf[MAXSTRLEN+1]; + UINT nTab = 0; + LPLINE lpLine; + LPTEXTLINE lpTextLine; + + szBuf[0] = '\0'; + +#if defined( USE_FRAMETOOLS ) + FrameTools_FB_GetEditText( + lpOutlineDoc->m_lpFrameTools, szBuf, sizeof(szBuf)); +#else + if (! InputTextDlg(lpOutlineDoc->m_hWndDoc, szBuf, "Add Line")) + return; +#endif + + hDC = LineList_GetDC(lpLL); + lpLine = LineList_GetLine(lpLL, nIndex); + if (lpLine) + nTab = Line_GetTabLevel(lpLine); + + lpTextLine=TextLine_Create(hDC, nTab, szBuf); + LineList_ReleaseDC(lpLL, hDC); + + if (! lpTextLine) { + OutlineApp_ErrorMessage(lpOutlineApp, ErrOutOfMemory); + return; + } + OutlineDoc_AddLine(lpOutlineDoc, (LPLINE)lpTextLine, nIndex); +} + + +/* OutlineDoc_AddTopLineCommand + * ---------------------------- + * + * Add a top (margin) line as the first line in the LineList. + * (do not change the current selection) + */ +void OutlineDoc_AddTopLineCommand( + LPOUTLINEDOC lpOutlineDoc, + UINT nHeightInHimetric +) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + HDC hDC = LineList_GetDC(lpLL); + LPTEXTLINE lpTextLine = TextLine_Create(hDC, 0, NULL); + LPLINE lpLine = (LPLINE)lpTextLine; + LINERANGE lrSel; + int nNumSel; + + LineList_ReleaseDC(lpLL, hDC); + + if (! lpTextLine) { + OutlineApp_ErrorMessage(lpOutlineApp, ErrOutOfMemory); + return; + } + + Line_SetHeightInHimetric(lpLine, nHeightInHimetric); + + nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel); + if (nNumSel > 0) { + // adjust current selection to keep equivalent selection + lrSel.m_nStartLine += 1; + lrSel.m_nEndLine += 1; + } + OutlineDoc_AddLine(lpOutlineDoc, lpLine, -1); + if (nNumSel > 0) + LineList_SetSel(lpLL, (LPLINERANGE)&lrSel); +} + + +#if defined( USE_FRAMETOOLS ) + + +/* OutlineDoc_SetFormulaBarEditText + * -------------------------------- + * + * Fill the edit control in the formula with the text string from a + * TextLine in focus. + */ +void OutlineDoc_SetFormulaBarEditText( + LPOUTLINEDOC lpOutlineDoc, + LPLINE lpLine +) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + char cBuf[MAXSTRLEN+1]; + + if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools) + return; + + if (Line_GetLineType(lpLine) != TEXTLINETYPE) { + FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, NULL); + } else { + TextLine_GetTextData((LPTEXTLINE)lpLine, (LPSTR)cBuf); + FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, (LPSTR)cBuf); + } +} + + +/* OutlineDoc_SetFormulaBarEditFocus + * --------------------------------- + * + * Setup for formula bar to gain or loose edit focus. + * if gaining focus, setup up special accelerator table and scroll line + * into view. + * else restore normal accelerator table. + */ +void OutlineDoc_SetFormulaBarEditFocus( + LPOUTLINEDOC lpOutlineDoc, + BOOL fEditFocus +) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPLINELIST lpLL; + int nFocusIndex; + + if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools) + return; + + lpOutlineDoc->m_lpFrameTools->m_fInFormulaBar = fEditFocus; + + if (fEditFocus && lpOutlineDoc->m_lpFrameTools) { + lpLL = OutlineDoc_GetLineList(lpOutlineDoc); + + nFocusIndex = LineList_GetFocusLineIndex(lpLL); + LineList_ScrollLineIntoView(lpLL, nFocusIndex); + FrameTools_FB_FocusEdit(lpOutlineDoc->m_lpFrameTools); + } + + OutlineApp_SetFormulaBarAccel(lpOutlineApp, fEditFocus); +} + + +/* OutlineDoc_IsEditFocusInFormulaBar +** ---------------------------------- +** Returns TRUE if edit focus is currently in the formula bar +** else FALSE if not. +*/ +BOOL OutlineDoc_IsEditFocusInFormulaBar(LPOUTLINEDOC lpOutlineDoc) +{ + if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools) + return FALSE; + + return lpOutlineDoc->m_lpFrameTools->m_fInFormulaBar; +} + + +/* OutlineDoc_UpdateFrameToolButtons +** --------------------------------- +** Update the Enable/Disable states of the buttons in the formula +** bar and button bar. +*/ +void OutlineDoc_UpdateFrameToolButtons(LPOUTLINEDOC lpOutlineDoc) +{ + if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools) + return; + FrameTools_UpdateButtons(lpOutlineDoc->m_lpFrameTools, lpOutlineDoc); +} +#endif // USE_FRAMETOOLS + + +/* OutlineDoc_EditLineCommand + * -------------------------- + * + * Edit the current focus line. + */ +void OutlineDoc_EditLineCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + HDC hDC = LineList_GetDC(lpLL); + int nIndex = LineList_GetFocusLineIndex(lpLL); + LPLINE lpLine = LineList_GetLine(lpLL, nIndex); + int nOrgLineWidthInHimetric; + int nNewLineWidthInHimetric; + BOOL fSizeChanged; + + if (!lpLine) + return; + + nOrgLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine); + if (Line_Edit(lpLine, lpOutlineDoc->m_hWndDoc, hDC)) { + nNewLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine); + + if (nNewLineWidthInHimetric > nOrgLineWidthInHimetric) { + fSizeChanged = LineList_SetMaxLineWidthInHimetric( + lpLL, + nNewLineWidthInHimetric + ); + } else { + fSizeChanged = LineList_RecalcMaxLineWidthInHimetric( + lpLL, + nOrgLineWidthInHimetric + ); + } + +#if defined( OLE_SERVER ) + /* Update Name Table */ + ServerNameTable_EditLineUpdate( + (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable, + nIndex + ); +#endif + + OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged); + + LineList_ForceLineRedraw(lpLL, nIndex, TRUE); + } + LineList_ReleaseDC(lpLL, hDC); +} + + +/* OutlineDoc_IndentCommand + * ------------------------ + * + * Indent selection of lines + */ +void OutlineDoc_IndentCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + LPLINE lpLine; + HDC hDC = LineList_GetDC(lpLL); + int i; + int nIndex; + int nNumSel; + LINERANGE lrSel; + BOOL fSizeChanged = FALSE; + + nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel); + + OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE ); + + for(i = 0; i < nNumSel; i++) { + nIndex = lrSel.m_nStartLine + i; + lpLine=LineList_GetLine(lpLL, nIndex); + if (! lpLine) + continue; + + Line_Indent(lpLine, hDC); + if (LineList_SetMaxLineWidthInHimetric(lpLL, + Line_GetTotalWidthInHimetric(lpLine))) { + fSizeChanged = TRUE; + } + LineList_ForceLineRedraw(lpLL, nIndex, TRUE); + +#if defined( OLE_SERVER ) + /* Update Name Table */ + ServerNameTable_EditLineUpdate( + (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable, + nIndex + ); +#endif + + } + + LineList_ReleaseDC(lpLL, hDC); + + OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged); + OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE ); +} + + +/* OutlineDoc_UnindentCommand + * -------------------------- + * + * Unindent selection of lines + */ +void OutlineDoc_UnindentCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + LPLINE lpLine; + HDC hDC = LineList_GetDC(lpLL); + int nOrgLineWidthInHimetric; + int nOrgMaxLineWidthInHimetric = 0; + int i; + int nIndex; + int nNumSel; + LINERANGE lrSel; + BOOL fSizeChanged; + + nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel); + + OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE ); + + for(i = 0; i < nNumSel; i++) { + nIndex = lrSel.m_nStartLine + i; + lpLine=LineList_GetLine(lpLL, nIndex); + if (!lpLine) + continue; + + nOrgLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine); + nOrgMaxLineWidthInHimetric = + (nOrgLineWidthInHimetric > nOrgMaxLineWidthInHimetric ? + nOrgLineWidthInHimetric : nOrgMaxLineWidthInHimetric); + Line_Unindent(lpLine, hDC); + LineList_ForceLineRedraw(lpLL, nIndex, TRUE); + +#if defined( OLE_SERVER ) + /* Update Name Table */ + ServerNameTable_EditLineUpdate( + (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable, + nIndex + ); +#endif + + } + + LineList_ReleaseDC(lpLL, hDC); + + fSizeChanged = LineList_RecalcMaxLineWidthInHimetric( + lpLL, + nOrgMaxLineWidthInHimetric + ); + + OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged); + OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE ); +} + + +/* OutlineDoc_SetLineHeightCommand + * ------------------------------- + * + * Set height of the selection of lines + */ +void OutlineDoc_SetLineHeightCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPLINELIST lpLL; + HDC hDC; + LPLINE lpLine; + int nNewHeight; + int i; + int nIndex; + int nNumSel; + LINERANGE lrSel; + + if (!lpOutlineDoc) + return; + + lpLL = &lpOutlineDoc->m_LineList; + nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel); + lpLine = LineList_GetLine(lpLL, lrSel.m_nStartLine); + if (!lpLine) + return; + + nNewHeight = Line_GetHeightInHimetric(lpLine); + +#if defined( OLE_VERSION ) + OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc); +#endif + + DialogBoxParam( + lpOutlineApp->m_hInst, + (LPSTR)"SetLineHeight", + lpOutlineDoc->m_hWndDoc, + (DLGPROC)SetLineHeightDlgProc, + (LPARAM)(LPINT)&nNewHeight + ); + +#if defined( OLE_VERSION ) + OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc); +#endif + + if (nNewHeight == 0) + return; /* user hit cancel */ + + hDC = LineList_GetDC(lpLL); + + for (i = 0; i < nNumSel; i++) { + nIndex = lrSel.m_nStartLine + i; + lpLine=LineList_GetLine(lpLL, nIndex); + if (nNewHeight == -1) { + switch (Line_GetLineType(lpLine)) { + + case TEXTLINETYPE: + + TextLine_CalcExtents((LPTEXTLINE)lpLine, hDC); + break; + +#if defined( OLE_CNTR ) + case CONTAINERLINETYPE: + + ContainerLine_SetHeightInHimetric( + (LPCONTAINERLINE)lpLine, -1); + break; +#endif + + } + } + else + Line_SetHeightInHimetric(lpLine, nNewHeight); + + + LineList_SetLineHeight(lpLL, nIndex, + Line_GetHeightInHimetric(lpLine)); + } + + LineList_ReleaseDC(lpLL, hDC); + + OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE); + LineList_ForceRedraw(lpLL, TRUE); +} + + + +/* OutlineDoc_SelectAllCommand + * --------------------------- + * + * Select all the lines in the document. + */ +void OutlineDoc_SelectAllCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + LINERANGE lrSel; + + lrSel.m_nStartLine = 0; + lrSel.m_nEndLine = LineList_GetCount(lpLL) - 1; + LineList_SetSel(lpLL, &lrSel); +} + + +/* OutlineDoc_DefineNameCommand + * ---------------------------- + * + * Define a name in the document + */ +void OutlineDoc_DefineNameCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + +#if defined( OLE_VERSION ) + OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc); +#endif + + DialogBoxParam( + lpOutlineApp->m_hInst, + (LPSTR)"DefineName", + lpOutlineDoc->m_hWndDoc, + (DLGPROC)DefineNameDlgProc, + (LPARAM) lpOutlineDoc + ); + +#if defined( OLE_VERSION ) + OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc); +#endif +} + + +/* OutlineDoc_GotoNameCommand + * -------------------------- + * + * Goto a predefined name in the document + */ +void OutlineDoc_GotoNameCommand(LPOUTLINEDOC lpOutlineDoc) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + +#if defined( OLE_VERSION ) + OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc); +#endif + + DialogBoxParam( + lpOutlineApp->m_hInst, + (LPSTR)"GotoName", + lpOutlineDoc->m_hWndDoc, + (DLGPROC)GotoNameDlgProc, + (LPARAM)lpOutlineDoc + ); + +#if defined( OLE_VERSION ) + OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc); +#endif +} + + +/* OutlineDoc_ShowWindow + * --------------------- + * + * Show the window of the document to the user. + */ +void OutlineDoc_ShowWindow(LPOUTLINEDOC lpOutlineDoc) +{ +#if defined( _DEBUG ) + OleDbgAssertSz(lpOutlineDoc->m_docInitType != DOCTYPE_UNKNOWN, + "OutlineDoc_ShowWindow: can't show unitialized document\r\n"); +#endif + if (lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN) + return; + +#if defined( OLE_VERSION ) + // Call OLE version of this function instead + OleDoc_ShowWindow((LPOLEDOC)lpOutlineDoc); +#else + ShowWindow(lpOutlineDoc->m_hWndDoc, SW_SHOWNORMAL); + SetFocus(lpOutlineDoc->m_hWndDoc); +#endif +} + + +#if defined( USE_FRAMETOOLS ) + +void OutlineDoc_AddFrameLevelTools(LPOUTLINEDOC lpOutlineDoc) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; +#if defined( INPLACE_CNTR ) + // Call OLE In-Place Container version of this function instead + ContainerDoc_AddFrameLevelTools((LPCONTAINERDOC)lpOutlineDoc); + +#else // ! INPLACE_CNTR + RECT rcFrameRect; + BORDERWIDTHS frameToolWidths; + +#if defined( INPLACE_SVR ) + LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc; + LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc); + + // if in-place active, add our tools to our in-place container's frame. + if (lpTopIPFrame) { + ServerDoc_AddFrameLevelTools(lpServerDoc); + return; + } +#endif // INPLACE_SVR + + OutlineApp_GetFrameRect(g_lpApp, (LPRECT)&rcFrameRect); + FrameTools_GetRequiredBorderSpace( + lpOutlineDoc->m_lpFrameTools, + (LPBORDERWIDTHS)&frameToolWidths + ); + OutlineApp_SetBorderSpace(g_lpApp, (LPBORDERWIDTHS)&frameToolWidths); + FrameTools_AttachToFrame( + lpOutlineDoc->m_lpFrameTools, OutlineApp_GetWindow(lpOutlineApp)); + FrameTools_Move(lpOutlineDoc->m_lpFrameTools, (LPRECT)&rcFrameRect); +#endif // ! INPLACE_CNTR + +} + +#endif // USE_FRAMETOOLS + + +/* OutlineDoc_GetWindow + * -------------------- + * + * Get the window handle of the document. + */ +HWND OutlineDoc_GetWindow(LPOUTLINEDOC lpOutlineDoc) +{ + if(! lpOutlineDoc) return NULL; + return lpOutlineDoc->m_hWndDoc; +} + + +/* OutlineDoc_AddLine + * ------------------ + * + * Add one line to the Document's LineList + */ +void OutlineDoc_AddLine(LPOUTLINEDOC lpOutlineDoc, LPLINE lpLine, int nIndex) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + + LineList_AddLine(lpLL, lpLine, nIndex); + + /* Update Name Table */ + OutlineNameTable_AddLineUpdate(lpOutlineDoc->m_lpNameTable, nIndex); + +#if defined( INPLACE_CNTR ) + { + LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc; + /* OLE2NOTE: after adding a line we need to + ** update the PosRect of the In-Place active + ** objects (if any) that follow the added line. + ** NOTE: nIndex is index of line before new line. + ** nIndex+1 is index of new line + ** nIndex+2 is index of line after new line. + */ + ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, nIndex+2); + } +#endif + + OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE); +} + + +/* OutlineDoc_DeleteLine + * --------------------- + * + * + * Delete one line from the document's LineList + */ +void OutlineDoc_DeleteLine(LPOUTLINEDOC lpOutlineDoc, int nIndex) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + +#if defined( OLE_CNTR ) + LPLINE lpLine = LineList_GetLine(lpLL, nIndex); + LPSTORAGE lpStgDoc = NULL; + char szSaveStgName[CWCSTORAGENAME]; + BOOL fDeleteChildStg = FALSE; + + if (lpLine && (Line_GetLineType(lpLine) == CONTAINERLINETYPE) ) { + + /* OLE2NOTE: when a ContainerLine is being deleted by the user, + ** it is important to delete the object's sub-storage + ** otherwise it wastes space in the ContainerDoc's file. + ** this function is called when lines are deleted by the + ** Clear command and when lines are deleted by a DRAGMOVE + ** operation. + */ + LPCONTAINERLINE lpContainerLine = (LPCONTAINERLINE)lpLine; + + // save name of child storage + LSTRCPYN(szSaveStgName, lpContainerLine->m_szStgName, + sizeof(szSaveStgName)); + lpStgDoc = ((LPOLEDOC)lpContainerLine->m_lpDoc)->m_lpStg; + fDeleteChildStg = TRUE; + } +#endif // OLE_CNTR + + LineList_DeleteLine(lpLL, nIndex); + +#if defined( OLE_CNTR ) + if (fDeleteChildStg && lpStgDoc) { + HRESULT hrErr; + + // delete the obsolete child storage. it is NOT fatal if this fails + + hrErr = CallIStorageDestroyElementA(lpStgDoc, szSaveStgName); + +#if defined( _DEBUG ) + if (hrErr != NOERROR) { + OleDbgOutHResult("IStorage::DestroyElement return", hrErr); + } +#endif + } +#endif // OLE_CNTR + + /* Update Name Table */ + OutlineNameTable_DeleteLineUpdate(lpOutlineDoc->m_lpNameTable, nIndex); + +#if defined( INPLACE_CNTR ) + { + LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc; + /* OLE2NOTE: after deleting a line we need to + ** update the PosRect of the In-Place active + ** objects (if any). + */ + ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, nIndex); + } +#endif + + OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE); + +#if defined( OLE_VERSION ) + { + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPOLEDOC lpClipboardDoc = (LPOLEDOC)lpOutlineApp->m_lpClipboardDoc; + + /* OLE2NOTE: if the document that is the source of data on the + ** clipborad has just had lines deleted, then the copied data + ** is no longer considered a valid potential link source. + ** disable the offering of CF_LINKSOURCE from the clipboard + ** document. this avoids problems that arise when the + ** editing operation changes or deletes the original data + ** copied. we will not go to the trouble of determining if + ** the deleted line actually is part of the link source. + */ + if (lpClipboardDoc + && lpClipboardDoc->m_fLinkSourceAvail + && lpClipboardDoc->m_lpSrcDocOfCopy == (LPOLEDOC)lpOutlineDoc) { + lpClipboardDoc->m_fLinkSourceAvail = FALSE; + + /* OLE2NOTE: since we are changing the list of formats on + ** the clipboard (ie. removing CF_LINKSOURCE), we must + ** call OleSetClipboard again. to be sure that the + ** clipboard datatransfer document object does not get + ** destroyed we will guard the call to OleSetClipboard + ** within a pair of AddRef/Release. + */ + OleDoc_AddRef((LPOLEDOC)lpClipboardDoc); // guard obj life-time + + OLEDBG_BEGIN2("OleSetClipboard called\r\n") + OleSetClipboard( + (LPDATAOBJECT)&((LPOLEDOC)lpClipboardDoc)->m_DataObject); + OLEDBG_END2 + + OleDoc_Release((LPOLEDOC)lpClipboardDoc); // rel. AddRef above + } + } +#endif // OLE_VERSION +} + + +/* OutlineDoc_AddName + * ------------------ + * + * Add a Name to the Document's NameTable + */ +void OutlineDoc_AddName(LPOUTLINEDOC lpOutlineDoc, LPOUTLINENAME lpOutlineName) +{ + LPOUTLINENAMETABLE lpOutlineNameTable = lpOutlineDoc->m_lpNameTable; + + OutlineNameTable_AddName(lpOutlineNameTable, lpOutlineName); + + OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE); +} + + +/* OutlineDoc_DeleteName + * --------------------- + * + * + * Delete Name from the document's NameTable + */ +void OutlineDoc_DeleteName(LPOUTLINEDOC lpOutlineDoc, int nIndex) +{ + LPOUTLINENAMETABLE lpOutlineNameTable = lpOutlineDoc->m_lpNameTable; + + OutlineNameTable_DeleteName(lpOutlineNameTable, nIndex); + + OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE); +} + + +/* OutlineDoc_Destroy + * ------------------ + * + * Free all memory that had been allocated for a document. + * this destroys the LineList & NameTable of the document. + */ +void OutlineDoc_Destroy(LPOUTLINEDOC lpOutlineDoc) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; +#if defined( OLE_VERSION ) + LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp; + LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc; + + if (lpOleDoc->m_fObjIsDestroying) + return; // doc destruction is in progress +#endif // OLE_VERSION + + OLEDBG_BEGIN3("OutlineDoc_Destroy\r\n"); + +#if defined( OLE_VERSION ) + + /* OLE2NOTE: in order to guarantee that the application does not + ** prematurely exit before the destruction of the document is + ** complete, we intially AddRef the App refcnt later Release it. + ** This initial AddRef is artificial; it simply guarantees that + ** the app object does not get destroyed until the end of this + ** routine. + */ + OleApp_AddRef(lpOleApp); + + /* OLE2NOTE: perform processing required for OLE */ + OleDoc_Destroy(lpOleDoc); +#endif + + LineList_Destroy(lpLL); + OutlineNameTable_Destroy(lpOutlineDoc->m_lpNameTable); + +#if defined( USE_HEADING ) + if (! lpOutlineDoc->m_fDataTransferDoc) + Heading_Destroy((LPHEADING)&lpOutlineDoc->m_heading); +#endif + +#if defined( USE_FRAMETOOLS ) + if (! lpOutlineDoc->m_fDataTransferDoc) + FrameTools_AssociateDoc(lpOutlineDoc->m_lpFrameTools, NULL); +#endif // USE_FRAMETOOLS + + DestroyWindow(lpOutlineDoc->m_hWndDoc); + Delete(lpOutlineDoc); // free memory for doc itself + OleDbgOut1("@@@@ DOC DESTROYED\r\n"); + +#if defined( OLE_VERSION ) + OleApp_Release(lpOleApp); // release artificial AddRef above +#endif + + OLEDBG_END3 +} + + +/* OutlineDoc_ReSize + * ----------------- + * + * Resize the document and its components + * + * Parameter: + * lpRect the new size of the document. Use current size if NULL + */ +void OutlineDoc_Resize(LPOUTLINEDOC lpOutlineDoc, LPRECT lpRect) +{ + RECT rect; + LPLINELIST lpLL; + +#if defined( USE_HEADING ) + LPHEADING lphead; +#endif // USE_HEADING + + LPSCALEFACTOR lpscale; + HWND hWndLL; + + if (!lpOutlineDoc) + return; + + lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList; + lpscale = (LPSCALEFACTOR)&lpOutlineDoc->m_scale; + hWndLL = LineList_GetWindow(lpLL); + + if (lpRect) { + CopyRect((LPRECT)&rect, lpRect); + MoveWindow(lpOutlineDoc->m_hWndDoc, rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top, TRUE); + } + + GetClientRect(lpOutlineDoc->m_hWndDoc, (LPRECT)&rect); + +#if defined( USE_HEADING ) + lphead = OutlineDoc_GetHeading(lpOutlineDoc); + rect.left += Heading_RH_GetWidth(lphead, lpscale); + rect.top += Heading_CH_GetHeight(lphead, lpscale); +#endif // USE_HEADING + + if (lpLL) { + MoveWindow(hWndLL, rect.left, rect.top, + rect.right-rect.left, rect.bottom-rect.top, TRUE); + } + +#if defined( USE_HEADING ) + if (lphead) + Heading_Move(lphead, lpOutlineDoc->m_hWndDoc, lpscale); +#endif // USE_HEADING + +#if defined( INPLACE_CNTR ) + ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0); +#endif +} + + +/* OutlineDoc_GetNameTable + * ----------------------- + * + * Get nametable associated with the line list + */ +LPOUTLINENAMETABLE OutlineDoc_GetNameTable(LPOUTLINEDOC lpOutlineDoc) +{ + if (!lpOutlineDoc) + return NULL; + else + return lpOutlineDoc->m_lpNameTable; +} + + +/* OutlineDoc_GetLineList + * ---------------------- + * + * Get listlist associated with the OutlineDoc + */ +LPLINELIST OutlineDoc_GetLineList(LPOUTLINEDOC lpOutlineDoc) +{ + if (!lpOutlineDoc) + return NULL; + else + return (LPLINELIST)&lpOutlineDoc->m_LineList; +} + + +/* OutlineDoc_GetNameCount + * ----------------------- + * + * Return number of names in table + */ +int OutlineDoc_GetNameCount(LPOUTLINEDOC lpOutlineDoc) +{ + return OutlineNameTable_GetCount(lpOutlineDoc->m_lpNameTable); +} + + +/* OutlineDoc_GetLineCount + * ----------------------- + * + * Return number of lines in the LineList + */ +int OutlineDoc_GetLineCount(LPOUTLINEDOC lpOutlineDoc) +{ + return LineList_GetCount(&lpOutlineDoc->m_LineList); +} + + +/* OutlineDoc_SetFileName + * ---------------------- + * + * Set the filename of a document. + * + * OLE2NOTE: If the ServerDoc has a valid filename then, the object is + * registered in the running object table (ROT). if the name of the doc + * changes (eg. via SaveAs) then the previous registration must be revoked + * and the document re-registered under the new name. + */ +BOOL OutlineDoc_SetFileName(LPOUTLINEDOC lpOutlineDoc, LPSTR lpszNewFileName, LPSTORAGE lpNewStg) +{ + OleDbgAssertSz(lpszNewFileName != NULL, "Can't reset doc to Untitled!"); + if (lpszNewFileName == NULL) + return FALSE; + + AnsiLowerBuff(lpszNewFileName, (UINT)lstrlen(lpszNewFileName)); + +#if defined( OLE_CNTR ) + { + LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc; + LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc; + + /* OLE2NOTE: the container version of the application keeps its + ** storage open at all times. if the document's storage is not + ** open, then open it. + */ + + if (lpNewStg) { + + /* CASE 1 -- document is being loaded from a file. lpNewStg is + ** still open from the OutlineDoc_LoadFromFile function. + */ + + lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE; + + } else { + + /* CASE 2 -- document is being associated with a valid file + ** that is not yet open. thus we must now open the file. + */ + + if (lpOutlineDoc->m_docInitType == DOCTYPE_FROMFILE && + lstrcmp(lpOutlineDoc->m_szFileName,lpszNewFileName)==0) { + + /* CASE 2a -- new filename is same as current file. if the + ** stg is already open, then the lpStg is still valid. + ** if it is not open, then open it. + */ + if (! lpOleDoc->m_lpStg) { + lpOleDoc->m_lpStg = OleStdOpenRootStorage( + lpszNewFileName, + STGM_READWRITE | STGM_SHARE_DENY_WRITE + ); + if (! lpOleDoc->m_lpStg) return FALSE; + } + + } else { + + /* CASE 2b -- new filename is NOT same as current file. + ** a SaveAs operation is pending. open the new file and + ** hold the storage pointer in m_lpNewStg. the + ** subsequent call to Doc_SaveToFile will save the + ** document into the new storage pointer and release the + ** old storage pointer. + */ + + lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE; + + lpContainerDoc->m_lpNewStg = OleStdCreateRootStorage( + lpszNewFileName, + STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_CREATE + ); + if (! lpContainerDoc->m_lpNewStg) return FALSE; + } + } + } +#endif // OLE_CNTR + + if (lpOutlineDoc->m_docInitType != DOCTYPE_FROMFILE || + lstrcmp(lpOutlineDoc->m_szFileName, lpszNewFileName) != 0) { + + /* A new valid file name is being associated with the document */ + + lstrcpy(lpOutlineDoc->m_szFileName, lpszNewFileName); + lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE; + + // set lpszDocTitle to point to filename without path + lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName + + lstrlen(lpOutlineDoc->m_szFileName) - 1; + while (lpOutlineDoc->m_lpszDocTitle > lpOutlineDoc->m_szFileName + && ! IS_FILENAME_DELIM(lpOutlineDoc->m_lpszDocTitle[-1])) { + lpOutlineDoc->m_lpszDocTitle--; + } + + OutlineDoc_SetTitle(lpOutlineDoc, TRUE /*fMakeUpperCase*/); + +#if defined( OLE_VERSION ) + { + /* OLE2NOTE: both containers and servers must properly + ** register in the RunningObjectTable. if the document + ** is performing a SaveAs operation, then it must + ** re-register in the ROT with the new moniker. in + ** addition any embedded object, pseudo objects, and/or + ** linking clients must be informed that the document's + ** moniker has changed. + */ + + LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc; + + if (lpOleDoc->m_lpFileMoniker) { + OleStdRelease((LPUNKNOWN)lpOleDoc->m_lpFileMoniker); + lpOleDoc->m_lpFileMoniker = NULL; + } + + CreateFileMonikerA(lpszNewFileName, + &lpOleDoc->m_lpFileMoniker); + + OleDoc_DocRenamedUpdate(lpOleDoc, lpOleDoc->m_lpFileMoniker); + } +#endif // OLE_VERSION + + } + + return TRUE; +} + + +/* OutlineDoc_SetTitle + * ------------------- + * + * Set window text to be current filename. + * The following window hierarchy exits: + * hWndApp + * hWndDoc + * hWndListBox + * The frame window is the window which gets the title. + */ +void OutlineDoc_SetTitle(LPOUTLINEDOC lpOutlineDoc, BOOL fMakeUpperCase) +{ + HWND hWnd; + LPSTR lpszText; + + if (!lpOutlineDoc->m_hWndDoc) return; + if ((hWnd = GetParent(lpOutlineDoc->m_hWndDoc)) == NULL) return; + + lpszText = OleStdMalloc((UINT)(lstrlen(APPNAME) + 4 + + lstrlen(lpOutlineDoc->m_lpszDocTitle))); + if (!lpszText) return; + + lstrcpy(lpszText, APPNAME); + lstrcat(lpszText," - "); + lstrcat(lpszText, (LPSTR)lpOutlineDoc->m_lpszDocTitle); + + if (fMakeUpperCase) + AnsiUpperBuff(lpszText, (UINT)lstrlen(lpszText)); + + SetWindowText(hWnd,lpszText); + OleStdFree(lpszText); +} + + +/* OutlineDoc_Close + * ---------------- + * + * Close active document. If modified, prompt the user if + * he wants to save. + * + * Returns: + * FALSE -- user canceled the closing of the doc. + * TRUE -- the doc was successfully closed + */ +BOOL OutlineDoc_Close(LPOUTLINEDOC lpOutlineDoc, DWORD dwSaveOption) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + +#if defined( OLE_VERSION ) + /* OLE2NOTE: call OLE specific function instead */ + return OleDoc_Close((LPOLEDOC)lpOutlineDoc, dwSaveOption); + +#else + + if (! lpOutlineDoc) + return TRUE; // active doc's are already destroyed + + if (! OutlineDoc_CheckSaveChanges(lpOutlineDoc, &dwSaveOption)) + return FALSE; // abort closing the doc + + OutlineDoc_Destroy(lpOutlineDoc); + + OutlineApp_DocUnlockApp(lpOutlineApp, lpOutlineDoc); + + return TRUE; + +#endif // ! OLE_VERSION +} + + +/* OutlineDoc_CheckSaveChanges + * --------------------------- + * + * Check if the document has been modified. if so, prompt the user if + * the changes should be saved. if yes save them. + * Returns TRUE if the doc is safe to close (user answered Yes or No) + * FALSE if the user canceled the save changes option. + */ +BOOL OutlineDoc_CheckSaveChanges( + LPOUTLINEDOC lpOutlineDoc, + LPDWORD lpdwSaveOption +) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + int nResponse; + + if (*lpdwSaveOption == OLECLOSE_NOSAVE) + return TRUE; + + if(! OutlineDoc_IsModified(lpOutlineDoc)) + return TRUE; // saving is not necessary + + /* OLE2NOTE: our document is dirty so it needs to be saved. if + ** OLECLOSE_PROMPTSAVE the user should be prompted to see if the + ** document should be saved. is specified but the document is NOT + ** visible to the user, then the user can NOT be prompted. in + ** the situation the document should be saved without prompting. + ** if OLECLOSE_SAVEIFDIRTY is specified then, the document + ** should also be saved without prompting. + */ + if (*lpdwSaveOption == OLECLOSE_PROMPTSAVE && + IsWindowVisible(lpOutlineDoc->m_hWndDoc)) { + + // prompt the user to see if changes should be saved. +#if defined( OLE_VERSION ) + OleApp_PreModalDialog( + (LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineApp->m_lpDoc); +#endif + nResponse = MessageBox( + lpOutlineApp->m_hWndApp, + MsgSaveFile, + APPNAME, + MB_ICONQUESTION | MB_YESNOCANCEL + ); +#if defined( OLE_VERSION ) + OleApp_PostModalDialog( + (LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineApp->m_lpDoc); +#endif + if(nResponse==IDCANCEL) + return FALSE; // close is canceled + if(nResponse==IDNO) { + // Reset the save option to NOSAVE per user choice + *lpdwSaveOption = OLECLOSE_NOSAVE; + return TRUE; // don't save, but is ok to close + } + } else if (*lpdwSaveOption != OLECLOSE_SAVEIFDIRTY) { + OleDbgAssertSz(FALSE, "Invalid dwSaveOption\r\n"); + *lpdwSaveOption = OLECLOSE_NOSAVE; + return TRUE; // unknown *lpdwSaveOption; close w/o saving + } + +#if defined( OLE_SERVER ) + if (lpOutlineDoc->m_docInitType == DOCTYPE_EMBEDDED) { + LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc; + HRESULT hrErr; + + /* OLE2NOTE: Update the container before closing without prompting + ** the user. To update the container, we must ask our container + ** to save us. + */ + OleDbgAssert(lpServerDoc->m_lpOleClientSite != NULL); + OLEDBG_BEGIN2("IOleClientSite::SaveObject called\r\n") + hrErr = lpServerDoc->m_lpOleClientSite->lpVtbl->SaveObject( + lpServerDoc->m_lpOleClientSite + ); + OLEDBG_END2 + + if (hrErr != NOERROR) { + OleDbgOutHResult("IOleClientSite::SaveObject returned", hrErr); + return FALSE; + } + + return TRUE; // doc is safe to be closed + + } else +#endif // OLE_SERVER + { + return OutlineApp_SaveCommand(lpOutlineApp); + } +} + + +/* OutlineDoc_IsModified + * --------------------- + * + * Return modify flag of OUTLINEDOC + */ +BOOL OutlineDoc_IsModified(LPOUTLINEDOC lpOutlineDoc) +{ + if (lpOutlineDoc->m_fModified) + return lpOutlineDoc->m_fModified; + +#if defined( OLE_CNTR ) + { + /* OLE2NOTE: if there are OLE objects, then we must ask if any of + ** them are dirty. if so we must consider our document + ** as modified. + */ + LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc; + LPLINELIST lpLL; + int nLines; + int nIndex; + LPLINE lpLine; + HRESULT hrErr; + + lpLL = (LPLINELIST)&((LPOUTLINEDOC)lpContainerDoc)->m_LineList; + nLines = LineList_GetCount(lpLL); + + for (nIndex = 0; nIndex < nLines; nIndex++) { + lpLine = LineList_GetLine(lpLL, nIndex); + if (!lpLine) + break; + if (Line_GetLineType(lpLine) == CONTAINERLINETYPE) { + LPCONTAINERLINE lpContainerLine = (LPCONTAINERLINE)lpLine; + if (lpContainerLine->m_lpPersistStg) { + hrErr = lpContainerLine->m_lpPersistStg->lpVtbl->IsDirty( + lpContainerLine->m_lpPersistStg); + /* OLE2NOTE: we will only accept an explicit "no i + ** am NOT dirty statement" (ie. S_FALSE) as an + ** indication that the object is clean. eg. if + ** the object returns E_NOTIMPL we must + ** interpret it as the object IS dirty. + */ + if (GetScode(hrErr) != S_FALSE) + return TRUE; + } + } + } + } +#endif + return FALSE; +} + + +/* OutlineDoc_SetModified + * ---------------------- + * + * Set the modified flag of the document + * + */ +void OutlineDoc_SetModified(LPOUTLINEDOC lpOutlineDoc, BOOL fModified, BOOL fDataChanged, BOOL fSizeChanged) +{ + lpOutlineDoc->m_fModified = fModified; + +#if defined( OLE_SERVER ) + if (! lpOutlineDoc->m_fDataTransferDoc) { + LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc; + + /* OLE2NOTE: if the document has changed, then broadcast the change + ** to all clients who have set up Advise connections. notify + ** them that our data (and possibly also our extents) have + ** changed. + */ + if (fDataChanged) { + lpServerDoc->m_fDataChanged = TRUE; + lpServerDoc->m_fSizeChanged = fSizeChanged; + lpServerDoc->m_fSendDataOnStop = TRUE; + + ServerDoc_SendAdvise( + lpServerDoc, + OLE_ONDATACHANGE, + NULL, /* lpmkDoc -- not relevant here */ + 0 /* advf -- no flags necessary */ + ); + } + } +#endif // OLE_SERVER +} + + +/* OutlineDoc_SetRedraw + * -------------------- + * + * Enable/Disable the redraw of the document on screen. + * The calls to SetRedraw counted so that nested calls can be handled + * properly. calls to SetRedraw must be balanced. + * + * fEnbaleDraw = TRUE - enable redraw + * FALSE - disable redraw + */ +void OutlineDoc_SetRedraw(LPOUTLINEDOC lpOutlineDoc, BOOL fEnableDraw) +{ + static HCURSOR hPrevCursor = NULL; + + if (fEnableDraw) { + if (lpOutlineDoc->m_nDisableDraw == 0) + return; // already enabled; no state transition + + if (--lpOutlineDoc->m_nDisableDraw > 0) + return; // drawing should still be disabled + } else { + if (lpOutlineDoc->m_nDisableDraw++ > 0) + return; // already disabled; no state transition + } + + if (lpOutlineDoc->m_nDisableDraw > 0) { + // this may take a while, put up hourglass cursor + hPrevCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); + } else { + if (hPrevCursor) { + SetCursor(hPrevCursor); // restore original cursor + hPrevCursor = NULL; + } + } + +#if defined( OLE_SERVER ) + /* OLE2NOTE: for the Server version, while Redraw is disabled + ** postpone sending advise notifications until Redraw is re-enabled. + */ + { + LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc; + LPSERVERNAMETABLE lpServerNameTable = + (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable; + + if (lpOutlineDoc->m_nDisableDraw == 0) { + /* drawing is being Enabled. if changes occurred while drawing + ** was disabled, then notify clients now. + */ + if (lpServerDoc->m_fDataChanged) + ServerDoc_SendAdvise( + lpServerDoc, + OLE_ONDATACHANGE, + NULL, /* lpmkDoc -- not relevant here */ + 0 /* advf -- no flags necessary */ + ); + + /* OLE2NOTE: send pending change notifications for pseudo objs. */ + ServerNameTable_SendPendingAdvises(lpServerNameTable); + + } + } +#endif // OLE_SERVER + +#if defined( OLE_CNTR ) + /* OLE2NOTE: for the Container version, while Redraw is disabled + ** postpone updating the extents of OLE objects until Redraw is + ** re-enabled. + */ + { + LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc; + + /* Update the extents of any OLE object that is marked that + ** its size may have changed. when an + ** IAdviseSink::OnViewChange notification is received, + ** the corresponding ContainerLine is marked + ** (m_fDoGetExtent==TRUE) and a message + ** (WM_U_UPDATEOBJECTEXTENT) is posted to the document + ** indicating that there are dirty objects. + */ + if (lpOutlineDoc->m_nDisableDraw == 0) + ContainerDoc_UpdateExtentOfAllOleObjects(lpContainerDoc); + } +#endif // OLE_CNTR + + // enable/disable redraw of the LineList listbox + LineList_SetRedraw(&lpOutlineDoc->m_LineList, fEnableDraw); +} + + +/* OutlineDoc_SetSel + * ----------------- + * + * Set the selection in the documents's LineList + */ +void OutlineDoc_SetSel(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel) +{ + LineList_SetSel(&lpOutlineDoc->m_LineList, lplrSel); +} + + +/* OutlineDoc_GetSel + * ----------------- + * + * Get the selection in the documents's LineList. + * + * Returns the count of items selected + */ +int OutlineDoc_GetSel(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel) +{ + return LineList_GetSel(&lpOutlineDoc->m_LineList, lplrSel); +} + + +/* OutlineDoc_ForceRedraw + * ---------------------- + * + * Force the document window to repaint. + */ +void OutlineDoc_ForceRedraw(LPOUTLINEDOC lpOutlineDoc, BOOL fErase) +{ + if (!lpOutlineDoc) + return; + + LineList_ForceRedraw(&lpOutlineDoc->m_LineList, fErase); + Heading_CH_ForceRedraw(&lpOutlineDoc->m_heading, fErase); + Heading_RH_ForceRedraw(&lpOutlineDoc->m_heading, fErase); +} + + +/* OutlineDoc_RenderFormat + * ----------------------- + * + * Render a clipboard format supported by ClipboardDoc + */ +void OutlineDoc_RenderFormat(LPOUTLINEDOC lpOutlineDoc, UINT uFormat) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + HGLOBAL hData = NULL; + + if (uFormat == lpOutlineApp->m_cfOutline) + hData = OutlineDoc_GetOutlineData(lpOutlineDoc, NULL); + + else if (uFormat == CF_TEXT) + hData = OutlineDoc_GetTextData(lpOutlineDoc, NULL); + + else { + OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgFormatNotSupported); + return; + } + + SetClipboardData(uFormat, hData); +} + + +/* OutlineDoc_RenderAllFormats + * --------------------------- + * + * Render all formats supported by ClipboardDoc + */ +void OutlineDoc_RenderAllFormats(LPOUTLINEDOC lpOutlineDoc) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + HGLOBAL hData = NULL; + + OpenClipboard(lpOutlineDoc->m_hWndDoc); + + hData = OutlineDoc_GetOutlineData(lpOutlineDoc, NULL); + SetClipboardData(lpOutlineApp->m_cfOutline, hData); + + hData = OutlineDoc_GetTextData(lpOutlineDoc, NULL); + SetClipboardData(CF_TEXT, hData); + + CloseClipboard(); +} + + + +/* OutlineDoc_GetOutlineData + * ------------------------- + * + * Return a handle to an array of TextLine objects for the desired line + * range. + * NOTE: if lplrSel == NULL, then all lines are returned + * + */ +HGLOBAL OutlineDoc_GetOutlineData(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel) +{ + HGLOBAL hOutline = NULL; + LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList; + LPLINE lpLine; + LPTEXTLINE arrLine; + int i; + int nStart = (lplrSel ? lplrSel->m_nStartLine : 0); + int nEnd =(lplrSel ? lplrSel->m_nEndLine : LineList_GetCount(lpLL)-1); + int nLines = nEnd - nStart + 1; + int nCopied = 0; + + hOutline=GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT,sizeof(TEXTLINE)*nLines); + + if (! hOutline) return NULL; + + arrLine=(LPTEXTLINE)GlobalLock(hOutline); + + for (i = nStart; i <= nEnd; i++) { + lpLine=LineList_GetLine(lpLL, i); + if (lpLine && Line_GetOutlineData(lpLine, &arrLine[nCopied])) + nCopied++; + } + + GlobalUnlock(hOutline); + + return hOutline; +} + + + +/* OutlineDoc_GetTextData + * ---------------------- + * + * Return a handle to an object's data in text form for the desired line + * range. + * NOTE: if lplrSel == NULL, then all lines are returned + * + */ +HGLOBAL OutlineDoc_GetTextData(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel) +{ + LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList; + LPLINE lpLine; + HGLOBAL hText = NULL; + LPSTR lpszText = NULL; + DWORD dwMemSize=0; + int i,j; + int nStart = (lplrSel ? lplrSel->m_nStartLine : 0); + int nEnd =(lplrSel ? lplrSel->m_nEndLine : LineList_GetCount(lpLL)-1); + int nTabLevel; + + // calculate memory size required + for(i = nStart; i <= nEnd; i++) { + lpLine=LineList_GetLine(lpLL, i); + if (! lpLine) + continue; + + dwMemSize += Line_GetTabLevel(lpLine); + dwMemSize += Line_GetTextLen(lpLine); + + dwMemSize += 2; // add 1 for '\r\n' at the end of each line + } + dwMemSize++; // add 1 for '\0' at the end of string + + if(!(hText = GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT, dwMemSize))) + return NULL; + + if(!(lpszText = (LPSTR)GlobalLock(hText))) + return NULL; + + // put line text to memory + for(i = nStart; i <= nEnd; i++) { + lpLine=LineList_GetLine(lpLL, i); + if (! lpLine) + continue; + + nTabLevel=Line_GetTabLevel(lpLine); + for(j = 0; j < nTabLevel; j++) + *lpszText++='\t'; + + Line_GetTextData(lpLine, lpszText); + while(*lpszText) + lpszText++; // advance to end of string + + *lpszText++ = '\r'; + *lpszText++ = '\n'; + } + + GlobalUnlock (hText); + + return hText; +} + + +/* OutlineDoc_SaveToFile + * --------------------- + * + * Save the document to a file with the same name as stored in the + * document + */ +BOOL OutlineDoc_SaveToFile(LPOUTLINEDOC lpOutlineDoc, LPCSTR lpszFileName, UINT uFormat, BOOL fRemember) +{ +#if defined( OLE_CNTR ) + // Call OLE container specific function instead + return ContainerDoc_SaveToFile( + (LPCONTAINERDOC)lpOutlineDoc, + lpszFileName, + uFormat, + fRemember + ); + +#else + + LPSTORAGE lpDestStg = NULL; + HRESULT hrErr; + BOOL fStatus; + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + + if (fRemember) { + if (lpszFileName) { + fStatus = OutlineDoc_SetFileName( + lpOutlineDoc, + (LPSTR)lpszFileName, + NULL + ); + if (! fStatus) goto error; + } else + lpszFileName = lpOutlineDoc->m_szFileName; // use cur. file name + } else if (! lpszFileName) { + goto error; + } + + hrErr = StgCreateDocfileA( + lpszFileName, + STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE|STGM_CREATE, + 0, + &lpDestStg + ); + + OleDbgAssertSz(hrErr == NOERROR, "Could not create Docfile"); + if (hrErr != NOERROR) + goto error; + +#if defined( OLE_SERVER ) + + /* OLE2NOTE: we must be sure to write our class ID into our + ** storage. this information is used by OLE to determine the + ** class of the data stored in our storage. Even for top + ** "file-level" objects this information should be written to + ** the file. + */ + if(WriteClassStg(lpDestStg, &CLSID_APP) != NOERROR) + goto error; +#endif + + fStatus = OutlineDoc_SaveSelToStg( + lpOutlineDoc, + NULL, + uFormat, + lpDestStg, + FALSE, /* fSameAsLoad */ + fRemember + ); + if (! fStatus) goto error; + + OleStdRelease((LPUNKNOWN)lpDestStg); + + if (fRemember) + OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE); + +#if defined( OLE_SERVER ) + + /* OLE2NOTE: (SERVER-ONLY) inform any linking clients that the + ** document has been saved. in addition, any currently active + ** pseudo objects should also inform their clients. + */ + ServerDoc_SendAdvise ( + (LPSERVERDOC)lpOutlineDoc, + OLE_ONSAVE, + NULL, /* lpmkDoc -- not relevant here */ + 0 /* advf -- not relevant here */ + ); + +#endif + + return TRUE; + +error: + if (lpDestStg) + OleStdRelease((LPUNKNOWN)lpDestStg); + + OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgSaving); + return FALSE; + +#endif // ! OLE_CNTR +} + + +/* OutlineDoc_LoadFromFile + * ----------------------- + * + * Load a document from a file + */ +BOOL OutlineDoc_LoadFromFile(LPOUTLINEDOC lpOutlineDoc, LPSTR lpszFileName) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + HRESULT hrErr; + SCODE sc; + LPSTORAGE lpSrcStg; + BOOL fStatus; + + hrErr = StgOpenStorageA(lpszFileName, + NULL, +#if defined( OLE_CNTR ) + STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE, +#else + STGM_READ | STGM_SHARE_DENY_WRITE, +#endif + NULL, + 0, + &lpSrcStg + ); + + if ((sc = GetScode(hrErr)) == STG_E_FILENOTFOUND) { + OutlineApp_ErrorMessage(lpOutlineApp, "File not found"); + return FALSE; + } else if (sc == STG_E_FILEALREADYEXISTS) { + OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgFormat); + return FALSE; + } else if (sc != S_OK) { + OleDbgOutScode("StgOpenStorage returned", sc); + OutlineApp_ErrorMessage( + lpOutlineApp, + "File already in use--could not be opened" + ); + return FALSE; + } + + if(! OutlineDoc_LoadFromStg(lpOutlineDoc, lpSrcStg)) goto error; + + fStatus = OutlineDoc_SetFileName(lpOutlineDoc, lpszFileName, lpSrcStg); + if (! fStatus) goto error; + + OleStdRelease((LPUNKNOWN)lpSrcStg); + + return TRUE; + +error: + OleStdRelease((LPUNKNOWN)lpSrcStg); + OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgOpening); + return FALSE; +} + + + +/* OutlineDoc_LoadFromStg + * ---------------------- + * + * Load entire document from an open IStorage pointer (lpSrcStg) + * Return TRUE if ok, FALSE if error. + */ +BOOL OutlineDoc_LoadFromStg(LPOUTLINEDOC lpOutlineDoc, LPSTORAGE lpSrcStg) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + HRESULT hrErr; + BOOL fStatus; + ULONG nRead; + LINERANGE lrSel = { 0, 0 }; + LPSTREAM lpLLStm; + OUTLINEDOCHEADER_ONDISK docRecordOnDisk; + OUTLINEDOCHEADER docRecord; + + hrErr = CallIStorageOpenStreamA( + lpSrcStg, + "LineList", + NULL, + STGM_READ | STGM_SHARE_EXCLUSIVE, + 0, + &lpLLStm + ); + + if (hrErr != NOERROR) { + OleDbgOutHResult("Open LineList Stream returned", hrErr); + goto error; + } + + /* read OutlineDoc header record */ + hrErr = lpLLStm->lpVtbl->Read( + lpLLStm, + (LPVOID)&docRecordOnDisk, + sizeof(docRecordOnDisk), + &nRead + ); + + if (hrErr != NOERROR) { + OleDbgOutHResult("Read OutlineDoc header returned", hrErr); + goto error; + } + + // Transform docRecordOnDisk into docRecord + // Compilers should handle aligment correctly + strcpy(docRecord.m_szFormatName, docRecordOnDisk.m_szFormatName); + docRecord.m_narrAppVersionNo[0] = (int) docRecordOnDisk.m_narrAppVersionNo[0]; + docRecord.m_narrAppVersionNo[1] = (int) docRecordOnDisk.m_narrAppVersionNo[1]; + docRecord.m_fShowHeading = (BOOL) docRecordOnDisk.m_fShowHeading; + docRecord.m_reserved1 = docRecordOnDisk.m_reserved1; + docRecord.m_reserved2 = docRecordOnDisk.m_reserved2; + docRecord.m_reserved3 = docRecordOnDisk.m_reserved3; + docRecord.m_reserved4 = docRecordOnDisk.m_reserved4; + + fStatus = OutlineApp_VersionNoCheck( + lpOutlineApp, + docRecord.m_szFormatName, + docRecord.m_narrAppVersionNo + ); + + /* storage is an incompatible version; file can not be read */ + if (! fStatus) + goto error; + + lpOutlineDoc->m_heading.m_fShow = docRecord.m_fShowHeading; + +#if defined( OLE_SERVER ) + { + // Load ServerDoc specific data + LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc; +#if defined( SVR_TREATAS ) + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + CLSID clsid; + CLIPFORMAT cfFmt; + LPSTR lpszType; +#endif // SVR_TREATAS + + lpServerDoc->m_nNextRangeNo = (ULONG)docRecord.m_reserved1; + +#if defined( SVR_TREATAS ) + /* OLE2NOTE: if the Server is capable of supporting "TreatAs" + ** (aka. ActivateAs), it must read the class that is written + ** into the storage. if this class is NOT the app's own + ** class ID, then this is a TreatAs operation. the server + ** then must faithfully pretend to be the class that is + ** written into the storage. it must also faithfully write + ** the data back to the storage in the SAME format as is + ** written in the storage. + ** + ** SVROUTL and ISVROTL can emulate each other. they have the + ** simplification that they both read/write the identical + ** format. thus for these apps no actual conversion of the + ** native bits is actually required. + */ + lpServerDoc->m_clsidTreatAs = CLSID_NULL; + if (OleStdGetTreatAsFmtUserType(&CLSID_APP, lpSrcStg, &clsid, + (CLIPFORMAT FAR*)&cfFmt, (LPSTR FAR*)&lpszType)) { + + if (cfFmt == lpOutlineApp->m_cfOutline) { + // We should perform TreatAs operation + if (lpServerDoc->m_lpszTreatAsType) + OleStdFreeString(lpServerDoc->m_lpszTreatAsType, NULL); + + lpServerDoc->m_clsidTreatAs = clsid; + ((LPOUTLINEDOC)lpServerDoc)->m_cfSaveFormat = cfFmt; + lpServerDoc->m_lpszTreatAsType = lpszType; + + OleDbgOut3("OutlineDoc_LoadFromStg: TreateAs ==> '"); + OleDbgOutNoPrefix3(lpServerDoc->m_lpszTreatAsType); + OleDbgOutNoPrefix3("'\r\n"); + } else { + // ERROR: we ONLY support TreatAs for CF_OUTLINE format + OleDbgOut("SvrDoc_PStg_InitNew: INVALID TreatAs Format\r\n"); + OleStdFreeString(lpszType, NULL); + } + } +#endif // SVR_TREATAS + } +#endif // OLE_SVR +#if defined( OLE_CNTR ) + { + // Load ContainerDoc specific data + LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc; + + lpContainerDoc->m_nNextObjNo = (ULONG)docRecord.m_reserved2; + } +#endif // OLE_CNTR + + OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE ); + + if(! LineList_LoadFromStg(&lpOutlineDoc->m_LineList, lpSrcStg, lpLLStm)) + goto error; + if(! OutlineNameTable_LoadFromStg(lpOutlineDoc->m_lpNameTable, lpSrcStg)) + goto error; + + OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE); + OutlineDoc_SetSel(lpOutlineDoc, &lrSel); + + OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE ); + + OleStdRelease((LPUNKNOWN)lpLLStm); + +#if defined( OLE_CNTR ) + { + LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc; + + /* A ContainerDoc keeps its storage open at all times. it is necessary + * to AddRef the lpSrcStg in order to hang on to it. + */ + if (lpOleDoc->m_lpStg) { + OleStdVerifyRelease((LPUNKNOWN)lpOleDoc->m_lpStg, + "Doc Storage not released properly"); + } + lpSrcStg->lpVtbl->AddRef(lpSrcStg); + lpOleDoc->m_lpStg = lpSrcStg; + } +#endif // OLE_CNTR + + return TRUE; + +error: + OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE ); + if (lpLLStm) + OleStdRelease((LPUNKNOWN)lpLLStm); + return FALSE; +} + +BOOL Booga(void) +{ + return FALSE; +} + + +/* OutlineDoc_SaveSelToStg + * ----------------------- + * + * Save the specified selection of document into an IStorage*. All lines + * within the selection along with any names completely contained within the + * selection will be written + * + * Return TRUE if ok, FALSE if error + */ +BOOL OutlineDoc_SaveSelToStg( + LPOUTLINEDOC lpOutlineDoc, + LPLINERANGE lplrSel, + UINT uFormat, + LPSTORAGE lpDestStg, + BOOL fSameAsLoad, + BOOL fRemember +) +{ + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + HRESULT hrErr = NOERROR; + LPSTREAM lpLLStm = NULL; + LPSTREAM lpNTStm = NULL; + ULONG nWritten; + BOOL fStatus; + OUTLINEDOCHEADER docRecord; + OUTLINEDOCHEADER_ONDISK docRecordOnDisk; + HCURSOR hPrevCursor; + +#if defined( OLE_VERSION ) + LPSTR lpszUserType; + LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc; + + /* OLE2NOTE: we must be sure to write the information required for + ** OLE into our docfile. this includes user type + ** name, data format, etc. Even for top "file-level" objects + ** this information should be written to the file. Both + ** containters and servers should write this information. + */ + +#if defined( OLE_SERVER ) && defined( SVR_TREATAS ) + LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc; + + /* OLE2NOTE: if the Server is emulating another class (ie. + ** "TreatAs" aka. ActivateAs), it must write the same user type + ** name and format that was was originally written into the + ** storage rather than its own user type name. + ** + ** SVROUTL and ISVROTL can emulate each other. they have the + ** simplification that they both read/write the identical + ** format. thus for these apps no actual conversion of the + ** native bits is actually required. + */ + if (! IsEqualCLSID(&lpServerDoc->m_clsidTreatAs, &CLSID_NULL)) + lpszUserType = lpServerDoc->m_lpszTreatAsType; + else +#endif // OLE_SERVER && SVR_TREATAS + + lpszUserType = (LPSTR)FULLUSERTYPENAME; + + hrErr = WriteFmtUserTypeStgA(lpDestStg, (CLIPFORMAT) uFormat, + lpszUserType); + + if(hrErr != NOERROR) goto error; + + if (fSameAsLoad) { + /* OLE2NOTE: we are saving into to same storage that we were + ** passed an load time. we deliberatly opened the streams we + ** need (lpLLStm and lpNTStm) at load time, so that we can + ** robustly save at save time in a low-memory situation. + ** this is particulary important the embedded objects do NOT + ** consume additional memory when + ** IPersistStorage::Save(fSameAsLoad==TRUE) is called. + */ + LARGE_INTEGER libZero; + ULARGE_INTEGER ulibZero; + LISet32( libZero, 0 ); + LISet32( ulibZero, 0 ); + lpLLStm = lpOleDoc->m_lpLLStm; + + /* because this is the fSameAsLoad==TRUE case, we will save + ** into the streams that we hold open. we will AddRef the + ** stream here so that the release below will NOT close the + ** stream. + */ + lpLLStm->lpVtbl->AddRef(lpLLStm); + + // truncate the current stream and seek to beginning + lpLLStm->lpVtbl->SetSize(lpLLStm, ulibZero); + lpLLStm->lpVtbl->Seek( + lpLLStm, libZero, STREAM_SEEK_SET, NULL); + + lpNTStm = lpOleDoc->m_lpNTStm; + lpNTStm->lpVtbl->AddRef(lpNTStm); // (see comment above) + + // truncate the current stream and seek to beginning + lpNTStm->lpVtbl->SetSize(lpNTStm, ulibZero); + lpNTStm->lpVtbl->Seek( + lpNTStm, libZero, STREAM_SEEK_SET, NULL); + } else +#endif // OLE_VERSION + { + hrErr = CallIStorageCreateStreamA( + lpDestStg, + "LineList", + STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, + 0, + 0, + &lpLLStm + ); + + if (hrErr != NOERROR) { + OleDbgAssertSz(hrErr==NOERROR,"Could not create LineList stream"); + OleDbgOutHResult("LineList CreateStream returned", hrErr); + goto error; + } + + hrErr = CallIStorageCreateStreamA( + lpDestStg, + "NameTable", + STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, + 0, + 0, + &lpNTStm + ); + + if (hrErr != NOERROR) { + OleDbgAssertSz(hrErr==NOERROR,"Could not create NameTable stream"); + OleDbgOutHResult("NameTable CreateStream returned", hrErr); + goto error; + } + } + + // this may take a while, put up hourglass cursor + hPrevCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); + + _fmemset((LPOUTLINEDOCHEADER)&docRecord,0,sizeof(OUTLINEDOCHEADER)); + GetClipboardFormatName( + uFormat, + docRecord.m_szFormatName, + sizeof(docRecord.m_szFormatName) + ); + OutlineApp_GetAppVersionNo(lpOutlineApp, docRecord.m_narrAppVersionNo); + + docRecord.m_fShowHeading = lpOutlineDoc->m_heading.m_fShow; + +#if defined( OLE_SERVER ) + { + // Store ServerDoc specific data + LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc; + + docRecord.m_reserved1 = (DWORD)lpServerDoc->m_nNextRangeNo; + } +#endif +#if defined( OLE_CNTR ) + { + // Store ContainerDoc specific data + LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc; + + docRecord.m_reserved2 = (DWORD)lpContainerDoc->m_nNextObjNo; + } +#endif + + /* write OutlineDoc header record */ + + // Transform docRecord into docRecordOnDisk + // Compilers should handle aligment correctly + strcpy(docRecordOnDisk.m_szFormatName, docRecord.m_szFormatName); + docRecordOnDisk.m_narrAppVersionNo[0] = (short) docRecord.m_narrAppVersionNo[0]; + docRecordOnDisk.m_narrAppVersionNo[1] = (short) docRecord.m_narrAppVersionNo[1]; + docRecordOnDisk.m_fShowHeading = (USHORT) docRecord.m_fShowHeading; + docRecordOnDisk.m_reserved1 = docRecord.m_reserved1; + docRecordOnDisk.m_reserved2 = docRecord.m_reserved2; + docRecordOnDisk.m_reserved3 = docRecord.m_reserved3; + docRecordOnDisk.m_reserved4 = docRecord.m_reserved4; + + hrErr = lpLLStm->lpVtbl->Write( + lpLLStm, + (LPVOID)&docRecordOnDisk, + sizeof(docRecordOnDisk), + &nWritten + ); + + if (hrErr != NOERROR) { + OleDbgOutHResult("Write OutlineDoc header returned", hrErr); + goto error; + } + + // Save LineList + /* OLE2NOTE: A ContainerDoc keeps its storage open at all times. It is + ** necessary to pass the current open storage (lpOleDoc->m_lpStg) + ** to the LineList_SaveSelToStg method so that currently written data + ** for any embeddings is also saved to the new destination + ** storage. The data required by a contained object is both the + ** ContainerLine information and the associated sub-storage that is + ** written directly by the embedded object. + */ + fStatus = LineList_SaveSelToStg( + &lpOutlineDoc->m_LineList, + lplrSel, + uFormat, +#if defined( OLE_CNTR ) + lpOleDoc->m_lpStg, +#else + NULL, +#endif + lpDestStg, + lpLLStm, + fRemember + ); + if (! fStatus) goto error; + + // Save associated NameTable + fStatus = OutlineNameTable_SaveSelToStg( + lpOutlineDoc->m_lpNameTable, + lplrSel, + uFormat, + lpNTStm + ); + + if (! fStatus) goto error; + + OleStdRelease((LPUNKNOWN)lpLLStm); + lpOutlineDoc->m_cfSaveFormat = uFormat; // remember format used to save + + SetCursor(hPrevCursor); // restore original cursor + return TRUE; + +error: + if (lpLLStm) + OleStdRelease((LPUNKNOWN)lpLLStm); + + SetCursor(hPrevCursor); // restore original cursor + return FALSE; +} + + +/* OutlineDoc_Print + * ---------------- + * Prints the contents of the list box in HIMETRIC mapping mode. Origin + * remains to be the upper left corner and the print proceeds down the + * page using a negative y-cordinate. + * + */ +void OutlineDoc_Print(LPOUTLINEDOC lpOutlineDoc, HDC hDC) +{ + LPLINELIST lpLL = &lpOutlineDoc->m_LineList; + LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; + WORD nIndex; + WORD nTotal; + int dy; + BOOL fError = FALSE; + LPLINE lpLine; + RECT rcLine; + RECT rcPix; + RECT rcHim; + RECT rcWindowOld; + RECT rcViewportOld; + HFONT hOldFont; + DOCINFO di; /* Document information for StartDoc function */ + + /* Get dimension of page */ + rcPix.left = 0; + rcPix.top = 0; + rcPix.right = GetDeviceCaps(hDC, HORZRES); + rcPix.bottom = GetDeviceCaps(hDC, VERTRES); + + SetDCToDrawInHimetricRect(hDC, (LPRECT)&rcPix, (LPRECT)&rcHim, + (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld); + + // Set the default font size, and font face name + hOldFont = SelectObject(hDC, lpOutlineApp->m_hStdFont); + + /* Get the lines in document */ + nIndex = 0; + nTotal = LineList_GetCount(lpLL); + + /* Create the Cancel dialog */ + // REVIEW: should load dialog title from string resource file + hWndPDlg = CreateDialog ( + lpOutlineApp->m_hInst, + "Print", + lpOutlineApp->m_hWndApp, + (DLGPROC)PrintDlgProc + ); + + if(!hWndPDlg) + goto getout; + + /* Allow the app. to inform GDI of the abort function to call */ + if(SetAbortProc(hDC, (ABORTPROC)AbortProc) < 0) { + fError = TRUE; + goto getout3; + } + + /* Disable the main application window */ + EnableWindow (lpOutlineApp->m_hWndApp, FALSE); + + // initialize the rectangle for the first line + rcLine.left = rcHim.left; + rcLine.bottom = rcHim.top; + + /* Initialize the document */ + fCancelPrint = FALSE; + + di.cbSize = sizeof(di); + di.lpszDocName = lpOutlineDoc->m_lpszDocTitle; + di.lpszOutput = NULL; + + if(StartDoc(hDC, (DOCINFO FAR*)&di) <= 0) { + fError = TRUE; + OleDbgOut2("StartDoc error\n"); + goto getout5; + } + + if(StartPage(hDC) <= 0) { // start first page + fError = TRUE; + OleDbgOut2("StartPage error\n"); + goto getout2; + } + + /* While more lines print out the text */ + while(nIndex < nTotal) { + lpLine = LineList_GetLine(lpLL, nIndex); + if (! lpLine) + continue; + + dy = Line_GetHeightInHimetric(lpLine); + + /* Reached end of page. Tell the device driver to eject a page */ + if(rcLine.bottom - dy < rcHim.bottom) { + if (EndPage(hDC) < 0) { + fError=TRUE; + OleDbgOut2("EndPage error\n"); + goto getout2; + } + + // NOTE: Reset the Mapping mode of DC + SetDCToDrawInHimetricRect(hDC, (LPRECT)&rcPix, (LPRECT)&rcHim, + (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld); + + // Set the default font size, and font face name + SelectObject(hDC, lpOutlineApp->m_hStdFont); + + if (StartPage(hDC) <= 0) { + fError=TRUE; + OleDbgOut2("StartPage error\n"); + goto getout2; + } + + rcLine.bottom = rcHim.top; + } + + rcLine.top = rcLine.bottom; + rcLine.bottom -= dy; + rcLine.right = rcLine.left + Line_GetWidthInHimetric(lpLine); + + /* Print the line */ + Line_Draw(lpLine, hDC, &rcLine, NULL, FALSE /*fHighlight*/); + + OleDbgOut2("a line is drawn\n"); + + /* Test and see if the Abort flag has been set. If yes, exit. */ + if (fCancelPrint) + goto getout2; + + /* Move down the page */ + nIndex++; + } + + { + int nCode; + + /* Eject the last page. */ + if((nCode = EndPage(hDC)) < 0) { +#if defined( _DEBUG ) + char szBuf[255]; + wsprintf(szBuf, "EndPage error code is %d\n", nCode); + OleDbgOut2(szBuf); +#endif + fError=TRUE; + goto getout2; + } + } + + + /* Complete the document. */ + if(EndDoc(hDC) < 0) { + fError=TRUE; + OleDbgOut2("EndDoc error\n"); + +getout2: + /* Ran into a problem before NEWFRAME? Abort the document */ + AbortDoc(hDC); + } + +getout5: + /* Re-enable main app. window */ + EnableWindow (lpOutlineApp->m_hWndApp, TRUE); + +getout3: + /* Close the cancel dialog */ + DestroyWindow (hWndPDlg); + +getout: + + /* Error? make sure the user knows... */ + if(fError || CommDlgExtendedError()) + OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgPrint); + + SelectObject(hDC, hOldFont); +} + + + + + +/* OutlineDoc_DialogHelp + * --------------------- + * + * Show help message for ole2ui dialogs. + * + * Parameters: + * + * hDlg HWND to the dialog the help message came from - use + * this in the call to WinHelp/MessageBox so that + * activation/focus goes back to the dialog, and not the + * main window. + * + * wParam ID of the dialog (so we know what type of dialog it is). + */ +void OutlineDoc_DialogHelp(HWND hDlg, WPARAM wDlgID) +{ + + char szMessageBoxText[64]; + + if (!IsWindow(hDlg)) // don't do anything if we've got a bogus hDlg. + return; + + lstrcpy(szMessageBoxText, "Help Message for "); + + switch (wDlgID) + { + + case IDD_CONVERT: + lstrcat(szMessageBoxText, "Convert"); + break; + + case IDD_CHANGEICON: + lstrcat(szMessageBoxText, "Change Icon"); + break; + + case IDD_INSERTOBJECT: + lstrcat(szMessageBoxText, "Insert Object"); + break; + + case IDD_PASTESPECIAL: + lstrcat(szMessageBoxText, "Paste Special"); + break; + + case IDD_EDITLINKS: + lstrcat(szMessageBoxText, "Edit Links"); + break; + + case IDD_CHANGESOURCE: + lstrcat(szMessageBoxText, "Change Source"); + break; + + case IDD_INSERTFILEBROWSE: + lstrcat(szMessageBoxText, "Insert From File Browse"); + break; + + case IDD_CHANGEICONBROWSE: + lstrcat(szMessageBoxText, "Change Icon Browse"); + break; + + default: + lstrcat(szMessageBoxText, "Unknown"); + break; + } + + lstrcat(szMessageBoxText, " Dialog."); + + // You'd probably really a call to WinHelp here. + MessageBox(hDlg, szMessageBoxText, "Help", MB_OK); + + return; +} + + +/* OutlineDoc_SetCurrentZoomCommand + * -------------------------------- + * + * Set current zoom level to be checked in the menu. + * Set the corresponding scalefactor for the document. + */ +void OutlineDoc_SetCurrentZoomCommand( + LPOUTLINEDOC lpOutlineDoc, + UINT uCurrentZoom +) +{ + SCALEFACTOR scale; + + if (!lpOutlineDoc) + return; + + lpOutlineDoc->m_uCurrentZoom = uCurrentZoom; + + switch (uCurrentZoom) { + +#if !defined( OLE_CNTR ) + case IDM_V_ZOOM_400: + scale.dwSxN = (DWORD) 4; + scale.dwSxD = (DWORD) 1; + scale.dwSyN = (DWORD) 4; + scale.dwSyD = (DWORD) 1; + break; + + case IDM_V_ZOOM_300: + scale.dwSxN = (DWORD) 3; + scale.dwSxD = (DWORD) 1; + scale.dwSyN = (DWORD) 3; + scale.dwSyD = (DWORD) 1; + break; + + case IDM_V_ZOOM_200: + scale.dwSxN = (DWORD) 2; + scale.dwSxD = (DWORD) 1; + scale.dwSyN = (DWORD) 2; + scale.dwSyD = (DWORD) 1; + break; +#endif // !OLE_CNTR + + case IDM_V_ZOOM_100: + scale.dwSxN = (DWORD) 1; + scale.dwSxD = (DWORD) 1; + scale.dwSyN = (DWORD) 1; + scale.dwSyD = (DWORD) 1; + break; + + case IDM_V_ZOOM_75: + scale.dwSxN = (DWORD) 3; + scale.dwSxD = (DWORD) 4; + scale.dwSyN = (DWORD) 3; + scale.dwSyD = (DWORD) 4; + break; + + case IDM_V_ZOOM_50: + scale.dwSxN = (DWORD) 1; + scale.dwSxD = (DWORD) 2; + scale.dwSyN = (DWORD) 1; + scale.dwSyD = (DWORD) 2; + break; + + case IDM_V_ZOOM_25: + scale.dwSxN = (DWORD) 1; + scale.dwSxD = (DWORD) 4; + scale.dwSyN = (DWORD) 1; + scale.dwSyD = (DWORD) 4; + break; + } + + OutlineDoc_SetScaleFactor(lpOutlineDoc, (LPSCALEFACTOR)&scale, NULL); +} + + +/* OutlineDoc_GetCurrentZoomMenuCheck + * ---------------------------------- + * + * Get current zoom level to be checked in the menu. + */ +UINT OutlineDoc_GetCurrentZoomMenuCheck(LPOUTLINEDOC lpOutlineDoc) +{ + return lpOutlineDoc->m_uCurrentZoom; +} + + +/* OutlineDoc_SetScaleFactor + * ------------------------- + * + * Set the scale factor of the document which will affect the + * size of the document on the screen + * + * Parameters: + * + * scale structure containing x and y scales + */ +void OutlineDoc_SetScaleFactor( + LPOUTLINEDOC lpOutlineDoc, + LPSCALEFACTOR lpscale, + LPRECT lprcDoc +) +{ + LPLINELIST lpLL = OutlineDoc_GetLineList(lpOutlineDoc); + HWND hWndLL = LineList_GetWindow(lpLL); + + if (!lpOutlineDoc || !lpscale) + return; + + InvalidateRect(hWndLL, NULL, TRUE); + + lpOutlineDoc->m_scale = *lpscale; + LineList_ReScale((LPLINELIST)&lpOutlineDoc->m_LineList, lpscale); + +#if defined( USE_HEADING ) + Heading_ReScale((LPHEADING)&lpOutlineDoc->m_heading, lpscale); +#endif + + OutlineDoc_Resize(lpOutlineDoc, lprcDoc); +} + + +/* OutlineDoc_GetScaleFactor + * ------------------------- + * + * Retrieve the scale factor of the document + * + * Parameters: + * + */ +LPSCALEFACTOR OutlineDoc_GetScaleFactor(LPOUTLINEDOC lpOutlineDoc) +{ + if (!lpOutlineDoc) + return NULL; + + return (LPSCALEFACTOR)&lpOutlineDoc->m_scale; +} + + +/* OutlineDoc_SetCurrentMarginCommand + * ---------------------------------- + * + * Set current Margin level to be checked in the menu. + */ +void OutlineDoc_SetCurrentMarginCommand( + LPOUTLINEDOC lpOutlineDoc, + UINT uCurrentMargin +) +{ + if (!lpOutlineDoc) + return; + + lpOutlineDoc->m_uCurrentMargin = uCurrentMargin; + + switch (uCurrentMargin) { + case IDM_V_SETMARGIN_0: + OutlineDoc_SetMargin(lpOutlineDoc, 0, 0); + break; + + case IDM_V_SETMARGIN_1: + OutlineDoc_SetMargin(lpOutlineDoc, 1000, 1000); + break; + + case IDM_V_SETMARGIN_2: + OutlineDoc_SetMargin(lpOutlineDoc, 2000, 2000); + break; + + case IDM_V_SETMARGIN_3: + OutlineDoc_SetMargin(lpOutlineDoc, 3000, 3000); + break; + + case IDM_V_SETMARGIN_4: + OutlineDoc_SetMargin(lpOutlineDoc, 4000, 4000); + break; + } +} + + +/* OutlineDoc_GetCurrentMarginMenuCheck + * ------------------------------------ + * + * Get current Margin level to be checked in the menu. + */ +UINT OutlineDoc_GetCurrentMarginMenuCheck(LPOUTLINEDOC lpOutlineDoc) +{ + return lpOutlineDoc->m_uCurrentMargin; +} + + +/* OutlineDoc_SetMargin + * -------------------- + * + * Set the left and right margin of the document + * + * Parameters: + * nLeftMargin - left margin in Himetric values + * nRightMargin - right margin in Himetric values + */ +void OutlineDoc_SetMargin(LPOUTLINEDOC lpOutlineDoc, int nLeftMargin, int nRightMargin) +{ + LPLINELIST lpLL; + int nMaxWidthInHim; + + if (!lpOutlineDoc) + return; + + lpOutlineDoc->m_nLeftMargin = nLeftMargin; + lpOutlineDoc->m_nRightMargin = nRightMargin; + lpLL = OutlineDoc_GetLineList(lpOutlineDoc); + + // Force recalculation of Horizontal extent + nMaxWidthInHim = LineList_GetMaxLineWidthInHimetric(lpLL); + LineList_SetMaxLineWidthInHimetric(lpLL, -nMaxWidthInHim); + +#if defined( INPLACE_CNTR ) + ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0); +#endif + + OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE); +} + + +/* OutlineDoc_GetMargin + * -------------------- + * + * Get the left and right margin of the document + * + * Parameters: + * nLeftMargin - left margin in Himetric values + * nRightMargin - right margin in Himetric values + * + * Returns: + * low order word - left margin + * high order word - right margin + */ +LONG OutlineDoc_GetMargin(LPOUTLINEDOC lpOutlineDoc) +{ + if (!lpOutlineDoc) + return 0; + + return MAKELONG(lpOutlineDoc->m_nLeftMargin, lpOutlineDoc->m_nRightMargin); +} + +#if defined( USE_HEADING ) + +/* OutlineDoc_GetHeading + * --------------------- + * + * Get Heading Object in OutlineDoc + */ +LPHEADING OutlineDoc_GetHeading(LPOUTLINEDOC lpOutlineDoc) +{ + if (!lpOutlineDoc || lpOutlineDoc->m_fDataTransferDoc) + return NULL; + else + return (LPHEADING)&lpOutlineDoc->m_heading; +} + + +/* OutlineDoc_ShowHeading + * ---------------------- + * + * Show/Hide document row/column headings. + */ +void OutlineDoc_ShowHeading(LPOUTLINEDOC lpOutlineDoc, BOOL fShow) +{ + LPHEADING lphead = OutlineDoc_GetHeading(lpOutlineDoc); +#if defined( INPLACE_SVR ) + LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc; +#endif + + if (! lphead) + return; + + Heading_Show(lphead, fShow); + +#if defined( INPLACE_SVR ) + if (lpServerDoc->m_fUIActive) { + LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; + + /* OLE2NOTE: our extents have NOT changed; only our the size of + ** our object-frame adornments is changing. we can use the + ** current PosRect and ClipRect and simply resize our + ** windows WITHOUT informing our in-place container. + */ + ServerDoc_ResizeInPlaceWindow( + lpServerDoc, + (LPRECT)&(lpIPData->rcPosRect), + (LPRECT)&(lpIPData->rcClipRect) + ); + } else +#else // !INPLACE_SVR + + OutlineDoc_Resize(lpOutlineDoc, NULL); + +#if defined( INPLACE_CNTR ) + ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0); +#endif // INPLACE_CNTR + +#endif // INPLACE_SVR + + OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE); +} + +#endif // USE_HEADING + + +/* AbortProc + * --------- + * AborProc is called by GDI print code to check for user abort. + */ +BOOL FAR PASCAL EXPORT AbortProc (HDC hdc, WORD reserved) +{ + MSG msg; + + /* Allow other apps to run, or get abort messages */ + while(! fCancelPrint && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { + if(!hWndPDlg || !IsDialogMessage (hWndPDlg, &msg)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } + return !fCancelPrint; +} + + +/* PrintDlgProc + * ------------ + * Dialog function for the print cancel dialog box. + * + * RETURNS : TRUE - OK to abort/ not OK to abort + * FALSE - otherwise. + */ +BOOL FAR PASCAL EXPORT PrintDlgProc( + HWND hwnd, + WORD msg, + WORD wParam, + LONG lParam +) +{ + switch (msg) { + case WM_COMMAND: + /* abort printing if the only button gets hit */ + fCancelPrint = TRUE; + return TRUE; + } + + return FALSE; +} |