3030#include " Windchestgroup.h"
3131#include " OrganFileParser.h"
3232#include " CopyElementAttributesDialog.h"
33+ #include < vector>
34+ #include < algorithm>
3335
3436// Event table
3537BEGIN_EVENT_TABLE (GOODFFrame, wxFrame)
@@ -1287,12 +1289,14 @@ void GOODFFrame::OnOrganTreeRightClicked(wxTreeEvent& event) {
12871289}
12881290
12891291void GOODFFrame::OnOrganTreeLeftDrag (wxTreeEvent& event) {
1290- // Only allow dragging if item is a switch, manual, windchestgroup, rank
1292+ // Only allow dragging if item is a switch, manual, windchestgroup, rank, stop
12911293 wxTreeItemId sourceItem = event.GetItem ();
1292- if ((m_organTreeCtrl->GetItemParent (sourceItem) == tree_switches && m_organTreeCtrl->GetChildrenCount (tree_switches, false ) > 1 ) ||
1293- (m_organTreeCtrl->GetItemParent (sourceItem) == tree_manuals && m_organTreeCtrl->GetChildrenCount (tree_manuals, false ) > 1 ) ||
1294- (m_organTreeCtrl->GetItemParent (sourceItem) == tree_windchestgrps && m_organTreeCtrl->GetChildrenCount (tree_windchestgrps, false ) > 1 ) ||
1295- (m_organTreeCtrl->GetItemParent (sourceItem) == tree_ranks && m_organTreeCtrl->GetChildrenCount (tree_ranks, false ) > 1 )
1294+ wxTreeItemId sourceParent = m_organTreeCtrl->GetItemParent (sourceItem);
1295+ if ((sourceParent == tree_switches && m_organTreeCtrl->GetChildrenCount (tree_switches, false ) > 1 ) ||
1296+ (sourceParent == tree_manuals && m_organTreeCtrl->GetChildrenCount (tree_manuals, false ) > 1 ) ||
1297+ (sourceParent == tree_windchestgrps && m_organTreeCtrl->GetChildrenCount (tree_windchestgrps, false ) > 1 ) ||
1298+ (sourceParent == tree_ranks && m_organTreeCtrl->GetChildrenCount (tree_ranks, false ) > 1 ) ||
1299+ (m_organTreeCtrl->GetItemText (sourceParent) == wxT (" Stops" ) && m_organTreeCtrl->GetItemText (m_organTreeCtrl->GetNextSibling (sourceParent)) == wxT (" Couplers" ))
12961300 ) {
12971301 m_draggedItem = sourceItem;
12981302 event.Allow ();
@@ -1302,9 +1306,13 @@ void GOODFFrame::OnOrganTreeLeftDrag(wxTreeEvent& event) {
13021306void GOODFFrame::OnOrganTreeDragCompleted (wxTreeEvent& event) {
13031307 wxTreeItemId srcItem = m_draggedItem;
13041308 wxTreeItemId dstItem = event.GetItem ();
1309+ wxTreeItemId srcParent = m_organTreeCtrl->GetItemParent (srcItem);
1310+ wxTreeItemId dstParent = m_organTreeCtrl->GetItemParent (dstItem);
1311+ wxTreeItemId srcGrandParent = m_organTreeCtrl->GetItemParent (srcParent);
1312+ wxTreeItemId dstGrandParent = m_organTreeCtrl->GetItemParent (dstParent);
13051313 m_draggedItem = (wxTreeItemId) 0l ;
13061314
1307- if (m_organTreeCtrl-> GetItemParent (dstItem) == tree_switches && m_organTreeCtrl-> GetItemParent (srcItem) == tree_switches) {
1315+ if (dstParent == tree_switches && srcParent == tree_switches) {
13081316 // we drop it after target switch but first check if the move really should happen
13091317 if (m_organTreeCtrl->GetNextSibling (dstItem) == srcItem) {
13101318 return ;
@@ -1334,7 +1342,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
13341342 m_organTreeCtrl->Delete (srcItem);
13351343 m_organ->moveSwitch (sourceIndex, targetIndex);
13361344 m_organTreeCtrl->SelectItem (newPos);
1337- } else if (dstItem == tree_switches && m_organTreeCtrl-> GetItemParent (srcItem) == tree_switches) {
1345+ } else if (dstItem == tree_switches && srcParent == tree_switches) {
13381346 // we make it first child
13391347 int sourceIndex = 0 ;
13401348 int numChildrens = m_organTreeCtrl->GetChildrenCount (tree_switches, false );
@@ -1354,7 +1362,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
13541362 m_organTreeCtrl->Delete (srcItem);
13551363 m_organ->moveSwitch (sourceIndex, 0 );
13561364 m_organTreeCtrl->SelectItem (newPos);
1357- } else if (m_organTreeCtrl-> GetItemParent (dstItem) == tree_manuals && m_organTreeCtrl-> GetItemParent (srcItem) == tree_manuals) {
1365+ } else if (dstParent == tree_manuals && srcParent == tree_manuals) {
13581366 // we drop it after target manual but first check if the move really should happen
13591367 if (m_organTreeCtrl->GetNextSibling (dstItem) == srcItem) {
13601368 return ;
@@ -1427,7 +1435,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
14271435 m_organTreeCtrl->Delete (srcItem);
14281436 m_organ->moveManual (sourceIndex, targetIndex);
14291437 m_organTreeCtrl->SelectItem (newPos);
1430- } else if (dstItem == tree_manuals && m_organTreeCtrl-> GetItemParent (srcItem) == tree_manuals) {
1438+ } else if (dstItem == tree_manuals && srcParent == tree_manuals) {
14311439 // we make it first child
14321440 int sourceIndex = 0 ;
14331441 int numChildrens = m_organTreeCtrl->GetChildrenCount (tree_manuals, false );
@@ -1490,7 +1498,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
14901498 m_organTreeCtrl->Delete (srcItem);
14911499 m_organ->moveManual (sourceIndex, 0 );
14921500 m_organTreeCtrl->SelectItem (newPos);
1493- } else if (m_organTreeCtrl-> GetItemParent (dstItem) == tree_windchestgrps && m_organTreeCtrl-> GetItemParent (srcItem) == tree_windchestgrps) {
1501+ } else if (dstParent == tree_windchestgrps && srcParent == tree_windchestgrps) {
14941502 // we drop it after target windchestgroup but first check if the move really should happen
14951503 if (m_organTreeCtrl->GetNextSibling (dstItem) == srcItem) {
14961504 return ;
@@ -1520,7 +1528,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
15201528 m_organTreeCtrl->Delete (srcItem);
15211529 m_organ->moveWindchestgroup (sourceIndex, targetIndex);
15221530 m_organTreeCtrl->SelectItem (newPos);
1523- } else if (dstItem == tree_windchestgrps && m_organTreeCtrl-> GetItemParent (srcItem) == tree_windchestgrps) {
1531+ } else if (dstItem == tree_windchestgrps && srcParent == tree_windchestgrps) {
15241532 // we make it first child
15251533 int sourceIndex = 0 ;
15261534 int numChildrens = m_organTreeCtrl->GetChildrenCount (tree_windchestgrps, false );
@@ -1541,7 +1549,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
15411549 m_organTreeCtrl->Delete (srcItem);
15421550 m_organ->moveWindchestgroup (sourceIndex, 0 );
15431551 m_organTreeCtrl->SelectItem (newPos);
1544- } else if (m_organTreeCtrl-> GetItemParent (dstItem) == tree_ranks && m_organTreeCtrl-> GetItemParent (srcItem) == tree_ranks) {
1552+ } else if (dstParent == tree_ranks && srcParent == tree_ranks) {
15451553 // we drop it after target rank but first check if the move really should happen
15461554 if (m_organTreeCtrl->GetNextSibling (dstItem) == srcItem) {
15471555 return ;
@@ -1571,7 +1579,7 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
15711579 m_organTreeCtrl->Delete (srcItem);
15721580 m_organ->moveRank (sourceIndex, targetIndex);
15731581 m_organTreeCtrl->SelectItem (newPos);
1574- } else if (dstItem == tree_ranks && m_organTreeCtrl-> GetItemParent (srcItem) == tree_ranks) {
1582+ } else if (dstItem == tree_ranks && srcParent == tree_ranks) {
15751583 // we make it first child
15761584 int sourceIndex = 0 ;
15771585 int numChildrens = m_organTreeCtrl->GetChildrenCount (tree_ranks, false );
@@ -1592,6 +1600,119 @@ void GOODFFrame::OnOrganTreeDragCompleted(wxTreeEvent& event) {
15921600 m_organTreeCtrl->Delete (srcItem);
15931601 m_organ->moveRank (sourceIndex, 0 );
15941602 m_organTreeCtrl->SelectItem (newPos);
1603+ } else if (m_organTreeCtrl->GetItemText (srcParent) == wxT (" Stops" ) && m_organTreeCtrl->GetItemText (m_organTreeCtrl->GetNextSibling (srcParent)) == wxT (" Couplers" )) {
1604+ // The source item is certainly a stop, allowed drop destinations are another stop, the stop main category and a manual
1605+ std::vector<wxTreeItemId> manualsInTree;
1606+ int nbrManuals = m_organTreeCtrl->GetChildrenCount (tree_manuals, false );
1607+ wxTreeItemIdValue cookie;
1608+ for (int i = 0 ; i < nbrManuals; i++) {
1609+ wxTreeItemId currentMan;
1610+ if (i == 0 )
1611+ currentMan = m_organTreeCtrl->GetFirstChild (tree_manuals, cookie);
1612+ else
1613+ currentMan = m_organTreeCtrl->GetNextChild (tree_manuals, cookie);
1614+
1615+ manualsInTree.push_back (currentMan);
1616+ }
1617+
1618+ // Get what index the source stop had to begin with
1619+ int srcStopIdx = -1 ;
1620+ int nbrSrcStops = m_organTreeCtrl->GetChildrenCount (srcParent, false );
1621+ wxTreeItemIdValue srcCookie;
1622+ for (int i = 0 ; i < nbrSrcStops; i++) {
1623+ wxTreeItemId currentStop;
1624+ if (i == 0 )
1625+ currentStop = m_organTreeCtrl->GetFirstChild (srcParent, srcCookie);
1626+ else
1627+ currentStop = m_organTreeCtrl->GetNextChild (srcParent, srcCookie);
1628+
1629+ if (currentStop == srcItem) {
1630+ srcStopIdx = i;
1631+ break ;
1632+ }
1633+ }
1634+
1635+ if (m_organTreeCtrl->GetItemText (dstParent) == wxT (" Stops" ) && m_organTreeCtrl->GetItemText (m_organTreeCtrl->GetNextSibling (dstParent)) == wxT (" Couplers" )) {
1636+ // The destination item is another stop, should the move proceed?
1637+ if (m_organTreeCtrl->GetNextSibling (dstItem) == srcItem) {
1638+ return ;
1639+ }
1640+
1641+ // Get what manual each of the stops belongs to
1642+ int srcManualIdx = -1 ;
1643+ int dstManualIdx = -1 ;
1644+ for (unsigned i = 0 ; i < manualsInTree.size (); i++) {
1645+ if (m_organTreeCtrl->GetItemText (manualsInTree[i]) == m_organTreeCtrl->GetItemText (srcGrandParent))
1646+ srcManualIdx = i;
1647+ if (m_organTreeCtrl->GetItemText (manualsInTree[i]) == m_organTreeCtrl->GetItemText (dstGrandParent))
1648+ dstManualIdx = i;
1649+ }
1650+
1651+ // Get what index the destination stop has
1652+ int dstStopIdx = -1 ;
1653+ int nbrDstStops = m_organTreeCtrl->GetChildrenCount (dstParent, false );
1654+ wxTreeItemIdValue dstCookie;
1655+ for (int i = 0 ; i < nbrDstStops; i++) {
1656+ wxTreeItemId currentStop;
1657+ if (i == 0 )
1658+ currentStop = m_organTreeCtrl->GetFirstChild (dstParent, dstCookie);
1659+ else
1660+ currentStop = m_organTreeCtrl->GetNextChild (dstParent, dstCookie);
1661+
1662+ if (currentStop == dstItem) {
1663+ dstStopIdx = i;
1664+ break ;
1665+ }
1666+ }
1667+ if (dstStopIdx < nbrDstStops) {
1668+ dstStopIdx += 1 ;
1669+ }
1670+
1671+ // Now we should know the source and destination index of respective manual and stop
1672+ if (m_organ->moveStop (srcManualIdx, srcStopIdx, dstManualIdx, dstStopIdx)) {
1673+ // The move succeeded in the organ so now it's just to take care of it in tree
1674+ wxTreeItemId newPos = m_organTreeCtrl->InsertItem (dstParent, dstItem, m_organTreeCtrl->GetItemText (srcItem));
1675+ m_organTreeCtrl->Delete (srcItem);
1676+ m_organTreeCtrl->SelectItem (newPos);
1677+ }
1678+ } else if ((std::find (manualsInTree.begin (), manualsInTree.end (), dstItem) != manualsInTree.end () && dstParent == tree_manuals) ||
1679+ (std::find (manualsInTree.begin (), manualsInTree.end (), dstParent) != manualsInTree.end () && m_organTreeCtrl->GetItemText (dstItem) == wxT (" Stops" ))
1680+ ) {
1681+ // The destination is a manual or a stops category, should the move proceed?
1682+ if (srcGrandParent == dstItem && m_organTreeCtrl->GetChildrenCount (srcParent, false ) < 2 ) {
1683+ return ;
1684+ } else if (srcParent == dstItem && m_organTreeCtrl->GetChildrenCount (srcParent, false ) < 2 ) {
1685+ return ;
1686+ }
1687+ // Get what manual the source stop belongs to and what manual is the destination
1688+ int srcManualIdx = -1 ;
1689+ int dstManualIdx = -1 ;
1690+ for (unsigned i = 0 ; i < manualsInTree.size (); i++) {
1691+ if (m_organTreeCtrl->GetItemText (manualsInTree[i]) == m_organTreeCtrl->GetItemText (srcGrandParent))
1692+ srcManualIdx = i;
1693+ if ((m_organTreeCtrl->GetItemText (manualsInTree[i]) == m_organTreeCtrl->GetItemText (dstItem)) ||
1694+ (m_organTreeCtrl->GetItemText (manualsInTree[i]) == m_organTreeCtrl->GetItemText (dstParent))
1695+ )
1696+ dstManualIdx = i;
1697+ }
1698+
1699+ // Target we will be the first (0th) element
1700+ int dstStopIdx = 0 ;
1701+ // Now we should know the source and destination index of respective manual and stop
1702+ if (m_organ->moveStop (srcManualIdx, srcStopIdx, dstManualIdx, dstStopIdx)) {
1703+ // The move succeeded in the organ so now it's just to take care of it in tree
1704+ wxTreeItemId newPos;
1705+ if (m_organTreeCtrl->GetItemText (dstItem) == wxT (" Stops" )) {
1706+ newPos = m_organTreeCtrl->InsertItem (dstItem, 0 , m_organTreeCtrl->GetItemText (srcItem));
1707+ } else {
1708+ wxTreeItemIdValue stopsCookie;
1709+ wxTreeItemId stopCategory = m_organTreeCtrl->GetFirstChild (dstItem, stopsCookie);
1710+ newPos = m_organTreeCtrl->InsertItem (stopCategory, 0 , m_organTreeCtrl->GetItemText (srcItem));
1711+ }
1712+ m_organTreeCtrl->Delete (srcItem);
1713+ m_organTreeCtrl->SelectItem (newPos);
1714+ }
1715+ }
15951716 }
15961717
15971718}
0 commit comments