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

#include <vcl.h>
#pragma hdrstop

#include "ide_editor.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
Tide_editor_Form *ide_editor_Form;
//---------------------------------------------------------------------------


//[다른 폼]
//{
    #include "main.h"
    #include "ide_main.h"
    #include "ide_mbutton.h"
    #include "ide_buttons.h"
    #include "ide_tree.h"
    #include "tree_tree.h"
    #include "ide_vsplit.h"
    #include "ide_hsplit.h"

    #include "editor_top.h"
    #include "editor_edit.h"
    #include "editor_info.h"

    #include "ide_library.h"

    //[2010.02.22.월][추가!!!]
    #include "ide_msgbox.h"

//}


__fastcall Tide_editor_Form::Tide_editor_Form(TComponent* Owner)
        : TForm(Owner)
{
  //[환경변수]
  //{
      //[2007.10.02.화][추가!!!]
      IDE_Get_Option(&_ide_option);

  //}

  //[초기화]
  //{
      //----------------------------------------------------------------------------------------------------------
      this->Left   = ide_vsplit_Form->Left + ide_vsplit_Form->Width - 1;
      this->Top    = ide_tree_Form->Top;
      this->Width  = main_Form->Width - (d_border_width * 2) - ide_tree_Form->Width - ide_vsplit_Form->Width + 4;
      this->Height = ide_tree_Form->Height;
      this->Color  = clWhite;
      //----------------------------------------------------------------------------------------------------------
  //}

  //[컨트롤 생성]
  //{
      //[편집기 경로막대]
      //{
          //가장 위에 위치해야 한다.
          editor_top_Form          = new Teditor_top_Form(this);
          editor_top_Form->Parent  = this;
          editor_top_Form->Visible = true;
      //}
      
      //[편집기]
      //{
          editor_edit_Form          = new Teditor_edit_Form(this);
          editor_edit_Form->Parent  = this;
          editor_edit_Form->Visible = true;
          editor_edit_Form->SendToBack();
          
      //}

      //[정보탭]
      //{
          editor_info_Form          = new Teditor_info_Form(this);
          editor_info_Form->Parent  = this;
          editor_info_Form->Visible = true;
          editor_info_Form->BringToFront();
      //}

      //[페이지]
      //{
          _page_Form          = new Tgui_page_Form(this);
          _page_Form->Parent  = this;
          _page_Form->Visible = true;

          //[컨트롤 초기화]
          //{
              //[주의!!!]{-------------------------------------------------------------------------
              //editor_top_Form 는 펼쳐지는 경우 높이가 바뀌므로 16 으로 상수 값을 사용해야 한다.
              //
              //[2009.10.15.목][수정!!!]-----------------------------------------------------------
              //<16> 값을 사용하는 것에서 <d_editorTopHeight> 정의상수를 사용하는 것으로 수정한다.
              //}----------------------------------------------------------------------------------

              _page_Form->_Top(editor_top_Form->Top + d_editorTopHeight/*editor_top_Form->Height*/);
              _page_Form->_Left(this->Width - _page_Form->Width - 1);

          //}

          //[EVENT 함수]
          //{
              _page_Form->_EVENT_ArrowUp   = _EVENT_PageUp;
              _page_Form->_EVENT_ArrowDown = _EVENT_PageDown;

          //}

      //}

      //[모서리 상자]
      //{
          _edgebox_Form          = new Tgui_edgebox_Form(this);
          _edgebox_Form->Parent  = this;
          _edgebox_Form->Visible = true;

          //[컨트롤 초기화]
          //{
              _edgebox_Form->_Top(this->Height - _edgebox_Form->Height);
              _edgebox_Form->_Left(this->Width - _edgebox_Form->Width);
          //}
      //}

      //[수직스크롤바]
      //{
          _scroll_v_Form          = new Tgui_scroll_v_Form(this);
          _scroll_v_Form->Parent  = this;
          _scroll_v_Form->Visible = true;

          //[컨트롤 초기화]
          //{
              _scroll_v_Form->_Left(this->Width - _scroll_v_Form->Width - 1);
              _scroll_v_Form->_Top(_page_Form->Top + _page_Form->Height);
              _scroll_v_Form->_Height(this->Height - _scroll_v_Form->Top - _edgebox_Form->Height);
          //}

          //[환경변수설정]
          //{
              //처음에는 문서가 없다.
              _scroll_v_Form->_DesignSize(0);
              _scroll_v_Form->_Max(0);

              editor_edit_Form->_Scroll_Set();
          //}

          //[EVENT 함수]
          //{
              //event 시 호출될 함수를 등록한다.
              _scroll_v_Form->_EVENT_Scroll    = _EVENT_V_Scroll;
              _scroll_v_Form->_EVENT_MouseDown = _EVENT_V_MouseDown;

          //}
      //}

      //[수평스크롤바]
      //{
          _scroll_h_Form          = new Tgui_scroll_h_Form(this);
          _scroll_h_Form->Parent  = this;
          _scroll_h_Form->Visible = true;

          //[컨트롤 초기화]
          //{
              _scroll_h_Form->_Left(editor_info_Form->Left + editor_info_Form->Width);
              _scroll_h_Form->_Top(_edgebox_Form->Top);
              _scroll_h_Form->_Width(this->Width - _scroll_h_Form->Left - _edgebox_Form->Width);
          //}

          //[환경변수설정]
          //{
              _scroll_h_Form->_DesignSize(400/4);
              _scroll_h_Form->_Max(400);
          //}

          //[EVENT 함수]
          //{
              //event 시 호출될 함수를 등록한다.
              _scroll_h_Form->_EVENT_Scroll    = _EVENT_H_Scroll;
              //[2007.04.05.목][추가!!!]
              _scroll_h_Form->_EVENT_MouseDown = _EVENT_H_MouseDown;

          //}

      //}

      //[전광판]
      //{
          //[2010.02.22.월][추가!!!]{-----------------------------------------------
          //[편집기] 에 열린 문서가 없는 경우 자동으로 나오는 [전광판] 을 생성한다.
          //}-----------------------------------------------------------------------

          _GDotMatrix          = new TGDotMatrix_Form(this);
          _GDotMatrix->Parent  = editor_edit_Form;
          _GDotMatrix->Visible = false;

          _GDotMatrix->_Left(d_gutter_width);
          _GDotMatrix->_Top(this->Height/2 - _GDotMatrix->Height/2);
          _GDotMatrix->_Width(Screen->Width);
		  _GDotMatrix->_Height(76);

          _GDotMatrix->_DotWidth(Screen->Width);
          //기본크기가 12(폰트크기)이므로 그대로 두어도 무관.
          //_GDotMatrix->_DotHeight(12);

          _GDotMatrix->_LedOrgX(0);
          _GDotMatrix->_LedOrgY(0);
		  _GDotMatrix->_LedGap(1);

		  //[배경그림] 을 다시 지정한다.
		  _GDotMatrix->_BackBmp(editor_edit_Form->_bmp_back_, this->Left + _GDotMatrix->Left - 2, _GDotMatrix->Top);

		  //영문이 보기 좋게 나오도록 굴림체 영문/가변 글꼴을 사용한다.
		  FONTPACK_SetFont_withName(&(_GDotMatrix->_font), 3, "굴림체(6_12_영문_d_v).gft");
		  _GDotMatrix->_font.en_offset_left  = 1;
		  _GDotMatrix->_font.en_offset_right = 0;

		  //[2010.05.11.화][추가!!!]{----------------------------------
		  //Win7 에서 빌드하면서 타이머 값을 변경하기 위하여 추가한다.
		  //금일 부터 Win7 에서 진행하게 되었다.
          //[2018.02.19.수][수정!!!]-----------------------------------
          //[환경변수] 에 등록한 값으로 초기화 하도록 수정.
		  _GDotMatrix->_RotTime(_ide_option->dotmatrixRotateTime);
		  //}----------------------------------------------------------

		  //[개발환경 설정 반영]
		  //{
			  //이미 설정문서에 설정된 문자열을 사용하여 설정한다.
			  _GDotMatrix->_Led_Make(d_GDotMatrix_LedBox, 5,
                                     _ide_option->dotmatrixColor, clWhite,
                                     false,
                                     clRed, clWhite);
              _GDotMatrix->_PrintStr(0, 0, _ide_option->dotmatrixStr);
			  _GDotMatrix->_RotStr(_ide_option->dotmatrixStr);

              if(_ide_option->dotmatrixUse == true)
              {
                //[전광판] 구동.
                _GDotMatrix->Visible = true;
				_GDotMatrix->_RotTimer(_ide_option->dotmatrixRotate);

              }
			  else
              {
                //[전광판] 정지.
				_GDotMatrix->Visible = false;
                _GDotMatrix->_RotTimer(false);

              }

          //}

      //}

      //[수직 순서 조정]
      //{
          //가장 위에 배치시킨다.
          _edgebox_Form->BringToFront();
          editor_top_Form->BringToFront();

      //}

  //}

  return;

}

