/*******************************************************}
{                                                       }
{       RichViewActions                                 }
{       Demo project for C++Builder 6-2007              }
{       You can use it as a basis for your              }
{       applications.                                   }
{                                                       }
{       Copyright (c) Sergey Tkachenko                  }
{       svt@trichview.com                               }
{       http://www.trichview.com                        }
{                                                       }
{*******************************************************/
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "dmActions.hpp"
#include "RVALocRuler.hpp"
//---------------------------------------------------------------------------
/*
  Uncomment the defines below to enable support for Gif and Png.

  GifImage (by Anders Melander)
    http://www.torry.net/vcl/graphics/gif/gifimage.exe (original)
    http://www.trichview.com/resources/thirdparty/gifimage.zip (update)
  Note: for C++Builder 2007+, use the built in TGifImage instead

  PngObject (by Gustavo Huffenbacher Daud)
    http://www.trichview.com/resources/thirdparty/pngimage.zip
*/
//#define USE_GIFIMAGE
//#define USE_PNGOBJECT

#ifdef USE_GIFIMAGE
#if __BORLANDC__>=0x0590
#include "GifImg.hpp"  // C++Builder 2007 or newer (using standard GIF class)
#else
#include "GifImage.hpp" // C++Builder 6-2006 (using thirdparty GIF class)
#endif
#endif

#ifdef USE_PNGOBJECT
#include "PngImage.hpp"
#endif
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PtblRV"
#pragma link "RichView"
#pragma link "RichViewActions"
#pragma link "Ruler"
#pragma link "RVEdit"
#pragma link "RVFontCombos"
#pragma link "RVRuler"
#pragma link "RVScroll"
#pragma link "RVStyle"
#pragma resource "*.dfm"


TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
        : TForm(Owner)
{
// GIF -----------
#ifdef USE_GIFIMAGE
  RegisterClass(__classid(TGIFImage));
  // uncomment the line below if Gif does not appear in Insert | Image
  //TPicture::RegisterFileFormat(__classid(TPicture), "gif", "Gif Image", __classid(TGIFImage));
  RV_RegisterHTMLGraphicFormat(__classid(TGIFImage));
#endif
// PNG -----------
#ifdef USE_PNGOBJECT
  // C++Builder 6-2007 (using thirdparty PNG class)
  RegisterClass(__classid(TPNGObject));
  RV_RegisterHTMLGraphicFormat(__classid(TPNGObject));
  RV_RegisterPngGraphic(__classid(TPNGObject));
#endif
}
//---------------------------------------------------------------------------

