diff options
author | Thales1330 <thaleslima.ufu@gmail.com> | 2016-12-29 14:14:21 -0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-29 14:14:21 -0200 |
commit | c5343c718cf80620c2fc7452a4315f7ddb9e5826 (patch) | |
tree | 3d5dbd283f31004cc6ef826c2b75d5e5ed9d9f27 /Project/Workspace.cpp | |
parent | 28e9cc4d9df63cb12c01d49017172c5f39ca9c22 (diff) | |
parent | 3750a0691f4975045647f3f70d8215fb1884e6fb (diff) | |
download | PSP.git-c5343c718cf80620c2fc7452a4315f7ddb9e5826.tar.gz PSP.git-c5343c718cf80620c2fc7452a4315f7ddb9e5826.tar.xz PSP.git-c5343c718cf80620c2fc7452a4315f7ddb9e5826.zip |
Merge pull request #4 from Thales1330/wip/copy-paste
Wip copy paste
Diffstat (limited to 'Project/Workspace.cpp')
-rw-r--r-- | Project/Workspace.cpp | 234 |
1 files changed, 204 insertions, 30 deletions
diff --git a/Project/Workspace.cpp b/Project/Workspace.cpp index bdb8211..2894ed2 100644 --- a/Project/Workspace.cpp +++ b/Project/Workspace.cpp @@ -10,6 +10,7 @@ #include "Load.h" #include "Inductor.h" #include "Capacitor.h" +#include "ElementDataObject.h" #include "Text.h" @@ -158,7 +159,7 @@ void Workspace::SetViewport() void Workspace::OnLeftClickDown(wxMouseEvent& event) { bool foundElement = false; - if(m_mode == MODE_INSERT_TEXT) { + if(m_mode == MODE_INSERT_TEXT || m_mode == MODE_PASTE) { m_mode = MODE_EDIT; } else if(m_mode == MODE_INSERT || m_mode == MODE_DRAG_INSERT || m_mode == MODE_DRAG_INSERT_TEXT) { // Get the last element inserted on the list. @@ -534,7 +535,8 @@ void Workspace::OnMouseMotion(wxMouseEvent& event) } } break; - case MODE_MOVE_ELEMENT: { + case MODE_MOVE_ELEMENT: + case MODE_PASTE: { for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) { Element* element = *it; // Parent's element moving... @@ -769,6 +771,15 @@ void Workspace::OnKeyDown(wxKeyEvent& event) m_mode = MODE_INSERT; m_statusBar->SetStatusText(_("Insert Capacitor: Click on a buses, ESC to cancel.")); Redraw(); + } else if(event.GetModifiers() == wxMOD_CONTROL) { // Copy. + CopySelection(); + } + } + } break; + case 'V': { + if(!insertingElement) { + if(event.GetModifiers() == wxMOD_CONTROL) { + Paste(); } } } break; @@ -788,6 +799,10 @@ void Workspace::UpdateStatusBar() m_statusBar->SetStatusText(_("MODE: DRAG"), 1); } break; + case MODE_PASTE: { + m_statusBar->SetStatusText(_("MODE: PASTE"), 1); + } + case MODE_INSERT: case MODE_INSERT_TEXT: case MODE_DRAG_INSERT: @@ -953,41 +968,53 @@ void Workspace::DeleteSelectedElements() Redraw(); } -void Workspace::Fit() +bool Workspace::GetElementsCorners(wxPoint2DDouble& leftUpCorner, + wxPoint2DDouble& rightDownCorner, + std::vector<Element*> elementList) { - if(m_elementList.size() > 0) { - wxPoint2DDouble leftUpCorner(0, 0); - wxPoint2DDouble rightDownCorner(0, 0); - m_elementList[0]->CalculateBoundaries(leftUpCorner, rightDownCorner); + if(elementList.size() == 0) return false; - for(auto it = m_elementList.begin() + 1; it != m_elementList.end(); it++) { - Element* element = *it; - wxPoint2DDouble leftUp; - wxPoint2DDouble rightDown; - element->CalculateBoundaries(leftUp, rightDown); - if(leftUp.m_x < leftUpCorner.m_x) leftUpCorner.m_x = leftUp.m_x; - if(leftUp.m_y < leftUpCorner.m_y) leftUpCorner.m_y = leftUp.m_y; - if(rightDown.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rightDown.m_x; - if(rightDown.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rightDown.m_y; - } + elementList[0]->CalculateBoundaries(leftUpCorner, rightDownCorner); - int width = 0.0; - int height = 0.0; - GetSize(&width, &height); + for(auto it = elementList.begin() + 1, itEnd = elementList.end(); it != itEnd; it++) { + Element* element = *it; + wxPoint2DDouble leftUp; + wxPoint2DDouble rightDown; + element->CalculateBoundaries(leftUp, rightDown); + if(leftUp.m_x < leftUpCorner.m_x) leftUpCorner.m_x = leftUp.m_x; + if(leftUp.m_y < leftUpCorner.m_y) leftUpCorner.m_y = leftUp.m_y; + if(rightDown.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rightDown.m_x; + if(rightDown.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rightDown.m_y; + } + return true; +} - double scaleX = double(width) / (rightDownCorner.m_x - leftUpCorner.m_x); - double scaleY = double(height) / (rightDownCorner.m_y - leftUpCorner.m_y); +void Workspace::Fit() +{ + wxPoint2DDouble leftUpCorner(0, 0); + wxPoint2DDouble rightDownCorner(0, 0); + std::vector<Element*> elementList = m_elementList; + for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) { + elementList.push_back(*it); + } - double scale = scaleX < scaleY ? scaleX : scaleY; - if(scale > m_camera->GetZoomMax()) scale = m_camera->GetZoomMax(); - if(scale < m_camera->GetZoomMin()) scale = m_camera->GetZoomMin(); + if(!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return; + int width = 0.0; + int height = 0.0; + GetSize(&width, &height); - m_camera->SetScale(scale); + double scaleX = double(width) / (rightDownCorner.m_x - leftUpCorner.m_x); + double scaleY = double(height) / (rightDownCorner.m_y - leftUpCorner.m_y); - m_camera->StartTranslation(leftUpCorner); - m_camera->SetTranslation(wxPoint2DDouble(0, 0)); - Redraw(); - } + double scale = scaleX < scaleY ? scaleX : scaleY; + if(scale > m_camera->GetZoomMax()) scale = m_camera->GetZoomMax(); + if(scale < m_camera->GetZoomMin()) scale = m_camera->GetZoomMin(); + + m_camera->SetScale(scale); + + m_camera->StartTranslation(leftUpCorner); + m_camera->SetTranslation(wxPoint2DDouble(0, 0)); + Redraw(); } void Workspace::ValidateBusesVoltages(Element* initialBus) @@ -1062,3 +1089,150 @@ void Workspace::UpdateTextElements() text->UpdateText(100e6); } } + +void Workspace::CopySelection() +{ + std::vector<Element*> selectedElements; + // The buses need to be numerated to associate the child's parents to the copies. + int busNumber = 0; + for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) { + Element* element = *it; + if(typeid(*element) == typeid(Bus)) { + Bus* bus = (Bus*)element; + auto data = bus->GetEletricalData(); + data.number = busNumber; + bus->SetElectricalData(data); + busNumber++; + } + if(element->IsSelected()) { + selectedElements.push_back(element); + } + } + for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) { + Text* text = *it; + if(text->IsSelected()) { + selectedElements.push_back(text); + } + } + ElementDataObject* dataObject = new ElementDataObject(selectedElements); + wxTheClipboard->SetData(dataObject); + wxTheClipboard->Close(); +} + +bool Workspace::Paste() +{ + if(wxTheClipboard->Open()) { + ElementDataObject dataObject; + + if(wxTheClipboard->IsSupported(wxDataFormat("PSPCopy"))) { + if(!wxTheClipboard->GetData(dataObject)) { + wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"), + wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition); + dialog.ShowModal(); + wxTheClipboard->Close(); + return false; + } + } else { + wxTheClipboard->Close(); + return false; + } + wxTheClipboard->Close(); + + UnselectAll(); + + std::vector<Element*> pastedElements; + ElementsLists* elementsLists = dataObject.GetElementsLists(); + + // Paste buses (parents). + auto parentList = elementsLists->parentList; + std::vector<Bus*> pastedBusList; // To set new parents; + for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) { + Element* copy = (*it)->GetCopy(); + if(copy) { + pastedElements.push_back((Bus*)copy); + pastedBusList.push_back((Bus*)copy); + m_elementList.push_back((Bus*)copy); + } + } + + // Paste other elements. + auto elementLists = elementsLists->elementList; + for(auto it = elementLists.begin(), itEnd = elementLists.end(); it != itEnd; ++it) { + Element* copy = (*it)->GetCopy(); + if(copy) { + // Check if is text element + if(typeid(*copy) == typeid(Text)) { + Text* text = (Text*)copy; + // Check if element associated with the text exists. + bool elementExist = false; + for(int i = 0; i < (int)m_elementList.size(); i++) { + if(text->GetElement() == m_elementList[i]) { + elementExist = true; + break; + } + } + if(elementExist) { + pastedElements.push_back(copy); + m_textList.push_back((Text*)copy); + } + } else { + // Change the parent if copied, otherwise remove it. + for(int j = 0; j < (int)copy->GetParentList().size(); j++) { + Bus* currentParent = (Bus*)copy->GetParentList()[j]; + if(currentParent) { + int parentNumber = currentParent->GetEletricalData().number; + bool parentCopied = false; + for(int k = 0; k < (int)pastedBusList.size(); k++) { + Bus* newParent = pastedBusList[k]; + if(parentNumber == newParent->GetEletricalData().number) + copy->ReplaceParent(currentParent, newParent); + } + if(!parentCopied) copy->RemoveParent(currentParent); + } + } + + pastedElements.push_back(copy); + m_elementList.push_back(copy); + } + } + } + + // Move elements (and nodes) to the mouse position. + // The start position it's the center of the pasted objects. + wxPoint2DDouble leftUpCorner, rightDownCorner; + GetElementsCorners(leftUpCorner, rightDownCorner, pastedElements); + wxPoint2DDouble startPosition = (leftUpCorner + rightDownCorner) / 2.0; + for(auto it = pastedElements.begin(), itEnd = pastedElements.end(); it != itEnd; ++it) { + Element* element = *it; + element->StartMove(startPosition); + element->Move(m_camera->GetMousePosition()); + for(int i = 0; i < (int)element->GetParentList().size(); i++) { + Element* parent = element->GetParentList()[i]; + element->MoveNode(parent, m_camera->GetMousePosition()); + } + } + } else { + wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"), + wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition); + dialog.ShowModal(); + return false; + } + + Redraw(); + m_mode = MODE_PASTE; + m_statusBar->SetStatusText(_("Click to paste.")); + UpdateStatusBar(); + return true; +} + +void Workspace::UnselectAll() +{ + for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; it++) { + Element* element = *it; + element->SetSelected(false); + } + for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; it++) { + Text* text = *it; + text->SetSelected(false); + } +} |