Logo Search packages:      
Sourcecode: yudit version File versions

SYudit.cpp

/** 
 *  Yudit Unicode Editor Source File
 *
 *  GNU Copyright (C) 2003  Gaspar Sinai <gsinai@yudit.org>  
 *  GNU Copyright (C) 2002  Gaspar Sinai <gsinai@yudit.org>  
 *  GNU Copyright (C) 2001  Gaspar Sinai <gsinai@yudit.org>  
 *  GNU Copyright (C) 2000  Gaspar Sinai <gsinai@yudit.org>  
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, version 2,
 *  dated June 1991. See file COPYYING for details.
 *
 *  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.
 */

#include "gui/SYudit.h"
#include "gui/Main.h"
#include "stoolkit/SEncoder.h"
#include "stoolkit/SIO.h"
#include "stoolkit/STypes.h"
#include "stoolkit/SIOStream.h"
#include "swidget/SUniPrint.h"
#include <swindow/SPrinter.h>
#include <swindow/SScriptProcessor.h>
#include <stdlib.h>

static int translateHighlightMode (const SString& hl);

/**
 * A caret that redraws itself differently for lr and rl text 
 */
00039 SYudit::SYudit (const SStringVector& args, const SProperties& props)
{
  freeHandShown = false;
  freehand = 0;
  freeHandHeight = 0;
  setLayout (SLayout (SLocation (0,0), SLocation (3000,2000)));
  originalProperties = props;

  /* TODO: move this to config file */
  helpStrings.put ("hilfe", "de");
  SEncoder kana("Kana");
  SEncoder utf8("utf-8-s");
  helpStrings.put (utf8.encode (kana.decode ("HERUPU", false)), "ja");
  SEncoder hung("Hungarian");
  helpStrings.put ("segit", "hu");
  helpStrings.put (utf8.encode (hung.decode ("segi't", false)), "hu");
  helpStrings.put (utf8.encode (hung.decode ("segi'tse'g", false)), "hu");
  SEncoder yidd("Yiddish");
  SV_UCS4 yi0;
  yi0.append (SD_CD_RLO);
  yi0.append (yidd.decode ("gehilF", false));
  yi0.append (SD_CD_PDF);
  SV_UCS4 yi1;
  yi1.append (SD_CD_RLO);
  yi1.append (yidd.decode ("helF", false));
  yi1.append (SD_CD_PDF);
  helpStrings.put (utf8.encode (yi0), "yi");
  helpStrings.put (utf8.encode (yi1), "yi");
  helpStrings.put (utf8.encode (yidd.decode ("gehilF", false)), "yi");
  helpStrings.put (utf8.encode (yidd.decode ("helF", false)), "yi");
  helpStrings.put ("ayuda", "es");

  configFile = props["yudit.config"];

  char fnc[64];
  /* get an unused filename */
  for (unsigned int fn=0; fn<100000; fn++)
  {
   if (fn==0)
   {
     sprintf (fnc, "untitled.txt"); 
   }
   else
   {
     sprintf (fnc, "untitled%d.txt", fn); 
   }
   currentFileName = SString (fnc);
   SFile cfile (currentFileName);
   if (cfile.size() < 0) break;
  }  
  lastprinterOption = props["yudit.default.printer.options"];
  lastpreviewOption ="-e ";
  lastpreviewOption.append (props["yudit.default.preview.command"]);
  lastpreviewOption.replaceAll("\\", "/");
  lastpreviewOption.replaceAll("//", "/");
  lastencoding=props["yudit.default.filetype"];

  setFrameListener (this);
  command = new STextEdit ();
  SString commandFont ("default");
  if (props.get("yudit.command.font"))
  {
    commandFont = props["yudit.command.font"];
  }
  SString commandFontSizeString ("16");
  if (props.get("yudit.command.fontsize"))
  {
    commandFontSizeString = props["yudit.command.fontsize"];
  }
  commandFontSizeString.append ((char)0);
  double commandFontSize=0;
  sscanf (commandFontSizeString.array(), "%lf", &commandFontSize);

  if (commandFontSize < 2.0) commandFontSize = 2.0;
  command->setFont (commandFont, commandFontSize);
  unsigned int commandHeight = command->getPreferredSize().height;
  command->setMultiline (false);
  command->setLineEndMark (false);

  messagebar = new SMessageBar (props);
  unsigned int msgbarHeight = messagebar->getPreferredSize().height;


  toolbar = new SToolBar (props);
  unsigned int toobarHeight = toolbar->getPreferredSize().height;

  toolbar->setLayout (
    SLayout (
     SLocation (2,0),
     SLocation (2998, toobarHeight+0),
     SLocation (0, 0),
     SLocation (100, 0)
    )
  );
  toolbar->setListener (this);

  messagelabel = new SMessageLabel (props);
  unsigned int messagelabeHeight = messagelabel->getPreferredSize().height;

  messagelabel->setLayout (
    SLayout (
      SLocation (2, 1998-messagelabeHeight),
      SLocation (2998, 1998),
      SLocation (0, 100),
      SLocation (100, 100)
    )
  );
  command->setLayout (
    SLayout (
      SLocation (2, 1998-commandHeight-messagelabeHeight),
      SLocation (2998, 1998-messagelabeHeight),
      SLocation (0, 100),
      SLocation (100, 100)
    )
  );

  messagebar->setLayout (
    SLayout (
     SLocation (2,1998-msgbarHeight-commandHeight-messagelabeHeight),
     SLocation (2998, 1998-commandHeight-messagelabeHeight),
     SLocation (0, 100),
     SLocation (100, 100)
    )
  );

  sliderLayout =  SLayout (
      SLocation (2978, toobarHeight+2),
      SLocation (2998, 1998 - commandHeight - msgbarHeight - messagelabeHeight),
      SLocation (100, 0),
      SLocation (100, 100)
  );

  slider = new SSlider ();
  slider->setLayout (sliderLayout);
  /* on mac somehow it did not want to resize - force it */
  slider->resize (SDimension (10, 200));
  
  SString currentFont = toolbar->fonts[toolbar->currentFont];
  SString currentFontSize = toolbar->fontsizes[toolbar->currentFontSize];
  SString currentInput = toolbar->inputs[toolbar->currentInput];
  SString currentParagraphSeparator = toolbar->paragraphBreaks[toolbar->currentParagraphSeparator];
  

  editor = new STextEdit ();
  currentFontSize.append ((char)0);
  double df;
  if (sscanf (currentFontSize.array(), "%lf", &df)==0 || df < 2.0) df = 2.0;
  editor->setFont (currentFont, df);

  editor->setMultiline (true);
  editor->setLineEndMark (true);
  editor->setDocumentEmbedding (toolbar->currentEmbedding);

  editorLayout = 
    SLayout (
      SLocation (2, toobarHeight+2),
      SLocation (2978, 1998 - commandHeight - msgbarHeight - messagelabeHeight),
      SLocation (0, 0),
      SLocation (100, 100)
    );
  editor->setLayout (editorLayout);

  /*SGC */
  SString inputStyle = originalProperties["yudit.editor.xinputs.style"];

  /* allowed styles */
  if (inputStyle=="preedit-over-status-under" 
       || inputStyle == "preedit-under-status-under"
       || inputStyle=="preedit-over-status-over"
       || inputStyle == "preedit-root-status-root" )
  {
    SProperties p;
    SColor cbg(originalProperties["yudit.background"]);
    SColor cfg(originalProperties["yudit.label.foreground"]);

    sprintf (fnc, "%lu,%lu", (unsigned long)cbg.getValue(),
      (unsigned long)cfg.getValue());
    p.put ("InputClientColor", fnc);

    SColor sbg(originalProperties["yudit.background"]);
    SColor sfg(originalProperties["yudit.title.foreground"]);

    sprintf (fnc, "%lu,%lu", (unsigned long)sbg.getValue(),
      (unsigned long)sfg.getValue());
    p.put ("InputStatusColor", fnc);
    editor->setXIMProperties (p);

    p.put ("InputStyle", inputStyle);
    editor->setXIMProperties (p);
  }
  else
  {
    fprintf (stderr, "Yudit: unkown yudit.editor.xinputs.style=%*.*s\n",
       SSARGS(inputStyle));
  }

  /* showInputStatus has set up the xim properties for editor */
  editor->setInputMethod (currentInput);

  if (currentInput.size() > 2) 
  {
    if (currentInput != SS_KINPUT2_IM  
       && currentInput != SS_WINDOWS_IM
       && currentInput[0] != 'x' 
       && currentInput[1] != 'X')
    {
      command->setInputMethod (currentInput);
    }
  }
  if (props["yudit.editor.showbreak"]=="true")
  {
    editor->setLineEndMark (true);
  }
  else
  {
    editor->setLineEndMark (false);
  }
  if (props["yudit.editor.wordwrap"]=="true")
  {
    editor->setWordWrap (true);
  }
  else
  {
    editor->setWordWrap (false);
  }
  const SString& hl = props["yudit.editor.syntax"];
  int mode = translateHighlightMode (hl);
  if (mode >= 0) 
  {
    editor->setHighlightMode ((STextView::SS_HighlightMode)mode);
  }

  SEditor e(currentParagraphSeparator);
  editor->setEditor (e);
  messagebar->setFontSize(df);
  command->setEditor(SEditor());
  
  add (slider);
  add (editor);
  add (command);
  add (toolbar);
  add (messagebar);
  add (messagelabel);

  setBackground (props["yudit.background"]);
  editor->setTextBackground (props["yudit.editor.background"]);
  editor->setForeground (props["yudit.editor.left.foreground"],
            props["yudit.editor.right.foreground"]);
  editor->setCaretForeground (props["yudit.editor.caret.left.foreground"],
            props["yudit.editor.caret.right.foreground"]);
  command->setTextBackground (props["yudit.command.background"]);
  command->setForeground (props["yudit.command.left.foreground"],
            props["yudit.command.right.foreground"]);
  command->setCaretForeground (props["yudit.command.caret.left.foreground"],
            props["yudit.command.caret.right.foreground"]);
  slider->setSliderBackground (props["yudit.slider.background"]);


  SString version("Yudit-");
  version.append (SD_YUDIT_VERSION);
  setTitle (version);

  SDimension pw = toolbar->getPreferredSize();
  /* get the dimension */
  SDimension ms(props["yudit.default.geometry"]);
  if (ms.width < pw.width + 10) ms.width = pw.width + 10;
  if (ms.height < pw.height + 10) ms.width = pw.height + 10;
  resize (ms);
  setMinimumSize (SDimension (150, 100));

  caretNow = STextIndex (0,0);
  messagebar->setRow(1);
  messagebar->setColumn (0);
  editor->setCursorIndex(SCursorIndex(0,0));
  editor->addTextEditLS (this);
  command->addTextEditLS (this);
  command->setHistorySize(30);

  kmapDialog = 0;
  fileDialog = 0;
  textDialog = 0;

#ifdef USE_WINAPI
  SToolBar::SFormatIndex ft=SToolBar::SS_FORMAT_DOS;
#else 
  SToolBar::SFormatIndex ft=SToolBar::SS_FORMAT_UNIX;
#endif
  toolbar->setParagraphSeparator (ft, true);

  if (args.size())
  {
    SString comm ("open -yes ");
    SString enc ((lastencoding.size()==0)?SString("utf-8"):lastencoding);
    SString filename;
    bool help=false;
    unsigned int i;
    for (i=1; i<args.size(); i++)
    {
      if (args[i] == SString("-e") && i+1 < args.size())
      {
        i++;
        enc = args[i];
      }
      else if (args[i] == SString("-help") || args[i] == SString("-h"))
      {
        help = true;
      }
      else if (args[i] == SString("-us"))
      {
        SScriptProcessor::support(true);
      }
      else if (args[i] == SString("-nus"))
      {
        SScriptProcessor::support(false);
      }
      else if (args[i] == SString("-noinit"))
      {
        SScriptProcessor::doInit(false);
      }
      else if ((args[i] == SString("-d") || args[i] == SString("-geometry")) 
            && i+1 < args.size()) {
        i++;
      ms = SDimension (args[i]);  
        if (ms.width < pw.width + 10) ms.width = pw.width + 10;
        if (ms.height < pw.height + 10) ms.width = pw.height + 10;
        resize (ms);
      }
      else 
      {
        filename = args[i];
        break;
      }
    }
    if (help)
    {
      filename = SString("help");
      command->putHistory (filename);
    }
    else
    {
       filename = composeFileNameCommand (comm, enc, 
            completeFileName(filename));
       /* now it comes handy - args starts with 1 */
       unsigned int j;
       for (j=args.size(); j>i; j--)
       {
          SString ss = composeFileNameCommand (comm, enc, 
                completeFileName (args[j-1]));
          command->putHistory (ss);
       }
    }
    SStringVector v;
    v.smartSplit (filename);
    load (v, filename);
  }

  toolbar->setFileName(currentFileName, lastencoding);
//fprintf (stderr, "SYudit.cpp EDITOR FOCUS REQUEST\n");
  setDropListener (this, SStringVector ("text/uri-list,text/plain"));
  showFreeHand (currentInput=="freehand");
  editor->setFocus ();
}

