Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ import org.kopi.galite.visual.dsl.chart.ChartMeasure
import org.kopi.galite.visual.dsl.common.CodeDescription
import org.kopi.galite.visual.dsl.common.LocalizationWriter
import org.kopi.galite.visual.dsl.form.FormField
import org.kopi.galite.visual.dsl.pivottable.Dimension
import org.kopi.galite.visual.dsl.pivottable.PivotTableField
import org.kopi.galite.visual.dsl.report.ReportField
import org.kopi.galite.visual.form.VBooleanCodeField
import org.kopi.galite.visual.form.VField
import org.kopi.galite.visual.form.VDecimalCodeField
import org.kopi.galite.visual.form.VIntegerCodeField
import org.kopi.galite.visual.form.VStringCodeField
import org.kopi.galite.visual.pivottable.VPivotTableColumn
import org.kopi.galite.visual.report.VBooleanCodeColumn
import org.kopi.galite.visual.report.VCalculateColumn
import org.kopi.galite.visual.report.VCellFormat
Expand Down Expand Up @@ -224,6 +227,59 @@ open class CodeDomain<T : Comparable<T>?> : Domain<T>() {
}
}

/**
* Builds the pivot table column model
*/
override fun buildPivotTableFieldModel(
field: PivotTableField<*>,
function: org.kopi.galite.visual.pivottable.VCalculateColumn?,
position: Dimension.Position?,
): VPivotTableColumn {
return with(field) {
when (kClass) {
Boolean::class -> org.kopi.galite.visual.pivottable.VBooleanCodeColumn(
ident,
function,
position,
this@CodeDomain.ident.ifEmpty { ident },
field.source,
codes.map { it.ident }.toTypedArray(),
codes.map { it.value as Boolean }.toBooleanArray()
)
BigDecimal::class -> org.kopi.galite.visual.pivottable.VDecimalCodeColumn(
ident,
function,
position,
this@CodeDomain.ident.ifEmpty { ident },
field.source,
codes.map { it.ident }.toTypedArray(),
codes.map { it.value as? BigDecimal }.toTypedArray()
)
Int::class, Long::class -> org.kopi.galite.visual.pivottable.VIntegerCodeColumn(
ident,
function,
position,
this@CodeDomain.ident.ifEmpty { ident },
field.source!!,
codes.map { it.ident }.toTypedArray(),
codes.map { it.value as Int }.toIntArray()
)
String::class -> org.kopi.galite.visual.pivottable.VStringCodeColumn(
ident,
function,
position,
this@CodeDomain.ident.ifEmpty { ident },
field.source,
codes.map { it.ident }.toTypedArray(),
codes.map { it.value as? String }.toTypedArray()
)
else -> throw RuntimeException("Type ${kClass!!.qualifiedName} is not supported")
}.also {
it.initLabels(codes.map { it.label }.toTypedArray())
}
}
}

