Commit 192df697 authored by Adrien's avatar Adrien Committed by GitHub
Browse files

fix(selection): selected line is invisible on macos (#2512)

* Since the Big Sur update, the behavior of the StyledCellLabelProvider
has changed. Depending on the content of the styled cell, the erase
method needs to perform some stuff or others (sending en paint signal
isn't always enough).

[STUDIO-3705](https://bonitasoft.atlassian.net/browse/STUDIO-3705)
[STUDIO-3708](https://bonitasoft.atlassian.net/browse/STUDIO-3708)
parent 4efda936
......@@ -14,13 +14,19 @@
*/
package org.bonitasoft.studio.application.ui.control;
import java.util.Objects;
import org.bonitasoft.studio.common.repository.model.IDisplayable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Event;
public class DeployTreeLabelProvider extends StyledCellLabelProvider implements ILabelProvider {
......@@ -42,7 +48,7 @@ public class DeployTreeLabelProvider extends StyledCellLabelProvider implements
@Override
public Image getImage(Object element) {
if(element instanceof IDisplayable) {
if (element instanceof IDisplayable) {
return ((IDisplayable) element).getIcon();
}
return null;
......@@ -50,10 +56,30 @@ public class DeployTreeLabelProvider extends StyledCellLabelProvider implements
@Override
public String getText(Object element) {
if(element instanceof IDisplayable) {
if (element instanceof IDisplayable) {
return ((IDisplayable) element).getDisplayName();
}
return element.toString();
}
@Override
protected void erase(Event event, Object element) {
super.erase(event, element);
// Necessary since the MacOS Big Sur update -> Seems that table with StyledCellLabelProvider aren't redraw automatically
// TODO Hopefully this could be removed on the futur (current date: 19/11/2020)
if (Objects.equals(Platform.OS_MACOSX, Platform.getOS())) {
Rectangle bounds = event.getBounds();
if ((event.detail & SWT.SELECTED) != 0) {
Color oldForeground = event.gc.getForeground();
event.gc.setForeground(event.item.getDisplay().getSystemColor(
SWT.COLOR_LIST_SELECTION_TEXT));
event.gc.fillRectangle(bounds);
/* restore the old GC colors */
event.gc.setForeground(oldForeground);
event.detail &= ~SWT.SELECTED;
}
}
}
}
......@@ -45,6 +45,7 @@ import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
......@@ -57,6 +58,7 @@ import org.eclipse.jface.layout.LayoutConstants;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
......@@ -205,6 +207,12 @@ public class AttributeEditionControl extends Composite {
viewer.setInput(fieldsObservable);
selectedFieldObservable = ViewerProperties.singleSelection(Field.class).observe(viewer);
// Necessary since the MacOS Big Sur update -> Seems that table with StyledCellLabelProvider aren't redraw automatically
// TODO Hopefully this could be removed on the futur (current date: 19/11/2020)
if (Objects.equals(Platform.OS_MACOSX, Platform.getOS())) {
selectedBoObservable.addValueChangeListener(e -> viewer.getTable().redraw());
}
addDragAndDropSupport();
}
......@@ -302,10 +310,10 @@ public class AttributeEditionControl extends Composite {
FieldNameValidator fieldNameValidator = new FieldNameValidator();
column.setLabelProvider(new LabelProviderBuilder<Field>()
.withTextProvider(element -> element.getName())
.withStyledStringProvider((element -> new StyledString(element.getName())))
.withStatusProvider(fieldNameValidator::validate)
.shouldRefreshAllLabels(viewer)
.createColumnLabelProvider());
.createStyledCellLabelProvider());
column.setEditingSupport(new EditingSupportBuilder<Field>(viewer)
.withId(SWTBotConstants.SWTBOT_ID_ATTRIBUTE_NAME_TEXTEDITOR)
.withValueProvider(Field::getName)
......
......@@ -14,6 +14,8 @@
*/
package org.bonitasoft.studio.businessobject.editor.editor.ui.provider;
import java.util.Objects;
import org.bonitasoft.studio.businessobject.editor.editor.ui.styler.DeprecatedTypeStyler;
import org.bonitasoft.studio.businessobject.editor.model.BusinessObject;
import org.bonitasoft.studio.businessobject.editor.model.BusinessObjectModel;
......@@ -25,6 +27,7 @@ import org.bonitasoft.studio.businessobject.validator.AttributeReferenceExitence
import org.bonitasoft.studio.ui.ColorConstants;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ColumnViewer;
......@@ -33,9 +36,12 @@ import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
public class TypeLabelProvider extends StyledCellLabelProvider implements ILabelProvider {
......@@ -122,6 +128,26 @@ public class TypeLabelProvider extends StyledCellLabelProvider implements ILabel
return getStyledString(element).getString();
}
@Override
protected void erase(Event event, Object element) {
super.erase(event, element);
// Necessary since the MacOS Big Sur update -> Seems that table with StyledCellLabelProvider aren't redraw automatically
// TODO Hopefully this could be removed on the futur (current date: 19/11/2020)
if (Objects.equals(Platform.OS_MACOSX, Platform.getOS())) {
Rectangle bounds = event.getBounds();
if ((event.detail & SWT.SELECTED) != 0) {
Color oldForeground = event.gc.getForeground();
event.gc.setForeground(event.item.getDisplay().getSystemColor(
SWT.COLOR_LIST_SELECTION_TEXT));
event.gc.fillRectangle(bounds);
/* restore the old GC colors */
event.gc.setForeground(oldForeground);
event.detail &= ~SWT.SELECTED;
}
}
}
@Override
public void dispose() {
errorColor.dispose();
......
......@@ -14,18 +14,23 @@
*/
package org.bonitasoft.studio.common.jface;
import java.util.Objects;
import org.bonitasoft.studio.pics.Pics;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.TreeItem;
public abstract class AbstractCheckboxLabelProvider extends StyledCellLabelProvider implements ILabelProvider {
public abstract class AbstractCheckboxLabelProvider extends StyledCellLabelProvider
implements ILabelProvider {
public AbstractCheckboxLabelProvider(final ColumnViewer viewer) {
}
......@@ -54,20 +59,21 @@ public abstract class AbstractCheckboxLabelProvider extends StyledCellLabelProvi
return true;
}
private Image checkboxImage(final boolean selected, final boolean enabled) {
if (selected) {
return enabled ? Pics.getImage("/checkboxes/checkbox_yes.png") : Pics.getImage("/checkboxes/checkbox_yes_disabled.png");
return enabled ? Pics.getImage("/checkboxes/checkbox_yes.png")
: Pics.getImage("/checkboxes/checkbox_yes_disabled.png");
}
return enabled ? Pics.getImage("/checkboxes/checkbox_no.png") : Pics.getImage("/checkboxes/checkbox_no_disabled.png");
return enabled ? Pics.getImage("/checkboxes/checkbox_no.png")
: Pics.getImage("/checkboxes/checkbox_no_disabled.png");
}
@Override
protected void paint(final Event event, final Object element) {
final Image img = getImage(element);
if (img != null) {
final Rectangle bounds = event.item instanceof TableItem ? ((TableItem) event.item).getBounds(event.index) :
((TreeItem) event.item).getBounds(event.index);
final Rectangle bounds = event.item instanceof TableItem ? ((TableItem) event.item).getBounds(event.index)
: ((TreeItem) event.item).getBounds(event.index);
final Rectangle imgBounds = img.getBounds();
bounds.width /= 2;
bounds.width -= imgBounds.width / 2;
......@@ -91,7 +97,26 @@ public abstract class AbstractCheckboxLabelProvider extends StyledCellLabelProvi
if (image != null) {
event.height = image.getBounds().height;
}
}
@Override
protected void erase(Event event, Object element) {
super.erase(event, element);
// Necessary since the MacOS Big Sur update -> Seems that table with StyledCellLabelProvider aren't redraw automatically
// TODO Hopefully this could be removed on the futur (current date: 19/11/2020)
if (Objects.equals(Platform.OS_MACOSX, Platform.getOS())) {
Rectangle bounds = event.getBounds();
if ((event.detail & SWT.SELECTED) != 0) {
Color oldForeground = event.gc.getForeground();
event.gc.setForeground(event.item.getDisplay().getSystemColor(
SWT.COLOR_LIST_SELECTION_TEXT));
event.gc.fillRectangle(bounds);
/* restore the old GC colors */
event.gc.setForeground(oldForeground);
event.detail &= ~SWT.SELECTED;
}
}
}
}
......@@ -66,7 +66,9 @@ public class ContractConstraintControllerTest {
FileActionDialog.setDisablePopup(true);
controller = spy(new ContractConstraintController(new WritableValue(aContract().build(), Contract.class)));
contract = ProcessFactory.eINSTANCE.createContract();
when(viewer.getInput()).thenReturn(EMFObservables.observeList(contract, ProcessPackage.Literals.CONTRACT__CONSTRAINTS));
when(viewer.getInput())
.thenReturn(EMFObservables.observeList(contract, ProcessPackage.Literals.CONTRACT__CONSTRAINTS));
doReturn(false).when(controller).isMacos();
}
@Test
......
......@@ -16,6 +16,8 @@ package org.bonitasoft.studio.contract.ui.property.constraint;
import static org.assertj.core.api.Assertions.assertThat;
import static org.bonitasoft.studio.model.process.builders.ContractBuilder.aContract;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import org.bonitasoft.studio.common.jface.FileActionDialog;
import org.bonitasoft.studio.model.process.Contract;
......@@ -30,6 +32,7 @@ import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
......@@ -67,8 +70,9 @@ public class ContractConstraintsTableViewerTest {
parent = realm.createComposite();
FileActionDialog.setDisablePopup(true);
viewer = new ContractConstraintsTableViewer(parent, new FormToolkit(parent.getDisplay()));
final ContractConstraintController inputController = new ContractConstraintController(new WritableValue(aContract()
.build(), Contract.class));
ContractConstraintController inputController = spy(
new ContractConstraintController(new WritableValue(aContract().build(), Contract.class)));
doReturn(false).when(inputController).isMacos();
viewer.initialize(inputController, messageManager, new EMFDataBindingContext());
final Contract contract = ProcessFactory.eINSTANCE.createContract();
final ContractInput input = ProcessFactory.eINSTANCE.createContractInput();
......@@ -81,7 +85,8 @@ public class ContractConstraintsTableViewerTest {
constraint2.setName("c2");
contract.getConstraints().add(constraint);
contract.getConstraints().add(constraint2);
viewer.setInput(EMFObservables.observeList(Realm.getDefault(), contract, ProcessPackage.Literals.CONTRACT__CONSTRAINTS));
viewer.setInput(
EMFObservables.observeList(Realm.getDefault(), contract, ProcessPackage.Literals.CONTRACT__CONSTRAINTS));
}
@Test
......@@ -94,7 +99,8 @@ public class ContractConstraintsTableViewerTest {
}
@Test
public void shoud_createRemoveListener_add_a_selection_listener_that_remove_selected_contract_constraints() throws Exception {
public void shoud_createRemoveListener_add_a_selection_listener_that_remove_selected_contract_constraints()
throws Exception {
final Button button = new Button(parent, SWT.PUSH);
viewer.createRemoveListener(button);
viewer.setSelection(new StructuredSelection(constraint));
......@@ -104,7 +110,8 @@ public class ContractConstraintsTableViewerTest {
}
@Test
public void shoud_createMoveUpListener_add_a_selection_listener_that_moveUp_selected_contract_constraint() throws Exception {
public void shoud_createMoveUpListener_add_a_selection_listener_that_moveUp_selected_contract_constraint()
throws Exception {
final Button button = new Button(parent, SWT.PUSH);
viewer.createMoveUpListener(button);
assertThat(viewer.getTable().getItem(1).getData()).isEqualTo(constraint2);
......@@ -114,7 +121,8 @@ public class ContractConstraintsTableViewerTest {
}
@Test
public void shoud_createMoveUpListener_add_a_selection_listener_that_moveDown_selected_contract_constraint() throws Exception {
public void shoud_createMoveUpListener_add_a_selection_listener_that_moveDown_selected_contract_constraint()
throws Exception {
final Button button = new Button(parent, SWT.PUSH);
viewer.createMoveDownListener(button);
assertThat(viewer.getTable().getItem(0).getData()).isEqualTo(constraint);
......@@ -123,4 +131,20 @@ public class ContractConstraintsTableViewerTest {
assertThat(viewer.getTable().getItem(1).getData()).isEqualTo(constraint);
}
@Test
public void should_getStyledText_strip_expression_charriage() throws Exception {
final ContractConstraint constraint = ProcessFactory.eINSTANCE.createContractConstraint();
constraint.setExpression("toto == true && \n titi == false \r");
final StyledString styledText = viewer.getExpressionStyledText(constraint);
assertThat(styledText.toString()).doesNotContain("\n").doesNotContain("\r");
}
@Test
public void should_getStyledText_supportNull() throws Exception {
final ContractConstraint constraint = ProcessFactory.eINSTANCE.createContractConstraint();
constraint.setExpression(null);
final StyledString styledText = viewer.getExpressionStyledText(constraint);
assertThat(styledText.toString()).doesNotContain("\n").doesNotContain("\r");
}
}
/**
* Copyright (C) 2014 BonitaSoft S.A.
* BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
* 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.0 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, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.contract.ui.property.constraint.labelProvider;
import static org.assertj.core.api.Assertions.assertThat;
import org.bonitasoft.studio.contract.ui.property.constraint.labelProvider.ConstraintExpressionCellLabelProvider;
import org.bonitasoft.studio.model.process.ContractConstraint;
import org.bonitasoft.studio.model.process.ProcessFactory;
import org.bonitasoft.studio.model.process.provider.ProcessItemProviderAdapterFactory;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.jface.viewers.StyledString;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/**
* @author Romain Bioteau
*/
@RunWith(MockitoJUnitRunner.class)
public class ConstraintExpressionCellLabelProviderTest {
private ConstraintExpressionCellLabelProvider labelProvider;
@Before
public void setUp() throws Exception {
labelProvider = new ConstraintExpressionCellLabelProvider(new AdapterFactoryContentProvider(new ProcessItemProviderAdapterFactory()), new WritableSet());
}
@Test
public void should_getStyledText_strip_expression_charriage() throws Exception {
final ContractConstraint constraint = ProcessFactory.eINSTANCE.createContractConstraint();
constraint.setExpression("toto == true && \n titi == false \r");
final StyledString styledText = labelProvider.getStyledText(constraint);
assertThat(styledText.toString()).doesNotContain("\n").doesNotContain("\r");
}
@Test
public void should_getStyledText_supportNull() throws Exception {
final ContractConstraint constraint = ProcessFactory.eINSTANCE.createContractConstraint();
constraint.setExpression(null);
final StyledString styledText = labelProvider.getStyledText(constraint);
assertThat(styledText.toString()).doesNotContain("\n").doesNotContain("\r");
}
}
/**
* Copyright (C) 2014 BonitaSoft S.A.
* BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
* 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.0 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, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.studio.contract.ui.property.input.labelProvider;
import static org.assertj.core.api.Assertions.assertThat;
import static org.bonitasoft.studio.model.process.builders.ContractInputBuilder.aContractInput;
import org.bonitasoft.studio.model.process.provider.ProcessItemProviderAdapterFactory;
import org.bonitasoft.studio.swt.rules.RealmWithDisplay;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.junit.Rule;
import org.junit.Test;
/**
* @author Romain Bioteau
*/
public class InputNameCellLabelProviderTest {
@Rule
public RealmWithDisplay realmWithDisplay = new RealmWithDisplay();
@Test
public void should_display_contract_input_name_as_text() throws Exception {
final InputNameCellLabelProvider labelProvider = new InputNameCellLabelProvider(new AdapterFactoryContentProvider(
new ProcessItemProviderAdapterFactory()), new WritableSet());
assertThat(labelProvider.getText(aContractInput().withName("myInput").build())).isEqualTo("myInput");
}
@Test
public void should_not_display_an_icon() throws Exception {
final InputNameCellLabelProvider labelProvider = new InputNameCellLabelProvider(new AdapterFactoryContentProvider(
new ProcessItemProviderAdapterFactory()), new WritableSet());
assertThat(labelProvider.getImage(aContractInput().build())).isNull();
}
}
......@@ -32,6 +32,7 @@ import org.bonitasoft.studio.model.process.ProcessFactory;
import org.bonitasoft.studio.model.process.ProcessPackage;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.IStructuredSelection;
......@@ -40,6 +41,7 @@ import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import com.google.common.base.Function;
import com.google.common.base.Objects;
/**
* @author Romain Bioteau
......@@ -71,7 +73,8 @@ public class ContractConstraintController implements IViewerController {
private String defaultConstraintName() {
final Contract contract = (Contract) contractObservableValue.getValue();
return NamingUtils.generateNewName(
newHashSet(transform(getAllElementOfTypeIn(contract, ContractConstraint.class), toConstraintName())), "constraint", 1);
newHashSet(transform(getAllElementOfTypeIn(contract, ContractConstraint.class), toConstraintName())),
"constraint", 1);
}
private Function<ContractConstraint, String> toConstraintName() {
......@@ -101,27 +104,45 @@ public class ContractConstraintController implements IViewerController {
public void moveUp(final ColumnViewer viewer) {
final ContractConstraint selectedConstraint = getSelectedConstraint(viewer);
final Contract contract = ModelHelper.getFirstContainerOfType(selectedConstraint, Contract.class);
final IObservableList list = CustomEMFEditObservables.observeList(contract, ProcessPackage.Literals.CONTRACT__CONSTRAINTS);
final IObservableList list = CustomEMFEditObservables.observeList(contract,
ProcessPackage.Literals.CONTRACT__CONSTRAINTS);
final int index = list.indexOf(selectedConstraint);
if (index > 0) {
list.move(index, index - 1);
//refresh button enablement
viewer.setSelection(new StructuredSelection());
viewer.setSelection(new StructuredSelection(selectedConstraint));
// Necessary since the MacOS Big Sur update -> Seems that table with StyledCellLabelProvider aren't redraw automatically
// TODO Hopefully this could be removed on the futur (current date: 20/11/2020)
if (isMacos()) {
viewer.getControl().redraw();
}
}
}
protected boolean isMacos() {
return Objects.equal(Platform.getOS(), Platform.OS_MACOSX);
}
@Override
public void moveDown(final ColumnViewer viewer) {
final ContractConstraint selectedConstraint = getSelectedConstraint(viewer);
final Contract contract = ModelHelper.getFirstContainerOfType(selectedConstraint, Contract.class);
final IObservableList list = CustomEMFEditObservables.observeList(contract, ProcessPackage.Literals.CONTRACT__CONSTRAINTS);
final IObservableList list = CustomEMFEditObservables.observeList(contract,
ProcessPackage.Literals.CONTRACT__CONSTRAINTS);
final int index = list.indexOf(selectedConstraint);
if (index < list.size() - 1) {
list.move(index, index + 1);
//refresh button enablement
viewer.setSelection(new StructuredSelection());
viewer.setSelection(new StructuredSelection(selectedConstraint));
// Necessary since the MacOS Big Sur update -> Seems that table with StyledCellLabelProvider aren't redraw automatically
// TODO Hopefully this could be removed on the futur (current date: 20/11/2020)
if (isMacos()) {
viewer.getControl().redraw();
}
}
}
......