I'm testing the feature to copy text and link URLs to memopad, which
has been wanted on this list.

When "Copy To Memo" in the menu is selected, it forces to redraw 
screen and copies the text in the viewport to the memo. URLs of the
links in the viewport is also added after the tag strings.

I think there must be much better way to take snapshot without
redrawing full paragraph, and also the links should better be listed 
at the bottom of the memo instead of in the lines, and so on.....

Anyway i want your opinion.

/matto



Index: anchor.c
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/anchor.c,v
retrieving revision 1.28
diff -C3 -r1.28 anchor.c
*** anchor.c    20 Jul 2001 20:14:05 -0000      1.28
--- anchor.c    19 Oct 2001 04:48:35 -0000
***************
*** 414,417 ****
--- 414,422 ----
      }
      else
          newAnchor->state = ANCHOR_UNUSED;   /* oooooh :( */
+ }
+ 
+ Int16 GetCurrentAnchorReference()
+ {
+   return currentAnchor->reference;
  }
Index: anchor.h
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/anchor.h,v
retrieving revision 1.20
diff -C3 -r1.20 anchor.h
*** anchor.h    18 Jul 2001 20:01:35 -0000      1.20
--- anchor.h    19 Oct 2001 04:48:35 -0000
***************
*** 52,56 ****
--- 52,57 ----
  void StopAnchor( const TextContext* tContext, const Int16 height );
  void StopImageAnchor( TextContext* tContext, const Int16 height,
          const Int16 width );
+ Int16 GetCurrentAnchorReference( void );
  
  #endif
Index: document.c
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/document.c,v
retrieving revision 1.45
diff -C3 -r1.45 document.c
*** document.c  18 Jul 2001 20:01:36 -0000      1.45
--- document.c  19 Oct 2001 04:48:37 -0000
***************
*** 306,311 ****
--- 306,314 ----
  
      WinSetClip( &viewportBounds );
  
+     if(GetHardcopyMode()==true)
+       OpenMemo(Prefs()->dbName);
+ 
      while ( numOfParagraphs-- ) {
          lastCursor = cursor;
  
***************
*** 335,346 ****
--- 338,353 ----
          metaParagraph++;
          paragraph_index++;
      }
+     if(GetHardcopyMode()==true)
+       CloseMemo();
+ 
      MemHandleUnlock( metaRecord );
      WinResetClip();
  }
  
  
  
