Enable editing of sheet fields.

This commit is contained in:
Jeff Young 2020-03-06 20:02:58 +00:00
parent a2ad9d67ba
commit 535033c5c9
31 changed files with 1760 additions and 1853 deletions

View File

@ -68,11 +68,11 @@ DIALOG_CONFIGURE_PATHS::DIALOG_CONFIGURE_PATHS( wxWindow* aParent, FILENAME_RESO
m_EnvVars->UseNativeColHeader( true ); m_EnvVars->UseNativeColHeader( true );
wxGridCellAttr* attr = new wxGridCellAttr; 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 ); m_EnvVars->SetColAttr( EV_PATH_COL, attr );
attr = new 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_SearchPaths->SetColAttr( EV_PATH_COL, attr ); m_SearchPaths->SetColAttr( EV_PATH_COL, attr );
// Give a bit more room for combobox editors // Give a bit more room for combobox editors

View File

@ -371,7 +371,10 @@ protected:
void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId, void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
wxEvtHandler* aEventHandler ) wxEvtHandler* aEventHandler )
{ {
if( m_ext.IsEmpty() )
m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_currentDir ); 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 #if wxUSE_VALIDATORS
// validate text in textctrl, if validator is set // validate text in textctrl, if validator is set

View File

@ -215,24 +215,26 @@ DIALOG_LIB_EDIT_ONE_FIELD::DIALOG_LIB_EDIT_ONE_FIELD(
} }
DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
SCH_BASE_FRAME* aParent, const wxString& aTitle, const SCH_FIELD* aField ) const wxString& aTitle,
: DIALOG_EDIT_ONE_FIELD( aParent, aTitle, aField ) const SCH_FIELD* aField ) :
DIALOG_EDIT_ONE_FIELD( aParent, aTitle, aField )
{ {
m_fieldId = aField->GetId(); m_fieldId = aField->GetId();
m_isPower = false;
const SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent();
wxASSERT_MSG( component && component->Type() == SCH_COMPONENT_T,
wxT( "Invalid schematic field parent item." ) );
// The library symbol may have been removed so using SCH_COMPONENT::GetPartRef() here // 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 // 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 // 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. // be entirely accurate if the power library is missing but it's better then a segfault.
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 ); const LIB_PART* part = GetParent()->GetLibPart( component->GetLibId(), true );
m_isPower = ( part ) ? part->IsPower() : false; if( part && part->IsPower() )
m_isPower = true;
}
init(); 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 ) 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 ); wxASSERT( aSheetPath );
SCH_COMPONENT* component = dynamic_cast< SCH_COMPONENT* >( aField->GetParent() ); static_cast<SCH_COMPONENT*>( parent )->SetRef( aSheetPath, m_text );
wxASSERT( component );
if( component )
component->SetRef( aSheetPath, m_text );
} }
bool positioningModified = false; bool positioningModified = false;
@ -270,8 +269,5 @@ void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH*
updateText( aField ); updateText( aField );
if( positioningModified ) if( positioningModified )
{ static_cast<SCH_ITEM*>( parent )->ClearFieldsAutoplaced();
auto component = static_cast< SCH_COMPONENT* >( aField->GetParent() );
component->ClearFieldsAutoplaced();
}
} }

View File

