Commit 179c8bbd authored by Øyvind gjesdal's avatar Øyvind gjesdal
Browse files

Merge branch 'master' of https://github.com/protegeproject/webprotege into gitlab-ci

parents d60fe2b1 80f3f077
Pipeline #49903 passed with stage
in 17 minutes and 53 seconds
......@@ -13,10 +13,11 @@
<guava.version>28.0</guava.version>
<dagger.version>2.20</dagger.version>
<owlapi.version>4.5.13</owlapi.version>
<widgetmap.version>3.0.0</widgetmap.version>
<widgetmap.version>4.0.1</widgetmap.version>
<graphtree.version>1.1.1</graphtree.version>
<autovalue.version>1.7.1</autovalue.version>
<jackson.version>2.11.0</jackson.version>
<commons.io.version>2.7</commons.io.version>
<!-- WebProtege Specific Properties -->
<mail.smtp.host/>
<mail.smtp.auth/>
......@@ -454,5 +455,6 @@
<module>webprotege-client</module>
<module>webprotege-shared-core</module>
<module>webprotege-cli</module>
<module>webprotege-server-lucene</module>
</modules>
</project>
......@@ -159,4 +159,28 @@ public interface FormsMessages extends com.google.gwt.i18n.client.Messages {
@DefaultMessage("Clear filters")
@Key("clearFilters")
String clearFilters();
@DefaultMessage("No label for form set")
@Key("noLabelForFormSet")
String noLabelForFormSet();
@DefaultMessage("Export forms...")
@Key("exportForms")
String exportFormsFromProject_title();
@DefaultMessage("Import forms...")
@Key("importForms.title")
String importFormsIntoProject_title();
@DefaultMessage("Please paste the forms description into the text area below")
@Key("importForms.message")
String importFormsIntoProject_message();
@DefaultMessage("Forms import failed")
@Key("importForms.error.title")
String importFormsIntoProject_error_title();
@DefaultMessage("An error occurred when importing the specified forms descriptors")
@Key("importForms.error.message")
String importFormsIntoProject_error_message();
}
......@@ -17,9 +17,17 @@ public interface Messages extends com.google.gwt.i18n.client.Messages {
@Key("back")
String back();
@DefaultMessage("tab")
@Key("perspective.tab")
String perspective_tab();
@DefaultMessage("Tabs")
@Key("perspective.tabs")
String perspective_tabs();
@DefaultMessage("Add tab")
@Key("addTab")
String addTab();
@Key("perspective.perspective_addTab")
String perspective_addTab();
@DefaultMessage("authored")
......@@ -655,27 +663,6 @@ public interface Messages extends com.google.gwt.i18n.client.Messages {
@Key("password.resetPassword")
String password_resetPassword();
@DefaultMessage("Add blank tab")
@Key("perspective.addBlankTab")
String perspective_addBlankTab();
@DefaultMessage("Add view")
@Key("perspective.addView")
String perspective_addView();
@DefaultMessage("Close")
@Key("perspective.close")
String perspective_close();
@DefaultMessage("Reset")
@Key("perspective.reset")
String perspective_reset();
@DefaultMessage("Plus")
@Key("plus")
String plus();
......@@ -732,6 +719,11 @@ public interface Messages extends com.google.gwt.i18n.client.Messages {
@Key("projectSettings.displayName")
String projectSettings_displayName();
@DefaultMessage("Project Settings")
@Key("projectSettings.headerSection.title")
String projectSettings_headerSection_title();
@DefaultMessage("Main Settings")
@Key("projectSettings.mainSettings")
......@@ -835,8 +827,7 @@ public interface Messages extends com.google.gwt.i18n.client.Messages {
String search_hint();
@DefaultMessage(
"Separate search words by spaces to perform multi-word search. Search for tagged entities by " +
"entering the name of the tag.")
"Separate search words by spaces to perform multi-word search")
@Key("search.help")
String search_help();
......@@ -1019,6 +1010,10 @@ public interface Messages extends com.google.gwt.i18n.client.Messages {
@Key("uploadAndMerge")
String uploadAndMerge();
@DefaultMessage("Merge Ontologies")
@Key("uploadAndMergeAdditions")
String uploadAndMergeAdditions();
@DefaultMessage("Upload Project")
@Key("uploadProject")
......@@ -1164,10 +1159,10 @@ public interface Messages extends com.google.gwt.i18n.client.Messages {
@Key("displayName.settings.project.title")
String displayName_settings_project_title();
@DefaultMessage("Specify a list of annotation property and language pairs that should be used for entity display names. " +
"The display name for an entity will be chosen based on its annotations and the ordering " +
"of the pairs listed below. Properties and languages that appear closer to the top of the list are given priority over " +
"properties and languages that appear closer to the bottom of the list.")
@DefaultMessage("Specify how entity display names should be generated. " +
"The display name for an entity will be chosen based the ordering below. Display names can be based on annotation properties and language pairs etc." +
"Items that appear closer to the top of the list are given priority over " +
"items that appear closer to the bottom of the list.")
@Key("displayName.settings.project.helpText")
String displayName_settings_project_helpText();
......@@ -1288,4 +1283,89 @@ public interface Messages extends com.google.gwt.i18n.client.Messages {
@AlternateMessage({"one", "(1 row in total)"})
@Key("pagination.rows")
String pagination_rows(long elementCount);
@DefaultMessage("Local name")
@Key("dictionaryLanguage.localName")
String dicationaryLanguage_localname();
@DefaultMessage("OBO Id")
@Key("dictionaryLanguage.oboId")
String dictionaryLanguage_oboId();
@DefaultMessage("Prefixed name")
@Key("dictionaryLanguage.prefixedName")
String dictionaryLanguage_prefixedName();
@DefaultMessage("Import Project Settings")
@Key("projectSettings.importSettings.title")
String projectSettings_importSettings_title();
@DefaultMessage("Paste the project settings that you wish to import into the text area below. These settings will replaced any existing settings.")
@Key("projectSettings.importSettings.message")
String projectSettings_importSettings_message();
@DefaultMessage("Import Project Settings Error")
@Key("projectSettings.importSettings.error.title")
String projectSettings_importSettings_error_title();
@DefaultMessage("An error occurred when importing the project settings")
@Key("projectSettings.importSettings.error.message")
String projectSettings_importSettings_error_message();
@DefaultMessage("Export settings...")
@Key("settings.export")
String settings_export();
@DefaultMessage("Import settings...")
@Key("settings.import")
String settings_import();
@DefaultMessage("Import settings")
@Key("settings.import.complete.title")
String settings_importSettings_complete_title();
@DefaultMessage("The settings have successfuly been imported. We recommend that your refresh your browser.")
@Key("settings.import.complete.message")
String settings_importSettings_complete_message();
@DefaultMessage("Add blank tab")
@Key("perspective.addBlankTab")
String perspective_addBlankTab();
@DefaultMessage("Add view")
@Key("perspective.addView")
String perspective_addView();
@DefaultMessage("Close")
@Key("perspective.close")
String perspective_close();
@DefaultMessage("Reset")
@Key("perspective.reset")
String perspective_reset();
@DefaultMessage("Manage...")
@Key("perspective.manage")
String perspective_manage();
@DefaultMessage("Delete {0} tab?")
@Key("perspective.deleteConfirmation.title")
String perspective_deleteConfirmation_title(String object);
@DefaultMessage("Are you sure that you want to permanently delete the <strong>{0}</strong> tab? This cannot be undone.")
@Key("perspective.deleteConfirmation.message")
String perspective_deleteConfirmation_message(String object);
@DefaultMessage("Reset tabs?")
@Key("perspective.resetConfirmation.title")
String perspective_resetConfirmation_title();
@DefaultMessage("Are you sure that you want to reset the tabs to the default set of tabs? This cannot be undone.")
@Key("perspective.resetConfirmation.message")
String perspective_resetConfirmation_message();
}
......@@ -59,6 +59,7 @@ public class WebProtege implements EntryPoint {
BUNDLE.entityNode().ensureInjected();
BUNDLE.modal().ensureInjected();
BUNDLE.glyphs().ensureInjected();
BUNDLE.primitiveData().ensureInjected();
WidgetMapClientBundle.BUNDLE.style().ensureInjected();
WebProtegeClientInjector injector = WebProtegeClientInjector.get();
......
......@@ -28,9 +28,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class CollectionViewImpl extends Composite implements CollectionView {
private static final TerminalNodeId OBJECT_LIST_NODE_ID = new TerminalNodeId("ObjectList");
private static final TerminalNodeId OBJECT_LIST_NODE_ID = TerminalNodeId.get("ObjectList");
private static final TerminalNodeId FORM_VIEW_NODE_ID = new TerminalNodeId("FormView");
private static final TerminalNodeId FORM_VIEW_NODE_ID = TerminalNodeId.get("FormView");
private final ViewHolder formHolder;
......
package edu.stanford.bmir.protege.web.client.dispatch;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.InvocationException;
import com.google.web.bindery.event.shared.UmbrellaException;
......@@ -103,6 +104,7 @@ public class DispatchServiceCallback<T> {
private void displayAndLogError(Throwable throwable) {
errorMessageDisplay.displayGeneralErrorMessage(getErrorMessageTitle(), getErrorMessage(throwable));
GWT.log("Error", throwable);
}
private void _handleIncompatibleRemoteServiceException(IncompatibleRemoteServiceException e) {
......@@ -124,7 +126,7 @@ public class DispatchServiceCallback<T> {
}
protected String getErrorMessage(Throwable throwable) {
return throwable.getMessage();
return "[" + throwable.getClass().getSimpleName() + "] " + throwable.getMessage();
}
......
package edu.stanford.bmir.protege.web.client.editor;
import com.google.gwt.user.client.ui.HasEnabled;
import edu.stanford.bmir.protege.web.client.library.common.HasPlaceholder;
import edu.stanford.bmir.protege.web.client.library.dlg.HasRequestFocus;
import javax.annotation.Nonnull;
......@@ -13,7 +14,7 @@ import java.util.function.Consumer;
* Bio-Medical Informatics Research Group<br>
* Date: 15/06/2013
*/
public interface ValueListEditor<O> extends ValueEditor<List<O>>, HasEnabled, HasRequestFocus {
public interface ValueListEditor<O> extends ValueEditor<List<O>>, HasEnabled, HasRequestFocus, HasPlaceholder {
enum NewRowMode {
AUTOMATIC,
......
......@@ -193,6 +193,10 @@ public class ValueListFlexEditorImpl<O> extends Composite implements ValueListEd
@Override
public void setPlaceholder(String placeholder) {
this.placeholder = checkNotNull(placeholder);
currentEditors.stream()
.filter(editor -> editor instanceof HasPlaceholder)
.map(editor -> (HasPlaceholder) editor)
.forEach(hasPlaceholder -> hasPlaceholder.setPlaceholder(placeholder));
}
@Override
......
......@@ -60,10 +60,8 @@ public class EntityNodeHtmlRenderer implements TreeNodeRenderer<EntityNode> {
public void setDisplayLanguage(@Nonnull DisplayNameSettings displayNameSettings) {
primaryLanguages = displayNameSettings.getPrimaryDisplayNameLanguages().stream()
.map(DictionaryLanguageData::getDictionaryLanguage)
.collect(toImmutableList());
secondaryLanguages = displayNameSettings.getSecondaryDisplayNameLanguages().stream()
.map(DictionaryLanguageData::getDictionaryLanguage)
.collect(toImmutableList());
}
......@@ -80,9 +78,13 @@ public class EntityNodeHtmlRenderer implements TreeNodeRenderer<EntityNode> {
@Override
public String getHtmlRendering(EntityNode node) {
GWT.log("[EntityNodeHtmlRenderer] Rendering node: " + node);
StringBuilder sb = new StringBuilder();
sb.append("<div class='wp-entity-node'>");
if (node.isDeprecated()) {
sb.append("<div class='wp-entity-node wp-pd wp-pd--deprecated'>");
}
else {
sb.append("<div class='wp-entity-node wp-pd'>");
}
renderIcon(node, sb);
renderDisplayName(node, sb);
renderCommentsIcon(node, sb);
......@@ -95,21 +97,31 @@ public class EntityNodeHtmlRenderer implements TreeNodeRenderer<EntityNode> {
private void renderIcon(EntityNode node, StringBuilder sb) {
String iconIri;
DataResource icon = getIcon(node);
sb.append("<img src='").append(icon.getSafeUri().asString()).append("'/>");
sb.append("<img src='").append(icon.getSafeUri().asString()).append("' class='wp-pd__icon'/>");
}
private void renderDisplayName(EntityNode node, StringBuilder sb) {
if (node.isDeprecated()) {
sb.append("<div class='wp-entity-node__display-name wp-entity-node__display-name--deprecated-entity'>");
sb.append("<div class='wp-entity-node__display-name wp-entity-node__display-name--deprecated-entity wp-pd__text'>");
}
else {
sb.append("<div class='wp-entity-node__display-name'>");
sb.append("<div class='wp-entity-node__display-name wp-pd__text'>");
}
renderPrimaryDisplayName(node, sb);
renderSecondaryDisplayName(node, sb);
sb.append("</div>");
}
@Nonnull
public String getPrimaryDisplayName(@Nonnull EntityNode node) {
if(!primaryLanguages.isEmpty()) {
return node.getText(primaryLanguages, NO_DISPLAY_NAME);
}
else {
return node.getBrowserText();
}
}
private void renderPrimaryDisplayName(EntityNode node, StringBuilder sb) {
if (node.getEntity().isBuiltIn()) {
sb.append(highlightText(node.getBrowserText()));
......@@ -224,12 +236,7 @@ public class EntityNodeHtmlRenderer implements TreeNodeRenderer<EntityNode> {
private DataResource getIcon(@Nonnull EntityNode node) {
OWLEntity entity = node.getEntity();
if (entity.isOWLClass()) {
if (node.isDeprecated()) {
return BUNDLE.svgDeprecatedClassIcon();
}
else {
return BUNDLE.svgClassIcon();
}
return BUNDLE.svgClassIcon();
}
else if (entity.isOWLObjectProperty()) {
return BUNDLE.svgObjectPropertyIcon();
......
......@@ -14,6 +14,9 @@ import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import edu.stanford.bmir.protege.web.client.primitive.PrimitiveDataEditorImpl;
import edu.stanford.bmir.protege.web.client.renderer.PrimitiveDataIconProvider;
import edu.stanford.bmir.protege.web.resources.WebProtegeClientBundle;
import edu.stanford.bmir.protege.web.shared.form.data.*;
import edu.stanford.bmir.protege.web.shared.form.field.*;
......@@ -44,15 +47,16 @@ public class ComboBoxChoiceControl extends Composite implements SingleChoiceCont
@UiField
ListBox comboBox;
@UiField
Label readOnlyLabel;
@UiField(provided = true)
PrimitiveDataEditorImpl readOnlyView;
private final List<PrimitiveFormControlData> choices = new ArrayList<>();
private final List<PrimitiveFormControlDataDto> choices = new ArrayList<>();
private Optional<PrimitiveFormControlData> defaultChoice = Optional.empty();
@Inject
public ComboBoxChoiceControl() {
public ComboBoxChoiceControl(PrimitiveDataEditorImpl primitiveDataEditor) {
this.readOnlyView = checkNotNull(primitiveDataEditor);
initWidget(ourUiBinder.createAndBindUi(this));
}
......@@ -63,8 +67,8 @@ public class ComboBoxChoiceControl extends Composite implements SingleChoiceCont
}
public void setChoices(List<ChoiceDescriptorDto> choices) {
List<PrimitiveFormControlData> nextChoices = choices.stream()
.map(d -> d.getValue().toPrimitiveFormControlData())
List<PrimitiveFormControlDataDto> nextChoices = choices.stream()
.map(ChoiceDescriptorDto::getValue)
.collect(toImmutableList());
if(this.choices.equals(nextChoices)) {
return;
......@@ -74,7 +78,7 @@ public class ComboBoxChoiceControl extends Composite implements SingleChoiceCont
comboBox.addItem("");
String langTag = LocaleInfo.getCurrentLocale().getLocaleName();
for(ChoiceDescriptorDto descriptor : choices) {
this.choices.add(descriptor.getValue().toPrimitiveFormControlData());
this.choices.add(descriptor.getValue());
comboBox.addItem(descriptor.getLabel().get(langTag));
}
selectDefaultChoice();
......@@ -93,25 +97,36 @@ public class ComboBoxChoiceControl extends Composite implements SingleChoiceCont
private void selectDefaultChoice() {
comboBox.setSelectedIndex(0);
readOnlyLabel.setText("");
readOnlyView.clearValue();
}
@Override
public void setValue(@Nonnull FormControlDataDto value) {
if(value instanceof SingleChoiceControlDataDto) {
SingleChoiceControlDataDto choiceControlDataDto = (SingleChoiceControlDataDto) value;
Optional<PrimitiveFormControlData> choice = choiceControlDataDto.getChoice().map(PrimitiveFormControlDataDto::toPrimitiveFormControlData);
Optional<PrimitiveFormControlDataDto> choice = choiceControlDataDto.getChoice();
if(choice.isPresent()) {
int index = 1;
for(PrimitiveFormControlData c : choices) {
if(c.equals(choice.get())) {
for(PrimitiveFormControlDataDto c : choices) {
PrimitiveFormControlDataDto theChoice = choice.get();
boolean deprecated = choiceControlDataDto.getChoice().map(PrimitiveFormControlDataDto::isDeprecated).orElse(false);
if(deprecated) {
addStyleName(WebProtegeClientBundle.BUNDLE.primitiveData().primitiveData_____deprecated());
}
else {
removeStyleName(WebProtegeClientBundle.BUNDLE.primitiveData().primitiveData_____deprecated());
}
if(c.equals(theChoice)) {
comboBox.setSelectedIndex(index);
String itemText = comboBox.getItemText(index);
readOnlyLabel.setText(itemText);
choiceControlDataDto.getChoice()
.map(PrimitiveFormControlDataDto::getPrimitiveData)
.ifPresent(readOnlyView::setValue);
break;
}
index++;
}
}
else {
clearValue();
......@@ -125,10 +140,11 @@ public class ComboBoxChoiceControl extends Composite implements SingleChoiceCont
private void updateReadonlyLabel() {
int sel = comboBox.getSelectedIndex();
if(sel == -1) {
readOnlyLabel.setText("");
readOnlyView.clearValue();
}
else {
readOnlyLabel.setText(comboBox.getItemText(sel));
PrimitiveFormControlDataDto choice = choices.get(sel);
readOnlyView.setValue(choice.getPrimitiveData());
}
}
......@@ -149,8 +165,8 @@ public class ComboBoxChoiceControl extends Composite implements SingleChoiceCont
if(selIndex < 1) {
return Optional.empty();
}
PrimitiveFormControlData choice = choices.get(selIndex - 1);
return Optional.of(SingleChoiceControlData.get(descriptor.toFormControlDescriptor(), choice));
PrimitiveFormControlDataDto choice = choices.get(selIndex - 1);
return Optional.of(SingleChoiceControlData.get(descriptor.toFormControlDescriptor(), choice.toPrimitiveFormControlData()));
}
@Override
......@@ -167,7 +183,7 @@ public class ComboBoxChoiceControl extends Composite implements SingleChoiceCont
public void setEnabled(boolean enabled) {
comboBox.setEnabled(enabled);
comboBox.setVisible(enabled);
readOnlyLabel.setVisible(!enabled);
readOnlyView.setVisible(!enabled);
}
@Override
......
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:primitive="urn:import:edu.stanford.bmir.protege.web.client.primitive">
<ui:with field="wp" type="edu.stanford.bmir.protege.web.resources.WebProtegeClientBundle"/>
<ui:style>
.main {
display: flex;
......@@ -14,8 +16,11 @@
line-height: 22px;
}
</ui:style>
<g:HTMLPanel addStyleNames="{style.main}">
<g:HTMLPanel addStyleNames="{style.main} {wp.primitiveData.primitiveData}">
<g:ListBox ui:field="comboBox" visibleItemCount="1"/>
<g:Label ui:field="readOnlyLabel" visible="false" addStyleNames="{style.readOnlyLabel}"/>
<g:HTMLPanel ui:field="iconContainer">
<g:Image ui:field="iconImage"/>
</g:HTMLPanel>
<primitive:PrimitiveDataEditorImpl ui:field="readOnlyView" visible="false"/>
</g:HTMLPanel>
</ui:UiBinder>
\ No newline at end of file
......@@ -12,6 +12,7 @@ import edu.stanford.bmir.protege.web.client.library.msgbox.MessageBox;
import edu.stanford.bmir.protege.web.client.progress.HasBusy;
import edu.stanford.bmir.protege.web.client.settings.SettingsPresenter;
import edu.stanford.bmir.protege.web.shared.form.*;
import edu.stanford.bmir.protege.web.shared.inject.ProjectSingleton;
import edu.stanford.bmir.protege.web.shared.lang.LanguageMap;
import edu.stanford.bmir.protege.web.shared.match.criteria.CompositeRootCriteria;
import edu.stanford.bmir.protege.web.shared.match.criteria.EntityTypeIsOneOfCriteria;
......@@ -47,8 +48,6 @@ public class FormEditorPresenter implements Presenter {
@Nonnull
private final EntityFormSelectorPresenter entityFormSelectorPresenter;
private HasBusy hasBusy = busy -> {};
private Optional<Place> nextPlace = Optional.empty();
@Nonnull
......@@ -76,7 +75,7 @@ public class FormEditorPresenter implements Presenter {
public void setFormId(@Nonnull FormId formId) {
dispatch.execute(new GetEntityFormDescriptorAction(projectId, formId),
hasBusy,
settingsPresenter,
result -> {
formDescriptorPresenter.clear();
formDescriptorPresenter.setFormId(formId);
......@@ -108,7 +107,6 @@ public class FormEditorPresenter implements Presenter {
AcceptsOneWidget descriptorViewContainer = settingsPresenter.addSection("Form");
formDescriptorPresenter.start(descriptorViewContainer, eventBus);
hasBusy = busy -> settingsPresenter.setBusy(container, busy);
AcceptsOneWidget selectorContainer = settingsPresenter.addSection("Selector Criteria");
...</