Status of source code changes suggested in November 2014

HMG Unicode versions 3.1.x related

Moderator: Rathinagiri

User avatar
Rathinagiri
Posts: 5471
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Contact:

Re: Status of source code changes suggested in November 2014

Post by Rathinagiri »

Hi,

It is really off topic.

Is there any way to include tables in rich edit text? If it can be, then we can have our Grids/reports to be exported to a well formatted Rich Edit Text File.
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
EduardoLuis
Posts: 682
Joined: Tue Jun 04, 2013 6:33 pm
Location: Argentina

Re: Status of source code changes suggested in November 2014

Post by EduardoLuis »

+10 (Rathinagiri)

Although richedittext is an interesting control, changes proposed by Karmody means investing too much hours to upgrade a control which have restricted uses (proccesing text only).- But what is inadmissible is the rude form Karmody uses to apply for to Claudio.- The best way to be part of a community is speak or write courtly.-
With regards. Eduardo
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: Status of source code changes suggested in November 2014

Post by srvet_claudio »

Rathinagiri wrote:Hi,

It is really off topic.

Is there any way to include tables in rich edit text? If it can be, then we can have our Grids/reports to be exported to a well formatted Rich Edit Text File.
Yes is possible, but maybe not easy with programming, click in Help icon of: C:\hmg.3.4.1\SAMPLES\Controls\RichEditBox
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: Status of source code changes suggested in November 2014

Post by srvet_claudio »

EduardoLuis wrote:But what is inadmissible is the rude form Karmody uses to apply for to Claudio.
Ok no problem, I want to believe that is problem of translation.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: Status of source code changes suggested in November 2014

Post by srvet_claudio »

kcarmody wrote:Following my discussion with Claudio earlier in this thread, I'm resubmitting the following changes, all relating to the RichEditBox control. I've developed a patch, based on Claudio's current patch (patch 6), which incorporates these changes. My patch should be installed on top of Claudio's patch.

Individual modified source files are at http://kevincarmody.com/hmg/, and a zip of files in the patch is at http://kevincarmody.com/hmg/HmgChangeProposal.zip.

This patch includes an overhauled Rich Edit demo, which uses all the source code changes (except for the SelPasteSpecial method). The new Rich Edit demo is at http://kevincarmody.com/hmg/SAMPLES/Con ... chEditBox/.

New manifest constants RTFTXTFILE_ANSI etc.

These constants are RTF and TXT file types returned by the new function GetRtfTxtFileType() and can be used by the RtfTxtLoadFile and RtfTxtSaveFile methods of the RichEditBox control.

http://kevincarmody.com/hmg/INCLUDE/i_richeditbox.ch - lines 161-169

Code: Select all

// Following 5 #defines added by Kevin Carmody, September 2015

*****************
*   File type   *
*****************

#define RTFTXTFILE_ANSI      1   // ANSI text file
#define RTFTXTFILE_UTF8      2   // UTF-8 text file
#define RTFTXTFILE_UTF16LE   3   // UTF-16 LE (little endian) text file
#define RTFTXTFILE_RTF       4   // RTF file
#define RTFTXTFILE_UTF16BE   5   // UTF-16 BE (big endian) text file
These constants are also used in the Rich Edit demo - http://kevincarmody.com/hmg/SAMPLES/Con ... x/demo.prg - lines 883-904 and lines 976-992.

New function GetRtfTxtFileType( cFile, lUtf8Test ) --> nFileType

This function returns a file type (RTF, ANSI, UTF-16, UTF-8) which can be used in RtfTxtLoadFile and RtfTxtSaveFile methods of RichEditBox control.

http://kevincarmody.com/hmg/SOURCE/h_richeditbox.prg - lines 52, 512-578

Code: Select all

// Following line added by Kevin Carmody, September 2015
#include "fileio.ch"

Code: Select all

// Following function added by Kevin Carmody, September 2015

*-----------------------------------------------------------------------------*
FUNCTION GetRtfTxtFileType ( cFile, lUtf8Test )
*-----------------------------------------------------------------------------*

LOCAL hFile    := FOPEN( cFile, FO_READ )
LOCAL cBuffer  := SPACE( 5 )
LOCAL nBufRead := 0
LOCAL nType    := 0

/*
  The following code block tests for the presence of non-ASCII characters in 
  an unmarked text file.  It assumes that such characters may be ANSI or 
  parts of UTF-8 sequences.  In UTF-8 mode, Windows reads bytes which are not 
  part of a valid UTF-8 sequence as ANSI.  It would be better to know if the 
  file contained UTF-8 sequences for non-ANSI characters, but since some ANSI 
  characters are not in the Latin-1 Supplement, testing for non-ANSI UTF-8 
  sequences is inefficient for large files.
*/

