Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3247 lines
86 KiB

  1. /*************************************************************************
  2. **
  3. ** OLE 2 Sample Code
  4. **
  5. ** outldoc.c
  6. **
  7. ** This file contains OutlineDoc functions.
  8. **
  9. ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
  10. **
  11. *************************************************************************/
  12. #include "outline.h"
  13. #if !defined( OLE_VERSION )
  14. #include <commdlg.h>
  15. #endif
  16. OLEDBGDATA
  17. extern LPOUTLINEAPP g_lpApp;
  18. // REVIEW: should use string resource for messages
  19. char ErrMsgDocWnd[] = "Can't create Document Window!";
  20. char ErrMsgFormatNotSupported[] = "Clipboard format not supported!";
  21. char MsgSaveFile[] = "Save existing file ?";
  22. char ErrMsgSaving[] = "Error in saving file!";
  23. char ErrMsgOpening[] = "Error in opening file!";
  24. char ErrMsgFormat[] = "Improper file format!";
  25. char ErrOutOfMemory[] = "Error: out of memory!";
  26. static char ErrMsgPrint[] = "Printing Error!";
  27. static BOOL fCancelPrint; // TRUE if the user has canceled the print job
  28. static HWND hWndPDlg; // Handle to the cancel print dialog
  29. /* OutlineDoc_Init
  30. * ---------------
  31. *
  32. * Initialize the fields of a new OutlineDoc object. The object is initially
  33. * not associated with a file or an (Untitled) document. This function sets
  34. * the docInitType to DOCTYPE_UNKNOWN. After calling this function the
  35. * caller should call:
  36. * 1. OutlineDoc_InitNewFile to set the OutlineDoc to (Untitled)
  37. * 2. OutlineDoc_LoadFromFile to associate the OutlineDoc with a file.
  38. * This function creates a new window for the document.
  39. *
  40. * NOTE: the window is initially created with a NIL size. it must be
  41. * sized and positioned by the caller. also the document is initially
  42. * created invisible. the caller must call OutlineDoc_ShowWindow
  43. * after sizing it to make the document window visible.
  44. */
  45. BOOL OutlineDoc_Init(LPOUTLINEDOC lpOutlineDoc, BOOL fDataTransferDoc)
  46. {
  47. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  48. #if defined( INPLACE_CNTR )
  49. lpOutlineDoc->m_hWndDoc = CreateWindow(
  50. DOCWNDCLASS, // Window class name
  51. NULL, // Window's title
  52. /* OLE2NOTE: an in-place contanier MUST use
  53. ** WS_CLIPCHILDREN window style for the window
  54. ** that it uses as the parent for the server's
  55. ** in-place active window so that its
  56. ** painting does NOT interfere with the painting
  57. ** of the server's in-place active child window.
  58. */
  59. WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  60. WS_CHILDWINDOW,
  61. 0, 0,
  62. 0, 0,
  63. lpOutlineApp->m_hWndApp,// Parent window's handle
  64. (HMENU)1, // child window id
  65. lpOutlineApp->m_hInst, // Instance of window
  66. NULL); // Create struct for WM_CREATE
  67. #else
  68. lpOutlineDoc->m_hWndDoc = CreateWindow(
  69. DOCWNDCLASS, // Window class name
  70. NULL, // Window's title
  71. WS_CHILDWINDOW,
  72. 0, 0,
  73. 0, 0,
  74. lpOutlineApp->m_hWndApp,// Parent window's handle
  75. (HMENU)1, // child window id
  76. lpOutlineApp->m_hInst, // Instance of window
  77. NULL); // Create struct for WM_CREATE
  78. #endif
  79. if(! lpOutlineDoc->m_hWndDoc) {
  80. OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgDocWnd);
  81. return FALSE;
  82. }
  83. SetWindowLong(lpOutlineDoc->m_hWndDoc, 0, (LONG) lpOutlineDoc);
  84. if (! LineList_Init(&lpOutlineDoc->m_LineList, lpOutlineDoc))
  85. return FALSE;
  86. lpOutlineDoc->m_lpNameTable = OutlineDoc_CreateNameTable(lpOutlineDoc);
  87. if (! lpOutlineDoc->m_lpNameTable )
  88. return FALSE;
  89. lpOutlineDoc->m_docInitType = DOCTYPE_UNKNOWN;
  90. lpOutlineDoc->m_cfSaveFormat = lpOutlineApp->m_cfOutline;
  91. lpOutlineDoc->m_szFileName[0] = '\0';
  92. lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
  93. lpOutlineDoc->m_fDataTransferDoc = fDataTransferDoc;
  94. lpOutlineDoc->m_uCurrentZoom = IDM_V_ZOOM_100;
  95. lpOutlineDoc->m_scale.dwSxN = (DWORD) 1;
  96. lpOutlineDoc->m_scale.dwSxD = (DWORD) 1;
  97. lpOutlineDoc->m_scale.dwSyN = (DWORD) 1;
  98. lpOutlineDoc->m_scale.dwSyD = (DWORD) 1;
  99. lpOutlineDoc->m_uCurrentMargin = IDM_V_SETMARGIN_0;
  100. lpOutlineDoc->m_nLeftMargin = 0;
  101. lpOutlineDoc->m_nRightMargin = 0;
  102. lpOutlineDoc->m_nDisableDraw = 0;
  103. OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
  104. #if defined( USE_HEADING )
  105. if (! fDataTransferDoc) {
  106. if (!Heading_Create((LPHEADING)&lpOutlineDoc->m_heading,
  107. lpOutlineDoc->m_hWndDoc, lpOutlineApp->m_hInst)) {
  108. return FALSE;
  109. }
  110. }
  111. #endif // USE_HEADING
  112. #if defined( USE_FRAMETOOLS )
  113. if (! fDataTransferDoc) {
  114. lpOutlineDoc->m_lpFrameTools = OutlineApp_GetFrameTools(lpOutlineApp);
  115. FrameTools_AssociateDoc(
  116. lpOutlineDoc->m_lpFrameTools,
  117. lpOutlineDoc
  118. );
  119. }
  120. #endif // USE_FRAMETOOLS
  121. #if defined( OLE_VERSION )
  122. /* OLE2NOTE: perform initialization required for OLE */
  123. if (! OleDoc_Init((LPOLEDOC)lpOutlineDoc, fDataTransferDoc))
  124. return FALSE;
  125. #endif // OLE_VERSION
  126. return TRUE;
  127. }
  128. /* OutlineDoc_InitNewFile
  129. * ----------------------
  130. *
  131. * Initialize the OutlineDoc object to be a new (Untitled) document.
  132. * This function sets the docInitType to DOCTYPE_NEW.
  133. */
  134. BOOL OutlineDoc_InitNewFile(LPOUTLINEDOC lpOutlineDoc)
  135. {
  136. #if defined( OLE_VERSION )
  137. // OLE2NOTE: call OLE version of this function instead
  138. return OleDoc_InitNewFile((LPOLEDOC)lpOutlineDoc);
  139. #else
  140. OleDbgAssert(lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN);
  141. // set file name to untitled
  142. // REVIEW: should load from string resource
  143. lstrcpy(lpOutlineDoc->m_szFileName, UNTITLED);
  144. lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName;
  145. lpOutlineDoc->m_docInitType = DOCTYPE_NEW;
  146. if (! lpOutlineDoc->m_fDataTransferDoc)
  147. OutlineDoc_SetTitle(lpOutlineDoc, FALSE /*fMakeUpperCase*/);
  148. return TRUE;
  149. #endif // BASE OUTLINE VERSION
  150. }
  151. /* OutlineDoc_CreateNameTable
  152. * --------------------------
  153. *
  154. * Allocate a new NameTable of the appropriate type. Each document has
  155. * a NameTable and a LineList.
  156. * OutlineDoc --> creates standard OutlineNameTable type name tables.
  157. * ServerDoc --> creates enhanced SeverNameTable type name tables.
  158. *
  159. * Returns lpNameTable for successful, NULL if error.
  160. */
  161. LPOUTLINENAMETABLE OutlineDoc_CreateNameTable(LPOUTLINEDOC lpOutlineDoc)
  162. {
  163. LPOUTLINENAMETABLE lpOutlineNameTable;
  164. lpOutlineNameTable = (LPOUTLINENAMETABLE)New(
  165. (DWORD)sizeof(OUTLINENAMETABLE)
  166. );
  167. OleDbgAssertSz(lpOutlineNameTable != NULL,"Error allocating NameTable");
  168. if (lpOutlineNameTable == NULL)
  169. return NULL;
  170. // initialize new NameTable
  171. if (! OutlineNameTable_Init(lpOutlineNameTable, lpOutlineDoc) )
  172. goto error;
  173. return lpOutlineNameTable;
  174. error:
  175. if (lpOutlineNameTable)
  176. Delete(lpOutlineNameTable);
  177. return NULL;
  178. }
  179. /* OutlineDoc_ClearCommand
  180. * -----------------------
  181. *
  182. * Delete selection in list box by calling OutlineDoc_Delete
  183. */
  184. void OutlineDoc_ClearCommand(LPOUTLINEDOC lpOutlineDoc)
  185. {
  186. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  187. int i;
  188. int nNumSel;
  189. LINERANGE lrSel;
  190. nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
  191. OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
  192. for(i = 0; i < nNumSel; i++)
  193. OutlineDoc_DeleteLine(lpOutlineDoc, lrSel.m_nStartLine);
  194. OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
  195. LineList_RecalcMaxLineWidthInHimetric(lpLL, 0);
  196. }
  197. /* OutlineDoc_CutCommand
  198. * ---------------------
  199. *
  200. * Cut selection to clipboard
  201. */
  202. void OutlineDoc_CutCommand(LPOUTLINEDOC lpOutlineDoc)
  203. {
  204. OutlineDoc_CopyCommand(lpOutlineDoc);
  205. OutlineDoc_ClearCommand(lpOutlineDoc);
  206. }
  207. /* OutlineDoc_CopyCommand
  208. * ----------------------
  209. * Copy selection to clipboard.
  210. * Post to the clipboard the formats that the app can render.
  211. * the actual data is not rendered at this time. using the
  212. * delayed rendering technique, Windows will send the clipboard
  213. * owner window either a WM_RENDERALLFORMATS or a WM_RENDERFORMAT
  214. * message when the actual data is requested.
  215. *
  216. * OLE2NOTE: the normal delayed rendering technique where Windows
  217. * sends the clipboard owner window either a WM_RENDERALLFORMATS or
  218. * a WM_RENDERFORMAT message when the actual data is requested is
  219. * NOT exposed to the app calling OleSetClipboard. OLE internally
  220. * creates its own window as the clipboard owner and thus our app
  221. * will NOT get these WM_RENDER messages.
  222. */
  223. void OutlineDoc_CopyCommand(LPOUTLINEDOC lpSrcOutlineDoc)
  224. {
  225. #if defined( OLE_VERSION )
  226. // Call OLE version of this function instead
  227. OleDoc_CopyCommand((LPOLEDOC)lpSrcOutlineDoc);
  228. #else
  229. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  230. LPOUTLINEDOC lpClipboardDoc;
  231. OpenClipboard(lpSrcOutlineDoc->m_hWndDoc);
  232. EmptyClipboard();
  233. /* squirrel away a copy of the current selection to the ClipboardDoc */
  234. lpClipboardDoc = OutlineDoc_CreateDataTransferDoc(lpSrcOutlineDoc);
  235. if (! lpClipboardDoc)
  236. return; // Error: could not create DataTransferDoc
  237. lpOutlineApp->m_lpClipboardDoc = (LPOUTLINEDOC)lpClipboardDoc;
  238. SetClipboardData(lpOutlineApp->m_cfOutline, NULL);
  239. SetClipboardData(CF_TEXT, NULL);
  240. CloseClipboard();
  241. #endif // ! OLE_VERSION
  242. }
  243. /* OutlineDoc_ClearAllLines
  244. * ------------------------
  245. *
  246. * Delete all lines in the document.
  247. */
  248. void OutlineDoc_ClearAllLines(LPOUTLINEDOC lpOutlineDoc)
  249. {
  250. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  251. int i;
  252. for(i = 0; i < lpLL->m_nNumLines; i++)
  253. OutlineDoc_DeleteLine(lpOutlineDoc, 0);
  254. LineList_RecalcMaxLineWidthInHimetric(lpLL, 0);
  255. }
  256. /* OutlineDoc_CreateDataTransferDoc
  257. * --------------------------------
  258. *
  259. * Create a document to be use to transfer data (either via a
  260. * drag/drop operation of the clipboard). Copy the selection of the
  261. * source doc to the data transfer document. A data transfer document is
  262. * the same as a document that is created by the user except that it is
  263. * NOT made visible to the user. it is specially used to hold a copy of
  264. * data that the user should not be able to change.
  265. *
  266. * OLE2NOTE: in the OLE version the data transfer document is used
  267. * specifically to provide an IDataObject* that renders the data copied.
  268. */
  269. LPOUTLINEDOC OutlineDoc_CreateDataTransferDoc(LPOUTLINEDOC lpSrcOutlineDoc)
  270. {
  271. #if defined( OLE_VERSION )
  272. // Call OLE version of this function instead
  273. return OleDoc_CreateDataTransferDoc((LPOLEDOC)lpSrcOutlineDoc);
  274. #else
  275. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  276. LPOUTLINEDOC lpDestOutlineDoc;
  277. LPLINELIST lpSrcLL = &lpSrcOutlineDoc->m_LineList;
  278. LINERANGE lrSel;
  279. int nCopied;
  280. lpDestOutlineDoc = OutlineApp_CreateDoc(lpOutlineApp, TRUE);
  281. if (! lpDestOutlineDoc) return NULL;
  282. // set the ClipboardDoc to an (Untitled) doc.
  283. if (! OutlineDoc_InitNewFile(lpDestOutlineDoc))
  284. goto error;
  285. LineList_GetSel(lpSrcLL, (LPLINERANGE)&lrSel);
  286. nCopied = LineList_CopySelToDoc(
  287. lpSrcLL,
  288. (LPLINERANGE)&lrSel,
  289. lpDestOutlineDoc
  290. );
  291. return lpDestOutlineDoc;
  292. error:
  293. if (lpDestOutlineDoc)
  294. OutlineDoc_Destroy(lpDestOutlineDoc);
  295. return NULL;
  296. #endif // ! OLE_VERSION
  297. }
  298. /* OutlineDoc_PasteCommand
  299. * -----------------------
  300. *
  301. * Paste lines from clipboard
  302. */
  303. void OutlineDoc_PasteCommand(LPOUTLINEDOC lpOutlineDoc)
  304. {
  305. #if defined( OLE_VERSION )
  306. // Call OLE version of this function instead
  307. OleDoc_PasteCommand((LPOLEDOC)lpOutlineDoc);
  308. #else
  309. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  310. LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
  311. int nIndex;
  312. int nCount;
  313. HGLOBAL hData;
  314. LINERANGE lrSel;
  315. UINT uFormat;
  316. if (LineList_GetCount(lpLL) == 0)
  317. nIndex = -1; // pasting to empty list
  318. else
  319. nIndex=LineList_GetFocusLineIndex(lpLL);
  320. OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
  321. OpenClipboard(lpOutlineDoc->m_hWndDoc);
  322. uFormat = 0;
  323. while(uFormat = EnumClipboardFormats(uFormat)) {
  324. if(uFormat == lpOutlineApp->m_cfOutline) {
  325. hData = GetClipboardData(lpOutlineApp->m_cfOutline);
  326. nCount = OutlineDoc_PasteOutlineData(lpOutlineDoc, hData, nIndex);
  327. break;
  328. }
  329. if(uFormat == CF_TEXT) {
  330. hData = GetClipboardData(CF_TEXT);
  331. nCount = OutlineDoc_PasteTextData(lpOutlineDoc, hData, nIndex);
  332. break;
  333. }
  334. }
  335. lrSel.m_nStartLine = nIndex + nCount;
  336. lrSel.m_nEndLine = nIndex + 1;
  337. LineList_SetSel(lpLL, &lrSel);
  338. OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
  339. CloseClipboard();
  340. #endif // ! OLE_VERSION
  341. }
  342. /* OutlineDoc_PasteOutlineData
  343. * ---------------------------
  344. *
  345. * Put an array of Line Objects (stored in hOutline) into the document
  346. *
  347. * Return the number of items added
  348. */
  349. int OutlineDoc_PasteOutlineData(LPOUTLINEDOC lpOutlineDoc, HGLOBAL hOutline, int nStartIndex)
  350. {
  351. int nCount;
  352. int i;
  353. LPTEXTLINE arrLine;
  354. nCount = (int) GlobalSize(hOutline) / sizeof(TEXTLINE);
  355. arrLine = (LPTEXTLINE)GlobalLock(hOutline);
  356. if (!arrLine)
  357. return 0;
  358. for(i = 0; i < nCount; i++)
  359. Line_CopyToDoc((LPLINE)&arrLine[i], lpOutlineDoc, nStartIndex+i);
  360. GlobalUnlock(hOutline);
  361. return nCount;
  362. }
  363. /* OutlineDoc_PasteTextData
  364. * ------------------------
  365. *
  366. * Build Line Objects from the strings (separated by '\n') in hText
  367. * and put them into the document
  368. */
  369. int OutlineDoc_PasteTextData(LPOUTLINEDOC lpOutlineDoc, HGLOBAL hText, int nStartIndex)
  370. {
  371. LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
  372. HDC hDC;
  373. LPSTR lpszText;
  374. LPSTR lpszEnd;
  375. LPTEXTLINE lpLine;
  376. int nLineCount;
  377. int i;
  378. UINT nTab;
  379. char szBuf[MAXSTRLEN+1];
  380. lpszText=(LPSTR)GlobalLock(hText);
  381. if(!lpszText)
  382. return 0;
  383. lpszEnd = lpszText + lstrlen(lpszText);
  384. nLineCount=0;
  385. while(*lpszText && (lpszText<lpszEnd)) {
  386. // count the tab level
  387. nTab = 0;
  388. while((*lpszText == '\t') && (lpszText<lpszEnd)) {
  389. nTab++;
  390. lpszText++;
  391. }
  392. // collect the text string character by character
  393. for(i=0; (i<MAXSTRLEN) && (lpszText<lpszEnd); i++) {
  394. if ((! *lpszText) || (*lpszText == '\n'))
  395. break;
  396. szBuf[i] = *lpszText++;
  397. }
  398. szBuf[i] = 0;
  399. lpszText++;
  400. if ((i > 0) && (szBuf[i-1] == '\r'))
  401. szBuf[i-1] = 0; // remove carriage return at the end
  402. hDC = LineList_GetDC(lpLL);
  403. lpLine = TextLine_Create(hDC, nTab, szBuf);
  404. LineList_ReleaseDC(lpLL, hDC);
  405. OutlineDoc_AddLine(
  406. lpOutlineDoc,
  407. (LPLINE)lpLine,
  408. nStartIndex + nLineCount
  409. );
  410. nLineCount++;
  411. }
  412. GlobalUnlock(hText);
  413. return nLineCount;
  414. }
  415. /* OutlineDoc_AddTextLineCommand
  416. * -----------------------------
  417. *
  418. * Add a new text line following the current focus line.
  419. */
  420. void OutlineDoc_AddTextLineCommand(LPOUTLINEDOC lpOutlineDoc)
  421. {
  422. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  423. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  424. HDC hDC;
  425. int nIndex = LineList_GetFocusLineIndex(lpLL);
  426. char szBuf[MAXSTRLEN+1];
  427. UINT nTab = 0;
  428. LPLINE lpLine;
  429. LPTEXTLINE lpTextLine;
  430. szBuf[0] = '\0';
  431. #if defined( USE_FRAMETOOLS )
  432. FrameTools_FB_GetEditText(
  433. lpOutlineDoc->m_lpFrameTools, szBuf, sizeof(szBuf));
  434. #else
  435. if (! InputTextDlg(lpOutlineDoc->m_hWndDoc, szBuf, "Add Line"))
  436. return;
  437. #endif
  438. hDC = LineList_GetDC(lpLL);
  439. lpLine = LineList_GetLine(lpLL, nIndex);
  440. if (lpLine)
  441. nTab = Line_GetTabLevel(lpLine);
  442. lpTextLine=TextLine_Create(hDC, nTab, szBuf);
  443. LineList_ReleaseDC(lpLL, hDC);
  444. if (! lpTextLine) {
  445. OutlineApp_ErrorMessage(lpOutlineApp, ErrOutOfMemory);
  446. return;
  447. }
  448. OutlineDoc_AddLine(lpOutlineDoc, (LPLINE)lpTextLine, nIndex);
  449. }
  450. /* OutlineDoc_AddTopLineCommand
  451. * ----------------------------
  452. *
  453. * Add a top (margin) line as the first line in the LineList.
  454. * (do not change the current selection)
  455. */
  456. void OutlineDoc_AddTopLineCommand(
  457. LPOUTLINEDOC lpOutlineDoc,
  458. UINT nHeightInHimetric
  459. )
  460. {
  461. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  462. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  463. HDC hDC = LineList_GetDC(lpLL);
  464. LPTEXTLINE lpTextLine = TextLine_Create(hDC, 0, NULL);
  465. LPLINE lpLine = (LPLINE)lpTextLine;
  466. LINERANGE lrSel;
  467. int nNumSel;
  468. LineList_ReleaseDC(lpLL, hDC);
  469. if (! lpTextLine) {
  470. OutlineApp_ErrorMessage(lpOutlineApp, ErrOutOfMemory);
  471. return;
  472. }
  473. Line_SetHeightInHimetric(lpLine, nHeightInHimetric);
  474. nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
  475. if (nNumSel > 0) {
  476. // adjust current selection to keep equivalent selection
  477. lrSel.m_nStartLine += 1;
  478. lrSel.m_nEndLine += 1;
  479. }
  480. OutlineDoc_AddLine(lpOutlineDoc, lpLine, -1);
  481. if (nNumSel > 0)
  482. LineList_SetSel(lpLL, (LPLINERANGE)&lrSel);
  483. }
  484. #if defined( USE_FRAMETOOLS )
  485. /* OutlineDoc_SetFormulaBarEditText
  486. * --------------------------------
  487. *
  488. * Fill the edit control in the formula with the text string from a
  489. * TextLine in focus.
  490. */
  491. void OutlineDoc_SetFormulaBarEditText(
  492. LPOUTLINEDOC lpOutlineDoc,
  493. LPLINE lpLine
  494. )
  495. {
  496. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  497. char cBuf[MAXSTRLEN+1];
  498. if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
  499. return;
  500. if (Line_GetLineType(lpLine) != TEXTLINETYPE) {
  501. FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, NULL);
  502. } else {
  503. TextLine_GetTextData((LPTEXTLINE)lpLine, (LPSTR)cBuf);
  504. FrameTools_FB_SetEditText(lpOutlineDoc->m_lpFrameTools, (LPSTR)cBuf);
  505. }
  506. }
  507. /* OutlineDoc_SetFormulaBarEditFocus
  508. * ---------------------------------
  509. *
  510. * Setup for formula bar to gain or loose edit focus.
  511. * if gaining focus, setup up special accelerator table and scroll line
  512. * into view.
  513. * else restore normal accelerator table.
  514. */
  515. void OutlineDoc_SetFormulaBarEditFocus(
  516. LPOUTLINEDOC lpOutlineDoc,
  517. BOOL fEditFocus
  518. )
  519. {
  520. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  521. LPLINELIST lpLL;
  522. int nFocusIndex;
  523. if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
  524. return;
  525. lpOutlineDoc->m_lpFrameTools->m_fInFormulaBar = fEditFocus;
  526. if (fEditFocus && lpOutlineDoc->m_lpFrameTools) {
  527. lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
  528. nFocusIndex = LineList_GetFocusLineIndex(lpLL);
  529. LineList_ScrollLineIntoView(lpLL, nFocusIndex);
  530. FrameTools_FB_FocusEdit(lpOutlineDoc->m_lpFrameTools);
  531. }
  532. OutlineApp_SetFormulaBarAccel(lpOutlineApp, fEditFocus);
  533. }
  534. /* OutlineDoc_IsEditFocusInFormulaBar
  535. ** ----------------------------------
  536. ** Returns TRUE if edit focus is currently in the formula bar
  537. ** else FALSE if not.
  538. */
  539. BOOL OutlineDoc_IsEditFocusInFormulaBar(LPOUTLINEDOC lpOutlineDoc)
  540. {
  541. if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
  542. return FALSE;
  543. return lpOutlineDoc->m_lpFrameTools->m_fInFormulaBar;
  544. }
  545. /* OutlineDoc_UpdateFrameToolButtons
  546. ** ---------------------------------
  547. ** Update the Enable/Disable states of the buttons in the formula
  548. ** bar and button bar.
  549. */
  550. void OutlineDoc_UpdateFrameToolButtons(LPOUTLINEDOC lpOutlineDoc)
  551. {
  552. if (! lpOutlineDoc || ! lpOutlineDoc->m_lpFrameTools)
  553. return;
  554. FrameTools_UpdateButtons(lpOutlineDoc->m_lpFrameTools, lpOutlineDoc);
  555. }
  556. #endif // USE_FRAMETOOLS
  557. /* OutlineDoc_EditLineCommand
  558. * --------------------------
  559. *
  560. * Edit the current focus line.
  561. */
  562. void OutlineDoc_EditLineCommand(LPOUTLINEDOC lpOutlineDoc)
  563. {
  564. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  565. HDC hDC = LineList_GetDC(lpLL);
  566. int nIndex = LineList_GetFocusLineIndex(lpLL);
  567. LPLINE lpLine = LineList_GetLine(lpLL, nIndex);
  568. int nOrgLineWidthInHimetric;
  569. int nNewLineWidthInHimetric;
  570. BOOL fSizeChanged;
  571. if (!lpLine)
  572. return;
  573. nOrgLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
  574. if (Line_Edit(lpLine, lpOutlineDoc->m_hWndDoc, hDC)) {
  575. nNewLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
  576. if (nNewLineWidthInHimetric > nOrgLineWidthInHimetric) {
  577. fSizeChanged = LineList_SetMaxLineWidthInHimetric(
  578. lpLL,
  579. nNewLineWidthInHimetric
  580. );
  581. } else {
  582. fSizeChanged = LineList_RecalcMaxLineWidthInHimetric(
  583. lpLL,
  584. nOrgLineWidthInHimetric
  585. );
  586. }
  587. #if defined( OLE_SERVER )
  588. /* Update Name Table */
  589. ServerNameTable_EditLineUpdate(
  590. (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
  591. nIndex
  592. );
  593. #endif
  594. OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
  595. LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
  596. }
  597. LineList_ReleaseDC(lpLL, hDC);
  598. }
  599. /* OutlineDoc_IndentCommand
  600. * ------------------------
  601. *
  602. * Indent selection of lines
  603. */
  604. void OutlineDoc_IndentCommand(LPOUTLINEDOC lpOutlineDoc)
  605. {
  606. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  607. LPLINE lpLine;
  608. HDC hDC = LineList_GetDC(lpLL);
  609. int i;
  610. int nIndex;
  611. int nNumSel;
  612. LINERANGE lrSel;
  613. BOOL fSizeChanged = FALSE;
  614. nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
  615. OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
  616. for(i = 0; i < nNumSel; i++) {
  617. nIndex = lrSel.m_nStartLine + i;
  618. lpLine=LineList_GetLine(lpLL, nIndex);
  619. if (! lpLine)
  620. continue;
  621. Line_Indent(lpLine, hDC);
  622. if (LineList_SetMaxLineWidthInHimetric(lpLL,
  623. Line_GetTotalWidthInHimetric(lpLine))) {
  624. fSizeChanged = TRUE;
  625. }
  626. LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
  627. #if defined( OLE_SERVER )
  628. /* Update Name Table */
  629. ServerNameTable_EditLineUpdate(
  630. (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
  631. nIndex
  632. );
  633. #endif
  634. }
  635. LineList_ReleaseDC(lpLL, hDC);
  636. OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
  637. OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
  638. }
  639. /* OutlineDoc_UnindentCommand
  640. * --------------------------
  641. *
  642. * Unindent selection of lines
  643. */
  644. void OutlineDoc_UnindentCommand(LPOUTLINEDOC lpOutlineDoc)
  645. {
  646. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  647. LPLINE lpLine;
  648. HDC hDC = LineList_GetDC(lpLL);
  649. int nOrgLineWidthInHimetric;
  650. int nOrgMaxLineWidthInHimetric = 0;
  651. int i;
  652. int nIndex;
  653. int nNumSel;
  654. LINERANGE lrSel;
  655. BOOL fSizeChanged;
  656. nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
  657. OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
  658. for(i = 0; i < nNumSel; i++) {
  659. nIndex = lrSel.m_nStartLine + i;
  660. lpLine=LineList_GetLine(lpLL, nIndex);
  661. if (!lpLine)
  662. continue;
  663. nOrgLineWidthInHimetric = Line_GetTotalWidthInHimetric(lpLine);
  664. nOrgMaxLineWidthInHimetric =
  665. (nOrgLineWidthInHimetric > nOrgMaxLineWidthInHimetric ?
  666. nOrgLineWidthInHimetric : nOrgMaxLineWidthInHimetric);
  667. Line_Unindent(lpLine, hDC);
  668. LineList_ForceLineRedraw(lpLL, nIndex, TRUE);
  669. #if defined( OLE_SERVER )
  670. /* Update Name Table */
  671. ServerNameTable_EditLineUpdate(
  672. (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable,
  673. nIndex
  674. );
  675. #endif
  676. }
  677. LineList_ReleaseDC(lpLL, hDC);
  678. fSizeChanged = LineList_RecalcMaxLineWidthInHimetric(
  679. lpLL,
  680. nOrgMaxLineWidthInHimetric
  681. );
  682. OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, fSizeChanged);
  683. OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
  684. }
  685. /* OutlineDoc_SetLineHeightCommand
  686. * -------------------------------
  687. *
  688. * Set height of the selection of lines
  689. */
  690. void OutlineDoc_SetLineHeightCommand(LPOUTLINEDOC lpOutlineDoc)
  691. {
  692. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  693. LPLINELIST lpLL;
  694. HDC hDC;
  695. LPLINE lpLine;
  696. int nNewHeight;
  697. int i;
  698. int nIndex;
  699. int nNumSel;
  700. LINERANGE lrSel;
  701. if (!lpOutlineDoc)
  702. return;
  703. lpLL = &lpOutlineDoc->m_LineList;
  704. nNumSel=LineList_GetSel(lpLL, (LPLINERANGE)&lrSel);
  705. lpLine = LineList_GetLine(lpLL, lrSel.m_nStartLine);
  706. if (!lpLine)
  707. return;
  708. nNewHeight = Line_GetHeightInHimetric(lpLine);
  709. #if defined( OLE_VERSION )
  710. OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
  711. #endif
  712. DialogBoxParam(
  713. lpOutlineApp->m_hInst,
  714. (LPSTR)"SetLineHeight",
  715. lpOutlineDoc->m_hWndDoc,
  716. SetLineHeightDlgProc,
  717. (LPARAM)(LPINT)&nNewHeight
  718. );
  719. #if defined( OLE_VERSION )
  720. OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
  721. #endif
  722. if (nNewHeight == 0)
  723. return; /* user hit cancel */
  724. hDC = LineList_GetDC(lpLL);
  725. for (i = 0; i < nNumSel; i++) {
  726. nIndex = lrSel.m_nStartLine + i;
  727. lpLine=LineList_GetLine(lpLL, nIndex);
  728. if (nNewHeight == -1) {
  729. switch (Line_GetLineType(lpLine)) {
  730. case TEXTLINETYPE:
  731. TextLine_CalcExtents((LPTEXTLINE)lpLine, hDC);
  732. break;
  733. #if defined( OLE_CNTR )
  734. case CONTAINERLINETYPE:
  735. ContainerLine_SetHeightInHimetric(
  736. (LPCONTAINERLINE)lpLine, -1);
  737. break;
  738. #endif
  739. }
  740. }
  741. else
  742. Line_SetHeightInHimetric(lpLine, nNewHeight);
  743. LineList_SetLineHeight(lpLL, nIndex,
  744. Line_GetHeightInHimetric(lpLine));
  745. }
  746. LineList_ReleaseDC(lpLL, hDC);
  747. OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE);
  748. LineList_ForceRedraw(lpLL, TRUE);
  749. }
  750. /* OutlineDoc_SelectAllCommand
  751. * ---------------------------
  752. *
  753. * Select all the lines in the document.
  754. */
  755. void OutlineDoc_SelectAllCommand(LPOUTLINEDOC lpOutlineDoc)
  756. {
  757. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  758. LINERANGE lrSel;
  759. lrSel.m_nStartLine = 0;
  760. lrSel.m_nEndLine = LineList_GetCount(lpLL) - 1;
  761. LineList_SetSel(lpLL, &lrSel);
  762. }
  763. /* OutlineDoc_DefineNameCommand
  764. * ----------------------------
  765. *
  766. * Define a name in the document
  767. */
  768. void OutlineDoc_DefineNameCommand(LPOUTLINEDOC lpOutlineDoc)
  769. {
  770. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  771. #if defined( OLE_VERSION )
  772. OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
  773. #endif
  774. DialogBoxParam(
  775. lpOutlineApp->m_hInst,
  776. (LPSTR)"DefineName",
  777. lpOutlineDoc->m_hWndDoc,
  778. DefineNameDlgProc,
  779. (LPARAM) lpOutlineDoc
  780. );
  781. #if defined( OLE_VERSION )
  782. OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
  783. #endif
  784. }
  785. /* OutlineDoc_GotoNameCommand
  786. * --------------------------
  787. *
  788. * Goto a predefined name in the document
  789. */
  790. void OutlineDoc_GotoNameCommand(LPOUTLINEDOC lpOutlineDoc)
  791. {
  792. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  793. #if defined( OLE_VERSION )
  794. OleApp_PreModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
  795. #endif
  796. DialogBoxParam(
  797. lpOutlineApp->m_hInst,
  798. (LPSTR)"GotoName",
  799. lpOutlineDoc->m_hWndDoc,
  800. GotoNameDlgProc,
  801. (LPARAM)lpOutlineDoc
  802. );
  803. #if defined( OLE_VERSION )
  804. OleApp_PostModalDialog((LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineDoc);
  805. #endif
  806. }
  807. /* OutlineDoc_ShowWindow
  808. * ---------------------
  809. *
  810. * Show the window of the document to the user.
  811. */
  812. void OutlineDoc_ShowWindow(LPOUTLINEDOC lpOutlineDoc)
  813. {
  814. #if defined( _DEBUG )
  815. OleDbgAssertSz(lpOutlineDoc->m_docInitType != DOCTYPE_UNKNOWN,
  816. "OutlineDoc_ShowWindow: can't show unitialized document\r\n");
  817. #endif
  818. if (lpOutlineDoc->m_docInitType == DOCTYPE_UNKNOWN)
  819. return;
  820. #if defined( OLE_VERSION )
  821. // Call OLE version of this function instead
  822. OleDoc_ShowWindow((LPOLEDOC)lpOutlineDoc);
  823. #else
  824. ShowWindow(lpOutlineDoc->m_hWndDoc, SW_SHOWNORMAL);
  825. SetFocus(lpOutlineDoc->m_hWndDoc);
  826. #endif
  827. }
  828. #if defined( USE_FRAMETOOLS )
  829. void OutlineDoc_AddFrameLevelTools(LPOUTLINEDOC lpOutlineDoc)
  830. {
  831. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  832. #if defined( INPLACE_CNTR )
  833. // Call OLE In-Place Container version of this function instead
  834. ContainerDoc_AddFrameLevelTools((LPCONTAINERDOC)lpOutlineDoc);
  835. #else // ! INPLACE_CNTR
  836. RECT rcFrameRect;
  837. BORDERWIDTHS frameToolWidths;
  838. #if defined( INPLACE_SVR )
  839. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  840. LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc);
  841. // if in-place active, add our tools to our in-place container's frame.
  842. if (lpTopIPFrame) {
  843. ServerDoc_AddFrameLevelTools(lpServerDoc);
  844. return;
  845. }
  846. #endif // INPLACE_SVR
  847. OutlineApp_GetFrameRect(g_lpApp, (LPRECT)&rcFrameRect);
  848. FrameTools_GetRequiredBorderSpace(
  849. lpOutlineDoc->m_lpFrameTools,
  850. (LPBORDERWIDTHS)&frameToolWidths
  851. );
  852. OutlineApp_SetBorderSpace(g_lpApp, (LPBORDERWIDTHS)&frameToolWidths);
  853. FrameTools_AttachToFrame(
  854. lpOutlineDoc->m_lpFrameTools, OutlineApp_GetWindow(lpOutlineApp));
  855. FrameTools_Move(lpOutlineDoc->m_lpFrameTools, (LPRECT)&rcFrameRect);
  856. #endif // ! INPLACE_CNTR
  857. }
  858. #endif // USE_FRAMETOOLS
  859. /* OutlineDoc_GetWindow
  860. * --------------------
  861. *
  862. * Get the window handle of the document.
  863. */
  864. HWND OutlineDoc_GetWindow(LPOUTLINEDOC lpOutlineDoc)
  865. {
  866. if(! lpOutlineDoc) return NULL;
  867. return lpOutlineDoc->m_hWndDoc;
  868. }
  869. /* OutlineDoc_AddLine
  870. * ------------------
  871. *
  872. * Add one line to the Document's LineList
  873. */
  874. void OutlineDoc_AddLine(LPOUTLINEDOC lpOutlineDoc, LPLINE lpLine, int nIndex)
  875. {
  876. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  877. LineList_AddLine(lpLL, lpLine, nIndex);
  878. /* Update Name Table */
  879. OutlineNameTable_AddLineUpdate(lpOutlineDoc->m_lpNameTable, nIndex);
  880. #if defined( INPLACE_CNTR )
  881. {
  882. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  883. /* OLE2NOTE: after adding a line we need to
  884. ** update the PosRect of the In-Place active
  885. ** objects (if any) that follow the added line.
  886. ** NOTE: nIndex is index of line before new line.
  887. ** nIndex+1 is index of new line
  888. ** nIndex+2 is index of line after new line.
  889. */
  890. ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, nIndex+2);
  891. }
  892. #endif
  893. OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE);
  894. }
  895. /* OutlineDoc_DeleteLine
  896. * ---------------------
  897. *
  898. *
  899. * Delete one line from the document's LineList
  900. */
  901. void OutlineDoc_DeleteLine(LPOUTLINEDOC lpOutlineDoc, int nIndex)
  902. {
  903. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  904. #if defined( OLE_CNTR )
  905. LPLINE lpLine = LineList_GetLine(lpLL, nIndex);
  906. LPSTORAGE lpStgDoc = NULL;
  907. char szSaveStgName[CWCSTORAGENAME];
  908. BOOL fDeleteChildStg = FALSE;
  909. if (lpLine && (Line_GetLineType(lpLine) == CONTAINERLINETYPE) ) {
  910. /* OLE2NOTE: when a ContainerLine is being deleted by the user,
  911. ** it is important to delete the object's sub-storage
  912. ** otherwise it wastes space in the ContainerDoc's file.
  913. ** this function is called when lines are deleted by the
  914. ** Clear command and when lines are deleted by a DRAGMOVE
  915. ** operation.
  916. */
  917. LPCONTAINERLINE lpContainerLine = (LPCONTAINERLINE)lpLine;
  918. // save name of child storage
  919. LSTRCPYN(szSaveStgName, lpContainerLine->m_szStgName,
  920. sizeof(szSaveStgName));
  921. lpStgDoc = ((LPOLEDOC)lpContainerLine->m_lpDoc)->m_lpStg;
  922. fDeleteChildStg = TRUE;
  923. }
  924. #endif // OLE_CNTR
  925. LineList_DeleteLine(lpLL, nIndex);
  926. #if defined( OLE_CNTR )
  927. if (fDeleteChildStg && lpStgDoc) {
  928. HRESULT hrErr;
  929. // delete the obsolete child storage. it is NOT fatal if this fails
  930. hrErr = CallIStorageDestroyElementA(lpStgDoc, szSaveStgName);
  931. #if defined( _DEBUG )
  932. if (hrErr != NOERROR) {
  933. OleDbgOutHResult("IStorage::DestroyElement return", hrErr);
  934. }
  935. #endif
  936. }
  937. #endif // OLE_CNTR
  938. /* Update Name Table */
  939. OutlineNameTable_DeleteLineUpdate(lpOutlineDoc->m_lpNameTable, nIndex);
  940. #if defined( INPLACE_CNTR )
  941. {
  942. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  943. /* OLE2NOTE: after deleting a line we need to
  944. ** update the PosRect of the In-Place active
  945. ** objects (if any).
  946. */
  947. ContainerDoc_UpdateInPlaceObjectRects(lpContainerDoc, nIndex);
  948. }
  949. #endif
  950. OutlineDoc_SetModified(lpOutlineDoc, TRUE, TRUE, TRUE);
  951. #if defined( OLE_VERSION )
  952. {
  953. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  954. LPOLEDOC lpClipboardDoc = (LPOLEDOC)lpOutlineApp->m_lpClipboardDoc;
  955. /* OLE2NOTE: if the document that is the source of data on the
  956. ** clipborad has just had lines deleted, then the copied data
  957. ** is no longer considered a valid potential link source.
  958. ** disable the offering of CF_LINKSOURCE from the clipboard
  959. ** document. this avoids problems that arise when the
  960. ** editing operation changes or deletes the original data
  961. ** copied. we will not go to the trouble of determining if
  962. ** the deleted line actually is part of the link source.
  963. */
  964. if (lpClipboardDoc
  965. && lpClipboardDoc->m_fLinkSourceAvail
  966. && lpClipboardDoc->m_lpSrcDocOfCopy == (LPOLEDOC)lpOutlineDoc) {
  967. lpClipboardDoc->m_fLinkSourceAvail = FALSE;
  968. /* OLE2NOTE: since we are changing the list of formats on
  969. ** the clipboard (ie. removing CF_LINKSOURCE), we must
  970. ** call OleSetClipboard again. to be sure that the
  971. ** clipboard datatransfer document object does not get
  972. ** destroyed we will guard the call to OleSetClipboard
  973. ** within a pair of AddRef/Release.
  974. */
  975. OleDoc_AddRef((LPOLEDOC)lpClipboardDoc); // guard obj life-time
  976. OLEDBG_BEGIN2("OleSetClipboard called\r\n")
  977. OleSetClipboard(
  978. (LPDATAOBJECT)&((LPOLEDOC)lpClipboardDoc)->m_DataObject);
  979. OLEDBG_END2
  980. OleDoc_Release((LPOLEDOC)lpClipboardDoc); // rel. AddRef above
  981. }
  982. }
  983. #endif // OLE_VERSION
  984. }
  985. /* OutlineDoc_AddName
  986. * ------------------
  987. *
  988. * Add a Name to the Document's NameTable
  989. */
  990. void OutlineDoc_AddName(LPOUTLINEDOC lpOutlineDoc, LPOUTLINENAME lpOutlineName)
  991. {
  992. LPOUTLINENAMETABLE lpOutlineNameTable = lpOutlineDoc->m_lpNameTable;
  993. OutlineNameTable_AddName(lpOutlineNameTable, lpOutlineName);
  994. OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
  995. }
  996. /* OutlineDoc_DeleteName
  997. * ---------------------
  998. *
  999. *
  1000. * Delete Name from the document's NameTable
  1001. */
  1002. void OutlineDoc_DeleteName(LPOUTLINEDOC lpOutlineDoc, int nIndex)
  1003. {
  1004. LPOUTLINENAMETABLE lpOutlineNameTable = lpOutlineDoc->m_lpNameTable;
  1005. OutlineNameTable_DeleteName(lpOutlineNameTable, nIndex);
  1006. OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
  1007. }
  1008. /* OutlineDoc_Destroy
  1009. * ------------------
  1010. *
  1011. * Free all memory that had been allocated for a document.
  1012. * this destroys the LineList & NameTable of the document.
  1013. */
  1014. void OutlineDoc_Destroy(LPOUTLINEDOC lpOutlineDoc)
  1015. {
  1016. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  1017. #if defined( OLE_VERSION )
  1018. LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp;
  1019. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  1020. if (lpOleDoc->m_fObjIsDestroying)
  1021. return; // doc destruction is in progress
  1022. #endif // OLE_VERSION
  1023. OLEDBG_BEGIN3("OutlineDoc_Destroy\r\n");
  1024. #if defined( OLE_VERSION )
  1025. /* OLE2NOTE: in order to guarantee that the application does not
  1026. ** prematurely exit before the destruction of the document is
  1027. ** complete, we intially AddRef the App refcnt later Release it.
  1028. ** This initial AddRef is artificial; it simply guarantees that
  1029. ** the app object does not get destroyed until the end of this
  1030. ** routine.
  1031. */
  1032. OleApp_AddRef(lpOleApp);
  1033. /* OLE2NOTE: perform processing required for OLE */
  1034. OleDoc_Destroy(lpOleDoc);
  1035. #endif
  1036. LineList_Destroy(lpLL);
  1037. OutlineNameTable_Destroy(lpOutlineDoc->m_lpNameTable);
  1038. #if defined( USE_HEADING )
  1039. if (! lpOutlineDoc->m_fDataTransferDoc)
  1040. Heading_Destroy((LPHEADING)&lpOutlineDoc->m_heading);
  1041. #endif
  1042. #if defined( USE_FRAMETOOLS )
  1043. if (! lpOutlineDoc->m_fDataTransferDoc)
  1044. FrameTools_AssociateDoc(lpOutlineDoc->m_lpFrameTools, NULL);
  1045. #endif // USE_FRAMETOOLS
  1046. DestroyWindow(lpOutlineDoc->m_hWndDoc);
  1047. Delete(lpOutlineDoc); // free memory for doc itself
  1048. OleDbgOut1("@@@@ DOC DESTROYED\r\n");
  1049. #if defined( OLE_VERSION )
  1050. OleApp_Release(lpOleApp); // release artificial AddRef above
  1051. #endif
  1052. OLEDBG_END3
  1053. }
  1054. /* OutlineDoc_ReSize
  1055. * -----------------
  1056. *
  1057. * Resize the document and its components
  1058. *
  1059. * Parameter:
  1060. * lpRect the new size of the document. Use current size if NULL
  1061. */
  1062. void OutlineDoc_Resize(LPOUTLINEDOC lpOutlineDoc, LPRECT lpRect)
  1063. {
  1064. RECT rect;
  1065. LPLINELIST lpLL;
  1066. #if defined( USE_HEADING )
  1067. LPHEADING lphead;
  1068. #endif // USE_HEADING
  1069. LPSCALEFACTOR lpscale;
  1070. HWND hWndLL;
  1071. if (!lpOutlineDoc)
  1072. return;
  1073. lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList;
  1074. lpscale = (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
  1075. hWndLL = LineList_GetWindow(lpLL);
  1076. if (lpRect) {
  1077. CopyRect((LPRECT)&rect, lpRect);
  1078. MoveWindow(lpOutlineDoc->m_hWndDoc, rect.left, rect.top,
  1079. rect.right-rect.left, rect.bottom-rect.top, TRUE);
  1080. }
  1081. GetClientRect(lpOutlineDoc->m_hWndDoc, (LPRECT)&rect);
  1082. #if defined( USE_HEADING )
  1083. lphead = OutlineDoc_GetHeading(lpOutlineDoc);
  1084. rect.left += Heading_RH_GetWidth(lphead, lpscale);
  1085. rect.top += Heading_CH_GetHeight(lphead, lpscale);
  1086. #endif // USE_HEADING
  1087. if (lpLL) {
  1088. MoveWindow(hWndLL, rect.left, rect.top,
  1089. rect.right-rect.left, rect.bottom-rect.top, TRUE);
  1090. }
  1091. #if defined( USE_HEADING )
  1092. if (lphead)
  1093. Heading_Move(lphead, lpOutlineDoc->m_hWndDoc, lpscale);
  1094. #endif // USE_HEADING
  1095. #if defined( INPLACE_CNTR )
  1096. ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
  1097. #endif
  1098. }
  1099. /* OutlineDoc_GetNameTable
  1100. * -----------------------
  1101. *
  1102. * Get nametable associated with the line list
  1103. */
  1104. LPOUTLINENAMETABLE OutlineDoc_GetNameTable(LPOUTLINEDOC lpOutlineDoc)
  1105. {
  1106. if (!lpOutlineDoc)
  1107. return NULL;
  1108. else
  1109. return lpOutlineDoc->m_lpNameTable;
  1110. }
  1111. /* OutlineDoc_GetLineList
  1112. * ----------------------
  1113. *
  1114. * Get listlist associated with the OutlineDoc
  1115. */
  1116. LPLINELIST OutlineDoc_GetLineList(LPOUTLINEDOC lpOutlineDoc)
  1117. {
  1118. if (!lpOutlineDoc)
  1119. return NULL;
  1120. else
  1121. return (LPLINELIST)&lpOutlineDoc->m_LineList;
  1122. }
  1123. /* OutlineDoc_GetNameCount
  1124. * -----------------------
  1125. *
  1126. * Return number of names in table
  1127. */
  1128. int OutlineDoc_GetNameCount(LPOUTLINEDOC lpOutlineDoc)
  1129. {
  1130. return OutlineNameTable_GetCount(lpOutlineDoc->m_lpNameTable);
  1131. }
  1132. /* OutlineDoc_GetLineCount
  1133. * -----------------------
  1134. *
  1135. * Return number of lines in the LineList
  1136. */
  1137. int OutlineDoc_GetLineCount(LPOUTLINEDOC lpOutlineDoc)
  1138. {
  1139. return LineList_GetCount(&lpOutlineDoc->m_LineList);
  1140. }
  1141. /* OutlineDoc_SetFileName
  1142. * ----------------------
  1143. *
  1144. * Set the filename of a document.
  1145. *
  1146. * OLE2NOTE: If the ServerDoc has a valid filename then, the object is
  1147. * registered in the running object table (ROT). if the name of the doc
  1148. * changes (eg. via SaveAs) then the previous registration must be revoked
  1149. * and the document re-registered under the new name.
  1150. */
  1151. BOOL OutlineDoc_SetFileName(LPOUTLINEDOC lpOutlineDoc, LPSTR lpszNewFileName, LPSTORAGE lpNewStg)
  1152. {
  1153. OleDbgAssertSz(lpszNewFileName != NULL, "Can't reset doc to Untitled!");
  1154. if (lpszNewFileName == NULL)
  1155. return FALSE;
  1156. AnsiLowerBuff(lpszNewFileName, (UINT)lstrlen(lpszNewFileName));
  1157. #if defined( OLE_CNTR )
  1158. {
  1159. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  1160. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  1161. /* OLE2NOTE: the container version of the application keeps its
  1162. ** storage open at all times. if the document's storage is not
  1163. ** open, then open it.
  1164. */
  1165. if (lpNewStg) {
  1166. /* CASE 1 -- document is being loaded from a file. lpNewStg is
  1167. ** still open from the OutlineDoc_LoadFromFile function.
  1168. */
  1169. lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
  1170. } else {
  1171. /* CASE 2 -- document is being associated with a valid file
  1172. ** that is not yet open. thus we must now open the file.
  1173. */
  1174. if (lpOutlineDoc->m_docInitType == DOCTYPE_FROMFILE &&
  1175. lstrcmp(lpOutlineDoc->m_szFileName,lpszNewFileName)==0) {
  1176. /* CASE 2a -- new filename is same as current file. if the
  1177. ** stg is already open, then the lpStg is still valid.
  1178. ** if it is not open, then open it.
  1179. */
  1180. if (! lpOleDoc->m_lpStg) {
  1181. lpOleDoc->m_lpStg = OleStdOpenRootStorage(
  1182. lpszNewFileName,
  1183. STGM_READWRITE | STGM_SHARE_DENY_WRITE
  1184. );
  1185. if (! lpOleDoc->m_lpStg) return FALSE;
  1186. }
  1187. } else {
  1188. /* CASE 2b -- new filename is NOT same as current file.
  1189. ** a SaveAs operation is pending. open the new file and
  1190. ** hold the storage pointer in m_lpNewStg. the
  1191. ** subsequent call to Doc_SaveToFile will save the
  1192. ** document into the new storage pointer and release the
  1193. ** old storage pointer.
  1194. */
  1195. lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
  1196. lpContainerDoc->m_lpNewStg = OleStdCreateRootStorage(
  1197. lpszNewFileName,
  1198. STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_CREATE
  1199. );
  1200. if (! lpContainerDoc->m_lpNewStg) return FALSE;
  1201. }
  1202. }
  1203. }
  1204. #endif // OLE_CNTR
  1205. if (lpOutlineDoc->m_docInitType != DOCTYPE_FROMFILE ||
  1206. lstrcmp(lpOutlineDoc->m_szFileName, lpszNewFileName) != 0) {
  1207. /* A new valid file name is being associated with the document */
  1208. lstrcpy(lpOutlineDoc->m_szFileName, lpszNewFileName);
  1209. lpOutlineDoc->m_docInitType = DOCTYPE_FROMFILE;
  1210. // set lpszDocTitle to point to filename without path
  1211. lpOutlineDoc->m_lpszDocTitle = lpOutlineDoc->m_szFileName +
  1212. lstrlen(lpOutlineDoc->m_szFileName) - 1;
  1213. while (lpOutlineDoc->m_lpszDocTitle > lpOutlineDoc->m_szFileName
  1214. && ! IS_FILENAME_DELIM(lpOutlineDoc->m_lpszDocTitle[-1])) {
  1215. lpOutlineDoc->m_lpszDocTitle--;
  1216. }
  1217. OutlineDoc_SetTitle(lpOutlineDoc, TRUE /*fMakeUpperCase*/);
  1218. #if defined( OLE_VERSION )
  1219. {
  1220. /* OLE2NOTE: both containers and servers must properly
  1221. ** register in the RunningObjectTable. if the document
  1222. ** is performing a SaveAs operation, then it must
  1223. ** re-register in the ROT with the new moniker. in
  1224. ** addition any embedded object, pseudo objects, and/or
  1225. ** linking clients must be informed that the document's
  1226. ** moniker has changed.
  1227. */
  1228. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  1229. if (lpOleDoc->m_lpFileMoniker) {
  1230. OleStdRelease((LPUNKNOWN)lpOleDoc->m_lpFileMoniker);
  1231. lpOleDoc->m_lpFileMoniker = NULL;
  1232. }
  1233. CreateFileMonikerA(lpszNewFileName,
  1234. &lpOleDoc->m_lpFileMoniker);
  1235. OleDoc_DocRenamedUpdate(lpOleDoc, lpOleDoc->m_lpFileMoniker);
  1236. }
  1237. #endif // OLE_VERSION
  1238. }
  1239. return TRUE;
  1240. }
  1241. /* OutlineDoc_SetTitle
  1242. * -------------------
  1243. *
  1244. * Set window text to be current filename.
  1245. * The following window hierarchy exits:
  1246. * hWndApp
  1247. * hWndDoc
  1248. * hWndListBox
  1249. * The frame window is the window which gets the title.
  1250. */
  1251. void OutlineDoc_SetTitle(LPOUTLINEDOC lpOutlineDoc, BOOL fMakeUpperCase)
  1252. {
  1253. HWND hWnd;
  1254. LPSTR lpszText;
  1255. if (!lpOutlineDoc->m_hWndDoc) return;
  1256. if ((hWnd = GetParent(lpOutlineDoc->m_hWndDoc)) == NULL) return;
  1257. lpszText = OleStdMalloc((UINT)(lstrlen(APPNAME) + 4 +
  1258. lstrlen(lpOutlineDoc->m_lpszDocTitle)));
  1259. if (!lpszText) return;
  1260. lstrcpy(lpszText, APPNAME);
  1261. lstrcat(lpszText," - ");
  1262. lstrcat(lpszText, (LPSTR)lpOutlineDoc->m_lpszDocTitle);
  1263. if (fMakeUpperCase)
  1264. AnsiUpperBuff(lpszText, (UINT)lstrlen(lpszText));
  1265. SetWindowText(hWnd,lpszText);
  1266. OleStdFree(lpszText);
  1267. }
  1268. /* OutlineDoc_Close
  1269. * ----------------
  1270. *
  1271. * Close active document. If modified, prompt the user if
  1272. * he wants to save.
  1273. *
  1274. * Returns:
  1275. * FALSE -- user canceled the closing of the doc.
  1276. * TRUE -- the doc was successfully closed
  1277. */
  1278. BOOL OutlineDoc_Close(LPOUTLINEDOC lpOutlineDoc, DWORD dwSaveOption)
  1279. {
  1280. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1281. #if defined( OLE_VERSION )
  1282. /* OLE2NOTE: call OLE specific function instead */
  1283. return OleDoc_Close((LPOLEDOC)lpOutlineDoc, dwSaveOption);
  1284. #else
  1285. if (! lpOutlineDoc)
  1286. return TRUE; // active doc's are already destroyed
  1287. if (! OutlineDoc_CheckSaveChanges(lpOutlineDoc, &dwSaveOption))
  1288. return FALSE; // abort closing the doc
  1289. OutlineDoc_Destroy(lpOutlineDoc);
  1290. OutlineApp_DocUnlockApp(lpOutlineApp, lpOutlineDoc);
  1291. return TRUE;
  1292. #endif // ! OLE_VERSION
  1293. }
  1294. /* OutlineDoc_CheckSaveChanges
  1295. * ---------------------------
  1296. *
  1297. * Check if the document has been modified. if so, prompt the user if
  1298. * the changes should be saved. if yes save them.
  1299. * Returns TRUE if the doc is safe to close (user answered Yes or No)
  1300. * FALSE if the user canceled the save changes option.
  1301. */
  1302. BOOL OutlineDoc_CheckSaveChanges(
  1303. LPOUTLINEDOC lpOutlineDoc,
  1304. LPDWORD lpdwSaveOption
  1305. )
  1306. {
  1307. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1308. int nResponse;
  1309. if (*lpdwSaveOption == OLECLOSE_NOSAVE)
  1310. return TRUE;
  1311. if(! OutlineDoc_IsModified(lpOutlineDoc))
  1312. return TRUE; // saving is not necessary
  1313. /* OLE2NOTE: our document is dirty so it needs to be saved. if
  1314. ** OLECLOSE_PROMPTSAVE the user should be prompted to see if the
  1315. ** document should be saved. is specified but the document is NOT
  1316. ** visible to the user, then the user can NOT be prompted. in
  1317. ** the situation the document should be saved without prompting.
  1318. ** if OLECLOSE_SAVEIFDIRTY is specified then, the document
  1319. ** should also be saved without prompting.
  1320. */
  1321. if (*lpdwSaveOption == OLECLOSE_PROMPTSAVE &&
  1322. IsWindowVisible(lpOutlineDoc->m_hWndDoc)) {
  1323. // prompt the user to see if changes should be saved.
  1324. #if defined( OLE_VERSION )
  1325. OleApp_PreModalDialog(
  1326. (LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineApp->m_lpDoc);
  1327. #endif
  1328. nResponse = MessageBox(
  1329. lpOutlineApp->m_hWndApp,
  1330. MsgSaveFile,
  1331. APPNAME,
  1332. MB_ICONQUESTION | MB_YESNOCANCEL
  1333. );
  1334. #if defined( OLE_VERSION )
  1335. OleApp_PostModalDialog(
  1336. (LPOLEAPP)lpOutlineApp, (LPOLEDOC)lpOutlineApp->m_lpDoc);
  1337. #endif
  1338. if(nResponse==IDCANCEL)
  1339. return FALSE; // close is canceled
  1340. if(nResponse==IDNO) {
  1341. // Reset the save option to NOSAVE per user choice
  1342. *lpdwSaveOption = OLECLOSE_NOSAVE;
  1343. return TRUE; // don't save, but is ok to close
  1344. }
  1345. } else if (*lpdwSaveOption != OLECLOSE_SAVEIFDIRTY) {
  1346. OleDbgAssertSz(FALSE, "Invalid dwSaveOption\r\n");
  1347. *lpdwSaveOption = OLECLOSE_NOSAVE;
  1348. return TRUE; // unknown *lpdwSaveOption; close w/o saving
  1349. }
  1350. #if defined( OLE_SERVER )
  1351. if (lpOutlineDoc->m_docInitType == DOCTYPE_EMBEDDED) {
  1352. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  1353. HRESULT hrErr;
  1354. /* OLE2NOTE: Update the container before closing without prompting
  1355. ** the user. To update the container, we must ask our container
  1356. ** to save us.
  1357. */
  1358. OleDbgAssert(lpServerDoc->m_lpOleClientSite != NULL);
  1359. OLEDBG_BEGIN2("IOleClientSite::SaveObject called\r\n")
  1360. hrErr = lpServerDoc->m_lpOleClientSite->lpVtbl->SaveObject(
  1361. lpServerDoc->m_lpOleClientSite
  1362. );
  1363. OLEDBG_END2
  1364. if (hrErr != NOERROR) {
  1365. OleDbgOutHResult("IOleClientSite::SaveObject returned", hrErr);
  1366. return FALSE;
  1367. }
  1368. return TRUE; // doc is safe to be closed
  1369. } else
  1370. #endif // OLE_SERVER
  1371. {
  1372. return OutlineApp_SaveCommand(lpOutlineApp);
  1373. }
  1374. }
  1375. /* OutlineDoc_IsModified
  1376. * ---------------------
  1377. *
  1378. * Return modify flag of OUTLINEDOC
  1379. */
  1380. BOOL OutlineDoc_IsModified(LPOUTLINEDOC lpOutlineDoc)
  1381. {
  1382. if (lpOutlineDoc->m_fModified)
  1383. return lpOutlineDoc->m_fModified;
  1384. #if defined( OLE_CNTR )
  1385. {
  1386. /* OLE2NOTE: if there are OLE objects, then we must ask if any of
  1387. ** them are dirty. if so we must consider our document
  1388. ** as modified.
  1389. */
  1390. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  1391. LPLINELIST lpLL;
  1392. int nLines;
  1393. int nIndex;
  1394. LPLINE lpLine;
  1395. HRESULT hrErr;
  1396. lpLL = (LPLINELIST)&((LPOUTLINEDOC)lpContainerDoc)->m_LineList;
  1397. nLines = LineList_GetCount(lpLL);
  1398. for (nIndex = 0; nIndex < nLines; nIndex++) {
  1399. lpLine = LineList_GetLine(lpLL, nIndex);
  1400. if (!lpLine)
  1401. break;
  1402. if (Line_GetLineType(lpLine) == CONTAINERLINETYPE) {
  1403. LPCONTAINERLINE lpContainerLine = (LPCONTAINERLINE)lpLine;
  1404. if (lpContainerLine->m_lpPersistStg) {
  1405. hrErr = lpContainerLine->m_lpPersistStg->lpVtbl->IsDirty(
  1406. lpContainerLine->m_lpPersistStg);
  1407. /* OLE2NOTE: we will only accept an explicit "no i
  1408. ** am NOT dirty statement" (ie. S_FALSE) as an
  1409. ** indication that the object is clean. eg. if
  1410. ** the object returns E_NOTIMPL we must
  1411. ** interpret it as the object IS dirty.
  1412. */
  1413. if (GetScode(hrErr) != S_FALSE)
  1414. return TRUE;
  1415. }
  1416. }
  1417. }
  1418. }
  1419. #endif
  1420. return FALSE;
  1421. }
  1422. /* OutlineDoc_SetModified
  1423. * ----------------------
  1424. *
  1425. * Set the modified flag of the document
  1426. *
  1427. */
  1428. void OutlineDoc_SetModified(LPOUTLINEDOC lpOutlineDoc, BOOL fModified, BOOL fDataChanged, BOOL fSizeChanged)
  1429. {
  1430. lpOutlineDoc->m_fModified = fModified;
  1431. #if defined( OLE_SERVER )
  1432. if (! lpOutlineDoc->m_fDataTransferDoc) {
  1433. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  1434. /* OLE2NOTE: if the document has changed, then broadcast the change
  1435. ** to all clients who have set up Advise connections. notify
  1436. ** them that our data (and possibly also our extents) have
  1437. ** changed.
  1438. */
  1439. if (fDataChanged) {
  1440. lpServerDoc->m_fDataChanged = TRUE;
  1441. lpServerDoc->m_fSizeChanged = fSizeChanged;
  1442. lpServerDoc->m_fSendDataOnStop = TRUE;
  1443. ServerDoc_SendAdvise(
  1444. lpServerDoc,
  1445. OLE_ONDATACHANGE,
  1446. NULL, /* lpmkDoc -- not relevant here */
  1447. 0 /* advf -- no flags necessary */
  1448. );
  1449. }
  1450. }
  1451. #endif // OLE_SERVER
  1452. }
  1453. /* OutlineDoc_SetRedraw
  1454. * --------------------
  1455. *
  1456. * Enable/Disable the redraw of the document on screen.
  1457. * The calls to SetRedraw counted so that nested calls can be handled
  1458. * properly. calls to SetRedraw must be balanced.
  1459. *
  1460. * fEnbaleDraw = TRUE - enable redraw
  1461. * FALSE - disable redraw
  1462. */
  1463. void OutlineDoc_SetRedraw(LPOUTLINEDOC lpOutlineDoc, BOOL fEnableDraw)
  1464. {
  1465. static HCURSOR hPrevCursor = NULL;
  1466. if (fEnableDraw) {
  1467. if (lpOutlineDoc->m_nDisableDraw == 0)
  1468. return; // already enabled; no state transition
  1469. if (--lpOutlineDoc->m_nDisableDraw > 0)
  1470. return; // drawing should still be disabled
  1471. } else {
  1472. if (lpOutlineDoc->m_nDisableDraw++ > 0)
  1473. return; // already disabled; no state transition
  1474. }
  1475. if (lpOutlineDoc->m_nDisableDraw > 0) {
  1476. // this may take a while, put up hourglass cursor
  1477. hPrevCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1478. } else {
  1479. if (hPrevCursor) {
  1480. SetCursor(hPrevCursor); // restore original cursor
  1481. hPrevCursor = NULL;
  1482. }
  1483. }
  1484. #if defined( OLE_SERVER )
  1485. /* OLE2NOTE: for the Server version, while Redraw is disabled
  1486. ** postpone sending advise notifications until Redraw is re-enabled.
  1487. */
  1488. {
  1489. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  1490. LPSERVERNAMETABLE lpServerNameTable =
  1491. (LPSERVERNAMETABLE)lpOutlineDoc->m_lpNameTable;
  1492. if (lpOutlineDoc->m_nDisableDraw == 0) {
  1493. /* drawing is being Enabled. if changes occurred while drawing
  1494. ** was disabled, then notify clients now.
  1495. */
  1496. if (lpServerDoc->m_fDataChanged)
  1497. ServerDoc_SendAdvise(
  1498. lpServerDoc,
  1499. OLE_ONDATACHANGE,
  1500. NULL, /* lpmkDoc -- not relevant here */
  1501. 0 /* advf -- no flags necessary */
  1502. );
  1503. /* OLE2NOTE: send pending change notifications for pseudo objs. */
  1504. ServerNameTable_SendPendingAdvises(lpServerNameTable);
  1505. }
  1506. }
  1507. #endif // OLE_SERVER
  1508. #if defined( OLE_CNTR )
  1509. /* OLE2NOTE: for the Container version, while Redraw is disabled
  1510. ** postpone updating the extents of OLE objects until Redraw is
  1511. ** re-enabled.
  1512. */
  1513. {
  1514. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  1515. /* Update the extents of any OLE object that is marked that
  1516. ** its size may have changed. when an
  1517. ** IAdviseSink::OnViewChange notification is received,
  1518. ** the corresponding ContainerLine is marked
  1519. ** (m_fDoGetExtent==TRUE) and a message
  1520. ** (WM_U_UPDATEOBJECTEXTENT) is posted to the document
  1521. ** indicating that there are dirty objects.
  1522. */
  1523. if (lpOutlineDoc->m_nDisableDraw == 0)
  1524. ContainerDoc_UpdateExtentOfAllOleObjects(lpContainerDoc);
  1525. }
  1526. #endif // OLE_CNTR
  1527. // enable/disable redraw of the LineList listbox
  1528. LineList_SetRedraw(&lpOutlineDoc->m_LineList, fEnableDraw);
  1529. }
  1530. /* OutlineDoc_SetSel
  1531. * -----------------
  1532. *
  1533. * Set the selection in the documents's LineList
  1534. */
  1535. void OutlineDoc_SetSel(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
  1536. {
  1537. LineList_SetSel(&lpOutlineDoc->m_LineList, lplrSel);
  1538. }
  1539. /* OutlineDoc_GetSel
  1540. * -----------------
  1541. *
  1542. * Get the selection in the documents's LineList.
  1543. *
  1544. * Returns the count of items selected
  1545. */
  1546. int OutlineDoc_GetSel(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
  1547. {
  1548. return LineList_GetSel(&lpOutlineDoc->m_LineList, lplrSel);
  1549. }
  1550. /* OutlineDoc_ForceRedraw
  1551. * ----------------------
  1552. *
  1553. * Force the document window to repaint.
  1554. */
  1555. void OutlineDoc_ForceRedraw(LPOUTLINEDOC lpOutlineDoc, BOOL fErase)
  1556. {
  1557. if (!lpOutlineDoc)
  1558. return;
  1559. LineList_ForceRedraw(&lpOutlineDoc->m_LineList, fErase);
  1560. Heading_CH_ForceRedraw(&lpOutlineDoc->m_heading, fErase);
  1561. Heading_RH_ForceRedraw(&lpOutlineDoc->m_heading, fErase);
  1562. }
  1563. /* OutlineDoc_RenderFormat
  1564. * -----------------------
  1565. *
  1566. * Render a clipboard format supported by ClipboardDoc
  1567. */
  1568. void OutlineDoc_RenderFormat(LPOUTLINEDOC lpOutlineDoc, UINT uFormat)
  1569. {
  1570. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1571. HGLOBAL hData = NULL;
  1572. if (uFormat == lpOutlineApp->m_cfOutline)
  1573. hData = OutlineDoc_GetOutlineData(lpOutlineDoc, NULL);
  1574. else if (uFormat == CF_TEXT)
  1575. hData = OutlineDoc_GetTextData(lpOutlineDoc, NULL);
  1576. else {
  1577. OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgFormatNotSupported);
  1578. return;
  1579. }
  1580. SetClipboardData(uFormat, hData);
  1581. }
  1582. /* OutlineDoc_RenderAllFormats
  1583. * ---------------------------
  1584. *
  1585. * Render all formats supported by ClipboardDoc
  1586. */
  1587. void OutlineDoc_RenderAllFormats(LPOUTLINEDOC lpOutlineDoc)
  1588. {
  1589. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1590. HGLOBAL hData = NULL;
  1591. OpenClipboard(lpOutlineDoc->m_hWndDoc);
  1592. hData = OutlineDoc_GetOutlineData(lpOutlineDoc, NULL);
  1593. SetClipboardData(lpOutlineApp->m_cfOutline, hData);
  1594. hData = OutlineDoc_GetTextData(lpOutlineDoc, NULL);
  1595. SetClipboardData(CF_TEXT, hData);
  1596. CloseClipboard();
  1597. }
  1598. /* OutlineDoc_GetOutlineData
  1599. * -------------------------
  1600. *
  1601. * Return a handle to an array of TextLine objects for the desired line
  1602. * range.
  1603. * NOTE: if lplrSel == NULL, then all lines are returned
  1604. *
  1605. */
  1606. HGLOBAL OutlineDoc_GetOutlineData(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
  1607. {
  1608. HGLOBAL hOutline = NULL;
  1609. LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
  1610. LPLINE lpLine;
  1611. LPTEXTLINE arrLine;
  1612. int i;
  1613. int nStart = (lplrSel ? lplrSel->m_nStartLine : 0);
  1614. int nEnd =(lplrSel ? lplrSel->m_nEndLine : LineList_GetCount(lpLL)-1);
  1615. int nLines = nEnd - nStart + 1;
  1616. int nCopied = 0;
  1617. hOutline=GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT,sizeof(TEXTLINE)*nLines);
  1618. if (! hOutline) return NULL;
  1619. arrLine=(LPTEXTLINE)GlobalLock(hOutline);
  1620. for (i = nStart; i <= nEnd; i++) {
  1621. lpLine=LineList_GetLine(lpLL, i);
  1622. if (lpLine && Line_GetOutlineData(lpLine, &arrLine[nCopied]))
  1623. nCopied++;
  1624. }
  1625. GlobalUnlock(hOutline);
  1626. return hOutline;
  1627. }
  1628. /* OutlineDoc_GetTextData
  1629. * ----------------------
  1630. *
  1631. * Return a handle to an object's data in text form for the desired line
  1632. * range.
  1633. * NOTE: if lplrSel == NULL, then all lines are returned
  1634. *
  1635. */
  1636. HGLOBAL OutlineDoc_GetTextData(LPOUTLINEDOC lpOutlineDoc, LPLINERANGE lplrSel)
  1637. {
  1638. LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList;
  1639. LPLINE lpLine;
  1640. HGLOBAL hText = NULL;
  1641. LPSTR lpszText = NULL;
  1642. DWORD dwMemSize=0;
  1643. int i,j;
  1644. int nStart = (lplrSel ? lplrSel->m_nStartLine : 0);
  1645. int nEnd =(lplrSel ? lplrSel->m_nEndLine : LineList_GetCount(lpLL)-1);
  1646. int nTabLevel;
  1647. // calculate memory size required
  1648. for(i = nStart; i <= nEnd; i++) {
  1649. lpLine=LineList_GetLine(lpLL, i);
  1650. if (! lpLine)
  1651. continue;
  1652. dwMemSize += Line_GetTabLevel(lpLine);
  1653. dwMemSize += Line_GetTextLen(lpLine);
  1654. dwMemSize += 2; // add 1 for '\r\n' at the end of each line
  1655. }
  1656. dwMemSize++; // add 1 for '\0' at the end of string
  1657. if(!(hText = GlobalAlloc(GMEM_SHARE | GMEM_ZEROINIT, dwMemSize)))
  1658. return NULL;
  1659. if(!(lpszText = (LPSTR)GlobalLock(hText)))
  1660. return NULL;
  1661. // put line text to memory
  1662. for(i = nStart; i <= nEnd; i++) {
  1663. lpLine=LineList_GetLine(lpLL, i);
  1664. if (! lpLine)
  1665. continue;
  1666. nTabLevel=Line_GetTabLevel(lpLine);
  1667. for(j = 0; j < nTabLevel; j++)
  1668. *lpszText++='\t';
  1669. Line_GetTextData(lpLine, lpszText);
  1670. while(*lpszText)
  1671. lpszText++; // advance to end of string
  1672. *lpszText++ = '\r';
  1673. *lpszText++ = '\n';
  1674. }
  1675. GlobalUnlock (hText);
  1676. return hText;
  1677. }
  1678. /* OutlineDoc_SaveToFile
  1679. * ---------------------
  1680. *
  1681. * Save the document to a file with the same name as stored in the
  1682. * document
  1683. */
  1684. BOOL OutlineDoc_SaveToFile(LPOUTLINEDOC lpOutlineDoc, LPCSTR lpszFileName, UINT uFormat, BOOL fRemember)
  1685. {
  1686. #if defined( OLE_CNTR )
  1687. // Call OLE container specific function instead
  1688. return ContainerDoc_SaveToFile(
  1689. (LPCONTAINERDOC)lpOutlineDoc,
  1690. lpszFileName,
  1691. uFormat,
  1692. fRemember
  1693. );
  1694. #else
  1695. LPSTORAGE lpDestStg = NULL;
  1696. HRESULT hrErr;
  1697. BOOL fStatus;
  1698. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1699. if (fRemember) {
  1700. if (lpszFileName) {
  1701. fStatus = OutlineDoc_SetFileName(
  1702. lpOutlineDoc,
  1703. (LPSTR)lpszFileName,
  1704. NULL
  1705. );
  1706. if (! fStatus) goto error;
  1707. } else
  1708. lpszFileName = lpOutlineDoc->m_szFileName; // use cur. file name
  1709. } else if (! lpszFileName) {
  1710. goto error;
  1711. }
  1712. hrErr = StgCreateDocfileA(
  1713. lpszFileName,
  1714. STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE|STGM_CREATE,
  1715. 0,
  1716. &lpDestStg
  1717. );
  1718. OleDbgAssertSz(hrErr == NOERROR, "Could not create Docfile");
  1719. if (hrErr != NOERROR)
  1720. goto error;
  1721. #if defined( OLE_SERVER )
  1722. /* OLE2NOTE: we must be sure to write our class ID into our
  1723. ** storage. this information is used by OLE to determine the
  1724. ** class of the data stored in our storage. Even for top
  1725. ** "file-level" objects this information should be written to
  1726. ** the file.
  1727. */
  1728. if(WriteClassStg(lpDestStg, &CLSID_APP) != NOERROR)
  1729. goto error;
  1730. #endif
  1731. fStatus = OutlineDoc_SaveSelToStg(
  1732. lpOutlineDoc,
  1733. NULL,
  1734. uFormat,
  1735. lpDestStg,
  1736. FALSE, /* fSameAsLoad */
  1737. fRemember
  1738. );
  1739. if (! fStatus) goto error;
  1740. OleStdRelease((LPUNKNOWN)lpDestStg);
  1741. if (fRemember)
  1742. OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
  1743. #if defined( OLE_SERVER )
  1744. /* OLE2NOTE: (SERVER-ONLY) inform any linking clients that the
  1745. ** document has been saved. in addition, any currently active
  1746. ** pseudo objects should also inform their clients.
  1747. */
  1748. ServerDoc_SendAdvise (
  1749. (LPSERVERDOC)lpOutlineDoc,
  1750. OLE_ONSAVE,
  1751. NULL, /* lpmkDoc -- not relevant here */
  1752. 0 /* advf -- not relevant here */
  1753. );
  1754. #endif
  1755. return TRUE;
  1756. error:
  1757. if (lpDestStg)
  1758. OleStdRelease((LPUNKNOWN)lpDestStg);
  1759. OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgSaving);
  1760. return FALSE;
  1761. #endif // ! OLE_CNTR
  1762. }
  1763. /* OutlineDoc_LoadFromFile
  1764. * -----------------------
  1765. *
  1766. * Load a document from a file
  1767. */
  1768. BOOL OutlineDoc_LoadFromFile(LPOUTLINEDOC lpOutlineDoc, LPSTR lpszFileName)
  1769. {
  1770. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1771. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  1772. HRESULT hrErr;
  1773. SCODE sc;
  1774. LPSTORAGE lpSrcStg;
  1775. BOOL fStatus;
  1776. hrErr = StgOpenStorageA(lpszFileName,
  1777. NULL,
  1778. #if defined( OLE_CNTR )
  1779. STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_DENY_WRITE,
  1780. #else
  1781. STGM_READ | STGM_SHARE_DENY_WRITE,
  1782. #endif
  1783. NULL,
  1784. 0,
  1785. &lpSrcStg
  1786. );
  1787. if ((sc = GetScode(hrErr)) == STG_E_FILENOTFOUND) {
  1788. OutlineApp_ErrorMessage(lpOutlineApp, "File not found");
  1789. return FALSE;
  1790. } else if (sc == STG_E_FILEALREADYEXISTS) {
  1791. OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgFormat);
  1792. return FALSE;
  1793. } else if (sc != S_OK) {
  1794. OleDbgOutScode("StgOpenStorage returned", sc);
  1795. OutlineApp_ErrorMessage(
  1796. lpOutlineApp,
  1797. "File already in use--could not be opened"
  1798. );
  1799. return FALSE;
  1800. }
  1801. if(! OutlineDoc_LoadFromStg(lpOutlineDoc, lpSrcStg)) goto error;
  1802. fStatus = OutlineDoc_SetFileName(lpOutlineDoc, lpszFileName, lpSrcStg);
  1803. if (! fStatus) goto error;
  1804. OleStdRelease((LPUNKNOWN)lpSrcStg);
  1805. return TRUE;
  1806. error:
  1807. OleStdRelease((LPUNKNOWN)lpSrcStg);
  1808. OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgOpening);
  1809. return FALSE;
  1810. }
  1811. /* OutlineDoc_LoadFromStg
  1812. * ----------------------
  1813. *
  1814. * Load entire document from an open IStorage pointer (lpSrcStg)
  1815. * Return TRUE if ok, FALSE if error.
  1816. */
  1817. BOOL OutlineDoc_LoadFromStg(LPOUTLINEDOC lpOutlineDoc, LPSTORAGE lpSrcStg)
  1818. {
  1819. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1820. HRESULT hrErr;
  1821. BOOL fStatus;
  1822. ULONG nRead;
  1823. LINERANGE lrSel = { 0, 0 };
  1824. LPSTREAM lpLLStm;
  1825. OUTLINEDOCHEADER_ONDISK docRecordOnDisk;
  1826. OUTLINEDOCHEADER docRecord;
  1827. hrErr = CallIStorageOpenStreamA(
  1828. lpSrcStg,
  1829. "LineList",
  1830. NULL,
  1831. STGM_READ | STGM_SHARE_EXCLUSIVE,
  1832. 0,
  1833. &lpLLStm
  1834. );
  1835. if (hrErr != NOERROR) {
  1836. OleDbgOutHResult("Open LineList Stream returned", hrErr);
  1837. goto error;
  1838. }
  1839. /* read OutlineDoc header record */
  1840. hrErr = lpLLStm->lpVtbl->Read(
  1841. lpLLStm,
  1842. (LPVOID)&docRecordOnDisk,
  1843. sizeof(docRecordOnDisk),
  1844. &nRead
  1845. );
  1846. if (hrErr != NOERROR) {
  1847. OleDbgOutHResult("Read OutlineDoc header returned", hrErr);
  1848. goto error;
  1849. }
  1850. // Transform docRecordOnDisk into docRecord
  1851. // Compilers should handle aligment correctly
  1852. strcpy(docRecord.m_szFormatName, docRecordOnDisk.m_szFormatName);
  1853. docRecord.m_narrAppVersionNo[0] = (int) docRecordOnDisk.m_narrAppVersionNo[0];
  1854. docRecord.m_narrAppVersionNo[1] = (int) docRecordOnDisk.m_narrAppVersionNo[1];
  1855. docRecord.m_fShowHeading = (BOOL) docRecordOnDisk.m_fShowHeading;
  1856. docRecord.m_reserved1 = docRecordOnDisk.m_reserved1;
  1857. docRecord.m_reserved2 = docRecordOnDisk.m_reserved2;
  1858. docRecord.m_reserved3 = docRecordOnDisk.m_reserved3;
  1859. docRecord.m_reserved4 = docRecordOnDisk.m_reserved4;
  1860. fStatus = OutlineApp_VersionNoCheck(
  1861. lpOutlineApp,
  1862. docRecord.m_szFormatName,
  1863. docRecord.m_narrAppVersionNo
  1864. );
  1865. /* storage is an incompatible version; file can not be read */
  1866. if (! fStatus)
  1867. goto error;
  1868. lpOutlineDoc->m_heading.m_fShow = docRecord.m_fShowHeading;
  1869. #if defined( OLE_SERVER )
  1870. {
  1871. // Load ServerDoc specific data
  1872. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  1873. #if defined( SVR_TREATAS )
  1874. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1875. CLSID clsid;
  1876. CLIPFORMAT cfFmt;
  1877. LPSTR lpszType;
  1878. #endif // SVR_TREATAS
  1879. lpServerDoc->m_nNextRangeNo = (ULONG)docRecord.m_reserved1;
  1880. #if defined( SVR_TREATAS )
  1881. /* OLE2NOTE: if the Server is capable of supporting "TreatAs"
  1882. ** (aka. ActivateAs), it must read the class that is written
  1883. ** into the storage. if this class is NOT the app's own
  1884. ** class ID, then this is a TreatAs operation. the server
  1885. ** then must faithfully pretend to be the class that is
  1886. ** written into the storage. it must also faithfully write
  1887. ** the data back to the storage in the SAME format as is
  1888. ** written in the storage.
  1889. **
  1890. ** SVROUTL and ISVROTL can emulate each other. they have the
  1891. ** simplification that they both read/write the identical
  1892. ** format. thus for these apps no actual conversion of the
  1893. ** native bits is actually required.
  1894. */
  1895. lpServerDoc->m_clsidTreatAs = CLSID_NULL;
  1896. if (OleStdGetTreatAsFmtUserType(&CLSID_APP, lpSrcStg, &clsid,
  1897. (CLIPFORMAT FAR*)&cfFmt, (LPSTR FAR*)&lpszType)) {
  1898. if (cfFmt == lpOutlineApp->m_cfOutline) {
  1899. // We should perform TreatAs operation
  1900. if (lpServerDoc->m_lpszTreatAsType)
  1901. OleStdFreeString(lpServerDoc->m_lpszTreatAsType, NULL);
  1902. lpServerDoc->m_clsidTreatAs = clsid;
  1903. ((LPOUTLINEDOC)lpServerDoc)->m_cfSaveFormat = cfFmt;
  1904. lpServerDoc->m_lpszTreatAsType = lpszType;
  1905. OleDbgOut3("OutlineDoc_LoadFromStg: TreateAs ==> '");
  1906. OleDbgOutNoPrefix3(lpServerDoc->m_lpszTreatAsType);
  1907. OleDbgOutNoPrefix3("'\r\n");
  1908. } else {
  1909. // ERROR: we ONLY support TreatAs for CF_OUTLINE format
  1910. OleDbgOut("SvrDoc_PStg_InitNew: INVALID TreatAs Format\r\n");
  1911. OleStdFreeString(lpszType, NULL);
  1912. }
  1913. }
  1914. #endif // SVR_TREATAS
  1915. }
  1916. #endif // OLE_SVR
  1917. #if defined( OLE_CNTR )
  1918. {
  1919. // Load ContainerDoc specific data
  1920. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  1921. lpContainerDoc->m_nNextObjNo = (ULONG)docRecord.m_reserved2;
  1922. }
  1923. #endif // OLE_CNTR
  1924. OutlineDoc_SetRedraw ( lpOutlineDoc, FALSE );
  1925. if(! LineList_LoadFromStg(&lpOutlineDoc->m_LineList, lpSrcStg, lpLLStm))
  1926. goto error;
  1927. if(! OutlineNameTable_LoadFromStg(lpOutlineDoc->m_lpNameTable, lpSrcStg))
  1928. goto error;
  1929. OutlineDoc_SetModified(lpOutlineDoc, FALSE, FALSE, FALSE);
  1930. OutlineDoc_SetSel(lpOutlineDoc, &lrSel);
  1931. OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
  1932. OleStdRelease((LPUNKNOWN)lpLLStm);
  1933. #if defined( OLE_CNTR )
  1934. {
  1935. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  1936. /* A ContainerDoc keeps its storage open at all times. it is necessary
  1937. * to AddRef the lpSrcStg in order to hang on to it.
  1938. */
  1939. if (lpOleDoc->m_lpStg) {
  1940. OleStdVerifyRelease((LPUNKNOWN)lpOleDoc->m_lpStg,
  1941. "Doc Storage not released properly");
  1942. }
  1943. lpSrcStg->lpVtbl->AddRef(lpSrcStg);
  1944. lpOleDoc->m_lpStg = lpSrcStg;
  1945. }
  1946. #endif // OLE_CNTR
  1947. return TRUE;
  1948. error:
  1949. OutlineDoc_SetRedraw ( lpOutlineDoc, TRUE );
  1950. if (lpLLStm)
  1951. OleStdRelease((LPUNKNOWN)lpLLStm);
  1952. return FALSE;
  1953. }
  1954. BOOL Booga(void)
  1955. {
  1956. return FALSE;
  1957. }
  1958. /* OutlineDoc_SaveSelToStg
  1959. * -----------------------
  1960. *
  1961. * Save the specified selection of document into an IStorage*. All lines
  1962. * within the selection along with any names completely contained within the
  1963. * selection will be written
  1964. *
  1965. * Return TRUE if ok, FALSE if error
  1966. */
  1967. BOOL OutlineDoc_SaveSelToStg(
  1968. LPOUTLINEDOC lpOutlineDoc,
  1969. LPLINERANGE lplrSel,
  1970. UINT uFormat,
  1971. LPSTORAGE lpDestStg,
  1972. BOOL fSameAsLoad,
  1973. BOOL fRemember
  1974. )
  1975. {
  1976. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  1977. HRESULT hrErr = NOERROR;
  1978. LPSTREAM lpLLStm = NULL;
  1979. LPSTREAM lpNTStm = NULL;
  1980. ULONG nWritten;
  1981. BOOL fStatus;
  1982. OUTLINEDOCHEADER docRecord;
  1983. OUTLINEDOCHEADER_ONDISK docRecordOnDisk;
  1984. HCURSOR hPrevCursor;
  1985. #if defined( OLE_VERSION )
  1986. LPSTR lpszUserType;
  1987. LPOLEDOC lpOleDoc = (LPOLEDOC)lpOutlineDoc;
  1988. /* OLE2NOTE: we must be sure to write the information required for
  1989. ** OLE into our docfile. this includes user type
  1990. ** name, data format, etc. Even for top "file-level" objects
  1991. ** this information should be written to the file. Both
  1992. ** containters and servers should write this information.
  1993. */
  1994. #if defined( OLE_SERVER ) && defined( SVR_TREATAS )
  1995. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  1996. /* OLE2NOTE: if the Server is emulating another class (ie.
  1997. ** "TreatAs" aka. ActivateAs), it must write the same user type
  1998. ** name and format that was was originally written into the
  1999. ** storage rather than its own user type name.
  2000. **
  2001. ** SVROUTL and ISVROTL can emulate each other. they have the
  2002. ** simplification that they both read/write the identical
  2003. ** format. thus for these apps no actual conversion of the
  2004. ** native bits is actually required.
  2005. */
  2006. if (! IsEqualCLSID(&lpServerDoc->m_clsidTreatAs, &CLSID_NULL))
  2007. lpszUserType = lpServerDoc->m_lpszTreatAsType;
  2008. else
  2009. #endif // OLE_SERVER && SVR_TREATAS
  2010. lpszUserType = (LPSTR)FULLUSERTYPENAME;
  2011. hrErr = WriteFmtUserTypeStgA(lpDestStg, (CLIPFORMAT) uFormat,
  2012. lpszUserType);
  2013. if(hrErr != NOERROR) goto error;
  2014. if (fSameAsLoad) {
  2015. /* OLE2NOTE: we are saving into to same storage that we were
  2016. ** passed an load time. we deliberatly opened the streams we
  2017. ** need (lpLLStm and lpNTStm) at load time, so that we can
  2018. ** robustly save at save time in a low-memory situation.
  2019. ** this is particulary important the embedded objects do NOT
  2020. ** consume additional memory when
  2021. ** IPersistStorage::Save(fSameAsLoad==TRUE) is called.
  2022. */
  2023. LARGE_INTEGER libZero;
  2024. ULARGE_INTEGER ulibZero;
  2025. LISet32( libZero, 0 );
  2026. LISet32( ulibZero, 0 );
  2027. lpLLStm = lpOleDoc->m_lpLLStm;
  2028. /* because this is the fSameAsLoad==TRUE case, we will save
  2029. ** into the streams that we hold open. we will AddRef the
  2030. ** stream here so that the release below will NOT close the
  2031. ** stream.
  2032. */
  2033. lpLLStm->lpVtbl->AddRef(lpLLStm);
  2034. // truncate the current stream and seek to beginning
  2035. lpLLStm->lpVtbl->SetSize(lpLLStm, ulibZero);
  2036. lpLLStm->lpVtbl->Seek(
  2037. lpLLStm, libZero, STREAM_SEEK_SET, NULL);
  2038. lpNTStm = lpOleDoc->m_lpNTStm;
  2039. lpNTStm->lpVtbl->AddRef(lpNTStm); // (see comment above)
  2040. // truncate the current stream and seek to beginning
  2041. lpNTStm->lpVtbl->SetSize(lpNTStm, ulibZero);
  2042. lpNTStm->lpVtbl->Seek(
  2043. lpNTStm, libZero, STREAM_SEEK_SET, NULL);
  2044. } else
  2045. #endif // OLE_VERSION
  2046. {
  2047. hrErr = CallIStorageCreateStreamA(
  2048. lpDestStg,
  2049. "LineList",
  2050. STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
  2051. 0,
  2052. 0,
  2053. &lpLLStm
  2054. );
  2055. if (hrErr != NOERROR) {
  2056. OleDbgAssertSz(hrErr==NOERROR,"Could not create LineList stream");
  2057. OleDbgOutHResult("LineList CreateStream returned", hrErr);
  2058. goto error;
  2059. }
  2060. hrErr = CallIStorageCreateStreamA(
  2061. lpDestStg,
  2062. "NameTable",
  2063. STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
  2064. 0,
  2065. 0,
  2066. &lpNTStm
  2067. );
  2068. if (hrErr != NOERROR) {
  2069. OleDbgAssertSz(hrErr==NOERROR,"Could not create NameTable stream");
  2070. OleDbgOutHResult("NameTable CreateStream returned", hrErr);
  2071. goto error;
  2072. }
  2073. }
  2074. // this may take a while, put up hourglass cursor
  2075. hPrevCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  2076. _fmemset((LPOUTLINEDOCHEADER)&docRecord,0,sizeof(OUTLINEDOCHEADER));
  2077. GetClipboardFormatName(
  2078. uFormat,
  2079. docRecord.m_szFormatName,
  2080. sizeof(docRecord.m_szFormatName)
  2081. );
  2082. OutlineApp_GetAppVersionNo(lpOutlineApp, docRecord.m_narrAppVersionNo);
  2083. docRecord.m_fShowHeading = lpOutlineDoc->m_heading.m_fShow;
  2084. #if defined( OLE_SERVER )
  2085. {
  2086. // Store ServerDoc specific data
  2087. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  2088. docRecord.m_reserved1 = (DWORD)lpServerDoc->m_nNextRangeNo;
  2089. }
  2090. #endif
  2091. #if defined( OLE_CNTR )
  2092. {
  2093. // Store ContainerDoc specific data
  2094. LPCONTAINERDOC lpContainerDoc = (LPCONTAINERDOC)lpOutlineDoc;
  2095. docRecord.m_reserved2 = (DWORD)lpContainerDoc->m_nNextObjNo;
  2096. }
  2097. #endif
  2098. /* write OutlineDoc header record */
  2099. // Transform docRecord into docRecordOnDisk
  2100. // Compilers should handle aligment correctly
  2101. strcpy(docRecordOnDisk.m_szFormatName, docRecord.m_szFormatName);
  2102. docRecordOnDisk.m_narrAppVersionNo[0] = (short) docRecord.m_narrAppVersionNo[0];
  2103. docRecordOnDisk.m_narrAppVersionNo[1] = (short) docRecord.m_narrAppVersionNo[1];
  2104. docRecordOnDisk.m_fShowHeading = (USHORT) docRecord.m_fShowHeading;
  2105. docRecordOnDisk.m_reserved1 = docRecord.m_reserved1;
  2106. docRecordOnDisk.m_reserved2 = docRecord.m_reserved2;
  2107. docRecordOnDisk.m_reserved3 = docRecord.m_reserved3;
  2108. docRecordOnDisk.m_reserved4 = docRecord.m_reserved4;
  2109. hrErr = lpLLStm->lpVtbl->Write(
  2110. lpLLStm,
  2111. (LPVOID)&docRecordOnDisk,
  2112. sizeof(docRecordOnDisk),
  2113. &nWritten
  2114. );
  2115. if (hrErr != NOERROR) {
  2116. OleDbgOutHResult("Write OutlineDoc header returned", hrErr);
  2117. goto error;
  2118. }
  2119. // Save LineList
  2120. /* OLE2NOTE: A ContainerDoc keeps its storage open at all times. It is
  2121. ** necessary to pass the current open storage (lpOleDoc->m_lpStg)
  2122. ** to the LineList_SaveSelToStg method so that currently written data
  2123. ** for any embeddings is also saved to the new destination
  2124. ** storage. The data required by a contained object is both the
  2125. ** ContainerLine information and the associated sub-storage that is
  2126. ** written directly by the embedded object.
  2127. */
  2128. fStatus = LineList_SaveSelToStg(
  2129. &lpOutlineDoc->m_LineList,
  2130. lplrSel,
  2131. uFormat,
  2132. #if defined( OLE_CNTR )
  2133. lpOleDoc->m_lpStg,
  2134. #else
  2135. NULL,
  2136. #endif
  2137. lpDestStg,
  2138. lpLLStm,
  2139. fRemember
  2140. );
  2141. if (! fStatus) goto error;
  2142. // Save associated NameTable
  2143. fStatus = OutlineNameTable_SaveSelToStg(
  2144. lpOutlineDoc->m_lpNameTable,
  2145. lplrSel,
  2146. uFormat,
  2147. lpNTStm
  2148. );
  2149. if (! fStatus) goto error;
  2150. OleStdRelease((LPUNKNOWN)lpLLStm);
  2151. lpOutlineDoc->m_cfSaveFormat = uFormat; // remember format used to save
  2152. SetCursor(hPrevCursor); // restore original cursor
  2153. return TRUE;
  2154. error:
  2155. if (lpLLStm)
  2156. OleStdRelease((LPUNKNOWN)lpLLStm);
  2157. SetCursor(hPrevCursor); // restore original cursor
  2158. return FALSE;
  2159. }
  2160. /* OutlineDoc_Print
  2161. * ----------------
  2162. * Prints the contents of the list box in HIMETRIC mapping mode. Origin
  2163. * remains to be the upper left corner and the print proceeds down the
  2164. * page using a negative y-cordinate.
  2165. *
  2166. */
  2167. void OutlineDoc_Print(LPOUTLINEDOC lpOutlineDoc, HDC hDC)
  2168. {
  2169. LPLINELIST lpLL = &lpOutlineDoc->m_LineList;
  2170. LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  2171. WORD nIndex;
  2172. WORD nTotal;
  2173. int dy;
  2174. BOOL fError = FALSE;
  2175. LPLINE lpLine;
  2176. RECT rcLine;
  2177. RECT rcPix;
  2178. RECT rcHim;
  2179. RECT rcWindowOld;
  2180. RECT rcViewportOld;
  2181. HFONT hOldFont;
  2182. DOCINFO di; /* Document information for StartDoc function */
  2183. /* Get dimension of page */
  2184. rcPix.left = 0;
  2185. rcPix.top = 0;
  2186. rcPix.right = GetDeviceCaps(hDC, HORZRES);
  2187. rcPix.bottom = GetDeviceCaps(hDC, VERTRES);
  2188. SetDCToDrawInHimetricRect(hDC, (LPRECT)&rcPix, (LPRECT)&rcHim,
  2189. (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
  2190. // Set the default font size, and font face name
  2191. hOldFont = SelectObject(hDC, lpOutlineApp->m_hStdFont);
  2192. /* Get the lines in document */
  2193. nIndex = 0;
  2194. nTotal = LineList_GetCount(lpLL);
  2195. /* Create the Cancel dialog */
  2196. // REVIEW: should load dialog title from string resource file
  2197. hWndPDlg = CreateDialog (
  2198. lpOutlineApp->m_hInst,
  2199. "Print",
  2200. lpOutlineApp->m_hWndApp,
  2201. PrintDlgProc
  2202. );
  2203. if(!hWndPDlg)
  2204. goto getout;
  2205. /* Allow the app. to inform GDI of the abort function to call */
  2206. if(SetAbortProc(hDC, (ABORTPROC)AbortProc) < 0) {
  2207. fError = TRUE;
  2208. goto getout3;
  2209. }
  2210. /* Disable the main application window */
  2211. EnableWindow (lpOutlineApp->m_hWndApp, FALSE);
  2212. // initialize the rectangle for the first line
  2213. rcLine.left = rcHim.left;
  2214. rcLine.bottom = rcHim.top;
  2215. /* Initialize the document */
  2216. fCancelPrint = FALSE;
  2217. di.cbSize = sizeof(di);
  2218. di.lpszDocName = lpOutlineDoc->m_lpszDocTitle;
  2219. di.lpszOutput = NULL;
  2220. if(StartDoc(hDC, (DOCINFO FAR*)&di) <= 0) {
  2221. fError = TRUE;
  2222. OleDbgOut2("StartDoc error\n");
  2223. goto getout5;
  2224. }
  2225. if(StartPage(hDC) <= 0) { // start first page
  2226. fError = TRUE;
  2227. OleDbgOut2("StartPage error\n");
  2228. goto getout2;
  2229. }
  2230. /* While more lines print out the text */
  2231. while(nIndex < nTotal) {
  2232. lpLine = LineList_GetLine(lpLL, nIndex);
  2233. if (! lpLine)
  2234. continue;
  2235. dy = Line_GetHeightInHimetric(lpLine);
  2236. /* Reached end of page. Tell the device driver to eject a page */
  2237. if(rcLine.bottom - dy < rcHim.bottom) {
  2238. if (EndPage(hDC) < 0) {
  2239. fError=TRUE;
  2240. OleDbgOut2("EndPage error\n");
  2241. goto getout2;
  2242. }
  2243. // NOTE: Reset the Mapping mode of DC
  2244. SetDCToDrawInHimetricRect(hDC, (LPRECT)&rcPix, (LPRECT)&rcHim,
  2245. (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
  2246. // Set the default font size, and font face name
  2247. SelectObject(hDC, lpOutlineApp->m_hStdFont);
  2248. if (StartPage(hDC) <= 0) {
  2249. fError=TRUE;
  2250. OleDbgOut2("StartPage error\n");
  2251. goto getout2;
  2252. }
  2253. rcLine.bottom = rcHim.top;
  2254. }
  2255. rcLine.top = rcLine.bottom;
  2256. rcLine.bottom -= dy;
  2257. rcLine.right = rcLine.left + Line_GetWidthInHimetric(lpLine);
  2258. /* Print the line */
  2259. Line_Draw(lpLine, hDC, &rcLine, NULL, FALSE /*fHighlight*/);
  2260. OleDbgOut2("a line is drawn\n");
  2261. /* Test and see if the Abort flag has been set. If yes, exit. */
  2262. if (fCancelPrint)
  2263. goto getout2;
  2264. /* Move down the page */
  2265. nIndex++;
  2266. }
  2267. {
  2268. int nCode;
  2269. /* Eject the last page. */
  2270. if((nCode = EndPage(hDC)) < 0) {
  2271. #if defined( _DEBUG )
  2272. char szBuf[255];
  2273. wsprintf(szBuf, "EndPage error code is %d\n", nCode);
  2274. OleDbgOut2(szBuf);
  2275. #endif
  2276. fError=TRUE;
  2277. goto getout2;
  2278. }
  2279. }
  2280. /* Complete the document. */
  2281. if(EndDoc(hDC) < 0) {
  2282. fError=TRUE;
  2283. OleDbgOut2("EndDoc error\n");
  2284. getout2:
  2285. /* Ran into a problem before NEWFRAME? Abort the document */
  2286. AbortDoc(hDC);
  2287. }
  2288. getout5:
  2289. /* Re-enable main app. window */
  2290. EnableWindow (lpOutlineApp->m_hWndApp, TRUE);
  2291. getout3:
  2292. /* Close the cancel dialog */
  2293. DestroyWindow (hWndPDlg);
  2294. getout:
  2295. /* Error? make sure the user knows... */
  2296. if(fError || CommDlgExtendedError())
  2297. OutlineApp_ErrorMessage(lpOutlineApp, ErrMsgPrint);
  2298. SelectObject(hDC, hOldFont);
  2299. }
  2300. /* OutlineDoc_DialogHelp
  2301. * ---------------------
  2302. *
  2303. * Show help message for ole2ui dialogs.
  2304. *
  2305. * Parameters:
  2306. *
  2307. * hDlg HWND to the dialog the help message came from - use
  2308. * this in the call to WinHelp/MessageBox so that
  2309. * activation/focus goes back to the dialog, and not the
  2310. * main window.
  2311. *
  2312. * wParam ID of the dialog (so we know what type of dialog it is).
  2313. */
  2314. void OutlineDoc_DialogHelp(HWND hDlg, WPARAM wDlgID)
  2315. {
  2316. char szMessageBoxText[64];
  2317. if (!IsWindow(hDlg)) // don't do anything if we've got a bogus hDlg.
  2318. return;
  2319. lstrcpy(szMessageBoxText, "Help Message for ");
  2320. switch (wDlgID)
  2321. {
  2322. case IDD_CONVERT:
  2323. lstrcat(szMessageBoxText, "Convert");
  2324. break;
  2325. case IDD_CHANGEICON:
  2326. lstrcat(szMessageBoxText, "Change Icon");
  2327. break;
  2328. case IDD_INSERTOBJECT:
  2329. lstrcat(szMessageBoxText, "Insert Object");
  2330. break;
  2331. case IDD_PASTESPECIAL:
  2332. lstrcat(szMessageBoxText, "Paste Special");
  2333. break;
  2334. case IDD_EDITLINKS:
  2335. lstrcat(szMessageBoxText, "Edit Links");
  2336. break;
  2337. case IDD_CHANGESOURCE:
  2338. lstrcat(szMessageBoxText, "Change Source");
  2339. break;
  2340. case IDD_INSERTFILEBROWSE:
  2341. lstrcat(szMessageBoxText, "Insert From File Browse");
  2342. break;
  2343. case IDD_CHANGEICONBROWSE:
  2344. lstrcat(szMessageBoxText, "Change Icon Browse");
  2345. break;
  2346. default:
  2347. lstrcat(szMessageBoxText, "Unknown");
  2348. break;
  2349. }
  2350. lstrcat(szMessageBoxText, " Dialog.");
  2351. // You'd probably really a call to WinHelp here.
  2352. MessageBox(hDlg, szMessageBoxText, "Help", MB_OK);
  2353. return;
  2354. }
  2355. /* OutlineDoc_SetCurrentZoomCommand
  2356. * --------------------------------
  2357. *
  2358. * Set current zoom level to be checked in the menu.
  2359. * Set the corresponding scalefactor for the document.
  2360. */
  2361. void OutlineDoc_SetCurrentZoomCommand(
  2362. LPOUTLINEDOC lpOutlineDoc,
  2363. UINT uCurrentZoom
  2364. )
  2365. {
  2366. SCALEFACTOR scale;
  2367. if (!lpOutlineDoc)
  2368. return;
  2369. lpOutlineDoc->m_uCurrentZoom = uCurrentZoom;
  2370. switch (uCurrentZoom) {
  2371. #if !defined( OLE_CNTR )
  2372. case IDM_V_ZOOM_400:
  2373. scale.dwSxN = (DWORD) 4;
  2374. scale.dwSxD = (DWORD) 1;
  2375. scale.dwSyN = (DWORD) 4;
  2376. scale.dwSyD = (DWORD) 1;
  2377. break;
  2378. case IDM_V_ZOOM_300:
  2379. scale.dwSxN = (DWORD) 3;
  2380. scale.dwSxD = (DWORD) 1;
  2381. scale.dwSyN = (DWORD) 3;
  2382. scale.dwSyD = (DWORD) 1;
  2383. break;
  2384. case IDM_V_ZOOM_200:
  2385. scale.dwSxN = (DWORD) 2;
  2386. scale.dwSxD = (DWORD) 1;
  2387. scale.dwSyN = (DWORD) 2;
  2388. scale.dwSyD = (DWORD) 1;
  2389. break;
  2390. #endif // !OLE_CNTR
  2391. case IDM_V_ZOOM_100:
  2392. scale.dwSxN = (DWORD) 1;
  2393. scale.dwSxD = (DWORD) 1;
  2394. scale.dwSyN = (DWORD) 1;
  2395. scale.dwSyD = (DWORD) 1;
  2396. break;
  2397. case IDM_V_ZOOM_75:
  2398. scale.dwSxN = (DWORD) 3;
  2399. scale.dwSxD = (DWORD) 4;
  2400. scale.dwSyN = (DWORD) 3;
  2401. scale.dwSyD = (DWORD) 4;
  2402. break;
  2403. case IDM_V_ZOOM_50:
  2404. scale.dwSxN = (DWORD) 1;
  2405. scale.dwSxD = (DWORD) 2;
  2406. scale.dwSyN = (DWORD) 1;
  2407. scale.dwSyD = (DWORD) 2;
  2408. break;
  2409. case IDM_V_ZOOM_25:
  2410. scale.dwSxN = (DWORD) 1;
  2411. scale.dwSxD = (DWORD) 4;
  2412. scale.dwSyN = (DWORD) 1;
  2413. scale.dwSyD = (DWORD) 4;
  2414. break;
  2415. }
  2416. OutlineDoc_SetScaleFactor(lpOutlineDoc, (LPSCALEFACTOR)&scale, NULL);
  2417. }
  2418. /* OutlineDoc_GetCurrentZoomMenuCheck
  2419. * ----------------------------------
  2420. *
  2421. * Get current zoom level to be checked in the menu.
  2422. */
  2423. UINT OutlineDoc_GetCurrentZoomMenuCheck(LPOUTLINEDOC lpOutlineDoc)
  2424. {
  2425. return lpOutlineDoc->m_uCurrentZoom;
  2426. }
  2427. /* OutlineDoc_SetScaleFactor
  2428. * -------------------------
  2429. *
  2430. * Set the scale factor of the document which will affect the
  2431. * size of the document on the screen
  2432. *
  2433. * Parameters:
  2434. *
  2435. * scale structure containing x and y scales
  2436. */
  2437. void OutlineDoc_SetScaleFactor(
  2438. LPOUTLINEDOC lpOutlineDoc,
  2439. LPSCALEFACTOR lpscale,
  2440. LPRECT lprcDoc
  2441. )
  2442. {
  2443. LPLINELIST lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
  2444. HWND hWndLL = LineList_GetWindow(lpLL);
  2445. if (!lpOutlineDoc || !lpscale)
  2446. return;
  2447. InvalidateRect(hWndLL, NULL, TRUE);
  2448. lpOutlineDoc->m_scale = *lpscale;
  2449. LineList_ReScale((LPLINELIST)&lpOutlineDoc->m_LineList, lpscale);
  2450. #if defined( USE_HEADING )
  2451. Heading_ReScale((LPHEADING)&lpOutlineDoc->m_heading, lpscale);
  2452. #endif
  2453. OutlineDoc_Resize(lpOutlineDoc, lprcDoc);
  2454. }
  2455. /* OutlineDoc_GetScaleFactor
  2456. * -------------------------
  2457. *
  2458. * Retrieve the scale factor of the document
  2459. *
  2460. * Parameters:
  2461. *
  2462. */
  2463. LPSCALEFACTOR OutlineDoc_GetScaleFactor(LPOUTLINEDOC lpOutlineDoc)
  2464. {
  2465. if (!lpOutlineDoc)
  2466. return NULL;
  2467. return (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
  2468. }
  2469. /* OutlineDoc_SetCurrentMarginCommand
  2470. * ----------------------------------
  2471. *
  2472. * Set current Margin level to be checked in the menu.
  2473. */
  2474. void OutlineDoc_SetCurrentMarginCommand(
  2475. LPOUTLINEDOC lpOutlineDoc,
  2476. UINT uCurrentMargin
  2477. )
  2478. {
  2479. if (!lpOutlineDoc)
  2480. return;
  2481. lpOutlineDoc->m_uCurrentMargin = uCurrentMargin;
  2482. switch (uCurrentMargin) {
  2483. case IDM_V_SETMARGIN_0:
  2484. OutlineDoc_SetMargin(lpOutlineDoc, 0, 0);
  2485. break;
  2486. case IDM_V_SETMARGIN_1:
  2487. OutlineDoc_SetMargin(lpOutlineDoc, 1000, 1000);
  2488. break;
  2489. case IDM_V_SETMARGIN_2:
  2490. OutlineDoc_SetMargin(lpOutlineDoc, 2000, 2000);
  2491. break;
  2492. case IDM_V_SETMARGIN_3:
  2493. OutlineDoc_SetMargin(lpOutlineDoc, 3000, 3000);
  2494. break;
  2495. case IDM_V_SETMARGIN_4:
  2496. OutlineDoc_SetMargin(lpOutlineDoc, 4000, 4000);
  2497. break;
  2498. }
  2499. }
  2500. /* OutlineDoc_GetCurrentMarginMenuCheck
  2501. * ------------------------------------
  2502. *
  2503. * Get current Margin level to be checked in the menu.
  2504. */
  2505. UINT OutlineDoc_GetCurrentMarginMenuCheck(LPOUTLINEDOC lpOutlineDoc)
  2506. {
  2507. return lpOutlineDoc->m_uCurrentMargin;
  2508. }
  2509. /* OutlineDoc_SetMargin
  2510. * --------------------
  2511. *
  2512. * Set the left and right margin of the document
  2513. *
  2514. * Parameters:
  2515. * nLeftMargin - left margin in Himetric values
  2516. * nRightMargin - right margin in Himetric values
  2517. */
  2518. void OutlineDoc_SetMargin(LPOUTLINEDOC lpOutlineDoc, int nLeftMargin, int nRightMargin)
  2519. {
  2520. LPLINELIST lpLL;
  2521. int nMaxWidthInHim;
  2522. if (!lpOutlineDoc)
  2523. return;
  2524. lpOutlineDoc->m_nLeftMargin = nLeftMargin;
  2525. lpOutlineDoc->m_nRightMargin = nRightMargin;
  2526. lpLL = OutlineDoc_GetLineList(lpOutlineDoc);
  2527. // Force recalculation of Horizontal extent
  2528. nMaxWidthInHim = LineList_GetMaxLineWidthInHimetric(lpLL);
  2529. LineList_SetMaxLineWidthInHimetric(lpLL, -nMaxWidthInHim);
  2530. #if defined( INPLACE_CNTR )
  2531. ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
  2532. #endif
  2533. OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE);
  2534. }
  2535. /* OutlineDoc_GetMargin
  2536. * --------------------
  2537. *
  2538. * Get the left and right margin of the document
  2539. *
  2540. * Parameters:
  2541. * nLeftMargin - left margin in Himetric values
  2542. * nRightMargin - right margin in Himetric values
  2543. *
  2544. * Returns:
  2545. * low order word - left margin
  2546. * high order word - right margin
  2547. */
  2548. LONG OutlineDoc_GetMargin(LPOUTLINEDOC lpOutlineDoc)
  2549. {
  2550. if (!lpOutlineDoc)
  2551. return 0;
  2552. return MAKELONG(lpOutlineDoc->m_nLeftMargin, lpOutlineDoc->m_nRightMargin);
  2553. }
  2554. #if defined( USE_HEADING )
  2555. /* OutlineDoc_GetHeading
  2556. * ---------------------
  2557. *
  2558. * Get Heading Object in OutlineDoc
  2559. */
  2560. LPHEADING OutlineDoc_GetHeading(LPOUTLINEDOC lpOutlineDoc)
  2561. {
  2562. if (!lpOutlineDoc || lpOutlineDoc->m_fDataTransferDoc)
  2563. return NULL;
  2564. else
  2565. return (LPHEADING)&lpOutlineDoc->m_heading;
  2566. }
  2567. /* OutlineDoc_ShowHeading
  2568. * ----------------------
  2569. *
  2570. * Show/Hide document row/column headings.
  2571. */
  2572. void OutlineDoc_ShowHeading(LPOUTLINEDOC lpOutlineDoc, BOOL fShow)
  2573. {
  2574. LPHEADING lphead = OutlineDoc_GetHeading(lpOutlineDoc);
  2575. #if defined( INPLACE_SVR )
  2576. LPSERVERDOC lpServerDoc = (LPSERVERDOC)lpOutlineDoc;
  2577. #endif
  2578. if (! lphead)
  2579. return;
  2580. Heading_Show(lphead, fShow);
  2581. #if defined( INPLACE_SVR )
  2582. if (lpServerDoc->m_fUIActive) {
  2583. LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData;
  2584. /* OLE2NOTE: our extents have NOT changed; only our the size of
  2585. ** our object-frame adornments is changing. we can use the
  2586. ** current PosRect and ClipRect and simply resize our
  2587. ** windows WITHOUT informing our in-place container.
  2588. */
  2589. ServerDoc_ResizeInPlaceWindow(
  2590. lpServerDoc,
  2591. (LPRECT)&(lpIPData->rcPosRect),
  2592. (LPRECT)&(lpIPData->rcClipRect)
  2593. );
  2594. } else
  2595. #else // !INPLACE_SVR
  2596. OutlineDoc_Resize(lpOutlineDoc, NULL);
  2597. #if defined( INPLACE_CNTR )
  2598. ContainerDoc_UpdateInPlaceObjectRects((LPCONTAINERDOC)lpOutlineDoc, 0);
  2599. #endif // INPLACE_CNTR
  2600. #endif // INPLACE_SVR
  2601. OutlineDoc_ForceRedraw(lpOutlineDoc, TRUE);
  2602. }
  2603. #endif // USE_HEADING
  2604. /* AbortProc
  2605. * ---------
  2606. * AborProc is called by GDI print code to check for user abort.
  2607. */
  2608. BOOL FAR PASCAL EXPORT AbortProc (HDC hdc, WORD reserved)
  2609. {
  2610. MSG msg;
  2611. /* Allow other apps to run, or get abort messages */
  2612. while(! fCancelPrint && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  2613. if(!hWndPDlg || !IsDialogMessage (hWndPDlg, &msg)) {
  2614. TranslateMessage (&msg);
  2615. DispatchMessage (&msg);
  2616. }
  2617. }
  2618. return !fCancelPrint;
  2619. }
  2620. /* PrintDlgProc
  2621. * ------------
  2622. * Dialog function for the print cancel dialog box.
  2623. *
  2624. * RETURNS : TRUE - OK to abort/ not OK to abort
  2625. * FALSE - otherwise.
  2626. */
  2627. INT_PTR CALLBACK EXPORT PrintDlgProc(
  2628. HWND hwnd,
  2629. UINT msg,
  2630. WPARAM wParam,
  2631. LPARAM lParam
  2632. )
  2633. {
  2634. switch (msg) {
  2635. case WM_COMMAND:
  2636. /* abort printing if the only button gets hit */
  2637. fCancelPrint = TRUE;
  2638. return TRUE;
  2639. }
  2640. return FALSE;
  2641. }