File: pgm_base.h

package info (click to toggle)
kicad 9.0.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 769,124 kB
  • sloc: cpp: 960,330; ansic: 121,001; xml: 66,428; python: 18,382; sh: 1,010; awk: 301; asm: 292; makefile: 227; javascript: 167; perl: 10
file content (462 lines) | stat: -rw-r--r-- 14,935 bytes parent folder | download | duplicates (4)
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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
 * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@gmail.com>
 * Copyright The 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
 */

/**
 * @file pgm_base.h
 * @brief see class PGM_BASE
 */

#ifndef  PGM_BASE_H_
#define  PGM_BASE_H_

#include <kicommon.h>
#include <singleton.h>
#include <exception>
#include <map>
#include <vector>
#include <memory>
#include <search_stack.h>
#include <settings/environment.h>
#include <wx/filename.h>

class wxApp;
class wxMenu;
class wxWindow;
class wxSplashScreen;
class wxSingleInstanceChecker;

class BACKGROUND_JOBS_MONITOR;
class NOTIFICATIONS_MANAGER;
class COMMON_SETTINGS;
class SETTINGS_MANAGER;
class SCRIPTING;

#ifdef KICAD_IPC_API
class API_PLUGIN_MANAGER;
class KICAD_API_SERVER;
#endif

/**
 * A small class to handle the list of existing translations.
 *
 * The locale translation is automatic.  The selection of languages is mainly for
 * maintainer's convenience.  To add a support to a new translation add a new item
 * to #LanguagesList[].
 */
struct KICOMMON_API LANGUAGE_DESCR
{
    /// wxWidgets locale identifier (See wxWidgets doc)
    int         m_WX_Lang_Identifier;

    /// KiCad identifier used in menu selection (See id.h)
    int         m_KI_Lang_Identifier;

    /// Labels used in menus
    wxString    m_Lang_Label;

    /// Set to true if the m_Lang_Label must not be translated
    bool        m_DoNotTranslate;
};


/**
 * An array containing all the languages that KiCad supports.
 */
KICOMMON_API extern LANGUAGE_DESCR LanguagesList[];

/**
 * Container for data for KiCad programs.
 *
 * The functions are virtual so we can do cross module calls without linking to them.  This
 * used to be a wxApp derivative, but that is difficult under wxPython which shapes the wxApp.
 * So now this is a "side-car" (like a motorcycle side-car) object with a back pointer into
 * the wxApp which initializes it.
 *
 * - OnPgmStart() is virtual, may be overridden, and parallels wxApp::OnInit(), from where it
 *   should called.
 * - OnPgmEnd() is virtual, may be overridden, and parallels wxApp::OnExit(), from where it
 *   should be called.
 */
class KICOMMON_API PGM_BASE
{
public:
    PGM_BASE();
    virtual ~PGM_BASE();

    /**
     * Builds the UTF8 based argv variable
     */
    void BuildArgvUtf8();

    BS::thread_pool& GetThreadPool() { return *m_singleton.m_ThreadPool; }

    GL_CONTEXT_MANAGER* GetGLContextManager() { return m_singleton.m_GLContextManager; }

    /**
     * Specific to MacOSX (not used under Linux or Windows).
     *
     * MacOSX requires it for file association.
     * @see http://wiki.wxwidgets.org/WxMac-specific_topics
     */
    virtual void MacOpenFile( const wxString& aFileName ) = 0;

    virtual SETTINGS_MANAGER& GetSettingsManager() const { return *m_settings_manager; }

    virtual COMMON_SETTINGS*  GetCommonSettings() const;

    virtual BACKGROUND_JOBS_MONITOR& GetBackgroundJobMonitor() const
    {
        return *m_background_jobs_monitor;
    }

    virtual NOTIFICATIONS_MANAGER& GetNotificationsManager() const
    {
        return *m_notifications_manager;
    }

#ifdef KICAD_IPC_API
    virtual API_PLUGIN_MANAGER& GetPluginManager() const { return *m_plugin_manager; }

    KICAD_API_SERVER& GetApiServer() { return *m_api_server; }
#endif

    virtual void SetTextEditor( const wxString& aFileName );

    /**
     * Return the path to the preferred text editor application.
     *
     * @param   aCanShowFileChooser If no editor is currently set and this argument is
     *          'true' then this method will show a file chooser dialog asking for the
     *          editor's executable.
     * @return  Returns the full path of the editor, or an empty string if no editor has
     *          been set.
     */
    virtual const wxString& GetTextEditor( bool aCanShowFileChooser = true );