void __fastcall TForm3::FormCreate(TObject *Sender)
{
  cmbFont->Font->Name = RVAControlPanel1->DialogFontName;
  cmbFontSize->Font->Name = RVAControlPanel1->DialogFontName;  
  cmbUnits->Font->Name = RVAControlPanel1->DialogFontName;

  // Almost all these assignments could be done at design time in the Object Inspector
  // But in this demo we do not want to modify rvActionsResource
  // (and we recommend to use a copy of it in your applications)

  rvActionsResource->rvActionSave1->OnDocumentFileChange = rvActionSave1DocumentFileChange;

  // Code for making color-picking buttons stay pressed while a
  // color-picker window is visible.
  rvActionsResource->rvActionColor1->OnShowColorPicker = ColorPickerShow;
  rvActionsResource->rvActionColor1->OnHideColorPicker = ColorPickerHide;
  rvActionsResource->rvActionParaColor1->OnShowColorPicker = ColorPickerShow;
  rvActionsResource->rvActionParaColor1->OnHideColorPicker = ColorPickerHide;
  rvActionsResource->rvActionFontColor1->OnShowColorPicker = ColorPickerShow;
  rvActionsResource->rvActionFontColor1->OnHideColorPicker = ColorPickerHide;
  rvActionsResource->rvActionFontBackColor1->OnShowColorPicker = ColorPickerShow;
  rvActionsResource->rvActionFontBackColor1->OnHideColorPicker = ColorPickerHide;

  // C++Builder 4 and 5 do not have ActionComponent property for actions.
  // Coloring actions have a substitution - CallerControl property
  // It is ignored in C++Builder 6
  rvActionsResource->rvActionParaColor1->CallerControl = ToolButton39;
  rvActionsResource->rvActionFontBackColor1->CallerControl = ToolButton38;
  rvActionsResource->rvActionFontColor1->CallerControl = ToolButton36;

#if __BORLANDC__>0x0550
  // AutoComplete feature causes OnClick generation when editing combo-box's text.
  // Since in OnClick we move input focus in RichViewEdit1, this effect is
  // undesirable
  cmbFont->AutoComplete = false;
  cmbFontSize->AutoComplete = false;
#endif

  cmbUnits->ItemIndex = (int) RVAControlPanel1->UnitsDisplay;

  Localize();

  // Loading initial file via ActionOpen (allowing to update user interface)
  AnsiString FileName = ExtractFilePath(Application->ExeName)+"readme.rvf";
  if (!FileExists(FileName))
    FileName = ExtractFilePath(Application->ExeName)+"..\\readme.rvf";
  rvActionsResource->rvActionOpen1->LoadFile(RichViewEdit1, FileName, ffiRVF);

  /*
  // alternative way to start
    rvActionsResource->rvActionNew1->ExecuteTarget(RichViewEdit1);
  */
}
//---------------------------------------------------------------------------
/*                       Working with document                             */
//---------------------------------------------------------------------------
// When document is created, saved, loaded...
void __fastcall TForm3::rvActionSave1DocumentFileChange(TObject* Sender,
  TCustomRichViewEdit* Editor, const AnsiString FileName,
  TrvFileSaveFilter FileFormat, bool IsNew)
{
  AnsiString s = ExtractFileName(FileName);
  rvActionsResource->rvActionPrint1->Title = s;
  rvActionsResource->rvActionQuickPrint1->Title = s;
  if (IsNew)
    s += " (*)";
  Caption = s + " - RichViewActionsTest";
}
//---------------------------------------------------------------------------
// Prompt for saving...
void __fastcall TForm3::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  CanClose = rvActionsResource->rvActionSave1->CanCloseDoc(RichViewEdit1);
}
//---------------------------------------------------------------------------
void __fastcall TForm3::mitExitClick(TObject *Sender)
{
  Close();
}
//---------------------------------------------------------------------------
/*                  Working with color-picking buttons                     */
//---------------------------------------------------------------------------
// Code for making color-picking buttons pressed while
// a color-picker window is visible.
void __fastcall TForm3::ColorPickerShow(TObject* Sender)
{
#if __BORLANDC__>0x0550
  TComponent* ActionComponent = ((TAction*)Sender)->ActionComponent;
  if (ActionComponent->InheritsFrom(__classid(TToolButton)))
    ((TToolButton*)ActionComponent)->Down = true;
#else
  TControl* CallerControl = ((TrvActionCustomColor*)Sender)->CallerControl;
  if (CallerControl)
    ((TToolButton*)CallerControl)->Down = true;
#endif
}
//---------------------------------------------------------------------------
void __fastcall TForm3::ColorPickerHide(TObject* Sender)
{
#if __BORLANDC__>0x0550
  TComponent* ActionComponent = ((TAction*)Sender)->ActionComponent;
  if (ActionComponent->InheritsFrom(__classid(TToolButton)))
    ((TToolButton*)ActionComponent)->Down = false;
#else
  TControl* CallerControl = ((TrvActionCustomColor*)Sender)->CallerControl;
  if (CallerControl)
    ((TToolButton*)CallerControl)->Down = false;
#endif
}
//---------------------------------------------------------------------------
/*             Set of events for processing hypertext jumps                */
//---------------------------------------------------------------------------
// Hyperlink click
void __fastcall TForm3::RichViewEdit1Jump(TObject *Sender, int id)
{
  rvActionsResource->rvActionInsertHyperlink1->GoToLink(RichViewEdit1, id);
}
//---------------------------------------------------------------------------
// Inserting hyperlinks from files (RTF) and drag source
void __fastcall TForm3::RichViewEdit1ReadHyperlink(TCustomRichView *Sender,
      const AnsiString Target, const AnsiString Extras,
      TRVLoadFormat DocFormat, int &StyleNo, int &ItemTag,
      TRVRawByteString &ItemName)
{
  if (DocFormat==rvlfURL)
    StyleNo = rvActionsResource->rvActionInsertHyperlink1->GetHyperlinkStyleNo(RichViewEdit1);
  AnsiString URL = rvActionsResource->rvActionInsertHyperlink1->EncodeTarget(Target);
  ItemTag = (int)StrNew(URL.c_str());
}
//---------------------------------------------------------------------------
// Exporting hyperlink to RTF and HTML
void __fastcall TForm3::RichViewEdit1WriteHyperlink(
      TCustomRichView *Sender, int id, TCustomRVData *RVData, int ItemNo,
      TRVSaveFormat SaveFormat, AnsiString &Target, AnsiString &Extras)
{
  Target = (char*)(RVData->GetItemTag(ItemNo));
}
//---------------------------------------------------------------------------
// URL detection on typing
void __fastcall TForm3::RichViewEdit1KeyPress(TObject *Sender, char &Key)
{
  /*
  // uncomment if you use Addict3
  if (Key=='\'' || Key==13 || Key==9 || RichViewEdit1->Delimiters.Pos(Key))
    RVA_Addict3AutoCorrect(RichViewEdit1);
  */
  if (Key==13 || Key==9 || Key==' ' || Key==',' || Key==';')
  {
    rvActionsResource->rvActionInsertHyperlink1->DetectURL(RichViewEdit1);
    rvActionsResource->rvActionInsertHyperlink1->TerminateHyperlink(RichViewEdit1);
  }
}
//---------------------------------------------------------------------------
/*                     Insert table popup                                  */
//---------------------------------------------------------------------------
/* We use a trick: insert-table button has style tbsDropDown and assigned
  DropDownMenu (pmFakeDropDown). This menu is empty, but shows table size
  popup instead of itself */