__fastcall Tide_editor_Form::~Tide_editor_Form(void)
{
  //[2012.04.29.일][수정!!!]{---------------
  //안전을 위하여 선언한 역순으로 삭제한다.
  //}---------------------------------------

  if(_GDotMatrix != NULL) { delete _GDotMatrix; _GDotMatrix = NULL; }

  if(_scroll_h_Form != NULL) { delete _scroll_h_Form; _scroll_h_Form = NULL; }

  if(_scroll_v_Form != NULL) { delete _scroll_v_Form; _scroll_v_Form = NULL; }

  if(_edgebox_Form != NULL) { delete _edgebox_Form; _edgebox_Form = NULL; }

  if(_page_Form != NULL) { delete _page_Form; _page_Form = NULL; }

  if(editor_info_Form != NULL) { delete editor_info_Form; editor_info_Form = NULL; }

  if(editor_edit_Form != NULL) { delete editor_edit_Form; editor_edit_Form = NULL; }

  if(editor_top_Form != NULL) { delete editor_top_Form; editor_top_Form = NULL; }

}

//------------------------------------------------------------------------------
//[서브클래싱]------------------------------------------------------------------
//------------------------------------------------------------------------------

void __fastcall Tide_editor_Form::WndProc(Messages::TMessage  &Message)
{
  //[2012.06.07.목][생성!!!]

  if(Message.Msg == WM_ERASEBKGND)
  {
    //[2012.06.07.목][추가!!!]{--------------------------------------
    //<ide_editor_Form> 의 경우는 보이는 부분이 없기 때문에 쓸데없이
    //바탕등이 그려지지 않도록 <WM_ERASEBKGND> 는 걸러낸다.
    //}--------------------------------------------------------------

    return;

  }

  //[기본처리]
  //{
      //기본 메세지는 반드시 처리 되어야 한다.
      TForm::WndProc(Message);

  //}

}

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

void __fastcall Tide_editor_Form::_Resize(void)
{
  //[2006.10.22.일][생성!!!]{--
  //컨트롤 크기를 조정한다.
  //}--------------------------

  //[크기조정]
  //{
      //IDE Form 에 맞게 크기를 조정한다.
      this->Top    = ide_tree_Form->Top;
      this->Width  = main_Form->Width - (d_border_width * 2) - ide_tree_Form->Width - ide_vsplit_Form->Width + 4;
      this->Height = ide_tree_Form->Height;
  //}

  //[전체 그림 사용]
  //{
      //[2007.03.25.일][추가!!!]
      //전체그림사용 의 경우는 위치가 바뀌는 경우도 무조건 다시 그려야 배경그림
      //이 정확한 위치에 표시된다.
      if(IDE_BACKBMP_entire)
      {
        editor_edit_Form->_Resize();

      }
  //}

  return;

}

