/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Copyright (C) 2011-2013 Marchand Eric <ricoh51@free.fr>
This file is part of Freegressi.
Freegressi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Freegressi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Freegressi. If not, see <http://www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package freegressi.tableur;
import freegressi.graphics.GraphicModel;
import freegressi.main.FreegressiEvent;
import freegressi.main.UndoRedo;
import freegressi.tableur.QuickSort.SortingDirection;
import freegressi.tableur.Sym.TypeVariable;
import freegressi.tableur.Tableur.Angle;
import freegressi.fit.FitModel;
import java.util.*;
import javax.swing.event.EventListenerList;
/**
* Singleton qui mantient la liste des tableurs, la feuille active, ainsi
* que les écouteurs
* @author marchand
*/
public class SpreadSheets{
private static SpreadSheets spreadSheets;
private List<Tableur> sheetList = new ArrayList<>();
private Tableur activeSheet = null;
private Angle angle = Angle.RADIAN;
private int CS = 3;
/** La liste des écouteurs des feuilles */
private EventListenerList sheetsListeners = new EventListenerList();
/** La correspondance entre les index de colonne dans le model et dans la vue */
private HashMap<Integer, Integer> map = new HashMap<>();
/**
* Constructeur privé pour singleton
*/
private SpreadSheets(){
}
public static SpreadSheets getInstance(){
if (spreadSheets == null) {
spreadSheets = new SpreadSheets();
}
return spreadSheets;
}
public int getCS() {
return CS;
}
public Angle getAngle() {
return angle;
}
public String getEditorString() {
return EditColumnsModel.getInstance().getEditorString();
}
public HashMap<Integer, Integer> getMap() {
return map;
}
public Tableur getActiveSheet() {
return activeSheet;
}
private void add(Tableur sheet){
sheetList.add(sheet);
// System.out.println(sheetList.size() + " Feuilles");
}
public void clear(){
sheetList.clear();
activeSheet = null;
}
public List<Tableur> getList(){
return sheetList;
}
public String toXML(String tab){
String tab2 = tab + "\t";
String tab3 = tab2 + "\t";
String str = tab+"<datas>\n";
str += tab2 + "<CS>" + CS + "</CS>\n";
str += tab2 + "<angle>" + angle + "</angle>\n";
str += tab2 + "<sheets>\n";
str += tab3 + "<sheets-number>" + sheetList.size() + "</sheets-number>\n";
for (Tableur sheet : sheetList){
str += tab3 + "<sheet-name>" + sheet.getName() + "</sheet-name>\n";
str += tab3 + "<sheet-description>" + sheet.getDescription() + "</sheet-description>\n";
}
str += tab2 + "</sheets>\n";
int index = -1;
for (Colonne column : activeSheet.getListeColonnes()) {
index++;
ColonneDescription cd = column.getColonneDescription();
if (cd.getType() == Sym.TypeVariable.VARIABLE_EXPERIMENTALE) {
str += tab2 + "<column>\n";
str += tab3 + "<column-name>" + cd.getNom() + "</column-name>\n";
str += tab3 + "<column-unit>" + cd.getUnite() + "</column-unit>\n";
//str += tab3 + "<column-type>" + cd.getType().getText() + "</column-type>\n";
String values;
Double dou;
for (Tableur sheet : sheetList){
Colonne col = sheet.donneColonne(index);
values = tab3 + "<sheet-values>";
for (int i = 0; i < col.size(); i++) {
dou = col.get(i);
if (dou == null) dou = Double.NaN;
values += dou + " ";
}
values += "</sheet-values>\n";
str += values;
}
str += tab2 + "</column>\n";
}
}
str += tab2 + "<columns-editor>" + activeSheet.toEditColumns()
+ "</columns-editor>\n";
str += tab+"</datas>\n";
return str;
}
/* **********************************************************************
*
* Changement de la feuille active
*
*********************************************************************** */
public class ActiveSheetChangedEvent extends EventObject {
private final Tableur oldActiveSheet;
private final boolean undoable;
private final Tableur newActiveSheet;
public ActiveSheetChangedEvent(Object source, Tableur oldActiveSheet,
Tableur newActiveSheet, boolean undoable) {
super(source);
this.oldActiveSheet = oldActiveSheet;
this.undoable = undoable;
this.newActiveSheet = newActiveSheet;
}
public String getTexte() {
return "Modifier la feuille active : ";
}
public boolean isUndoable() {
return undoable;
}
public Tableur getNewActiveSheet() {
return newActiveSheet;
}
public Tableur getOldActiveSheet() {
return oldActiveSheet;
}
}
private void setActiveSheet(Tableur newSheet) {
Tableur oldActiveSheet = activeSheet;
this.activeSheet = newSheet;
// if (newSheet != null){
// System.out.println("Feuille active = " + sheetList.indexOf(newSheet));
// } else {
// System.out.println("Feuille active = null");
// }
//System.out.println(sheetList.size() + " Feuille(s)");
fireActiveSheetChanged(oldActiveSheet, activeSheet, false);
}
private void setActiveSheet(int index) {
if (index > -1 && index < sheetList.size()){
Tableur sheet = sheetList.get(index);
setActiveSheet(sheet);
} else {
setActiveSheet(null);
}
//System.out.println("Ecouteurs du spreadsheets : " + sheetsListeners.getListenerCount());
}
public void notifyActiveSheetChanged(int index){
setActiveSheet(index);
}
private void fireActiveSheetChanged(Tableur oldSheet, Tableur newSheet,
boolean undoable) {
ActiveSheetChangedEvent event = new ActiveSheetChangedEvent(this,
oldSheet, newSheet, undoable);
SheetsListener[] listenerList = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.activeSheetChanged(event);
}
}
/* **********************************************************************
*
* Ajout d'une nouvelle feuille
*
*********************************************************************** */
public class SheetAddedEvent extends FreegressiEvent {
private final Tableur sheet;
public SheetAddedEvent(Object source, Tableur sheet, boolean undoable) {
super(source);
this.sheet = sheet;
this.undoable = undoable;
}
@Override
public boolean isUndoable() {
return undoable;
}
public Tableur getSheet() {
return sheet;
}
@Override
public String getText() {
return "Créer une feuille";
}
@Override
public void undo() {
notifySheetDeleted(sheet, false);
}
@Override
public void redo() {
notifySheetAdded(sheet, false);
}
}
private void fireSheetAdded(Tableur sheet, boolean undoable) {
SheetAddedEvent event = new SheetAddedEvent(this, sheet, undoable);
SheetsListener[] listenerList = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.sheetAdded(event);
}
}
/**
* Notifier l'ajout d'une nouvelle feuille
* @param sheet la nouvelle feuille
* @param undoable true si on peut annuler l'ajout false sinon
*/
public void notifySheetAdded(Tableur sheet, boolean undoable){
sheet.addTableurChangeListener(FitModel.getInstance());
sheet.addTableurChangeListener(GraphicModel.getInstance());
sheet.addTableurChangeListener(UndoRedo.getInstance());
add(sheet);
fireSheetAdded(sheet, undoable);
}
/**
* Notifier qu'on crée un nouveau document avec de nouvelles feuilles
* @param sheetList la liste des feuilles
*/
public void notifyNewDocument(List<Tableur> newSheetList, String editor,
int newCS){
map.clear();
Tableur sheet = newSheetList.get(0);
for (int i = 0; i < sheet.getColumnCount(); i++){
map.put(i, i);
}
for (int i = sheetList.size() - 1; i > -1; i--){
notifySheetDeleted(sheetList.get(i), false);
}
if (newSheetList != null){
for (Tableur sh : newSheetList){
notifySheetAdded(sh, false);
}
}
EditColumnsModel.getInstance().setEditorString(editor);
CS = newCS;
fireSheetsCSChanged(CS, newCS, true);
angle = sheet.getAngle();
fireSheetsAngleChanged(angle, sheet.getAngle(), true);
}
/* **********************************************************************
*
* Destruction d'une feuille
*
*********************************************************************** */
public class SheetDeletedEvent extends FreegressiEvent {
private final Tableur sheet;
public SheetDeletedEvent(Object source, Tableur sheet, boolean undoable) {
super(source);
this.sheet = sheet;
this.undoable = undoable;
}
@Override
public boolean isUndoable() {
return undoable;
}
public Tableur getSheet() {
return sheet;
}
@Override
public String getText() {
return "Supprimer une feuille";
}
@Override
public void undo() {
notifySheetAdded(sheet, false);
}
@Override
public void redo() {
notifySheetDeleted(sheet, false);
}
}
public void notifySheetDeleted(Tableur sheet, boolean undoable){
sheet.removeTableurChangeListener(FitModel.getInstance());
sheet.removeTableurChangeListener(GraphicModel.getInstance());
sheet.removeTableurChangeListener(UndoRedo.getInstance());
sheetList.remove(sheet);
fireSheetDeleted(sheet, undoable);
if (activeSheet!= null && activeSheet.equals(sheet)){
if (sheetList.isEmpty()){
setActiveSheet(null);
} else {
setActiveSheet(0);
}
}
}
private void fireSheetDeleted(Tableur sheet, boolean undoable) {
SheetDeletedEvent event = new SheetDeletedEvent(this, sheet, undoable);
SheetsListener[] listenerList = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.sheetDeleted(event);
}
}
/* **********************************************************************
*
* Changer la description d'une feuille
*
*********************************************************************** */
public class SheetDescriptionChangedEvent extends FreegressiEvent {
private final Tableur sheet;
private final String oldDescription, newDescription;
public SheetDescriptionChangedEvent(Object source, Tableur sheet, String oldDescription,
String newDescription, boolean undoable) {
super(source);
this.sheet = sheet;
this.oldDescription = oldDescription;
this.newDescription = newDescription;
this.undoable = undoable;
}
@Override
public boolean isUndoable() {
return undoable;
}
public Tableur getSheet() {
return sheet;
}
@Override
public String getText() {
return "Changer : " + oldDescription;
}
public String getNewDescription() {
return newDescription;
}
public String getOldDescription() {
return oldDescription;
}
@Override
public void undo() {
notifySheetDescriptionChanged(sheet, oldDescription, false);
}
@Override
public void redo() {
notifySheetDescriptionChanged(sheet, newDescription, false);
}
}
public void notifySheetDescriptionChanged(Tableur sheet, String newDescription, boolean undoable){
String oldDescription = sheet.getDescription();
sheet.setDescription(newDescription);
fireSheetDescriptionChanged(sheet, oldDescription, newDescription, undoable);
}
private void fireSheetDescriptionChanged(Tableur sheet, String oldDescription,
String newDescription, boolean undoable) {
SheetDescriptionChangedEvent event = new SheetDescriptionChangedEvent(this,
sheet,oldDescription, newDescription, undoable);
SheetsListener[] listenerList =
(SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.sheetDescriptionChanged(event);
}
}
/* **********************************************************************
*
* Changer la description d'une feuille
*
*********************************************************************** */
public class SheetsCSChangedEvent extends FreegressiEvent {
private final int oldCS, newCS;
public SheetsCSChangedEvent(Object source, int oldCS, int newCS,
boolean undoable) {
super(source);
this.newCS = newCS;
this.undoable = undoable;
this.oldCS = oldCS;
}
@Override
public boolean isUndoable() {
return undoable;
}
@Override
public String getText() {
return "Changer les chiffres significatifs : " + oldCS;
}
public int getNewCS() {
return newCS;
}
public int getOldCS() {
return oldCS;
}
@Override
public void undo() {
notifySheetsCSChanged(oldCS, false);
}
@Override
public void redo() {
notifySheetsCSChanged(newCS, false);
}
}
public void notifySheetsCSChanged(int newCS, boolean undoable){
int oldCS = CS;
CS = newCS;
fireSheetsCSChanged(oldCS, newCS, undoable);
}
private void fireSheetsCSChanged(int oldCS, int newCS, boolean undoable) {
SheetsCSChangedEvent event = new SheetsCSChangedEvent(this, oldCS, newCS,
undoable);
SheetsListener[] listenerList =
(SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.sheetsCSChanged(event);
}
}
/* **********************************************************************
*
* Renommer une feuille
*
*********************************************************************** */
public class SheetsRenamedEvent extends FreegressiEvent {
private final Tableur sheet;
private final String oldName, newName;
public SheetsRenamedEvent(Object source, Tableur sheet, String oldName,
String newName, boolean undoable) {
super(source);
this.sheet = sheet;
this.oldName = oldName;
this.newName = newName;
this.undoable = undoable;
}
@Override
public boolean isUndoable() {
return undoable;
}
public Tableur getSheet() {
return sheet;
}
@Override
public String getText() {
return "Renommer " + oldName;
}
@Override
public void undo() {
notifySheetRenamed(sheet, oldName, false);
}
@Override
public void redo() {
notifySheetRenamed(sheet, newName, false);
}
}
public void notifySheetRenamed(Tableur sheet, String newName, boolean undoable){
String oldName = sheet.getName();
sheet.setName(newName);
fireSheetRenamed(sheet, oldName, newName, undoable);
}
private void fireSheetRenamed(Tableur sheet, String oldName,
String newName, boolean undoable) {
SheetsRenamedEvent event = new SheetsRenamedEvent(this, sheet,oldName, newName, undoable);
SheetsListener[] listenerList = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.sheetRenamed(event);
}
}
/* **********************************************************************
*
* Ajout, destruction, changement, angle et tri de colonne
*
*********************************************************************** */
/* **********************************************************************
*
* Ajout d'une colonne
*
*********************************************************************** */
public class SheetsColumnAddedEvent extends FreegressiEvent {
/** Une colonne par feuille */
private List<Colonne> colonnes;
/** Position de la colonne */
private final int position;
public SheetsColumnAddedEvent(Object source, List<Colonne> colonnes, int position, boolean undoable){
super(source);
this.colonnes = colonnes;
this.position = position;
this.undoable = undoable;
}
public List<Colonne> getColonnes() {
return colonnes;
}
public int getPosition() {
return position;
}
@Override
public String getText() {
String name = colonnes.get(0).getColonneDescription().getNom();
return "Ajout colonne : " + name;
}
@Override
public void undo() {
for (int i = 0; i < sheetList.size(); i++){
String str = colonnes.get(i).getColonneDescription().getNom();
//sheetList.get(i).supprimeColonne(colonnes.get(i));
// retirer -1 pour la colonne des numéros
sheetList.get(i).supprimeColonne(position - 1);
}
List<List<Colonne>> columns = new ArrayList<>();
columns.add(colonnes);
int[] positions = new int[1];
positions[0] = position;
fireColumnsDeleted(columns, positions, false);
}
@Override
public void redo() {
for (int i = 0; i < sheetList.size(); i++){
sheetList.get(i).ajouteColonnePosition(colonnes.get(i), position);
}
fireColonneAdded(colonnes, position, false);
}
}
/**
* Une nouvelle colonne vient d'être ajoutée par l'utilisateur, si c'est une
* colonne expérimentale, elle est ajoutée après les précédentes colonnes
* expérimentales, sinon elle est ajoutée à la fin.
* @param type
* @param name
* @param unit
* @param expr
* @param position
*/
public void notifyColumnAdded(TypeVariable type, String name, String unit,
String expr){
List<Colonne> columns = new ArrayList<>();
int position;
if (type == Sym.TypeVariable.VARIABLE_EXPERIMENTALE){
// ajouter +1 pour la colonne des numéros
position = activeSheet.getNumberOfExperimentalColumns() + 1;
}else{
position = activeSheet.getColumnCount();
}
for (Tableur sheet : sheetList){
columns.add(sheet.notifyAjouteNouvelleColonne(type, name, unit, expr, position));
}
fireColonneAdded(columns, position, true);
}
/**
* Appelée par ce tableur pour informer les écouteurs qu'une colonne a été
* ajoutée
*/
private void fireColonneAdded(List<Colonne> colonnes, int position, boolean undoable) {
SheetsColumnAddedEvent event = new SheetsColumnAddedEvent(this, colonnes, position, undoable);
SheetsListener[] listenerListe = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerListe) {
listener.columnAdded(event);
}
}
/* **********************************************************************
*
* Suppression d'une ou plusieurs colonnes
*
*********************************************************************** */
public class SheetsColumnDeletedEvent extends FreegressiEvent {
/** Une colonne par feuille */
private List<List<Colonne>> colonnes;
/** Position de la colonne */
private final int[] positions;
public SheetsColumnDeletedEvent(Object source, List<List<Colonne>> colonnes, int[] positions, boolean undoable){
super(source);
this.colonnes = colonnes;
this.positions = positions;
this.undoable = undoable;
}
public List<List<Colonne>> getColonnes() {
return colonnes;
}
public int[] getPositions() {
return positions;
}
@Override
public String getText() {
//String name = colonnes.get(0).get(0).getColonneDescription().getNom();
return "Supprimer des colonnes : " ;
}
@Override
public void undo() {
List<Colonne> columns;
Tableur sheet;
int position;
Colonne colonne;
for (int i = 0; i < colonnes.size(); i++){ // pour chaque tableur
columns = colonnes.get(i); // liste des colonnes à supprimer
sheet = sheetList.get(i); // le tableur
for (int j = 0; j < columns.size(); j++){ // pour chaque colonne
//for (int j = columns.size() - 1; j > -1; j--){ // pour chaque colonne
position = positions[j]; // récupérer sa position
colonne = columns.get(j);
String str = colonne.getColonneDescription().getNom();
sheet.ajouteColonnePosition(colonne, position);
}
//
}
// Créer les liste de colonnes pour le fireColonneAdded
List<Colonne> columns2;
//columns = colonnes.get(0);
for (int i = 0; i < positions.length; i++){ // pour chaque colonne
position = positions[i]; // récupérer sa position
columns2 = new ArrayList<>();
for (int j = 0; j < colonnes.size(); j++){ // pour chaque tableur
columns = colonnes.get(j); // liste des colonnes à supprimer
colonne = columns.get(i); // récupérer la bonne
String str = colonne.getColonneDescription().getNom();
columns2.add(colonne);
}
fireColonneAdded(columns2, position, false);
}
//
}
@Override
public void redo() {
List<List<Colonne>> columnsList = new ArrayList<>();
List<Colonne> columns;
for (Tableur sheet : sheetList){
columns = sheet.notifyColumnsDeleted(positions);
columnsList.add(columns);
}
fireColumnsDeleted(columnsList, positions, false);
}
}
/**
* Une liste de colonnes vient d'être supprimée par l'utilisateur
* @param positions le tableau des positions des colonnes à supprimer
*/
public void notifyColumnsDeleted(int[] positions){
List<List<Colonne>> columnsList = new ArrayList<>();
List<Colonne> columns;
for (Tableur sheet : sheetList){
columns = sheet.notifyColumnsDeleted(positions);
columnsList.add(columns);
}
fireColumnsDeleted(columnsList, positions, true);
}
/**
*
*/
private void fireColumnsDeleted(List<List<Colonne>> colonnes, int[] position, boolean undoable) {
SheetsColumnDeletedEvent event = new SheetsColumnDeletedEvent(this, colonnes, position, undoable);
SheetsListener[] listenerListe = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerListe) {
listener.columnDeleted(event);
}
}
public class ColumnList{
ArrayList<Colonne> list;
}
/* **********************************************************************
*
* Changer l'unité d'angle
*
*********************************************************************** */
public class SheetsAngleChangedEvent extends FreegressiEvent {
private final Angle oldAngle, newAngle;
public SheetsAngleChangedEvent(Object source, Angle oldAngle,
Angle newAngle, boolean undoable) {
super(source);
this.oldAngle = oldAngle;
this.newAngle = newAngle;
this.undoable = undoable;
}
public Angle getNewAngle() {
return newAngle;
}
@Override
public boolean isUndoable() {
return undoable;
}
@Override
public String getText() {
return "Changer l'unité d'angle " + oldAngle;
}
@Override
public void undo() {
notifySheetsAngleChanged(oldAngle, false);
}
@Override
public void redo() {
notifySheetsAngleChanged(newAngle, false);
}
}
public void notifySheetsAngleChanged(Angle newAngle, boolean undoable){
Angle oldAngle = angle;
angle = newAngle;
for (Tableur sheet : sheetList){
sheet.notifyAngleChanged(newAngle);
}
fireSheetsAngleChanged(oldAngle, newAngle, undoable);
}
private void fireSheetsAngleChanged( Angle oldAngle, Angle newAngle, boolean undoable) {
SheetsAngleChangedEvent event = new SheetsAngleChangedEvent(this, oldAngle, newAngle, undoable);
SheetsListener[] listenerList = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.angleChanged(event);
}
}
/* **********************************************************************
*
* Modifier une colonne
*
*********************************************************************** */
public class SheetsColumnModifiedEvent extends FreegressiEvent {
private List<Colonne> columns;
private final String ancienExpression;
//private final Noeud ancienNoeud;
//private final Noeud newNoeud;
private final String ancienNom;
private final String ancienUnite;
private final String newNom;
private final String newUnite;
private final String newExpression;
public SheetsColumnModifiedEvent(Object source, List<Colonne> columns,
String ancienNom, String ancienUnite, String ancienExpression,
//Noeud ancienNoeud,
String newNom, String newUnite, String newExpression,
//Noeud newNoeud, /*String oldEditorString,*/
boolean undoable){
super(source);
this.columns = columns;
this.ancienExpression = ancienExpression;
//this.ancienNoeud = ancienNoeud;
//this.newNoeud = newNoeud;
this.undoable = undoable;
this.ancienNom = ancienNom;
this.ancienUnite = ancienUnite;
this.newNom = newNom;
this.newUnite = newUnite;
this.newExpression = newExpression;
}
public String getAncienExpression() {
return ancienExpression;
}
// public Noeud getAncienNoeud() {
// return ancienNoeud;
// }
public String getAncienNom() {
return ancienNom;
}
public String getAncienUnite() {
return ancienUnite;
}
public List<Colonne> getColumns() {
return columns;
}
public String getNewExpression() {
return newExpression;
}
// public Noeud getNewNoeud() {
// return newNoeud;
// }
public String getNewNom() {
return newNom;
}
public String getNewUnite() {
return newUnite;
}
@Override
public String getText() {
return "Modifier une colonne : " + ancienNom ;
}
@Override
public void undo() {
Tableur sheet;
Colonne column;
for (int i = 0; i < sheetList.size(); i++){
sheet = sheetList.get(i);
column = columns.get(i);
sheet.notifyModifierColonne(column, ancienNom, ancienUnite, ancienExpression/*, ancienNoeud*/);
}
fireSheetsColumnModified(columns, newNom, newUnite, newExpression, //newNoeud,
ancienNom, ancienUnite, ancienExpression, /*ancienNoeud,*/
/*oldEditorString,*/ false);
}
@Override
public void redo() {
Tableur sheet;
Colonne column;
for (int i = 0; i < sheetList.size(); i++){
sheet = sheetList.get(i);
column = columns.get(i);
sheet.notifyModifierColonne(column, newNom, newUnite, newExpression/*, newNoeud*/);
}
fireSheetsColumnModified(columns,
ancienNom, ancienUnite, ancienExpression, //ancienNoeud,
newNom, newUnite, newExpression, /*newNoeud,*/
/*oldEditorString,*/ false);
}
}
public void notifyColumnModified(Colonne col,
String name, String unit, String expr) {
List<Colonne> columns = new ArrayList<>();
String oldName = col.getColonneDescription().getNom();
String oldUnit = col.getColonneDescription().getUnite();
String oldExpr = col.getColonneDescription().getExpression();
// Modifier les colonnes de chaque tableur
for (Tableur sheet : sheetList){
Colonne column = sheet.donneColonne(oldName);
sheet.notifyModifierColonne(column, name, unit, expr);
columns.add(column);
}
fireSheetsColumnModified(columns, oldName, oldUnit, oldExpr,
name, unit, expr, true);
}
private void fireSheetsColumnModified(List<Colonne> columns,
String ancienNom, String ancienUnite, String ancienExpression,
String newNom, String newUnite, String newExpression,
boolean undoable) {
SheetsColumnModifiedEvent event = new SheetsColumnModifiedEvent(this, columns,
ancienNom, ancienUnite, ancienExpression,
newNom, newUnite, newExpression,
undoable);
SheetsListener[] listenerList = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.columnModified(event);
}
}
/* **********************************************************************
*
* Déplacement d'une colonne
*
*********************************************************************** */
public class SheetsColumnMovedEvent extends FreegressiEvent {
/** position de départ */
private int from;
/** Position d'arrivée */
private int to;
/** Le tableur où l'évenement s'est produit */
private Tableur sheet;
/** Le nom de la colonne bougée */
private String name;
/** Flag indiquant si la colonne a déjà été bougée par l'utilisateur */
private boolean moved;
public SheetsColumnMovedEvent(Object source, Tableur sheet, int from,
int to, String name, boolean moved, boolean undoable){
super(source);
this.name = name;
this.moved = moved;
this.undoable = undoable;
this.sheet = sheet;
this.from = from;
this.to = to;
}
public boolean isMoved() {
return moved;
}
public int getFrom() {
return from;
}
public String getName() {
return name;
}
public Tableur getSheet() {
return sheet;
}
public int getTo() {
return to;
}
@Override
public String getText() {
return "Déplacer la colonne " + name;
}
@Override
public void undo() {
fireSheetsColumnMoved(sheet, to, from, name, false, false);
}
@Override
public void redo() {
fireSheetsColumnMoved(sheet, from, to, name, false, false);
}
}
// private void moveColumn(Tableur sheet, int from, int to){
//
// }
/**
* Ne fonctionne pas encore, désactivé dans JTableColonnes
* @param sheet
* @param from
* @param to
* @param name
*/
public void notifySheetsColumnMoved(Tableur sheet, int from, int to, String name){
//String name = sheet.getColumnName(map.get(from));
// int temp = map.get(from);
// if (from > to){
// for (int i = from; i > to; i--){
// //value = map.get(i - 1);
// map.put(i, map.get(i - 1));
// }
//
// } else {
// for (int i = from; i < to; i++){
// //value = map.get(i + 1);
// map.put(i, map.get(i + 1));
// }
// }
// map.put(to, temp);
// System.out.println(map);
// Informer les autre JtableColonnes de déplacer la colonne
fireSheetsColumnMoved(sheet, from, to, name, true, true);
}
private void fireSheetsColumnMoved(Tableur sheet, int from,
int to, String name, boolean moved, boolean undoable) {
SheetsColumnMovedEvent event =
new SheetsColumnMovedEvent(this, sheet, from, to, name, moved, undoable);
SheetsListener[] listenerList =
(SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.columnMoved(event);
}
}
/* **********************************************************************
*
* Trier une colonne
*
*********************************************************************** */
public class SheetsColumnSortedEvent extends FreegressiEvent {
private final String name;
private final List<int[]> tabs;
public SheetsColumnSortedEvent(Object source, String name, List<int[]> tabs,
boolean undoable){
super(source);
this.undoable = undoable;
this.name = name;
this.tabs = tabs;
}
public String getName() {
return name;
}
public List<int[]> getTabs() {
return tabs;
}
@Override
public String getText() {
return "Trier la colonne " + name ;
}
@Override
public void undo() {
Tableur sheet;
int[] tab;
for (int i = 0; i < sheetList.size(); i++){
sheet = sheetList.get(i);
tab = tabs.get(i);
sheet.notifySortColumn(tab, false);
}
fireSheetsColumnSorted(name, tabs, false);
}
@Override
public void redo() {
Tableur sheet;
int[] tab;
for (int i = 0; i < sheetList.size(); i++){
sheet = sheetList.get(i);
tab = tabs.get(i);
sheet.notifySortColumn(tab, true);
}
fireSheetsColumnSorted(name, tabs, false);
}
}
public void notifySheetsSortColumn(String name, SortingDirection sd){
List<int[]> tabs = new ArrayList<>();
int[] tab;
for (Tableur sheet : sheetList){
Colonne column = sheet.donneColonne(name);
tab = QuickSort.sort(column, sd);
sheet.notifySortColumn(tab, true);
tabs.add(tab);
}
fireSheetsColumnSorted(name, tabs, true);
}
private void fireSheetsColumnSorted(String name, List<int[]> tabs, boolean undoable) {
SheetsColumnSortedEvent event = new SheetsColumnSortedEvent(this, name, tabs,undoable);
SheetsListener[] listenerList = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.columnSorted(event);
}
}
/* **********************************************************************
*
* Colonnes modifiées par édition
*
*********************************************************************** */
public class SheetsColumnsEditedEvent extends FreegressiEvent {
private final ArrayList<String> oldNames;
private final ArrayList<String> oldExpressions;
private final ArrayList<String> oldUnits;
private final ArrayList<String> newNames;
private final ArrayList<String> newExpressions;
private final ArrayList<String> newUnits;
private final String oldEditor;
private final String newEditor;
public SheetsColumnsEditedEvent(Object source, ArrayList<String> oldNames,
ArrayList<String> oldExpressions, ArrayList<String> oldUnits,
ArrayList<String> newNames,
ArrayList<String> newExpressions, ArrayList<String> newUnits,
String oldEditor, String newEditor,
boolean undoable){
super(source);
this.oldNames = new ArrayList<>(oldNames);
this.oldExpressions = new ArrayList<>(oldExpressions);
this.oldUnits = new ArrayList<>(oldUnits);
this.newUnits = new ArrayList<>(newUnits);
this.newEditor = newEditor;
this.undoable = undoable;
this.newNames = new ArrayList<>(newNames);
this.newExpressions = new ArrayList<>(newExpressions);
this.oldEditor = oldEditor;
//
// if (oldNames.equals(newNames)){
// System.out.println("!!!!!!!!");
// }
}
public String getNewEditor() {
return newEditor;
}
public String getOldEditor() {
return oldEditor;
}
public List<String> getNewExpressions() {
return newExpressions;
}
public List<String> getNewNames() {
return newNames;
}
public List<String> getNewUnits() {
return newUnits;
}
public ArrayList<String> getOldExpressions() {
return oldExpressions;
}
public ArrayList<String> getOldNames() {
return oldNames;
}
public ArrayList<String> getOldUnits() {
return oldUnits;
}
@Override
public String getText() {
return "Editer les colonnes";
}
@Override
public void undo() {
for(Tableur sheet : sheetList){
sheet.notifyModifierColonnesCalculees(oldNames, oldExpressions, oldUnits);
}
//EditColumnsModel.getInstance().setEditorString(oldEditor);
fireSheetsColumnsEdited(newNames, newExpressions, newUnits,
oldNames, oldExpressions, oldUnits,
newEditor, oldEditor, false);
}
@Override
public void redo() {
for(Tableur sheet : sheetList){
sheet.notifyModifierColonnesCalculees(newNames, newExpressions, newUnits);
}
//EditColumnsModel.getInstance().setEditorString(newEditor);
fireSheetsColumnsEdited(oldNames, oldExpressions, oldUnits,
newNames, newExpressions, newUnits,
oldEditor, newEditor, false);
}
}
public void notifySheetsColumnsEdited(ArrayList<String> newNames,
ArrayList<String> newExpressions, ArrayList<String> newUnits,
String oldEditor, String newEditor){
ArrayList<String> oldNames = activeSheet.getListCalculatedNames();
ArrayList<String> oldExpressions = activeSheet.getListCalculatedExpressions();
ArrayList<String> oldUnits = activeSheet.getListCalculatedUnits();
for(Tableur sheet : sheetList){
sheet.notifyModifierColonnesCalculees(newNames, newExpressions, newUnits);
}
//editorString = newEditor;
fireSheetsColumnsEdited(oldNames, oldExpressions, oldUnits,
newNames, newExpressions, newUnits, oldEditor, newEditor, true);
}
private void fireSheetsColumnsEdited(ArrayList<String> oldNames,
ArrayList<String> oldExpressions, ArrayList<String> oldUnits,
ArrayList<String> newNames,
ArrayList<String> newExpressions, ArrayList<String> newUnits,
String oldEditor, String newEditor,
boolean undoable) {
SheetsColumnsEditedEvent event = new SheetsColumnsEditedEvent(this,
oldNames, oldExpressions, oldUnits,
newNames, newExpressions, newUnits,
oldEditor, newEditor, undoable);
SheetsListener[] listenerList = (SheetsListener[]) sheetsListeners.getListeners(SheetsListener.class);
for (SheetsListener listener : listenerList) {
listener.columnsEdited(event);
}
}
/* **********************************************************************
*
* Gestion des écouteurs
*
*********************************************************************** */
public interface SheetsListener extends EventListener {
public void activeSheetChanged(ActiveSheetChangedEvent event);
public void sheetAdded(SheetAddedEvent event);
public void sheetDeleted(SheetDeletedEvent event);
public void sheetRenamed(SheetsRenamedEvent event);
public void columnAdded(SheetsColumnAddedEvent event);
public void columnDeleted(SheetsColumnDeletedEvent event);
public void angleChanged(SheetsAngleChangedEvent event);
public void columnModified(SheetsColumnModifiedEvent event);
public void columnMoved(SheetsColumnMovedEvent event);
public void columnSorted(SheetsColumnSortedEvent event);
public void columnsEdited(SheetsColumnsEditedEvent event);
public void sheetDescriptionChanged(SheetDescriptionChangedEvent event);
public void sheetsCSChanged(SheetsCSChangedEvent event);
}
/**
* Ajoute un écouteur à la liste
* @param listener l'écouteur à ajouter
*/
public final void addSheetsListener(SheetsListener listener) {
sheetsListeners.add(SheetsListener.class, listener);
}
/**
* Retire un écouteur de la liste
* @param listener l'écouteur à retirer
*/
public void removeSheetsListener(SheetsListener listener) {
sheetsListeners.remove(SheetsListener.class, listener);
}
}