/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * For information about the authors of this project Have a look * at the AUTHORS file in the root of this project. */ package net.sourceforge.fullsync.ui; import java.io.IOException; import net.sourceforge.fullsync.ExceptionHandler; import net.sourceforge.fullsync.IoStatistics; import net.sourceforge.fullsync.Synchronizer; import net.sourceforge.fullsync.Task; import net.sourceforge.fullsync.TaskFinishedEvent; import net.sourceforge.fullsync.TaskTree; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableItem; public class TaskDecisionPage extends WizardDialog { private GuiController guiController; private TaskTree taskTree; private boolean processing; private int tasksFinished; private int tasksTotal; private TaskDecisionList list; private Combo comboFilter; private Label labelProgress; public TaskDecisionPage(Shell parent, GuiController guiController, TaskTree taskTree) { super(parent); this.guiController = guiController; this.taskTree = taskTree; } @Override public String getTitle() { return Messages.getString("TaskDecisionPage.TaskDecision"); //$NON-NLS-1$ } @Override public String getCaption() { return Messages.getString("TaskDecisionPage.ChooseTheActions"); //$NON-NLS-1$ } @Override public String getDescription() { return Messages.getString("TaskDecisionPage.Source") + ": " + taskTree.getSource().getConnectionDescription().getDisplayPath() + "\n" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Messages.getString("TaskDecisionPage.Destination") + ": " + taskTree.getDestination().getConnectionDescription().getDisplayPath(); //$NON-NLS-1$ //$NON-NLS-2$ } @Override public Image getIcon() { return GuiController.getInstance().getImage("Tasklist_Icon.png"); //$NON-NLS-1$ } @Override public Image getImage() { return GuiController.getInstance().getImage("Tasklist_Wizard.png"); //$NON-NLS-1$ } @Override public void createContent(final Composite content) { content.setLayout(new GridLayout(2, false)); // filter combo comboFilter = new Combo(content, SWT.DROP_DOWN | SWT.READ_ONLY); comboFilter.add(Messages.getString("TaskDecisionPage.Everything")); //$NON-NLS-1$ comboFilter.add(Messages.getString("TaskDecisionPage.ChangesOnly")); //$NON-NLS-1$ comboFilter.select(1); comboFilter.addModifyListener(e -> { if (!processing) { list.setOnlyChanges(comboFilter.getSelectionIndex() == 1); if (taskTree != null) { list.rebuildActionList(); } } }); // progress label labelProgress = new Label(content, SWT.NONE); GridData labelProgressLData = new GridData(); labelProgressLData.horizontalAlignment = SWT.FILL; labelProgressLData.horizontalIndent = 5; labelProgressLData.grabExcessHorizontalSpace = true; labelProgress.setLayoutData(labelProgressLData); Synchronizer synchronizer = GuiController.getInstance().getSynchronizer(); IoStatistics stats = synchronizer.getIoStatistics(taskTree); labelProgress.setText("Totals: " + stats.getCountActions() + " tasks, " + UISettings.formatSize(stats.getBytesTransferred())); list = new TaskDecisionList(content, SWT.NULL); list.setTaskTree(taskTree); GridData listLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true); listLayoutData.horizontalSpan = 2; list.setLayoutData(listLayoutData); list.setOnlyChanges(true); if (taskTree != null) { list.rebuildActionList(); } } @Override public boolean apply() { if (!processing) { setCancelButtonEnabled(false); performActions(); } return false; } @Override public boolean cancel() { if (!processing) { try { taskTree.getSource().close(); } catch (IOException ioe) { ExceptionHandler.reportException(ioe); } try { taskTree.getDestination().close(); } catch (IOException ioe) { ExceptionHandler.reportException(ioe); } return true; } MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); mb.setText(Messages.getString("TaskDecisionPage.Error")); //$NON-NLS-1$ mb.setMessage(Messages.getString("TaskDecisionPage.SyncWindowCantBeClosed")); //$NON-NLS-1$ mb.open(); //TODO: implement canceling a running profile return false; } void performActions() { Thread worker = new Thread(() -> { guiController.showBusyCursor(true); final Display display = getDisplay(); try { processing = true; list.setChangeAllowed(false); Synchronizer synchronizer = GuiController.getInstance().getSynchronizer(); IoStatistics stats = synchronizer.getIoStatistics(taskTree); tasksTotal = stats.getCountActions(); tasksFinished = 0; final Color colorFinishedSuccessful = new Color(null, 150, 255, 150); final Color colorFinishedUnsuccessful = new Color(null, 255, 150, 150); display.syncExec(() -> setOkButtonEnabled(false)); final GUIUpdateQueue<TaskFinishedEvent> updateQueue = new GUIUpdateQueue<TaskFinishedEvent>(display, (display1, items) -> { TableItem item = null; System.err.println("GUIUpdateQueue<TaskFinishedEvent>::doUpdate: " + items.size()); for (TaskFinishedEvent event : items) { tasksFinished++; // TODO: move this into one translatable string with arguments labelProgress .setText(tasksFinished + " " + Messages.getString("TaskDecisionPage.of") + " " + tasksTotal + " " + Messages.getString("TaskDecisionPage.tasksFinished")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ Task task = event.getTask(); item = list.getTableItemForTask(task); // FIXME This doesn't seams to work. Even if there is an exception in the sync of one item // the item is colored with the "successful" color. if (item != null) { if (event.isSuccessful()) { item.setBackground(colorFinishedSuccessful); } else { item.setBackground(colorFinishedUnsuccessful); } } } if (null != item) { list.showItem(item); } }); synchronizer.performActions(taskTree, e -> updateQueue.add(e)); display.asyncExec(() -> { // Notification Window. MessageBox mb = new MessageBox(getShell(), SWT.ICON_INFORMATION | SWT.OK); mb.setText(Messages.getString("TaskDecisionPage.Finished")); //$NON-NLS-1$ mb.setMessage(Messages.getString("TaskDecisionPage.ProfileFinished")); //$NON-NLS-1$ mb.open(); checkAndCancel(); }); } catch (Exception e) { ExceptionHandler.reportException(e); } finally { guiController.showBusyCursor(false); processing = false; list.setChangeAllowed(true); } }, "ActionPerformer"); //$NON-NLS-1$ worker.start(); } }