void __fastcall Tide_editor_Form::_Split_v(void)
{
  //[2006.10.24.화][생성!!!]{------
  //수직 spliter 동작시 크기 조정.
  //}------------------------------

  //[크기조정]
  //{
      //IDE Form 에 맞게 크기를 조정한다.
      this->Top    = ide_tree_Form->Top;
      this->Left   = ide_vsplit_Form->Left + ide_vsplit_Form->Width - 1;
      this->Width  = main_Form->Width - (d_border_width * 2) - ide_tree_Form->Width - ide_vsplit_Form->Width + 4;
  //}

  return;

}

void __fastcall Tide_editor_Form::_Split_h(void)
{
  //[2006.10.24.화][생성!!!]{------
  //수평 spliter 동작시 크기 조정.
  //}------------------------------

  //[크기조정]
  //{
      //IDE Form 에 맞게 크기를 조정한다.
      this->Top    = ide_mbutton_Form->Top + ide_mbutton_Form->Height - 1;
      this->Height = ide_hsplit_Form->Top - this->Top + 1;
  //}

  return;

}

void __fastcall Tide_editor_Form::_Enable(bool  pENABLE)
{
  //[2007.03.31.토][생성!!!]{------------------------------------
  //ide_editor_Form 과 이 안의 모든 컨트롤을 무효화/유효화 한다.
  //수반하는 작업도 동시에 수행할수 있다.

  //[2007.04.16.월][추가!!!]
  //관련되는 [기능버튼] 도 같이 [유/무효] 처리를 수행한다.
  //}------------------------------------------------------------

  switch(pENABLE)
  {
    case true :
    {
      //전체 활성화.
      this->Enabled = true;
      //ide_buttons_Form->Enabled = true;

      //[전광판]
      //{
          //[2010.02.23.화][추가!!!]{---------------------------------
          //[문서] 가 한개라도 열린 경우는 반대로 [전광판] 을 감춘다.
          //}---------------------------------------------------------

          //일단 현재 [문자열 회전] 의 경우라면 무조건 정지시킨다.
          //이미 현재상태는 [환경변수] 에 저장돼 있으므로 별도 대피는 하지 않는다.
          //_GDotMatrix->_RotTimer(false);
          //[2010.04.09.금][수정!!!]
          //위 함수 대신 이 함수를 사용하고, 반드시 처리해야 하므로 _GDotMatrix_RotateTemp2() 를 사용한다.
          _GDotMatrix_RotateTemp2(false);

          //보이지 않게 만든다.
          //단, 일시적인 것이므로 [환경변수] 에 반영하지는 않는다.
          _GDotMatrix->Visible = false;

      //}

    } break;

    case false :
    {
      //전체 비활성화.
      this->Enabled = false;

      //[설계묶음 존재 확인]
      //{
          //[2009.01.30.금][수정!!!]{--------------------------------------------------------
          //모든 문서가 닫히는 경우라도 [설계묶음] 이 열려 있다면 활성화 상태로 두어야 한다.
          //[편집기] 에 문서를 열지 않은 상태라도 [Build] 는 할수 있어야 하므로.
          //}--------------------------------------------------------------------------------

          //[2012.04.20.금][수정!!!]
          if(STR_Match_NoCase(tree_tree_Form->_Item_Txt_StrPtr(d_TREE_project, 0), "새설계묶음") == true)
          {
            //ide_buttons_Form->Enabled = false;

          }

      //}

      //[전광판]
      //{
          //[2010.02.23.화][추가!!!]{-----------------------------
          //[문서] 가 모두 닫힌 경우는 다시 [전광판] 을 보여준다.
          //}-----------------------------------------------------

          //다시 보이게 만든다.
          //단, 현재 [환경변수] 의 설정 값으로 처리해야 한다.
          _GDotMatrix->Visible = _ide_option->dotmatrixUse;

          if(_GDotMatrix->Visible == true)
          {
            //[2010.03.03.수][수정!!!]{-----------------------------------------
            //반드시 보일때만 돌려야 한다. 그렇지 않으면 계속 타이머가 동작되어
            //전체 실행에 영향을 주게 된다.
            //오늘 이 문제를 발견하고 수정한다.
            //}-----------------------------------------------------------------

            //[환경변수] 의 값으로 다시 설정한다.
            //_GDotMatrix->_RotTimer(_ide_option->dotmatrixRotate);
            //위 함수 대신 이 함수를 사용한다.
            //이는 [맷돌가상구동/직접연결] 선택시 [전광판 정지] 설정을 건드리기 않기 위한것이다.
            _GDotMatrix_RotateTemp(true);

          }

      //}

    } break;

  }

  return;

}

//[EVENT]-----------------------------------------------------------------------

