From 535033c5c9a4fac7dff03a93c48c9cc4ab2c17b4 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Fri, 6 Mar 2020 20:02:58 +0000 Subject: [PATCH] Enable editing of sheet fields. --- common/dialogs/dialog_configure_paths.cpp | 4 +- common/widgets/grid_text_button_helpers.cpp | 5 +- eeschema/dialogs/dialog_edit_one_field.cpp | 38 +- eeschema/dialogs/dialog_sch_sheet_props.cpp | 622 +++++- eeschema/dialogs/dialog_sch_sheet_props.h | 41 +- .../dialogs/dialog_sch_sheet_props_base.cpp | 232 ++- .../dialogs/dialog_sch_sheet_props_base.fbp | 1720 ++++++----------- .../dialogs/dialog_sch_sheet_props_base.h | 71 +- eeschema/ee_collectors.cpp | 2 +- eeschema/eeschema_settings.cpp | 3 + eeschema/eeschema_settings.h | 1 + eeschema/fields_grid_table.cpp | 85 +- eeschema/fields_grid_table.h | 9 + eeschema/sch_component.cpp | 24 +- eeschema/sch_component.h | 32 +- eeschema/sch_edit_frame.h | 24 +- eeschema/sch_field.cpp | 74 +- eeschema/sch_field.h | 8 - eeschema/sch_item.h | 46 +- eeschema/sch_painter.cpp | 17 +- eeschema/sch_sheet.cpp | 131 +- eeschema/sch_sheet.h | 42 +- eeschema/sch_sheet_pin.cpp | 40 +- eeschema/sheet.cpp | 244 +-- eeschema/tools/ee_selection_tool.cpp | 26 +- eeschema/tools/sch_edit_tool.cpp | 34 +- eeschema/tools/sch_edit_tool.h | 2 +- eeschema/tools/sch_editor_control.cpp | 7 +- eeschema/tools/sch_move_tool.cpp | 19 +- include/widgets/grid_text_button_helpers.h | 8 +- pcbnew/dialogs/panel_fp_lib_table.cpp | 2 +- 31 files changed, 1760 insertions(+), 1853 deletions(-) diff --git a/common/dialogs/dialog_configure_paths.cpp b/common/dialogs/dialog_configure_paths.cpp index 1fa78eb0b4..6fae3cca22 100644 --- a/common/dialogs/dialog_configure_paths.cpp +++ b/common/dialogs/dialog_configure_paths.cpp @@ -68,11 +68,11 @@ DIALOG_CONFIGURE_PATHS::DIALOG_CONFIGURE_PATHS( wxWindow* aParent, FILENAME_RESO m_EnvVars->UseNativeColHeader( true ); wxGridCellAttr* attr = new wxGridCellAttr; - attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, &m_curdir ) ); + attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, &m_curdir, wxEmptyString ) ); m_EnvVars->SetColAttr( EV_PATH_COL, attr ); attr = new wxGridCellAttr; - attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, &m_curdir ) ); + attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, &m_curdir, wxEmptyString ) ); m_SearchPaths->SetColAttr( EV_PATH_COL, attr ); // Give a bit more room for combobox editors diff --git a/common/widgets/grid_text_button_helpers.cpp b/common/widgets/grid_text_button_helpers.cpp index dc689c29e4..eed7526ec4 100644 --- a/common/widgets/grid_text_button_helpers.cpp +++ b/common/widgets/grid_text_button_helpers.cpp @@ -371,7 +371,10 @@ protected: void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler ) { - m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_currentDir ); + if( m_ext.IsEmpty() ) + m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_currentDir ); + else + m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_currentDir, &m_ext ); #if wxUSE_VALIDATORS // validate text in textctrl, if validator is set diff --git a/eeschema/dialogs/dialog_edit_one_field.cpp b/eeschema/dialogs/dialog_edit_one_field.cpp index e0cf153968..a89b285736 100644 --- a/eeschema/dialogs/dialog_edit_one_field.cpp +++ b/eeschema/dialogs/dialog_edit_one_field.cpp @@ -215,24 +215,26 @@ DIALOG_LIB_EDIT_ONE_FIELD::DIALOG_LIB_EDIT_ONE_FIELD( } -DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( - SCH_BASE_FRAME* aParent, const wxString& aTitle, const SCH_FIELD* aField ) - : DIALOG_EDIT_ONE_FIELD( aParent, aTitle, aField ) +DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, + const wxString& aTitle, + const SCH_FIELD* aField ) : + DIALOG_EDIT_ONE_FIELD( aParent, aTitle, aField ) { m_fieldId = aField->GetId(); - - const SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent(); - - wxASSERT_MSG( component && component->Type() == SCH_COMPONENT_T, - wxT( "Invalid schematic field parent item." ) ); + m_isPower = false; // The library symbol may have been removed so using SCH_COMPONENT::GetPartRef() here // could result in a segfault. If the library symbol is no longer available, the // schematic fields can still edit so set the power symbol flag to false. This may not // be entirely accurate if the power library is missing but it's better then a segfault. - const LIB_PART* part = GetParent()->GetLibPart( component->GetLibId(), true ); + if( aField->GetParent() && aField->GetParent()->Type() == SCH_COMPONENT_T ) + { + const SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent(); + const LIB_PART* part = GetParent()->GetLibPart( component->GetLibId(), true ); - m_isPower = ( part ) ? part->IsPower() : false; + if( part && part->IsPower() ) + m_isPower = true; + } init(); } @@ -240,16 +242,13 @@ DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* aSheetPath ) { - if( aField->GetId() == REFERENCE ) + EDA_ITEM* parent = aField->GetParent(); + + if( parent && parent->Type() == SCH_COMPONENT_T && aField->GetId() == REFERENCE ) { wxASSERT( aSheetPath ); - SCH_COMPONENT* component = dynamic_cast< SCH_COMPONENT* >( aField->GetParent() ); - - wxASSERT( component ); - - if( component ) - component->SetRef( aSheetPath, m_text ); + static_cast( parent )->SetRef( aSheetPath, m_text ); } bool positioningModified = false; @@ -270,8 +269,5 @@ void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* updateText( aField ); if( positioningModified ) - { - auto component = static_cast< SCH_COMPONENT* >( aField->GetParent() ); - component->ClearFieldsAutoplaced(); - } + static_cast( parent )->ClearFieldsAutoplaced(); } diff --git a/eeschema/dialogs/dialog_sch_sheet_props.cpp b/eeschema/dialogs/dialog_sch_sheet_props.cpp index baa2f62ad5..3c3f5d67bf 100644 --- a/eeschema/dialogs/dialog_sch_sheet_props.cpp +++ b/eeschema/dialogs/dialog_sch_sheet_props.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -32,120 +33,603 @@ #include #include #include +#include -DIALOG_SCH_SHEET_PROPS::DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* parent, SCH_SHEET* aSheet ) : - DIALOG_SCH_SHEET_PROPS_BASE( parent ), - m_sheet( aSheet ), - m_filenameTextSize( parent, m_filenameSizeLabel, m_filenameSizeCtrl, m_filenameSizeUnits, true ), - m_sheetnameTextSize( parent, m_sheetnameSizeLabel, m_sheetnameSizeCtrl, m_sheetnameSizeUnits, true ) + +DIALOG_SCH_SHEET_PROPS::DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* aParent, SCH_SHEET* aSheet, + bool* aClearAnnotationNewItems ) : + DIALOG_SCH_SHEET_PROPS_BASE( aParent ), + m_frame( aParent ), + m_clearAnnotationNewItems( aClearAnnotationNewItems ) { - m_textFileName->SetValidator( FILE_NAME_WITH_PATH_CHAR_VALIDATOR() ); - m_textFileName->SetFocus(); - m_sdbSizer1OK->SetDefault(); + m_sheet = aSheet; + m_fields = new FIELDS_GRID_TABLE( this, aParent, m_sheet ); - m_browseButton->SetBitmap( KiBitmap( folder_xpm ) ); + m_width = 0; + m_delayedFocusRow = SHEETNAME; + m_delayedFocusColumn = FDC_VALUE; - // We can't set the tab order through wxWidgets due to shortcomings in their mnemonics - // implementation on MSW - m_tabOrder = { - m_textFileName, - m_browseButton, - m_filenameVisible, - m_filenameSizeCtrl, + // Give a bit more room for combobox editors + m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 ); - m_textSheetName, - m_sheetnameSizeCtrl, - m_sheetnameVisible, + m_grid->SetTable( m_fields ); + m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) ); - m_sdbSizer1OK, - m_sdbSizer1Cancel - }; + // Show/hide columns according to user's preference + auto cfg = dynamic_cast( Kiface().KifaceSettings() ); + m_shownColumns = cfg->m_Appearance.edit_sheet_visible_columns; + m_grid->ShowHideColumns( m_shownColumns ); - SetInitialFocus( m_textFileName ); + wxToolTip::Enable( true ); + m_stdDialogButtonSizerOK->SetDefault(); + + // Configure button logos + m_bpAdd->SetBitmap( KiBitmap( small_plus_xpm ) ); + m_bpDelete->SetBitmap( KiBitmap( trash_xpm ) ); + m_bpMoveUp->SetBitmap( KiBitmap( small_up_xpm ) ); + m_bpMoveDown->SetBitmap( KiBitmap( small_down_xpm ) ); + + // wxFormBuilder doesn't include this event... + m_grid->Connect( wxEVT_GRID_CELL_CHANGING, + wxGridEventHandler( DIALOG_SCH_SHEET_PROPS::OnGridCellChanging ), + NULL, this ); - // Now all widgets have the size fixed, call FinishDialogSettings FinishDialogSettings(); +} - /* - * This ugly hack fixes a bug in wxWidgets 2.8.7 and likely earlier versions for the flex - * grid sizer in wxGTK that prevents the last column from being sized correctly. It doesn't - * appear to cause any problems on other platforms so we don't use conditional compilation. - * Still present in wxWidgets 3.0.2 - */ - Layout(); - Fit(); - SetMinSize( GetSize() ); - GetSizer()->Fit( this ); + +DIALOG_SCH_SHEET_PROPS::~DIALOG_SCH_SHEET_PROPS() +{ + auto cfg = dynamic_cast( Kiface().KifaceSettings() ); + cfg->m_Appearance.edit_sheet_visible_columns = m_grid->GetShownColumns(); + + // Prevents crash bug in wxGrid's d'tor + m_grid->DestroyTable( m_fields ); + + m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING, + wxGridEventHandler( DIALOG_SCH_SHEET_PROPS::OnGridCellChanging ), + NULL, this ); + + // Delete the GRID_TRICKS. + m_grid->PopEventHandler( true ); } bool DIALOG_SCH_SHEET_PROPS::TransferDataToWindow() { - // Filenames are stored using unix notation - wxString fname = m_sheet->GetFileName(); + if( !wxDialog::TransferDataToWindow() ) + return false; + + // Push a copy of each field into m_fields + for( SCH_FIELD& field : m_sheet->GetFields() ) + { + SCH_FIELD field_copy( field ); #ifdef __WINDOWS__ - fname.Replace( wxT("/"), wxT("\\") ); + // Filenames are stored using unix notation + if( field_copy.GetId() == SHEETFILENAME ) + { + wxString filename = field_copy.GetText(); + filename.Replace( wxT("/"), wxT("\\") ) ); + field_copy.SetText( filename ); + } #endif - m_textFileName->SetValue( fname ); - m_filenameVisible->SetValue( m_sheet->GetShowFileName() ); - m_textSheetName->SetValue( m_sheet->GetName() ); - m_sheetnameVisible->SetValue( m_sheet->GetShowSheetName() ); + // change offset to be symbol-relative + field_copy.Offset( -m_sheet->GetPosition() ); - m_filenameTextSize.SetValue( m_sheet->GetFileNameSize() ); - m_sheetnameTextSize.SetValue( m_sheet->GetSheetNameSize() ); + m_fields->push_back( field_copy ); + } - m_textCtrlUuid->SetValue( m_sheet->m_Uuid.AsString() ); - m_textCtrlHpath->SetValue( g_CurrentSheet->PathHumanReadable() ); + // notify the grid + wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->size() ); + m_grid->ProcessTableMessage( msg ); + AdjustGridColumns( m_grid->GetRect().GetWidth() ); + + m_heirarchyPath->SetValue( g_CurrentSheet->PathHumanReadable() ); + + // Set the component's unique ID time stamp. + m_textCtrlTimeStamp->SetValue( m_sheet->m_Uuid.AsString() ); + + Layout(); return true; } +bool DIALOG_SCH_SHEET_PROPS::Validate() +{ + wxString msg; + LIB_ID id; + + if( !m_grid->CommitPendingChanges() || !m_grid->Validate() ) + return false; + + // Check for missing field names. + for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields->size(); ++i ) + { + SCH_FIELD& field = m_fields->at( i ); + wxString fieldName = field.GetName( false ); + + if( fieldName.IsEmpty() ) + { + DisplayErrorMessage( this, _( "Fields must have a name." ) ); + + m_delayedFocusColumn = FDC_NAME; + m_delayedFocusRow = i; + + return false; + } + } + + return true; +} + + +static bool positioningChanged( const SCH_FIELD& a, const SCH_FIELD& b ) +{ + if( a.GetPosition() != b.GetPosition() ) + return true; + + if( a.GetHorizJustify() != b.GetHorizJustify() ) + return true; + + if( a.GetVertJustify() != b.GetVertJustify() ) + return true; + + if( a.GetTextAngle() != b.GetTextAngle() ) + return true; + + return false; +} + + +static bool positioningChanged( FIELDS_GRID_TABLE* a, std::vector& b ) +{ + for( int i = 0; i < a->size(); ++i ) + { + if( positioningChanged( a->at( i ), b.at( i ) ) ) + return true; + } + + return false; +} + + bool DIALOG_SCH_SHEET_PROPS::TransferDataFromWindow() { - wxFileName fileName = GetFileName(); + if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method. + return false; + + wxString newRelativeNativeFilename = m_fields->at( SHEETFILENAME ).GetText(); + wxString newRelativeFilename = newRelativeNativeFilename; + + // Inside Eeschema, filenames are stored using unix notation + newRelativeFilename.Replace( wxT( "\\" ), wxT( "/" ) ); + + wxString newSheetname = m_fields->at( SHEETNAME ).GetText(); + + if( newSheetname.IsEmpty() ) + newSheetname = _( "Untitled Sheet" ); + + // Relative file names are relative to the path of the current sheet. This allows for + // nesting of schematic files in subfolders. + wxFileName fileName( newRelativeNativeFilename ); fileName.SetExt( SchematicFileExtension ); - if( !fileName.IsOk() ) + if( !fileName.IsAbsolute() ) { - DisplayError( this, _( "File name is not valid!" ) ); - return false; + const SCH_SCREEN* currentScreen = g_CurrentSheet->LastScreen(); + + wxCHECK_MSG( currentScreen, false, "Invalid sheet path object." ); + + wxFileName currentSheetFileName = currentScreen->GetFileName(); + + wxCHECK_MSG( fileName.Normalize( wxPATH_NORM_ALL, currentSheetFileName.GetPath() ), false, + "Cannot normalize new sheet schematic file path." ); } - m_sheet->SetShowFileName( m_filenameVisible->GetValue() ); - m_sheet->SetFileNameSize( m_filenameTextSize.GetValue() ); - m_sheet->SetShowSheetName( m_sheetnameVisible->GetValue() ); - m_sheet->SetSheetNameSize( m_sheetnameTextSize.GetValue() ); + wxString newAbsoluteFilename = fileName.GetFullPath(); + + // Inside Eeschema, filenames are stored using unix notation + newAbsoluteFilename.Replace( wxT( "\\" ), wxT( "/" ) ); + + wxString msg; + bool renameFile = false; + bool loadFromFile = false; + bool clearAnnotation = false; + bool restoreSheet = false; + bool isExistingSheet = false; + SCH_SCREEN* useScreen = NULL; + + // Search for a schematic file having the same filename already in use in the hierarchy + // or on disk, in order to reuse it. + if( !g_RootSheet->SearchHierarchy( newAbsoluteFilename, &useScreen ) ) + { + loadFromFile = wxFileExists( newAbsoluteFilename ); + wxLogDebug( "Sheet requested file \"%s\", %s", + newAbsoluteFilename, + ( loadFromFile ) ? "found" : "not found" ); + } + + if( m_sheet->GetScreen() == NULL ) // New sheet. + { + if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) ) + return false; + + if( useScreen || loadFromFile ) // Load from existing file. + { + clearAnnotation = true; + + wxString existsMsg; + wxString linkMsg; + existsMsg.Printf( _( "\"%s\" already exists." ), fileName.GetFullName() ); + linkMsg.Printf( _( "Link \"%s\" to this file?" ), newSheetname ); + msg.Printf( wxT( "%s\n\n%s" ), existsMsg, linkMsg ); + + if( !IsOK( this, msg ) ) + return false; + + } + else // New file. + { + m_frame->InitSheet( m_sheet, newAbsoluteFilename ); + } + } + else // Existing sheet. + { + bool isUndoable = true; + wxString replaceMsg; + wxString newMsg; + wxString noUndoMsg; + + isExistingSheet = true; + + if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) ) + return false; + + // Changing the filename of a sheet can modify the full hierarchy structure + // and can be not always undoable. + // So prepare messages for user notifications: + replaceMsg.Printf( _( "Change \"%s\" link from \"%s\" to \"%s\"?" ), + newSheetname, + m_sheet->GetFileName(), + fileName.GetFullName() ); + newMsg.Printf( _( "Create new file \"%s\" with contents of \"%s\"?" ), + fileName.GetFullName(), + m_sheet->GetFileName() ); + noUndoMsg = _( "This action cannot be undone." ); + + // We are always using here a case insensitive comparison to avoid issues + // under Windows, although under Unix filenames are case sensitive. + // But many users create schematic under both Unix and Windows + // ** + // N.B. 1: aSheet->GetFileName() will return a relative path + // aSheet->GetScreen()->GetFileName() returns a full path + // + // N.B. 2: newFilename uses the unix notation for separator. + // so we must use it also to compare the old and new filenames + wxString oldAbsoluteFilename = m_sheet->GetScreen()->GetFileName(); + oldAbsoluteFilename.Replace( wxT( "\\" ), wxT( "/" ) ); + + if( newAbsoluteFilename.Cmp( oldAbsoluteFilename ) != 0 ) + { + // Sheet file name changes cannot be undone. + isUndoable = false; + + if( useScreen || loadFromFile ) // Load from existing file. + { + clearAnnotation = true; + + msg.Printf( wxT( "%s\n\n%s" ), replaceMsg, noUndoMsg ); + + if( !IsOK( this, msg ) ) + return false; + + if( loadFromFile ) + m_sheet->SetScreen( NULL ); + } + else // Save to new file name. + { + if( m_sheet->GetScreenCount() > 1 ) + { + msg.Printf( wxT( "%s\n\n%s" ), newMsg, noUndoMsg ); + + if( !IsOK( this, msg ) ) + return false; + } + + renameFile = true; + } + } + + if( isUndoable ) + m_frame->SaveCopyInUndoList( m_sheet, UR_CHANGED ); + + if( renameFile ) + { + SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) ); + + // If the the associated screen is shared by more than one sheet, do not + // change the filename of the corresponding screen here. + // (a new screen will be created later) + // if it is not shared, update the filename + if( m_sheet->GetScreenCount() <= 1 ) + m_sheet->GetScreen()->SetFileName( newAbsoluteFilename ); + + try + { + pi->Save( newAbsoluteFilename, m_sheet->GetScreen(), &Kiway() ); + } + catch( const IO_ERROR& ioe ) + { + msg.Printf( _( "Error occurred saving schematic file \"%s\"." ), newAbsoluteFilename ); + DisplayErrorMessage( this, msg, ioe.What() ); + + msg.Printf( _( "Failed to save schematic \"%s\"" ), newAbsoluteFilename ); + m_frame->AppendMsgPanel( wxEmptyString, msg, CYAN ); + + return false; + } + + // If the the associated screen is shared by more than one sheet, remove the + // screen and reload the file to a new screen. Failure to do this will trash + // the screen reference counting in complex hierarchies. + if( m_sheet->GetScreenCount() > 1 ) + { + m_sheet->SetScreen( NULL ); + loadFromFile = true; + } + } + } + + wxFileName nativeFileName( newRelativeNativeFilename ); + nativeFileName.SetExt( SchematicFileExtension ); + + if( useScreen ) + { + // Create a temporary sheet for recursion testing to prevent a possible recursion error. + std::unique_ptr< SCH_SHEET> tmpSheet( new SCH_SHEET ); + tmpSheet->SetName( m_fields->at( SHEETNAME ).GetText() ); + tmpSheet->SetFileName( nativeFileName.GetFullPath() ); + tmpSheet->SetScreen( useScreen ); + + // No need to check for valid library IDs if we are using an existing screen. + if( m_frame->CheckSheetForRecursion( tmpSheet.get(), g_CurrentSheet ) ) + { + if( restoreSheet ) + g_CurrentSheet->LastScreen()->Append( m_sheet ); + + return false; + } + + // It's safe to set the sheet screen now. + m_sheet->SetScreen( useScreen ); + } + else if( loadFromFile ) + { + if( isExistingSheet ) + { + // Temporarily remove the sheet from the current schematic page so that recursion + // and symbol library link tests can be performed with the modified sheet settings. + restoreSheet = true; + g_CurrentSheet->LastScreen()->Remove( m_sheet ); + } + + if( !m_frame->LoadSheetFromFile( m_sheet, g_CurrentSheet, newAbsoluteFilename ) + || m_frame->CheckSheetForRecursion( m_sheet, g_CurrentSheet ) ) + { + if( restoreSheet ) + g_CurrentSheet->LastScreen()->Append( m_sheet ); + + return false; + } + + if( restoreSheet ) + g_CurrentSheet->LastScreen()->Append( m_sheet ); + } + + m_fields->at( SHEETFILENAME ).SetText( newRelativeFilename ); + m_fields->at( SHEETNAME ).SetText( newSheetname ); + + // change all field positions from relative to absolute + for( unsigned i = 0; i < m_fields->size(); ++i ) + m_fields->at( i ).Offset( m_sheet->GetPosition() ); + + if( positioningChanged( m_fields, m_sheet->GetFields() ) ) + m_sheet->ClearFieldsAutoplaced(); + + m_sheet->SetFields( *m_fields ); + + if( m_clearAnnotationNewItems ) + *m_clearAnnotationNewItems = clearAnnotation; + + m_frame->TestDanglingEnds(); + m_frame->RefreshItem( m_sheet ); + m_frame->OnModify(); return true; } -void DIALOG_SCH_SHEET_PROPS::OnBrowseClicked( wxCommandEvent& event ) +void DIALOG_SCH_SHEET_PROPS::OnGridCellChanging( wxGridEvent& event ) { - // Build the absolute path of current sheet to preselect it when opening the dialog. - wxString path = Prj().AbsolutePath( m_textFileName->GetValue() ); - wxFileName fn( path ); + wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() ); + wxControl* control = editor->GetControl(); - wxFileDialog fileDialog( this, _( "Sheet File" ), fn.GetPath(), fn.GetFullName(), - SchematicFileExtension, wxFD_OPEN | wxFD_FILE_MUST_EXIST ); - - if( fileDialog.ShowModal() == wxID_OK ) + if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) ) { - fn.Assign( fileDialog.GetPath() ); - fn.MakeRelativeTo( Prj().GetProjectPath() ); + event.Veto(); + m_delayedFocusRow = event.GetRow(); + m_delayedFocusColumn = event.GetCol(); + } - m_textFileName->ChangeValue( fn.GetFullPath() ); + editor->DecRef(); +} + + +void DIALOG_SCH_SHEET_PROPS::OnAddField( wxCommandEvent& event ) +{ + if( !m_grid->CommitPendingChanges() ) + return; + + int fieldID = m_fields->size(); + SCH_FIELD newField( wxPoint( 0, 0 ), fieldID, m_sheet ); + + newField.SetName( SCH_SHEET::GetDefaultFieldName( fieldID ) ); + newField.SetTextAngle( m_fields->at( SHEETNAME ).GetTextAngle() ); + + m_fields->push_back( newField ); + + // notify the grid + wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1 ); + m_grid->ProcessTableMessage( msg ); + + m_grid->MakeCellVisible( m_fields->size() - 1, 0 ); + m_grid->SetGridCursor( m_fields->size() - 1, 0 ); + + m_grid->EnableCellEditControl(); + m_grid->ShowCellEditControl(); +} + + +void DIALOG_SCH_SHEET_PROPS::OnDeleteField( wxCommandEvent& event ) +{ + int curRow = m_grid->GetGridCursorRow(); + + if( curRow < 0 ) + return; + else if( curRow < SHEET_MANDATORY_FIELDS ) + { + DisplayError( this, wxString::Format( _( "The first %d fields are mandatory." ), + SHEET_MANDATORY_FIELDS ) ); + return; + } + + m_grid->CommitPendingChanges( true /* quiet mode */ ); + + m_fields->erase( m_fields->begin() + curRow ); + + // notify the grid + wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_DELETED, curRow, 1 ); + m_grid->ProcessTableMessage( msg ); + + if( m_grid->GetNumberRows() > 0 ) + { + m_grid->MakeCellVisible( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() ); + m_grid->SetGridCursor( std::max( 0, curRow-1 ), m_grid->GetGridCursorCol() ); } } -const wxString DIALOG_SCH_SHEET_PROPS::GetFileName() +void DIALOG_SCH_SHEET_PROPS::OnMoveUp( wxCommandEvent& event ) { - // Filenames are stored using unix notation - wxString fname = m_textFileName->GetValue(); - fname.Replace( wxT("\\"), wxT("/") ); - return fname; + if( !m_grid->CommitPendingChanges() ) + return; + + int i = m_grid->GetGridCursorRow(); + + if( i > SHEET_MANDATORY_FIELDS ) + { + SCH_FIELD tmp = m_fields->at( (unsigned) i ); + m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 ); + m_fields->insert( m_fields->begin() + i - 1, tmp ); + m_grid->ForceRefresh(); + + m_grid->SetGridCursor( i - 1, m_grid->GetGridCursorCol() ); + m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() ); + } + else + wxBell(); +} + + +void DIALOG_SCH_SHEET_PROPS::OnMoveDown( wxCommandEvent& event ) +{ + if( !m_grid->CommitPendingChanges() ) + return; + + int i = m_grid->GetGridCursorRow(); + + if( i >= SHEET_MANDATORY_FIELDS && i < m_grid->GetNumberRows() - 1 ) + { + SCH_FIELD tmp = m_fields->at( (unsigned) i ); + m_fields->erase( m_fields->begin() + i, m_fields->begin() + i + 1 ); + m_fields->insert( m_fields->begin() + i + 1, tmp ); + m_grid->ForceRefresh(); + + m_grid->SetGridCursor( i + 1, m_grid->GetGridCursorCol() ); + m_grid->MakeCellVisible( m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol() ); + } + else + wxBell(); +} + + +void DIALOG_SCH_SHEET_PROPS::AdjustGridColumns( int aWidth ) +{ + m_width = aWidth; + // Account for scroll bars + aWidth -= ( m_grid->GetSize().x - m_grid->GetClientSize().x ); + + m_grid->AutoSizeColumn( 0 ); + + int fixedColsWidth = m_grid->GetColSize( 0 ); + + for( int i = 2; i < m_grid->GetNumberCols(); i++ ) + fixedColsWidth += m_grid->GetColSize( i ); + + m_grid->SetColSize( 1, aWidth - fixedColsWidth ); +} + + +void DIALOG_SCH_SHEET_PROPS::OnUpdateUI( wxUpdateUIEvent& event ) +{ + wxString shownColumns = m_grid->GetShownColumns(); + + if( shownColumns != m_shownColumns ) + { + m_shownColumns = shownColumns; + + if( !m_grid->IsCellEditControlShown() ) + AdjustGridColumns( m_grid->GetRect().GetWidth() ); + } + + // Handle a delayed focus + if( m_delayedFocusRow >= 0 ) + { + m_grid->SetFocus(); + m_grid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn ); + m_grid->SetGridCursor( m_delayedFocusRow, m_delayedFocusColumn ); + + + m_grid->EnableCellEditControl( true ); + m_grid->ShowCellEditControl(); + + m_delayedFocusRow = -1; + m_delayedFocusColumn = -1; + } +} + + +void DIALOG_SCH_SHEET_PROPS::OnSizeGrid( wxSizeEvent& event ) +{ + auto new_size = event.GetSize().GetX(); + + if( m_width != new_size ) + { + AdjustGridColumns( new_size ); + } + + // Always propagate for a grid repaint (needed if the height changes, as well as width) + event.Skip(); +} + + +void DIALOG_SCH_SHEET_PROPS::OnInitDlg( wxInitDialogEvent& event ) +{ + TransferDataToWindow(); + + // Now all widgets have the size fixed, call FinishDialogSettings + FinishDialogSettings(); } diff --git a/eeschema/dialogs/dialog_sch_sheet_props.h b/eeschema/dialogs/dialog_sch_sheet_props.h index 2fbc6a6bbe..fa607f7bdc 100644 --- a/eeschema/dialogs/dialog_sch_sheet_props.h +++ b/eeschema/dialogs/dialog_sch_sheet_props.h @@ -26,32 +26,49 @@ #define __dialog_sch_sheet_props__ #include -#include +#include class SCH_SHEET; class SCH_EDIT_FRAME; -/** Implementing DIALOG_SCH_SHEET_PROPS_BASE */ class DIALOG_SCH_SHEET_PROPS : public DIALOG_SCH_SHEET_PROPS_BASE { - SCH_SHEET* m_sheet; - - UNIT_BINDER m_filenameTextSize; - UNIT_BINDER m_sheetnameTextSize; - public: - /** Constructor */ - DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* parent, SCH_SHEET* aSheet ); + DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* aParent, SCH_SHEET* aSheet, + bool* aClearAnnotationNewItems ); + + ~DIALOG_SCH_SHEET_PROPS() override; + +private: + SCH_EDIT_FRAME* m_frame; + SCH_SHEET* m_sheet; + bool* m_clearAnnotationNewItems; + + int m_width; + int m_delayedFocusRow; + int m_delayedFocusColumn; + wxString m_shownColumns; + + FIELDS_GRID_TABLE* m_fields; bool TransferDataToWindow() override; bool TransferDataFromWindow() override; - void OnBrowseClicked( wxCommandEvent& event ) override; + bool Validate() override; - const wxString GetFileName(); - wxString GetSheetName() { return m_textSheetName->GetValue(); } + // event handlers + void OnAddField( wxCommandEvent& event ) override; + void OnDeleteField( wxCommandEvent& event ) override; + void OnMoveUp( wxCommandEvent& event ) override; + void OnMoveDown( wxCommandEvent& event ) override; + void OnSizeGrid( wxSizeEvent& event ) override; + void OnGridCellChanging( wxGridEvent& event ); + void OnUpdateUI( wxUpdateUIEvent& event ) override; + void OnInitDlg( wxInitDialogEvent& event ) override; + + void AdjustGridColumns( int aWidth ); }; #endif // __dialog_sch_sheet_props__ diff --git a/eeschema/dialogs/dialog_sch_sheet_props_base.cpp b/eeschema/dialogs/dialog_sch_sheet_props_base.cpp index acfe646d5a..6029e98bb5 100644 --- a/eeschema/dialogs/dialog_sch_sheet_props_base.cpp +++ b/eeschema/dialogs/dialog_sch_sheet_props_base.cpp @@ -1,147 +1,193 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jul 10 2019) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// +#include "widgets/wx_grid.h" + #include "dialog_sch_sheet_props_base.h" /////////////////////////////////////////////////////////////////////////// -BEGIN_EVENT_TABLE( DIALOG_SCH_SHEET_PROPS_BASE, DIALOG_SHIM ) - EVT_BUTTON( ID_BUTTON_BROWSE_SHEET, DIALOG_SCH_SHEET_PROPS_BASE::_wxFB_OnBrowseClicked ) -END_EVENT_TABLE() - DIALOG_SCH_SHEET_PROPS_BASE::DIALOG_SCH_SHEET_PROPS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxSize( 500,150 ), wxDefaultSize ); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); wxBoxSizer* mainSizer; mainSizer = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer* bupperSizer; - bupperSizer = new wxBoxSizer( wxVERTICAL ); + m_longForm = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer* bSizer3; - bSizer3 = new wxBoxSizer( wxHORIZONTAL ); + wxStaticBoxSizer* sbFields; + sbFields = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Fields") ), wxVERTICAL ); - m_filenameLabel = new wxStaticText( this, wxID_ANY, _("&File name:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_filenameLabel->Wrap( -1 ); - bSizer3->Add( m_filenameLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + m_grid = new WX_GRID( sbFields->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); - m_textFileName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textFileName->SetMinSize( wxSize( 360,-1 ) ); + // Grid + m_grid->CreateGrid( 4, 11 ); + m_grid->EnableEditing( true ); + m_grid->EnableGridLines( true ); + m_grid->EnableDragGridSize( false ); + m_grid->SetMargins( 0, 0 ); - bSizer3->Add( m_textFileName, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + // Columns + m_grid->SetColSize( 0, 72 ); + m_grid->SetColSize( 1, 120 ); + m_grid->SetColSize( 2, 48 ); + m_grid->SetColSize( 3, 72 ); + m_grid->SetColSize( 4, 72 ); + m_grid->SetColSize( 5, 48 ); + m_grid->SetColSize( 6, 48 ); + m_grid->SetColSize( 7, 84 ); + m_grid->SetColSize( 8, 84 ); + m_grid->SetColSize( 9, 84 ); + m_grid->SetColSize( 10, 84 ); + m_grid->EnableDragColMove( false ); + m_grid->EnableDragColSize( true ); + m_grid->SetColLabelSize( 22 ); + m_grid->SetColLabelValue( 0, _("Name") ); + m_grid->SetColLabelValue( 1, _("Value") ); + m_grid->SetColLabelValue( 2, _("Show") ); + m_grid->SetColLabelValue( 3, _("H Align") ); + m_grid->SetColLabelValue( 4, _("V Align") ); + m_grid->SetColLabelValue( 5, _("Italic") ); + m_grid->SetColLabelValue( 6, _("Bold") ); + m_grid->SetColLabelValue( 7, _("Text Size") ); + m_grid->SetColLabelValue( 8, _("Orientation") ); + m_grid->SetColLabelValue( 9, _("X Position") ); + m_grid->SetColLabelValue( 10, _("Y Position") ); + m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); - m_browseButton = new wxBitmapButton( this, ID_BUTTON_BROWSE_SHEET, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); - m_browseButton->SetMinSize( wxSize( 30,28 ) ); + // Rows + m_grid->EnableDragRowSize( true ); + m_grid->SetRowLabelSize( 0 ); + m_grid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); - bSizer3->Add( m_browseButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + // Label Appearance + + // Cell Defaults + m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + m_grid->SetMinSize( wxSize( -1,180 ) ); + + sbFields->Add( m_grid, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bButtonSize; + bButtonSize = new wxBoxSizer( wxHORIZONTAL ); + + m_bpAdd = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + m_bpAdd->SetToolTip( _("Add field") ); + m_bpAdd->SetMinSize( wxSize( 30,30 ) ); + + bButtonSize->Add( m_bpAdd, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_bpMoveUp = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + m_bpMoveUp->SetToolTip( _("Move up") ); + m_bpMoveUp->SetMinSize( wxSize( 30,30 ) ); + + bButtonSize->Add( m_bpMoveUp, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_bpMoveDown = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + m_bpMoveDown->SetToolTip( _("Move down") ); + m_bpMoveDown->SetMinSize( wxSize( 30,30 ) ); + + bButtonSize->Add( m_bpMoveDown, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - bupperSizer->Add( bSizer3, 0, wxEXPAND, 5 ); + bButtonSize->Add( 0, 0, 0, wxEXPAND|wxLEFT|wxRIGHT, 10 ); - wxBoxSizer* bSizerFilenameSettings; - bSizerFilenameSettings = new wxBoxSizer( wxHORIZONTAL ); + m_bpDelete = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + m_bpDelete->SetToolTip( _("Delete field") ); + m_bpDelete->SetMinSize( wxSize( 30,30 ) ); - m_filenameVisible = new wxCheckBox( this, wxID_ANY, _("Visible"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizerFilenameSettings->Add( m_filenameVisible, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 36 ); - - m_filenameSizeLabel = new wxStaticText( this, wxID_ANY, _("Text size:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_filenameSizeLabel->Wrap( -1 ); - bSizerFilenameSettings->Add( m_filenameSizeLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_filenameSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - bSizerFilenameSettings->Add( m_filenameSizeCtrl, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - m_filenameSizeUnits = new wxStaticText( this, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 ); - m_filenameSizeUnits->Wrap( -1 ); - bSizerFilenameSettings->Add( m_filenameSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + bButtonSize->Add( m_bpDelete, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - bupperSizer->Add( bSizerFilenameSettings, 0, wxEXPAND, 5 ); + bButtonSize->Add( 0, 0, 1, wxEXPAND, 5 ); - bupperSizer->Add( 0, 15, 0, wxEXPAND, 5 ); + sbFields->Add( bButtonSize, 0, wxALL|wxEXPAND, 5 ); + + + m_longForm->Add( sbFields, 1, wxALL|wxEXPAND, 5 ); wxBoxSizer* bSizer5; bSizer5 = new wxBoxSizer( wxHORIZONTAL ); - m_sheetnameLabel = new wxStaticText( this, wxID_ANY, _("&Sheet name:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_sheetnameLabel->Wrap( -1 ); - bSizer5->Add( m_sheetnameLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + m_staticText2 = new wxStaticText( this, wxID_ANY, _("Hierarchical Path:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText2->Wrap( -1 ); + bSizer5->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_textSheetName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - bSizer5->Add( m_textSheetName, 5, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + m_heirarchyPath = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); + bSizer5->Add( m_heirarchyPath, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - bupperSizer->Add( bSizer5, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizerSheetnameSettings; - bSizerSheetnameSettings = new wxBoxSizer( wxHORIZONTAL ); - - m_sheetnameVisible = new wxCheckBox( this, wxID_ANY, _("Visible"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizerSheetnameSettings->Add( m_sheetnameVisible, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 36 ); - - m_sheetnameSizeLabel = new wxStaticText( this, wxID_ANY, _("Text size:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_sheetnameSizeLabel->Wrap( -1 ); - bSizerSheetnameSettings->Add( m_sheetnameSizeLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_sheetnameSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - bSizerSheetnameSettings->Add( m_sheetnameSizeCtrl, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - m_sheetnameSizeUnits = new wxStaticText( this, wxID_ANY, _("units"), wxDefaultPosition, wxDefaultSize, 0 ); - m_sheetnameSizeUnits->Wrap( -1 ); - bSizerSheetnameSettings->Add( m_sheetnameSizeUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + m_longForm->Add( bSizer5, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - bupperSizer->Add( bSizerSheetnameSettings, 0, wxEXPAND, 5 ); - - - bupperSizer->Add( 0, 20, 0, 0, 5 ); - - m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bupperSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 ); - - m_staticTextUuid = new wxStaticText( this, wxID_ANY, _("UUID:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextUuid->Wrap( -1 ); - bupperSizer->Add( m_staticTextUuid, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlUuid = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); - bupperSizer->Add( m_textCtrlUuid, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - m_staticTextHpath = new wxStaticText( this, wxID_ANY, _("Hierarchical Path:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextHpath->Wrap( -1 ); - bupperSizer->Add( m_staticTextHpath, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlHpath = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); - bupperSizer->Add( m_textCtrlHpath, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 ); - - - mainSizer->Add( bupperSizer, 0, wxEXPAND|wxALL, 5 ); + mainSizer->Add( m_longForm, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); mainSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 ); - m_sdbSizer1 = new wxStdDialogButtonSizer(); - m_sdbSizer1OK = new wxButton( this, wxID_OK ); - m_sdbSizer1->AddButton( m_sdbSizer1OK ); - m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL ); - m_sdbSizer1->AddButton( m_sdbSizer1Cancel ); - m_sdbSizer1->Realize(); + wxBoxSizer* bSizerBottom; + bSizerBottom = new wxBoxSizer( wxHORIZONTAL ); - mainSizer->Add( m_sdbSizer1, 0, wxALL|wxEXPAND, 5 ); + wxBoxSizer* bSizerUUID; + bSizerUUID = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticText* timeStampLabel; + timeStampLabel = new wxStaticText( this, wxID_ANY, _("Unique ID:"), wxDefaultPosition, wxDefaultSize, 0 ); + timeStampLabel->Wrap( -1 ); + bSizerUUID->Add( timeStampLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlTimeStamp = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); + m_textCtrlTimeStamp->SetToolTip( _("Unique ID that identifies the symbol") ); + + bSizerUUID->Add( m_textCtrlTimeStamp, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + bSizerBottom->Add( bSizerUUID, 3, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + + bSizerBottom->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_stdDialogButtonSizer = new wxStdDialogButtonSizer(); + m_stdDialogButtonSizerOK = new wxButton( this, wxID_OK ); + m_stdDialogButtonSizer->AddButton( m_stdDialogButtonSizerOK ); + m_stdDialogButtonSizerCancel = new wxButton( this, wxID_CANCEL ); + m_stdDialogButtonSizer->AddButton( m_stdDialogButtonSizerCancel ); + m_stdDialogButtonSizer->Realize(); + + bSizerBottom->Add( m_stdDialogButtonSizer, 0, wxEXPAND|wxALL, 5 ); + + + mainSizer->Add( bSizerBottom, 0, wxEXPAND|wxLEFT, 5 ); this->SetSizer( mainSizer ); this->Layout(); - mainSizer->Fit( this ); - this->Centre( wxBOTH ); + // Connect Events + this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnInitDlg ) ); + this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnUpdateUI ) ); + m_grid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnSizeGrid ), NULL, this ); + m_bpAdd->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnAddField ), NULL, this ); + m_bpMoveUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnMoveUp ), NULL, this ); + m_bpMoveDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnMoveDown ), NULL, this ); + m_bpDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnDeleteField ), NULL, this ); } DIALOG_SCH_SHEET_PROPS_BASE::~DIALOG_SCH_SHEET_PROPS_BASE() { + // Disconnect Events + this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnInitDlg ) ); + this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnUpdateUI ) ); + m_grid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnSizeGrid ), NULL, this ); + m_bpAdd->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnAddField ), NULL, this ); + m_bpMoveUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnMoveUp ), NULL, this ); + m_bpMoveDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnMoveDown ), NULL, this ); + m_bpDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SCH_SHEET_PROPS_BASE::OnDeleteField ), NULL, this ); + } diff --git a/eeschema/dialogs/dialog_sch_sheet_props_base.fbp b/eeschema/dialogs/dialog_sch_sheet_props_base.fbp index cad70c98de..aecb160bd1 100644 --- a/eeschema/dialogs/dialog_sch_sheet_props_base.fbp +++ b/eeschema/dialogs/dialog_sch_sheet_props_base.fbp @@ -2,22 +2,21 @@ - + ; C++ 1 source_name 0 0 res - UTF-8 - table + ANSI + connect dialog_sch_sheet_props_base 1000 none - 1 - dialog_sch_sheet_props + dialog_sch_sheet_props_base . @@ -26,14 +25,13 @@ 1 1 UI - 0 - 1 + 0 0 0 wxAUI_MGR_DEFAULT - wxBOTH + 1 1 @@ -44,17 +42,19 @@ 0 wxID_ANY - 500,150 + DIALOG_SCH_SHEET_PROPS_BASE - -1,-1 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + 864,440 + wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU DIALOG_SHIM; dialog_shim.h - Schematic Sheet Properties + Symbol Properties + OnInitDlg + OnUpdateUI mainSizer @@ -62,25 +62,451 @@ none 5 - wxEXPAND|wxALL - 0 + wxEXPAND|wxRIGHT|wxLEFT + 1 - bupperSizer + m_longForm wxVERTICAL - none + protected 5 - wxEXPAND + wxALL|wxEXPAND + 1 + + wxID_ANY + Fields + + sbFields + wxVERTICAL + 1 + none + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTER + 22 + "Name" "Value" "Show" "H Align" "V Align" "Italic" "Bold" "Text Size" "Orientation" "X Position" "Y Position" + wxALIGN_CENTER + 11 + 72,120,48,72,72,48,48,84,84,84,84 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + 0 + 1 + 1 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + -1,180 + 1 + m_grid + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 4 + 1 + + WX_GRID; widgets/wx_grid.h; forward_declare + 0 + + + + + OnSizeGrid + + + + 5 + wxALL|wxEXPAND + 0 + + + bButtonSize + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Add Field + + 0 + + 0 + + + 0 + 30,30 + 1 + m_bpAdd + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; forward_declare + 0 + Add field + + wxFILTER_NONE + wxDefaultValidator + + + + + OnAddField + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Move Up + + 0 + + 0 + + + 0 + 30,30 + 1 + m_bpMoveUp + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; forward_declare + 0 + Move up + + wxFILTER_NONE + wxDefaultValidator + + + + + OnMoveUp + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Move Down + + 0 + + 0 + + + 0 + 30,30 + 1 + m_bpMoveDown + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; forward_declare + 0 + Move down + + wxFILTER_NONE + wxDefaultValidator + + + + + OnMoveDown + + + + 10 + wxEXPAND|wxLEFT|wxRIGHT + 0 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Delete Field + + 0 + + 0 + + + 0 + 30,30 + 1 + m_bpDelete + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; forward_declare + 0 + Delete field + + wxFILTER_NONE + wxDefaultValidator + + + + + OnDeleteField + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT 0 - bSizer3 + bSizer5 wxHORIZONTAL none 5 - wxALL|wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 1 @@ -110,7 +536,7 @@ 0 0 wxID_ANY - &File name: + Hierarchical Path: 0 0 @@ -119,7 +545,7 @@ 0 1 - m_filenameLabel + m_staticText2 1 @@ -130,7 +556,7 @@ 1 - + ; ; forward_declare 0 @@ -174,12 +600,12 @@ 0 - 0 + 0 - 360,-1 + 1 - m_textFileName + m_heirarchyPath 1 @@ -189,80 +615,7 @@ Resizable 1 - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - - 1 - 0 - 1 - - 1 - - 0 - 0 - - Dock - 0 - Left - 1 - - 1 - - - 0 - 0 - ID_BUTTON_BROWSE_SHEET - Browse... - - 0 - - 0 - - - 0 - 30,28 - 1 - m_browseButton - 1 - - - protected - 1 - - - - Resizable - 1 - - + wxTE_READONLY ; ; forward_declare 0 @@ -270,998 +623,12 @@ wxFILTER_NONE wxDefaultValidator - - - - OnBrowseClicked - - - - - - 5 - wxEXPAND - 0 - - - bSizerFilenameSettings - wxHORIZONTAL - none - - 36 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Visible - - 0 - - - 0 - - 1 - m_filenameVisible - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Text size: - 0 - - 0 - - - 0 - - 1 - m_filenameSizeLabel - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - - 1 - m_filenameSizeCtrl - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - units - 0 - - 0 - - - 0 - - 1 - m_filenameSizeUnits - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - 5 - wxEXPAND - 0 - - 15 - protected - 0 - - - - 5 - wxEXPAND - 0 - - - bSizer5 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - &Sheet name: - 0 - - 0 - - - 0 - - 1 - m_sheetnameLabel - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT - 5 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - - 1 - m_textSheetName - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - 5 - wxEXPAND - 0 - - - bSizerSheetnameSettings - wxHORIZONTAL - none - - 36 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Visible - - 0 - - - 0 - - 1 - m_sheetnameVisible - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Text size: - 0 - - 0 - - - 0 - - 1 - m_sheetnameSizeLabel - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - - 1 - m_sheetnameSizeCtrl - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - units - 0 - - 0 - - - 0 - - 1 - m_sheetnameSizeUnits - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - 5 - - 0 - - 20 - protected - 0 - - - - 5 - wxEXPAND | wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_staticline2 - 1 - - - protected - 1 - - Resizable - 1 - - wxLI_HORIZONTAL - ; ; forward_declare - 0 - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - UUID: - 0 - - 0 - - - 0 - - 1 - m_staticTextUuid - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_textCtrlUuid - 1 - - - protected - 1 - - Resizable - 1 - - wxTE_READONLY - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Hierarchical Path: - 0 - - 0 - - - 0 - - 1 - m_staticTextHpath - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_textCtrlHpath - 1 - - - protected - 1 - - Resizable - 1 - - wxTE_READONLY - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - @@ -1316,7 +683,7 @@ 1 wxLI_HORIZONTAL - + ; forward_declare 0 @@ -1326,20 +693,177 @@ 5 - wxALL|wxEXPAND + wxEXPAND|wxLEFT 0 - - 0 - 1 - 0 - 0 - 0 - 1 - 0 - 0 + - m_sdbSizer1 - protected + bSizerBottom + wxHORIZONTAL + none + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 3 + + + bSizerUUID + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Unique ID: + 0 + + 0 + + + 0 + + 1 + timeStampLabel + 1 + + + none + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_textCtrlTimeStamp + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_READONLY + + 0 + Unique ID that identifies the symbol + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxEXPAND|wxALL + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_stdDialogButtonSizer + protected + + diff --git a/eeschema/dialogs/dialog_sch_sheet_props_base.h b/eeschema/dialogs/dialog_sch_sheet_props_base.h index eb3d7d9564..69a13daca5 100644 --- a/eeschema/dialogs/dialog_sch_sheet_props_base.h +++ b/eeschema/dialogs/dialog_sch_sheet_props_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Jul 10 2019) +// C++ code generated with wxFormBuilder (version Oct 26 2018) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -10,74 +10,65 @@ #include #include #include +class WX_GRID; + #include "dialog_shim.h" -#include -#include -#include -#include #include #include -#include +#include +#include +#include +#include #include #include #include #include #include #include -#include +#include +#include +#include #include #include /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// /// Class DIALOG_SCH_SHEET_PROPS_BASE /////////////////////////////////////////////////////////////////////////////// class DIALOG_SCH_SHEET_PROPS_BASE : public DIALOG_SHIM { - DECLARE_EVENT_TABLE() private: - // Private event handlers - void _wxFB_OnBrowseClicked( wxCommandEvent& event ){ OnBrowseClicked( event ); } - - protected: - enum - { - ID_BUTTON_BROWSE_SHEET = 1000 - }; - - wxStaticText* m_filenameLabel; - wxTextCtrl* m_textFileName; - wxBitmapButton* m_browseButton; - wxCheckBox* m_filenameVisible; - wxStaticText* m_filenameSizeLabel; - wxTextCtrl* m_filenameSizeCtrl; - wxStaticText* m_filenameSizeUnits; - wxStaticText* m_sheetnameLabel; - wxTextCtrl* m_textSheetName; - wxCheckBox* m_sheetnameVisible; - wxStaticText* m_sheetnameSizeLabel; - wxTextCtrl* m_sheetnameSizeCtrl; - wxStaticText* m_sheetnameSizeUnits; - wxStaticLine* m_staticline2; - wxStaticText* m_staticTextUuid; - wxTextCtrl* m_textCtrlUuid; - wxStaticText* m_staticTextHpath; - wxTextCtrl* m_textCtrlHpath; + wxBoxSizer* m_longForm; + WX_GRID* m_grid; + wxBitmapButton* m_bpAdd; + wxBitmapButton* m_bpMoveUp; + wxBitmapButton* m_bpMoveDown; + wxBitmapButton* m_bpDelete; + wxStaticText* m_staticText2; + wxTextCtrl* m_heirarchyPath; wxStaticLine* m_staticline1; - wxStdDialogButtonSizer* m_sdbSizer1; - wxButton* m_sdbSizer1OK; - wxButton* m_sdbSizer1Cancel; + wxTextCtrl* m_textCtrlTimeStamp; + wxStdDialogButtonSizer* m_stdDialogButtonSizer; + wxButton* m_stdDialogButtonSizerOK; + wxButton* m_stdDialogButtonSizerCancel; // Virtual event handlers, overide them in your derived class - virtual void OnBrowseClicked( wxCommandEvent& event ) { event.Skip(); } + virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); } + virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } + virtual void OnSizeGrid( wxSizeEvent& event ) { event.Skip(); } + virtual void OnAddField( wxCommandEvent& event ) { event.Skip(); } + virtual void OnMoveUp( wxCommandEvent& event ) { event.Skip(); } + virtual void OnMoveDown( wxCommandEvent& event ) { event.Skip(); } + virtual void OnDeleteField( wxCommandEvent& event ) { event.Skip(); } public: - DIALOG_SCH_SHEET_PROPS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Schematic Sheet Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_SCH_SHEET_PROPS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Symbol Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 864,440 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU ); ~DIALOG_SCH_SHEET_PROPS_BASE(); }; diff --git a/eeschema/ee_collectors.cpp b/eeschema/ee_collectors.cpp index 460edea393..19832e30d1 100644 --- a/eeschema/ee_collectors.cpp +++ b/eeschema/ee_collectors.cpp @@ -73,7 +73,7 @@ SEARCH_RESULT EE_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData ) if( aItem->Type() == LIB_PIN_T ) { // Special selection rules apply to pins of different units when edited in - // synchronized pins mode. Leave it to EE_SELECTION_TOOL::isSelectable() to + // synchronized pins mode. Leave it to EE_SELECTION_TOOL::Selectable() to // decide what to do with them. } else if( m_Unit || m_Convert ) diff --git a/eeschema/eeschema_settings.cpp b/eeschema/eeschema_settings.cpp index 0b038c83f3..f3a12601f0 100644 --- a/eeschema/eeschema_settings.cpp +++ b/eeschema/eeschema_settings.cpp @@ -40,6 +40,9 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() : APP_SETTINGS_BASE( "eeschema", eeschema m_params.emplace_back( new PARAM( "appearance.edit_component_visible_columns", &m_Appearance.edit_component_visible_columns, "0 1 2 3 4 5 6 7" ) ); + m_params.emplace_back( new PARAM( "appearance.edit_sheet_visible_columns", + &m_Appearance.edit_sheet_visible_columns, "0 1 2 3 4 5 6 7" ) ); + m_params.emplace_back( new PARAM( "appearance.footprint_preview", &m_Appearance.footprint_preview, true ) ); diff --git a/eeschema/eeschema_settings.h b/eeschema/eeschema_settings.h index 296a87b69f..afc2be5893 100644 --- a/eeschema/eeschema_settings.h +++ b/eeschema/eeschema_settings.h @@ -34,6 +34,7 @@ public: struct APPEARANCE { wxString edit_component_visible_columns; + wxString edit_sheet_visible_columns; bool footprint_preview; bool navigator_stays_open; bool print_sheet_reference; diff --git a/eeschema/fields_grid_table.cpp b/eeschema/fields_grid_table.cpp index e698b7da67..dbf6f9c393 100644 --- a/eeschema/fields_grid_table.cpp +++ b/eeschema/fields_grid_table.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include "eda_doc.h" @@ -47,15 +48,45 @@ enum template FIELDS_GRID_TABLE::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* aFrame, LIB_PART* aPart ) : - m_frame( aFrame ), - m_userUnits( aDialog->GetUserUnits() ), - m_part( aPart ), - m_fieldNameValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_NAME ), - m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE ), - m_valueValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), VALUE ), - m_libIdValidator( LIB_ID::ID_PCB ), - m_urlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ), - m_nonUrlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ) + m_frame( aFrame ), + m_userUnits( aDialog->GetUserUnits() ), + m_parentType( SCH_COMPONENT_T ), + m_mandatoryFieldCount( MANDATORY_FIELDS ), + m_part( aPart ), + m_fieldNameValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_NAME ), + m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE ), + m_valueValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), VALUE ), + m_libIdValidator( LIB_ID::ID_PCB ), + m_urlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ), + m_nonUrlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ), + m_filepathValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), SHEETFILENAME ) +{ + initGrid( aDialog ); +} + + +template +FIELDS_GRID_TABLE::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* aFrame, + SCH_SHEET* aSheet ) : + m_frame( aFrame ), + m_userUnits( aDialog->GetUserUnits() ), + m_parentType( SCH_SHEET_T ), + m_mandatoryFieldCount( SHEET_MANDATORY_FIELDS ), + m_part( nullptr ), + m_fieldNameValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_NAME ), + m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE ), + m_valueValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), VALUE ), + m_libIdValidator( LIB_ID::ID_PCB ), + m_urlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ), + m_nonUrlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ), + m_filepathValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), SHEETFILENAME ) +{ + initGrid( aDialog ); +} + + +template +void FIELDS_GRID_TABLE::initGrid( DIALOG_SHIM* aDialog ) { // Build the various grid cell attributes. // NOTE: validators and cellAttrs are member variables to get the destruction order @@ -94,6 +125,13 @@ FIELDS_GRID_TABLE::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* a nonUrlEditor->SetValidator( m_nonUrlValidator ); m_nonUrlAttr->SetEditor( nonUrlEditor ); + m_curdir = m_frame->Prj().GetProjectPath(); + m_filepathAttr = new wxGridCellAttr; + GRID_CELL_PATH_EDITOR* filepathEditor = new GRID_CELL_PATH_EDITOR( aDialog, &m_curdir, + SchematicFileExtension ); + filepathEditor->SetValidator( m_filepathValidator ); + m_filepathAttr->SetEditor( filepathEditor ); + m_boolAttr = new wxGridCellAttr; m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() ); m_boolAttr->SetEditor( new wxGridCellBoolEditor() ); @@ -135,6 +173,7 @@ FIELDS_GRID_TABLE::~FIELDS_GRID_TABLE() m_footprintAttr->DecRef(); m_urlAttr->DecRef(); m_nonUrlAttr->DecRef(); + m_filepathAttr->DecRef(); m_vAlignAttr->DecRef(); m_hAlignAttr->DecRef(); m_orientationAttr->DecRef(); @@ -207,7 +246,7 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAtt switch( aCol ) { case FDC_NAME: - if( aRow < MANDATORY_FIELDS || rowIsReadOnly ) + if( aRow < m_mandatoryFieldCount || rowIsReadOnly ) { tmp = m_fieldNameAttr->Clone(); tmp->SetReadOnly( true ); @@ -221,7 +260,7 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAtt } case FDC_VALUE: - if( aRow == REFERENCE ) + if( m_parentType == SCH_COMPONENT_T && aRow == REFERENCE ) { if( rowIsReadOnly ) { @@ -236,7 +275,7 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAtt return m_referenceAttr; } } - else if( aRow == VALUE ) + else if( m_parentType == SCH_COMPONENT_T && aRow == VALUE ) { // For power symbols, the value is not editable, because value and pin name must // be the same and can be edited only in library editor. @@ -254,7 +293,7 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAtt return m_valueAttr; } } - else if( aRow == FOOTPRINT ) + else if( m_parentType == SCH_COMPONENT_T && aRow == FOOTPRINT ) { if( rowIsReadOnly ) { @@ -269,11 +308,16 @@ wxGridCellAttr* FIELDS_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAtt return m_footprintAttr; } } - else if( aRow == DATASHEET ) + else if( m_parentType == SCH_COMPONENT_T && aRow == DATASHEET ) { m_urlAttr->IncRef(); return m_urlAttr; } + else if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME ) + { + m_filepathAttr->IncRef(); + return m_filepathAttr; + } else { wxString fieldname = GetValue( aRow, FDC_NAME ); @@ -403,10 +447,15 @@ wxString FIELDS_GRID_TABLE::GetValue( int aRow, int aCol ) case FDC_NAME: // Use default field name for mandatory fields, because they are translated // according to the current locale - if( aRow < MANDATORY_FIELDS ) - return TEMPLATE_FIELDNAME::GetDefaultFieldName( aRow ); - else - return field.GetName( false ); + if( aRow < m_mandatoryFieldCount ) + { + if( m_parentType == SCH_COMPONENT_T ) + return TEMPLATE_FIELDNAME::GetDefaultFieldName( aRow ); + else if( m_parentType == SCH_SHEET_T ) + return SCH_SHEET::GetDefaultFieldName( aRow ); + } + + return field.GetName( false ); case FDC_VALUE: return field.GetText(); diff --git a/eeschema/fields_grid_table.h b/eeschema/fields_grid_table.h index 2b71d6a037..c25c68de27 100644 --- a/eeschema/fields_grid_table.h +++ b/eeschema/fields_grid_table.h @@ -73,6 +73,7 @@ class FIELDS_GRID_TABLE : public wxGridTableBase, public std::vector { public: FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* aFrame, LIB_PART* aPart ); + FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* aFrame, SCH_SHEET* aSheet ); ~FIELDS_GRID_TABLE(); int GetNumberRows() override { return (int) this->size(); } @@ -98,10 +99,16 @@ public: wxString StringFromBool( bool aValue ); bool BoolFromString( wxString aValue ); +protected: + void initGrid( DIALOG_SHIM* aDialog ); + private: SCH_BASE_FRAME* m_frame; EDA_UNITS m_userUnits; + KICAD_T m_parentType; + int m_mandatoryFieldCount; LIB_PART* m_part; + wxString m_curdir; SCH_FIELD_VALIDATOR m_fieldNameValidator; SCH_FIELD_VALIDATOR m_referenceValidator; @@ -109,6 +116,7 @@ private: LIB_ID_VALIDATOR m_libIdValidator; SCH_FIELD_VALIDATOR m_urlValidator; SCH_FIELD_VALIDATOR m_nonUrlValidator; + SCH_FIELD_VALIDATOR m_filepathValidator; wxGridCellAttr* m_readOnlyAttr; wxGridCellAttr* m_fieldNameAttr; @@ -117,6 +125,7 @@ private: wxGridCellAttr* m_footprintAttr; wxGridCellAttr* m_urlAttr; wxGridCellAttr* m_nonUrlAttr; + wxGridCellAttr* m_filepathAttr; wxGridCellAttr* m_boolAttr; wxGridCellAttr* m_vAlignAttr; wxGridCellAttr* m_hAlignAttr; diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index c857fbe79b..a1bdd20b8c 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -928,11 +928,11 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem ) m_Fields.swap( component->m_Fields ); // std::vector's swap() - for( int ii = 0; ii < component->GetFieldCount(); ++ii ) - component->GetField( ii )->SetParent( component ); + for( SCH_FIELD& field : component->m_Fields ) + field.SetParent( component ); - for( int ii = 0; ii < GetFieldCount(); ++ii ) - GetField( ii )->SetParent( this ); + for( SCH_FIELD& field : m_Fields ) + field.SetParent( this ); TRANSFORM tmp = m_transform; @@ -1345,12 +1345,12 @@ void SCH_COMPONENT::MirrorY( int aYaxis_position ) MIRROR( m_Pos.x, aYaxis_position ); dx -= m_Pos.x; // dx,0 is the move vector for this transform - for( int ii = 0; ii < GetFieldCount(); ii++ ) + for( SCH_FIELD& field : m_Fields ) { // Move the fields to the new position because the component itself has moved. - wxPoint pos = GetField( ii )->GetTextPos(); + wxPoint pos = field.GetTextPos(); pos.x -= dx; - GetField( ii )->SetTextPos( pos ); + field.SetTextPos( pos ); } } @@ -1363,12 +1363,12 @@ void SCH_COMPONENT::MirrorX( int aXaxis_position ) MIRROR( m_Pos.y, aXaxis_position ); dy -= m_Pos.y; // dy,0 is the move vector for this transform - for( int ii = 0; ii < GetFieldCount(); ii++ ) + for( SCH_FIELD& field : m_Fields ) { // Move the fields to the new position because the component itself has moved. - wxPoint pos = GetField( ii )->GetTextPos(); + wxPoint pos = field.GetTextPos(); pos.y -= dy; - GetField( ii )->SetTextPos( pos ); + field.SetTextPos( pos ); } } @@ -1530,9 +1530,9 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR aInspector, void* aTestData, if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T ) { // Test the bounding boxes of fields if they are visible and not empty. - for( int ii = 0; ii < GetFieldCount(); ii++ ) + for( SCH_FIELD& field : m_Fields ) { - if( SEARCH_RESULT::QUIT == aInspector( GetField( ii ), (void*) this ) ) + if( SEARCH_RESULT::QUIT == aInspector( &field, (void*) this ) ) return SEARCH_RESULT::QUIT; } } diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 5cd5633b6a..ec55824f87 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -124,8 +124,6 @@ private: SCH_PINS m_pins; ///< a SCH_PIN for every LIB_PIN (across all units) SCH_PIN_MAP m_pinMap; ///< the component's pins mapped by LIB_PIN* - FIELDS_AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement - bool m_isInNetlist; ///< True if the component should appear in the netlist // Defines the hierarchical path and reference of the component. This allows support @@ -424,16 +422,6 @@ public: */ int GetFieldCount() const { return (int)m_Fields.size(); } - /** - * Return whether the fields have been automatically placed. - */ - FIELDS_AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; } - - /** - * Set fields automatically placed flag false. - */ - void ClearFieldsAutoplaced() { m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; } - /** * Automatically orient all the fields in the component. * @@ -443,21 +431,7 @@ public: * or a menu item). Some more 'intelligent' routines will be used that would be * annoying if done automatically during moves. */ - void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ); - - /** - * Autoplace fields only if correct to do so automatically. - * - * Fields that have been moved by hand are not automatically placed. - * - * @param aScreen is the SCH_SCREEN associated with the current instance of the - * component. - */ - void AutoAutoplaceFields( SCH_SCREEN* aScreen ) - { - if( GetFieldsAutoplaced() ) - AutoplaceFields( aScreen, GetFieldsAutoplaced() == FIELDS_AUTOPLACED_MANUAL ); - } + void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override; //--------------------------------------------------------------- @@ -558,8 +532,8 @@ public: m_Pos += aMoveVector; - for( int ii = 0; ii < GetFieldCount(); ii++ ) - GetField( ii )->Move( aMoveVector ); + for( SCH_FIELD& field : m_Fields ) + field.Move( aMoveVector ); SetModified(); } diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index bf3c41347a..d8b98755b2 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -725,16 +725,6 @@ private: */ void UpdateTitle(); - /** - * Verify that \a aSheet will not cause a recursion error in \a aHierarchy. - * - * @param aSheet is the #SCH_SHEET object to test. - * @param aHierarchy is the #SCH_SHEET_PATH where \a aSheet is going to reside. - * - * @return true if \a aSheet will cause a resursion error in \a aHierarchy. - */ - bool checkSheetForRecursion( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy ); - /** * Verify that the symbol library links \a aSheet and all of it's child sheets have * been remapped to the symbol library table. @@ -753,6 +743,17 @@ private: */ bool importFile( const wxString& aFileName, int aFileType ); +public: + /** + * Verify that \a aSheet will not cause a recursion error in \a aHierarchy. + * + * @param aSheet is the #SCH_SHEET object to test. + * @param aHierarchy is the #SCH_SHEET_PATH where \a aSheet is going to reside. + * + * @return true if \a aSheet will cause a resursion error in \a aHierarchy. + */ + bool CheckSheetForRecursion( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy ); + /** * Check \a aSchematicFileName for a potential file name case sensitivity clashes. * @@ -764,9 +765,8 @@ private: * @param aSchematicFileName is the absolute path and file name of the file to test. * @return true if the user accepts the potential file name clase risk. */ - bool allowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName ); + bool AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName ); -public: /** * Change a text type to another one. * diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index f0ea15db1e..56a4efdb54 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -216,18 +216,26 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const RotatePoint( &begin, pos, GetTextAngle() ); RotatePoint( &end, pos, GetTextAngle() ); - // Due to the Y axis direction, we must mirror the bounding box, - // relative to the text position: - MIRROR( begin.y, pos.y ); - MIRROR( end.y, pos.y ); - // Now, apply the component transform (mirror/rot) + TRANSFORM transform; + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) { + // Due to the Y axis direction, we must mirror the bounding box, + // relative to the text position: + MIRROR( begin.y, pos.y ); + MIRROR( end.y, pos.y ); + SCH_COMPONENT* parentComponent = static_cast( m_Parent ); - rect.SetOrigin( parentComponent->GetTransform().TransformCoordinate( begin )); - rect.SetEnd( parentComponent->GetTransform().TransformCoordinate( end )); + transform = parentComponent->GetTransform(); } + else + { + transform = TRANSFORM( 1, 0, 0, 1 ); // identity transform + } + + rect.SetOrigin( transform.TransformCoordinate( begin ) ); + rect.SetEnd( transform.TransformCoordinate( end ) ); rect.Move( origin ); rect.Normalize(); @@ -296,14 +304,23 @@ bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData ) bool SCH_FIELD::IsReplaceable() const { - if( m_id != VALUE ) - return true; + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) + { + if( m_id == VALUE ) + { + LIB_PART* part = static_cast( GetParent() )->GetPartRef().get(); - SCH_COMPONENT* component = dynamic_cast( GetParent() ); - LIB_PART* part = component ? component->GetPartRef().get() : nullptr; - bool isPower = part ? part->IsPower() : false; + if( part && part->IsPower() ) + return false; + } + } + else if( m_Parent && m_Parent->Type() == SCH_SHEET_T ) + { + if( m_id == SHEETFILENAME ) + return false; + } - return !isPower; + return true; } @@ -311,10 +328,8 @@ bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData ) { bool isReplaced = false; wxString text = GetFullyQualifiedText(); - bool isReference = m_Parent && m_Parent->Type() == SCH_COMPONENT_T && m_id == REFERENCE; - bool isFilename = m_Parent && m_Parent->Type() == SCH_SHEET_T && m_id == SHEETFILENAME; - if( isReference ) + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T && m_id == REFERENCE ) { wxCHECK_MSG( aAuxData != NULL, false, wxT( "Cannot replace reference designator without valid sheet path." ) ); @@ -324,8 +339,6 @@ bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData ) SCH_COMPONENT* component = (SCH_COMPONENT*) m_Parent; - wxCHECK_MSG( component != NULL, false, wxT( "No symbol associated with field" ) + text ); - text = component->GetRef( (SCH_SHEET_PATH*) aAuxData ); // if( component->GetUnitCount() > 1 ) @@ -336,7 +349,7 @@ bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData ) if( isReplaced ) component->SetRef( (SCH_SHEET_PATH*) aAuxData, text ); } - else if( isFilename ) + else if( m_Parent && m_Parent->Type() == SCH_SHEET_T && m_id == SHEETFILENAME ) { // This is likely too dangerous to allow.... } @@ -368,7 +381,12 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const if( !m_name.IsEmpty() ) return m_name; else if( aUseDefaultName ) - return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id ); + { + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) + return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id ); + else if( m_Parent && m_Parent->Type() == SCH_SHEET_T ) + return SCH_SHEET::GetDefaultFieldName( m_id ); + } return wxEmptyString; } @@ -376,7 +394,7 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const BITMAP_DEF SCH_FIELD::GetMenuImage() const { - if( dynamic_cast( m_Parent ) ) + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) { switch( m_id ) { @@ -475,16 +493,20 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter ) void SCH_FIELD::SetPosition( const wxPoint& aPosition ) { - SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent(); - - wxPoint pos = ( (SCH_COMPONENT*) GetParent() )->GetPosition(); + wxPoint pos = GetParentPosition(); // Actual positions are calculated by the rotation/mirror transform of the // parent component of the field. The inverse transform is used to calculate // the position relative to the parent component. - wxPoint pt = aPosition - pos; + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) + { + SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent(); + wxPoint pt = aPosition - pos; - SetTextPos( pos + component->GetTransform().InverseTransform().TransformCoordinate( pt ) ); + pos += component->GetTransform().InverseTransform().TransformCoordinate( pt ); + } + + SetTextPos( pos ); } diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h index 4044a80f7f..5062db44e8 100644 --- a/eeschema/sch_field.h +++ b/eeschema/sch_field.h @@ -37,14 +37,6 @@ class SCH_COMPONENT; class LIB_FIELD; -enum FIELDS_AUTOPLACED -{ - FIELDS_AUTOPLACED_NO = 0, - FIELDS_AUTOPLACED_AUTO, - FIELDS_AUTOPLACED_MANUAL -}; - - /** * SCH_FIELD * instances are attached to a component and provide a place for the component's value, diff --git a/eeschema/sch_item.h b/eeschema/sch_item.h index 6e0ac6a056..cc27ae0d52 100644 --- a/eeschema/sch_item.h +++ b/eeschema/sch_item.h @@ -43,7 +43,16 @@ class NETLIST_OBJECT; class NETLIST_OBJECT_LIST; -enum DANGLING_END_T { +enum FIELDS_AUTOPLACED +{ + FIELDS_AUTOPLACED_NO = 0, + FIELDS_AUTOPLACED_AUTO, + FIELDS_AUTOPLACED_MANUAL +}; + + +enum DANGLING_END_T +{ UNKNOWN = 0, WIRE_START_END, WIRE_END_END, @@ -140,10 +149,11 @@ class SCH_ITEM : public EDA_ITEM friend class CONNECTION_GRAPH; protected: - SCH_LAYER_ID m_Layer; - EDA_ITEMS m_connections; ///< List of items connected to this item. - wxPoint m_storedPos; ///< a temporary variable used in some move commands - ///> to store a initial pos (of the item or mouse cursor) + SCH_LAYER_ID m_Layer; + EDA_ITEMS m_connections; // List of items connected to this item. + FIELDS_AUTOPLACED m_fieldsAutoplaced; // indicates status of field autoplacement + wxPoint m_storedPos; // a temporary variable used in some move commands + // to store a initial pos of the item or mouse cursor /// Stores pointers to other items that are connected to this one, per sheet std::unordered_map m_connected_items; @@ -388,6 +398,32 @@ public: virtual bool CanIncrementLabel() const { return false; } + /** + * Return whether the fields have been automatically placed. + */ + FIELDS_AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; } + + /** + * Set fields automatically placed flag false. + */ + void ClearFieldsAutoplaced() { m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; } + + /** + * Autoplace fields only if correct to do so automatically. + * + * Fields that have been moved by hand are not automatically placed. + * + * @param aScreen is the SCH_SCREEN associated with the current instance of the + * component. + */ + void AutoAutoplaceFields( SCH_SCREEN* aScreen ) + { + if( GetFieldsAutoplaced() ) + AutoplaceFields( aScreen, GetFieldsAutoplaced() == FIELDS_AUTOPLACED_MANUAL ); + } + + virtual void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) { } + /** * Function Plot * plots the schematic item to \a aPlotter. diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index df580a5a7c..f4b9e24233 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -1387,7 +1387,7 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) } /* Calculate the text justification, according to the component orientation/mirror. - * Tthis is a bit complicated due to cumulative calculations: + * This is a bit complicated due to cumulative calculations: * - numerous cases (mirrored or not, rotation) * - the DrawGraphicText function recalculate also H and H justifications according to the * text orientation. @@ -1410,8 +1410,8 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 ); boundaryBox.RevertYAxis(); - m_gal->DrawRectangle( - mapCoords( boundaryBox.GetPosition() ), mapCoords( boundaryBox.GetEnd() ) ); + m_gal->DrawRectangle( mapCoords( boundaryBox.GetPosition() ), + mapCoords( boundaryBox.GetEnd() ) ); } else { @@ -1424,7 +1424,7 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) m_gal->SetTextMirrored( aField->IsMirrored() ); strokeText( aField->GetFullyQualifiedText(), textpos, - orient == TEXT_ANGLE_VERT ? M_PI / 2 : 0 ); + orient == TEXT_ANGLE_VERT ? M_PI / 2 : 0 ); } // Draw the umbilical line @@ -1511,7 +1511,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer ) { bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS; - if( aLayer == LAYER_HIERLABEL || drawingShadows ) + if( aLayer == LAYER_HIERLABEL || aLayer == LAYER_SELECTION_SHADOWS ) { for( SCH_SHEET_PIN* sheetPin : aSheet->GetPins() ) { @@ -1542,9 +1542,6 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer ) } } - if( drawingShadows && !aSheet->IsSelected() ) - return; - VECTOR2D pos = aSheet->GetPosition(); VECTOR2D size = aSheet->GetSize(); @@ -1571,7 +1568,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer ) m_gal->DrawRectangle( pos, pos + size ); } - if( aLayer == LAYER_SHEET || drawingShadows ) + if( aLayer == LAYER_SHEET || aLayer == LAYER_SELECTION_SHADOWS ) { m_gal->SetStrokeColor( getRenderColor( aSheet, LAYER_SHEET, drawingShadows ) ); m_gal->SetIsStroke( true ); @@ -1580,7 +1577,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer ) m_gal->DrawRectangle( pos, pos + size ); - if( drawingShadows && !GetSelectionDrawChildItems() ) + if( drawingShadows && !GetSelectionDrawChildItems() && aSheet->IsSelected() ) return; for( SCH_FIELD& field : aSheet->GetFields() ) diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 286a449681..35a4807e32 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -40,7 +40,7 @@ #include -const wxString GetDefaultFieldName( int aFieldNdx ) +const wxString SCH_SHEET::GetDefaultFieldName( int aFieldNdx ) { static void* locale = nullptr; static wxString sheetnameDefault; @@ -51,9 +51,9 @@ const wxString GetDefaultFieldName( int aFieldNdx ) // so only do it when necessary. if( Pgm().GetLocale() != locale ) { - sheetnameDefault = _( "Sheet Name" ); - sheetfilenameDefault = _( "Sheet Filename" ); - fieldDefault = _( "Field" ); + sheetnameDefault = _( "Sheet name" ); + sheetfilenameDefault = _( "Sheet file" ); + fieldDefault = _( "Field%d" ); locale = Pgm().GetLocale(); } @@ -426,43 +426,45 @@ int SCH_SHEET::GetPenSize() const } -wxPoint SCH_SHEET::getSheetNamePosition() -{ - wxSize textSize = m_fields[ SHEETNAME ].GetTextSize(); - int margin = KiROUND( GetPenSize() / 2.0 + 4 + std::max( textSize.x, textSize.y ) * 0.3 ); - - if( IsVerticalOrientation() ) - return wxPoint( -margin, m_size.y ); - else - return wxPoint( 0, -margin ); -} - - -wxPoint SCH_SHEET::getFileNamePosition() -{ - wxSize textSize = m_fields[ SHEETNAME ].GetTextSize(); - int margin = KiROUND( GetPenSize() / 2.0 + 4 + std::max( textSize.x, textSize.y ) * 0.4 ); - - if( IsVerticalOrientation() ) - return wxPoint( m_size.x + margin, m_size.y ); - else - return wxPoint( 0, m_size.y + margin ); -} - - void SCH_SHEET::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) { wxASSERT_MSG( !aManual, "manual autoplacement not currently supported for sheets" ); - m_fields[ SHEETNAME ].SetTextPos( getSheetNamePosition() ); - m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); - m_fields[ SHEETNAME ].SetVertJustify(GR_TEXT_VJUSTIFY_BOTTOM ); - m_fields[ SHEETNAME ].SetTextAngle( IsVerticalOrientation() ? 900 : 0 ); + wxSize textSize = m_fields[ SHEETNAME ].GetTextSize(); + int margin = KiROUND( GetPenSize() / 2.0 + 4 + std::max( textSize.x, textSize.y ) * 0.5 ); - m_fields[ SHEETFILENAME ].SetTextPos( getFileNamePosition() ); - m_fields[ SHEETFILENAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); - m_fields[ SHEETFILENAME ].SetVertJustify(GR_TEXT_VJUSTIFY_TOP ); - m_fields[ SHEETFILENAME ].SetTextAngle( IsVerticalOrientation() ? 900 : 0 ); + if( IsVerticalOrientation() ) + { + m_fields[ SHEETNAME ].SetTextPos( m_pos + wxPoint( -margin, m_size.y ) ); + m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); + m_fields[ SHEETNAME ].SetVertJustify(GR_TEXT_VJUSTIFY_BOTTOM ); + m_fields[ SHEETNAME ].SetTextAngle( TEXT_ANGLE_VERT ); + } + else + { + m_fields[ SHEETNAME ].SetTextPos( m_pos + wxPoint( 0, -margin ) ); + m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); + m_fields[ SHEETNAME ].SetVertJustify(GR_TEXT_VJUSTIFY_BOTTOM ); + m_fields[ SHEETNAME ].SetTextAngle( TEXT_ANGLE_HORIZ ); + } + + textSize = m_fields[ SHEETFILENAME ].GetTextSize(); + margin = KiROUND( GetPenSize() / 2.0 + 4 + std::max( textSize.x, textSize.y ) * 0.4 ); + + if( IsVerticalOrientation() ) + { + m_fields[ SHEETFILENAME ].SetTextPos( m_pos + wxPoint( m_size.x + margin, m_size.y ) ); + m_fields[ SHEETFILENAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); + m_fields[ SHEETFILENAME ].SetVertJustify(GR_TEXT_VJUSTIFY_TOP ); + m_fields[ SHEETFILENAME ].SetTextAngle( TEXT_ANGLE_VERT ); + } + else + { + m_fields[ SHEETFILENAME ].SetTextPos( m_pos + wxPoint( 0, m_size.y + margin ) ); + m_fields[ SHEETFILENAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); + m_fields[ SHEETFILENAME ].SetVertJustify(GR_TEXT_VJUSTIFY_TOP ); + m_fields[ SHEETFILENAME ].SetTextAngle( TEXT_ANGLE_HORIZ ); + } m_fieldsAutoplaced = FIELDS_AUTOPLACED_AUTO; } @@ -496,7 +498,7 @@ void SCH_SHEET::Print( wxDC* aDC, const wxPoint& aOffset ) } -const EDA_RECT SCH_SHEET::GetBoundingBox() const +const EDA_RECT SCH_SHEET::GetBodyBoundingBox() const { wxPoint end; EDA_RECT box( m_pos, m_size ); @@ -513,8 +515,16 @@ const EDA_RECT SCH_SHEET::GetBoundingBox() const box.SetEnd( end ); box.Inflate( lineWidth / 2 ); - for( size_t i = 0; i < m_fields.size(); i++ ) - box.Merge( m_fields[i].GetBoundingBox() ); + return box; +} + + +const EDA_RECT SCH_SHEET::GetBoundingBox() const +{ + EDA_RECT box = GetBodyBoundingBox(); + + for( const SCH_FIELD& field : m_fields ) + box.Merge( field.GetBoundingBox() ); return box; } @@ -659,17 +669,26 @@ void SCH_SHEET::Rotate(wxPoint aPosition) m_size.y = -m_size.y; } - for( SCH_FIELD& field : m_fields ) - { - // Move the fields to the new position because the sheet itself has moved. - wxPoint pos = field.GetTextPos(); - pos.x -= prev.x - m_pos.x; - pos.y -= prev.y - m_pos.y; - field.SetTextPos( pos ); - } - + // Pins must be rotated first as that's how we determine vertical vs horizontal + // orientation for auto-placement for( SCH_SHEET_PIN* sheetPin : m_pins ) sheetPin->Rotate( aPosition ); + + if( m_fieldsAutoplaced == FIELDS_AUTOPLACED_AUTO ) + { + AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); + } + else + { + // Move the fields to the new position because the component itself has moved. + for( SCH_FIELD& field : m_fields ) + { + wxPoint pos = field.GetTextPos(); + pos.x -= prev.x - m_pos.x; + pos.y -= prev.y - m_pos.y; + field.SetTextPos( pos ); + } + } } @@ -783,6 +802,16 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICA return SEARCH_RESULT::QUIT; } + if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T ) + { + // Test the sheet fields. + for( SCH_FIELD& field : m_fields ) + { + if( SEARCH_RESULT::QUIT == aInspector( &field, this ) ) + return SEARCH_RESULT::QUIT; + } + } + if( stype == SCH_LOCATE_ANY_T || stype == SCH_SHEET_PIN_T ) { // Test the sheet labels. @@ -812,7 +841,7 @@ BITMAP_DEF SCH_SHEET::GetMenuImage() const bool SCH_SHEET::HitTest( const wxPoint& aPosition, int aAccuracy ) const { - EDA_RECT rect = GetBoundingBox(); + EDA_RECT rect = GetBodyBoundingBox(); rect.Inflate( aAccuracy ); @@ -827,9 +856,9 @@ bool SCH_SHEET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) rect.Inflate( aAccuracy ); if( aContained ) - return rect.Contains( GetBoundingBox() ); + return rect.Contains( GetBodyBoundingBox() ); - return rect.Intersects( GetBoundingBox() ); + return rect.Intersects( GetBodyBoundingBox() ); } diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index 98fd8c9822..266348c8fb 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -263,6 +263,16 @@ public: std::vector& GetFields() { return m_fields; } + /** + * Set multiple schematic fields. + * + * @param aFields are the fields to set in this symbol. + */ + void SetFields( const std::vector& aFields ) + { + m_fields = aFields; // vector copying, length is changed possibly + } + // JEY TODO: retite these once new dialog is implemented... wxString GetName() const { return m_fields[ SHEETNAME ].GetText(); } void SetName( const wxString& aName ) { m_fields[ SHEETNAME ].SetText( aName ); } @@ -411,7 +421,12 @@ public: void Print( wxDC* aDC, const wxPoint& aOffset ) override; - EDA_RECT const GetBoundingBox() const override; + /** + * Return a bounding box for the sheet body but not the fields. + */ + const EDA_RECT GetBodyBoundingBox() const; + + const EDA_RECT GetBoundingBox() const override; /** * Rotating around the boundingBox's center can cause walking when the sheetname or @@ -500,17 +515,7 @@ public: */ void Resize( const wxSize& aSize ); - /** - * Return whether the fields have been automatically placed. - */ - FIELDS_AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; } - - /** - * Set fields automatically placed flag false. - */ - void ClearFieldsAutoplaced() { m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; } - - void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ); + void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override; void GetEndPoints( std::vector & aItemList ) override; @@ -557,18 +562,9 @@ public: void Show( int nestLevel, std::ostream& os ) const override; #endif + static const wxString GetDefaultFieldName( int aFieldNdx ); + protected: - - /** - * @return the position of the anchor of sheet name text - */ - wxPoint getSheetNamePosition(); - - /** - * @return the position of the anchor of filename text - */ - wxPoint getFileNamePosition(); - /** * Renumber the sheet pins in the sheet. * diff --git a/eeschema/sch_sheet_pin.cpp b/eeschema/sch_sheet_pin.cpp index 1c2a372637..8fda0f5bfc 100644 --- a/eeschema/sch_sheet_pin.cpp +++ b/eeschema/sch_sheet_pin.cpp @@ -175,20 +175,11 @@ void SCH_SHEET_PIN::ConstrainOnEdge( wxPoint Pos ) switch( sheetEdge.NearestSegment( Pos ) ) { - case 0: - SetEdge( SHEET_TOP_SIDE ); - break; - case 1: - SetEdge( SHEET_RIGHT_SIDE ); - break; - case 2: - SetEdge( SHEET_BOTTOM_SIDE ); - break; - case 3: - SetEdge( SHEET_LEFT_SIDE ); - break; - default: - wxASSERT( "Invalid segment number" ); + case 0: SetEdge( SHEET_TOP_SIDE ); break; + case 1: SetEdge( SHEET_RIGHT_SIDE ); break; + case 2: SetEdge( SHEET_BOTTOM_SIDE ); break; + case 3: SetEdge( SHEET_LEFT_SIDE ); break; + default: wxASSERT( "Invalid segment number" ); } switch( GetEdge() ) @@ -257,16 +248,6 @@ void SCH_SHEET_PIN::Rotate( wxPoint aPosition ) { wxPoint pt = GetTextPos(); RotatePoint( &pt, aPosition, 900 ); - - switch( m_edge ) - { - case SHEET_LEFT_SIDE: SetEdge( SHEET_BOTTOM_SIDE ); break; - case SHEET_RIGHT_SIDE: SetEdge( SHEET_TOP_SIDE ); break; - case SHEET_TOP_SIDE: SetEdge( SHEET_LEFT_SIDE ); break; - case SHEET_BOTTOM_SIDE: SetEdge( SHEET_RIGHT_SIDE ); break; - default: break; - } - ConstrainOnEdge( pt ); } @@ -283,14 +264,9 @@ void SCH_SHEET_PIN::CreateGraphicShape( std::vector & aPoints, const wx switch( m_shape ) { - case PINSHEETLABEL_SHAPE::PS_INPUT: - m_shape = PINSHEETLABEL_SHAPE::PS_OUTPUT; - break; - case PINSHEETLABEL_SHAPE::PS_OUTPUT: - m_shape = PINSHEETLABEL_SHAPE::PS_INPUT; - break; - default: - break; + case PINSHEETLABEL_SHAPE::PS_INPUT: m_shape = PINSHEETLABEL_SHAPE::PS_OUTPUT; break; + case PINSHEETLABEL_SHAPE::PS_OUTPUT: m_shape = PINSHEETLABEL_SHAPE::PS_INPUT; break; + default: break; } SCH_HIERLABEL::CreateGraphicShape( aPoints, aPos ); diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 403f2ace5f..a935816a86 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -41,7 +41,7 @@ #include -bool SCH_EDIT_FRAME::checkSheetForRecursion( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy ) +bool SCH_EDIT_FRAME::CheckSheetForRecursion( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy ) { wxASSERT( aSheet && aHierarchy ); @@ -207,7 +207,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier SCH_SHEET_LIST hierarchy( g_RootSheet ); // This is the schematic sheet hierarchy. SCH_SHEET_LIST sheetHierarchy( newSheet.get() ); // This is the hierarchy of the loaded file. - if( checkSheetForRecursion( newSheet.get(), aHierarchy ) + if( CheckSheetForRecursion( newSheet.get(), aHierarchy ) || checkForNoFullyDefinedLibIds( newSheet.get() ) ) return false; @@ -483,247 +483,11 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy, return false; // Get the new texts - DIALOG_SCH_SHEET_PROPS dlg( this, aSheet ); + DIALOG_SCH_SHEET_PROPS dlg( this, aSheet, aClearAnnotationNewItems ); if( dlg.ShowModal() == wxID_CANCEL ) return false; - wxFileName fileName = dlg.GetFileName(); - fileName.SetExt( SchematicFileExtension ); - - wxString msg; - bool renameFile = false; - bool loadFromFile = false; - bool clearAnnotation = false; - bool restoreSheet = false; - bool isExistingSheet = false; - SCH_SCREEN* useScreen = NULL; - - // Relative file names are relative to the path of the current sheet. This allows for - // nesting of schematic files in subfolders. - if( !fileName.IsAbsolute() ) - { - const SCH_SCREEN* currentScreen = aHierarchy->LastScreen(); - - wxCHECK_MSG( currentScreen, false, "Invalid sheet path object." ); - - wxFileName currentSheetFileName = currentScreen->GetFileName(); - - wxCHECK_MSG( fileName.Normalize( wxPATH_NORM_ALL, currentSheetFileName.GetPath() ), false, - "Cannot normalize new sheet schematic file path." ); - } - - wxString newFilename = fileName.GetFullPath(); - - // Search for a schematic file having the same filename already in use in the hierarchy - // or on disk, in order to reuse it. - if( !g_RootSheet->SearchHierarchy( newFilename, &useScreen ) ) - { - loadFromFile = wxFileExists( newFilename ); - wxLogDebug( "Sheet requested file \"%s\", %s", - newFilename, - ( loadFromFile ) ? "found" : "not found" ); - } - - // Inside Eeschema, filenames are stored using unix notation - newFilename.Replace( wxT( "\\" ), wxT( "/" ) ); - - if( aSheet->GetScreen() == NULL ) // New sheet. - { - if( !allowCaseSensitiveFileNameClashes( newFilename ) ) - return false; - - if( useScreen || loadFromFile ) // Load from existing file. - { - clearAnnotation = true; - - wxString existsMsg; - wxString linkMsg; - existsMsg.Printf( _( "\"%s\" already exists." ), fileName.GetFullName() ); - linkMsg.Printf( _( "Link \"%s\" to this file?" ), dlg.GetSheetName() ); - msg.Printf( wxT( "%s\n\n%s" ), existsMsg, linkMsg ); - - if( !IsOK( this, msg ) ) - return false; - - } - else // New file. - { - InitSheet( aSheet, newFilename ); - } - } - else // Existing sheet. - { - bool isUndoable = true; - wxString replaceMsg; - wxString newMsg; - wxString noUndoMsg; - - isExistingSheet = true; - - if( !allowCaseSensitiveFileNameClashes( newFilename ) ) - return false; - - // Changing the filename of a sheet can modify the full hierarchy structure - // and can be not always undoable. - // So prepare messages for user notifications: - replaceMsg.Printf( _( "Change \"%s\" link from \"%s\" to \"%s\"?" ), - dlg.GetSheetName(), - aSheet->GetFileName(), - fileName.GetFullName() ); - newMsg.Printf( _( "Create new file \"%s\" with contents of \"%s\"?" ), - fileName.GetFullName(), - aSheet->GetFileName() ); - noUndoMsg = _( "This action cannot be undone." ); - - // We are always using here a case insensitive comparison - // to avoid issues under Windows, although under Unix - // filenames are case sensitive. - // But many users create schematic under both Unix and Windows - // ** - // N.B. 1: aSheet->GetFileName() will return a relative path - // aSheet->GetScreen()->GetFileName() returns a full path - // - // N.B. 2: newFilename uses the unix notation for separator. - // so we must use it also to compare the old filename to the new filename - wxString oldFilename = aSheet->GetScreen()->GetFileName(); - oldFilename.Replace( wxT( "\\" ), wxT( "/" ) ); - - if( newFilename.Cmp( oldFilename ) != 0 ) - { - // Sheet file name changes cannot be undone. - isUndoable = false; - - if( useScreen || loadFromFile ) // Load from existing file. - { - clearAnnotation = true; - - msg.Printf( wxT( "%s\n\n%s" ), replaceMsg, noUndoMsg ); - - if( !IsOK( this, msg ) ) - return false; - - if( loadFromFile ) - aSheet->SetScreen( NULL ); - } - else // Save to new file name. - { - if( aSheet->GetScreenCount() > 1 ) - { - msg.Printf( wxT( "%s\n\n%s" ), newMsg, noUndoMsg ); - - if( !IsOK( this, msg ) ) - return false; - } - - renameFile = true; - } - } - - if( isUndoable ) - SaveCopyInUndoList( aSheet, UR_CHANGED ); - - if( renameFile ) - { - SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) ); - - // If the the associated screen is shared by more than one sheet, do not - // change the filename of the corresponding screen here. - // (a new screen will be created later) - // if it is not shared, update the filename - if( aSheet->GetScreenCount() <= 1 ) - aSheet->GetScreen()->SetFileName( newFilename ); - - try - { - pi->Save( newFilename, aSheet->GetScreen(), &Kiway() ); - } - catch( const IO_ERROR& ioe ) - { - msg.Printf( _( "Error occurred saving schematic file \"%s\"." ), newFilename ); - DisplayErrorMessage( this, msg, ioe.What() ); - - msg.Printf( _( "Failed to save schematic \"%s\"" ), newFilename ); - AppendMsgPanel( wxEmptyString, msg, CYAN ); - - return false; - } - - // If the the associated screen is shared by more than one sheet, remove the - // screen and reload the file to a new screen. Failure to do this will trash - // the screen reference counting in complex hierarchies. - if( aSheet->GetScreenCount() > 1 ) - { - aSheet->SetScreen( NULL ); - loadFromFile = true; - } - } - } - - wxFileName userFileName = dlg.GetFileName(); - userFileName.SetExt( SchematicFileExtension ); - - if( useScreen ) - { - // Create a temporary sheet for recursion testing to prevent a possible recursion error. - std::unique_ptr< SCH_SHEET> tmpSheet( new SCH_SHEET ); - tmpSheet->SetName( dlg.GetSheetName() ); - tmpSheet->SetFileName( userFileName.GetFullPath() ); - tmpSheet->SetScreen( useScreen ); - - // No need to check for valid library IDs if we are using an existing screen. - if( checkSheetForRecursion( tmpSheet.get(), aHierarchy ) ) - { - if( restoreSheet ) - aHierarchy->LastScreen()->Append( aSheet ); - - return false; - } - - // It's safe to set the sheet screen now. - aSheet->SetScreen( useScreen ); - } - else if( loadFromFile ) - { - if( isExistingSheet ) - { - // Temporarily remove the sheet from the current schematic page so that recursion - // and symbol library link tests can be performed with the modified sheet settings. - restoreSheet = true; - aHierarchy->LastScreen()->Remove( aSheet ); - } - - if( !LoadSheetFromFile( aSheet, aHierarchy, newFilename ) - || checkSheetForRecursion( aSheet, aHierarchy ) ) - { - if( restoreSheet ) - aHierarchy->LastScreen()->Append( aSheet ); - - return false; - } - - if( restoreSheet ) - aHierarchy->LastScreen()->Append( aSheet ); - } - - wxString tmpFn = userFileName.GetFullPath(); - - if( wxFileName::GetPathSeparator() == '\\' ) - tmpFn.Replace( "\\", "/" ); - - aSheet->SetFileName( tmpFn ); - aSheet->SetName( dlg.GetSheetName() ); - - if( aSheet->GetName().IsEmpty() ) - aSheet->SetName( wxT( "Untitled Sheet" ) ); - - if( aClearAnnotationNewItems ) - *aClearAnnotationNewItems = clearAnnotation; - - GetCanvas()->GetView()->Update( aSheet ); - - OnModify(); - return true; } @@ -870,7 +634,7 @@ void SCH_EDIT_FRAME::DrawCurrentSheetToClipboard() } -bool SCH_EDIT_FRAME::allowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName ) +bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName ) { wxString msg; SCH_SCREENS screens; diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 53b6559bb0..f3cd796a24 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -607,10 +607,18 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const EE_SELECTION& EE_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] ) { - // Filter an existing selection - if( !m_selection.Empty() ) + if( m_selection.Empty() ) { - for( int i = m_selection.GetSize() - 1; i >= 0; --i ) + VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true ); + + ClearSelection(); + SelectPoint( cursorPos, aFilterList ); + m_selection.SetIsHover( true ); + m_selection.ClearReferencePoint(); + } + else // Trim an existing selection by aFilterList + { + for( int i = (int) m_selection.GetSize() - 1; i >= 0; --i ) { EDA_ITEM* item = (EDA_ITEM*) m_selection.GetItem( i ); @@ -620,18 +628,6 @@ EE_SELECTION& EE_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] ) m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); } } - - } - - // If nothing was selected, or we filtered everything out, do a hover selection - if( m_selection.Empty() ) - { - VECTOR2D cursorPos = getViewControls()->GetCursorPosition( true ); - - ClearSelection(); - SelectPoint( cursorPos, aFilterList ); - m_selection.SetIsHover( true ); - m_selection.ClearReferencePoint(); } updateReferencePoint(); diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 4aa6e3acf0..7992ce47cd 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -446,11 +446,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) field->SetTextAngle( TEXT_ANGLE_HORIZ ); // Now that we're moving a field, they're no longer autoplaced. - if( item->GetParent()->Type() == SCH_COMPONENT_T ) - { - SCH_COMPONENT* parent = static_cast( item->GetParent() ); - parent->ClearFieldsAutoplaced(); - } + static_cast( item->GetParent() )->ClearFieldsAutoplaced(); break; } @@ -469,7 +465,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) SCH_SHEET* sheet = static_cast( item ); // Rotate the sheet on itself. Sheets do not have an anchor point. - for( int i = 0; clockwise ? i < 1 : i < 3; ++i ) + for( int i = 0; clockwise ? i < 3 : i < 1; ++i ) { rotPoint = m_frame->GetNearestGridPosition( sheet->GetRotationCenter() ); sheet->Rotate( rotPoint ); @@ -635,11 +631,7 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent ) field->SetHorizJustify( (EDA_TEXT_HJUSTIFY_T)-field->GetHorizJustify() ); // Now that we're re-justifying a field, they're no longer autoplaced. - if( item->GetParent()->Type() == SCH_COMPONENT_T ) - { - SCH_COMPONENT *parent = static_cast( item->GetParent() ); - parent->ClearFieldsAutoplaced(); - } + static_cast( item->GetParent() )->ClearFieldsAutoplaced(); break; } @@ -1065,13 +1057,11 @@ int SCH_EDIT_TOOL::DeleteItemCursor( const TOOL_EVENT& aEvent ) } -void SCH_EDIT_TOOL::editComponentFieldText( SCH_FIELD* aField ) +void SCH_EDIT_TOOL::editFieldText( SCH_FIELD* aField ) { - SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent(); - // Save old component in undo list if not already in edit, or moving. if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved - m_frame->SaveCopyInUndoList( component, UR_CHANGED ); + m_frame->SaveCopyInUndoList( (SCH_ITEM*) aField->GetParent(), UR_CHANGED ); wxString title = wxString::Format( _( "Edit %s Field" ), aField->GetName() ); @@ -1083,8 +1073,8 @@ void SCH_EDIT_TOOL::editComponentFieldText( SCH_FIELD* aField ) dlg.UpdateField( aField, g_CurrentSheet ); - if( m_frame->GetAutoplaceFields() ) - component->AutoAutoplaceFields( m_frame->GetScreen() ); + if( m_frame->GetAutoplaceFields() || aField->GetParent()->Type() == SCH_SHEET_T ) + static_cast( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() ); m_toolMgr->PostEvent( EVENTS::SelectedItemsModified ); m_frame->RefreshItem( aField ); @@ -1120,15 +1110,15 @@ int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent ) SCH_COMPONENT* component = (SCH_COMPONENT*) item; if( aEvent.IsAction( &EE_ACTIONS::editReference ) ) - editComponentFieldText( component->GetField( REFERENCE ) ); + editFieldText( component->GetField( REFERENCE ) ); else if( aEvent.IsAction( &EE_ACTIONS::editValue ) ) - editComponentFieldText( component->GetField( VALUE ) ); + editFieldText( component->GetField( VALUE ) ); else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) ) - editComponentFieldText( component->GetField( FOOTPRINT ) ); + editFieldText( component->GetField( FOOTPRINT ) ); } else if( item->Type() == SCH_FIELD_T ) { - editComponentFieldText( (SCH_FIELD*) item ); + editFieldText( (SCH_FIELD*) item ); } return 0; @@ -1288,7 +1278,7 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) break; case SCH_FIELD_T: - editComponentFieldText( (SCH_FIELD*) item ); + editFieldText( (SCH_FIELD*) item ); break; case SCH_BITMAP_T: diff --git a/eeschema/tools/sch_edit_tool.h b/eeschema/tools/sch_edit_tool.h index af234d0ade..91beb2104d 100644 --- a/eeschema/tools/sch_edit_tool.h +++ b/eeschema/tools/sch_edit_tool.h @@ -69,7 +69,7 @@ public: int DeleteItemCursor( const TOOL_EVENT& aEvent ); private: - void editComponentFieldText( SCH_FIELD* aField ); + void editFieldText( SCH_FIELD* aField ); ///> Sets up handlers for various events. void setTransitions() override; diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 2e7e30d60c..648af0fd5a 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -443,8 +443,11 @@ void SCH_EDITOR_CONTROL::doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aF { case SCH_FIELD_T: case LIB_FIELD_T: - component = (SCH_COMPONENT*) item->GetParent(); - m_frame->SendMessageToPCBNEW( item, component ); + if( item->GetParent() && item->GetParent()->Type() == SCH_COMPONENT_T ) + { + component = (SCH_COMPONENT*) item->GetParent(); + m_frame->SendMessageToPCBNEW( item, component ); + } break; case SCH_COMPONENT_T: diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index 05e26898ab..3321c6e35a 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -621,15 +621,22 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, VECTOR2I aDelta, bool isDrag ) case SCH_PIN_T: case SCH_FIELD_T: { - SCH_COMPONENT* component = (SCH_COMPONENT*) aItem->GetParent(); - TRANSFORM transform = component->GetTransform().InverseTransform(); - wxPoint transformedDelta = transform.TransformCoordinate( (wxPoint) aDelta ); + SCH_ITEM* parent = (SCH_ITEM*) aItem->GetParent(); + wxPoint delta( aDelta ); - static_cast( aItem )->Move( transformedDelta ); + if( parent && parent->Type() == SCH_COMPONENT_T ) + { + SCH_COMPONENT* component = (SCH_COMPONENT*) aItem->GetParent(); + TRANSFORM transform = component->GetTransform().InverseTransform(); + + delta = transform.TransformCoordinate( delta ); + } + + static_cast( aItem )->Move( delta ); // If we're moving a field with respect to its parent then it's no longer auto-placed - if( aItem->Type() == SCH_FIELD_T && !component->IsSelected() ) - component->ClearFieldsAutoplaced(); + if( aItem->Type() == SCH_FIELD_T && !parent->IsSelected() ) + parent->ClearFieldsAutoplaced(); break; } diff --git a/include/widgets/grid_text_button_helpers.h b/include/widgets/grid_text_button_helpers.h index 4e6c49d2bb..2361e3a720 100644 --- a/include/widgets/grid_text_button_helpers.h +++ b/include/widgets/grid_text_button_helpers.h @@ -131,14 +131,15 @@ protected: class GRID_CELL_PATH_EDITOR : public GRID_CELL_TEXT_BUTTON { public: - GRID_CELL_PATH_EDITOR( DIALOG_SHIM* aParent, wxString* aCurrentDir ) : + GRID_CELL_PATH_EDITOR( DIALOG_SHIM* aParent, wxString* aCurrentDir, const wxString& aExt ) : m_dlg( aParent ), - m_currentDir( aCurrentDir ) + m_currentDir( aCurrentDir ), + m_ext( aExt ) { } wxGridCellEditor* Clone() const override { - return new GRID_CELL_PATH_EDITOR( m_dlg, m_currentDir ); + return new GRID_CELL_PATH_EDITOR( m_dlg, m_currentDir, m_ext ); } void Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler ) override; @@ -146,6 +147,7 @@ public: protected: DIALOG_SHIM* m_dlg; wxString* m_currentDir; + wxString m_ext; }; diff --git a/pcbnew/dialogs/panel_fp_lib_table.cpp b/pcbnew/dialogs/panel_fp_lib_table.cpp index 14f9c61722..46d9b2c945 100644 --- a/pcbnew/dialogs/panel_fp_lib_table.cpp +++ b/pcbnew/dialogs/panel_fp_lib_table.cpp @@ -389,7 +389,7 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent, wxGridCellAttr* attr; attr = new wxGridCellAttr; - attr->SetEditor( new GRID_CELL_PATH_EDITOR( m_parent, &m_lastBrowseDir ) ); + attr->SetEditor( new GRID_CELL_PATH_EDITOR( m_parent, &m_lastBrowseDir, wxEmptyString ) ); g->SetColAttr( COL_URI, attr ); attr = new wxGridCellAttr;