# Preferences system

## Preference system introduction

Each preference is defined in a text file associated with the collection it belongs to. The contents of these text files are then used to generate the associated source code necessary to define the preference.

## Adding a new collection

To add a new collection, you need to perform at least the following steps:

1. Copy one of the existing collections in `modules/prefs/prefsmanager/collections/` as a base (you need to copy the `.cpp`, `.h` and `.txt` file), adapting it and possibly moving it to a more relevant location. If your collection needs to be able to host site-specific preferences, you must inherit from the `OpPrefsCollectionWithHostOverride` class, if not, you should inherit `OpPrefsCollectionDefault`.
2. Add an entry for the collection in the `module.prefs` file for the module where you added the collection. Each line in the `module.prefs` file lists the name of a single collection, listing the path relative to the module root for the .txt file that lists the preferences to generate code for.
   See the `module.prefs` file in the prefs module for an example.
3. Add an initializer for the collection in `PrefsManager::ConstructL` and an OperaGlobal reference for it in `PrefsModule`

Finally, you need to add preferences to the collection, continue reading below for details.

## Adding a new preference

To add a new preference, find the collection appropriate for your preference, and then locate the text file associated with this collection (see for example the core collection preferences).

Add the new preference to the list and invoke the `opersetup.py` script (this is usually done whenever you build the Opera sources) to generate the source code necessary to define the preference (this will also update the settings documentation). If the preference is controlled by a feature definition, the preference for it should also be controlled by the same feature definition. If not, it should be exported as an API which the appropriate module can import.

In addition, a corresponding entry must also be added to the `CheckConditionsL()` function, which should check for constraints, if necessary. TODO: It should be possible to set up constraints using the preferences system.

### Exceptions

TODO: Currently, font preferences are not handled through the preferences system, due to various implementation details.

Special preferences, for instance uncountable preferences where the outside system needs access to an entire section, or the number of entries in the section is variable, is handled by special-purpose functionality in the preferences module.

Preferences for system colors (the OP_SYSTEM_COLOR enumeration) are special-cased in the pc_fontcolor.cpp file; see the comments in the file for more information. Custom colors can be defined in the pc_fontcolor.txt file.

## File format

This section documents the format of the text files that defines preferences in the preferences system.

Any lines starting with a hash sign (`#`) are comments and will be ignored. Empty lines are used to the header and the entries, and the individual entries.

An entry is defined on the form

FieldName: Value

### The collection header

Field | Description
--- | ---
Collection | The name of the C++ class holding the collection
Macro name | The C++ macro prefix used in the source code to define collection-specific constants
Description | A description of the collection
Type | The type of collection specified, one of `normal`, `files` and `fontcolor`

### The preferences entry

Field | Applies to | Description
--- | --- | ---
Preference | All | The C++ enumeration name identifying this preference
Depends on | All | Any preprocessor macro dependency for this entry, can either be a single macro name, which will be prefixed by `#ifdef`, or a more complex check which will be prefixed by `#if`
Section | All | The name of the preferences section this preferences belongs to
Key | All | The name of the key that identifies this preference in its section
Type | All | The type of preference specified, one of `boolean`, `integer`, `string`, `file`, `directory`, `color`
Description | All | A description of the preference that will appear in the source code and extracted documentation
Directory | file | The directory (defined by in the OpFileFolder enumeration) that is the default for this file
Default | All but directory | The default value for this preference
Fall back | File | Whether or not the default value should be used if the user has specified a specific path, but that file does not exist

### The footer

A line containing only the string `.eof` marks the end of the file. Anything after this marker will be ignored. It must be separated from the last entry in the file by a blank line.