void __fastcall Tide_editor_Form::FormResize(TObject *Sender)
{

  //[2006.10.26][생성!!!]{---------------------------
  //이 Form 안의 다른 컨트롤의 크기를 새로 조정한다.
  //[2018.03.04.일][수정!!!]-------------------------
  //}------------------------------------------------

  if(editor_top_Form != NULL)
  {
    editor_top_Form->_Resize();

  }

  if(editor_edit_Form != NULL)
  {
    editor_edit_Form->_Resize();

  }

  if(editor_info_Form != NULL)
  {
    editor_info_Form->_Resize();

  }

  if(_page_Form != NULL)
  {
    //[주의!!!]{-------------------------------------------------------------------------
    //editor_top_Form 는 펼쳐지는 경우 높이가 바뀌므로 16 으로 상수 값을 사용해야 한다.
    //
    //[2009.10.15.목][수정!!!]-----------------------------------------------------------
    //<16> 값을 사용하는 것에서 <d_editorTopHeight> 정의상수를 사용하는 것으로 수정한다.
    //}----------------------------------------------------------------------------------

    _page_Form->_Top(editor_top_Form->Top + d_editorTopHeight/*editor_top_Form->Height*/);
    _page_Form->_Left(this->Width - _page_Form->Width - 1);

  }

  if(_edgebox_Form != NULL)
  {
    _edgebox_Form->_Top(this->Height - _edgebox_Form->Height);
    _edgebox_Form->_Left(this->Width - _edgebox_Form->Width);

  }

  if(_scroll_v_Form != NULL)
  {
    _scroll_v_Form->_Left(this->Width - _scroll_v_Form->Width - 1);
    _scroll_v_Form->_Top(_page_Form->Top + _page_Form->Height);
    _scroll_v_Form->_Height(this->Height - _scroll_v_Form->Top - _edgebox_Form->Height);

    //스크롤 영역을 재 조정한다.(보이는 영역의 크기가 변경되므로.)
    editor_edit_Form->_Scroll_Resize();

  }

  if(_scroll_h_Form != NULL)
  {
    _scroll_h_Form->_Left(editor_info_Form->Left + editor_info_Form->Width);
    _scroll_h_Form->_Top(_edgebox_Form->Top);
    _scroll_h_Form->_Width(this->Width - _scroll_h_Form->Left - _edgebox_Form->Width);

  }

  if(_GDotMatrix != NULL)
  {
    //[2010.02.22.월][추가!!!]{-------------------------------------
    //[2012.06.05.화][중요수정!!!]----------------------------------
    //사용하지 않는 것인데 그동안 계속 크기 조정시 반영되고 있었다.
    //문제는 이게 [처리 시간 대부분을 다 잡아 먹는다] 라는 것.
    //금일 [맷돌-통합개발환경] 크기 조정시 [중복 처리 방지] 를 위한
    //전체 점검중 밟견하고 [주석] 으로 처리한다.
    //}-------------------------------------------------------------

    //[2012.06.05.화][주석처리!!!]{--------------------------
    //[2018.02.18.일][수정!!!]-------------------------------
    //처리 시간이 많이 걸리므로 [전광판:사용] 시만 반영한다.
    //}------------------------------------------------------

    //[크기/위치:조정]
    //{
        //[2018.03.04.일][수정!!!]{---
        //새로 만든 전용 함수로 대체.
        //}---------------------------

        _GDotMatrix_ReSize();

    //}

    //[배경그림:조정]
    //{
        //[2018.03.04.일][수정!!!]{---
        //새로 만든 전용 함수로 대체.
        //}---------------------------
        
        _GDotMatrix_BackBmpChange();

    //}
        
  }

}

void __fastcall Tide_editor_Form::FormShow(TObject *Sender)
{
  //[2007.03.25.일][생성!!!]{-----------------------------------------------------
  //이 폼이 생성될때는 크기 정보가 확정되지 않으므로 여기서 한번 그려주어야 한다.
  //단, 이 경우는 [전체그림사용] 의 경우로 한정된다.
  //}-----------------------------------------------------------------------------

  if(IDE_BACKBMP_entire)
  {
    editor_edit_Form->_Shape();

  }

  return;

}

//[FUNCTION POINTER]------------------------------------------------------------

void __fastcall Tide_editor_Form::_EVENT_V_MouseDown(void)
{
  //[2006.11.28.화][생성!!!]{-------------------
  //[수직스크롤바] 의 click 시 처리를 수행한다.
  //}-------------------------------------------

  //[포커스 주기]
  //{
      //이미 [촛점] 이 있는 경우는 WM_SETFOCUS 의 중복처리 방지를 위하여 처리하지 않는다.
      if(editor_edit_Form->Focused() != true)
      {
        //----------------------------------------------------------------
        //[휠마우스] 를 사용하게 하기 위하여 반드시 포커스를 주어야 한다.
        //휠은 수직 스크롤바에만 적용한다.
        editor_edit_Form->SetFocus();
        //----------------------------------------------------------------
      }  
  //}

  return;

}

void __fastcall Tide_editor_Form::_EVENT_V_Scroll(void)
{
  //[2006.11.28.화][생성!!!]{-------------------------------------
  //[수직스크롤바] 의 이동시 처리를 수행한다.
  //이는 해당 [스크롤바] 의 _position 값이 바뀌었음을 의미하므로,
  //_position 의 변화에 따른 처리를 수행하면 된다.
  //}-------------------------------------------------------------

  //[포커스 주기]
  //{
      //이미 [촛점] 이 있는 경우는 WM_SETFOCUS 의 중복처리 방지를 위하여 처리하지 않는다.
      if(editor_edit_Form->Focused() != true)
      {
        //----------------------------------------------------------------
        //[휠마우스] 를 사용하게 하기 위하여 반드시 포커스를 주어야 한다.
        //휠은 수직 스크롤바에만 적용한다.
        editor_edit_Form->SetFocus();
        //----------------------------------------------------------------
      }
  //}

  //[스크롤 동기화]
  //{
      //[편집기] 내용을 동기화 시킨다.
      editor_edit_Form->_EDIT_V_Scroll();

  //}

  return;

}

void __fastcall Tide_editor_Form::_EVENT_H_MouseDown(void)
{
  //[2007.04.05.목][생성!!!]{-------------------
  //[수평스크롤바] 의 click 시 처리를 수행한다.
  //}-------------------------------------------

  //[포커스 주기]
  //{
      //이미 [촛점] 이 있는 경우는 WM_SETFOCUS 의 중복처리 방지를 위하여 처리하지 않는다.
      if(editor_edit_Form->Focused() != true)
      {
        //----------------------------------------------------------------
        //[휠마우스] 를 사용하게 하기 위하여 반드시 포커스를 주어야 한다.
        //휠은 수직 스크롤바에만 적용한다.
        editor_edit_Form->SetFocus();
        //----------------------------------------------------------------
      }
  //}

  return;

}

