KiCad PCB EDA Suite
Loading...
Searching...
No Matches
jobset.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2024 Mark Roszko <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <i18n_utility.h>
22#include <json_common.h>
23
24#include <settings/parameters.h>
26
27#include <jobs/jobset.h>
28#include <jobs/job_registry.h>
29#include <jobs/job_unknown.h>
32#include <kiid.h>
33#include <reporter.h>
34#include <wx/filename.h>
35
36#include <algorithm>
37#include <memory>
38
40
41
42KICOMMON_API std::map<JOBSET_DESTINATION_T, JOBSET_DESTINATION_T_INFO> JobsetDestinationTypeInfos =
43{
44 { JOBSET_DESTINATION_T::FOLDER,
45 { _HKI( "Folder" ), BITMAPS::small_folder, true, "" } },
46 { JOBSET_DESTINATION_T::ARCHIVE,
47 { _HKI( "Archive" ), BITMAPS::zip, false, FILEEXT::ZipFileWildcard() } },
48};
49
50
52 {
53 { JOBSET_DESTINATION_T::FOLDER, "folder" },
54 { JOBSET_DESTINATION_T::ARCHIVE, "archive" }
55 } )
56
57KICOMMON_API void to_json( nlohmann::json& j, const JOBSET_JOB& f )
58{
59 j = nlohmann::json{ { "id", f.m_id },
60 { "type", f.m_type },
61 { "description", f.m_description },
62 { "settings", nlohmann::json::object( {} ) }
63 };
64
65 f.m_job->ToJson( j.at( "settings" ) );
66}
67
68
69KICOMMON_API void from_json( const nlohmann::json& j, JOBSET_JOB& f )
70{
71 j.at( "type" ).get_to( f.m_type );
72 j.at( "id" ).get_to( f.m_id );
73 f.m_description = j.value( "description", "" );
74
75 nlohmann::json settings_obj = j.at( "settings" );
76
78
79 if( f.m_job != nullptr )
80 f.m_job->FromJson( settings_obj );
81 else
82 f.m_job = std::make_shared<JOB_UNKNOWN>( f.m_type.ToStdString(), settings_obj );
83}
84
85
86KICOMMON_API void to_json( nlohmann::json& j, const JOBSET_DESTINATION& destination )
87{
88 j = nlohmann::json{ { "id", destination.m_id },
89 { "type", destination.m_type },
90 { "only", destination.m_only },
91 { "description", destination.m_description },
92 { "settings", nlohmann::json::object( {} ) }
93 };
94
95 destination.m_outputHandler->ToJson( j.at( "settings" ) );
96}
97
98
99KICOMMON_API void from_json( const nlohmann::json& j, JOBSET_DESTINATION& destination )
100{
101 // During 9.0 development outputs didn't get ids.
102 if( j.contains( "id" ) )
103 j.at( "id" ).get_to( destination.m_id );
104 else
105 destination.m_id = KIID().AsString();
106
107 j.at( "type" ).get_to( destination.m_type );
108 destination.m_only = j.value( "only", std::vector<wxString>() );
109 destination.m_description = j.value( "description", "" );
110
111 const nlohmann::json& settings_obj = j.at( "settings" );
112
113 destination.InitOutputHandler();
114
115 if( destination.m_outputHandler != nullptr )
116 destination.m_outputHandler->FromJson( settings_obj );
117}
118
119
127
128
130 m_id( id ),
131 m_type( type ),
132 m_outputHandler( nullptr ),
135{
137}
138
139
141{
142 if( m_type == JOBSET_DESTINATION_T::FOLDER )
143 {
144 m_outputHandler = std::make_shared<JOBS_OUTPUT_FOLDER>( );
145 }
146 else if( m_type == JOBSET_DESTINATION_T::ARCHIVE )
147 {
148 m_outputHandler = std::make_shared<JOBS_OUTPUT_ARCHIVE>( );
149 }
150}
151
152
154{
155 return m_description.IsEmpty() ? m_outputHandler->GetDefaultDescription() : m_description;
156}
157
158
160{
161 return m_outputHandler->GetOutputPath();
162}
163
164void JOBSET_DESTINATION::SetDescription( const wxString& aDescription )
165{
166 if( aDescription == m_outputHandler->GetDefaultDescription() )
167 m_description = wxEmptyString;
168 else
169 m_description = aDescription;
170}
171
172
173bool JOBSET_JOB::operator==( const JOBSET_JOB & rhs ) const
174{
175 return rhs.m_type == m_type;
176}
177
178
180{
181 return m_description.IsEmpty() ? m_job->GetDefaultDescription() : m_description;
182}
183
184
185void JOBSET_JOB::SetDescription( const wxString& aDescription )
186{
187 if( aDescription == m_job->GetDefaultDescription() )
188 m_description = wxEmptyString;
189 else
190 m_description = aDescription;
191}
192
193
195{
196 return rhs.m_type == m_type;
197}
198
199
200JOBSET::JOBSET( const wxString& aFilename ) :
202 m_dirty( false )
203{
204 m_params.emplace_back( new PARAM_LIST<JOBSET_JOB>( "jobs", &m_jobs, {} ) );
205 m_params.emplace_back( new PARAM_LIST<JOBSET_DESTINATION>( "outputs", &m_destinations, {} ) );
206
207 m_fileNameWithoutPath = wxFileName( aFilename ).GetFullName();
208}
209
210
211wxString JOBSET::getFileExt() const
212{
214}
215
216
217void JOBSET::AddNewJob( wxString aType, JOB* aJob )
218{
219 m_jobs.emplace_back( KIID().AsString(), aType, aJob );
220 SetDirty();
221}
222
223
225{
226 m_destinations.emplace_back( KIID().AsString(), aType );
227 SetDirty();
228
229 return &m_destinations.back();
230}
231
232
234{
235 std::erase_if( m_destinations,
236 [&]( JOBSET_DESTINATION const& destination )
237 {
238 return destination.m_id == aDestination->m_id;
239 } );
240}
241
242
243void JOBSET::MoveJobUp( size_t aJobIdx )
244{
245 if( aJobIdx > 0 )
246 {
247 std::swap( m_jobs[aJobIdx], m_jobs[aJobIdx - 1] );
248 SetDirty();
249 }
250}
251
252
253void JOBSET::MoveJobDown( size_t aJobIdx )
254{
255 if( aJobIdx < m_jobs.size() - 1 )
256 {
257 std::swap( m_jobs[aJobIdx], m_jobs[aJobIdx + 1] );
258 SetDirty();
259 }
260}
261
262
263void JOBSET::RemoveJob( size_t aJobIdx )
264{
265 m_jobs.erase( m_jobs.begin() + aJobIdx );
266 SetDirty();
267}
268
269
270bool JOBSET::SaveToFile( const wxString& aDirectory, bool aForce )
271{
272 bool success = JSON_SETTINGS::SaveToFile( aDirectory, aForce );
273 if( success )
274 {
275 m_dirty = false;
276 }
277
278 return success;
279}
280
281
282JOBSET_DESTINATION* JOBSET::FindDestination( wxString& aDestinationStr )
283{
284 auto is_matching_dest = [&]( const JOBSET_DESTINATION& destination )
285 {
286 if( destination.m_id == aDestinationStr || destination.m_description == aDestinationStr )
287 return true;
288
289 return false;
290 };
291
292 auto count = std::count_if( m_destinations.begin(), m_destinations.end(), is_matching_dest );
293
294 // we want to intentionally fail if more than one matching dest exists
295 // as theres no good way to handle it
296 if( count != 1 )
297 return nullptr;
298
299 auto it = std::find_if( m_destinations.begin(), m_destinations.end(), is_matching_dest );
300
301 if( it != m_destinations.end() )
302 return &(*it);
303
304 return nullptr;
305}
306
307
308std::vector<JOBSET_JOB> JOBSET::GetJobsForDestination( JOBSET_DESTINATION* aDestination )
309{
310 wxASSERT( aDestination != nullptr );
311
312 if( aDestination->m_only.size() == 0 )
313 {
314 return m_jobs;
315 }
316
317 std::vector<JOBSET_JOB> result;
318 for( wxString& onlyId : aDestination->m_only )
319 {
320 auto it = std::find_if( m_jobs.begin(), m_jobs.end(),
321 [&]( const JOBSET_JOB& job )
322 {
323 if( job.m_id == onlyId )
324 return true;
325
326 return false;
327 } );
328
329 if( it != m_jobs.end() )
330 result.push_back( *it );
331 }
332
333 return result;
334}
335
336
337#if !defined( __MINGW32__ )
340#endif
wxString m_fileNameWithoutPath
Definition jobset.h:192
bool SaveToFile(const wxString &aDirectory="", bool aForce=false) override
Calls Store() and then writes the contents of the JSON document to a file.
Definition jobset.cpp:270
void SetDirty(bool aFlag=true)
Definition jobset.h:171
void MoveJobUp(size_t aJobIdx)
Definition jobset.cpp:243
std::vector< JOBSET_DESTINATION > m_destinations
Definition jobset.h:189
std::vector< JOBSET_JOB > GetJobsForDestination(JOBSET_DESTINATION *aDestination)
Definition jobset.cpp:308
std::vector< JOBSET_JOB > m_jobs
Definition jobset.h:188
void RemoveJob(size_t aJobIdx)
Definition jobset.cpp:263
void AddNewJob(wxString aType, JOB *aJob)
Definition jobset.cpp:217
void MoveJobDown(size_t aJobIdx)
Definition jobset.cpp:253
JOBSET_DESTINATION * AddNewDestination(JOBSET_DESTINATION_T aType)
Definition jobset.cpp:224
wxString getFileExt() const override
Definition jobset.cpp:211
bool m_dirty
Definition jobset.h:191
JOBSET(const wxString &aFilename)
Definition jobset.cpp:200
void RemoveDestination(JOBSET_DESTINATION *aDestination)
Definition jobset.cpp:233
JOBSET_DESTINATION * FindDestination(wxString &aDestinationStr)
Attempts to find a destination based on the given string Both the uuid of the destination and descrip...
Definition jobset.cpp:282
virtual void ToJson(nlohmann::json &j) const =0
virtual void FromJson(const nlohmann::json &j)=0
static T * CreateInstance(const wxString &aName)
An simple container class that lets us dispatch output jobs to kifaces.
Definition job.h:184
virtual void FromJson(const nlohmann::json &j)
Definition job.cpp:60
virtual void ToJson(nlohmann::json &j) const
Definition job.cpp:67
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
JSON_SETTINGS(const wxString &aFilename, SETTINGS_LOC aLocation, int aSchemaVersion)
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
Calls Store() and then writes the contents of the JSON document to a file.
Definition kiid.h:46
wxString AsString() const
Definition kiid.cpp:264
@ NONE
Definition eda_shape.h:72
static const std::string KiCadJobSetFileExtension
static wxString ZipFileWildcard()
Some functions to handle hotkeys in KiCad.
KICOMMON_API void to_json(nlohmann::json &j, const JOBSET_DESTINATION &destination)
Definition jobset.cpp:86
KICOMMON_API void from_json(const nlohmann::json &j, JOBSET_JOB &f)
Definition jobset.cpp:69
NLOHMANN_JSON_SERIALIZE_ENUM(JOBSET_DESTINATION_T, { { JOBSET_DESTINATION_T::FOLDER, "folder" }, { JOBSET_DESTINATION_T::ARCHIVE, "archive" } }) KICOMMON_API void to_json(nlohmann
Definition jobset.cpp:51
const int jobsFileSchemaVersion
Definition jobset.cpp:39
KICOMMON_API std::map< JOBSET_DESTINATION_T, JOBSET_DESTINATION_T_INFO > JobsetDestinationTypeInfos
Definition jobset.cpp:42
enum KICOMMON_API JOBSET_DESTINATION_T
Definition jobset.h:100
FOLDER
Definition jobset.h:101
SETTINGS_LOC
#define KICOMMON_API
Definition kicommon.h:27
#define _HKI(x)
Definition page_info.cpp:40
std::unordered_map< wxString, std::shared_ptr< JOBSET_OUTPUT_REPORTER > > m_lastRunReporters
Definition jobset.h:142
void SetDescription(const wxString &aDescription)
Definition jobset.cpp:164
std::shared_ptr< JOBS_OUTPUT_HANDLER > m_outputHandler
Definition jobset.h:136
JOBSET_DESTINATION_T m_type
Definition jobset.h:134
wxString m_description
Definition jobset.h:135
std::vector< wxString > m_only
Transient property, not stored for now.
Definition jobset.h:137
void InitOutputHandler()
Definition jobset.cpp:140
wxString GetPathInfo() const
Definition jobset.cpp:159
bool operator==(const JOBSET_DESTINATION &rhs) const
Definition jobset.cpp:194
wxString GetDescription() const
Definition jobset.cpp:153
std::optional< bool > m_lastRunSuccess
Definition jobset.h:140
wxString m_id
Definition jobset.h:133
wxString m_id
Definition jobset.h:87
std::shared_ptr< JOB > m_job
Definition jobset.h:90
wxString m_description
Definition jobset.h:89
wxString m_type
Definition jobset.h:88
bool operator==(const JOBSET_JOB &rhs) const
Definition jobset.cpp:173
JOBSET_JOB()
Definition jobset.h:77
wxString GetDescription() const
Definition jobset.cpp:179
void SetDescription(const wxString &aDescription)
Definition jobset.cpp:185
wxString result
Test unit parsing edge cases and error handling.
Definition of file extensions used in Kicad.