CalendarFilter.kt
CalendarFilter is the core user-facing configuration object for the ProjectForge calendar. It extends the favorite system, allowing users to create named filter profiles, switch between them, and persist their preferences. Each filter controls which calendars are displayed, which are hidden, what default calendar new entries are assigned to, timesheet visibility (for a specific user), vacation entries (by group or user), break highlighting, and display parameters such as grid size and the first visible hour of the day. The class also includes deep-copy, serialization clean-up, and legacy migration support (from the old Wicket-based calendar of ProjectForge v6).
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
String? |
null |
Human-readable name of the filter (inherited from AbstractFavorite). |
id |
Long? |
null |
Database ID of the filter (inherited from AbstractFavorite). |
defaultCalendarId |
Long? |
null |
New calendar entries will be assumed to belong to this calendar. If null, the timesheet creation page is instantiated instead. |
gridSize |
Int |
15 |
Grid step size in minutes. Must evenly divide 60. |
firstHour |
Int |
8 |
First hour of the day shown in week and day time grids (e.g., 8 for 08:00). |
otherTimesheetUsersEnabled |
Boolean |
false |
Whether timesheets of other users can be shown. |
timesheetUserId |
Long? |
null |
If set, display time sheets only for this user. If null, no timesheets are shown. |
vacationGroupIds |
Set<Long?>? |
null |
Vacations of employees in these groups will be displayed. |
vacationUserIds |
Set<Long?>? |
null |
Vacations of these specific employees (by user ID) will be displayed. |
showBreaks |
Boolean? |
null |
If true, gaps between time sheets within a day are highlighted, and clicking a gap allows creating a new time sheet in that window. |
showPlanning |
Boolean? |
null |
Not yet supported. Reserved for future planning features. |
calendarIds: MutableSet<Long?>All calendar IDs managed by this filter (both visible and hidden). This is the master set of calendars the filter knows about.
invisibleCalendars: MutableSet<Long?>Subset of calendarIds that are currently hidden. Calendars in calendarIds but not in this set are visible.
copyFrom(src: CalendarFilter): CalendarFilterPerforms a deep copy of all fields from src into this, including copying all collection contents. Returns this for fluent chaining. The calendarIds and invisibleCalendars sets are re-allocated and populated with the source values.
addCalendarId(calendarId: Long)Adds a calendar to the filter and ensures it is visible (removes it from invisibleCalendars if present).
removeCalendarId(calendarId: Long)Removes a calendar from both calendarIds and invisibleCalendars.
setVisibility(calendarId: Long?, visible: Boolean)Toggles visibility for a given calendar. If calendarId is null (possible during deserialization), the call is silently ignored. Calls tidyUp() after mutation.
isInvisible(calendarId: Long?): BooleanReturns true if the calendar is either null or present in invisibleCalendars.
tidyUp()Removes entries from invisibleCalendars that are not present in the main calendarIds set. Keeps the two sets in sync.
afterDeserialization()Post-deserialization clean-up. Handles the case where calendarIds or invisibleCalendars might be null after deserialization, and strips any spurious null values from the sets. Calls tidyUp() at the end.
isModified(other: CalendarFilter): BooleanCompares all fields (name, id, defaultCalendarId, timesheetUserId, gridSize, firstHour, showBreaks, showPlanning, plus all collection contents) against another filter to determine if any value differs. Uses a helper isModified(col1, col2) for collection comparison (checking mutual containment of non-null values).
copySet(srcSet: Set<Long?>?): Set<Long>?Copies a nullable set, filtering out null entries. Returns null if the source is null.
isModified(col1, col2)Compares two nullable collections by checking that each non-null element of col1 exists in col2 and vice versa.
copyFrom(templateEntry: TemplateEntry?): CalendarFilterFactory method that converts a legacy TemplateEntry (from the old Wicket calendar system, ProjectForge ≤v6) into a new CalendarFilter. Maps properties including calendar IDs, visibility settings, timesheet settings, and break/planning flags. If the old template had showTimesheets enabled, the timesheet user is set to the currently logged-in user.
CalendarFilter is a data-rich model class rather than a traditional DTO. It carries business logic for maintaining consistency between its two related sets (calendarIds and invisibleCalendars) through methods like tidyUp() and afterDeserialization(). The @Suppress("SENSELESS_COMPARISON") annotations acknowledge that nullable Long? values in the sets are technically possible after XML/JSON deserialization, and the class defensively cleans them up. By extending AbstractFavorite, it inherits the named-favorites infrastructure (name + id), allowing users to create, name, and switch between multiple filter configurations — a key UX feature of the calendar. The deep-copy via copyFrom() (rather than a clone() override or data class) gives callers explicit control over when copies occur, avoiding unintended shared mutable state. The legacy copyFrom(TemplateEntry) in the companion object encapsulates all migration logic from the old Wicket calendar, keeping the main class clean while preserving backward compatibility for existing user preferences.