This is an automated email from the git hooks/post-receive script. New commit to branch feature/sync in repository jtimer. See https://gitlab.nuiton.org/chorem/jtimer.git commit b7083543390046a16354a2038ef2df26498fd00c Author: servantie <servantie.c@gmail.com> Date: Tue Jul 19 17:09:52 2016 +0200 turned the jcombobox into a jtable for url edition --- .../org/chorem/jtimer/data/TimerDataManager.java | 14 - .../java/org/chorem/jtimer/entities/TimerTask.java | 2 +- .../jtimer/ui/report/TimerTaskSyncInfoEditor.java | 440 ++++++++++----------- .../resources/TimerTaskSyncInfoEditor.properties | 12 +- .../TimerTaskSyncInfoEditor_fr.properties | 15 +- 5 files changed, 226 insertions(+), 257 deletions(-) diff --git a/src/main/java/org/chorem/jtimer/data/TimerDataManager.java b/src/main/java/org/chorem/jtimer/data/TimerDataManager.java index f459fff..6d03164 100644 --- a/src/main/java/org/chorem/jtimer/data/TimerDataManager.java +++ b/src/main/java/org/chorem/jtimer/data/TimerDataManager.java @@ -670,18 +670,4 @@ public class TimerDataManager { log.debug("SyncInfo deleted: " + info.getSyncURL()); } } -// -// /** -// * When a task is synced -// * @param task -// * @param syncInfo -// */ -// public void taskSynchronized(TimerTask task, SyncInfo syncInfo) { -// for (DataEventListener dataEventListener: dataEventListeners) { -// dataEventListener.taskSynchronized(task, syncInfo); -// } -// if (log.isDebugEnabled()) { -// log.debug("Task " + task.getName() + " synced at " + syncInfo.getSyncURL()); -// } -// } } diff --git a/src/main/java/org/chorem/jtimer/entities/TimerTask.java b/src/main/java/org/chorem/jtimer/entities/TimerTask.java index 8213f47..35996a7 100644 --- a/src/main/java/org/chorem/jtimer/entities/TimerTask.java +++ b/src/main/java/org/chorem/jtimer/entities/TimerTask.java @@ -318,7 +318,7 @@ public class TimerTask implements Cloneable, */ public void addSyncInfo(SyncInfo info) { - if (!getSynchronizingInfoList().contains(info)) { + if (!getSynchronizingInfoList().contains(info) && !info.getSyncURL().isEmpty()) { synchronisingInfoList.add(info); } } diff --git a/src/main/java/org/chorem/jtimer/ui/report/TimerTaskSyncInfoEditor.java b/src/main/java/org/chorem/jtimer/ui/report/TimerTaskSyncInfoEditor.java index 45128ef..6e67b42 100644 --- a/src/main/java/org/chorem/jtimer/ui/report/TimerTaskSyncInfoEditor.java +++ b/src/main/java/org/chorem/jtimer/ui/report/TimerTaskSyncInfoEditor.java @@ -24,25 +24,21 @@ package org.chorem.jtimer.ui.report; import com.google.gson.JsonObject; import java.awt.BorderLayout; +import java.awt.Component; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.DefaultComboBoxModel; +import java.util.List; import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; import javax.swing.JComponent; -import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.table.AbstractTableModel; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.jtimer.data.TimerCore; @@ -50,7 +46,6 @@ import org.chorem.jtimer.entities.SyncInfo; import org.chorem.jtimer.entities.TimerTask; import org.chorem.jtimer.entities.TimerTaskHelper; import org.chorem.jtimer.io.TimerTaskSynchronizer; -import org.jdesktop.application.Action; import org.jdesktop.application.Application; import org.jdesktop.application.FrameView; @@ -59,7 +54,7 @@ import org.jdesktop.application.FrameView; * * Created by servantie on 13/05/16. */ -public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener, ItemListener { +public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener { /** Class logger */ protected static Log log = LogFactory.getLog(TimerTaskSyncInfoEditor.class); @@ -67,11 +62,8 @@ public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener /** Timer core. */ protected TimerCore core; - /** Include annotations on updates */ - protected JCheckBox checkIncludesAnnotations; - - /** Activate a sync URL */ - protected JCheckBox checkIsActiveSync; + /** button to add a URL */ + protected JButton addButton; /** button to delete a URL */ protected JButton deleteButton; @@ -79,14 +71,8 @@ public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener /** button to test a url */ protected JButton testSyncUrlButton; - /** ComboBox of URLs */ - protected JComboBox<SyncInfo> urlComboBox; - - /** LastSync */ - protected JLabel lastUpdate; - - /** lastSync Label */ - protected JLabel lastSyncDateLabel; + /** JTable of URLs */ + protected JTable urlJTable; /** task to update */ protected TimerTask task; @@ -116,8 +102,6 @@ public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener df = new SimpleDateFormat("dd/MM/yy HH:mm:ss"); setComponent(getMainComponent()); - - } /** @@ -133,67 +117,22 @@ public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener JPanel urlPanel = new JPanel(); urlPanel.setLayout(new BorderLayout(5,5)); - //url combobox - JLabel urlcomboBoxLabel = new JLabel(getResourceMap().getString("urlComboLabel")); - urlComboBox = new JComboBox<>(new DefaultComboBoxModel<>()); - //make it editable to add new urls - urlComboBox.setEditable(true); - urlComboBox.addItemListener(this); - urlComboBox.addActionListener(this); - //add the urls to the combobox - for (SyncInfo info : task.getSynchronizingInfoList()) { - urlComboBox.addItem(info); - } - urlComboBox.setActionCommand("comboBox"); - - urlPanel.add(urlcomboBoxLabel, BorderLayout.NORTH); - urlPanel.add(urlComboBox, BorderLayout.SOUTH); - - //a box containing the url sync time label and the checkboxes - Box labelBox = new Box(BoxLayout.PAGE_AXIS); - - - //checkbox to include annotations - checkIncludesAnnotations = new JCheckBox(); - checkIncludesAnnotations.setAction(getContext().getActionMap(this).get("isIncludingAnnotations")); - //checkbox for active sync - checkIsActiveSync = new JCheckBox(); - checkIsActiveSync.addActionListener(this); - checkIsActiveSync.setAction(getContext().getActionMap(this).get("isActiveSync")); - //display last Sync time - lastSyncDateLabel = new JLabel(getResourceMap().getString("lastUpdateLabel")); - lastUpdate = new JLabel(); - if (urlComboBox.getSelectedItem() != null) { - SyncInfo selectedInfo = (SyncInfo) urlComboBox.getSelectedItem(); - if (task.getSynchronizingInfoList().contains(selectedInfo)){ - SyncInfo syncInfo = task.getSynchronizingInfo(selectedInfo.getSyncURL()); - Date lastSyncTime = syncInfo.getLastSync(); - //if there has been an update before, display its date - if ((lastSyncTime != null) && lastSyncTime.after(new Date(0))) { - lastUpdate.setText(df.format(lastSyncTime)); - //logging change of lastSync - if (log.isDebugEnabled()) { - log.debug("Last Sync time loaded : " + lastSyncTime.toString()); - } - lastSyncDateLabel.setVisible(true); - } - else { - if (log.isDebugEnabled()) { - log.debug("No Last Sync time loaded"); - } - lastSyncDateLabel.setVisible(false); - } - checkIsActiveSync.setSelected(task.getSynchronizingInfo(selectedInfo.getSyncURL()).getIsActiveSync()); - } - } - labelBox.add(checkIsActiveSync); - labelBox.add(checkIncludesAnnotations); - labelBox.add(lastSyncDateLabel); - labelBox.add(lastUpdate); - - //box to hold the delete button and the test sync button - Box deleteBox = new Box(BoxLayout.PAGE_AXIS); - //option to delete url + + urlJTable = new JTable(new SyncInfoTableModel()); + + + //add the headers and the table + urlPanel.add(urlJTable.getTableHeader(), BorderLayout.NORTH); + urlPanel.add(urlJTable, BorderLayout.CENTER); + + //panel to hold the buttons + JPanel buttonPane = new JPanel(); + buttonPane.setAlignmentX(Component.CENTER_ALIGNMENT); + + addButton = new JButton(getResourceMap().getString("addButton")); + addButton.addActionListener(this); + addButton.setActionCommand("addURL"); + deleteButton = new JButton(getResourceMap().getString("deleteButton")); deleteButton.addActionListener(this); deleteButton.setActionCommand("deleteURL"); @@ -202,19 +141,16 @@ public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener testSyncUrlButton.addActionListener(this); testSyncUrlButton.setActionCommand("testURL"); - - deleteBox.add(deleteButton); - deleteBox.add(testSyncUrlButton); - - // button to close + buttonPane.add(addButton); + buttonPane.add(testSyncUrlButton); + buttonPane.add(deleteButton); + // button to close JButton closeButton = new JButton(); closeButton.setAction(getContext().getActionMap(this).get("closeView")); //adding components to the main one - configComponent.add(urlPanel, BorderLayout.NORTH); - configComponent.add(labelBox, BorderLayout.WEST); - configComponent.add(deleteBox, BorderLayout.EAST); + configComponent.add(buttonPane, BorderLayout.CENTER); configComponent.add(closeButton, BorderLayout.SOUTH); // color fix on linux ? @@ -233,42 +169,6 @@ public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener getApplication().hide(this); } - - /** - * Add annotation checkbox checked. - */ - @Action - public boolean isIncludingAnnotations() { - boolean ischeckedIncludeAnnotations = checkIncludesAnnotations.isSelected(); - if (urlComboBox.getSelectedItem() instanceof SyncInfo) { - SyncInfo syncInfo = (SyncInfo) urlComboBox.getSelectedItem(); - task.getSynchronizingInfo(syncInfo.getSyncURL()).setIsWithAnnotations(ischeckedIncludeAnnotations); - core.getData().syncInfoChanged(task,syncInfo); - - } - if (log.isDebugEnabled()) { - log.debug("Inclusion of annotations in sync changed"); - } - return ischeckedIncludeAnnotations; - } - - /** - * Active sync checkbox checked, activates sync - */ - @Action - public boolean isActiveSync() { - boolean isActiveSyncURL = checkIsActiveSync.isSelected(); - if (urlComboBox.getSelectedItem() instanceof SyncInfo) { - SyncInfo syncInfo = (SyncInfo) urlComboBox.getSelectedItem(); - task.getSynchronizingInfo(syncInfo.getSyncURL()).setIsActiveSync(isActiveSyncURL); - core.getData().syncInfoChanged(task,syncInfo); - } - if (log.isDebugEnabled()) { - log.debug("Activity of url changed "); - } - return isActiveSyncURL; - } - /** * Method to display an error message * @param errorMessage the message to display @@ -288,127 +188,209 @@ public class TimerTaskSyncInfoEditor extends FrameView implements ActionListener JOptionPane.showMessageDialog(null, infoMessage, titleBar, JOptionPane.INFORMATION_MESSAGE); } - /** - * when an item is added to the list, - * add it to the url displayed, and to the syncInfo of the task + * Class to deal with the SyncInfos in a table */ - public void itemAdded(String urlToAdd){ - if ((urlToAdd != null) && (!urlToAdd.isEmpty()) && ((!task.getSynchronizingURLList().contains(urlToAdd)))) { - SyncInfo infoToAdd = new SyncInfo(urlToAdd); - core.getData().syncInfoChanged(task, infoToAdd); - urlComboBox.addItem(infoToAdd); - if (log.isDebugEnabled()) { - log.debug("New SyncInfo with URL : " + urlToAdd); - } + protected class SyncInfoTableModel extends AbstractTableModel { + + /** the syncInfo list */ + protected List<SyncInfo> syncInfoList; + + /** headers of the columns */ + protected String[] columnHeaders= {getResourceMap().getString("syncURLHeader"), getResourceMap().getString("isActiveHeader"), + getResourceMap().getString("isWithAnnotationsHeader"), getResourceMap().getString("lastSyncHeader")}; + + + public SyncInfoTableModel() { syncInfoList = task.getSynchronizingInfoList(); } + + + /** + * Gets the column headers + * @param col the column + * @return a string for the header + */ + @Override + public String getColumnName(int col) { + return columnHeaders[col]; } - } - /** - * deals with item selection in the combobox - * @param itemEvent - */ - @Override - public void itemStateChanged(ItemEvent itemEvent) { - if (itemEvent.getStateChange()== ItemEvent.SELECTED) { - if (urlComboBox.getSelectedItem() != null) { - SyncInfo syncInfo; - String urlToDisplay; - if (urlComboBox.getSelectedItem() instanceof String) { - urlToDisplay = (String)urlComboBox.getSelectedItem(); - //trim the whitespaces - urlToDisplay = urlToDisplay.trim(); - syncInfo = new SyncInfo(urlToDisplay); - urlComboBox.setSelectedItem(syncInfo); + @Override + public int getRowCount() { + return syncInfoList.size(); + } - } - else { - syncInfo = (SyncInfo) urlComboBox.getSelectedItem(); - urlToDisplay = syncInfo.getSyncURL(); - } - if (!urlToDisplay.isEmpty()) { - if (log.isDebugEnabled()) { - log.debug("Selected an object : " + urlToDisplay); - } - if (checkIsActiveSync != null) { - checkIsActiveSync.setSelected(syncInfo.getIsActiveSync()); - } - if (checkIncludesAnnotations != null) { - checkIncludesAnnotations.setSelected(syncInfo.getIsWithAnnotations()); - } - //display last Sync Time - if (lastUpdate != null && syncInfo.getLastSync() != null) { - if (syncInfo.getLastSync().after(new Date(0))) { - lastUpdate.setText(df.format(syncInfo.getLastSync())); - lastUpdate.setVisible(true); - lastSyncDateLabel.setVisible(true); - } - else { - lastUpdate.setVisible(false); - lastSyncDateLabel.setVisible(false); - } - } - } + /** + * returns the column number (url, activity, annotations and last sync, so 4) + */ + @Override + public int getColumnCount() { + return 4; + } + + /** + * Returns the value at rowIndex, columnIndex + * column 0 is url String, column 1 is activity boolean, + * column 2 is annotations boolean, column 3 is lastSync Date + * @param rowIndex + * @param columnIndex + * @return an Object + */ + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + Object value = ""; + SyncInfo syncInfo = syncInfoList.get(rowIndex); + switch (columnIndex) { + case 0: + value = syncInfo.getSyncURL(); + break; + case 1: + value = syncInfo.getIsActiveSync(); + break; + case 2: + value = syncInfo.getIsWithAnnotations(); + break; + case 3: + value = syncInfo.getLastSync(); + break; } + return value; } - } - @Override - public void actionPerformed(ActionEvent actionEvent) { + /** + * When the data is changed + * @param value an object -a string- + * @param rowIndex the row selected + * @param columnIndex the column modified + */ + @Override + public void setValueAt(Object value, int rowIndex, int columnIndex) { + SyncInfo syncInfo = syncInfoList.get(rowIndex); + //if the url changes + if (columnIndex == 0) { + syncInfo.setSyncURL((String) value); + } + //if the checkbox of activity changes + else if (columnIndex == 1) { + syncInfo.setIsActiveSync((Boolean) value); + } + //if the checkbox of annotation changes + else if (columnIndex == 2) { + syncInfo.setIsWithAnnotations((Boolean) value); + } + else if (columnIndex == 3) { + syncInfo.setLastSync(new Date()); + } + core.getData().syncInfoChanged(task, syncInfo); - String actionCommand = actionEvent.getActionCommand(); - SyncInfo infoToUse; - String urlToUse; - if (urlComboBox.getSelectedItem() instanceof String) { - urlToUse = (String) urlComboBox.getSelectedItem(); - infoToUse = new SyncInfo(urlToUse); } - else{ - infoToUse = (SyncInfo) urlComboBox.getSelectedItem(); - urlToUse = infoToUse.getSyncURL(); + + /** To mark the url and checkbox cells as editable but not the date + * + * @param rowIndex + * @param columnIndex + * @return + */ + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + //the sync date is not editable + if (columnIndex >= 3) { + return false; + } + else { + return true; + } } - if ("deleteURL".equals(actionCommand)) { - //if the delete button has been clicked, delete the task (if it exists) - if ((task.getSynchronizingInfoList().contains(infoToUse))) { - task.removeSyncInfo(infoToUse); - urlComboBox.removeItem(infoToUse); - core.getData().deleteSyncInfo(task, infoToUse); - } else { - errorBox(getResourceMap().getString("deleteErrorMessage"), getResourceMap().getString("deleteErrorTitle")); + + /** Returns the class of objects in the columns + * + * @param columnIndex + * @return the class + */ + + @Override + public Class<?> getColumnClass(int columnIndex) { + if (columnIndex == 0) { + return String.class; } + else if(columnIndex == 1 || columnIndex == 2) { + return Boolean.class; + } + else if (columnIndex == 3) { + return Date.class; + } + return Object.class; } - else if ("comboBoxEdited".equals(actionCommand)) { - if (!task.getSynchronizingInfoList().contains(infoToUse)) { - if (log.isDebugEnabled()) { - log.debug("New URL added"); - } - itemAdded(urlToUse); + + /** + * Adds a syncInfo + * @param sync + */ + public void add(SyncInfo sync) { + if (!syncInfoList.contains(sync)) { + syncInfoList.add(sync); + fireTableRowsInserted(syncInfoList.indexOf(sync), syncInfoList.indexOf(sync)); } - else if (log.isDebugEnabled()) { - log.debug("No addition"); + } + + /** + * removes a syncInfo + * @param sync + */ + public void remove(SyncInfo sync) { + if (syncInfoList.contains(sync)) { + fireTableRowsDeleted(syncInfoList.indexOf(sync), syncInfoList.indexOf(sync)); + syncInfoList.remove(sync); } + } + } + @Override + public void actionPerformed(ActionEvent actionEvent) { + + String actionCommand = actionEvent.getActionCommand(); + SyncInfo infoToUse; + SyncInfoTableModel model = (SyncInfoTableModel) urlJTable.getModel(); + + if ("addURL".equals(actionCommand)) { + model.add(new SyncInfo("")); } - else if ("testURL".equals(actionCommand)) { - //if the test button has been clicked, test the sync on the URL and returns a message to the user - //tests only if the info exists - if (task.getSynchronizingInfoList().contains(infoToUse)) { - JsonObject testObject = TimerTaskHelper.taskURLToJSONObject(task, urlToUse, isIncludingAnnotations(), timezone); - int responseCode = TimerTaskSynchronizer.synchronizeTaskOnURL(testObject); - if (responseCode > 199 && responseCode < 300) { - infoBox(getResourceMap().getString("testSyncSuccessMessage"), getResourceMap().getString("testSyncSuccessTitle")); - Calendar cal = Calendar.getInstance(); - infoToUse.setLastSync(cal.getTime()); - //update the last synctime displayed - lastUpdate.setVisible(true); - lastSyncDateLabel.setVisible(true); - lastUpdate.setText(df.format(infoToUse.getLastSync())); + else if (!task.getSynchronizingInfoList().isEmpty()) { + //first check that a row is selected + if (urlJTable.getSelectedRow() != -1) { + infoToUse = task.getSynchronizingInfo((String) urlJTable.getModel().getValueAt(urlJTable.getSelectedRow(), 0)); + if ("deleteURL".equals(actionCommand)) { + if (!((SyncInfoTableModel) urlJTable.getModel()).syncInfoList.isEmpty()) { + //if the delete button has been clicked, delete the task (if it exists) + if ((task.getSynchronizingInfoList().contains(infoToUse))) { + task.removeSyncInfo(infoToUse); + model.remove(infoToUse); + core.getData().deleteSyncInfo(task, infoToUse); + } else { + errorBox(getResourceMap().getString("deleteErrorMessage"), getResourceMap().getString("deleteErrorTitle")); + } } else { - errorBox(getResourceMap().getString("testSyncFailureMessage"), getResourceMap().getString("testSyncFailureTitle")); + errorBox(getResourceMap().getString("deleteErrorMessage"), getResourceMap().getString("deleteErrorTitle")); } } + else if ("testURL".equals(actionCommand)) { + //if the test button has been clicked, test the sync on the URL and returns a message to the user + //tests only if the info exists + if (task.getSynchronizingInfoList().contains(infoToUse)) { + JsonObject testObject = TimerTaskHelper.taskURLToJSONObject(task, infoToUse.getSyncURL(), false, timezone); + int responseCode = TimerTaskSynchronizer.synchronizeTaskOnURL(testObject); + if (responseCode > 199 && responseCode < 300) { + infoBox(getResourceMap().getString("testSyncSuccessMessage"), getResourceMap().getString("testSyncSuccessTitle")); + Calendar cal = Calendar.getInstance(); + infoToUse.setLastSync(cal.getTime()); + } + else { + errorBox(getResourceMap().getString("testSyncFailureMessage"), getResourceMap().getString("testSyncFailureTitle")); + } + } + } + } } else { if (log.isDebugEnabled()) { diff --git a/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskSyncInfoEditor.properties b/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskSyncInfoEditor.properties index 990a73e..dc0e956 100644 --- a/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskSyncInfoEditor.properties +++ b/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskSyncInfoEditor.properties @@ -20,11 +20,6 @@ # #L% ### syncTitle=${Application.title} - Edition of Synchronization Info -syncGeneral=General -syncOptions=Options - -lastUpdateLabel=Last Synchronization at: -urlComboLabel = Synchronization Url: updateAnnotations.Action.text = Include annotations updateAnnotations.Action.shortDescription = Include annotations @@ -37,10 +32,15 @@ deleteButton = Delete URL deleteErrorMessage = No URL to delete deleteErrorTitle = Deletion error +addButton = Add URL + testSyncButton = Test URL testSyncSuccessMessage = Synchronization test successful ! testSyncSuccessTitle = Successful test testSyncFailureMessage = Test failed to synchronize, check the URL ? testSyncFailureTitle = Synchronization test failure -isActiveSync.Action.text = Active synchronization \ No newline at end of file +syncURLHeader = URL +isActiveHeader = is Active +isWithAnnotationsHeader = With annotations +lastSyncHeader = Last Synchronization \ No newline at end of file diff --git a/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskSyncInfoEditor_fr.properties b/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskSyncInfoEditor_fr.properties index d3e733c..cd69cce 100644 --- a/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskSyncInfoEditor_fr.properties +++ b/src/main/resources/org/chorem/jtimer/ui/report/resources/TimerTaskSyncInfoEditor_fr.properties @@ -21,13 +21,7 @@ ### # update i18n syncTitle=${Application.title} - Edition de la Synchronisation -syncGeneral=G\u00E9n\u00E9ral -syncOptions=Options -lastUpdateLabel=Derni\u00E8re synchronisation : -urlComboLabel=Url de synchronisation : - -isIncludingAnnotations.Action.text = Inclure les annotations closeView.Action.text = &Fermer closeView.Action.icon = dialog-close.png @@ -37,10 +31,17 @@ deleteButton = Supprimer l'URL deleteErrorMessage = Aucune URL \u00E0 supprimer deleteErrorTitle = Erreur de suppression +addButton = Ajouter une URL + testSyncButton = Tester l'URL testSyncSuccessMessage = Test r\u00E9ussi, URL de synchronisation valide ! testSyncSuccessTitle = Test r\u00E9ussi testSyncFailureMessage = Test \u00E9chou\u00E9, v\u00E9rifier l'URL ? testSyncFailureTitle = Echec du test de synchronisation -isActiveSync.Action.text = Synchronisation Active \ No newline at end of file +isActiveSync.Action.text = Synchronisation Active + +syncURLHeader = URL +isActiveHeader = Active +isWithAnnotationsHeader = Avec annotations +lastSyncHeader = Derni\u00E8re synchronisation \ No newline at end of file -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.