LOCAL bHasUnicodeChars := {||
   LOCAL lHasUnicode := .N.
   LOCAL cChar, cStr
   cBuffer  := SPACE( 0x400 )
   nBufRead := 1
   BEGIN SEQUENCE
      WHILE nBufRead > 0
         nBufRead := FREAD( hFile, @cBuffer, 0x400 )
         IF nBufRead > 0
            cStr := LEFT( cBuffer, nBufRead )
            FOR EACH cChar IN cStr
               IF cChar >= CHR(0x80)
                  lHasUnicode := .Y.
                  BREAK
               ENDIF
            NEXT
         ENDIF
      ENDDO
   END SEQUENCE
   RETURN lHasUnicode
   }

BEGIN SEQUENCE

   IF hFile < 0
      BREAK
   ENDIF
   nBufRead := FREAD( hFile, @cBuffer, 5 )
   DO CASE
   CASE nBufRead >= 5 .AND. LEFT( cBuffer, 5 ) == "{\rtf"
      nType := RTFTXTFILE_RTF
   CASE nBufRead >= 3 .AND. LEFT( cBuffer, 3 ) == E"\xEF\xBB\xBF"
      nType := RTFTXTFILE_UTF8
   CASE nBufRead >= 2 .AND. LEFT( cBuffer, 2 ) == E"\xFF\xFE"
      nType := RTFTXTFILE_UTF16LE
   CASE nBufRead >= 2 .AND. LEFT( cBuffer, 2 ) == E"\xFE\xFF"
      nType := RTFTXTFILE_UTF16BE
   CASE ! EMPTY( lUtf8Test ) .AND. bHasUnicodeChars:EVAL( )
      nType := RTFTXTFILE_UTF8
   OTHERWISE
      nType := RTFTXTFILE_ANSI
   ENDCASE

END SEQUENCE

FCLOSE( hFile )

RETURN nType
This function is used in http://kevincarmody.com/hmg/SAMPLES/Con ... x/demo.prg - line 880

Code: Select all

   LOCAL nFormat        := GETRTFTXTFILETYPE(cFileName, .Y.)
New function Utf16ByteSwap( cInFile, cOutFile )

This function supports the UTF-16 BE (big endian) file type for the RtfTxtLoadFile and RtfTxtSaveFile methods of RichEditBox control.

http://kevincarmody.com/hmg/SOURCE/h_richeditbox.prg - lines 52, 583-623

Code: Select all

// Following line added by Kevin Carmody, September 2015
#include "fileio.ch"

Code: Select all

// Following function added by Kevin Carmody, September 2015

*-----------------------------------------------------------------------------*
FUNCTION Utf16ByteSwap( cInFile, cOutFile )
*-----------------------------------------------------------------------------*

LOCAL hInFile   := FOPEN( cInFile , FO_READ )
LOCAL hOutFile  := FCREATE( cOutFile )
LOCAL cInBuffer := SPACE( 0x400 )
LOCAL nBufRead  := 1
LOCAL lSuccess  := .N.
LOCAL cOutBuffer, cBytePair, nBufWrite, nByte

BEGIN SEQUENCE

   IF hInFile < 0
      BREAK
   ENDIF
   IF hOutFile < 0
      BREAK
   ENDIF
   WHILE nBufRead > 0
      cOutBuffer := ""
      nBufRead   := FREAD( hInFile, @cInBuffer, 0x400 )
      IF nBufRead > 0
         FOR nByte := 1 TO nBufRead STEP 2
            cBytePair  := SUBSTR( cInBuffer, nByte, 2 )
            cOutBuffer += RIGHT( cBytePair, 1 ) + LEFT( cBytePair, 1 )
         NEXT
         nBufWrite := FWRITE( hOutFile, cOutBuffer )
         IF nBufWrite < nBufRead
            BREAK
         ENDIF
      ENDIF
   ENDDO
   lSuccess := .Y.
    
END SEQUENCE

FCLOSE( hInFile )
FCLOSE( hOutFile )

RETURN lSuccess
This function is used in RichEditBox_RtfTxtLoadFile() and RichEditBox_RtfTxtSaveFile() - see below.

Fixed RichEditBox_StreamIn( hWndControl, cFileName, lSelection, nDataFormat ) --> lSuccess

This function now skips over a byte order mark (BOM) in a Unicode text file if one is present.

http://kevincarmody.com/hmg/SOURCE/c_richeditbox.c - lines 190-192, 199-203, 216-233

Code: Select all

