/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt
******************************************************************************/
package com.opendoorlogistics.studio;
import java.io.File;
import java.util.HashMap;
import java.util.concurrent.Callable;
import java.util.logging.Logger;
import com.opendoorlogistics.api.ExecutionReport;
import com.opendoorlogistics.api.app.ODLAppLoadedState;
import com.opendoorlogistics.api.components.ProcessingApi;
import com.opendoorlogistics.api.tables.DatastoreManagerPlugin;
import com.opendoorlogistics.api.tables.DatastoreManagerPlugin.DatastoreManagerPluginState;
import com.opendoorlogistics.api.tables.ODLDatastore;
import com.opendoorlogistics.api.tables.ODLDatastoreUndoable;
import com.opendoorlogistics.api.tables.ODLListener;
import com.opendoorlogistics.api.tables.ODLTable;
import com.opendoorlogistics.api.tables.ODLTableAlterable;
import com.opendoorlogistics.api.tables.ODLTableReadOnly;
import com.opendoorlogistics.api.tables.TableFlags;
import com.opendoorlogistics.api.ui.Disposable;
import com.opendoorlogistics.core.tables.DatastoreManagerGlobalPlugin;
import com.opendoorlogistics.core.tables.io.PoiIO;
import com.opendoorlogistics.core.tables.utils.TableFlagUtils;
import com.opendoorlogistics.core.tables.utils.TableUtils;
import com.opendoorlogistics.core.utils.LoggerUtils;
import com.opendoorlogistics.studio.appframe.AbstractAppFrame;
import com.opendoorlogistics.studio.scripts.execution.ScriptsRunner;
public class LoadedState extends GlobalMapSelectedRowsManager implements Disposable,ODLAppLoadedState {
private final static Logger LOGGER = Logger.getLogger(LoadedState.class.getName());
private final ODLDatastoreUndoable<? extends ODLTableAlterable> ds;
private final AbstractAppFrame appFrame;
private File lastFile;
private final ScriptsRunner runner;
private final HashMap<DatastoreManagerPlugin, DatastoreManagerPluginState> pluginStates = new HashMap<>();
public LoadedState(ODLDatastoreUndoable<? extends ODLTableAlterable> decoratedDs, File file, AbstractAppFrame appFrame) {
this.appFrame = appFrame;
this.ds = decoratedDs;
lastFile = file;
// create scripts runner - this has a thread-pool which exists for the lifetime of the open datastore
runner = new ScriptsRunner(appFrame,ds);
// add listeners which cause the app to update appearance when the data changes
ds.addListener(tableChangeListener, -1);
ds.addListener(tableSetChangeListener);
}
public void putPluginState(DatastoreManagerPlugin plugin,DatastoreManagerPluginState state){
pluginStates.put(plugin, state);
}
public ODLDatastoreUndoable<? extends ODLTableAlterable> getDs() {
return ds;
}
public void onSaved(File file) {
lastFile = file;
}
public boolean save(File file, boolean xlsx,ProcessingApi processing, ExecutionReport report) {
// filter if we have a datastore manager plugin
DatastoreManagerPlugin plugin = DatastoreManagerGlobalPlugin.getPlugin();
if(plugin!=null && ds!=null){
ODLDatastore<? extends ODLTableReadOnly> filtered = plugin.getDatastore2Save(appFrame.getApi(), this);
return PoiIO.exportDatastore(filtered, file, xlsx, processing,report);
}
return PoiIO.exportDatastore(ds, file, xlsx, processing,report);
}
public boolean runTransaction(Callable<Boolean> callable) {
return TableUtils.runTransaction(ds, callable);
}
/**
* This is called by a map selection list when the selection state changes.
* It modifies the selected flags in the rows in the global datastore as needed,
* and then notifies all selection listeners that the selection state has changed.
*/
@Override
public void onMapSelectedChanged() {
// update selection state in the ds for everything
long countSelected=0;
long countChanged=0;
for(int i = 0 ;i<ds.getTableCount() ; i++){
ODLTable table = ds.getTableAt(i);
int n = table.getRowCount();
for(int row=0;row<n;row++){
long id = table.getRowId(row);
boolean selected = isRowSelectedInMap(id);
if(selected){
countSelected++;
}
long flags = table.getRowFlags(id);
boolean selectedInDs = (flags & TableFlags.FLAG_ROW_SELECTED_IN_MAP)==TableFlags.FLAG_ROW_SELECTED_IN_MAP;
if(selectedInDs!=selected){
flags = TableFlagUtils.setFlag(flags, TableFlags.FLAG_ROW_SELECTED_IN_MAP, selected);
table.setRowFlags(flags, id);
countChanged++;
}
}
}
LOGGER.info(LoggerUtils.addPrefix(" - " + Long.toString(countSelected) + " obj(s) sel., " + Long.toString(countChanged) +" sel. state changes"));
fireListeners();
}
public ScriptsRunner getRunner(){
return runner;
}
private ODLListener tableChangeListener = new ODLListener() {
@Override
public void datastoreStructureChanged() {
// TODO Auto-generated method stub
}
@Override
public void tableChanged(int tableId, int firstRow, int lastRow) {
appFrame.updateAppearance();
}
@Override
public ODLListenerType getType() {
return ODLListenerType.TABLE_CHANGED;
}
};
private ODLListener tableSetChangeListener = new ODLListener() {
@Override
public void datastoreStructureChanged() {
appFrame.updateAppearance();
}
@Override
public void tableChanged(int tableId, int firstRow, int lastRow) {
// TODO Auto-generated method stub
}
@Override
public ODLListenerType getType() {
return ODLListenerType.DATASTORE_STRUCTURE_CHANGED;
}
};
@Override
public void dispose() {
runner.dispose();
getDs().removeListener(tableChangeListener);
getDs().removeListener(tableSetChangeListener);
}
public interface HasLoadedDatastore{
LoadedState getLoadedDatastore();
}
@Override
public File getFile() {
return lastFile;
}
@Override
public DatastoreManagerPluginState getDatastorePluginState(DatastoreManagerPlugin plugin) {
return pluginStates.get(plugin);
}
}