/*
 * Function UpdateTitleAndInfo
 * displays the filename (if exists) of the current page layout descr file.
 */
void PL_EDITOR_FRAME::UpdateTitleAndInfo()
{
    wxString title;
    title.Printf( wxT( "Pl_Editor %s [%s]" ), GetChars( GetBuildVersion() ),
        GetChars( GetCurrFileName() ) );
    SetTitle( title );
}
void PL_EDITOR_FRAME::OnCloseWindow( wxCloseEvent& Event )
{
    if( GetScreen()->IsModify() )
    {
        wxString msg;
        wxString filename = GetCurrFileName();

        if( filename.IsEmpty() )
            msg = _("Save changes in a new file before closing?");
        else
            msg.Printf( _("Save the changes in\n<%s>\nbefore closing?"),
                        GetChars( filename ) );

        int ii = DisplayExitDialog( this, msg );

        switch( ii )
        {
        case wxID_CANCEL:
            Event.Veto();
            return;

        case wxID_NO:
            break;

        case wxID_OK:
        case wxID_YES:
        {
            if( filename.IsEmpty() )
            {
                wxFileDialog openFileDialog(this, _("Create file"), wxEmptyString,
                        wxEmptyString, PageLayoutDescrFileWildcard, wxFD_SAVE);

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

                filename = openFileDialog.GetPath();
            }

            if( !SavePageLayoutDescrFile( filename ) )
            {
                msg.Printf( _("Unable to create <%s>"), GetChars( filename ) );
                wxMessageBox( msg );
            }
        }
            break;
        }
    }

    // do not show the window because we do not want any paint event
    Show( false );

    // was: Pgm().SaveCurrentSetupValues( m_configSettings );
    wxConfigSaveSetups( Kiface().KifaceSettings(), m_configSettings );

    // On Linux, m_propertiesPagelayout must be destroyed
    // before deleting the main frame to avoid a crash when closing
    m_propertiesPagelayout->Destroy();
    Destroy();
}
void PL_EDITOR_FRAME::UpdateTitleAndInfo()
{
    wxString title;
    wxString file = GetCurrFileName();

    title.Printf( _( "Page Layout Editor" ) + wxT( " \u2014 %s" ),
                  file.Length() ? file : _( "no file selected" ) );
    SetTitle( title );
}
void PL_EDITOR_FRAME::RedrawActiveWindow( wxDC* aDC, bool aEraseBg )
{

    GetScreen()-> m_ScreenNumber = GetPageNumberOption() ? 1 : 2;

    if( aEraseBg )
        m_canvas->EraseScreen( aDC );

    m_canvas->DrawBackGround( aDC );

    const WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
    WORKSHEET_DATAITEM* selecteditem = GetSelectedItem();

    // the color to draw selected items
    if( GetDrawBgColor() == WHITE )
        WORKSHEET_DATAITEM::m_SelectedColor = DARKCYAN;
    else
        WORKSHEET_DATAITEM::m_SelectedColor = YELLOW;

    for( unsigned ii = 0; ; ii++ )
    {
        WORKSHEET_DATAITEM* item = pglayout.GetItem( ii );

        if( item == NULL )
            break;

        item->SetSelected( item == selecteditem );
    }

    DrawWorkSheet( aDC, GetScreen(), 0, IU_PER_MILS, GetCurrFileName() );

#ifdef USE_WX_OVERLAY
    if( IsShown() )
    {
        m_overlay.Reset();
        wxDCOverlay overlaydc( m_overlay, (wxWindowDC*)aDC );
        overlaydc.Clear();
    }
#endif

    if( m_canvas->IsMouseCaptured() )
        m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );

    m_canvas->DrawCrossHair( aDC );

    // Display the filename
    UpdateTitleAndInfo();
}
/* return the page layout item found at position aPosition
 * aPosition = the position (in user units) of the reference point
 */
