Example #1
0
void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item = screen->GetCurItem();

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    // Allows block rotate operation on hot key.
    if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
    {
        screen->m_BlockLocate.SetCommand( BLOCK_ROTATE );
        HandleBlockEnd( &dc );
        return;
    }

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::RotatableItems,
                                  aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }

    switch( item->Type() )
    {
    case SCH_COMPONENT_T:
        {
            SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
            if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
                OrientComponent( CMP_ROTATE_CLOCKWISE );
            else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
                OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
            else
                wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );

            if( m_autoplaceFields )
                component->AutoAutoplaceFields( GetScreen() );

            m_canvas->Refresh();

            break;
        }

    case SCH_TEXT_T:
    case SCH_LABEL_T:
    case SCH_GLOBAL_LABEL_T:
    case SCH_HIERARCHICAL_LABEL_T:
        m_canvas->MoveCursorToCrossHair();
        ChangeTextOrient( (SCH_TEXT*) item );
        m_canvas->Refresh();
        break;

    case SCH_FIELD_T:
        m_canvas->MoveCursorToCrossHair();
        RotateField( (SCH_FIELD*) item );
        if( item->GetParent()->Type() == SCH_COMPONENT_T )
        {
            // Now that we're moving a field, they're no longer autoplaced.
            SCH_COMPONENT *parent = static_cast<SCH_COMPONENT*>( item->GetParent() );
            parent->ClearFieldsAutoplaced();
        }
        m_canvas->Refresh();
        break;

    case SCH_BITMAP_T:
        RotateImage( (SCH_BITMAP*) item );
        break;

    case SCH_SHEET_T:
        if( !item->IsNew() )    // rotate a sheet during its creation has no sense
        {
            bool retCCW = ( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE );
            RotateHierarchicalSheet( static_cast<SCH_SHEET*>( item ), retCCW );
        }

        break;

    case SCH_JUNCTION_T:
    case SCH_NO_CONNECT_T:
        // these items are not rotated, because rotation does not change them.
        break;

    default:
        // Other items (wires...) cannot be rotated, at least during creation
        if( item->IsNew() )
            break;

        wxFAIL_MSG( wxString::Format( wxT( "Cannot rotate schematic item type %s." ),
                                      GetChars( item->GetClass() ) ) );
    }

    if( item->GetFlags() == 0 )
        screen->SetCurItem( NULL );
}
XNODE* NETLIST_EXPORTER_GENERIC::makeDesignHeader()
{
    SCH_SCREEN* screen;
    XNODE*     xdesign = node( wxT( "design" ) );
    XNODE*     xtitleBlock;
    XNODE*     xsheet;
    XNODE*     xcomment;
    wxString   sheetTxt;
    wxFileName sourceFileName;

    // the root sheet is a special sheet, call it source
    xdesign->AddChild( node( wxT( "source" ), g_RootSheet->GetScreen()->GetFileName() ) );

    xdesign->AddChild( node( wxT( "date" ), DateAndTime() ) );

    // which Eeschema tool
    xdesign->AddChild( node( wxT( "tool" ), wxT( "Eeschema " ) + GetBuildVersion() ) );

    /*
        Export the sheets information
    */
    SCH_SHEET_LIST sheetList( g_RootSheet );

    for( unsigned i = 0;  i < sheetList.size();  i++ )
    {
        screen = sheetList[i].LastScreen();

        xdesign->AddChild( xsheet = node( wxT( "sheet" ) ) );

        // get the string representation of the sheet index number.
        // Note that sheet->GetIndex() is zero index base and we need to increment the
        // number by one to make it human readable
        sheetTxt.Printf( wxT( "%u" ), i + 1 );
        xsheet->AddAttribute( wxT( "number" ), sheetTxt );
        xsheet->AddAttribute( wxT( "name" ), sheetList[i].PathHumanReadable() );
        xsheet->AddAttribute( wxT( "tstamps" ), sheetList[i].Path() );


        TITLE_BLOCK tb = screen->GetTitleBlock();

        xsheet->AddChild( xtitleBlock = node( wxT( "title_block" ) ) );

        xtitleBlock->AddChild( node( wxT( "title" ), tb.GetTitle() ) );
        xtitleBlock->AddChild( node( wxT( "company" ), tb.GetCompany() ) );
        xtitleBlock->AddChild( node( wxT( "rev" ), tb.GetRevision() ) );
        xtitleBlock->AddChild( node( wxT( "date" ), tb.GetDate() ) );

        // We are going to remove the fileName directories.
        sourceFileName = wxFileName( screen->GetFileName() );
        xtitleBlock->AddChild( node( wxT( "source" ), sourceFileName.GetFullName() ) );

        xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
        xcomment->AddAttribute( wxT("number"), wxT("1") );
        xcomment->AddAttribute( wxT( "value" ), tb.GetComment1() );

        xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
        xcomment->AddAttribute( wxT("number"), wxT("2") );
        xcomment->AddAttribute( wxT( "value" ), tb.GetComment2() );

        xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
        xcomment->AddAttribute( wxT("number"), wxT("3") );
        xcomment->AddAttribute( wxT( "value" ), tb.GetComment3() );

        xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
        xcomment->AddAttribute( wxT("number"), wxT("4") );
        xcomment->AddAttribute( wxT( "value" ), tb.GetComment4() );
    }

    return xdesign;
}
bool DIALOG_SYMBOL_REMAP::backupProject( REPORTER& aReporter )
{
    static wxString backupFolder = "rescue-backup";

    wxString tmp;
    wxString errorMsg;
    wxFileName srcFileName;
    wxFileName destFileName;
    wxFileName backupPath;
    SCH_SCREENS schematic;

    // Copy backup files to different folder so as not to pollute the project folder.
    destFileName.SetPath( Prj().GetProjectPath() );
    destFileName.AppendDir( backupFolder );
    backupPath = destFileName;

    if( !destFileName.DirExists() )
    {
        if( !destFileName.Mkdir() )
        {
            errorMsg.Printf( _( "Cannot create project remap back up folder \"%s\"." ),
                             destFileName.GetPath() );

            wxMessageDialog dlg( this, errorMsg, _( "Backup Error" ),
                                 wxYES_NO | wxCENTRE | wxRESIZE_BORDER | wxICON_QUESTION );
            dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Continue with Rescue" ) ),
                                wxMessageDialog::ButtonLabel( _( "Abort Rescue" ) ) );

            if( dlg.ShowModal() == wxID_NO )
                return false;
        }
    }

    // Time stamp to append to file name in case multiple remappings are performed.
    wxString timeStamp = wxDateTime::Now().Format( "-%Y-%m-%d-%H-%M-%S" );

    // Back up symbol library table.
    srcFileName.SetPath( Prj().GetProjectPath() );
    srcFileName.SetName( SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
    destFileName = srcFileName;
    destFileName.AppendDir( backupFolder );
    destFileName.SetName( destFileName.GetName() + timeStamp );

    tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ),
                srcFileName.GetFullPath(), destFileName.GetFullPath() );
    aReporter.Report( tmp, REPORTER::RPT_INFO );

    if( wxFileName::Exists( srcFileName.GetFullPath() )
      && !wxCopyFile( srcFileName.GetFullPath(), destFileName.GetFullPath() ) )
    {
        tmp.Printf( _( "Failed to back up file \"%s\".\n" ), srcFileName.GetFullPath() );
        errorMsg += tmp;
    }

    // Back up the schematic files.
    for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
    {
        destFileName = screen->GetFileName();
        destFileName.SetName( destFileName.GetName() + timeStamp );

        // Check for nest hierarchical schematic paths.
        if( destFileName.GetPath() != backupPath.GetPath() )
        {
            destFileName.SetPath( backupPath.GetPath() );

            wxArrayString srcDirs = wxFileName( screen->GetFileName() ).GetDirs();
            wxArrayString destDirs = wxFileName( Prj().GetProjectPath() ).GetDirs();

            for( size_t i = destDirs.GetCount(); i < srcDirs.GetCount(); i++ )
                destFileName.AppendDir( srcDirs[i] );
        }
        else
        {
            destFileName.AppendDir( backupFolder );
        }

        tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ),
                    screen->GetFileName(), destFileName.GetFullPath() );
        aReporter.Report( tmp, REPORTER::RPT_INFO );

        if( !destFileName.DirExists() && !destFileName.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
        {
            tmp.Printf( _( "Failed to create backup folder \"%s\"\n" ), destFileName.GetPath() );
            errorMsg += tmp;
            continue;
        }

        if( wxFileName::Exists( screen->GetFileName() )
          && !wxCopyFile( screen->GetFileName(), destFileName.GetFullPath() ) )
        {
            tmp.Printf( _( "Failed to back up file \"%s\".\n" ), screen->GetFileName() );
            errorMsg += tmp;
        }
    }

    // Back up the project file.
    destFileName = Prj().GetProjectFullName();
    destFileName.SetName( destFileName.GetName() + timeStamp );
    destFileName.AppendDir( backupFolder );

    tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ),
                   Prj().GetProjectFullName(), destFileName.GetFullPath() );
    aReporter.Report( tmp, REPORTER::RPT_INFO );

    if( wxFileName::Exists( Prj().GetProjectFullName() )
      && !wxCopyFile( Prj().GetProjectFullName(), destFileName.GetFullPath() ) )
    {
        tmp.Printf( _( "Failed to back up file \"%s\".\n" ), Prj().GetProjectFullName() );
        errorMsg += tmp;
    }

    // Back up the cache library.
    srcFileName.SetPath( Prj().GetProjectPath() );
    srcFileName.SetName( Prj().GetProjectName() + "-cache" );
    srcFileName.SetExt( SchematicLibraryFileExtension );

    destFileName = srcFileName;
    destFileName.SetName( destFileName.GetName() + timeStamp );
    destFileName.AppendDir( backupFolder );

    tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ),
                srcFileName.GetFullPath(), destFileName.GetFullPath() );
    aReporter.Report( tmp, REPORTER::RPT_INFO );

    if( srcFileName.Exists()
      && !wxCopyFile( srcFileName.GetFullPath(), destFileName.GetFullPath() ) )
    {
        tmp.Printf( _( "Failed to back up file \"%s\".\n" ), srcFileName.GetFullPath() );
        errorMsg += tmp;
    }

    // Back up the rescue symbol library if it exists.
    srcFileName.SetName( Prj().GetProjectName() + "-rescue" );
    destFileName.SetName( srcFileName.GetName() + timeStamp );

    tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ),
                srcFileName.GetFullPath(), destFileName.GetFullPath() );
    aReporter.Report( tmp, REPORTER::RPT_INFO );

    if( srcFileName.Exists()
      && !wxCopyFile( srcFileName.GetFullPath(), destFileName.GetFullPath() ) )
    {
        tmp.Printf( _( "Failed to back up file \"%s\".\n" ), srcFileName.GetFullPath() );
        errorMsg += tmp;
    }

    // Back up the rescue symbol library document file if it exists.
    srcFileName.SetExt( "dcm" );
    destFileName.SetExt( srcFileName.GetExt() );

    tmp.Printf( _( "Backing up file \"%s\" to file \"%s\"." ),
                srcFileName.GetFullPath(), destFileName.GetFullPath() );
    aReporter.Report( tmp, REPORTER::RPT_INFO );

    if( srcFileName.Exists()
      && !wxCopyFile( srcFileName.GetFullPath(), destFileName.GetFullPath() ) )
    {
        tmp.Printf( _( "Failed to back up file \"%s\".\n" ), srcFileName.GetFullPath() );
        errorMsg += tmp;
    }

    if( !errorMsg.IsEmpty() )
    {
        wxMessageDialog dlg( this, _( "Some of the project files could not be backed up." ),
                             _( "Backup Error" ),
                             wxYES_NO | wxCENTRE | wxRESIZE_BORDER | wxICON_QUESTION );
        errorMsg.Trim();
        dlg.SetExtendedMessage( errorMsg );
        dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Continue with Rescue" ) ),
                            wxMessageDialog::ButtonLabel( _( "Abort Rescue" ) ) );

        if( dlg.ShowModal() == wxID_NO )
            return false;
    }

    return true;
}
bool DIALOG_PAGES_SETTINGS::SavePageSettings()
{
    bool success = false;

    wxString fileName = GetWksFileName();

    if( fileName != BASE_SCREEN::m_PageLayoutDescrFileName )
    {
        wxString fullFileName = WORKSHEET_LAYOUT::MakeFullFileName( fileName, m_projectPath );

        if( !fullFileName.IsEmpty() && !wxFileExists( fullFileName ) )
        {
            wxString msg;
            msg.Printf( _( "Page layout description file \"%s\" not found." ),
                        GetChars( fullFileName ) );
            wxMessageBox( msg );
            return false;
        }

        BASE_SCREEN::m_PageLayoutDescrFileName = fileName;
        WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
        pglayout.SetPageLayout( fullFileName );
        m_localPrjConfigChanged = true;
    }

    int idx = std::max( m_paperSizeComboBox->GetSelection(), 0 );
    const wxString paperType = m_pageFmt[idx];

    if( paperType.Contains( PAGE_INFO::Custom ) )
    {
        GetCustomSizeMilsFromDialog();

        success = m_pageInfo.SetType( PAGE_INFO::Custom );

        if( success )
        {
            PAGE_INFO::SetCustomWidthMils( m_layout_size.x );
            PAGE_INFO::SetCustomHeightMils( m_layout_size.y );

            m_pageInfo.SetWidthMils( m_layout_size.x );
            m_pageInfo.SetHeightMils( m_layout_size.y );
        }
    }
    else
    {
        // search for longest common string first, e.g. A4 before A
        if( paperType.Contains( PAGE_INFO::USLetter ) )
            success = m_pageInfo.SetType( PAGE_INFO::USLetter );
        else if( paperType.Contains( PAGE_INFO::USLegal ) )
            success = m_pageInfo.SetType( PAGE_INFO::USLegal );
        else if( paperType.Contains( PAGE_INFO::USLedger ) )
            success = m_pageInfo.SetType( PAGE_INFO::USLedger );
        else if( paperType.Contains( PAGE_INFO::GERBER ) )
            success = m_pageInfo.SetType( PAGE_INFO::GERBER );
        else if( paperType.Contains( PAGE_INFO::A4 ) )
            success = m_pageInfo.SetType( PAGE_INFO::A4 );
        else if( paperType.Contains( PAGE_INFO::A3 ) )
            success = m_pageInfo.SetType( PAGE_INFO::A3 );
        else if( paperType.Contains( PAGE_INFO::A2 ) )
            success = m_pageInfo.SetType( PAGE_INFO::A2 );
        else if( paperType.Contains( PAGE_INFO::A1 ) )
            success = m_pageInfo.SetType( PAGE_INFO::A1 );
        else if( paperType.Contains( PAGE_INFO::A0 ) )
            success = m_pageInfo.SetType( PAGE_INFO::A0 );
        else if( paperType.Contains( PAGE_INFO::A ) )
            success = m_pageInfo.SetType( PAGE_INFO::A );
        else if( paperType.Contains( PAGE_INFO::B ) )
            success = m_pageInfo.SetType( PAGE_INFO::B );
        else if( paperType.Contains( PAGE_INFO::C ) )
            success = m_pageInfo.SetType( PAGE_INFO::C );
        else if( paperType.Contains( PAGE_INFO::D ) )
            success = m_pageInfo.SetType( PAGE_INFO::D );
        else if( paperType.Contains( PAGE_INFO::E ) )
            success = m_pageInfo.SetType( PAGE_INFO::E );

        if( success )
        {
            int choice = m_orientationComboBox->GetSelection();
            m_pageInfo.SetPortrait( choice != 0 );
        }
    }

    if( !success )
    {
        wxASSERT_MSG( false, _( "the translation for paper size must preserve original spellings" ) );
        m_pageInfo.SetType( PAGE_INFO::A4 );
    }

    m_parent->SetPageSettings( m_pageInfo );

    m_tb.SetRevision( m_TextRevision->GetValue() );
    m_tb.SetDate(     m_TextDate->GetValue() );
    m_tb.SetCompany(  m_TextCompany->GetValue() );
    m_tb.SetTitle(    m_TextTitle->GetValue() );
    m_tb.SetComment1( m_TextComment1->GetValue() );
    m_tb.SetComment2( m_TextComment2->GetValue() );
    m_tb.SetComment3( m_TextComment3->GetValue() );
    m_tb.SetComment4( m_TextComment4->GetValue() );

    m_parent->SetTitleBlock( m_tb );


#ifdef EESCHEMA
    // Exports settings to other sheets if requested:
    SCH_SCREEN* screen;

    // Build the screen list
    SCH_SCREENS ScreenList;

    // Update title blocks for all screens
    for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
    {
        if( screen == m_screen )
            continue;

        TITLE_BLOCK tb2 = screen->GetTitleBlock();

        if( m_RevisionExport->IsChecked() )
            tb2.SetRevision( m_tb.GetRevision() );

        if( m_DateExport->IsChecked() )
            tb2.SetDate( m_tb.GetDate() );

        if( m_TitleExport->IsChecked() )
            tb2.SetTitle( m_tb.GetTitle() );

        if( m_CompanyExport->IsChecked() )
            tb2.SetCompany( m_tb.GetCompany() );

        if( m_Comment1Export->IsChecked() )
            tb2.SetComment1( m_tb.GetComment1() );

        if( m_Comment2Export->IsChecked() )
            tb2.SetComment2( m_tb.GetComment2() );

        if( m_Comment3Export->IsChecked() )
            tb2.SetComment3( m_tb.GetComment3() );

        if( m_Comment4Export->IsChecked() )
            tb2.SetComment4( m_tb.GetComment4() );

        screen->SetTitleBlock( tb2 );
    }

#endif

    return true;
}
Example #5
0
bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
{
    // implement the pseudo code from KIWAY_PLAYER.h:

    SCH_SCREENS screenList;

    // This is for python:
    if( aFileSet.size() != 1 )
    {
        UTF8 msg = StrPrintf( "Eeschema:%s() takes only a single filename", __func__ );
        DisplayError( this, msg );
        return false;
    }

    wxString    fullFileName( aFileSet[0] );

    // We insist on caller sending us an absolute path, if it does not, we say it's a bug.
    wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(),
        wxT( "bug in single_top.cpp or project manager." ) );

    if( !LockFile( fullFileName ) )
    {
        wxString msg = wxString::Format( _(
                "Schematic file '%s' is already open." ),
                GetChars( fullFileName )
                );
        DisplayError( this, msg );
        return false;
    }

    // save any currently open and modified project files.
    for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
    {
        if( screen->IsModify() )
        {
            int response = YesNoCancelDialog( this, _(
                "The current schematic has been modified.  Do you wish to save the changes?" ),
                wxEmptyString,
                _( "Save and Load" ),
                _( "Load Without Saving" )
                );

            if( response == wxID_CANCEL )
            {
                return false;
            }
            else if( response == wxID_YES )
            {
                wxCommandEvent dummy;
                OnSaveProject( dummy );
            }
            else
            {
                // response == wxID_NO, fall thru
            }
            break;
        }
    }

    wxFileName pro = fullFileName;
    pro.SetExt( ProjectFileExtension );

    bool is_new = !wxFileName::IsFileReadable( fullFileName );

    // If its a non-existent schematic and caller thinks it exists
    if( is_new && !( aCtl & KICTL_CREATE ) )
    {
        // notify user that fullFileName does not exist, ask if user wants to create it.
        wxString ask = wxString::Format( _(
                "Schematic '%s' does not exist.  Do you wish to create it?" ),
                GetChars( fullFileName )
                );
        if( !IsOK( this, ask ) )
            return false;
    }

    // unload current project file before loading new
    {
        delete g_RootSheet;
        g_RootSheet = NULL;

        CreateScreens();
    }

    GetScreen()->SetFileName( fullFileName );
    g_RootSheet->SetFileName( fullFileName );

    SetStatusText( wxEmptyString );
    ClearMsgPanel();

    wxString msg = wxString::Format( _(
            "Ready\nProject dir: '%s'\n" ),
            GetChars( wxPathOnly( Prj().GetProjectFullName() ) )
            );
    SetStatusText( msg );

    // PROJECT::SetProjectFullName() is an impactful function.  It should only be
    // called under carefully considered circumstances.

    // The calling code should know not to ask me here to change projects unless
    // it knows what consequences that will have on other KIFACEs running and using
    // this same PROJECT.  It can be very harmful if that calling code is stupid.
    Prj().SetProjectFullName( pro.GetFullPath() );

    LoadProjectFile();

    // load the libraries here, not in SCH_SCREEN::Draw() which is a context
    // that will not tolerate DisplayError() dialog since we're already in an
    // event handler in there.
    // And when a schematic file is loaded, we need these libs to initialize
    // some parameters (links to PART LIB, dangling ends ...)
    Prj().SchLibs();

    if( is_new )
    {
        // mark new, unsaved file as modified.
        GetScreen()->SetModify();
    }
    else
    {
        g_RootSheet->SetScreen( NULL );

        DBG( printf( "%s: loading schematic %s\n", __func__, TO_UTF8( fullFileName ) );)

        bool diag = g_RootSheet->Load( this );
        (void) diag;

        SetScreen( m_CurrentSheet->LastScreen() );

        GetScreen()->ClrModify();

        UpdateFileHistory( fullFileName );
    }
