NS_IMETHODIMP nsMsgSearchDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder) { int32_t rowCountBeforeSort = GetSize(); if (!rowCountBeforeSort) return NS_OK; if (m_viewFlags & (nsMsgViewFlagsType::kThreadedDisplay | nsMsgViewFlagsType::kGroupBySort)) { // ### This forgets which threads were expanded, and is sub-optimal // since it rebuilds the thread objects. m_sortType = sortType; m_sortOrder = sortOrder; return RebuildView(m_viewFlags); } nsMsgKey preservedKey; nsAutoTArray<nsMsgKey, 1> preservedSelection; SaveAndClearSelection(&preservedKey, preservedSelection); nsresult rv = nsMsgDBView::Sort(sortType,sortOrder); // the sort may have changed the number of rows // before we restore the selection, tell the tree // do this before we call restore selection // this is safe when there is no selection. rv = AdjustRowCount(rowCountBeforeSort, GetSize()); RestoreSelection(preservedKey, preservedSelection); if (mTree) mTree->Invalidate(); NS_ENSURE_SUCCESS(rv,rv); return rv; }
void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart ) { if( !aPart && !m_my_part ) return; m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); if( m_my_part != aPart ) { if( m_my_part ) delete m_my_part; m_my_part = aPart; } // select the current component in the tree widget if( aPart ) m_treePane->GetLibTree()->SelectLibId( aPart->GetLibId() ); wxString partName = aPart ? aPart->GetName() : wxString(); m_libMgr->SetCurrentPart( partName ); // retain in case this wxFrame is re-opened later on the same PROJECT Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, partName ); // Ensure synchronized pin edit can be enabled only symbols with interchangeable units m_SyncPinEdit = aPart && aPart->IsMulti() && !aPart->UnitsLocked(); m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); RebuildView(); }
NS_IMETHODIMP nsMsgGroupView::OnHdrDeleted(nsIMsgDBHdr *aHdrDeleted, nsMsgKey aParentKey, int32_t aFlags, nsIDBChangeListener *aInstigator) { if (!(m_viewFlags & nsMsgViewFlagsType::kGroupBySort)) return nsMsgDBView::OnHdrDeleted(aHdrDeleted, aParentKey, aFlags, aInstigator); // check if we're adding a header, and the current day has changed. If it has, we're just going to // close and re-open the view so things will be correctly categorized. if (m_dayChanged) return RebuildView(m_viewFlags); nsCOMPtr <nsIMsgThread> thread; nsMsgKey keyDeleted; aHdrDeleted->GetMessageKey(&keyDeleted); nsresult rv = GetThreadContainingMsgHdr(aHdrDeleted, getter_AddRefs(thread)); NS_ENSURE_SUCCESS(rv, rv); nsMsgViewIndex viewIndexOfThread = GetIndexOfFirstDisplayedKeyInThread( thread, true); // yes to dummy node thread->RemoveChildHdr(aHdrDeleted, nullptr); nsMsgGroupThread *groupThread = static_cast<nsMsgGroupThread *>((nsIMsgThread *) thread); bool rootDeleted = viewIndexOfThread != nsMsgKey_None && m_keys[viewIndexOfThread] == keyDeleted; rv = nsMsgDBView::OnHdrDeleted(aHdrDeleted, aParentKey, aFlags, aInstigator); if (groupThread->m_dummy) { if (!groupThread->NumRealChildren()) { thread->RemoveChildAt(0); // get rid of dummy if (viewIndexOfThread != nsMsgKey_None) { RemoveByIndex(viewIndexOfThread); if (m_deletingRows) mIndicesToNoteChange.AppendElement(viewIndexOfThread); } } else if (rootDeleted) { // reflect new thread root into view.dummy row. nsCOMPtr<nsIMsgDBHdr> hdr; thread->GetChildHdrAt(0, getter_AddRefs(hdr)); if (hdr) { nsMsgKey msgKey; hdr->GetMessageKey(&msgKey); SetMsgHdrAt(hdr, viewIndexOfThread, msgKey, m_flags[viewIndexOfThread], 0); } } } if (!groupThread->m_keys.Length()) { nsString hashKey; rv = HashHdr(aHdrDeleted, hashKey); if (NS_SUCCEEDED(rv)) m_groupsTable.Remove(hashKey); } return rv; }
void LIB_EDIT_FRAME::OnSelectBodyStyle( wxCommandEvent& event ) { m_toolManager->RunAction( ACTIONS::cancelInteractive, true ); m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); m_convert = event.GetId() == ID_DE_MORGAN_NORMAL_BUTT ? 1 : 2; m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); RebuildView(); }
NS_IMETHODIMP nsMsgQuickSearchDBView::SetViewFlags(nsMsgViewFlagsTypeValue aViewFlags) { nsresult rv = NS_OK; // if the grouping has changed, rebuild the view if (m_viewFlags & nsMsgViewFlagsType::kGroupBySort ^ (aViewFlags & nsMsgViewFlagsType::kGroupBySort)) rv = RebuildView(aViewFlags); nsMsgDBView::SetViewFlags(aViewFlags); return rv; }
NS_IMETHODIMP nsMsgXFVirtualFolderDBView::SetViewFlags(nsMsgViewFlagsTypeValue aViewFlags) { nsresult rv = NS_OK; // if the grouping/threading has changed, rebuild the view if ((m_viewFlags & (nsMsgViewFlagsType::kGroupBySort | nsMsgViewFlagsType::kThreadedDisplay)) != (aViewFlags & (nsMsgViewFlagsType::kGroupBySort | nsMsgViewFlagsType::kThreadedDisplay))) rv = RebuildView(aViewFlags); nsMsgDBView::SetViewFlags(aViewFlags); return rv; }
void LIB_EDIT_FRAME::OnSelectUnit( wxCommandEvent& event ) { int i = event.GetSelection(); if( ( i == wxNOT_FOUND ) || ( ( i + 1 ) == m_unit ) ) return; m_toolManager->RunAction( ACTIONS::cancelInteractive, true ); m_toolManager->RunAction( EE_ACTIONS::clearSelection, true ); m_unit = i + 1; m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); RebuildView(); }
NS_IMETHODIMP nsMsgGroupView::AddColumnHandler(const nsAString& column, nsIMsgCustomColumnHandler* handler) { nsMsgDBView::AddColumnHandler(column, handler); // If the sortType is byCustom and the desired custom column is the one just // registered, build the view. if (m_viewFlags & nsMsgViewFlagsType::kGroupBySort && m_sortType == nsMsgViewSortType::byCustom) { nsAutoString curCustomColumn; GetCurCustomColumn(curCustomColumn); if (curCustomColumn == column) RebuildView(m_viewFlags); } return NS_OK; }
NS_IMETHODIMP nsMsgGroupView::OnHdrFlagsChanged(nsIMsgDBHdr *aHdrChanged, uint32_t aOldFlags, uint32_t aNewFlags, nsIDBChangeListener *aInstigator) { if (!(m_viewFlags & nsMsgViewFlagsType::kGroupBySort)) return nsMsgDBView::OnHdrFlagsChanged(aHdrChanged, aOldFlags, aNewFlags, aInstigator); nsCOMPtr <nsIMsgThread> thread; // check if we're adding a header, and the current day has changed. If it has, we're just going to // close and re-open the view so things will be correctly categorized. if (m_dayChanged) return RebuildView(m_viewFlags); nsresult rv = GetThreadContainingMsgHdr(aHdrChanged, getter_AddRefs(thread)); NS_ENSURE_SUCCESS(rv, rv); uint32_t deltaFlags = (aOldFlags ^ aNewFlags); if (deltaFlags & nsMsgMessageFlags::Read) thread->MarkChildRead(aNewFlags & nsMsgMessageFlags::Read); return nsMsgDBView::OnHdrFlagsChanged(aHdrChanged, aOldFlags, aNewFlags, aInstigator); }
void LIB_EDIT_FRAME::pasteClipboard( const wxPoint& aOffset ) { LIB_PART* part = GetCurPart(); if( !part || m_clipboard.GetCount() == 0 ) return; for( unsigned int i = 0; i < m_clipboard.GetCount(); i++ ) { // Append a copy to the current part, so the clipboard buffer might be pasted multiple times LIB_ITEM* item = (LIB_ITEM*) m_clipboard.GetItem( i )->Clone(); item->SetParent( part ); item->SetSelected(); item->SetUnit( GetUnit() ); part->AddDrawItem( item ); } BlockMoveSelectedItems( aOffset, GetCurPart(), &GetScreen()->m_BlockLocate ); RebuildView(); GetCanvas()->Refresh(); OnModify(); }
void LIB_EDIT_FRAME::HardRedraw() { SyncLibraries( true ); RebuildView(); }
nsresult nsMsgGroupView::OnNewHeader(nsIMsgDBHdr *newHdr, nsMsgKey aParentKey, bool ensureListed) { if (!(m_viewFlags & nsMsgViewFlagsType::kGroupBySort)) return nsMsgDBView::OnNewHeader(newHdr, aParentKey, ensureListed); // check if we're adding a header, and the current day has changed. If it has, we're just going to // close and re-open the view so things will be correctly categorized. if (m_dayChanged) return RebuildView(m_viewFlags); bool newThread; nsMsgGroupThread *thread = AddHdrToThread(newHdr, &newThread); if (thread) { // find the view index of (the root node of) the thread nsMsgViewIndex threadIndex = ThreadIndexOfMsgHdr(newHdr); // may need to fix thread counts if (threadIndex != nsMsgViewIndex_None) { if (newThread) { // AddHdrToThread creates the header elided, so we need to un-elide it // if we want it expanded. if(m_viewFlags & nsMsgViewFlagsType::kExpandAll) m_flags[threadIndex] &= ~nsMsgMessageFlags::Elided; } else { m_flags[threadIndex] |= MSG_VIEW_FLAG_HASCHILDREN | MSG_VIEW_FLAG_ISTHREAD; } int32_t numRowsToInvalidate = 1; // if the thread is expanded (not elided), we should add the header to // the view. if (! (m_flags[threadIndex] & nsMsgMessageFlags::Elided)) { uint32_t msgIndexInThread = thread->FindMsgHdr(newHdr); bool insertedAtThreadRoot = !msgIndexInThread; // Add any new display node and potentially fix-up changes in the root. // (If this is a new thread and we are not using a dummy row, the only // node to display is the root node which has already been added by // AddHdrToThread. And since there is just the one, no change in root // could have occurred, so we have nothing to do.) if (!newThread || GroupViewUsesDummyRow()) { // we never want to insert/update the root node, because // AddHdrToThread has already done that for us (in all cases). if (insertedAtThreadRoot) msgIndexInThread++; // If this header is the new parent of the thread... AND // If we are not using a dummy row, this means we need to append our // old node as the first child of the new root. // (If we are using a dummy row, the old node's "content" node already // exists (at position threadIndex + 1) and we need to insert the // "content" copy of the new root node there, pushing our old // "content" node down.) // Example mini-diagrams, wrapping the to-add thing with () // No dummy row; we had: [A], now we have [B], we want [B (A)]. // Dummy row; we had: [A A], now we have [B A], we want [B (B) A]. // (Coming into this we're adding 'B') if (!newThread && insertedAtThreadRoot && !GroupViewUsesDummyRow()) { // grab a copy of the old root node ('A') from the thread so we can // insert it. (offset msgIndexInThread=1 is the right thing; we are // non-dummy.) thread->GetChildHdrAt(msgIndexInThread, &newHdr); } // nothing to do for dummy case, we're already inserting 'B'. nsMsgKey msgKey; uint32_t msgFlags; newHdr->GetMessageKey(&msgKey); newHdr->GetFlags(&msgFlags); InsertMsgHdrAt(threadIndex + msgIndexInThread, newHdr, msgKey, msgFlags, 1); } // the call to NoteChange() has to happen after we add the key // as NoteChange() will call RowCountChanged() which will call our GetRowCount() // (msgIndexInThread states. new thread: 0, old thread at root: 1) if (newThread && GroupViewUsesDummyRow()) NoteChange(threadIndex, 2, nsMsgViewNotificationCode::insertOrDelete); else NoteChange(threadIndex + msgIndexInThread, 1, nsMsgViewNotificationCode::insertOrDelete); numRowsToInvalidate = msgIndexInThread; } // we still need the addition notification for new threads when elided else if (newThread) { NoteChange(threadIndex, 1, nsMsgViewNotificationCode::insertOrDelete); } NoteChange(threadIndex, numRowsToInvalidate, nsMsgViewNotificationCode::changed); } } // if thread is expanded, we need to add hdr to view... return NS_OK; }
void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC ) { BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; wxPoint pt; if( !m_canvas->IsMouseCaptured() ) { DisplayError( this, wxT( "HandleBlockPLace : m_mouseCaptureCallback = NULL" ) ); } block->SetState( STATE_BLOCK_STOP ); switch( block->GetCommand() ) { case BLOCK_IDLE: break; case BLOCK_DRAG: // Drag case BLOCK_DRAG_ITEM: case BLOCK_MOVE: // Move case BLOCK_DUPLICATE: // Duplicate if( GetCurPart() && !block->AppendUndo() ) SaveCopyInUndoList( GetCurPart() ); pt = block->GetMoveVector(); if( GetCurPart() ) BlockMoveSelectedItems( pt, GetCurPart(), block ); block->ClearItemsList(); break; case BLOCK_PASTE: // Paste (recopy the last block saved) if( GetCurPart() ) SaveCopyInUndoList( GetCurPart() ); pt = block->GetMoveVector(); pasteClipboard( pt ); block->ClearItemsList(); break; case BLOCK_ZOOM: // Handled by HandleBlockEnd case BLOCK_DELETE: case BLOCK_COPY: case BLOCK_ABORT: default: break; } RebuildView(); GetCanvas()->Refresh(); OnModify(); block->SetState( STATE_NO_BLOCK ); block->SetCommand( BLOCK_IDLE ); GetScreen()->SetCurItem( NULL ); m_canvas->EndMouseCapture( GetToolId(), GetGalCanvas()->GetCurrentCursor(), wxEmptyString, false ); GetCanvas()->GetView()->ClearPreview(); GetCanvas()->GetView()->ClearHiddenFlags(); }
bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* aDC ) { int ItemCount = 0; bool nextCmd = false; BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate; wxPoint pt; auto panel =static_cast<SCH_DRAW_PANEL*>(m_canvas); auto view = panel->GetView(); auto area = view->GetSelectionArea(); auto start = area->GetOrigin(); auto end = area->GetEnd(); block->SetOrigin( wxPoint( start.x, start.y ) ); block->SetEnd( wxPoint( end.x, end.y ) ); view->ShowSelectionArea( false ); view->ClearHiddenFlags(); if( block->GetCount() ) { BLOCK_STATE_T state = block->GetState(); BLOCK_COMMAND_T command = block->GetCommand(); m_canvas->CallEndMouseCapture( aDC ); block->SetState( state ); block->SetCommand( command ); m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand ); if( block->GetCommand() != BLOCK_ABORT && block->GetCommand() != BLOCK_DUPLICATE && block->GetCommand() != BLOCK_COPY && block->GetCommand() != BLOCK_CUT && block->GetCommand() != BLOCK_DELETE ) { SetCrossHairPosition( block->GetEnd() ); m_canvas->MoveCursorToCrossHair(); } } if( m_canvas->IsMouseCaptured() ) { switch( block->GetCommand() ) { case BLOCK_IDLE: DisplayError( this, wxT( "Error in HandleBlockPLace" ) ); break; case BLOCK_DRAG: // Drag case BLOCK_DRAG_ITEM: case BLOCK_MOVE: // Move case BLOCK_DUPLICATE: // Duplicate if( GetCurPart() ) ItemCount = BlockSelectItems( GetCurPart(), block, m_unit, m_convert, m_syncPinEdit ); if( ItemCount ) { nextCmd = true; block->SetState( STATE_BLOCK_MOVE ); if( block->GetCommand() == BLOCK_DUPLICATE ) { if( block->AppendUndo() ) ; // UR_LIBEDIT saves entire state, so no need to append anything more else { SaveCopyInUndoList( GetCurPart(), UR_LIBEDIT ); block->SetAppendUndo(); } BlockCopySelectedItems( pt, GetCurPart(), block ); block->SetLastCursorPosition( GetCrossHairPosition( true ) ); } m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines ); m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false ); } else { m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false ); m_canvas->SetMouseCapture( NULL, NULL ); } break; case BLOCK_COPY: // Save a copy of items in the clipboard buffer case BLOCK_CUT: if( GetCurPart() ) ItemCount = BlockSelectItems( GetCurPart(), block, m_unit, m_convert, m_syncPinEdit ); if( ItemCount ) { copySelectedItems(); auto cmd = block->GetCommand(); if( cmd == BLOCK_COPY ) { BlockClearSelectedItems( GetCurPart(), block ); block->ClearItemsList(); } else if( cmd == BLOCK_CUT ) { if( block->AppendUndo() ) ; // UR_LIBEDIT saves entire state, so no need to append anything more else { SaveCopyInUndoList( GetCurPart(), UR_LIBEDIT ); block->SetAppendUndo(); } BlockDeleteSelectedItems( GetCurPart(), block ); RebuildView(); GetCanvas()->Refresh(); OnModify(); } } break; case BLOCK_DELETE: // Delete if( GetCurPart() ) ItemCount = BlockSelectItems( GetCurPart(), block, m_unit, m_convert, m_syncPinEdit ); if( block->AppendUndo() ) ; // UR_LIBEDIT saves entire state, so no need to append anything more else if( ItemCount ) { SaveCopyInUndoList( GetCurPart(), UR_LIBEDIT ); block->SetAppendUndo(); } if( GetCurPart() ) { BlockDeleteSelectedItems( GetCurPart(), block ); RebuildView(); GetCanvas()->Refresh(); OnModify(); } break; case BLOCK_PASTE: case BLOCK_ROTATE: case BLOCK_MIRROR_X: case BLOCK_MIRROR_Y: case BLOCK_FLIP: wxFAIL; // should not happen break; case BLOCK_ZOOM: // Window Zoom Window_Zoom( *block ); break; case BLOCK_ABORT: break; case BLOCK_SELECT_ITEMS_ONLY: break; case BLOCK_PRESELECT_MOVE: // not used in LibEdit case BLOCK_DUPLICATE_AND_INCREMENT: // not used in Eeschema case BLOCK_MOVE_EXACT: // not used in Eeschema break; } } if( block->GetCommand() == BLOCK_ABORT ) { GetScreen()->ClearDrawingState(); } if( !nextCmd ) { if( block->GetCommand() != BLOCK_SELECT_ITEMS_ONLY && GetCurPart() ) BlockClearSelectedItems( GetCurPart(), block ); GetScreen()->ClearBlockCommand(); GetScreen()->SetCurItem( NULL ); m_canvas->EndMouseCapture( GetToolId(), GetGalCanvas()->GetCurrentCursor(), wxEmptyString, false ); } view->ShowSelectionArea( false ); view->ShowPreview( nextCmd ); return nextCmd; }