void __fastcall TForm3::pmFakeDropDownPopup(TObject *Sender)
{
  rvActionsResource->rvActionInsertTable1->ShowTableSizeDialog(RichViewEdit1,
    ToolButton12);
}
//---------------------------------------------------------------------------
/*                    Working with combo-boxes                             */
//---------------------------------------------------------------------------
// Current font is changed. Updating the combo-boxes.
void __fastcall TForm3::RichViewEdit1CurTextStyleChanged(TObject *Sender)
{
  UpdatingCombos = true;
  TFontInfo* CurStyle = RVStyle1->TextStyles->Items[RichViewEdit1->CurTextStyleNo];
  cmbFont->Text = CurStyle->FontName;
  cmbFont->OnClick(Sender);
  cmbFontSize->FontName = CurStyle->FontName;
  cmbFontSize->Text = IntToStr(CurStyle->Size);
  UpdatingCombos = false;
}
//---------------------------------------------------------------------------
// Applying the font name
void __fastcall TForm3::cmbFontClick(TObject *Sender)
{
  AnsiString FontName;
  if (cmbFont->ItemIndex<0)
    FontName = cmbFont->Text;
  else
    FontName = cmbFont->Items->Strings[cmbFont->ItemIndex];
  if (UpdatingCombos)
    return;
  UpdatingCombos = true;
  cmbFontSize->FontName = FontName;
  UpdatingCombos = False;
  if (cmbFont->ItemIndex<0)
    cmbFont->ItemIndex = cmbFont->Items->IndexOf(FontName);
  if (cmbFont->ItemIndex<0)
    Beep();
  else
  {
    rvActionsResource->rvActionFontEx1->UserInterface = false;
    rvActionsResource->rvActionFontEx1->ValidProperties = (TRVFontInfoMainProperties() << rvfimFontName);
    rvActionsResource->rvActionFontEx1->Font->Name = FontName;
    rvActionsResource->rvActionFontEx1->Execute();
    rvActionsResource->rvActionFontEx1->UserInterface = true;
  }
  RichViewEdit1->SetFocus();
}
//---------------------------------------------------------------------------
// Changing the font size
void __fastcall TForm3::cmbFontSizeClick(TObject *Sender)
{
  if (UpdatingCombos)
    return;
  try
  {
    int FontSize = StrToInt(cmbFontSize->Text);
    rvActionsResource->rvActionFontEx1->UserInterface = false;
    rvActionsResource->rvActionFontEx1->ValidProperties = (TRVFontInfoMainProperties() << rvfimSize);
    rvActionsResource->rvActionFontEx1->Font->Size = FontSize;
    rvActionsResource->rvActionFontEx1->Execute();
    rvActionsResource->rvActionFontEx1->UserInterface = true;
  }
  catch(...)
  {
    Beep();
  }
  RichViewEdit1->SetFocus();
}
//---------------------------------------------------------------------------