    /**
     * Show a dialog that instructs the user to select a new preferred editor.
     *
     * @param   aDefaultEditor Default full path for the default editor this dialog should
     *          show by default.
     * @return  the full path of the editor, or an empty string if no editor was chosen.
     */
    virtual const wxString AskUserForPreferredEditor(
            const wxString& aDefaultEditor = wxEmptyString );

    virtual bool IsKicadEnvVariableDefined() const               { return !m_kicad_env.IsEmpty(); }

    virtual const wxString& GetKicadEnvVariable() const          { return m_kicad_env; }

    virtual const wxString& GetExecutablePath() const;

    virtual wxLocale* GetLocale()                                { return m_locale; }

    virtual const wxString& GetPdfBrowserName() const            { return m_pdf_browser; }

    virtual void SetPdfBrowserName( const wxString& aFileName )  { m_pdf_browser = aFileName; }

    /**
     * @return true if the PDF browser is the default (system) PDF browser and false if the
     *         PDF browser is the preferred (selected) browser, else returns false if there
     *         is no selected browser.
     */
    virtual bool UseSystemPdfBrowser() const
    {
        return m_use_system_pdf_browser || m_pdf_browser.IsEmpty();
    }

    /**
     * Force the use of system PDF browser, even if a preferred PDF browser is set.
     */
    virtual void ForceSystemPdfBrowser( bool aFlg ) { m_use_system_pdf_browser = aFlg; }

    /**
     * Set the dictionary file name for internationalization.
     *
     * The files are in kicad/internat/xx or kicad/internat/xx_XX and are named kicad.mo
     *
     * @param aErrMsg is the string to return the error message it.
     * @param first_time must be set to true the first time this function is called,
     *                   false otherwise.
     * @return false if there was an error setting the language.
     */
    virtual bool SetLanguage( wxString& aErrMsg, bool first_time = false );

    /**
     * Set the default language without reference to any preferences.
     *
     * Can be used to set the language for dialogs that show before preferences are loaded.
     *
     * @param aErrMsg String to return the error message(s) in.
     * @return false if the language could not be set.
     */
    bool SetDefaultLanguage( wxString& aErrMsg );

    /**
     * Set in .m_language_id member the wxWidgets language identifier ID from the KiCad
     * menu id (internal menu identifier).
     *
     * @param menu_id The KiCad menuitem id (returned by Menu Event, when clicking on a
     *                 menu item)
     */
    virtual void SetLanguageIdentifier( int menu_id );

    /**
     * @return the wxWidgets language identifier Id of the language currently selected.
     */
    virtual int GetSelectedLanguageIdentifier() const { return m_language_id; }

    /**
     * @return the current selected language in rfc3066 format
     */
    virtual wxString GetLanguageTag();

    virtual void SetLanguagePath();

    /**
     * Read the PDF browser choice from the common configuration.
     */
    virtual void ReadPdfBrowserInfos();

    /**
     * Save the PDF browser choice to the common configuration.
     */
    virtual void WritePdfBrowserInfos();

    /**
     * Set the environment variable \a aName to \a aValue.
     *
     * This function first checks to see if the environment variable \a aName is already
     * defined.  If it is not defined, then the environment variable \a aName is set to
     * a value.  Otherwise, the environment variable is left unchanged.  This allows the user
     * to override environment variables for testing purposes.
     *
     * @param aName is a wxString containing the environment variable name.
     * @param aValue is a wxString containing the environment variable value.
     * @return true if the environment variable \a Name was set to \a aValue.
     */
    virtual bool SetLocalEnvVariable( const wxString& aName, const wxString& aValue );

    /**
     * Update the local environment with the contents of the current #ENV_VAR_MAP stored in the
     * #COMMON_SETTINGS.
     *
     * @see GetLocalEnvVariables()
     */
    virtual void SetLocalEnvVariables();

    virtual ENV_VAR_MAP& GetLocalEnvVariables() const;

    /**
     * Return a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
     *
     * This should return what wxGetApp() returns.
     */
    virtual wxApp&   App();

    static const wxChar workingDirKey[];

    /**
     * Initialize this program.
     *
     * Initialize the process in a KiCad standard way using some generalized techniques:
     *  - Default paths (help, libs, bin) and configuration file names
     *  - Language and locale
     *  - fonts
     *
     * @note Do not initialize anything relating to DSOs or projects.
     *
     * @param aHeadless If true, run in headless mode (e.g. for unit tests)
     * @param aSkipPyInit If true, do not init python stuff.
     * Useful in application that do not use python, to disable python dependency at run time
     * @return true if success, false if failure and program is to terminate.
     */
    bool InitPgm( bool aHeadless = false, bool aSkipPyInit = false, bool aIsUnitTest = false );

    // The PGM_* classes can have difficulties at termination if they
    // are not destroyed soon enough.  Relying on a static destructor can be
    // too late for contained objects like wxSingleInstanceChecker.
    void Destroy();