Example #6
0
void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item   = screen->GetCurItem();

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    // Allows block rotate operation on hot key.
    if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
    {
        if( aEvent.GetId() == ID_SCH_MIRROR_X )
        {
            m_canvas->MoveCursorToCrossHair();
            screen->m_BlockLocate.SetMessageBlock( this );
            screen->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
            HandleBlockEnd( &dc );
        }
        else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
        {
            m_canvas->MoveCursorToCrossHair();
            screen->m_BlockLocate.SetMessageBlock( this );
            screen->m_BlockLocate.SetCommand( BLOCK_MIRROR_Y );
            HandleBlockEnd( &dc );
        }
        else
        {
            wxFAIL_MSG( wxT( "Unknown block oriention command ID." ) );
        }

        return;
    }

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::OrientableItems,
                                  aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }


    switch( item->Type() )
    {
    case SCH_COMPONENT_T:
        if( aEvent.GetId() == ID_SCH_MIRROR_X )
            OrientComponent( CMP_MIRROR_X );
        else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
            OrientComponent( CMP_MIRROR_Y );
        else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL )
            OrientComponent( CMP_NORMAL );
        else
            wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) );

        break;

    case SCH_BITMAP_T:
        if( aEvent.GetId() == ID_SCH_MIRROR_X )
            MirrorImage( (SCH_BITMAP*) item, true );
        else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
            MirrorImage( (SCH_BITMAP*) item, false );

        break;

    default:
        wxFAIL_MSG( wxString::Format( wxT( "Schematic object type %s cannot be oriented." ),
                                      GetChars( item->GetClass() ) ) );
    }

    if( item->GetFlags() == 0 )
        screen->SetCurItem( NULL );
}
Example #7
0
bool SCH_EDIT_FRAME::LoadOneEEProject( const wxString& aFileName, bool aIsNew )
{
    SCH_SCREEN* screen;
    wxString    FullFileName, msg;
    bool        LibCacheExist = false;
    SCH_SCREENS ScreenList;

    for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() )
    {
        if( screen->IsModify() )
            break;
    }

    if( screen )
    {
        int response = YesNoCancelDialog( this, _( "The current schematic has been modified.  Do "
                                                   "you wish to save the changes?" ),
                                          wxEmptyString,
                                          _( "Save and Load" ), _( "Load Without Saving" ) );

        if( response == wxID_CANCEL )
        {
            return false;
        }
        else if( response == wxID_YES )
        {
            wxCommandEvent dummy;
            OnSaveProject( dummy );
        }
    }

    FullFileName = aFileName;

    if( FullFileName.IsEmpty() && !aIsNew )
    {
        wxFileDialog dlg( this, _( "Open Schematic" ), wxGetCwd(),
                          wxEmptyString, SchematicFileWildcard,
                          wxFD_OPEN | wxFD_FILE_MUST_EXIST );

        if( dlg.ShowModal() == wxID_CANCEL )
            return false;

        FullFileName = dlg.GetPath();
    }

    wxFileName fn = FullFileName;

    if( fn.IsRelative() )
    {
        fn.MakeAbsolute();
        FullFileName = fn.GetFullPath();
    }

    if( !wxGetApp().LockFile( FullFileName ) )
    {
        DisplayError( this, _( "This file is already open." ) );
        return false;
    }

    // Clear the screen before open a new file
    if( g_RootSheet )
    {
        delete g_RootSheet;
        g_RootSheet = NULL;
    }

    CreateScreens();
    screen = GetScreen();

    wxLogDebug( wxT( "Loading schematic " ) + FullFileName );
    wxSetWorkingDirectory( fn.GetPath() );

    screen->SetFileName( FullFileName );
    g_RootSheet->SetFileName( FullFileName );
    SetStatusText( wxEmptyString );
    ClearMsgPanel();

    screen->ClrModify();

    if( aIsNew )
    {
        /* SCH_SCREEN constructor does this now
        screen->SetPageSettings( PAGE_INFO( wxT( "A4" ) ) );
        */

        screen->SetZoom( 32 );
        screen->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId  );

        TITLE_BLOCK tb;
        wxString    title;

        title += NAMELESS_PROJECT;
        title += wxT( ".sch" );
        tb.SetTitle( title );
        screen->SetTitleBlock( tb );

        GetScreen()->SetFileName( title );

        LoadProjectFile( wxEmptyString, true );
        Zoom_Automatique( false );
        SetSheetNumberAndCount();
        m_canvas->Refresh();
        return true;
    }

    // Reloading configuration.
    msg.Printf( _( "Ready\nWorking dir: <%s>\n" ), GetChars( wxGetCwd() ) );
    PrintMsg( msg );

    LoadProjectFile( wxEmptyString, false );

    // Clear (if needed) the current active library in libedit because it could be
    // removed from memory
    LIB_EDIT_FRAME::EnsureActiveLibExists();

    // Delete old caches.
    CMP_LIBRARY::RemoveCacheLibrary();

    LibCacheExist = LoadCacheLibrary( g_RootSheet->GetScreen()->GetFileName() );

    if( !wxFileExists( g_RootSheet->GetScreen()->GetFileName() ) && !LibCacheExist )
    {
        Zoom_Automatique( false );
        msg.Printf( _( "File <%s> not found." ),
                    GetChars( g_RootSheet->GetScreen()->GetFileName() ) );
        DisplayInfoMessage( this, msg );
        return false;
    }

    // load the project.
    g_RootSheet->SetScreen( NULL );
    bool diag = g_RootSheet->Load( this );
    SetScreen( m_CurrentSheet->LastScreen() );

    UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() );

    /* Redraw base screen (ROOT) if necessary. */
    GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
    Zoom_Automatique( false );
    SetSheetNumberAndCount();
    m_canvas->Refresh( true );
    return diag;
}
/*
 * Hot keys. Some commands are relative to the item under the mouse cursor
 * Commands are case insensitive
 */
bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem )
{
    if( aHotKey == 0 )
        return false;

    wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );

    SCH_SCREEN* screen = GetScreen();

    // itemInEdit == false means no item currently edited. We can ask for editing a new item
    bool itemInEdit = screen->GetCurItem() && screen->GetCurItem()->GetFlags();

    // blocInProgress == false means no block in progress.
    // Because a drag command uses a drag block, false means also no drag in progress
    // If false, we can ask for editing a new item
    bool blocInProgress = screen->m_BlockLocate.GetState() != STATE_NO_BLOCK;

    // notBusy == true means no item currently edited and no other command in progress
    // We can change active tool and ask for editing a new item
    bool notBusy = (!itemInEdit) && (!blocInProgress);

    /* Convert lower to upper case (the usual toupper function has problem
     * with non ascii codes like function keys */
    if( (aHotKey >= 'a') && (aHotKey <= 'z') )
        aHotKey += 'A' - 'a';

    // Search command from key :
    EDA_HOTKEY* hotKey = GetDescriptorFromHotkey( aHotKey, common_Hotkey_List );

    if( hotKey == NULL )
        hotKey = GetDescriptorFromHotkey( aHotKey, schematic_Hotkey_List );

    if( hotKey == NULL )
        return false;

    switch( hotKey->m_Idcommand )
    {
    default:
    case HK_NOT_FOUND:
        return false;

    case HK_HELP:       // Display Current hotkey list
        DisplayHotkeyList( this, g_Schematic_Hokeys_Descr );
        break;

    case HK_RESET_LOCAL_COORD:         // Reset the relative coord
        GetScreen()->m_O_Curseur = GetCrossHairPosition();
        break;

    case ID_HOTKEY_HIGHLIGHT:
        if( notBusy )
            HighlightConnectionAtPosition( GetCrossHairPosition() );
        break;

    case HK_LEFT_CLICK:
    case HK_LEFT_DCLICK:    // Simulate a double left click: generate 2 events
        if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
        {
            GetCanvas()->SetAutoPanRequest( false );
            HandleBlockPlace( aDC );
        }
        else if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK )
        {
            OnLeftClick( aDC, aPosition );

            if( hotKey->m_Idcommand == HK_LEFT_DCLICK )
                OnLeftDClick( aDC, aPosition );
        }
        break;

    case HK_ZOOM_IN:
    case HK_ZOOM_OUT:
    case HK_ZOOM_REDRAW:
    case HK_ZOOM_CENTER:
    case HK_ZOOM_AUTO:
    case HK_ZOOM_SELECTION:
    case HK_MOVEBLOCK_TO_DRAGBLOCK:          // Switch to drag mode, when block moving
    case HK_SAVE_BLOCK:                      // Copy block to paste buffer.
        cmd.SetId( hotKey->m_IdMenuEvent );
        GetEventHandler()->ProcessEvent( cmd );
        break;

    case HK_DELETE:
        if( notBusy )
            DeleteItemAtCrossHair( aDC );
        break;

    case HK_REPEAT_LAST:
        if( notBusy )
            RepeatDrawItem( aDC );
        break;

    case HK_END_CURR_LINEWIREBUS:
        // this key terminates a new line/bus/wire in progress
        if( aItem && aItem->IsNew() &&
            aItem->Type() == SCH_LINE_T )
        {
            cmd.SetId( hotKey->m_IdMenuEvent );
            GetEventHandler()->ProcessEvent( cmd );
        }
        break;

    case HK_UNDO:             // Hot keys that map to command IDs that cannot be called
    case HK_REDO:             // while busy performing another command.
    case HK_FIND_ITEM:
    case HK_FIND_REPLACE:
    case HK_DELETE_NODE:
    case HK_LEAVE_SHEET:
        if( notBusy )
        {
            cmd.SetId( hotKey->m_IdMenuEvent );
            GetEventHandler()->ProcessEvent( cmd );
        }
        break;

    case HK_FIND_NEXT_ITEM:
    case HK_FIND_NEXT_DRC_MARKER:
        if( notBusy )
        {
            wxFindDialogEvent event( hotKey->m_IdMenuEvent, GetId() );
            event.SetEventObject( this );
            event.SetFlags( m_findReplaceData->GetFlags() );
            event.SetFindString( m_findReplaceData->GetFindString() );
            GetEventHandler()->ProcessEvent( event );
        }
        break;

    case HK_ADD_NEW_COMPONENT:      // Add component
    case HK_ADD_NEW_POWER:          // Add power component
    case HK_ADD_LABEL:
    case HK_ADD_HLABEL:
    case HK_ADD_GLABEL:
    case HK_ADD_JUNCTION:
    case HK_ADD_WIRE_ENTRY:
    case HK_ADD_BUS_ENTRY:
    case HK_ADD_HIER_SHEET:
    case HK_ADD_GRAPHIC_TEXT:
    case HK_ADD_GRAPHIC_POLYLINE:
    case HK_ADD_NOCONN_FLAG:        // Add a no connected flag
    case HK_BEGIN_BUS:
    case HK_BEGIN_WIRE:
        if( notBusy )
        {
            EDA_HOTKEY_CLIENT_DATA data( aPosition );
            cmd.SetInt( aHotKey );
            cmd.SetClientObject( &data );
            cmd.SetId( hotKey->m_IdMenuEvent );
            GetEventHandler()->ProcessEvent( cmd );
        }
        else if( aItem && aItem->IsNew() )
        {
            // If the item is a bus or a wire, a begin command is not possible.
            if( (GetToolId() == ID_BUS_BUTT) && (aItem->Type() == SCH_LINE_T) )
            {
                SCH_LINE* segment = (SCH_LINE*) aItem;

                if( segment->GetLayer() != LAYER_BUS )
                    break;

                // Bus in progress:
                OnLeftClick( aDC, aPosition );
            }
            else if( (GetToolId() == ID_WIRE_BUTT ) && (aItem->Type() == SCH_LINE_T) )
            {
                SCH_LINE* segment = (SCH_LINE*) aItem;

                if( segment->GetLayer() != LAYER_WIRE )
                    break;

                // Wire in progress:
                OnLeftClick( aDC, aPosition );
            }
        }
        break;

    case HK_COPY_COMPONENT_OR_LABEL:        // Duplicate component or text/label
        if( itemInEdit )
            break;

        if( aItem == NULL )
        {
            aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::CopyableItems );

            if( aItem == NULL )
                break;
        }

        cmd.SetId( hotKey->m_IdMenuEvent );
        wxPostEvent( this, cmd );
        break;

    case HK_DRAG:                           // Start drag
    case HK_MOVE_COMPONENT_OR_ITEM:         // Start move schematic item.
        if( ! notBusy )
            break;

        // Fall through
    case HK_EDIT:
        // Edit schematic item. Do not allow sheet edition when mowing
        // Because a sheet edition can be complex.
        if( itemInEdit && screen->GetCurItem()->Type() == SCH_SHEET_T )
                break;

        // Fall through
    case HK_EDIT_COMPONENT_VALUE:           // Edit component value field.
    case HK_EDIT_COMPONENT_REFERENCE:       // Edit component value reference.
    case HK_EDIT_COMPONENT_FOOTPRINT:       // Edit component footprint field.
    case HK_MIRROR_Y:                       // Mirror Y
    case HK_MIRROR_X:                       // Mirror X
    case HK_ORIENT_NORMAL_COMPONENT:        // Orient 0, no mirror (Component)
    case HK_ROTATE:                         // Rotate schematic item.
    case HK_EDIT_COMPONENT_WITH_LIBEDIT:    // Call Libedit and load the current component
    case HK_AUTOPLACE_FIELDS:               // Autoplace all fields around component
        {
            // force a new item search on hot keys at current position,
            // if there is no currently edited item,
            // to avoid using a previously selected item
            if( ! itemInEdit )
                screen->SetCurItem( NULL );
            EDA_HOTKEY_CLIENT_DATA data( aPosition );
            cmd.SetInt( hotKey->m_Idcommand );
            cmd.SetClientObject( &data );
            cmd.SetId( hotKey->m_IdMenuEvent );
            GetEventHandler()->ProcessEvent( cmd );
        }
        break;
    }

    // Hot key handled.
    return true;
}
Example #9
0
void LIB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
{
    wxRealPoint gridSize;
    SCH_SCREEN* screen = GetScreen();
    wxPoint     oldpos;
    wxPoint     pos = aPosition;

    // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
    // for next cursor position
    // ( shift or ctrl key down are PAN command with mouse wheel)
    bool snapToGrid = true;
    if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
        snapToGrid = false;

    // Cursor is left off grid only if no block in progress
    if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
        snapToGrid = true;

    if( snapToGrid )
        pos = screen->GetNearestGridPosition( pos );

    oldpos = screen->GetCrossHairPosition();
    gridSize = screen->GetGridSize();

    switch( aHotKey )
    {
    case 0:
        break;

    case WXK_NUMPAD8:
    case WXK_UP:
        pos.y -= KiROUND( gridSize.y );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD2:
    case WXK_DOWN:
        pos.y += KiROUND( gridSize.y );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD4:
    case WXK_LEFT:
        pos.x -= KiROUND( gridSize.x );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD6:
    case WXK_RIGHT:
        pos.x += KiROUND( gridSize.x );
        m_canvas->MoveCursor( pos );
        break;

    default:
        break;
    }

    // Update the cursor position.
    screen->SetCrossHairPosition( pos, snapToGrid );

    if( oldpos != screen->GetCrossHairPosition() )
    {
        pos = screen->GetCrossHairPosition();
        screen->SetCrossHairPosition( oldpos, false );
        m_canvas->CrossHairOff( aDC );
        screen->SetCrossHairPosition( pos, snapToGrid );
        m_canvas->CrossHairOn( aDC );

        if( m_canvas->IsMouseCaptured() )
        {
#ifdef USE_WX_OVERLAY
            wxDCOverlay oDC( m_overlay, (wxWindowDC*)aDC );
            oDC.Clear();
            m_canvas->CallMouseCapture( aDC, aPosition, false );
#else
            m_canvas->CallMouseCapture( aDC, aPosition, true );
#endif
        }
#ifdef USE_WX_OVERLAY
        else
        {
            m_overlay.Reset();
        }
#endif
    }

    if( aHotKey )
    {
        OnHotKey( aDC, aHotKey, aPosition, NULL );
    }

    UpdateStatusBar();
}
Example #10
0
/*
 * OnConvertTextType is a command event handler to change a text type to an other one.
 * The new text, label, hierarchical label, or global label is created from the old text
 * The old text is deleted.
 * A tricky case is when the 'old" text is being edited (i.e. moving)
 * because we must create a new text, and prepare the undo/redo command data for this
 * change and the current move/edit command
 */