void __fastcall Tide_editor_Form::_EVENT_H_Scroll(void)
{
  //[2006.11.01.수][생성!!!]{-------------------------------------
  //[수평스크롤바] 의 이동시 처리를 수행한다.
  //이는 해당 [스크롤바] 의 _position 값이 바뀌었음을 의미하므로,
  //_position 의 변화에 따른 처리를 수행하면 된다.
  //}-------------------------------------------------------------

  //[포커스 주기]
  //{
      //이미 [촛점] 이 있는 경우는 WM_SETFOCUS 의 중복처리 방지를 위하여 처리하지 않는다.
      if(editor_edit_Form->Focused() != true)
      {
        //----------------------------------------------------------------
        //[휠마우스] 를 사용하게 하기 위하여 반드시 포커스를 주어야 한다.
        //휠은 수직 스크롤바에만 적용한다.
        editor_edit_Form->SetFocus();
        //----------------------------------------------------------------
      }
  //}

  //[스크롤 동기화]
  //{
      //[편집기] 내용을 동기화 시킨다.
      editor_edit_Form->_EDIT_H_Scroll();
  //}

  return;

}

void __fastcall Tide_editor_Form::_EVENT_PageUp(void)
{
  //[VAR]
  //{
      int  position = _scroll_v_Form->_position;
  //}

  position -= ((editor_edit_Form->Height - editor_info_Form->Height) / editor_edit_Form->_line_height);

  _scroll_v_Form->_Position(position);

  //[스크롤 동기화]
  //{
      //_Position() 함수를 호출하면 자동으로 _EVENT_V_Scroll() 가 호출되므로
      //[문서] 는 자동으로 [스크롤] 에 동기화 된다.
  //}

  return;

}

void __fastcall Tide_editor_Form::_EVENT_PageDown(void)
{
  //[VAR]
  //{
      int  position = _scroll_v_Form->_position;
  //}

  position += ((editor_edit_Form->Height - editor_info_Form->Height) / editor_edit_Form->_line_height);

  _scroll_v_Form->_Position(position);

  //[스크롤 동기화]
  //{
      //_Position() 함수를 호출하면 자동으로 _EVENT_V_Scroll() 가 호출되므로
      //[문서] 는 자동으로 [스크롤] 에 동기화 된다.
  //}

  return;

}

//[기능함수]--------------------------------------------------------------------

void __fastcall Tide_editor_Form::_RUN_Line(int  pLINEnumber)
{
  //[2006.12.07.목][생성!!!]{----------------------------
  //[실행지정상자] 와 [실행지정자] 를 지정행에 배치한다.
  //각각 지정 함수를 사용하여 처리한다.
  //}----------------------------------------------------

  //[지정자 지정]
  //{
      //[실행지정상자] 의 위치를 수정한다.
      //[2010.02.16.화][수정!!!]{---------------------------------------
      //<editor_linebox_Form> 을 [지정행] 으로 대체한다.
      editor_edit_Form->_FocusLineNum(pLINEnumber);
      //}---------------------------------------------------------------

      //[실행지정자] 의 위치를 수정한다.
      editor_edit_Form->_DEBUG_RunArrow(editor_edit_Form->_focusLineNum, true);

  //}

  //[지정행 항상 보이기]
  //{
      //[2007.12.01.토][추가!!!]
      //항상 지정행이 [편집기] 상의 보이는 영역에 위치하도록 만든다.
      _Line_View(pLINEnumber);

  //}

  return;

}

void __fastcall Tide_editor_Form::_Line_View(int  pLineNumber)
{
  //[2007.12.01.토][생성!!!]{---------------------------------------
  //지정된 행이 보이지 않는 영역에 있다면 항상 보이는 영역에 있도록
  //자동으로 수직 줄이동을 해준다.
  //}---------------------------------------------------------------

  //[방법]
  //{
      //[위 행으로 보이지 않는 경우]
      //editor_edit_Form 에서 관리되는 모든 문서정보는에는 [보이는 영역의 가장 위 행]
      //의 정보가 있으므로 이 값보다 지정행이 작은 값이면 보이지 않는 영역에 있는 것으로
      //간주하고 이 값의 차이만큼 위로 [줄이동] 해주면 된다.

      //[아래 행으로 보이지 않는 경우]
      //보이는 영역의 가장 아래 행번호를 구하고 이보다 크면 보이지 않는 영역에 있는 것으로
      //간주하고 이 값의 차이만큼 아래로 [줄이동] 해주면 된다.

  //}


  //[VAR]
  //{
      //[편집기] 상의 눈에 보이는 영역의 행 수.
      int   viewLineCount;

      //보이는 영역의 가장 위 행번호.
      int   lineTopNumber;

      //보이는 영역의 가장 아래 행번호.
      int   lineBottomNumber;

  //}


  //[행정보 얻기]
  //{
      //[편집기] 의 보여지는 영역의 전체 행수를 구한다.
      viewLineCount    = (editor_edit_Form->Height - editor_info_Form->Height) / editor_edit_Form->_line_height;

      //가장 위 행번호.(항상 관리되고 있는 정보를 사용한다.)
      lineTopNumber    = editor_edit_Form->_linetop_linenumber;

      //가장 아래 행번호.
      lineBottomNumber = lineTopNumber + viewLineCount - 2;

  //}

  //[영역 검사]
  //{
      if     (pLineNumber <= lineTopNumber)
      {
        //위로 보이지 않는 경우.

        //지정행이 보이도록 위로 [줄이동] 한다.
        _scroll_v_Form->_Position(_scroll_v_Form->_position - (lineTopNumber - pLineNumber + 1));

      }
      else if((lineTopNumber < pLineNumber) && (pLineNumber < lineBottomNumber))
      {
        //보이는 영역에 있는 경우.
        //아무것도 하지 않으면 된다.

      }
      else if(lineBottomNumber <= pLineNumber)
      {
        //아래로 보이지 않는 경우.

        //항상 지정행이 보이는 영역의 중간에 위치하도록 한다.
        //검증시는  아래로 한줄씩 실행되므로 계속 [줄이동] 을 하는 번거로움이 생기지 않도록
        //아예 중간에 위치시킨다. 그러면 아래 행에 여유가 있으므로 매행마다 [줄이동] 을 하지 않게된다.
        //이 편이 보기도 편하고 어지럽지 않다.
        _scroll_v_Form->_Position(_scroll_v_Form->_position + (pLineNumber - lineBottomNumber + viewLineCount/2));

      }

  //}

  return;

}

