doc.cpp

来自「Wxpython Implemented on Windows CE, Sou」· C++ 代码 · 共 594 行 · 第 1/2 页

CPP
594
字号
        // not actually added until this point).
        // The new 'saved state' is therefore 'nothing' since there
        // was nothing there before.

        wxASSERT( (m_shapeOnCanvas == NULL) );
        wxASSERT( (m_savedState != NULL) );
        wxASSERT( (m_doc != NULL) );

        m_shapeOnCanvas = m_savedState;
        m_savedState = NULL;

        m_doc->GetDiagram()->AddShape(m_shapeOnCanvas);
        m_shapeOnCanvas->Show(true);

        wxClientDC dc(m_shapeOnCanvas->GetCanvas());
        m_shapeOnCanvas->GetCanvas()->PrepareDC(dc);

        csEvtHandler *handler = (csEvtHandler *)m_shapeOnCanvas->GetEventHandler();
        m_shapeOnCanvas->FormatText(dc, handler->m_label);

        m_shapeOnCanvas->Move(dc, m_shapeOnCanvas->GetX(), m_shapeOnCanvas->GetY());

        if (m_cmd == ID_CS_ADD_SHAPE_SELECT)
        {
            m_shapeOnCanvas->Select(true, &dc);
            ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, true);
        }

        m_doc->Modify(true);
        m_doc->UpdateAllViews();
        break;
    }
    case ID_CS_ADD_LINE:
    case ID_CS_ADD_LINE_SELECT:
    {
        wxASSERT( (m_shapeOnCanvas == NULL) );
        wxASSERT( (m_savedState != NULL) );
        wxASSERT( (m_doc != NULL) );

        wxLineShape *lineShape = (wxLineShape *)m_savedState;
        wxASSERT( (lineShape->GetFrom() != NULL) );
        wxASSERT( (lineShape->GetTo() != NULL) );

        m_shapeOnCanvas = m_savedState;
        m_savedState = NULL;

        m_doc->GetDiagram()->AddShape(lineShape);

        lineShape->GetFrom()->AddLine(lineShape, lineShape->GetTo(),
            lineShape->GetAttachmentFrom(), lineShape->GetAttachmentTo());

        lineShape->Show(true);

        wxClientDC dc(lineShape->GetCanvas());
        lineShape->GetCanvas()->PrepareDC(dc);

        // It won't get drawn properly unless you move both
        // connected images
        lineShape->GetFrom()->Move(dc, lineShape->GetFrom()->GetX(), lineShape->GetFrom()->GetY());
        lineShape->GetTo()->Move(dc, lineShape->GetTo()->GetX(), lineShape->GetTo()->GetY());

        if (m_cmd == ID_CS_ADD_LINE_SELECT)
        {
            lineShape->Select(true, &dc);
            ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, true);
        }

        m_doc->Modify(true);
        m_doc->UpdateAllViews();
        break;
    }
    case ID_CS_CHANGE_BACKGROUND_COLOUR:
    case ID_CS_MOVE:
    case ID_CS_SIZE:
    case ID_CS_EDIT_PROPERTIES:
    case ID_CS_FONT_CHANGE:
    case ID_CS_ARROW_CHANGE:
    case ID_CS_ROTATE_CLOCKWISE:
    case ID_CS_ROTATE_ANTICLOCKWISE:
    case ID_CS_CHANGE_LINE_ORDERING:
    case ID_CS_CHANGE_LINE_ATTACHMENT:
    case ID_CS_ALIGN:
    case ID_CS_NEW_POINT:
    case ID_CS_CUT_POINT:
    case ID_CS_MOVE_LINE_POINT:
    case ID_CS_STRAIGHTEN:
    case ID_CS_MOVE_LABEL:
    {
        // At this point we have been given a new shape
        // just like the old one but with a changed colour.
        // It's now time to apply that change to the
        // shape on the canvas, saving the old state.
        // NOTE: this is general enough to work with MOST attribute
        // changes!

        wxASSERT( (m_shapeOnCanvas != NULL) );
        wxASSERT( (m_savedState != NULL) ); // This is the new shape with changed colour
        wxASSERT( (m_doc != NULL) );

        wxClientDC dc(m_shapeOnCanvas->GetCanvas());
        m_shapeOnCanvas->GetCanvas()->PrepareDC(dc);

        bool isSelected = m_shapeOnCanvas->Selected();
        if (isSelected)
            m_shapeOnCanvas->Select(false, & dc);

        if (m_cmd == ID_CS_SIZE || m_cmd == ID_CS_ROTATE_CLOCKWISE || m_cmd == ID_CS_ROTATE_ANTICLOCKWISE ||
            m_cmd == ID_CS_CHANGE_LINE_ORDERING || m_cmd == ID_CS_CHANGE_LINE_ATTACHMENT)
        {
            m_shapeOnCanvas->Erase(dc);
        }

        // TODO: make sure the ID is the same. Or, when applying the new state,
        // don't change the original ID.
        wxShape* tempShape = m_shapeOnCanvas->CreateNewCopy();

        // Apply the saved state to the shape on the canvas, by copying.
        m_savedState->CopyWithHandler(*m_shapeOnCanvas);

        // Delete this state now it's been used (m_shapeOnCanvas currently holds this state)
        delete m_savedState;

        // Remember the previous state
        m_savedState = tempShape;

        // Redraw the shape

        if (m_cmd == ID_CS_MOVE || m_cmd == ID_CS_ROTATE_CLOCKWISE || m_cmd == ID_CS_ROTATE_ANTICLOCKWISE ||
            m_cmd == ID_CS_ALIGN)
        {
            m_shapeOnCanvas->Move(dc, m_shapeOnCanvas->GetX(), m_shapeOnCanvas->GetY());

            csEvtHandler *handler = (csEvtHandler *)m_shapeOnCanvas->GetEventHandler();
            m_shapeOnCanvas->FormatText(dc, handler->m_label);
            m_shapeOnCanvas->Draw(dc);
        }
        else if (m_cmd == ID_CS_CHANGE_LINE_ORDERING)
        {
            m_shapeOnCanvas->MoveLinks(dc);
        }
        else if (m_cmd == ID_CS_CHANGE_LINE_ATTACHMENT)
        {
            wxLineShape *lineShape = (wxLineShape *)m_shapeOnCanvas;

            // Have to move both sets of links since we don't know which links
            // have been affected (unless we compared before and after states).
            lineShape->GetFrom()->MoveLinks(dc);
            lineShape->GetTo()->MoveLinks(dc);
        }
        else if (m_cmd == ID_CS_SIZE)
        {
            double width, height;
            m_shapeOnCanvas->GetBoundingBoxMax(&width, &height);

            m_shapeOnCanvas->SetSize(width, height);
            m_shapeOnCanvas->Move(dc, m_shapeOnCanvas->GetX(), m_shapeOnCanvas->GetY());

            m_shapeOnCanvas->Show(true);

            // Recursively redraw links if we have a composite.
            if (m_shapeOnCanvas->GetChildren().GetCount() > 0)
                m_shapeOnCanvas->DrawLinks(dc, -1, true);

            m_shapeOnCanvas->GetEventHandler()->OnEndSize(width, height);
        }
        else if (m_cmd == ID_CS_EDIT_PROPERTIES || m_cmd == ID_CS_FONT_CHANGE)
        {
            csEvtHandler *handler = (csEvtHandler *)m_shapeOnCanvas->GetEventHandler();
            m_shapeOnCanvas->FormatText(dc, handler->m_label);
            m_shapeOnCanvas->Draw(dc);
        }
        else
        {
            m_shapeOnCanvas->Draw(dc);
        }

        if (isSelected)
            m_shapeOnCanvas->Select(true, & dc);

        m_doc->Modify(true);
        m_doc->UpdateAllViews();

        break;
    }
  }
  return true;
}

