home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osp1.exe / src / text / textplat.cpp < prev    next >
C/C++ Source or Header  |  1997-04-02  |  17KB  |  498 lines

  1. // %Z 1.13 os2/src/samples/text/textplat.cpp, odtextpart, od96os2, odos29712d 97/03/21 17:48:53 (97/01/29 15:56:11)
  2. //====START_GENERATED_PROLOG======================================
  3. //
  4. //
  5. //   COMPONENT_NAME: odtextpart
  6. //
  7. //   CLASSES: none
  8. //
  9. //   ORIGINS: 27
  10. //
  11. //
  12. //   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  13. //   All Rights Reserved
  14. //   Licensed Materials - Property of IBM
  15. //   US Government Users Restricted Rights - Use, duplication or
  16. //   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17. //
  18. //   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  19. //   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. //   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21. //   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  22. //   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  23. //   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  24. //   OR PERFORMANCE OF THIS SOFTWARE.
  25. //
  26. //====END_GENERATED_PROLOG========================================
  27. //
  28. #include "iodtext.h"
  29. #include <io.h>       // for file extensions
  30. #include <fcntl.h>    // for file open modes
  31. #include <sys\stat.h> // for file permissions
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <indxcoll.hpp>
  35.  
  36. #ifndef SOM_ODFacet_xh
  37. #include <Facet.xh>
  38. #endif
  39. #ifndef SOM_ODTransform_xh
  40. #include <Trnsform.xh>
  41. #endif
  42.  
  43. //------------------------------------------------------------------------------
  44. //                             ImportDlg
  45. //
  46. // - invokes the common Open File dialog box to import an ASCII file.
  47. // - returns the name of the file selected.
  48. //------------------------------------------------------------------------------
  49. ODBoolean PlatImportDlg(HWND hwnd, char* docName)
  50. {
  51.     char         szFile[kODMaxFileNameSize];
  52.     HWND         hwndDlg;  // Dialog box's hwnd
  53.     FILEDLG      fd;       // Control Block for WinFileDlg
  54.     char* dialogText;      // pointer for dialog title
  55.  
  56. #if defined(__IBMCPP__) || defined(_IBMR2)
  57.     nl_catd txNLSCat;       // NLS message catalog handle
  58.     setlocale(LC_ALL,"");
  59.  
  60.     txNLSCat=catopen(TX_NLS_CATALOG, NL_CAT_LOCALE); // Open NLS message catalog
  61.     dialogText = catgets(txNLSCat, TP_MSG_SET, TP_MSG_IMPORT_DLG, "Import");
  62. #else
  63.     dialogText = "Import";
  64. #endif
  65.  
  66.     // Initialize the FILEDLG control block to pass to the
  67.     // File Dialog - indicate it's a File Open Dialog
  68.     memset( &fd, 0, sizeof( fd ) );
  69.     fd.cbSize           = sizeof( FILEDLG );
  70.     fd.fl               = FDS_OPEN_DIALOG | FDS_HELPBUTTON | FDS_CENTER;
  71.     fd.pszTitle = dialogText;
  72.  
  73.     // Set the initial file filter to display all files (*.*)
  74.     strcpy(fd.szFullFile, "*.*");
  75.  
  76.     // Now we're ready to ask for the filename to import
  77.     hwndDlg = WinFileDlg(HWND_DESKTOP, hwnd, &fd);
  78.     WinUpdateWindow(hwnd);
  79.  
  80.     if (hwndDlg && (fd.lReturn == DID_OK))
  81.     {
  82.       strcpy(docName, fd.szFullFile);
  83. #ifdef ODDebug
  84.       PRINT ("Document Name is %s\n",docName);
  85. #endif
  86.       return kODTrue;
  87.     } // endif DID_OK
  88.     else
  89.        return kODFalse;
  90. }
  91.  
  92.  
  93. //------------------------------------------------------------------------------
  94. //                           ExportDlg
  95. // - invokes the common Save As File dialog box to obtain a file
  96. //   name to export TextPart's data.
  97. // - returns the name of the file specified.
  98. //------------------------------------------------------------------------------
  99. ODBoolean PlatExportDlg(HWND hwnd, char* docName)
  100. {
  101.  
  102.     char         szFile[kODMaxFileNameSize];
  103.     HWND         hwndDlg;  // Dialog box's hwnd
  104.     FILEDLG      fd;       // Control Block for WinFileDlg
  105.     char* dialogText;      // pointer for dialog title
  106.     ODBoolean    result = kODFalse;
  107.  
  108. #if defined(__IBMCPP__) || defined(_IBMR2)
  109.     nl_catd txNLSCat;       // NLS message catalog handle
  110.     setlocale(LC_ALL,"");
  111.  
  112.     txNLSCat=catopen(TX_NLS_CATALOG, NL_CAT_LOCALE); // Open NLS message catalog
  113.     dialogText = catgets(txNLSCat, TP_MSG_SET, TP_MSG_EXPORT_DLG, "Export");
  114. #else
  115.     dialogText = "Export";
  116. #endif
  117.  
  118.     // Initialize the FILEDLG control block to pass to the
  119.     // File Dialog - indicate it's a File Save As Dialog
  120.     memset( &fd, 0, sizeof( fd ) );
  121.     fd.cbSize           = sizeof( FILEDLG );
  122.     fd.fl               = FDS_SAVEAS_DIALOG | FDS_HELPBUTTON | FDS_CENTER;
  123.     fd.pszTitle = dialogText;
  124.  
  125.     // Set the initial file filter from the message catalog.  The
  126.     // default is to display all files (*.*).
  127.     // Set the initial file filter to display all files (*.*)
  128.     strcpy(fd.szFullFile, "*.*");
  129.  
  130.     // Now we're ready to ask for the filename to export
  131.     hwndDlg = WinFileDlg(HWND_DESKTOP, hwnd, &fd);
  132.     WinUpdateWindow(hwnd);
  133.  
  134.     if (hwndDlg && (fd.lReturn == DID_OK))
  135.     {
  136.       strcpy(docName, fd.szFullFile);
  137. #ifdef ODDebug
  138.       PRINT ("Document Name is %s\n",docName);
  139. #endif
  140.       return kODTrue;
  141.     } // endif DID_OK
  142.     else
  143.        return kODFalse;
  144. }
  145.  
  146. //------------------------------------------------------------------------------
  147. //                         PlatReadFile
  148. //
  149. // - allocates a buffer to read in the requested file.
  150. // - reads the requested file into the specified buffer.
  151. // - returns the buffer with the file contents.
  152. //------------------------------------------------------------------------------
  153. ODBoolean PlatReadFile(char* docName, char* &buffer, int& bytesRead)
  154. {
  155.     int hFile;
  156.     int fileSize;
  157.  
  158.     // If no file is read in, buffer will be empty
  159.     buffer = NULL;
  160.     bytesRead = 0;
  161.  
  162.     // Open the file for reading.
  163.     hFile = open(docName, O_RDONLY | O_TEXT);
  164.  
  165.     if (hFile == -1)
  166.     {
  167. #ifdef ODDebug
  168.       PRINT ("File open failed for %s\n",docName);
  169. #endif
  170.       return kODFalse;
  171.     }
  172.  
  173.     // Get the size of the file.
  174.     fileSize = filelength(hFile);
  175.  
  176.     // Allocate a buffer for the file to be read into.
  177.     buffer = (char *)SOMMalloc(fileSize);
  178.     if (buffer == NULL)
  179.     {
  180. #ifdef ODDebug
  181.       PRINT ("SOMMalloc failed!\n");
  182. #endif
  183.        close(hFile);
  184.       return kODFalse;
  185.     }
  186.  
  187.     // Read the file contents into a buffer.
  188.     bytesRead = read(hFile, buffer, fileSize);
  189.  
  190.     if (bytesRead == 0)
  191.     {
  192. #ifdef ODDebug
  193.       PRINT ("Zero bytes read.\n");
  194. #endif
  195.       close( hFile );
  196.       SOMFree(buffer);
  197.       return kODFalse;
  198.     }
  199.  
  200.     // Close the file
  201.       close( hFile );
  202. #ifdef ODDebug
  203.     PRINT ("File was successfully read.\n");
  204. #endif
  205.     return kODTrue;
  206. }
  207.  
  208.  
  209. //------------------------------------------------------------------------------
  210. //                        PlatWriteFile
  211. //
  212. // - creates the requested file.
  213. // - writes data from the specified buffer into the file.
  214. // - does not deallocate the buffer.
  215. //------------------------------------------------------------------------------
  216. ODBoolean PlatWriteFile(char* docName, char* buffer, int bufferSize)
  217. {
  218.     int hFile;
  219.     int bytesWritten = 0;
  220.  
  221.     // Open the file for writing.
  222.     hFile = open(docName, O_CREAT | O_WRONLY | O_TEXT, S_IREAD | S_IWRITE);
  223.  
  224.     if (hFile == -1)
  225.     {
  226. #ifdef ODDebug
  227.       PRINT ("File open failed for %s\n",docName);
  228. #endif
  229.       return kODFalse;
  230.     }
  231.  
  232.     // Write the file contents from the buffer.
  233.     bytesWritten = write(hFile,           // file handle
  234.                          (void*) buffer,  // data to write
  235.                          bufferSize);     // number bytes to write
  236.  
  237.     if (bytesWritten == 0)
  238.     {
  239. #ifdef ODDebug
  240.       PRINT ("Zero bytes written.\n");
  241. #endif
  242.       close( hFile );
  243.       return kODFalse;
  244.     }
  245.  
  246.     // Close the file
  247.     close( hFile );
  248. #ifdef ODDebug
  249.     PRINT ("File was successfully written.\n");
  250. #endif
  251.     return kODTrue;
  252. }
  253.  
  254. //------------------------------------------------------------------------------
  255. //                        TextMgr::DrawText
  256. //
  257. // - sets up the drawing environment
  258. // - draws all text for the specified area
  259. //------------------------------------------------------------------------------
  260. void TextMgr::DrawText(HPS hps, ODRect clipRect)
  261. {
  262.    RECTL frameRect;
  263.    int numPara = paragraphs->Count();
  264.    int firstParI;
  265.    int lastParI;
  266.  
  267.    // if there is no text to draw, no sense in continuing
  268.    if (!HasText())
  269.       return;
  270.  
  271.    frameRect.xLeft = FixedToInt(clipRect.left);
  272.    frameRect.xRight  = FixedToInt(clipRect.right);
  273.    frameRect.yTop  = FixedToInt(clipRect.top);
  274.    frameRect.yBottom  = FixedToInt(clipRect.bottom);
  275.  
  276.    // Figure out which paragraphs to draw, based on the clip region
  277.    firstParI = max(0, numPara - (frameRect.yTop / myFont.height));
  278.    lastParI = min(numPara-1, numPara - (frameRect.yBottom / myFont.height));
  279.  
  280.    // Adjust the clip region to correspond to one line of text
  281.    frameRect.yBottom  = frameRect.yTop - myFont.height;
  282.  
  283.    // Iterate through each paragraph to draw its text
  284.    for (int i=firstParI; i <= lastParI; i++)
  285.    {
  286.        Paragraph* para = (Paragraph*) paragraphs->FromIndex(i);
  287.        para->DrawText(hps, frameRect, myFont.width, myFont.descender);
  288.  
  289.        // Set up the clip region for the line of text below this one.
  290.        frameRect.yTop  = frameRect.yBottom - myFont.externalLeading;
  291.        frameRect.yBottom = frameRect.yTop - myFont.height;
  292.    } /* endfor */
  293. }
  294.  
  295. //------------------------------------------------------------------------------
  296. //                        TextMgr::SetCursor
  297. //
  298. // - Sets the cursor to the input position
  299. //------------------------------------------------------------------------------
  300. void TextMgr::SetCursor(HWND hwnd, ODPoint cursor, ODRect clipRect)
  301. {
  302.    int inputRow = FixedToInt(clipRect.top - cursor.y) / myFont.height;
  303.  
  304.    // Ensure that the cursor does not go beyond the last row of text.
  305.    currentPos.row = min(inputRow, paragraphs->Count()-1);
  306.  
  307.    // Set the current paragraph pointer so we can ensure the cursor does
  308.    // not go beyond the last column of the paragraph.
  309.    currentParagraph = (Paragraph*) paragraphs->FromIndex(currentPos.row);
  310.    currentPos.column = min(FixedToInt(cursor.x) / myFont.width,
  311.                            currentParagraph->GetTextSize());
  312. }
  313.  
  314. //------------------------------------------------------------------------------
  315. //                        TextMgr::DisplayCursor
  316. //
  317. // - Displays the cursor in the given window
  318. //------------------------------------------------------------------------------
  319. void TextMgr::DisplayCursor(ODFacet* facet, ODRect clipRect)
  320. {
  321.    RECTL frameRect;
  322.    POINTL origin;
  323.    ODPoint odOrigin;
  324.    BOOL rc;
  325.    int numPara = paragraphs->Count();
  326.    int firstParI;
  327.    int lastParI;
  328.  
  329.    frameRect.xLeft = FixedToInt(clipRect.left);
  330.    frameRect.xRight  = FixedToInt(clipRect.right);
  331.    frameRect.yTop  = FixedToInt(clipRect.top);
  332.    frameRect.yBottom  = FixedToInt(clipRect.bottom);
  333.  
  334.    // Figure out which paragraphs to draw, based on the clip region
  335.    firstParI = max(0, numPara - (frameRect.yTop / myFont.height));
  336.    lastParI = min(numPara-1, numPara - (frameRect.yBottom / myFont.height));
  337.  
  338.    // Use the paragraph range to determine if we need to display the cursor
  339.    if (currentPos.row >= firstParI && currentPos.row <= lastParI)
  340.    {
  341.       // Determine the cursor position relative to the frame
  342.       origin.x = frameRect.xLeft + currentPos.column * myFont.width;
  343.       origin.y = frameRect.yTop - ((currentPos.row - firstParI +1) * myFont.height);
  344.  
  345.       // Convert the cursor position to ODPoint coordinates and transform
  346.       // again to window coordinates.
  347.       odOrigin.x = IntToFixed(origin.x);
  348.       odOrigin.y = IntToFixed(origin.y);
  349.       HWND hwnd = facet->GetFacetHWND(myEv);
  350.       TempODTransform xform = facet->AcquireWindowContentTransform(myEv, kODNULL);
  351.       xform->TransformPoint (myEv, &odOrigin);
  352.  
  353.       // Convert the position back to integer coordinates, and set the cursor
  354.       // position.
  355.       origin.x = FixedToInt(odOrigin.x);
  356.       origin.y = FixedToInt(odOrigin.y);
  357.       rc = WinCreateCursor(hwnd,
  358.                     origin.x,            // x coordinate of cursor
  359.                     origin.y,            // y coordinate of cursor
  360.                     0, 0,                // use size from cursor creation
  361.                     CURSOR_SETPOS,       // set cursor position
  362.                     NULL);               // clip within window hwnd
  363.       WinShowCursor(hwnd, kODTrue);
  364.       if (rc == kODFalse)
  365.       {
  366.          HAB hab;
  367.          ERRORID errid = WinGetLastError(hab);
  368. #ifdef ODDebug
  369.       PRINT ("Error %x displaying cursor.\n",errid);
  370. #endif
  371.       } /* endif */
  372.    } /* endif */
  373. }
  374.  
  375. //------------------------------------------------------------------------------
  376. //                        TextMgr::SetFont
  377. //
  378. // - chooses a font for the drawing environment
  379. // - stores the necessary font metrics
  380. //------------------------------------------------------------------------------
  381. void TextMgr::SetFont(HPS hps, int printing)
  382. {
  383.    FONTMETRICS fontM;
  384.    FATTRS fontA;
  385.    LONG lcid = 42;
  386.  
  387.    // Set up our font attributes.  Since we are using an Outline font
  388.    // (as opposed to an Image font), we do not need to specify the
  389.    // MaxBaselineExt or the AveCharWidth fields.
  390.    memset(&fontA,0,sizeof(fontA));
  391.    fontA.usRecordLength = sizeof(FATTRS);
  392.    strcpy(fontA.szFacename, "Courier");
  393.    fontA.fsFontUse = FATTR_FONTUSE_OUTLINE;
  394.  
  395.    // Let the system choose a courier font for us
  396.    LONG match = GpiCreateLogFont(hps, (PSTR8) NULL, lcid, &fontA);
  397. #ifdef ODDebug
  398.    if (match == FONT_DEFAULT) {
  399.       PRINT ("Default font used.\n");
  400.    } else if (match == GPI_ERROR) {
  401.       PRINT ("Error in choosing font.\n");
  402.    } /* endif */
  403. #endif
  404.  
  405.    // Set the drawing font, color, etc. for our hps
  406.    GpiSetCharSet(hps, lcid);
  407.    GpiSetTextAlignment(hps, TA_STANDARD_HORIZ, TA_BASE);
  408.    GpiSetBackMix(hps,BM_LEAVEALONE);
  409.    GpiSetColor(hps, CLR_BLACK);
  410.  
  411.    // If we're printing, adjust the scale of the font
  412.    if (printing) {
  413.        SIZEF sizfCharBox;
  414.        sizfCharBox.cx = MAKEFIXED (12, 0);
  415.        sizfCharBox.cy = MAKEFIXED (12, 0);
  416.        GpiSetCharBox(hps,&sizfCharBox);  // scale the font
  417.    } /* endif */
  418.  
  419.    // Save the font characteristics to use later when we draw
  420.    GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fontM);
  421.    strcpy(myFont.name, fontM.szFacename);
  422.    myFont.id = fontM.lMatch;
  423.    myFont.width = fontM.lMaxCharInc;
  424.    myFont.height = fontM.lMaxBaselineExt;
  425.    myFont.externalLeading = fontM.lExternalLeading;
  426.    myFont.descender = fontM.lMaxDescender;
  427.    myFont.ascender = fontM.lMaxAscender;
  428. }
  429.  
  430. //------------------------------------------------------------------------------
  431. //                        TextMgr::CreateCursor
  432. //
  433. // - creates a system cursor for the given window
  434. //------------------------------------------------------------------------------
  435. void TextMgr::CreateCursor(HWND hwnd)
  436. {
  437.   BOOL rc = WinCreateCursor(hwnd,
  438.                   0, 0,                          // where to display cursor - set later
  439.                   0, myFont.height,              // use default width for cursor
  440.                   CURSOR_SOLID | CURSOR_FLASH,   // cursor appearance
  441.                   NULL);                         // clip within window hwnd
  442.   WinShowCursor(hwnd, kODTrue);
  443.   if (rc == kODFalse)
  444.   {
  445.      HAB hab;
  446.      ERRORID errid = WinGetLastError(hab);
  447. #ifdef ODDebug
  448.      PRINT ("Error %x creating cursor.\n",errid);
  449. #endif
  450.   }
  451. }
  452.  
  453. //------------------------------------------------------------------------------
  454. //                        TextMgr::DeleteCursor
  455. //
  456. // - deletes the system cursor for the given window
  457. //------------------------------------------------------------------------------
  458. void TextMgr::DeleteCursor(HWND hwnd)
  459. {
  460.   // First hide the cursor so no residual is left.
  461.   WinShowCursor(hwnd, kODFalse);
  462.   BOOL rc = WinDestroyCursor(hwnd);
  463.  
  464.   if (rc == kODFalse)
  465.   {
  466.      HAB hab;
  467.      ERRORID errid = WinGetLastError(hab);
  468. #ifdef ODDebug
  469.      PRINT ("Error %x deleting cursor.\n",errid);
  470. #endif
  471.   }
  472. }
  473.  
  474. //------------------------------------------------------------------------------
  475. //                        Paragraph::DrawText
  476. //
  477. // - draws this paragraph's text for the specified area
  478. //------------------------------------------------------------------------------
  479. void Paragraph::DrawText(HPS hps, RECTL frameRect, int fontWidth, int fontDesc)
  480. {
  481.    POINTL origin;
  482.    origin.x = frameRect.xLeft;
  483.    origin.y = frameRect.yBottom + fontDesc;
  484.    int startChar = frameRect.xLeft / fontWidth;
  485.    int numChars = textBufferSize - startChar;
  486.  
  487.    // Make sure we have characters to output.
  488.    if (numChars >0) {
  489.       GpiCharStringPosAt(hps,
  490.                     &origin,
  491.                     &frameRect,
  492.                     CHS_CLIP,
  493.                     numChars,
  494.                     textBuffer + startChar,
  495.                     NULL);
  496.    }
  497. }
  498.