//        RichEditBox_StreamIn ( hWndControl, cFileName, lSelection, nDataFormat ) --> return lSuccess
HB_FUNC ( RICHEDITBOX_STREAMIN )
{
   HWND       hWndControl = (HWND)   HMG_parnl (1);
   TCHAR     *cFileName   = (TCHAR*) HMG_parc (2);
   BOOL       lSelection  = (BOOL)   hb_parl  (3);
   LONG       nDataFormat = (LONG)   hb_parnl (4);
   HANDLE     hFile;
   // Following 3 lines added by Kevin Carmody, September 2015
   BYTE       bUtf8Bom[3]; 
   BYTE       bUtf16Bom[2]; 
   DWORD      dwRead;
   EDITSTREAM es;
   LONG       Format;

   switch( nDataFormat )
   {
   // Comments in this switch block modified by Kevin Carmody, September 2015
      case 1:   Format = SF_TEXT; break; // ANSI or UTF-8 with BOM or mixed (UTF-8 BOM removed, overlong UTF-8 accepted, invalid UTF-8 read as ANSI)
      case 2:   Format = ( CP_UTF8 << 16 ) | SF_USECODEPAGE | SF_TEXT; break; // UTF-8 without BOM (BOM not removed)
      case 3:   Format = SF_TEXT | SF_UNICODE; break; // UTF-16 LE without BOM (BOM not removed)
      case 4:   Format = SF_RTF;  break;
      // case 5, UTF-8 RTF, removed by Kevin Carmody, September 2015, because it can never occur
      default:  Format = SF_RTF; break;
   }

   if ( lSelection )
        Format = Format | SFF_SELECTION;

   if( ( hFile = CreateFile (cFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL )) == INVALID_HANDLE_VALUE )
   {   hb_retl (FALSE);
       return;
   }

   // Following switch block added by Kevin Carmody, September 2015
   switch( nDataFormat )
   {
      case 1:   break;
      case 2:   
         if ( ! ReadFile (hFile, bUtf8Bom, 3, &dwRead, NULL) ) // read past BOM if present
            hb_retl (FALSE);
         if ( ! ( dwRead == 3 && bUtf8Bom[0] == 0xEF && bUtf8Bom[1] == 0xBB && bUtf8Bom[2] == 0xBF ) )
            SetFilePointer (hFile, 0, 0, FILE_BEGIN);
         break;
      case 3:
         if ( ! ReadFile (hFile, bUtf16Bom, 2, &dwRead, NULL) ) // read past BOM if present
            hb_retl (FALSE);
         if ( ! ( dwRead == 2 && bUtf16Bom[0] == 0xFF && bUtf16Bom[1] == 0xFE ) )
            SetFilePointer (hFile, 0, 0, FILE_BEGIN);
         break;
      case 4:   break;
      default:  break;
   }
   es.pfnCallback = EditStreamCallbackRead;
   es.dwCookie    = (DWORD_PTR) hFile;
   es.dwError     = 0;

   SendMessage ( hWndControl, EM_STREAMIN, (WPARAM) Format, (LPARAM) &es );

   CloseHandle (hFile);

   if( es.dwError )
      hb_retl (FALSE);
   else
      hb_retl (TRUE);
}
This function is called by RichEditBox_RtfTxtLoadFile() - see below.

Fixed RichEditBox_StreamOut( hWndControl, cFileName, lSelection, nDataFormat ) --> lSuccess

This function now writes a byte order mark (BOM) to a Unicode text file.

http://kevincarmody.com/hmg/SOURCE/c_richeditbox.c - lines 269-271, 278-282, 295-302

Code: Select all

//        RichEditBox_StreamOut ( hWndControl, cFileName, lSelection, nDataFormat ) --> return lSuccess
HB_FUNC ( RICHEDITBOX_STREAMOUT )
{
   HWND       hWndControl = (HWND)   HMG_parnl (1);
   TCHAR     *cFileName   = (TCHAR*) HMG_parc (2);
   BOOL       lSelection  = (BOOL)   hb_parl  (3);
   LONG       nDataFormat = (LONG)   hb_parnl (4);
   HANDLE     hFile;
   // Following 3 lines added by Kevin Carmody, September 2015
   BYTE       bUtf8Bom[3]  = {0xEF, 0xBB, 0xBF};
   BYTE       bUtf16Bom[2] = {0xFF, 0xFE}; 
   DWORD      dwWritten;
   EDITSTREAM es;
   LONG       Format;

   switch( nDataFormat )
   {
   // Comments in this switch block modified by Kevin Carmody, September 2015
      case 1:   Format = SF_TEXT; break; // ANSI (non-ANSI characters converted to question marks)
      case 2:   Format = ( CP_UTF8 << 16 ) | SF_USECODEPAGE | SF_TEXT; break; // UTF-8 without BOM
      case 3:   Format = SF_TEXT | SF_UNICODE; break; // UTF-16 LE without BOM
      case 4:   Format = SF_RTF;  break;
      // case 5, UTF-8 RTF, removed by Kevin Carmody, September 2015, because it can never occur
      default:  Format = SF_RTF; break;
   }

   if ( lSelection )
        Format = Format | SFF_SELECTION;

   if( ( hFile = CreateFile (cFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL )) == INVALID_HANDLE_VALUE )
   {   hb_retl (FALSE);
       return;
   }

   // Following switch block added by Kevin Carmody, September 2015
   switch( nDataFormat )
   {
      case 1:   break;
      case 2:   WriteFile( hFile, bUtf8Bom, 3, &dwWritten, NULL ); break; // write UTF-8 BOM at head of file
      case 3:   WriteFile( hFile, bUtf16Bom, 2, &dwWritten, NULL ); break; // write UTF-16 LE BOM at head of file
      case 4:   break;
      default:  break;
   }
   es.pfnCallback = EditStreamCallbackWrite;
   es.dwCookie    = (DWORD_PTR) hFile;
   es.dwError     = 0;

   SendMessage ( hWndControl, EM_STREAMOUT, (WPARAM) Format, (LPARAM) &es );
   
   CloseHandle (hFile);

   if( es.dwError )
      hb_retl (FALSE);
   else
      hb_retl (TRUE);
}
This function is used in RichEditBox_RtfTxtSaveFile() - see below.

