[0] Page: beforeNum_start=-1, beforeNum_over=2, afterNum=2
[1] Ink:
[2] Step
[3] Step
Undo
Redo
m_Now
Undo_Buf* CMainFrame::m_UndoBuf
Undo_Buf::AllocNewStep
Undo_Buf::ClearAfterSteps
Undo_Buf::Undo
Undo_Buf::Redo
Undo_Buf::OnSaved
アンドゥ情報を記録する
現在位置(Undo_Buf::m_Now)より後の記録を消す
アンドゥする
リドゥする
保存したときの処理
Undo_Step_Com
Undo_Step
Undo_Step_Ink
Undo_Step_Page
Undo_Step_Text
アンドゥバッファ全体
アンドゥ情報の1つずつ
図形
インク
テキスト
ListX Undo_Buf::m_Steps;
CChildView::OnEditUndo
frame->m_UndoBuf->StartMulti();
frame->m_UndoBuf->AllocNewStep( m_BeforePrim, m_DragPrim->GetNewCopy( &app->m_file.m_prims ),
NULL, NULL, app->m_file.m_CurrentPageNum - app->m_file.m_StartPageNum );
frame->m_UndoBuf->EndMulti();
アンドゥ情報を記録する基本的なコード
m_BeforePrim は、ドラッグ開始で 非NULL になり、ドラッグ終了で NULL になる。
アンドゥするとき、接続関係がある図形も同時に操作することがあります。
接続関係は、通常、ポインタを使って参照できますが、削除した図形がアンドゥによって復活したときは、
ポインタを使えません。 そこで、ID番号を使います。
CadPrim::AdjustLinks
Text_Box
m_Controler ← m_Controler_id
m_Links : CadPrim_Link::prim ← CadPrim_Link::prim_id
Text_Box の位置指定方法
CadPrim::LinkMove
HoldPrimsの移動・変形や、アンドゥ・リドゥ
アンドゥバッファにリンク図形を入れない場合:
リンクの影響範囲について再考慮が必要(現在は1段階のみ対応)
Hold
Link1
Link2
テキストを編集したときのアンドゥは、入力や削除のブロックごとに行います。
最新のテキスト
入力または削除を
アンドゥした状態のテキスト
アンドゥ
リドゥ
[ テスト ]
Text_Editor::OnChar
/* 削除のアンドゥデータを保存する */
Text_Editor::OnChar
/* 追加のアンドゥデータを保存する */
Text_Editor::Undo
Text_Editor::Redo
Text_Editor::FixUndoPoint
Text_Editor::FixUndoPoint
UndoBuf::AllocNewStep_Text
アンドゥバッファ
アンドゥに関するデータは、2段階で記録されます。
FixUndoPoint でアンドゥ・リドゥする単位(ブロック)を確定します。
確定してから、AllocNewStep_Text で、アンドゥバッファに記録します。
参考:
CMainFrame::OnEditPaste_sub 関数の /* エディタ内にテキストを貼り付ける */
Undo_Step_Text クラス
pos
inputText
deleteText
アンドゥバッファの内容
入力したテキストのコピー( アンドゥで消す内容、リドゥで追加する内容)
削除したテキストのコピー( アンドゥで追加する内容、リドゥで消す内容)
入力または削除した位置。m_Undo_iStart と同じ座標
m_Undo_iStart
m_Undo_iEnd
m_Undo_DeletingText
m_Undo_i
m_Undo_InputText
m_Undo_DeleteText
追加テキストの開始位置(*1)
追加テキストの末尾の次の位置(*1)
(*1)
改行文字は "\r\n" なので、位置的には 2文字分になります。
削除したテキスト
アンドゥバッファに記録する、追加/削除したテキストの位置
アンドゥバッファに記録する、追加したテキストのコピー
アンドゥバッファに記録する、削除したテキストのコピー
以下は、Text_Editor::FixUndoPoint で、上記 3変数から作られ、アンドゥバッファに記録します。
(未確定ブロック)
(確定ブロック)
追加中
削除中
削除テキストの位置
初期状態(*1)
-1
-1
""
(同上)
""
未確定ブロックの変化の様子の例
m_Undo_DeletingText
m_Undo_iEnd
m_Undo_iStart
-1
-1
""
AB
C
A
0
1
""
0
5
補足
""
改行なので
End は 4ではない
A
C
1
1
"B"
FixUndoPoint もする
AC
"B\r\n"
1
1
ABC
2
""
1
FixUndoPoint もする
(*1) Text_Editor::FixUndoPoint を実行した後も、初期状態に戻ります
m_Undo_iStart = 5 ( 'a' の位置 )
m_Undo_iEnd = 8 ( '5' の位置 )
0123456789
… 元のテキスト
テキストの範囲を選択していないとき
01234abc56789
… 入力後のテキスト
abc
キャレットが、4 と 5 の間にあり、「abc」 を入力したとき、m_Undo_iStart と m_Undo_iEnd を設定します。
Text_Editor::OnChar
/* 追加のアンドゥデータを保存する */
ソース:
テキストの範囲を選択しているとき
選択中のテキストを削除してから追加します。
01234fghijk56789
… 元のテキスト、"abc" を選択中
01234abc56789
… 入力後のテキスト
abc
fghijk
m_Undo_iEnd = 11 ( '5' の位置 )
m_Undo_iStart = 5 ( 'f' の位置 )
m_Undo_DeletingText = ""
m_Undo_DeletingText = "abc"
編集中は、Text_Editor クラスの m_Undo_iStart、m_Undo_iEnd、m_Undo_DeletingText を更新します。
アンドゥ、リドゥする単位が確定したら、Text_Editor::FixUndoPoint で、m_Undo_i、m_Undo_InputText、
m_Undo_DeleteText にまとめてから、アンドゥバッファに記録します。
Text_Editor::FixUndoPoint
Undo_Buf::AllocNewStep_Text
Text_Editor::OnChar
/* 削除のアンドゥデータを保存する */
ソース:
0123456789
… 元のテキスト
01234abc56789
… 削除後のテキスト
abc
m_Undo_DeletingText = "abc"
m_Undo_iStart = 5 ( 'a' だった位置 )
m_Undo_iEnd = 5
"abc" を選択中に削除を行ったとき、削除した文字列 "abc" を m_Undo_DeletingText に設定し、
削除を行った位置を、m_Undo_iStart、 m_Undo_iEnd に設定します。
編集中は、m_Undo_iStart、m_Undo_iEnd、m_Undo_DeletingText を更新します。
アンドゥ、リドゥする単位が確定したら、Text_Editor::FixUndoPoint で、m_Undo_i、m_Undo_InputText、
m_Undo_DeleteText にまとめてから、アンドゥバッファに記録します。
Text_Editor::FixUndoPoint
Text_Editor::Undo
CChildView::OnEditUndo
ソースツリー
Text_Editor::FixUndoPoint
Undo_Buf::AllocNewStep_Text
Undo_Buf::Undo
/* テキストに対する操作のアンドゥをする */
編集中の状況を、アンドゥバッファに入れる
CChildView::EnableEditor
Undo_TextType
編集中の状況を、アンドゥバッファに入れる
エディタを起動する
テキストを編集する
Text_Editor::Undo の内容
void Text_Editor::Undo( int pos, const char* inputText, const char* deleteText );
pos の位置から、長さ = strlen( inputText ) だけ削除して、deleteTest を挿入します。
アンドゥが要求されたときに、編集中なら、アンドゥバッファに記録してから、アンドゥします。
編集中で無いなら、アンドゥするテキストのエディタを開いてから、アンドゥします。
Undo_Step_Text クラスの inputText と deleteText を入れ替えるだけで、他はアンドゥと同じです。
Text_Editor::Redo
CChildView::OnEditRedo
Undo_Buf::Redo
ソースツリー(差分)
ここでは、アンドゥとの差分だけ挙げています。
詳細のソースツリーは、テキストのアンドゥのソースツリーを
参照してください。
ページ操作や、キャンバスのプロパティのアンドゥ情報が格納されています。
ページタイトルの編集
ページの移動
ページの作成
ページの削除
記録する操作は次のものがあります。
Undo_Buf::Undo
ページに対する操作のアンドゥ
(Undo_Step_Page構造体)
アンドゥ、リドゥを行う関数を示します。
Undo_Buf::Undo
ページに対する操作のリドゥ
削除
新規作成
移動
CMainFrame::MovePage
関連
Undo_Step_Page のメンバ変数の意味を示します。
afterNum
beforeNum_over
beforeNum_start
移動
新規作成
削除
処理前の
開始ページ番号
処理前の
最後の次の
ページ番号
処理前の
移動先の
ページ番号
-1
タイトル修正
redoBaseNum
未使用
作成位置
兄弟上、
兄弟下、子
処理前の
作成位置の
ページ番号
redoBaseNum
移動先
兄弟上、
兄弟下、子
iFirstPage
afterTitle
beforeType
beforeType
移動前の状況
兄弟下、単独子
firstPage
beforeTitle
未使用
処理前の
最後の次の
ページ番号
処理前の
開始ページ番号
-1
Undo_DeletePageStep
Undo_NewPageStep
-2
Undo_EditTitleStep
ページ番号
未使用
→ Undo_Step_Page 構造体
参照
→ SVGCat_Page 構造体
Undo_Step_Page::beforeNum_start
Undo_Step_Page::beforeNum_over
Undo_Step_Page::afterNum
移動
移動前
ページの集合(処理前の移動前)
移動後の位置 (処理前の移動後の基準)
Undo_Step_Page::redoBaseNum
afterNum のどこへ移動するか、
兄弟上、兄弟下、子
移動前
移動先
・なし(新規)
・トップ
・ラスト
・途中
・子のトップ
・子のラスト
・子の途中
・なし(削除)
・トップ
・ラスト
・途中
・子のトップ
・子のラスト
・子の途中
タイトル編集