1 // -*- mode: c++; c-file-style: "linux"; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 //
3 //  Copyright (C) 2004-2015 Andrej Vodopivec <andrej.vodopivec@gmail.com>
4 //            (C) 2014-2018 Gunter Königsmann <wxMaxima@physikbuch.de>
5 //
6 //  This program is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 2 of the License, or
9 //  (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 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 //
21 //  SPDX-License-Identifier: GPL-2.0+
22 
23 /*! \file
24   This file defines the class FunCell
25 
26   FunCell is the Cell type that represents functions that don't require special handling.
27  */
28 
29 #include "FunCell.h"
30 #include "TextCell.h"
31 
FunCell(Cell * parent,Configuration ** config,CellPointers * cellPointers)32 FunCell::FunCell(Cell *parent, Configuration **config, CellPointers *cellPointers) :
33   Cell(parent, config, cellPointers),
34   m_nameCell(new TextCell(parent, config, cellPointers)),
35   m_argCell(new TextCell(parent, config, cellPointers))
36 {
37   m_nameCell_Last = m_nameCell.get();
38   if(m_nameCell_Last)
39     while(m_nameCell_Last->m_next)
40       m_nameCell_Last = m_nameCell_Last->m_next;
41 
42   m_argCell_Last = m_argCell.get();
43   if(m_argCell_Last)
44     while(m_argCell_Last->m_next)
45       m_argCell_Last = m_argCell_Last->m_next;
46 }
47 
FunCell(const FunCell & cell)48 FunCell::FunCell(const FunCell &cell):
49  FunCell(cell.m_group, cell.m_configuration, cell.m_cellPointers)
50 {
51   CopyCommonData(cell);
52   if(cell.m_nameCell)
53     SetName(cell.m_nameCell->CopyList());
54   if(cell.m_argCell)
55     SetArg(cell.m_argCell->CopyList());
56 }
57 
~FunCell()58 FunCell::~FunCell()
59 {
60   MarkAsDeleted();
61 }
62 
GetInnerCells()63 std::list<std::shared_ptr<Cell>> FunCell::GetInnerCells()
64 {
65   std::list<std::shared_ptr<Cell>> innerCells;
66   if(m_nameCell)
67     innerCells.push_back(m_nameCell);
68   if(m_argCell)
69     innerCells.push_back(m_argCell);
70   return innerCells;
71 }
72 
SetName(Cell * name)73 void FunCell::SetName(Cell *name)
74 {
75   if (name == NULL)
76     return;
77   m_nameCell = std::shared_ptr<Cell>(name);
78 
79 
80   m_nameCell_Last = name;
81   while(m_nameCell_Last->m_next)
82     m_nameCell_Last = m_nameCell_Last->m_next;
83   name->SetStyle(TS_FUNCTION);
84 }
85 
SetArg(Cell * arg)86 void FunCell::SetArg(Cell *arg)
87 {
88   if (arg == NULL)
89     return;
90   m_argCell = std::shared_ptr<Cell>(arg);
91 
92   m_argCell_Last = arg;
93   while(m_argCell_Last->m_next)
94     m_argCell_Last = m_argCell_Last->m_next;
95 }
96 
RecalculateWidths(int fontsize)97 void FunCell::RecalculateWidths(int fontsize)
98 {
99   if(!NeedsRecalculation(fontsize))
100     return;
101 
102   m_argCell->RecalculateWidthsList(fontsize);
103   m_nameCell->RecalculateWidthsList(fontsize);
104   m_width = m_nameCell->GetFullWidth() + m_argCell->GetFullWidth() - Scale_Px(1);
105 
106   if(m_isBrokenIntoLines)
107     m_width = 0;
108   Cell::RecalculateWidths(fontsize);
109 }
110 
RecalculateHeight(int fontsize)111 void FunCell::RecalculateHeight(int fontsize)
112 {
113   if(!NeedsRecalculation(fontsize))
114     return;
115 
116   m_nameCell->RecalculateHeightList(fontsize);
117   m_argCell->RecalculateHeightList(fontsize);
118   if(!m_isBrokenIntoLines)
119   {
120     m_center = wxMax(m_nameCell->GetCenterList(), m_argCell->GetCenterList());
121     m_height = m_center + wxMax(m_nameCell->GetMaxDrop(), m_argCell->GetMaxDrop());
122   }
123   else
124     m_height = 0;
125   Cell::RecalculateHeight(fontsize);
126 }
127 
Draw(wxPoint point)128 void FunCell::Draw(wxPoint point)
129 {
130   Cell::Draw(point);
131   if (DrawThisCell(point))
132   {
133 
134     wxPoint name(point), arg(point);
135     m_nameCell->DrawList(name);
136 
137     arg.x += m_nameCell->GetFullWidth();
138     m_argCell->DrawList(arg);
139   }
140 }
141 
ToString()142 wxString FunCell::ToString()
143 {
144   if (m_isBrokenIntoLines)
145     return wxEmptyString;
146   if (m_altCopyText != wxEmptyString)
147     return m_altCopyText + Cell::ListToString();
148   wxString s = m_nameCell->ListToString() + m_argCell->ListToString();
149   return s;
150 }
151 
ToMatlab()152 wxString FunCell::ToMatlab()
153 {
154   if (m_isBrokenIntoLines)
155 	return wxEmptyString;
156   if (m_altCopyText != wxEmptyString)
157 	return m_altCopyText + Cell::ListToMatlab();
158   wxString s = m_nameCell->ListToMatlab() + m_argCell->ListToMatlab();
159   return s;
160 }
161 
ToTeX()162 wxString FunCell::ToTeX()
163 {
164   if (m_isBrokenIntoLines)
165     return wxEmptyString;
166 
167   wxString s;
168 
169   if (
170     (m_nameCell->ToString() == wxT("sin")) ||
171     (m_nameCell->ToString() == wxT("cos")) ||
172     (m_nameCell->ToString() == wxT("cosh")) ||
173     (m_nameCell->ToString() == wxT("cos")) ||
174     (m_nameCell->ToString() == wxT("log")) ||
175     (m_nameCell->ToString() == wxT("cot")) ||
176     (m_nameCell->ToString() == wxT("sec")) ||
177     (m_nameCell->ToString() == wxT("csc")) ||
178     (m_nameCell->ToString() == wxT("tan"))
179     )
180     s = wxT("\\") + m_nameCell->ToString() + wxT("{") + m_argCell->ListToTeX() + wxT("}");
181   else
182     s = m_nameCell->ListToTeX() + m_argCell->ListToTeX();
183 
184   return s;
185 }
186 
ToXML()187 wxString FunCell::ToXML()
188 {
189 //  if (m_isBrokenIntoLines)
190 //    return wxEmptyString;
191   wxString flags;
192   if (m_forceBreakLine)
193     flags += wxT(" breakline=\"true\"");
194   return wxT("<fn") + flags + wxT("><r>") + m_nameCell->ListToXML() + wxT("</r>") +
195          m_argCell->ListToXML() + wxT("</fn>");
196 }
197 
ToMathML()198 wxString FunCell::ToMathML()
199 {
200 //  if (m_isBrokenIntoLines)
201 //    return wxEmptyString;
202   return wxT("<mrow>") + m_nameCell->ListToMathML() +
203          wxT("<mo>&#x2061;</mo>") + m_argCell->ListToMathML() + wxT("</mrow>\n");
204 }
205 
ToOMML()206 wxString FunCell::ToOMML()
207 {
208   return m_nameCell->ListToOMML() +
209          m_argCell->ListToOMML();
210 }
211 
BreakUp()212 bool FunCell::BreakUp()
213 {
214   if (!m_isBrokenIntoLines)
215   {
216     m_isBrokenIntoLines = true;
217     m_nameCell_Last->m_nextToDraw = m_argCell.get();
218     m_argCell_Last->m_nextToDraw = m_nextToDraw;
219     m_nextToDraw = m_nameCell.get();
220     m_width = 0;
221     ResetData();
222     return true;
223   }
224   return false;
225 }
226