New RichEditBox property HasUnicodeChars (read only)

This property detects whether a rich edit control contains non-ASCII Unicode characters.

http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - lines 10266-10268, at end of _RichEditBox_GetProperty()

Code: Select all

   // Following case added by Kevin Carmody, September 2015
   CASE Arg3 == "HASUNICODECHARS"
        xData  := RichEditBox_HasUnicodeChars ( hWndControl )
        RetVal := .T.
http://kevincarmody.com/hmg/INCLUDE/i_window.ch - line 164

Code: Select all

;; // Following line modified by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFTextMode,AutoURLDetect,Zoom,SelectRange,CaretPos,Value,GetSelectText,GetTextLength,ViewRect,HasUnicodeChars\> => GetProperty ( <"w">, \<"c"\> , \<"p"\> ) ;;
http://kevincarmody.com/hmg/SOURCE/h_richeditbox.prg - lines 418-440

Code: Select all

// Following function added by Kevin Carmody, September 2015

/*
  The following function tests for the presence of non-ASCII characters in 
  a rich edit control.  It would be better to know if the control contained
  non-ANSI characters, but since some ANSI characters are not in the Latin-1 
  Supplement, testing for non-ANSI characters is inefficient for large 
  documents.
*/

*-----------------------------------------------------------------------------*
FUNCTION RichEditBox_HasUnicodeChars( hWndControl )
*-----------------------------------------------------------------------------*

LOCAL cBuffer     := RichEditBox_GetText( hWndControl , .N. )
LOCAL lHasUnicode := .N.
LOCAL cChar

FOR EACH cChar IN cBuffer
   IF cChar >= CHR(0x80)
      lHasUnicode := .Y.
   ENDIF
NEXT

RETURN lHasUnicode
This function is used in http://kevincarmody.com/hmg/SAMPLES/Con ... x/demo.prg - line 945

Code: Select all

   LOCAL lUnicode := wMain.ebDoc.HASUNICODECHARS
New RichEditBox method RtfTxtLoadFile( cFile, lSelection, nType ) --> lSuccess

This method is a synonym for the RtfLoadFile method. It now uses the file type returned by GetRtfTxtFileType(). It skips over a byte order mark in a Unicode text file, and it supports UTF-16 BE (big endian Unicode text file).

http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - lines 10440-10442

Code: Select all

   // Following case modified by Kevin Carmody, September 2015
   CASE Arg3 == "RTFLOADFILE" .OR. Arg3 == "RTFTXTLOADFILE"
        xData := RichEditBox_RtfTxtLoadFile ( hWndControl, Arg4, Arg5, Arg6 )   // by default save in SF_RTF format
        RetVal := .T.
http://kevincarmody.com/hmg/INCLUDE/i_window.ch - lines 172-173, 175

Code: Select all

;; // Following 2 lines modified by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>,\<arg2\>,\<arg3\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> , \<arg2\>, \<arg3\> ) ;;
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>,\<arg2\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> , \<arg2\> ) ;;
;; // Following line added by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> ) ;;
http://kevincarmody.com/hmg/SOURCE/h_richeditbox.prg - lines 445-477

Code: Select all

// Following function added by Kevin Carmody, September 2015

*-----------------------------------------------------------------------------*
FUNCTION RichEditBox_RtfTxtLoadFile( hWndControl, cFile, lSelection, nType )
*-----------------------------------------------------------------------------*

LOCAL lSuccess := .N.
LOCAL cTempFile

IF ! HB_ISLOGICAL( lSelection )
   lSelection := .N.
ENDIF
IF ! HB_ISNUMERIC( nType )
   nType := RTFTXTFILE_RTF
ENDIF

IF lSelection
   RichEditBox_UnSelectAll( hWndControl )
