/*==============================================================================
 RichEditor Demo
  Menu items disabling/enabling is not implemented here.

  The main idea: new styles are created and added to rvs->TextStyles when needed.
  The right place for this - rve->OnStyleConversion.
  rvfoSaveTextStyles, rvfoSaveParaStyles are included in rve->RVFOptions.
==============================================================================*/
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "RichView"
#pragma link "RVEdit"
#pragma link "RVScroll"
#pragma link "RVStyle"
#pragma link "SVFontCombos"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
// Parameters for ApplyStyleConversion
#define DEMO_MAKEBOLD       1
#define DEMO_MAKEITALIC     2
#define DEMO_MAKEUNDERLINE  3
#define DEMO_APPLYFONTNAME  4
#define DEMO_APPLYFONT      5
#define DEMO_CLEARBOLD      6
#define DEMO_CLEARITALIC    7
#define DEMO_CLEARUNDERLINE 8
#define DEMO_APPLYFONTSIZE  9
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  // Filling text styles combobox
  cmbTextStyles->Items->Assign(rvs->TextStyles);
  // Filling font names combobox
  cmbFont->Items->Assign(Screen->Fonts);
  New();
}
//---------------------------------------------------------------------------
bool TForm1::SaveIfNeeded()
{
  if (Modified)
    switch (Application->MessageBox("Save file now?","File was modified",
                                MB_ICONQUESTION | MB_YESNOCANCEL))
    {
      case IDYES:
        return Save();
      case IDNO:
        return true;
      default: //case IDCANCEL:
        return false;
    }
  else
    return true;
}
//---------------------------------------------------------------------------
bool TForm1::Save()
{
  if (FileName=="")
    return SaveAs();
  else
  {
    rve->SaveRVF(FileName, false);
    Modified = false;
    StatusBar1->Panels->Items[0]->Text = "";
    return true;
  }
}
//---------------------------------------------------------------------------
bool TForm1::SaveAs()
{
  if (sd->Execute())
  {
    FileName = sd->FileName;
    bool r = Save();
    if (r)
      Caption = ExtractFileName(FileName) + "- RDemo";
    return r;
  }
  else
    return false;
}
//---------------------------------------------------------------------------
void TForm1::Open()
{
  if (!SaveIfNeeded())
    return;
  if (od->Execute())
  {
    FileName = od->FileName;
    rve->LoadRVF(FileName);
    rve->Format();
    rveCurTextStyleChanged(NULL);
    rveCurParaStyleChanged(NULL);
    Modified = false;
    StatusBar1->Panels->Items[0]->Text = "";
    Caption = ExtractFileName(FileName) + "- RDemo";
  }
}
//---------------------------------------------------------------------------
void TForm1::New()
{
  if (!SaveIfNeeded())
    return;
  FileName = "";
  Modified = false;
  StatusBar1->Panels->Items[0]->Text = "";
  Caption = "Unnamed - RDemo";
  rve->Clear();
  rve->Format();
  rve->DeleteUnusedStyles(true,true);
  rveCurTextStyleChanged(NULL);
  rveCurParaStyleChanged(NULL);
}
//---------------------------------------------------------------------------
void TForm1::UpdateFontButtons()
{
  btnBold->Down      = mitBold->Checked;
  btnItalic->Down    = mitItalic->Checked;
  btnUnderline->Down = mitUnderline->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitNewClick(TObject *Sender)
{
  New();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitOpenClick(TObject *Sender)
{
  Open();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitSaveClick(TObject *Sender)
{
  Save();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitSaveAsClick(TObject *Sender)
{
  SaveAs();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitExitClick(TObject *Sender)
{
  Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  CanClose = SaveIfNeeded();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitUndoClick(TObject *Sender)
{
  rve->Undo();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitRedoClick(TObject *Sender)
{
  rve->Redo();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitCutClick(TObject *Sender)
{
  rve->CutDef();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitCopyClick(TObject *Sender)
{
  rve->CopyDef();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitPasteClick(TObject *Sender)
{
  rve->Paste();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitDeleteClick(TObject *Sender)
{
  rve->DeleteSelection();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitBoldClick(TObject *Sender)
{
  mitBold->Checked = ! mitBold->Checked;
  if (mitBold->Checked)
    rve->ApplyStyleConversion(DEMO_MAKEBOLD);
  else
    rve->ApplyStyleConversion(DEMO_CLEARBOLD);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitItalicClick(TObject *Sender)
{
  mitItalic->Checked = ! mitItalic->Checked;
  if (mitItalic->Checked)
    rve->ApplyStyleConversion(DEMO_MAKEITALIC);
  else
    rve->ApplyStyleConversion(DEMO_CLEARITALIC);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitUnderlineClick(TObject *Sender)
{
  mitUnderline->Checked = ! mitUnderline->Checked;
  if (mitUnderline->Checked)
    rve->ApplyStyleConversion(DEMO_MAKEUNDERLINE);
  else
    rve->ApplyStyleConversion(DEMO_CLEARUNDERLINE);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::mitFontClick(TObject *Sender)
{
  fd->Font->Assign(rvs->TextStyles->Items[rve->CurTextStyleNo]);
  if (fd->Execute())
    rve->ApplyStyleConversion(DEMO_APPLYFONT);
}
//---------------------------------------------------------------------------
// data in editor were changed
void __fastcall TForm1::rveChange(TObject *Sender)
{
  Modified = true;
  StatusBar1->Panels->Items[0]->Text = "Modified";
}
//---------------------------------------------------------------------------
// current text style was changed
void __fastcall TForm1::rveCurTextStyleChanged(TObject *Sender)
{
  IgnoreChanges = true;
  StatusBar1->Panels->Items[1]->Text = "Style : "+IntToStr(rve->CurTextStyleNo);
  // Changing selection on combobox with styles:
  if (rve->CurTextStyleNo<cmbTextStyles->Items->Count)
    cmbTextStyles->ItemIndex = rve->CurTextStyleNo;
  else
    cmbTextStyles->ItemIndex = -1;
  // Changing selection in combobox with font names:
  TFontInfo* fi = rvs->TextStyles->Items[rve->CurTextStyleNo];
  cmbFont->ItemIndex = cmbFont->Items->IndexOf(fi->FontName);
  // Changing combobox with font sizes:
  cmbFont->OnClick(NULL);
  cmbFontSize->Text = IntToStr(fi->Size);
  // Checking font buttons and menu
  mitBold->Checked      = fi->Style.Contains(fsBold);
  mitItalic->Checked    = fi->Style.Contains(fsItalic);
  mitUnderline->Checked = fi->Style.Contains(fsUnderline);
  UpdateFontButtons();
  IgnoreChanges = false;
}
//---------------------------------------------------------------------------
// current paragraph style was changed
void __fastcall TForm1::rveCurParaStyleChanged(TObject *Sender)
{
  switch (rve->CurParaStyleNo)
  {
    case 0:
      btnLeft->Down = true;
      break;
    case 1:
      btnCenter->Down = true;
      break;
    case 2:
      btnRight->Down = true;
      break;
    case 3:
      btnJustify->Down = true;
      break;
  }
}
//---------------------------------------------------------------------------
// applying standard text style
void __fastcall TForm1::cmbTextStylesClick(TObject *Sender)
{
  if (!IgnoreChanges && cmbTextStyles->ItemIndex!=-1)
    rve->ApplyTextStyle(cmbTextStyles->ItemIndex);
  if (Visible)
    rve->SetFocus();
}
//---------------------------------------------------------------------------
// applying font name
void __fastcall TForm1::cmbFontClick(TObject *Sender)
{
  if (cmbFont->ItemIndex!=-1)
  {
    cmbFontSize->FontName = cmbFont->Items->Strings[cmbFont->ItemIndex];
    if (!IgnoreChanges)
    {
      FontName = cmbFont->Items->Strings[cmbFont->ItemIndex];
      rve->ApplyStyleConversion(DEMO_APPLYFONTNAME);
    }
  };
  if (Visible)
    rve->SetFocus();
}
//---------------------------------------------------------------------------
// applying font size
void __fastcall TForm1::cmbFontSizeClick(TObject *Sender)
{
  if (cmbFontSize->Text!="" && !IgnoreChanges)
  {
    FontSize = StrToIntDef(cmbFontSize->Text, 10);
    rve->ApplyStyleConversion(DEMO_APPLYFONTSIZE);
  }
  if (Visible)
    rve->SetFocus();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cmbFontSizeKeyPress(TObject *Sender, char &Key)
{
  if (Key==VK_RETURN)
  {
    Key = 0;
    cmbFontSizeClick(NULL);
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cmbFontSizeExit(TObject *Sender)
{
  cmbFontSizeClick(NULL);
}
//---------------------------------------------------------------------------
TFontStyle GetFontStyle(int UserData)
{
  switch(UserData)
  {
    case DEMO_MAKEBOLD:
    case DEMO_CLEARBOLD:
      return fsBold;
    case DEMO_MAKEITALIC:
    case DEMO_CLEARITALIC:
      return fsItalic;
    case DEMO_MAKEUNDERLINE:
    case DEMO_CLEARUNDERLINE:
      return fsUnderline;
    default:
      return fsBold; // <-- avoiding warnings
  }
}
//---------------------------------------------------------------------------
// The heart of this demo: rve->OnStyleConversion

void __fastcall TForm1::rveStyleConversion(TCustomRichViewEdit *Sender,
      int StyleNo, int UserData, bool AppliedToText, int &NewStyleNo)
{
  switch (UserData)
  {
    case DEMO_MAKEBOLD:
    case DEMO_MAKEITALIC:
    case DEMO_MAKEUNDERLINE:
    {
      TFontStyle fs = GetFontStyle(UserData);
      NewStyleNo = rvs->TextStyles->FindStyleWithFontStyle(StyleNo, TFontStyles()<<fs,TFontStyles()<<fs);
      if (NewStyleNo==-1)
      {
        rvs->TextStyles->Add();
        NewStyleNo = rvs->TextStyles->Count-1;
        rvs->TextStyles->Items[NewStyleNo]->Assign(rvs->TextStyles->Items[StyleNo]);
        rvs->TextStyles->Items[NewStyleNo]->Style << fs;
        rvs->TextStyles->Items[NewStyleNo]->Standard = false;
      }
      break;
    }
    case DEMO_CLEARBOLD:
    case DEMO_CLEARITALIC:
    case DEMO_CLEARUNDERLINE:
    {
      TFontStyle fs = GetFontStyle(UserData);
      NewStyleNo = rvs->TextStyles->FindStyleWithFontStyle(StyleNo, TFontStyles(),TFontStyles()<<fs);
      if (NewStyleNo==-1)
      {
        rvs->TextStyles->Add();
        NewStyleNo = rvs->TextStyles->Count-1;
        rvs->TextStyles->Items[NewStyleNo]->Assign(rvs->TextStyles->Items[StyleNo]);
        rvs->TextStyles->Items[NewStyleNo]->Style >> fs;
        rvs->TextStyles->Items[NewStyleNo]->Standard = false;
      }
      break;
    }
    case DEMO_APPLYFONTNAME:
    {
      NewStyleNo = rvs->TextStyles->FindStyleWithFontName(StyleNo, FontName);
      if (NewStyleNo==-1)
      {
        rvs->TextStyles->Add();
        NewStyleNo = rvs->TextStyles->Count-1;
        rvs->TextStyles->Items[NewStyleNo]->Assign(rvs->TextStyles->Items[StyleNo]);
        rvs->TextStyles->Items[NewStyleNo]->FontName = FontName;
        rvs->TextStyles->Items[NewStyleNo]->Standard = false;
      }
      break;
    }
    case DEMO_APPLYFONTSIZE:
    {
      NewStyleNo = rvs->TextStyles->FindStyleWithFontSize(StyleNo, FontSize);
      if (NewStyleNo==-1)
      {
        rvs->TextStyles->Add();
        NewStyleNo = rvs->TextStyles->Count-1;
        rvs->TextStyles->Items[NewStyleNo]->Assign(rvs->TextStyles->Items[StyleNo]);
        rvs->TextStyles->Items[NewStyleNo]->Size = FontSize;
        rvs->TextStyles->Items[NewStyleNo]->Standard = false;
      }
      break;
    }
    case DEMO_APPLYFONT:
    {
      NewStyleNo = rvs->TextStyles->FindStyleWithFont(StyleNo, fd->Font);
      if (NewStyleNo==-1)
      {
        rvs->TextStyles->Add();
        NewStyleNo = rvs->TextStyles->Count-1;
        rvs->TextStyles->Items[NewStyleNo]->Assign(rvs->TextStyles->Items[StyleNo]);
        rvs->TextStyles->Items[NewStyleNo]->Assign(fd->Font);
        rvs->TextStyles->Items[NewStyleNo]->Standard = false;
      }
      break;
    }
  }
}
//---------------------------------------------------------------------------
// applying paragraph style
void __fastcall TForm1::btnApplyPara(TObject *Sender)
{
  rve->ApplyParaStyle(((TSpeedButton*)(Sender))->Tag);
}
//---------------------------------------------------------------------------