void __fastcall Tide_editor_Form::_Shape(void)
{
  //[2022.06.28.화][생성]{--------------------------------------------------------
  //<editor_edit, editor_top> 만 다시 그려준다.
  //
  //[참고]------------------------------------------------------------------------
  //이 함수는 [순간보기] 지원을 위한 것으로 <tree_tree_Form:_Tree_ApiInfo_View()>
  //함수 내부적으로 [순간보기] 문서 처리시 깜박임 방지를 위하여 사용된다.
  //}-----------------------------------------------------------------------------

  editor_top_Form->_Shape();

  editor_edit_Form->_EditBuf_Text();

}

//------------------------------------------------------------------------------
//[전광판 관련]-----------------------------------------------------------------
//------------------------------------------------------------------------------

void __fastcall Tide_editor_Form::_GDotMatrix_Str(void)
{
  //[2010.02.22.월][생성!!!]{----------------------
  //[전광판] 에 출력할 문자열을 설정한다.
  //단, 반드시 [환경변수] 에도 저장해 놓아야 한다.
  //한줄편집기가 있는 대화상자를 열어서 보여준다.
  //
  //[2018.02.16.금][수정!!!]-----------------------
  //}----------------------------------------------

  //[문자열 설정]
  //{
      //[2018.02.16.금][추가!!!]{-----------------------------
      //대화상자를 보여주기 전에 이전에 설정된 문자열을 설정.
      //}-----------------------------------------------------

      if(_ide_option->dotmatrixStr != NULL)
      {
        //문자열 설정.
        ide_msgbox_Form->_edit_Edit->_EDIT_TextOut(_ide_option->dotmatrixStr);

        //항상 첫 문자가 보이도록 유지.
        ide_msgbox_Form->_edit_Edit->_KEY_Home(false);

      }  

  //}

  //[대화상자 보이기]
  //{
      if(ide_msgbox_Form->_MsgBox_Edit
         (d_MSGBOX_default,
          "[전광판] 에 설정할 문자열을 기술합니다.") != true) return;

  //}

  //[문자열 크기 검사]
  //{
      if(STR_Length(ide_msgbox_Form->_edit_Edit->_editbuf) > 512)
      {
        //문자열의 길이는 [환경변수:512 바이트 문자열] 의 길이를 넘을수 없다(환경변수 참고).
        ide_msgbox_Form->_MsgBox(d_MSGBOX_error, "[전광판] 문자열의 길이는 512 바이트를 넘을수 없습니다.");

        return;

      }

  //}

  //먼저 [환경변수] 에 저장한다.
  STR_Assign(_ide_option->dotmatrixStr, ide_msgbox_Form->_edit_Edit->_editbuf);

  //문자열을 설정한다.
  _GDotMatrix->_RotStr(_ide_option->dotmatrixStr);

}

void __fastcall Tide_editor_Form::_GDotMatrix_Color(void)
{
  //[2010.02.22.월][생성!!!]{----------------------
  //[전광판] 에 출려되는 문자색을 설정한다.
  //단, 반드시 [환경변수] 에도 저장해 놓아야 한다.
  //색 대화상자를 보여준다.
  //}----------------------------------------------

  //[색 대화상자를 보이기]
  //{
      if(main_Form->color_ColorDialog->Execute() != true) return;

  //}

  //먼저 [환경변수] 에 저장한다.
  _ide_option->dotmatrixColor = main_Form->color_ColorDialog->Color;

  //문자열을 설정한다.
  _GDotMatrix->_Led_Make(d_GDotMatrix_LedBox, 5,
                         _ide_option->dotmatrixColor, clWhite,
                         false,
                         clRed, clWhite);

}

void __fastcall Tide_editor_Form::_GDotMatrix_ReSize(void)
{
  //[2018.03.04.일][생성!!!]{----------------
  //[전광판:크기위치조정] 을 하는 경우 사용.
  //}----------------------------------------

  //[전광판:사용] 인 경우만 처리.
  if(_ide_option->dotmatrixUse != true) return;

  _GDotMatrix->_Top(this->Height/2 - _GDotMatrix->Height/2);

}

void __fastcall Tide_editor_Form::_GDotMatrix_BackBmpChange(void)
{
  //[2018.03.04.일][생성!!!]{------------------------------------------------------------------
  //[전광판:배경그림] 을 바꿔야 하는 경우 사용.
  //[전광판:배경그림] 은 [포인터] 로 항상 [편집기:배경그림] 을 지정하도록 돼 있으므로
  //단순하게 <_Shape()> 로 다시 그려주는 것만으로 반영된다.
  //단, [편집기:배경그림] 을 지정하므로 [편집기:배경그림] 이 먼저 교체된 다음에 호출해야 한다.
  //}------------------------------------------------------------------------------------------

  //[전광판:사용] 인 경우만 처리.
  if(_ide_option->dotmatrixUse != true) return;

  //[포인터] 로 관리되어 같은 그림을 가지므로 이 줄은 필요 없으나 다시 지정.
  _GDotMatrix->_BackBmp(editor_edit_Form->_bmp_back_, this->Left + _GDotMatrix->Left - 3, _GDotMatrix->Top);

  //배경 그림을 다시 출력한다.
  _GDotMatrix->_Shape();

}