@ -25,6 +25,7 @@
#include <dialog_sch_sheet_props.h> #include <dialog_sch_sheet_props.h>
#include <kiface_i.h> #include <kiface_i.h>
#include <wx/string.h> #include <wx/string.h>
#include <wx/tooltip.h>
#include <confirm.h> #include <confirm.h>
#include <validators.h> #include <validators.h>
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
@ -32,120 +33,603 @@
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <sch_sheet.h> #include <sch_sheet.h>
#include <bitmaps.h> #include <bitmaps.h>
#include <eeschema_settings.h>
DIALOG_SCH_SHEET_PROPS::DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* parent, SCH_SHEET* aSheet ) :
DIALOG_SCH_SHEET_PROPS_BASE( parent ), DIALOG_SCH_SHEET_PROPS::DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* aParent, SCH_SHEET* aSheet,
m_sheet( aSheet ), bool* aClearAnnotationNewItems ) :
m_filenameTextSize( parent, m_filenameSizeLabel, m_filenameSizeCtrl, m_filenameSizeUnits, true ), DIALOG_SCH_SHEET_PROPS_BASE( aParent ),
m_sheetnameTextSize( parent, m_sheetnameSizeLabel, m_sheetnameSizeCtrl, m_sheetnameSizeUnits, true ) m_frame( aParent ),
m_clearAnnotationNewItems( aClearAnnotationNewItems )
{ {
m_textFileName->SetValidator( FILE_NAME_WITH_PATH_CHAR_VALIDATOR() ); m_sheet = aSheet;
m_textFileName->SetFocus(); m_fields = new FIELDS_GRID_TABLE<SCH_FIELD>( this, aParent, m_sheet );
m_sdbSizer1OK->SetDefault();
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 // Give a bit more room for combobox editors
// implementation on MSW m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
m_tabOrder = {
m_textFileName,
m_browseButton,
m_filenameVisible,
m_filenameSizeCtrl,
m_textSheetName, m_grid->SetTable( m_fields );
m_sheetnameSizeCtrl, m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) );
m_sheetnameVisible,
m_sdbSizer1OK, // Show/hide columns according to user's preference
m_sdbSizer1Cancel auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( 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(); FinishDialogSettings();
}
/*
* This ugly hack fixes a bug in wxWidgets 2.8.7 and likely earlier versions for the flex DIALOG_SCH_SHEET_PROPS::~DIALOG_SCH_SHEET_PROPS()
* 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. auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
* Still present in wxWidgets 3.0.2 cfg->m_Appearance.edit_sheet_visible_columns = m_grid->GetShownColumns();
*/
Layout(); // Prevents crash bug in wxGrid's d'tor
Fit(); m_grid->DestroyTable( m_fields );
SetMinSize( GetSize() );
GetSizer()->Fit( this ); 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() bool DIALOG_SCH_SHEET_PROPS::TransferDataToWindow()
{ {
// Filenames are stored using unix notation if( !wxDialog::TransferDataToWindow() )
wxString fname = m_sheet->GetFileName(); 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__ #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 #endif
m_textFileName->SetValue( fname );
m_filenameVisible->SetValue( m_sheet->GetShowFileName() );
m_textSheetName->SetValue( m_sheet->GetName() ); // change offset to be symbol-relative
m_sheetnameVisible->SetValue( m_sheet->GetShowSheetName() ); field_copy.Offset( -m_sheet->GetPosition() );
m_filenameTextSize.SetValue( m_sheet->GetFileNameSize() ); m_fields->push_back( field_copy );
m_sheetnameTextSize.SetValue( m_sheet->GetSheetNameSize() ); }
m_textCtrlUuid->SetValue( m_sheet->m_Uuid.AsString() ); // notify the grid
m_textCtrlHpath->SetValue( g_CurrentSheet->PathHumanReadable() ); 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; 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<SCH_FIELD>* a, std::vector<SCH_FIELD>& 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() 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 ); fileName.SetExt( SchematicFileExtension );
if( !fileName.IsOk() ) if( !fileName.IsAbsolute() )
{ {
DisplayError( this, _( "File name is not valid!" ) ); 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." );
}
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; return false;
} }
m_sheet->SetShowFileName( m_filenameVisible->GetValue() ); renameFile = true;
m_sheet->SetFileNameSize( m_filenameTextSize.GetValue() ); }
m_sheet->SetShowSheetName( m_sheetnameVisible->GetValue() ); }
m_sheet->SetSheetNameSize( m_sheetnameTextSize.GetValue() );
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; 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. wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
wxString path = Prj().AbsolutePath( m_textFileName->GetValue() ); wxControl* control = editor->GetControl();
wxFileName fn( path );
wxFileDialog fileDialog( this, _( "Sheet File" ), fn.GetPath(), fn.GetFullName(), if( control && control->GetValidator() && !control->GetValidator()->Validate( control ) )
SchematicFileExtension, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
if( fileDialog.ShowModal() == wxID_OK )
{ {
fn.Assign( fileDialog.GetPath() ); event.Veto();
fn.MakeRelativeTo( Prj().GetProjectPath() ); 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 if( !m_grid->CommitPendingChanges() )
wxString fname = m_textFileName->GetValue(); return;
fname.Replace( wxT("\\"), wxT("/") );
return fname; 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();
} }

View File

@ -26,32 +26,49 @@
#define __dialog_sch_sheet_props__ #define __dialog_sch_sheet_props__
#include <dialog_sch_sheet_props_base.h> #include <dialog_sch_sheet_props_base.h>
#include <widgets/unit_binder.h> #include <fields_grid_table.h>
class SCH_SHEET; class SCH_SHEET;
class SCH_EDIT_FRAME; class SCH_EDIT_FRAME;
/** Implementing DIALOG_SCH_SHEET_PROPS_BASE */
class DIALOG_SCH_SHEET_PROPS : public 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: public:
/** Constructor */ DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* aParent, SCH_SHEET* aSheet,
DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* parent, 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<SCH_FIELD>* m_fields;
bool TransferDataToWindow() override; bool TransferDataToWindow() override;
bool TransferDataFromWindow() override; bool TransferDataFromWindow() override;
void OnBrowseClicked( wxCommandEvent& event ) override; bool Validate() override;
const wxString GetFileName(); // event handlers
wxString GetSheetName() { return m_textSheetName->GetValue(); } 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__ #endif // __dialog_sch_sheet_props__

View File

@ -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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
#include "widgets/wx_grid.h"
#include "dialog_sch_sheet_props_base.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 ) 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; wxBoxSizer* mainSizer;
mainSizer = new wxBoxSizer( wxVERTICAL ); mainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bupperSizer; m_longForm = new wxBoxSizer( wxVERTICAL );
bupperSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer3; wxStaticBoxSizer* sbFields;
bSizer3 = new wxBoxSizer( wxHORIZONTAL ); sbFields = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Fields") ), wxVERTICAL );
m_filenameLabel = new wxStaticText( this, wxID_ANY, _("&File name:"), wxDefaultPosition, wxDefaultSize, 0 ); m_grid = new WX_GRID( sbFields->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_filenameLabel->Wrap( -1 );
bSizer3->Add( m_filenameLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_textFileName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); // Grid
m_textFileName->SetMinSize( wxSize( 360,-1 ) ); 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 ); // Rows
m_browseButton->SetMinSize( wxSize( 30,28 ) ); 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; m_bpDelete = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizerFilenameSettings = new wxBoxSizer( wxHORIZONTAL ); m_bpDelete->SetToolTip( _("Delete field") );
m_bpDelete->SetMinSize( wxSize( 30,30 ) );
m_filenameVisible = new wxCheckBox( this, wxID_ANY, _("Visible"), wxDefaultPosition, wxDefaultSize, 0 ); bButtonSize->Add( m_bpDelete, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
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 );
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; wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer( wxHORIZONTAL ); bSizer5 = new wxBoxSizer( wxHORIZONTAL );
m_sheetnameLabel = new wxStaticText( this, wxID_ANY, _("&Sheet name:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText2 = new wxStaticText( this, wxID_ANY, _("Hierarchical Path:"), wxDefaultPosition, wxDefaultSize, 0 );
m_sheetnameLabel->Wrap( -1 ); m_staticText2->Wrap( -1 );
bSizer5->Add( m_sheetnameLabel, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); bSizer5->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_textSheetName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_heirarchyPath = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
bSizer5->Add( m_textSheetName, 5, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 ); bSizer5->Add( m_heirarchyPath, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bupperSizer->Add( bSizer5, 0, wxEXPAND, 5 ); m_longForm->Add( bSizer5, 0, wxEXPAND|wxRIGHT|wxLEFT, 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 );
bupperSizer->Add( bSizerSheetnameSettings, 0, wxEXPAND, 5 ); mainSizer->Add( m_longForm, 1, wxEXPAND|wxRIGHT|wxLEFT, 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 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
mainSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 ); mainSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
m_sdbSizer1 = new wxStdDialogButtonSizer(); wxBoxSizer* bSizerBottom;
m_sdbSizer1OK = new wxButton( this, wxID_OK ); bSizerBottom = new wxBoxSizer( wxHORIZONTAL );
m_sdbSizer1->AddButton( m_sdbSizer1OK );
m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
m_sdbSizer1->Realize();
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->SetSizer( mainSizer );
this->Layout(); 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() 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 );
} }

File diff suppressed because it is too large Load Diff

View File

@ -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/ // http://www.wxformbuilder.org/
// //
// PLEASE DO *NOT* EDIT THIS FILE! // PLEASE DO *NOT* EDIT THIS FILE!
@ -10,74 +10,65 @@
#include <wx/artprov.h> #include <wx/artprov.h>
#include <wx/xrc/xmlres.h> #include <wx/xrc/xmlres.h>
#include <wx/intl.h> #include <wx/intl.h>
class WX_GRID;
#include "dialog_shim.h" #include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h> #include <wx/colour.h>
#include <wx/settings.h> #include <wx/settings.h>
#include <wx/textctrl.h> #include <wx/string.h>
#include <wx/font.h>
#include <wx/grid.h>
#include <wx/gdicmn.h>
#include <wx/bmpbuttn.h> #include <wx/bmpbuttn.h>
#include <wx/bitmap.h> #include <wx/bitmap.h>
#include <wx/image.h> #include <wx/image.h>
#include <wx/icon.h> #include <wx/icon.h>
#include <wx/button.h> #include <wx/button.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/checkbox.h> #include <wx/statbox.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/statline.h> #include <wx/statline.h>
#include <wx/dialog.h> #include <wx/dialog.h>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_SCH_SHEET_PROPS_BASE /// Class DIALOG_SCH_SHEET_PROPS_BASE
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
class DIALOG_SCH_SHEET_PROPS_BASE : public DIALOG_SHIM class DIALOG_SCH_SHEET_PROPS_BASE : public DIALOG_SHIM
{ {
DECLARE_EVENT_TABLE()
private: private:
// Private event handlers
void _wxFB_OnBrowseClicked( wxCommandEvent& event ){ OnBrowseClicked( event ); }
protected: protected:
enum wxBoxSizer* m_longForm;
{ WX_GRID* m_grid;
ID_BUTTON_BROWSE_SHEET = 1000 wxBitmapButton* m_bpAdd;
}; wxBitmapButton* m_bpMoveUp;
wxBitmapButton* m_bpMoveDown;
wxStaticText* m_filenameLabel; wxBitmapButton* m_bpDelete;
wxTextCtrl* m_textFileName; wxStaticText* m_staticText2;
wxBitmapButton* m_browseButton; wxTextCtrl* m_heirarchyPath;
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;
wxStaticLine* m_staticline1; wxStaticLine* m_staticline1;
wxStdDialogButtonSizer* m_sdbSizer1; wxTextCtrl* m_textCtrlTimeStamp;
wxButton* m_sdbSizer1OK; wxStdDialogButtonSizer* m_stdDialogButtonSizer;
wxButton* m_sdbSizer1Cancel; wxButton* m_stdDialogButtonSizerOK;
wxButton* m_stdDialogButtonSizerCancel;
// Virtual event handlers, overide them in your derived class // 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: 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(); ~DIALOG_SCH_SHEET_PROPS_BASE();
}; };

View File

@ -73,7 +73,7 @@ SEARCH_RESULT EE_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData )
if( aItem->Type() == LIB_PIN_T ) if( aItem->Type() == LIB_PIN_T )
{ {
// Special selection rules apply to pins of different units when edited in // 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. // decide what to do with them.
} }
else if( m_Unit || m_Convert ) else if( m_Unit || m_Convert )

