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.

352 lines
9.3 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <kiway_player.h>
  24. #include <fp_text_grid_table.h>
  25. #include <widgets/grid_icon_text_helpers.h>
  26. #include <widgets/grid_combobox.h>
  27. #include <trigo.h>
  28. #include <pcb_base_frame.h>
  29. #include "grid_layer_box_helpers.h"
  30. enum
  31. {
  32. MYID_SELECT_FOOTPRINT = 991, // must be within GRID_TRICKS' enum range
  33. MYID_SHOW_DATASHEET
  34. };
  35. wxArrayString g_menuOrientations;
  36. FP_TEXT_GRID_TABLE::FP_TEXT_GRID_TABLE( PCB_BASE_FRAME* aFrame ) :
  37. m_frame( aFrame )
  38. {
  39. // Build the column attributes.
  40. m_readOnlyAttr = new wxGridCellAttr;
  41. m_readOnlyAttr->SetReadOnly( true );
  42. m_boolColAttr = new wxGridCellAttr;
  43. m_boolColAttr->SetRenderer( new wxGridCellBoolRenderer() );
  44. m_boolColAttr->SetEditor( new wxGridCellBoolEditor() );
  45. m_boolColAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
  46. if( g_menuOrientations.IsEmpty() )
  47. {
  48. g_menuOrientations.push_back( "0" + GetAbbreviatedUnitsLabel( EDA_UNITS::DEGREES ) );
  49. g_menuOrientations.push_back( "90" + GetAbbreviatedUnitsLabel( EDA_UNITS::DEGREES ) );
  50. g_menuOrientations.push_back( "-90" + GetAbbreviatedUnitsLabel( EDA_UNITS::DEGREES ) );
  51. g_menuOrientations.push_back( "180" + GetAbbreviatedUnitsLabel( EDA_UNITS::DEGREES ) );
  52. }
  53. m_orientationColAttr = new wxGridCellAttr;
  54. m_orientationColAttr->SetEditor( new GRID_CELL_COMBOBOX( g_menuOrientations ) );
  55. m_layerColAttr = new wxGridCellAttr;
  56. m_layerColAttr->SetRenderer( new GRID_CELL_LAYER_RENDERER( m_frame ) );
  57. m_layerColAttr->SetEditor( new GRID_CELL_LAYER_SELECTOR( m_frame, {} ) );
  58. m_frame->Bind( UNITS_CHANGED, &FP_TEXT_GRID_TABLE::onUnitsChanged, this );
  59. }
  60. FP_TEXT_GRID_TABLE::~FP_TEXT_GRID_TABLE()
  61. {
  62. m_readOnlyAttr->DecRef();
  63. m_boolColAttr->DecRef();
  64. m_orientationColAttr->DecRef();
  65. m_layerColAttr->DecRef();
  66. m_frame->Unbind( UNITS_CHANGED, &FP_TEXT_GRID_TABLE::onUnitsChanged, this );
  67. }
  68. void FP_TEXT_GRID_TABLE::onUnitsChanged( wxCommandEvent& aEvent )
  69. {
  70. if( GetView() )
  71. GetView()->ForceRefresh();
  72. aEvent.Skip();
  73. }
  74. wxString FP_TEXT_GRID_TABLE::GetColLabelValue( int aCol )
  75. {
  76. switch( aCol )
  77. {
  78. case FPT_TEXT: return _( "Text Items" );
  79. case FPT_SHOWN: return _( "Show" );
  80. case FPT_WIDTH: return _( "Width" );
  81. case FPT_HEIGHT: return _( "Height" );
  82. case FPT_THICKNESS: return _( "Thickness" );
  83. case FPT_ITALIC: return _( "Italic" );
  84. case FPT_LAYER: return _( "Layer" );
  85. case FPT_ORIENTATION: return _( "Orientation" );
  86. case FPT_UPRIGHT: return _( "Keep Upright" );
  87. case FPT_XOFFSET: return _( "X Offset" );
  88. case FPT_YOFFSET: return _( "Y Offset" );
  89. default: wxFAIL; return wxEmptyString;
  90. }
  91. }
  92. wxString FP_TEXT_GRID_TABLE::GetRowLabelValue( int aRow )
  93. {
  94. switch( aRow )
  95. {
  96. case 0: return _( "Reference designator" );
  97. case 1: return _( "Value" );
  98. default: return wxEmptyString;
  99. }
  100. }
  101. bool FP_TEXT_GRID_TABLE::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
  102. {
  103. switch( aCol )
  104. {
  105. case FPT_TEXT:
  106. case FPT_WIDTH:
  107. case FPT_HEIGHT:
  108. case FPT_THICKNESS:
  109. case FPT_ORIENTATION:
  110. case FPT_XOFFSET:
  111. case FPT_YOFFSET:
  112. return aTypeName == wxGRID_VALUE_STRING;
  113. case FPT_SHOWN:
  114. case FPT_ITALIC:
  115. case FPT_UPRIGHT:
  116. return aTypeName == wxGRID_VALUE_BOOL;
  117. case FPT_LAYER:
  118. return aTypeName == wxGRID_VALUE_NUMBER;
  119. default:
  120. wxFAIL;
  121. return false;
  122. }
  123. }
  124. bool FP_TEXT_GRID_TABLE::CanSetValueAs( int aRow, int aCol, const wxString& aTypeName )
  125. {
  126. return CanGetValueAs( aRow, aCol, aTypeName );
  127. }
  128. wxGridCellAttr* FP_TEXT_GRID_TABLE::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
  129. {
  130. switch( aCol )
  131. {
  132. case FPT_TEXT:
  133. case FPT_WIDTH:
  134. case FPT_HEIGHT:
  135. case FPT_THICKNESS:
  136. case FPT_XOFFSET:
  137. case FPT_YOFFSET:
  138. return nullptr;
  139. case FPT_SHOWN:
  140. case FPT_ITALIC:
  141. case FPT_UPRIGHT:
  142. m_boolColAttr->IncRef();
  143. return m_boolColAttr;
  144. case FPT_LAYER:
  145. m_layerColAttr->IncRef();
  146. return m_layerColAttr;
  147. case FPT_ORIENTATION:
  148. m_orientationColAttr->IncRef();
  149. return m_orientationColAttr;
  150. default:
  151. wxFAIL;
  152. return nullptr;
  153. }
  154. }
  155. wxString FP_TEXT_GRID_TABLE::GetValue( int aRow, int aCol )
  156. {
  157. const FP_TEXT& text = this->at( (size_t) aRow );
  158. switch( aCol )
  159. {
  160. case FPT_TEXT:
  161. return text.GetText();
  162. case FPT_WIDTH:
  163. return StringFromValue( m_frame->GetUserUnits(), text.GetTextWidth(), true );
  164. case FPT_HEIGHT:
  165. return StringFromValue( m_frame->GetUserUnits(), text.GetTextHeight(), true );
  166. case FPT_THICKNESS:
  167. return StringFromValue( m_frame->GetUserUnits(), text.GetTextThickness(), true );
  168. case FPT_LAYER:
  169. return text.GetLayerName();
  170. case FPT_ORIENTATION:
  171. return StringFromValue( EDA_UNITS::DEGREES, text.GetTextAngle().AsDegrees(), true );
  172. case FPT_XOFFSET:
  173. return StringFromValue( m_frame->GetUserUnits(), text.GetPos0().x, true );
  174. case FPT_YOFFSET:
  175. return StringFromValue( m_frame->GetUserUnits(), text.GetPos0().y, true );
  176. default:
  177. // we can't assert here because wxWidgets sometimes calls this without checking
  178. // the column type when trying to see if there's an overflow
  179. return wxT( "bad wxWidgets!" );
  180. }
  181. }
  182. bool FP_TEXT_GRID_TABLE::GetValueAsBool( int aRow, int aCol )
  183. {
  184. FP_TEXT& text = this->at( (size_t) aRow );
  185. switch( aCol )
  186. {
  187. case FPT_SHOWN: return text.IsVisible();
  188. case FPT_ITALIC: return text.IsItalic();
  189. case FPT_UPRIGHT: return text.IsKeepUpright();
  190. default:
  191. wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
  192. return false;
  193. }
  194. }
  195. long FP_TEXT_GRID_TABLE::GetValueAsLong( int aRow, int aCol )
  196. {
  197. FP_TEXT& text = this->at( (size_t) aRow );
  198. switch( aCol )
  199. {
  200. case FPT_LAYER: return text.GetLayer();
  201. default:
  202. wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a long value" ), aCol ) );
  203. return 0;
  204. }
  205. }
  206. void FP_TEXT_GRID_TABLE::SetValue( int aRow, int aCol, const wxString &aValue )
  207. {
  208. FP_TEXT& text = this->at( (size_t) aRow );
  209. VECTOR2I pos;
  210. switch( aCol )
  211. {
  212. case FPT_TEXT:
  213. text.SetText( aValue );
  214. break;
  215. case FPT_WIDTH:
  216. text.SetTextWidth( ValueFromString( m_frame->GetUserUnits(), aValue ) );
  217. break;
  218. case FPT_HEIGHT:
  219. text.SetTextHeight( ValueFromString( m_frame->GetUserUnits(), aValue ) );
  220. break;
  221. case FPT_THICKNESS:text.SetTextThickness( ValueFromString( m_frame->GetUserUnits(), aValue ) );
  222. break;
  223. case FPT_ORIENTATION:
  224. text.SetTextAngle( EDA_ANGLE( DoubleValueFromString( EDA_UNITS::UNSCALED, aValue ),
  225. DEGREES_T ) );
  226. text.SetDrawCoord();
  227. break;
  228. case FPT_XOFFSET:
  229. case FPT_YOFFSET:
  230. pos = text.GetPos0();
  231. if( aCol == FPT_XOFFSET )
  232. pos.x = ValueFromString( m_frame->GetUserUnits(), aValue );
  233. else
  234. pos.y = ValueFromString( m_frame->GetUserUnits(), aValue );
  235. text.SetPos0( pos );
  236. text.SetDrawCoord();
  237. break;
  238. default:
  239. wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a string value" ), aCol ) );
  240. break;
  241. }
  242. GetView()->Refresh();
  243. }
  244. void FP_TEXT_GRID_TABLE::SetValueAsBool( int aRow, int aCol, bool aValue )
  245. {
  246. FP_TEXT& text = this->at( (size_t) aRow );
  247. switch( aCol )
  248. {
  249. case FPT_SHOWN:
  250. text.SetVisible( aValue );
  251. break;
  252. case FPT_ITALIC:
  253. text.SetItalic( aValue );
  254. break;
  255. case FPT_UPRIGHT:text.SetKeepUpright( aValue );
  256. break;
  257. default:
  258. wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a bool value" ), aCol ) );
  259. break;
  260. }
  261. }
  262. void FP_TEXT_GRID_TABLE::SetValueAsLong( int aRow, int aCol, long aValue )
  263. {
  264. FP_TEXT& text = this->at( (size_t) aRow );
  265. switch( aCol )
  266. {
  267. case FPT_LAYER:
  268. text.SetLayer( ToLAYER_ID( (int) aValue ) );
  269. text.SetMirrored( IsBackLayer( text.GetLayer() ) );
  270. break;
  271. default:
  272. wxFAIL_MSG( wxString::Format( wxT( "column %d doesn't hold a long value" ), aCol ) );
  273. break;
  274. }
  275. }