ENDIF
IF RichEditBox_RTFLoadResourceFile( hWndControl, cFile, lSelection )
   lSuccess := .T.
ELSE
   IF nType == RTFTXTFILE_UTF16BE
      cTempFile := GETTEMPFOLDER() + "_RtfTxtLoadFile.txt"
      lSuccess  := Utf16ByteSwap( cFile, cTempFile )
      IF lSuccess
         lSuccess := RichEditBox_StreamIn( hWndControl, cTempFile, lSelection, RTFTXTFILE_UTF16LE )
      ENDIF
      DELETE FILE ( cTempFile )
   ELSE
      lSuccess := RichEditBox_StreamIn( hWndControl, cFile, lSelection, nType )
   ENDIF
ENDIF

RETURN lSuccess
This method is used in http://kevincarmody.com/hmg/SAMPLES/Con ... x/demo.prg - line 906

Code: Select all

      IF ! wMain.ebDoc.RTFTXTLOADFILE(cFileName, .N., nFormat)
New RichEditBox method RtfTxtSaveFile( cFile, lSelection, nType ) --> lSuccess

This method is a synonym for the RtfSaveFile method. It now uses the file type returned by GetRtfTxtFileType(), writes a byte order mark to a Unicode text file, and supports UTF-16 BE (big endian Unicode text file).

http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - lines 10445-10447

Code: Select all

   // Following case modified by Kevin Carmody, September 2015
   CASE Arg3 == "RTFSAVEFILE" .OR. Arg3 == "RTFTXTSAVEFILE"
        xData := RichEditBox_RtfTxtSaveFile ( hWndControl, Arg4, Arg5, Arg6 )   // by default save in SF_RTF format
        RetVal := .T.
http://kevincarmody.com/hmg/INCLUDE/i_window.ch - lines 172-173, 175

Code: Select all

;; // Following 2 lines modified by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>,\<arg2\>,\<arg3\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> , \<arg2\>, \<arg3\> ) ;;
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>,\<arg2\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> , \<arg2\> ) ;;
;; // Following line added by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> ) ;;
http://kevincarmody.com/hmg/SOURCE/h_richeditbox.prg - lines 482-507

Code: Select all

// Following function added by Kevin Carmody, September 2015

*-----------------------------------------------------------------------------*
FUNCTION RichEditBox_RtfTxtSaveFile( hWndControl, cFile, lSelection, nType )
*-----------------------------------------------------------------------------*

LOCAL lSuccess := .N.
LOCAL cTempFile

IF ! HB_ISLOGICAL( lSelection )
   lSelection := .N.
ENDIF
IF ! HB_ISNUMERIC( nType )
   nType := RTFTXTFILE_RTF
ENDIF

IF nType == RTFTXTFILE_UTF16BE
   cTempFile := GETTEMPFOLDER() + "_RtfTxtLoadFile.txt"
   lSuccess := RichEditBox_StreamOut( hWndControl, cTempFile, lSelection, RTFTXTFILE_UTF16LE )
   IF lSuccess
      lSuccess  := Utf16ByteSwap( cTempFile, cFile )
   ENDIF
   DELETE FILE ( cTempFile )
ELSE
   lSuccess := RichEditBox_StreamOut( hWndControl, cFile, lSelection, nType )
ENDIF

RETURN lSuccess
This method is used in http://kevincarmody.com/hmg/SAMPLES/Con ... x/demo.prg - line 993

Code: Select all

      IF ! wMain.ebDoc.RTFTXTSAVEFILE(cFileName, .N., nFormat)
New RichEditBox method SelPasteSpecial

Paste special - needs documentation of clipboard format argument.

http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - lines 10458-10460

Code: Select all

   // Following case added by Kevin Carmody, September 2015
   CASE Arg3 == HMG_UPPER ("SelPasteSpecial")
        RichEditBox_PasteSpecial ( hWndControl, Arg4 )
        RetVal := .T.
http://kevincarmody.com/hmg/INCLUDE/i_window.ch - line 179

Code: Select all

;; // Following line added by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:SelPasteSpecial\> (\<arg1\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> ) ;;
This method is not used in the Rich Edit demo.

Enhanced RichEditBox method RtfLoadFile( cFile, lSelection, nType ) --> lSuccess

This method is a synonym for the RtfTxtLoadFile method described above.

http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - lines 10440-10442

Code: Select all

   // Following case modified by Kevin Carmody, September 2015
   CASE Arg3 == "RTFLOADFILE" .OR. Arg3 == "RTFTXTLOADFILE"
        xData := RichEditBox_RtfTxtLoadFile ( hWndControl, Arg4, Arg5, Arg6 )   // by default save in SF_RTF format
        RetVal := .T.
http://kevincarmody.com/hmg/INCLUDE/i_window.ch - lines 172-173, 175

Code: Select all