void __fastcall Tide_editor_Form::_GDotMatrix_Use(//[2018.02.17.토][추가!!!]
                                                  //사용하는 경우는 true.
                                                  bool  pUse)
{
  //[2010.02.22.월][생성!!!]{------------------------------------------------------
  //[전광판] 을 사용하거나 사용하지 않는다.
  //단, 이는 [반전] 속성으로, 현재 [사용] 중이라면 [중지] 로,
  //현재 [중지] 라면 [사용] 으로 전환한다.
  //
  //[중지시]-----------------------------------------------------------------------
  //
  //(1) 현재 [문자열 회전] 상태를 저장한다
  //    이는 다시 [사용] 시 원래 상태로 돌려놓기 위한 것이다.
  //(2) 현재 [문자열 회전] 중이라도 무조건 타이머를 중지시키고 보이기 않게 만든다.
  //
  //[사용시]-----------------------------------------------------------------------
  //
  //(1) 다시 보이게 만든다.
  //(2) 이전 [문자열 회전] 상태를 복구하여 다시 설정한다.
  //    이전에 [문자열 회전] 상태였다면, 다시 타이머를 기동하여 회전시켜준다.
  //
  //[2018.02.17.토][수정!!!]-------------------------------------------------------
  //[사용여부] 를 인수로 전달 받아 처리하도록 수정.
  //}------------------------------------------------------------------------------

  //[현재 문서가 열려있나?]
  //{
      //[2010.04.06.화][추가!!!]{------------------------------------------------
      //현재 [문서] 가 한개라도 열려 있는 경우는 [전광판] 을 보이지 않아야 한다.
      //}------------------------------------------------------------------------

      //열려있는 문서가 한개라도 있는 경우는 처리하지 않는다.
      if(editor_edit_Form->_textinfo_count > 0) return;

  //}

  //[맷돌가상구동/직접연결 중인가?]
  //{
      //[2010.04.09.금][수정!!!]{----------------------------------------------------------
      //[맷돌가상구동] 이나 [맷돌직접연결] 인 경우는 각각 검증등에 영향을 주지 않도록
      //처리하지 않는다.
      //이는 [맷돌가상구동] 이나 [맷돌직접연결] 시 자동으로 [전광판] 동작이 중지되는데
      //[제목줄] 로 끌어 이동하는 경우등에서 다시 [활성화] 되도록 되어 있어, 여기서
      //다시 [활성화] 되는 것을 막기 위한것이다.
      //즉, [맷돌가상구동] 이나 [맷돌직접연결] 에서 한 설정이 바뀌지 않게 하기 위한것이다.
      //}----------------------------------------------------------------------------------

      if((ide_buttons_Form->_vmosSim_CheckBtn->_checked == true) ||
         (ide_buttons_Form->_vmosMdl_CheckBtn->_checked == true))
      {
        return;

      }

  //}

  if(pUse == true)
  {
    //[!]{--------------------------
    //[전광판] 환경 설정 대로 사용.
    //}-----------------------------

    //[선행처리]
    //{
        //[2018.03.04.일][추가!!!]{-----------------------------------------
        //[사용] 인 경우는 [배경그림] 과 [크기/위치] 를 [재조정] 한다.
        //이는 [미사용] 의 경우는 [편집기] 크기 조정이나 [배경그림:교체] 시
        //반영되지 않기 때문.
        //}-----------------------------------------------------------------
        
        _GDotMatrix_ReSize();
        _GDotMatrix_BackBmpChange();

    //}

    //보이게 만든다.
    _GDotMatrix->Visible = true;

    //[환경변수] 에 저장된 이전 상태를 다시 복구한다.
	_GDotMatrix->_RotTimer(_ide_option->dotmatrixRotate);

    //[환경변수] 에 현재 상태를 기록한다.
    _ide_option->dotmatrixUse = true;

  }
  else
  {
    //[!]{-----------
    //[전광판] 끄기.
    //}--------------

    //일단 현재 [문자열 회전] 의 경우라면 무조건 정지시킨다.
    //이미 현재상태는 [환경변수] 에 저장돼 있으므로 별도 대피는 하지 않는다.
    _GDotMatrix->_RotTimer(false);

    //보이지 않게 만든다.
    _GDotMatrix->Visible = false;

    //[환경변수] 에 현재 상태를 기록한다.
    _ide_option->dotmatrixUse = false;

  }
  
}

