3.8. Настройки пользователя

Added in version AS: 1.26.0-ms31

В данном разделе описывается взаимодействие с пользовательскими настройками

3.8.1. Формат данных

3.8.1.1. Версия “1.0”

Настройки пользователя сохраняются в бинарном формате, полученном из JSON-строки. В данной версии формат совпадает с тем, что используется в реестре настроек

3.8.2. Сохраняемые/загружаемые настройки

Далее перечислены настройки списка, которые будут сохраняться и загружаться:

  1. Настройки списка в целом:

  • Видимость области итогов

  • Значение флага Разместить все колонки на экране

  • Высота заголовка

  • Высота строк

  • Видимость области группировки

  • Условия группировки

  1. Настройки колонок списка:

  • Видимость колонки

  • Ширина колонки

  • Функция агрегации

  • Порядковый номер

3.8.3. События прикладного слоя

3.8.4. Жизненный цикл загрузки/сохранения настроек

3.8.4.1. Открытие фрейма

  1. Клиент выполняет selection.FeatureCheck. Проверяется готовность прикладным слоем обрабатывать события, которые отвечают за доступность контекстных пунктов меню и загрузку умолчательных настроек.

  2. Если ответ не является CoreFeatureCheckResponse, механизм считается неподдерживаемым.

  3. Применяется состояние, если версия формата пришедших настроек поддерживается:

3.8.4.2. Действия пользователя

Пользователь может сохранять и загружать пользовательские настройки, используя контекстное меню списочного контрола

3.8.4.3. Применение из прикладного кода

Added in version AS: 1.29.0-ms3

Прикладной код применяет настройку к построенному списку через CoreGridView.userSettings() (см. API). Применённая настройка перестраивает колонки, группировку и итоги сразу, тем же путём, что и загрузка из контекстного меню, и становится текущей.

3.8.4.4. Повторная активация источника данных

Changed in version AS: 1.29.0-ms3 Повторная активация применяет последнюю применённую настройку, а не умолчание, и сохраняет правки списка, сделанные пользователем.

Список хранит одну «последнюю применённую» настройку: умолчание, полученное при построении, настройку, загруженную пользователем из контекстного меню, или настройку, применённую из прикладного кода. При каждой активации источника данных (обновление в режиме closeOpen, смена записи мастера у детали) список применяет её повторно. Умолчание при этом не запрашивается заново: если пользователь или прикладной код подменили настройку, переактивация не откатит список к умолчанию.

Изменение списка пользователем (видимость, порядок и ширина колонок, группировка, сортировка) снимает привязку списка к сохранённой настройке, а последней применённой настройкой становится снимок текущего состояния без определения: переактивация источника данных сохраняет правки пользователя, а не возвращает применённую ранее настройку.

Сохранение настройки из контекстного меню («Сохранить», «Сохранить как…») привязывает список к определению, которое вернул прикладной слой. Если у списка есть последняя применённая настройка, ею становятся сохранённые данные с этим определением, поэтому переактивация источника данных возвращает список к сохранённому состоянию.

Пустая настройка (без данных и без определения) не запоминается: если ни одна настройка с данными не применялась, правка пользователя снимка не создаёт и переактивация источника данных список не перестраивает. Пустая настройка в ответ на загрузку из контекстного меню считается отказом от загрузки и список не меняет.

3.8.4.5. Закрытие фрейма

3.8.5. API

3.8.5.1. Прикладной API применения настроек

Added in version AS: 1.29.0-ms3

Интерфейс CoreGridUserSettings даёт прикладному коду четыре операции:

  • apply(settings) — применить настройку немедленно и запомнить её как текущую. Данные настройки (CoreSettings.data()) применяются к колонкам, группировке и итогам, определение (CoreSettings.definition()) задаёт идентификатор и заголовок текущей настройки; заголовок показывается в подменю «Настройки пользователя». Настройка без определения применяет только данные и снимает привязку списка к сохранённой настройке: definition() возвращает null, заголовок в подменю не показывается. В событие selection.layout.composer.frame.grid.SaveUserSettings определение не передаётся, поэтому какую настройку перезапишет «Сохранить», решает прикладной обработчик — свою привязку он сбрасывает сам. Настройка без данных не меняет состояние списка и обновляет только определение. Если данные настройки не удалось разобрать, вызов завершается исключением UserSettingsParseException.

  • applyDefault() — запросить умолчание событием selection.layout.composer.frame.grid.LoadDefaultUserSettings и применить ответ как текущую настройку. Если прикладной слой не объявил событие в ответе на selection.FeatureCheck или вернул пустую настройку, ничего не применяется и текущая настройка не сбрасывается.

  • data() — снимок текущего состояния списка в формате настроек версии 1.0: те же данные, что уходят в selection.layout.composer.frame.grid.SaveUserSettings.

  • definition() — определение текущей настройки или null, если список не привязан к настройке.

Ограничения:

  • методы не зависят от флага «Восстанавливать изменения…»: вызов из прикладного кода — явное намерение, флаг влияет только на автозагрузку при построении;

  • список должен быть построен. Вызов до построения (например, из onLoadMeta) завершается IllegalStateException;

  • data() и definition() можно вызывать из любого обработчика после построения, а apply и applyDefault() — из операций и обработчиков событий, но не из afterOpen: afterOpen выполняется на каждой активации источника данных, и применение в нём перетирало бы правки, сделанные пользователем после применения.

Пример: смена профиля отчёта в шапке подставляет в деталь настройку, привязанную к профилю. Настройку применяют только при смене профиля: при каждой активации источника данных список сам повторно применяет последнюю применённую настройку. Деталь отбирается по имени, так как настройка профиля описывает колонки именно её списка. Детали на закладках, которые ещё не открывали, не построены (layout равен null) и пропускаются: при первом построении деталь сама возвращает настройку профиля в ответ на selection.layout.composer.frame.grid.LoadDefaultUserSettings. Если у профиля нет настройки, деталь запрашивает умолчание через applyDefault(). Обработчик LoadDefaultUserSettings детали в этом случае должен вернуть общее умолчание выборки: на пустой ответ applyDefault() список не меняет, и в нём остались бы колонки прежнего профиля.

Прикладной код вызывает API через Scala-обёртку GridView.userSettings модуля gtk; в версиях gtk без обёртки прикладному коду API недоступен, так как GridViewImpl.coreGridView закрыт для пакетов вне gtk.

// шапка: при смене профиля подставить настройку профиля в деталь отчёта
@Setter
def setidReportProfile(value: NLong): Unit = {
  calcStatement.idReportProfile = value
  val settings: CoreSettings = loadProfileSettings(value)
  selection.details
    .filter(detail => detail.name == ReportDetailName && detail.layout != null)
    .foreach { detail =>
      val userSettings = detail.layout.frame.view.asGridView.userSettings
      if (settings != null) userSettings.apply(settings) else userSettings.applyDefault()
    }
}

Здесь loadProfileSettings собирает CoreSettings из записи хранилища настроек: данные в формате версии 1.0 и определение с идентификатором и заголовком, или возвращает null, если у профиля нет настройки; ReportDetailName — имя выборки детали отчёта.

3.8.6. UI