;; // Following 2 lines modified by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>,\<arg2\>,\<arg3\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> , \<arg2\>, \<arg3\> ) ;;
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>,\<arg2\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> , \<arg2\> ) ;;
;; // Following line added by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> ) ;;
This method is not used in the Rich Edit demo.

Enhanced RichEditBox method RtfSaveFile( cFile, lSelection, nType ) --> lSuccess

This method is a synonym for the RtfTxtSaveFile method described above.

http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - lines 10445-10447

Code: Select all

   // Following case modified by Kevin Carmody, September 2015
   CASE Arg3 == "RTFSAVEFILE" .OR. Arg3 == "RTFTXTSAVEFILE"
        xData := RichEditBox_RtfTxtSaveFile ( hWndControl, Arg4, Arg5, Arg6 )   // by default save in SF_RTF format
        RetVal := .T.
http://kevincarmody.com/hmg/INCLUDE/i_window.ch - lines 172-173, 175

Code: Select all

// Following 2 lines modified by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>,\<arg2\>,\<arg3\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> , \<arg2\>, \<arg3\> ) ;;
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>,\<arg2\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> , \<arg2\> ) ;;
// Following line added by Kevin Carmody, September 2015
#xtranslate <w>. \<c\> . \<p:RTFLoadFile,RTFSaveFile,RtfTxtLoadFile,RtfTxtSaveFile\> (\<arg1\>) => DoMethod ( <"w">, \<"c"\> , \<"p"\> , \<arg1\> ) ;;
This method is not used in the Rich Edit demo.

Enhanced function DoMethod ( Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Arg8 , Arg9 )

Enabled this function to return a value from a RichEditBox method.

http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - line 8869

Code: Select all

Function DoMethod ( Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Arg8 , Arg9 )
// Following line modified by Kevin Carmody, September 2015
Local xData, i, hWnd
http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - lines 8881-8882

Code: Select all

// Following 2 lines modified by Kevin Carmody, September 2015
IF _RichEditBox_DoMethod ( @xData, Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Arg8 , Arg9 ) == .T.
   Return xData
ENDIF
http://kevincarmody.com/hmg/SOURCE/h_controlmisc.prg - line 10416

Code: Select all

// Following line modified by Kevin Carmody, September 2015
Function _RichEditBox_DoMethod ( xData, Arg1 , Arg2 , Arg3 , Arg4 , Arg5 , Arg6 , Arg7 , Arg8 , Arg9 )
The return value is used in http://kevincarmody.com/hmg/SAMPLES/Con ... x/demo.prg - lines 906

Code: Select all

      IF ! wMain.ebDoc.RTFTXTLOADFILE(cFileName, .N., nFormat)
The return value is used in http://kevincarmody.com/hmg/SAMPLES/Con ... x/demo.prg - lines 993

Code: Select all

      IF ! wMain.ebDoc.RTFTXTSAVEFILE(cFileName, .N., nFormat)
Hi Kevin,
I have some suggestions on your code:

1) Insert/remove BOM for UTF16-BE, like:

Code: Select all

#define UTF16BE_BOM   0xFEFF
DWORD dwBOM = 0;
if ( ! ReadFile (hFile, &dwBOM, 2, &dwRead, NULL) )
     hb_retl (FALSE);
if ( ( dwBOM & UTF16BE_BOM ) != UTF16BE_BOM )
     SetFilePointer (hFile, 0, 0, FILE_BEGIN);

Code: Select all

WriteFile( hFile, bUTF16BE_BOM, 2, &dwWritten, NULL );


2) Rewrite:

Code: Select all

FUNCTION RichEditBox_HasUnicodeChars( hWndControl )
LOCAL cBuffer := RichEditBox_GetText( hWndControl , .F. )
RETURN HMG_IsUTF8( cBuffer )
3) rename constants:

Code: Select all

#define RTFFILE_ANSI      1   // ANSI text file
#define RTFFILE_UTF8      2   // UTF-8 text file
#define RTFFILE_UTF16LE   3   // UTF-16 LE (little endian) text file
#define RTFFILE_RTF       4   // RTF file
#define RTFFILE_UTF16BE   5   // UTF-16 BE (big endian) text file
4) rename the function:
RichEditBox_RtfTxtLoadFile and RichEditBox_RtfTxtSaveFile for:

Code: Select all

RichEditBox_RTFLoadFile
RichEditBox_RTFSaveFile
4) in file h_controlmisc.prg, use only method names:

Code: Select all

CASE Arg3 == HMG_UPPER ("RTFLoadFile")
CASE Arg3 == HMG_UPPER ("RTFSaveFile")
the use of RtfTxtLoadFile and RtfTxtSaveFile It is an unnecessary duplecación.

Please, make this changes and send me.
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
User avatar
Rathinagiri
Posts: 5471
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Contact:

