1 // -*- compile-command: "g++ -DHAVE_CONFIG_H -I. -I.. -g -c Tableur.cc -Wall" -*- 2 #ifdef HAVE_CONFIG_H 3 #include "config.h" 4 #endif 5 #ifndef IN_GIAC 6 #include <giac/first.h> 7 #else 8 #include "first.h" 9 #endif 10 /* 11 * Copyright (C) 2002,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 3 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program. If not, see <http://www.gnu.org/licenses/>. 25 */ 26 27 #ifdef HAVE_LIBFLTK 28 #include "Tableur.h" 29 #include "Xcas1.h" 30 #include "Print.h" 31 #ifndef IN_GIAC 32 #include <giac/vecteur.h> 33 #else 34 #include "vecteur.h" 35 #endif 36 #ifndef IN_GIAC 37 #include <giac/identificateur.h> 38 #include <giac/usual.h> 39 #include <giac/prog.h> 40 #include <giac/misc.h> 41 #include <giac/global.h> 42 #else 43 #include "identificateur.h" 44 #include "usual.h" 45 #include "prog.h" 46 #include "misc.h" 47 #include "global.h" 48 #endif 49 #ifdef HAVE_UNISTD_H 50 #include <unistd.h> 51 #endif 52 53 #include <FL/Fl_Text_Editor.H> 54 #include <FL/Fl_Value_Input.H> 55 #include <FL/Fl_Return_Button.H> 56 #include <FL/Fl_Check_Button.H> 57 #include <sys/stat.h> 58 #include <cerrno> 59 using namespace std; 60 using namespace giac; 61 62 #ifndef NO_NAMESPACE_XCAS 63 namespace xcas { 64 #endif // ndef NO_NAMESPACE_XCAS 65 66 objet_bidon mon_objet_bidon_tableur; 67 68 #ifdef IPAQ 69 int Flv_Table_Gen::def_rows=10,Flv_Table_Gen::def_cols=4; 70 #else 71 int Flv_Table_Gen::def_rows=40,Flv_Table_Gen::def_cols=10; 72 #endif 73 fillsheet(bool is_spreadsheet)74 vecteur fillsheet(bool is_spreadsheet){ 75 vecteur res; 76 if (is_spreadsheet) 77 res=vecteur(3,string2gen(string(""),false)); 78 else 79 res=vecteur(3,zero); 80 res[2]=plus_two; 81 return res; 82 } 83 do_find_table_brother(Fl_Widget * widget)84 Flv_Table_Gen * do_find_table_brother(Fl_Widget * widget){ 85 if (!widget) 86 return 0; 87 Fl_Group * gr = widget->parent(); 88 if (!gr) 89 return 0; 90 Flv_Table_Gen * spread_ptr=0; 91 int n=gr->children(); 92 for (int i=0;i<n;++i){ 93 if ( (spread_ptr= dynamic_cast<Flv_Table_Gen *>(gr->child(i))) ) 94 break; 95 } 96 if (!spread_ptr) 97 return do_find_table_brother(gr); 98 return spread_ptr; 99 } 100 find_table_brother(Fl_Widget * widget)101 Flv_Table_Gen * find_table_brother(Fl_Widget * widget){ 102 Flv_Table_Gen * ptr = do_find_table_brother(widget); 103 if (!ptr) 104 ptr=do_find_table_brother(Fl::focus()); 105 if (!ptr) 106 fl_alert("%s",gettext("No spreadsheet found. Please click in or add one")); 107 return ptr; 108 } 109 cb_Tableur_Recompute(Fl_Menu_ * m,void *)110 void cb_Tableur_Recompute(Fl_Menu_* m , void*) { 111 Flv_Table_Gen * spread_ptr=find_table_brother(m); 112 if (spread_ptr){ 113 spread_ptr->spread_eval_interrupt(); 114 spread_ptr->redraw(); 115 } 116 } 117 changed()118 void Flv_Table_Gen::changed(){ 119 changed_=true; 120 backup(); 121 } 122 config()123 void Flv_Table_Gen::config(){ 124 static Fl_Window * w = 0; 125 static Fl_Input * varname=0,*input_init=0; // sheet variable name 126 static Fl_Check_Button* evaltype=0,*moveright=0,*mat2cell=0,* issheet=0,*horiz=0,*viewgr=0; 127 static Fl_Value_Input * nrow=0,*ncol=0,*max_hist=0; 128 static Fl_Return_Button * button0 = 0 ; 129 static Fl_Button * button1 =0; 130 if (!w){ 131 int nlignes=8; 132 #ifdef IPAQ 133 int dx=240,dy=300; 134 #else 135 int dx=20*labelsize(), dy=14*labelsize(); 136 #endif 137 Fl_Group::current(0); 138 w=new Fl_Window(dx,dy); 139 varname=new Fl_Input(dx/2,2,dx/2-4,dy/nlignes-4,gettext("Variable")); 140 varname->tooltip(gettext("Save the spreadsheet as a matrix in this variable")); 141 nrow = new Fl_Value_Input(dx/4,2+dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Rows")); 142 nrow->minimum(1); 143 nrow->maximum(1000); 144 nrow->step(1); 145 ncol = new Fl_Value_Input(3*dx/4,2+dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Cols")); 146 ncol->minimum(1); 147 ncol->maximum(1000); 148 ncol->step(1); 149 evaltype = new Fl_Check_Button(2,2+2*dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Eval")); 150 evaltype->tooltip(gettext("Reeval spreadsheet automatically")); 151 // evaltype->callback((Fl_Callback *) cb_Tableur_Recompute); 152 moveright = new Fl_Check_Button(2+dx/2,2+2*dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Move right")); 153 moveright->tooltip(gettext("Move right or down after Enter")); 154 mat2cell = new Fl_Check_Button(2,2+3*dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Distribute")); 155 mat2cell->tooltip(gettext("Matrix input is distributed or kept inside a cell")); 156 issheet = new Fl_Check_Button(2+dx/2,2+3*dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Spreadsheet")); 157 issheet->tooltip(gettext("Matrix or spreadsheet")); 158 horiz = new Fl_Check_Button(2,2+4*dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Landscape")); 159 horiz->tooltip(gettext("Split sheet/graph horizontally or vertically")); 160 viewgr = new Fl_Check_Button(2+dx/2,2+4*dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Graph")); 161 viewgr->tooltip(gettext("Show or hide graph connected to this sheet")); 162 max_hist = new Fl_Value_Input(3*dx/4,2+5*dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Undo history")); 163 input_init = new Fl_Input(3*dx/4,2+6*dy/nlignes,dx/4-2,dy/nlignes-4,gettext("Init sheet")); 164 button0 = new Fl_Return_Button(2,2+7*dy/nlignes,dx/2-4,dy/nlignes-4); 165 button0->shortcut(0xff0d); 166 button0->label(gettext("OK")); 167 button1 = new Fl_Button(dx/2+2,2+7*dy/nlignes,dx/2-4,dy/nlignes-4); 168 button1->shortcut(0xff1b); 169 button1->label(gettext("Cancel")); 170 w->end(); 171 change_group_fontsize(w,labelsize()); 172 w->resizable(w); 173 w->label(gettext("Sheet configuration")); 174 } 175 Tableur_Group * gr = dynamic_cast<Tableur_Group *>(parent()); 176 contextptr = get_context(gr); 177 varname->value(name.print(contextptr).c_str()); 178 nrow->value(rows()); 179 ncol->value(cols()); 180 max_hist->value(max_history); 181 issheet->value(is_spreadsheet); 182 mat2cell->value(matrix_fill_cells); 183 moveright->value(move_right); 184 evaltype->value(spreadsheet_recompute); 185 input_init->value(init.print(contextptr).c_str()); 186 if (gr){ 187 viewgr->value(gr->disposition/2); 188 horiz->value(!(gr->disposition % 2)); 189 } 190 int r=-1; 191 w->set_modal(); 192 w->show(); 193 autosave_disabled=true; 194 w->hotspot(w); 195 Fl::focus(varname); 196 for (;;) { 197 Fl_Widget *o = Fl::readqueue(); 198 if (!o) Fl::wait(); 199 else { 200 if (o == button0) {r = 0; break;} 201 if (o == button1) {r = 1; break;} 202 if (o == w) { r=1; break; } 203 } 204 } 205 autosave_disabled=false; 206 w->hide(); 207 if (!r){ 208 max_history=max(int(max_hist->value()),2); 209 if ( nrow->value()>=1 && ncol->value()>=1 && (nrow->value()!=rows() || ncol->value()!= cols()) ){ 210 changed(); 211 resizesheet(int(nrow->value()),int(ncol->value())); 212 if ((7+nrow->value())*(labelsize()+1)<h()){ 213 increase_size(this,(7+nrow->value())*(labelsize()+1)-h()); 214 } 215 } 216 is_spreadsheet=issheet->value(); 217 matrix_fill_cells=mat2cell->value(); 218 move_right=moveright->value(); 219 is_spreadsheet=issheet->value(); 220 init=gen(input_init->value(),contextptr); 221 if (init.type==_SYMB) 222 protecteval(init,eval_level(contextptr),contextptr); 223 if (!spreadsheet_recompute && evaltype->value()){ 224 spreadsheet_recompute=evaltype->value(); 225 spread_eval_interrupt(); 226 } 227 else 228 spreadsheet_recompute=evaltype->value(); 229 gen tmp(varname->value(),contextptr); 230 if (tmp.type==_IDNT && !is_undef(tmp)){ 231 name=tmp; 232 if (filename) 233 delete filename; 234 filename = new string(tmp.print(contextptr)+".tab"); 235 if (filename){ 236 prefix_filename="Save "+ remove_path(* filename); 237 if (Tableur_Group * gr=dynamic_cast<Tableur_Group *>(parent())){ 238 gr->fname->label(prefix_filename.c_str()); 239 gr->fname->show(); 240 } 241 } 242 sto(extractmatricefromsheet(m),name,contextptr); 243 } 244 if (gr){ 245 if (!viewgr->value() && (gr->disposition & 0x2)) 246 gr->save_dparam(); 247 gr->disposition=2*viewgr->value()+!horiz->value(); 248 gr->resize2(); 249 } 250 update_status(); 251 } 252 if (gr) Fl::focus(gr->table); 253 } 254 spread_erase(int nrows,int ncols)255 void Flv_Table_Gen::spread_erase(int nrows,int ncols){ 256 changed(); 257 if ( (nrows>=rows()) || (ncols>=cols()) ) 258 return; 259 contextptr=get_context(this); 260 m=matrice_erase(m,row(),col(),nrows,ncols,contextptr); 261 rows(rows()-nrows); 262 cols(cols()-ncols); 263 row(min(rows()-1,row())); 264 col(min(cols()-1,col())); 265 update_status(); 266 update_name(); 267 } 268 269 blank(int row_min,int r,int col_min,int c)270 void Flv_Table_Gen::blank(int row_min,int r,int col_min,int c){ 271 changed(); 272 vecteur fill(fillsheet(is_spreadsheet)); 273 if (c<col_min) 274 swap(c,col_min); 275 if (r<row_min) 276 swap(r,row_min); 277 ++r; 278 r=min(rows(),r); 279 ++c; 280 c=min(cols(),c); 281 if ( (c==col_min) || (r==row_min) ) 282 return; 283 selected.clear(); 284 selected.reserve(r-row_min); 285 for (int i=row_min;i<r;++i){ 286 vecteur & v=*m[i]._VECTptr; 287 vecteur tmp; 288 tmp.reserve(c-col_min); 289 for (int j=col_min;j<c;++j){ 290 tmp.push_back(v[j]); 291 v[j]=freecopy(fill); 292 } 293 selected.push_back(tmp); 294 } 295 redraw(); 296 update_name(); 297 } 298 blank()299 void Flv_Table_Gen::blank(){ 300 changed(); 301 int row_min=select_start_row(),r=row(); 302 int col_min=select_start_col(),c=col(); 303 blank(row_min,r,col_min,c); 304 } 305 spread_insert(int nrows,int ncols)306 void Flv_Table_Gen::spread_insert(int nrows,int ncols){ 307 changed(); 308 vecteur fill(fillsheet(is_spreadsheet)); 309 contextptr=get_context(this); 310 m=matrice_insert(m,row(),col(),nrows,ncols,fill,contextptr); 311 rows(rows()+nrows); 312 cols(cols()+ncols); 313 update_status(); 314 redraw(); 315 update_name(); 316 } 317 addrowatend()318 void Flv_Table_Gen::addrowatend(){ 319 changed(); 320 vecteur fill(fillsheet(is_spreadsheet)); 321 int C=cols(); 322 vecteur addrow(C); 323 for (int j=0;j<C;++j) 324 addrow[j]=freecopy(fill); 325 m.push_back(addrow); 326 rows(rows()+1); 327 update_status(); 328 redraw(); 329 update_name(); 330 } 331 addcolatend()332 void Flv_Table_Gen::addcolatend(){ 333 changed(); 334 vecteur fill(fillsheet(is_spreadsheet)); 335 int R=rows(); 336 for (int i=0;i<R;++i){ 337 m[i]._VECTptr->push_back(freecopy(fill)); 338 } 339 cols(cols()+1); 340 update_status(); 341 redraw(); 342 update_name(); 343 } 344 resizesheet(int nr,int nc)345 void Flv_Table_Gen::resizesheet(int nr,int nc){ 346 changed(); 347 int cur_r=rows(); 348 vecteur fill(fillsheet(is_spreadsheet)); 349 if (nr<cur_r) // erase rows 350 m=vecteur(m.begin(),m.begin()+nr); 351 else { 352 for (;cur_r<nr;++cur_r){ 353 vecteur tmp; 354 for (int j=0;j<nc;++j) 355 tmp.push_back(freecopy(fill)); 356 m.push_back(tmp); 357 } 358 } 359 for (int i=0;i<nr;++i){ 360 vecteur & v=*m[i]._VECTptr; 361 int cur_c=v.size(); 362 if (nc<cur_c){ 363 m[i]=vecteur(v.begin(),v.begin()+nc); 364 } 365 else { 366 for (;cur_c<nc;++cur_c) 367 v.push_back(freecopy(fill)); 368 } 369 } 370 rows(nr); 371 cols(nc); 372 row(0); 373 col(0); 374 spread_eval_interrupt(); 375 update_status(); 376 redraw(); 377 update_name(); 378 } 379 copy(int clipboard)380 void Flv_Table_Gen::copy(int clipboard){ 381 contextptr = get_context(this); 382 int row_min=select_start_row(),r=row(); 383 int col_min=select_start_col(),c=col(); 384 selected.clear(); 385 if (c<col_min) 386 swap(c,col_min); 387 if (r<row_min) 388 swap(r,row_min); 389 ++r; 390 ++c; 391 if ( (c==col_min) || (r==row_min) ) 392 return; 393 selected.reserve(r-row_min); 394 for (int i=row_min;i<r;++i){ 395 vecteur tmp; 396 tmp.reserve(c-col_min); 397 for (int j=col_min;j<c;++j){ 398 tmp.push_back(m[i][j]); 399 } 400 selected.push_back(tmp); 401 } 402 gen g(extractmatricefromsheet(selected)); 403 static string s; 404 s=g.print(contextptr); 405 // Fl::selection(*this,s.c_str(),s.size()); 406 Fl::copy(s.c_str(),s.size(),clipboard); 407 update_name(); 408 } 409 copy_right()410 void Flv_Table_Gen::copy_right(){ 411 changed(); 412 int R=row(),C=col(); 413 int c=cols(),r=rows(); 414 int R0=select_start_row(); 415 if (R0<0 || R0>=r) 416 R0=R; 417 if (R0<R) 418 giac::swapint(R0,R); 419 for (;R<=R0;++R){ 420 vecteur & v=*m[R]._VECTptr; 421 gen g=v[C]; 422 for (int i=C+1;i<c;++i){ 423 v[i]=freecopy(g); 424 } 425 } 426 spread_eval_interrupt(); 427 redraw(); 428 } 429 copy_down()430 void Flv_Table_Gen::copy_down(){ 431 changed(); 432 int R=row(),C=col(); 433 int r=rows(),c=cols(); 434 int C0=select_start_col(); 435 if (C0<0 || C0>=c) 436 C0=C; 437 if (C0<C) 438 giac::swapint(C0,C); 439 for (;C<=C0;++C){ 440 gen g=m[R][C]; 441 for (int i=R+1;i<r;++i){ 442 vecteur & v=*m[i]._VECTptr; 443 v[C]=freecopy(g); 444 } 445 } 446 spread_eval_interrupt(); 447 redraw(); 448 } 449 copy_first_in_selection()450 void Flv_Table_Gen::copy_first_in_selection(){ 451 changed(); 452 int R=row(),C=col(); 453 int r=select_start_row(),c=select_start_col(); 454 if (r==R && c==C) 455 return; 456 gen g=m[r][c]; 457 if (r<R) 458 giac::swapint(r,R); 459 if (c<C) 460 giac::swapint(c,C); 461 R=max(R,0); C=max(C,0); r=min(r,rows()-1); c=min(c,cols()-1); 462 for (int i=R;i<=r;++i){ 463 vecteur & v=*m[i]._VECTptr; 464 for (int j=C;j<=c;++j) 465 v[j]=freecopy(g); 466 } 467 spread_eval_interrupt(); 468 update_input(); 469 redraw(); 470 } 471 paste(const matrice & m_orig,bool reeval)472 void Flv_Table_Gen::paste(const matrice & m_orig,bool reeval){ 473 changed(); 474 contextptr=get_context(this); 475 matrice m_copy(makefreematrice(m_orig)); 476 makespreadsheetmatrice(m_copy,contextptr); 477 int nr,nc; 478 mdims(m_copy,nr,nc); 479 int r=row(),c=col(); 480 if (r+nr>rows()||c+nc>cols()) 481 resizesheet(max(r+nr,rows()),max(c+nc,cols())); 482 int R=min(r+nr,rows()),C=min(c+nc,cols()); 483 for (int i=r;i<R;++i){ 484 vecteur & v=*m[i]._VECTptr; 485 for (int j=c;j<C;++j){ 486 v[j]=m_copy[i-r][j-c]; 487 } 488 } 489 if (reeval) 490 spread_eval_interrupt(); 491 update_input(); 492 redraw(); 493 } 494 erase_row_col(int i)495 void Flv_Table_Gen::erase_row_col(int i){ 496 int R=row(),C=col(); 497 // erase rows push_row -> R && push_col -> C 498 if (i==2) 499 i=fl_choice(gettext("Remove what?"),gettext("Rows"),gettext("Cols"),gettext("Cancel")); 500 int r1=min(push_row,R),r2=absint(push_row-R)+1,c1=min(push_col,C),c2=absint(push_col-C)+1; 501 if (i==0){ 502 row(r1); 503 push_row=r1; 504 spread_erase(r2,0); 505 } 506 if (i==1){ 507 col(c1); 508 push_col=c1; 509 spread_erase(0,c2); 510 } 511 } 512 update_goto()513 void Flv_Table_Gen::update_goto(){ 514 contextptr = get_context(this); 515 if (_goto){ 516 printcell_current_row(contextptr)=row(); 517 printcell_current_col(contextptr)=col(); 518 string s_s=printcell(makevecteur(makevecteur(0),makevecteur(0)),contextptr); 519 _goto->value(s_s.c_str()); 520 } 521 } 522 update_input()523 void Flv_Table_Gen::update_input(){ 524 contextptr = get_context(this); 525 int R=row(); 526 int C=col(); 527 edit_row=R; 528 edit_col=C; 529 if (input && R<rows() && C<cols()){ 530 gen tmp=m[R][col()]; 531 if (tmp.type==_VECT && tmp._VECTptr->size()==3) 532 tmp=tmp._VECTptr->front(); 533 input->value(tmp.print(contextptr).c_str()); 534 input->position(0,input->value().size()); 535 // input->position(0,strlen(input->value())); 536 } 537 } 538 enter_move()539 void Flv_Table_Gen::enter_move(){ 540 int R=row(),C=col(); 541 if (!move_right){ 542 if (R<rows()-1) 543 row(R+1); 544 else { 545 row(0); 546 if (C<cols()-1) 547 col(C+1); 548 else 549 col(0); 550 } 551 } 552 else { 553 if (C<cols()-1) 554 col(C+1); 555 else { 556 col(0); 557 if (R<rows()-1) 558 row(R+1); 559 else 560 row(0); 561 } 562 } 563 select_start_row(row()); 564 select_start_col(col()); 565 update_goto(); 566 redraw(); 567 update_input(); 568 } 569 570 handle(int event)571 int Flv_Table_Gen::handle(int event){ 572 if (event==FL_MOUSEWHEEL){ 573 if (!Fl::event_inside(this)) 574 return 0; 575 } 576 contextptr = get_context(this); 577 static string s; 578 if (Fl::event_button()== FL_RIGHT_MOUSE) 579 return 0; 580 last_event=event; 581 if (event==FL_KEYBOARD){ 582 Xcas_input_focus=this; 583 // int mode=Fl::event_state(FL_CTRL); 584 if (Fl::event_key()==FL_Escape){ 585 editing=false; 586 // cerr << "Mtrw edit leave"<<'\n'; 587 } 588 if (Fl::event_key()==FL_Delete){ 589 erase_row_col(2); 590 return 1; 591 } 592 if (Fl::event_key()==FL_Enter || Fl::event_key()==FL_KP_Enter){ 593 enter_move(); 594 return 1; 595 } 596 switch (Fl::event_key()){ 597 case FL_Control_R: case FL_Control_L: case FL_Alt_L: case FL_Alt_R: 598 return 0; 599 } 600 char ch=Fl::event_text()?Fl::event_text()[0]:0; 601 if (ch==3){ 602 if (selected.empty() && row()>=0 && row()<rows() && col()>=0 && col()<cols()) 603 selected_1=vecteur(1,vecteur(1,m[row()][col()])); 604 else 605 selected_1=selected; 606 copy(1); 607 return 1; 608 } 609 if (ch==22){ 610 if (selected_1.empty()){ 611 Fl::paste(*this,1); 612 } 613 else 614 paste(selected_1); 615 return 1; 616 } 617 if (ch==25){ 618 restore(1); 619 return 1; 620 } 621 if (ch==26){ 622 restore(-1); 623 return 1; 624 } 625 if (ch==4 || ch==18) 626 return 0; 627 } 628 int res=Flv_Table::handle(event); 629 if (!editing){ 630 edit_row=row(); 631 edit_col=col(); 632 } 633 bool shift=Fl::event_state(FL_SHIFT); 634 if (event==FL_FOCUS){ 635 Fl::focus(this); 636 return 1; 637 } 638 if (event==FL_PUSH && Fl::focus()!=this) 639 Fl::focus(this); 640 if (event==FL_RELEASE){ 641 set_cursor(this,FL_CURSOR_ARROW); 642 if (editing) 643 click_fill=false; 644 if (click_fill){ // fill area 645 copy_first_in_selection(); 646 click_fill=false; 647 return 1; 648 } 649 } 650 if (event==FL_RELEASE && Fl::event_button()== FL_MIDDLE_MOUSE ){ 651 Fl::paste(*this); 652 return 1; 653 } 654 if (event==FL_PASTE){ 655 if (selected.empty()){ 656 Fl::focus(input); 657 input->handle(FL_PASTE); 658 input->do_callback(); 659 } 660 else 661 paste(selected); 662 return 1; 663 } 664 if ( event==FL_UNFOCUS || event==FL_HIDE || event==FL_SHOW ){ 665 /* 666 if (event==FL_UNFOCUS){ 667 selected.clear(); 668 selected_1.clear(); 669 } 670 */ 671 return res; 672 } 673 if (res){ 674 int R=row(),C=col(); 675 printcell_current_row(contextptr)=R; 676 printcell_current_col(contextptr)=C; 677 s=printcell(makevecteur(makevecteur(0),makevecteur(0)),contextptr); 678 bool head=header_event==FLVE_ROW_HEADER_CLICKED || header_event==FLVE_COL_HEADER_CLICKED ||header_event==FLVE_ROW_FOOTER_CLICKED || header_event==FLVE_COL_FOOTER_CLICKED; 679 if (head){ 680 if (event==FL_PUSH){ 681 if (header_event==FLVE_ROW_HEADER_CLICKED){ 682 push_col=col(); 683 push_row=rows()-1; 684 } 685 if (header_event==FLVE_ROW_FOOTER_CLICKED){ 686 push_col=col(); 687 push_row=0; 688 } 689 if (header_event==FLVE_COL_HEADER_CLICKED){ 690 push_col=cols()-1; 691 push_row=row(); 692 } 693 if (header_event==FLVE_COL_FOOTER_CLICKED){ 694 push_col=0; 695 push_row=row(); 696 } 697 } 698 s=printcell(makevecteur(makevecteur(push_row-R),makevecteur(push_col-C)),contextptr)+":"+s; 699 } 700 else { // else head 701 if (event==FL_PUSH){ 702 if (shift){ 703 editing=false; 704 select_start_row(push_row); 705 select_start_col(push_col); 706 } 707 else { 708 push_row=R; 709 push_col=C; 710 } 711 if (!editing){ 712 edit_row=R; 713 edit_col=C; 714 } 715 } 716 else { 717 if (push_row!=R || push_col!=C) { 718 if (editing) 719 s=printcell(makevecteur(makevecteur(push_row-R),makevecteur(push_col-C)),contextptr)+":"+s; 720 else 721 if (event==FL_DRAG || event==FL_RELEASE ){ 722 s=printcell(makevecteur(makevecteur(push_row-R),makevecteur(push_col-C)),contextptr)+":"+s; 723 } 724 } 725 } 726 } // end else header_event 727 if (event!=FL_ENTER && event!=FL_LEAVE && event!=FL_MOVE && _goto) 728 _goto->value(s.c_str()); 729 if (editing && (header_event || (event==FL_PUSH || event ==FL_DRAG || event == FL_RELEASE) ) ){ 730 header_event = 0; 731 if (event==FL_PUSH || event ==FL_DRAG || event == FL_RELEASE) 732 input->insert_replace(s.c_str(),true); 733 if (event==FL_RELEASE){ 734 row(edit_row); col(edit_col); select_start_row(edit_row); select_start_col(edit_col); 735 Fl::focus(input); 736 // int s=strlen(input->value()); 737 input->position(input->mark(),input->mark()); 738 if (_goto){ 739 _goto->value(printcell(makevecteur(makevecteur(edit_row-R),makevecteur(edit_col-C)),contextptr).c_str()); 740 } 741 return 1; 742 } 743 if (editing) 744 return 1; 745 } 746 if (head || (event==FL_RELEASE && (push_row!=R || push_col!=C)) ){ 747 header_event = 0; 748 copy(); 749 if (Xcas_help_output){ 750 gen g=extractmatricefromsheet(selected); 751 static string s1; 752 s1=g.print(contextptr); 753 Xcas_help_output->value(s1.c_str()); 754 } 755 return 1; 756 } 757 if ( !editing && (C>=0) && (R>=0) && (event!=FL_MOVE) && (event!=FL_ENTER) && (event!=FL_LEAVE) ){ 758 if ( (m[R][C].type==_VECT) && (m[R][C]._VECTptr->size()==3) ){ 759 int save_r=printcell_current_row(contextptr),save_c=printcell_current_col(contextptr); 760 printcell_current_row(contextptr)=R,printcell_current_col(contextptr)=C; 761 s=m[R][C][0].print(contextptr); 762 printcell_current_row(contextptr)=save_r;printcell_current_col(contextptr)=save_c; 763 } 764 else 765 s=m[R][C].print(contextptr); 766 input->value(s.c_str()); 767 input->position(0,s.size()); 768 } 769 } 770 if (!res && !shift && event==FL_KEYBOARD && !editing){ 771 editing=true; 772 edit_row=row(); edit_col=col(); 773 Fl::focus(input); 774 int r=Fl::handle(FL_KEYBOARD,window()); 775 return 1; 776 } 777 return res; 778 } 779 780 #ifdef HAVE_LIBPTHREAD in_thread_spread_eval(void * arg)781 void * in_thread_spread_eval(void * arg){ 782 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); 783 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); 784 vecteur *v = (vecteur *) arg; 785 context * contextptr=(context *) (*v)[2]._POINTER_val; 786 matrice * mptr = (matrice *) (*v)[0]._POINTER_val; 787 giac::spread_eval(*mptr,contextptr); 788 thread_eval_status(0,contextptr); 789 pthread_exit(0); 790 } 791 thread_spread_eval(matrice & m,GIAC_CONTEXT)792 void thread_spread_eval(matrice &m,GIAC_CONTEXT){ 793 if (is_context_busy(contextptr)) 794 return; 795 bool old_io_graph=io_graph(contextptr); 796 io_graph(false,contextptr); 797 pthread_t spread_eval_thread; 798 giac::vecteur v(3); 799 v[0]=gen((void *)&m,3); 800 v[2]=gen((void *) contextptr,3); 801 thread_eval_status(1,contextptr); 802 pthread_mutex_lock(mutexptr(contextptr)); 803 int cres=pthread_create (&spread_eval_thread, (pthread_attr_t *) NULL, in_thread_spread_eval,(void *)&v); 804 if (!cres){ 805 Fl::remove_idle(xcas::Xcas_idle_function,0); 806 for (;;){ 807 int eval_status=thread_eval_status(contextptr); 808 if (!eval_status) 809 break; 810 Fl::wait(0.0001); 811 if (kill_thread(contextptr)){ 812 kill_thread(false,contextptr); 813 try { 814 pthread_cancel(spread_eval_thread) ; 815 } catch (std::runtime_error & err){ 816 } 817 pthread_mutex_unlock(mutexptr(contextptr)); 818 Fl::add_idle(xcas::Xcas_idle_function,0); 819 fl_message("%s",gettext("computation aborted")); 820 io_graph(old_io_graph,contextptr); 821 return ; 822 } 823 Xcas_idle_function((void *)contextptr); 824 } 825 void * ptr; 826 pthread_join(spread_eval_thread,&ptr); 827 // Restore pointers 828 pthread_mutex_unlock(mutexptr(contextptr)); 829 Fl::add_idle(xcas::Xcas_idle_function,0); 830 return ; 831 } 832 pthread_mutex_unlock(mutexptr(contextptr)); 833 spread_eval(m,contextptr); 834 io_graph(old_io_graph,contextptr); 835 } 836 837 #else 838 thread_spread_eval(matrice & m,GIAC_CONTEXT)839 void thread_spread_eval(matrice &m,GIAC_CONTEXT){ 840 spread_eval(m,contextptr); 841 } 842 #endif 843 set_matrix(const matrice & mym,bool interruptible,bool reeval)844 void Flv_Table_Gen::set_matrix(const matrice & mym,bool interruptible,bool reeval){ 845 changed(); 846 m=makefreematrice(mym); 847 cols(mcols(m)); 848 rows(m.size()); 849 contextptr=get_context(this); 850 makespreadsheetmatrice(m,contextptr); 851 if (is_spreadsheet && reeval) { 852 if (interruptible) 853 spread_eval_interrupt(); 854 else { 855 evaled_table(contextptr)=(void *) this; 856 spread_eval(m,contextptr); 857 } 858 } 859 /* 860 if (is_spreadsheet) 861 spread_eval_interrupt(); 862 */ 863 is_spreadsheet=false; 864 if ( !mym.empty() && (!mym.front()._VECTptr->empty()) ) 865 is_spreadsheet=(mym[0][0].type==_VECT); 866 move_on_enter(FLV_MOVE_ON_ENTER_COL_ROW); 867 col(0); 868 row(0); 869 select_start_row(0); 870 select_start_col(0); 871 redraw(); 872 } 873 update_status()874 void Flv_Table_Gen::update_status() { 875 contextptr = get_context(this); 876 redraw(); 877 status_string = "Sheet config: "; 878 status_string += changed_?"* ":"- "; 879 status_string += is_spreadsheet?"Spreadsheet ":"Matrix "; 880 status_string += (name.type==_IDNT?name.print(contextptr):string("<>"))+" "; 881 if (filename){ 882 if (Fl_Group * g=parent()){ 883 int n=g->children(); 884 for (int i=0;i<n;++i){ 885 if (Fl_Output * o=dynamic_cast<Fl_Output *>(g->child(i))){ 886 o->value(filename->c_str()); 887 } 888 } 889 } 890 } 891 status_string += "R" +print_INT_(rows())+"C"+print_INT_(cols())+" "; 892 status_string += spreadsheet_recompute?"auto ":"manual "; 893 switch(matrix_symmetry){ 894 case 1: 895 status_string += "Antihermitian "; 896 break; 897 case 2: 898 status_string += "Hermitian "; 899 break; 900 case 3: 901 status_string += "Antisymmetric "; 902 break; 903 case 4: 904 status_string += "Symmetric "; 905 } 906 status_string += move_right?"right ":"down "; 907 status_string += matrix_fill_cells?"fill":"cell"; 908 label(status_string.c_str()); 909 } 910 set_matrix(const gen & g,bool interruptible,bool reeval)911 void Flv_Table_Gen::set_matrix(const gen & g,bool interruptible,bool reeval){ 912 changed(); 913 if (!ckmatrix(g,true)) 914 settypeerr(); 915 set_matrix(*g._VECTptr,interruptible,reeval); 916 } 917 backup()918 void Flv_Table_Gen::backup(){ 919 int vs=m_history.size(); 920 if (cur_history==vs){ 921 if (vs==max_history) 922 m_history.erase(m_history.begin()); 923 else 924 ++cur_history; 925 m_history.push_back(makefreematrice(m)); 926 } 927 else { 928 m_history[cur_history]=makefreematrice(m); 929 ++cur_history; 930 } 931 } 932 restore(int delta)933 void Flv_Table_Gen::restore(int delta){ 934 int vs=m_history.size(); 935 if (delta==-1 && cur_history==vs){ 936 backup(); 937 --delta; 938 } 939 cur_history += delta; 940 if (cur_history<0) 941 cur_history=0; 942 if (vs && cur_history<vs){ 943 m=*m_history[cur_history]._VECTptr; 944 changed_=true; 945 int r,c; 946 mdims(m,r,c); 947 rows(r); 948 cols(c); 949 redraw(); 950 } 951 else 952 cur_history=vs; 953 } 954 ~Flv_Table_Gen()955 Flv_Table_Gen::~Flv_Table_Gen(){ 956 if (Xcas_input_focus==this) Xcas_input_focus=0; 957 contextptr=get_context(this); 958 if (evaled_table(contextptr)==this) 959 evaled_table(contextptr)=0; 960 if (win2){ 961 win2->hide(); 962 delete win2; 963 } 964 if (win3){ 965 win3->hide(); 966 delete win3; 967 } 968 } 969 Flv_Table_Gen(int X,int Y,int W,int H,const matrice & mym,const char * l)970 Flv_Table_Gen::Flv_Table_Gen( int X, int Y, int W, int H ,const matrice & mym, const char *l) : Flv_Table(X,Y,W,H,l),max_history(4),cur_history(0),matrix_fill_cells(true),move_right(false),matrix_symmetry(0),spreadsheet_recompute(true),push_row(0),push_col(0),contextptr(0),editing(false),computing(false),filename(0),max_printsize(1024) { 971 if (!ckmatrix(mym)) 972 settypeerr(); 973 set_matrix(mym,false); 974 changed_=false; 975 graph3d=0; graph2d=0; graph=0; _goto=0; input=0; 976 name=0; init=0; 977 finish_flv_table_gen(); 978 } 979 Flv_Table_Gen(int X,int Y,int W,int H,const gen & g,const char * l)980 Flv_Table_Gen::Flv_Table_Gen( int X, int Y, int W, int H ,const gen &g, const char *l) : Flv_Table(X,Y,W,H,l),matrix_fill_cells(true),move_right(false),matrix_symmetry(0),spreadsheet_recompute(true),push_row(0),push_col(0),contextptr(0),editing(false),computing(false),filename(0),max_printsize(1024) { 981 set_matrix(g,false); 982 changed_=false; 983 graph2d=0; graph3d=0; graph=0; _goto=0; input=0; 984 name=0; init=0; 985 finish_flv_table_gen(); 986 } 987 parse_interval(const char * ch)988 gen parse_interval(const char * ch){ 989 gen g=undef; 990 string s; 991 int l=strlen(ch); 992 for (int i=0;i<l;++i,++ch){ 993 if (*ch==':') 994 s += ".."; 995 else 996 s+=*ch; 997 } 998 try { 999 g=gen(s,context0); // ok 1000 } 1001 catch (std::runtime_error & e){ 1002 if (Xcas_help_output) 1003 Xcas_help_output->value(e.what()); 1004 } 1005 return g; 1006 } 1007 next_cell(const string & s,Flv_Table_Gen * ptr)1008 string next_cell(const string & s,Flv_Table_Gen * ptr){ 1009 if (!ptr) return ""; 1010 const giac::context * contextptr = get_context(ptr); 1011 int maxr=ptr->rows(),maxc=ptr->cols(); 1012 gen g=parse_interval(s.c_str()); 1013 if (g.is_symb_of_sommet(at_interval)){ 1014 gen & f=g._SYMBptr->feuille; 1015 if (f.type!=_VECT || f._VECTptr->size()!=2) 1016 return ""; 1017 int r1,r2,c1,c2; 1018 if (!iscell(f._VECTptr->front(),c1,r1,contextptr) || !iscell(f._VECTptr->back(),c2,r2,contextptr)) 1019 return ""; 1020 if (r1>r2) 1021 giac::swapint(r1,r2); 1022 if (c1>c2) 1023 giac::swapint(c1,c2); 1024 // search for an empty cell 1025 for (int j=c2+1;j<maxc;++j){ 1026 for (int i=0;i<maxr;++i){ 1027 gen tmp=ptr->m[i][j][0]; 1028 if (is_zero(tmp,contextptr)|| (tmp.type==_STRNG && tmp._STRNGptr->empty())){ 1029 int pr1=printcell_current_row(contextptr),pc1=printcell_current_col(contextptr); 1030 printcell_current_row(contextptr)=printcell_current_col(contextptr)=0; 1031 string s=printcell(makevecteur(vecteur(1,i),vecteur(1,j)),contextptr); 1032 printcell_current_row(contextptr)=pr1; 1033 printcell_current_col(contextptr)=pc1; 1034 return s; 1035 } 1036 } 1037 } 1038 } 1039 return ""; 1040 } 1041 cb_Spread_goto(Fl_Widget * widg,void *)1042 void cb_Spread_goto(Fl_Widget* widg, void*) { 1043 // Find a spreadsheet in the brothers of widget (parent's children) 1044 Flv_Table_Gen * spread_ptr=find_table_brother(widg); 1045 const giac::context * contextptr = get_context(spread_ptr); 1046 if (!spread_ptr) 1047 return; 1048 Fl::focus(spread_ptr); 1049 Fl_Input * widget=dynamic_cast<Fl_Input *>(widg); 1050 gen g=undef; 1051 if (widget) 1052 g=parse_interval(widget->value()); 1053 int r,c; 1054 if (iscell(g,c,r,contextptr) ){ 1055 if (r>=spread_ptr->rows()||c>=spread_ptr->cols()) 1056 spread_ptr->resizesheet(max(r+1,spread_ptr->rows()),max(c+1,spread_ptr->cols())); 1057 // cerr << g << " " << r << " " << c << '\n'; 1058 spread_ptr->row(r); 1059 spread_ptr->col(c); 1060 spread_ptr->select_start_row(r); 1061 spread_ptr->select_start_col(c); 1062 printcell_current_row(contextptr)=r; 1063 printcell_current_col(contextptr)=c; 1064 if (spread_ptr->input){ 1065 string s(spread_ptr->m[r][c][0].print(contextptr)); 1066 spread_ptr->input->value(s.c_str()); 1067 spread_ptr->input->position(s.size(),0); 1068 } 1069 return; 1070 } 1071 matrice m; 1072 if (iscell_range(g,spread_ptr->m,spread_ptr->selected,spread_ptr) ){ 1073 g=extractmatricefromsheet(spread_ptr->selected); 1074 string s(g.print(contextptr)); 1075 Fl::selection(*spread_ptr,s.c_str(),s.size()); 1076 if (Xcas_help_output) 1077 Xcas_help_output->value(s.c_str()); 1078 } 1079 } 1080 1081 // scan filename supposed to be a CSV data file 1082 // guess separator and newline character csv_guess(const string & filename,char & sep,char & nl,char & decsep)1083 bool csv_guess(const string & filename,char & sep,char & nl,char & decsep){ 1084 struct stat st; 1085 if (stat(filename.c_str(),&st)==ENOENT) 1086 return false; 1087 FILE * f=fopen(filename.c_str(),"r"); 1088 if (!f) 1089 return false; 1090 size_t size=1,count=st.st_size; 1091 char data[count]; 1092 fread(data,size,count,f); 1093 fclose(f); 1094 return giac::csv_guess(data,count,sep,nl,decsep); 1095 } 1096 cb_Sheet_Input(Fl_Widget * widg,void *)1097 void cb_Sheet_Input(Fl_Widget* widg, void*) { 1098 Flv_Table_Gen * spread_ptr=find_table_brother(widg); 1099 if (!spread_ptr) 1100 return; 1101 context * contextptr=get_context(spread_ptr); 1102 Fl::focus(spread_ptr); 1103 if (spread_ptr && spread_ptr->editing){ 1104 spread_ptr->editing=false; 1105 // cerr << "Mtrw edit end" << '\n'; 1106 spread_ptr->row(spread_ptr->edit_row); 1107 spread_ptr->col(spread_ptr->edit_col); 1108 } 1109 spread_ptr->changed(); 1110 int R=spread_ptr->row(),C=spread_ptr->col(); 1111 string str(spread_ptr->input->value()); 1112 gen g; 1113 try { 1114 g=gen(str,contextptr); 1115 } 1116 catch (std::runtime_error & e){ 1117 cerr << e.what() << '\n'; 1118 } 1119 // count number of newline 1120 unsigned strs=str.size(); 1121 unsigned nlpos=str.find('\n'); 1122 if (giac::first_error_line(contextptr)>0 && nlpos>0 && nlpos<strs-1){ 1123 char nl,sep,decsep,eof=-1; 1124 // removed the test sep!=' ' 1125 if (giac::csv_guess(str.c_str(),strs,sep,nl,decsep)){ 1126 if (str[strs-1]!=nl) 1127 str += nl; 1128 istringstream i(str); 1129 matrice M(csv2gen(i,sep,nl,decsep,eof,contextptr)); 1130 int nc=M.front()._VECTptr->size(); 1131 if (nc>=2 && ckmatrix(M,true)){ 1132 makespreadsheetmatrice(M,contextptr); // in place modifications of value 1133 spread_ptr->paste(M); 1134 if (spread_ptr->move_right){ 1135 C += nc-1; 1136 if (C<spread_ptr->cols()){ 1137 spread_ptr->col(C); 1138 spread_ptr->enter_move(); 1139 } 1140 } 1141 else { 1142 R += M.size()-1; 1143 if (R<spread_ptr->rows()){ 1144 spread_ptr->row(R); 1145 spread_ptr->enter_move(); 1146 } 1147 } 1148 return; 1149 } 1150 } 1151 } 1152 int dofill=0; 1153 if ( (R>=0) && (C>=0) ){ 1154 vecteur & v=*spread_ptr->m[R]._VECTptr; 1155 if (g.type==_SYMB){ 1156 if ( (g._SYMBptr->sommet==at_tablefunc ) || (g._SYMBptr->sommet==at_tableseq) ) { 1157 if (g._SYMBptr->sommet==at_tablefunc) 1158 dofill=2; 1159 else 1160 dofill=1; 1161 spread_ptr->is_spreadsheet=true; 1162 // FIXME update_sheet_label(); 1163 R=-1; 1164 g=protecteval(g,eval_level(contextptr),contextptr); 1165 spread_ptr->row(0); 1166 } 1167 else { 1168 if (!spread_ptr->is_spreadsheet || spread_ptr->matrix_fill_cells) 1169 g=protecteval(g,eval_level(contextptr),contextptr); 1170 } 1171 } 1172 if ( spread_ptr->matrix_fill_cells && g.type==_VECT){ 1173 matrice & m=*g._VECTptr; 1174 if (!ckmatrix(m)) 1175 m=vecteur(1,m); 1176 spread_ptr->paste(m); 1177 spread_ptr->redraw(); 1178 Fl::focus(spread_ptr); 1179 spread_ptr->row(giacmin(R+m.size(),spread_ptr->rows())); 1180 if (dofill){ 1181 spread_ptr->copy_down(); 1182 if (dofill==2){ 1183 spread_ptr->col(spread_ptr->col()+1); 1184 spread_ptr->copy_down(); 1185 } 1186 } 1187 spread_ptr->select_start_row(spread_ptr->row()); 1188 spread_ptr->select_start_col(spread_ptr->col()); 1189 spread_ptr->update_goto(); 1190 spread_ptr->update_input(); 1191 return; 1192 } 1193 if ( (v[C].type==_VECT) && (v[C]._VECTptr->size()==3)){ 1194 v[C]._VECTptr->front()=spread_convert(g,R,C,contextptr); 1195 if (!spread_ptr->is_spreadsheet) 1196 (*v[C]._VECTptr)[1]=g; 1197 if (spread_ptr->spreadsheet_recompute) 1198 spread_ptr->spread_eval_interrupt(); 1199 else 1200 (*v[C]._VECTptr)[1]=g; 1201 } 1202 else 1203 v[C]=g; 1204 if (spread_ptr->matrix_symmetry && spread_ptr->matrix_symmetry %2) 1205 g=-g; 1206 if (spread_ptr->matrix_symmetry && spread_ptr->matrix_symmetry/2) 1207 g=conj(g,contextptr); 1208 if (spread_ptr->matrix_symmetry && !spread_ptr->is_spreadsheet && (spread_ptr->rows()==spread_ptr->cols()) ){ 1209 vecteur & v=*spread_ptr->m[C]._VECTptr; 1210 if ( (v[R].type==_VECT) && (v[R]._VECTptr->size()==3)){ 1211 v[R]._VECTptr->front()=spread_convert(g,C,R,contextptr); 1212 (*v[R]._VECTptr)[1]=g; 1213 } 1214 else 1215 v[R]=g; 1216 } 1217 spread_ptr->enter_move(); 1218 } 1219 } 1220 1221 cb_Tableur_Eval_Sheet(Fl_Widget * m,void *)1222 void cb_Tableur_Eval_Sheet(Fl_Widget * m , void*) { 1223 Flv_Table_Gen * tg=find_table_brother(m); 1224 if (tg) 1225 tg->spread_eval_interrupt(); 1226 } 1227 cb_Tableur_Init(Fl_Widget * m,void * param)1228 void cb_Tableur_Init(Fl_Widget * m , void*param) { 1229 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1230 const giac::context * contextptr =get_context(spread_ptr); 1231 if (spread_ptr){ 1232 protecteval(spread_ptr->init,eval_level(contextptr),contextptr); 1233 cb_Tableur_Eval_Sheet(m,param); 1234 } 1235 } 1236 cb_Tableur_Value(Fl_Widget * m,void *)1237 void cb_Tableur_Value(Fl_Widget * m , void*) { 1238 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1239 const giac::context * contextptr =get_context(spread_ptr); 1240 if (spread_ptr){ 1241 int R=spread_ptr->row(),C=spread_ptr->col(); 1242 if (spread_ptr->m.size()>unsigned(R)){ 1243 gen g=spread_ptr->m[R]; 1244 if (g.type==_VECT && g._VECTptr->size()>unsigned(C)){ 1245 g=(*g._VECTptr)[C]; 1246 if (g.type==_VECT && g._VECTptr->size()>2) 1247 g=(*g._VECTptr)[1]; 1248 spread_ptr->input->value(g.print(contextptr).c_str()); 1249 } 1250 } 1251 } 1252 } 1253 1254 /* 1255 void cb_Tableur_LaTeX_Preview(Fl_Menu_* m , void*) { 1256 Flv_Table_Gen * tg=find_table_brother(m); 1257 } 1258 1259 void cb_Tableur_LaTeX_Print(Fl_Menu_* m , void*) { 1260 Flv_Table_Gen * tg=find_table_brother(m); 1261 } 1262 */ 1263 1264 void cb_Tableur_Save(Fl_Widget* m , void*); 1265 get_filename(string & tmp,const string & extension)1266 bool get_filename(string & tmp,const string & extension){ 1267 for (;;){ 1268 char * newfile = file_chooser(gettext("Save sheet"), ("*."+extension).c_str(), ""); 1269 if ( (!newfile) || (!*newfile)) 1270 return false; 1271 tmp=newfile; 1272 // tmp=remove_path(newfile); 1273 if (tmp.size()>1000) 1274 tmp=tmp.substr(0,1000); 1275 tmp=remove_extension(tmp.c_str())+"."+extension; 1276 if (access(tmp.c_str(),R_OK)) 1277 return true; 1278 int i=fl_ask("%s",(tmp+gettext(": file exists. Overwrite?")).c_str()); 1279 if (i==1) 1280 return true; 1281 } 1282 return false; 1283 } 1284 cb_Tableur_Graph2d(Fl_Widget * m,void *)1285 void cb_Tableur_Graph2d(Fl_Widget* m , void*) { 1286 Flv_Table_Gen * tg=find_table_brother(m); 1287 if (tg && tg->graph2d) 1288 tg->graph2d->window()->show(); 1289 } 1290 cb_Tableur_Graph3d(Fl_Widget * m,void *)1291 void cb_Tableur_Graph3d(Fl_Widget* m , void*) { 1292 Flv_Table_Gen * tg=find_table_brother(m); 1293 if (tg){ 1294 if (tg->win3){ 1295 delete tg->graph3d; 1296 delete tg->win3; 1297 } 1298 Fl_Group::current(0); 1299 tg->win3=new Fl_Window(tg->x()+10,tg->y()+10,2*tg->w()/3,2*tg->h()/3); 1300 #ifdef HAVE_LIBFLTK_GL 1301 tg->graph3d = new Graph3d(0,0,tg->win3->w(),tg->win3->h(),"",0); 1302 tg->graph3d->ylegende=1.5; 1303 tg->win3->end(); 1304 tg->win3->resizable(tg->win3); 1305 tg->win3->show(); 1306 tg->update_spread_graph(); 1307 #endif 1308 } 1309 } 1310 cb_Tableur_Save_as(Fl_Widget * m,void *)1311 void cb_Tableur_Save_as(Fl_Widget* m , void*) { 1312 Flv_Table_Gen * tg=find_table_brother(m); 1313 if (!tg) 1314 return; 1315 string tmp; 1316 if (!get_filename(tmp,"tab")) 1317 return ; 1318 if (tg->filename) 1319 delete tg->filename; 1320 tg->filename = new string(tmp); 1321 if (tg->filename){ 1322 gen tmp(remove_extension(remove_path(*tg->filename)),context0); 1323 if (tmp.type==_IDNT && !is_undef(tmp)){ 1324 tg->name=tmp; 1325 tg->update_name(); 1326 } 1327 tg->prefix_filename="Save "+remove_path(*tg->filename); 1328 if (Tableur_Group * gr=dynamic_cast<Tableur_Group *>(tg->parent())){ 1329 gr->fname->label(tg->prefix_filename.c_str()); 1330 gr->fname->show(); 1331 } 1332 } 1333 cb_Tableur_Save(m,0); 1334 } 1335 1336 cb_Tableur_Save_mathml(Fl_Menu_ * m,void *)1337 void cb_Tableur_Save_mathml(Fl_Menu_* m , void*) { 1338 Flv_Table_Gen * tg=find_table_brother(m); 1339 if (!tg) return; 1340 const giac::context * contextptr = get_context(tg); 1341 string tmp; 1342 if (!get_filename(tmp,"htm")) 1343 return ; 1344 ofstream of(tmp.c_str()); 1345 if (!of){ 1346 fl_message("%s","Write error"); 1347 return; 1348 } 1349 of << mathml_preamble << '\n'; 1350 int formule=tg->is_spreadsheet?0:1; 1351 of << spread2mathml(tg->m,formule,contextptr); 1352 of << mathml_end << '\n'; 1353 } 1354 cb_Tableur_Save_CSV(Fl_Menu_ * m,void *)1355 void cb_Tableur_Save_CSV(Fl_Menu_* m , void*) { 1356 Flv_Table_Gen * tg=find_table_brother(m); 1357 if (!tg) return; 1358 string tmp; 1359 if (!get_filename(tmp,"csv")) 1360 return ; 1361 ofstream of(tmp.c_str()); 1362 if (!of){ 1363 fl_message("%s","Write error"); 1364 return; 1365 } 1366 matrice M(extractmatricefromsheet(tg->m)); 1367 const_iterateur it=M.begin(),itend=M.end(); 1368 for (;it!=itend;++it){ 1369 if (it->type==_VECT){ 1370 const_iterateur jt=it->_VECTptr->begin(),jtend=it->_VECTptr->end(); 1371 for (;jt!=jtend;++jt){ 1372 of << *jt << ";"; 1373 } 1374 of << '\n'; 1375 } 1376 } 1377 of << '\n'; 1378 of.close(); 1379 } 1380 1381 cb_Tableur_Save(Fl_Widget * m,void *)1382 void cb_Tableur_Save(Fl_Widget * m , void*) { 1383 Flv_Table_Gen * tg=find_table_brother(m); 1384 if (!tg) return; 1385 if (!tg->filename) 1386 cb_Tableur_Save_as(m,0); 1387 if (tg->filename){ 1388 ofstream of(tg->filename->c_str()); 1389 if (!of){ 1390 fl_message("%s","Write error"); 1391 return; 1392 } 1393 if (tg->is_spreadsheet) 1394 of << gen(tg->m,_SPREAD__VECT) << '\n'; 1395 else 1396 of << gen(extractmatricefromsheet(tg->m)) << '\n'; 1397 of.close(); 1398 tg->changed_ = false; 1399 } 1400 tg->update_status(); 1401 } 1402 cb_Tableur_Save_var(Fl_Widget * m,void *)1403 void cb_Tableur_Save_var(Fl_Widget* m , void*) { 1404 Flv_Table_Gen * tg=find_table_brother(m); 1405 if (!tg) return; 1406 const giac::context * contextptr = get_context(tg); 1407 if (tg){ 1408 matrice mat=extractmatricefromsheet(tg->selected); 1409 if (mat.empty() && tg->row()<tg->rows() && tg->col() < tg->cols()){ 1410 gen res=tg->m[tg->row()][tg->col()]; 1411 if (res.type==_VECT && res._VECTptr->size()==3) 1412 res=(*res._VECTptr)[1]; 1413 mat=vecteur(1,vecteur(1,res)); 1414 } 1415 const char * varname = fl_input(gettext("Variable name?")); 1416 if (varname){ 1417 gen g(varname,contextptr); 1418 if (g.type!=_IDNT){ 1419 fl_message("%s",(g.print(contextptr)+gettext("is not a variable name")).c_str()); 1420 cb_Tableur_Save_var(m,0); 1421 } 1422 protecteval(symb_sto(mat,g),eval_level(contextptr),contextptr); 1423 } 1424 } 1425 } 1426 1427 // Insure that all elements of m that are vectors have length <= 3 spread_ck(matrice & m)1428 void spread_ck(matrice & m){ 1429 iterateur it=m.begin(),itend=m.end(); 1430 for (;it!=itend;++it){ 1431 if (it->type==_VECT){ 1432 iterateur jt=it->_VECTptr->begin(),jtend=it->_VECTptr->end(); 1433 for (;jt!=jtend;++jt){ 1434 if (jt->type==_VECT && jt->_VECTptr->size()>3){ 1435 *jt=makevecteur(jt->_VECTptr->front(),vecteur(jt->_VECTptr->begin()+1,jt->_VECTptr->end()-1),jt->_VECTptr->back()); 1436 } 1437 } 1438 } 1439 } 1440 } 1441 tableur_insert(Flv_Table_Gen * tg)1442 std::string tableur_insert(Flv_Table_Gen * tg){ 1443 char * newfile = load_file_chooser(gettext("Insert sheet"), "*.tab", "",0,false); 1444 if (!newfile || file_not_available(newfile)) 1445 return ""; 1446 ifstream inf(newfile); 1447 const giac::context * contextptr = get_context(tg); 1448 gen value(read1arg_from_stream(inf,contextptr)); 1449 if (!ckmatrix(value,true)) 1450 return ""; 1451 spread_ck(*value._VECTptr); // in place modifications of value 1452 tg->paste(*value._VECTptr); 1453 return remove_path(remove_extension(newfile)); 1454 } 1455 cb_Tableur_Insert(Fl_Menu_ * m,void *)1456 void cb_Tableur_Insert(Fl_Menu_* m , void*) { 1457 Flv_Table_Gen * tg=find_table_brother(m); 1458 if (!tg) return; 1459 tableur_insert(tg); 1460 } 1461 cb_Tableur_Insert_CSV(Fl_Menu_ * m,void *)1462 void cb_Tableur_Insert_CSV(Fl_Menu_* m , void*) { 1463 Flv_Table_Gen * tg=find_table_brother(m); 1464 if (!tg) return; 1465 const giac::context * contextptr = get_context(tg); 1466 char * newfile = load_file_chooser(gettext("Insert CSV sheet"), "*.csv", "",0,false); 1467 if (!newfile || file_not_available(newfile)) 1468 return; 1469 char sep=';',nl='\n',decsep=','; 1470 csv_guess(newfile,sep,nl,decsep); 1471 static Fl_Window * w = 0; 1472 static Fl_Input * separator=0, * newline=0,*decimal_sep=0,*end_file=0; // field separator, newline, decimal sep, end of file 1473 static Fl_Check_Button* import_syntax=0; 1474 static Fl_Return_Button * button0 = 0 ; 1475 static Fl_Button * button1 =0; 1476 if (!w){ 1477 #ifdef IPAQ 1478 int dx=240, dy=300; 1479 #else 1480 int dx=300, dy=120; 1481 #endif 1482 Fl_Group::current(0); 1483 w=new Fl_Window(dx,dy); 1484 separator=new Fl_Input(dx/4,2,dx/4-2,dy/4-4,gettext("Separator")); 1485 separator->tooltip(gettext("One character used to separate fields, like ; Use ^I for tab")); 1486 newline=new Fl_Input(3*dx/4,2,dx/4-2,dy/4-4,gettext("Newline")); 1487 newline->tooltip(gettext("One character used to separate lines, like <return> Use ^I for tab")); 1488 decimal_sep=new Fl_Input(dx/4,2+dy/4,dx/4-2,dy/4-4,gettext("Decimal")); 1489 decimal_sep->tooltip(gettext("One character used for decimal digit separator, like . or ,")); 1490 end_file=new Fl_Input(3*dx/4,2+dy/4,dx/4-2,dy/4-4,gettext("Endfile")); 1491 end_file->tooltip(gettext("Stop reading at first occurence of this character, leave blank for none")); 1492 import_syntax = new Fl_Check_Button(dx/4,2+2*dy/4,dx/4-2,dy/4-4,gettext("Start row=1")); 1493 import_syntax->value(1); 1494 button0 = new Fl_Return_Button(2,2+3*dy/4,dx/2-4,dy/4-4); 1495 button0->shortcut(0xff0d); 1496 button0->label(gettext("OK")); 1497 button1 = new Fl_Button(dx/2+2,2+3*dy/4,dx/2-4,dy/4-4); 1498 button1->shortcut(0xff1b); 1499 button1->label(gettext("Cancel")); 1500 w->end(); 1501 w->resizable(w); 1502 w->label(gettext("CSV Import filter")); 1503 } 1504 // Guess separator and newline values from file scanning 1505 separator->value(string(1,sep).c_str()); 1506 newline->value(string(1,nl).c_str()); 1507 decimal_sep->value(string(1,decsep).c_str()); 1508 int r=-1; 1509 w->set_modal(); 1510 w->show(); 1511 autosave_disabled=true; 1512 w->hotspot(w); 1513 Fl::focus(separator); 1514 for (;;) { 1515 Fl_Widget *o = Fl::readqueue(); 1516 if (!o) Fl::wait(); 1517 else { 1518 if (o == button0) {r = 0; break;} 1519 if (o == button1) {r = 1; break;} 1520 if (o == w) { r=1; break; } 1521 } 1522 } 1523 autosave_disabled=false; 1524 w->hide(); 1525 if (!r){ 1526 ifstream i(newfile); 1527 char sep=';',nl='\n',decsep=',',eof=0; 1528 if (strlen(separator->value()) && separator->value()[0]){ 1529 if (separator->value()[1]) 1530 sep=separator->value()[1]-64; 1531 else 1532 sep=separator->value()[0]; 1533 } 1534 if (strlen(newline->value()) && newline->value()[0]){ 1535 if (newline->value()[1]) 1536 nl=newline->value()[1]-64; 1537 else 1538 nl=newline->value()[0]; 1539 } 1540 if (decimal_sep->value()[0]) 1541 decsep=decimal_sep->value()[0]; 1542 if (end_file->value()[0]) 1543 eof=end_file->value()[0]; 1544 int save_maple_mode=xcas_mode(contextptr); 1545 xcas_mode(contextptr)=import_syntax->value(); 1546 matrice M(csv2gen(i,sep,nl,decsep,eof,contextptr)); 1547 if (!ckmatrix(M,true)) 1548 return; 1549 context * contextptr=get_context(tg); 1550 makespreadsheetmatrice(M,contextptr); // in place modifications of value 1551 tg->paste(M); 1552 xcas_mode(contextptr)=save_maple_mode; 1553 } 1554 } 1555 cb_Tableur_Preview(Fl_Menu_ * m,void *)1556 void cb_Tableur_Preview(Fl_Menu_* m , void*) { 1557 Flv_Table_Gen * tg=find_table_brother(m); 1558 if (!tg) return; 1559 widget_ps_print(tg,tg->filename?*tg->filename:"table",false); 1560 } 1561 cb_Tableur_Print(Fl_Menu_ * m,void *)1562 void cb_Tableur_Print(Fl_Menu_* m , void*) { 1563 Flv_Table_Gen * tg=find_table_brother(m); 1564 if (!tg) return; 1565 widget_print(tg); 1566 } 1567 cb_Tableur_Copy_Cell(Fl_Menu_ * m,void *)1568 void cb_Tableur_Copy_Cell(Fl_Menu_* m , void*) { 1569 Flv_Table_Gen * tg=find_table_brother(m); 1570 if (!tg) return; 1571 tg->copy(); 1572 } 1573 cb_Tableur_Copy_Right(Fl_Menu_ * m,void *)1574 void cb_Tableur_Copy_Right(Fl_Menu_* m , void*) { 1575 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1576 if (!spread_ptr) return; 1577 spread_ptr->copy_right(); 1578 } 1579 cb_Tableur_Copy_Down(Fl_Menu_ * m,void *)1580 void cb_Tableur_Copy_Down(Fl_Menu_* m , void*) { 1581 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1582 if (!spread_ptr) return; 1583 spread_ptr->copy_down(); 1584 } 1585 cb_Tableur_DelRow(Fl_Menu_ * m,void *)1586 void cb_Tableur_DelRow(Fl_Menu_* m , void*) { 1587 Flv_Table_Gen * tg=find_table_brother(m); 1588 if (!tg) return; 1589 tg->spread_erase(1,0); 1590 } 1591 cb_Tableur_Del(Fl_Menu_ * m,void *)1592 void cb_Tableur_Del(Fl_Menu_* m , void*) { 1593 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1594 if (!spread_ptr) return; 1595 bool tmp=spread_ptr->is_spreadsheet; 1596 spread_ptr->is_spreadsheet=false; 1597 spread_ptr->blank(0,spread_ptr->rows(),0,spread_ptr->cols()); 1598 spread_ptr->is_spreadsheet=tmp; 1599 } 1600 cb_Tableur_DelRows(Fl_Menu_ * m,void *)1601 void cb_Tableur_DelRows(Fl_Menu_* m , void*) { 1602 Flv_Table_Gen * tg=find_table_brother(m); 1603 if (!tg) return; 1604 tg->erase_row_col(0); 1605 } 1606 cb_Tableur_DelCol(Fl_Menu_ * m,void *)1607 void cb_Tableur_DelCol(Fl_Menu_* m , void*) { 1608 Flv_Table_Gen * tg=find_table_brother(m); 1609 if (!tg) return; 1610 tg->spread_erase(0,1); 1611 } 1612 cb_Tableur_DelCols(Fl_Menu_ * m,void *)1613 void cb_Tableur_DelCols(Fl_Menu_* m , void*) { 1614 Flv_Table_Gen * tg=find_table_brother(m); 1615 if (!tg) return; 1616 tg->erase_row_col(1); 1617 } 1618 cb_Tableur_InsRow(Fl_Menu_ * m,void *)1619 void cb_Tableur_InsRow(Fl_Menu_* m , void*) { 1620 Flv_Table_Gen * tg=find_table_brother(m); 1621 if (!tg) return; 1622 tg->spread_insert(1,0); 1623 } 1624 cb_Tableur_InsCol(Fl_Menu_ * m,void *)1625 void cb_Tableur_InsCol(Fl_Menu_* m , void*) { 1626 Flv_Table_Gen * tg=find_table_brother(m); 1627 if (!tg) return; 1628 tg->spread_insert(0,1); 1629 } 1630 cb_Tableur_InsCol_End(Fl_Menu_ * m,void *)1631 void cb_Tableur_InsCol_End(Fl_Menu_* m , void*) { 1632 Flv_Table_Gen * tg=find_table_brother(m); 1633 if (!tg) return; 1634 tg->addcolatend(); 1635 } 1636 cb_Tableur_InsRow_End(Fl_Menu_ * m,void *)1637 void cb_Tableur_InsRow_End(Fl_Menu_* m , void*) { 1638 Flv_Table_Gen * tg=find_table_brother(m); 1639 if (!tg) return; 1640 tg->addrowatend(); 1641 } 1642 cb_Tableur_MoveRight(Fl_Menu_ * m,void *)1643 void cb_Tableur_MoveRight(Fl_Menu_* m , void*) { 1644 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1645 if (!spread_ptr) return; 1646 spread_ptr->move_on_enter(FLV_MOVE_ON_ENTER_COL_ROW); 1647 spread_ptr->move_right=true; 1648 spread_ptr->update_status(); 1649 } 1650 cb_Tableur_MoveDown(Fl_Menu_ * m,void *)1651 void cb_Tableur_MoveDown(Fl_Menu_* m , void*) { 1652 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1653 if (!spread_ptr) return; 1654 spread_ptr->move_on_enter(FLV_MOVE_ON_ENTER_ROW_COL); 1655 spread_ptr->move_right=false; 1656 spread_ptr->update_status(); 1657 } 1658 cb_Tableur_FillSelection(Fl_Menu_ * m,void *)1659 void cb_Tableur_FillSelection(Fl_Menu_* m , void*) { 1660 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1661 if (!spread_ptr) return; 1662 spread_ptr->copy_first_in_selection(); 1663 } 1664 cb_Tableur_Col_Larger(Fl_Menu_ * m,void *)1665 void cb_Tableur_Col_Larger(Fl_Menu_* m , void*) { 1666 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1667 if (!spread_ptr) return; 1668 spread_ptr->col_width(spread_ptr->col_width(spread_ptr->col())+5,spread_ptr->col()); 1669 } 1670 cb_Tableur_Col_Smaller(Fl_Menu_ * m,void *)1671 void cb_Tableur_Col_Smaller(Fl_Menu_* m , void*) { 1672 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1673 if (!spread_ptr) return; 1674 spread_ptr->col_width(spread_ptr->col_width(spread_ptr->col())-5,spread_ptr->col()); 1675 } 1676 cb_Tableur_Fill0(Fl_Menu_ * m,void *)1677 void cb_Tableur_Fill0(Fl_Menu_* m , void*) { 1678 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1679 if (!spread_ptr) return; 1680 bool tmp=spread_ptr->is_spreadsheet; 1681 spread_ptr->is_spreadsheet=false; 1682 // int r1=spread_ptr->select_start_row(),r2=spread_ptr->row(),c1=spread_ptr->select_start_col(),c2=spread_ptr->col(); 1683 // spread_ptr->blank(r1,r2,c1,c2); 1684 spread_ptr->blank(); 1685 spread_ptr->is_spreadsheet=tmp; 1686 } 1687 tableur_insert_replace(Flv_Table_Gen * spread_ptr,const string & s)1688 void tableur_insert_replace(Flv_Table_Gen * spread_ptr,const string & s){ 1689 if (!spread_ptr) return; 1690 if (!spread_ptr->editing){ 1691 spread_ptr->edit_row=spread_ptr->row(); 1692 spread_ptr->edit_col=spread_ptr->col(); 1693 spread_ptr->editing=true; 1694 } 1695 spread_ptr->input->insert_replace(s,true); 1696 spread_ptr->input->position(spread_ptr->input->mark(),spread_ptr->input->mark()); 1697 Fl::focus(spread_ptr->input); 1698 } 1699 1700 coltocolname(int i)1701 std::string coltocolname(int i){ 1702 string tmp; 1703 for(int j=0;;++j){ 1704 tmp=char('A'+i%26-(j!=0))+tmp; 1705 i=i/26; 1706 if (!i) 1707 break; 1708 } 1709 return tmp; 1710 } 1711 1712 // return true if s parsed has identifiers which are cell names has_cell(const string & s,gen & cell,GIAC_CONTEXT)1713 bool has_cell(const string & s,gen & cell,GIAC_CONTEXT){ 1714 gen g(s,contextptr); 1715 vecteur l(lidnt(g)); 1716 int ls=l.size(),r,c; 1717 for (int i=0;i<ls;++i){ 1718 if (iscell((cell=l[i]),r,c,contextptr)) 1719 return true; 1720 } 1721 return false; 1722 } 1723 1724 int xcas_integration_method=0; 1725 Fl_Output * Xcas_Methodes_Output=0; cb_Xcas_Methodes_builtin(Fl_Menu_ * m,void *)1726 void cb_Xcas_Methodes_builtin(Fl_Menu_* m , void*) { 1727 xcas_integration_method=0; 1728 if (Xcas_Methodes_Output) 1729 Xcas_Methodes_Output->value(gettext("builtin")); 1730 } 1731 cb_Xcas_Methodes_right_rectangle(Fl_Menu_ * m,void *)1732 void cb_Xcas_Methodes_right_rectangle(Fl_Menu_* m , void*) { 1733 xcas_integration_method=1; 1734 if (Xcas_Methodes_Output) 1735 Xcas_Methodes_Output->value(gettext("right rectangle")); 1736 } 1737 cb_Xcas_Methodes_left_rectangle(Fl_Menu_ * m,void *)1738 void cb_Xcas_Methodes_left_rectangle(Fl_Menu_* m , void*) { 1739 xcas_integration_method=2; 1740 if (Xcas_Methodes_Output) 1741 Xcas_Methodes_Output->value(gettext("left rectangle")); 1742 } 1743 cb_Xcas_Methodes_middle_point(Fl_Menu_ * m,void *)1744 void cb_Xcas_Methodes_middle_point(Fl_Menu_* m , void*) { 1745 xcas_integration_method=3; 1746 if (Xcas_Methodes_Output) 1747 Xcas_Methodes_Output->value(gettext("middle point")); 1748 } 1749 cb_Xcas_Methodes_trapezoid(Fl_Menu_ * m,void *)1750 void cb_Xcas_Methodes_trapezoid(Fl_Menu_* m , void*) { 1751 xcas_integration_method=4; 1752 if (Xcas_Methodes_Output) 1753 Xcas_Methodes_Output->value(gettext("trapezoid")); 1754 } 1755 1756 Fl_Menu_Item Xcas_Menu_Methodes[] = { 1757 {gettext("builtin"), 0, (Fl_Callback*)cb_Xcas_Methodes_builtin, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, 1758 {gettext("right_rectangle"), 0, (Fl_Callback*)cb_Xcas_Methodes_right_rectangle, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, 1759 {gettext("left_rectangle"), 0, (Fl_Callback*)cb_Xcas_Methodes_left_rectangle, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, 1760 {gettext("middle_point"), 0, (Fl_Callback*)cb_Xcas_Methodes_middle_point, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, 1761 {gettext("trapezoid"), 0, (Fl_Callback*)cb_Xcas_Methodes_trapezoid, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, 1762 {0,0,0,0,0,0,0,0,0} 1763 }; 1764 1765 // type 1= plotfunc 3d, 0 plotfunc 2d, 2 plotarea tablefunc_dialog(Fl_Widget * spread_ptr,std::string & arg,bool plot,int type,const string & title)1766 bool tablefunc_dialog(Fl_Widget * spread_ptr,std::string & arg,bool plot,int type,const string & title){ 1767 static Fl_Window * w = 0; 1768 static Fl_Input *fcn=0, *fcn3d=0,* varname=0, * varnamey=0,*target=0; 1769 static Fl_Value_Input * xmin=0,*xstep=0,*xmax=0; 1770 static Fl_Value_Input * ymin=0,*ystep=0,*ymax=0; 1771 static Fl_Return_Button * button0 = 0 ; 1772 static Fl_Menu_Button * methode=0; 1773 static Fl_Button * button1 =0; 1774 static Line_Type * ltres=0; 1775 if (!w){ 1776 #ifdef IPAQ 1777 int dx=240,dy=300; 1778 #else 1779 int dx=(spread_ptr?20*spread_ptr->labelsize():400), 1780 dy=spread_ptr?8*spread_ptr->labelsize():300; 1781 #endif 1782 int lignes=5; 1783 Fl_Group::current(0); 1784 w=new Fl_Window(dx,dy); 1785 ltres = new Line_Type(2,2,dx/15,dy/lignes-4,_MAGENTA+_FILL_POLYGON); 1786 ltres->show_pnt(true); 1787 ltres->show_poly(true); 1788 ltres->tooltip(gettext("Plot style (select a point type or width for dotted plot)")); 1789 fcn=new Fl_Input(dx/2,2,dx/2-4,dy/lignes-4,gettext("Expression")); 1790 fcn->value("x^2"); 1791 fcn->tooltip(gettext("Expression of the function (e.g sin(x))")); 1792 fcn3d=new Fl_Input(dx/2,2,dx/2-4,dy/lignes-4,gettext("Expression")); 1793 fcn3d->value("x^2-y^2"); 1794 fcn3d->tooltip(gettext("Expression of the function (e.g x-y^2)")); 1795 varname=new Fl_Input(dx/4,2+dy/lignes,dx/4-4,dy/lignes-4,gettext("1st var")); 1796 varname->value("x"); 1797 varname->tooltip(gettext("Independant variable name (e.g x)")); 1798 varnamey=new Fl_Input(3*dx/4,2+dy/lignes,dx/4-4,dy/lignes-4,gettext("2nd var")); 1799 varnamey->value("y"); 1800 varnamey->tooltip(gettext("Second independant variable name (e.g y)")); 1801 xmin = new Fl_Value_Input(dx/6,2+2*dy/lignes,dx/6-2,dy/lignes-4,gettext("xmin")); 1802 xmin->value(-4); 1803 xmin->step(0.5); 1804 xmin->tooltip(gettext("Minimal value for 1st independant variable")); 1805 xstep = new Fl_Value_Input(3*dx/6,2+2*dy/lignes,dx/6-2,dy/lignes-4,gettext("xstep")); 1806 xstep->value(0.5); 1807 xstep->step(0.01); 1808 xstep->tooltip(gettext("Discretization step for 1st independant variable")); 1809 xmax = new Fl_Value_Input(5*dx/6,2+2*dy/lignes,dx/6-2,dy/lignes-4,gettext("xmax")); 1810 xmax->value(4); 1811 xmax->step(0.5); 1812 xmax->tooltip(gettext("Maximal value for 1st independant variable")); 1813 target = new Fl_Input(dx/6,2+3*dy/lignes,dx/6-2,dy/lignes-4,gettext("Target")); 1814 target->tooltip(gettext("Name of the first of two columns that will be overwritten by the tablefunc")); 1815 ymin = new Fl_Value_Input(dx/6,2+3*dy/lignes,dx/6-2,dy/lignes-4,gettext("ymin")); 1816 ymin->value(-4); 1817 ymin->step(0.5); 1818 ymin->tooltip(gettext("Minimal value for 2nd independant variable")); 1819 ystep = new Fl_Value_Input(3*dx/6,2+3*dy/lignes,dx/6-2,dy/lignes-4,gettext("ystep")); 1820 ystep->value(0.5); 1821 ystep->step(0.01); 1822 ystep->tooltip(gettext("Discretization step for 2nd independant variable")); 1823 ymax = new Fl_Value_Input(5*dx/6,2+3*dy/lignes,dx/6-2,dy/lignes-4,gettext("ymax")); 1824 ymax->value(4); 1825 ymax->step(0.5); 1826 ymin->tooltip(gettext("Maximal value for 2nd independant variable")); 1827 methode = new Fl_Menu_Button(0,2+3*dy/lignes,dx/3-2,dy/lignes-4,gettext("Choose")); 1828 methode->menu(Xcas_Menu_Methodes); 1829 Xcas_Methodes_Output = new Fl_Output(4*dx/6,2+3*dy/lignes,dx/3-2,dy/lignes-4,gettext("int. method")); 1830 Xcas_Methodes_Output->value(gettext("builtin")); 1831 button0 = new Fl_Return_Button(2,2+4*dy/lignes,dx/2-4,dy/lignes-4); 1832 button0->shortcut(0xff0d); 1833 button0->label(gettext("OK")); 1834 button1 = new Fl_Button(dx/2+2,2+4*dy/lignes,dx/2-4,dy/lignes-4); 1835 button1->shortcut(0xff1b); 1836 button1->label(gettext("Cancel")); 1837 w->end(); 1838 change_group_fontsize(w,spread_ptr?spread_ptr->labelsize():14); 1839 w->resizable(w); 1840 } 1841 w->label(title.c_str()); 1842 Flv_Table_Gen * tbl=dynamic_cast<Flv_Table_Gen *>(spread_ptr); 1843 if (tbl) 1844 target->value(coltocolname(tbl->col()).c_str()); 1845 if (plot){ 1846 target->hide(); 1847 } 1848 else { 1849 target->show(); 1850 } 1851 if (type==2){ 1852 methode->show(); 1853 Xcas_Methodes_Output->show(); 1854 } 1855 else { 1856 methode->hide(); 1857 Xcas_Methodes_Output->hide(); 1858 } 1859 if (type==1){ 1860 ymax->show(); 1861 ymin->show(); 1862 ystep->show(); 1863 varnamey->show(); 1864 fcn->hide(); 1865 fcn3d->show(); 1866 } 1867 else { 1868 ymax->hide(); 1869 ymin->hide(); 1870 ystep->hide(); 1871 varnamey->hide(); 1872 fcn->show(); 1873 fcn3d->hide(); 1874 } 1875 int r=-1; 1876 w->set_modal(); 1877 w->show(); 1878 autosave_disabled=true; 1879 w->hotspot(w); 1880 Fl::focus(varname); 1881 for (;;) { 1882 Fl_Widget *o = Fl::readqueue(); 1883 if (!o) Fl::wait(); 1884 else { 1885 if (o==ltres){ 1886 int i=ltres->line_type(); 1887 bool formel=false,untranslate=false,approx=false; 1888 change_line_type(i,true,approx,"",fcn3d->visible(),formel,untranslate,false,spread_ptr?spread_ptr->labelsize():14); 1889 ltres->line_type(i); 1890 } 1891 if (o == button0) {r = 0; break;} 1892 if (o == button1) {r = 1; break;} 1893 if (o == w) { r=1; break; } 1894 } 1895 } 1896 autosave_disabled=false; 1897 w->hide(); 1898 if (!r){ 1899 if (tbl){ 1900 int r; 1901 if (!alphaposcell(target->value(),r)){ 1902 fl_alert("%s","Invalid column"); 1903 return false; 1904 } 1905 tbl->col(r); 1906 } 1907 arg=(type==1?fcn3d:fcn)->value(); 1908 gen cell; 1909 if (has_cell(arg,cell,context0)){ 1910 fl_alert("%s",("Expression contains a cell name "+cell.print()).c_str()); 1911 return false; 1912 } 1913 arg += string(","); 1914 if (plot){ 1915 if (type==1){ 1916 arg += "["+string(varname->value())+"="+print_DOUBLE_(xmin->value())+".."+print_DOUBLE_(xmax->value()) + string(",")+varnamey->value()+string("=")+print_DOUBLE_(ymin->value())+".."+print_DOUBLE_(ymax->value())+"],xstep="+print_DOUBLE_(xstep->value())+",ystep="+print_DOUBLE_(ystep->value())+",display="+print_color(ltres->line_type()); 1917 } 1918 else { 1919 arg += string(varname->value())+"="+print_DOUBLE_(xmin->value())+".."+print_DOUBLE_(xmax->value()); 1920 if (type==2 && xcas_integration_method){ 1921 arg += ","+print_INT_(int((xmax->value()-xmin->value())/xstep->value())); 1922 switch (xcas_integration_method){ 1923 case 1: 1924 arg += ",right_rectangle"; 1925 break; 1926 case 2: 1927 arg += ",left_rectangle"; 1928 break; 1929 case 3: 1930 arg += ",middle_point"; 1931 break; 1932 case 4: 1933 arg += ",trapezoid"; 1934 break; 1935 } 1936 } 1937 else 1938 arg += ",xstep="+print_DOUBLE_(xstep->value()); 1939 arg += ",display="+print_color(ltres->line_type()); 1940 } 1941 } 1942 else 1943 arg += string(varname->value())+","+print_DOUBLE_(xmin->value())+","+print_DOUBLE_(xstep->value())+","+print_DOUBLE_(xmax->value())+",display="+print_color(ltres->line_type()); 1944 return true; 1945 } 1946 return false; 1947 } 1948 cb_Tableur_Tablefunc(Fl_Menu_ * m,void *)1949 void cb_Tableur_Tablefunc(Fl_Menu_* m , void*) { 1950 Flv_Table_Gen * spread_ptr=find_table_brother(m); 1951 if (!spread_ptr) return; 1952 string arg; 1953 if (spread_ptr && tablefunc_dialog(spread_ptr,arg,false,0,gettext("Table of value of a function"))){ 1954 arg="tablefunc("+arg+")"; 1955 spread_ptr->input->value(""); 1956 tableur_insert_replace(spread_ptr,arg); 1957 Tableur_Group * gr = dynamic_cast<Tableur_Group *>(spread_ptr->parent()); 1958 if (gr && !(gr->disposition & 2) && !spread_ptr->graph2d->window()->visible() ){ 1959 gr->disposition |= 2; 1960 gr->resize2(); 1961 } 1962 spread_ptr->input->do_callback(); 1963 // browser_help(gen("tablefunc"),language(get_context(spread_ptr))); 1964 } 1965 } 1966 random_dialog(Fl_Widget * spread_ptr,gen & arg,double & Xmin,double & Xmax,bool & intg,bool & once)1967 bool random_dialog(Fl_Widget * spread_ptr,gen & arg,double & Xmin,double & Xmax,bool & intg,bool & once){ 1968 static Fl_Window * w = 0; 1969 static Fl_Input *target=0; 1970 static Fl_Value_Input *xmin=0,*xmax=0; 1971 static Fl_Check_Button * intg_button=0, * once_button=0; 1972 static Fl_Return_Button * button0 = 0 ; 1973 static Fl_Button * button1 =0; 1974 if (!w){ 1975 int lignes=4; 1976 #ifdef IPAQ 1977 int dx=240,dy=300; 1978 #else 1979 int dx=(spread_ptr?15*spread_ptr->labelsize():240), 1980 dy=spread_ptr?8*spread_ptr->labelsize():300; 1981 #endif 1982 Fl_Group::current(0); 1983 w=new Fl_Window(dx,dy); 1984 target=new Fl_Input(dx/2,2,dx/2-2,dy/lignes-4,gettext("Target cell range")); 1985 target->tooltip(gettext("Target cell range will be filled by random numbers, e.g. A1:A8")); 1986 xmin=new Fl_Value_Input(dx/4,2+dy/lignes,dx/4-2,dy/lignes-4,gettext("x-")); 1987 xmin->value(1); 1988 xmin->tooltip(gettext("Minimal value")); 1989 xmax = new Fl_Value_Input(dx/2+dx/4,2+dy/lignes,dx/4-2,dy/lignes-4,gettext("x+")); 1990 xmax->value(6); 1991 xmax->tooltip(gettext("Maximal value")); 1992 intg_button=new Fl_Check_Button(4, 2+2*dy/lignes,dx/4,dy/lignes-4,gettext("integers")); 1993 intg_button->tooltip(gettext("Real or integers")); 1994 intg_button->down_box(FL_DOWN_BOX); 1995 intg_button->value(true); 1996 once_button=new Fl_Check_Button(dx/2+4, 2+2*dy/lignes,dx/4,dy/lignes-4,gettext("static")); 1997 once_button->tooltip(gettext("Immediate static value or formula reevaled each time")); 1998 once_button->down_box(FL_DOWN_BOX); 1999 once_button->value(true); 2000 button0 = new Fl_Return_Button(2,2+(lignes-1)*dy/lignes,dx/2-4,dy/lignes-4); 2001 button0->shortcut(0xff0d); 2002 button0->label(gettext("OK")); 2003 button1 = new Fl_Button(dx/2+2,2+(lignes-1)*dy/lignes,dx/2-4,dy/lignes-4); 2004 button1->shortcut(0xff1b); 2005 button1->label(gettext("Cancel")); 2006 w->end(); 2007 change_group_fontsize(w,spread_ptr?spread_ptr->labelsize():14); 2008 w->resizable(w); 2009 } 2010 w->label("Random numbers"); 2011 Flv_Table_Gen * tbl=dynamic_cast<Flv_Table_Gen *>(spread_ptr); 2012 if (tbl && strlen(tbl->_goto->value())) 2013 target->value(tbl->_goto->value()); 2014 int r=-1; 2015 w->set_modal(); 2016 w->show(); 2017 autosave_disabled=true; 2018 w->hotspot(w); 2019 Fl::focus(target); 2020 for (;;) { 2021 Fl_Widget *o = Fl::readqueue(); 2022 if (!o) Fl::wait(); 2023 else { 2024 if (o == button0) {r = 0; break;} 2025 if (o == button1) {r = 1; break;} 2026 if (o == w) { r=1; break; } 2027 } 2028 } 2029 autosave_disabled=false; 2030 w->hide(); 2031 if (r==1) 2032 return false; 2033 intg=intg_button->value(); 2034 once=once_button->value(); 2035 arg=parse_interval(target->value()); 2036 Xmin=xmin->value(); 2037 Xmax=xmax->value(); 2038 return true; 2039 } 2040 tableseq_dialog(Fl_Widget * spread_ptr,std::string & arg,bool plot,const string & title,std::string & u0param)2041 bool tableseq_dialog(Fl_Widget * spread_ptr,std::string & arg,bool plot,const string & title,std::string & u0param){ 2042 static Fl_Window * w = 0; 2043 static Fl_Input *fcn=0, * varname=0; 2044 static Fl_Value_Input *xmin=0,*xmax=0; 2045 static Fl_Input *u0name=0,* u0=0,* target=0; 2046 static Fl_Value_Input * nterms=0; 2047 static Fl_Return_Button * button0 = 0 ; 2048 static Fl_Button * button1 =0; 2049 if (!w){ 2050 int lignes=5; 2051 #ifdef IPAQ 2052 int dx=240,dy=300; 2053 #else 2054 int dx=(spread_ptr?15*spread_ptr->labelsize():240), 2055 dy=spread_ptr?8*spread_ptr->labelsize():300; 2056 #endif 2057 Fl_Group::current(0); 2058 w=new Fl_Window(dx,dy); 2059 fcn=new Fl_Input(dx/2,2,dx/2-4,dy/lignes-4,gettext("Expression")); 2060 fcn->value("(x+2)/(x+1)"); 2061 fcn->tooltip(gettext("Expression of u_(n+1) in terms of a variable=u_n, e.g. 1/2*(x+2/x)\nOr expression of u_(n+k+1) in terms of a list of variables=[u_n,...,u_(n+k)], e.g. x+y")); 2062 varname=new Fl_Input(dx/2,2+dy/lignes,dx/2-4,dy/lignes-4,gettext("Variable(s)")); 2063 varname->value("x"); 2064 varname->tooltip(gettext("Independant variable name representing u_n, e.g. x\nOr list of independant variables representing u_n,...,u_(n+k), e.g. [x,y]")); 2065 u0name = new Fl_Input(0,2+2*dy/lignes,dx/8,dy/lignes-4); 2066 u0name->value("u0"); 2067 u0name->tooltip(gettext("Name of the initial value of un")); 2068 u0 = new Fl_Input(dx/6,2+2*dy/lignes,dx/3,dy/lignes-4,gettext("=")); 2069 u0->value("1.0"); 2070 u0->tooltip(gettext("Initial value, e.g. 1.0\nOr list of initial values, e.g. [1.0,1.0]")); 2071 xmin = new Fl_Value_Input(dx/2+dx/8,2+2*dy/lignes,dx/8-2,dy/lignes-4,gettext("x-")); 2072 xmin->value(gnuplot_xmin); 2073 xmin->tooltip(gettext("Minimal value for the function graph")); 2074 xmax = new Fl_Value_Input(dx/2+3*dx/8,2+2*dy/lignes,dx/8-2,dy/lignes-4,gettext("x+")); 2075 xmax->value(gnuplot_xmax); 2076 xmax->tooltip(gettext("Maximal value for the function graph")); 2077 target = new Fl_Input(dx/2,2+3*dy/lignes,dx/2-2,dy/lignes-4,gettext("Target column")); 2078 target->tooltip("Name of the column that will be overwritten by the table of the sequence"); 2079 nterms = new Fl_Value_Input(dx/2,2+3*dy/lignes,dx/2-2,dy/lignes-4,gettext("Number of terms")); 2080 nterms->value(10); 2081 nterms->step(1); 2082 button0 = new Fl_Return_Button(2,2+4*dy/lignes,dx/2-4,dy/lignes-4); 2083 button0->shortcut(0xff0d); 2084 button0->label(gettext("OK")); 2085 button1 = new Fl_Button(dx/2+2,2+4*dy/lignes,dx/2-4,dy/lignes-4); 2086 button1->shortcut(0xff1b); 2087 button1->label(gettext("Cancel")); 2088 w->end(); 2089 change_group_fontsize(w,spread_ptr?spread_ptr->labelsize():14); 2090 w->resizable(w); 2091 } 2092 Flv_Table_Gen * tbl=dynamic_cast<Flv_Table_Gen *>(spread_ptr); 2093 if (tbl){ 2094 target->show(); 2095 target->value(coltocolname(tbl->col()).c_str()); 2096 nterms->hide(); 2097 u0name->hide(); 2098 u0->label("u0"); 2099 } 2100 else { 2101 target->hide(); 2102 nterms->show(); 2103 u0name->show(); 2104 u0->label("="); 2105 } 2106 w->label(title.c_str()); 2107 int r=-1; 2108 w->set_modal(); 2109 w->show(); 2110 autosave_disabled=true; 2111 w->hotspot(w); 2112 Fl::focus(fcn); 2113 for (;;) { 2114 Fl_Widget *o = Fl::readqueue(); 2115 if (!o) Fl::wait(); 2116 else { 2117 if (o == button0) {r = 0; break;} 2118 if (o == button1) {r = 1; break;} 2119 if (o == w) { r=1; break; } 2120 } 2121 } 2122 autosave_disabled=false; 2123 w->hide(); 2124 if (!r){ 2125 if (tbl){ 2126 int r; 2127 if (!alphaposcell(target->value(),r)){ 2128 fl_alert("%s","Invalid column"); 2129 return false; 2130 } 2131 tbl->col(r); 2132 tbl->row(1); 2133 if (Tableur_Group * par=dynamic_cast<Tableur_Group *> (tbl->parent())){ 2134 par->disposition=3; 2135 par->resize2(); 2136 } 2137 } 2138 gen cell; 2139 if (has_cell(fcn->value(),cell,context0)){ 2140 fl_alert("%s",(gettext("Expression contains a cell name ")+cell.print()).c_str()); 2141 return false; 2142 } 2143 if (gen(u0->value(),context0).type==_VECT){ 2144 fl_alert("%s",(string(gettext("Invalid list initial value "))+u0->value()).c_str()); 2145 return false; 2146 } 2147 if (Figure * fig = dynamic_cast<Figure *>(spread_ptr)){ 2148 fig->geo->window_xmin=xmin->value(); 2149 fig->geo->window_xmax=xmax->value(); 2150 fig->geo->orthonormalize(); 2151 } 2152 u0param="assume("+string(u0name->value())+string("=[")+u0->value()+string(",")+print_DOUBLE_(xmin->value())+string(",")+print_DOUBLE_(xmax->value())+string("])"); 2153 arg=fcn->value()+string(",")+varname->value(); 2154 string u0s=tbl?u0->value():u0name->value(); 2155 if (plot) 2156 arg += string("=[")+u0s+string(",")+print_DOUBLE_(xmin->value())+string(",")+print_DOUBLE_(xmax->value())+string("],")+print_DOUBLE_(nterms->value()); 2157 else 2158 arg += string(",[")+u0s+string(",")+print_DOUBLE_(xmin->value())+string(",")+print_DOUBLE_(xmax->value())+string("]"); 2159 return true; 2160 } 2161 return false; 2162 } 2163 cb_Tableur_ranm(Fl_Menu_ * m,void *)2164 void cb_Tableur_ranm(Fl_Menu_* m , void*) { 2165 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2166 if (!spread_ptr) return; 2167 const giac::context * contextptr = get_context(spread_ptr); 2168 gen g; 2169 bool intg,once; 2170 double xmin,xmax; 2171 if (spread_ptr && random_dialog(spread_ptr,g,xmin,xmax,intg,once)){ 2172 int r,c; 2173 string formulas; 2174 if (!once) 2175 formulas="="; 2176 if (intg) 2177 formulas+="floor("; 2178 formulas += "rand("; 2179 formulas += print_DOUBLE_(xmin); 2180 formulas += ","; 2181 formulas += print_DOUBLE_(intg?xmax+1:xmax); 2182 formulas += ")"; 2183 if (intg) 2184 formulas+=")"; 2185 if (iscell(g,c,r,contextptr) ){ 2186 if (r>=spread_ptr->rows()||c>=spread_ptr->cols()) 2187 spread_ptr->resizesheet(max(r+1,spread_ptr->rows()),max(c+1,spread_ptr->cols())); 2188 // cerr << g << " " << r << " " << c << '\n'; 2189 spread_ptr->row(r); 2190 spread_ptr->col(c); 2191 spread_ptr->select_start_row(r); 2192 spread_ptr->select_start_col(c); 2193 if (spread_ptr->input){ 2194 spread_ptr->input->value(formulas.c_str()); 2195 spread_ptr->input->do_callback(); 2196 } 2197 } // end if iscell(g,r,c) 2198 if (!g.is_symb_of_sommet(at_interval)) 2199 return; 2200 gen & f=g._SYMBptr->feuille; 2201 if (f.type!=_VECT || f._VECTptr->size()!=2) 2202 return; 2203 int r1,r2,c1,c2; 2204 if (!iscell(f._VECTptr->front(),c1,r1,contextptr) || !iscell(f._VECTptr->back(),c2,r2,contextptr)) 2205 return; 2206 if (r1>r2) 2207 giac::swapint(r1,r2); 2208 r2=min(r2+1,spread_ptr->rows()); 2209 r1=max(r1,0); 2210 if (c1>c2) 2211 giac::swapint(c1,c2); 2212 c2=min(c2+1,spread_ptr->cols()); 2213 c1=max(c1,0); 2214 gen formula(formulas,contextptr); 2215 for (int i=r1;i<r2;++i){ 2216 vecteur & v=*spread_ptr->m[i]._VECTptr; 2217 for (int j=c1;j<c2;++j){ 2218 v[j]=makevecteur((once?eval(formula,1,0):formula),0,2); 2219 } 2220 } 2221 spread_ptr->spread_eval_interrupt(); 2222 spread_ptr->redraw(); 2223 } 2224 } 2225 cb_Tableur_Tableseq(Fl_Menu_ * m,void *)2226 void cb_Tableur_Tableseq(Fl_Menu_* m , void*) { 2227 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2228 if (!spread_ptr) return; 2229 string arg,u0param; 2230 if (spread_ptr && tableseq_dialog(spread_ptr,arg,false,gettext("Table of value of a recurrent sequence"),u0param)){ 2231 arg="tableseq("+arg+")"; 2232 spread_ptr->input->value(""); 2233 tableur_insert_replace(spread_ptr,arg); 2234 Tableur_Group * gr = dynamic_cast<Tableur_Group *>(spread_ptr->parent()); 2235 if (gr && !(gr->disposition & 2) && !spread_ptr->graph2d->window()->visible()){ 2236 gr->disposition |= 2; 2237 gr->resize2(); 2238 } 2239 spread_ptr->input->do_callback(); 2240 // browser_help(gen("tableseq"),language(get_context(spread_ptr))); 2241 } 2242 } 2243 set_graphic_dialog(const string & title,const string & aide,gen & in,gen & out,bool show_class,bool & absolu,bool & transpose,double & degree)2244 int Flv_Table_Gen::set_graphic_dialog(const string & title,const string & aide,gen & in, gen & out,bool show_class,bool & absolu,bool & transpose,double & degree){ 2245 const giac::context * contextptr = get_context(this); 2246 static Fl_Window * w = 0; 2247 static Fl_Output * help=0; 2248 static Fl_Input * i1=0, * i2=0; // Cells to analyse and cell output 2249 static Fl_Value_Input * v1=0, *v2=0,*v3=0; // Class_min/size, poly degree 2250 static Fl_Return_Button * button0 = 0 ; 2251 static Fl_Button * button1 =0; 2252 static Fl_Check_Button* c1=0,*c2=0,*c3=0; 2253 int dx=(2*this->w())/3,dy=(2*h())/3; 2254 if (dy<200) 2255 dy=200; 2256 if (dy>6*labelsize()) 2257 dy=6*labelsize(); 2258 if (dx<200) 2259 dx=200; 2260 if (!w){ 2261 Fl_Group::current(0); 2262 w=new Fl_Window(dx,dy); 2263 int lignes=4; 2264 help = new Fl_Output(dx/2,2,0,0,""); 2265 help->align(FL_ALIGN_BOTTOM); 2266 i1=new Fl_Input(dx/4,2+dy/lignes,dx/4-2,dy/lignes-4,gettext("cells input")); 2267 i1->tooltip(gettext("Zone over which the function will be applied, e.g. A1..B7 or A1..B7,D,E")); 2268 i2=new Fl_Input((3*dx)/4,2+dy/lignes,dx/4-2,dy/lignes-4,gettext("target cell")); 2269 i2->tooltip(gettext("Target cell(s) will be filled by the formula, e.g. A8")); 2270 v1=new Fl_Value_Input(dx/4,2+2*dy/lignes,dx/4-2,dy/lignes-4,gettext("class min")); 2271 v1->tooltip(gettext("Minimal value of classes for histogramsl, e.g. -10")); 2272 v2=new Fl_Value_Input((3*dx)/4,2+2*dy/lignes,dx/4-2,dy/lignes-4,gettext("class size")); 2273 v2->tooltip(gettext("Size of a class for histograms, e.g. 2")); 2274 c1=new Fl_Check_Button(0, 2+2*dy/lignes,dx/8,dy/lignes-4,gettext("value")); 2275 c1->tooltip(gettext("Use submatrix by reference (dynamic) or by value (static)")); 2276 c1->down_box(FL_DOWN_BOX); 2277 c2=new Fl_Check_Button(dx/4, 2+2*dy/lignes,dx/8,dy/lignes-4,gettext("lines")); 2278 c2->tooltip(gettext("Use line or columns")); 2279 c2->down_box(FL_DOWN_BOX); 2280 c3=new Fl_Check_Button(dx/2, 2+2*dy/lignes,dx/8,dy/lignes-4,gettext("outside")); 2281 c3->tooltip(gettext("Sheet graph or standalone graph")); 2282 c3->down_box(FL_DOWN_BOX); 2283 v3=new Fl_Value_Input(3*dx/4+dx/8, 2+2*dy/lignes,dx/8,dy/lignes-4,gettext("degree")); 2284 v3->tooltip(gettext("Degree of the polynomial regression")); 2285 button0 = new Fl_Return_Button(2,2+(3*dy/lignes),dx/2-4,dy/lignes-4); 2286 button0->shortcut(0xff0d); 2287 button0->label(gettext("OK")); 2288 button1 = new Fl_Button(dx/2+2,2+(3*dy)/lignes,dx/2-4,dy/lignes-4); 2289 button1->shortcut(0xff1b); 2290 button1->label(gettext("Cancel")); 2291 w->end(); 2292 w->resizable(w); 2293 } 2294 help->label(aide.c_str()); 2295 w->label(title.c_str()); 2296 change_group_fontsize(w,labelsize()); 2297 /* 2298 printcell_current_row=row()+1; 2299 printcell_current_col=select_start_col(); 2300 string s=printcell(makevecteur(makevecteur(0),makevecteur(0))); 2301 i2->value(s.c_str()); // removed so that the user MUST specify target 2302 */ 2303 if (strlen(_goto->value())) 2304 i1->value(_goto->value()); 2305 if (show_class){ 2306 c3->value(false); 2307 c3->hide(); 2308 } 2309 else 2310 c3->show(); 2311 static string i2s; 2312 i2s=next_cell(i1->value(),this); 2313 i2->value(i2s.c_str()); 2314 v1->value(class_minimum); 2315 v2->value(class_size); 2316 v3->value(degree); 2317 if (show_class){ 2318 v1->show(); v2->show(); c1->hide(); c2->hide(); v3->hide(); 2319 } 2320 else { 2321 v1->hide(); v2->hide(); c1->show(); c2->show(); 2322 if (degree){ 2323 v3->label(degree==1?"y1":"degree"); 2324 v3->show(); 2325 } 2326 else 2327 v3->hide(); 2328 } 2329 int r=-1; 2330 for (;;){ 2331 w->set_modal(); 2332 w->show(); 2333 autosave_disabled=true; 2334 w->hotspot(w); 2335 Fl::focus(i1); 2336 for (;;) { 2337 Fl_Widget *o = Fl::readqueue(); 2338 if (!o) Fl::wait(); 2339 else { 2340 if (o == button0) {r = 0; break;} 2341 if (o == button1) {r = 1; break;} 2342 if (o==c3){ if (c3->value()) i2->deactivate(); else i2->activate();} 2343 if (o == w) { r=1; break; } 2344 } 2345 } 2346 autosave_disabled=false; 2347 w->hide(); 2348 if (r) 2349 break; 2350 // r=0, not cancelled 2351 degree=int(v3->value()); 2352 absolu=c1->value(); 2353 transpose=c2->value(); 2354 class_minimum=v1->value(); 2355 class_size=v2->value(); 2356 const char * ch =i1->value(); 2357 string s; 2358 int l=strlen(ch); 2359 for (int i=0;i<l;++i,++ch){ 2360 if (*ch==':') 2361 s += ".."; 2362 else 2363 s+=*ch; 2364 } 2365 try { 2366 in=gen(s,contextptr); 2367 out=(c3->value() || !strlen(i2->value()))?undef:gen(i2->value(),contextptr); 2368 Tableur_Group * gr = dynamic_cast<Tableur_Group *>(parent()); 2369 if (!is_undef(out) && gr && !(gr->disposition & 2) ){ 2370 gr->disposition |= 2; 2371 gr->resize2(); 2372 } 2373 } 2374 catch (std::runtime_error & e){ 2375 fl_message("%s",(gettext("Syntax error")+string(e.what())).c_str()); 2376 continue; 2377 } 2378 break; 2379 } // end endless for(;;) loop 2380 return r; 2381 } 2382 interval2deuxpoints(const gen & g)2383 gen interval2deuxpoints(const gen & g){ 2384 return g.is_symb_of_sommet(at_interval)?symbolic(at_deuxpoints,g._SYMBptr->feuille):g; 2385 } 2386 set_graphic(const gen & function,const std::string & aide)2387 void Flv_Table_Gen::set_graphic(const gen & function,const std::string & aide){ 2388 if (function.type!=_FUNC) 2389 return; 2390 gen in,out; 2391 bool absolu=false,transpose; 2392 string fs=function.print(contextptr); 2393 double deg=0; 2394 bool polyreg=(fs=="'polynomial_regression_plot'"); 2395 bool logisreg=(fs=="'logistic_regression_plot'"); 2396 if (polyreg) 2397 deg=2; 2398 if (logisreg) 2399 deg=1; 2400 int r=set_graphic_dialog(fs,aide,in,out,fs=="'histogram'",absolu,transpose,deg); 2401 if (r==0){ 2402 gen tmp; 2403 int r1,r2,res,R,C; 2404 vector<int> vc; 2405 matrice mselect; 2406 bool absolu2=false; 2407 if ( (res=iscell_range(in,m,mselect,this,r1,r2,vc,absolu2)) ){ 2408 bool inside=iscell(out,C,R,contextptr); 2409 // If vc.size()!=#cols mselect colmuns are non-contiguous, 2410 // use mselect else use matrix(r2-r1+1,vc.size(),g) 2411 if (absolu || mselect.front()._VECTptr->size()!=vc.size() || (inside?absolu2:name.type!=_IDNT) ){ 2412 tmp=extractmatricefromsheet(mselect); 2413 if (transpose) 2414 tmp=_tran(tmp,contextptr); 2415 } 2416 else { 2417 if (inside){ 2418 in=apply(in,interval2deuxpoints); 2419 tmp=logisreg?in:symbolic(at_matrix,makevecteur(r2-r1,vc.size(),in)); 2420 } 2421 else { 2422 vecteur vcg; 2423 vector_int2vecteur(vc,vcg); 2424 in=gen(makevecteur(symb_interval(r1,r2-1),vcg),_SEQ__VECT); 2425 tmp=symbolic(at_at,gen(makevecteur(name,in),_SEQ__VECT)); 2426 } 2427 if (transpose) 2428 tmp=symbolic(at_tran,tmp); 2429 } 2430 if (polyreg) 2431 tmp=gen(makevecteur(tmp,deg),_SEQ__VECT); 2432 if (logisreg) 2433 tmp=gen(makevecteur(tmp,1,deg),_SEQ__VECT); 2434 tmp=symbolic(*function._FUNCptr,tmp); 2435 if (inside){ 2436 tmp.change_subtype(_SPREAD__SYMB); 2437 row(R); 2438 col(C); 2439 input->value(tmp.print(contextptr).c_str()); 2440 // input->set_g(tmp); 2441 input->do_callback(); 2442 } 2443 else { 2444 int pos; 2445 History_Pack * hp=get_history_pack(this,pos); 2446 if (hp){ 2447 hp->add_entry(pos+1); 2448 hp->set_gen_value(pos+1,tmp,true); 2449 } 2450 } 2451 } 2452 } 2453 } 2454 cb_Tableur_SetRows(Fl_Menu_ * m,void *)2455 void cb_Tableur_SetRows(Fl_Menu_* m , void*) { 2456 Flv_Table_Gen * tg=find_table_brother(m); 2457 if (!tg) return; 2458 const char * ch=fl_input(gettext("New row number"),print_INT_(tg->rows()).c_str()); 2459 if (ch){ 2460 int i=atoi(ch); 2461 if (i<tg->rows()){ 2462 int j=fl_ask("%s",gettext("Really delete rows?")); 2463 if (!j) 2464 return; 2465 } 2466 if (i>0 && double(i)*tg->cols()<7e4) 2467 tg->resizesheet(i,tg->cols()); 2468 } 2469 } 2470 cb_Tableur_SetCols(Fl_Menu_ * m,void *)2471 void cb_Tableur_SetCols(Fl_Menu_* m , void*) { 2472 Flv_Table_Gen * tg=find_table_brother(m); 2473 if (!tg) return; 2474 const char * ch=fl_input(gettext("New col number"),print_INT_(tg->cols()).c_str()); 2475 if (ch){ 2476 int i=atoi(ch); 2477 if (i<tg->cols()){ 2478 int j=fl_ask("%s",gettext("Really delete columns?")); 2479 if (!j) 2480 return; 2481 } 2482 if (i>0 && double(i)*tg->rows()<7e4){ 2483 tg->resizesheet(tg->rows(),i); 2484 } 2485 } 2486 } 2487 cb_Tableur_Histogram(Fl_Menu_ * m,void *)2488 void cb_Tableur_Histogram(Fl_Menu_* m , void*) { 2489 Flv_Table_Gen * tg=find_table_brother(m); 2490 if (!tg) return; 2491 const giac::context * contextptr = get_context(tg); 2492 tg->set_graphic(gen("histogram",contextptr),gettext("Histogram 1 or 2 columns: data or data/eff")); 2493 } 2494 cb_Tableur_Classes(Fl_Menu_ * m,void *)2495 void cb_Tableur_Classes(Fl_Menu_* m , void*) { 2496 Flv_Table_Gen * tg=find_table_brother(m); 2497 if (!tg) return; 2498 const giac::context * contextptr = get_context(tg); 2499 gen in,out; 2500 bool absolu,transpose; // always true for histograms 2501 double deg=0; 2502 int r=tg->set_graphic_dialog("classes",gettext("Make classes from column data or data/eff into two adjacent columns"),in,out,true,absolu,transpose,deg); 2503 if (r==0){ 2504 gen tmp; 2505 int r1,r2,R,C; 2506 vector<int> vc; 2507 matrice mselect; 2508 if ( (iscell_range(in,tg->m,mselect,tg,r1,r2,vc,absolu)==1) && iscell(out,C,R,contextptr) ){ 2509 matrice g; 2510 try { 2511 tg->select_start_row(r1); tg->row(r2-1); 2512 tg->select_start_col(vc.front()); tg->col(vc.back()); 2513 tg->copy(); 2514 matrice tmp=extractmatricefromsheet(tg->selected); 2515 if (transpose) 2516 tmp=mtran(tmp); 2517 g=effectifs(tmp,class_minimum,class_size,get_context(tg)); 2518 } catch (std::runtime_error & e){ 2519 return; 2520 } 2521 tg->row(R); tg->col(C); 2522 tg->paste(g); 2523 } 2524 } 2525 } 2526 cb_Tableur_Boxwhisker(Fl_Menu_ * m,void *)2527 void cb_Tableur_Boxwhisker(Fl_Menu_* m , void*) { 2528 Flv_Table_Gen * tg=find_table_brother(m); 2529 if (!tg) return; 2530 const giac::context * contextptr = get_context(tg); 2531 tg->set_graphic(gen("boxwhisker",contextptr),gettext("One boxwhisker per column")); 2532 } 2533 cb_Tableur_plotlist(Fl_Menu_ * m,void *)2534 void cb_Tableur_plotlist(Fl_Menu_* m , void*) { 2535 Flv_Table_Gen * tg=find_table_brother(m); 2536 if (!tg) return; 2537 const giac::context * contextptr = get_context(tg); 2538 tg->set_graphic(gen("plotlist",contextptr),gettext("Plotlist: One column (y) or two columns (x,y)")); 2539 } 2540 cb_Tableur_camembert(Fl_Menu_ * m,void *)2541 void cb_Tableur_camembert(Fl_Menu_* m , void*) { 2542 Flv_Table_Gen * tg=find_table_brother(m); 2543 if (!tg) return; 2544 const giac::context * contextptr = get_context(tg); 2545 tg->set_graphic(gen("camembert",contextptr),gettext("Camembert: column 1: legends, column 2: data")); 2546 } 2547 cb_Tableur_batons(Fl_Menu_ * m,void *)2548 void cb_Tableur_batons(Fl_Menu_* m , void*) { 2549 Flv_Table_Gen * tg=find_table_brother(m); 2550 if (!tg) return; 2551 const giac::context * contextptr = get_context(tg); 2552 tg->set_graphic(gen("bar_plot",contextptr),gettext("Bar_plot: column 1: legends, column 2: data")); 2553 } 2554 cb_Tableur_Scatterplot(Fl_Menu_ * m,void *)2555 void cb_Tableur_Scatterplot(Fl_Menu_* m , void*) { 2556 Flv_Table_Gen * tg=find_table_brother(m); 2557 if (!tg) return; 2558 const giac::context * contextptr = get_context(tg); 2559 tg->set_graphic(gen("scatterplot",contextptr),gettext("Column 1: x, one scatterplot per remaining column")); 2560 } 2561 cb_Tableur_Polygonplot(Fl_Menu_ * m,void *)2562 void cb_Tableur_Polygonplot(Fl_Menu_* m , void*) { 2563 Flv_Table_Gen * tg=find_table_brother(m); 2564 if (!tg) return; 2565 const giac::context * contextptr = get_context(tg); 2566 tg->set_graphic(gen("polygonplot",contextptr),gettext("Column 1: x, one polygonplot per remaining column")); 2567 } 2568 cb_Tableur_Polygonscatterplot(Fl_Menu_ * m,void *)2569 void cb_Tableur_Polygonscatterplot(Fl_Menu_* m , void*) { 2570 Flv_Table_Gen * tg=find_table_brother(m); 2571 if (!tg) return; 2572 const giac::context * contextptr = get_context(tg); 2573 tg->set_graphic(gen("polygonscatterplot",contextptr),gettext("Column 1: x, one polygon line per remaining column")); 2574 } 2575 cb_Tableur_linear_regression_plot(Fl_Menu_ * m,void *)2576 void cb_Tableur_linear_regression_plot(Fl_Menu_* m , void*) { 2577 Flv_Table_Gen * tg=find_table_brother(m); 2578 if (!tg) return; 2579 const giac::context * contextptr = get_context(tg); 2580 tg->set_graphic(gen("linear_regression_plot",contextptr),gettext("Linear regression: column 1: x, column 2: y")); 2581 } 2582 cb_Tableur_power_regression_plot(Fl_Menu_ * m,void *)2583 void cb_Tableur_power_regression_plot(Fl_Menu_* m , void*) { 2584 Flv_Table_Gen * tg=find_table_brother(m); 2585 if (!tg) return; 2586 const giac::context * contextptr = get_context(tg); 2587 tg->set_graphic(gen("power_regression_plot",contextptr),gettext("Power regression: Column 1: x, column 2: y")); 2588 } 2589 cb_Tableur_logarithmic_regression_plot(Fl_Menu_ * m,void *)2590 void cb_Tableur_logarithmic_regression_plot(Fl_Menu_* m , void*) { 2591 Flv_Table_Gen * tg=find_table_brother(m); 2592 if (!tg) return; 2593 const giac::context * contextptr = get_context(tg); 2594 tg->set_graphic(gen("logarithmic_regression_plot",contextptr),gettext("Log regression: Column 1: x, column 2: y")); 2595 } 2596 cb_Tableur_exponential_regression_plot(Fl_Menu_ * m,void *)2597 void cb_Tableur_exponential_regression_plot(Fl_Menu_* m , void*) { 2598 Flv_Table_Gen * tg=find_table_brother(m); 2599 if (!tg) return; 2600 const giac::context * contextptr = get_context(tg); 2601 tg->set_graphic(gen("exponential_regression_plot",contextptr),gettext("Exp regression: Column 1: x, column 2: y")); 2602 } 2603 cb_Tableur_polynomial_regression_plot(Fl_Menu_ * m,void *)2604 void cb_Tableur_polynomial_regression_plot(Fl_Menu_* m , void*) { 2605 Flv_Table_Gen * tg=find_table_brother(m); 2606 if (!tg) return; 2607 const giac::context * contextptr = get_context(tg); 2608 tg->set_graphic(gen("polynomial_regression_plot",contextptr),gettext("Polynomial regression degree d: Column 1: x, column 2: y")); 2609 } 2610 cb_Tableur_logistic_regression_plot(Fl_Menu_ * m,void *)2611 void cb_Tableur_logistic_regression_plot(Fl_Menu_* m , void*) { 2612 Flv_Table_Gen * tg=find_table_brother(m); 2613 if (!tg) return; 2614 const giac::context * contextptr = get_context(tg); 2615 tg->set_graphic(gen("logistic_regression_plot",contextptr),gettext("Logistic regression for y', with y(x=1)=y1")); 2616 } 2617 find_sort_row(int c2,bool isrow,GIAC_CONTEXT)2618 int find_sort_row(int c2,bool isrow,GIAC_CONTEXT){ 2619 int c; 2620 if (xcas_mode(contextptr)) 2621 c=c2+1; 2622 else 2623 c=c2; 2624 string question=gettext("Sort with respect to "); 2625 if (isrow) 2626 question += gettext("row"); 2627 else 2628 question += gettext("column"); 2629 const char * chptr=fl_input("%s",print_INT_(c).c_str(),question.c_str()); 2630 if (!chptr) 2631 return -1; 2632 string colonne(chptr); 2633 gen g(colonne,contextptr); 2634 if (xcas_mode(contextptr)) 2635 g = g + minus_one; 2636 if (g.type!=_INT_ ) 2637 return -1; 2638 return g.val; 2639 } 2640 2641 // Global variable is used for sorting only. 2642 static Flv_Table_Gen * current_spread_ptr; thesheetsort(const gen & a,const gen & b)2643 bool thesheetsort(const gen & a,const gen &b){ 2644 const giac::context * contextptr = get_context(current_spread_ptr); 2645 gen a1=a[current_spread_ptr->sort_col][1].evalf_double(1,contextptr),a2=b[current_spread_ptr->sort_col][1].evalf_double(1,contextptr); 2646 if (a1.type!=_DOUBLE_ || a2.type!=_DOUBLE_) 2647 return a1.islesscomplexthan(a2); 2648 return a1._DOUBLE_val<a2._DOUBLE_val; 2649 } 2650 sheetsort(Flv_Table_Gen * spread_ptr,bool row_sort,bool increasing)2651 void sheetsort(Flv_Table_Gen * spread_ptr,bool row_sort,bool increasing){ 2652 const giac::context * contextptr = get_context(spread_ptr); 2653 current_spread_ptr=spread_ptr; 2654 if (spread_ptr->is_spreadsheet){ 2655 int i=fl_ask("%s",gettext("Sorting is not compatible with some cell references. Sort anyway"),gettext("Yes"),gettext("No")); 2656 if (i!=1) return ; 2657 } 2658 int r1,r2,c1,c2; 2659 matrice m; 2660 if (row_sort){ // Transpose if sort w.r. to current row 2661 m=mtran(spread_ptr->m); 2662 r1=spread_ptr->col(); 2663 r2=spread_ptr->push_col; 2664 c1=spread_ptr->row(); 2665 c2=spread_ptr->push_row; 2666 int r=find_sort_row(c2,true,contextptr); 2667 if (r<0 || r>=spread_ptr->rows()) 2668 return; 2669 spread_ptr->sort_col=r; 2670 } 2671 else { 2672 m=spread_ptr->m; 2673 r1=spread_ptr->row(); 2674 r2=spread_ptr->push_row; 2675 c1=spread_ptr->col(); 2676 c2=spread_ptr->push_col; 2677 if (spread_ptr->is_spreadsheet){ 2678 int r,c; 2679 string tmp=coltocolname(c2); 2680 string question=gettext("Sort with respect to "); 2681 if (row_sort) 2682 question += gettext("row"); 2683 else 2684 question += gettext("column"); 2685 const char * chptr=fl_input("%s",tmp.c_str(),question.c_str()); 2686 if (!chptr){ 2687 return; 2688 } 2689 string therow=chptr; 2690 therow +='1'; 2691 if (!iscell(gen(therow,contextptr),r,c,contextptr)) 2692 return; 2693 spread_ptr->sort_col=r; 2694 } 2695 else { 2696 int c=find_sort_row(c2,false,contextptr); 2697 if (c<0 || c>= spread_ptr->cols() ) 2698 return; 2699 spread_ptr->sort_col=c; 2700 } 2701 } 2702 if (r1==r2) 2703 return; 2704 if (r1>r2) 2705 giac::swapint(r1,r2); 2706 if (c1>c2) 2707 giac::swapint(c1,c2); 2708 // keep only rows r1->r2 and cols c1->c2 2709 m=mtran(matrice(m.begin()+r1,m.begin()+r2+1)); 2710 m=mtran(matrice(m.begin()+c1,m.begin()+c2+1)); 2711 // sort 2712 spread_ptr->sort_col -= c1; 2713 sort(m.begin(),m.end(),thesheetsort); 2714 if (!increasing) 2715 reverse(m.begin(),m.end()); 2716 // put in the matrix 2717 if (row_sort){ // Back transpose 2718 m=mtran(m); 2719 spread_ptr->row(c1); 2720 spread_ptr->col(r1); 2721 } 2722 else { 2723 spread_ptr->row(r1); 2724 spread_ptr->col(c1); 2725 } 2726 spread_ptr->paste(m); 2727 } 2728 cb_Tableur_Sort_Dec_Col(Fl_Menu_ * m,void *)2729 void cb_Tableur_Sort_Dec_Col(Fl_Menu_* m , void*) { 2730 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2731 if (!spread_ptr) return; 2732 sheetsort(spread_ptr,false,false); 2733 spread_ptr->spread_eval_interrupt(); 2734 spread_ptr->redraw(); 2735 } 2736 cb_Tableur_Sort_Inc_Col(Fl_Menu_ * m,void *)2737 void cb_Tableur_Sort_Inc_Col(Fl_Menu_* m , void*) { 2738 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2739 if (!spread_ptr) return; 2740 sheetsort(spread_ptr,false,true); 2741 spread_ptr->spread_eval_interrupt(); 2742 spread_ptr->redraw(); 2743 } 2744 cb_Tableur_Sort_Dec_Row(Fl_Menu_ * m,void *)2745 void cb_Tableur_Sort_Dec_Row(Fl_Menu_* m , void*) { 2746 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2747 if (!spread_ptr) return; 2748 sheetsort(spread_ptr,true,false); 2749 spread_ptr->spread_eval_interrupt(); 2750 spread_ptr->redraw(); 2751 } 2752 cb_Tableur_Sort_Inc_Row(Fl_Menu_ * m,void *)2753 void cb_Tableur_Sort_Inc_Row(Fl_Menu_* m , void*) { 2754 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2755 if (!spread_ptr) return; 2756 sheetsort(spread_ptr,true,true); 2757 spread_ptr->spread_eval_interrupt(); 2758 spread_ptr->redraw(); 2759 } 2760 cb_Tableur_Auto_Recompute(Fl_Menu_ * m,void *)2761 void cb_Tableur_Auto_Recompute(Fl_Menu_* m , void*) { 2762 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2763 if (!spread_ptr) return; 2764 spread_ptr->spreadsheet_recompute=1; 2765 spread_ptr->update_status(); 2766 } 2767 cb_Tableur_No_Recompute(Fl_Menu_ * m,void *)2768 void cb_Tableur_No_Recompute(Fl_Menu_* m , void*) { 2769 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2770 if (!spread_ptr) return; 2771 spread_ptr->spreadsheet_recompute=0; 2772 spread_ptr->update_status(); 2773 } 2774 cb_Tableur_Matrix_Fill(Fl_Menu_ * m,void *)2775 void cb_Tableur_Matrix_Fill(Fl_Menu_* m , void*) { 2776 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2777 if (!spread_ptr) return; 2778 spread_ptr->matrix_fill_cells=1; 2779 spread_ptr->update_status(); 2780 } 2781 cb_Tableur_No_Matrix_Fill(Fl_Menu_ * m,void *)2782 void cb_Tableur_No_Matrix_Fill(Fl_Menu_* m , void*) { 2783 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2784 if (!spread_ptr) return; 2785 spread_ptr->matrix_fill_cells=0; 2786 spread_ptr->update_status(); 2787 } 2788 cb_Tableur_Variable_Name(Fl_Menu_ * m,void *)2789 void cb_Tableur_Variable_Name(Fl_Menu_* m , void*) { 2790 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2791 if (!spread_ptr) return; 2792 spread_ptr->config(); 2793 } 2794 cb_Tableur_Spreadsheet_Mode(Fl_Menu_ * m,void *)2795 void cb_Tableur_Spreadsheet_Mode(Fl_Menu_* m , void*) { 2796 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2797 if (!spread_ptr) return; 2798 spread_ptr->is_spreadsheet=1; 2799 spread_ptr->update_status(); 2800 } 2801 cb_Tableur_Matrix_Mode(Fl_Menu_ * m,void *)2802 void cb_Tableur_Matrix_Mode(Fl_Menu_* m , void*) { 2803 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2804 if (!spread_ptr) return; 2805 spread_ptr->is_spreadsheet=0; 2806 spread_ptr->update_status(); 2807 } 2808 cb_Tableur_Normal_Matrix(Fl_Menu_ * m,void *)2809 void cb_Tableur_Normal_Matrix(Fl_Menu_* m , void*) { 2810 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2811 if (!spread_ptr) return; 2812 spread_ptr->matrix_symmetry=0; 2813 spread_ptr->update_status(); 2814 } 2815 cb_Tableur_Symmetric_Matrix(Fl_Menu_ * m,void *)2816 void cb_Tableur_Symmetric_Matrix(Fl_Menu_* m , void*) { 2817 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2818 if (!spread_ptr) return; 2819 if (spread_ptr->rows()!=spread_ptr->cols()){ 2820 fl_message("%s",gettext("Make rows==cols first!")); 2821 return; 2822 } 2823 spread_ptr->is_spreadsheet=0; 2824 spread_ptr->matrix_symmetry=4; 2825 spread_ptr->update_status(); 2826 } 2827 cb_Tableur_AntiSymmetric_Matrix(Fl_Menu_ * m,void *)2828 void cb_Tableur_AntiSymmetric_Matrix(Fl_Menu_* m , void*) { 2829 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2830 if (!spread_ptr) return; 2831 if (spread_ptr->rows()!=spread_ptr->cols()){ 2832 fl_message("%s",gettext("Make rows==cols first!")); 2833 return; 2834 } 2835 spread_ptr->is_spreadsheet=0; 2836 spread_ptr->matrix_symmetry=3; 2837 spread_ptr->update_status(); 2838 } 2839 cb_Tableur_Hermitian_Matrix(Fl_Menu_ * m,void *)2840 void cb_Tableur_Hermitian_Matrix(Fl_Menu_* m , void*) { 2841 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2842 if (!spread_ptr) return; 2843 if (spread_ptr->rows()!=spread_ptr->cols()){ 2844 fl_message("%s",gettext("Make rows==cols first!")); 2845 return; 2846 } 2847 spread_ptr->is_spreadsheet=0; 2848 spread_ptr->matrix_symmetry=2; 2849 spread_ptr->update_status(); 2850 } 2851 cb_Tableur_AntiHermitian_Matrix(Fl_Menu_ * m,void *)2852 void cb_Tableur_AntiHermitian_Matrix(Fl_Menu_* m , void*) { 2853 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2854 if (!spread_ptr) return; 2855 if (spread_ptr->rows()!=spread_ptr->cols()){ 2856 fl_message("%s",gettext("Make rows==cols first!")); 2857 return; 2858 } 2859 spread_ptr->is_spreadsheet=0; 2860 spread_ptr->matrix_symmetry=1; 2861 spread_ptr->update_status(); 2862 } 2863 cb_Tableur_Hide_Graph(Fl_Menu_ * m,void *)2864 void cb_Tableur_Hide_Graph(Fl_Menu_* m , void*) { 2865 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2866 if (!spread_ptr) return; 2867 Tableur_Group * tg=dynamic_cast<Tableur_Group *>(spread_ptr->parent()); 2868 if (tg){ 2869 if (tg->disposition & 0x2) 2870 tg->save_dparam(); 2871 tg->disposition=0; 2872 tg->resize2(); 2873 tg->redraw(); 2874 } 2875 } 2876 cb_Tableur_Portrait(Fl_Menu_ * m,void *)2877 void cb_Tableur_Portrait(Fl_Menu_* m , void*) { 2878 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2879 if (!spread_ptr) return; 2880 Tableur_Group * tg=dynamic_cast<Tableur_Group *>(spread_ptr->parent()); 2881 if (tg){ 2882 tg->disposition=3; 2883 tg->resize2(); 2884 tg->redraw(); 2885 } 2886 } 2887 cb_Tableur_Landscape(Fl_Menu_ * m,void *)2888 void cb_Tableur_Landscape(Fl_Menu_* m , void*) { 2889 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2890 if (!spread_ptr) return; 2891 Tableur_Group * tg=dynamic_cast<Tableur_Group *>(spread_ptr->parent()); 2892 if (tg){ 2893 tg->disposition=2; 2894 tg->resize2(); 2895 tg->redraw(); 2896 } 2897 } 2898 cb_Tableur_Autoscale(Fl_Menu_ * m,void *)2899 void cb_Tableur_Autoscale(Fl_Menu_* m , void*) { 2900 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2901 if (!spread_ptr) return; 2902 Tableur_Group * tg=dynamic_cast<Tableur_Group *>(spread_ptr->parent()); 2903 if (tg){ 2904 tg->disposition |= 2; 2905 tg->resize2(); 2906 tg->table->graph->autoscale(); 2907 tg->redraw(); 2908 } 2909 } 2910 cb_Tableur_Cfg_Window(Fl_Menu_ * m,void *)2911 void cb_Tableur_Cfg_Window(Fl_Menu_* m , void*) { 2912 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2913 if (!spread_ptr) return; 2914 if (spread_ptr) 2915 spread_ptr->config(); 2916 } 2917 cb_Tableur_Undo(Fl_Menu_ * m,void *)2918 void cb_Tableur_Undo(Fl_Menu_* m , void*) { 2919 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2920 if (spread_ptr) 2921 spread_ptr->restore(-1); 2922 } 2923 cb_Tableur_Redo(Fl_Menu_ * m,void *)2924 void cb_Tableur_Redo(Fl_Menu_* m , void*) { 2925 Flv_Table_Gen * spread_ptr=find_table_brother(m); 2926 if (spread_ptr) 2927 spread_ptr->restore(1); 2928 } 2929 2930 Fl_Menu_Item Tableur_menu[] = { 2931 {gettext("Table"), 0, 0, 0, 64, 0, 0, 14, 56}, 2932 {gettext("Save sheet as text"), 0, (Fl_Callback*)cb_Tableur_Save, 0, 0, 0, 0, 14, 56}, 2933 {gettext("Save as alternate filename"), 0, (Fl_Callback*)cb_Tableur_Save_as, 0, 0, 0, 0, 14, 56}, 2934 {gettext("Save as CSV"), 0, (Fl_Callback*)cb_Tableur_Save_CSV, 0, 0, 0, 0, 14, 56}, 2935 {gettext("Save as mathml"), 0, (Fl_Callback*)cb_Tableur_Save_mathml, 0, 0, 0, 0, 14, 56}, 2936 {gettext("Save selection to variable"), 0, (Fl_Callback*)cb_Tableur_Save_var, 0, 0, 0, 0, 14, 56}, 2937 {gettext("Insert"), 0, (Fl_Callback*)cb_Tableur_Insert, 0, 0, 0, 0, 14, 56}, 2938 {gettext("Insert CSV"), 0, (Fl_Callback*)cb_Tableur_Insert_CSV, 0, 0, 0, 0, 14, 56}, 2939 {gettext("Sheet configuration"), 0, (Fl_Callback*)cb_Tableur_Variable_Name, 0, 0, 0, 0, 14, 56}, 2940 {gettext("Print Export"), 0, 0, 0, 64, 0, 0, 14, 56}, 2941 // {gettext("latex preview"), 0, (Fl_Callback*)cb_Tableur_LaTeX_Preview, 0, 0, 0, 0, 14, 56}, 2942 // {gettext("latex printer"), 0, (Fl_Callback*)cb_Tableur_LaTeX_Print, 0, 0, 0, 0, 14, 56}, 2943 {gettext("EPS PNG and preview"), 0, (Fl_Callback*)cb_Tableur_Preview, 0, 0, 0, 0, 14, 56}, 2944 {gettext("to printer"), 0, (Fl_Callback*)cb_Tableur_Print, 0, 0, 0, 0, 14, 56}, 2945 {0}, 2946 {0}, 2947 {gettext("Edit"), 0, 0, 0, 64, 0, 0, 14, 56}, 2948 {gettext("Eval sheet"), 0xffc6, (Fl_Callback *) cb_Tableur_Eval_Sheet, 0, 0, 0, 0, 14, 56}, 2949 {gettext("Copy Cell"), 0, (Fl_Callback *) cb_Tableur_Copy_Cell, 0, 0, 0, 0, 14, 56}, 2950 {gettext("Paste"), 0, (Fl_Callback *) cb_Paste, 0, 0, 0, 0, 14, 56}, 2951 {gettext("Undo"), 0x4007a, (Fl_Callback *) cb_Tableur_Undo, 0, 0, 0, 0, 14, 56}, 2952 {gettext("Redo"), 0x40079, (Fl_Callback *) cb_Tableur_Redo, 0, 0, 0, 0, 14, 56}, 2953 {gettext("Configuration"), 0, 0, 0, 64, 0, 0, 14, 56}, 2954 {gettext("Cfg window"), 0, (Fl_Callback *) cb_Tableur_Cfg_Window, 0, 0, 0, 0, 14, 56}, 2955 {gettext("Graph"), 0, 0, 0, 64, 0, 0, 14, 56}, 2956 {gettext("Autoscale graph"), 0, (Fl_Callback *) cb_Tableur_Autoscale, 0, 0, 0, 0, 14, 56}, 2957 {gettext("Graph portrait"), 0, (Fl_Callback *) cb_Tableur_Portrait, 0, 0, 0, 0, 14, 56}, 2958 {gettext("Graph landscape"), 0, (Fl_Callback *) cb_Tableur_Landscape, 0, 0, 0, 0, 14, 56}, 2959 {gettext("Hide Graph"), 0, (Fl_Callback *) cb_Tableur_Hide_Graph, 0, 0, 0, 0, 14, 56}, 2960 {0}, // end graph 2961 {gettext("Format"), 0, 0, 0, 64, 0, 0, 14, 56}, 2962 {gettext("Spreadsheet"), 0, (Fl_Callback *) cb_Tableur_Spreadsheet_Mode, 0, 0, 0, 0, 14, 56}, 2963 {gettext("Matrix"), 0, (Fl_Callback *) cb_Tableur_Matrix_Mode, 0, 0, 0, 0, 14, 56}, 2964 {gettext("Normal matrix"), 0, (Fl_Callback *) cb_Tableur_Normal_Matrix, 0, 0, 0, 0, 14, 56}, 2965 {gettext("Symmetric matrix"), 0, (Fl_Callback *) cb_Tableur_Symmetric_Matrix, 0, 0, 0, 0, 14, 56}, 2966 {gettext("AntiSymmetric matrix"), 0, (Fl_Callback *) cb_Tableur_AntiSymmetric_Matrix, 0, 0, 0, 0, 14, 56}, 2967 {gettext("Hermitian matrix"), 0, (Fl_Callback *) cb_Tableur_Hermitian_Matrix, 0, 0, 0, 0, 14, 56}, 2968 {gettext("AntiHermitian matrix"), 0, (Fl_Callback *) cb_Tableur_AntiHermitian_Matrix, 0, 0, 0, 0, 14, 56}, 2969 {0}, // end format 2970 {gettext("Set Rows Number"), 0, (Fl_Callback *) cb_Tableur_SetRows, 0, 0, 0, 0, 14, 56}, 2971 {gettext("Set Cols Number"), 0, (Fl_Callback *) cb_Tableur_SetCols, 0, 0, 0, 0, 14, 56}, 2972 {gettext("Move ->"), 0, (Fl_Callback *) cb_Tableur_MoveRight, 0, 0, 0, 0, 14, 56}, 2973 {gettext("Move down"), 0, (Fl_Callback *) cb_Tableur_MoveDown, 0, 0, 0, 0, 14, 56}, 2974 {gettext("Auto Recompute"), 0, (Fl_Callback *) cb_Tableur_Auto_Recompute, 0, 0, 0, 0, 14, 56}, 2975 {gettext("No Recompute"), 0, (Fl_Callback *) cb_Tableur_No_Recompute, 0, 0, 0, 0, 14, 56}, 2976 {gettext("Dispatch matrix to cells"), 0, (Fl_Callback *) cb_Tableur_Matrix_Fill, 0, 0, 0, 0, 14, 56}, 2977 {gettext("Keep matrix in one cell"), 0, (Fl_Callback *) cb_Tableur_No_Matrix_Fill, 0, 0, 0, 0, 14, 56}, 2978 {0}, // end Configuration 2979 {gettext("Fill"), 0, 0, 0, 64, 0, 0, 14, 56}, 2980 {gettext("Copy right"), 0x40072, (Fl_Callback *) cb_Tableur_Copy_Right, 0, 0, 0, 0, 14, 56}, 2981 {gettext("Copy down"), 0x40064, (Fl_Callback *) cb_Tableur_Copy_Down, 0, 0, 0, 0, 14, 56}, 2982 {gettext("Fill selection with pushed cell"), 0, (Fl_Callback *) cb_Tableur_FillSelection, 0, 0, 0, 0, 14, 56}, 2983 {gettext("Fill selection with 0"), 0, (Fl_Callback *) cb_Tableur_Fill0, 0, 0, 0, 0, 14, 56}, 2984 {gettext("Fill sheet with 0"), 0, (Fl_Callback *) cb_Tableur_Del, 0, 0, 0, 0, 14, 56}, 2985 {0}, 2986 {gettext("Add or delete"), 0, 0, 0, 64, 0, 0, 14, 56}, 2987 {gettext("Insert Row"), 0, (Fl_Callback *) cb_Tableur_InsRow, 0, 0, 0, 0, 14, 56}, 2988 {gettext("Row+ at end"), 0, (Fl_Callback *) cb_Tableur_InsRow_End, 0, 0, 0, 0, 14, 56}, 2989 {gettext("Insert Col"), 0, (Fl_Callback *) cb_Tableur_InsCol, 0, 0, 0, 0, 14, 56}, 2990 {gettext("Col+ at end"), 0, (Fl_Callback *) cb_Tableur_InsCol_End, 0, 0, 0, 0, 14, 56}, 2991 {gettext("Erase current row"), 0, (Fl_Callback *) cb_Tableur_DelRow, 0, 0, 0, 0, 14, 56}, 2992 {gettext("Erase selection rows"), 0, (Fl_Callback *) cb_Tableur_DelRows, 0, 0, 0, 0, 14, 56}, 2993 {gettext("Erase current col"), 0, (Fl_Callback *) cb_Tableur_DelCol, 0, 0, 0, 0, 14, 56}, 2994 {gettext("Erase selection cols"), 0, (Fl_Callback *) cb_Tableur_DelCols, 0, 0, 0, 0, 14, 56}, 2995 {0}, 2996 {gettext("Sort"), 0, 0, 0, 64, 0, 0, 14, 56}, 2997 {gettext("Inc col"), 0, (Fl_Callback *) cb_Tableur_Sort_Inc_Col, 0, 0, 0, 0, 14, 56}, 2998 {gettext("Dec col"), 0, (Fl_Callback *) cb_Tableur_Sort_Dec_Col, 0, 0, 0, 0, 14, 56}, 2999 {gettext("Inc row"), 0, (Fl_Callback *) cb_Tableur_Sort_Inc_Row, 0, 0, 0, 0, 14, 56}, 3000 {gettext("Dec row"), 0, (Fl_Callback *) cb_Tableur_Sort_Dec_Row, 0, 0, 0, 0, 14, 56}, 3001 {0}, 3002 {gettext("Col larger"), 0, (Fl_Callback *) cb_Tableur_Col_Larger, 0, 0, 0, 0, 14, 56}, 3003 {gettext("Col smaller"), 0, (Fl_Callback *) cb_Tableur_Col_Smaller, 0, 0, 0, 0, 14, 56}, 3004 #ifndef IPAQ // on ipaq put Stat inside Edit 3005 {0}, // end Edit 3006 #endif 3007 {gettext("Maths"), 0, 0, 0, 64, 0, 0, 14, 56}, 3008 {gettext("Function"), 0, (Fl_Callback *) cb_Tableur_Tablefunc, 0, 0, 0, 0, 14, 56}, 3009 {gettext("Random values"), 0, (Fl_Callback *) cb_Tableur_ranm, 0, 0, 0, 0, 14, 56}, 3010 {gettext("Sequences"), 0, 0, 0, 64, 0, 0, 14, 56}, 3011 {gettext("Recurrent sequence"), 0, (Fl_Callback *) cb_Tableur_Tableseq, 0, 0, 0, 0, 14, 56}, 3012 {gettext("Bar plot"), 0, (Fl_Callback *) cb_Tableur_batons, 0, 0, 0, 0, 14, 56}, 3013 {gettext("plotlist"), 0, (Fl_Callback *) cb_Tableur_plotlist, 0, 0, 0, 0, 14, 56}, 3014 {gettext("Polygonscatterplot"), 0, (Fl_Callback *) cb_Tableur_Polygonscatterplot, 0, 0, 0, 0, 14, 56}, 3015 {gettext("Scatterplot"), 0, (Fl_Callback *) cb_Tableur_Scatterplot, 0, 0, 0, 0, 14, 56}, 3016 {gettext("Polygonplot"), 0, (Fl_Callback *) cb_Tableur_Polygonplot, 0, 0, 0, 0, 14, 56}, 3017 {0}, 3018 {gettext("1-d stats"), 0, 0, 0, 64, 0, 0, 14, 56}, 3019 {gettext("camembert"), 0, (Fl_Callback *) cb_Tableur_camembert, 0, 0, 0, 0, 14, 56}, 3020 {gettext("Bar plot"), 0, (Fl_Callback *) cb_Tableur_batons, 0, 0, 0, 0, 14, 56}, 3021 {gettext("plotlist"), 0, (Fl_Callback *) cb_Tableur_plotlist, 0, 0, 0, 0, 14, 56}, 3022 {gettext("Boxwhisker"), 0, (Fl_Callback *) cb_Tableur_Boxwhisker, 0, 0, 0, 0, 14, 56}, 3023 {gettext("Classes (data or data,eff)"), 0, (Fl_Callback *) cb_Tableur_Classes, 0, 0, 0, 0, 14, 56}, 3024 {gettext("Histogram (interval,eff)"), 0, (Fl_Callback *) cb_Tableur_Histogram, 0, 0, 0, 0, 14, 56}, 3025 {0}, 3026 {gettext("2-d stats"), 0, 0, 0, 64, 0, 0, 14, 56}, 3027 {gettext("Polygonscatterplot"), 0, (Fl_Callback *) cb_Tableur_Polygonscatterplot, 0, 0, 0, 0, 14, 56}, 3028 {gettext("Scatterplot"), 0, (Fl_Callback *) cb_Tableur_Scatterplot, 0, 0, 0, 0, 14, 56}, 3029 {gettext("Polygonplot"), 0, (Fl_Callback *) cb_Tableur_Polygonplot, 0, 0, 0, 0, 14, 56}, 3030 {0}, // end 2-d 3031 {gettext("Regressions"), 0, 0, 0, 64, 0, 0, 14, 56}, 3032 {gettext("Linear"), 0, (Fl_Callback *) cb_Tableur_linear_regression_plot, 0, 0, 0, 0, 14, 56}, 3033 {gettext("Polynomial"), 0, (Fl_Callback *) cb_Tableur_polynomial_regression_plot, 0, 0, 0, 0, 14, 56}, 3034 {gettext("Exponential"), 0, (Fl_Callback *) cb_Tableur_exponential_regression_plot, 0, 0, 0, 0, 14, 56}, 3035 {gettext("Logarithmic"), 0, (Fl_Callback *) cb_Tableur_logarithmic_regression_plot, 0, 0, 0, 0, 14, 56}, 3036 {gettext("Power"), 0, (Fl_Callback *) cb_Tableur_power_regression_plot, 0, 0, 0, 0, 14, 56}, 3037 {gettext("Logistic"), 0, (Fl_Callback *) cb_Tableur_logistic_regression_plot, 0, 0, 0, 0, 14, 56}, 3038 {0}, // end regressions 3039 {0}, // end Statistics 3040 #ifdef IPAQ 3041 {0}, // end Edit 3042 #endif 3043 {0} // end menu 3044 }; 3045 Tableur_callback(Flv_Table_Gen * l,void *)3046 void Tableur_callback(Flv_Table_Gen *l, void * ){ 3047 l->header_event=l->why_event(); 3048 // FLVE_TITLE_CLICKED, FLVE_ROW_HEADER_CLICKED, FLVE_COL_HEADER_CLICKED 3049 // FLVE_CLICKED 3050 if (l->header_event==FLVE_TITLE_CLICKED && l->last_event==FL_PUSH){ 3051 if (l->computing) 3052 kill_thread(true,l->contextptr); 3053 else 3054 l->config(); 3055 return; 3056 } 3057 /* 3058 if (!l->editing && l->header_event==FLVE_CLICKED && l->clicks()>1 && l->row()==l->select_start_row() && l->select_start_col()==l->col()){ 3059 // double-click, begin copy cell to area 3060 l->click_fill=true; 3061 set_cursor(l,FL_CURSOR_HAND); 3062 } 3063 */ 3064 if (l->header_event==FLVE_ROW_HEADER_CLICKED && l->rows()){ 3065 if (l->last_event!=FL_PUSH) 3066 l->row(l->row()-1); 3067 else { 3068 l->row(0); 3069 l->select_start_row(l->rows()-1); 3070 } 3071 } 3072 if (l->header_event==FLVE_ROW_FOOTER_CLICKED && l->rows()){ 3073 if (l->last_event!=FL_PUSH) 3074 l->row(l->row()+1); 3075 else { 3076 l->row(l->rows()-1); 3077 l->select_start_row(0); 3078 } 3079 } 3080 if (l->header_event==FLVE_COL_HEADER_CLICKED && l->cols()){ 3081 if (l->last_event!=FL_PUSH) 3082 l->col(l->col()-1); 3083 else { 3084 l->col(0); 3085 l->select_start_col(l->cols()-1); 3086 } 3087 } 3088 if (l->header_event==FLVE_COL_FOOTER_CLICKED && l->cols()){ 3089 if (l->last_event!=FL_PUSH) 3090 l->col(l->col()+1); 3091 else { 3092 l->select_start_col(0); 3093 l->col(l->cols()-1); 3094 } 3095 } 3096 } 3097 finish_flv_table_gen()3098 void Flv_Table_Gen::finish_flv_table_gen(){ 3099 if (Fl_Group * gr=parent()){ 3100 labelsize(gr->labelsize()); 3101 mb = new Fl_Menu_Button(x(),y(),w(),h(),"&Table"); 3102 mb->type(Fl_Menu_Button::POPUP3); 3103 mb->box(FL_NO_BOX); 3104 mb->menu(Tableur_menu); 3105 gr->insert(*mb,gr->find(this)); 3106 } 3107 else 3108 mb=0; 3109 // Style 3110 is_spreadsheet=true; 3111 header_event=0; 3112 // spread_editor = new Flve_Input( 0, 0, 0,0); 3113 // edit_when(FLV_EDIT_AUTOMATIC); 3114 // global_style.editor(spread_editor); 3115 // spread_editor->textsize(12); 3116 callback_when( FLVEcb_ROW_HEADER_CLICKED | FLVEcb_COL_HEADER_CLICKED | FLVEcb_CLICKED | FLVEcb_TITLE_CLICKED | FLVEcb_ROW_FOOTER_CLICKED | FLVEcb_COL_FOOTER_CLICKED | FLVEcb_CLICKED); 3117 callback((Fl_Callback*)Tableur_callback); 3118 select_locked(false); 3119 global_style.font_size(labelsize()); 3120 global_style.x_margin(5); 3121 global_style.locked(false); 3122 3123 #ifdef IPAQ 3124 col_width(25,-1); 3125 #else // IPAQ 3126 col_width(50,-1); 3127 #endif // IPAQ 3128 feature(FLVF_HEADERS|FLVF_ROW_FOOTER|FLVF_DIVIDERS|FLVF_MULTI_SELECT|FLVF_PERSIST_SELECT ); // add FLVF_COL_FOOTER for right footers 3129 global_style.resizable(true); 3130 #ifdef IPAQ 3131 global_style.width(40); 3132 #else // IPAQ 3133 global_style.width(10+10*labelsize()); 3134 #endif // IPAQ 3135 global_style.height(labelsize()+4); 3136 row_style[-1].align(FL_ALIGN_CLIP); 3137 col_style[-1].align(FL_ALIGN_CLIP); 3138 update_status(); 3139 Fl::focus(this); 3140 // Fl::focus(input); 3141 } 3142 draw_cell(int Offset,int & X,int & Y,int & W,int & H,int R,int C)3143 void Flv_Table_Gen::draw_cell( int Offset, int &X, int &Y, int &W, int &H, int R, int C ){ 3144 Flv_Style s; 3145 3146 get_style(s, R, C); 3147 Flv_Table::draw_cell(Offset,X,Y,W,H,R,C); 3148 string ss; 3149 if (C<0){ 3150 if (R>=0){ 3151 if (xcas_mode(contextptr)>0) 3152 ss=gen(R+1).print(contextptr); 3153 else 3154 ss=gen(R).print(contextptr); 3155 } 3156 } 3157 else { 3158 if (R<0){ 3159 if (is_spreadsheet && R==-1){ 3160 int i=C; 3161 for(int j=0;;++j){ 3162 ss=char('A'+i%26-(j!=0))+ss; 3163 i=i/26; 3164 if (!i) 3165 break; 3166 } 3167 } 3168 else { 3169 if (xcas_mode(contextptr)>0) 3170 ss=gen(C+1).print(contextptr); 3171 else 3172 ss=gen(C).print(contextptr); 3173 } 3174 } 3175 else { 3176 const gen & g=m[R][C]; 3177 if ((g.type==_VECT) && (g._VECTptr->size()==3) ){ 3178 int save_r=printcell_current_row(contextptr),save_c=printcell_current_col(contextptr); 3179 printcell_current_row(contextptr)=R,printcell_current_col(contextptr)=C; 3180 ss=pnt2string((*g._VECTptr)[1],contextptr); 3181 printcell_current_row(contextptr)=save_r;printcell_current_col(contextptr)=save_c; 3182 } 3183 else 3184 ss=g.print(contextptr); 3185 } 3186 } 3187 fl_color(FL_BLACK); 3188 if (ss.size()>max_printsize) 3189 ss=gettext("Too large for cell display"); 3190 fl_draw(ss.c_str(), X-Offset, Y, W, H, s.align() ); 3191 } 3192 3193 /* 3194 void Flv_Table_Gen::save_editor( Fl_Widget *e, int R, int C ){ 3195 if ( (R>=0) && (C>=0) ){ 3196 vecteur & v=*m[R]._VECTptr; 3197 gen g(string( ((Flve_Input *) e)->value() )); 3198 if ( (v[C].type==_VECT) && (v[C]._VECTptr->size()==3)){ 3199 v[C]._VECTptr->front()=spread_convert(g,R,C); 3200 if (is_spreadsheet) spread_eval_interrupt(); 3201 } 3202 else 3203 v[C]=g; 3204 } 3205 } 3206 3207 void Flv_Table_Gen::load_editor( Fl_Widget *e, int R, int C ){ 3208 if ((C>=0) && (R>=0)){ 3209 if ( (m[R][C].type==_VECT) && (m[R][C]._VECTptr->size()==3) ){ 3210 int save_r=printcell_current_row,save_c=printcell_current_col; 3211 printcell_current_row=R,printcell_current_col=C; 3212 ((Flve_Input *)e)->value( m[R][C][0].print(contextptr).c_str() ); 3213 printcell_current_row=save_r;printcell_current_col=save_c; 3214 } 3215 else 3216 ((Flve_Input *)e)->value( m[R][C].print(contextptr).c_str() ); 3217 ((Flve_Input *)e)->position(((Flve_Input *)e)->size(), 0 ); 3218 } 3219 } 3220 3221 void Flv_Table_Gen::position_editor( Fl_Widget *e, int x, int y, int w, int h, Flv_Style &s ){ 3222 3223 // Out of cell 3224 // e->resize( 10, 10, 200, 20 ); 3225 3226 // In cell 3227 // Flv_Table::position_editor(e,x+s.x_margin(),y,w-s.x_margin(),h,s); 3228 Flv_Table::position_editor(e,x,y,w,h,s); 3229 } 3230 */ 3231 sheet2pnt(const matrice & m,vecteur & v)3232 void sheet2pnt(const matrice & m,vecteur & v){ 3233 v.clear(); 3234 gen tmp; 3235 const_iterateur it=m.begin(),itend=m.end(); 3236 for (;it!=itend;++it){ 3237 if (it->type==_VECT){ 3238 const_iterateur jt=it->_VECTptr->begin(),jtend=it->_VECTptr->end(); 3239 for (;jt!=jtend;++jt){ 3240 if (jt->type==_VECT && jt->_VECTptr->size()==3) 3241 tmp=(*jt->_VECTptr)[1]; 3242 else 3243 tmp=*jt; 3244 bool test=tmp.is_symb_of_sommet(at_pnt); 3245 if (tmp.type==_VECT && !tmp._VECTptr->empty()) 3246 test=tmp._VECTptr->back().is_symb_of_sommet(at_pnt); 3247 if (test) 3248 v.push_back(tmp); 3249 } 3250 } 3251 } 3252 } 3253 update_name()3254 void Flv_Table_Gen::update_name(){ 3255 if (name.type==_IDNT) 3256 sto(extractmatricefromsheet(m),name,contextptr); 3257 } 3258 update_spread_graph()3259 void Flv_Table_Gen::update_spread_graph(){ 3260 // Update graph 3261 if (graph){ 3262 sheet2pnt(m,graph->plot_instructions); 3263 graph2d->plot_instructions=graph->plot_instructions; 3264 if (graph3d){ 3265 graph3d->plot_instructions=graph->plot_instructions; 3266 graph3d->redraw(); 3267 } 3268 graph->redraw(); 3269 graph2d->redraw(); 3270 } 3271 } 3272 spread_eval_interrupt()3273 void Flv_Table_Gen::spread_eval_interrupt(){ 3274 if (computing || is_context_busy(contextptr)){ 3275 fl_message("%s",gettext("CAS is busy")); 3276 return; 3277 } 3278 bool save_interrupt_button=interrupt_button; 3279 interrupt_button = true; 3280 if (is_spreadsheet){ 3281 computing=true; 3282 label("Recomputing: click here to interrupt"); 3283 redraw(); 3284 evaled_table(contextptr)=this; 3285 thread_spread_eval(m,contextptr); 3286 update_spread_graph(); 3287 computing=false; 3288 } 3289 update_name(); 3290 update_status(); 3291 interrupt_button=save_interrupt_button; 3292 redraw(); 3293 } 3294 3295 3296 // Check that g is one of the following form 3297 // col1,col2...coln 3298 // cell1..row,col2,...,coln 3299 // return the corresponding submatrix of m in mselect iscell_range(const giac::gen & g,const matrice & m,matrice & mselect,Flv_Table_Gen * sptr,int & r1,int & r2,std::vector<int> & vc,bool & absolu)3300 int iscell_range(const giac::gen & g,const matrice & m,matrice & mselect,Flv_Table_Gen * sptr,int & r1,int & r2,std::vector<int> & vc,bool & absolu){ 3301 vc.clear(); 3302 const giac::context * contextptr = get_context(sptr); 3303 if (g.is_symb_of_sommet(at_interval)){ 3304 gen & f=g._SYMBptr->feuille; 3305 if (f.type!=_VECT || f._VECTptr->size()!=2) 3306 return 0; 3307 int c1,c2; 3308 if (!iscell(f._VECTptr->front(),c1,r1,contextptr) || !iscell(f._VECTptr->back(),c2,r2,contextptr)) 3309 return 0; 3310 if (r1>r2) 3311 giac::swapint(r1,r2); 3312 r2=giacmin(r2+1,m.size()); 3313 r1=giacmax(r1,0); 3314 mselect=vecteur(m.begin()+r1,m.begin()+r2); 3315 mselect=mtran(mselect); 3316 if (c1>c2) 3317 giac::swapint(c1,c2); 3318 c2=giacmin(c2+1,m.size()); 3319 c1=giacmax(c1,0); 3320 mselect=vecteur(mselect.begin()+c1,mselect.begin()+c2); 3321 mselect=mtran(mselect); 3322 if (sptr){ 3323 sptr->select_start_row(r1); 3324 if (r2) 3325 sptr->row(r2-1); 3326 sptr->select_start_col(c1); 3327 if (c2) 3328 sptr->col(c2-1); 3329 } 3330 for (int j=c1;j<c2;++j) 3331 vc.push_back(j); 3332 return 1; 3333 } 3334 if (g.type!=_VECT) 3335 return 0; 3336 vecteur v=*g._VECTptr; 3337 int s=v.size(); 3338 if (s<2) 3339 return 0; 3340 r1=0; r2=m.size(); 3341 if (v.front().is_symb_of_sommet(at_interval) || v.front().is_symb_of_sommet(at_deuxpoints)){ // compute r1, r2 3342 gen & f=v.front()._SYMBptr->feuille; 3343 if (f.type!=_VECT || f._VECTptr->size()!=2) 3344 return 0; 3345 vecteur & w=*f._VECTptr; 3346 int c; 3347 if (!iscell(w[0],c,r1,contextptr)) 3348 return 0; 3349 r1=giacmax(giacmin(r1,m.size()),0); 3350 if (w[1].type==_INT_) 3351 r2=w[1].val-(xcas_mode(contextptr)!=0); 3352 else { 3353 if (!iscell(w[1],c,r2,contextptr)) 3354 return 0; 3355 } 3356 r2=giacmax(giacmin(r2+1,m.size()),0); 3357 if (r2<r1) giac::swapint(r1,r2); 3358 } 3359 // full columns selection 3360 matrice mt(mtran(m)); 3361 int mts=mt.size(); 3362 matrice tselect; 3363 for (int i=0;i<s;++i){ 3364 gen h=v[i]; 3365 if (h.type==_INT_ && h.val>=0 && h.val<mts){ 3366 tselect.push_back(mt[h.val]); 3367 vc.push_back(h.val); 3368 continue; 3369 } 3370 if (h.is_symb_of_sommet(at_interval)){ 3371 gen & f=h._SYMBptr->feuille; 3372 if (f.type!=_VECT || f._VECTptr->size()!=2) 3373 return 0; 3374 vecteur & w=*f._VECTptr; 3375 int ca,ra,cb,rb; 3376 if (!iscell(w[0],ca,ra,contextptr)) 3377 return 0; 3378 if (!iscell(w[1],cb,rb,contextptr)) 3379 return 0; 3380 if (ca>cb) giac::swapint(ca,cb); 3381 if (ra>rb) giac::swapint(ra,rb); 3382 if (ra!=r1 || rb+1!=r2) 3383 return 0; 3384 for (int c=ca;c<=cb;++c){ 3385 tselect.push_back(mt[c]); 3386 vc.push_back(c); 3387 } 3388 } 3389 if (h.type!=_IDNT) 3390 continue; 3391 absolu=true; 3392 const string & ss=h._IDNTptr->name(); 3393 int sss=ss.size(); 3394 if (sss<1) 3395 return 0; 3396 int c; 3397 alphaposcell(ss,c); 3398 if (c>=0 && c<mts){ 3399 tselect.push_back(mt[c]); 3400 vc.push_back(c); 3401 } 3402 } 3403 mselect=mtran(tselect); 3404 mselect=vecteur(mselect.begin()+r1,mselect.begin()+r2); 3405 return vc.size(); 3406 } 3407 iscell_range(const gen & g,const matrice & m,matrice & mselect,Flv_Table_Gen * sptr)3408 bool iscell_range(const gen & g,const matrice & m,matrice & mselect,Flv_Table_Gen * sptr){ 3409 int r1,r2; 3410 vector<int> vc; 3411 bool absolu; 3412 return iscell_range(g,m,mselect,sptr,r1,r2,vc,absolu); 3413 } 3414 handle(int event)3415 int Tableur_Group::handle(int event){ 3416 if (table && event==FL_UNFOCUS){ 3417 if (Fl::event_x()<x() || Fl::event_x()>x()+w() || Fl::event_y()<y() || Fl::event_y()>y()+h()){ 3418 // cerr << "unfocus " << '\n'; 3419 table->editing=false; 3420 } 3421 } 3422 return Fl_Tile::handle(event); 3423 } 3424 Tableur_Group(int X,int Y,int W,int H,int L,int disp)3425 Tableur_Group::Tableur_Group(int X,int Y,int W,int H,int L,int disp):Fl_Tile(X,Y,W,H),disposition(disp),dtable(0),dgraph(0),dparam(0){ 3426 labelsize(L); 3427 int l=L+6,inputh=L+18; 3428 borderbox = new Fl_Box(X,Y,w()-labelsize(),h()-labelsize()); 3429 resizable(borderbox); 3430 end(); 3431 box(FL_FLAT_BOX); 3432 matrice m(Flv_Table_Gen::def_rows,vecteur(Flv_Table_Gen::def_cols,0)); 3433 Fl_Group::current(this); 3434 table=new Flv_Table_Gen(X,Y,W,H,m,"Spreadsheet"); 3435 Fl_Group::current(this); 3436 if (!table->graph){ 3437 table->graph = new Graph2d(X,Y+l,W,H-inputh,""); 3438 table->graph->ylegende=1.5; 3439 } 3440 if (!table->input){ 3441 Fl_Text_Buffer * ptr=new Fl_Text_Buffer; 3442 table->input = new Xcas_Text_Editor(X,Y,W,inputh,ptr); 3443 table->input->scrollbar_width(12); 3444 table->input->buffer()->add_modify_callback(style_update, table->input); 3445 // table->input = new Multiline_Input_tab(X,Y,W,l); 3446 table->input->tableur=table; 3447 table->input->textsize(labelsize()); 3448 table->input->callback(cb_Sheet_Input); 3449 table->input->tooltip(gettext("Spreadsheet commandline")); 3450 table->input->when(FL_WHEN_ENTER_KEY); 3451 } 3452 if (!table->_goto && table->input){ 3453 table->_goto = new Multiline_Input_tab(X,Y,W,inputh); 3454 table->_goto->callback(cb_Spread_goto); 3455 table->_goto->textsize(labelsize()); 3456 table->_goto->tooltip(gettext("Selection area")); 3457 table->_goto->when(FL_WHEN_ENTER_KEY|FL_WHEN_NOT_CHANGED); 3458 } 3459 // Attach input just after the sheet 3460 menubar = new Fl_Menu_Bar(X,Y,4*l,l); 3461 /* int s= Tableur_menu->size(); 3462 Fl_Menu_Item * menuitem = new Fl_Menu_Item[s]; 3463 for (int i=0;i<s;++i) 3464 *(menuitem+i)=*(Tableur_menu+i); 3465 menubar->menu (menuitem); 3466 */ 3467 menubar->menu(Tableur_menu); 3468 int n=find(table)+1; 3469 insert(*table->graph,n); 3470 insert(*table->graph->mouse_param_group,n); 3471 insert(*table->input,n); 3472 insert(*table->_goto,n); 3473 insert(*menubar,n); 3474 // Add buttons here 3475 int bx=menubar->x()+menubar->w(),bs=w()-menubar->w(),by=Y,bw=3*l; 3476 if (bs<4*bw) 3477 bw=bs/4; 3478 reevalsave = new Fl_Group(bx,by,bs,H); 3479 Fl_Button * reeval=new Fl_Button(bx,by,bw,H,"eval"); 3480 reeval->callback(cb_Tableur_Eval_Sheet); 3481 reeval->tooltip(gettext("Reeval current sheet")); 3482 bx += bw ; bs -= bw ; 3483 Fl_Button * seevalue=new Fl_Button(bx,by,bw,H,"val"); 3484 seevalue->callback(cb_Tableur_Value); 3485 seevalue->tooltip(gettext("See value instead of formula")); 3486 bx += bw; bs -= bw; 3487 Fl_Button * reinit=new Fl_Button(bx,by,bw,H,"init"); 3488 reinit->callback(cb_Tableur_Init); 3489 reinit->tooltip(gettext("Initialize the sheet using init formula")); 3490 bx += bw; bs -= bw; 3491 Fl_Button * viewgraph2d=new Fl_Button(bx,by,bw,H,"2-d"); 3492 viewgraph2d->callback(cb_Tableur_Graph2d); 3493 viewgraph2d->tooltip(gettext("View attached graph 2-d")); 3494 bx += bw; bs -= bw; 3495 Fl_Button * viewgraph3d=new Fl_Button(bx,by,bw,H,"3-d"); 3496 viewgraph3d->callback(cb_Tableur_Graph3d); 3497 viewgraph3d->tooltip(gettext("View attached graph 3-d")); 3498 bx += bw; bs -= bw; 3499 // Fill the remainder with an output (filename) 3500 fname =new Fl_Button(bx,by,bs,H); 3501 fname->label(gettext("<Save sheet as text>")); 3502 fname->callback(cb_Tableur_Save); 3503 fname->tooltip(gettext("Save spreadsheet independently of session")); 3504 fname->hide(); 3505 reevalsave->end(); 3506 insert(*reevalsave,n); 3507 change_group_fontsize(this,L); 3508 Fl_Group::current(0); 3509 table->win2=new Fl_Window(X,Y,2*W/3,2*H/3); 3510 if (!table->graph2d){ 3511 table->graph2d = new Graph2d(X,Y,2*W/3,2*H/3,""); 3512 table->graph2d->ylegende=1.5; 3513 } 3514 table->win2->end(); 3515 table->win2->resizable(table->win2); 3516 table->win2->hide(); 3517 table->win3=0; 3518 resize2(); 3519 // handle(FL_FOCUS); 3520 } 3521 save_dparam()3522 void Tableur_Group::save_dparam(){ 3523 if (disposition & 0x1){ 3524 dtable=table->w(); 3525 dgraph=table->graph->w(); 3526 dparam=table->graph->mouse_param_group->w(); 3527 } 3528 else { 3529 dtable=double(table->h())/h(); 3530 dgraph=((1-dtable)*table->graph->w())/table->w(); 3531 dparam=max(1-dtable-dgraph,0.05); 3532 } 3533 } 3534 resize2(double dt,double dg,double dp)3535 void Tableur_Group::resize2(double dt,double dg,double dp){ 3536 if (dt>0 && dg>0 && dp>0){ 3537 dtable=dt; 3538 dgraph=dg; 3539 dparam=dp; 3540 } 3541 if (dtable<=0 || dgraph<=0 || dparam<=0 ){ 3542 dtable=0.56; 3543 dgraph=0.37; 3544 dparam=0.07; 3545 } 3546 double total=dtable+dgraph+dparam; 3547 dtable/=total; 3548 dgraph/=total; 3549 dparam/=total; 3550 int X=x(),Y=y(),W=w(),H=h(); 3551 int L=labelsize(); 3552 int l=L+6,inputh=L+18; 3553 menubar->resize(X,Y,W/3,l); 3554 reevalsave->resize(X+W/3,Y,2*W/3,l); 3555 if (disposition/2){ 3556 if (disposition %2){ // table || graph 3557 int itable=int(W*dtable+.5); 3558 int igraph=int(W*dgraph+.5); 3559 table->_goto->resize(X,Y+l,itable/3,inputh); 3560 table->input->resize(X+itable/3,Y+l,itable-itable/3,inputh); 3561 int itg=itable+igraph; 3562 table->resize(X,Y+l+inputh,itable,H-l-inputh); 3563 if (table->mb) 3564 table->mb->resize(X,Y+l+inputh,itable,H-l-inputh); 3565 table->graph->resize(X+itable,Y+l,igraph,H-l); 3566 /* 3567 table->graph->mouse_param_group->resize(X+itg,Y+l,W-itg,H-l); 3568 int hh=(H-l); 3569 if (hh>8*labelsize()) 3570 hh=8*labelsize(); 3571 table->graph->mouse_position->resize(X+itg,Y+l,W-itg,hh/4); 3572 table->graph->button_group->resize(X+itg,Y+l+hh/4,W-itg,hh/2); 3573 */ 3574 table->graph->resize_mouse_param_group(W-itg); 3575 } 3576 else { // graph below 3577 table->_goto->resize(X,Y+l,W/4,inputh); 3578 table->input->resize(X+W/4,Y+l,3*W/4,inputh); 3579 int itable=int(H*dtable+.5); 3580 int igraph=int(W*dgraph/(dgraph+dparam)+.5); 3581 table->resize(X,Y+l+inputh,W,itable); 3582 if (table->mb) 3583 table->mb->resize(X,Y+l+inputh,W,itable); 3584 table->graph->resize(X,Y+l+inputh+itable,igraph,H-itable-l-inputh); 3585 /* 3586 int hh=H-itable-2*l; 3587 if (hh>8*labelsize()) 3588 hh=8*labelsize(); 3589 int Y1=Y+2*l+itable; 3590 table->graph->mouse_param_group->resize(X+igraph,Y1,W-igraph,hh); 3591 int dh=hh/4; 3592 table->graph->mouse_position->resize(X+igraph,Y1,W-igraph,dh); 3593 table->graph->button_group->resize(X+igraph,Y1+dh,W-igraph,hh/2); 3594 dh += hh/2; 3595 */ 3596 table->graph->resize_mouse_param_group(W-igraph); 3597 } 3598 table->graph->show(); 3599 table->graph->mouse_param_group->show(); 3600 } 3601 else { 3602 table->resize(X,Y+l+inputh,W,H-l-inputh); 3603 if (table->mb) 3604 table->mb->resize(X,Y+l+inputh,W,H-(l+inputh)); 3605 table->_goto->resize(X,Y+l,W/4,inputh); 3606 table->input->resize(X+W/4,Y+l,3*W/4,inputh); 3607 table->graph->resize(X,Y+H,5*W/6,0); 3608 table->graph->mouse_param_group->resize(X+5*W/6,Y+H,W/6,0); 3609 table->graph->hide(); 3610 table->graph->mouse_param_group->hide(); 3611 } 3612 redraw(); 3613 init_sizes(); 3614 } 3615 Xcas_fltk_Row(const gen & g,GIAC_CONTEXT)3616 gen Xcas_fltk_Row(const gen & g,GIAC_CONTEXT){ 3617 Flv_Table_Gen * tptr=(Flv_Table_Gen * )evaled_table(contextptr); 3618 if (tptr) 3619 return tptr->row(); 3620 return -1; 3621 } 3622 Xcas_fltk_current_sheet(const gen & g,GIAC_CONTEXT)3623 gen Xcas_fltk_current_sheet(const gen & g,GIAC_CONTEXT){ 3624 Flv_Table_Gen * tptr=(Flv_Table_Gen * )evaled_table(contextptr); 3625 if (tptr){ 3626 const giac::context * contextptr = get_context((tptr)); 3627 int r,c; 3628 if (iscell(g,c,r,contextptr)){ 3629 if (r>=tptr->rows()||c>=tptr->cols()) 3630 return undef; 3631 gen tmp=tptr->m[r]; 3632 tmp=tmp[c]; 3633 return tmp[1]; 3634 } 3635 if (g.type==_VECT && g._VECTptr->size()==2 && g._VECTptr->front().type==_INT_ && g._VECTptr->back().type==_INT_) 3636 return gen(extractmatricefromsheet(tptr->m),_MATRIX__VECT)[g]; 3637 if (iscell_range(g,tptr->m,tptr->selected,tptr) ){ 3638 return extractmatricefromsheet(tptr->selected); 3639 } 3640 return gen(extractmatricefromsheet(tptr->m),_MATRIX__VECT)[g]; 3641 } 3642 return 0; 3643 } 3644 Xcas_fltk_Col(const gen & g,GIAC_CONTEXT)3645 gen Xcas_fltk_Col(const gen & g,GIAC_CONTEXT){ 3646 Flv_Table_Gen * tptr=(Flv_Table_Gen * )evaled_table(contextptr); 3647 if (tptr) 3648 return tptr->col(); 3649 return -1; 3650 } 3651 3652 #ifndef NO_NAMESPACE_XCAS 3653 } // namespace xcas 3654 #endif // ndef NO_NAMESPACE_XCAS 3655 3656 #endif // HAVE_LIBFLTK 3657