void __fastcall TForm3::cmbtKeyPress(TObject *Sender, char &Key)
{
  if (Key==13)
  {
    Key = 0;
    ((TComboBox*)Sender)->OnClick(Sender);
  }
}
//---------------------------------------------------------------------------
/*                             Ruler                                       */
//---------------------------------------------------------------------------
void __fastcall TForm3::RVAControlPanel1MarginsChanged(TrvAction *Sender,
      TCustomRichViewEdit *Edit)
{
  RVRuler1->UpdateRulerMargins();
}
//---------------------------------------------------------------------------
/*                           Localization                                  */
//---------------------------------------------------------------------------
void __fastcall TForm3::Button1Click(TObject *Sender)
{
  if (RVA_ChooseLanguage())
    Localize();
}
//---------------------------------------------------------------------------
void TForm3::Localize()
{
  // Fonts
  Font->Charset             = RVA_GetCharset();
  StatusBar1->Font->Charset = RVA_GetCharset();
  cmbUnits->Font->Charset = RVA_GetCharset();
#if __BORLANDC__>0x0550
  Screen->HintFont->Charset = RVA_GetCharset();
  Screen->MenuFont->Charset = RVA_GetCharset();
#endif
  // Localizing all actions on rvActionsResource
  RVA_LocalizeForm(rvActionsResource);
  // Localizing all actions on this form
  RVA_LocalizeForm(this);
  // Localizing ruler
  RVALocalizeRuler(RVRuler1);
  // Localizing units
  int Idx = cmbUnits->ItemIndex;
  RVA_TranslateUnits(cmbUnits->Items);
  cmbUnits->ItemIndex = Idx;
  for (int i=0; i<CoolBar1->Bands->Count; i++)
    if (CoolBar1->Bands->Items[i]->Control == tbUnits)
      CoolBar1->Bands->Items[i]->Text = RVA_GetS(rvam_lbl_Units);
  // Localizing menus
  mitFile->Caption   = RVA_GetS(rvam_menu_File);
  mitEdit->Caption   = RVA_GetS(rvam_menu_Edit);
  mitFont->Caption   = RVA_GetS(rvam_menu_Font);
  mitPara->Caption   = RVA_GetS(rvam_menu_Para);
  mitFormat->Caption = RVA_GetS(rvam_menu_Format);
  mitInsert->Caption = RVA_GetS(rvam_menu_Insert);
  mitTable->Caption  = RVA_GetS(rvam_menu_Table);
  mitExit->Caption   = RVA_GetS(rvam_menu_Exit);
  mitTextFlow->Caption   = RVA_GetS(rvam_menu_TextFlow);  
  mitHelp->Caption   = RVA_GetS(rvam_menu_Help);
  mitHelpTOC->Caption   = RVA_GetS(rvam_menu_Help);  

  mitFontSize->Caption = RVA_GetS(rvam_menu_FontSize);
  mitFontStyle->Caption = RVA_GetS(rvam_menu_FontStyle);
  mitTableSelect->Caption = RVA_GetS(rvam_menu_TableSelect);
  mitTableCellBorders->Caption = RVA_GetS(rvam_menu_TableCellBorders);
  mitTableAlignCellContents->Caption = RVA_GetS(rvam_menu_TableCellAlign);
  // In your application, you can use either TrvActionFonts or TrvActionFontEx
  rvActionsResource->rvActionFonts1->Caption = rvActionsResource->rvActionFonts1->Caption+" (Standard)";
  rvActionsResource->rvActionFontEx1->Caption = rvActionsResource->rvActionFontEx1->Caption+" (Advanced)";

  /*
  // uncomment if you use Addict3. It's assumed that RVAddictSpell31
  // and RVThesaurus31 are on this form.
  RVAddictSpell31->UILanguage = GetAddictSpellLanguage(RVA_GetLanguageName());
  RVThesaurus31->UILanguage = GetAddictThesLanguage(RVA_GetLanguageName());
  */
}
//---------------------------------------------------------------------------
/*                             Misc.                                       */
//---------------------------------------------------------------------------
void __fastcall TForm3::RVAControlPanel1Download(TrvAction *Sender,
      const AnsiString Source)
{
  if (Source=="")
    Application->Hint = "";
  else
    Application->Hint = "Downloading "+Source+"...";
}
//---------------------------------------------------------------------------

