The R Project SVN R

Rev

Rev 15609 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

/*
 *  R : A Computer Language for Statistical Data Analysis
 *  File RPreference.c
 *  Copyright (C) 1998-1999  Ross Ihaka
 *                2000-2001  Stefano M. Iacus and the R core team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 *  This file is adapted from the public demos coming with the Waste library
 *  distribution:  WASTE Text Engine © 1993-2000 Marco Piovanelli.
 *   
 *  This file was originally written by: Wing Kwong (Tiki), WAN 3/2/99
 *  Updated to last version of WasteLib library: Stefano M. Iacus, 2001
 *
 *  Original file was:
 *
 *  WASTE Demo Project:
 *  Preferences
 *
 *  Copyright © 1993-1998 Marco Piovanelli
 *  All Rights Reserved
 *
 *  C port by John C. Daub

    ************************************************************************************************ 
     
    RPreference
    by wing kwong (Tiki), WAN 3/2/99
    Temporarily removed preferences because using Environments.
    
    ************************************************************************************************ 
    Description
    
    This file is used to control the Menu item, Preference. It includes  routine to load the 
    preference when the program start; routine to display the current preference when user click on
    the Menu; routine to save the preference.
    
    In here, the appearence of the Preference is design by the resource "DLOG" and "DITL". As long 
    as you didn't change the resource ID, you can feel free to change the appearence of the dialog 
    box without recomplies the codes    
    ************************************************************************************************ 
*/

#include <RCarbon.h>

/* ************************************************************************************************ */
/*                                    INCLUDE HEADER FILE                                           */
/* ************************************************************************************************ */
#include "RIntf.h"
#include "WETabs.h"
#include "WETabHooks.h"
#include <ColorPicker.h>
#include <ATSUnicode.h>

/* ************************************************************************************************ */
/*                                      DEFINE CONSTANT                                             */
/* ************************************************************************************************ */
#define  rPreStringList      132
#define  rPrefsDialog        128
#define  itabSize            1  
#define  iHistorySize        4
#define  iPrefsFileName      1
#define  rTypeAppMiss        'STR '
#define  kAppMissID          -16397
#define  eTabSize            7
#define  eHistorySize        8
#define  eTextSize           13
#define  eR_NSize            14
#define  eR_VSize            15
#define  eScreenRes          16
#define  kWordSize           9

int     EIGHTY, F_HEIGHT;
#define FixedToInt(a)   ((int)(a) / fixed1)

extern SInt32       systemVersion ;
extern Boolean      Have_Console;
/* ************************************************************************************************ */
/*                          Constant, Global variables and prototype                                */
/* ************************************************************************************************ */

/*
Here include all the Control in the Preference dialog, if you want to add more control, 
you needed to add the corresponding item in here.
*/
enum
{
   kActiveTextButton            = 12,
   kCompletedTextButton         = 2,
   kComputerResponseButton      = 3,
   kActiveTextField             = 4,
   kCompletedTextField          = 5,
   kComputerResponseField       = 6,
   kTabSize                     = 7,
   kHistoryLength               = 8,
//   kTextSize                    = 9,  // Jago
   kR_Vsize                     = 10,
   kR_Nsize                     = 11,
   kOkButton                    = 1,       // 1 is default button.
   kCancelButton                = 13,   
   kEditRect                    = 27,
   kScreenRes                   = 29,
   kMemoryRect                  = 30   
   
} ;

/*
Here include all the content that the preference will store, if you wanted to add more.
You need to add the corresponding item in here.
*/
typedef struct
{
   char                        tabSize[3];
   char                        textSize[3];
   char                        ScreenR[5];
   RGBColor                    TypeColour;
   RGBColor                    FinishedColour;
   RGBColor                    ComputerColour;
   FSSpec                      sfFile;
   StandardFileReply           sfr;
   char                        envString[255];
}  appPrefs, *appPrefsPointer, **appPrefsHandle;

/* ************************************************************************************************ */
/*                                        Global variables                                          */
/* ************************************************************************************************ */ 
SInt16                                     gPrefsFileRefNum =0;
FSSpec                                     gHelpFile;
StandardFileReply                          gsfr;
RGBColor                                   tempTypeColour, gTypeColour;
RGBColor                                   tempFinishedColour,gFinishedColour;
RGBColor                                   tempComputerColour,gComputerColour;
SInt16                                     gTextSize;
SInt16                                     storeHistory; 
int                                        PR_NSize;
int                                        PR_VSize;
int                                        gScreenRes;