void SCH_EDIT_FRAME::OnConvertTextType( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_TEXT* text = (SCH_TEXT*) screen->GetCurItem();

    wxCHECK_RET( (text != NULL) && text->CanIncrementLabel(),
                 wxT( "Cannot convert text type." ) );

    KICAD_T type;

    switch( aEvent.GetId() )
    {
    case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL:
        type = SCH_LABEL_T;
        break;

    case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL:
        type = SCH_GLOBAL_LABEL_T;
        break;

    case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL:
        type = SCH_HIERARCHICAL_LABEL_T;
        break;

    case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT:
        type = SCH_TEXT_T;
        break;

    default:
        wxFAIL_MSG( wxString::Format( wxT( "Invalid text type command ID %d." ),
                                      aEvent.GetId() ) );
        return;
    }

    if( text->Type() == type )
        return;

    SCH_TEXT* newtext;
    const wxPoint &position = text->GetPosition();
    const wxString &txt = text->GetText();

    switch( type )
    {
    case SCH_LABEL_T:
        newtext = new SCH_LABEL( position, txt );
        break;

    case SCH_GLOBAL_LABEL_T:
        newtext = new SCH_GLOBALLABEL( position, txt );
        break;

    case SCH_HIERARCHICAL_LABEL_T:
        newtext = new SCH_HIERLABEL( position, txt );
        break;

    case SCH_TEXT_T:
        newtext = new SCH_TEXT( position, txt );
        break;

    default:
        newtext = NULL;
        wxFAIL_MSG( wxString::Format( wxT( "Cannot convert text type to %d" ), type ) );
        return;
    }

    /* Copy the old text item settings to the new one.  Justifications are not copied because
     * they are not used in labels.  Justifications will be set to default value in the new
     * text item type.
     */
    newtext->SetFlags( text->GetFlags() );
    newtext->SetShape( text->GetShape() );
    newtext->SetOrientation( text->GetOrientation() );
    newtext->SetSize( text->GetSize() );
    newtext->SetThickness( text->GetThickness() );
    newtext->SetItalic( text->IsItalic() );
    newtext->SetBold( text->IsBold() );

    /* Save the new text in undo list if the old text was not itself a "new created text"
     * In this case, the old text is already in undo list as a deleted item.
     * Of course if the old text was a "new created text" the new text will be
     * put in undo list later, at the end of the current command (if not aborted)
     */

    INSTALL_UNBUFFERED_DC( dc, m_canvas );
    m_canvas->CrossHairOff( &dc );   // Erase schematic cursor
    text->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );

    // For an exiting item (i.e. already in list):
    // replace the existing item by the new text in list
    for( SCH_ITEM* item = screen->GetDrawItems(); item != NULL; item = item->Next() )
    {
        if( item == text )
        {
            screen->Remove( text );
            screen->Append( newtext );
            break;
        }
    }

    SetRepeatItem( NULL );
    OnModify();
    newtext->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
    m_canvas->CrossHairOn( &dc );    // redraw schematic cursor

    // if the old item is the current schematic item, replace it by the new text:
    if( screen->GetCurItem() == text )
        screen->SetCurItem( newtext );

    if( text->IsNew() )
    {
        // if the previous text is new, no undo command to prepare here
        // just delete this previous text.
        delete text;
        return;
    }

    // previous text is not new and we replace text by new text.
    // So this is equivalent to delete text and add newtext
    // If text if being currently edited (i.e. moved)
    // we also save the initial copy of text, and prepare undo command for new text modifications.
    // we must save it as modified text,if it is currently edited, then save as deleted text,
    // and replace text with newtext
    PICKED_ITEMS_LIST pickList;
    ITEM_PICKER picker( text, UR_CHANGED );

    if( text->GetFlags() )
    {
        // text is being edited, save initial text for undo command
        picker.SetLink( GetUndoItem() );
        pickList.PushItem( picker );

        // the owner of undoItem is no more "this", it is now "picker":
        SetUndoItem( NULL );

        // save current newtext copy for undo/abort current command
        SetUndoItem( newtext );
    }

    // Prepare undo command for delete old text
    picker.SetStatus( UR_DELETED );
    picker.SetLink( NULL );
    pickList.PushItem( picker );

    // Prepare undo command for new text
    picker.SetStatus( UR_NEW );
    picker.SetItem(newtext);
    pickList.PushItem( picker );

    SaveCopyInUndoList( pickList, UR_UNSPECIFIED );
}
void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef )
{
    SCH_SCREEN*     screen = m_parent->GetScreen();
    SCH_SHEET_PATH  oldsheetpath = m_parent->GetCurrentSheet();

    /* When printing all pages, the printed page is not the current page.
     *  In complex hierarchies, we must setup references and other parameters
     *  in the printed SCH_SCREEN
     *  because in complex hierarchies a SCH_SCREEN (a schematic drawings)
     *  is shared between many sheets
     */
    SCH_SHEET_LIST  sheetList;

    if( aPlotAll )
        sheetList.BuildSheetList( g_RootSheet );
    else
        sheetList.push_back( m_parent->GetCurrentSheet() );

    REPORTER& reporter = m_MessagesBox->Reporter();

    SetHPGLPenWidth();

    for( unsigned i = 0; i < sheetList.size(); i++ )
    {
        m_parent->SetCurrentSheet( sheetList[i] );
        m_parent->GetCurrentSheet().UpdateAllScreenReferences();
        m_parent->SetSheetNumberAndCount();

        screen = m_parent->GetCurrentSheet().LastScreen();

        if( !screen ) // LastScreen() may return NULL
            screen = m_parent->GetScreen();

        const PAGE_INFO&    curPage = screen->GetPageSettings();

        PAGE_INFO           plotPage = curPage;

        // if plotting on a page size other than curPage
        if( m_HPGLPaperSizeOption->GetSelection() != PAGE_DEFAULT )
            plotPage.SetType( plot_sheet_list( m_HPGLPaperSizeOption->GetSelection() ) );

        // Calculation of conversion scales.
        double  plot_scale = (double) plotPage.GetWidthMils() / curPage.GetWidthMils();

        // Calculate offsets
        wxPoint plotOffset;
        wxString msg;

        if( GetPlotOriginCenter() )
        {
            plotOffset.x    = plotPage.GetWidthIU() / 2;
            plotOffset.y    = -plotPage.GetHeightIU() / 2;
        }

        try
        {
            wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
            wxString ext = HPGL_PLOTTER::GetDefaultFileExtension();
            wxFileName plotFileName = createPlotFileName( m_outputDirectoryName, fname,
                                                          ext, &reporter );

            LOCALE_IO toggle;

            if( Plot_1_Page_HPGL( plotFileName.GetFullPath(), screen, plotPage, plotOffset,
                                  plot_scale, aPlotFrameRef ) )
            {
                msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
                reporter.Report( msg, REPORTER::RPT_ACTION );
            }
            else
            {
                msg.Printf( _( "Unable to create file '%s'.\n" ),
                            GetChars( plotFileName.GetFullPath() ) );
                reporter.Report( msg, REPORTER::RPT_ERROR );
            }
        }
        catch( IO_ERROR& e )
        {
            msg.Printf( wxT( "HPGL Plotter exception: %s"), GetChars( e.errorText ) );
            reporter.Report( msg, REPORTER::RPT_ERROR );
        }

    }

    m_parent->SetCurrentSheet( oldsheetpath );
    m_parent->GetCurrentSheet().UpdateAllScreenReferences();
    m_parent->SetSheetNumberAndCount();
}
Example #12
0
void SCH_SCREENS::TestDanglingEnds()
{
    for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
        screen->TestDanglingEnds();
}
Example #13
0
void SCH_SCREENS::UpdateSymbolLinks( bool aForce )
{
    for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
        screen->UpdateSymbolLinks( aForce );
}
Example #14
0
void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst,
               int aMinConn, int aDiag )
{
    SCH_MARKER*     marker = NULL;
    SCH_SCREEN*     screen;
    ELECTRICAL_PINTYPE ii, jj;

    if( aDiag == OK || aMinConn < 1 )
        return;

    /* Create new marker for ERC error. */
    marker = new SCH_MARKER();
    marker->SetTimeStamp( GetNewTimeStamp() );

    marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
    marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
    screen = aNetItemRef->m_SheetPath.LastScreen();
    screen->Append( marker );

    wxString msg;

    ii = aNetItemRef->m_ElectricalPinType;

    wxString cmp_ref( "?" );

    if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
        cmp_ref = aNetItemRef->GetComponentParent()->GetRef( &aNetItemRef->m_SheetPath );

    if( aNetItemTst == NULL )
    {
        if( aMinConn == NOD )    /* Nothing driving the net. */
        {
            if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
                cmp_ref = aNetItemRef->GetComponentParent()->GetRef(
                    &aNetItemRef->m_SheetPath );

            msg.Printf( _( "Pin %s (%s) of component %s is not driven (Net %d)." ),
                        aNetItemRef->m_PinNum,
                        GetChars( GetText( ii ) ),
                        GetChars( cmp_ref ),
                        aNetItemRef->GetNet() );
            marker->SetData( ERCE_PIN_NOT_DRIVEN,
                             aNetItemRef->m_Start,
                             msg,
                             aNetItemRef->m_Start );
            return;
        }
    }

    if( aNetItemTst )         /* Error between 2 pins */
    {
        jj = aNetItemTst->m_ElectricalPinType;
        int errortype = ERCE_PIN_TO_PIN_WARNING;

        if( aDiag == ERR )
        {
            marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR );
            errortype = ERCE_PIN_TO_PIN_ERROR;
        }

        wxString alt_cmp( "?" );

        if( aNetItemTst->m_Type == NET_PIN && aNetItemTst->m_Link )
            alt_cmp = aNetItemTst->GetComponentParent()->GetRef( &aNetItemTst->m_SheetPath );

        msg.Printf( _( "Pin %s (%s) of component %s is connected to " ),
                    aNetItemRef->m_PinNum,
                    GetChars( GetText( ii ) ),
                    GetChars( cmp_ref ) );
        marker->SetData( errortype, aNetItemRef->m_Start, msg, aNetItemRef->m_Start );
        msg.Printf( _( "pin %s (%s) of component %s (net %d)." ),
                    aNetItemTst->m_PinNum,
                    GetChars( GetText( jj ) ),
                    GetChars( alt_cmp ),
                    aNetItemRef->GetNet() );
        marker->SetAuxiliaryData( msg, aNetItemTst->m_Start );
    }
}
Example #15
0
void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM* item = screen->GetCurItem();

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        // Set the locat filter, according to the edit command
        const KICAD_T* filterList = SCH_COLLECTOR::EditableItems;
        const KICAD_T* filterListAux = NULL;

        switch( aEvent.GetId() )
        {
        case ID_SCH_EDIT_COMPONENT_REFERENCE:
            filterList = SCH_COLLECTOR::CmpFieldReferenceOnly;
            filterListAux = SCH_COLLECTOR::ComponentsOnly;
            break;

        case ID_SCH_EDIT_COMPONENT_VALUE:
            filterList = SCH_COLLECTOR::CmpFieldValueOnly;
            filterListAux = SCH_COLLECTOR::ComponentsOnly;
            break;

        case ID_SCH_EDIT_COMPONENT_FOOTPRINT:
            filterList = SCH_COLLECTOR::CmpFieldFootprintOnly;
            filterListAux = SCH_COLLECTOR::ComponentsOnly;
            break;

        default:
            break;
        }

        item = LocateAndShowItem( data->GetPosition(), filterList, aEvent.GetInt() );

        // If no item found, and if an auxiliary filter exists, try to use it
        if( !item && filterListAux )
            item = LocateAndShowItem( data->GetPosition(), filterListAux, aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }

    switch( item->Type() )
    {
    case SCH_COMPONENT_T:
    {
        switch( aEvent.GetId() )
        {
        case ID_SCH_EDIT_COMPONENT_REFERENCE:
            EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( REFERENCE ) );
            break;

        case ID_SCH_EDIT_COMPONENT_VALUE:
            EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( VALUE ) );
            break;

        case ID_SCH_EDIT_COMPONENT_FOOTPRINT:
            EditComponentFieldText( ( (SCH_COMPONENT*) item )->GetField( FOOTPRINT ) );
            break;

        case ID_SCH_EDIT_ITEM:
            EditComponent( (SCH_COMPONENT*) item );
            break;

        default:
            wxFAIL_MSG( wxString::Format( wxT( "Invalid schematic component edit command ID %d" ),
                                          aEvent.GetId() ) );
        }

        break;
    }

    case SCH_SHEET_T:
        EditSheet( (SCH_SHEET*) item, &dc );
        break;

    case SCH_SHEET_PIN_T:
        EditSheetPin( (SCH_SHEET_PIN*) item, &dc );
        break;

    case SCH_TEXT_T:
    case SCH_LABEL_T:
    case SCH_GLOBAL_LABEL_T:
    case SCH_HIERARCHICAL_LABEL_T:
        EditSchematicText( (SCH_TEXT*) item );
        break;

    case SCH_FIELD_T:
        EditComponentFieldText( (SCH_FIELD*) item );
        break;

    case SCH_BITMAP_T:
        EditImage( (SCH_BITMAP*) item );
        break;

    default:
        wxFAIL_MSG( wxString::Format( wxT( "Cannot edit schematic item type %s." ),
                                      GetChars( item->GetClass() ) ) );
    }

    if( item->GetFlags() == 0 )
        screen->SetCurItem( NULL );
}
Example #16
0
void LIB_VIEW_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
{
    wxRealPoint gridSize;
    SCH_SCREEN* screen = GetScreen();
    wxPoint     oldpos;
    wxPoint     pos = aPosition;

    pos = screen->GetNearestGridPosition( pos );
    oldpos = screen->GetCrossHairPosition();
    gridSize = screen->GetGridSize();

    switch( aHotKey )
    {
    case 0:
        break;

    case WXK_NUMPAD8:
    case WXK_UP:
        pos.y -= KiROUND( gridSize.y );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD2:
    case WXK_DOWN:
        pos.y += KiROUND( gridSize.y );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD4:
    case WXK_LEFT:
        pos.x -= KiROUND( gridSize.x );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD6:
    case WXK_RIGHT:
        pos.x += KiROUND( gridSize.x );
        m_canvas->MoveCursor( pos );
        break;

    default:
        break;
    }

    // Update cursor position.
    screen->SetCrossHairPosition( pos );

    if( oldpos != screen->GetCrossHairPosition() )
    {
        pos = screen->GetCrossHairPosition();
        screen->SetCrossHairPosition( oldpos );
        m_canvas->CrossHairOff( aDC );
        screen->SetCrossHairPosition( pos );
        m_canvas->CrossHairOn( aDC );

        if( m_canvas->IsMouseCaptured() )
        {
            m_canvas->CallMouseCapture( aDC, aPosition, true );
        }
    }

    if( aHotKey )
    {
        if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
            OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
        else
            OnHotKey( aDC, aHotKey, aPosition, NULL );
    }

    UpdateStatusBar();
}
Example #17
0
void SCH_EDIT_FRAME::OnDragItem( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM* item = screen->GetCurItem();

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::DraggableItems,
                                  aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }

    switch( item->Type() )
    {
    case SCH_BUS_BUS_ENTRY_T:
    case SCH_BUS_WIRE_ENTRY_T:
    case SCH_LINE_T:
    case SCH_JUNCTION_T:
        if( item->GetLayer() == LAYER_BUS )
            break;

        // Fall thru if item is not on bus layer.
    case SCH_COMPONENT_T:
    case SCH_LABEL_T:
    case SCH_GLOBAL_LABEL_T:
    case SCH_HIERARCHICAL_LABEL_T:
    case SCH_SHEET_T:
        m_canvas->MoveCursorToCrossHair();

        // The easiest way to handle a drag component or sheet command
        // is to simulate a block drag command
        if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK )
        {
            if( !HandleBlockBegin( &dc, BLOCK_DRAG, GetCrossHairPosition() ) )
                break;

            // Give a non null size to the search block:
            screen->m_BlockLocate.Inflate( 1 );
            HandleBlockEnd( &dc );
        }

        break;

    default:
        wxFAIL_MSG( wxString::Format( wxT( "Cannot drag schematic item type %s." ),
                                      GetChars( item->GetClass() ) ) );
    }
}
Example #18
0
File: erc.cpp Project: natsfr/kicad
void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst,
               int aMinConn, int aDiag )
{
    SCH_MARKER* marker = NULL;
    SCH_SCREEN* screen;
    int         ii, jj;

    if( aDiag == OK )
        return;

    /* Create new marker for ERC error. */
    marker = new SCH_MARKER();
    marker->SetTimeStamp( GetNewTimeStamp() );

    marker->SetMarkerType( MARK_ERC );
    marker->SetErrorLevel( WAR );
    screen = aNetItemRef->m_SheetPath.LastScreen();
    screen->Append( marker );

    wxString msg;

    if( aMinConn < 0 )
    {
        if( (aNetItemRef->m_Type == NET_HIERLABEL)
            || (aNetItemRef->m_Type == NET_HIERBUSLABELMEMBER) )
        {
            msg.Printf( _( "Hierarchical label %s is not connected to a sheet label." ),
                        GetChars( aNetItemRef->m_Label ) );
        }
        else
        {
            msg.Printf( _( "Sheet label %s is not connected to a hierarchical label." ),
                        GetChars( aNetItemRef->m_Label ) );
        }


        marker->SetData( ERCE_HIERACHICAL_LABEL,
                         aNetItemRef->m_Start,
                         msg,
                         aNetItemRef->m_Start );
        return;
    }

    ii = aNetItemRef->m_ElectricalType;

    wxString string_pinnum, cmp_ref;
    char     ascii_buf[5];
    ascii_buf[4] = 0;
    memcpy( ascii_buf, &aNetItemRef->m_PinNum, 4 );
    string_pinnum = FROM_UTF8( ascii_buf );
    cmp_ref = wxT( "?" );

    if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
        cmp_ref = aNetItemRef->GetComponentParent()->GetRef( &aNetItemRef->m_SheetPath );

    if( aNetItemTst == NULL )
    {
        if( aMinConn == NOC )    /* Only 1 element in the net. */
        {
            msg.Printf( _( "Pin %s (%s) of component %s is unconnected." ),
                        GetChars( string_pinnum ), MsgPinElectricType[ii], GetChars( cmp_ref ) );
            marker->SetData( ERCE_PIN_NOT_CONNECTED,
                             aNetItemRef->m_Start,
                             msg,
                             aNetItemRef->m_Start );
            return;
        }

        if( aMinConn == NOD )    /* Nothing driving the net. */
        {
            if( aNetItemRef->m_Type == NET_PIN && aNetItemRef->m_Link )
                cmp_ref = aNetItemRef->GetComponentParent()->GetRef(
                    &aNetItemRef->m_SheetPath );

            msg.Printf( _( "Pin %s (%s) of component %s is not driven (Net %d)." ),
                        GetChars( string_pinnum ), MsgPinElectricType[ii], GetChars( cmp_ref ),
                        aNetItemRef->GetNet() );
            marker->SetData( ERCE_PIN_NOT_DRIVEN,
                             aNetItemRef->m_Start,
                             msg,
                             aNetItemRef->m_Start );
            return;
        }

        if( aDiag == UNC )
        {
            msg.Printf( _( "More than 1 pin connected to an UnConnect symbol." ) );
            marker->SetData( ERCE_NOCONNECT_CONNECTED,
                             aNetItemRef->m_Start,
                             msg,
                             aNetItemRef->m_Start );
            return;
        }
    }

    if( aNetItemTst )         /* Error between 2 pins */
    {
        jj = aNetItemTst->m_ElectricalType;
        int errortype = ERCE_PIN_TO_PIN_WARNING;

        if( aDiag == ERR )
        {
            marker->SetErrorLevel( ERR );
            errortype = ERCE_PIN_TO_PIN_ERROR;
        }

        wxString alt_string_pinnum, alt_cmp;
        memcpy( ascii_buf, &aNetItemTst->m_PinNum, 4 );
        alt_string_pinnum = FROM_UTF8( ascii_buf );
        alt_cmp = wxT( "?" );

        if( aNetItemTst->m_Type == NET_PIN && aNetItemTst->m_Link )
            alt_cmp = aNetItemTst->GetComponentParent()->GetRef( &aNetItemTst->m_SheetPath );

        msg.Printf( _( "Pin %s (%s) of component %s is connected to " ),
                    GetChars( string_pinnum ), MsgPinElectricType[ii], GetChars( cmp_ref ) );
        marker->SetData( errortype, aNetItemRef->m_Start, msg, aNetItemRef->m_Start );
        msg.Printf( _( "pin %s (%s) of component %s (net %d)." ),
                    GetChars( alt_string_pinnum ), MsgPinElectricType[jj], GetChars( alt_cmp ),
                    aNetItemRef->GetNet() );
        marker->SetAuxiliaryData( msg, aNetItemTst->m_Start );
    }
}
void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef )
{
    SCH_SCREEN*     screen = m_parent->GetScreen();
    SCH_SHEET_PATH  oldsheetpath = m_parent->GetCurrentSheet();  // sheetpath is saved here
    PAGE_INFO       actualPage;                                  // page size selected in schematic
    PAGE_INFO       plotPage;                                    // page size selected to plot

    /* When printing all pages, the printed page is not the current page.
     * In complex hierarchies, we must update component references
     *  and others parameters in the given printed SCH_SCREEN, accordint to the sheet path
     *  because in complex hierarchies a SCH_SCREEN (a drawing )
     *  is shared between many sheets and component references depend on the actual sheet path used
     */
    SCH_SHEET_LIST  sheetList;

    if( aPlotAll )
        sheetList.BuildSheetList( g_RootSheet );
    else
        sheetList.push_back( m_parent->GetCurrentSheet() );

    for( unsigned i = 0; i < sheetList.size(); i++ )
    {
        m_parent->SetCurrentSheet( sheetList[i] );
        m_parent->GetCurrentSheet().UpdateAllScreenReferences();
        m_parent->SetSheetNumberAndCount();
        screen = m_parent->GetCurrentSheet().LastScreen();
        actualPage = screen->GetPageSettings();

        switch( m_pageSizeSelect )
        {
        case PAGE_SIZE_A:
            plotPage.SetType( wxT( "A" ) );
            plotPage.SetPortrait( actualPage.IsPortrait() );
            break;

        case PAGE_SIZE_A4:
            plotPage.SetType( wxT( "A4" ) );
            plotPage.SetPortrait( actualPage.IsPortrait() );
            break;

        case PAGE_SIZE_AUTO:
        default:
            plotPage = actualPage;
            break;
        }

        double  scalex  = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
        double  scaley  = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();

        double  scale = std::min( scalex, scaley );

        wxPoint plot_offset;

        wxString outputDirName = m_outputDirectoryName->GetValue();

        wxString msg;
        REPORTER& reporter = m_MessagesBox->Reporter();

        try
        {
            wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
            wxString ext = PS_PLOTTER::GetDefaultFileExtension();
            wxFileName plotFileName = createPlotFileName( m_outputDirectoryName,
                                                          fname, ext, &reporter );

            if( plotOneSheetPS( plotFileName.GetFullPath(), screen, plotPage, plot_offset,
                                scale, aPlotFrameRef ) )
            {
                msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
                reporter.Report( msg, REPORTER::RPT_ACTION );
            }
            else
            {
                // Error
                msg.Printf( _( "Unable to create file '%s'.\n" ),
                            GetChars( plotFileName.GetFullPath() ) );
                reporter.Report( msg, REPORTER::RPT_ERROR );
            }

        }
        catch( IO_ERROR& e )
        {
            msg.Printf( wxT( "PS Plotter exception: %s"), GetChars( e.errorText ) );
            reporter.Report( msg, REPORTER::RPT_ERROR );
        }
    }

    m_parent->SetCurrentSheet( oldsheetpath );
    m_parent->GetCurrentSheet().UpdateAllScreenReferences();
    m_parent->SetSheetNumberAndCount();
}
void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
{
    wxFileName fn;

    m_writeErcFile = m_WriteResultOpt->GetValue();
    m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue();
    m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue();

    // Build the whole sheet list in hierarchy (sheet, not screen)
    SCH_SHEET_LIST sheets;
    sheets.AnnotatePowerSymbols( Prj().SchLibs() );

    if( m_parent->CheckAnnotate( aMessagesList, false ) )
    {
        if( aMessagesList )
        {
            wxString msg = _( "Annotation required!" );
            msg += wxT( "\n" );
            aMessagesList->Add( msg );
        }

        return;
    }

    SCH_SCREENS screens;

    // Erase all previous DRC markers.
    screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC );

    for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
    {
        /* Ff wire list has changed, delete Undo Redo list to avoid pointers on deleted
         * data problems.
         */
        if( screen->SchematicCleanUp( NULL ) )
            screen->ClearUndoRedoList();
    }

    /* Test duplicate sheet names inside a given sheet, one cannot have sheets with
     * duplicate names (file names can be duplicated).
     */
    TestDuplicateSheetNames( true );

    std::auto_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( m_parent->BuildNetListBase() );

    // Reset the connection type indicator
    objectsConnectedList->ResetConnectionsType();

    unsigned lastNet;
    unsigned nextNet = lastNet = 0;
    int MinConn    = NOC;

    for( unsigned net = 0; net < objectsConnectedList->size(); net++ )
    {
        if( objectsConnectedList->GetItemNet( lastNet ) !=
            objectsConnectedList->GetItemNet( net ) )
        {
            // New net found:
            MinConn    = NOC;
            nextNet   = net;
        }

        switch( objectsConnectedList->GetItemType( net ) )
        {
        // These items do not create erc problems
        case NET_ITEM_UNSPECIFIED:
        case NET_SEGMENT:
        case NET_BUS:
        case NET_JUNCTION:
        case NET_LABEL:
        case NET_BUSLABELMEMBER:
        case NET_PINLABEL:
        case NET_GLOBBUSLABELMEMBER:
            break;

        case NET_HIERLABEL:
        case NET_HIERBUSLABELMEMBER:
        case NET_SHEETLABEL:
        case NET_SHEETBUSLABELMEMBER:
            // ERC problems when pin sheets do not match hierarchical labels.
            // Each pin sheet must match a hierarchical label
            // Each hierarchical label must match a pin sheet
            objectsConnectedList->TestforNonOrphanLabel( net, nextNet );
            break;
        case NET_GLOBLABEL:
            if( m_tstUniqueGlobalLabels )
                objectsConnectedList->TestforNonOrphanLabel( net, nextNet );
            break;

        case NET_NOCONNECT:

            // ERC problems when a noconnect symbol is connected to more than one pin.
            MinConn = NET_NC;

            if( objectsConnectedList->CountPinsInNet( nextNet ) > 1 )
                Diagnose( objectsConnectedList->GetItem( net ), NULL, MinConn, UNC );

            break;

        case NET_PIN:

            // Look for ERC problems between pins:
            TestOthersItems( objectsConnectedList.get(), net, nextNet, &MinConn );
            break;
        }

        lastNet = net;
    }

    // Test similar labels (i;e. labels which are identical when
    // using case insensitive comparisons)
    if( m_TestSimilarLabels )
        objectsConnectedList->TestforSimilarLabels();

    // Displays global results:
    updateMarkerCounts( &screens );

    // Display diags:
    DisplayERC_MarkersList();

    // Display new markers:
    m_parent->GetCanvas()->Refresh();

    if( m_writeErcFile )
    {
        fn = g_RootSheet->GetScreen()->GetFileName();
        fn.SetExt( wxT( "erc" ) );

        wxFileDialog dlg( this, _( "ERC File" ), fn.GetPath(), fn.GetFullName(),
                          _( "Electronic rule check file (.erc)|*.erc" ),
                          wxFD_SAVE );

        if( dlg.ShowModal() == wxID_CANCEL )
            return;

        if( WriteDiagnosticERC( dlg.GetPath() ) )
        {
            Close( true );
            ExecuteFile( this, Pgm().GetEditorName(), QuoteFullPath( fn ) );
        }
    }
}
Example #21
0
bool SCH_EDIT_FRAME::AppendOneEEProject()
{
    SCH_SCREEN* screen;
    wxString    FullFileName;
    wxString msg;

    screen = GetScreen();

    if( !screen )
    {
        wxLogError( wxT("Document not ready, cannot import") );
        return false;
    }

    // open file chooser dialog
    wxFileDialog dlg( this, _( "Import Schematic" ), wxGetCwd(),
                      wxEmptyString, SchematicFileWildcard,
                      wxFD_OPEN | wxFD_FILE_MUST_EXIST );

    if( dlg.ShowModal() == wxID_CANCEL )
        return false;

    FullFileName = dlg.GetPath();

    wxFileName fn = FullFileName;

    if( fn.IsRelative() )
    {
        fn.MakeAbsolute();
        FullFileName = fn.GetFullPath();
    }

    LoadCacheLibrary( FullFileName );

    wxLogDebug( wxT( "Importing schematic " ) + FullFileName );

    // load the project
    bool success = LoadOneEEFile( screen, FullFileName, true );
    if( success )
    {
        // load sub-sheets
        EDA_ITEM* bs = screen->GetDrawItems();
        while( bs )
        {
            // do not append hierarchical sheets
            if( bs->Type() ==  SCH_SHEET_T )
            {
                screen->Remove( (SCH_SHEET*) bs );
            }
            // clear annotation and init new time stamp for the new components
            else if( bs->Type() == SCH_COMPONENT_T )
            {
                ( (SCH_COMPONENT*) bs )->SetTimeStamp( GetNewTimeStamp() );
                ( (SCH_COMPONENT*) bs )->ClearAnnotation( NULL );
                // Clear flags, which are set by these previous modifications:
                bs->ClearFlags();
            }

            bs = bs->Next();
        }
    }

    // redraw base screen (ROOT) if necessary
    GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
    Zoom_Automatique( false );
    SetSheetNumberAndCount();
    m_canvas->Refresh( true );
    return success;
}
Example #22
0
bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName )
{
    SCH_SCREENS     screens;
    PART_LIBS*      libs = Prj().SchLibs();

    std::unique_ptr<PART_LIB> libCache( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) );

    libCache->SetCache();

    /* examine all screens (not sheets) used and build the list of components
     * found in lib.
     * Complex hierarchies are not a problem because we just want
     * to know used components in libraries
     */
    for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
    {
        for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
        {
            if( item->Type() != SCH_COMPONENT_T )
                continue;

            SCH_COMPONENT* component = (SCH_COMPONENT*) item;

            // If not already saved in the new cache, put it:
            if( !libCache->FindEntry( component->GetPartName() ) )
            {
                if( LIB_PART* part = libs->FindLibPart( component->GetPartName() ) )
                {
                    // AddPart() does first clone the part before adding.
                    libCache->AddPart( part );
                }
            }
        }
    }

    try
    {
        FILE_OUTPUTFORMATTER    formatter( aFileName );

        if( !libCache->Save( formatter ) )
        {
            wxString msg = wxString::Format( _(
                "An error occurred attempting to save component library '%s'." ),
                GetChars( aFileName )
                );
            DisplayError( this, msg );
            return false;
        }
    }
    catch( ... /* IO_ERROR ioe */ )
    {
        wxString msg = wxString::Format( _(
            "Failed to create component library file '%s'" ),
            GetChars( aFileName )
            );
        DisplayError( this, msg );
        return false;
    }

    return true;
}
Example #23
0
void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef )
{
    wxString    msg;

    if( aPrintAll )
    {
        SCH_SHEET_PATH* sheetpath;
        SCH_SHEET_PATH  oldsheetpath    = m_parent->GetCurrentSheet();
        SCH_SHEET_LIST  SheetList( NULL );
        sheetpath = SheetList.GetFirst();
        SCH_SHEET_PATH  list;
        WX_TEXT_CTRL_REPORTER reporter(m_MessagesBox);

        for( ; ; )
        {
            if( sheetpath == NULL )
            {
                break;
            }

            SCH_SCREEN*  screen;
            list.Clear();

            if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) )
            {
                m_parent->SetCurrentSheet( list );
                m_parent->GetCurrentSheet().UpdateAllScreenReferences();
                m_parent->SetSheetNumberAndCount();
                screen = m_parent->GetCurrentSheet().LastScreen();
            }
            else // Should not happen
            {
                return;
            }

            sheetpath = SheetList.GetNext();

            try
            {
                wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
                wxString ext = SVG_PLOTTER::GetDefaultFileExtension();
                wxFileName plotFileName = createPlotFileName( m_outputDirectoryName,
                                          fname, ext, &reporter );

                bool success = plotOneSheetSVG( m_parent, plotFileName.GetFullPath(), screen,
                                                getModeColor() ? false : true,
                                                aPrintFrameRef );

                if( !success )
                {
                    msg.Printf( _( "Error creating file '%s'\n" ),
                                GetChars( plotFileName.GetFullPath() ) );
                }
                else
                {
                    msg.Printf( _( "File '%s' OK\n" ),
                                GetChars( plotFileName.GetFullPath() ) );
                }

                m_MessagesBox->AppendText( msg );
            }
            catch( const IO_ERROR& e )
            {
                // Cannot plot SVG file
                msg.Printf( wxT( "SVG Plotter Exception : '%s'" ), GetChars( e.errorText ) );
                m_MessagesBox->AppendText( msg );

                m_parent->SetCurrentSheet( oldsheetpath );
                m_parent->GetCurrentSheet().UpdateAllScreenReferences();
                m_parent->SetSheetNumberAndCount();
                return;
            }
        }

        m_parent->SetCurrentSheet( oldsheetpath );
        m_parent->GetCurrentSheet().UpdateAllScreenReferences();
        m_parent->SetSheetNumberAndCount();
    }
    else    // Print current sheet
    {
        SCH_SCREEN* screen = (SCH_SCREEN*) m_parent->GetScreen();

        try
        {
            wxString fname = screen->GetFileName();
            wxString ext = SVG_PLOTTER::GetDefaultFileExtension();
            wxFileName fn = createPlotFileName( m_outputDirectoryName, fname, ext );

            bool success = plotOneSheetSVG( m_parent, fn.GetFullPath(), screen,
                                            getModeColor() ? false : true,
                                            aPrintFrameRef );
            if( success )
            {
                msg.Printf( _( "Plot: <%s> OK\n" ),
                            GetChars( fn.GetFullPath() ) );
            }
            else    // Error
            {
                msg.Printf( _( "Unable to create <%s>\n" ),
                            GetChars( fn.GetFullPath() ) );
            }
            m_MessagesBox->AppendText( msg );
        }
        catch( const IO_ERROR& e )
        {
            // Cannot plot SVG file
            msg.Printf( wxT( "SVG Plotter Exception : <%s>"), GetChars( e.errorText ) );
            m_MessagesBox->AppendText( msg );
            return;
        }
    }
}
Example #24
0
void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item = screen->GetCurItem();

    if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
    {
        // trying to move an item when there is a block at the same time is not acceptable
        return;
    }

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::MovableItems,
                                  aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    switch( item->Type() )
    {
    case SCH_LINE_T:
        break;

    case SCH_JUNCTION_T:
    case SCH_NO_CONNECT_T:
    case SCH_BUS_BUS_ENTRY_T:
    case SCH_BUS_WIRE_ENTRY_T:
    case SCH_LABEL_T:
    case SCH_GLOBAL_LABEL_T:
    case SCH_HIERARCHICAL_LABEL_T:
    case SCH_TEXT_T:
    case SCH_COMPONENT_T:
    case SCH_SHEET_PIN_T:
    case SCH_FIELD_T:
        MoveItem( item, &dc );
        break;

    case SCH_BITMAP_T:
        MoveImage( (SCH_BITMAP*) item, &dc );
        break;

    case SCH_SHEET_T:
        StartMoveSheet( (SCH_SHEET*) item, &dc );
        break;

    case SCH_MARKER_T:
    default:
        wxFAIL_MSG( wxString::Format( wxT( "Cannot move item type %s" ),
                                      GetChars( item->GetClass() ) ) );
        break;
    }

    if( GetToolId() == ID_NO_TOOL_SELECTED )
        SetRepeatItem( NULL );
}
Example #25
0
bool SCH_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
{
    // Filter out the 'fake' mouse motion after a keyboard movement
    if( !aHotKey && m_movingCursorWithKeyboard )
    {
        m_movingCursorWithKeyboard = false;
        return false;
    }

    // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
    // for next cursor position
    // ( shift or ctrl key down are PAN command with mouse wheel)
    bool snapToGrid = true;

    if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
        snapToGrid = false;

    // Cursor is left off grid only if no block in progress
    if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
        snapToGrid = true;

    wxPoint pos = aPosition;
    bool keyHandled = GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );

    if( GetToolId() == ID_NO_TOOL_SELECTED )
        m_canvas->CrossHairOff( aDC );
    else
        m_canvas->CrossHairOn( aDC );

    GetGalCanvas()->GetViewControls()->SetSnapping( snapToGrid );
    SetCrossHairPosition( pos, snapToGrid );

    if( m_canvas->IsMouseCaptured() )
        m_canvas->CallMouseCapture( aDC, aPosition, true );

    if( aHotKey )
    {
        if( m_movingCursorWithKeyboard )    // The hotkey was a move crossahir cursor command
        {
            // The crossair was moved. move the mouse cursor to the new crosshair position:
            GetGalCanvas()->GetViewControls()->WarpCursor( GetCrossHairPosition(), true );
            m_movingCursorWithKeyboard = 0;
        }
        else
        {
            SCH_SCREEN* screen = GetScreen();
            bool hk_handled;

            if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
                hk_handled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
            else
                hk_handled = OnHotKey( aDC, aHotKey, aPosition, NULL );

            if( hk_handled )
                keyHandled = true;
        }
    }

    UpdateStatusBar();    /* Display cursor coordinates info */

    return keyHandled;
}
Example #26
0
void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
    int         id = event.GetId();
    wxPoint     pos;
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item = screen->GetCurItem();

    pos = wxGetMousePosition();

    pos.y += 20;

    // If needed, stop the current command and deselect current tool
    switch( id )
    {
    case wxID_CUT:
    case wxID_COPY:
    case ID_POPUP_CANCEL_CURRENT_COMMAND:
    case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
    case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH:
    case ID_POPUP_SCH_BEGIN_WIRE:
    case ID_POPUP_SCH_BEGIN_BUS:
    case ID_POPUP_END_LINE:
    case ID_POPUP_SCH_SET_SHAPE_TEXT:
    case ID_POPUP_SCH_CLEANUP_SHEET:
    case ID_POPUP_SCH_END_SHEET:
    case ID_POPUP_SCH_RESIZE_SHEET:
    case ID_POPUP_IMPORT_GLABEL:
    case ID_POPUP_SCH_INIT_CMP:
    case ID_POPUP_SCH_DISPLAYDOC_CMP:
    case ID_POPUP_SCH_EDIT_CONVERT_CMP:
    case ID_POPUP_DELETE_BLOCK:
    case ID_POPUP_PLACE_BLOCK:
    case ID_POPUP_ZOOM_BLOCK:
    case ID_POPUP_DRAG_BLOCK:
    case ID_POPUP_COPY_BLOCK:
    case ID_POPUP_SCH_DELETE_NODE:
    case ID_POPUP_SCH_DELETE_CONNECTION:
    case ID_POPUP_SCH_ENTER_SHEET:
    case ID_POPUP_SCH_LEAVE_SHEET:
    case ID_POPUP_SCH_ADD_JUNCTION:
    case ID_POPUP_SCH_ADD_LABEL:
    case ID_POPUP_SCH_GETINFO_MARKER:

        /* At this point: Do nothing. these commands do not need to stop the
         * current command (mainly a block command) or reset the current state
         * They will be executed later, in next switch structure.
         */
        break;

    case ID_POPUP_SCH_DELETE_CMP:
    case ID_POPUP_SCH_DELETE:

        // Stop the current command (if any) but keep the current tool
        m_canvas->EndMouseCapture();
        break;

    default:

        // Stop the current command and deselect the current tool
        m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
        break;
    }

    INSTALL_UNBUFFERED_DC( dc, m_canvas );
    item = screen->GetCurItem();    // Can be modified by previous calls.

    switch( id )
    {
    case ID_HIERARCHY:
        InstallHierarchyFrame( &dc, pos );
        SetRepeatItem( NULL );
        break;

    case wxID_CUT:
        if( screen->m_BlockLocate.GetCommand() != BLOCK_MOVE )
            break;

        screen->m_BlockLocate.SetCommand( BLOCK_DELETE );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        SetRepeatItem( NULL );
        SetSheetNumberAndCount();
        break;

    case wxID_PASTE:
        HandleBlockBegin( &dc, BLOCK_PASTE, GetCrossHairPosition() );
        break;

    case ID_POPUP_SCH_ENTRY_SELECT_SLASH:
        m_canvas->MoveCursorToCrossHair();
        SetBusEntryShape( &dc, dynamic_cast<SCH_BUS_ENTRY_BASE*>( item ), '/' );
        break;

    case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH:
        m_canvas->MoveCursorToCrossHair();
        SetBusEntryShape( &dc, dynamic_cast<SCH_BUS_ENTRY_BASE*>( item ), '\\' );
        break;

    case ID_POPUP_CANCEL_CURRENT_COMMAND:
        if( m_canvas->IsMouseCaptured() )
        {
            m_canvas->EndMouseCapture();
            SetToolID( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString );
        }
        else
        {
            SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
        }

        break;

    case ID_POPUP_END_LINE:
        m_canvas->MoveCursorToCrossHair();
        EndSegment( &dc );
        break;

    case ID_POPUP_SCH_BEGIN_WIRE:
        m_canvas->MoveCursorToCrossHair();
        OnLeftClick( &dc, GetCrossHairPosition() );
        break;

    case ID_POPUP_SCH_BEGIN_BUS:
        m_canvas->MoveCursorToCrossHair();
        OnLeftClick( &dc, GetCrossHairPosition() );
        break;

    case ID_POPUP_SCH_SET_SHAPE_TEXT:
        // Not used
        break;

    case ID_POPUP_SCH_DELETE_NODE:
    case ID_POPUP_SCH_DELETE_CONNECTION:
        m_canvas->MoveCursorToCrossHair();
        DeleteConnection( id == ID_POPUP_SCH_DELETE_CONNECTION );
        screen->SetCurItem( NULL );
        SetRepeatItem( NULL );
        screen->TestDanglingEnds( m_canvas, &dc );
        m_canvas->Refresh();
        break;

    case ID_POPUP_SCH_BREAK_WIRE:
    {
        DLIST< SCH_ITEM > oldWires;

        oldWires.SetOwnership( false );      // Prevent DLIST for deleting items in destructor.
        m_canvas->MoveCursorToCrossHair();
        screen->ExtractWires( oldWires, true );
        screen->BreakSegment( GetCrossHairPosition() );

        if( oldWires.GetCount() != 0 )
        {
            PICKED_ITEMS_LIST oldItems;

            oldItems.m_Status = UR_WIRE_IMAGE;

            while( oldWires.GetCount() != 0 )
            {
                ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
                oldItems.PushItem( picker );
            }

            SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
        }

        screen->TestDanglingEnds( m_canvas, &dc );
    }
    break;

    case ID_POPUP_SCH_DELETE_CMP:
    case ID_POPUP_SCH_DELETE:
        if( item == NULL )
            break;

        DeleteItem( item );
        screen->SetCurItem( NULL );
        SetRepeatItem( NULL );
        screen->TestDanglingEnds( m_canvas, &dc );
        SetSheetNumberAndCount();
        OnModify();
        break;

    case ID_POPUP_SCH_END_SHEET:
        m_canvas->MoveCursorToCrossHair();
        addCurrentItemToList( &dc );
        break;

    case ID_POPUP_SCH_RESIZE_SHEET:
        ReSizeSheet( (SCH_SHEET*) item, &dc );
        screen->TestDanglingEnds( m_canvas, &dc );
        break;

    case ID_POPUP_IMPORT_GLABEL:
        if( item != NULL && item->Type() == SCH_SHEET_T )
            screen->SetCurItem( ImportSheetPin( (SCH_SHEET*) item, &dc ) );
        break;

    case ID_POPUP_SCH_CLEANUP_SHEET:
        if( item != NULL && item->Type() == SCH_SHEET_T )
        {
            SCH_SHEET* sheet = (SCH_SHEET*) item;

            if( !sheet->HasUndefinedPins() )
            {
                DisplayInfoMessage( this,
                                    _( "There are no undefined labels in this sheet to clean up." ) );
                return;
            }

            if( !IsOK( this, _( "Do you wish to cleanup this sheet?" ) ) )
                return;

            /* Save sheet in undo list before cleaning up unreferenced hierarchical labels. */
            SaveCopyInUndoList( sheet, UR_CHANGED );
            sheet->CleanupSheet();
            OnModify();
            m_canvas->RefreshDrawingRect( sheet->GetBoundingBox() );
        }
        break;

    case ID_POPUP_SCH_INIT_CMP:
        m_canvas->MoveCursorToCrossHair();
        break;

    case ID_POPUP_SCH_EDIT_CONVERT_CMP:

        // Ensure the struct is a component (could be a struct of a component, like Field, text..)
        if( item && item->Type() == SCH_COMPONENT_T )
        {
            m_canvas->MoveCursorToCrossHair();
            ConvertPart( (SCH_COMPONENT*) item, &dc );
        }

        break;

    case ID_POPUP_SCH_DISPLAYDOC_CMP:

        // Ensure the struct is a component (could be a piece of a component, like Field, text..)
        if( item && item->Type() == SCH_COMPONENT_T )
        {
            LIB_ALIAS* LibEntry;
            LibEntry = CMP_LIBRARY::FindLibraryEntry( ( (SCH_COMPONENT*) item )->GetLibName() );

            if( LibEntry && LibEntry->GetDocFileName() != wxEmptyString )
            {
                GetAssociatedDocument( this, LibEntry->GetDocFileName(),
                                       &wxGetApp().GetLibraryPathList() );
            }
        }
        break;

    case ID_POPUP_SCH_ENTER_SHEET:

        if( item && (item->Type() == SCH_SHEET_T) )
        {
            m_CurrentSheet->Push( (SCH_SHEET*) item );
            DisplayCurrentSheet();
        }

        break;

    case ID_POPUP_SCH_LEAVE_SHEET:
        m_CurrentSheet->Pop();
        DisplayCurrentSheet();
        break;

    case wxID_COPY:         // really this is a Save block for paste
        screen->m_BlockLocate.SetCommand( BLOCK_SAVE );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_PLACE_BLOCK:
        m_canvas->SetAutoPanRequest( false );
        m_canvas->MoveCursorToCrossHair();
        HandleBlockPlace( &dc );
        break;

    case ID_POPUP_ZOOM_BLOCK:
        screen->m_BlockLocate.SetCommand( BLOCK_ZOOM );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_DELETE_BLOCK:
        m_canvas->MoveCursorToCrossHair();
        screen->m_BlockLocate.SetCommand( BLOCK_DELETE );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        SetSheetNumberAndCount();
        break;

    case ID_POPUP_COPY_BLOCK:
        m_canvas->MoveCursorToCrossHair();
        screen->m_BlockLocate.SetCommand( BLOCK_COPY );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_DRAG_BLOCK:
        m_canvas->MoveCursorToCrossHair();
        screen->m_BlockLocate.SetCommand( BLOCK_DRAG );
        screen->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_SCH_ADD_JUNCTION:
        m_canvas->MoveCursorToCrossHair();
        screen->SetCurItem( AddJunction( &dc, GetCrossHairPosition(), true ) );
        screen->TestDanglingEnds( m_canvas, &dc );
        screen->SetCurItem( NULL );
        break;

    case ID_POPUP_SCH_ADD_LABEL:
    case ID_POPUP_SCH_ADD_GLABEL:
        screen->SetCurItem( CreateNewText( &dc, id == ID_POPUP_SCH_ADD_LABEL ?
                                           LAYER_LOCLABEL : LAYER_GLOBLABEL ) );
        item = screen->GetCurItem();

        if( item )
            addCurrentItemToList( &dc );

        break;

    case ID_POPUP_SCH_GETINFO_MARKER:
        if( item && item->Type() == SCH_MARKER_T )
            ( (SCH_MARKER*) item )->DisplayMarkerInfo( this );

        break;

    default:        // Log error:
        wxFAIL_MSG( wxString::Format( wxT( "Cannot process command event ID %d" ),
                                      event.GetId() ) );
        break;
    }

    // End switch ( id )    (Command execution)

    if( GetToolId() == ID_NO_TOOL_SELECTED )
        SetRepeatItem( NULL );
}
Example #27
0
void DeleteSubHierarchy(DrawSheetStruct * FirstSheet)
/*********************************************************/