Re: Status of source code changes suggested in November 2014

Post by Rathinagiri »

srvet_claudio wrote:
Rathinagiri wrote:Hi,

It is really off topic.

Is there any way to include tables in rich edit text? If it can be, then we can have our Grids/reports to be exported to a well formatted Rich Edit Text File.
Yes is possible, but maybe not easy with programming, click in Help icon of: C:\hmg.3.4.1\SAMPLES\Controls\RichEditBox
Thank you Claudio. Preparing a pre-formatted RTF using HMG coding would be great and useful.

This is a simple example given in the net.

Code: Select all

{\rtf1\ansi\deff0
\trowd
\cellx1000
\cellx2000
\cellx3000
\intbl cell 1\cell
\intbl cell 2\cell
\intbl cell 3\cell
\row
} 
But it is not simple or as easy as HMG! And if it is Unicode, it is further complicated!
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
User avatar
kcarmody
Posts: 152
Joined: Tue Oct 07, 2014 11:13 am
Contact:

Re: Status of source code changes suggested in November 2014

Post by kcarmody »

srvet_claudio wrote:Hi Kevin,
I have some suggestions on your code:

1) Insert/remove BOM for UTF16-BE, like:

Code: Select all

#define UTF16BE_BOM   0xFEFF
DWORD dwBOM = 0;
if ( ! ReadFile (hFile, &dwBOM, 2, &dwRead, NULL) )
     hb_retl (FALSE);
if ( ( dwBOM & UTF16BE_BOM ) != UTF16BE_BOM )
     SetFilePointer (hFile, 0, 0, FILE_BEGIN);

Code: Select all

WriteFile( hFile, bUTF16BE_BOM, 2, &dwWritten, NULL );


2) Rewrite:

Code: Select all

FUNCTION RichEditBox_HasUnicodeChars( hWndControl )
LOCAL cBuffer := RichEditBox_GetText( hWndControl , .F. )
RETURN HMG_IsUTF8( cBuffer )
3) rename constants:

Code: Select all

#define RTFFILE_ANSI      1   // ANSI text file
#define RTFFILE_UTF8      2   // UTF-8 text file
#define RTFFILE_UTF16LE   3   // UTF-16 LE (little endian) text file
#define RTFFILE_RTF       4   // RTF file
#define RTFFILE_UTF16BE   5   // UTF-16 BE (big endian) text file
4) rename the function:
RichEditBox_RtfTxtLoadFile and RichEditBox_RtfTxtSaveFile for:

Code: Select all

RichEditBox_RTFLoadFile
RichEditBox_RTFSaveFile
4) in file h_controlmisc.prg, use only method names:

Code: Select all

CASE Arg3 == HMG_UPPER ("RTFLoadFile")
CASE Arg3 == HMG_UPPER ("RTFSaveFile")
the use of RtfTxtLoadFile and RtfTxtSaveFile It is an unnecessary duplecación.

Please, make this changes and send me.
Hi Claudio,

Thanks for your suggestions. I would really like to do these for you, but first please consider the following.

For number 1, it appears you are suggesting that I put this code into RichEditBox_StreamIn and RichEditBox_StreamOut in c_richeditbox.c. I considered this before and found it could not work there. These functions read and write text through the Windows EM_STREAMIN and EM_STREAMOUT messages. These messages accept UTF-8 and UTF-16LE formats but not UTF-16BE. So, unlike UTF-8 and UTF-16LE, for UTF-16BE we cannot remove the BOM and then use EM_STREAMIN or EM_STREAMOUT to read or write the text. I worked around this by using the function Utf16ByteSwap in RichEditBox_RtfTxtLoadFile and RichEditBox_RtfTxtSaveFile to convert between UTF-16BE to UTF-16LE.

For number 2, the function RichEditBox_HasUnicodeChars implements the HasUnicodeChars property. The purpose of this property is to detect whether the buffer has any non-ASCII characters. This is so we can warn the user if he tries to save non-ASCII characters to an ANSI file -- see demo.prg lines 961-965. The HMG_IsUtf8 function does not distinguish betweeen ASCII and non-ASCII. It only determines whether a string is in correct UTF-8 format, and pure ASCII is correct UTF-8. RichEditBox_GetText always returns correct UTF-8 text, so the function as you have written it will always return true.

Numbers 3, 4, and 5 will work, but I would prefer to have the names as RTFTXT instead of RTF only. Before I started making these changes, HMG supported only RTF reading and writing to and from rich edit controls. The changes I am submitting will enable it to support both RTF and TXT files, and I would like the names to reflect that. The name RTFFILE_UTF8, for example, is confusing, because it is not a format of an RTF file, but a TXT file.

Please let me know what you think.

Kevin
User avatar
kcarmody
Posts: 152
Joined: Tue Oct 07, 2014 11:13 am
Contact:

