Dépôt officiel du code source de l'ERP OpenConcerto
/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; |
} |
} |