void __fastcall Tide_editor_Form::_GDotMatrix_Rotate(//[2018.02.17.토][추가!!!]
                                                     //사용하는 경우는 true.
                                                     bool  pRotate)
{
  //[2010.02.23.화][생성!!!]{-------------------------------
  //현재 [문자열 회전] 상태를 반전한다.
  //
  //반전후 상태는 반드시 [환경변수] 에 기록해야 한다.
  //단, 현재 [중지] 상태라면 아무것도 처리하지 않아야 한다.
  //
  //[2018.02.17.토][수정!!!]--------------------------------
  //[사용여부] 를 인수로 전달 받아 처리하도록 수정.
  //}-------------------------------------------------------

  //[현재 문서가 열려있나?]
  //{
      //[2010.04.06.화][추가!!!]{------------------------------------------------
      //현재 [문서] 가 한개라도 열려 있는 경우는 [전광판] 을 보이지 않아야 한다.
      //}------------------------------------------------------------------------

      //열려있는 문서가 한개라도 있는 경우는 처리하지 않는다.
      if(editor_edit_Form->_textinfo_count > 0) return;

  //}

  //[사용중인가?]
  //{
      //반드시 [사용중] 인 경우만 처리해야 한다.
      if(_GDotMatrix->Visible != true) return;

  //}

  //[맷돌가상구동/직접연결 중인가?]
  //{
      //[2010.04.09.금][수정!!!]{----------------------------------------------------------
      //[맷돌가상구동] 이나 [맷돌직접연결] 인 경우는 각각 검증등에 영향을 주지 않도록
      //처리하지 않는다.
      //이는 [맷돌가상구동] 이나 [맷돌직접연결] 시 자동으로 [전광판] 동작이 중지되는데
      //[제목줄] 로 끌어 이동하는 경우등에서 다시 [활성화] 되도록 되어 있어, 여기서
      //다시 [활성화] 되는 것을 막기 위한것이다.
      //즉, [맷돌가상구동] 이나 [맷돌직접연결] 에서 한 설정이 바뀌지 않게 하기 위한것이다.
      //}----------------------------------------------------------------------------------

      if((ide_buttons_Form->_vmosSim_CheckBtn->_checked == true) ||
         (ide_buttons_Form->_vmosMdl_CheckBtn->_checked == true))
      {
        return;

      }

  //}
  
  if(pRotate == true)
  {
    //[!]{----------------
    //[문자열:회전] 적용.
    //}-------------------

    //[문자열 회전] 시작.
    _GDotMatrix->_RotTimer(true);

    //[환경변수] 에 현재 상태를 기록한다.
    _ide_option->dotmatrixRotate = true;

  }
  else
  {
    //[!]{----------------
    //[문자열:회전] 해제.
    //}-------------------

    //[문자열 회전] 을 정지시킨다.
    _GDotMatrix->_RotTimer(false);

    //[환경변수] 에 현재 상태를 기록한다.
    _ide_option->dotmatrixRotate = false;

  }

}

void __fastcall Tide_editor_Form::_GDotMatrix_RotateTemp(bool  pRotate)
{
  //[2010.02.23.화][생성!!!]{---------------------------------------------------
  //현재 [문자열 회전] 상태를 임시 설정한다.
  //이는 [문자열 회전] 상태에서는 전체이동, 크기조정시 끊어짐 문제가 발생하므로
  //이를 막기 위한 것이다.
  //필요한 부분에서 이 함수를 사용하여 일시 [중지/해제] 시킬수 있다.
  //}---------------------------------------------------------------------------

  //[현재 문서가 열려있나?]
  //{
      //[2010.04.06.화][추가!!!]{------------------------------------------------
      //현재 [문서] 가 한개라도 열려 있는 경우는 [전광판] 을 보이지 않아야 한다.
      //}------------------------------------------------------------------------

      //열려있는 문서가 한개라도 있는 경우는 처리하지 않는다.
      if(editor_edit_Form->_textinfo_count > 0) return;

  //}

  //[사용중인가?]
  //{
      //반드시 [사용중] 인 경우만 처리해야 한다.
      if(_GDotMatrix->Visible != true) return;

  //}

  //[맷돌가상구동/직접연결 중인가?]
  //{
      //[2010.04.09.금][수정!!!]{----------------------------------------------------------
      //[맷돌가상구동] 이나 [맷돌직접연결] 인 경우는 각각 검증등에 영향을 주지 않도록
      //처리하지 않는다.
      //이는 [맷돌가상구동] 이나 [맷돌직접연결] 시 자동으로 [전광판] 동작이 중지되는데
      //[제목줄] 로 끌어 이동하는 경우등에서 다시 [활성화] 되도록 되어 있어, 여기서
      //다시 [활성화] 되는 것을 막기 위한것이다.
      //즉, [맷돌가상구동] 이나 [맷돌직접연결] 에서 한 설정이 바뀌지 않게 하기 위한것이다.
      //}----------------------------------------------------------------------------------

      if((ide_buttons_Form->_vmosSim_CheckBtn->_checked == true) ||
         (ide_buttons_Form->_vmosMdl_CheckBtn->_checked == true))
      {
        return;

      }

  //}

  if(pRotate == true)
  {
    //[문자열 회전] 을 다시 시작하되 [환경변수] 의 설정을 다시 할당한다.
    _GDotMatrix->_RotTimer(_ide_option->dotmatrixRotate);

  }
  else
  {
    //[문자열 회전] 을 정지시킨다.
    _GDotMatrix->_RotTimer(false);

  }

}

void __fastcall Tide_editor_Form::_GDotMatrix_RotateTemp2(bool  pRotate)
{
  //[2010.04.09.금][생성!!!]{------------------------------------------------------
  //_GDotMatrix_RotateTemp() 와 완전히 같지만, [맷돌가상구동/직접연결] 을 확인하지
  //않고 무조건 처리한다.
  //이는 [맷돌가상구동/직접연결] 에서 전광판을 정지시킬때만 사용하는 전용함수이다.
  //}------------------------------------------------------------------------------

  //[현재 문서가 열려있나?]
  //{
      //[2010.04.06.화][추가!!!]{------------------------------------------------
      //현재 [문서] 가 한개라도 열려 있는 경우는 [전광판] 을 보이지 않아야 한다.
      //}------------------------------------------------------------------------

      //열려있는 문서가 한개라도 있는 경우는 처리하지 않는다.
      if(editor_edit_Form->_textinfo_count > 0) return;

  //}

  //[사용중인가?]
  //{
      //반드시 [사용중] 인 경우만 처리해야 한다.
      if(_GDotMatrix->Visible != true) return;

  //}

  if(pRotate == true)
  {
    //[문자열 회전] 을 다시 시작하되 [환경변수] 의 설정을 다시 할당한다.
    _GDotMatrix->_RotTimer(_ide_option->dotmatrixRotate);

  }
  else
  {
    //[문자열 회전] 을 정지시킨다.
    _GDotMatrix->_RotTimer(false);

  }

}







