OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Compare Revisions

Regard whitespace Rev 149 → Rev 150

/trunk/jOpenCalendar/src/org/jopencalendar/ui/MultipleDayView.java
522,23 → 522,24
 
}
 
public void setZoom(int zIndex) {
public final void setZoom(int zIndex) {
if (zIndex >= 0) {
int rh = 22 + zIndex * 22;
int rh = (1 + zIndex) * 22;
setRowHeight(rh);
}
}
 
this.rowHeight = rh;
// update size
final int w = this.getSize().width;
final int h = getPreferredSize().height;
setSize(new Dimension(w, h));
validate();
repaint();
public final int getZoom() {
return (this.rowHeight / 22) - 1;
}
 
private void zoom(int v) {
setRowHeight(this.rowHeight + v);
}
 
private void zoom(int v) {
if (rowHeight < 200 && rowHeight > 60) {
rowHeight += v;
public final void setRowHeight(final int v) {
if (this.rowHeight != v && v < 200 && v > 20) {
this.rowHeight = v;
// update size
final int w = this.getSize().width;
final int h = getPreferredSize().height;
545,10 → 546,13
setSize(new Dimension(w, h));
validate();
repaint();
this.firePropertyChange("rowHeight", null, v);
this.firePropertyChange("zoom", null, getZoom());
}
}
 
public int getRowHeight() {
// how many pixels for one hour
public final int getRowHeight() {
return this.rowHeight;
}
 
/trunk/jOpenCalendar/src/org/jopencalendar/ui/CalendarWithToolBar.java
29,9 → 29,10
import javax.swing.event.ChangeListener;
 
public class CalendarWithToolBar extends JPanel {
private WeekView weekView;
private JSpinner spinWeek;
private JSpinner spinYear;
private final WeekView weekView;
private final JSpinner spinWeek;
private final JSpinner spinYear;
private final DatePicker picker;
private String title;
final JScrollPane contentPane = new JScrollPane();
 
40,6 → 41,8
}
 
public CalendarWithToolBar(JCalendarItemProvider manager, boolean showPrintButton) {
this.weekView = new WeekView(manager);
 
JPanel toolbar = new JPanel();
toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));
 
76,21 → 79,11
spinYear = new JSpinner(new SpinnerNumberModel(year, 1000, year + 20, 1));
toolbar.add(spinYear);
//
final DatePicker picker = new DatePicker(false);
this.picker = new DatePicker(false);
toolbar.add(picker);
//
 
final JSlider zoomSlider = new JSlider(1, 9, 1);
zoomSlider.setSnapToTicks(true);
zoomSlider.setMajorTickSpacing(1);
zoomSlider.setPaintTicks(true);
zoomSlider.addChangeListener(new ChangeListener() {
 
@Override
public void stateChanged(ChangeEvent e) {
weekView.setZoom(zoomSlider.getValue());
}
});
final JSlider zoomSlider = createZoomSlider(this.weekView);
toolbar.add(new JLabel(" Zoom"));
toolbar.add(zoomSlider);
if (showPrintButton) {
133,7 → 126,6
 
contentPane.setBorder(BorderFactory.createEmptyBorder());
contentPane.setOpaque(false);
weekView = new WeekView(manager);
contentPane.setColumnHeaderView(new WeekViewHeader(weekView));
contentPane.setViewportView(weekView);
contentPane.getViewport().setBackground(Color.WHITE);
189,6 → 181,26
 
}
 
public static JSlider createZoomSlider(final MultipleDayView mdview) {
final JSlider zoomSlider = new JSlider(1, 9, 1);
zoomSlider.setSnapToTicks(true);
zoomSlider.setMajorTickSpacing(1);
zoomSlider.setPaintTicks(true);
zoomSlider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
mdview.setZoom(zoomSlider.getValue());
}
});
mdview.addPropertyChangeListener("zoom", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
zoomSlider.setValue(((Number) evt.getNewValue()).intValue());
}
});
return zoomSlider;
}
 
protected void addWeek(int i) {
Calendar c = getCurrentDate();
c.add(Calendar.DAY_OF_YEAR, i * 7);
207,6 → 219,14
return c;
}
 
public final void setCurrentDate(final Calendar c) {
this.setCurrentDate(c.getTime());
}
 
public final void setCurrentDate(final Date d) {
this.picker.setDate(d);
}
 
