423 lines
13 KiB
C++
423 lines
13 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 2010-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
|
|
* Copyright (C) 1992-2016 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 <fctsys.h>
|
|
|
|
#include <kiface_i.h>
|
|
#include <common.h>
|
|
#include <class_drawpanel.h>
|
|
#include <confirm.h>
|
|
|
|
#include <dialog_print_using_printer_base.h>
|
|
#include <printout_controler.h>
|
|
|
|
#include <gerbview.h>
|
|
#include <gerbview_frame.h>
|
|
#include <gerber_file_image.h>
|
|
#include <gerber_file_image_list.h>
|
|
|
|
#include <enabler.h>
|
|
|
|
///@{
|
|
/// \ingroup config
|
|
|
|
#define OPTKEY_LAYERBASE wxT( "PlotLayer_%d" )
|
|
#define OPTKEY_PRINT_X_FINESCALE_ADJ wxT( "PrintXFineScaleAdj" )
|
|
#define OPTKEY_PRINT_Y_FINESCALE_ADJ wxT( "PrintYFineScaleAdj" )
|
|
#define OPTKEY_PRINT_SCALE wxT( "PrintScale" )
|
|
#define OPTKEY_PRINT_PAGE_FRAME wxT( "PrintPageFrame" )
|
|
#define OPTKEY_PRINT_MONOCHROME_MODE wxT( "PrintMonochrome" )
|
|
|
|
///@}
|
|
|
|
static double s_ScaleList[] =
|
|
{ 0, 0.5, 0.7, 0.999, 1.0, 1.4, 2.0, 3.0, 4.0 };
|
|
|
|
// Define min et max reasonnable values for print scale
|
|
#define MIN_SCALE 0.01
|
|
#define MAX_SCALE 100.0
|
|
|
|
// static print data and page setup data, to remember settings during the session
|
|
static wxPrintData* s_printData;
|
|
static wxPageSetupDialogData* s_pageSetupData = (wxPageSetupDialogData*) NULL;
|
|
|
|
// Variables locales
|
|
static PRINT_PARAMETERS s_Parameters;
|
|
|
|
|
|
/* Dialog to print schematic. Class derived from DIALOG_PRINT_USING_PRINTER_BASE
|
|
* created by wxFormBuilder
|
|
*/
|
|
class DIALOG_PRINT_USING_PRINTER : public DIALOG_PRINT_USING_PRINTER_BASE
|
|
{
|
|
private:
|
|
GERBVIEW_FRAME* m_Parent;
|
|
wxConfigBase* m_Config;
|
|
wxCheckBox* m_BoxSelectLayer[32];
|
|
|
|
public:
|
|
DIALOG_PRINT_USING_PRINTER( GERBVIEW_FRAME* parent );
|
|
~DIALOG_PRINT_USING_PRINTER() {};
|
|
|
|
private:
|
|
void OnCloseWindow( wxCloseEvent& event ) override;
|
|
void OnInitDialog( wxInitDialogEvent& event );
|
|
void OnPageSetup( wxCommandEvent& event ) override;
|
|
void OnPrintPreview( wxCommandEvent& event ) override;
|
|
void OnPrintButtonClick( wxCommandEvent& event ) override;
|
|
void OnScaleSelectionClick( wxCommandEvent& event ) override;
|
|
|
|
void OnButtonCloseClick( wxCommandEvent& event ) override { Close(); }
|
|
void SetPrintParameters();
|
|
void InitValues();
|
|
|
|
public:
|
|
bool IsMirrored() { return m_Print_Mirror->IsChecked(); }
|
|
bool PrintUsingSinglePage() { return true; }
|
|
int SetLayerSetFromListSelection();
|
|
// Prepare print parameters. return true if OK,
|
|
// false if there is an issue (mainly no printable layers)
|
|
bool PreparePrintPrms();
|
|
};
|
|
|
|
|
|
void GERBVIEW_FRAME::ToPrinter( wxCommandEvent& event )
|
|
{
|
|
if( s_printData == NULL ) // First print
|
|
s_printData = new wxPrintData();
|
|
|
|
if( !s_printData->Ok() )
|
|
{
|
|
DisplayError( this, _( "Error Init Printer info" ) );
|
|
return;
|
|
}
|
|
|
|
s_printData->SetQuality( wxPRINT_QUALITY_HIGH );
|
|
s_printData->SetOrientation( GetPageSettings().IsPortrait() ?
|
|
wxPORTRAIT : wxLANDSCAPE );
|
|
|
|
DIALOG_PRINT_USING_PRINTER* frame = new DIALOG_PRINT_USING_PRINTER( this );
|
|
|
|
frame->ShowModal();
|
|
frame->Destroy();
|
|
}
|
|
|
|
|
|
DIALOG_PRINT_USING_PRINTER::DIALOG_PRINT_USING_PRINTER( GERBVIEW_FRAME* parent ) :
|
|
DIALOG_PRINT_USING_PRINTER_BASE( parent )
|
|
{
|
|
m_Parent = parent;
|
|
m_Config = Kiface().KifaceSettings();
|
|
|
|
InitValues( );
|
|
GetSizer()->SetSizeHints( this );
|
|
|
|
#ifdef __WXMAC__
|
|
/* Problems with modal on wx-2.9 - Anyway preview is standard for OSX */
|
|
m_buttonPreview->Hide();
|
|
#endif
|
|
|
|
GetSizer()->Fit( this );
|
|
}
|
|
|
|
|
|
void DIALOG_PRINT_USING_PRINTER::InitValues( )
|
|
{
|
|
SetFocus();
|
|
wxString msg;
|
|
|
|
if( s_pageSetupData == NULL )
|
|
{
|
|
s_pageSetupData = new wxPageSetupDialogData;
|
|
// Set initial page margins.
|
|
// Margins are already set in Gerbview, so we can use 0
|
|
s_pageSetupData->SetMarginTopLeft( wxPoint( 0, 0 ) );
|
|
s_pageSetupData->SetMarginBottomRight( wxPoint( 0, 0 ) );
|
|
}
|
|
|
|
s_Parameters.m_PageSetupData = s_pageSetupData;
|
|
GERBER_FILE_IMAGE_LIST* images = m_Parent->GetGerberLayout()->GetImagesList();
|
|
|
|
// Create layer list
|
|
for( unsigned ii = 0; ii < images->ImagesMaxCount(); ++ii )
|
|
{
|
|
msg = _( "Layer" );
|
|
msg << wxT( " " ) << ii + 1;
|
|
|
|
wxStaticBoxSizer* boxSizer = ( ii < 16 ) ? m_leftLayersBoxSizer
|
|
: m_rightLayersBoxSizer;
|
|
|
|
m_BoxSelectLayer[ii] = new wxCheckBox( boxSizer->GetStaticBox(),
|
|
wxID_ANY, msg );
|
|
boxSizer->Add( m_BoxSelectLayer[ii], wxGROW | wxLEFT | wxRIGHT | wxTOP );
|
|
|
|
if( images->GetGbrImage( ii ) == NULL ) // Nothing loaded on this draw layer
|
|
m_BoxSelectLayer[ii]->Enable( false );
|
|
}
|
|
|
|
// Read the scale adjust option
|
|
int scale_idx = 4; // default selected scale = ScaleList[4] = 1.000
|
|
|
|
if( m_Config )
|
|
{
|
|
m_Config->Read( OPTKEY_PRINT_X_FINESCALE_ADJ, &s_Parameters.m_XScaleAdjust );
|
|
m_Config->Read( OPTKEY_PRINT_Y_FINESCALE_ADJ, &s_Parameters.m_YScaleAdjust );
|
|
m_Config->Read( OPTKEY_PRINT_SCALE, &scale_idx );
|
|
m_Config->Read( OPTKEY_PRINT_PAGE_FRAME, &s_Parameters.m_Print_Sheet_Ref, 1 );
|
|
m_Config->Read( OPTKEY_PRINT_MONOCHROME_MODE, &s_Parameters.m_Print_Black_and_White, 1 );
|
|
|
|
// Test for a reasonnable scale value. Set to 1 if problem
|
|
if( s_Parameters.m_XScaleAdjust < MIN_SCALE ||
|
|
s_Parameters.m_YScaleAdjust < MIN_SCALE ||
|
|
s_Parameters.m_XScaleAdjust > MAX_SCALE ||
|
|
s_Parameters.m_YScaleAdjust > MAX_SCALE )
|
|
s_Parameters.m_XScaleAdjust = s_Parameters.m_YScaleAdjust = 1.0;
|
|
|
|
for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
|
|
{
|
|
wxString layerKey;
|
|
bool option;
|
|
|
|
layerKey.Printf( OPTKEY_LAYERBASE, layer );
|
|
m_Config->Read( layerKey, &option, false );
|
|
m_BoxSelectLayer[layer]->SetValue( option );
|
|
}
|
|
}
|
|
|
|
m_ScaleOption->SetSelection( scale_idx );
|
|
scale_idx = m_ScaleOption->GetSelection();
|
|
s_Parameters.m_PrintScale = s_ScaleList[scale_idx];
|
|
m_Print_Mirror->SetValue( s_Parameters.m_PrintMirror );
|
|
|
|
|
|
if( s_Parameters.m_Print_Black_and_White )
|
|
m_ModeColorOption->SetSelection( 1 );
|
|
else
|
|
m_ModeColorOption->SetSelection( 0 );
|
|
|
|
s_Parameters.m_PenDefaultSize = 0;
|
|
|
|
// Create scale adjust option
|
|
msg.Printf( wxT( "%f" ), s_Parameters.m_XScaleAdjust );
|
|
m_FineAdjustXscaleOpt->SetValue( msg );
|
|
msg.Printf( wxT( "%f" ), s_Parameters.m_YScaleAdjust );
|
|
m_FineAdjustYscaleOpt->SetValue( msg );
|
|
|
|
bool enable = (s_Parameters.m_PrintScale == 1.0);
|
|
|
|
m_FineAdjustXscaleOpt->Enable(enable);
|
|
m_FineAdjustYscaleOpt->Enable(enable);
|
|
}
|
|
|
|
|
|
int DIALOG_PRINT_USING_PRINTER::SetLayerSetFromListSelection()
|
|
{
|
|
std::vector<int> layerList;
|
|
|
|
for( int ii = 0; ii < GERBER_DRAWLAYERS_COUNT; ++ii )
|
|
{
|
|
if( m_BoxSelectLayer[ii]->IsChecked() && m_BoxSelectLayer[ii]->IsEnabled() )
|
|
layerList.push_back( ii );
|
|
}
|
|
|
|
m_Parent->GetGerberLayout()->SetPrintableLayers( layerList );
|
|
s_Parameters.m_PageCount = layerList.size();
|
|
|
|
return s_Parameters.m_PageCount;
|
|
}
|
|
|
|
|
|
void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event )
|
|
{
|
|
SetPrintParameters();
|
|
|
|
if( m_Config )
|
|
{
|
|
m_Config->Write( OPTKEY_PRINT_X_FINESCALE_ADJ, s_Parameters.m_XScaleAdjust );
|
|
m_Config->Write( OPTKEY_PRINT_Y_FINESCALE_ADJ, s_Parameters.m_YScaleAdjust );
|
|
m_Config->Write( OPTKEY_PRINT_SCALE, m_ScaleOption->GetSelection() );
|
|
m_Config->Write( OPTKEY_PRINT_PAGE_FRAME, s_Parameters.m_Print_Sheet_Ref);
|
|
m_Config->Write( OPTKEY_PRINT_MONOCHROME_MODE, s_Parameters.m_Print_Black_and_White);
|
|
wxString layerKey;
|
|
|
|
for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
|
|
{
|
|
layerKey.Printf( OPTKEY_LAYERBASE, layer );
|
|
m_Config->Write( layerKey, m_BoxSelectLayer[layer]->IsChecked() );
|
|
}
|
|
}
|
|
|
|
EndModal( 0 );
|
|
}
|
|
|
|
|
|
void DIALOG_PRINT_USING_PRINTER::SetPrintParameters()
|
|
{
|
|
s_Parameters.m_PrintMirror = m_Print_Mirror->GetValue();
|
|
s_Parameters.m_Print_Black_and_White =
|
|
m_ModeColorOption->GetSelection() != 0;
|
|
|
|
// Due to negative objects in gerber objects, always use one page per image,
|
|
// because these objects create artefact when they are printed on an existing image.
|
|
s_Parameters.m_OptionPrintPage = false;
|
|
|
|
SetLayerSetFromListSelection();
|
|
|
|
int idx = m_ScaleOption->GetSelection();
|
|
s_Parameters.m_PrintScale = s_ScaleList[idx];
|
|
|
|
// Test for a reasonnable scale value
|
|
bool ok = true;
|
|
double scaleX;
|
|
m_FineAdjustXscaleOpt->GetValue().ToDouble( &scaleX );
|
|
|
|
double scaleY;
|
|
m_FineAdjustYscaleOpt->GetValue().ToDouble( &scaleY );
|
|
|
|
if( scaleX > MAX_SCALE || scaleY > MAX_SCALE )
|
|
{
|
|
DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very large value" ) );
|
|
ok = false;
|
|
}
|
|
|
|
if( scaleX < MIN_SCALE || scaleY < MIN_SCALE )
|
|
{
|
|
DisplayInfoMessage( NULL, _( "Warning: Scale option set to a very small value" ) );
|
|
ok = false;
|
|
}
|
|
|
|
if( ok )
|
|
{
|
|
s_Parameters.m_XScaleAdjust = scaleX;
|
|
s_Parameters.m_YScaleAdjust = scaleY;
|
|
}
|
|
else
|
|
{
|
|
// Update actual fine scale value
|
|
m_FineAdjustXscaleOpt->SetValue( wxString::Format( "%f", s_Parameters.m_XScaleAdjust ) );
|
|
m_FineAdjustYscaleOpt->SetValue( wxString::Format( "%f", s_Parameters.m_YScaleAdjust ) );
|
|
}
|
|
}
|
|
|
|
void DIALOG_PRINT_USING_PRINTER::OnScaleSelectionClick( wxCommandEvent& event )
|
|
{
|
|
double scale = s_ScaleList[m_ScaleOption->GetSelection()];
|
|
bool enable = (scale == 1.0);
|
|
|
|
if( m_FineAdjustXscaleOpt )
|
|
m_FineAdjustXscaleOpt->Enable(enable);
|
|
|
|
if( m_FineAdjustYscaleOpt )
|
|
m_FineAdjustYscaleOpt->Enable(enable);
|
|
}
|
|
|
|
// Open a dialog box for printer setup (printer options, page size ...)
|
|
void DIALOG_PRINT_USING_PRINTER::OnPageSetup( wxCommandEvent& event )
|
|
{
|
|
*s_pageSetupData = *s_printData;
|
|
|
|
wxPageSetupDialog pageSetupDialog(this, s_pageSetupData);
|
|
pageSetupDialog.ShowModal();
|
|
|
|
(*s_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
|
|
(*s_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
|
|
}
|
|
|
|
bool DIALOG_PRINT_USING_PRINTER::PreparePrintPrms()
|
|
{
|
|
SetPrintParameters();
|
|
|
|
// If no layer selected, we have no plot. prompt user if it happens
|
|
// because he could think there is a bug in Pcbnew:
|
|
if( m_Parent->GetGerberLayout()->GetPrintableLayers().size() == 0 )
|
|
{
|
|
DisplayError( this, _( "No layer selected" ) );
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Open and display a previewer frame for printing
|
|
void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event )
|
|
{
|
|
if( !PreparePrintPrms() )
|
|
return;
|
|
|
|
// Pass two printout objects: for preview, and possible printing.
|
|
wxString title = _( "Print Preview" );
|
|
wxPrintPreview* preview =
|
|
new wxPrintPreview( new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ),
|
|
new BOARD_PRINTOUT_CONTROLLER( s_Parameters, m_Parent, title ),
|
|
s_printData );
|
|
|
|
if( preview == NULL )
|
|
{
|
|
DisplayError( this, wxT( "OnPrintPreview() problem" ) );
|
|
return;
|
|
}
|
|
|
|
|
|
// Uses the parent position and size.
|
|
// @todo uses last position and size ans store them when exit in m_Config
|
|
wxPoint WPos = m_Parent->GetPosition();
|
|
wxSize WSize = m_Parent->GetSize();
|
|
|
|
wxPreviewFrame* frame = new wxPreviewFrame( preview, this, title, WPos, WSize );
|
|
frame->SetMinSize( wxSize( 550, 350 ) );
|
|
|
|
frame->Initialize();
|
|
|
|
frame->Raise(); // Needed on Ubuntu/Unity to display the frame
|
|
frame->Show( true );
|
|
}
|
|
|
|
|
|
void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event )
|
|
{
|
|
if( !PreparePrintPrms() )
|
|
return;
|
|
|
|
wxPrintDialogData printDialogData( *s_printData );
|
|
|
|
wxPrinter printer( &printDialogData );
|
|
wxString title = _( "Print" );
|
|
BOARD_PRINTOUT_CONTROLLER printout( s_Parameters, m_Parent, title );
|
|
|
|
// Disable 'Print' button to prevent issuing another print
|
|
// command before the previous one is finished (causes problems on Windows)
|
|
ENABLER printBtnDisable( *m_buttonPrint, false );
|
|
|
|
if( !printer.Print( this, &printout, true ) )
|
|
{
|
|
if( wxPrinter::GetLastError() == wxPRINTER_ERROR )
|
|
DisplayError( this, _( "There was a problem printing" ) );
|
|
}
|
|
else
|
|
{
|
|
*s_printData = printer.GetPrintDialogData().GetPrintData();
|
|
}
|
|
}
|
|
|