WORKSHEET_DATAITEM* PL_EDITOR_FRAME::Locate( const wxPoint& aPosition )
{
    const PAGE_INFO&    pageInfo = GetPageSettings();
    TITLE_BLOCK         t_block = GetTitleBlock();
    EDA_COLOR_T         color = RED;    // Needed, not used
    PL_EDITOR_SCREEN*   screen = (PL_EDITOR_SCREEN*) GetScreen();

    screen-> m_ScreenNumber = GetPageNumberOption() ? 1 : 2;

    WS_DRAW_ITEM_LIST drawList;
    drawList.SetPenSize( 0 );
    drawList.SetMilsToIUfactor( IU_PER_MILS );
    drawList.SetSheetNumber( screen->m_ScreenNumber );
    drawList.SetSheetCount( screen->m_NumberOfScreens );
    drawList.SetFileName( GetCurrFileName() );
    // GetScreenDesc() returns a temporary string. Store it to avoid issues.
    wxString descr = GetScreenDesc();
    drawList.SetSheetName( descr );

    drawList.BuildWorkSheetGraphicList( pageInfo, t_block, color, color );

    // locate items.
    // We do not use here the COLLECTOR classes in use in pcbnew and eeschema
    // because the locate requirements are very basic.
    std::vector <WS_DRAW_ITEM_BASE*> list;
    drawList.Locate( list, aPosition );

    if( list.size() == 0 )
        return NULL;

    WS_DRAW_ITEM_BASE* drawitem = list[0];

    // Choose item in list if more than 1 item
    if( list.size() > 1 )
    {
        wxArrayString choices;
        wxString text;
        wxPoint cursPos = GetCrossHairPosition();

        for( unsigned ii = 0; ii < list.size(); ++ii )
        {
            drawitem = list[ii];
            text = drawitem->GetParent()->m_Name;

            if( (drawitem->m_Flags & (LOCATE_STARTPOINT|LOCATE_ENDPOINT))
                == (LOCATE_STARTPOINT|LOCATE_ENDPOINT) )
                text << wxT(" ") << _("(start or end point)");
            else
            {
                if( (drawitem->m_Flags & LOCATE_STARTPOINT) )
                    text << wxT(" ") << _("(start point)");

                if( (drawitem->m_Flags & LOCATE_ENDPOINT) )
                    text << wxT(" ") << _("(end point)");
            }

            if( ! drawitem->GetParent()->m_Info.IsEmpty() )
                text << wxT(" \"") << drawitem->GetParent()->m_Info << wxT("\"");

            choices.Add( text );
        }
        int selection = wxGetSingleChoiceIndex ( wxEmptyString,
                                                _( "Selection Clarification" ),
                                                choices, this );
        if( selection < 0 )
            return NULL;

        SetCrossHairPosition( cursPos );
        m_canvas->MoveCursorToCrossHair();
        drawitem = list[selection];
    }

    WORKSHEET_DATAITEM* item = drawitem->GetParent();
    item->ClearFlags(LOCATE_STARTPOINT|LOCATE_ENDPOINT);

    if( (drawitem->m_Flags & LOCATE_STARTPOINT) )
        item->SetFlags( LOCATE_STARTPOINT );

    if( (drawitem->m_Flags & LOCATE_ENDPOINT) )
        item->SetFlags( LOCATE_ENDPOINT );

    return item;
}
/* File commands. */
void PL_EDITOR_FRAME::Files_io( wxCommandEvent& event )
{
    wxString msg;
    int        id = event.GetId();
    wxString   filename = GetCurrFileName();
    WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();

    if( filename.IsEmpty() && id == wxID_SAVE )
        id = wxID_SAVEAS;

    switch( id )
    {
    case ID_LOAD_DEFAULT_PAGE_LAYOUT:
    case wxID_NEW:
    case wxID_OPEN:
        if( GetScreen()->IsModify() && !IsOK( this,
                   _( "The current page layout has been modified.\n"
                      "Do you wish to discard the changes?" ) ) )
            return;
        break;

    default:
        break;
    }


    switch( id )
    {
    case ID_LOAD_DEFAULT_PAGE_LAYOUT:
        pglayout.SetPageLayout();
        OnNewPageLayout();
        break;

    case wxID_NEW:
        pglayout.AllowVoidList( true );
        SetCurrFileName( wxEmptyString );
        pglayout.ClearList();
        OnNewPageLayout();
        break;

    case ID_APPEND_DESCR_FILE:
    {
         wxFileDialog openFileDialog(this, _("Append Page Layout Descr File"),
                wxEmptyString,
                wxEmptyString, PageLayoutDescrFileWildcard, wxFD_OPEN);

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

        filename = openFileDialog.GetPath();
        if( ! InsertPageLayoutDescrFile( filename ) )
        {
            msg.Printf( _("Unable to load %s file"), GetChars( filename ) );
            wxMessageBox( msg );
        }
        else
        {
            GetScreen()->SetModify();
            RebuildDesignTree();
            m_canvas->Refresh();
            msg.Printf( _("File <%s> inserted"), GetChars( filename ) );
            SetStatusText( msg );
        }
    }
        break;

    case wxID_OPEN:
    {
         wxFileDialog openFileDialog(this, _("Open file"), wxEmptyString,
                wxEmptyString, PageLayoutDescrFileWildcard, wxFD_OPEN);

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

        filename = openFileDialog.GetPath();
        if( ! LoadPageLayoutDescrFile( filename ) )
        {
            msg.Printf( _("Unable to load %s file"), GetChars( filename ) );
            wxMessageBox( msg );
        }
        else
        {
            OnNewPageLayout();
            msg.Printf( _("File <%s> loaded"), GetChars( filename ) );
            SetStatusText( msg );
        }
    }
        break;

    case wxID_SAVE:
        if( !SavePageLayoutDescrFile( filename ) )
        {
            msg.Printf( _("Unable to write <%s>"), GetChars( filename ) );
            wxMessageBox( msg );
        }
        else
        {
            msg.Printf( _("File <%s> written"), GetChars( filename ) );
            SetStatusText( msg );
        }
        break;

    case wxID_SAVEAS:
    {
         wxFileDialog openFileDialog(this, _("Create file"), wxEmptyString,
                wxEmptyString, PageLayoutDescrFileWildcard, wxFD_SAVE);

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

        filename = openFileDialog.GetPath();
        // Ensure the file has the right extension:
        // because a name like name.subname.subsubname is legal,
        // add the right extension without replacing the wxFileName
        // extension
        wxFileName fn(filename);

        if( fn.GetExt() != PageLayoutDescrFileExtension )
            filename << wxT(".") << PageLayoutDescrFileExtension;

        if( !SavePageLayoutDescrFile( filename ) )
        {
            msg.Printf( _("Unable to create <%s>"), GetChars( filename ) );
            wxMessageBox( msg );
        }

        else
        {
            msg.Printf( _("File <%s> written"), GetChars( filename ) );
            SetStatusText( msg );
            if( GetCurrFileName().IsEmpty() )
                SetCurrFileName( filename );
        }
    }
        break;

    default:
        wxMessageBox( wxT( "File_io: unexpected command id" ) );
        break;
    }
}
/* Handles the selection of tools, menu, and popup menu commands.
 */
