/* $Id: event.cc,v 1.7 1998/10/20 11:20:47 cthulhu Exp $ */ #include #include "cell.hh" #include "sheet.hh" #include "event.hh" #define max(a,b) a > b ? a : b #define min(a,b) a < b ? a : b /********************* Cell Events ********************/ CellSetEvent::CellSetEvent(Sheet *sht,Cell *act) { sheet=sht; cell_sav.loadvalue(*act); row=act->row; col=act->col; } void CellSetEvent::UndoEvent() { Cell *aux,swp; char command[512]; int code; aux=sheet->cellFind(col,row); if(aux->type==CODE_FORMULA) sheet->manipulateReferences(aux, REMOVE_REFERENCES); swp.loadvalue(*aux); aux->loadvalue(cell_sav); cell_sav.loadvalue(swp); if(aux->type==CODE_FORMULA) sheet->manipulateReferences(aux, INSERT_REFERENCES); aux->modified=TRUE; sheet->recalc(aux); sheet->display(aux); sprintf(command,"unhighlightActiveCell \n" "unhighlightCurrentRange [canvasFromSheet $activeSheet] \n" "unhighlightColSelection \n" "unhighlightRowSelection \n" "set activeCellCol %d \n" "set activeCellRow %d \n" "highlightActiveCell",col,row); sheet->RunScript(command); } void CellSetEvent::RedoEvent() { UndoEvent(); } /********** Col/Row Insert Events **********/ ColRowInsertEvent::ColRowInsertEvent(Sheet *sht,char cr_option, short cr_index,short cr_number) { col_or_row=cr_option; cr_ind=cr_index; cr_num=cr_number; sheet=sht; } void ColRowInsertEvent::UndoEvent() { char command[512]; sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "DeleteRowOrColumn $activeSheet %d %d %c 0\n" "highlightActiveCell", cr_ind,cr_num,col_or_row); sheet->RunScript(command); UndoGraph(); } void ColRowInsertEvent::RedoEvent() { char command[512]; if(col_or_row='c') sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "InsertRowOrColumn $activeSheet %d %d c 0\n" "redrawCanvas $activeSheet\n" "set cols_selected [list %d %d]\n" "highlightColSelection\n" "set currentRange \\\n" " [list %d 0 %d [expr [DefSheetHeight] - 1]]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", cr_ind,cr_num,cr_ind,cr_ind+cr_num-1,cr_ind,cr_ind+cr_num-1); else sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "InsertRowOrColumn $activeSheet %d %d r 0\n" "redrawCanvas $activeSheet\n" "set rows_selected [list %d %d]\n" "highlightRowSelection\n" "set currentRange \\\n" " [list 0 %d [expr [DefSheetWidth] - 1] %d]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", cr_ind,cr_num,cr_ind,cr_ind+cr_num-1,cr_ind,cr_ind+cr_num-1); sheet->RunScript(command); RedoGraph(); } void ColRowInsertEvent::RegisterGraphEvent(Event *ev) { Event *aux; if((event_it=event_l.AddHead(ev))==NULL) internal_error(); return; } void ColRowInsertEvent::UndoGraph() { Event *aux; Node *last; if(event_it==NULL) return; last=event_it; while((last!=NULL)&&(aux=event_l.GetNext(&last))!=NULL) aux->UndoEvent(); } void ColRowInsertEvent::RedoGraph() { Event *aux; Node *last; if(event_it==NULL) return; last=event_it; while((last!=NULL)&&(aux=event_l.GetNext(&last))!=NULL) aux->RedoEvent(); } /********** Col/Row Delete Events **********/ ColRowDeleteEvent::ColRowDeleteEvent(Sheet *sht,char cr_option, short cr_index,short cr_number) { char command[512]; int i,j; Cell *aux; event_it=NULL; col_or_row=cr_option; cr_ind=cr_index; cr_num=cr_number; sheet=sht; if(col_or_row=='c') { for(j=cr_ind;j<=cr_ind+cr_num-1;j++) for(i=0;i<=sheet->max_row_used;i++) { aux=sheet->cellFind(j,i); lastcells+=*aux; } } else { for(j=0;j<=sheet->max_col_used;j++) for(i=cr_ind;i<=cr_ind+cr_num-1;i++) { aux=sheet->cellFind(j,i); lastcells+=*aux; } } } void ColRowDeleteEvent::UndoEvent() { char command[512]; int i,j,k; Cell *aux; sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "InsertRowOrColumn $activeSheet %d %d %c 0", cr_ind,cr_num,col_or_row); sheet->RunScript(command); if(col_or_row=='c') { for(j=cr_ind;j<=cr_ind+cr_num-1;j++) for(i=0;i<=sheet->max_row_used;i++) { aux=sheet->cellFind(j,i); *aux=lastcells[(j-cr_ind)*(sheet->max_row_used+1)+i]; } } else { for(j=0;j<=sheet->max_col_used;j++) for(i=cr_ind;i<=cr_ind+cr_num-1;i++) { aux=sheet->cellFind(j,i); // *aux=lastcells[j*(cr_ind+cr_num)+i-cr_ind]; *aux=lastcells[j*cr_num+i-cr_ind]; } } UndoGraph(); if(col_or_row=='c') sprintf(command, "redrawCanvas $activeSheet\n" "set cols_selected [list %d %d]\n" "highlightColSelection\n" "set currentRange \\\n" " [list %d 0 %d [expr [DefSheetHeight] - 1]]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", cr_ind,cr_ind+cr_num-1,cr_ind,cr_ind+cr_num-1); else sprintf(command, "redrawCanvas $activeSheet\n" "set rows_selected [list %d %d]\n" "highlightRowSelection\n" "set currentRange \\\n" " [list 0 %d [expr [DefSheetWidth] - 1] %d]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", cr_ind,cr_ind+cr_num-1,cr_ind,cr_ind+cr_num-1); sheet->RunScript(command); } void ColRowDeleteEvent::RedoEvent() { char command[512]; sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "DeleteRowOrColumn $activeSheet %d %d %c 0\n" "highlightActiveCell", cr_ind,cr_num,col_or_row); sheet->RunScript(command); RedoGraph(); } void ColRowDeleteEvent::RegisterGraphEvent(Event *ev) { Event *aux; if((event_it=event_l.AddHead(ev))==NULL) internal_error(); return; } void ColRowDeleteEvent::UndoGraph() { Event *aux; Node *last; if(event_it==NULL) return; last=event_it; while((last!=NULL)&&(aux=event_l.GetNext(&last))!=NULL) aux->UndoEvent(); } void ColRowDeleteEvent::RedoGraph() { Event *aux; Node *last; if(event_it==NULL) return; last=event_it; while((last!=NULL)&&(aux=event_l.GetNext(&last))!=NULL) aux->RedoEvent(); } /******************** Range Events ********************/ RangeEvent::RangeEvent(Sheet *sht,short x1,short y1,short x2,short y2) { Range rg; Ref rf; Cell *cell,*aux; x_start=x1; x_end=x2; y_start=y1; y_end=y2; sheet=sht; if(x_end==-1 || ((x_start==x_end) && (y_start==y_end))) { aux=sheet->cellFind(x_start,y_start); cell_sav=new Cell; *cell_sav=*aux; } else { rg.start.col=x1; rg.start.row=y1; rg.end.col=x2; rg.end.row=y2; Range_iter rang(rg); for(rang.first(rf);!rang.last();rang.next(rf)) { cell=new Cell; aux=sheet->cellFind(rf.col,rf.row); *cell=*aux; cells_sav+=cell; } } } RangeEvent::~RangeEvent() { int i; if(x_start!=-1) for(i=0;i to_calc,new_savs; int i; char command[512]; if(x_end==-1 || ((x_start==x_end) && (y_start==y_end))) { new_sav=new Cell; *new_sav=*cell_sav; aux=sheet->cellFind(x_start,y_start); *cell_sav=*aux; if(aux->type==CODE_FORMULA) sheet->manipulateReferences(aux,REMOVE_REFERENCES); *aux=*new_sav; if(aux->type==CODE_FORMULA) sheet->manipulateReferences(aux,INSERT_REFERENCES); delete new_sav; aux->modified=TRUE; sheet->recalc(aux); sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set activeCellCol %d\n" "set activeCellRow %d\n" "highlightActiveCell",x_start,y_start); } else { for(i=0;icellFind(rf.col,rf.row); *(cells_sav[i])=*aux; if(aux->type==CODE_FORMULA) sheet->manipulateReferences(aux,REMOVE_REFERENCES); *aux=*(new_savs[i]); if(aux->type==CODE_FORMULA) sheet->manipulateReferences(aux,INSERT_REFERENCES); aux->modified=TRUE; to_calc+=aux; } sheet->recalc(to_calc); for(i=0;iRunScript(command); } void RangeEvent::RedoEvent() { UndoEvent(); } short RangeEvent::GetXStart() { return(x_start); } short RangeEvent::GetYStart() { return(y_start); } short RangeEvent::GetXEnd() { return(x_end); } short RangeEvent::GetYEnd() { return(y_end); } Sheet *RangeEvent::GetSheet() { return(sheet); } RangeMoveEvent::RangeMoveEvent(RangeEvent *rng1,RangeEvent *rng2) { from=rng1; to=rng2; } RangeMoveEvent::~RangeMoveEvent() { delete from; delete to; } void RangeMoveEvent::UndoEvent() { char command[512]; from->UndoEvent(); to->UndoEvent(); sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set currentRange [list %d %d %d %d]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", from->GetXStart(),from->GetYStart(), from->GetXEnd(),from->GetYEnd()); (to->GetSheet())->RunScript(command); } void RangeMoveEvent::RedoEvent() { char command[512]; from->UndoEvent(); to->UndoEvent(); sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set currentRange [list %d %d %d %d]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", to->GetXStart(),to->GetYStart(), to->GetXEnd(),to->GetYEnd()); (to->GetSheet())->RunScript(command); } /******************* Format Events ********************/ SetFormatEvent::SetFormatEvent(Sheet *sht,short scol,short srow, short ecol,short erow) { Cell *aux; Format tmp; sheet=sht; if(srow==-1) // columns { startcol=min(scol,ecol); startrow=srow; endcol=max(scol,ecol); endrow=erow; for(int j=startcol;j<=endcol;j++) for(int i=0;i<=sheet->max_row_used;i++) if(aux=sheet->cellExists(j,i)) { tmp=aux->format; if(aux->format.borders.top==7) tmp.borders.top=0; if(aux->format.borders.bottom==7) tmp.borders.bottom=0; if(aux->format.borders.left==7) tmp.borders.left=0; if(aux->format.borders.right==7) tmp.borders.right=0; lastformats+=tmp; } } else if(scol==-1) // rows { startcol=scol; startrow=min(srow,erow); endcol=ecol; endrow=max(srow,erow); for(int i=startrow;i<=endrow;i++) for(int j=0;j<=sheet->max_col_used;j++) if(aux=sheet->cellExists(j,i)) { tmp=aux->format; if(aux->format.borders.top==7) tmp.borders.top=0; if(aux->format.borders.bottom==7) tmp.borders.bottom=0; if(aux->format.borders.left==7) tmp.borders.left=0; if(aux->format.borders.right==7) tmp.borders.right=0; lastformats+=tmp; } } else if((erow==-1)&&(ecol==-1)) // cell - && is not necessary { startcol=scol; startrow=srow; endcol=ecol; endrow=erow; if(aux=sheet->cellExists(scol,srow)) { lastformat=aux->format; if(aux->format.borders.top==7) lastformat.borders.top=0; if(aux->format.borders.bottom==7) lastformat.borders.bottom=0; if(aux->format.borders.left==7) lastformat.borders.left=0; if(aux->format.borders.right==7) lastformat.borders.right=0; } } else // range { startcol=scol; startrow=srow; endcol=ecol; endrow=erow; for(int i=startrow;i<=endrow;i++) for(int j=startcol;j<=endcol;j++) if((aux=sheet->cellFind(j,i))!=NULL) { tmp=aux->format; if(aux->format.borders.top==7) tmp.borders.top=0; if(aux->format.borders.bottom==7) tmp.borders.bottom=0; if(aux->format.borders.left==7) tmp.borders.left=0; if(aux->format.borders.right==7) tmp.borders.right=0; lastformats+=tmp; } else internal_error(); } } void SetFormatEvent::UndoEvent() { Cell *aux; char command[512]; Format swp; int num=0; if(startrow==-1) { for(int j=startcol;j<=endcol;j++) for(int i=0;i<=sheet->max_row_used;i++) if(aux=sheet->cellExists(j,i)) { aux=sheet->cellFind(j,i); swp=aux->format; aux->format=lastformats[num]; lastformats[num]=swp; sheet->display(aux); num++; } sprintf(command,"unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set cols_selected [list %d %d]\n" "highlightColSelection\n" "set currentRange \\\n" " [list %d 0 %d [expr [DefSheetHeight] - 1]]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", startcol,endcol,startcol,endcol); } else if(startcol==-1) { for(int i=startrow;i<=endrow;i++) for(int j=0;j<=sheet->max_col_used;j++) if(aux=sheet->cellExists(j,i)) { aux=sheet->cellFind(j,i); swp=aux->format; aux->format=lastformats[num]; lastformats[num]=swp; sheet->display(aux); num++; } sprintf(command,"unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set rows_selected [list %d %d]\n" "highlightRowSelection\n" "set currentRange \\n" " [list 0 %d [expr [DefSheetWidth] - 1] %d]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", startrow,endrow,startrow,endrow); } else if((endrow==-1)&&(endcol==-1)) // cell - && is not necessary { if(aux=sheet->cellExists(startcol,startrow)) { swp=aux->format; aux->format=lastformat; lastformat=swp; sheet->display(aux); sprintf(command, "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set activeCellCol %d\n" "set activeCellRow %d\n" "highlightActiveCell",startcol,startrow); } } else { for(int i=startrow;i<=endrow;i++) for(int j=startcol;j<=endcol;j++) if((aux=sheet->cellFind(j,i))!=NULL) { aux=sheet->cellFind(j,i); swp=aux->format; aux->format= lastformats[(i-startrow)*(endcol-startcol+1)+(j-startcol)]; lastformats[(i-startrow)*(endcol-startcol+1)+(j-startcol)]=swp; sheet->display(aux); } else internal_error(); sprintf(command,"unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet]\n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set currentRange [list %d %d %d %d]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", startcol,startrow,endcol,endrow); } sheet->RunScript(command); } void SetFormatEvent::RedoEvent() { UndoEvent(); } /***************** Geometry Events ********************/ SetColWidthEvent::SetColWidthEvent(Sheet *sht,short column) { sheet=sht; col=column; width=sheet->cell_width(col); } void SetColWidthEvent::UndoEvent() { Cell *cell; int prev_width; int i; char command[256]; prev_width=sheet->cell_width(col); sheet->set_col_width(col,width); for (i=0; icols[col].cells.cnt ; i++) { cell = sheet->cols[col].cells[i]; if (cell->wid+2*INTERNAL_CELL_BORDER > prev_width || cell->wid+2*INTERNAL_CELL_BORDER > width) sheet->display(cell); } width=prev_width; sprintf(command,"[canvasFromSheet $activeSheet] yview scroll 1 units\n" "[canvasFromSheet $activeSheet] yview scroll -1 units"); sheet->RunScript(command); } void SetColWidthEvent::RedoEvent() { UndoEvent(); } SetRowHeightEvent::SetRowHeightEvent(Sheet *sht,short row_name) { sheet=sht; row=row_name; height=sheet->cell_height(row); } void SetRowHeightEvent::UndoEvent() { Cell *cell; int prev_height; char command[512]; prev_height=sheet->cell_height(row); sheet->set_row_height(row,height); height=prev_height; sprintf(command,"[canvasFromSheet $activeSheet] yview scroll 1 units\n" "[canvasFromSheet $activeSheet] yview scroll -1 units"); sheet->RunScript(command); } void SetRowHeightEvent::RedoEvent() { UndoEvent(); } /***************** Graphics Events ********************/ SetGraphEvent::SetGraphEvent(Sheet *sht,Graph grph) { gr=new Graph; *gr=grph; sheet=sht; } void SetGraphEvent::UndoEvent() { char command[512]; sprintf(command,"doDeleteGraph %d\n" "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet] \n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set currentRange [list %d %d %d %d]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", gr->number, gr->range.start.col,gr->range.start.row, gr->range.end.col,gr->range.end.row); sheet->RunScript(command); } void SetGraphEvent::RedoEvent() { char command[512]; Graph *grph = new Graph; *grph=*gr; int i=grph->number; if (!sheet->graphs[i]) { sheet->graphs[i] = grph; } else { cout<< "Erro: event.cc tentei por um grafico numa posicao ja ocupada"<add_graph_deps(grph); sprintf(command,"doDrawGraph [GetGraphParams $activeSheet %d] %d ", grph->number,grph->number); sheet->RunScript(command); } SetGraphEvent::~SetGraphEvent() { delete gr; } /************* Delete Graphics Events *****************/ DelGraphEvent::DelGraphEvent(Sheet *sht,Graph grph) { gr=new Graph; *gr=grph; sheet=sht; } void DelGraphEvent::UndoEvent() { char command[512]; Graph *grph = new Graph; *grph=*gr; int i=grph->number; if (!sheet->graphs[i]) { sheet->graphs[i] = grph; } else { cout<< "Erro: event.cc tentei por um grafico numa posicao ja ocupada"<add_graph_deps(sheet->graphs[i]); sprintf(command,"doDrawGraph [GetGraphParams $activeSheet %d] %d ", grph->number,grph->number); sheet->RunScript(command); } void DelGraphEvent::RedoEvent() { char command[512]; sprintf(command,"doDeleteGraph %d\n" "unhighlightActiveCell\n" "unhighlightCurrentRange [canvasFromSheet $activeSheet] \n" "unhighlightColSelection\n" "unhighlightRowSelection\n" "set currentRange [list %d %d %d %d]\n" "highlightCurrentRange [canvasFromSheet $activeSheet]", gr->number, gr->range.start.col,gr->range.start.row, gr->range.end.col,gr->range.end.row); sheet->RunScript(command); } DelGraphEvent::~DelGraphEvent() { delete gr; } /************* Change Graphics Events *****************/ ChangeGraphEvent::ChangeGraphEvent(Sheet *sht,Graph grph) { gr=new Graph; *gr=grph; sheet=sht; } void ChangeGraphEvent::UndoEvent() { char command[512]; Graph *grph = new Graph; *grph=*gr; int i=grph->number; *gr=*(sheet->graphs[i]); sheet->remove_graph_deps(sheet->graphs[i]); *(sheet->graphs[i]) = *grph; sheet->add_graph_deps(sheet->graphs[i]); sprintf(command," [canvasFromSheet $activeSheet] delete graphrect\n" "[canvasFromSheet $activeSheet] delete graph_%d\n" "doDrawGraph [GetGraphParams $activeSheet %d] %d ", grph->number,grph->number,grph->number); delete grph; sheet->RunScript(command); } void ChangeGraphEvent::RedoEvent() { UndoEvent(); } ChangeGraphEvent::~ChangeGraphEvent() { delete gr; } /* $Log: event.cc,v $ * Revision 1.7 1998/10/20 11:20:47 cthulhu * Fixed RangeEvent destructor that was receiving parameters somehow - blame it on * copy & paste. * * Revision 1.6 1998/10/11 22:43:48 cthulhu * Fixed row deletion bug. * * Revision 1.5 1998/10/05 20:44:31 cthulhu * Fixed CellSet reference bug. * * Revision 1.4 1998/08/21 18:43:42 cthulhu * Range formats with empty cells weren't redoable correctly. Fixed by using * CellFind instead of CellExists inside Undo/Event for cycles. * * Revision 1.3 1998/08/21 18:09:50 cthulhu * Fixed SetFormat constructor bug * * Revision 1.2 1998/08/20 21:40:45 cthulhu * Format events now handle multiple columns and row changes instead of just a * single column or row * * Revision 1.1 1998/08/17 20:23:26 cthulhu * Initial revision * */