void CancelBaseSpecialModesExcept(int id)
 {
     if (id != MID_SPLIT_BLOCK && DoSplitBlock()) SplitBlockOff();
     if (id != MID_MERGE_BLOCKS && DoMergeBlocks()) MergeBlocksOff();
     if (id != MID_CREATE_BLOCK && DoCreateBlock()) CreateBlockOff();
     if (id != MID_DELETE_BLOCK && DoDeleteBlock()) DeleteBlockOff();
 }
void ViewerWindowBase::OnEditMenu(wxCommandEvent& event)
{
    bool turnEditorOn = menuBar->IsChecked(MID_ENABLE_EDIT);

    switch (event.GetId()) {

        case MID_ENABLE_EDIT:
            if (turnEditorOn) {
                TRACEMSG("turning on editor");
                if (!RequestEditorEnable(true)) {
                    menuBar->Check(MID_ENABLE_EDIT, false);
                    break;
                }
                EnableBaseEditorMenuItems(true);
                viewer->GetCurrentDisplay()->AddBlockBoundaryRows();    // add before push!
                viewer->EnableStacks();     // start up undo/redo stack system
                ProcessCommand(MID_DRAG_HORIZ);    // switch to drag mode
            } else {
                TRACEMSG("turning off editor");
                if (!RequestEditorEnable(false)) {   // cancelled
                    menuBar->Check(MID_ENABLE_EDIT, true);
                    break;
                }
                EnableBaseEditorMenuItems(false);
                viewer->GetCurrentDisplay()->RemoveBlockBoundaryRows();
                if (!(menuBar->IsChecked(MID_SELECT_COLS) || menuBar->IsChecked(MID_SELECT_ROWS) ||
                        menuBar->IsChecked(MID_SELECT_BLOCKS)))
                    ProcessCommand(MID_SELECT_RECT);
            }
            break;

        case MID_UNDO:
            TRACEMSG("undoing...");
            viewer->Undo();
            UpdateDisplay(viewer->GetCurrentDisplay());
            if (AlwaysSyncStructures()) SyncStructures();
            break;

        case MID_REDO:
            TRACEMSG("redoing...");
            viewer->Redo();
            UpdateDisplay(viewer->GetCurrentDisplay());
            if (AlwaysSyncStructures()) SyncStructures();
            break;

        case MID_SPLIT_BLOCK:
            CancelAllSpecialModesExcept(MID_SPLIT_BLOCK);
            if (DoSplitBlock())
                SetCursor(*wxCROSS_CURSOR);
            else
                SplitBlockOff();
            break;

        case MID_MERGE_BLOCKS:
            CancelAllSpecialModesExcept(MID_MERGE_BLOCKS);
            if (DoMergeBlocks()) {
                SetCursor(*wxCROSS_CURSOR);
                prevMouseMode = viewerWidget->GetMouseMode();
                viewerWidget->SetMouseMode(GetMouseModeForCreateAndMerge());
            } else
                MergeBlocksOff();
            break;

        case MID_CREATE_BLOCK:
            CancelAllSpecialModesExcept(MID_CREATE_BLOCK);
            if (DoCreateBlock()) {
                SetCursor(*wxCROSS_CURSOR);
                prevMouseMode = viewerWidget->GetMouseMode();
                viewerWidget->SetMouseMode(GetMouseModeForCreateAndMerge());
            } else
                CreateBlockOff();
            break;

        case MID_DELETE_BLOCK:
            CancelAllSpecialModesExcept(MID_DELETE_BLOCK);
            if (DoDeleteBlock())
                SetCursor(*wxCROSS_CURSOR);
            else
                DeleteBlockOff();
            break;

        case MID_SYNC_STRUCS:
            viewer->GetCurrentDisplay()->RedrawAlignedMolecules();
            break;
    }
}