Skip to content

Commit

Permalink
Merge pull request #2413 from bardsoftware/tkt-2404-duplicated-custom…
Browse files Browse the repository at this point in the history
…-column-names

Custom column names validation
  • Loading branch information
dbarashev authored Feb 6, 2024
2 parents 353b876 + c3f752f commit ec3d1b9
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 19 deletions.
4 changes: 2 additions & 2 deletions cloud.ganttproject.colloboque/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ repositories {
}

dependencies {
implementation("biz.ganttproject:biz.ganttproject.core:23.+")
implementation("biz.ganttproject:ganttproject:23.+")
implementation("biz.ganttproject:biz.ganttproject.core:24.+")
implementation("biz.ganttproject:ganttproject:24.+")
implementation("ch.qos.logback:logback-classic:1.2.11")
implementation("com.google.guava:guava:31.1-jre")

Expand Down
2 changes: 1 addition & 1 deletion ganttproject-builder/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.3300
3.3.3301
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,17 @@ class LocalizedString(
return this
}

fun update(vararg args: Any): LocalizedString {
this.args = args.map { it.toString() }.toList()
observable.value = build()
return this
}

internal fun update() {
observable.value = build()
}

private fun build(): String = i18n.formatText(key, *args.toTypedArray())
private fun build(): String = i18n.formatText(key, *(args.toTypedArray()))
}

/**
Expand Down Expand Up @@ -172,11 +178,11 @@ open class DefaultLocalizer(
* This localizer searches for key values in a map. The map values are lambdas which
* allows for values calculation.
*/
class MappingLocalizer(val key2lambda: Map<String, (()->String)?>, val unhandledKey: (String)->String?) : Localizer {
class MappingLocalizer(val key2lambda: Map<String, ()->LocalizedString?>, val unhandledKey: (String)->LocalizedString?) : Localizer {
override fun create(key: String) = LocalizedString(key, this)

override fun formatTextOrNull(key: String, vararg args: Any): String? =
key2lambda[key]?.invoke() ?: unhandledKey(key)
key2lambda[key]?.invoke()?.update(*args)?.value ?: unhandledKey(key)?.update(*args)?.value
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,17 +264,29 @@ internal class CustomPropertyEditor(
) {
private val localizer = run {
val fallback1 = MappingLocalizer(mapOf()) {
if (it.endsWith(".label")) {
val key = it.split('.', limit = 2)[0]
RootLocalizer.formatText(key)
} else {
null
when {
it.endsWith(".label") -> {
val key = it.split('.', limit = 2)[0]
RootLocalizer.create(key)
}
it == "columnExists" -> RootLocalizer.create(it)
else -> null
}
}
val fallback2 = RootLocalizer.createWithRootKey("option.taskProperties.customColumn", fallback1)
RootLocalizer.createWithRootKey("option.customPropertyDialog", fallback2)
}
private val nameOption = ObservableString(id = "name")
private val nameOption = ObservableString(id = "name", validator = {value ->
listItems.find { it.title == value }?.let {
if (it != selectedItem?.cloneOf) {
throw ValidationException(localizer.formatText("columnExists", value))
}
}
if (value.isBlank()) {
throw ValidationException(localizer.formatText("name.validation.empty"))
}
value
})
private val typeOption = ObservableEnum(id ="type", initValue = PropertyType.STRING, allValues = PropertyType.values())
private val defaultValueOption = ObservableString(
id = "defaultValue",
Expand Down Expand Up @@ -456,6 +468,7 @@ private class CellImpl : ListCell<ColumnAsListItem>() {

init {
styleClass.add("column-item-cell")
alignment = Pos.CENTER_LEFT
}

override fun updateItem(item: ColumnAsListItem?, empty: Boolean) {
Expand All @@ -466,14 +479,19 @@ private class CellImpl : ListCell<ColumnAsListItem>() {
return
}
text = item.title
if (text.isEmpty()) {
text = " "
}
if (graphic == null) {
graphic = iconPane
}
if (item.isVisible) {
styleClass.add("is-visible")
styleClass.remove("is-hidden")
iconPane.children.setAll(iconVisible)
} else {
if (!styleClass.contains("is-hidden")) {
styleClass.remove("is-visible")
styleClass.add("is-hidden")
iconPane.children.setAll(iconHidden)
}
Expand Down Expand Up @@ -531,7 +549,7 @@ private fun showColumnManager(columnList: ColumnList, customColumnsManager: Cust
dlg.hide()
}
}
dlg.setupButton(ButtonType.CANCEL) { btn ->
dlg.setupButton(ButtonType.NEXT) { btn ->
btn.text = localizer.formatText("add")
ButtonBar.setButtonData(btn, ButtonBar.ButtonData.HELP)
btn.disableProperty().bind(columnManager.btnAddController.isDisabled)
Expand All @@ -541,7 +559,7 @@ private fun showColumnManager(columnList: ColumnList, customColumnsManager: Cust
}
btn.styleClass.addAll("btn-attention", "secondary")
}
dlg.setupButton(ButtonType.CANCEL) { btn ->
dlg.setupButton(ButtonType.NEXT) { btn ->
btn.text = localizer.formatText("delete")
ButtonBar.setButtonData(btn, ButtonBar.ButtonData.HELP_2)
btn.disableProperty().bind(columnManager.btnDeleteController.isDisabled)
Expand Down
8 changes: 4 additions & 4 deletions ganttproject/src/main/java/biz/ganttproject/print/PrintUi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ fun showPrintDialog(activeChart: Chart, preferences: Preferences) {
)
add(
DateRangePicker(previews.dateRangeModel, MappingLocalizer(mapOf(
"custom" to { prefixedLocalizer.formatText("dateRange.custom") },
"view" to { prefixedLocalizer.formatText("dateRange.currentView") },
"project" to { i18n.formatText("wholeProject") }
"custom" to { prefixedLocalizer.create("dateRange.custom") },
"view" to { prefixedLocalizer.create("dateRange.currentView") },
"project" to { i18n.create("wholeProject") }
)) { key ->
i18n.formatText(key)
i18n.create(key)
}).component
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
-fx-font-size: 100%;
-fx-padding: 5 10 5 15;
-fx-strikethrough: false;

.glyph-icon {
-glyph-size: 18;
-fx-alignment: center;
Expand All @@ -30,6 +29,9 @@
-glyph-size: 18;
}
}
&.is-visible {
-fx-font-weight: bold;
}
&.is-hidden > * {
-fx-fill: lighten($gp-medium-gray, 20%);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ class InternationalizationTest {
assertEquals("Hello, World!", i18n.formatText("hello", i18n.formatText("world")))
assertEquals("Hello, GanttProject!", i18n.formatText("hello", i18n.formatText("ganttproject")))
}

@Test fun `mapping localizer`() {
val rootLocalizer = DefaultLocalizer(
currentTranslation = newResourceBundle(mapOf(
"foo.hello" to "Hello, {0}",
)))
val mappingLocalizer = MappingLocalizer(mapOf(
"helloWorld" to { rootLocalizer.create("foo.hello") }
)) {
LocalizedString("Unknown String", DummyLocalizer)
}

assertEquals("Hello, Local World", mappingLocalizer.formatText("helloWorld", "Local World"))
assertEquals("Unknown String", mappingLocalizer.formatText("helloUniverse"))
}


}

private fun newResourceBundle(kv: Map<Any, Any>) : SimpleObjectProperty<ResourceBundle?> {
Expand Down

0 comments on commit ec3d1b9

Please sign in to comment.