private void configureButton(JButton b) {
b.setOpaque(false);
b.setBorderPainted(false);
/trunk/jOpenCalendar/src/org/jopencalendar/ui/DatePicker.java
112,7 → 112,7
d.setContentPane(pickerPanel);
d.setUndecorated(true);
pickerPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
d.setSize(220, 180);
d.setSize(330, 270);
 
pickerPanel.addPropertyChangeListener(DatePickerPanel.TIME_IN_MILLIS, new PropertyChangeListener() {
 
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationCalendar.java
File deleted
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/AbstractCalendarPanel.java
1,123 → 1,295
package org.openconcerto.modules.operation;
 
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.SwingWorker;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
 
import org.jopencalendar.model.JCalendarItem;
import org.jdom2.Element;
import org.jdom2.input.DOMBuilder;
import org.jopencalendar.model.JCalendarItemPart;
import org.jopencalendar.ui.ItemPartHoverListener;
import org.jopencalendar.ui.MultipleDayView;
import org.jopencalendar.ui.WeekView;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.PropsConfiguration;
import org.openconcerto.sql.users.User;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.Log;
import org.openconcerto.ui.state.ListenerXMLStateManager;
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.FileUtils;
import org.openconcerto.utils.XMLCalendarFormat;
import org.openconcerto.utils.model.SimpleListDataListener;
import org.openconcerto.xml.JDOM2Utils;
import org.w3c.dom.Document;
 
public class AbstractCalendarPanel extends JPanel implements OperationCalendar {
protected CheckList<String> statesList;
protected CheckList<User> usesrList;
final protected Map<User, String> userInfo = new HashMap<User, String>();
protected UserOperationListModel usersModel;
final protected JSplitPane split = new JSplitPane();
public abstract class AbstractCalendarPanel extends JPanel {
public static final int HOUR_START = 5;
public static final int HOUR_STOP = 21;
private static final String FILE_STRUCT_VERSION = "20180518";
 
public synchronized String getUserInfo(User user) {
return userInfo.get(user);
protected static final class CalendarPanelStateManager extends ListenerXMLStateManager<AbstractCalendarPanel, PropertyChangeListener> {
private static final Set<String> PROP_NAMES = CollectionUtils.createSet(MultipleDayView.CALENDARD_ITEMS_PROPERTY, "rowHeight");
private static final String VERSION = "20180525";
 
private final MultipleDayView w;
private final XMLCalendarFormat xmlCalendarFormat = new XMLCalendarFormat();
 
protected CalendarPanelStateManager(AbstractCalendarPanel src, File f, MultipleDayView w) {
// don't let the superclass call our methods, we need this.w
super(src, f, false);
this.w = w;
}
 
public List<String> getSelectedStates() {
return this.statesList.getSelectedObjects();
@Override
protected PropertyChangeListener createListener() {
return new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (PROP_NAMES.contains(evt.getPropertyName())) {
try {
saveState();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
}
 
public List<User> getSelectedUsers() {
return this.usesrList.getSelectedObjects();
@Override
protected void addListener(PropertyChangeListener l) {
this.w.addPropertyChangeListener(l);
}
 
protected String formatDuration(int durationMinute) {
int h = durationMinute / 60;
int m = durationMinute % 60;
if (m != 0) {
String mS = String.valueOf(m);
if (m < 10) {
mS = "0" + mS;
@Override
protected void rmListener(PropertyChangeListener l) {
this.w.removePropertyChangeListener(l);
}
return h + ":" + mS;
 
@Override
protected void writeState(BufferedWriter out) throws IOException {
final FilterPanel filterPanel = getSrc().filterPanel;
 
out.write("<calendarPanel version=\"" + VERSION + "\">\n");
 
out.write("<filterPanel");
out.write(" hideLocked=\"" + filterPanel.checkLocked.isSelected() + "\"");
out.write(" hideUnlocked=\"" + filterPanel.checkUnlocked.isSelected() + "\"");
out.write(">\n");
out.write("<selectedStates>");
for (final Object k : filterPanel.statesList.getModel().getWantedCheckedKeys(false)) {
out.write("<state key=\"" + JDOM2Utils.OUTPUTTER.escapeAttributeEntities(k.toString()) + "\"/>");
}
return String.valueOf(h);
out.write("</selectedStates>");
out.write("<selectedUsers>");
for (final Object k : filterPanel.usesrList.getModel().getWantedCheckedKeys(false)) {
out.write("<user key=\"" + JDOM2Utils.OUTPUTTER.escapeAttributeEntities(k.toString()) + "\"/>");
}
out.write("</selectedUsers>");
out.write("</filterPanel>");
 
public void registerCalendarItemListener(MultipleDayView multipleDayView) {
multipleDayView.addPropertyChangeListener(WeekView.CALENDARD_ITEMS_PROPERTY, new PropertyChangeListener() {
out.write("<operationDateView");
final Date viewDate = getSrc().getViewDate();
if (viewDate != null)
out.write(" date=\"" + this.xmlCalendarFormat.format(viewDate) + "\"");
out.write(" rowHeight=\"" + this.w.getRowHeight() + "\"");
out.write("/>\n");
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
@SuppressWarnings("unchecked")
final List<List<JCalendarItem>> items = new ArrayList<List<JCalendarItem>>((List<List<JCalendarItem>>) evt.getNewValue());
SwingWorker<Map<User, String>, Object> worker = new SwingWorker<Map<User, String>, Object>() {
out.write("</calendarPanel>");
}
 
@Override
protected Map<User, String> doInBackground() throws Exception {
final Map<User, String> uInfo = new HashMap<User, String>();
protected boolean readState(Document doc) {
final String docVersion = doc.getDocumentElement().getAttribute("version");
if (!VERSION.equals(docVersion)) {
Log.get().info("wrong version :" + docVersion + " != " + VERSION);
return false;
} else {
final FilterPanel filterPanel = getSrc().filterPanel;
 
final SQLTable tSalarie = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement("SALARIE").getTable();
final DOMBuilder builder = new DOMBuilder();
org.jdom2.Document d = builder.build(doc);
 
final SQLRowValues v = new SQLRowValues(tSalarie);
v.putNulls("NOM", "PRENOM");
v.putRowValues("ID_INFOS_SALARIE_PAYE").putNulls("DUREE_HEBDO");
final List<SQLRowValues> rows = SQLRowValuesListFetcher.create(v).fetch();
final List<User> users = UserManager.getInstance().getAllActiveUsers();
final int size = users.size();
for (int i = 0; i < size; i++) {
final Element filterElem = d.getRootElement().getChild("filterPanel");
filterPanel.checkLocked.setSelected(Boolean.parseBoolean(filterElem.getAttributeValue("hideLocked")));
filterPanel.checkUnlocked.setSelected(Boolean.parseBoolean(filterElem.getAttributeValue("hideUnlocked")));
// states
final List<Element> stateElements = filterElem.getChild("selectedStates").getChildren("state");
final List<String> states = new ArrayList<>();
for (final Element stateElem : stateElements) {
states.add(stateElem.getAttributeValue("key"));
}
filterPanel.statesList.getModel().setCheckedKeys(states);
// users
final List<Element> userElements = filterElem.getChild("selectedUsers").getChildren("user");
final List<Integer> users = new ArrayList<>();
for (final Element userElem : userElements) {
users.add(Integer.valueOf(userElem.getAttributeValue("key")));
}
filterPanel.usesrList.getModel().setCheckedKeys(users);
 
final User u = users.get(i);
final String name = u.getName().trim();
final String firstName = u.getFirstName();
for (SQLRowValues row : rows) {
final Element dateViewElem = d.getRootElement().getChild("operationDateView");
this.w.setRowHeight(Integer.parseInt(dateViewElem.getAttributeValue("rowHeight")));
try {
final String dateString = dateViewElem.getAttributeValue("date");
if (dateString != null) {
final Calendar cal = (Calendar) this.xmlCalendarFormat.parseObject(dateString);
getSrc().setViewDate(cal.getTime());
}
} catch (Exception e) {
e.printStackTrace();
}
}
 
if (row.getString("NOM").trim().equalsIgnoreCase(name) && row.getString("PRENOM").trim().equalsIgnoreCase(firstName)) {
return true;
}
}
 
final int durationMinute = (int) row.getForeign("ID_INFOS_SALARIE_PAYE").getFloat("DUREE_HEBDO") * 60;
protected static final class FilterPanel extends JPanel {
private final CheckList<String> statesList;
private final CheckList<User> usesrList;
private final JCheckBox checkLocked, checkUnlocked;
 
// Durée plannifiée
final int d = OperationCalendarPanel.getDuration(items, u);
// Durée verrouillée
int d2 = OperationCalendarPanel.getDurationLocked(items, u);
uInfo.put(u, "[" + formatDuration(d2) + " / " + formatDuration(d) + " / " + formatDuration(durationMinute) + "]");
public FilterPanel(final OperationStateListModel statesModel, final UserOperationListModel usersModel) {
super(new GridBagLayout());
this.statesList = new CheckList<String>(statesModel);
this.usesrList = new CheckList<User>(usersModel);
 
final JPanel statesPanel = new JPanel(new BorderLayout());
statesPanel.add(new JLabel("Etats"), BorderLayout.PAGE_START);
statesPanel.add(new JScrollPane(this.statesList), BorderLayout.CENTER);
 
final JPanel usersPanel = new JPanel(new BorderLayout());
usersPanel.add(new JLabel("Employés"), BorderLayout.PAGE_START);
usersPanel.add(new JScrollPane(this.usesrList), BorderLayout.CENTER);
 
final JPanel p = this;
final GridBagConstraints c = new DefaultGridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
final JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, statesPanel, usersPanel);
p.add(split, c);
c.gridy++;
c.weighty = 0;
this.checkLocked = new JCheckBox("masquer les verrouillés");
p.add(this.checkLocked, c);
c.gridy++;
this.checkUnlocked = new JCheckBox("masquer les déverrouillés");
p.add(this.checkUnlocked, c);
statesModel.loadContent();
// UserOperationListModel is loaded automatically
 
p.setMinimumSize(new Dimension(200, 200));
p.setPreferredSize(new Dimension(250, 200));
}
 
private JSplitPane getSplitPane() {
return (JSplitPane) this.getComponent(0);
}
}
return uInfo;
 
private FilterPanel filterPanel;
final protected JSplitPane split = new JSplitPane();
 
public List<String> getSelectedStates() {
return this.filterPanel.statesList.getSelectedObjects();
}
 
public List<User> getSelectedUsers() {
return this.filterPanel.usesrList.getSelectedObjects();
}
 
protected final JPanel createFilterPanel(PropsConfiguration conf, MultipleDayView w) {
final OperationStateListModel statesModel = new OperationStateListModel();
final UserOperationListModel usersModel = new UserOperationListModel(conf.getUserManager(), conf.getDirectory(), w);
 
this.filterPanel = new FilterPanel(statesModel, usersModel);
final ListDataListener listener = new SimpleListDataListener() {
@Override
protected void done() {
synchronized (AbstractCalendarPanel.this) {
Map<User, String> uInfo;
try {
uInfo = get();
userInfo.clear();
userInfo.putAll(uInfo);
usersModel.refresh();
} catch (Exception e) {
ExceptionHandler.handle("Cannot update user info", e);
public void contentsChanged(ListDataEvent e) {
filterUIChanged();
}
};
this.filterPanel.statesList.getModel().addListDataListener(listener);
this.filterPanel.usesrList.getModel().addListDataListener(listener);
final ItemListener itemL = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
filterUIChanged();
}
};
this.filterPanel.checkLocked.addItemListener(itemL);
this.filterPanel.checkUnlocked.addItemListener(itemL);
 
w.addItemPartHoverListener(createHoverListener(this.filterPanel.getSplitPane()));
 
return this.filterPanel;
}
 
private final void filterUIChanged() {
List<User> users = null;
if (!this.filterPanel.usesrList.isAllSelected()) {
users = getSelectedUsers();
}
List<String> states = null;
if (!this.filterPanel.statesList.isAllSelected()) {
states = getSelectedStates();
}
setFilter(this.filterPanel.checkLocked, this.filterPanel.checkUnlocked, users, states);
}
 
private static final ItemPartHoverListener createHoverListener(final JSplitPane hoverSplitPane) {
return new ItemPartHoverListener() {
private final Component overwritten = hoverSplitPane.getLeftComponent();
 
@Override
public void mouseOn(JCalendarItemPart newSelection) {
final int location = hoverSplitPane.getDividerLocation();
final Component comp;
if (newSelection == null) {
comp = this.overwritten;
} else {
comp = new JCalendarItemInfoPanel(newSelection.getItem());
}
hoverSplitPane.setLeftComponent(comp);
hoverSplitPane.setDividerLocation(location);
}
};
worker.execute();
}
 
protected abstract void setFilter(JCheckBox check1, JCheckBox check2, List<User> users, List<String> states);
 
protected final void beginStateSaving(final File confDir, final MultipleDayView w) {
final File structFile = new File(confDir, "calendarPanelState-" + FILE_STRUCT_VERSION);
final CalendarPanelStateManager stateManager = new CalendarPanelStateManager(this, new File(structFile, FileUtils.FILENAME_ESCAPER.escape(this.getClass().getSimpleName()) + ".xml"), w);
stateManager.beginAutoSave();
stateManager.loadState();
}
});
 
protected abstract Date getViewDate();
 
protected abstract void setViewDate(Date d);
 
}
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationGroup.java
11,6 → 11,7
this.addItem("operation.type", new LayoutHints(true, false, true, false, true, false));
this.addItem("operation.user");
this.addItem("operation.status");
this.addItem("operation.freeTime");
this.addItem("operation.dates", new LayoutHints(true, false, true, false, true, true, true));
this.addItem("operation.description", new LayoutHints(true, false, true, false, true, true, true));
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/MultiOperationSQLComponent.java
62,8 → 62,13
dateRangePlannerPanel.getJDateEnd().addValueListener(listener);
return dateRangePlannerPanel;
} else if (id.equals("operation.type") || id.equals("operation.status")) {
return new SQLTextCombo();
return new SQLTextCombo() {
@Override
public boolean canComplete(String originalText) {
return originalText != null && !originalText.trim().isEmpty();
}
};
}
return super.createEditor(id);
}
 
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationExportPanel.java
9,6 → 9,8
import java.awt.event.ActionListener;
import java.io.File;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
16,7 → 18,10
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
 
import javax.swing.ButtonGroup;
import javax.swing.JButton;
30,6 → 35,7
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
 
import org.jdom2.Document;
import org.jopencalendar.model.JCalendarItem;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.TemplateManager;
36,21 → 42,34
import org.openconcerto.openoffice.OOUtils;
import org.openconcerto.openoffice.spreadsheet.Sheet;
import org.openconcerto.openoffice.spreadsheet.SpreadSheet;
import org.openconcerto.sql.PropsConfiguration;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.FieldMapper;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
import org.openconcerto.sql.sqlobject.SQLTextCombo.ITextComboCacheSQL;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.date.DateRangePlannerPanel;
import org.openconcerto.utils.CollectionMap2.Mode;
import org.openconcerto.utils.CompareUtils;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.ListMap;
import org.openconcerto.utils.StreamUtils;
import org.openconcerto.utils.cc.ITransformer;
import org.openconcerto.utils.StringUtils;
import org.openconcerto.utils.TimeUtils;
import org.openconcerto.xml.JDOM2Utils;
 
import net.jcip.annotations.GuardedBy;
 
public class OperationExportPanel extends JPanel {
 
@GuardedBy("EDT")
static private final DateFormat DF = new SimpleDateFormat("yyyyMMdd");
 
final JCheckBox lockedCheckBox = new JCheckBox("verrouillées uniquement");
final JButton bPrint = new JButton("Exporter");
 
86,6 → 105,19
c.weightx = 1;
this.add(d2, c);
 
final OperationSQLElement operationElem = manager.getDirectory().getElement(OperationSQLElement.class);
final OperationSQLComponent operationSQLComp = new OperationSQLComponent(operationElem);
final String statusID = "operation.status";
c.gridy++;
c.gridx = 0;
c.gridwidth = 1;
this.add(operationSQLComp.getLabel(statusID), c);
c.gridx++;
final SQLTextCombo statusCombo = (SQLTextCombo) operationSQLComp.createEditor(statusID);
final FieldMapper fieldMapper = PropsConfiguration.getInstance().getFieldMapper();
statusCombo.initCache(new ITextComboCacheSQL(fieldMapper.getSQLFieldForItem(statusID)));
this.add(statusCombo, c);
 
//
c.gridwidth = 2;
c.gridx = 0;
93,7 → 125,7
final JRadioButton radio1 = new JRadioButton("interventions");
radio1.setSelected(true);
this.add(radio1, c);
final JRadioButton radio2 = new JRadioButton("plannifications");
final JRadioButton radio2 = new JRadioButton("planifications");
c.gridy++;
this.add(radio2, c);
final ButtonGroup g = new ButtonGroup();
120,7 → 152,9
if (d1.getDate().after(d2.getDate())) {
return;
}
final List<JCalendarItem> items = manager.getItemIn(d1.getDate(), d2.getDate(), null, null);
final String statusVal = statusCombo.getValue();
final List<String> states = StringUtils.isEmpty(statusVal, true) ? null : Collections.singletonList(statusVal);
final List<JCalendarItem> items = manager.getItemIn(d1.getDate(), d2.getDate(), null, states);
final List<JCalendarItemDB> itemsToExport = new ArrayList<JCalendarItemDB>(items.size());
if (lockedCheckBox.isSelected()) {
for (JCalendarItem jCalendarItem : items) {
166,10 → 200,11
return (int) (((Number) o1.getUserId()).longValue() - ((Number) o2.getUserId()).longValue());
}
});
final String dates = " " + DF.format(d1.getDate()) + '-' + DF.format(d2.getDate());
if (radio1.isSelected()) {
export(itemsToExport);
export(itemsToExport, "export " + radio1.getText() + dates);
} else {
exportPlan(itemsToExport);
exportPlan(itemsToExport, "export " + radio2.getText() + dates);
}
closeFrame();
 
177,8 → 212,71
});
}
 
protected void exportPlan(List<JCalendarItemDB> itemsToExport) {
static private final class Planner implements Comparable<Planner> {
private final String uid;
private final String xml;
private Date rangeStart;
 
protected Planner(String uid, String xml) {
super();
this.uid = uid;
this.xml = xml;
}
 
public final String getUID() {
return this.uid;
}
 
public final String getDescription() {
return DateRangePlannerPanel.getDescriptionFromXML(this.xml);
}
 
public final Date getRangeStart() {
if (this.rangeStart == null) {
try {
final Document doc = JDOM2Utils.parseStringDocument(this.xml);
this.rangeStart = new Date(Long.valueOf(doc.getRootElement().getChild("range").getAttributeValue("start")));
} catch (Exception e) {
throw new IllegalStateException("couldn't get start for " + this.xml, e);
}
}
return this.rangeStart;
}
 
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.uid.hashCode();
return result;
}
 
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Planner other = (Planner) obj;
return this.uid.equals(other.uid);
}
 
@Override
public int compareTo(Planner o) {
if (this.equals(o))
return 0;
final int startComparison = this.getRangeStart().compareTo(o.getRangeStart());
if (startComparison != 0)
return startComparison;
return this.getUID().compareTo(o.getUID());
 
}
}
 
protected void exportPlan(List<JCalendarItemDB> itemsToExport, final String name) {
 
final List<Long> ids = ModuleOperation.getOperationIdsFrom(new HashSet<JCalendarItemDB>(itemsToExport));
 
final DBRoot root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
197,27 → 295,13
 
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(valOperation);
fetcher.setFullOnly(true);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
 
@Override
public SQLSelect transformChecked(SQLSelect input) {
input.andWhere(new Where(table.getKey(), ids));
return input;
}
});
 
final List<SQLRowValues> itemsFetched = fetcher.fetch();
final List<SQLRowValues> items = new ArrayList<SQLRowValues>();
final Set<String> plannnerUId = new HashSet<String>();
final List<SQLRowValues> itemsFetched = fetcher.fetch(new Where(table.getKey(), ids).and(Where.createRaw("length(" + table.getField("PLANNER_UID").getFieldRef() + ")>2")));
final ListMap<Planner, SQLRowValues> operationsByPlanner = new ListMap<>(new TreeMap<Planner, List<SQLRowValues>>(), Mode.NULL_FORBIDDEN);
for (SQLRowValues d : itemsFetched) {
if (d.getObject("PLANNER_UID") != null) {
final String string = d.getString("PLANNER_UID");
if (string.length() > 3 && !plannnerUId.contains(string)) {
items.add(d);
plannnerUId.add(string);
operationsByPlanner.add(new Planner(d.getString("PLANNER_UID"), d.getString("PLANNER_XML")), d);
}
}
}
final List<Entry<Planner, List<SQLRowValues>>> items = new ArrayList<>(operationsByPlanner.entrySet());
 
TableModel model = new AbstractTableModel() {
 
233,17 → 317,49
 
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
SQLRowValues i = items.get(rowIndex);
final Entry<Planner, List<SQLRowValues>> rows = items.get(rowIndex);
final Planner planner = rows.getKey();
// for now, only the "Employé" column check all operations for a planner, the other
// columns just take the first one.
final SQLRowValues i = rows.getValue().get(0);
switch (columnIndex) {
case 0:
// Plannif
String start = DateRangePlannerPanel.getDescriptionFromXML(i.getString("PLANNER_XML"));
return start;
return planner.getDescription();
 
case 1:
// Employé
final String user = i.getForeign("ID_USER_COMMON").getString("NOM");
return user;
final ListMap<Integer, SQLRowValues> operationsByUserID = new ListMap<>();
for (final SQLRowValues r : rows.getValue()) {
operationsByUserID.add(r.getForeignID("ID_USER_COMMON"), r);
}
final List<Entry<Integer, List<SQLRowValues>>> entries = new ArrayList<>(operationsByUserID.entrySet());
// the users with the most operations first
Collections.sort(entries, new Comparator<Entry<Integer, List<SQLRowValues>>>() {
@Override
public int compare(Entry<Integer, List<SQLRowValues>> o1, Entry<Integer, List<SQLRowValues>> o2) {
final int sizeComparison = CompareUtils.compareInt(o1.getValue().size(), o2.getValue().size());
if (sizeComparison != 0)
return -sizeComparison;
return o1.getKey().compareTo(o2.getKey());
}
});
final ListIterator<Entry<Integer, List<SQLRowValues>>> listIter = entries.listIterator();
final StringBuilder sb = new StringBuilder(128);
while (listIter.hasNext()) {
final Entry<Integer, List<SQLRowValues>> element = listIter.next();
final SQLRowValues operationR = element.getValue().get(0);
sb.append(operationR.getForeign("ID_USER_COMMON").getString("NOM"));
if (listIter.previousIndex() > 0) {
sb.append(" (");
sb.append(element.getValue().size());
sb.append(")");
}
if (listIter.hasNext()) {
sb.append(", ");
}
}
return sb.toString();
case 2:
// Nature
final String type = i.getString("TYPE");
266,11 → 382,10
 
// Save the data to an ODS file and open it.
final String templateId = ModuleOperation.OPERATIONS_REPORT_TEMPLATE2_ID;
saveAsODS(model, templateId);
 
saveAsODS(model, templateId, name);
}
 
protected void export(final List<JCalendarItemDB> items) {
protected void export(final List<JCalendarItemDB> items, final String name) {
 
TableModel model = new AbstractTableModel() {
 
290,7 → 405,7
switch (columnIndex) {
case 0:
// Date
Date start = i.getDtStart().getTime();
Date start = TimeUtils.clearTime((Calendar) i.getDtStart().clone()).getTime();
return start;
case 1:
// Heure
302,8 → 417,8
return m;
case 3:
// Employé
final String user = ((SQLRowAccessor) (i.getCookie())).getString("NOM");
return user;
final SQLRowValues user = i.getUserRow();
return user.getString("PRENOM") + " " + user.getString("NOM");
case 4:
// Nature
final String type = i.getType();
326,11 → 441,11
 
// Save the data to an ODS file and open it.
final String templateId = ModuleOperation.OPERATIONS_REPORT_TEMPLATE_ID;
saveAsODS(model, templateId);
saveAsODS(model, templateId, name);
 
}
 
public void saveAsODS(TableModel model, final String templateId) {
public void saveAsODS(TableModel model, final String templateId, final String name) {
try {
final InputStream inStream = TemplateManager.getInstance().getTemplate(templateId);
final File templateFile = File.createTempFile(templateId, ".ods");
351,7 → 466,7
}
 
final FileDialog d = new FileDialog((Frame) SwingUtilities.getWindowAncestor(this), "Exporter sous...", FileDialog.SAVE);
d.setFile("export.ods");
d.setFile(name + ".ods");
d.setVisible(true);
String fileName = d.getFile();
if (fileName != null) {
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationCalendarManager.java
9,6 → 9,7
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
 
import javax.swing.SwingUtilities;
 
17,6 → 18,9
import org.jopencalendar.model.JCalendarItemGroup;
import org.jopencalendar.ui.JCalendarItemProvider;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.project.element.CalendarItemGroupSQLElement;
import org.openconcerto.erp.core.project.element.CalendarItemSQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowMode;
35,35 → 39,68
import org.openconcerto.utils.cc.ITransformer;
 
public class OperationCalendarManager extends JCalendarItemProvider {
private DBRoot root;
private final DBRoot root;
private final SQLElementDirectory dir;
private final UserManager userMngr;
private List<User> users;
private List<String> states;
private boolean hideLocked = false;
private boolean hideUnlocked = false;
 
public OperationCalendarManager(String name) {
super(name);
this.root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
this(name, ComptaPropsConfiguration.getInstanceCompta());
}
 
public OperationCalendarManager(String name, DBRoot root) {
public OperationCalendarManager(final String name, final ComptaPropsConfiguration comptaConf) {
this(name, comptaConf.getRootSociete(), comptaConf.getDirectory(), comptaConf.getUserManager());
}
 
public OperationCalendarManager(final String name, final DBRoot root, final SQLElementDirectory dir, final UserManager userMngr) {
super(name);
this.root = root;
this.dir = dir;
this.userMngr = userMngr;
}
 
private List<User> users;
private List<String> states;
private boolean hideLocked = false;
private boolean hideUnlocked = false;
public final SQLElementDirectory getDirectory() {
return this.dir;
}
 
/**
private final SQLTable getCalendarItemTable() {
return this.dir.getElement(CalendarItemSQLElement.class).getTable();
}
 
private final SQLTable getCalendarItemGroupTable() {
return this.dir.getElement(CalendarItemGroupSQLElement.class).getTable();
}
 
/*
* Set the filter to retrieve items
*
* @param users if null don't limit to specific users
* @param states if null don't limite to specific states
*
* @param states if null don't limit to specific states
*/
synchronized public void setFilter(List<User> users, List<String> states, boolean hideLocked, boolean hideUnlocked) {
synchronized public boolean setFilter(List<User> users, List<String> states, boolean hideLocked, boolean hideUnlocked) {
boolean res = false;
if (!Objects.equals(this.users, users)) {
this.users = users;
res = true;
}
if (!Objects.equals(this.states, states)) {
this.states = states;
res = true;
}
if (this.hideLocked != hideLocked) {
this.hideLocked = hideLocked;
res = true;
}
if (this.hideUnlocked != hideUnlocked) {
this.hideUnlocked = hideUnlocked;
res = true;
}
return res;
}
 
@Override
synchronized public List<JCalendarItem> getItemInWeek(int week, int year) {
103,7 → 140,7
public List<JCalendarItem> getItemIn(final Date date1, final Date date2, List<User> selectedUsers, final List<String> selectedStates, final String uid) {
final List<User> users = new ArrayList<User>();
if (selectedUsers == null) {
users.addAll(UserManager.getInstance().getAllActiveUsers());
users.addAll(this.userMngr.getAllActiveUsers());
} else {
users.addAll(selectedUsers);
}
113,7 → 150,7
if (selectedStates != null && selectedStates.isEmpty()) {
return Collections.emptyList();
}
final SQLRowValues valCalendarItems = new SQLRowValues(root.getTable("CALENDAR_ITEM"));
final SQLRowValues valCalendarItems = new SQLRowValues(getCalendarItemTable());
valCalendarItems.putNulls("START", "END", "DURATION_S", "SUMMARY", "DESCRIPTION", "FLAGS", "STATUS", "SOURCE_ID", "SOURCE_TABLE", "UID", "LOCATION");
final SQLRowValues valsCalendarItemsGroup = valCalendarItems.putRowValues("ID_CALENDAR_ITEM_GROUP");
valsCalendarItemsGroup.put("NAME", null);
122,12 → 159,13
valSite.putNulls("NAME", "COMMENT");
 
final SQLRowValues valOperation = new SQLRowValues(root.getTable(ModuleOperation.TABLE_OPERATION));
final SQLRowValues userVals = valOperation.putRowValues("ID_USER_COMMON").putNulls("NOM");
final SQLRowValues userVals = valOperation.putRowValues("ID_USER_COMMON").putNulls("NOM", "PRENOM");
valOperation.put("ID_CALENDAR_ITEM_GROUP", valsCalendarItemsGroup);
valOperation.put("ID_SITE", valSite);
valOperation.putNulls("STATUS", "TYPE", "PLANNER_XML", "PLANNER_UID");
 
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(valCalendarItems);
fetcher.setReturnedRowsUnmodifiable(true);
fetcher.setFullOnly(true);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
 
196,7 → 234,7
 
if (user != null) {
final SQLRowValues operation = r.followPath(pItemToOperation);
final JCalendarItemDB item = new JCalendarItemDB(r.getID(), r.getString("SOURCE_TABLE"), r.getInt("SOURCE_ID"), r.getForeign("ID_CALENDAR_ITEM_GROUP").getID());
final JCalendarItemDB item = new JCalendarItemDB(this.dir, r);
 
item.setDayOnly(false);
item.setDtStart(r.getDate("START"));
282,7 → 320,7
final SQLRow operationRow = vOperation.commit();
SQLRow calendarGroupRow = operationRow.getForeignRow("ID_CALENDAR_ITEM_GROUP", SQLRowMode.DEFINED);
 
final SQLRowValues rowItemGroup = new SQLRowValues(root.getTable("CALENDAR_ITEM_GROUP"));
final SQLRowValues rowItemGroup = new SQLRowValues(getCalendarItemGroupTable());
rowItemGroup.put("NAME", summary);
rowItemGroup.put("DESCRIPTION", description);
 
295,7 → 333,7
DateRange dateRange = new DateRange();
dateRange.setStart(start.getTime());
dateRange.setStop(end.getTime());
final SQLRowValues rowItem = new SQLRowValues(root.getTable("CALENDAR_ITEM"));
final SQLRowValues rowItem = new SQLRowValues(getCalendarItemTable());
rowItem.put("START", new Date(dateRange.getStart()));
rowItem.put("END", new Date(dateRange.getStop()));
rowItem.put("DURATION_S", (dateRange.getStop() - dateRange.getStart()) / 1000);
313,21 → 351,19
if (i instanceof JCalendarItemDB) {
JCalendarItemDB item = (JCalendarItemDB) i;
//
final SQLRowValues vOperation = tOperation.getRow((int) item.getSourceId()).createEmptyUpdateRow();
final SQLRowValues vOperation = item.getSource().createEmptyUpdateRow();
vOperation.put("DESCRIPTION", description);
vOperation.commit();
// group
final SQLTable tGroup = root.getTable("CALENDAR_ITEM_GROUP");
final SQLRowValues rowItemGroup = tGroup.getRow(item.getIdCalendarGroup()).createEmptyUpdateRow();
final SQLRowValues rowItemGroup = item.getCalendarGroup().createEmptyUpdateRow();
rowItemGroup.put("NAME", summary);
rowItemGroup.put("DESCRIPTION", description);
rowItemGroup.commit();
// item
final SQLTable tItem = root.getTable("CALENDAR_ITEM");
DateRange dateRange = new DateRange();
dateRange.setStart(start.getTime());
dateRange.setStop(end.getTime());
final SQLRowValues rowItem = tItem.getRow(item.getId()).createEmptyUpdateRow();
final SQLRowValues rowItem = item.getRow().createEmptyUpdateRow();
rowItem.put("START", new Date(dateRange.getStart()));
rowItem.put("END", new Date(dateRange.getStop()));
rowItem.put("DURATION_S", (dateRange.getStop() - dateRange.getStart()) / 1000);
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationDayView.java
6,6 → 6,7
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
 
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
119,10 → 120,24
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException();
}
boolean changed = false;
if (!Objects.equals(this.filterUsers, users)) {
this.filterUsers = users;
changed = true;
}
if (!Objects.equals(this.filterStates, states)) {
this.filterStates = states;
changed = true;
}
if (this.hideLocked != hideLocked) {
this.hideLocked = hideLocked;
changed = true;
}
if (this.hideUnlocked != hideUnlocked) {
this.hideUnlocked = hideUnlocked;
changed = true;
}
if (changed)
reload();
}
 
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/action/RePlanAction.java
11,7 → 11,7
import org.jopencalendar.model.JCalendarItemPart;
import org.openconcerto.modules.operation.JCalendarItemDB;
import org.openconcerto.modules.operation.MultiOperationSQLComponent;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.ui.FrameUtil;
20,7 → 20,7
private List<JCalendarItemPart> selectedItems;
 
public RePlanAction(List<JCalendarItemPart> selectedItems) {
putValue(Action.NAME, "Replannifier");
putValue(Action.NAME, "Replanifier");
this.selectedItems = selectedItems;
}
 
30,16 → 30,15
return;
}
final JCalendarItemDB item = (JCalendarItemDB) selectedItems.get(0).getItem();
final int operationId = (int) item.getSourceId();
final SQLRow r = item.getSourceElement().getTable().getRow(operationId);
if (!r.getString("PLANNER_UID").isEmpty()) {
final SQLRowValues r = item.getSource();
if (item.isPlanned()) {
final MultiOperationSQLComponent comp = new MultiOperationSQLComponent(item.getSourceElement());
final EditFrame f = new EditFrame(comp, EditMode.MODIFICATION);
f.selectionId(operationId);
f.selectionId(r.getID());
comp.setDateStart((Date) selectedItems.get(0).getItem().getDtStart().getTime().clone());
FrameUtil.show(f);
} else {
JOptionPane.showMessageDialog(null, "Cette intervention ne peut pas être directement replannifiée");
JOptionPane.showMessageDialog(null, "Cette intervention ne peut pas être directement replanifiée");
}
 
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/action/DeletePanel.java
4,6 → 4,7
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
20,18 → 21,25
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
 
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jopencalendar.model.JCalendarItemPart;
import org.openconcerto.modules.operation.JCalendarItemDB;
import org.openconcerto.modules.operation.ModuleOperation;
import org.openconcerto.modules.operation.OperationSQLElement;
import org.openconcerto.sql.PropsConfiguration;
import org.openconcerto.sql.model.ConnectionHandlerNoSetup;
import org.openconcerto.sql.model.DBSystemRoot;
import org.openconcerto.sql.model.SQLDataSource;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.UpdateBuilder;
import org.openconcerto.sql.utils.SQLUtils;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.xml.JDOM2Utils;
 
public class DeletePanel extends JPanel {
 
103,8 → 111,10
 
protected void deleteSelected() {
final Set<JCalendarItemDB> toDelete = ModuleOperation.getItemDB(this.selectedItems);
if (toDelete.isEmpty())
return;
final List<Long> ids = ModuleOperation.getOperationIdsFrom(toDelete);
deleteInBackgroundOperations(ids);
deleteInBackgroundOperations(toDelete.iterator().next().getSourceElement(), ids, null, null);
}
 
@SuppressWarnings("unchecked")
126,14 → 136,16
startDate = item.getDtStart();
}
}
final SQLTable tableOperation = firstItem.getSourceElement().getTable();
final OperationSQLElement operationElem = firstItem.getSourceElement();
final SQLTable tableOperation = operationElem.getTable();
final DBSystemRoot dbSystemRoot = tableOperation.getDBSystemRoot();
 
SQLRow rowOperation = tableOperation.getRow((int) firstItem.getSourceId());
SQLRowValues rowOperation = firstItem.getSource();
int idSite = rowOperation.getForeignID("ID_SITE");
 
// plannerUID de OPERATION
String plannerUID = firstItem.getPlannerUID();
String plannerNewXML = null;
 
final SQLSelect select = new SQLSelect();
select.addSelect(tableOperation.getField("ID_CALENDAR_ITEM_GROUP"));
141,6 → 153,15
// Recuperation des groupes correspondants au meme site et intervenant
select.setWhere(new Where(tableOperation.getField("ID_SITE"), "=", idSite).and(new Where(tableOperation.getField("ID_USER_COMMON"), "=", idUser)));
} else {
// keep XML in sync with actual events
try {
final Document doc = JDOM2Utils.parseStringDocument(firstItem.getPlannerXML());
doc.getRootElement().getChild("range").setAttribute("end", String.valueOf(startDate.getTimeInMillis())).removeAttribute("repeat");
plannerNewXML = JDOM2Utils.output(doc);
} catch (JDOMException e) {
System.err.println("Couldn't update end to " + startDate);
e.printStackTrace();
}
// Recuperation des groupes correspondants au meme plannerUID
select.setWhere(new Where(tableOperation.getField("PLANNER_UID"), "LIKE", plannerUID));
}
172,18 → 193,30
oidsToDelete.addAll(oids);
Collections.sort(oidsToDelete);
 
deleteInBackgroundOperations(oidsToDelete);
deleteInBackgroundOperations(operationElem, oidsToDelete, plannerUID, plannerNewXML);
}
 
public void deleteInBackgroundOperations(final List<Long> ids) {
public void deleteInBackgroundOperations(final OperationSQLElement elem, final List<Long> ids, final String plannerUID, final String plannerNewXML) {
Collections.sort(ids);
SwingWorker<Object, Object> worker = new SwingWorker<Object, Object>() {
 
@Override
protected Object doInBackground() throws Exception {
final OperationSQLElement elem = (OperationSQLElement) PropsConfiguration.getInstance().getDirectory().getElement(ModuleOperation.TABLE_OPERATION);
try {
SQLUtils.executeAtomic(elem.getTable().getDBSystemRoot().getDataSource(), new ConnectionHandlerNoSetup<Object, SQLException>() {
@Override
public Object handle(SQLDataSource ds) throws SQLException, SQLException {
elem.fastDelete(ids);
if (plannerNewXML != null) {
final UpdateBuilder upd = new UpdateBuilder(elem.getTable());
upd.setObject("PLANNER_XML", plannerNewXML);
upd.setWhere(new Where(upd.getTable().getField("PLANNER_UID"), "=", plannerUID));
ds.execute(upd.asString());
upd.getTable().fireTableModified(SQLRow.NONEXISTANT_ID);
}
return null;
}
});
} catch (Exception e) {
e.printStackTrace();
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/action/ModifyAction.java
29,7 → 29,7
final JCalendarItemDB item = (JCalendarItemDB) selectedItems.get(0).getItem();
item.getSourceElement().createDefaultComponent();
final EditFrame f = new EditFrame(item.getSourceElement(), EditMode.MODIFICATION);
f.selectionId((int) item.getSourceId());
f.selectionId(item.getSource().getID());
FrameUtil.show(f);
 
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/action/DuplicateAction.java
3,6 → 3,7
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
 
import javax.swing.Action;
 
42,8 → 43,8
final String type = item.getType();
final String status = item.getStatus();
final long idSite = item.getSiteId().longValue();
final String plannerUid = "";
final String plannerXML = "";
final String plannerUid = item.isPlanned() ? UUID.randomUUID().toString() : "";
final String plannerXML = item.getPlannerXML();
final int idUser = (Integer) item.getUserId();
final SQLTable tOperation = root.getTable(ModuleOperation.TABLE_OPERATION);
String query2 = " (\"ID_SITE\", \"STATUS\", \"TYPE\", \"DESCRIPTION\", \"PLANNER_UID\", \"PLANNER_XML\", \"ID_USER_COMMON\", \"ID_CALENDAR_ITEM_GROUP\" , \"ORDRE\") ";
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/MultipleDayCalendarWithToolBar.java
22,9 → 22,8
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import org.jopencalendar.ui.CalendarWithToolBar;
import org.jopencalendar.ui.DatePicker;
import org.jopencalendar.ui.DayView;
import org.jopencalendar.ui.ItemPartView;
32,36 → 31,24
import org.jopencalendar.ui.MultipleDayViewHeader;
 
public class MultipleDayCalendarWithToolBar extends JPanel {
private OperationDayView weekView;
private final OperationDayView weekView;
 
final JScrollPane contentPane = new JScrollPane();
private Date date;
private final DatePicker jDate;
 
public MultipleDayCalendarWithToolBar(OperationDayView mDayView) {
this.weekView = mDayView;
 
JPanel toolbar = new JPanel();
toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));
 
Calendar cal = Calendar.getInstance();
 
this.date = cal.getTime();
final DatePicker jDate = new DatePicker(false);
jDate.setDate(date);
this.jDate = new DatePicker(false);
JButton bLeft = createButton(new ImageIcon(DayView.class.getResource("left.png")));
JButton bRight = createButton(new ImageIcon(DayView.class.getResource("right.png")));
toolbar.add(bLeft);
toolbar.add(bRight);
toolbar.add(jDate);
final JSlider zoomSlider = new JSlider(1, 9, 1);
zoomSlider.setSnapToTicks(true);
zoomSlider.setMajorTickSpacing(1);
zoomSlider.setPaintTicks(true);
zoomSlider.addChangeListener(new ChangeListener() {
 
@Override
public void stateChanged(ChangeEvent e) {
weekView.setZoom(zoomSlider.getValue());
}
});
final JSlider zoomSlider = CalendarWithToolBar.createZoomSlider(this.getWeekView());
toolbar.add(new JLabel(" Zoom"));
toolbar.add(zoomSlider);
JButton reloadButton = createButton(new ImageIcon(ItemPartView.class.getResource("auto.png")));
89,7 → 76,6
 
contentPane.setBorder(BorderFactory.createEmptyBorder());
contentPane.setOpaque(false);
weekView = mDayView;
contentPane.setColumnHeaderView(new MultipleDayViewHeader(weekView));
contentPane.setViewportView(weekView);
contentPane.getViewport().setBackground(Color.WHITE);
109,29 → 95,29
this.add(contentPane, c);
final int value = 300;
contentPane.getVerticalScrollBar().setValue(value);
weekView.loadDay(date);
 
jDate.addPropertyChangeListener("value", new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() != null) {
final Date d = (Date) evt.getNewValue();
date = d;
weekView.loadDay(d);
}
}
});
// initial value (don't leave null value)
assert getDate() == null : "Pb with constructor";
setDate(new Date());
 
bLeft.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
Calendar c = Calendar.getInstance();
c.setTime(date);
c.setTime(getDate());
c.add(Calendar.DAY_OF_YEAR, -1);
final Date time = c.getTime();
jDate.setDate(time);
date = time;
setDate(time);
}
});
bRight.addActionListener(new ActionListener() {
139,16 → 125,23
@Override
public void actionPerformed(ActionEvent e) {
Calendar c = Calendar.getInstance();
c.setTime(date);
c.setTime(getDate());
c.add(Calendar.DAY_OF_YEAR, 1);
final Date time = c.getTime();
jDate.setDate(time);
date = time;
setDate(time);
}
});
 
}
 
public final void setDate(Date date) {
this.jDate.setDate(date);
}
 
public final Date getDate() {
return this.jDate.getDate();
}
 
public void reload() {
weekView.reload();
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationSQLComponent.java
8,13 → 8,18
import java.util.Map;
import java.util.Set;
 
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JToggleButton;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.sql.PropsConfiguration;
import org.openconcerto.sql.element.GroupSQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.FieldMapper;
import org.openconcerto.sql.model.SQLDataSource;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowMode;
22,12 → 27,16
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
import org.openconcerto.ui.JLabelBold;
import org.openconcerto.ui.component.ITextArea;
import org.openconcerto.ui.date.DateRange;
import org.openconcerto.ui.date.DateRangeTable;
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.StringUtils;
 
public class OperationSQLComponent extends GroupSQLComponent {
 
39,12 → 48,33
public JComponent createEditor(String id) {
if (id.equals("operation.description")) {
return new ITextArea(15, 3);
} else if (id.equals("operation.freeTime")) {
return new JCheckBox();
} else if (id.equals("operation.dates")) {
return new DateRangeTable(true, false, false);
} else if (id.equals("operation.type") || id.equals("operation.status")) {
return new SQLTextCombo();
return new SQLTextCombo() {
@Override
public boolean canComplete(String originalText) {
return originalText != null && !originalText.trim().isEmpty();
}
};
} else if (id.equals("operation.user")) {
// do not show desactivated users
final FieldMapper fieldMapper = PropsConfiguration.getInstance().getFieldMapper();
final SQLField field = fieldMapper.getSQLFieldForItem(id);
final SQLElement foreignElement = getElement().getForeignElement(field.getName());
final ElementComboBox comp = new ElementComboBox();
final ComboSQLRequest comboRequest = foreignElement.getComboRequest();
final SQLTable userTable = foreignElement.getTable();
comboRequest.setWhere(new Where(userTable.getField("DISABLED"), "=", false));
comp.init(foreignElement, comboRequest);
comp.setOpaque(false);
return comp;
 
}
return super.createEditor(id);
 
}
 
@Override
73,6 → 103,7
public void select(final SQLRowAccessor r) {
super.select(r);
 
final boolean isFreeTime;
if (r != null && r.getID() > this.getTable().getUndefinedID()) {
SQLSelect select = new SQLSelect();
int idGroup = r.getInt("ID_CALENDAR_ITEM_GROUP");
79,9 → 110,10
final SQLTable calendarItemTable = r.getTable().getTable("CALENDAR_ITEM");
select.addSelectStar(calendarItemTable);
select.setWhere(calendarItemTable.getField("ID_CALENDAR_ITEM_GROUP"), "=", idGroup);
final SQLDataSource ds = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getDBSystemRoot().getDataSource();
final SQLDataSource ds = calendarItemTable.getDBSystemRoot().getDataSource();
@SuppressWarnings("unchecked")
final List<Map<String, Object>> result = ds.execute(select.asString());
boolean freeTimeTmp = false;
final List<DateRange> ranges = new ArrayList<DateRange>();
for (Map<String, Object> row : result) {
final DateRange range = new DateRange();
90,13 → 122,15
range.setStart(dStart.getTime());
range.setStop(dEnd.getTime());
ranges.add(range);
freeTimeTmp |= row.get("FLAGS") == null ? false : StringUtils.fastSplit((String) row.get("FLAGS"), ',').contains(ModuleOperation.FREE_TIME_FLAG.getTypeId());
}
 
isFreeTime = freeTimeTmp;
getDateRangeTable().fillFrom(ranges);
 
} else {
getDateRangeTable().clear();
isFreeTime = false;
}
((JToggleButton) getEditor("operation.freeTime")).setSelected(isFreeTime);
}
 
@Override
154,7 → 188,13
rowItem.put("DURATION_S", (dateRange.getStop() - dateRange.getStart()) / 1000);
rowItem.put("SUMMARY", operationRow.getForeignRow("ID_SITE").getString("NAME") + "\n" + operationRow.getString("TYPE"));
rowItem.put("DESCRIPTION", operationRow.getString("DESCRIPTION"));
rowItem.put("FLAGS", "");
final List<String> flags = new ArrayList<>();
final boolean isFreeTime = ((JToggleButton) getEditor("operation.freeTime")).isSelected();
if (isFreeTime)
flags.add(ModuleOperation.FREE_TIME_FLAG.getTypeId());
if (!StringUtils.isEmpty(operationRow.getString("PLANNER_UID")))
flags.add("planned");
rowItem.put("FLAGS", CollectionUtils.join(flags, ","));
rowItem.put("STATUS", operationRow.getString("STATUS"));
rowItem.put("ID_CALENDAR_ITEM_GROUP", calendarGroupRow.getID());
rowItem.put("SOURCE_ID", idOperation);
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/translation_fr.xml
1,5 → 1,6
<translation lang="fr">
<item id="operation.dates" label="Dates d'intervention" />
<item id="operation.freeTime" label="Temps non travaillé" />
<menu id="operation" label="Interventions" />
<menu id="operation.export" label="Export des interventions"/>
</translation>
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/ModuleOperation.java
5,7 → 5,6
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
28,7 → 27,6
import org.openconcerto.erp.modules.MenuContext;
import org.openconcerto.erp.modules.ModuleFactory;
import org.openconcerto.modules.operation.action.LockAction;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.SQLRowValues;
45,6 → 43,8
public static final String TABLE_SITE = "SITE";
public static final String TABLE_OPERATION = "OPERATION";
 
public static final Flag FREE_TIME_FLAG = new Flag("freeTime", null, "Non travaillé", "");
 
public ModuleOperation(ModuleFactory f) throws IOException {
super(f);
}
57,7 → 57,6
dir.addSQLElement(new SiteSQLElement(this));
dir.addSQLElement(new OperationSQLElement(this));
 
Configuration.getInstance().getShowAs().show("SITE", Arrays.asList("NAME"));
// SQLRequestLog.setEnabled(true);
// SQLRequestLog.showFrame();
TemplateManager.getInstance().register(OPERATIONS_REPORT_TEMPLATE_ID);
69,7 → 68,7
@Override
protected void setupMenu(MenuContext ctxt) {
ctxt.addMenuItem(ctxt.createListAction(TABLE_SITE), "operation");
final SQLElement element = Configuration.getInstance().getDirectory().getElement(TABLE_OPERATION);
final SQLElement element = ctxt.getElement(TABLE_OPERATION);
final AbstractAction aOperations = new AbstractAction(getTM().trM("listAction.name", "element", element.getName())) {
 
@Override
160,9 → 159,11
Flag.register(new Flag("planned", icon, "Planifié", ""));
icon = new ImageIcon(LockAction.class.getResource("locked.png"));
Flag.register(new Flag("locked", icon, "Verrouillé", ""));
Flag.register(FREE_TIME_FLAG);
 
comp = new OperationCalendarPanel();
comp2 = new DailyOperationCalendarPanel();
final ComptaPropsConfiguration conf = ComptaPropsConfiguration.getInstanceCompta();
comp = new OperationCalendarPanel(conf);
comp2 = new DailyOperationCalendarPanel(conf);
 
MainFrame.getInstance().getTabbedPane().addTab("Planning", comp);
MainFrame.getInstance().getTabbedPane().addTab("Planning journalier", comp2);
185,11 → 186,11
public static List<Long> getOperationIdsFrom(Set<JCalendarItemDB> toDelete) {
final List<Long> ids = new ArrayList<Long>();
for (JCalendarItemDB jCalendarItemDB : toDelete) {
if (!jCalendarItemDB.getTableSource().equals(ModuleOperation.TABLE_OPERATION)) {
throw new IllegalStateException("Table is not " + ModuleOperation.TABLE_OPERATION + " but " + jCalendarItemDB.getTableSource());
if (jCalendarItemDB.getSourceElement().getClass() != OperationSQLElement.class) {
throw new IllegalStateException("Table is not " + ModuleOperation.TABLE_OPERATION + " but " + jCalendarItemDB.getSource());
 
}
final long sourceId = jCalendarItemDB.getSourceId();
final long sourceId = jCalendarItemDB.getSource().getID();
if (!ids.contains(sourceId)) {
ids.add(sourceId);
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/CheckList.java
2,7 → 2,6
 
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
 
import javax.swing.JList;
12,44 → 11,50
import org.openconcerto.ui.list.CheckListItem;
import org.openconcerto.ui.list.CheckListRenderer;
 
public class CheckList<T> extends JList {
public class CheckList<T> extends JList<CheckListItem> {
 
public CheckList(ListModel statesModel) {
public CheckList(CheckListModel<T> statesModel) {
super(statesModel);
setCellRenderer(new CheckListRenderer());
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event) {
final JList list = (JList) event.getSource();
final JList<?> list = (JList<?>) event.getSource();
final CheckListModel<?> model = (CheckListModel<?>) list.getModel();
final int index = list.locationToIndex(event.getPoint());
if (index >= 0 && index < list.getModel().getSize()) {
final CheckListItem item = (CheckListItem) list.getModel().getElementAt(index);
if (index >= 0 && index < model.getSize()) {
if (event.getClickCount() == 1) {
item.setSelected(!item.isSelected());
list.repaint(list.getCellBounds(index, index));
model.invertCheckAt(index);
} else {
final boolean newStat = item.isSelected();
final ListModel model = getModel();
final int size = model.getSize();
for (int i = 0; i < size; i++) {
final CheckListItem cItem = (CheckListItem) model.getElementAt(i);
cItem.setSelected(newStat);
model.checkAllAs(index);
}
list.repaint();
 
}
firePropertyChange("checked", null, item);
}
}
 
});
}
 
@Override
public void setModel(ListModel<CheckListItem> model) {
if (!(model instanceof CheckListModel))
throw new IllegalArgumentException("Not a " + CheckListModel.class + " : " + model);
if (((CheckListModel<?>) model).getItemClass() != this.getModel().getItemClass())
throw new IllegalArgumentException("Not same item class");
super.setModel(model);
}
 
@SuppressWarnings("unchecked")
@Override
public CheckListModel<T> getModel() {
return (CheckListModel<T>) super.getModel();
}
 
public boolean isAllSelected() {
final ListModel model = getModel();
final CheckListModel model = getModel();
final int size = model.getSize();
for (int i = 0; i < size; i++) {
final CheckListItem item = (CheckListItem) model.getElementAt(i);
final CheckListItem item = model.getElementAt(i);
if (!item.isSelected()) {
return false;
}
57,17 → 62,8
return true;
}
 
@SuppressWarnings("unchecked")
@Deprecated
public List<T> getSelectedObjects() {
final List<T> result = new ArrayList<T>();
final ListModel model = getModel();
final int size = model.getSize();
for (int i = 0; i < size; i++) {
final CheckListItem item = (CheckListItem) model.getElementAt(i);
if (item.isSelected()) {
result.add((T) item.getObject());
return getModel().getCheckedObjects();
}
}
return result;
}
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationStateListModel.java
16,10 → 16,11
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.ui.list.CheckListItem;
 
public class OperationStateListModel extends CheckListModel {
public class OperationStateListModel extends CheckListModel<String> {
private static List<String> lCache = null;
 
OperationStateListModel() {
super(String.class);
final DBRoot r = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
final SQLTable operationTable = r.getTable(ModuleOperation.TABLE_OPERATION);
operationTable.addTableModifiedListener(new SQLTableModifiedListener() {
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/SiteGroup.java
8,7 → 8,7
public SiteGroup() {
super("operation.site");
final Group g = new Group("operation.site.identifier");
g.addItem("operation.site.label");
g.addItem("operation.site.label", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
g.addItem("operation.site.customer", new LayoutHints(true, false, true, true, true, false));
// g.addItem("operation.site.optionaladdress", new LayoutHints(true, false, true, false,
// true, false));
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/CheckListModel.java
1,7 → 1,11
package org.openconcerto.modules.operation;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import javax.swing.AbstractListModel;
import javax.swing.SwingUtilities;
9,22 → 13,51
 
import org.openconcerto.ui.list.CheckListItem;
 
public abstract class CheckListModel extends AbstractListModel {
import net.jcip.annotations.GuardedBy;
 
public abstract class CheckListModel<T> extends AbstractListModel<CheckListItem> {
private final Class<T> itemClass;
private List<CheckListItem> items = new ArrayList<CheckListItem>();
// don't do multiple loads concurrently, allow to know if an update is coming
@GuardedBy("EDT")
private SwingWorker<?, ?> loadWorker;
// needed so that we can store wantedCheckedKeys before the first fill
@GuardedBy("EDT")
private boolean neverFilled = true;
// keys are needed since other classes might not be able to create instances of T
// e.g. the key is an Integer ID and T is an SQLRow
@GuardedBy("EDT")
private Set<Object> wantedCheckedKeys;
 
public CheckListModel(final Class<T> clazz) {
this.itemClass = clazz;
}
 
public final Class<T> getItemClass() {
return this.itemClass;
}
 
private final List<CheckListItem> getItems() {
assert SwingUtilities.isEventDispatchThread();
return this.items;
}
 
@Override
public int getSize() {
return items.size();
return getItems().size();
}
 
@Override
public Object getElementAt(int index) {
return items.get(index);
public CheckListItem getElementAt(int index) {
return getItems().get(index);
}
 
public void loadContent() {
assert SwingUtilities.isEventDispatchThread();
SwingWorker<List<CheckListItem>, Object> worker = new SwingWorker<List<CheckListItem>, Object>() {
if (this.loadWorker != null) {
this.loadWorker.cancel(true);
}
this.loadWorker = new SwingWorker<List<CheckListItem>, Object>() {
 
@Override
protected List<CheckListItem> doInBackground() throws Exception {
33,43 → 66,119
 
@Override
protected void done() {
// if cancel() is called after doInBackground() nothing happens
// but updating is set to a new instance
if (this.isCancelled() || CheckListModel.this.loadWorker != this) {
// une autre maj arrive
return;
}
 
try {
final List<CheckListItem> l = get();
if (items.isEmpty()) {
final Collection<Object> wantedKeys = getWantedCheckedKeys(true);
final boolean checkAll = items.isEmpty() && wantedKeys == null;
if (checkAll) {
// On ajoute tout, et on sélectionne tout
items.clear();
items.addAll(l);
for (CheckListItem item : items) {
item.setSelected(true);
}
} else {
List<Object> previouslySelectedObject = new ArrayList<Object>();
for (CheckListItem item : items) {
if (item.isSelected()) {
previouslySelectedObject.add(item.getObject());
}
}
final Collection<Object> toCheck = wantedKeys == null ? getCheckedKeys() : wantedKeys;
items.clear();
items.addAll(l);
// restaure la sélection
for (CheckListItem item : items) {
final boolean wasSelected = previouslySelectedObject.contains(item.getObject());
item.setSelected(wasSelected);
_setCheckedKeys(toCheck);
}
}
refresh();
CheckListModel.this.neverFilled = false;
CheckListModel.this.wantedCheckedKeys = null;
fireContentsChanged();
} catch (Exception e) {
e.printStackTrace();
} finally {
assert CheckListModel.this.loadWorker == this;
CheckListModel.this.loadWorker = null;
}
 
}
};
worker.execute();
this.loadWorker.execute();
}
 
public abstract List<CheckListItem> loadItems();
 
public void refresh() {
fireContentsChanged(this, 0, items.size());
protected final void fireContentsChanged() {
fireContentsChanged(this, 0, getSize() - 1);
}
 
public final List<CheckListItem> getCheckedItems() {
final List<CheckListItem> result = new ArrayList<CheckListItem>();
final int size = this.getSize();
for (int i = 0; i < size; i++) {
final CheckListItem item = this.getElementAt(i);
if (item.isSelected()) {
result.add(item);
}
}
return result;
}
 
public final List<T> getCheckedObjects() {
final List<CheckListItem> checkedItems = this.getCheckedItems();
final int size = checkedItems.size();
final List<T> result = new ArrayList<T>(size);
for (int i = 0; i < size; i++) {
result.add(this.itemClass.cast(checkedItems.get(i).getObject()));
}
return result;
}
 
public final List<Object> getCheckedKeys() {
final List<CheckListItem> checkedItems = this.getCheckedItems();
final int size = checkedItems.size();
final List<Object> result = new ArrayList<Object>(size);
for (int i = 0; i < size; i++) {
result.add(checkedItems.get(i).getKey());
}
return result;
}
 
public final Collection<Object> getWantedCheckedKeys(final boolean allowNull) {
if (allowNull || this.wantedCheckedKeys != null)
return this.wantedCheckedKeys;
return this.getCheckedKeys();
}
 
public final void setCheckedKeys(final Collection<?> sel) {
if (this.loadWorker != null || this.neverFilled) {
this.wantedCheckedKeys = Collections.unmodifiableSet(new HashSet<>(sel));
} else {
_setCheckedKeys(sel);
}
}
 
private final void _setCheckedKeys(final Collection<?> sel) {
for (CheckListItem item : this.getItems()) {
item.setSelected(sel.contains(item.getKey()));
}
}
 
public final void invertCheckAt(final int index) {
final CheckListItem item = this.items.get(index);
item.setSelected(!item.isSelected());
fireContentsChanged(this, index, index);
}
 
public final void checkAllAs(final int index) {
final boolean newVal = this.items.get(index).isSelected();
for (final CheckListItem i : this.items) {
i.setSelected(newVal);
}
fireContentsChanged();
}
 
@Override
public String toString() {
return this.getClass().getSimpleName() + " of " + this.getItemClass();
}
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/DailyOperationCalendarPanel.java
1,26 → 1,16
package org.openconcerto.modules.operation;
 
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;
import java.util.List;
 
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
 
import org.jopencalendar.model.JCalendarItemPart;
import org.jopencalendar.ui.ItemPartHoverListener;
import org.jopencalendar.ui.MultipleDayView;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.sql.element.SQLElement;
30,7 → 20,6
import org.openconcerto.sql.users.User;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FrameUtil;
 
/**
42,8 → 31,7
 
private OperationDayView mDayView;
 
public DailyOperationCalendarPanel() {
 
public DailyOperationCalendarPanel(final ComptaPropsConfiguration conf) {
this.setLayout(new BorderLayout());
JPanel toolbar = new JPanel();
toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));
54,41 → 42,24
bCreate.setOpaque(false);
toolbar.add(bCreate);
//
final JButton bPlan = new JButton("Plannifier des interventions");
final JButton bPlan = new JButton("Planifier des interventions");
bPlan.setOpaque(false);
toolbar.add(bPlan);
//
this.add(toolbar, BorderLayout.NORTH);
 
final JPanel filters = createFilterPanel();
split.setLeftComponent(filters);
mDayView = new OperationDayView();
calendar = new MultipleDayCalendarWithToolBar(mDayView);
final MultipleDayView w = calendar.getWeekView();
w.setHourRange(HOUR_START, HOUR_STOP);
w.addItemPartHoverListener(new ItemPartHoverListener() {
 
@Override
public void mouseOn(JCalendarItemPart newSelection) {
if (newSelection == null) {
final int location = split.getDividerLocation();
final JPanel filters = createFilterPanel(conf, w);
split.setLeftComponent(filters);
split.setDividerLocation(location);
} else {
w.setHourRange(HOUR_START, HOUR_STOP);
 
final int location = split.getDividerLocation();
final JCalendarItemInfoPanel comp = new JCalendarItemInfoPanel(newSelection.getItem());
split.setLeftComponent(comp);
split.setDividerLocation(location);
}
 
}
});
 
split.setRightComponent(calendar);
split.setDividerLocation(250);
this.add(split, BorderLayout.CENTER);
ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable("CALENDAR_ITEM").addTableModifiedListener(new SQLTableModifiedListener() {
conf.getRootSociete().getTable("CALENDAR_ITEM").addTableModifiedListener(new SQLTableModifiedListener() {
 
@Override
public void tableModified(SQLTableEvent evt) {
97,7 → 68,7
 
});
 
final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(ModuleOperation.TABLE_OPERATION);
final SQLElement element = conf.getDirectory().getElement(ModuleOperation.TABLE_OPERATION);
// Create a new operation
bCreate.addActionListener(new ActionListener() {
 
122,14 → 93,14
public void actionPerformed(ActionEvent e) {
final MultiOperationSQLComponent comp = new MultiOperationSQLComponent(element);
final EditFrame f = new EditFrame(comp, EditMode.CREATION);
f.setTitle("Plannication d'interventions");
f.setTitle("Planification d'interventions");
FrameUtil.show(f);
}
});
calendar.scrollTo(8);
registerCalendarItemListener(calendar.getWeekView());
 
calendar.getWeekView().setPopupMenuProvider(new OperationMenuProvider());
w.setPopupMenuProvider(new OperationMenuProvider());
this.beginStateSaving(conf.getConfDir(), w);
}
 
public void reload() {
136,69 → 107,18
this.mDayView.reload();
}
 
protected JPanel createFilterPanel() {
@Override
protected void setFilter(final JCheckBox check1, final JCheckBox check2, List<User> users, List<String> states) {
mDayView.setFilter(users, states, check1.isSelected(), check2.isSelected());
}
 
final JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
p.add(new JLabel("Etats"), c);
c.gridy++;
c.weighty = 1;
final OperationStateListModel statesModel = new OperationStateListModel();
statesList = new CheckList<String>(statesModel);
p.add(new JScrollPane(statesList), c);
c.gridy++;
c.weighty = 0;
p.add(new JLabel("Employés"), c);
c.gridy++;
c.weighty = 1;
usersModel = new UserOperationListModel(this);
usesrList = new CheckList<User>(usersModel);
p.add(new JScrollPane(usesrList), c);
c.gridy++;
c.weighty = 0;
final JCheckBox check1 = new JCheckBox("masquer les verrouillés");
p.add(check1, c);
c.gridy++;
final JCheckBox check2 = new JCheckBox("masquer les déverrouillés");
p.add(check2, c);
statesModel.loadContent();
usersModel.loadContent();
 
p.setMinimumSize(new Dimension(200, 200));
p.setPreferredSize(new Dimension(200, 200));
 
final PropertyChangeListener listener = new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
List<User> users = null;
if (!usesrList.isAllSelected()) {
users = getSelectedUsers();
protected Date getViewDate() {
return this.calendar.getDate();
}
List<String> states = null;
if (!statesList.isAllSelected()) {
states = getSelectedStates();
}
mDayView.setFilter(users, states, check1.isSelected(), check2.isSelected());
calendar.reload();
 
@Override
protected void setViewDate(Date d) {
this.calendar.setDate(d);
}
};
statesList.addPropertyChangeListener("checked", listener);
usesrList.addPropertyChangeListener("checked", listener);
check1.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
listener.propertyChange(null);
}
});
check2.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
listener.propertyChange(null);
}
});
return p;
}
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/SiteSQLElement.java
6,6 → 6,7
import org.openconcerto.erp.modules.AbstractModule;
import org.openconcerto.erp.modules.ModuleElement;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.utils.ListMap;
 
public class SiteSQLElement extends ModuleElement {
 
19,6 → 20,11
}
 
@Override
public ListMap<String, String> getShowAs() {
return ListMap.singleton(null, "NAME");
}
 
@Override
protected SQLComponent createComponent() {
return new SiteSQLComponent(this);
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/JCalendarItemDB.java
4,59 → 4,80
 
import org.jopencalendar.model.Flag;
import org.jopencalendar.model.JCalendarItem;
import org.openconcerto.sql.PropsConfiguration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.utils.CollectionUtils;
 
public class JCalendarItemDB extends JCalendarItem {
private final String tableSource;
private final int id;
private final SQLRowValues item;
private final SQLRowValues group;
private final OperationSQLElement operationElem;
private final SQLRowValues operation;
private String status;
private String type;
private int idCalendarGroup;
private String plannerXML;
private String plannerUID;
private String siteName;
private String siteComment;
private Number siteId;
private int idSource;
 
public JCalendarItemDB(int id, String tableSource, int idSource, int idCalendarGroup) {
this.tableSource = tableSource;
this.id = id;
this.idCalendarGroup = idCalendarGroup;
this.idSource = idSource;
public JCalendarItemDB(final SQLElementDirectory dir, final SQLRowValues r) {
assert r.isFrozen();
this.item = r;
this.group = dir.getElement(this.item.getTable()).getContainer(this.item);
this.operationElem = dir.getElement(OperationSQLElement.class);
this.operation = CollectionUtils.getSole(this.group.getReferentRows(this.operationElem.getTable()));
}
 
public SQLElement getSourceElement() {
final SQLElement e = PropsConfiguration.getInstance().getDirectory().getElement(tableSource);
return e;
// OK since frozen
public final SQLRowValues getRow() {
return this.item;
}
 
public String getTableSource() {
return this.tableSource;
public final OperationSQLElement getSourceElement() {
return this.operationElem;
}
 
public int getSourceId() {
return idSource;
// OK since frozen
public final SQLRowValues getSource() {
return this.operation;
}
 
public final boolean isPlanned() {
// there's also a flag "planned" but it's for the UI
return !this.getSource().getString("PLANNER_UID").isEmpty();
}
 
// OK since frozen
public final SQLRowValues getUserRow() {
return (SQLRowValues) this.getSource().getForeign("ID_USER_COMMON");
}
 
// OK since frozen
public final SQLRowValues getCalendarGroup() {
return this.group;
}
 
public int getIdCalendarGroup() {
return idCalendarGroup;
return this.getCalendarGroup().getID();
}
 
@Override
public int hashCode() {
return id;
return this.getId();
}
 
@Override
public boolean equals(Object obj) {
if (obj instanceof JCalendarItemDB) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final JCalendarItemDB o = (JCalendarItemDB) obj;
return o.id == id;
return this.item.equalsAsRow(o.item);
}
return super.equals(obj);
}
 
public void setOperationStatus(String status) {
this.status = status;
128,6 → 149,6
}
 
public int getId() {
return this.id;
return this.getRow().getID();
}
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/OperationCalendarPanel.java
1,30 → 1,22
package org.openconcerto.modules.operation;
 
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
 
import org.jopencalendar.model.Flag;
import org.jopencalendar.model.JCalendarItem;
import org.jopencalendar.model.JCalendarItemPart;
import org.jopencalendar.ui.CalendarWithToolBar;
import org.jopencalendar.ui.ItemPartHoverListener;
import org.jopencalendar.ui.MultipleDayView;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.sql.element.SQLElement;
34,7 → 26,6
import org.openconcerto.sql.users.User;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FrameUtil;
 
/**
45,8 → 36,7
private CalendarWithToolBar calendar;
private OperationCalendarManager manager;
 
public OperationCalendarPanel() {
 
public OperationCalendarPanel(final ComptaPropsConfiguration conf) {
this.setLayout(new BorderLayout());
JPanel toolbar = new JPanel();
toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));
59,40 → 49,24
bCreate.setOpaque(false);
toolbar.add(bCreate);
//
final JButton bPlan = new JButton("Plannifier des interventions");
final JButton bPlan = new JButton("Planifier des interventions");
bPlan.setOpaque(false);
toolbar.add(bPlan);
//
this.add(toolbar, BorderLayout.NORTH);
 
final JPanel filters = createFilterPanel();
split.setLeftComponent(filters);
manager = new OperationCalendarManager("Plannings");
calendar = new CalendarWithToolBar(manager);
final MultipleDayView w = calendar.getWeekView();
w.setHourRange(HOUR_START, HOUR_STOP);
w.addItemPartHoverListener(new ItemPartHoverListener() {
 
@Override
public void mouseOn(JCalendarItemPart newSelection) {
if (newSelection == null) {
final int location = split.getDividerLocation();
final JPanel filters = createFilterPanel(conf, w);
split.setLeftComponent(filters);
split.setDividerLocation(location);
} else {
w.setHourRange(HOUR_START, HOUR_STOP);
 
final int location = split.getDividerLocation();
final JCalendarItemInfoPanel comp = new JCalendarItemInfoPanel(newSelection.getItem());
split.setLeftComponent(comp);
split.setDividerLocation(location);
}
}
});
 
split.setRightComponent(calendar);
split.setDividerLocation(250);
this.add(split, BorderLayout.CENTER);
ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable("CALENDAR_ITEM").addTableModifiedListener(new SQLTableModifiedListener() {
conf.getRootSociete().getTable("CALENDAR_ITEM").addTableModifiedListener(new SQLTableModifiedListener() {
 
@Override
public void tableModified(SQLTableEvent evt) {
118,7 → 92,7
f.setVisible(true);
}
});
final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(ModuleOperation.TABLE_OPERATION);
final SQLElement element = conf.getDirectory().getElement(ModuleOperation.TABLE_OPERATION);
// Create a new operation
bCreate.addActionListener(new ActionListener() {
 
139,109 → 113,44
}
});
calendar.scrollTo(8);
registerCalendarItemListener(calendar.getWeekView());
calendar.getWeekView().setPopupMenuProvider(new OperationMenuProvider());
w.setPopupMenuProvider(new OperationMenuProvider());
this.beginStateSaving(conf.getConfDir(), w);
}
 
public static int getDuration(List<List<JCalendarItem>> list, User u) {
int t = 0;
public static Map<Integer, Long> getDurations(List<List<JCalendarItem>> list, final Flag requiredFlag) {
final Map<Integer, Long> res = new HashMap<>();
final Flag freeTimeFlag = ModuleOperation.FREE_TIME_FLAG;
for (List<JCalendarItem> items : list) {
for (JCalendarItem item : items) {
if (item.getCookie() != null && item.getCookie() instanceof SQLRowValues) {
SQLRowValues user = (SQLRowValues) item.getCookie();
if (user.getID() == u.getId()) {
t += (item.getDtEnd().getTimeInMillis() - item.getDtStart().getTimeInMillis()) / (60 * 1000);
if (!item.hasFlag(freeTimeFlag) && (requiredFlag == null || item.hasFlag(requiredFlag)) && item.getCookie() instanceof SQLRowValues) {
final SQLRowValues user = (SQLRowValues) item.getCookie();
final long toAddMinutes = (item.getDtEnd().getTimeInMillis() - item.getDtStart().getTimeInMillis()) / (60 * 1000);
final Integer key = user.getID();
final Long currentVal = res.get(key);
res.put(key, (currentVal == null ? 0 : currentVal.longValue()) + toAddMinutes);
}
}
}
return res;
}
return t;
}
 
public static int getDurationLocked(List<List<JCalendarItem>> list, User u) {
int t = 0;
final Flag flag = Flag.getFlag("locked");
for (List<JCalendarItem> items : list) {
for (JCalendarItem item : items) {
if (item.hasFlag(flag) && item.getCookie() != null && item.getCookie() instanceof SQLRowValues) {
SQLRowValues user = (SQLRowValues) item.getCookie();
if (user.getID() == u.getId()) {
t += (item.getDtEnd().getTimeInMillis() - item.getDtStart().getTimeInMillis()) / (60 * 1000);
}
}
}
}
return t;
}
 
public void reload() {
calendar.reload();
}
 
private JPanel createFilterPanel() {
@Override
protected void setFilter(final JCheckBox check1, final JCheckBox check2, List<User> users, List<String> states) {
if (manager.setFilter(users, states, check1.isSelected(), check2.isSelected()))
reload();
}
 
final JPanel p = new JPanel();
p.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
p.add(new JLabel("Etats"), c);
c.gridy++;
c.weighty = 1;
final OperationStateListModel statesModel = new OperationStateListModel();
statesList = new CheckList<String>(statesModel);
p.add(new JScrollPane(statesList), c);
c.gridy++;
c.weighty = 0;
p.add(new JLabel("Employés"), c);
c.gridy++;
c.weighty = 1;
usersModel = new UserOperationListModel(this);
usesrList = new CheckList<User>(usersModel);
p.add(new JScrollPane(usesrList), c);
c.gridy++;
c.weighty = 0;
final JCheckBox check1 = new JCheckBox("masquer les verrouillés");
p.add(check1, c);
c.gridy++;
final JCheckBox check2 = new JCheckBox("masquer les déverrouillés");
p.add(check2, c);
statesModel.loadContent();
usersModel.loadContent();
 
p.setMinimumSize(new Dimension(200, 200));
p.setPreferredSize(new Dimension(250, 200));
 
final PropertyChangeListener listener = new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
List<User> users = null;
if (!usesrList.isAllSelected()) {
users = getSelectedUsers();
protected Date getViewDate() {
return this.calendar.getCurrentDate().getTime();
}
List<String> states = null;
if (!statesList.isAllSelected()) {
states = getSelectedStates();
}
manager.setFilter(users, states, check1.isSelected(), check2.isSelected());
reload();
 
@Override
protected void setViewDate(Date d) {
this.calendar.setCurrentDate(d);
}
};
statesList.addPropertyChangeListener("checked", listener);
usesrList.addPropertyChangeListener("checked", listener);
check1.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
listener.propertyChange(null);
}
});
check2.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
listener.propertyChange(null);
}
});
return p;
}
 
}
/trunk/Modules/Module Operation/src/org/openconcerto/modules/operation/UserOperationListModel.java
1,45 → 1,230
package org.openconcerto.modules.operation;
 
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
 
import javax.swing.SwingUtilities;
 
import org.jopencalendar.model.Flag;
import org.jopencalendar.model.JCalendarItem;
import org.jopencalendar.ui.MultipleDayView;
import org.jopencalendar.ui.WeekView;
import org.openconcerto.erp.core.humanresources.payroll.element.SalarieSQLElement;
import org.openconcerto.sql.element.SQLElementDirectory;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.SQLTable.VirtualFields;
import org.openconcerto.sql.model.SQLTableEvent;
import org.openconcerto.sql.model.SQLTableModifiedListener;
import org.openconcerto.sql.users.User;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.ui.DisplayabilityListener;
import org.openconcerto.ui.list.CheckListItem;
 
public class UserOperationListModel extends CheckListModel {
OperationCalendar p;
import net.jcip.annotations.GuardedBy;
 
public UserOperationListModel(OperationCalendar operationCalendarPanel) {
this.p = operationCalendarPanel;
public class UserOperationListModel extends CheckListModel<User> {
 
protected static String formatDuration(int durationMinute) {
int h = durationMinute / 60;
int m = durationMinute % 60;
if (m != 0) {
String mS = String.valueOf(m);
if (m < 10) {
mS = "0" + mS;
}
return h + ":" + mS;
}
return String.valueOf(h);
}
 
private static final class UsersListener implements PropertyChangeListener, SQLTableModifiedListener {
 
private final UserOperationListModel model;
 
protected UsersListener(UserOperationListModel model) {
super();
this.model = model;
}
 
@Override
public List<CheckListItem> loadItems() {
final List<CheckListItem> items = new ArrayList<CheckListItem>();
final List<User> users = UserManager.getInstance().getAllActiveUsers();
public void tableModified(SQLTableEvent evt) {
this.model.refreshUsers();
}
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
this.model.refreshUsers();
}
}
 
private final MultipleDayView view;
private final UserManager userMngr;
private final SalarieSQLElement salarieElem;
 
// all users to display and their the weekly work time, if null, not a Salarie
@GuardedBy("this")
private Map<User, Integer> usersAndWeeklyMinutes;
private final UsersListener usersL = new UsersListener(this);
// durations by user ID
@GuardedBy("this")
private Map<Integer, Long> allDurations;
@GuardedBy("this")
private Map<Integer, Long> lockedDurations;
private final PropertyChangeListener viewL = new PropertyChangeListener() {
@SuppressWarnings("unchecked")
@Override
public void propertyChange(PropertyChangeEvent evt) {
assert SwingUtilities.isEventDispatchThread();
setDurations((List<List<JCalendarItem>>) evt.getNewValue());
loadContent();
}
};
 
public UserOperationListModel(final UserManager userMngr, final SQLElementDirectory dir, final MultipleDayView multipleDayView) {
super(User.class);
this.view = multipleDayView;
this.userMngr = userMngr;
this.salarieElem = dir.getElement(SalarieSQLElement.class);
this.view.addHierarchyListener(new DisplayabilityListener() {
@Override
protected void displayabilityChanged(Component c) {
setRunning(c.isDisplayable());
}
});
// initial value
setRunning(this.view.isDisplayable());
}
 
public final void setRunning(final boolean b) {
if (b) {
this.userMngr.addUsersListener(this.usersL);
for (final SQLTable salT : this.salarieElem.createGraph(VirtualFields.PRIMARY_KEY).getGraphTables()) {
salT.addTableModifiedListener(this.usersL);
}
this.view.addPropertyChangeListener(WeekView.CALENDARD_ITEMS_PROPERTY, this.viewL);
// initial value
refreshUsers();
} else {
this.userMngr.removeUsersListener(this.usersL);
for (final SQLTable salT : this.salarieElem.createGraph(VirtualFields.PRIMARY_KEY).getGraphTables()) {
salT.removeTableModifiedListener(this.usersL);
}
this.view.removePropertyChangeListener(WeekView.CALENDARD_ITEMS_PROPERTY, this.viewL);
}
}
 
private void refreshUsers() {
synchronized (this) {
this.usersAndWeeklyMinutes = null;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
loadContent();
}
});
}
 
private Map<User, Integer> setUsers() {
synchronized (this) {
if (this.usersAndWeeklyMinutes != null) {
return this.usersAndWeeklyMinutes;
}
}
final Map<User, Integer> uInfo = new LinkedHashMap<User, Integer>();
final SQLRowValues v = new SQLRowValues(this.salarieElem.getTable());
v.putNulls("NOM", "PRENOM");
v.putRowValues("ID_INFOS_SALARIE_PAYE").putNulls("DUREE_HEBDO");
final List<SQLRowValues> rows = SQLRowValuesListFetcher.create(v).fetch();
final List<User> users = new ArrayList<>(this.userMngr.getAllActiveUsers());
// Sort by full name
Collections.sort(users, new UserComparator());
// Create list item (with check box)
final int size = users.size();
for (int i = 0; i < size; i++) {
User u = users.get(i);
final User u = users.get(i);
final String name = u.getName().trim();
final String firstName = u.getFirstName();
Integer minutes = null;
for (SQLRowValues row : rows) {
if (row.getString("NOM").trim().equalsIgnoreCase(name) && row.getString("PRENOM").trim().equalsIgnoreCase(firstName)) {
minutes = (int) row.getForeign("ID_INFOS_SALARIE_PAYE").getFloat("DUREE_HEBDO") * 60;
break;
}
}
uInfo.put(u, minutes);
}
synchronized (this) {
this.usersAndWeeklyMinutes = Collections.unmodifiableMap(uInfo);
}
return uInfo;
}
 
private void setDurations(final List<List<JCalendarItem>> viewItems) {
final Map<Integer, Long> all = OperationCalendarPanel.getDurations(viewItems, null);
final Map<Integer, Long> locked = OperationCalendarPanel.getDurations(viewItems, Flag.getFlag("locked"));
synchronized (this) {
this.allDurations = Collections.unmodifiableMap(all);
this.lockedDurations = Collections.unmodifiableMap(locked);
}
}
 
// static to make sure that the returned object doesn't depend on any instance attribute
static protected CheckListItem createItem(final User u, final String label) {
final CheckListItem item = new CheckListItem(u, true) {
 
@Override
public Object getKey() {
return u.getId();
}
 
@Override
public String toString() {
final User user = (User) getObject();
final String info = p.getUserInfo(user);
String name = user.getFullName();
if (info != null) {
name += " " + info;
return label;
}
return name.trim();
}
};
item.setColor(UserColor.getInstance().getColor(u.getId()));
items.add(item);
return item;
}
return items;
 
static private final int getDuration(final Map<Integer, Long> m, final Integer key) {
final Long res = m == null ? null : m.get(key);
return res == null ? 0 : res.intValue();
}
 
@Override
public List<CheckListItem> loadItems() {
final Map<User, Integer> usersAndWeeklyMinutes = setUsers();
final Map<Integer, Long> all, locked;
synchronized (this) {
all = this.allDurations;
locked = this.lockedDurations;
}
final List<CheckListItem> res = new ArrayList<>(usersAndWeeklyMinutes.size());
for (final Entry<User, Integer> e : usersAndWeeklyMinutes.entrySet()) {
final User u = e.getKey();
final Integer weeklyMinutes = e.getValue();
final String suffix;
if (weeklyMinutes == null) {
// not a SALARIE
suffix = "";
} else {
// Durée planifiée
final int d = getDuration(all, u.getId());
// Durée verrouillée
final int d2 = getDuration(locked, u.getId());
suffix = " [" + formatDuration(d2) + " / " + formatDuration(d) + " / " + formatDuration(weeklyMinutes) + "]";
}
res.add(createItem(u, (u.getFullName() + suffix).trim()));
}
return res;
}
}