. 취소 조건

취소 기능 구현을 위한 자료구조 정의와 ApiEdit의 수정이 완료되었으며 이제 실제로 취소 레코드를 기록하는 함수들을 작성해보자. 동작이 복잡하기 때문에 많은 함수가 필요하다. 다음 함수들을 CApiEdit 클래스의 멤버함수로 추가한다.

 

class CApiEdit

{

     ....

     void URInsert(int nPos, TCHAR *str);

     void URDelete(int nPos, TCHAR *str);

     void URMove(int nPos, int Dest, TCHAR *str);

     void Undo();

     void Redo();

     BOOL CanUndo();

     BOOL CanRedo();

     void ClearRedo();

     void NextRecord();

     void AllocURData(int idx,int need,int extra);

 

앞쪽부터 순서대로 삽입 기록, 삭제 기록, 이동 기록, 취소, 재실행 함수이며 나머지 함수들은 이 함수들이 사용하는 유틸리티 함수들이다. 논리적인 순서에 따라 차례대로 구현하도록 하자.

먼저 유틸리티 함수 중에 비교적 이해하기 쉬운 CanUndo, CanRedo 함수부터 작성한다. 취소와 재실행은 항상 가능한 것이 아니라 일정한 조건을 만족할 때만 가능하다. CanUndo 함수는 현재 문서 상태에서 취소가 가능한지를 조사하는데 문서를 연 후 한 번이라도 편집을 했으면 가능하다. 문서를 연 직후나 모든 편집 동작이 다 취소된 상태에서는 더 이상 취소할 동작이 없다. 이 조건은 다음과 같이 정의된다.

 

BOOL CApiEdit::CanUndo()

{

     if (nowur == 0 && (pUR[0].action==UR_NONE || pUR[0].status==UR_CANCELED))

          return FALSE;

 

     return TRUE;

}

 

일단 취소가 불가능하려면 nowur 0, 즉 첫 번째 레코드에 있어야 한다. 이 상태에서 action이 정의되지 않았거나 취소된 레코드라면 더 이상 취소할 수 없다. 액션이 정의되지 않았다는 것은 문서를 연 후 한 번도 편집을 하지 않았다는 뜻이며 첫 번째 레코드가 취소되었다는 것은 편집은 했지만 모든 편집 동작이 취소되었다는 뜻이다. 그 외의 경우는 TRUE를 리턴하여 취소할 수 있음을 알려준다.

재실행 가능 조건은 더 간단하다. 재실행이란 취소된 레코드를 다시 실행하는 것이므로 현재 레코드가 취소된 레코드이면 가능하다. 즉 현재 레코드의 statusUR_CANCELED 이면 재실행할 수 있다. 현재 레코드가 만들어지고 있는 중(UR_MAKING)이면 재실행할 수 없다. Redo 함수의 코드는 다음과 같이 작성한다.

 

BOOL CApiEdit::CanRedo()

{

     if (pUR[nowur].status == UR_CANCELED) {

          return TRUE;

     } else {

          return FALSE;

     }

}

 

이 두 함수는 레코드 기록 함수에서 호출하기도 하지만 호스트에서 메뉴항목의 상태관리를 위해 호출하기도 한다.