bool csCommandState::Undo()
{
  switch (m_cmd)
  {
    case ID_CS_CUT:
    {
        wxASSERT( (m_savedState != NULL) );
        wxASSERT( (m_doc != NULL) );

        m_doc->GetDiagram()->AddShape(m_savedState);
        m_shapeOnCanvas = m_savedState;
        m_savedState = NULL;

        if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape)))
        {
            wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas;
            lineShape->GetFrom()->AddLine(lineShape, lineShape->GetTo(),
                lineShape->GetAttachmentFrom(), lineShape->GetAttachmentTo(),
                m_linePositionFrom, m_linePositionTo);

            wxShapeCanvas* canvas = lineShape->GetFrom()->GetCanvas();

            wxClientDC dc(canvas);
            canvas->PrepareDC(dc);

            lineShape->GetFrom()->MoveLinks(dc);
            lineShape->GetTo()->MoveLinks(dc);

        }
        m_shapeOnCanvas->Show(true);

        m_doc->Modify(true);
        m_doc->UpdateAllViews();
        break;
    }
    case ID_CS_ADD_SHAPE:
    case ID_CS_ADD_LINE:
    case ID_CS_ADD_SHAPE_SELECT:
    case ID_CS_ADD_LINE_SELECT:
    {
        wxASSERT( (m_shapeOnCanvas != NULL) );
        wxASSERT( (m_savedState == NULL) );
        wxASSERT( (m_doc != NULL) );

        // In case this is a line
        wxShape* lineFrom = NULL;
        wxShape* lineTo = NULL;
        int attachmentFrom = 0, attachmentTo = 0;

        if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape)))
        {
            // Store the from/to info to save in the line shape
            wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas;
            lineFrom = lineShape->GetFrom();
            lineTo = lineShape->GetTo();
            attachmentFrom = lineShape->GetAttachmentFrom();
            attachmentTo = lineShape->GetAttachmentTo();
        }

        wxClientDC dc(m_shapeOnCanvas->GetCanvas());
        m_shapeOnCanvas->GetCanvas()->PrepareDC(dc);

        m_shapeOnCanvas->Select(false, &dc);
        ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, false);
        m_doc->GetDiagram()->RemoveShape(m_shapeOnCanvas);
        m_shapeOnCanvas->Unlink(); // Unlinks the line, if it is a line

        if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape)))
        {
            // Restore the from/to info for future reference
            wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas;
            lineShape->SetFrom(lineFrom);
            lineShape->SetTo(lineTo);
            lineShape->SetAttachments(attachmentFrom, attachmentTo);
        }

        m_savedState = m_shapeOnCanvas;
        m_shapeOnCanvas = NULL;

        m_doc->Modify(true);
        m_doc->UpdateAllViews();
        break;
    }
    case ID_CS_CHANGE_BACKGROUND_COLOUR:
    case ID_CS_MOVE:
    case ID_CS_SIZE:
    case ID_CS_EDIT_PROPERTIES:
    case ID_CS_FONT_CHANGE:
    case ID_CS_ARROW_CHANGE:
    case ID_CS_ROTATE_CLOCKWISE:
    case ID_CS_ROTATE_ANTICLOCKWISE:
    case ID_CS_CHANGE_LINE_ORDERING:
    case ID_CS_CHANGE_LINE_ATTACHMENT:
    case ID_CS_ALIGN:
    case ID_CS_NEW_POINT:
    case ID_CS_CUT_POINT:
    case ID_CS_MOVE_LINE_POINT:
    case ID_CS_STRAIGHTEN:
    case ID_CS_MOVE_LABEL:
    {
        // Exactly like the Do case; we're just swapping states.
        Do();
        break;
    }
  }

    return true;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?