private void InitPlaceholdersBox(bool bRtl) { const string VkcBreak = @"<break />"; string[] vSpecialKeyCodes = new string[] { "TAB", "ENTER", "UP", "DOWN", "LEFT", "RIGHT", "HOME", "END", "PGUP", "PGDN", "INSERT", "DELETE", "SPACE", VkcBreak, "BACKSPACE", "BREAK", "CAPSLOCK", "ESC", "WIN", "LWIN", "RWIN", "APPS", "HELP", "NUMLOCK", "PRTSC", "SCROLLLOCK", VkcBreak, "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", VkcBreak, "ADD", "SUBTRACT", "MULTIPLY", "DIVIDE", "NUMPAD0", "NUMPAD1", "NUMPAD2", "NUMPAD3", "NUMPAD4", "NUMPAD5", "NUMPAD6", "NUMPAD7", "NUMPAD8", "NUMPAD9" }; string[] vSpecialPlaceholders = new string[] { "GROUP", "GROUP_PATH", "GROUP_NOTES", "GROUP_SEL", "GROUP_SEL_PATH", "GROUP_SEL_NOTES", "PASSWORD_ENC", "URL:RMVSCM", "URL:SCM", "URL:HOST", "URL:PORT", "URL:PATH", "URL:QUERY", "URL:USERINFO", "URL:USERNAME", "URL:PASSWORD", // "BASE", "UUID", "T-REPLACE-RX:/T/S/R/", "T-CONV:/T/C/", "C:Comment", VkcBreak, "DELAY 1000", "DELAY=200", "VKEY 13", "VKEY 13 E", // "VKEY-NX 13", "VKEY-EX 13", "PICKCHARS", "PICKCHARS:Password:C=3", "PICKFIELD", "NEWPASSWORD", "NEWPASSWORD:/Profile/", "HMACOTP", "TIMEOTP", "CLEARFIELD", // https://sourceforge.net/p/keepass/discussion/329220/thread/f98dece5/ "APPACTIVATE " + (bRtl ? "Title" : KPRes.Title), "BEEP 800 200", "CLIPBOARD", "CLIPBOARD-SET:/T/", "CMD:/C/O/", VkcBreak, "APPDIR", "DB_PATH", "DB_DIR", "DB_NAME", "DB_BASENAME", "DB_EXT", "ENV_DIRSEP", "ENV_PROGRAMFILES_X86", VkcBreak, // "INTERNETEXPLORER", "FIREFOX", "OPERA", "GOOGLECHROME", // "SAFARI", VkcBreak, "DT_SIMPLE", "DT_YEAR", "DT_MONTH", "DT_DAY", "DT_HOUR", "DT_MINUTE", "DT_SECOND", "DT_UTC_SIMPLE", "DT_UTC_YEAR", "DT_UTC_MONTH", "DT_UTC_DAY", "DT_UTC_HOUR", "DT_UTC_MINUTE", "DT_UTC_SECOND" }; string strSfx = (bRtl ? string.Empty : ":"); RichTextBuilder rb = new RichTextBuilder(); rb.AppendLine(KPRes.StandardFields, FontStyle.Bold, null, null, strSfx, null); rb.Append("{" + PwDefs.TitleField + "} "); rb.Append("{" + PwDefs.UserNameField + "} "); rb.Append("{" + PwDefs.PasswordField + "} "); rb.Append("{" + PwDefs.UrlField + "} "); rb.Append("{" + PwDefs.NotesField + "}"); bool bCustomInitialized = false, bFirst = true; foreach (KeyValuePair <string, ProtectedString> kvp in m_vStringDict) { if (!PwDefs.IsStandardField(kvp.Key)) { if (bCustomInitialized == false) { rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.CustomFields, FontStyle.Bold, null, null, strSfx, null); bCustomInitialized = true; } if (!bFirst) { rb.Append(" "); } rb.Append("{" + PwDefs.AutoTypeStringPrefix + kvp.Key + "}"); bFirst = false; } } rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.KeyboardKeyModifiers, FontStyle.Bold, null, null, strSfx, null); rb.Append(KPRes.KeyboardKeyShift + @": +, "); rb.Append(KPRes.KeyboardKeyCtrl + @": ^, "); rb.Append(KPRes.KeyboardKeyAlt + @": %"); rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.SpecialKeys, FontStyle.Bold, null, null, strSfx, null); bFirst = true; foreach (string strNav in vSpecialKeyCodes) { if (strNav == VkcBreak) { rb.AppendLine(); rb.AppendLine(); bFirst = true; } else { if (!bFirst) { rb.Append(" "); } rb.Append("{" + strNav + "}"); bFirst = false; } } rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.OtherPlaceholders, FontStyle.Bold, null, null, strSfx, null); bFirst = true; foreach (string strPH in vSpecialPlaceholders) { if (strPH == VkcBreak) { rb.AppendLine(); rb.AppendLine(); bFirst = true; } else { if (!bFirst) { rb.Append(" "); } rb.Append("{" + strPH + "}"); bFirst = false; } } if (SprEngine.FilterPlaceholderHints.Count > 0) { rb.AppendLine(); rb.AppendLine(); rb.AppendLine(KPRes.PluginProvided, FontStyle.Bold, null, null, strSfx, null); bFirst = true; foreach (string strP in SprEngine.FilterPlaceholderHints) { if (string.IsNullOrEmpty(strP)) { continue; } if (!bFirst) { rb.Append(" "); } rb.Append(strP); bFirst = false; } } rb.Build(m_rtbPlaceholders, true); LinkifyRtf(m_rtbPlaceholders); }