// you can't change the Global variable HISTORY when you do change on Preference

/* ************************************************************************************************ */
/*                                Extern  Global variables                                          */
/* ************************************************************************************************ */ 
extern SInt16                              gtabSize;
extern SInt16                              gAppResFileRefNum ;
extern Ptr                                 *Cmd_Hist;
extern SInt16                              HISTORY;
extern WindowPtr                           Console_Window;
extern SInt16                              Edit_Window;
extern WindowPtr                           Edit_Windows[MAX_NUM_E_WIN + 1];
extern SInt16                              Help_Window;
extern WindowPtr                           Help_Windows[MAX_NUM_H_WIN + 1];
extern char                                genvString[255];
extern int                                 R_NSize;  
extern int                                 R_VSize;
extern Str255                              MacSymbolFont;
extern Str255                              PostFont;
extern Str255                              UserFont;


/* ************************************************************************************************ */
/*                                        Protocols                                                 */
/* ************************************************************************************************ */ 
unsigned char*                            StrToPStr(char*, SInt8);
void                                      doSavePreference(DialogPtr );
void                                      doGetPreferences(void);
void                                      savePreference(void);
void                                      DrawBox (DialogPtr PreferenceBox);
void                                      SetTab(void);
pascal  OSErr                             FSpGetFullPath (const FSSpec*, short*, Handle*);
void                                      pickColor(DialogPtr, SInt16 , RGBColor , RGBColor*);
void                                      SetTextSize(void);
extern int                                R_SetOptionWidth(int w);

extern int GetTextSize(void);
int EightyWidth(void);





/* ************************************************************************************************
StrToPStr: Transfer a string to Pascal String with size 'size'
************************************************************************************************ */
Str255 returnString;
unsigned char* StrToPStr(char* buf, SInt8 size){
    // Str255 returnString;
    returnString[0] = size;
    BlockMoveData(buf,returnString + 1,(SInt32) size);
    return returnString;
}


extern char *mac_getenv(const char *name);
Boolean Interrupt =false;
Boolean OnOpenSource = false;

/* ************************************************************************************************
doGetPreferences :  This function will be called at the beginning when R application starts.
                    It sets up some parameters specified by the user in the .Renviron file
                    such as the graphic device screen resolution and font, the Console font and
                    size and the tab-size of all the text windows. Etc.
Jago, April 2001, Stefano M. Iacus  
************************************************************************************************ */
void  doGetPreferences(void)
{
   Str255               prefsFileName;
   OSErr                osError;
   SInt16               volRefNum;
   long                 directoryID;
   FSSpec               fileSSpec;
   SInt16               fileRefNum;
   appPrefsHandle       appPrefsHdl;
   char                 userfont[25];
   FMFontFamily         postFontId;
     
      strcpy(genvString, ".Renviron");
      
      SetTab();
    
      storeHistory = atoi(mac_getenv("RHISTSIZE"));
       
       
      if(storeHistory < 1 || storeHistory > 512)  
       storeHistory = 512;
      HISTORY = storeHistory +1;
      Cmd_Hist = malloc(HISTORY * sizeof(Ptr));
  
         
      gTextSize = GetTextSize();

      gScreenRes = GetScreenRes();
      
      doCopyPString("\psymbol", MacSymbolFont);  /* Jago */

      strncpy(userfont,mac_getenv("GraphFontName"),20);
 
      if(strlen(userfont)>0)
       CopyCStringToPascal(userfont,PostFont);
 
      if(GetFontIDFromMacFontName(PostFont) == kATSUInvalidFontID)
         doCopyPString("\phelvetica", PostFont); /* Emergency font ! */

      strncpy(userfont,mac_getenv("FontName"),20);
      
      if(strlen(userfont)>0)
       CopyCStringToPascal(userfont,UserFont);
  
      if(systemVersion > kMinSystemVersion){
      if( FMGetFontFamilyFromName(UserFont) == kInvalidFontFamily)
         doCopyPString("\pmonaco", UserFont); /* Emergency font ! */
      }
      else {
       GetFNum(UserFont, &postFontId);
       if( postFontId == kInvalidFontFamily)
          doCopyPString("\pmonaco", UserFont); /* Emergency font ! */
      }

      EIGHTY = EightyWidth();
      
      tempTypeColour.red = gTypeColour.red =  0xffff;
      tempTypeColour.green = gTypeColour.green =  0x0000;
      tempTypeColour.blue = gTypeColour.blue =  0x0000;
      tempFinishedColour.red = gFinishedColour.red = 0x0000;
      tempFinishedColour.green = gFinishedColour.green = 0x0000;
      tempFinishedColour.blue = gFinishedColour.blue = 0xffff;
 
      tempComputerColour.red = gComputerColour.red = 0x0000;
      tempComputerColour.green = gComputerColour.green = 0x0000;
      tempComputerColour.blue = gComputerColour.blue = 0x0000;
      
      if(strcmp(mac_getenv("Interrupt"),"TRUE")==0)
       Interrupt = true;
      else  
       Interrupt = false;
       
       
      if(strcmp(mac_getenv("OnOpenSource"),"TRUE")==0)
       OnOpenSource = true;
      else  
       OnOpenSource = false;
  
}

