You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
8.7 KiB

13 years ago
13 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
  5. * Copyright (C) 2013-2021 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU 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, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #ifndef _REPORTER_H_
  25. #define _REPORTER_H_
  26. #include <memory>
  27. #include <eda_units.h>
  28. #include <widgets/report_severity.h>
  29. /**
  30. * @file reporter.h
  31. * @author Wayne Stambaugh
  32. * @note A special thanks to Dick Hollenbeck who came up with the idea that inspired
  33. * me to write this.
  34. * @warning Do not add any dependencies to wxWidgets (or any other third party UI library )
  35. * to the REPORTER object. All wxWidgets objects should be defined by pointer or
  36. * reference and forward declared so that using reporters in low level KiCad objects
  37. * will not require pulling in wxWidgets to building them.
  38. */
  39. class wxString;
  40. class wxStatusBar;
  41. class wxTextCtrl;
  42. class WX_HTML_REPORT_PANEL;
  43. class WX_INFOBAR;
  44. /**
  45. * A pure virtual class used to derive REPORTER objects from.
  46. *
  47. * The purpose of the REPORTER object is to offer a way for a procedural function
  48. * to report multiple errors without having to:
  49. * <ul>
  50. * <li> know too much about the caller's UI, i.e. wx. </li>
  51. * <li> stop after the first error </li>
  52. * </ul>
  53. * the reporter has 4 severity levels (flags) tagging the messages:
  54. * - information
  55. * - warning
  56. * - error
  57. * - action (i.e. indication of changes - add component, change footprint, etc. )
  58. *
  59. * They are indicators for the message formatting and displaying code,
  60. * filtering is not made here.
  61. */
  62. class REPORTER
  63. {
  64. public:
  65. /**
  66. * Location where the message is to be reported.
  67. * LOC_HEAD messages are printed before all others (typically intro messages)
  68. * LOC_BODY messages are printed in the middle
  69. * LOC_TAIL messages are printed after all others (typically status messages)
  70. */
  71. enum LOCATION {
  72. LOC_HEAD = 0,
  73. LOC_BODY,
  74. LOC_TAIL
  75. };
  76. /**
  77. * Report a string with a given severity.
  78. *
  79. * @param aText is the string to report.
  80. * @param aSeverity is an indicator ( RPT_UNDEFINED, RPT_INFO, RPT_WARNING, RPT_ERROR,
  81. * RPT_ACTION ) used to filter and format messages
  82. */
  83. virtual REPORTER& Report( const wxString& aText,
  84. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) = 0;
  85. /**
  86. * Places the report at the end of the list, for objects that support report ordering
  87. */
  88. virtual REPORTER& ReportTail( const wxString& aText,
  89. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED )
  90. {
  91. return Report( aText, aSeverity );
  92. }
  93. /**
  94. * Places the report at the beginning of the list for objects that support ordering.
  95. */
  96. virtual REPORTER& ReportHead( const wxString& aText,
  97. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED )
  98. {
  99. return Report( aText, aSeverity );
  100. }
  101. REPORTER& Report( const char* aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED );
  102. REPORTER& operator <<( const wxString& aText ) { return Report( aText ); }
  103. /**
  104. * Returns true if the reporter client is non-empty.
  105. */
  106. virtual bool HasMessage() const = 0;
  107. virtual EDA_UNITS GetUnits() const
  108. {
  109. return EDA_UNITS::MILLIMETRES;
  110. }
  111. virtual ~REPORTER()
  112. {
  113. }
  114. };
  115. /**
  116. * A wrapper for reporting to a wxTextCtrl object.
  117. */
  118. class WX_TEXT_CTRL_REPORTER : public REPORTER
  119. {
  120. public:
  121. WX_TEXT_CTRL_REPORTER( wxTextCtrl* aTextCtrl ) :
  122. REPORTER(),
  123. m_textCtrl( aTextCtrl )
  124. {
  125. }
  126. virtual ~WX_TEXT_CTRL_REPORTER()
  127. {
  128. }
  129. REPORTER& Report( const wxString& aText,
  130. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  131. bool HasMessage() const override;
  132. private:
  133. wxTextCtrl* m_textCtrl;
  134. };
  135. /**
  136. * A wrapper for reporting to a wxString object.
  137. */
  138. class WX_STRING_REPORTER : public REPORTER
  139. {
  140. public:
  141. WX_STRING_REPORTER( wxString* aString ) :
  142. REPORTER(),
  143. m_string( aString )
  144. {
  145. }
  146. virtual ~WX_STRING_REPORTER()
  147. {
  148. }
  149. REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  150. bool HasMessage() const override;
  151. private:
  152. wxString* m_string;
  153. };
  154. /**
  155. * A wrapper for reporting to a wx HTML window.
  156. */
  157. class WX_HTML_PANEL_REPORTER : public REPORTER
  158. {
  159. public:
  160. WX_HTML_PANEL_REPORTER( WX_HTML_REPORT_PANEL* aPanel ) :
  161. REPORTER(),
  162. m_panel( aPanel )
  163. {
  164. }
  165. virtual ~WX_HTML_PANEL_REPORTER()
  166. {
  167. }
  168. REPORTER& Report( const wxString& aText,
  169. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  170. REPORTER& ReportTail( const wxString& aText,
  171. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  172. REPORTER& ReportHead( const wxString& aText,
  173. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  174. bool HasMessage() const override;
  175. private:
  176. WX_HTML_REPORT_PANEL* m_panel;
  177. };
  178. /**
  179. * A singleton reporter that reports to nowhere.
  180. *
  181. * Used as to simplify code by avoiding the reportee to check for a non-NULL reporter object.
  182. */
  183. class NULL_REPORTER : public REPORTER
  184. {
  185. public:
  186. NULL_REPORTER()
  187. {
  188. }
  189. virtual ~NULL_REPORTER()
  190. {
  191. }
  192. static REPORTER& GetInstance();
  193. REPORTER& Report( const wxString& aText,
  194. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  195. bool HasMessage() const override { return false; }
  196. };
  197. /**
  198. * Debug type reporter, forwarding messages to std::cout.
  199. */
  200. class STDOUT_REPORTER : public REPORTER
  201. {
  202. public:
  203. STDOUT_REPORTER()
  204. {
  205. }
  206. virtual ~STDOUT_REPORTER()
  207. {
  208. }
  209. static REPORTER& GetInstance();
  210. REPORTER& Report( const wxString& aMsg, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  211. bool HasMessage() const override { return false; }
  212. };
  213. class WXLOG_REPORTER : public REPORTER
  214. {
  215. public:
  216. WXLOG_REPORTER()
  217. {
  218. }
  219. virtual ~WXLOG_REPORTER()
  220. {
  221. }
  222. static REPORTER& GetInstance();
  223. REPORTER& Report( const wxString& aMsg, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  224. bool HasMessage() const override { return false; }
  225. };
  226. /**
  227. * A wrapper for reporting to a specific text location in a statusbar.
  228. */
  229. class STATUSBAR_REPORTER : public REPORTER
  230. {
  231. public:
  232. STATUSBAR_REPORTER( wxStatusBar* aStatusBar, int aPosition = 0 )
  233. : REPORTER(),
  234. m_statusBar( aStatusBar ),
  235. m_position( aPosition )
  236. {
  237. }
  238. REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  239. bool HasMessage() const override;
  240. private:
  241. wxStatusBar* m_statusBar;
  242. int m_position;
  243. };
  244. /**
  245. * A wrapper for reporting to a #WX_INFOBAR UI element.
  246. *
  247. * The infobar is not updated until the @c Finalize() method is called. That method will
  248. * queue either a show message or a dismiss event for the infobar - so this reporter is
  249. * safe to use inside a paint event without causing an infinite paint event loop.
  250. *
  251. * No action is taken if no message is given to the reporter.
  252. */
  253. class INFOBAR_REPORTER : public REPORTER
  254. {
  255. public:
  256. INFOBAR_REPORTER( WX_INFOBAR* aInfoBar )
  257. : REPORTER(),
  258. m_messageSet( false ),
  259. m_infoBar( aInfoBar ),
  260. m_severity( RPT_SEVERITY_UNDEFINED )
  261. {
  262. }
  263. virtual ~INFOBAR_REPORTER();
  264. REPORTER& Report( const wxString& aText,
  265. SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override;
  266. bool HasMessage() const override;
  267. /**
  268. * Update the infobar with the reported text.
  269. */
  270. void Finalize();
  271. private:
  272. bool m_messageSet;
  273. WX_INFOBAR* m_infoBar;
  274. std::unique_ptr<wxString> m_message;
  275. SEVERITY m_severity;
  276. };
  277. #endif // _REPORTER_H_