+ 
  /* Scroll record up */
  static void ScrollUp
      (
Index: externalform.c
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/externalform.c,v
retrieving revision 1.19
diff -C3 -r1.19 externalform.c
*** externalform.c      18 Jul 2001 20:01:36 -0000      1.19
--- externalform.c      19 Oct 2001 04:48:39 -0000
***************
*** 32,41 ****
  
  void SetLinkIndex( Int16 index ) PLKRDB_SECTION;
  void AddURLToField( FieldType* fldPtr, Int16 index ) PLKRDB_SECTION;
  void WriteMemo( FieldType* field ) PLKRDB_SECTION;
  
  static void ExternalLinksFormInit( void ) PLKRDB_SECTION;
! 
  
  /***********************************************************************
   *
--- 32,45 ----
  
  void SetLinkIndex( Int16 index ) PLKRDB_SECTION;
  void AddURLToField( FieldType* fldPtr, Int16 index ) PLKRDB_SECTION;
+ void WriteMemo_new( FieldType* field ) PLKRDB_SECTION;
  void WriteMemo( FieldType* field ) PLKRDB_SECTION;
  
  static void ExternalLinksFormInit( void ) PLKRDB_SECTION;
! void OpenMemo(Char *text) PLKRDB_SECTION;
! void CloseMemo(void) PLKRDB_SECTION;
! void ScribeMemo(Char *text,UInt16 length) PLKRDB_SECTION;
! void AddURLToMemo( Int16 index ) PLKRDB_SECTION;
  
  /***********************************************************************
   *
***************
*** 220,226 ****
  }
  
  
- 
  /* Event handler for the externallinks form */
  Boolean ExternalLinksFormHandleEvent
      (
--- 224,229 ----
***************
*** 263,265 ****
--- 266,446 ----
  
      return handled;
  }
+ 
+ static DmOpenRef MemopadDB=NULL;
+ static UInt16 index;
+ static UInt32 offset;
+ /* Write the text from a TextField to a Memo */
+ void OpenMemo
+     (
+      Char *title
+     )
+ {
+     UInt16      mode;
+     mode = dmModeReadWrite;
+     if ( ( MemopadDB = DmOpenDatabaseByTypeCreator( 'DATA', 'memo', mode ) ) != NULL 
+)
+       {
+       //always open new memo, because paragraph size often exceeds 3000 bytes
+       MemHandle   recH;
+       UInt32 secs;
+       DateTimeType dateTime;
+       Char        header[ 60 ];
+       UInt16 length;
+       
+       secs = TimGetSeconds();
+       TimSecondsToDateTime( secs, &dateTime );
+       StrPrintF( header, "%4d-%02d-%02d %02d:%02d %s\n", 
+                  dateTime.year, dateTime.month, dateTime.day, dateTime.hour, 
+dateTime.minute,title );
+       length=StrLen(header);
+       recH = DmNewRecord( MemopadDB, &index, length+1 );
+       if ( recH != NULL ) {
+         Char    null;
+         MemPtr  recP;
+         UInt16  attr;
+         Int16   category;
+ 
+         null = '\0';
+         recP = MemHandleLock( recH );
+         
+         DmWrite( recP, 0, header, length);
+         DmWrite( recP, length, &null, 1 );
+         
+         MemHandleUnlock( recH );
+         
+         DmRecordInfo( MemopadDB, index, &attr, NULL, NULL );
+         attr &= ~dmRecAttrCategoryMask;
+         
+         category = CategoryFind( MemopadDB, "Plucker" );
+         
+         if ( category == dmAllCategories )
+           attr |= dmUnfiledCategory;
+         else
+           attr |= category;
+         
+         DmSetRecordInfo( MemopadDB, index, &attr, NULL );
+         DmReleaseRecord( MemopadDB, index, true );
+ 
+         offset = length;
+       }
+     }
+ }
+ 
+ /* Write the text from a TextField to a Memo */
+ void CloseMemo
+     (
+     )
+ {
+   if(MemopadDB!=NULL)
+     DmCloseDatabase( MemopadDB );
+ }
+ 
+ /* Write the text to a Memo */
+ void ScribeMemo
+     (
+     Char *text,
+     UInt16 length
+     )
+ {
+     MemHandle   recH;
+     if ( length == 0 )
+         return;
+     if(MemopadDB==NULL)
+       return;
+ 
+     recH = DmResizeRecord( MemopadDB, index, offset + length + 1 );
+     /* Should we pop up an alert form here?? */
+     if ( recH != NULL ) {
+         Char    eol[]="\0";
+         MemPtr  recP;
+ 
+         recP = MemHandleLock( recH );
+ 
+         DmWrite( recP, offset , text, length );
+         DmWrite( recP, offset + length, eol, 1 );
+ 
+         MemHandleUnlock( recH );
+ 
+         offset += length;
+     }
+ }
+ 
+ void WriteMemo_new
+     (
+     FieldType* field    /* field to get text from */
+     )
+ {
+   OpenMemo("Plucker URLs");
+   ScribeMemo(FldGetTextPtr( field ),FldGetTextLength( field ));
+   ScribeMemo("\n",1);
+   CloseMemo();
+ }
+ 
+ /* Initialize field with URL string */
+ //converted from AddURLToField
+ void AddURLToMemo
+     (
+     Int16       index   /* index in URL record */
+     )
+ {
+     MemHandle   linkHandle;
+     Char*       text;
+ 
+     linkHandle = NULL;
+     text = NULL;
+     if ( ReturnRecordHandle( PLUCKER_LINKS_ID, &linkHandle ) == 0 ) {
+         MemHandle   uncompressHandle;
+         Header*     linkDocument;
+         Int16       count;
+         Int16       offset;
+         Int16*      numP;
+ 
+         count   = index;
+         offset  = 0;
+ 
+         linkDocument = (Header*) MemHandleLock( linkHandle );
+         numP = (Int16*) ( linkDocument + 1 );
+ 
+         while ( *numP < index ) {
+             offset  = *numP;
+             numP   += 2;
+         }
+         numP    += 1;
+         count   -= offset;
+ 
+         MemHandleUnlock( linkHandle );
+ 
+         if ( ReturnRecordHandle( *numP, &linkHandle ) != 0 )
+             return;
+ 
+         uncompressHandle    = NULL;
+         linkDocument        = (Header*) MemHandleLock( linkHandle );
+         if ( linkDocument->type == DATATYPE_LINKS_COMPRESSED ) {
+             uncompressHandle = Uncompress( linkDocument );
+             MemHandleUnlock( linkHandle );
+             linkHandle = NULL;
+             if ( uncompressHandle )
+                 text = (Char*) MemHandleLock( uncompressHandle );
+         }
+         else if ( linkDocument->type == DATATYPE_LINKS ) {
+             text = (Char*) ( linkDocument + 1 );
+         }
+ 
+         if ( text != NULL ) {
+             while ( --count )
+                 text += StrLen( text ) + 1;
+             //FldInsert( fldPtr, text, StrLen( text ) );
+             ScribeMemo(text,StrLen(text));
+         }
+         if ( linkHandle != NULL )
+             MemHandleUnlock( linkHandle );
+         if ( uncompressHandle != NULL )
+             MemHandleUnlock( uncompressHandle );
+     }
+     //if ( text == NULL ) {
+     //    Char buff[ 100 ];
+ 
+     //    SysCopyStringResource( buff, strNoURL );
+     //    FldInsert( fldPtr, buff, StrLen( buff ) );
+     //}
+ }
+ 
Index: externalform.h
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/externalform.h,v
retrieving revision 1.12
diff -C3 -r1.12 externalform.h
*** externalform.h      18 Jul 2001 20:01:36 -0000      1.12
--- externalform.h      19 Oct 2001 04:48:39 -0000
***************
*** 30,34 ****
--- 30,38 ----
  void SetLinkIndex( Int16 index ) PLKRDB_SECTION;
  void AddURLToField( FieldType* fldPtr, Int16 index ) PLKRDB_SECTION;
  void WriteMemo( FieldType* field ) PLKRDB_SECTION;
+ void ScribeMemo( Char *text, UInt16 length ) PLKRDB_SECTION;
+ void OpenMemo(Char *text) PLKRDB_SECTION;
+ void CloseMemo( void ) PLKRDB_SECTION;
+ void AddURLToMemo( Int16 index ) PLKRDB_SECTION;
  
  #endif
Index: mainform.c
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/mainform.c,v
retrieving revision 1.37
diff -C3 -r1.37 mainform.c
*** mainform.c  18 Jul 2001 20:01:36 -0000      1.37
--- mainform.c  19 Oct 2001 04:48:40 -0000
***************
*** 121,127 ****
      )
  {
      Boolean handled;
! 
      handled = false;
      if ( HandleCommonMenuItems( itemID ) )
          return true;
--- 121,127 ----
      )
  {
      Boolean handled;
!     
      handled = false;
      if ( HandleCommonMenuItems( itemID ) )
          return true;
***************
*** 161,166 ****
--- 161,175 ----
  
              case mGoBookmarks:
                  FrmPopupForm( frmBookmarks );
+                 handled = true;
+                 break;
+ 
+             case mGoCopyMemo:
+               SetScreenMode();
+               MainFormInit();
+               SetHardcopyMode(true);
+               ViewRecord( GetHistoryCurrent(), !GetAddHistory(),NO_OFFSET );
+               SetHardcopyMode(false);
                  handled = true;
                  break;
  
Index: paragraph.c
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/paragraph.c,v
retrieving revision 1.42
diff -C3 -r1.42 paragraph.c
*** paragraph.c 22 Jul 2001 15:59:01 -0000      1.42
--- paragraph.c 19 Oct 2001 04:48:43 -0000
***************
*** 33,39 ****
--- 33,79 ----
  #include "search.h"
  #include "uncompress.h"
  #include "util.h"
+ #include "externalform.h"
  
+ #define JOS
+ #ifdef JOS
+ UInt16 myTxtCharSize(WChar ch)
+ {
+   return (ch>=256)?2:1;
+ }
+ UInt16 myTxtGetNextChar(const Char *txt,UInt32 n,WChar *ch)
+ {
+   *ch=txt[n];
+   if(*ch&0x80){
+     WChar ch2=txt[n+1];
+     ch2&=0xff;
+     *ch=(*ch<<8)+ch2;
+     return 2;
+   }else{
+     return 1;
+   }
+ }
+ UInt16 myTxtSetNextChar(Char *txt,UInt32 n,WChar ch)
+ {
+   if(myTxtCharSize(ch)==2){
+     txt[n]=((UInt16)ch) >> 8;
+     txt[n+1]=ch&0xff;
+     return 2;
+   }else{
+     txt[n]=ch;
+     return 1;
+   }
+ }
+ Int16 myTxtCharWidth(WChar c)
+ {
+   return FntCharsWidth((Char *)&c,myTxtCharSize(c));
+ }
+ #else
+ #define myTxtCharSize(x) TxtCharSize(x)
+ #define myTxtGetNextChar(x,y,z) TxtGetNextChar(x,y,z)
+ #define myTxtSetNextChar(x,y,z) TxtSetNextChar(x,y,z)
+ #define myTxtCharWidth(x) TxtCharWidth(x)
+ #endif
  
  /***********************************************************************
   *
***************
*** 83,89 ****
--- 123,143 ----
  static Int16 bigSpace       = 0;    /* How many get 1 extra */
  static Int16 littleSpace    = 0;    /* Extra pixels in each */
  
+ /* TEST toggle Copy2Memo mode*/
+ static Boolean hardcopy = false;
+ static Boolean inView   = false;
  
+ Boolean GetHardcopyMode(void)
+ {
+   return hardcopy;
+ }
+ 
+ Boolean SetHardcopyMode(Boolean new)
+ {
+   Boolean old=hardcopy;
+   hardcopy=new;
+   return old;
+ }
  
  /* Check if current font is the fixed width font */
  static Boolean FixedWidthFont(void)
***************
*** 574,589 ****
  static TokenType GetNextToken
      (
      ParagraphContext*   pContext,   /* pointer to paragraph context */
!     Char*               nextToken   /* token value */
      )
  {
!     Char    nextChar;
      Int16   offset;
  
      if ( pContext->last <= pContext->position )
          return TOKEN_PARAGRAPH_END;
  
!     nextChar = *( pContext->position++ );
  
      if ( nextChar != '\0' ) {
          *nextToken = nextChar;
--- 628,643 ----
  static TokenType GetNextToken
      (
      ParagraphContext*   pContext,   /* pointer to paragraph context */
!     WChar*               nextToken   /* token value */
      )
  {
!     WChar    nextChar;
      Int16   offset;
  
      if ( pContext->last <= pContext->position )
          return TOKEN_PARAGRAPH_END;
  
!     pContext->position+=myTxtGetNextChar(pContext->position,0,&nextChar);
  
      if ( nextChar != '\0' ) {
          *nextToken = nextChar;
***************
*** 642,648 ****
      lastSpaceIsVisible  = false;
  
      for ( ;; ) {
!         Char        nextToken;
          TokenType   nextTokenType;
  
          nextTokenType = GetNextToken( pContext, &nextToken );
--- 696,702 ----
      lastSpaceIsVisible  = false;
  
      for ( ;; ) {
!         WChar        nextToken;
          TokenType   nextTokenType;
  
          nextTokenType = GetNextToken( pContext, &nextToken );
***************
*** 701,707 ****
              lastSpaceHeight     = *height;
              lastSpace           = tokenCount;
          }
!         charWidth = FntCharWidth( nextToken );
  
          if ( pContext->maxPixels < ( charWidth + linePixels ) ) {
              if ( ( pContext->maxPixels / 2 ) < lastSpacePixels ) {
--- 755,761 ----
              lastSpaceHeight     = *height;
              lastSpace           = tokenCount;
          }
!         charWidth = myTxtCharWidth( nextToken );
  
          if ( pContext->maxPixels < ( charWidth + linePixels ) ) {
              if ( ( pContext->maxPixels / 2 ) < lastSpacePixels ) {
***************
*** 719,724 ****
--- 773,787 ----
              *height = pContext->fontHeight = FntLineHeight();
  
          tokenCount++;
+ 
+       // CRLF can be inserted anywhere if it is multibyte char
+       if (myTxtCharSize(nextToken) == 2) {
+         lastSpacePixels = linePixels;
+         lastSpace = tokenCount;       // This is the count *after* the char
+         lastSpaceHeight=*height;//!
+         lastSpaceIsVisible=false;//!
+       }
+ 
      }
      if ( pContext->fontHeight != *height )
          pContext->fontHeight = *height;
***************
*** 736,742 ****
  }
  
  
- 
  /* Draw characters from a paragraph onto the display */
  static void WriteLine
      (
--- 799,804 ----
***************
*** 751,757 ****
      const Int16 findPatternStop   = findPatternStart + findPatternLen - 1;
  
      Boolean   invertPattern;
!     Char      chars[ characters + 1 ];
      Int16     count;
      Int16     storeChar;
  
--- 813,819 ----
      const Int16 findPatternStop   = findPatternStart + findPatternLen - 1;
  
      Boolean   invertPattern;
!     Char      chars[ characters*2 + 1 ];
      Int16     count;
      Int16     storeChar;
  
***************
*** 765,771 ****
  
      while ( count < characters ) {
          TokenType nextTokenType;
!         Char      nextChar;
          Int16     imageWidth;
  
          nextTokenType = GetNextToken( pContext, &nextChar );
--- 827,833 ----
  
      while ( count < characters ) {
          TokenType nextTokenType;
!         WChar     nextChar;
          Int16     imageWidth;
  
          nextTokenType = GetNextToken( pContext, &nextChar );
***************
*** 775,780 ****
--- 837,844 ----
          else if ( nextTokenType == TOKEN_FUNCTION ) {
              if ( 0 < storeChar ) {
                  if ( tContext->writeMode ) {
+                 if(inView&&(GetHardcopyMode()==true))
+                   ScribeMemo(chars,storeChar);
                      if ( invertPattern )
                          WinDrawInvertedChars( chars, storeChar, 
                              tContext->cursorX, 
***************
*** 786,791 ****
--- 850,862 ----
                  tContext->cursorX  += FntCharsWidth( chars, storeChar );
                  storeChar           = 0;
              }
+             
+if(inView&&(GetHardcopyMode()==true)&&((ParagraphFunction)*pContext->function == 
+ANCHOR_END)){
+               Char str[20];
+             Int16 reference=GetCurrentAnchorReference();
+             StrPrintF(str,"[%d]",reference);
+               ScribeMemo(str,StrLen(str));
+             AddURLToMemo(reference);
+             }
              HandleFunction( pContext, tContext, &imageWidth );
              tContext->cursorX += imageWidth;
  
***************
*** 809,814 ****
--- 880,887 ----
          if ( patternCount == findPatternStart ) {
              if ( 0 < storeChar ) {
                  if ( tContext->writeMode ) {
+                 if(inView&&(GetHardcopyMode()==true))
+                   ScribeMemo(chars,storeChar);
                      WinDrawChars( chars, storeChar, tContext->cursorX, 
                          tContext->cursorY - FntCharHeight() );
                  }
***************
*** 820,830 ****
                                        TopLeftY();
          }
  
!         chars[ storeChar++ ] = nextChar;
          count++;
  
          if ( patternCount == findPatternStop ) {
              if ( tContext->writeMode ) {
                  WinDrawInvertedChars( chars, storeChar, tContext->cursorX, 
                      tContext->cursorY - FntCharHeight() );
              }
--- 893,905 ----
                                        TopLeftY();
          }
  
!       storeChar+=myTxtSetNextChar(chars,storeChar,nextChar);
          count++;
  
          if ( patternCount == findPatternStop ) {
              if ( tContext->writeMode ) {
+                 if(inView&&(GetHardcopyMode()==true))
+                   ScribeMemo(chars,storeChar);
                  WinDrawInvertedChars( chars, storeChar, tContext->cursorX, 
                      tContext->cursorY - FntCharHeight() );
              }
***************
*** 836,841 ****
--- 911,918 ----
          if ( pContext->type == ALIGNMENT_JUSTIFY && nextChar == ' ' ) {
              if ( 0 < storeChar ) {
                  if ( tContext->writeMode ) {
+                 if(inView&&(GetHardcopyMode()==true))
+                 ScribeMemo(chars,storeChar);
                      WinDrawChars( chars, storeChar, tContext->cursorX, 
                          tContext->cursorY - FntCharHeight() );
                  }
***************
*** 851,856 ****
--- 928,935 ----
      }
      if ( 0 < storeChar ) {
          if ( tContext->writeMode ) {
+                 if(inView&&(GetHardcopyMode()==true))
+                   ScribeMemo(chars,storeChar);
              if ( invertPattern )
                  WinDrawInvertedChars( chars, storeChar, tContext->cursorX, 
                      tContext->cursorY - FntCharHeight() );
***************
*** 876,881 ****
--- 955,963 ----
      Int16               length;
      Int16               height;
      Int16               storeCount;
+     Int16               ymax;
+ 
+     ymax=MaxExtentY();
  
      InitializeParagraphContext( &pContext, paragraph, record );
      tContext->cursorX = TopLeftX();
***************
*** 929,935 ****
              ContinueStrike( tContext );
  
          /* Draw the characters and move the cursor...  */
!         WriteLine( &pContext, tContext, length, true );
  
          /* End any anchor which was going on the last line; continue it on the
             next line. */
--- 1011,1018 ----
              ContinueStrike( tContext );
  
          /* Draw the characters and move the cursor...  */
!       inView=(tContext->cursorY>0)&&(tContext->cursorY<ymax);
!       WriteLine( &pContext, tContext, length, true );
  
          /* End any anchor which was going on the last line; continue it on the
             next line. */
***************
*** 957,959 ****
--- 1040,1043 ----
      if ( record->type == DATATYPE_PHTML_COMPRESSED )
          MemHandleUnlock( GetUncompressTextHandle() );
  }
+ 
Index: paragraph.h
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/paragraph.h,v
retrieving revision 1.21
diff -C3 -r1.21 paragraph.h
*** paragraph.h 18 Jul 2001 20:01:36 -0000      1.21
--- paragraph.h 19 Oct 2001 04:48:43 -0000
***************
*** 145,151 ****
          Header* record );
  void SetFindPatternData( const Int16 pos, const Int16 len );
  void ClearFindPatternData( void );
! 
  
  // Return pointer to paragraph with given index
  #define GET_PARAGRAPH( RECORD, INDEX )      ( (Paragraph*) ( (UInt8*) ( ( RECORD ) + 
1 ) + ( INDEX ) * sizeof( Paragraph ) ) )
--- 145,152 ----
          Header* record );
  void SetFindPatternData( const Int16 pos, const Int16 len );
  void ClearFindPatternData( void );
! Boolean GetHardcopyMode(void);
! Boolean SetHardcopyMode(Boolean);
  
  // Return pointer to paragraph with given index
  #define GET_PARAGRAPH( RECORD, INDEX )      ( (Paragraph*) ( (UInt8*) ( ( RECORD ) + 
1 ) + ( INDEX ) * sizeof( Paragraph ) ) )
Index: resourceids.h
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/resourceids.h,v
retrieving revision 1.55
diff -C3 -r1.55 resourceids.h
*** resourceids.h       22 Jul 2001 15:59:01 -0000      1.55
--- resourceids.h       19 Oct 2001 04:48:44 -0000
***************
*** 295,300 ****
--- 295,301 ----
  #define mGoBookmarks            5107
  #define mGoTop                  5108
  #define mGoBottom               5109
+ #define mGoCopyMemo             5110 /*matto*/
  
  #define mViewTopToolbar         5111
  #define mViewBottomToolbar      5112
Index: viewer.rcp.in
===================================================================
RCS file: /cvs/plucker/plucker_src/viewer/viewer.rcp.in,v
retrieving revision 1.61
diff -C3 -r1.61 viewer.rcp.in
*** viewer.rcp.in       24 Jul 2001 17:11:11 -0000      1.61
--- viewer.rcp.in       19 Oct 2001 04:48:47 -0000
***************
*** 114,119 ****
--- 114,121 ----
          MENUITEM SEPARATOR
          MENUITEM "$$ADD BOOKMARK"   mGoAddBookmark      "$$SC ADD BOOKMARK"
          MENUITEM "$$BOOKMARKS..."   mGoBookmarks        "$$SC BOOKMARKS"
+         MENUITEM SEPARATOR
+         MENUITEM "Copy To Memo"     mGoCopyMemo         "M"
      END
  
      PULLDOWN "$$VIEW"

Reply via email to