int EightyWidth(void)
{
    CGrafPtr        tempPort=NULL;
    char            userfont[26];
    char            eighty[81];
    Str255          ottanta;
    int             eightywidth = 50*12,i;
    FMFontFamily    fontFamily = 0 ;
    FMetricRec      myFMetric;

    F_HEIGHT = gTextSize+2;
    
    tempPort = CreateNewPort();
    
    if(tempPort == NULL)
     return(eightywidth);
      
    if(systemVersion > kMinSystemVersion)     
    fontFamily = FMGetFontFamilyFromName(UserFont);
    else
     GetFNum(UserFont,&fontFamily);
  
    if(fontFamily == kInvalidFontFamily)
     return(eightywidth);
     
    TextFont(fontFamily);
    TextSize(gTextSize);
    
    for(i=0;i<80;i++)
     eighty[i]=0x52; /* R ! */
    eighty[80]='\0';
    
    CopyCStringToPascal(eighty,ottanta);
    eightywidth = StringWidth(ottanta);
    
    FontMetrics(&myFMetric);

    F_HEIGHT = FixedToInt(myFMetric.ascent + myFMetric.descent + myFMetric.leading);
    
    if(tempPort)
     DisposePort(tempPort);
    
    return(eightywidth);
}


/*
************************************************************************************************
pickColor routine :
************************************************************************************************
Desciption :
This procedure is used to redraw (Update) the update the color of the text that you selected.
The purpose of this routine is to give the end user a impression of the color that they picked.
************************************************************************************************
*/
void pickColor(DialogPtr PreferenceBox, SInt16 itemID, RGBColor inColour, RGBColor *outColor){
   RGBColor           blackColour;
   short              type; 
   Rect               itemRect;
   Handle             itemHandle=NULL;
   Str255            prompt = "\pChoose a rectangle colour:";
   Point             where ={0,0};
   GrafPtr           savePort;
   long              SaveColor;
   Boolean      okButton;
   
   blackColour.red   = 0x0000;
   blackColour.green = 0x0000;
   blackColour.blue  = 0x0000;
   GetDialogItem(PreferenceBox,  itemID, &type, &itemHandle, &itemRect);
   okButton = GetColor(where,prompt,&inColour,outColor);
   if (okButton){
      RGBForeColor(outColor);
      SetDialogItemText(itemHandle, "\pText Color"); 
      RGBForeColor(&blackColour);
   }else{
      *outColor = inColour;
   }

}


/*
************************************************************************************************
DrawBox routine :
************************************************************************************************
Desciption :
This procedure is used to redraw (Update) the preference dialog box.
When you open the dialog box, you may also open dialog like color picker, the preference dialog
box didn't know how to recover the content, thus, we need to call this procedure and update the
bitmap by ourself.
************************************************************************************************
*/
void DrawBox(DialogPtr PreferenceBox){
   short              type; 
   Handle             itemHandle=NULL;
   Rect               itemRect;
   Pattern            myPat;
   RGBColor          blackColour;
   blackColour.red   = 0x0000;
   blackColour.green = 0x0000;
   blackColour.blue  = 0x0000;
   GetIndPattern( &myPat, sysPatListID,2 );     /* brickwork */
   PenPat( &myPat );
   GetDialogItem(PreferenceBox,kEditRect,&type,&itemHandle,&itemRect);
   FrameRect(&itemRect);
   GetDialogItem(PreferenceBox,kMemoryRect,&type,&itemHandle,&itemRect);
   FrameRect(&itemRect);
   GetIndPattern( &myPat, sysPatListID,1 );     /* Restore */
  //SetColor 
   GetDialogItem(PreferenceBox,   kActiveTextField, &type, &itemHandle, &itemRect);
   RGBForeColor(&tempTypeColour);
   SetDialogItemText(itemHandle, "\pActive Text Color");
   GetDialogItem(PreferenceBox,  kCompletedTextField, &type, &itemHandle, &itemRect);
   RGBForeColor(&tempFinishedColour);
   SetDialogItemText(itemHandle, "\pCompleted Text Color");
   GetDialogItem(PreferenceBox,  kComputerResponseField, &type, &itemHandle, &itemRect);
   RGBForeColor(&tempComputerColour);
   SetDialogItemText(itemHandle, "\pComputer Text Color");
   RGBForeColor(&blackColour); 

   PenPat( &myPat );
}