SYudit::~SYudit ()
{
}
bool
SYudit::close (SPanel* comp)
{

  if (textDialog != 0 && textDialog->isShown())
  {
    textDialog->center();
    return false;
  }
  bool ret = false;
  if (toolbar->modified)
  {
    createTextDialog ();
    ret = textDialog->getInput (
        "Yudit: Exit", translate ("Unsaved changes.\nExit anyway?\n"),
        STextDialog::SS_QUESTION); 
    if (ret)
    {
       saveProperties();
       exit (0);
    }
    return false;
  }
  if (toolbar->printing)
  {
    createTextDialog ();
    ret = textDialog->getInput (
        "Yudit: Exit", translate ("Pending printing job.\nExit anyway?\n"),
        SDialog::SS_QUESTION); 
    if (ret)
    {
       saveProperties();
       exit (0);
    }
  }
  saveProperties();
  exit (0);
} 

/**
 * Listening to toolbar.
 */
void
00448 SYudit::buttonPressed (void* src, int which, bool accel)
{
  if (!toolbar->printing) messagelabel->setMessage("");
  if (textDialog != 0 && textDialog->isShown()) return;
  SString currentFont = toolbar->fonts[toolbar->currentFont];
  SString currentFontSize = toolbar->fontsizes[toolbar->currentFontSize];
  SString currentInput = toolbar->inputs[toolbar->currentInput];
  SString currentParagraphSeparator = toolbar->paragraphBreaks[toolbar->currentParagraphSeparator];
  currentFontSize.append ((char)0);
  double df;
  SString pstr;
  SStringVector pstrVector;
  if (sscanf (currentFontSize.array(), "%lf", &df)==0 || df < 2.0) df = 2.0;
  bool ok = false;
  int dire = false;
  bool wasmodified = toolbar->modified;
 
  switch (which)
  {
  /* FIXME */
  case SToolBar::SS_OPEN:
    if (!accel)
    {
       createFileDialog();
       if (toolbar->modified)
       {
         createTextDialog();
         ok = textDialog->getInput (
          "Yudit: Open", translate ("Unsaved changes.\nOpen anyway?\n"),
           STextDialog::SS_QUESTION); 
         if (!ok)
         {
           return;
         }
       }
       fileDialog->setFileName (currentFileName);
       fileDialog->setFileType (lastencoding);
       ok = fileDialog->getInput ("Yudit: Open", false, false);
       if (!ok)
       {
          return;
       }
       pstr.clear();
       pstr.append ("open ");
       pstr.append ("-yes ");
       pstr.append ("-e ");
       pstr.append (fileDialog->getFileType());
       pstr.append (" ");
       pstr.append (quoteFileName (fileDialog->getFileName()));
       command->setText (pstr);
       command->setCursorIndex (SCursorIndex(0,10000));
       command->putHistory (pstr);
       pstrVector.smartSplit(pstr);
       load (pstrVector, pstr);
       return;
    }
    if (toolbar->modified)
    {
      messagelabel->setMessage (translate ("Unsaved changes. Enter discards!"), SMessageLabel::SS_ERR);
      SString str = composeFileNameCommand ("open -yes ", 
         lastencoding, currentFileName);
      command->setText(str);
      command->setCursorIndex (SCursorIndex(0,10000));
    }
    else
    {
      messagelabel->setMessage (translate ("open -yes -e encoding file"), 
         SMessageLabel::SS_INFO);
      SString str = composeFileNameCommand (
             "open ", lastencoding, currentFileName);
      command->setText(str);
      command->setCursorIndex (SCursorIndex(0,10000));
    }
    command->setFocus();
    break;
  case SToolBar::SS_SAVE:
    if (!accel)
    {
       createFileDialog();
       fileDialog->setFileName (currentFileName);
       fileDialog->setFileType (lastencoding);
       pstr = fileDialog->getFileName();
       ok = fileDialog->getInput ("Yudit: Save", false, false);
       if (!ok)
       {
          return;
       }
       if (pstr != fileDialog->getFileName() &&
          newFileExists (fileDialog->getFileName()))
       {
         createTextDialog();
         ok = textDialog->getInput (
          "Yudit: Save", translate ("File exists.\nSave anyway?"),
           STextDialog::SS_QUESTION); 
         if (!ok)
         {
           return;
         }
       }
       pstr.clear();
       pstr.append ("save ");
       pstr.append ("-yes ");
       pstr.append ("-e ");
       pstr.append (fileDialog->getFileType());
       pstr.append (" ");
       pstr.append (quoteFileName (fileDialog->getFileName()));
       command->setText (pstr);
       command->setCursorIndex (SCursorIndex(0,10000));
       command->putHistory (pstr);
       pstrVector.smartSplit(pstr);
       save (pstrVector, pstr);
       return;
    }
    messagelabel->setMessage (translate ("save -e encoding file"), 
       SMessageLabel::SS_INFO);
    {
      SString str = composeFileNameCommand (
             "save ", lastencoding, currentFileName);;
      command->setText(str);
      command->setCursorIndex (SCursorIndex(0,10000));
    }
    command->setFocus();
    break;
  case SToolBar::SS_FIND:
    messagelabel->setMessage (translate ("find string"), 
       SMessageLabel::SS_INFO);
    command->setText("find ");
    command->setCursorIndex (SCursorIndex(0,10000));
    command->setFocus();
    break;
  case SToolBar::SS_GOTO:
    messagelabel->setMessage (translate ("go line [column]"), 
       SMessageLabel::SS_INFO);
    command->setText("go ");
    command->setCursorIndex (SCursorIndex(0,10000));
    command->setFocus();
    break;
  case SToolBar::SS_PRINT:
    messagelabel->setMessage (translate ("print -o file -p printer -break"), 
       SMessageLabel::SS_INFO);
    pstr.append ("print ");
    pstr.append (lastprinterOption);
    command->setText(pstr);
    command->setCursorIndex (SCursorIndex(0,10000));
    command->setFocus();
    break; 
  case SToolBar::SS_PRINT_PREVIEW:
    messagelabel->setMessage (translate ("print -e program"), 
       SMessageLabel::SS_INFO);
    pstr.append ("print ");
    pstr.append (lastpreviewOption);
    command->setText(pstr);
    command->setCursorIndex (SCursorIndex(0,10000));
    command->setFocus();
    break; 
  case SToolBar::SS_UNDO:
    if (!editor->undo())
    {
      messagelabel->setMessage (translate ("Nothing to undo."), 
         SMessageLabel::SS_WARN);
      toolbar->setModified (false);
    }
    toolbar->setEmbedding(editor->getDocumentEmbedding(), false);
    break;
  case SToolBar::SS_REDO: 
    if (!editor->redo())
    {
      messagelabel->setMessage (translate ("Nothing to redo."), 
         SMessageLabel::SS_WARN);
    }
    toolbar->setEmbedding(editor->getDocumentEmbedding(), false);
    break;
  case SToolBar::SS_DOCUMENT_EMBEDDING: 
    editor->setDocumentEmbedding (toolbar->currentEmbedding);
    break;
  case SToolBar::SS_SET_OVERRIDE: 
    /* change it back */ 
    dire = editor->changeDirection (toolbar->overrideLR ? SS_DR_LO : SS_DR_RO);
    if (dire)
    {
      messagelabel->setMessage("");
    }
    else 
    {
      /* leave it back */ 
      if (!wasmodified) toolbar->setModified (true);
      messagelabel->setMessage (
        translate ("Direction of selected text has been set."), 
        SMessageLabel::SS_INFO);
    }
    break;
  case SToolBar::SS_YIELD_EMBEDDING: 
    dire = editor->changeDirection  (toolbar->currentLR ? SS_DR_L : SS_DR_R);
    if (dire)
    {
      messagelabel->setMessage("");
    }
    else 
    {
      /* leave it back */ 
      if (!wasmodified) toolbar->setModified (true);
      messagelabel->setMessage (
        translate ("Direction of selected text has been re-set."), 
        SMessageLabel::SS_INFO);
    }
    break;
    
  case SToolBar::SS_SET_EMBEDDING: 
    /* change it back */ 
    dire = editor->changeDirection (toolbar->embedLR ? SS_DR_LE : SS_DR_RE);
    if (dire)
    {
      messagelabel->setMessage("");
    }
    else 
    {
      /* leave it back */ 
      if (!wasmodified) toolbar->setModified (true);
      messagelabel->setMessage (
        translate ("Direction of selected text has been set."), 
        SMessageLabel::SS_INFO);
    }
    break;
  case SToolBar::SS_MAGNIFY_PLUS: 
  case SToolBar::SS_MAGNIFY_MINUS: 
    messagebar->setFontSize(df);
    editor->setFontSize (df);
    if (freehand) freehand->setFontSize (df);
    break;
  case SToolBar::SS_FONT: 
    editor->setFont (currentFont, df);
    if (freehand) freehand->setFont (currentFont, df);
    break;
  case SToolBar::SS_INPUT: 
    if (!accel)
    {
       createKMapDialog ();
       ok = kmapDialog->getInput ("Yudit: KMap Setup",
            toolbar->inputs, toolbar->currentInput);
       if (!ok || kmapDialog->getSelectedKMap() < 0) break;
       toolbar->inputChanged(kmapDialog->getKMapList (), 
          kmapDialog->getSelectedKMap());
       currentInput =  toolbar->inputs[toolbar->currentInput];
       userProps.put ("yudit.editor.inputs", toolbar->inputs.join (","));
       userProps.put ("yudit.editor.input", currentInput);
       saveProperties();
    }
    editor->setInputMethod (currentInput);
    showFreeHand (currentInput=="freehand");
   
    if (currentInput != SS_KINPUT2_IM
       && currentInput != SS_WINDOWS_IM
       && currentInput[0] != 'x' 
       && currentInput[1] != 'X')
    {
      command->setInputMethod (currentInput);
    }
    else
    {
      command->setInputMethod ("straight");
    }
    /* update glyph info */
    caretMoved();
    break;
  case SToolBar::SS_PARAGRAPH_BREAK: 
    editor->setParagraphSeparator (currentParagraphSeparator, true);
    break;
  default:
    break;
  }
}

