UserSettings.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "UserSettings.h"
  2. #include "AppConfig.h"
  3. #include <QDir>
  4. #include <QRect>
  5. #include <QSettings>
  6. #include <QtGlobal>
  7. namespace
  8. {
  9. const char kXor[] = "IM-Client-local";
  10. QString encodeSecret(const QString &plain)
  11. {
  12. if (plain.isEmpty())
  13. return QString();
  14. QByteArray raw = plain.toUtf8();
  15. const int kn = static_cast<int>(sizeof(kXor) - 1);
  16. for (int i = 0; i < raw.size(); ++i)
  17. raw[i] = raw[i] ^ kXor[i % kn];
  18. return QString::fromLatin1(raw.toBase64());
  19. }
  20. QString decodeSecret(const QString &stored)
  21. {
  22. if (stored.isEmpty())
  23. return QString();
  24. QByteArray raw = QByteArray::fromBase64(stored.toLatin1());
  25. const int kn = static_cast<int>(sizeof(kXor) - 1);
  26. for (int i = 0; i < raw.size(); ++i)
  27. raw[i] = raw[i] ^ kXor[i % kn];
  28. return QString::fromUtf8(raw);
  29. }
  30. void applyIniCodec(QSettings &ini)
  31. {
  32. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  33. ini.setIniCodec("UTF-8");
  34. #else
  35. Q_UNUSED(ini);
  36. #endif
  37. }
  38. }
  39. UserSettings &UserSettings::instance()
  40. {
  41. static UserSettings s;
  42. return s;
  43. }
  44. bool UserSettings::load()
  45. {
  46. m_path = QDir(AppConfig::dataDir()).filePath(QStringLiteral("user.ini"));
  47. QSettings ini(m_path, QSettings::IniFormat);
  48. applyIniCodec(ini);
  49. m_account = ini.value(QStringLiteral("login/account")).toString().trimmed();
  50. m_nickname = ini.value(QStringLiteral("login/nickname")).toString().trimmed();
  51. m_rememberPassword = ini.value(QStringLiteral("login/remember_password"), false).toBool();
  52. m_autoLogin = ini.value(QStringLiteral("login/auto_login"), false).toBool();
  53. if (m_rememberPassword)
  54. m_password = decodeSecret(ini.value(QStringLiteral("login/password")).toString());
  55. else
  56. m_password.clear();
  57. if (!m_rememberPassword)
  58. m_autoLogin = false;
  59. m_fontPreset = ini.value(QStringLiteral("ui/font_preset")).toString().trimmed();
  60. const int x = ini.value(QStringLiteral("window/x"), -1).toInt();
  61. const int y = ini.value(QStringLiteral("window/y"), -1).toInt();
  62. const int w = ini.value(QStringLiteral("window/w"), 0).toInt();
  63. const int h = ini.value(QStringLiteral("window/h"), 0).toInt();
  64. if (w > 0 && h > 0)
  65. m_windowRect = QRect(x, y, w, h);
  66. m_windowMaximized = ini.value(QStringLiteral("window/maximized"), false).toBool();
  67. const QString closeAct = ini.value(QStringLiteral("window/close_action")).toString().trimmed();
  68. if (closeAct == QLatin1String("tray"))
  69. m_closeAction = 1;
  70. else if (closeAct == QLatin1String("quit"))
  71. m_closeAction = 2;
  72. else
  73. m_closeAction = 0;
  74. return true;
  75. }
  76. void UserSettings::persist() const
  77. {
  78. if (m_path.isEmpty())
  79. return;
  80. QSettings ini(m_path, QSettings::IniFormat);
  81. applyIniCodec(ini);
  82. ini.setValue(QStringLiteral("login/account"), m_account);
  83. ini.setValue(QStringLiteral("login/nickname"), m_nickname);
  84. ini.setValue(QStringLiteral("login/remember_password"), m_rememberPassword);
  85. ini.setValue(QStringLiteral("login/auto_login"), m_autoLogin && m_rememberPassword);
  86. ini.setValue(QStringLiteral("login/password"),
  87. m_rememberPassword ? encodeSecret(m_password) : QString());
  88. ini.setValue(QStringLiteral("ui/font_preset"), m_fontPreset);
  89. if (m_windowRect.isValid())
  90. {
  91. ini.setValue(QStringLiteral("window/x"), m_windowRect.x());
  92. ini.setValue(QStringLiteral("window/y"), m_windowRect.y());
  93. ini.setValue(QStringLiteral("window/w"), m_windowRect.width());
  94. ini.setValue(QStringLiteral("window/h"), m_windowRect.height());
  95. }
  96. ini.setValue(QStringLiteral("window/maximized"), m_windowMaximized);
  97. if (m_closeAction == 1)
  98. ini.setValue(QStringLiteral("window/close_action"), QStringLiteral("tray"));
  99. else if (m_closeAction == 2)
  100. ini.setValue(QStringLiteral("window/close_action"), QStringLiteral("quit"));
  101. else
  102. ini.remove(QStringLiteral("window/close_action"));
  103. ini.sync();
  104. }
  105. void UserSettings::saveLogin(const QString &account, const QString &nickname,
  106. const QString &password, bool rememberPassword, bool autoLogin)
  107. {
  108. m_account = account.trimmed();
  109. m_nickname = nickname.trimmed();
  110. m_rememberPassword = rememberPassword && !password.isEmpty();
  111. m_autoLogin = autoLogin && m_rememberPassword;
  112. m_password = m_rememberPassword ? password : QString();
  113. persist();
  114. }
  115. void UserSettings::setFontPreset(const QString &key)
  116. {
  117. m_fontPreset = key;
  118. persist();
  119. }
  120. void UserSettings::saveWindow(const QRect &rect, bool maximized)
  121. {
  122. if (rect.width() > 0 && rect.height() > 0)
  123. m_windowRect = rect;
  124. m_windowMaximized = maximized;
  125. persist();
  126. }
  127. void UserSettings::setCloseAction(int action)
  128. {
  129. m_closeAction = (action == 1 || action == 2) ? action : 0;
  130. persist();
  131. }