/*
************************************************************************************************
SetTab routine :
************************************************************************************************
Desciption :
A procedure which used to set the Tab space of the Console window and the Edit window according
to the Preference (Global Variables). Actually, you can set different Tab Sapce in different 
text editing window. However, I predict it will confuse the user.
************************************************************************************************
*/
void SetTab(){
   GrafPtr savePort;
   WEReference we ;
   WEStyleMode    mode;
   TextStyle      ts;
   SInt16         i;  
   char         tabsize[10];
   
   gtabSize = atoi(mac_getenv("TabSize"));
     
   if(gtabSize < 1 || gtabSize > 20)
    gtabSize = 5;
       
   if (!(Console_Window == nil)){
       we = GetWindowWE ( Console_Window);
       WESetTabSize(gtabSize,we); 
       WEInstallTabHooks(we);
   }
   
   for (i=1; i<Edit_Window; i++){
       we = GetWindowWE ( Edit_Windows[i]); 
       WESetTabSize(gtabSize,we);
       // The following three lines is working, however, we only allow fix size font.
       // It is much more better than query the WASTE about the font size you are 
       // currently using. Cause they can use different font size in one page.       
       mode = weDoAll ;  // query about all attributes
       WEContinuousStyle ( & mode, & ts, we ) ;
       WESetTabSize(gtabSize*(ts . tsSize),we);

       WEInstallTabHooks(we);
   
   }
   
    for (i=1; i<Help_Window; i++){
       we = GetWindowWE ( Help_Windows[i]); 
       WESetTabSize(gtabSize,we);
       mode = weDoAll ;  // query about all attributes
       WEContinuousStyle ( & mode, & ts, we ) ;
       WESetTabSize(gtabSize*(ts . tsSize),we);

       WEInstallTabHooks(we);
   
   }
}


void SetTextSize(){
   SInt16 i;
   SInt32 selStart, selEnd;
   WEReference we ;
   SInt16 Console_Width, NumofChar;
   GrafPtr savePort;    
   Rect portRect;
   
   we = GetWindowWE ( Console_Window);
   if(!we)
    return;
   WEGetSelection ( & selStart, & selEnd, we );
   WESetSelection ( 0, WEGetTextLength(we), we );
   gTextSize = GetTextSize();
   changeSize(Console_Window, gTextSize);
   WESetSelection (selStart, selEnd, we);
   GetWindowPortBounds ( Console_Window, & portRect ) ;
   Console_Width = portRect.right - portRect.left ;
   GetPort(&savePort);
   SetPortWindowPort(Console_Window);
   TextFont(4);
   TextSize(gTextSize);
   NumofChar =    (int)((((Console_Width - 15) / CharWidth('M'))) - 0.5) ; 
   R_SetOptionWidth(NumofChar);
   SetPort(savePort);

    for(i=1; i<Help_Window; i++){
       we = GetWindowWE ( Help_Windows[i]);
       WEGetSelection ( & selStart, & selEnd, we );
       WESetSelection ( 0, WEGetTextLength(we), we );
       changeSize(Help_Windows[i], gTextSize);
       WESetSelection (selStart, selEnd, we);
    }

   for(i=1; i < Edit_Window; i++){
      we = GetWindowWE ( Edit_Windows[i]);
      WEGetSelection ( & selStart, & selEnd, we );
      WESetSelection ( 0, WEGetTextLength(we), we );
      changeSize(Edit_Windows[i], gTextSize);
      WESetSelection (selStart, selEnd, we);
   }


}