void TrackList::ClearPendingTracks( ListOfTracks *pAdded ) // NOFAIL-GUARANTEE { for (const auto &pTrack: mPendingUpdates) pTrack->SetOwner( {}, {} ); mPendingUpdates.clear(); mUpdaters.clear(); if (pAdded) pAdded->clear(); for (auto it = ListOfTracks::begin(), stop = ListOfTracks::end(); it != stop;) { if (it->get()->GetId() == TrackId{}) { if (pAdded) pAdded->push_back( *it ); (*it)->SetOwner( {}, {} ); it = erase( it ); } else ++it; } if (!empty()) RecalcPositions(getBegin()); }
BOOL HexView::OpenFile(LPCTSTR szFileName, UINT uOpenFlags) { bool fReadonly = (uOpenFlags & HVOF_READONLY) ? true : false; bool fQuickload = (uOpenFlags & HVOF_QUICKLOAD) ? true : false; bool fQuicksave = (uOpenFlags & HVOF_QUICKSAVE) ? true : false; // try to open as the caller requests us if(m_pDataSeq->open(szFileName, fReadonly, fQuickload)) { TCHAR *fp; DWORD e = GetLastError(); GetFullPathName(szFileName, MAX_PATH, m_szFilePath, &fp); RecalcPositions(); SetCaretPos((m_nAddressWidth + m_nHexPaddingLeft) * m_nFontHeight, 0); UpdateMetrics(); SetLastError(e); if(m_pDataSeq->isreadonly()) m_nEditMode = HVMODE_READONLY; else m_nEditMode = HVMODE_OVERWRITE; m_nSearchLen = 0; return TRUE; } return FALSE; }
bool TrackList::ApplyPendingTracks() { bool result = false; ListOfTracks additions; ListOfTracks updates; { // Always clear, even if one of the update functions throws auto cleanup = finally( [&] { ClearPendingTracks( &additions ); } ); UpdatePendingTracks(); updates.swap( mPendingUpdates ); } // Remaining steps must be NOFAIL-GUARANTEE so that this function // gives STRONG-GUARANTEE std::vector< std::shared_ptr<Track> > reinstated; for (auto &pendingTrack : updates) { if (pendingTrack) { auto src = FindById( pendingTrack->GetId() ); if (src) this->Replace(src, pendingTrack), result = true; else // Perhaps a track marked for pending changes got deleted by // some other action. Recreate it so we don't lose the // accumulated changes. reinstated.push_back(pendingTrack); } } // If there are tracks to reinstate, append them to the list. for (auto &pendingTrack : reinstated) if (pendingTrack) this->Add( pendingTrack ), result = true; // Put the pending added tracks back into the list, preserving their // positions. bool inserted = false; ListOfTracks::iterator first; for (auto &pendingTrack : additions) { if (pendingTrack) { auto iter = ListOfTracks::begin(); std::advance( iter, pendingTrack->GetIndex() ); iter = ListOfTracks::insert( iter, pendingTrack ); pendingTrack->SetOwner( shared_from_this(), {iter, this} ); pendingTrack->SetId( TrackId{ ++sCounter } ); if (!inserted) { first = iter; inserted = true; } } } if (inserted) { RecalcPositions({first, this}); result = true; } return result; }
void TrackList::Remove(Track * t, bool deletetrack) { if (t) { TrackListNode *node = (TrackListNode *) t->GetNode(); t->SetOwner(NULL, NULL); if (deletetrack) { delete t; } if (node) { if (node->prev) { node->prev->next = node->next; } else { head = node->next; } if (node->next) { node->next->prev = node->prev; RecalcPositions(node->next); } else { tail = node->prev; } UpdatedEvent(NULL); ResizedEvent(node->next); delete node; } } }
void PG_ScrollBar::eventSizeWidget(Uint16 w, Uint16 h) { PG_Widget::eventSizeWidget(w, h); RecalcPositions(); SetPosition(scroll_current); return; }
// This is used when you want to swap the channel group starting // at s1 with that starting at s2. // The complication is that the tracks are stored in a single // linked list. void TrackList::SwapNodes(TrackNodePointer s1, TrackNodePointer s2) { // if a null pointer is passed in, we want to know about it wxASSERT(!isNull(s1)); wxASSERT(!isNull(s2)); // Deal with first track in each team s1 = ( * FindLeader( s1.first->get() ) )->GetNode(); s2 = ( * FindLeader( s2.first->get() ) )->GetNode(); // Safety check... if (s1 == s2) return; // Be sure s1 is the earlier iterator if ((*s1.first)->GetIndex() >= (*s2.first)->GetIndex()) std::swap(s1, s2); // For saving the removed tracks using Saved = std::vector< ListOfTracks::value_type >; Saved saved1, saved2; auto doSave = [&] ( Saved &saved, TrackNodePointer &s ) { size_t nn = Channels( s.first->get() ).size(); saved.resize( nn ); // Save them in backwards order while( nn-- ) saved[nn] = *s.first, s.first = erase(s.first); }; doSave( saved1, s1 ); // The two ranges are assumed to be disjoint but might abut const bool same = (s1 == s2); doSave( saved2, s2 ); if (same) // Careful, we invalidated s1 in the second doSave! s1 = s2; // Reinsert them auto doInsert = [&] ( Saved &saved, TrackNodePointer &s ) { Track *pTrack; for (auto & pointer : saved) pTrack = pointer.get(), // Insert before s, and reassign s to point at the new node before // old s; which is why we saved pointers in backwards order pTrack->SetOwner(shared_from_this(), s = { insert(s.first, pointer), this } ); }; // This does not invalidate s2 even when it equals s1: doInsert( saved2, s1 ); // Even if s2 was same as s1, this correctly inserts the saved1 range // after the saved2 range, when done after: doInsert( saved1, s2 ); // Now correct the Index in the tracks, and other things RecalcPositions(s1); PermutationEvent(); }
void CVisualContainer::AddComponent(CVisualComponent* pComponent) { pComponent->SetContainer(this); m_arrComponents.Add(pComponent); m_Rect.Expand(0, pComponent->Rect().h() + TOP_MARGIN); RecalcPositions(); }
Track *TrackList::Add(std::shared_ptr<TrackKind> &&t) { push_back(t); auto n = end(); --n; t->SetOwner(this, n); RecalcPositions(n); UpdatedEvent(n); return back().get(); }
Track *TrackList::AddToHead(std::unique_ptr<TrackKind> &&t) { Track *pTrack; push_front(value_type(pTrack = t.release())); auto n = begin(); pTrack->SetOwner(this, n); RecalcPositions(n); UpdatedEvent(n); ResizedEvent(n); return front().get(); }
Track *TrackList::Add(std::unique_ptr<TrackKind> &&t) { Track *pTrack; push_back(value_type(pTrack = t.release())); auto n = end(); --n; pTrack->SetOwner(this, n); RecalcPositions(n); UpdatedEvent(n); return back().get(); }
Track *TrackList::DoAddToHead(const std::shared_ptr<Track> &t) { Track *pTrack = t.get(); push_front(ListOfTracks::value_type(t)); auto n = getBegin(); pTrack->SetOwner(shared_from_this(), n); pTrack->SetId( TrackId{ ++sCounter } ); RecalcPositions(n); AdditionEvent(n); return front().get(); }
Track *TrackList::DoAdd(const std::shared_ptr<Track> &t) { push_back(t); auto n = getPrev( getEnd() ); t->SetOwner(shared_from_this(), n); t->SetId( TrackId{ ++sCounter } ); RecalcPositions(n); AdditionEvent(n); return back().get(); }
void TrackList::Permute(const std::vector<TrackNodePointer> &permutation) { for (const auto iter : permutation) { value_type track = std::move(*iter); erase(iter); Track *pTrack = track.get(); pTrack->SetOwner(this, insert(end(), std::move(track))); } auto n = begin(); RecalcPositions(n); UpdatedEvent(n); ResizedEvent(n); }
void TrackList::Permute(const std::vector<TrackNodePointer> &permutation) { for (const auto iter : permutation) { ListOfTracks::value_type track = *iter.first; erase(iter.first); Track *pTrack = track.get(); pTrack->SetOwner(shared_from_this(), { insert(ListOfTracks::end(), track), this }); } auto n = getBegin(); RecalcPositions(n); PermutationEvent(); }
void TrackList::Replace(Track * t, Track * with, bool deletetrack) { if (t && with) { TrackListNode *node = (TrackListNode *) t->GetNode(); t->SetOwner(NULL, NULL); if (deletetrack) { delete t; } node->t = with; with->SetOwner(this, node); RecalcPositions(node); UpdatedEvent(node); ResizedEvent(node); } }
TrackNodePointer TrackList::Remove(Track *t) { TrackNodePointer result(end()); if (t) { auto node = t->GetNode(); if (!isNull(node)) { result = erase(node); if (!isNull(result)) { RecalcPositions(result); } UpdatedEvent(end()); ResizedEvent(result); } } return result; }
void Track::SetLinked(bool l) { auto pList = mList.lock(); if (pList && !pList->mPendingUpdates.empty()) { auto orig = pList->FindById( GetId() ); if (orig && orig != this) { // delegate, and rely on RecalcPositions to copy back orig->SetLinked(l); return; } } DoSetLinked(l); if (pList) { pList->RecalcPositions(mNode); pList->ResizingEvent(mNode); } }
TrackNodePointer TrackList::Remove(Track *t) { auto result = getEnd(); if (t) { auto node = t->GetNode(); t->SetOwner({}, {}); if ( !isNull( node ) ) { ListOfTracks::value_type holder = *node.first; result = getNext( node ); erase(node.first); if ( !isNull( result ) ) RecalcPositions(result); DeletionEvent(); } } return result; }
void PG_ScrollBar::SetPosition(int pos) { if(pos < scroll_min) { pos = scroll_min; } if(pos > scroll_max) { pos = scroll_max; } scroll_current = pos; pos -= scroll_min; // check if we are currently in a drag operation if(dragbutton->GetPressed()) { return; } RecalcPositions(); }
BOOL HexView::InitBuf(const BYTE *buffer, size_t len, bool copybuf, bool readonly) { if(m_pDataSeq->init(buffer, len, copybuf)) { m_szFilePath[0] = '\0'; m_nEditMode = readonly ? HVMODE_READONLY : HVMODE_OVERWRITE; RecalcPositions(); SetCaretPos((m_nAddressWidth + m_nHexPaddingLeft) * m_nFontHeight, 0); UpdateMetrics(); m_nSearchLen = 0; return TRUE; } else { return FALSE; } }
void TrackList::Replace(const Track * t, const Track * with, bool deletetrack) { Track *const mutableT = const_cast<Track*>(t); Track *const mutableWith = const_cast<Track*>(with); if (mutableT && with) { TrackListNode *node = const_cast<TrackListNode *>(mutableT->GetNode()); mutableT->SetOwner(NULL, NULL); if (deletetrack) { delete t; } node->t = mutableWith; mutableWith->SetOwner(this, node); RecalcPositions(node); UpdatedEvent(node); ResizedEvent(node); } }
void TrackList::Add(Track * t) { TrackListNode *n = new TrackListNode; t->SetOwner(this, n); n->t = (Track *) t; n->prev = tail; n->next = NULL; if (tail) { tail->next = n; } tail = n; if (!head) { head = n; } RecalcPositions(n); UpdatedEvent(n); }
void TrackList::AddToHead(Track * t) { TrackListNode *n = new TrackListNode; t->SetOwner(this, n); n->t = (Track *) t; n->prev = NULL; n->next = head; if (head) { head->prev = n; } head = n; if (!tail) { tail = n; } RecalcPositions(head); UpdatedEvent(n); ResizedEvent(n); }
void CVisualContainer::AddPosition(double x, double y) { CVisualObject::AddPosition(x, y); RecalcPositions(); }
// Precondition: if either of s1 or s2 are "linked", then // s1 and s2 must each be the FIRST node of the linked pair. // // This is used when you want to swap the track or pair of // tracks in s1 with the track or pair of tracks in s2. // The complication is that the tracks are stored in a single // linked list, and pairs of tracks are marked only by a flag // in one of the tracks. void TrackList::SwapNodes(TrackListNode * s1, TrackListNode * s2) { Track *link; Track *source[4]; TrackListNode *target[4]; // if a null pointer is passed in, we want to know about it wxASSERT(s1); wxASSERT(s2); // Deal with firat track in each team link = s1->t->GetLink(); if (!s1->t->GetLinked() && link) { s1 = (TrackListNode *) link->GetNode(); } link = s2->t->GetLink(); if (!s2->t->GetLinked() && link) { s2 = (TrackListNode *) link->GetNode(); } target[0] = s1; source[0] = target[0]->t; if (source[0]->GetLinked()) { target[1] = target[0]->next; source[1] = target[1]->t; } else { target[1] = NULL; source[1] = NULL; } target[2] = s2; source[2] = target[2]->t; if (source[2]->GetLinked()) { target[3] = target[2]->next; source[3] = target[3]->t; } else { target[3] = NULL; source[3] = NULL; } int s = 2; for (int t = 0; t < 4; t++) { if (target[t]) { target[t]->t = source[s]; target[t]->t->SetOwner(NULL, NULL); target[t]->t->SetOwner(this, target[t]); s = (s + 1) % 4; if (!source[s]) { s = (s + 1) % 4; } } } RecalcPositions(s1); UpdatedEvent(s1); ResizedEvent(s1); }
// This is used when you want to swap the track or pair of // tracks in s1 with the track or pair of tracks in s2. // The complication is that the tracks are stored in a single // linked list, and pairs of tracks are marked only by a flag // in one of the tracks. void TrackList::SwapNodes(TrackNodePointer s1, TrackNodePointer s2) { // if a null pointer is passed in, we want to know about it wxASSERT(!isNull(s1)); wxASSERT(!isNull(s2)); // Deal with first track in each team Track *link; link = (*s1)->GetLink(); bool linked1 = link != nullptr; if (linked1 && !(*s1)->GetLinked()) { s1 = link->GetNode(); } link = (*s2)->GetLink(); bool linked2 = link != nullptr; if (linked2 && !(*s2)->GetLinked()) { s2 = link->GetNode(); } // Safety check... if (s1 == s2) return; // Be sure s1 is the earlier iterator if ((*s1)->GetIndex() >= (*s2)->GetIndex()) { std::swap(s1, s2); std::swap(linked1, linked2); } // Remove tracks value_type save11 = std::move(*s1), save12{}; s1 = erase(s1); if (linked1) { wxASSERT(s1 != s2); save12 = std::move(*s1), s1 = erase(s1); } const bool same = (s1 == s2); value_type save21 = std::move(*s2), save22{}; s2 = erase(s2); if (linked2) save22 = std::move(*s2), s2 = erase(s2); if (same) // We invalidated s1! s1 = s2; // Reinsert them Track *pTrack; if (save22) pTrack = save22.get(), pTrack->SetOwner(this, s1 = insert(s1, std::move(save22))); pTrack = save21.get(), pTrack->SetOwner(this, s1 = insert(s1, std::move(save21))); if (save12) pTrack = save12.get(), pTrack->SetOwner(this, s2 = insert(s2, std::move(save12))); pTrack = save11.get(), pTrack->SetOwner(this, s2 = insert(s2, std::move(save11))); // Now correct the Index in the tracks, and other things RecalcPositions(s1); UpdatedEvent(s1); ResizedEvent(s1); }