View File

@ -40,6 +40,9 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() : APP_SETTINGS_BASE( "eeschema", eeschema
m_params.emplace_back( new PARAM<wxString>( "appearance.edit_component_visible_columns", m_params.emplace_back( new PARAM<wxString>( "appearance.edit_component_visible_columns",
&m_Appearance.edit_component_visible_columns, "0 1 2 3 4 5 6 7" ) ); &m_Appearance.edit_component_visible_columns, "0 1 2 3 4 5 6 7" ) );
m_params.emplace_back( new PARAM<wxString>( "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<bool>( "appearance.footprint_preview", m_params.emplace_back( new PARAM<bool>( "appearance.footprint_preview",
&m_Appearance.footprint_preview, true ) ); &m_Appearance.footprint_preview, true ) );

View File

@ -34,6 +34,7 @@ public:
struct APPEARANCE struct APPEARANCE
{ {
wxString edit_component_visible_columns; wxString edit_component_visible_columns;
wxString edit_sheet_visible_columns;
bool footprint_preview; bool footprint_preview;
bool navigator_stays_open; bool navigator_stays_open;
bool print_sheet_reference; bool print_sheet_reference;

View File

@ -33,6 +33,7 @@
#include <template_fieldnames.h> #include <template_fieldnames.h>
#include <widgets/grid_icon_text_helpers.h> #include <widgets/grid_icon_text_helpers.h>
#include <widgets/grid_text_button_helpers.h> #include <widgets/grid_text_button_helpers.h>
#include <wildcards_and_files_ext.h>
#include "eda_doc.h" #include "eda_doc.h"
@ -49,13 +50,43 @@ FIELDS_GRID_TABLE<T>::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* a
LIB_PART* aPart ) : LIB_PART* aPart ) :
m_frame( aFrame ), m_frame( aFrame ),
m_userUnits( aDialog->GetUserUnits() ), m_userUnits( aDialog->GetUserUnits() ),
m_parentType( SCH_COMPONENT_T ),
m_mandatoryFieldCount( MANDATORY_FIELDS ),
m_part( aPart ), m_part( aPart ),
m_fieldNameValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_NAME ), m_fieldNameValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_NAME ),
m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE ), m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE ),
m_valueValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), VALUE ), m_valueValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), VALUE ),
m_libIdValidator( LIB_ID::ID_PCB ), m_libIdValidator( LIB_ID::ID_PCB ),
m_urlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ), m_urlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ),
m_nonUrlValidator( 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 <class T>
FIELDS_GRID_TABLE<T>::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 <class T>
void FIELDS_GRID_TABLE<T>::initGrid( DIALOG_SHIM* aDialog )
{ {
// Build the various grid cell attributes. // Build the various grid cell attributes.
// NOTE: validators and cellAttrs are member variables to get the destruction order // NOTE: validators and cellAttrs are member variables to get the destruction order
@ -94,6 +125,13 @@ FIELDS_GRID_TABLE<T>::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* a
nonUrlEditor->SetValidator( m_nonUrlValidator ); nonUrlEditor->SetValidator( m_nonUrlValidator );
m_nonUrlAttr->SetEditor( nonUrlEditor ); 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 = new wxGridCellAttr;
m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() ); m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() );
m_boolAttr->SetEditor( new wxGridCellBoolEditor() ); m_boolAttr->SetEditor( new wxGridCellBoolEditor() );
@ -135,6 +173,7 @@ FIELDS_GRID_TABLE<T>::~FIELDS_GRID_TABLE()
m_footprintAttr->DecRef(); m_footprintAttr->DecRef();
m_urlAttr->DecRef(); m_urlAttr->DecRef();
m_nonUrlAttr->DecRef(); m_nonUrlAttr->DecRef();
m_filepathAttr->DecRef();
m_vAlignAttr->DecRef(); m_vAlignAttr->DecRef();
m_hAlignAttr->DecRef(); m_hAlignAttr->DecRef();
m_orientationAttr->DecRef(); m_orientationAttr->DecRef();
@ -207,7 +246,7 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
switch( aCol ) switch( aCol )
{ {
case FDC_NAME: case FDC_NAME:
if( aRow < MANDATORY_FIELDS || rowIsReadOnly ) if( aRow < m_mandatoryFieldCount || rowIsReadOnly )
{ {
tmp = m_fieldNameAttr->Clone(); tmp = m_fieldNameAttr->Clone();
tmp->SetReadOnly( true ); tmp->SetReadOnly( true );
@ -221,7 +260,7 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
} }
case FDC_VALUE: case FDC_VALUE:
if( aRow == REFERENCE ) if( m_parentType == SCH_COMPONENT_T && aRow == REFERENCE )
{ {
if( rowIsReadOnly ) if( rowIsReadOnly )
{ {
@ -236,7 +275,7 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
return m_referenceAttr; 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 // 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. // be the same and can be edited only in library editor.
@ -254,7 +293,7 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
return m_valueAttr; return m_valueAttr;
} }
} }
else if( aRow == FOOTPRINT ) else if( m_parentType == SCH_COMPONENT_T && aRow == FOOTPRINT )
{ {
if( rowIsReadOnly ) if( rowIsReadOnly )
{ {
@ -269,11 +308,16 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
return m_footprintAttr; return m_footprintAttr;
} }
} }
else if( aRow == DATASHEET ) else if( m_parentType == SCH_COMPONENT_T && aRow == DATASHEET )
{ {
m_urlAttr->IncRef(); m_urlAttr->IncRef();
return m_urlAttr; return m_urlAttr;
} }
else if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME )
{
m_filepathAttr->IncRef();
return m_filepathAttr;
}
else else
{ {
wxString fieldname = GetValue( aRow, FDC_NAME ); wxString fieldname = GetValue( aRow, FDC_NAME );
@ -403,9 +447,14 @@ wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
case FDC_NAME: case FDC_NAME:
// Use default field name for mandatory fields, because they are translated // Use default field name for mandatory fields, because they are translated
// according to the current locale // according to the current locale
if( aRow < MANDATORY_FIELDS ) if( aRow < m_mandatoryFieldCount )
{
if( m_parentType == SCH_COMPONENT_T )
return TEMPLATE_FIELDNAME::GetDefaultFieldName( aRow ); return TEMPLATE_FIELDNAME::GetDefaultFieldName( aRow );
else else if( m_parentType == SCH_SHEET_T )
return SCH_SHEET::GetDefaultFieldName( aRow );
}
return field.GetName( false ); return field.GetName( false );
case FDC_VALUE: case FDC_VALUE:

View File

@ -73,6 +73,7 @@ class FIELDS_GRID_TABLE : public wxGridTableBase, public std::vector<T>
{ {
public: public:
FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* aFrame, LIB_PART* aPart ); 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(); ~FIELDS_GRID_TABLE();
int GetNumberRows() override { return (int) this->size(); } int GetNumberRows() override { return (int) this->size(); }
@ -98,10 +99,16 @@ public:
wxString StringFromBool( bool aValue ); wxString StringFromBool( bool aValue );
bool BoolFromString( wxString aValue ); bool BoolFromString( wxString aValue );
protected:
void initGrid( DIALOG_SHIM* aDialog );
private: private:
SCH_BASE_FRAME* m_frame; SCH_BASE_FRAME* m_frame;
EDA_UNITS m_userUnits; EDA_UNITS m_userUnits;
KICAD_T m_parentType;
int m_mandatoryFieldCount;
LIB_PART* m_part; LIB_PART* m_part;
wxString m_curdir;
SCH_FIELD_VALIDATOR m_fieldNameValidator; SCH_FIELD_VALIDATOR m_fieldNameValidator;
SCH_FIELD_VALIDATOR m_referenceValidator; SCH_FIELD_VALIDATOR m_referenceValidator;
@ -109,6 +116,7 @@ private:
LIB_ID_VALIDATOR m_libIdValidator; LIB_ID_VALIDATOR m_libIdValidator;
SCH_FIELD_VALIDATOR m_urlValidator; SCH_FIELD_VALIDATOR m_urlValidator;
SCH_FIELD_VALIDATOR m_nonUrlValidator; SCH_FIELD_VALIDATOR m_nonUrlValidator;
SCH_FIELD_VALIDATOR m_filepathValidator;
wxGridCellAttr* m_readOnlyAttr; wxGridCellAttr* m_readOnlyAttr;
wxGridCellAttr* m_fieldNameAttr; wxGridCellAttr* m_fieldNameAttr;
@ -117,6 +125,7 @@ private:
wxGridCellAttr* m_footprintAttr; wxGridCellAttr* m_footprintAttr;
wxGridCellAttr* m_urlAttr; wxGridCellAttr* m_urlAttr;
wxGridCellAttr* m_nonUrlAttr; wxGridCellAttr* m_nonUrlAttr;
wxGridCellAttr* m_filepathAttr;
wxGridCellAttr* m_boolAttr; wxGridCellAttr* m_boolAttr;
wxGridCellAttr* m_vAlignAttr; wxGridCellAttr* m_vAlignAttr;
wxGridCellAttr* m_hAlignAttr; wxGridCellAttr* m_hAlignAttr;

View File

@ -928,11 +928,11 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
m_Fields.swap( component->m_Fields ); // std::vector's swap() m_Fields.swap( component->m_Fields ); // std::vector's swap()
for( int ii = 0; ii < component->GetFieldCount(); ++ii ) for( SCH_FIELD& field : component->m_Fields )
component->GetField( ii )->SetParent( component ); field.SetParent( component );
for( int ii = 0; ii < GetFieldCount(); ++ii ) for( SCH_FIELD& field : m_Fields )
GetField( ii )->SetParent( this ); field.SetParent( this );
TRANSFORM tmp = m_transform; TRANSFORM tmp = m_transform;
@ -1345,12 +1345,12 @@ void SCH_COMPONENT::MirrorY( int aYaxis_position )
MIRROR( m_Pos.x, aYaxis_position ); MIRROR( m_Pos.x, aYaxis_position );
dx -= m_Pos.x; // dx,0 is the move vector for this transform 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. // 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; 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 ); MIRROR( m_Pos.y, aXaxis_position );
dy -= m_Pos.y; // dy,0 is the move vector for this transform 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. // 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; 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 ) if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T )
{ {
// Test the bounding boxes of fields if they are visible and not empty. // 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; return SEARCH_RESULT::QUIT;
} }
} }

View File

@ -124,8 +124,6 @@ private:
SCH_PINS m_pins; ///< a SCH_PIN for every LIB_PIN (across all units) 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* 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 bool m_isInNetlist; ///< True if the component should appear in the netlist
// Defines the hierarchical path and reference of the component. This allows support // 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(); } 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. * 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 * or a menu item). Some more 'intelligent' routines will be used that would be
* annoying if done automatically during moves. * annoying if done automatically during moves.
*/ */
void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ); void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override;
/**
* 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 );
}
//-----</Fields>---------------------------------------------------------- //-----</Fields>----------------------------------------------------------
@ -558,8 +532,8 @@ public:
m_Pos += aMoveVector; m_Pos += aMoveVector;
for( int ii = 0; ii < GetFieldCount(); ii++ ) for( SCH_FIELD& field : m_Fields )
GetField( ii )->Move( aMoveVector ); field.Move( aMoveVector );
SetModified(); SetModified();
} }

View File

@ -725,16 +725,6 @@ private:
*/ */
void UpdateTitle(); 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 * Verify that the symbol library links \a aSheet and all of it's child sheets have
* been remapped to the symbol library table. * been remapped to the symbol library table.
@ -753,6 +743,17 @@ private:
*/ */
bool importFile( const wxString& aFileName, int aFileType ); 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. * 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. * @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. * @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. * Change a text type to another one.
* *

View File

@ -216,18 +216,26 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const
RotatePoint( &begin, pos, GetTextAngle() ); RotatePoint( &begin, pos, GetTextAngle() );
RotatePoint( &end, pos, GetTextAngle() ); RotatePoint( &end, pos, GetTextAngle() );
// 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, // Due to the Y axis direction, we must mirror the bounding box,
// relative to the text position: // relative to the text position:
MIRROR( begin.y, pos.y ); MIRROR( begin.y, pos.y );
MIRROR( end.y, pos.y ); MIRROR( end.y, pos.y );
// Now, apply the component transform (mirror/rot)
if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T )
{
SCH_COMPONENT* parentComponent = static_cast<SCH_COMPONENT*>( m_Parent ); SCH_COMPONENT* parentComponent = static_cast<SCH_COMPONENT*>( m_Parent );
rect.SetOrigin( parentComponent->GetTransform().TransformCoordinate( begin )); transform = parentComponent->GetTransform();
rect.SetEnd( parentComponent->GetTransform().TransformCoordinate( end ));
} }
else
{
transform = TRANSFORM( 1, 0, 0, 1 ); // identity transform
}
rect.SetOrigin( transform.TransformCoordinate( begin ) );
rect.SetEnd( transform.TransformCoordinate( end ) );
rect.Move( origin ); rect.Move( origin );
rect.Normalize(); rect.Normalize();
@ -296,14 +304,23 @@ bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData )
bool SCH_FIELD::IsReplaceable() const bool SCH_FIELD::IsReplaceable() const
{ {
if( m_id != VALUE ) if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T )
{
if( m_id == VALUE )
{
LIB_PART* part = static_cast<SCH_COMPONENT*>( GetParent() )->GetPartRef().get();
if( part && part->IsPower() )
return false;
}
}
else if( m_Parent && m_Parent->Type() == SCH_SHEET_T )
{
if( m_id == SHEETFILENAME )
return false;
}
return true; return true;
SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( GetParent() );
LIB_PART* part = component ? component->GetPartRef().get() : nullptr;
bool isPower = part ? part->IsPower() : false;
return !isPower;
} }
@ -311,10 +328,8 @@ bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData )
{ {
bool isReplaced = false; bool isReplaced = false;
wxString text = GetFullyQualifiedText(); 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, wxCHECK_MSG( aAuxData != NULL, false,
wxT( "Cannot replace reference designator without valid sheet path." ) ); 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; 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 ); text = component->GetRef( (SCH_SHEET_PATH*) aAuxData );
// if( component->GetUnitCount() > 1 ) // if( component->GetUnitCount() > 1 )
@ -336,7 +349,7 @@ bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData )
if( isReplaced ) if( isReplaced )
component->SetRef( (SCH_SHEET_PATH*) aAuxData, text ); 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.... // This is likely too dangerous to allow....
} }
@ -368,7 +381,12 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
if( !m_name.IsEmpty() ) if( !m_name.IsEmpty() )
return m_name; return m_name;
else if( aUseDefaultName ) else if( aUseDefaultName )
{
if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T )
return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id ); return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id );
else if( m_Parent && m_Parent->Type() == SCH_SHEET_T )
return SCH_SHEET::GetDefaultFieldName( m_id );
}
return wxEmptyString; return wxEmptyString;
} }
@ -376,7 +394,7 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
BITMAP_DEF SCH_FIELD::GetMenuImage() const BITMAP_DEF SCH_FIELD::GetMenuImage() const
{ {
if( dynamic_cast<SCH_COMPONENT*>( m_Parent ) ) if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T )
{ {
switch( m_id ) switch( m_id )
{ {
@ -475,16 +493,20 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter )
void SCH_FIELD::SetPosition( const wxPoint& aPosition ) void SCH_FIELD::SetPosition( const wxPoint& aPosition )
{ {
SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent(); wxPoint pos = GetParentPosition();
wxPoint pos = ( (SCH_COMPONENT*) GetParent() )->GetPosition();
// Actual positions are calculated by the rotation/mirror transform of the // Actual positions are calculated by the rotation/mirror transform of the
// parent component of the field. The inverse transform is used to calculate // parent component of the field. The inverse transform is used to calculate
// the position relative to the parent component. // the position relative to the parent component.
if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T )
{
SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent();
wxPoint pt = aPosition - pos; wxPoint pt = aPosition - pos;
SetTextPos( pos + component->GetTransform().InverseTransform().TransformCoordinate( pt ) ); pos += component->GetTransform().InverseTransform().TransformCoordinate( pt );
}
SetTextPos( pos );
} }

View File

@ -37,14 +37,6 @@ class SCH_COMPONENT;
class LIB_FIELD; class LIB_FIELD;
enum FIELDS_AUTOPLACED
{
FIELDS_AUTOPLACED_NO = 0,
FIELDS_AUTOPLACED_AUTO,
FIELDS_AUTOPLACED_MANUAL
};
/** /**
* SCH_FIELD * SCH_FIELD
* instances are attached to a component and provide a place for the component's value, * instances are attached to a component and provide a place for the component's value,

View File

@ -43,7 +43,16 @@ class NETLIST_OBJECT;
class NETLIST_OBJECT_LIST; 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, UNKNOWN = 0,
WIRE_START_END, WIRE_START_END,
WIRE_END_END, WIRE_END_END,
@ -141,9 +150,10 @@ class SCH_ITEM : public EDA_ITEM
protected: protected:
SCH_LAYER_ID m_Layer; SCH_LAYER_ID m_Layer;
EDA_ITEMS m_connections; ///< List of items connected to this item. EDA_ITEMS m_connections; // List of items connected to this item.
wxPoint m_storedPos; ///< a temporary variable used in some move commands FIELDS_AUTOPLACED m_fieldsAutoplaced; // indicates status of field autoplacement
///> to store a initial pos (of the item or mouse cursor) 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 /// Stores pointers to other items that are connected to this one, per sheet
std::unordered_map<SCH_SHEET_PATH, ITEM_SET> m_connected_items; std::unordered_map<SCH_SHEET_PATH, ITEM_SET> m_connected_items;
@ -388,6 +398,32 @@ public:
virtual bool CanIncrementLabel() const { return false; } 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 * Function Plot
* plots the schematic item to \a aPlotter. * plots the schematic item to \a aPlotter.

View File

@ -1387,7 +1387,7 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer )
} }
/* Calculate the text justification, according to the component orientation/mirror. /* 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) * - numerous cases (mirrored or not, rotation)
* - the DrawGraphicText function recalculate also H and H justifications according to the * - the DrawGraphicText function recalculate also H and H justifications according to the
* text orientation. * text orientation.
@ -1410,8 +1410,8 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer )
m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 ); m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 );
boundaryBox.RevertYAxis(); boundaryBox.RevertYAxis();
m_gal->DrawRectangle( m_gal->DrawRectangle( mapCoords( boundaryBox.GetPosition() ),
mapCoords( boundaryBox.GetPosition() ), mapCoords( boundaryBox.GetEnd() ) ); mapCoords( boundaryBox.GetEnd() ) );
} }
else else
{ {
@ -1511,7 +1511,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer )
{ {
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS; 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() ) 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 pos = aSheet->GetPosition();
VECTOR2D size = aSheet->GetSize(); VECTOR2D size = aSheet->GetSize();
@ -1571,7 +1568,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer )
m_gal->DrawRectangle( pos, pos + size ); 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->SetStrokeColor( getRenderColor( aSheet, LAYER_SHEET, drawingShadows ) );
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
@ -1580,7 +1577,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer )
m_gal->DrawRectangle( pos, pos + size ); m_gal->DrawRectangle( pos, pos + size );
if( drawingShadows && !GetSelectionDrawChildItems() ) if( drawingShadows && !GetSelectionDrawChildItems() && aSheet->IsSelected() )
return; return;
for( SCH_FIELD& field : aSheet->GetFields() ) for( SCH_FIELD& field : aSheet->GetFields() )

View File

@ -40,7 +40,7 @@
#include <pgm_base.h> #include <pgm_base.h>
const wxString GetDefaultFieldName( int aFieldNdx ) const wxString SCH_SHEET::GetDefaultFieldName( int aFieldNdx )
{ {
static void* locale = nullptr; static void* locale = nullptr;
static wxString sheetnameDefault; static wxString sheetnameDefault;
@ -51,9 +51,9 @@ const wxString GetDefaultFieldName( int aFieldNdx )
// so only do it when necessary. // so only do it when necessary.
if( Pgm().GetLocale() != locale ) if( Pgm().GetLocale() != locale )
{ {
sheetnameDefault = _( "Sheet Name" ); sheetnameDefault = _( "Sheet name" );
sheetfilenameDefault = _( "Sheet Filename" ); sheetfilenameDefault = _( "Sheet file" );
fieldDefault = _( "Field" ); fieldDefault = _( "Field%d" );
locale = Pgm().GetLocale(); 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 ) void SCH_SHEET::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual )
{ {
wxASSERT_MSG( !aManual, "manual autoplacement not currently supported for sheets" ); wxASSERT_MSG( !aManual, "manual autoplacement not currently supported for sheets" );
m_fields[ SHEETNAME ].SetTextPos( getSheetNamePosition() ); wxSize textSize = m_fields[ SHEETNAME ].GetTextSize();
int margin = KiROUND( GetPenSize() / 2.0 + 4 + std::max( textSize.x, textSize.y ) * 0.5 );
if( IsVerticalOrientation() )
{
m_fields[ SHEETNAME ].SetTextPos( m_pos + wxPoint( -margin, m_size.y ) );
m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
m_fields[ SHEETNAME ].SetVertJustify(GR_TEXT_VJUSTIFY_BOTTOM ); m_fields[ SHEETNAME ].SetVertJustify(GR_TEXT_VJUSTIFY_BOTTOM );
m_fields[ SHEETNAME ].SetTextAngle( IsVerticalOrientation() ? 900 : 0 ); 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 );
}
m_fields[ SHEETFILENAME ].SetTextPos( getFileNamePosition() ); 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 ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
m_fields[ SHEETFILENAME ].SetVertJustify(GR_TEXT_VJUSTIFY_TOP ); m_fields[ SHEETFILENAME ].SetVertJustify(GR_TEXT_VJUSTIFY_TOP );
m_fields[ SHEETFILENAME ].SetTextAngle( IsVerticalOrientation() ? 900 : 0 ); 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; 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; wxPoint end;
EDA_RECT box( m_pos, m_size ); EDA_RECT box( m_pos, m_size );
@ -513,8 +515,16 @@ const EDA_RECT SCH_SHEET::GetBoundingBox() const
box.SetEnd( end ); box.SetEnd( end );
box.Inflate( lineWidth / 2 ); box.Inflate( lineWidth / 2 );
for( size_t i = 0; i < m_fields.size(); i++ ) return box;
box.Merge( m_fields[i].GetBoundingBox() ); }
const EDA_RECT SCH_SHEET::GetBoundingBox() const
{
EDA_RECT box = GetBodyBoundingBox();
for( const SCH_FIELD& field : m_fields )
box.Merge( field.GetBoundingBox() );
return box; return box;
} }
@ -659,17 +669,26 @@ void SCH_SHEET::Rotate(wxPoint aPosition)
m_size.y = -m_size.y; m_size.y = -m_size.y;
} }
// 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 ) for( SCH_FIELD& field : m_fields )
{ {
// Move the fields to the new position because the sheet itself has moved.
wxPoint pos = field.GetTextPos(); wxPoint pos = field.GetTextPos();
pos.x -= prev.x - m_pos.x; pos.x -= prev.x - m_pos.x;
pos.y -= prev.y - m_pos.y; pos.y -= prev.y - m_pos.y;
field.SetTextPos( pos ); field.SetTextPos( pos );
} }
}
for( SCH_SHEET_PIN* sheetPin : m_pins )
sheetPin->Rotate( aPosition );
} }
@ -783,6 +802,16 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICA
return SEARCH_RESULT::QUIT; 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 ) if( stype == SCH_LOCATE_ANY_T || stype == SCH_SHEET_PIN_T )
{ {
// Test the sheet labels. // Test the sheet labels.
@ -812,7 +841,7 @@ BITMAP_DEF SCH_SHEET::GetMenuImage() const
bool SCH_SHEET::HitTest( const wxPoint& aPosition, int aAccuracy ) const bool SCH_SHEET::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{ {
EDA_RECT rect = GetBoundingBox(); EDA_RECT rect = GetBodyBoundingBox();
rect.Inflate( aAccuracy ); rect.Inflate( aAccuracy );
@ -827,9 +856,9 @@ bool SCH_SHEET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy )
rect.Inflate( aAccuracy ); rect.Inflate( aAccuracy );
if( aContained ) if( aContained )
return rect.Contains( GetBoundingBox() ); return rect.Contains( GetBodyBoundingBox() );
return rect.Intersects( GetBoundingBox() ); return rect.Intersects( GetBodyBoundingBox() );
} }

View File

@ -263,6 +263,16 @@ public:
std::vector<SCH_FIELD>& GetFields() { return m_fields; } std::vector<SCH_FIELD>& GetFields() { return m_fields; }
/**
* Set multiple schematic fields.
*
* @param aFields are the fields to set in this symbol.
*/
void SetFields( const std::vector<SCH_FIELD>& aFields )
{
m_fields = aFields; // vector copying, length is changed possibly
}
// JEY TODO: retite these once new dialog is implemented... // JEY TODO: retite these once new dialog is implemented...
wxString GetName() const { return m_fields[ SHEETNAME ].GetText(); } wxString GetName() const { return m_fields[ SHEETNAME ].GetText(); }
void SetName( const wxString& aName ) { m_fields[ SHEETNAME ].SetText( aName ); } void SetName( const wxString& aName ) { m_fields[ SHEETNAME ].SetText( aName ); }
@ -411,7 +421,12 @@ public:
void Print( wxDC* aDC, const wxPoint& aOffset ) override; 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 * Rotating around the boundingBox's center can cause walking when the sheetname or
@ -500,17 +515,7 @@ public:
*/ */
void Resize( const wxSize& aSize ); void Resize( const wxSize& aSize );
/** void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override;
* 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 GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList ) override; void GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList ) override;
@ -557,18 +562,9 @@ public:
void Show( int nestLevel, std::ostream& os ) const override; void Show( int nestLevel, std::ostream& os ) const override;
#endif #endif
static const wxString GetDefaultFieldName( int aFieldNdx );
protected: 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. * Renumber the sheet pins in the sheet.
* *

View File

@ -175,20 +175,11 @@ void SCH_SHEET_PIN::ConstrainOnEdge( wxPoint Pos )
switch( sheetEdge.NearestSegment( Pos ) ) switch( sheetEdge.NearestSegment( Pos ) )
{ {
case 0: case 0: SetEdge( SHEET_TOP_SIDE ); break;
SetEdge( SHEET_TOP_SIDE ); case 1: SetEdge( SHEET_RIGHT_SIDE ); break;
break; case 2: SetEdge( SHEET_BOTTOM_SIDE ); break;
case 1: case 3: SetEdge( SHEET_LEFT_SIDE ); break;
SetEdge( SHEET_RIGHT_SIDE ); default: wxASSERT( "Invalid segment number" );
break;
case 2:
SetEdge( SHEET_BOTTOM_SIDE );
break;
case 3:
SetEdge( SHEET_LEFT_SIDE );
break;
default:
wxASSERT( "Invalid segment number" );
} }
switch( GetEdge() ) switch( GetEdge() )
@ -257,16 +248,6 @@ void SCH_SHEET_PIN::Rotate( wxPoint aPosition )
{ {
wxPoint pt = GetTextPos(); wxPoint pt = GetTextPos();
RotatePoint( &pt, aPosition, 900 ); 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 ); ConstrainOnEdge( pt );
} }
@ -283,14 +264,9 @@ void SCH_SHEET_PIN::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wx
switch( m_shape ) switch( m_shape )
{ {
case PINSHEETLABEL_SHAPE::PS_INPUT: case PINSHEETLABEL_SHAPE::PS_INPUT: m_shape = PINSHEETLABEL_SHAPE::PS_OUTPUT; break;
m_shape = PINSHEETLABEL_SHAPE::PS_OUTPUT; case PINSHEETLABEL_SHAPE::PS_OUTPUT: m_shape = PINSHEETLABEL_SHAPE::PS_INPUT; break;
break; default: break;
case PINSHEETLABEL_SHAPE::PS_OUTPUT:
m_shape = PINSHEETLABEL_SHAPE::PS_INPUT;
break;
default:
break;
} }
SCH_HIERLABEL::CreateGraphicShape( aPoints, aPos ); SCH_HIERLABEL::CreateGraphicShape( aPoints, aPos );

View File

@ -41,7 +41,7 @@
#include <tool/actions.h> #include <tool/actions.h>
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 ); 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 hierarchy( g_RootSheet ); // This is the schematic sheet hierarchy.
SCH_SHEET_LIST sheetHierarchy( newSheet.get() ); // This is the hierarchy of the loaded file. 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() ) ) || checkForNoFullyDefinedLibIds( newSheet.get() ) )
return false; return false;
@ -483,247 +483,11 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy,
return false; return false;
// Get the new texts // Get the new texts
DIALOG_SCH_SHEET_PROPS dlg( this, aSheet ); DIALOG_SCH_SHEET_PROPS dlg( this, aSheet, aClearAnnotationNewItems );
if( dlg.ShowModal() == wxID_CANCEL ) if( dlg.ShowModal() == wxID_CANCEL )
return false; 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; 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; wxString msg;
SCH_SCREENS screens; SCH_SCREENS screens;

View File

@ -607,10 +607,18 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
EE_SELECTION& EE_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] ) 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 ); 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 ); 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(); updateReferencePoint();

View File

@ -446,11 +446,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
field->SetTextAngle( TEXT_ANGLE_HORIZ ); field->SetTextAngle( TEXT_ANGLE_HORIZ );
// Now that we're moving a field, they're no longer autoplaced. // Now that we're moving a field, they're no longer autoplaced.
if( item->GetParent()->Type() == SCH_COMPONENT_T ) static_cast<SCH_ITEM*>( item->GetParent() )->ClearFieldsAutoplaced();
{
SCH_COMPONENT* parent = static_cast<SCH_COMPONENT*>( item->GetParent() );
parent->ClearFieldsAutoplaced();
}
break; break;
} }
@ -469,7 +465,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item ); SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
// Rotate the sheet on itself. Sheets do not have an anchor point. // 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() ); rotPoint = m_frame->GetNearestGridPosition( sheet->GetRotationCenter() );
sheet->Rotate( rotPoint ); sheet->Rotate( rotPoint );
@ -635,11 +631,7 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
field->SetHorizJustify( (EDA_TEXT_HJUSTIFY_T)-field->GetHorizJustify() ); field->SetHorizJustify( (EDA_TEXT_HJUSTIFY_T)-field->GetHorizJustify() );
// Now that we're re-justifying a field, they're no longer autoplaced. // Now that we're re-justifying a field, they're no longer autoplaced.
if( item->GetParent()->Type() == SCH_COMPONENT_T ) static_cast<SCH_ITEM*>( item->GetParent() )->ClearFieldsAutoplaced();
{
SCH_COMPONENT *parent = static_cast<SCH_COMPONENT*>( item->GetParent() );
parent->ClearFieldsAutoplaced();
}
break; 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. // Save old component in undo list if not already in edit, or moving.
if( aField->GetEditFlags() == 0 ) // i.e. not edited, or moved 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() ); 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 ); dlg.UpdateField( aField, g_CurrentSheet );
if( m_frame->GetAutoplaceFields() ) if( m_frame->GetAutoplaceFields() || aField->GetParent()->Type() == SCH_SHEET_T )
component->AutoAutoplaceFields( m_frame->GetScreen() ); static_cast<SCH_ITEM*>( aField->GetParent() )->AutoAutoplaceFields( m_frame->GetScreen() );
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified ); m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
m_frame->RefreshItem( aField ); m_frame->RefreshItem( aField );
@ -1120,15 +1110,15 @@ int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent )
SCH_COMPONENT* component = (SCH_COMPONENT*) item; SCH_COMPONENT* component = (SCH_COMPONENT*) item;
if( aEvent.IsAction( &EE_ACTIONS::editReference ) ) if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
editComponentFieldText( component->GetField( REFERENCE ) ); editFieldText( component->GetField( REFERENCE ) );
else if( aEvent.IsAction( &EE_ACTIONS::editValue ) ) else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
editComponentFieldText( component->GetField( VALUE ) ); editFieldText( component->GetField( VALUE ) );
else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) ) else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
editComponentFieldText( component->GetField( FOOTPRINT ) ); editFieldText( component->GetField( FOOTPRINT ) );
} }
else if( item->Type() == SCH_FIELD_T ) else if( item->Type() == SCH_FIELD_T )
{ {
editComponentFieldText( (SCH_FIELD*) item ); editFieldText( (SCH_FIELD*) item );
} }
return 0; return 0;
@ -1288,7 +1278,7 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
break; break;
case SCH_FIELD_T: case SCH_FIELD_T:
editComponentFieldText( (SCH_FIELD*) item ); editFieldText( (SCH_FIELD*) item );
break; break;
case SCH_BITMAP_T: case SCH_BITMAP_T:

View File

@ -69,7 +69,7 @@ public:
int DeleteItemCursor( const TOOL_EVENT& aEvent ); int DeleteItemCursor( const TOOL_EVENT& aEvent );
private: private:
void editComponentFieldText( SCH_FIELD* aField ); void editFieldText( SCH_FIELD* aField );
///> Sets up handlers for various events. ///> Sets up handlers for various events.
void setTransitions() override; void setTransitions() override;

View File

@ -443,8 +443,11 @@ void SCH_EDITOR_CONTROL::doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aF
{ {
case SCH_FIELD_T: case SCH_FIELD_T:
case LIB_FIELD_T: case LIB_FIELD_T:
if( item->GetParent() && item->GetParent()->Type() == SCH_COMPONENT_T )
{
component = (SCH_COMPONENT*) item->GetParent(); component = (SCH_COMPONENT*) item->GetParent();
m_frame->SendMessageToPCBNEW( item, component ); m_frame->SendMessageToPCBNEW( item, component );
}
break; break;
case SCH_COMPONENT_T: case SCH_COMPONENT_T:

View File

@ -620,16 +620,23 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, VECTOR2I aDelta, bool isDrag )
case SCH_PIN_T: case SCH_PIN_T:
case SCH_FIELD_T: case SCH_FIELD_T:
{
SCH_ITEM* parent = (SCH_ITEM*) aItem->GetParent();
wxPoint delta( aDelta );
if( parent && parent->Type() == SCH_COMPONENT_T )
{ {
SCH_COMPONENT* component = (SCH_COMPONENT*) aItem->GetParent(); SCH_COMPONENT* component = (SCH_COMPONENT*) aItem->GetParent();
TRANSFORM transform = component->GetTransform().InverseTransform(); TRANSFORM transform = component->GetTransform().InverseTransform();
wxPoint transformedDelta = transform.TransformCoordinate( (wxPoint) aDelta );
static_cast<SCH_ITEM*>( aItem )->Move( transformedDelta ); delta = transform.TransformCoordinate( delta );
}
static_cast<SCH_ITEM*>( aItem )->Move( delta );
// If we're moving a field with respect to its parent then it's no longer auto-placed // 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() ) if( aItem->Type() == SCH_FIELD_T && !parent->IsSelected() )
component->ClearFieldsAutoplaced(); parent->ClearFieldsAutoplaced();
break; break;
} }

View File

@ -131,14 +131,15 @@ protected:
class GRID_CELL_PATH_EDITOR : public GRID_CELL_TEXT_BUTTON class GRID_CELL_PATH_EDITOR : public GRID_CELL_TEXT_BUTTON
{ {
public: 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_dlg( aParent ),
m_currentDir( aCurrentDir ) m_currentDir( aCurrentDir ),
m_ext( aExt )
{ } { }
wxGridCellEditor* Clone() const override 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; void Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler ) override;
@ -146,6 +147,7 @@ public:
protected: protected:
DIALOG_SHIM* m_dlg; DIALOG_SHIM* m_dlg;
wxString* m_currentDir; wxString* m_currentDir;
wxString m_ext;
}; };

View File

@ -389,7 +389,7 @@ PANEL_FP_LIB_TABLE::PANEL_FP_LIB_TABLE( DIALOG_EDIT_LIBRARY_TABLES* aParent,
wxGridCellAttr* attr; wxGridCellAttr* attr;
attr = new wxGridCellAttr; 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 ); g->SetColAttr( COL_URI, attr );
attr = new wxGridCellAttr; attr = new wxGridCellAttr;