    /**
     * Save the program (process) settings subset which are stored .kicad_common.
     */
    void SaveCommonSettings();

#ifdef KICAD_USE_SENTRY
    /**
     * @return True if the user agreed to sentry data collection
     */
    bool IsSentryOptedIn();

    /**
     * Set the Sentry opt in state, this will also terminate sentry
     * immediately if needed, however it will not init sentry if opted in.
     *
     * @param aOptIn True/false to agreeing to the use of sentry.
     */
    void SetSentryOptIn( bool aOptIn );

    /**
     * Generate and stores a new sentry id at random using the boost uuid generator.
     */
    void ResetSentryId();

    /**
     * Get the current id string being used as "user id" in sentry reports.
     */
    const wxString& GetSentryId();
#endif

    /**
     * A exception handler to be used at the top level if exceptions bubble up that for.
     *
     * The purpose is to have a central place to log a wxWidgets error message and/or sentry report.
     *
     * @param aPtr Pass the std::current_exception() from within the catch block.
     */
    void HandleException( std::exception_ptr aPtr );

    /**
     * A common assert handler to be used between single_top and kicad.
     *
     * This lets us have a common set of assert handling, including triggering sentry reports.
     *
     * @param aFile the file path of the assert.
     * @param aLine the line number of the assert.
     * @param aFunc the function name the assert is within.
     * @param aCond the condition of the assert.
     * @param aMsg the attached assert message (can be empty).
     */
    void HandleAssert( const wxString& aFile, int aLine, const wxString& aFunc,
                       const wxString& aCond, const wxString& aMsg );

    /**
     * Determine if the application is running with a GUI.
     *
     * @return true if there is a GUI and false otherwise.
     */
    bool IsGUI();


    void ShowSplash();
    void HideSplash();

    /**
     * Allow access to the wxSingleInstanceChecker to test for other running KiCads.
     */
    std::unique_ptr<wxSingleInstanceChecker>& SingleInstance()
    {
        return m_pgm_checker;
    }

    /**
     * wxWidgets on MSW tends to crash if you spool up more than one print job at a time.
     */
    bool m_Printing;

    std::vector<void*> m_ModalDialogs;

    bool m_Quitting;

    bool m_PropertyGridInitialized;

protected:
    /// Load internal settings from #COMMON_SETTINGS.
    void loadCommonSettings();

    /// Trap all changes in here, simplifies debugging.
    void setLanguageId( int aId )       { m_language_id = aId; }

#ifdef KICAD_USE_SENTRY
    void     sentryInit();
    void     sentryPrompt();
    wxString sentryCreateUid();
#endif

protected:
    std::unique_ptr<SETTINGS_MANAGER> m_settings_manager;
    std::unique_ptr<BACKGROUND_JOBS_MONITOR> m_background_jobs_monitor;
    std::unique_ptr<NOTIFICATIONS_MANAGER> m_notifications_manager;

    std::unique_ptr<SCRIPTING> m_python_scripting;

    /// Check if there is another copy of Kicad running at the same time.
    std::unique_ptr<wxSingleInstanceChecker> m_pgm_checker;

#ifdef KICAD_IPC_API
    std::unique_ptr<API_PLUGIN_MANAGER> m_plugin_manager;
    std::unique_ptr<KICAD_API_SERVER> m_api_server;
#endif

    wxString        m_kicad_env;              ///< The KICAD system environment variable.

    wxLocale*       m_locale;
    int             m_language_id;

    bool            m_use_system_pdf_browser;
    wxString        m_pdf_browser;            ///< Filename of the app selected for browsing PDFs.

    wxString        m_text_editor;

    KICAD_SINGLETON m_singleton;

#ifdef KICAD_USE_SENTRY
    wxFileName      m_sentry_optin_fn;
    wxFileName      m_sentry_uid_fn;
    wxString        m_sentryUid;
#endif

    /**
     * argv parameters converted to utf8 form because wxWidgets has opinions.
     *
     * This will return argv as either force converted to ASCII in char* or wchar_t only.
     */
    char** m_argvUtf8;

    int m_argcUtf8;

    wxSplashScreen* m_splash;
};


/**
 * The global program "get" accessor.
 *
 * Implemented in:
 *    1. common/single_top.cpp
 *    2. kicad/kicad.cpp
 *    3. scripting/kiway.i
 */
KICOMMON_API extern PGM_BASE& Pgm();

/// Return a reference that can be nullptr when running a shared lib from a script, not from
/// a kicad app.
KICOMMON_API extern PGM_BASE* PgmOrNull();

KICOMMON_API extern void SetPgm( PGM_BASE* pgm );


#endif  // PGM_BASE_H_