/** * @file dialog_annotate.cpp * @brief Annotation dialog functions. */ /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 1992-2017 jean-pierre Charras jp.charras at wanadoo.fr * Copyright (C) 1992-2017 Kicad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #define KEY_ANNOTATE_SORT_OPTION wxT( "AnnotateSortOption" ) #define KEY_ANNOTATE_ALGO_OPTION wxT( "AnnotateAlgoOption" ) #define KEY_ANNOTATE_MESSAGES_FILTER wxT( "AnnotateFilterMsg" ) // A window name for the annotate dialog to retrieve is if not destroyed #define DLG_WINDOW_NAME "DialogAnnotateWindowName" class wxConfigBase; /** * Class DIALOG_ANNOTATE: a dialog to set/clear reference designators, * of a schematic hierarchy, with different options */ class DIALOG_ANNOTATE: public DIALOG_ANNOTATE_BASE { public: DIALOG_ANNOTATE( SCH_EDIT_FRAME* parent, const wxString& message ); ~DIALOG_ANNOTATE(); private: SCH_EDIT_FRAME* m_Parent; wxConfigBase* m_Config; /// Initialises member variables void InitValues(); void OnClearAnnotationCmpClick( wxCommandEvent& event ) override; void OnCloseClick( wxCommandEvent& event ) override; void OnClose( wxCloseEvent& event ) override; void OnApplyClick( wxCommandEvent& event ) override; // User functions: bool GetLevel(); bool GetResetItems(); bool GetLockUnits(); /** * Function GetSortOrder * @return 0 if annotation by X position, * 1 if annotation by Y position, */ int GetSortOrder(); /** * Function GetAnnotateAlgo * @return 0 if annotation using first free Id value * 1 for first free Id value inside sheet num * 100 to sheet num * 100 + 99 * 2 for first free Id value inside sheet num * 1000 to sheet num * 1000 + 999 */ int GetAnnotateAlgo(); int GetStartNumber(); }; DIALOG_ANNOTATE::DIALOG_ANNOTATE( SCH_EDIT_FRAME* parent, const wxString& message ) : DIALOG_ANNOTATE_BASE( parent ) { SetName( DLG_WINDOW_NAME ); m_Parent = parent; if( !message.IsEmpty() ) { m_userMessage->SetLabelText( message ); m_userMessage->Show( true ); m_rbScope->Enable( false ); } m_MessageWindow->SetLabel( _( "Annotation Messages:" ) ); // We use a sdbSizer to get platform-dependent ordering of the action buttons, but // that requires us to correct the button labels here. m_sdbSizer1OK->SetLabel( _( "Annotate" ) ); m_sdbSizer1Cancel->SetLabel( _( "Close" ) ); m_sdbSizer1->Layout(); m_sdbSizer1OK->SetDefault(); InitValues(); Layout(); // When all widgets have the size fixed, call FinishDialogSettings FinishDialogSettings(); } DIALOG_ANNOTATE::~DIALOG_ANNOTATE() { m_Config->Write( KEY_ANNOTATE_SORT_OPTION, GetSortOrder() ); m_Config->Write( KEY_ANNOTATE_ALGO_OPTION, GetAnnotateAlgo() ); m_Config->Write( KEY_ANNOTATE_MESSAGES_FILTER, (long) m_MessageWindow->GetVisibleSeverities() ); } void DIALOG_ANNOTATE::InitValues() { m_Config = Kiface().KifaceSettings(); long option; // These are always reset to attempt to keep the user out of trouble... m_rbScope->SetSelection( 0 ); m_rbOptions->SetSelection( 0 ); m_Config->Read( KEY_ANNOTATE_SORT_OPTION, &option, 0L ); switch( option ) { default: case 0: m_rbSortBy_X_Position->SetValue( 1 ); break; case 1: m_rbSortBy_Y_Position->SetValue( 1 ); break; } m_Config->Read( KEY_ANNOTATE_ALGO_OPTION, &option, 0L ); switch( option ) { default: case 0: m_rbFirstFree->SetValue( 1 ); break; case 1: m_rbSheetX100->SetValue( 100 ); break; case 2: m_rbSheetX1000->SetValue( 1000 ); break; } m_textNumberAfter->SetValue( wxT( "0" ) ); annotate_down_right_bitmap->SetBitmap( KiBitmap( annotate_down_right_xpm ) ); annotate_right_down_bitmap->SetBitmap( KiBitmap( annotate_right_down_xpm ) ); int severities = m_Config->Read( KEY_ANNOTATE_MESSAGES_FILTER, -1l ); m_MessageWindow->SetVisibleSeverities( severities ); m_MessageWindow->MsgPanelSetMinSize( wxSize( -1, 160 ) ); } // This is a modeless dialog so we have to handle these ourselves. void DIALOG_ANNOTATE::OnCloseClick( wxCommandEvent& event ) { Close(); } void DIALOG_ANNOTATE::OnClose( wxCloseEvent& event ) { Destroy(); } void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event ) { wxString message; // Ask for confirmation of destructive actions. if( GetResetItems() ) { if( GetLevel() ) message += _( "Clear and annotate all of the symbols on the entire schematic?" ); else message += _( "Clear and annotate all of the symbols on the current sheet?" ); message += _( "\n\nThis operation will change the current annotation and cannot be undone." ); KIDIALOG dlg( this, message, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); dlg.SetOKLabel( _( "Clear and Annotate" ) ); dlg.DoNotShowCheckbox( __FILE__, __LINE__ ); if( dlg.ShowModal() == wxCANCEL ) return; } m_MessageWindow->Clear(); REPORTER& reporter = m_MessageWindow->Reporter(); m_MessageWindow->SetLazyUpdate( true ); // Don't update after each message m_Parent->AnnotateComponents( GetLevel(), (ANNOTATE_ORDER_T) GetSortOrder(), (ANNOTATE_OPTION_T) GetAnnotateAlgo(), GetStartNumber(), GetResetItems() , true, GetLockUnits(), reporter ); m_MessageWindow->Flush( true ); // Now update to show all messages m_Parent->GetCanvas()->Refresh(); m_btnClear->Enable(); // Don't close dialog if there are things the user needs to address if( reporter.HasMessage() ) return; if( m_userMessage->IsShown() ) { // Close the dialog by calling the default handler for a wxID_OK event event.SetId( wxID_OK ); event.Skip(); } } void DIALOG_ANNOTATE::OnClearAnnotationCmpClick( wxCommandEvent& event ) { wxString message; if( GetLevel() ) message = _( "Clear the existing annotation for the entire schematic?" ); else message = _( "Clear the existing annotation for the current sheet?" ); message += _( "\n\nThis operation will clear the existing annotation and cannot be undone." ); KIDIALOG dlg( this, message, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); dlg.SetOKLabel( _( "Clear Annotation" ) ); dlg.DoNotShowCheckbox( __FILE__, __LINE__ ); if( dlg.ShowModal() == wxID_CANCEL ) return; m_Parent->DeleteAnnotation( !GetLevel() ); m_btnClear->Enable( false ); } bool DIALOG_ANNOTATE::GetLevel() { return m_rbScope->GetSelection() == 0; } bool DIALOG_ANNOTATE::GetResetItems() { return m_rbOptions->GetSelection() >= 1; } bool DIALOG_ANNOTATE::GetLockUnits() { return m_rbOptions->GetSelection() == 2; } int DIALOG_ANNOTATE::GetSortOrder() { if( m_rbSortBy_Y_Position->GetValue() ) return 1; else return 0; } int DIALOG_ANNOTATE::GetAnnotateAlgo() { if( m_rbSheetX100->GetValue() ) return 1; else if( m_rbSheetX1000->GetValue() ) return 2; else return 0; } int DIALOG_ANNOTATE::GetStartNumber() { return ValueFromString( EDA_UNITS_T::UNSCALED_UNITS, m_textNumberAfter->GetValue() ); } void SCH_EDIT_FRAME::OnAnnotate( wxCommandEvent& event ) { DIALOG_ANNOTATE* dlg = static_cast ( wxWindow::FindWindowByName( DLG_WINDOW_NAME ) ); if( !dlg ) { dlg = new DIALOG_ANNOTATE( this, wxEmptyString ); dlg->Show( true ); } else // The dialog is already opened, perhaps not visible { dlg->Show( true ); } } int SCH_EDIT_FRAME::ModalAnnotate( const wxString& aMessage ) { DIALOG_ANNOTATE dlg( this, aMessage ); return dlg.ShowModal(); }