Java tutorial
/******************************************************************************* * Copyright (C) 2005, 2015 Wolfgang Schramm and Contributors * * 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 version 2 of the License. * * 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 St, Fifth Floor, Boston, MA 02110, USA *******************************************************************************/ package net.tourbook.ui.views.tourCatalog; import java.util.ArrayList; import java.util.Iterator; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import net.tourbook.Messages; import net.tourbook.application.TourbookPlugin; import net.tourbook.common.UI; import net.tourbook.common.formatter.ValueFormat; import net.tourbook.common.formatter.ValueFormatSet; import net.tourbook.common.util.ColumnDefinition; import net.tourbook.common.util.ColumnManager; import net.tourbook.common.util.ITourViewer; import net.tourbook.common.util.PostSelectionProvider; import net.tourbook.common.util.TreeColumnDefinition; import net.tourbook.common.util.TreeViewerItem; import net.tourbook.data.TourData; import net.tourbook.data.TourTag; import net.tourbook.data.TourType; import net.tourbook.database.TourDatabase; import net.tourbook.preferences.ITourbookPreferences; import net.tourbook.tag.TagMenuManager; import net.tourbook.tour.ITourEventListener; import net.tourbook.tour.TourEvent; import net.tourbook.tour.TourEventId; import net.tourbook.tour.TourManager; import net.tourbook.tour.TourTypeMenuManager; import net.tourbook.ui.ITourProvider; import net.tourbook.ui.TreeColumnFactory; import net.tourbook.ui.action.ActionCollapseAll; import net.tourbook.ui.action.ActionEditQuick; import net.tourbook.ui.action.ActionEditTour; import net.tourbook.ui.action.ActionModifyColumns; import net.tourbook.ui.action.ActionOpenTour; import net.tourbook.ui.action.ActionSetTourTypeMenu; import net.tourbook.ui.views.TourInfoToolTipCellLabelProvider; import net.tourbook.ui.views.TreeViewerTourInfoToolTip; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.MenuAdapter; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer; import org.eclipse.ui.part.ViewPart; public class TourCompareResultView extends ViewPart implements ITourViewer, ITourProvider { public static final String ID = "net.tourbook.views.tourCatalog.CompareResultView"; //$NON-NLS-1$ private final IPreferenceStore _prefStore = TourbookPlugin.getDefault().getPreferenceStore(); private final IDialogSettings _state = TourbookPlugin.getDefault() // .getDialogSettingsSection(ID); private TVICompareResultRootItem _rootItem; private PostSelectionProvider _postSelectionProvider; private ISelectionListener _postSelectionListener; private IPartListener2 _partListener; private IPropertyChangeListener _prefChangeListener; private ITourEventListener _tourPropertyListener; private ITourEventListener _compareTourPropertyListener; private boolean _isToolbarCreated; private ColumnManager _columnManager; private TagMenuManager _tagMenuMgr; private SelectionRemovedComparedTours _oldRemoveSelection = null; /* * resources */ private Image _dbImage = TourbookPlugin.getImageDescriptor(// Messages.Image__database).createImage(true); private TreeViewerTourInfoToolTip _tourInfoToolTip; private PixelConverter _pc; /* * UI controls */ private Composite _viewerContainer; private CheckboxTreeViewer _tourViewer; private ActionSaveComparedTours _actionSaveComparedTours; private ActionRemoveComparedTourSaveStatus _actionRemoveComparedTourSaveStatus; private ActionCheckTours _actionCheckTours; private ActionUncheckTours _actionUncheckTours; private ActionModifyColumns _actionModifyColumns; private ActionCollapseAll _actionCollapseAll; private ActionEditQuick _actionEditQuick; private ActionEditTour _actionEditTour; private ActionSetTourTypeMenu _actionSetTourType; private ActionOpenTour _actionOpenTour; class ResultContentProvider implements ITreeContentProvider { @Override public void dispose() { } @Override public Object[] getChildren(final Object parentElement) { return ((TreeViewerItem) parentElement).getFetchedChildrenAsArray(); } @Override public Object[] getElements(final Object inputElement) { return _rootItem.getFetchedChildrenAsArray(); } @Override public Object getParent(final Object element) { return ((TreeViewerItem) element).getParentItem(); } @Override public boolean hasChildren(final Object element) { return ((TreeViewerItem) element).hasChildren(); } @Override public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) { } } public TourCompareResultView() { } private void addCompareTourPropertyListener() { _compareTourPropertyListener = new ITourEventListener() { @Override public void tourChanged(final IWorkbenchPart part, final TourEventId propertyId, final Object propertyData) { if (propertyId == TourEventId.COMPARE_TOUR_CHANGED && propertyData instanceof TourPropertyCompareTourChanged) { final TourPropertyCompareTourChanged compareTourProperty = (TourPropertyCompareTourChanged) propertyData; final long compareId = compareTourProperty.compareId; final ArrayList<Long> compareIds = new ArrayList<Long>(); compareIds.add(compareId); if (compareId == -1) { // compare result is not saved final Object comparedTourItem = compareTourProperty.comparedTourItem; if (comparedTourItem instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour resultItem = (TVICompareResultComparedTour) comparedTourItem; // resultItem.movedStartIndex = compareTourProperty.startIndex; // resultItem.movedEndIndex = compareTourProperty.endIndex; resultItem.movedSpeed = compareTourProperty.speed; // update viewer _tourViewer.update(comparedTourItem, null); } } else { // compare result is saved // find compared tour in the viewer final ArrayList<TVICompareResultComparedTour> comparedTours = new ArrayList<TVICompareResultComparedTour>(); getComparedTours(comparedTours, _rootItem, compareIds); if (comparedTours.size() > 0) { final TVICompareResultComparedTour compareTourItem = comparedTours.get(0); if (compareTourProperty.isDataSaved) { // compared tour was saved compareTourItem.dbStartIndex = compareTourProperty.startIndex; compareTourItem.dbEndIndex = compareTourProperty.endIndex; compareTourItem.dbSpeed = compareTourProperty.speed; } else { // compareTourItem.movedStartIndex = compareTourProperty.startIndex; // compareTourItem.movedEndIndex = compareTourProperty.endIndex; compareTourItem.movedSpeed = compareTourProperty.speed; } // update viewer _tourViewer.update(compareTourItem, null); } } } } }; TourManager.getInstance().addTourEventListener(_compareTourPropertyListener); } /** * set the part listener to save the view settings, the listeners are called before the controls * are disposed */ private void addPartListeners() { _partListener = new IPartListener2() { @Override public void partActivated(final IWorkbenchPartReference partRef) { } @Override public void partBroughtToTop(final IWorkbenchPartReference partRef) { } @Override public void partClosed(final IWorkbenchPartReference partRef) { if (partRef.getPart(false) == TourCompareResultView.this) { saveState(); clearCompareResult(); } } @Override public void partDeactivated(final IWorkbenchPartReference partRef) { } @Override public void partHidden(final IWorkbenchPartReference partRef) { } @Override public void partInputChanged(final IWorkbenchPartReference partRef) { } @Override public void partOpened(final IWorkbenchPartReference partRef) { /* * add the actions in the part open event so they are appended AFTER the actions * which are defined in the plugin.xml */ fillToolbar(); } @Override public void partVisible(final IWorkbenchPartReference partRef) { } }; getViewSite().getPage().addPartListener(_partListener); } private void addPrefListener() { _prefChangeListener = new IPropertyChangeListener() { @Override public void propertyChange(final PropertyChangeEvent event) { final String property = event.getProperty(); if (property.equals(ITourbookPreferences.MEASUREMENT_SYSTEM)) { // measurement system has changed net.tourbook.ui.UI.updateUnits(); _columnManager.saveState(_state); _columnManager.clearColumns(); defineAllColumns(_viewerContainer); recreateViewer(null); } else if (property.equals(ITourbookPreferences.VIEW_LAYOUT_CHANGED)) { _tourViewer.getTree() .setLinesVisible(_prefStore.getBoolean(ITourbookPreferences.VIEW_LAYOUT_DISPLAY_LINES)); _tourViewer.refresh(); /* * the tree must be redrawn because the styled text does not show with the new * color */ _tourViewer.getTree().redraw(); } } }; _prefStore.addPropertyChangeListener(_prefChangeListener); } /** * Listen to post selections */ private void addSelectionListeners() { _postSelectionListener = new ISelectionListener() { @Override public void selectionChanged(final IWorkbenchPart part, final ISelection selection) { onSelectionChanged(part, selection); } }; // register selection listener in the page getSite().getPage().addPostSelectionListener(_postSelectionListener); } private void addTourEventListener() { _tourPropertyListener = new ITourEventListener() { @Override public void tourChanged(final IWorkbenchPart part, final TourEventId eventId, final Object eventData) { if (part == TourCompareResultView.this) { return; } if (eventId == TourEventId.TOUR_CHANGED && eventData instanceof TourEvent) { final ArrayList<TourData> modifiedTours = ((TourEvent) eventData).getModifiedTours(); if (modifiedTours != null) { updateTourViewer(_rootItem, modifiedTours); } } else if (eventId == TourEventId.TAG_STRUCTURE_CHANGED) { reloadViewer(); } } }; TourManager.getInstance().addTourEventListener(_tourPropertyListener); } private void clearCompareResult() { TourCompareManager.getInstance().clearCompareResult(); } private void createActions() { _actionSaveComparedTours = new ActionSaveComparedTours(this); _actionRemoveComparedTourSaveStatus = new ActionRemoveComparedTourSaveStatus(this); _actionCheckTours = new ActionCheckTours(this); _actionUncheckTours = new ActionUncheckTours(this); _actionSetTourType = new ActionSetTourTypeMenu(this); _tagMenuMgr = new TagMenuManager(this, true); _actionEditQuick = new ActionEditQuick(this); _actionEditTour = new ActionEditTour(this); _actionOpenTour = new ActionOpenTour(this); _actionModifyColumns = new ActionModifyColumns(this); _actionCollapseAll = new ActionCollapseAll(this); } @Override public void createPartControl(final Composite parent) { _pc = new PixelConverter(parent); // define all columns for the viewer _columnManager = new ColumnManager(this, _state); // _columnManager.setIsCategoryAvailable(true); defineAllColumns(parent); createUI(parent); addPartListeners(); addSelectionListeners(); addCompareTourPropertyListener(); addPrefListener(); addTourEventListener(); createActions(); fillViewMenu(); getSite().setSelectionProvider(_postSelectionProvider = new PostSelectionProvider(ID)); _tourViewer.setInput(_rootItem = new TVICompareResultRootItem()); } private void createUI(final Composite parent) { _viewerContainer = new Composite(parent, SWT.NONE); GridLayoutFactory.fillDefaults().applyTo(_viewerContainer); { createUI_10_TourViewer(_viewerContainer); } } private Control createUI_10_TourViewer(final Composite parent) { // tour tree final Tree tree = new Tree(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION | SWT.CHECK); GridDataFactory.fillDefaults().grab(true, true).applyTo(tree); tree.setHeaderVisible(true); tree.setLinesVisible(_prefStore.getBoolean(ITourbookPreferences.VIEW_LAYOUT_DISPLAY_LINES)); _tourViewer = new ContainerCheckedTreeViewer(tree); _columnManager.createColumns(_tourViewer); _tourViewer.setContentProvider(new ResultContentProvider()); _tourViewer.setUseHashlookup(true); _tourViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(final SelectionChangedEvent event) { onSelect(event); } }); _tourViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(final DoubleClickEvent event) { // expand/collapse current item final Object treeItem = ((IStructuredSelection) event.getSelection()).getFirstElement(); if (_tourViewer.getExpandedState(treeItem)) { _tourViewer.collapseToLevel(treeItem, 1); } else { _tourViewer.expandToLevel(treeItem, 1); } } }); _tourViewer.getTree().addKeyListener(new KeyAdapter() { @Override public void keyPressed(final KeyEvent keyEvent) { if (keyEvent.keyCode == SWT.DEL) { removeComparedTourFromDb(); } } }); _tourViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(final CheckStateChangedEvent event) { if (event.getElement() instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareResult = (TVICompareResultComparedTour) event .getElement(); if (event.getChecked() && compareResult.isSaved()) { /* * uncheck elements which are already stored for the reftour, it would be * better to disable them, but this is not possible because this is a * limitation by the OS */ _tourViewer.setChecked(compareResult, false); } else { enableActions(); } } else { // uncheck all other tree items _tourViewer.setChecked(event.getElement(), false); } } }); createUI_20_ContextMenu(); // set tour info tooltip provider _tourInfoToolTip = new TreeViewerTourInfoToolTip(_tourViewer); return tree; } /** * create the views context menu */ private void createUI_20_ContextMenu() { final MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(final IMenuManager manager) { fillContextMenu(manager); } }); final Tree tree = (Tree) _tourViewer.getControl(); final Menu treeContextMenu = menuMgr.createContextMenu(tree); treeContextMenu.addMenuListener(new MenuAdapter() { @Override public void menuHidden(final MenuEvent e) { _tagMenuMgr.onHideMenu(); } @Override public void menuShown(final MenuEvent menuEvent) { _tagMenuMgr.onShowMenu(menuEvent, tree, Display.getCurrent().getCursorLocation(), _tourInfoToolTip); } }); _columnManager.createHeaderContextMenu(tree, treeContextMenu); } private void defineAllColumns(final Composite parent) { defineColumn_1st_ComparedTour(); defineColumn_Data_Diff(); defineColumn_Motion_SpeedComputed(); defineColumn_Motion_SpeedSaved(); defineColumn_Motion_SpeedMoved(); defineColumn_Motion_Distance(); defineColumn_Data_TimeInterval(); defineColumn_Tour_Type(); defineColumn_Tour_Title(); defineColumn_Tour_Tags(); } /** * tree column: reference tour/date */ private void defineColumn_1st_ComparedTour() { final TreeColumnDefinition colDef = new TreeColumnDefinition(_columnManager, "comparedTour", SWT.LEAD); //$NON-NLS-1$ colDef.setIsDefaultColumn(); colDef.setColumnLabel(Messages.Compare_Result_Column_tour); colDef.setColumnHeaderText(Messages.Compare_Result_Column_tour); colDef.setDefaultColumnWidth(_pc.convertWidthInCharsToPixels(25) + 16); colDef.setCanModifyVisibility(false); colDef.setLabelProvider(new TourInfoToolTipCellLabelProvider() { @Override public Long getTourId(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultReferenceTour) { return ((TVICompareResultReferenceTour) element).tourId; } else if (element instanceof TVICompareResultComparedTour) { return ((TVICompareResultComparedTour) element).comparedTourData.getTourId(); } return null; } @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultReferenceTour) { final TVICompareResultReferenceTour refItem = (TVICompareResultReferenceTour) element; cell.setText(refItem.label); } else if (element instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareItem = (TVICompareResultComparedTour) element; cell.setText(TourManager.getTourDateShort(compareItem.comparedTourData)); // display an image when a tour is saved if (compareItem.isSaved()) { cell.setImage(_dbImage); } else { cell.setImage(null); } } setCellColor(cell, element); } }); } /** * column: altitude difference */ private void defineColumn_Data_Diff() { final TreeColumnDefinition colDef = new TreeColumnDefinition(_columnManager, "diff", SWT.TRAIL); //$NON-NLS-1$ colDef.setIsDefaultColumn(); colDef.setColumnHeaderText(Messages.Compare_Result_Column_diff); colDef.setColumnHeaderToolTipText(Messages.Compare_Result_Column_diff_tooltip); colDef.setColumnLabel(Messages.Compare_Result_Column_diff_label); colDef.setDefaultColumnWidth(_pc.convertWidthInCharsToPixels(8)); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareItem = (TVICompareResultComparedTour) element; final float value = (compareItem.minAltitudeDiff * 100) / (compareItem.normalizedEndIndex - compareItem.normalizedStartIndex); cell.setText(Integer.toString((int) value)); setCellColor(cell, element); } } }); } /** * column: time interval */ private void defineColumn_Data_TimeInterval() { final TreeColumnDefinition colDef = TreeColumnFactory.DATA_TIME_INTERVAL.createColumn(_columnManager, _pc); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { cell.setText(Integer.toString(((TVICompareResultComparedTour) element).timeIntervall)); setCellColor(cell, element); } } }); } /** * column: distance */ private void defineColumn_Motion_Distance() { final TreeColumnDefinition colDef = TreeColumnFactory.MOTION_DISTANCE.createColumn(_columnManager, _pc); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareItem = (TVICompareResultComparedTour) element; final float value = compareItem.compareDistance / (1000 * net.tourbook.ui.UI.UNIT_VALUE_DISTANCE); colDef.printDetailValue(cell, value); setCellColor(cell, element); } } }); } /** * column: speed computed */ private void defineColumn_Motion_SpeedComputed() { final TreeColumnDefinition colDef = new TreeColumnDefinition(_columnManager, "speedComputed", SWT.TRAIL); //$NON-NLS-1$ colDef.setIsDefaultColumn(); colDef.setColumnHeaderText(UI.UNIT_LABEL_SPEED); colDef.setColumnUnit(UI.UNIT_LABEL_SPEED); colDef.setColumnHeaderToolTipText(Messages.Compare_Result_Column_kmh_tooltip); colDef.setColumnLabel(Messages.Compare_Result_Column_kmh_label); colDef.setDefaultColumnWidth(_pc.convertWidthInCharsToPixels(8)); colDef.setValueFormats(// ValueFormatSet.Number, ValueFormat.NUMBER_1_1, _columnManager); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareItem = (TVICompareResultComparedTour) element; final double value = compareItem.compareSpeed / net.tourbook.ui.UI.UNIT_VALUE_DISTANCE; colDef.printDetailValue(cell, value); setCellColor(cell, element); } } }); } /** * column: speed moved */ private void defineColumn_Motion_SpeedMoved() { final TreeColumnDefinition colDef = new TreeColumnDefinition(_columnManager, "speedMoved", SWT.TRAIL); //$NON-NLS-1$ colDef.setColumnHeaderText(UI.UNIT_LABEL_SPEED); colDef.setColumnUnit(UI.UNIT_LABEL_SPEED); colDef.setColumnHeaderToolTipText(Messages.Compare_Result_Column_kmh_moved_tooltip); colDef.setColumnLabel(Messages.Compare_Result_Column_kmh_moved_label); colDef.setDefaultColumnWidth(_pc.convertWidthInCharsToPixels(8)); colDef.setValueFormats(// ValueFormatSet.Number, ValueFormat.NUMBER_1_1, _columnManager); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareItem = (TVICompareResultComparedTour) element; final double value = compareItem.movedSpeed / net.tourbook.ui.UI.UNIT_VALUE_DISTANCE; colDef.printDetailValue(cell, value); setCellColor(cell, element); } } }); } /** * column: speed saved */ private void defineColumn_Motion_SpeedSaved() { final TreeColumnDefinition colDef = new TreeColumnDefinition(_columnManager, "speedSaved", SWT.TRAIL); //$NON-NLS-1$ colDef.setColumnHeaderText(UI.UNIT_LABEL_SPEED); colDef.setColumnUnit(UI.UNIT_LABEL_SPEED); colDef.setColumnHeaderToolTipText(Messages.Compare_Result_Column_kmh_db_tooltip); colDef.setColumnLabel(Messages.Compare_Result_Column_kmh_db_label); colDef.setDefaultColumnWidth(_pc.convertWidthInCharsToPixels(8)); colDef.setValueFormats(// ValueFormatSet.Number, ValueFormat.NUMBER_1_1, _columnManager); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareItem = (TVICompareResultComparedTour) element; final double value = compareItem.dbSpeed / net.tourbook.ui.UI.UNIT_VALUE_DISTANCE; colDef.printDetailValue(cell, value); setCellColor(cell, element); } } }); } /** * column: tags */ private void defineColumn_Tour_Tags() { final TreeColumnDefinition colDef = TreeColumnFactory.TOUR_TAGS.createColumn(_columnManager, _pc); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { final Set<TourTag> tourTags = ((TVICompareResultComparedTour) element).comparedTourData .getTourTags(); if (tourTags.size() == 0) { // the tags could have been removed, set empty field cell.setText(UI.EMPTY_STRING); } else { cell.setText(TourDatabase.getTagNames(tourTags)); setCellColor(cell, element); } } } }); } /** * column: title */ private void defineColumn_Tour_Title() { final TreeColumnDefinition colDef = TreeColumnFactory.TOUR_TITLE.createColumn(_columnManager, _pc); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { cell.setText(((TVICompareResultComparedTour) element).comparedTourData.getTourTitle()); setCellColor(cell, element); } } }); } /** * column: tour type */ private void defineColumn_Tour_Type() { final TreeColumnDefinition colDef = TreeColumnFactory.TOUR_TYPE.createColumn(_columnManager, _pc); colDef.setLabelProvider(new CellLabelProvider() { @Override public void update(final ViewerCell cell) { final Object element = cell.getElement(); if (element instanceof TVICompareResultComparedTour) { final TourData comparedTourData = ((TVICompareResultComparedTour) element).comparedTourData; final TourType tourType = comparedTourData.getTourType(); if (tourType != null) { cell.setImage(net.tourbook.ui.UI.getInstance().getTourTypeImage(tourType.getTypeId())); } } } }); } @Override public void dispose() { getSite().getPage().removePostSelectionListener(_postSelectionListener); getSite().getPage().removePartListener(_partListener); TourManager.getInstance().removeTourEventListener(_compareTourPropertyListener); TourManager.getInstance().removeTourEventListener(_tourPropertyListener); _prefStore.removePropertyChangeListener(_prefChangeListener); _dbImage.dispose(); super.dispose(); } private void enableActions() { final ITreeSelection selection = (ITreeSelection) _tourViewer.getSelection(); int tourItems = 0; int otherItems = 0; int savedTourItems = 0; int unsavedTourItems = 0; TVICompareResultComparedTour firstTourItem = null; TVICompareResultComparedTour firstCheckedItem = null; TVICompareResultComparedTour firstSelectedItem = null; /* * count selected items */ int selectedTours = 0; for (final Iterator<?> iter = selection.iterator(); iter.hasNext();) { final Object treeItem = iter.next(); if (treeItem instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour comparedTourItem = (TVICompareResultComparedTour) treeItem; // count tours if (tourItems == 0) { firstTourItem = comparedTourItem; firstSelectedItem = comparedTourItem; } tourItems++; // count saved tours if (comparedTourItem.isSaved()) { savedTourItems++; } else { unsavedTourItems++; } selectedTours++; } else { otherItems++; } } /* * count checked items */ int checkedTours = 0; for (final Object checkedElement : _tourViewer.getCheckedElements()) { if (checkedElement instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour comparedTourItem = (TVICompareResultComparedTour) checkedElement; // count tours if (tourItems <= 1) { firstTourItem = comparedTourItem; firstCheckedItem = comparedTourItem; } tourItems++; // count saved tours if (comparedTourItem.isSaved()) { savedTourItems++; } else { unsavedTourItems++; } checkedTours++; } } final boolean isTourSelected = tourItems > 0 && otherItems == 0; boolean isOneTour = tourItems == 1 && otherItems == 0; boolean isOneTourSelected = selectedTours == 1; // check if the same tour is selected and/or checked if (tourItems == 2 && otherItems == 0 && firstSelectedItem == firstCheckedItem) { isOneTour = true; isOneTourSelected = true; } _actionCheckTours.setEnabled(unsavedTourItems > 0); _actionUncheckTours.setEnabled(checkedTours > 0); // action: save compare result _actionSaveComparedTours.setEnabled(unsavedTourItems > 0); // action: remove tour from saved compare result, currently only one tour item is supported _actionRemoveComparedTourSaveStatus.setEnabled(savedTourItems > 0); // actions: edit tour _actionEditQuick.setEnabled(isOneTourSelected); _actionEditTour.setEnabled(isOneTourSelected); _actionOpenTour.setEnabled(isOneTourSelected); // action: tour type final ArrayList<TourType> tourTypes = TourDatabase.getAllTourTypes(); _actionSetTourType.setEnabled(isTourSelected && tourTypes.size() > 0); // tags: add/remove/remove all Set<TourTag> allExistingTags = null; long existingTourTypeId = TourDatabase.ENTITY_IS_NOT_SAVED; if (isOneTour) { // one tour is selected allExistingTags = firstTourItem.comparedTourData.getTourTags(); final TourType tourType = firstTourItem.comparedTourData.getTourType(); existingTourTypeId = tourType == null ? TourDatabase.ENTITY_IS_NOT_SAVED : tourType.getTypeId(); } _tagMenuMgr.enableTagActions(isTourSelected, isOneTour, allExistingTags); TourTypeMenuManager.enableRecentTourTypeActions(isTourSelected, existingTourTypeId); } private void fillContextMenu(final IMenuManager menuMgr) { menuMgr.add(_actionSaveComparedTours); menuMgr.add(_actionRemoveComparedTourSaveStatus); menuMgr.add(_actionCheckTours); menuMgr.add(_actionUncheckTours); menuMgr.add(new Separator()); menuMgr.add(_actionEditQuick); menuMgr.add(_actionEditTour); menuMgr.add(_actionOpenTour); // tour tag actions _tagMenuMgr.fillTagMenu(menuMgr); // tour type actions menuMgr.add(new Separator()); menuMgr.add(_actionSetTourType); TourTypeMenuManager.fillMenuWithRecentTourTypes(menuMgr, this, true); enableActions(); } private void fillToolbar() { // check if toolbar is created if (_isToolbarCreated) { return; } _isToolbarCreated = true; final IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager(); tbm.add(_actionCollapseAll); tbm.update(true); } private void fillViewMenu() { /* * fill view menu */ final IMenuManager menuMgr = getViewSite().getActionBars().getMenuManager(); menuMgr.add(_actionModifyColumns); } @Override public ColumnManager getColumnManager() { return _columnManager; } /** * Recursive method to walk down the tour tree items and find the compared tours * * @param parentItem * @param CompareIds */ private void getComparedTours(final ArrayList<TVICompareResultComparedTour> comparedTours, final TreeViewerItem parentItem, final ArrayList<Long> CompareIds) { final ArrayList<TreeViewerItem> unfetchedChildren = parentItem.getUnfetchedChildren(); if (unfetchedChildren != null) { // children are available for (final TreeViewerItem treeItem : unfetchedChildren) { if (treeItem instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour ttiCompResult = (TVICompareResultComparedTour) treeItem; final long compId = ttiCompResult.compId; for (final Long removedCompId : CompareIds) { if (compId == removedCompId) { comparedTours.add(ttiCompResult); } } } else { // this is a child which can be the parent for other childs getComparedTours(comparedTours, treeItem, CompareIds); } } } } private TVICompareResultComparedTour getSelectedComparedTour() { final TreeSelection selection = (TreeSelection) _tourViewer.getSelection(); for (final Iterator<?> iterator = selection.iterator(); iterator.hasNext();) { final Object treeItem = iterator.next(); if (treeItem instanceof TVICompareResultComparedTour) { return (TVICompareResultComparedTour) treeItem; } } return null; } private TVICompareResultReferenceTour getSelectedRefTour() { final TreeSelection selection = (TreeSelection) _tourViewer.getSelection(); for (final Iterator<?> iterator = selection.iterator(); iterator.hasNext();) { final Object treeItem = iterator.next(); if (treeItem instanceof TVICompareResultReferenceTour) { return (TVICompareResultReferenceTour) treeItem; } } return null; } @Override public ArrayList<TourData> getSelectedTours() { // get selected tours final IStructuredSelection selectedTours = ((IStructuredSelection) _tourViewer.getSelection()); final ArrayList<TourData> selectedTourData = new ArrayList<TourData>(); // loop: all selected tours for (final Iterator<?> iter = selectedTours.iterator(); iter.hasNext();) { final Object treeItem = iter.next(); if (treeItem instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareItem = ((TVICompareResultComparedTour) treeItem); final TourData tourData = TourManager.getInstance() .getTourData(compareItem.comparedTourData.getTourId()); if (tourData != null) { selectedTourData.add(tourData); } } } return selectedTourData; } /** * @return Returns the tour viewer */ @Override public CheckboxTreeViewer getViewer() { return _tourViewer; } TVICompareResultComparedTour navigateTour(final boolean isNextTour) { final TVICompareResultComparedTour selectedCompareResult = getSelectedComparedTour(); if (selectedCompareResult != null) { // compared tour is selected final TreeViewerItem parentItem = selectedCompareResult.getParentItem(); if (parentItem instanceof TVICompareResultReferenceTour) { final TVICompareResultReferenceTour refTourItem = (TVICompareResultReferenceTour) parentItem; final ArrayList<TreeViewerItem> children = refTourItem.getChildren(); for (int childIndex = 0; childIndex < children.size(); childIndex++) { final TreeViewerItem refTourChild = children.get(childIndex); if (refTourChild == selectedCompareResult) { if (isNextTour) { // navigate next if (childIndex < children.size() - 1) { // next tour is available final TreeViewerItem nextRefTourChild = children.get(childIndex + 1); if (nextRefTourChild instanceof TVICompareResultComparedTour) { return (TVICompareResultComparedTour) nextRefTourChild; } } else { // return first tour final TreeViewerItem nextRefTourChild = children.get(0); if (nextRefTourChild instanceof TVICompareResultComparedTour) { return (TVICompareResultComparedTour) nextRefTourChild; } } } else { // navigate previous if (childIndex > 0) { // previous tour is available final TreeViewerItem nextChild = children.get(childIndex - 1); if (nextChild instanceof TVICompareResultComparedTour) { return (TVICompareResultComparedTour) nextChild; } } else { // return last tour final TreeViewerItem prevChild = children.get(children.size() - 1); if (prevChild instanceof TVICompareResultComparedTour) { return (TVICompareResultComparedTour) prevChild; } } } } } } } else { final TVICompareResultReferenceTour selectedRefTour = getSelectedRefTour(); if (selectedRefTour != null) { // ref tour is selected final ArrayList<TreeViewerItem> refChildren = selectedRefTour.getFetchedChildren(); if (refChildren.size() > 0) { // navigate to the first child and ignore direction _tourViewer.expandToLevel(selectedRefTour, 1); // return first tour final TreeViewerItem nextRefTourChild = refChildren.get(0); if (nextRefTourChild instanceof TVICompareResultComparedTour) { return (TVICompareResultComparedTour) nextRefTourChild; } } } } return null; } private void onSelect(final SelectionChangedEvent event) { final IStructuredSelection selection = (IStructuredSelection) event.getSelection(); final Object treeItem = selection.getFirstElement(); if (treeItem instanceof TVICompareResultReferenceTour) { final TVICompareResultReferenceTour refItem = (TVICompareResultReferenceTour) treeItem; _postSelectionProvider.setSelection(new SelectionTourCatalogView(refItem.refTourItem.refId)); } else if (treeItem instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour resultItem = (TVICompareResultComparedTour) treeItem; _postSelectionProvider.setSelection(new StructuredSelection(resultItem)); } } private void onSelectionChanged(final IWorkbenchPart part, final ISelection selection) { if (part == TourCompareResultView.this) { return; } if (selection instanceof StructuredSelection) { final Object firstElement = ((StructuredSelection) selection).getFirstElement(); if (firstElement instanceof TVICompareResultComparedTour) { _tourViewer.setSelection(selection, true); } } else if (selection instanceof SelectionRemovedComparedTours) { removeComparedToursFromViewer(selection); } else if (selection instanceof SelectionPersistedCompareResults) { final SelectionPersistedCompareResults selectionPersisted = (SelectionPersistedCompareResults) selection; final ArrayList<TVICompareResultComparedTour> persistedCompareResults = selectionPersisted.persistedCompareResults; if (persistedCompareResults.size() > 0) { final TVICompareResultComparedTour comparedTourItem = persistedCompareResults.get(0); // uncheck persisted tours _tourViewer.setChecked(comparedTourItem, false); // update changed item _tourViewer.update(comparedTourItem, null); } } } @Override public ColumnViewer recreateViewer(final ColumnViewer columnViewer) { _viewerContainer.setRedraw(false); { final Object[] expandedElements = _tourViewer.getExpandedElements(); final ISelection selection = _tourViewer.getSelection(); _tourViewer.getTree().dispose(); createUI_10_TourViewer(_viewerContainer); _viewerContainer.layout(); _tourViewer.setInput(_rootItem = new TVICompareResultRootItem()); _tourViewer.setExpandedElements(expandedElements); _tourViewer.setSelection(selection); } _viewerContainer.setRedraw(true); return _tourViewer; } @Override public void reloadViewer() { final Tree tree = _tourViewer.getTree(); tree.setRedraw(false); { final Object[] expandedElements = _tourViewer.getExpandedElements(); final ISelection selection = _tourViewer.getSelection(); _tourViewer.setInput(_rootItem = new TVICompareResultRootItem()); _tourViewer.setExpandedElements(expandedElements); _tourViewer.setSelection(selection); } tree.setRedraw(true); } /** * Remove compared tour from the database */ void removeComparedTourFromDb() { final StructuredSelection selection = (StructuredSelection) _tourViewer.getSelection(); final SelectionRemovedComparedTours selectionRemovedCompareTours = new SelectionRemovedComparedTours(); final ArrayList<Long> removedComparedTours = selectionRemovedCompareTours.removedComparedTours; for (final Iterator<?> iterator = selection.iterator(); iterator.hasNext();) { final Object selectedElement = iterator.next(); if (selectedElement instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour compareItem = (TVICompareResultComparedTour) selectedElement; if (TourCompareManager.removeComparedTourFromDb(compareItem.compId)) { removedComparedTours.add(compareItem.compId); } } } if (removedComparedTours.size() > 0) { _postSelectionProvider.setSelection(selectionRemovedCompareTours); removeComparedToursFromViewer(selectionRemovedCompareTours); } } private void removeComparedToursFromViewer(final ISelection selection) { final SelectionRemovedComparedTours removedTourSelection = (SelectionRemovedComparedTours) selection; final ArrayList<Long> removedTourCompareIds = removedTourSelection.removedComparedTours; /* * return when there are no removed tours or when the selection has not changed */ if (removedTourCompareIds.size() == 0 || removedTourSelection == _oldRemoveSelection) { return; } _oldRemoveSelection = removedTourSelection; /* * find/update the removed compared tours in the viewer */ final ArrayList<TVICompareResultComparedTour> comparedTourItems = new ArrayList<TVICompareResultComparedTour>(); getComparedTours(comparedTourItems, _rootItem, removedTourCompareIds); // reset entity for the removed compared tours for (final TVICompareResultComparedTour removedTourItem : comparedTourItems) { removedTourItem.compId = -1; removedTourItem.dbStartIndex = -1; removedTourItem.dbEndIndex = -1; removedTourItem.dbSpeed = 0; // removedTourItem.movedStartIndex = -1; // removedTourItem.movedEndIndex = -1; removedTourItem.movedSpeed = 0; } // update viewer _tourViewer.update(comparedTourItems.toArray(), null); } /** * Persist the compared tours which are checked or selected */ @SuppressWarnings("unchecked") void saveCompareResults() { final EntityManager em = TourDatabase.getInstance().getEntityManager(); if (em != null) { final EntityTransaction ts = em.getTransaction(); try { final ArrayList<TVICompareResultComparedTour> updatedItems = new ArrayList<TVICompareResultComparedTour>(); final SelectionPersistedCompareResults compareResultSelection = new SelectionPersistedCompareResults(); final ArrayList<TVICompareResultComparedTour> persistedCompareResults = compareResultSelection.persistedCompareResults; /* * save checked items */ for (final Object checkedItem : _tourViewer.getCheckedElements()) { if (checkedItem instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour checkedCompareItem = (TVICompareResultComparedTour) checkedItem; if (checkedCompareItem.isSaved() == false) { TourCompareManager.saveComparedTourItem(checkedCompareItem, em, ts); persistedCompareResults.add(checkedCompareItem); updatedItems.add(checkedCompareItem); } } } /* * save selected items which are not checked */ final TreeSelection selection = (TreeSelection) _tourViewer.getSelection(); for (final Iterator<Object> iterator = selection.iterator(); iterator.hasNext();) { final Object treeItem = iterator.next(); if (treeItem instanceof TVICompareResultComparedTour) { final TVICompareResultComparedTour selectedComparedItem = (TVICompareResultComparedTour) treeItem; if (selectedComparedItem.isSaved() == false) { TourCompareManager.saveComparedTourItem(selectedComparedItem, em, ts); persistedCompareResults.add(selectedComparedItem); updatedItems.add(selectedComparedItem); } } } // uncheck all _tourViewer.setCheckedElements(new Object[0]); // update persistent status _tourViewer.update(updatedItems.toArray(), null); // fire post selection to update the tour catalog view _postSelectionProvider.setSelection(compareResultSelection); } catch (final Exception e) { e.printStackTrace(); } finally { if (ts.isActive()) { ts.rollback(); } em.close(); } } } private void saveState() { _columnManager.saveState(_state); } private void setCellColor(final ViewerCell cell, final Object element) { if (element instanceof TVICompareResultReferenceTour) { cell.setForeground(JFaceResources.getColorRegistry().get(net.tourbook.ui.UI.VIEW_COLOR_TITLE)); } else if (element instanceof TVICompareResultComparedTour) { // show the saved tours in a different color if (((TVICompareResultComparedTour) (element)).isSaved()) { cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); } else { // show the text with tour color cell.setForeground(JFaceResources.getColorRegistry().get(net.tourbook.ui.UI.VIEW_COLOR_TOUR)); // cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND)); } } } @Override public void setFocus() { _tourViewer.getTree().setFocus(); } @Override public void updateColumnHeader(final ColumnDefinition colDef) { // TODO Auto-generated method stub } /** * !!!Recursive !!! update all tour items with new data * * @param rootItem * @param modifiedTours */ private void updateTourViewer(final TreeViewerItem parentItem, final ArrayList<TourData> modifiedTours) { final ArrayList<TreeViewerItem> children = parentItem.getUnfetchedChildren(); if (children == null) { return; } // loop: all children for (final Object object : children) { final TreeViewerItem treeItem = (TreeViewerItem) object; if (object instanceof TVICompareResultComparedTour) { // update compared items final TVICompareResultComparedTour compareItem = (TVICompareResultComparedTour) treeItem; final TourData comparedTourData = compareItem.comparedTourData; final long tourItemId = comparedTourData.getTourId(); for (final TourData modifiedTourData : modifiedTours) { if (modifiedTourData.getTourId().longValue() == tourItemId) { comparedTourData.setTourType(modifiedTourData.getTourType()); comparedTourData.setTourTitle(modifiedTourData.getTourTitle()); comparedTourData.setTourTags(modifiedTourData.getTourTags()); // update item in the viewer _tourViewer.update(compareItem, null); break; } } } else { // update children updateTourViewer(treeItem, modifiedTours); } } } }