void __fastcall TForm3::mitHelpTOCClick(TObject *Sender)
{
  TRVUnicodeString HelpFileName = ExtractFilePath(Application->ExeName)+
    "Help\\RichViewActions.chm";
  RvHtmlHelp(HelpFileName);
}
//---------------------------------------------------------------------------
/*                    Live spelling with Addict 3                          */
//---------------------------------------------------------------------------
/*
// Add these events if you use Addict3
// (Assuming that you have RVAddictSpell31: TRVAddictSpell3 on the form)

// RichViewEdit1->OnSpellingCheck event
void __fastcall TForm3::RichViewEdit1SpellingCheck(TCustomRichView* Sender,
  const AnsiString AWord, int StyleNo, bool& Misspelled)
{
  Misspelled = ! (RVAddictSpell31->WordAcceptable(AWord));
}

// RVAddictSpell31->OnParserIgnoreWord: if Ignore All or Add buttons were pressed
// in spellchecker dialog, removing underlines from the ignored word
void __fastcall TForm3::RVAddictSpell31ParserIgnoreWord(TObject* Sender,
  bool Before, int State)
{
  if (!Before && (State==IgnoreState_IgnoreAll || State==IgnoreState_Add))
    RichViewEdit1->LiveSpellingValidateWord(RVAddictSpell31->CurrentWord);
}

// Besides, if you want spelling check starting when loading document, call
// RichViewEdit1.StartLiveSpelling in rvActionFileOpen.OnOpenFile event
*/

//---------------------------------------------------------------------------

void __fastcall TForm3::cmbUnitsClick(TObject *Sender)
{

// --- 1. Units displayed to the user
  // units for displaying in dialogs
  RVAControlPanel1->UnitsDisplay = (TRVUnits)cmbUnits->ItemIndex;
  // units for displaying in the ruler
  RVRuler1->UnitsDisplay = (TRulerUnits)cmbUnits->ItemIndex;
  // units for page setup dialog
  if (RVAControlPanel1->UnitsDisplay==rvuPixels ||
      RVAControlPanel1->UnitsDisplay==rvuCentimeters ||
      RVAControlPanel1->UnitsDisplay==rvuMillimeters) 
    rvActionsResource->rvActionPageSetup1->MarginsUnits = rvpmuMillimeters;
  else
    rvActionsResource->rvActionPageSetup1->MarginsUnits = rvpmuInches;
// --- 2. units for internal measurement
  // units of measurement for RichViewActions
  if (RVAControlPanel1->UnitsDisplay==rvuPixels)
  {
    RVA_ConvertToPixels(rvActionsResource);
    RVAControlPanel1->UnitsProgram = rvstuPixels;
  }
  else
  {
    RVA_ConvertToTwips(rvActionsResource);
    RVAControlPanel1->UnitsProgram = rvstuTwips;
  }
  // units of measurement for the current document
  if (RVStyle1->Units != RVAControlPanel1->UnitsProgram)
  {
    RichViewEdit1->ConvertDocToDifferentUnits(RVAControlPanel1->UnitsProgram);
    RVStyle1->ConvertToDifferentUnits(RVAControlPanel1->UnitsProgram);
    RichViewEdit1->Change();
  }
  RichViewEdit1->SetFocus();
}
//---------------------------------------------------------------------------