void
SYudit::buttonLeave (void* src, int which)
{
}

void
SYudit::buttonEnter (void* src, int which)
{
}


/**
 * This is the STextEditLS
 */
void
00735 SYudit::textChanged (void *source)
{
  if (source == editor)
  {
    if (!toolbar->printing) messagelabel->setMessage("");
    toolbar->setModified (true);
    return;
  }
}

void
SYudit::textEntered (void *source)
{
  if (!toolbar->printing) messagelabel->setMessage("");
  if (source != command) return;
  SString text =  command->getText();
  if (text.size()==0)
  {
    editor->setFocus();
    return;
  }
  SStringVector cv;
  cv.smartSplit (text);
  if (cv.size()==2 && cv[0]=="quit" && cv[1] == "-yes")
  {
    exit (0);
  }
  if (cv.size()==1 && cv[0] == "quit")
  {
    if (toolbar->modified)
    {
      messagelabel->setMessage (translate ("Unsaved changes. Enter quits!"), 
         SMessageLabel::SS_ERR);
      command->setText("quit -yes");
      command->setCursorIndex (SCursorIndex(0,10000));
      command->setFocus();
      return;
    }
    if (toolbar->printing)
    {
      messagelabel->setMessage (translate ("Pending printing job. Enter quits!"), 
         SMessageLabel::SS_ERR);
      command->setText("quit -yes");
      command->setCursorIndex (SCursorIndex(0,10000));
      command->setFocus();
      return;
    }
    exit (0);
  }
  command->putHistory(text);
  if (cv.size()>0 && cv[0] == "print")
  {
    print (cv, text);
    return;
  }
  if (cv.size()>0 && (cv[0] == "help" || cv[0] == "test" || 
       helpStrings.get(cv[0]) != 0) 
     || (cv.size() > 1 && cv[0] == "howto"))
  {
    load (cv, text);
    return;
  }
  if (cv.size()>0 && (cv[0] == "open" || cv[0] == "load"))
  {
    load (cv, text);
    return;
  }
  if (cv.size()>0 && (cv[0] == "configure" || cv[0] == "config"))
  {
    load (cv, text);
    return;
  }
  if (cv.size()>0 && (cv[0] == "save" || cv[0] == "save"))
  {
    save (cv, text);
    return;
  }
  if (cv.size()>0 && cv[0] == "go")
  {
    goLineRow (cv, text);
    return;
  }
  if (cv.size()>0 && cv[0] == "find")
  {
    find (cv, text);
    return;
  }
  if (cv.size()>0 && cv[0] == "replace")
  {
    replace (cv, text);
    return;
  }
  if (cv.size() > 0 && cv[0] == "syntax")
  {
    int smode = -1;
    if (cv.size() != 2 || (smode = translateHighlightMode (cv[1])) < 0)
    {
      SString err = translate ("usage: ");
      err.append ("syntax none|simple|simple-dark");
      messagelabel->setMessage (err, SMessageLabel::SS_ERR);
      return;
    }
    editor->setHighlightMode ((STextView::SS_HighlightMode)smode);
    userProps.put ("yudit.editor.syntax", cv[1]);
    editor->setFocus();
    command->putHistory(text);
    return;
  }
  if (cv.size() > 0 && cv[0] == "wordwrap")
  {
    if (cv.size() != 2 || (cv[1] != "true" && cv[1] != "false"))
    {
      SString err = translate ("usage: ");
      err.append ("wordwrap true|false");
      messagelabel->setMessage (err, SMessageLabel::SS_ERR);
      return;
    }
    if (cv[1]=="true")
    {
      editor->setWordWrap (true);
    }
    else
    {
      editor->setWordWrap (false);
    }
    userProps.put ("yudit.editor.wordwrap", cv[1]);
    editor->setFocus();
    command->putHistory(text);
    return;
  }
  SString mess ("syntax error: ");
  mess.append (SS_LB_LRE);
  mess.append ("'");
  mess.append (text);
  mess.append ("'");
  mess.append (SS_LB_PDF);
  messagelabel->setMessage (mess, SMessageLabel::SS_ERR);
  command->clear();
  command->historyEnd();
  //editor->setFocus();
}