/**
* Sets a mapping between the values that the domain can take
* and a corresponding text to be displayed in a field.
Expand Down
38 changes: 27 additions & 11 deletions galite-core/src/main/kotlin/org/kopi/galite/visual/domain/Domain.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ import org.kopi.galite.visual.dsl.chart.ChartDimension
import org.kopi.galite.visual.dsl.chart.ChartMeasure
import org.kopi.galite.visual.dsl.common.LocalizationWriter
import org.kopi.galite.visual.dsl.form.FormField
import org.kopi.galite.visual.dsl.report.ReportField
import org.kopi.galite.visual.form.*
import org.kopi.galite.visual.report.*
import org.kopi.galite.visual.dsl.pivottable.Dimension
import org.kopi.galite.visual.dsl.pivottable.PivotTableField
import org.kopi.galite.visual.dsl.report.ReportField
import org.kopi.galite.visual.form.*
import org.kopi.galite.visual.pivottable.VPivotTableColumn
import org.kopi.galite.visual.report.*


/**
* A domain is a data type with predefined list of allowed values.
Expand Down Expand Up @@ -182,8 +183,8 @@ open class Domain<T>(val width: Int? = null,
BigDecimal::class -> VDecimalDimension(ident, format, height ?: 6, true)
String::class -> VStringDimension(ident, format)
Boolean::class -> VBooleanDimension(ident, format)
org.joda.time.LocalDate::class, LocalDate::class, java.sql.Date::class, java.util.Date::class ->
VDateDimension(ident, format)
org.joda.time.LocalDate::class, LocalDate::class, java.sql.Date::class, java.util.Date::class
-> VDateDimension(ident, format)
Month::class -> VMonthDimension(ident, format)
Week::class -> VWeekDimension(ident, format)
org.joda.time.LocalTime::class, LocalTime::class -> VTimeDimension(ident, format)
Expand Down Expand Up @@ -244,14 +245,29 @@ open class Domain<T>(val width: Int? = null,
/**
* Builds the pivot table column model
*/
open fun buildPivotTableFieldModel(field: PivotTableField<*>, position: Dimension.Position?): VPivotTableColumn {
open fun buildPivotTableFieldModel(field: PivotTableField<*>,
function: org.kopi.galite.visual.pivottable.VCalculateColumn?,
position: Dimension.Position?): VPivotTableColumn {
return with(field) {
when (kClass) {
Int::class, Long::class, String::class, BigDecimal::class, Boolean::class, org.joda.time.LocalDate::class,
LocalDate::class, java.sql.Date::class, java.util.Date::class, Month::class, Week::class, org.joda.time.LocalTime::class,
LocalTime::class, Instant::class, LocalDateTime::class, DateTime::class ->
VPivotTableColumn(ident, position)

Int::class, Long::class->
org.kopi.galite.visual.pivottable.VIntegerColumn(ident,function, position)
String::class->
org.kopi.galite.visual.pivottable.VStringColumn(ident, function, position)
BigDecimal::class->
org.kopi.galite.visual.pivottable.VDecimalColumn(ident, function, position)
Boolean::class ->
org.kopi.galite.visual.pivottable.VBooleanColumn(ident, function, position)
org.joda.time.LocalDate::class, LocalDate::class, java.sql.Date::class, java.util.Date::class ->
org.kopi.galite.visual.pivottable.VDateColumn(ident, function, position)
Month::class ->
org.kopi.galite.visual.pivottable.VMonthColumn(ident, function, position)
Week::class ->
org.kopi.galite.visual.pivottable.VWeekColumn(ident, function, position)
org.joda.time.LocalTime::class, LocalTime::class ->
org.kopi.galite.visual.pivottable.VTimeColumn(ident, function, position)
Instant::class, LocalDateTime::class, DateTime::class ->
org.kopi.galite.visual.pivottable.VTimestampColumn(ident, function, position)
else -> throw java.lang.RuntimeException("Type ${kClass!!.qualifiedName} is not supported")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2013-2024 kopiLeft Services SARL, Tunis TN
* Copyright (c) 1990-2024 kopiRight Managed Solutions GmbH, Wien AT
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.kopi.galite.visual.dsl.common

import org.kopi.galite.visual.pivottable.Constants

/**
* This class represents a trigger, ie an action to be executed on events
*/
class PivotTableTrigger(events: Long, action: Action<*>) : Trigger(events, action) {
override fun getTriggers(): IntArray = Constants.TRG_TYPES
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package org.kopi.galite.visual.dsl.pivottable
import org.kopi.galite.visual.domain.Domain
import org.kopi.galite.visual.dsl.common.LocalizationWriter
import org.kopi.galite.visual.pivottable.Constants
import org.kopi.galite.visual.pivottable.VCalculateColumn
import org.kopi.galite.visual.pivottable.VPivotTableColumn

class Dimension<T>(override val domain: Domain<T>,
Expand All @@ -35,7 +36,13 @@ class Dimension<T>(override val domain: Domain<T>,
lateinit var model: VPivotTableColumn

fun buildPivotTableColumn(): VPivotTableColumn {
model = domain.buildPivotTableFieldModel(this, position).also { column ->
val function: VCalculateColumn? = if (computeTrigger != null) {
computeTrigger!!.action.method() as VCalculateColumn
} else {
null
}

model = domain.buildPivotTableFieldModel(this, function, position).also { column ->
column.label = label ?: ""
column.help = help
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package org.kopi.galite.visual.dsl.pivottable

import org.kopi.galite.visual.domain.Domain
import org.kopi.galite.visual.dsl.common.LocalizationWriter
import org.kopi.galite.visual.pivottable.VCalculateColumn
import org.kopi.galite.visual.pivottable.VPivotTableColumn

class Measure<T>(override val domain: Domain<T>,
Expand All @@ -33,7 +34,12 @@ class Measure<T>(override val domain: Domain<T>,
lateinit var model: VPivotTableColumn

fun buildPivotTableColumn(): VPivotTableColumn {
model = domain.buildPivotTableFieldModel(this, Dimension.Position.NONE).also { column ->
val function: VCalculateColumn? = if (computeTrigger != null) {
computeTrigger!!.action.method() as VCalculateColumn
} else {
null
}
model = domain.buildPivotTableFieldModel(this, function, Dimension.Position.NONE).also { column ->
column.label = label ?: ""
column.help = help
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ abstract class PivotTable(title: String, val help: String?, locale: Locale? = nu
* @param method the method to execute when trigger is called
*/
fun <T> trigger(vararg pivotTriggerEvents: PivotTableTriggerEvent<T>, method: () -> T): Trigger {
val event = formEventList(pivotTriggerEvents)
val event = pivotEventList(pivotTriggerEvents)
val pivotTableAction = Action(null, method)
val trigger = FormTrigger(event, pivotTableAction)
val trigger = PivotTableTrigger(event, pivotTableAction)

triggers.add(FormTrigger(event, Action(null, method)))
triggers.add(PivotTableTrigger(event, Action(null, method)))
// PIVOT TABLE TRIGGERS
triggers.forEach { trigger ->
for (i in VConstants.TRG_TYPES.indices) {
Expand All @@ -108,7 +108,7 @@ abstract class PivotTable(title: String, val help: String?, locale: Locale? = nu
return trigger
}

private fun formEventList(PivotTableTriggerEvent: Array<out PivotTableTriggerEvent<*>>): Long {
private fun pivotEventList(PivotTableTriggerEvent: Array<out PivotTableTriggerEvent<*>>): Long {
var self = 0L

PivotTableTriggerEvent.forEach { trigger ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,32 @@
package org.kopi.galite.visual.dsl.pivottable

import org.kopi.galite.visual.domain.Domain
import org.kopi.galite.visual.dsl.common.Action
import org.kopi.galite.visual.dsl.common.LocalizationWriter
import org.kopi.galite.visual.dsl.common.PivotTableTrigger
import org.kopi.galite.visual.dsl.common.Trigger
import org.kopi.galite.visual.dsl.field.Field
import org.kopi.galite.visual.pivottable.Constants
import org.kopi.galite.visual.pivottable.VCalculateColumn

abstract class PivotTableField<T>(override val domain: Domain<T>, ident: String? = null) : Field<T>(domain, ident) {

/** compute trigger */
internal var computeTrigger: Trigger? = null

/**
* executed when the pivot Table is displayed and can be used to compute expressions on the pivot columns and show
* the result.
*
* @param method The method to execute when compute trigger is executed.
*/
fun compute(method: () -> VCalculateColumn): PivotTableTrigger {
val fieldAction = Action(null, method)
return PivotTableTrigger(0L or (1L shl Constants.TRG_COMPUTE), fieldAction).also {
computeTrigger = it
}
}

// ----------------------------------------------------------------------
// XML LOCALIZATION GENERATION
// ----------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ interface Constants : Constants {
const val TRG_INIT = 0
const val TRG_PRE_PIVOT_TABLE = 1
const val TRG_POST_PIVOT_TABLE = 2
const val TRG_VOID = VConstants.TRG_VOID
const val TRG_OBJECT = VConstants.TRG_OBJECT
const val TRG_COMPUTE = 3
const val TRG_VOID: Int = VConstants.TRG_VOID
const val TRG_OBJECT: Int = VConstants.TRG_OBJECT

// ---------------------------------------------------------------------
// TRIGGER INFO
Expand All @@ -68,11 +69,13 @@ interface Constants : Constants {
"TRG_INIT",
"TRG_PRE_PIVOT_TABLE",
"TRG_POST_PIVOT_TABLE",
"TRG_COMPUTE"
)
val TRG_TYPES = intArrayOf(
TRG_VOID,
TRG_VOID,
TRG_VOID
TRG_VOID,
TRG_OBJECT
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package org.kopi.galite.visual.pivottable
import java.io.Serializable

import org.kopi.galite.visual.MessageCode
import org.kopi.galite.visual.report.VReportRow

class MPivotTable : Serializable {

Expand All @@ -31,7 +30,7 @@ class MPivotTable : Serializable {
// Columns contains all columns defined by the user
var columns = mutableListOf<VPivotTableColumn?>() // array of column definitions

// Baserows contains data give by the request of the user
// UserRows contains data give by the request of the user
internal var userRows: ArrayList<VPivotTableRow>? = ArrayList()

/**
Expand Down Expand Up @@ -80,5 +79,38 @@ class MPivotTable : Serializable {
* @param row the index of the desired row
* @return the desired row
*/
fun getRow(row: Int): VPivotTableRow? = userRows!![row]
fun getRow(row: Int): VPivotTableRow? = userRows?.get(row)

/**
* Returns an attribute value for a cell.
*
* @param row the index of the row whose value is to be looked up
* @param column the index of the column whose value is to be looked up (column of the model)
* @return the value Object at the specified cell
*/
fun getValueAt(row: Int, column: Int): Any? {
var x: Any? = null

try {
x = userRows?.get(row)!!.getValueAt(column)
} catch (e: Exception) {
e.printStackTrace()
}
return x
}

/**
* Calculate all columns which need to be calculated
*/
fun calculateColumns() {
for (i in columns.indices) {
val function: VCalculateColumn? = columns[i]!!.function

if (function != null) {
userRows?.forEach {
function.calculate(it, i)
}
}
}
}
}
Loading