1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
18 #include <Standard_Stream.hxx>
20 #include <IFSelect_SessionPilot.ixx>
21 #include <IFSelect_Activator.hxx>
22 #include <IFSelect_Selection.hxx>
23 #include <Interface_EntityIterator.hxx>
24 #include <Interface_InterfaceModel.hxx>
25 #include <TColStd_HSequenceOfAsciiString.hxx>
27 #include <Interface_Macros.hxx>
28 #include <Message_Messenger.hxx>
29 #include <Message.hxx>
36 static int initactor = 0;
39 static TCollection_AsciiString nulword;
41 // Nb Maxi de words : cf thewords et method SetCommandLine
43 IFSelect_SessionPilot::IFSelect_SessionPilot (const Standard_CString prompt)
44 : theprompt (prompt) , thewords (0,MAXWORDS-1) , thewordeb (0,MAXWORDS-1)
46 if (theprompt.Length() == 0) theprompt.AssignCat ("Test-XSTEP>");
47 therecord = Standard_False; thenbwords = 0;
48 if (initactor) return; initactor = 1;
57 trace = getenv("DEBUGMODE");
61 Handle(IFSelect_WorkSession) IFSelect_SessionPilot::Session () const
62 { return thesession; }
64 Handle(IFSelect_WorkLibrary) IFSelect_SessionPilot::Library () const
65 { return thesession->WorkLibrary(); }
67 Standard_Boolean IFSelect_SessionPilot::RecordMode () const
70 void IFSelect_SessionPilot::SetSession
71 (const Handle(IFSelect_WorkSession)& WS)
74 void IFSelect_SessionPilot::SetLibrary
75 (const Handle(IFSelect_WorkLibrary)& WL)
76 { if (!thesession.IsNull()) thesession->SetLibrary(WL); }
78 void IFSelect_SessionPilot::SetRecordMode (const Standard_Boolean mode)
82 void IFSelect_SessionPilot::SetCommandLine
83 (const TCollection_AsciiString& command)
85 Standard_Integer lc = command.Length();
86 if (lc > 200) cout<<" Commande TRES LONGUE : "<<lc<<" caracteres :"<<endl
87 <<command.ToCString()<<endl;
89 if (thecommand.Value(lc) <= ' ') { thecommand.Remove(lc); lc --; }
91 Standard_Integer i, nc = 0;
93 for (i = 1; i <= lc; i ++) {
94 char val = command.Value(i);
96 if (nc == 0) continue;
97 if (thenbwords >= MAXWORDS) { unarg[nc] = val; nc ++; continue; }
99 thewords(thenbwords).Clear(); thewords(thenbwords).AssignCat(unarg);
100 if (trace) cout<<"thewords("<<thenbwords<<") ="<<unarg<<endl;
101 thenbwords ++; nc = 0;
104 if (nc == 0) thewordeb.SetValue (thenbwords,i);
105 if (nc > MAXCARS) { cout<<"Arg."<<thenbwords<<" > "<<MAXCARS<<" car.s, tronque"<<endl; continue; }
106 unarg[nc] = val; nc ++;
109 unarg[nc] = '\0'; thewords(thenbwords).Clear();
110 thewords(thenbwords).AssignCat(unarg);
111 if (trace) cout<<"thewords("<<thenbwords<<")="<<unarg<<endl<<" .. Fin avec thenbwords="<<thenbwords+1<<endl;
116 char l0[80],l1[80],l2[80],l3[80],l4[80],l5[80],l6[80],l7[80],l8[80],l9[80];
117 char m0[80],m1[80],m2[80],m3[80],m4[80],m5[80],m6[80],m7[80],m8[80],m9[80];
119 (thecommand.ToCString(),"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
120 l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,m0,m1,m2,m3,m4,m5,m6,m7,m8,m9);
121 if (thenbwords < 0) thenbwords = 0;
122 if (thenbwords > MAXWORDS) thenbwords = MAXWORDS;
123 Standard_Integer nb = thewords.Upper();
124 for (i = 0; i <= nb; i ++) thewords(i).Clear();
125 switch (thenbwords) {
126 case 20 : thewords(19).AssignCat(m9);
127 case 19 : thewords(18).AssignCat(m8);
128 case 18 : thewords(17).AssignCat(m7);
129 case 17 : thewords(16).AssignCat(m6);
130 case 16 : thewords(15).AssignCat(m5);
131 case 15 : thewords(14).AssignCat(m4);
132 case 14 : thewords(13).AssignCat(m3);
133 case 13 : thewords(12).AssignCat(m2);
134 case 12 : thewords(11).AssignCat(m1);
135 case 11 : thewords(10).AssignCat(m0);
136 case 10 : thewords(9).AssignCat(l9);
137 case 9 : thewords(8).AssignCat(l8);
138 case 8 : thewords(7).AssignCat(l7);
139 case 7 : thewords(6).AssignCat(l6);
140 case 6 : thewords(5).AssignCat(l5);
141 case 5 : thewords(4).AssignCat(l4);
142 case 4 : thewords(3).AssignCat(l3);
143 case 3 : thewords(2).AssignCat(l2);
144 case 2 : thewords(1).AssignCat(l1);
145 case 1 : thewords(0).AssignCat(l0);
153 const TCollection_AsciiString& IFSelect_SessionPilot::CommandLine () const
154 { return thecommand; }
156 Standard_CString IFSelect_SessionPilot::CommandPart
157 (const Standard_Integer numarg) const
159 if (numarg <= 0) return thecommand.ToCString();
160 if (numarg >= thenbwords) return "";
161 return &(thecommand.ToCString())[thewordeb(numarg)-1];
164 Standard_Integer IFSelect_SessionPilot::NbWords () const
165 { return thenbwords; }
167 const TCollection_AsciiString& IFSelect_SessionPilot::Word
168 (const Standard_Integer num) const
169 { if (num < thenbwords) return thewords(num); return nulword; }
171 Standard_CString IFSelect_SessionPilot::Arg
172 (const Standard_Integer num) const
173 { return Word(num).ToCString(); }
175 Standard_Boolean IFSelect_SessionPilot::RemoveWord
176 (const Standard_Integer num)
178 if (num < 0 || num > thenbwords) return Standard_False;
179 Standard_Integer i; // svv Jan11 2000 : porting on DEC
180 for (i = num; i < thenbwords; i ++) {
182 thewords(i).AssignCat(thewords(i+1).ToCString());
184 thewords(thenbwords).Clear();
186 // Et refaire thecommand. Si num = 0, on supprime le debut (facile)
188 thecommand.Remove(1,thewordeb(1));
190 // Sinon, reconstituer, a partir des words
192 for (i = 0; i < thenbwords; i ++) {
193 if (i > 0) thecommand.AssignCat(" ");
194 thecommand.AssignCat(thewords(i));
198 return Standard_True;
201 Standard_Integer IFSelect_SessionPilot::NbCommands () const
202 { return thecomlist.Length(); }
204 const TCollection_AsciiString& IFSelect_SessionPilot::Command
205 (const Standard_Integer num) const
206 { return thecomlist(num); }
209 IFSelect_ReturnStatus IFSelect_SessionPilot::RecordItem
210 (const Handle(Standard_Transient)& item)
213 return (item.IsNull() ? IFSelect_RetFail : IFSelect_RetDone);
216 Handle(Standard_Transient) IFSelect_SessionPilot::RecordedItem () const
217 { return theobjrec; }
219 void IFSelect_SessionPilot::Clear ()
220 { thecomlist.Clear(); }
223 // #######################################################################
224 // ######## CONTROLE D EXECUTION
227 IFSelect_ReturnStatus IFSelect_SessionPilot::ReadScript
228 (const Standard_CString file)
230 FILE* fic; int lefic = 0;
231 if (file != NULL && file[0] != '\0') {
232 fic = fopen (file,"r");
234 else { cout<<" ... Script File "<<file<<" not found"<<endl; return IFSelect_RetFail; }
235 cout << " ... Reading Script File " << file << endl;
238 IFSelect_ReturnStatus stat = IFSelect_RetVoid;
242 if (!lefic) std::cout << theprompt.ToCString();
244 fgets(ligne,100,fic);
245 if (feof(fic)) break;
246 if (ligne[0] == '\0') continue;
247 // On interprete cette commande
248 TCollection_AsciiString command(ligne);
249 if (lefic) cout<<file<<":"<<command; // le return est dans la ligne ... !
250 stat = Execute(command);
251 if (stat == IFSelect_RetStop) break;
252 if ((stat == IFSelect_RetError || stat == IFSelect_RetFail) && lefic)
253 { cout << " ... Error in Script File, abandon"<<endl; break; }
255 if (!lefic) return IFSelect_RetStop;
257 cout<<"End of Reading Script File " << file << endl;
258 if (stat == IFSelect_RetError || stat == IFSelect_RetFail) return stat;
259 return IFSelect_RetVoid; // fin fichier : depiler
263 // On boucle sur la lecture jusqu a une commande de fin ou un EOF
265 IFSelect_ReturnStatus IFSelect_SessionPilot::Perform ()
267 IFSelect_ReturnStatus stat = IFSelect_RetVoid;
268 if (thenbwords == 0) return stat;
269 if (thewords(0).Value(1) == '#') return stat; // commentaire
274 // Commande pour un Acteur
275 Handle(IFSelect_Activator) actor; Standard_Integer num;
276 if (IFSelect_Activator::Select(thewords(0).ToCString(),num,actor)) {
277 stat = actor->Do(num,this);
278 // Prise en compte des commandes a resultat
279 // Ici, resultat non nomme; Resultat nomme par commande x (plus loin)
280 if (!theobjrec.IsNull()) {
281 thesession->RemoveItem(theobjrec); //// depannage ?
282 Standard_Boolean addws = thesession->AddItem(theobjrec);
283 if (!addws) { cout<<"Could not add item to session, sorry"<<endl; return IFSelect_RetFail; }
286 if (stat == IFSelect_RetVoid || stat == IFSelect_RetDone) {
287 if (therecord) thecomlist.Append(thecommand);
289 else if (stat == IFSelect_RetError) cout<<"Error in Command : "<<thecommand<<endl;
290 else if (stat == IFSelect_RetFail) cout << "Execution Failure for : " <<thecommand<<endl;
293 cout << " Command : " << thewords(0) << " unknown" << endl;
294 return IFSelect_RetError; // pas reconnu donc incorrect
297 IFSelect_ReturnStatus IFSelect_SessionPilot::ExecuteAlias
298 (const TCollection_AsciiString& alias)
300 if (alias.Length() > 0) thewords(0) = alias;
304 IFSelect_ReturnStatus IFSelect_SessionPilot::Execute
305 (const TCollection_AsciiString& command)
307 SetCommandLine(command);
311 IFSelect_ReturnStatus IFSelect_SessionPilot::ExecuteCounter
312 (const Handle(IFSelect_SignCounter)& counter, const Standard_Integer numword,
313 const IFSelect_PrintCount mode)
315 if (counter.IsNull()) return IFSelect_RetError;
317 if (NbWords() <= numword) counter->AddModel (thesession->Model());
319 // on demande un givelist
320 Handle(TColStd_HSequenceOfTransient) list = thesession->GiveList (CommandPart(numword));
322 cout<<"Nothing selected from : "<<CommandPart(numword)<<endl;
323 return IFSelect_RetError;
325 counter->AddWithGraph (list,thesession->Graph());
327 counter->PrintList(Message::DefaultMessenger(),thesession->Model(),mode);
328 return IFSelect_RetVoid;
331 Standard_Integer IFSelect_SessionPilot::Number
332 (const Standard_CString val) const
334 Standard_Integer num = thesession->NumberFromLabel (val);
335 if (num < 0) cout<<" Label:"<<val<<" ->"<<-num<<" ent.s, refus"<<endl;
340 // #########################################################################
341 // ######## ACTIONS SPECIFIQUES DU PILOTE
343 #define MAXCOMPERLINE 5
344 #define LENGTHFORCOM 15
346 IFSelect_ReturnStatus IFSelect_SessionPilot::Do
347 (const Standard_Integer number,
348 const Handle(IFSelect_SessionPilot)& session)
350 // Commandes Propres : x, exit, undo, redo, ?, help
351 IFSelect_ReturnStatus stat = IFSelect_RetVoid;
352 Standard_Integer argc = NbWords();
353 const Standard_CString arg1 = Word(1).ToCString();
354 Standard_Integer modhelp = -1;
356 case -1 : // **** HELP-XSNEW
358 cout<<" -- Commands candidate for xsnew --"<<endl;
359 // HELP : soit complet (par defaut) soit limite a xsnew
360 case 0 : { // **** HELP
361 Handle(TColStd_HSequenceOfAsciiString) list;
362 // Help complet : on donne la liste des commandes, sans plus (deja pas mal)
363 if (thenbwords <= 1) {
364 list = IFSelect_Activator::Commands(modhelp);
365 Standard_Integer nbcom = 0;
366 Standard_Integer nb = list->Length();
367 cout << " -- Liste des Commands Disponibles --"<<endl;
368 for (Standard_Integer i = 1; i <= nb; i ++) {
369 const TCollection_AsciiString& uncom = list->Value(i);
370 Standard_Integer loncom = uncom.Length();
372 if (nbcom > MAXCOMPERLINE) { cout<<endl; nbcom = 1; }
374 if (nbcom == MAXCOMPERLINE) continue;
375 for (Standard_Integer j = loncom; j < LENGTHFORCOM; j ++) cout<<" ";
377 if (nbcom > 0) cout<<endl;
378 cout<<"\nhelp * liste toutes les commandes avec un help sur chacune\n"
379 <<"help <com> liste la ou les commande debutant par <com>"
380 <<" avec un help sur chacune"<<endl;
382 // Un Help particulier
384 if (thewords(1).IsEqual("*")) list = IFSelect_Activator::Commands(modhelp);
386 else list = IFSelect_Activator::Commands(modhelp,thewords(1).ToCString());
388 Standard_Integer nb = list->Length();
389 for (Standard_Integer i = 1; i <= nb; i ++) {
390 Handle(IFSelect_Activator) actor; Standard_Integer num;
391 if (IFSelect_Activator::Select
392 (list->Value(i).ToCString(),num,actor)) {
393 if (IFSelect_Activator::Mode (list->Value(i).ToCString()) == 1)
394 cout<<"[xsnew name] ";
395 cout << list->Value(i) << " : " << actor->Help(num) << endl;
398 if (nb == 0 && thenbwords > 1) cout<<" Command "<<Word(1)<<" unknown. "
399 << " help (without command) lists all the commands" << endl;
401 return IFSelect_RetVoid;
403 case 1 : return IFSelect_RetStop; // **** Fin de session
404 case 2 : { // **** HELP
407 case 3 : { // **** COMMAND
408 if (argc < 2) { cout << "Donner une option :\n"
409 <<"a : analyse une ligne r : toggle record mode\n"
410 <<"l : list recorded c : clear f nom : sauver dans fichier de nom"
411 << endl; return IFSelect_RetVoid; }
413 case 'a' : { // **** command analyse
414 cout<<"Command n0 " << number <<" : "<< session->CommandLine()<<endl;
415 cout<<"Nb Words : " << argc-2 << " :\n";
416 for (Standard_Integer i = 2; i < argc; i ++) {
417 cout << " Word." << i-1 << " : " << session->Word(i) <<endl;
421 case 'c' : session->Clear(); break; // **** command clear
423 if (argc < 3) { cout<<"Donner nom de fichier"<<endl; return IFSelect_RetError; }
424 Standard_Integer nb = session->NbCommands();
425 if (nb == 0) { cout<<"Aucune commande enregistree"<<endl; break; }
426 cout << "Nb Commandes enregistrees : " << nb <<endl;
427 ofstream fout(Word(2).ToCString(),ios::out);
428 for (Standard_Integer i = 1; i <= nb; i ++)
429 fout<<session->Command(i)<<endl;
432 case 'l' : { // **** command list
433 if (session->RecordMode()) cout<<" -- Record Mode Actif"<<endl;
434 else cout<<" -- Record Mode Inactif"<<endl;
435 Standard_Integer nb = session->NbCommands();
436 cout << "Nb Commandes enregistrees : " << nb << " :"<<endl;
437 for (Standard_Integer i = 1; i <= nb; i ++) {
438 cout<<" "<<i<<" "<<session->Command(i)<<endl;
442 case 'r' : { // **** command record
443 Standard_Boolean mode = session->RecordMode();
444 if (mode) cout << " -- Record Mode a present Inactif" <<endl;
445 else cout << " -- Record Mode a present Actif" <<endl;
446 session->SetRecordMode(!mode);
449 default : cout << "Option de controle de commande non comprise"<<endl;
451 return IFSelect_RetVoid;
454 case 4 : { // **** FILE
455 if (argc < 2) { cout<<"Donner nom de fichier"<<endl; return IFSelect_RetError; }
456 return session->ReadScript
457 (TCollection_AsciiString(session->Word(1)).ToCString());
458 // On recopie la string parce que Word(1) change tout le temps !
461 case 5 : { // **** XSTEP
463 cout<<"xstep : prefixe neutre pour toute commande xstep-draw"<<endl
464 <<"xstep command args equivaut a command args"<<endl;
471 case 6 : { // **** XSNEW(variable)
473 cout<<"xsnew nomvar command [args] creates an item"<<endl
474 <<" nomvar : name of item (must be a new name) in the session"<<endl;
479 TCollection_AsciiString name = Word(1);
480 // Le nom ne doit pas etre deja pris !
481 if (thesession.IsNull()) { cout<<"Command with a Name and no Session defined !"<<endl; return IFSelect_RetFail; }
482 ////// if (thesession->NameIdent(thewords(0).ToCString()) > 0)
483 ////// { cout<<"Command with name:"<<thewords(0)<<", already taken"<<endl; return IFSelect_RetFail; }
484 RemoveWord(0); RemoveWord(0);
486 // Commande pour un Acteur
487 Handle(IFSelect_Activator) actor; Standard_Integer num;
488 if (IFSelect_Activator::Select(thewords(0).ToCString(),num,actor)) {
490 stat = actor->Do(num,this);
491 // Prise en compte des commandes a resultat
492 if (!theobjrec.IsNull()) {
493 thesession->RemoveItem(theobjrec); //// depannage ?
494 Standard_Boolean addws =
495 thesession->AddNamedItem(name.ToCString(),theobjrec);
497 if (!addws) { cout<<"Could not add named item:"<<name<<", sorry"<<endl; return IFSelect_RetFail; }
499 else cout<<"Remark : xsnew with name:"<<name<<" and no result"<<endl;
503 cout << " Command : " << thewords(0) << " unknown" << endl;
504 return IFSelect_RetError; // pas reconnu donc incorrect
507 default : return IFSelect_RetError;
513 Standard_CString IFSelect_SessionPilot::Help
514 (const Standard_Integer number) const
517 case 1 : return "exit ou x : Fin de session";
518 case 2 : return "Liste les commandes. ? <titre> : commandes debutant par <titre>";
519 case 3 : return "controle de commande. command tout court pour help complet";
520 case 4 : return "lit les commandes depuis un fichier";
521 case 5 : return "prefixe neutre pour xstep-draw";
522 case 6 : return "creation item : donner nom_item puis commande args";