From 6b7ab76199d1d0c5d042c6c1d445b47a838bb017 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Fri, 20 May 2011 15:21:09 -0400 Subject: [PATCH] Add drag context menu entry for junctions in EESchema, fixes lp:783173. * Add drag context menu entry for junctions that actually form a junction with wires to EESchema. * Add function to test for junctions to SCH_COLLECTOR class. * Create annotate type and sort order enums to eliminate magic numbers used in annotate code. * Remove duplicate Doxygen comments from annotate.cpp and improve the actual Doxygen comments in wxEeschemaStruct.h. --- eeschema/annotate.cpp | 70 +++------------ eeschema/controle.cpp | 3 +- eeschema/dialogs/annotate_dialog.cpp | 3 +- eeschema/hotkeys.cpp | 2 +- eeschema/onrightclick.cpp | 31 +++---- eeschema/sch_collectors.cpp | 41 +++++++++ eeschema/sch_collectors.h | 15 ++++ include/class_sch_screen.h | 2 +- include/wxEeschemaStruct.h | 123 +++++++++++++++++---------- 9 files changed, 167 insertions(+), 123 deletions(-) diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index 022af0bb23..eec3a46122 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -20,12 +20,6 @@ #include "lib_pin.h" -/** - * Function DeleteAnnotation - * Remove current component annotations - * @param aCurrentSheetOnly : if false: remove all annotations, else remove - * annotation relative to the current sheet only - */ void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly ) { if( aCurrentSheetOnly ) @@ -45,36 +39,11 @@ void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly ) } -/** - * Function AnnotateComponents: - * - * Compute the annotation of the components for the whole project, or the - * current sheet only. All the components or the new ones only will be - * annotated. - * @param aAnnotateSchematic : true = entire schematic annotation, - * false = current sheet only - * @param aSortOption : 0 = annotate by sorting X position, - * 1 = annotate by sorting Y position, - * 2 = annotate by sorting value - * @param aAlgoOption : 0 = annotate schematic using first free Id number - * 1 = annotate using first free Id number, starting to sheet number * 100 - * 2 = annotate using first free Id number, starting to sheet number * 1000 - * @param aResetAnnotation : true = remove previous annotation - * false = annotate new components only - * @param aRepairsTimestamps : true = test for duplicate times stamps and - * replace duplicated - * Note: this option could change previous annotation, because time - * stamps are used to handle annotation mainly in complex - * hierarchies. - * When the sheet number is used in annotation, - * for each sheet annotation starts from sheet number * 100 - * ( the first sheet uses 100 to 199, the second 200 to 299 ... ) - */ -void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, - int aSortOption, - int aAlgoOption, - bool aResetAnnotation, - bool aRepairsTimestamps ) +void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, + ANNOTATE_ORDER_T aSortOption, + ANNOTATE_OPTION_T aAlgoOption, + bool aResetAnnotation, + bool aRepairTimestamps ) { SCH_REFERENCE_LIST references; @@ -82,13 +51,13 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, SCH_SCREENS screens; - /* Build the sheet list */ + // Build the sheet list. SCH_SHEET_LIST sheets; // Test for and replace duplicate time stamps in components and sheets. Duplicate // time stamps can happen with old schematics, schematic conversions, or manual // editing of files. - if( aRepairsTimestamps ) + if( aRepairTimestamps ) { int count = screens.ReplaceDuplicateTimeStamps(); @@ -127,11 +96,11 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, switch( aSortOption ) { default: - case 0: + case SORT_BY_X_POSITION: references.SortByXCoordinate(); break; - case 1: + case SORT_BY_Y_POSITION: references.SortByYCoordinate(); break; } @@ -142,14 +111,14 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, switch( aAlgoOption ) { default: - case 0: + case INCREMENTAL_BY_REF: break; - case 1: + case SHEET_NUMBER_X_100: useSheetNum = true; break; - case 2: + case SHEET_NUMBER_X_1000: useSheetNum = true; idStep = 1000; break; @@ -161,7 +130,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, wxArrayString errors; - /* Final control (just in case ... )*/ + // Final control (just in case ... ). if( CheckAnnotate( &errors, !aAnnotateSchematic ) ) { wxString msg; @@ -185,19 +154,6 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, } -/** - * Function CheckAnnotate - * Check errors relatives to annotation: - * components not annotated - * components having the same reference (duplicates) - * for multiple parts per package components : - * part number > number of parts - * different values between parts - * @param aMessageList = a wxArrayString to store messages. - * @param aOneSheetOnly : true = search is made only in the current sheet - * false = search in whole hierarchy (usual search). - * @return errors count - */ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly ) { /* build the screen list */ diff --git a/eeschema/controle.cpp b/eeschema/controle.cpp index 550f9328d8..f7b73e8697 100644 --- a/eeschema/controle.cpp +++ b/eeschema/controle.cpp @@ -118,7 +118,8 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, const KICAD_T aF switch( aHotKeyCommandId ) { case HK_DRAG: - if( m_collectedItems.IsCorner() || m_collectedItems.IsNode( false ) ) + if( m_collectedItems.IsCorner() || m_collectedItems.IsNode( false ) + || m_collectedItems.IsDraggableJunction() ) { item = m_collectedItems[0]; GetScreen()->SetCurItem( item ); diff --git a/eeschema/dialogs/annotate_dialog.cpp b/eeschema/dialogs/annotate_dialog.cpp index 34cddce137..ce915e69d6 100644 --- a/eeschema/dialogs/annotate_dialog.cpp +++ b/eeschema/dialogs/annotate_dialog.cpp @@ -135,7 +135,8 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event ) if (response == wxCANCEL) return; - m_Parent->AnnotateComponents( GetLevel(), GetSortOrder(), GetAnnotateAlgo(), + m_Parent->AnnotateComponents( GetLevel(), (ANNOTATE_ORDER_T) GetSortOrder(), + (ANNOTATE_OPTION_T) GetAnnotateAlgo(), GetResetItems() , true ); m_Parent->DrawPanel->Refresh(); diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp index d4541950d7..04c07902a8 100644 --- a/eeschema/hotkeys.cpp +++ b/eeschema/hotkeys.cpp @@ -696,6 +696,7 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, case SCH_BUS_ENTRY_T: case SCH_LINE_T: + case SCH_JUNCTION_T: if( ((SCH_ITEM*) aItem )->GetLayer() != LAYER_BUS ) { cmd.SetId( ID_POPUP_SCH_DRAG_WIRE_REQUEST ); @@ -711,7 +712,6 @@ void SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, break; - case HK_MOVE_COMPONENT_OR_ITEM: // Start move component or other schematic item if( itemInEdit ) break; diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp index 4897a2fc91..5ff794858c 100644 --- a/eeschema/onrightclick.cpp +++ b/eeschema/onrightclick.cpp @@ -40,7 +40,6 @@ static void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel ); static void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* GLabel ); static void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ); static void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field ); -static void AddMenusForJunction( wxMenu* PopMenu, SCH_JUNCTION* Junction, SCH_EDIT_FRAME* frame ); static void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* aFrame ); @@ -118,7 +117,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) break; case SCH_JUNCTION_T: - AddMenusForJunction( PopMenu, (SCH_JUNCTION*) item, this ); + addJunctionMenuEntries( PopMenu, (SCH_JUNCTION*) item ); break; case SCH_BUS_ENTRY_T: @@ -465,25 +464,27 @@ void AddMenusForText( wxMenu* PopMenu, SCH_TEXT* Text ) } -void AddMenusForJunction( wxMenu* PopMenu, SCH_JUNCTION* Junction, SCH_EDIT_FRAME* frame ) +void SCH_EDIT_FRAME::addJunctionMenuEntries( wxMenu* aMenu, SCH_JUNCTION* aJunction ) { - bool is_new = Junction->IsNew(); - SCH_SCREEN* screen = frame->GetScreen(); wxString msg; - - if( !is_new ) - { - if( screen->GetWire( screen->GetCrossHairPosition(), EXCLUDE_END_POINTS_T ) ) - ADD_MENUITEM( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ), break_line_xpm ); - } + SCH_SCREEN* screen = GetScreen(); msg = AddHotkeyName( _( "Delete Junction" ), s_Schematic_Hokeys_Descr, HK_DELETE ); - ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE, msg, delete_xpm ); + ADD_MENUITEM( aMenu, ID_POPUP_SCH_DELETE, msg, delete_xpm ); - if( screen->GetWireOrBus( screen->GetCrossHairPosition() ) ) + if( !aJunction->IsNew() ) { - ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE_NODE, _( "Delete Node" ), delete_node_xpm ); - ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ), + if( m_collectedItems.IsDraggableJunction() ) + ADD_MENUITEM( aMenu, ID_POPUP_SCH_DRAG_WIRE_REQUEST, _( "Drag Junction" ), move_xpm ); + + if( screen->GetWire( aJunction->m_Pos, EXCLUDE_END_POINTS_T ) ) + ADD_MENUITEM( aMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Wire" ), break_line_xpm ); + } + + if( screen->GetWireOrBus( aJunction->m_Pos ) ) + { + ADD_MENUITEM( aMenu, ID_POPUP_SCH_DELETE_NODE, _( "Delete Node" ), delete_node_xpm ); + ADD_MENUITEM( aMenu, ID_POPUP_SCH_DELETE_CONNECTION, _( "Delete Connection" ), delete_connection_xpm ); } } diff --git a/eeschema/sch_collectors.cpp b/eeschema/sch_collectors.cpp index 24cc257849..8e4ab512cb 100644 --- a/eeschema/sch_collectors.cpp +++ b/eeschema/sch_collectors.cpp @@ -254,3 +254,44 @@ bool SCH_COLLECTOR::IsNode( bool aIncludePins ) const return true; } + + +bool SCH_COLLECTOR::IsDraggableJunction() const +{ + int wireEndCount = 0; + int wireMidPoint = 0; + int junctionCount = 0; + + for( size_t i = 0; i < m_List.size(); i++ ) + { + SCH_ITEM* item = (SCH_ITEM*) m_List[ i ]; + KICAD_T type = item->Type(); + + if( type == SCH_JUNCTION_T ) + { + junctionCount++; + continue; + } + + if( type == SCH_LINE_T ) + { + if( item->GetLayer() != LAYER_WIRE ) + return false; + + SCH_LINE* line = (SCH_LINE*) item; + + if( line->IsEndPoint( m_RefPos ) ) + wireEndCount++; + else + wireMidPoint++; + + continue; + } + + // Any other item types indicate that this collection is not a draggable junction. + return false; + } + + return (wireEndCount >= 3) || ((wireEndCount >= 1) && (wireMidPoint == 1)) + || ((wireMidPoint >= 2) && (junctionCount == 1)); +} diff --git a/eeschema/sch_collectors.h b/eeschema/sch_collectors.h index e3ae00cad8..3d93a33a63 100644 --- a/eeschema/sch_collectors.h +++ b/eeschema/sch_collectors.h @@ -148,6 +148,21 @@ public: * @return True if the collected items form a node. */ bool IsNode( bool aIncludePins = true ) const; + + /** + * Function IsDraggableJunction + * tests to see if the collected items form a draggable junction. + *

