summaryrefslogtreecommitdiff
path: root/indra/newview/llautoreplace.h
blob: 2d94132c522d00d257afc4d2659b2d5f60d6e93f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/**
 * @file llautoreplace.h
 * @brief Auto Replace Manager
 * $LicenseInfo:firstyear=2012&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2012, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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
 */
#ifndef LLAUTOREPLACE_H
#define LLAUTOREPLACE_H

#include "lllineeditor.h"

class LLAutoReplace;

/** The configuration data for the LLAutoReplace object
 *
 * This is a separate class so that the LLFloaterAutoReplaceSettings
 * can have a copy of the configuration to manipulate before committing
 * the changes back to the LLAutoReplace singleton that provides the
 * autoreplace callback.
 */
class LLAutoReplaceSettings
{
  public:
    LLAutoReplaceSettings();
    ~LLAutoReplaceSettings();

    /// Constructor for creating a tempory copy of the current settings
    LLAutoReplaceSettings(const LLAutoReplaceSettings& settings);

    /// Replace the current settings with new ones and save them to the user settings file
    void set(const LLAutoReplaceSettings& newSettings);

    /// Load the current settings read from an LLSD file
    bool setFromLLSD(const LLSD& settingsFromLLSD);
    ///< @returns whether or not the settingsFromLLSD were valid

    // ================================================================
    ///@{ @name List Operations
    // ================================================================

    /// @returns the configured list names as an LLSD Array of strings
    LLSD getListNames();

    /// Status values returned from the addList method
    typedef enum
    {
        AddListOk,
        AddListDuplicateName,
        AddListInvalidList,
    } AddListResult;

    /// Inserts a new list at the end of the priority order
    AddListResult addList(const LLSD& newList);

    /// Inserts a list in place of an existing list of the same name
    AddListResult replaceList(const LLSD& newList);

    /// Removes the named list, @returns false if not found
    bool removeReplacementList(std::string listName);

    /// Move the named list up in the priority order
    bool increaseListPriority(std::string listName);
    ///< @returns false if the list is not found

    /// Move the named list down in the priority order
    bool decreaseListPriority(std::string listName);
    ///< @returns false if the list is not found

    /// Get a copy of just one list (for saving to an export file)
    const LLSD* exportList(std::string listName);
    /// @returns an LLSD map

    /// Checks for required elements, and that each has the correct type.
    bool listIsValid(const LLSD& listSettings);

    /// Checks for required elements, and that each has the correct type.
    bool listNameIs(const LLSD& listSettings);

    /// Checks to see if a new lists name conflicts with one in the settings
    bool listNameIsUnique(const LLSD& newList);
    /// @note must be called with LLSD that has passed listIsValid

    /// Initializes emptyList to an empty list named 'Empty'
    static void createEmptyList(LLSD& emptyList);

    /// Resets the name of a list to a new value
    static void setListName(LLSD& list, const std::string& newName);

    /// Gets the name of a list
    static std::string getListName(LLSD& list);

    ///@}
    // ================================================================
    ///@{ @name Replacement Entry Operations
    // ================================================================

    /// Get the replacements specified by a given list
    const LLSD* getListEntries(std::string listName);
    ///< @returns an LLSD Map of keyword -> replacement test pairs

    /// Get the replacement for the keyword from the specified list
    std::string replacementFor(std::string keyword, std::string listName);

    /// Adds a keywword/replacement pair to the named list
    bool addEntryToList(LLWString keyword, LLWString replacement, std::string listName);

    /// Removes the keywword and its replacement from the named list
    bool removeEntryFromList(std::string keyword, std::string listName);

    /**
     * Look for currentWord in the lists in order, returning any substitution found
     * If no configured substitution is found, returns currentWord
     */
    std::string replaceWord(const std::string currentWord /**< word to search for */ );

    /// Provides a hard-coded example of settings
    LLSD getExampleLLSD();

    /// Get the actual settings as LLSD
    const LLSD& asLLSD();
    ///< @note for use only in AutoReplace::saveToUserSettings

  private:
    /// Efficiently and safely compare list names
    bool listNameMatches( const LLSD& list, const std::string name );

    /// The actual llsd data structure
    LLSD mLists;

    static const std::string AUTOREPLACE_LIST_NAME;      ///< key for looking up list names
    static const std::string AUTOREPLACE_LIST_REPLACEMENTS; ///< key for looking up replacement map

    /**<
     * LLSD structure of the lists
     * - The configuration is an array (mLists),
     * - Each entry in the array is a replacement list
     * - Each replacement list is a map with three keys:
     * @verbatim
     *     "name"         String    the name of the list
     *     "replacements" Map       keyword -> replacement pairs
     *
     * <llsd>
     *   <array>
     *     <map>
     *       <key>name</key>    <string>List 1</string>
     *       <key>data</key>
     *         <map>
     *           <key>keyword1</key>  <string>replacement1</string>
     *           <key>keyword2</key>  <string>replacement2</string>
     *         </map>
     *     </map>
     *     <map>
     *       <key>name</key>    <string>List 2</string>
     *       <key>data</key>
     *         <map>
     *           <key>keyword1</key>  <string>replacement1</string>
     *           <key>keyword2</key>  <string>replacement2</string>
     *         </map>
     *     </map>
     *   </array>
     * </llsd>
     * @endverbatim
     */
};

/** Provides a facility to auto-replace text dynamically as it is entered.
 *
 * When the end of a word is detected (defined as any punctuation character,
 * or any whitespace except newline or return), the preceding word is used
 * as a lookup key in an ordered list of maps.  If a match is found in any
 * map, the replacement start index and length are returned along with the
 * new replacement string.
 *
 * See the autoreplaceCallback method for how to add autoreplace functionality
 * to a text entry tool.
 */
class LLAutoReplace : public LLSingleton<LLAutoReplace>
{
    LLSINGLETON(LLAutoReplace);
public:
    /// Callback that provides the hook for use in text entry methods
    void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text);

    /// Get a copy of the current settings
    LLAutoReplaceSettings getSettings();

    /// Commit new settings after making changes
    void setSettings(const LLAutoReplaceSettings& settings);

private:
    /*virtual*/ void initSingleton() override;

    LLAutoReplaceSettings mSettings; ///< configuration information

    /// Read settings from persistent storage
    void loadFromSettings();

    /// Make the newSettings active and write them to user storage
    void saveToUserSettings();

    /// Compute the user settings file name
    std::string getUserSettingsFileName();

    /// Compute the (read-ony) application settings file name
    std::string getAppSettingsFileName();

    /// basename for the settings files
    static const char* SETTINGS_FILE_NAME;
};

#endif /* LLAUTOREPLACE_H */