# Changes since [4.4.1](./4.4.1.md)

## Bug fixes

- Fix 2 log messages in `glos._resolveConvertSortParams`

- Fixes and improvements in Dictfile (.df) reader

  - Fix exception: disable loading info (Dicfile does not support info)
  - TextGlossaryReader: prevent producing duplicate data entries
    - This fixes: `error in DataEntry.save: [Errno 2] No such file or directory: ...` because `entry.save()` moves the temp file to output path
    - This bug only existed for Dictfile (.df) format.
  - Remove extra colon, #358
  - Remove some extra newline
  - And add test for Dictfile to/from Tabfile

- Fix not cleaning up temp directory on return with error from `glos.convert`

## Features

- ui_gtk: add a "General Options" button that opens a dialog for:

  - Settings for `sort` and `sortKey`
  - Checkbox for SQLite mode
  - Check boxes for config params: `save_info_json`, `lower`, `skip_resources`, `rtl`, `enable_alts`, `cleanup`, `remove_html_all`

- Add support for `--sort-key random` to shuffle entries

## Performance improvements

- Performance improvement: remove `gc.collect()` calls in `Glossary` and `*EntryList`

  - Not needed since Python 3.8
  - Change minimum python requirement to 3.8 in `README.md`

- Do not import all plugin modules (only import two plugins that are used)

  - Load json file `plugins-meta/index.json` instead
  - In debug mode, all plugin modules are still imported and validated
  - User plugins are still imported

## Other improvements

- Improve detection of languages from glossary name, and add tests
- Update `langs.json`: add new 3-letter codes for 25 languages
- `glos.preventDuplicateWords` and `glos.removeHtmlTagsAll`: prevent adding filter twice
- `glos.cleanup`: reset path list to avoid (non-critical) error if called again
- Minor improvements in `Glossary.init()`
- `DataEntry.save`: on `FileNotFoundError` show a 1-line error instead of `log.exception`
- ui_gtk: create a new `Glossary` object every time Convert button is clicked
- Add docstring for `Glossary.init`

## Unit testing

- Update `tests/glossary_errors_test.py`
- Add missing cleanup for some temp file
- add test for LDF to/from Tabfile

# Refactoring

- Plugins: replace import of `formats_common` from current directory with `pyglossary.plugins.formats_common`

- Fix `logging.warn` method is deprecated, use `warning` instead, PR #360 by @BoboTiG

- Fix `DeprecationWarning: invalid escape sequence`, PR #361 by @BoboTiG

- Move some functions from `glossary_utils.py` to `compression.py`

- Move some methods from `Glossary` to new parent classes `PluginManager` and `GlossaryInfo`

- Some refactoring in `plugin_prop.py` and `plugin_manager.py`

  - Rename `plugin.pluginModule` to `plugin.module`
  - Minimize direct access to `plugin.module`, `plugin.readerClass` or `plugin.writerClass`
  - Add some new properties to `PluginProp`
  - Remove a log from `glossary.py`
  - Disable validation of plugins unless in debug mode
  - `plugin_prop.py`: fix checking debug level

- `sq_entry_list.py`: rename `sortColumns` to `sqliteSortKey`

- Some refactoring around `setSortKey` between `Glossary`, `EntryList` and `SqEntryList`

- Remove `Entry.sqliteSortKeyFrom` and related classmethods

- Some more simplification in `glossary.py`

- Remove `Entry.defaultSortKey`

- Some style fixes

- `iter_utils.py`: remove unused `key=` argument from `unique_everseen`

- Refactor ui_gtk and update config comments

- `extractInlineHtmlImages`: avoid writing file within sub func