/*  Supprime tous les elements de la sous hierarchie correspondante a
	la feuille FirstSheet
	FirstSheet n'est pas touche
*/
{
SCH_SCREEN *Screen;
EDA_BaseStruct *DrawStruct;
EDA_BaseStruct *EEDrawList;
WinEDA_SchematicFrame * frame = EDA_Appl->SchematicFrame;
char Line[256];

	if( FirstSheet == NULL ) return;

	if( FirstSheet->m_StructType != DRAW_SHEET_STRUCT_TYPE)
		{
		DisplayError(NULL,
				"DeleteSubHierarchy error: NOT a SubSheet");
		return;
		}

	/* effacement du sous schema correspondant */
	Screen = (SCH_SCREEN*)FirstSheet->m_Son;

	if(Screen == NULL) return;

	if( Screen->IsModify() )
		{
		sprintf(Line,"Sheet %s (file %s) modified. Save ?",
					FirstSheet->m_Field[VALUE].m_Text.GetData(),
					Screen->m_FileName.GetData()); 
		if( IsOK(frame, Line) )
			{
			frame->SaveEEFile(Screen, FILE_SAVE_AS);
			}
		}

	/* Effacement des sous feuilles */
	EEDrawList = Screen->EEDrawList;
	while (EEDrawList != NULL)
		{
		DrawStruct = EEDrawList;
		EEDrawList = EEDrawList->Pnext;
		if( DrawStruct->m_StructType == DRAW_SHEET_STRUCT_TYPE)
			{
			DeleteSubHierarchy((DrawSheetStruct *) DrawStruct);
			}
		}

	/* Effacement des elements autres que les sous feuilles */
	Screen->ClearDrawList();

	/* Modification du chainage des structures ecran
	et suppression de l'ecran */
	SCH_SCREEN * Pscreen, * Nscreen;
	Pscreen = (SCH_SCREEN*) Screen->Pback;
	Nscreen = Screen->Next();
	if( Pscreen ) Pscreen->Pnext = Nscreen;
	if ( Nscreen ) Nscreen->Pback = Pscreen;
	if ( frame->GetScreen() == Screen ) frame->m_CurrentScreen = ScreenSch;
	ActiveScreen = frame->GetScreen();
	if( Screen != ScreenSch ) delete(Screen);
}
Example #28
0
void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item = screen->GetCurItem();

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    // Allows block rotate operation on hot key.
    if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
    {
        screen->m_BlockLocate.SetCommand( BLOCK_ROTATE );
        HandleBlockEnd( &dc );
        return;
    }

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::RotatableItems,
                                  aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }

    switch( item->Type() )
    {
    case SCH_COMPONENT_T:
        if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
            OrientComponent( CMP_ROTATE_CLOCKWISE );
        else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
            OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
        else
            wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );

        break;

    case SCH_TEXT_T:
    case SCH_LABEL_T:
    case SCH_GLOBAL_LABEL_T:
    case SCH_HIERARCHICAL_LABEL_T:
        m_canvas->MoveCursorToCrossHair();
        ChangeTextOrient( (SCH_TEXT*) item, &dc );
        break;

    case SCH_FIELD_T:
        m_canvas->MoveCursorToCrossHair();
        RotateField( (SCH_FIELD*) item, &dc );
        break;

    case SCH_BITMAP_T:
        RotateImage( (SCH_BITMAP*) item );
        break;

    case SCH_SHEET_T:           /// @todo allow sheet rotate on hotkey
    default:
        wxFAIL_MSG( wxString::Format( wxT( "Cannot rotate schematic item type %s." ),
                                      GetChars( item->GetClass() ) ) );
    }

    if( item->GetFlags() == 0 )
        screen->SetCurItem( NULL );
}
void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_LINE* segment = (SCH_LINE*) screen->GetCurItem();

    if( segment == NULL || segment->Type() != SCH_LINE_T || !segment->IsNew() )
        return;

    // Delete zero length segments and clear item flags.
    SCH_ITEM* item = s_wires.begin();

    while( item )
    {
        item->ClearFlags();

        wxCHECK_RET( item->Type() == SCH_LINE_T, wxT( "Unexpected object type in wire list." ) );

        segment = (SCH_LINE*) item;
        item = item->Next();

        if( segment->IsNull() )
            delete s_wires.Remove( segment );
    }

    if( s_wires.GetCount() == 0 )
        return;

    // Get the last non-null wire (this is the last created segment).
    SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );

    screen->SetCurItem( NULL );
    m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );

    // store the terminal point of this last segment: a junction could be needed
    // (the last wire could be merged/deleted/modified, and lost)
    wxPoint endpoint = segment->GetEndPoint();

    // store the starting point of this first segment: a junction could be needed
    SCH_LINE* firstsegment = (SCH_LINE*) s_wires.GetFirst();
    wxPoint startPoint = firstsegment->GetStartPoint();

    // Save the old wires for the undo command
    DLIST< SCH_ITEM > oldWires;                     // stores here the old wires
    GetScreen()->ExtractWires( oldWires, true );    // Save them in oldWires list
    // Put the snap shot of the previous wire, buses, and junctions in the undo/redo list.
    PICKED_ITEMS_LIST oldItems;
    oldItems.m_Status = UR_WIRE_IMAGE;

    while( oldWires.GetCount() != 0 )
    {
        ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE );
        oldItems.PushItem( picker );
    }

    SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );

    // Remove segments backtracking over others
    RemoveBacktracks( s_wires );

    // Add the new wires
    screen->Append( s_wires );

    // Correct and remove segments that need to be merged.
    screen->SchematicCleanUp();

    // A junction could be needed to connect the end point of the last created segment.
    if( screen->IsJunctionNeeded( endpoint ) )
        screen->Append( AddJunction( DC, endpoint ) );

    // A junction could be needed to connect the start point of the set of new created wires
    if( screen->IsJunctionNeeded( startPoint ) )
        screen->Append( AddJunction( DC, startPoint ) );

    m_canvas->Refresh();

    OnModify();
}
Example #30
0
void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent )
{
    SCH_SCREEN* screen = GetScreen();
    SCH_ITEM*   item = screen->GetCurItem();

    if( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK )
    {
        // trying to move an item when there is a block at the same time is not acceptable
        return;
    }

    if( item == NULL )
    {
        // If we didn't get here by a hot key, then something has gone wrong.
        if( aEvent.GetInt() == 0 )
            return;

        EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();

        wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );

        item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::MovableItems,
                                  aEvent.GetInt() );

        // Exit if no item found at the current location or the item is already being edited.
        if( (item == NULL) || (item->GetFlags() != 0) )
            return;
    }

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    switch( item->Type() )
    {
    case SCH_LINE_T:
        break;

    case SCH_JUNCTION_T:
    case SCH_NO_CONNECT_T:
    case SCH_BUS_BUS_ENTRY_T:
    case SCH_BUS_WIRE_ENTRY_T:
    case SCH_LABEL_T:
    case SCH_GLOBAL_LABEL_T:
    case SCH_HIERARCHICAL_LABEL_T:
    case SCH_TEXT_T:
    case SCH_COMPONENT_T:
    case SCH_SHEET_PIN_T:
    case SCH_FIELD_T:
    case SCH_SHEET_T:
        PrepareMoveItem( item, &dc );
        break;

    case SCH_BITMAP_T:
        // move an image is a special case:
        // we cannot undraw/redraw a bitmap just using our xor mode
        // the MoveImage function handle this undraw/redraw difficulty
        // By redrawing the full bounding box
        MoveImage( (SCH_BITMAP*) item, &dc );
        break;

    case SCH_MARKER_T:
        // Moving a marker has no sense
        break;

    default:
        // Unknown items cannot be moved
        wxFAIL_MSG( wxString::Format(
                    wxT( "Cannot move item type %d" ), item->Type() ) );
        break;
    }

    if( GetToolId() == ID_NO_TOOL_SELECTED )
        SetRepeatItem( NULL );
}