summaryrefslogtreecommitdiff
path: root/pcbnew/kicad_plugin.h
blob: f81555f2a3ce936a9af51d21800b0de9b552ee01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2012 CERN.
 * 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
 */

#ifndef KICAD_PLUGIN_H_
#define KICAD_PLUGIN_H_

#include <io_mgr.h>
#include <string>
#include <layers_id_colors_and_visibility.h>

class BOARD;
class BOARD_ITEM;
class FP_CACHE;
class PCB_PARSER;
class NETINFO_MAPPING;


/// Current s-expression file format version.  2 was the last legacy format version.

//#define SEXPR_BOARD_FILE_VERSION    3     // first s-expression format, used legacy cu stack
#define SEXPR_BOARD_FILE_VERSION    4       // reversed cu stack, changed Inner* to In* in reverse order
                                            // went to 32 Cu layers from 16.

#define CTL_STD_LAYER_NAMES         (1 << 0)    ///< Use English Standard layer names
#define CTL_OMIT_NETS               (1 << 1)    ///< Omit pads net names (useless in library)
#define CTL_OMIT_TSTAMPS            (1 << 2)    ///< Omit component time stamp (useless in library)
#define CTL_OMIT_INITIAL_COMMENTS   (1 << 3)    ///< omit MODULE initial comments
#define CTL_OMIT_PATH               (1 << 4)    ///< Omit component sheet time stamp (useless in library)
#define CTL_OMIT_AT                 (1 << 5)    ///< Omit position and rotation
                                                // (always saved with potion 0,0 and rotation = 0 in library)


// common combinations of the above:

/// Format output for the clipboard instead of footprint library or BOARD
#define CTL_FOR_CLIPBOARD           (CTL_STD_LAYER_NAMES|CTL_OMIT_NETS)

/// Format output for a footprint library instead of clipboard or BOARD
#define CTL_FOR_LIBRARY             (CTL_STD_LAYER_NAMES|CTL_OMIT_NETS|CTL_OMIT_TSTAMPS|CTL_OMIT_PATH|CTL_OMIT_AT)

/// The zero arg constructor when PCB_IO is used for PLUGIN::Load() and PLUGIN::Save()ing
/// a BOARD file underneath IO_MGR.
#define CTL_FOR_BOARD               (CTL_OMIT_INITIAL_COMMENTS)


class DIMENSION;
class EDGE_MODULE;
class DRAWSEGMENT;
class PCB_TARGET;
class D_PAD;
class TEXTE_MODULE;
class TRACK;
class ZONE_CONTAINER;
class TEXTE_PCB;



/**
 * Class PCB_IO
 * is a PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
 *
 * @note This class is not thread safe, but it is re-entrant multiple times in sequence.
 */
class PCB_IO : public PLUGIN
{
    friend class FP_CACHE;

public:

    //-----<PLUGIN API>---------------------------------------------------------

    const wxString PluginName() const
    {
        return wxT( "KiCad" );
    }

    const wxString GetFileExtension() const
    {
        // Would have used wildcards_and_files_ext.cpp's KiCadPcbFileExtension,
        // but to be pure, a plugin should not assume that it will always be linked
        // with the core of the pcbnew code. (Might someday be a DLL/DSO.)  Besides,
        // file extension policy should be controlled by the plugin.
        return wxT( "kicad_pcb" );
    }

    void Save( const wxString& aFileName, BOARD* aBoard,
               const PROPERTIES* aProperties = NULL );          // overload

    BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties = NULL );

    wxArrayString FootprintEnumerate( const wxString& aLibraryPath,
            const PROPERTIES* aProperties = NULL );

    MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
            const PROPERTIES* aProperties = NULL );

    void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
                        const PROPERTIES* aProperties = NULL );

    void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties = NULL );

    void FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL);

    bool FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL );

    bool IsFootprintLibWritable( const wxString& aLibraryPath );

    //-----</PLUGIN API>--------------------------------------------------------

    PCB_IO( int aControlFlags = CTL_FOR_BOARD );

    ~PCB_IO();

    /**
     * Function Format
     * outputs \a aItem to \a aFormatter in s-expression format.
     *
     * @param aItem A pointer the an #BOARD_ITEM object to format.
     * @param aNestLevel The indentation nest level.
     * @throw IO_ERROR on write error.
     */
    void Format( BOARD_ITEM* aItem, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    std::string GetStringOutput( bool doClear )
    {
        std::string ret = m_sf.GetString();
        if( doClear )
            m_sf.Clear();

        return ret;
    }

    void SetOutputFormatter( OUTPUTFORMATTER* aFormatter ) { m_out = aFormatter; }

    BOARD_ITEM* Parse( const wxString& aClipboardSourceInput )
        throw( FUTURE_FORMAT_ERROR, PARSE_ERROR, IO_ERROR );

protected:

    wxString        m_error;        ///< for throwing exceptions
    BOARD*          m_board;        ///< which BOARD, no ownership here

    const
    PROPERTIES*     m_props;        ///< passed via Save() or Load(), no ownership, may be NULL.
    FP_CACHE*       m_cache;        ///< Footprint library cache.

    LINE_READER*    m_reader;       ///< no ownership here.
    wxString        m_filename;     ///< for saves only, name is in m_reader for loads

    int             m_loading_format_version; ///< which #SEXPR_BOARD_FILE_VERSION should be Load()ed?

    STRING_FORMATTER    m_sf;
    OUTPUTFORMATTER*    m_out;      ///< output any Format()s to this, no ownership
    int                 m_ctl;
    PCB_PARSER*         m_parser;
    NETINFO_MAPPING*    m_mapping;  ///< mapping for net codes, so only not empty net codes
                                    ///< are stored with consecutive integers as net codes

    /// we only cache one footprint library, this determines which one.
    void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString );

    void init( const PROPERTIES* aProperties );

private:
    void format( BOARD* aBoard, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( DIMENSION* aDimension, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( EDGE_MODULE* aModuleDrawing, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( DRAWSEGMENT* aSegment, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( PCB_TARGET* aTarget, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( MODULE* aModule, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( D_PAD* aPad, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( TEXTE_PCB* aText, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( TEXTE_MODULE* aText, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( TRACK* aTrack, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void format( ZONE_CONTAINER* aZone, int aNestLevel = 0 ) const
        throw( IO_ERROR );

    void formatLayer( const BOARD_ITEM* aItem ) const;

    void formatLayers( LSET aLayerMask, int aNestLevel = 0 ) const
        throw( IO_ERROR );
};

#endif  // KICAD_PLUGIN_H_