void PL_EDITOR_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
    int id = event.GetId();
    int idx;
    wxString msg;
    WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance();
    WORKSHEET_DATAITEM* item = NULL;
    wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
    cmd.SetEventObject( this );

    switch( id )
    {
    case ID_NO_TOOL_SELECTED:
        SetNoToolSelected();
        break;

    case ID_MENU_ZOOM_SELECTION:
    case ID_ZOOM_SELECTION:
        // This tool is located on the main toolbar: switch it on or off on click
        if( GetToolId() != ID_ZOOM_SELECTION )
            SetToolID( ID_ZOOM_SELECTION, wxCURSOR_MAGNIFIER, _( "Zoom to selection" ) );
        else
            SetNoToolSelected();
        break;

    case ID_SELECT_PAGE_NUMBER:
        m_canvas->Refresh();
        break;

    case ID_SHEET_SET:
        {
        DIALOG_PAGES_SETTINGS dlg( this );
        dlg.SetWksFileName( GetCurrFileName() );
        dlg.EnableWksFileNamePicker( false );
        dlg.ShowModal();

        cmd.SetId( ID_ZOOM_PAGE );
        wxPostEvent( this, cmd );
        }
        break;

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

    case ID_POPUP_DESIGN_TREE_ITEM_DELETE:
    case ID_POPUP_ITEM_DELETE:
    case wxID_CUT:
        // Delete item, and select the previous item
        item = m_treePagelayout->GetPageLayoutSelectedItem();

        if( item == NULL )
            break;

        SaveCopyInUndoList();
        idx = pglayout.GetItemIndex( item );
        pglayout.Remove( item );
        RebuildDesignTree();

        if( id == ID_POPUP_DESIGN_TREE_ITEM_DELETE )
        {
            item = pglayout.GetItem( (unsigned) (idx-1) );

            if( item )
                m_treePagelayout->SelectCell( item );
        }

        item = NULL;
        OnModify();
        m_canvas->Refresh();
        break;

    case ID_POPUP_ITEM_ADD_LINE:
        SaveCopyInUndoList();
        idx =  m_treePagelayout->GetSelectedItemIndex();
        item = AddPageLayoutItem( WORKSHEET_DATAITEM::WS_SEGMENT, idx );

        if( InvokeDialogNewItem( this, item ) == wxID_CANCEL )
        {
            RemoveLastCommandInUndoList();
            pglayout.Remove( item );
            RebuildDesignTree();
            item = NULL;
        }
        else
        {
            // Put the new item in move mode, after putting the cursor
            // on the start point:
            wxPoint position = item->GetStartPosUi();
            SetCrossHairPosition( position, false );
            position = GetCrossHairPosition();

            if( m_canvas->IsPointOnDisplay( position ) )
                m_canvas->MoveCursorToCrossHair();
            else
                RedrawScreen( position, true );

            item->SetFlags( NEW_ITEM );
            MoveItem( item );
        }
        break;

    case ID_POPUP_ITEM_ADD_RECT:
        SaveCopyInUndoList();
        idx =  m_treePagelayout->GetSelectedItemIndex();
        item = AddPageLayoutItem( WORKSHEET_DATAITEM::WS_RECT, idx );

        if( InvokeDialogNewItem( this, item ) == wxID_CANCEL )
        {
            RemoveLastCommandInUndoList();
            pglayout.Remove( item );
            RebuildDesignTree();
            item = NULL;
        }
        else
        {
            // Put the new item in move mode, after putting the cursor
            // on the start point:
            wxPoint position = item->GetStartPosUi();
            SetCrossHairPosition( position, false );
            position = GetCrossHairPosition();

            if( m_canvas->IsPointOnDisplay( position ) )
                m_canvas->MoveCursorToCrossHair();
            else
                RedrawScreen( position, true );

            item->SetFlags( NEW_ITEM );
            MoveItem( item );
        }
        break;

    case ID_POPUP_ITEM_ADD_TEXT:
        SaveCopyInUndoList();
        idx =  m_treePagelayout->GetSelectedItemIndex();
        item = AddPageLayoutItem( WORKSHEET_DATAITEM::WS_TEXT, idx );
        if( InvokeDialogNewItem( this, item ) == wxID_CANCEL )
        {
            RemoveLastCommandInUndoList();
            pglayout.Remove( item );
            RebuildDesignTree();
            item = NULL;
        }
        else
        {
            // Put the new text in move mode:
            item->SetFlags( NEW_ITEM | LOCATE_STARTPOINT );
            MoveItem( item );
        }
        break;

    case ID_POPUP_ITEM_ADD_BITMAP:
        SaveCopyInUndoList();
        idx =  m_treePagelayout->GetSelectedItemIndex();
        item = AddPageLayoutItem( WORKSHEET_DATAITEM::WS_BITMAP, idx );
        if( item && InvokeDialogNewItem( this, item ) == wxID_CANCEL )
        {
            RemoveLastCommandInUndoList();
            pglayout.Remove( item );
            RebuildDesignTree();
            item = NULL;
        }
        if( item )
        {
            // Put the new text in move mode:
            item->SetFlags( NEW_ITEM | LOCATE_STARTPOINT );
            MoveItem( item );
        }
        break;

    case ID_POPUP_ITEM_APPEND_PAGE_LAYOUT:
        cmd.SetId( ID_APPEND_DESCR_FILE );
        wxPostEvent( this, cmd );
        break;

    case ID_POPUP_ITEM_PLACE:
        item = GetScreen()->GetCurItem();
        PlaceItem( item );
        break;

    case ID_POPUP_ITEM_PLACE_CANCEL:
        if(  m_canvas->IsMouseCaptured() )
             m_canvas->EndMouseCapture();
        break;

    case ID_POPUP_ITEM_MOVE_START_POINT:
        item = m_treePagelayout->GetPageLayoutSelectedItem();
        // Ensure flags are properly set
        item->ClearFlags( LOCATE_ENDPOINT );
        item->SetFlags( LOCATE_STARTPOINT );
        MoveItem( item );
        break;

    case ID_POPUP_ITEM_MOVE_END_POINT:
        item = m_treePagelayout->GetPageLayoutSelectedItem();
        // Ensure flags are properly set
        item->ClearFlags( LOCATE_STARTPOINT );
        item->SetFlags( LOCATE_ENDPOINT );
        MoveItem( item );
        break;

    case ID_POPUP_ITEM_MOVE:
        item = m_treePagelayout->GetPageLayoutSelectedItem();
        item->ClearFlags( LOCATE_ENDPOINT|LOCATE_STARTPOINT );
        MoveItem( item );
        break;

    default:
        wxMessageBox( wxT( "PL_EDITOR_FRAME::Process_Special_Functions error" ) );
        break;
    }

    if( item )
    {
        OnModify();
        m_propertiesPagelayout->CopyPrmsFromItemToPanel( item );
        m_treePagelayout->SelectCell( item );
    }

}