Re: Status of source code changes suggested in November 2014

Post by kcarmody »

Rathinagiri wrote:
srvet_claudio wrote:
Rathinagiri wrote:Hi,

It is really off topic.

Is there any way to include tables in rich edit text? If it can be, then we can have our Grids/reports to be exported to a well formatted Rich Edit Text File.
Yes is possible, but maybe not easy with programming, click in Help icon of: C:\hmg.3.4.1\SAMPLES\Controls\RichEditBox
Thank you Claudio. Preparing a pre-formatted RTF using HMG coding would be great and useful.

This is a simple example given in the net.

Code: Select all

{\rtf1\ansi\deff0
\trowd
\cellx1000
\cellx2000
\cellx3000
\intbl cell 1\cell
\intbl cell 2\cell
\intbl cell 3\cell
\row
} 
But it is not simple or as easy as HMG! And if it is Unicode, it is further complicated!
I have some experience with tables in RTF. The RTF code that Rathinagiri has given is a very basic RTF table for 3 columns and 1 row, although it is not necessary repeat \intbl for each cell, only at the beginning of a row.

Code: Select all

{\rtf1\ansi\deff0
\trowd
\cellx1000
\cellx2000
\cellx3000
\intbl cell 1\cell
cell 2\cell
cell 3\cell
\row
} 
For more rows, you would repeat \intbl, \cell, and \row. This code makes each column 50 points wide (0.7 inch or 1.8 cm). The unit for \cellx is a "twip", 20 twips = 1 point, 72 points = 1 inch. The column widths are fixed and do not grow and shrink as in HTML tables. Only the row heights vary according to text.

The table written with this code will have very thin grid lines around each cell. It is possible to do fancier formatting, but RTF code for tables can get very messy very quickly, and I have never tried to do this.

Unicode is quite easy in RTF. For each character, the syntax is \u followed by the code point in decimal, followed by a question mark. Example \u243? for ó.

A table-to-RTF function would have to have to know how wide the user wants each column to be, and would have to convert UTF-8 to RTF Unicode.

Kevin
User avatar
kcarmody
Posts: 152
Joined: Tue Oct 07, 2014 11:13 am
Contact:

Re: Status of source code changes suggested in November 2014

Post by kcarmody »

EduardoLuis wrote:But what is inadmissible is the rude form Karmody uses to apply for to Claudio.- The best way to be part of a community is speak or write courtly.
I'm sorry, I will try to be more polite.
Kevin
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: Status of source code changes suggested in November 2014

Post by srvet_claudio »

kcarmody wrote:For number 1, it appears you are suggesting that I put this code into RichEditBox_StreamIn and RichEditBox_StreamOut in c_richeditbox.c. I considered this before and found it could not work there. These functions read and write text through the Windows EM_STREAMIN and EM_STREAMOUT messages. These messages accept UTF-8 and UTF-16LE formats but not UTF-16BE. So, unlike UTF-8 and UTF-16LE, for UTF-16BE we cannot remove the BOM and then use EM_STREAMIN or EM_STREAMOUT to read or write the text. I worked around this by using the function Utf16ByteSwap in RichEditBox_RtfTxtLoadFile and RichEditBox_RtfTxtSaveFile to convert between UTF-16BE to UTF-16LE.
Ok, I see your code, you first save in LE and swap, this convert file and Bom in BE, in load the process is inverse, this is ok.
kcarmody wrote:For number 2, the function RichEditBox_HasUnicodeChars implements the HasUnicodeChars property. The purpose of this property is to detect whether the buffer has any non-ASCII characters. This is so we can warn the user if he tries to save non-ASCII characters to an ANSI file -- see demo.prg lines 961-965. The HMG_IsUtf8 function does not distinguish betweeen ASCII and non-ASCII. It only determines whether a string is in correct UTF-8 format, and pure ASCII is correct UTF-8. RichEditBox_GetText always returns correct UTF-8 text, so the function as you have written it will always return true.
Your original code only detect ASCII character (firsts 128 character of ANSI and Unicode character set) then is RichEditBox_HasOnlyASCII()
I think this function is unnecessary in RichEdit because it is very easy to write and only in very special cases is required. In addition is far from the characteristics of the Windows control which is mainly thinking for working with RTF files.
kcarmody wrote:Numbers 3, 4, and 5 will work, but I would prefer to have the names as RTFTXT instead of RTF only. Before I started making these changes, HMG supported only RTF reading and writing to and from rich edit controls. The changes I am submitting will enable it to support both RTF and TXT files, and I would like the names to reflect that. The name RTFFILE_UTF8, for example, is confusing, because it is not a format of an RTF file, but a TXT file.


Then the right thing is RichEditBox_SaveFile() and RichEditBox_LoadFile(),
#define RICHEDITFILE_UTF8
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
Post Reply