void 
SYudit::print (const SStringVector& args, const SString& str)
{
  if (toolbar->printing) return;
  SString executable;
  SString printer;
  SString filename;
  SString hsize("10");
  unsigned int i;
  bool shownl = false;
  bool islpr = false;

  for (i=1; i<args.size(); i++)
  {
    if ((args[i] == "-printer" || args[i] =="-p") && i+1 < args.size())
    {
      i++;
      printer = args[i];
    }
    else if ((args[i] == "-hsize") && i+1 < args.size())
    {
      i++;
      hsize = args[i];
    }
    else if ((args[i] == "-out" || args[i] =="-o") && i+1 < args.size())
    {
      i++;
      filename = completeFileName (args[i]);
    }
    else if (args[i] == "-exec" && i+1 < args.size())
    {
      i++;
      executable = args[i];
      int ind = str.find("-exec");
      if (ind > 0)
      {
        /* strlen ("-exec")*/
        ind += 5;
        while (ind < (int) str.size() 
              && (str[(unsigned int)ind] == ' '
                  || str[(unsigned int)ind] == '\t')) ind++;
        if (ind < (int) str.size())
        {
          executable = SString (&str.array()[(unsigned int)ind], 
             str.size()-(unsigned int)ind);
          i = args.size();
          break;
        }
      }
    }
    else if (args[i] =="-e" && i+1 < args.size())
    {
      /* strlen ("-e")*/
      i++;
      executable = args[i];
      int ind = str.find("-e");
      if (ind > 0)
      {
        ind += 2;
        while (ind < (int) str.size() 
              && (str[(unsigned int)ind] == ' '
                  || str[(unsigned int)ind] == '\t')) ind++;
        if (ind < (int) str.size())
        {
          executable = SString (&str.array()[(unsigned int)ind], 
             str.size()-(unsigned int)ind);
          i = args.size();
          break;
        }
      }
    }
    else if (args[i] == "-break" || args[i] =="-b")
    {
      shownl = true;
    }
    else
    {
      break;
    }
  }
  hsize.append ((char)0);
  double hsized=10.0;
  sscanf (hsize.array(), "%lf", &hsized);
  if (hsized < 2.0) hsized = 1.0;
  if (hsized > 100.0) hsized = 100.0;

  if (filename.size()==0 && executable.size()==0)
  {
     islpr = true;

#ifdef USE_WINAPI
     executable  = originalProperties["yudit.default.preview.command"];
     executable.replaceAll("\\", "/");
     executable.replaceAll("//", "/");
     if (!addMytoolPrefix (&executable)) return;
#else 
     executable = "lpr";
#endif
  }
  if (i<args.size() || (filename.size()!=0 && executable.size()!=0)
     || (filename.size()!=0 && printer.size() > 0))
  {
    messagelabel->setMessage (
      translate ("usage: print [-o file] [-p printer] [-e exec] [-break] [-hsize header-font-size]"), 
      SMessageLabel::SS_ERR);
    return;
  }
  SOutputStream os;
  if (executable.size())
  {
    if (!islpr && !addMytoolPrefix (&executable)) return;
    if (printer.size())
    {
      executable.append (" -P ");
      executable.append (printer);
    }
    //fprintf (stderr, "executable [%*.*s]\n", SSARGS (executable));
    SPipe p(executable);
    os = p.getOutputStream();
    if (!os.isOK())
    {
      SString ems ("Can not execute: ");
      ems.append (SS_LB_LRE);
      ems.append ("'");
      ems.append (executable);
      ems.append ("'");
      ems.append (SS_LB_PDF);
      messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
      return;
    }
  }
  else
  {
    SFile f(filename);
    os = f.getOutputStream();
    if (!os.isOK())
    {
      SString ems ("Can not open: ");
      ems.append (SS_LB_LRE);
      ems.append ("");
      ems.append (filename);
      ems.append ("'");
      ems.append (SS_LB_PDF);
      messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    }
  }
  SWriter writer(os);
  SString fontName = toolbar->fonts[toolbar->currentFont];
  SUniPrint uniPrint(writer, fontName, hsized, fontName, messagebar->fontSize);
  SString text = editor->getText();

  uniPrint.setDocumentEmbedding (toolbar->currentEmbedding);
  uniPrint.setLineEndMark(shownl);
  uniPrint.setWordWrap (editor->getWordWrap());
  toolbar->setPrinting(true);

  command->clear();
  command->historyEnd();
  editor->setFocus();
  messagelabel->setMessage (
     translate ("Printing..."),
      SMessageLabel::SS_NONE);
  if (!uniPrint.print (currentFileName, text, true))
  {
      toolbar->setPrinting (false);
      SString ems ("Printing failed on '");
      ems.append (executable);
      ems.append (filename);
      ems.append ("'");
      messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
      return;
  }
  int pagecount = uniPrint.getPageCount();
  char a[64];
  if (pagecount >= 1)
  {
    SString tr(translate("Printed %d page(s)."));
    tr.append ((char)0);
    sprintf (a, tr.array(), pagecount);
    if (uniPrint.hasNative())
    {
      SString ms ("Bitmap font (Bad Quality). ");
      ms.append (a);
      messagelabel->setMessage (ms, SMessageLabel::SS_WARN);
    }
    else
    {
      SString ms (a);
      messagelabel->setMessage (ms, SMessageLabel::SS_INFO);
    }
  }
  command->clear();
  command->historyEnd();
 
  SString  op;
  for (i=strlen ("print "); i<str.size(); i++)
  {
    op.append ((char)str[i]);
  }
  if (executable.size() && !islpr && args.size() != 1)
  {
    lastpreviewOption = op;
  }
  else
  {
    lastprinterOption = op;
    //fprintf (stderr, "lastprinterOption=[%*.*s] str=[%*.*s]\n", 
     //   SSARGS(lastprinterOption), SSARGS (str));
  }
  toolbar->setPrinting (false);
}

