1 // $Id: constraintmenus.cpp,v 1.11 2011/03/08 19:22:01 bobgian Exp $
2 
3 /*
4   Copyright 2002  Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein
5 
6   This software is distributed free of charge for non-commercial use
7   and is copyrighted.  Of course, we do not guarantee that the software
8   works, and are not responsible for any damage you may cause or have.
9 */
10 
11 #include <cassert>
12 #include <string>
13 
14 #include "display.h"
15 #include "lamarc_strings.h"
16 #include "newmenuitems.h"
17 #include "constraintmenus.h"
18 #include "togglemenuitem.h"
19 #include "ui_interface.h"
20 #include "ui_strings.h"
21 
22 using std::string;
23 
24 //------------------------------------------------------------------------------------
25 
ConstraintMenuForOneForce(UIInterface & ui,UIId id)26 ConstraintMenuForOneForce::ConstraintMenuForOneForce(UIInterface& ui,UIId id)
27     : NewMenu(ui,lamarcmenu::forceConstraintTitle+ToString(id.GetForceType()),
28               lamarcmenu::forceConstraintInfo)
29 {
30     AddMenuItem(new AddToGroupedConstraintsMenuItem("A", ui, id));
31     AddMenuItem(new RemoveFromGroupedConstraintsMenuItem("R", ui, id));
32     AddMenuItem(new ToggleMenuItemUngroupedConstraints(ui,id));
33     AddMenuItem(new ToggleMenuItemGroupedConstraints(ui, id));
34 }
35 
~ConstraintMenuForOneForce()36 ConstraintMenuForOneForce::~ConstraintMenuForOneForce()
37 {
38 }
39 
40 //------------------------------------------------------------------------------------
41 
SubMenuConstraintsForOneForce(std::string key,UIInterface & ui,UIId id)42 SubMenuConstraintsForOneForce::SubMenuConstraintsForOneForce(std::string key, UIInterface& ui, UIId id)
43     : ForceSubMenuItem(key, ui, new ConstraintsMenuForOneForceCreator(ui, id), id)
44 {
45 }
46 
~SubMenuConstraintsForOneForce()47 SubMenuConstraintsForOneForce::~SubMenuConstraintsForOneForce()
48 {
49 }
50 
51 //------------------------------------------------------------------------------------
52 
AddToGroupedConstraintsMenuItem(std::string key,UIInterface & ui,UIId id)53 AddToGroupedConstraintsMenuItem::AddToGroupedConstraintsMenuItem
54 (std::string key, UIInterface& ui, UIId id)
55     : SetMenuItemId(key, ui, uistr::addParamToGroup, id)
56 {
57 }
58 
~AddToGroupedConstraintsMenuItem()59 AddToGroupedConstraintsMenuItem::~AddToGroupedConstraintsMenuItem()
60 {
61 }
62 
63 MenuInteraction_ptr
GetHandler(std::string input)64 AddToGroupedConstraintsMenuItem::GetHandler(std::string input)
65 {
66     assert(Handles(input));
67     return MenuInteraction_ptr(new GetIdAndAddDialog(ui, menuKey, id));
68 }
69 
70 //------------------------------------------------------------------------------------
71 
GetIdAndAddDialog(UIInterface & ui,string menuKey,UIId id)72 GetIdAndAddDialog::GetIdAndAddDialog(UIInterface& ui, string menuKey, UIId id)
73     : SetDialog(ui, menuKey, id),
74       outputId()
75 {
76 }
77 
~GetIdAndAddDialog()78 GetIdAndAddDialog::~GetIdAndAddDialog()
79 {
80 }
81 
InvokeMe(Display & display)82 menu_return_type GetIdAndAddDialog::InvokeMe(Display& display)
83 {
84     display.DisplayDialogOutput(beforeLoopOutputString());
85     bool success = false;
86     for(int i=0;(i<maxTries() && success==false);i++)
87     {
88         display.DisplayDialogOutput(inLoopOutputString());
89         std::string result = display.GetUserInput();
90         if (handleInput(result))
91         {
92             display.DisplayDialogOutput(afterLoopSuccessOutputString());
93             success = true;
94         }
95         else
96         {
97             display.DisplayDialogOutput(inLoopFailureOutputString());
98         }
99     }
100     if (success)
101     {
102         for(int i=0;i<maxTries();i++)
103         {
104             display.DisplayDialogOutput(inLoopOutputString2());
105             std::string result = display.GetUserInput();
106             if (handleInput2(result))
107             {
108                 display.DisplayDialogOutput(afterLoopSuccessOutputString());
109                 return menu_REDISPLAY;
110             }
111             else
112             {
113                 display.DisplayDialogOutput(inLoopFailureOutputString());
114             }
115         }
116     }
117     display.DisplayDialogOutput(afterLoopFailureOutputString());
118     doFailure();
119     return menu_REDISPLAY;
120 }
121 
handleInput2(std::string input)122 bool GetIdAndAddDialog::handleInput2(std::string input)
123 {
124     haveError = false;
125     try
126     {
127         stuffVal2IntoUI(input);
128     }
129     catch (data_error& e)
130     {
131         currError = e.what();
132         haveError = true;
133         return false;
134     }
135     return true;
136 }
137 
stuffValIntoUI(std::string val)138 void GetIdAndAddDialog::stuffValIntoUI(std::string val)
139 {
140     long pindex = ProduceLongOrBarf(val) - 1;
141     UIIdVec1d ungroupedIds=ui.doGetUIIdVec1d(uistr::ungroupedParamsForForce,id);
142     bool matched = false;
143     //The following code basically reiterates Group::Handles, below.
144     for (UIIdVec1d::iterator thisId = ungroupedIds.begin();
145          thisId != ungroupedIds.end(); thisId++)
146     {
147         UIId& visibleId = *thisId;
148         if(visibleId.GetIndex1() == pindex)
149         {
150             matched = true;
151         }
152     }
153     if (!matched)
154     {
155         throw data_error("That number is not the index of an ungrouped parameter.");
156     }
157 
158     //Set Index2 of the UIId equal to the pindex.  Since we don't know the
159     // gindex yet, just set it to zero.
160     long gindex = 0;
161     UIId newid(id.GetForceType(), gindex, pindex);
162     outputId = newid;
163 };
164 
stuffVal2IntoUI(std::string val)165 void GetIdAndAddDialog::stuffVal2IntoUI(std::string val)
166 {
167     if (CaselessStrCmp("N", val))
168     {
169         ui.doSet(uistr::addParamToNewGroup, ToString(noval_none), outputId);
170         return;
171     }
172     long gindex = ProduceLongOrBarf(val) - 1;
173     UIIdVec2d groupedIds=ui.doGetUIIdVec2d(uistr::groupedParamsForForce,id);
174     if (0 > gindex || gindex >= static_cast<long>(groupedIds.size()))
175     {
176         throw data_error("Please enter a valid group index or 'N'.");
177     }
178     UIId newId(outputId.GetForceType(), gindex, outputId.GetIndex2());
179     ui.doSet(menuKey,ToString(noval_none),newId);
180 };
181 
inLoopOutputString()182 string GetIdAndAddDialog::inLoopOutputString()
183 {
184     return "Select a parameter to add to a group.\n";
185 }
186 
inLoopOutputString2()187 string GetIdAndAddDialog::inLoopOutputString2()
188 {
189     return "Select a group to add this parameter to (or N for a new group).\n";
190 }
191 
192 //------------------------------------------------------------------------------------
193 
RemoveFromGroupedConstraintsMenuItem(std::string key,UIInterface & ui,UIId id)194 RemoveFromGroupedConstraintsMenuItem::RemoveFromGroupedConstraintsMenuItem
195 (std::string key, UIInterface& ui, UIId id)
196     : SetMenuItemId(key, ui, uistr::removeParamFromGroup, id)
197 {
198 }
199 
~RemoveFromGroupedConstraintsMenuItem()200 RemoveFromGroupedConstraintsMenuItem::~RemoveFromGroupedConstraintsMenuItem()
201 {
202 }
203 
204 MenuInteraction_ptr
GetHandler(std::string input)205 RemoveFromGroupedConstraintsMenuItem::GetHandler(std::string input)
206 {
207     assert(Handles(input));
208     return MenuInteraction_ptr(new GetIdAndRemoveDialog(ui, menuKey, id));
209 }
210 
211 //------------------------------------------------------------------------------------
212 
GetIdAndRemoveDialog(UIInterface & ui,string menuKey,UIId id)213 GetIdAndRemoveDialog::GetIdAndRemoveDialog(UIInterface& ui, string menuKey,
214                                            UIId id)
215     : SetDialog(ui, menuKey, id)
216 {
217 }
218 
~GetIdAndRemoveDialog()219 GetIdAndRemoveDialog::~GetIdAndRemoveDialog()
220 {
221 }
222 
stuffValIntoUI(std::string val)223 void GetIdAndRemoveDialog::stuffValIntoUI(std::string val)
224 {
225     long pindex = ProduceLongOrBarf(val) - 1;
226     UIIdVec2d groupIds = ui.doGetUIIdVec2d(uistr::groupedParamsForForce,id);
227     bool matched = false;
228     //The following code basically reiterates 2dGroup::Handles, below.
229     UIIdVec2d::iterator group;
230     for(group = groupIds.begin(); group != groupIds.end(); group++)
231     {
232         for (UIIdVec1d::iterator id = (*group).begin();
233              id != (*group).end(); id++)
234         {
235             UIId& visibleId = *id;
236             if(visibleId.GetIndex2() == pindex)
237             {
238                 matched = true;
239             }
240         }
241     }
242     if (!matched)
243     {
244         throw data_error("That number is not the index of a grouped parameter.");
245     }
246     UIId newid(id.GetForceType(), pindex);
247     ui.doSet(menuKey,ToString(noval_none),newid);
248 };
249 
inLoopOutputString()250 string GetIdAndRemoveDialog::inLoopOutputString()
251 {
252     return "Enter the index of the parameter you wish to remove from a group.\n";
253 }
254 
255 //------------------------------------------------------------------------------------
256 
ToggleMenuItemUngroupedConstraints(UIInterface & ui,UIId id)257 ToggleMenuItemUngroupedConstraints::ToggleMenuItemUngroupedConstraints(UIInterface & ui,UIId id)
258     : ToggleMenuItemGroup(ui,uistr::constraintType), m_id(id)
259 {
260 }
261 
~ToggleMenuItemUngroupedConstraints()262 ToggleMenuItemUngroupedConstraints::~ToggleMenuItemUngroupedConstraints()
263 {
264 }
265 
GetGroupDescription()266 string ToggleMenuItemUngroupedConstraints::GetGroupDescription()
267 {
268     return "Ungrouped parameters:";
269 }
270 
GetEmptyDescription()271 string ToggleMenuItemUngroupedConstraints::GetEmptyDescription()
272 {
273     return "  **None**";
274 }
275 
276 UIIdVec1d
GetVisibleIds()277 ToggleMenuItemUngroupedConstraints::GetVisibleIds()
278 {
279     return ui.doGetUIIdVec1d(uistr::ungroupedParamsForForce,m_id);
280 }
281 
282 //------------------------------------------------------------------------------------
283 
ToggleMenuItem2dGroup(UIInterface & myui,string myMenuKey)284 ToggleMenuItem2dGroup::ToggleMenuItem2dGroup(UIInterface & myui,
285                                              string myMenuKey)
286     : ui(myui), menuKey(myMenuKey)
287 {
288 }
289 
GetGroupIdFromLocalId(UIId localId)290 UIId ToggleMenuItem2dGroup::GetGroupIdFromLocalId(UIId localId)
291 {
292     UIIdVec2d allvisibles = GetVisibleIds();
293     long gindex = 0;
294     for(UIIdVec2d::iterator visibleset = allvisibles.begin();
295         visibleset != allvisibles.end(); visibleset++, gindex++)
296     {
297         for(UIIdVec1d::iterator id = (*visibleset).begin();
298             id != (*visibleset).end(); id++)
299         {
300             UIId& visibleId = *id;
301             if (visibleId.GetIndex2() == localId.GetIndex1())
302             {
303                 return visibleId;
304             }
305         }
306     }
307     return UIId(FLAGLONG);
308 }
309 
GetIdFromKey(string key)310 UIId ToggleMenuItem2dGroup::GetIdFromKey(string key)
311 {
312     UIId localId(keyToIndex(key));
313     return GetGroupIdFromLocalId(localId);
314 }
315 
GetKey(UIId id)316 string ToggleMenuItem2dGroup::GetKey(UIId id)
317 {
318     // There is no guarantee that this key
319     // has a unique index1, but most will
320     // so this is the default implementation.
321     // If this is causing you trouble, override
322     // this virtual method
323     return indexToKey(id.GetIndex2());
324 }
325 
GetText(UIId id)326 string ToggleMenuItem2dGroup::GetText(UIId id)
327 {
328     return ui.doGetDescription(menuKey,id);
329 }
330 
GetVariableText(UIId id)331 string ToggleMenuItem2dGroup::GetVariableText(UIId id)
332 {
333     return ui.doGetPrintString(menuKey,id);
334 }
335 
GetGroupDescription(long gid)336 string ToggleMenuItem2dGroup::GetGroupDescription(long gid)
337 {
338     return "\n";
339 }
340 
GetEmptyDescription(long gid)341 string ToggleMenuItem2dGroup::GetEmptyDescription(long gid)
342 {
343     return "\n";
344 }
345 
Handles(string input)346 bool ToggleMenuItem2dGroup::Handles(string input)
347 {
348     // kinda wasteful, but avoids some unpleasant to
349     // code error checking
350     UIIdVec2d allvisibles = GetVisibleIds();
351     UIIdVec2d::iterator group;
352     for(group = allvisibles.begin(); group != allvisibles.end(); group++)
353     {
354         for (UIIdVec1d::iterator id = (*group).begin();
355              id != (*group).end(); id++)
356         {
357             UIId& visibleId = *id;
358             if(CaselessStrCmp(GetKey(visibleId),input))
359             {
360                 return true;
361             }
362         }
363     }
364     return false;
365 }
366 
GetHandler(string input)367 MenuInteraction_ptr ToggleMenuItem2dGroup::GetHandler(string input)
368 {
369     UIId groupId = GetIdFromKey(input);
370     if (groupId.GetIndex1() != FLAGLONG)
371     {
372         return MakeOneHandler(groupId);
373     }
374     else
375     {
376         return MenuInteraction_ptr(new DoNothingHandler());
377     }
378 }
379 
MakeOneHandler(UIId id)380 MenuInteraction_ptr ToggleMenuItem2dGroup::MakeOneHandler(UIId id)
381 {
382     return MenuInteraction_ptr(new NewToggleHandler(ui,menuKey,id));
383 }
384 
DisplayItemOn(Display & display)385 void ToggleMenuItem2dGroup::DisplayItemOn(Display & display)
386 {
387     display.ShowMenuDisplay2dGroup(*this);
388 }
389 
390 //------------------------------------------------------------------------------------
391 
ToggleMenuItemGroupedConstraints(UIInterface & ui,UIId id)392 ToggleMenuItemGroupedConstraints::ToggleMenuItemGroupedConstraints
393 (UIInterface & ui,UIId id)
394     : ToggleMenuItem2dGroup(ui,uistr::groupConstraintType),
395       m_id(id)
396 {
397 }
398 
~ToggleMenuItemGroupedConstraints()399 ToggleMenuItemGroupedConstraints::~ToggleMenuItemGroupedConstraints()
400 {
401 }
402 
GetVisibleIds()403 UIIdVec2d ToggleMenuItemGroupedConstraints::GetVisibleIds()
404 {
405     return ui.doGetUIIdVec2d(uistr::groupedParamsForForce,m_id);
406 }
407 
GetGroupDescription(long gid)408 string ToggleMenuItemGroupedConstraints::GetGroupDescription(long gid)
409 {
410     return ("Group " + ToString(gid+1));
411 }
412 
GetEmptyDescription(long gid)413 string ToggleMenuItemGroupedConstraints::GetEmptyDescription(long gid)
414 {
415     return ("  **No parameters in this group**");
416 }
417 
418 //____________________________________________________________________________________
419