+ * Daggable juntions are defined as: + *

+ *

+ * @return True if the collection is a draggable junction. + */ + bool IsDraggableJunction() const; }; diff --git a/include/class_sch_screen.h b/include/class_sch_screen.h index bd179a1bf6..49f5fcfb92 100644 --- a/include/class_sch_screen.h +++ b/include/class_sch_screen.h @@ -193,7 +193,7 @@ public: * @param aPosition The position of the first connection object in drawing units. * @param aList The pick list to add the connect item to. * @param aFullConnection If true all the objects that make up this connection are - * add to \aList. Otherwise, only the objects up to the first + * add to \a aList. Otherwise, only the objects up to the first * node are added. * @return The number of items added to \a aList. */ diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index bcc2088dc4..e7a9585345 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -52,6 +52,25 @@ enum fl_rot_cmp { }; +/** Schematic annotation order options. */ +enum ANNOTATE_ORDER_T { + SORT_BY_X_POSITION, ///< Annotate by X position from left to right. + SORT_BY_Y_POSITION, ///< Annotate by Y position from top to bottom. + UNSORTED, ///< Annotate by position of component in the schematic sheet + ///< object list. +}; + + +/** Schematic annotation type options. */ +enum ANNOTATE_OPTION_T { + INCREMENTAL_BY_REF, ///< Annotate incrementally using the first free reference number. + SHEET_NUMBER_X_100, ///< Annotate using the first free reference number starting at + ///< the sheet number * 100. + SHEET_NUMBER_X_1000, ///< Annotate using the first free reference number starting at + ///< the sheet number * 1000. +}; + + /** * Schematic editor (EESchema) main window. */ @@ -207,7 +226,7 @@ public: /** * Function LocateAndShowItem * checks the schematic at \a aPosition in logical (drawing) units for a item - * matching \a aFilterList and \a aGuide. + * matching the types in \a aFilterList. *

* The search is first performed at the nearest grid position to \a aPosition. If no * item if found on grid, then \a aPosition is tested for any items. If the item found @@ -226,7 +245,7 @@ public: /** * Function LocateItem - * checks for items at \a aPosition matching \a aFilter. + * checks for items at \a aPosition matching the types in \a aFilterList. *

* If multiple items are located at \a aPosition, a context menu is displayed to clarify * which item the user intended to select. If the user aborts the context menu, NULL is @@ -303,40 +322,58 @@ public: /** * Function DeleteAnnotation - * Remove current component annotations - * @param aCurrentSheetOnly : if false: remove all annotations, else - * remove annotation relative to the current - * sheet only + * clears the current component annotation. + * @param aCurrentSheetOnly Clear the entire schematic annotation if true. Otherwise + * only clear the annotation for the current sheet. */ - void DeleteAnnotation( bool aCurrentSheetOnly ); + void DeleteAnnotation( bool aCurrentSheetOnly ); /** - * Function AnnotateComponents: + * Function AnnotateComponents * - * Compute the annotation of the components for the whole project, or the - * current sheet only. All the components or the new ones only will be - * annotated. - * @param aAnnotateSchematic : true = entire schematic annotation, - * false = current sheet only - * @param aSortOption : 0 = annotate by sorting X position, - * 1 = annotate by sorting Y position, - * 2 = annotate by sorting value - * @param aAlgoOption : 0 = annotate schematic using first free Id number - * 1 = annotate using first free Id number, starting to sheet number * 100 - * 2 = annotate using first free Id number, starting to sheet number * 1000 - * @param aResetAnnotation : true = remove previous annotation - * false = annotate new components only - * @param aRepairsTimestamps : true = test for duplicate times stamps and - * replace duplicated - * Note: this option could change previous annotation, because time - * stamps are used to handle annotation mainly in complex - * hierarchies. - * When the sheet number is used in annotation, - * for each sheet annotation starts from sheet number * 100 - * ( the first sheet uses 100 to 199, the second 200 to 299 ... ) + * annotates the components in the schematic that are not currently annotated. + * + * @param aAnnotateSchematic Annotate the entire schematic if true. Otherwise annotate + * the current sheet only. + * @param aSortOption Define the annotation order. See #ANNOTATE_ORDER_T. + * @param aAlgoOption Define the annotation style. See #ANNOTATE_OPTION_T. + * @param aResetAnnotation Clear any previous annotation if true. Otherwise, keep the + * existing component annotation. + * @param aRepairTimestamps Test for and repair any duplicate time stamps if true. + * Otherwise, keep the existing time stamps. This option + * could change previous annotation because time stamps are + * used to handle annotation in complex hierarchies. + * + * When the sheet number is used in annotation, each sheet annotation starts from sheet + * number * 100. In other words the first sheet uses 100 to 199, the second sheet uses + * 200 to 299, and so on. */ - void AnnotateComponents( bool aAnnotateSchematic, int aSortOption, int aAlgoOption, - bool aResetAnnotation, bool aRepairsTimestamps ); + void AnnotateComponents( bool aAnnotateSchematic, ANNOTATE_ORDER_T aSortOption, + ANNOTATE_OPTION_T aAlgoOption, bool aResetAnnotation, + bool aRepairTimestamps ); + + /** + * Function CheckAnnotate + * checks for annotation errors. + * + *

+ * The following list of items are checked: + *

+ *

+ * + * @return Number of annotation errors found. + * @param aMessageList A wxArrayString to store error messages. + * @param aOneSheetOnly Check the current sheet only if true. Otherwise check + * the entire schematic. + */ + int CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly ); // Functions used for hierarchy handling /** @@ -690,6 +727,14 @@ private: */ void copyBlockItems( PICKED_ITEMS_LIST& aItemsList ); + /** + * Function addJunctionMenuEntries + * adds the context menu items to \a aMenu for \a aJunction. + * @params aMenu The menu to add the items to. + * @params aJunction The SCH_JUNCTION object selected. + */ + void addJunctionMenuEntries( wxMenu* aMenu, SCH_JUNCTION* aJunction ); + public: void Key( wxDC* DC, int hotkey, EDA_ITEM* DrawStruct ); @@ -756,22 +801,6 @@ public: // ERC: - /** - * Function CheckAnnotate - * Check errors relatives to annotation: - * components not annotated - * components having the same reference (duplicates) - * for multiple parts per package components : - * part number > number of parts - * different values between parts - * @return errors count - * @param aMessageList = a wxArrayString to store messages. If NULL, - * they are displayed in a wxMessageBox - * @param aOneSheetOnly : true = search is made only in the current sheet - * false = search in whole hierarchy (usual search). - */ - int CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly ); - /** * Load component libraries defined in project file. */