doc.cpp

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

CPP
594
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        contrib/samples/ogl/studio/doc.cpp
// Purpose:     Implements document functionality
// Author:      Julian Smart
// Modified by:
// Created:     12/07/98
// RCS-ID:      $Id: doc.cpp,v 1.11 2006/02/10 11:59:48 ABX Exp $
// Copyright:   (c) Julian Smart
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "studio.h"
#include "doc.h"
#include "view.h"
#include "wx/ogl/basicp.h"

IMPLEMENT_DYNAMIC_CLASS(csDiagramDocument, wxDocument)

#ifdef __VISUALC__
#pragma warning(disable:4355)
#endif

csDiagramDocument::csDiagramDocument():m_diagram(this)
{
}

#ifdef __VISUALC__
#pragma warning(default:4355)
#endif

csDiagramDocument::~csDiagramDocument()
{
}

bool csDiagramDocument::OnCloseDocument()
{
  m_diagram.DeleteAllShapes();
  return true;
}

#if wxUSE_PROLOGIO
bool csDiagramDocument::OnSaveDocument(const wxString& file)
{
  if (file == wxEmptyString)
    return false;

  if (!m_diagram.SaveFile(file))
  {
    wxString msgTitle;
    if (wxTheApp->GetAppName() != wxEmptyString)
        msgTitle = wxTheApp->GetAppName();
    else
        msgTitle = wxString(_T("File error"));

    (void)wxMessageBox(_T("Sorry, could not open this file for saving."), msgTitle, wxOK | wxICON_EXCLAMATION,
      GetDocumentWindow());
    return false;
  }

  Modify(false);
  SetFilename(file);
  return true;
}

bool csDiagramDocument::OnOpenDocument(const wxString& file)
{
  if (!OnSaveModified())
    return false;

  wxString msgTitle;
  if (wxTheApp->GetAppName() != wxEmptyString)
    msgTitle = wxTheApp->GetAppName();
  else
    msgTitle = wxString(_T("File error"));

  m_diagram.DeleteAllShapes();
  if (!m_diagram.LoadFile(file))
  {
    (void)wxMessageBox(_T("Sorry, could not open this file."), msgTitle, wxOK|wxICON_EXCLAMATION,
     GetDocumentWindow());
    return false;
  }
  SetFilename(file, true);
  Modify(false);
  UpdateAllViews();

  return true;
}
#endif // wxUSE_PROLOGIO


/*
 * Implementation of drawing command
 */

csDiagramCommand::csDiagramCommand(const wxString& name, csDiagramDocument *doc,
    csCommandState* onlyState):
  wxCommand(true, name)
{
  m_doc = doc;

  if (onlyState)
  {
    AddState(onlyState);
  }
}

csDiagramCommand::~csDiagramCommand()
{
    wxObjectList::compatibility_iterator node = m_states.GetFirst();
    while (node)
    {
        csCommandState* state = (csCommandState*) node->GetData();
        delete state;
        node = node->GetNext();
    }
}

void csDiagramCommand::AddState(csCommandState* state)
{
    state->m_doc = m_doc;
//    state->m_cmd = m_cmd;
    m_states.Append(state);
}

// Insert a state at the beginning of the list
void csDiagramCommand::InsertState(csCommandState* state)
{
    state->m_doc = m_doc;
//    state->m_cmd = m_cmd;
    m_states.Insert(state);
}

// Schedule all lines connected to the states to be cut.
void csDiagramCommand::RemoveLines()
{
    wxObjectList::compatibility_iterator node = m_states.GetFirst();
    while (node)
    {
        csCommandState* state = (csCommandState*) node->GetData();
        wxShape* shape = state->GetShapeOnCanvas();
        wxASSERT( (shape != NULL) );

        wxObjectList::compatibility_iterator node1 = shape->GetLines().GetFirst();
        while (node1)
        {
            wxLineShape *line = (wxLineShape *)node1->GetData();
            if (!FindStateByShape(line))
            {
                csCommandState* newState = new csCommandState(ID_CS_CUT, NULL, line);
                InsertState(newState);
            }

            node1 = node1->GetNext();
        }
        node = node->GetNext();
    }
}

csCommandState* csDiagramCommand::FindStateByShape(wxShape* shape)
{
    wxObjectList::compatibility_iterator node = m_states.GetFirst();
    while (node)
    {
        csCommandState* state = (csCommandState*) node->GetData();
        if (shape == state->GetShapeOnCanvas() || shape == state->GetSavedState())
            return state;
        node = node->GetNext();
    }
    return NULL;
}

bool csDiagramCommand::Do()
{
    wxObjectList::compatibility_iterator node = m_states.GetFirst();
    while (node)
    {
        csCommandState* state = (csCommandState*) node->GetData();
        if (!state->Do())
            return false;
        node = node->GetNext();
    }
    return true;
}

bool csDiagramCommand::Undo()
{
    // Undo in reverse order, so e.g. shapes get added
    // back before the lines do.
    wxObjectList::compatibility_iterator node = m_states.GetLast();
    while (node)
    {
        csCommandState* state = (csCommandState*) node->GetData();
        if (!state->Undo())
            return false;
        node = node->GetPrevious();
    }
    return true;
}

csCommandState::csCommandState(int cmd, wxShape* savedState, wxShape* shapeOnCanvas)
{
    m_cmd = cmd;
    m_doc = NULL;
    m_savedState = savedState;
    m_shapeOnCanvas = shapeOnCanvas;
    m_linePositionFrom = 0;
    m_linePositionTo = 0;
}

csCommandState::~csCommandState()
{
    if (m_savedState)
    {
        m_savedState->SetCanvas(NULL);
        delete m_savedState;
    }
}

bool csCommandState::Do()
{
  switch (m_cmd)
  {
    case ID_CS_CUT:
    {
        // New state is 'nothing' - maybe pass shape ID to state so we know what
        // we're talking about.
        // Then save old shape in m_savedState (actually swap pointers)

        wxASSERT( (m_shapeOnCanvas != NULL) );
        wxASSERT( (m_savedState == NULL) ); // new state will be 'nothing'
        wxASSERT( (m_doc != NULL) );

        wxShapeCanvas* canvas = m_shapeOnCanvas->GetCanvas();

        // 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();

            m_linePositionFrom = lineFrom->GetLinePosition(lineShape);
            m_linePositionTo = lineTo->GetLinePosition(lineShape);
        }

        m_shapeOnCanvas->Select(false);
        ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, false);

        m_shapeOnCanvas->Unlink();

        m_doc->GetDiagram()->RemoveShape(m_shapeOnCanvas);

        m_savedState = m_shapeOnCanvas;

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

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

            lineFrom->MoveLinks(dc);
            lineTo->MoveLinks(dc);
        }

        m_doc->Modify(true);
        m_doc->UpdateAllViews();
        break;
    }
    case ID_CS_ADD_SHAPE:
    case ID_CS_ADD_SHAPE_SELECT:
    {
        // The app has given the command state a new m_savedState
        // shape, which is the new shape to add to the canvas (but

⌨️ 快捷键说明

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