void 
SYudit::load (const SStringVector& args, const SString& str)
{
  caretIndex.put (currentFileName, caretNow);
  SString encode="utf-8";
  bool hasyes = false;
  SString filename;
  unsigned int i;
  SString internal;
  for (i=1; i<args.size(); i++)
  {
    if (args[i] == "-e" && i+1 < args.size())
    {
      i++;
      encode = args[i];
    }
    else if (args[i] =="-yes")
    {
      hasyes = true;
    }
    else if (i+1 == args.size())
    {
      filename = completeFileName(args[i]);
    }
    else
    {
      break;
    }
  }
  if (args[0] =="help" || helpStrings.get (args[0]) != 0)
  {
    internal =  getPrefix();
    internal.append ("/doc/");
    SString lang = getLanguage();
    if (helpStrings.get (args[0]) != 0) 
    {
      lang = helpStrings[args[0]];
    }
    if (lang.size())
    {
      SString nd = internal;
      nd.append (lang);
      nd.append ("/");
      nd.append ("FAQ.TXT");
      SFile file (nd);
      if (file.size() > 0)
      {
        internal.append (lang);
        internal.append ("/");
      }
    }
    
    internal.append ("FAQ.TXT");
    i = args.size();
    encode = "utf-8";
    filename = internal;
  }

  if (args[0] =="howto" && args.size() >1)
  {
    internal =  getPrefix();
    internal.append ("/doc/");
    SString lang = getLanguage();
    if (helpStrings.get (args[0]) != 0) 
    {
      lang = helpStrings[args[0]];
    }
    if (lang.size())
    {
      SString nd = internal;
      nd.append (lang);
      nd.append ("/");
      nd.append ("HOWTO-");
      nd.append (args[1]);
      nd.append (".txt");
      SFile file (nd);
      if (file.size() > 0)
      {
        internal.append (lang);
        internal.append ("/");
      }
    }
    internal.append ("HOWTO-");
    internal.append (args[1]);
    internal.append (".txt");
    i = args.size();
    encode = "utf-8";
    filename = internal;
  }

  if (args[0] =="test")
  {
    internal =  getPrefix();
    internal.append ("/doc/");
    internal.append ("TestPage.txt");
    i = args.size();
    encode = "utf-8";
    filename = internal;
  }
  if (args[0] =="configure" || args[0] =="config")
  {
    SString afile = currentFileName;
    currentFileName = "/dev/null";
    /* trick to save properties */
    saveProperties();
    currentFileName = afile;
    SString internal = getHome();;
    internal.append ("/.yudit/yudit.properties");
    i = args.size();
    encode = "utf-8";
    filename = internal;
  }

  if (filename.size()==0)
  {
    if (i<args.size())
    {
      messagelabel->setMessage (translate ("usage: open -e utf-8 -yes filename"), 
          SMessageLabel::SS_ERR);
      return;
    }
    filename = currentFileName;
  }
  if (!hasyes && toolbar->modified)
  {
    messagelabel->setMessage (translate ("Unsaved changes. Try -yes option"),
       SMessageLabel::SS_ERR);
    return;
  }
  if (!hasyes && toolbar->printing)
  {
    messagelabel->setMessage (translate ("Pending printing job. Try -yes option"),
       SMessageLabel::SS_ERR);
    return;
  }

  SEncoder utf8("utf-8-s"); 
  SEncoder enc(encode);
  if (!enc.isOK())
  {
    SString ems = translate ("Unknown encoding: ");
    
    ems.append (SS_LB_LRE);
    ems.append ("'"); 
    ems.append (encode); 
    ems.append ("'");
    ems.append (SS_LB_PDF);

    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
  SFile f(filename);
  SFileImage im = f.getFileImage();
  if (f.size()<0 || im.size()<0 || im.array()==0)
  {
    if (hasyes)
    {
      lastencoding = encode;
      command->clear();
      currentFileName = filename;
      toolbar->setFileName(currentFileName, lastencoding);
      editor->clear();
      editor->setFocus();
      toolbar->setModified(false);
    }
    SString ems = translate ("Can not read: ");
    ems.append (SS_LB_LRE);
    ems.append ("'"); 
    ems.append (filename); 
    ems.append ("'");
    ems.append (SS_LB_PDF);
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
  
  SString text (im.array(), f.size());
//fprintf (stderr, "BOTTLE\n");
  SV_UCS4 ucs4 = enc.decode (text);
//fprintf (stderr, "BOTTLE - END\n");
  bool sft = false;
#ifdef USE_WINAPI
  SToolBar::SFormatIndex ft=SToolBar::SS_FORMAT_DOS;
#else 
  SToolBar::SFormatIndex ft=SToolBar::SS_FORMAT_UNIX;
#endif
  bool hadlinebreak = false;
  if (ucs4.size() 
    || ucs4[ucs4.size()-1] == (SS_UCS4) '\r' 
    || ucs4[ucs4.size()-1] == (SS_UCS4) '\n' 
    || ucs4[ucs4.size()-1] == (SS_UCS4) 0x2029) 
  { 
    switch (ucs4[ucs4.size()-1])
    {
    case '\n': 
      ft =  (ucs4.size()>1 && ucs4[ucs4.size()-2]=='\r')
         ? SToolBar::SS_FORMAT_DOS : SToolBar::SS_FORMAT_UNIX; 
      hadlinebreak = true;
      break;
    case '\r': ft = SToolBar::SS_FORMAT_MAC; 
      hadlinebreak = true;
      break;
    case 0x2029: ft = SToolBar::SS_FORMAT_PS;
      hadlinebreak = true;
      break;
    }
  }
  else
  {
    ft = SToolBar::SS_FORMAT_UNIX;
  }
  sft = (toolbar->currentParagraphSeparator != (unsigned int) ft);
  text = utf8.encode (ucs4);
  editor->clear();
  editor->setText(text);
  editor->setCursorIndex(SCursorIndex(0,0));

  SString ems = translate ("Opened: ");
  ems.append (SS_LB_LRE);
  ems.append ("'"); 
  ems.append (filename); 
  ems.append ("'");
  ems.append (SS_LB_PDF);
  ems.append (".");
  if (sft)
  {
    ems.append (translate (" Line Break:"));
    ems.append (translate (toolbar->paragraphBreakStrings[ft]));
  }
  if (!hadlinebreak)
  {
    ems.append (translate(" Incomplete Last Line..."));
  }

  if (sft)
  {
    toolbar->setParagraphSeparator ((int) ft, false);
    SString currentParagraphSeparator = 
         toolbar->paragraphBreaks[toolbar->currentParagraphSeparator];
    editor->setParagraphSeparator (currentParagraphSeparator, false);
  }
  
  toolbar->setModified (false);
  editor->setFocus();

  /*FIXME: load and set currentFileName */
  lastencoding = encode;
  command->clear();
  currentFileName = filename;
  toolbar->setFileName(currentFileName, lastencoding);
  messagelabel->setMessage (ems, 
       sft ?  SMessageLabel::SS_WARN : SMessageLabel::SS_INFO);
  const STextIndex* sindex = caretIndex.get (filename);
  if (sindex)
  {
    editor->setCursorIndex(SCursorIndex(sindex->line, sindex->index));
  }
  editor->setFocus();
}

void 
SYudit::save (const SStringVector& args, const SString& str)
{
  SString encode="utf-8";
  SString filename;
  unsigned int i;
  bool hasyes = false;
  for (i=1; i<args.size(); i++)
  {
    if (args[i] == "-e" && i+1 < args.size())
    {
      i++;
      encode = args[i];
    }
    else if (i+1 == args.size())
    {
      filename = completeFileName (args[i]);
    }
    else if (args[i] =="-yes")
    {
      hasyes = true;
    }
    else
    {
      break;
    }
  }
  if (filename.size()==0)
  {
    if (i<args.size())
    {
      messagelabel->setMessage (translate ("usage: save -e utf-8 -yes filename"), 
          SMessageLabel::SS_ERR);
      return;
    }
    filename = completeFileName (currentFileName);
  }

  if (!hasyes && newFileExists (filename))
  {
    SString ems = translate ("File exists. Use -yes option.");
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }

  SEncoder utf8("utf-8-s"); 
  SEncoder enc(encode);
  if (!enc.isOK())
  {
    SString ems = translate ("Unknown encoding: ");
    ems.append (SS_LB_LRE);
    ems.append ("'"); 
    ems.append (encode); 
    ems.append ("'");
    ems.append (SS_LB_PDF);
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
  SFile f(filename);
  SOutputStream os = f.getOutputStream();  
  if (!os.isOK())
  {
    SString ems = translate ("Can not write: ");
    ems.append (SS_LB_LRE);
    ems.append ("'"); 
    ems.append (filename); 
    ems.append ("'");
    ems.append (SS_LB_PDF);
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
  SWriter writer(os);
  SString text = editor->getText();
  SV_UCS4 ucs4 = utf8.decode (text);
  bool completed = false;
  if (ucs4.size() 
    && ucs4[ucs4.size()-1] != (SS_UCS4) '\r' 
    && ucs4[ucs4.size()-1] != (SS_UCS4) '\n' 
    && ucs4[ucs4.size()-1] != (SS_UCS4) 0x2029)
  { 
    completed = true;
  }
  text = enc.encode (ucs4);
  if ((text.size() > 0 && !writer.write (text)) || !writer.close())
  {
    SString ems = translate ("Error while writing: ");
    ems.append (SS_LB_LRE);
    ems.append ("'"); 
    ems.append (filename); 
    ems.append ("'");
    ems.append (SS_LB_PDF);
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
  lastencoding = encode;
  currentFileName = filename;
  toolbar->setFileName(currentFileName, lastencoding);
  command->clear();
  command->historyEnd();

  SString ems = translate ("Wrote: ");
  ems.append (SS_LB_LRE);
  ems.append ("'"); 
  ems.append (filename); 
  ems.append ("'");
  ems.append (SS_LB_PDF);
  ems.append (".");
  if (completed) ems.append (translate(" Incomplete Last Line..."));
  messagelabel->setMessage (ems, 
         (completed) ? SMessageLabel::SS_WARN : SMessageLabel::SS_INFO);
  toolbar->setModified (false);
  editor->setFocus();
  caretIndex.put (currentFileName, caretNow);
}

/**
 * move the cursor
 */
void
01467 SYudit::goLineRow (const SStringVector& args, const SString& str)
{
  if (args.size () < 2 || args.size() > 3) 
  {
    SString ems = translate ("usage: go line [column] ");
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
  SString l=args[1];
  SString c;
  if (args.size()==3) c=args[2];
  l.append ((char)0);
  c.append ((char)0);
  int li=0;
  int ci=0;
  sscanf (l.array(), "%d", &li);
  sscanf (c.array(), "%d", &ci);
  if (li <= 0)
  {
    editor->setCursorIndex(SCursorIndex(0, 0, true));
  }
  else if (ci <= 0)
  {
    editor->setCursorIndex(SCursorIndex((unsigned int)(li-1), 0, true));
  }
  else
  {
    editor->setCursorIndex(SCursorIndex((unsigned int)(li-1),
       (unsigned int) (ci-1), false));
  }
}

/**
 * find text
 */
void
01503 SYudit::find (const SStringVector& args, const SString& str)
{
  if (args.size () != 2) 
  {
    SString ems = translate ("usage: find text");
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
  if (!editor->find (args[1]))
  {
    SString ems = translate ("search string not found.");
    ems.append (SS_LB_LRE);
    ems.append ("'");
    ems.append (args[1]);
    ems.append ("'");
    ems.append (SS_LB_PDF);
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
}

/**
 * replace text
 */
void
01528 SYudit::replace (const SStringVector& args, const SString& str)
{
  if (args.size () != 3 || args[1].size()==0) 
  {
    SString ems = translate ("usage: replace original new");
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
    return;
  }
  if (!editor->replace (args[1], args[2]))
  {
    SString ems = translate ("search string not found.");
    ems.append (SS_LB_LRE);
    ems.append ("'");
    ems.append (args[1]);
    ems.append ("'");
    ems.append (SS_LB_PDF);
    messagelabel->setMessage (ems, SMessageLabel::SS_ERR);
  }
  return;
}

void
SYudit::focusOutRequest (void *source)
{
  if (source == editor)
  {
    command->setFocus();
  }
  else
  {
    editor->setFocus();
  }
}
void
SYudit::focusChanged (void *source, bool in)
{
}
void
SYudit::caretMoved (void *source, 
   unsigned int _line, unsigned int _column, bool _before)
{
  if (source != editor) return;
  caretMoved();
}

void 
SYudit::caretMoved ()
{
  STextIndex ti = editor->getCaretArrowFrom ();

  if (ti.line != caretNow.line) messagebar->setRow(ti.line+1);
  if (ti.index != caretNow.index) messagebar->setColumn (ti.index);

  if ((caretNow.line != ti.line || caretNow.index != ti.index) 
      && !toolbar->printing)
  {
    messagelabel->setMessage("");
  }
  caretNow = ti;
  
  toolbar->directionChanged (editor->isEmbedStateLR());

  if (ti.index == 0)
  {
    messagebar->setGlyphInfo (0, SString());
  }
  else
  {
    STextIndex tn (ti.line, ti.index-1);
    const SGlyph* g = editor->glyphAt(tn);
    SV_UCS4 chars;
    if (g!=0)
    {
      chars = g->getChars();
    }
    messagebar->setGlyphInfo (g, editor->encode (chars));
  }
}

/**
 * compose an escaped  file name.
 */
SString
01611 SYudit::composeFileNameCommand (const SString& prefix, 
        const SString &encoding, const SString& file)
{
  SString ret (prefix);
  ret.append ("-e ");
  ret.append (encoding);
  ret.append (" ");
  ret.append (quoteFileName (file));
  return SString(ret);
}

SString
SYudit::quoteFileName (const SString& file)
{
  SString ret;
  if (file.find(" ") < 0)
  {
    ret.append (file);
  }
  else if (file.find ("\"") < 0)
  {
    ret.append ("\"");
    ret.append (file);
    ret.append ("\"");
  }
  else
  {
    ret.append ("\'");
    ret.append (file);
    ret.append ("\'");
  }
  return SString(ret);
}

SString
SYudit::completeFileName(const SString& _file)
{
  /* home directory substitution ~/ */
  SString file(_file);
  if (file.size() > 2 && file[0] == '~' && file[1]=='/')
  {
    file.remove (0, 2);
    SString homedir = getHome();
    homedir.append ("/");
    file.insert (0, homedir);
  }
  return SString(file);
}

/**
 * return false if it is not a new file or the file does not exist.
 */
bool
01664 SYudit::newFileExists (const SString& filename)
{
  if (filename == currentFileName) return false;
  SFile f (filename);
  if (f.size() <0) return false;
  return true;
}

void
SYudit::saveProperties ()
{
  /* do not save proeprties if it is being edited */
  SString cfile = getHome();;
  cfile.append ("/.yudit/yudit.properties");
  if (currentFileName == cfile) return;

  //userProps.put ("yudit.default.printer", lastprinterOption);
  //userProps.put ("yudit.default.previewer", lastpreviewOption);

  SString s;
  s = toolbar->fonts[toolbar->currentFont];
  userProps.put ("yudit.editor.font", s);
  s = toolbar->inputs[toolbar->currentInput];
  userProps.put ("yudit.editor.input", s);
  s = toolbar->fontsizes[toolbar->currentFontSize];
  userProps.put ("yudit.editor.fontsize", s);
  if (freehand)
  {
    SString s = freehand->getConverter();
    if (s.size())
    {
      userProps.put ("yudit.freehand.converter", s);
    }
  }

  /* create a property file that has the original properties and 
   * the ones that I changed.
   */
  /* create a property list that has changes since last save */
  SProperties changes;
  for (unsigned int i=0; i<userProps.size(); i++)
  {
    for (unsigned int j=0; j<userProps.size(i); j++)
    {
      if (userProps.get(i, j) ==0) continue;
      const SString& key = userProps.key(i, j);
      const SString& vle = *userProps.get(i, j);
      if (originalProperties.get (key) == 0)
      {
         changes.put (key, vle);
      }
      else  if (vle != originalProperties[key])
      {
         changes.put (key, vle);
      }
    }
  }
  SProperties full = originalProperties;
  SProperties current;
  ::loadProperties (configFile, &current);
  /* just save back everything - change in yudit 2.5 */
  full.merge (current);
  /* merge in changes */
  full.merge (changes); 

  /* That stupid old properties header comment. */
  const SString *pstr = full.get ("yudit.background.#");
  /* compatibility. remove this. */
  if (pstr!=0)
  { 
    /* Test it */
    if (pstr->find ("#   Autosave will eliminate all comments and '\\' (line joiner) characters.") > 0)
    {
      SString a;
      a.append ("# From version 2.7.6 Yudit preserves comment lines\n");
      a.append ("# that start with a '#' and preceed the property  \n");
      a.append ("# line they refer to. ");
      full.put ("yudit.background.#", a);
    }
  }

  if (!::saveProperties (configFile, full))
  {
    SString str = translate ("Could not save preferences");
    str.append (" ");
    str.append (configFile);
    messagelabel->setMessage (str, SMessageLabel::SS_ERR);
    fprintf (stderr, "Could not save properties into %*.*s.\n",
       SSARGS(configFile));
  }
}

bool
SYudit::dropped (void* p, const SString& mimetype, const SString& data)
{
  if (textDialog != 0 && textDialog->isShown()) return false;
  //fprintf (stderr, "SYudit::dropped %*.*s [%*.*s]\n", SSARGS(mimetype), SSARGS(data));
  SStringVector v (data, "\r\n");
  SString file=v[0];
  if (mimetype == "text/uri-list")
  {
    if (file.size() < strlen ("file:") 
       || strncmp (file.array(), "file:", strlen ("file:"))!=0)
    {
      SString msg = translate ("unsupported text/uri: ");
      msg.append (SS_LB_LRE);
      msg.append ("'");
      msg.append (file);
      msg.append ("'");
      msg.append (SS_LB_PDF);
      messagelabel->setMessage (msg, SMessageLabel::SS_ERR);
      return false;
    }
    file.remove (0, strlen ("file:"));
  }
  if (fileDialog != 0 && fileDialog->isShown())
  {
     fileDialog->center();
     fileDialog->setFileName (file);
     return true;
  }
  SString cm ("open -e ");;
  cm.append (lastencoding);
  cm.append (" ");
  if (toolbar->modified)
  {
    messagelabel->setMessage (translate ("Unsaved changes. Enter discards!"), SMessageLabel::SS_ERR);
    cm.append ("-yes ");
    cm.append (file);
    command->setText(cm);
    command->setCursorIndex (SCursorIndex(0,10000));
    command->setFocus();
  }
  else
  {
    messagelabel->setMessage (translate ("open -yes -e encoding file"), 
       SMessageLabel::SS_INFO);
    cm.append (file);
    command->setText(cm);
    command->setCursorIndex (SCursorIndex(0,10000));
    command->putHistory(cm);
    SStringVector cv; cv.smartSplit (cm);
    load (cv, cm);
  }
  return true;
}

void
SYudit::createFileDialog () // If needed
{
  if (fileDialog) return;

  fileDialog = new SFileDialog();
  fileDialog->setModal (this);
  fileDialog->setBackground (originalProperties["yudit.background"]);
  fileDialog->setLabelForeground (originalProperties["yudit.label.foreground"]);
  fileDialog->setTitleForeground (originalProperties["yudit.title.foreground"]);
  fileDialog->setSliderBackground (originalProperties["yudit.slider.background"]);

  SStringVector enc;
  if (originalProperties.get("yudit.editor.filetypes"))
  {
    //SString s = originalProperties["yudit.editor.filetypes"];
    //fprintf (stderr, "Specified filetypes: %*.*s\n", SSARGS (s));
    enc.append (SStringVector (originalProperties["yudit.editor.filetypes"]));
  }
  SBinHashtable<bool> ph;
  unsigned int ic=0;

  for (ic=0; ic<enc.size(); ic++)
  {
    ph.put (enc[ic], true);
  }
  SStringVector benc = SEncoder::builtin();
  
  unsigned int ib=0;
  for (ib=0; ib<benc.size(); ib++)
  {
    /* this is an input method and it is misleading. */
    if (benc[ib] == "unicode") continue;
    ph.put (benc[ib], true);
  }
  SStringVector bext = SEncoder::external();
  
  for (ib=0; ib<bext.size(); ib++)
  {
    /* this is an input method and it is misleading. */
    if (bext[ib].match("iso-8859*"))
    {
      ph.put (bext[ib], true);
    }
    if (bext[ib].match("mik"))
    {
      ph.put (bext[ib], true);
    }
    else if (bext[ib] == "viscii")
    {
      ph.put (bext[ib], true);
    }
    else if (bext[ib] == "wingreek")
    {
      ph.put (bext[ib], true);
    }
    else if (bext[ib] == "tcvn")
    {
      ph.put (bext[ib], true);
    }
    else if (bext[ib].match("koi8-*"))
    {
      ph.put (bext[ib], true);
    }
    else if (bext[ib] == "rovas")
    {
      ph.put (bext[ib], true);
    }
    else if (bext[ib] == "cp-1251")
    {
      ph.put (bext[ib], true);
    }
    else if (bext[ib] == "cp-1250")
    {
      ph.put (bext[ib], true);
    }
  }
 
  SStringVector addEnc;
  for (ic=0; ic<ph.size(); ic++)
  {
    for (ib=0; ib<ph.size(ic); ib++)
    {
       bool vle = ph.get (ic, ib);
       if (vle)
       {
         addEnc.append (ph.key (ic, ib));
       }
    }
  }
  /* set the filetypes */
  SString font = originalProperties["yudit.default.font"];
  SString fontSizeString=originalProperties["yudit.default.fontsize"];

  double fontSize=0;
  fontSizeString.append ((char)0);
  sscanf (fontSizeString.array(), "%lf", &fontSize);
  if (fontSize < 2.0) fontSize = 2.0;
  fileDialog->setFont (font, fontSize);
  fileDialog->setFileTypes (addEnc);
}

void
SYudit::createKMapDialog ()
{
  if (kmapDialog) return;
  kmapDialog = new SKMapDialog ();
  kmapDialog->setModal (this);
  kmapDialog->setXInputs (originalProperties["yudit.editor.xinputs"]);
  kmapDialog->setBackground (originalProperties["yudit.background"]);
  kmapDialog->setLabelForeground (originalProperties["yudit.label.foreground"]);
  kmapDialog->setTitleForeground (originalProperties["yudit.title.foreground"]);
  kmapDialog->setSliderBackground (originalProperties["yudit.slider.background"]);
  /* set the filetypes */
  SString font = originalProperties["yudit.default.font"];
  SString fontSizeString=originalProperties["yudit.default.fontsize"];

  double fontSize=0;
  fontSizeString.append ((char)0);
  sscanf (fontSizeString.array(), "%lf", &fontSize);
  if (fontSize < 2.0) fontSize = 2.0;
  kmapDialog->setFont (font, fontSize);
  /* button size bug workaround */
  SDimension dim = kmapDialog->getPreferredSize();
  kmapDialog->resize(SDimension(dim.width+2, dim.height+2));
}

void
SYudit::createTextDialog ()
{
  if (textDialog) return;

  textDialog = new STextDialog();
  textDialog->setModal (this);

  textDialog->setBackground (originalProperties["yudit.background"]);
  textDialog->setLabelForeground (originalProperties["yudit.label.foreground"]);
  textDialog->setTitleForeground (originalProperties["yudit.title.foreground"]);

  SString font = originalProperties["yudit.default.font"];
  SString fontSizeString=originalProperties["yudit.default.fontsize"];

  double fontSize=0;
  fontSizeString.append ((char)0);
  sscanf (fontSizeString.array(), "%lf", &fontSize);
  if (fontSize < 2.0) fontSize = 2.0;

  textDialog->setFont (font, fontSize);
}

/*
 * SFreeHandListener
 * FIXME:
 */
void
SYudit::freeHandTextChanged (void* source, const SString& lookup)
{
  if (lookup.size()==0) return;
  if (editor->isFocused ())
  {
    editor->insertEditorText (lookup);
  }
  else if (command->isFocused())
  {
    command->insertEditorText (lookup);
  }
}

void
printl (const SLayout lo)
{
  SLocation l = lo.getLocation();
  SDimension d = lo.getDimension();
  fprintf (stderr, "l= (%d,%d) d= (%u,%u)          l2 =(%d,%d)\n",
    l.x, l.y, d.width, d.height, l.x + (int) d.width, l.y + d.height);
}


void
SYudit::showFreeHand(bool is)
{
  if (!(is ^ freeHandShown)) return;
  /* need to create */
  bool newhand = (freehand==0);
  freeHandShown = is;
  if (freehand==0)
  {
    freehand = new SFreeHand ();
    freehand->setBackground (originalProperties["yudit.background"]);
    freehand->setLabelForeground (originalProperties["yudit.label.foreground"]);
    freehand->setForeground (originalProperties["yudit.title.foreground"]);
    freehand->setDrawingForeground (SColor("green"), SColor("yellow"));
    freehand->setDrawingBackground (SColor("black"));
    freehand->setConverter (originalProperties["yudit.freehand.converter"]);

    freehand->setSliderBackground (
         originalProperties["yudit.slider.background"]);
    freehand->setFreeHandListener (this);
    SString font = originalProperties["yudit.default.font"];
    SString fontSize=originalProperties["yudit.default.fontsize"];

    double df=0;
    fontSize.append ((char)0);
    sscanf (fontSize.array(), "%lf", &df);
    if (fontSize < 2.0) df = 2.0;
    freehand->setButtonFont (font, df);

    font = toolbar->fonts[toolbar->currentFont];
    fontSize = toolbar->fontsizes[toolbar->currentFontSize];
    fontSize.append ((char)0);

    if (sscanf (fontSize.array(), "%lf", &df)==0 || df < 2.0) df = 2.0;
    freehand->setFont (font, df);
    freeHandHeight = freehand->getPreferredSize().height;
  }

  SLocation l = editorLayout.getLocation ();
  SDimension d = editorLayout.getDimension ();
  SLocation sl = sliderLayout.getLocation(); 
  SDimension sd = sliderLayout.getDimension(); 
  int hp = l.y + (int) d.height -(int)freeHandHeight;

  if (is)
  {
    editor->setLayout (
      SLayout ( 
       SLocation (l.x, l.y),
       SLocation (l.x+(int) d.width, hp),
        SLocation (0, 0),
        SLocation (100, 100)
      )
    );
    slider->setLayout (SLayout (
      SLocation (sl.x, sl.y),
      SLocation (sl.x+(int)sd.width, hp),
      SLocation (100, 0),
      SLocation (100, 100)
    ));

    freehand->setLayout (
      SLayout (
        SLocation (l.x, hp), 
        SLocation (sl.x + (int) sd.width, 
           hp+(int)freeHandHeight),
        SLocation (0, 100),
        SLocation (100, 100)
      )
    );
    SLocation ml = freehand->getLayout().getLocation (layout, getSize());
    SDimension md = freehand->getLayout().getDimension (layout, getSize());
  }
  else 
  {
    editor->setLayout (editorLayout);
    slider->setLayout (sliderLayout);
    /* move it away */
    freehand->setLayout (
      SLayout (
        SLocation (l.x, -(int)hp -(int)freeHandHeight-1), 
        SLocation (sl.x + (int) sd.width, -1),
        SLocation (0, 0),
        SLocation (0, 0)
      )
    );
  }
  if (newhand)
  {
    add (freehand);
    editor->setFocus();
  }
  _resized ();
}

/**
 * Try to prefix executable with mytool -pipecmd.
 * @return false if mytool not found.
 */
bool
02089 SYudit::addMytoolPrefix (SString* executable)
{
  if (executable->size()==0) return false;
#ifdef USE_WINAPI
  SString pr = getPrefix();
  pr.append ("/bin/mytool.exe");
  SFile f (pr);
  if (f.size () <= 0) 
  {
    SString message=translate ("Command not found: ");
    message.append (SS_LB_RLE);
    message.append ("'");
    message.append (pr);
    message.append ("'");
    message.append (SS_LB_PDF);
    messagelabel->setMessage (message, SMessageLabel::SS_ERR);
    return false;
  }
#else
  SString pr = getPrefix();
  pr.append ("/bin/mytool");
  SFile f0 (pr);
  if (f0.size () <= 0) 
  {
    pr = getPrefix();
    SStringVector pv(pr, "/");
    if (pv.size() > 1)
    {
      pv.truncate (pv.size()-2);
    }
    pr = pv.join ("/");
    pr.insert (0, "/");
    pr.append ("/bin/mytool");
    SFile f0 (pr);
    if (f0.size () <= 0) 
    {
      SString message=translate ("Command not found: ");
      message.append (SS_LB_LRE);
      message.append ("'");
      message.append (pr);
      message.append ("'");
      message.append (SS_LB_PDF);
      messagelabel->setMessage (message, SMessageLabel::SS_ERR);
      return false;
    }
  }
#endif
  SStringVector v;
  v.smartSplit (*executable);
  if (!commandExists (v[0]))
  {
    SString message=translate ("Command not found: ");
    message.append (SS_LB_LRE);
    message.append ("'");
    message.append (v[0]);
    message.append ("'");
    message.append (SS_LB_PDF);
    messagelabel->setMessage (message, SMessageLabel::SS_ERR);
    return false;
  }
  pr.insert (0, "\"");
  pr.append ("\"");
  pr.append (" -pipecmd ");
  executable->insert (0, pr);
  return true;
}

/**
 * Translate our string highlight mode to an integer
 * @return -1 if it can not be translated.
 */
static int 
translateHighlightMode (const SString& hl)
{
  if (hl == "none")
  {
    return (int) STextView::HM_None;
  }
  else if (hl == "simple")
  {
    return (int) STextView::HM_Simple;
  }
  else if (hl == "simple-dark")
  {
    return (int) STextView::HM_SimpleDark;
  }
  else if (hl == "html")
  {
    return (int) STextView::HM_HTML;
  }
  return -1;
}

Generated by  Doxygen 1.6.0   Back to index