00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CConfig.h"
00016 #include "KeyTypes.h"
00017 #include "OptionTypes.h"
00018 #include "ProtocolTypes.h"
00019 #include "CStringUtil.h"
00020 #include "CArch.h"
00021 #include "CAddScreen.h"
00022 #include "LaunchUtil.h"
00023 #include "resource.h"
00024
00025 struct CModifierInfo {
00026 public:
00027 int m_ctrlID;
00028 const char* m_name;
00029 KeyModifierID m_modifierID;
00030 OptionID m_optionID;
00031 };
00032
00033 static const CModifierInfo s_modifiers[] = {
00034 { IDC_ADD_MOD_SHIFT, "Shift",
00035 kKeyModifierIDShift, kOptionModifierMapForShift },
00036 { IDC_ADD_MOD_CTRL, "Ctrl",
00037 kKeyModifierIDControl, kOptionModifierMapForControl },
00038 { IDC_ADD_MOD_ALT, "Alt",
00039 kKeyModifierIDAlt, kOptionModifierMapForAlt },
00040 { IDC_ADD_MOD_META, "Meta",
00041 kKeyModifierIDMeta, kOptionModifierMapForMeta },
00042 { IDC_ADD_MOD_SUPER, "Super",
00043 kKeyModifierIDSuper, kOptionModifierMapForSuper }
00044 };
00045
00046 static const KeyModifierID baseModifier = kKeyModifierIDShift;
00047
00048
00049
00050
00051
00052 CAddScreen* CAddScreen::s_singleton = NULL;
00053
00054 CAddScreen::CAddScreen(HWND parent, CConfig* config, const CString& name) :
00055 m_parent(parent),
00056 m_config(config),
00057 m_name(name)
00058 {
00059 assert(s_singleton == NULL);
00060 s_singleton = this;
00061 }
00062
00063 CAddScreen::~CAddScreen()
00064 {
00065 s_singleton = NULL;
00066 }
00067
00068 bool
00069 CAddScreen::doModal()
00070 {
00071
00072 return (DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_ADD),
00073 m_parent, (DLGPROC)dlgProc, (LPARAM)this) != 0);
00074 }
00075
00076 CString
00077 CAddScreen::getName() const
00078 {
00079 return m_name;
00080 }
00081
00082 void
00083 CAddScreen::init(HWND hwnd)
00084 {
00085
00086 CString title;
00087 if (m_name.empty()) {
00088 title = getString(IDS_ADD_SCREEN);
00089 }
00090 else {
00091 title = CStringUtil::format(
00092 getString(IDS_EDIT_SCREEN).c_str(),
00093 m_name.c_str());
00094 }
00095 SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)title.c_str());
00096
00097
00098 HWND child = getItem(hwnd, IDC_ADD_SCREEN_NAME_EDIT);
00099 SendMessage(child, WM_SETTEXT, 0, (LPARAM)m_name.c_str());
00100
00101
00102 CString aliases;
00103 for (CConfig::all_const_iterator index = m_config->beginAll();
00104 index != m_config->endAll(); ++index) {
00105 if (CStringUtil::CaselessCmp::equal(index->second, m_name) &&
00106 !CStringUtil::CaselessCmp::equal(index->second, index->first)) {
00107 if (!aliases.empty()) {
00108 aliases += "\r\n";
00109 }
00110 aliases += index->first;
00111 }
00112 }
00113 child = getItem(hwnd, IDC_ADD_ALIASES_EDIT);
00114 SendMessage(child, WM_SETTEXT, 0, (LPARAM)aliases.c_str());
00115
00116
00117 CConfig::CScreenOptions options;
00118 getOptions(options);
00119 CConfig::CScreenOptions::const_iterator index;
00120 child = getItem(hwnd, IDC_ADD_HD_CAPS_CHECK);
00121 index = options.find(kOptionHalfDuplexCapsLock);
00122 setItemChecked(child, (index != options.end() && index->second != 0));
00123 child = getItem(hwnd, IDC_ADD_HD_NUM_CHECK);
00124 index = options.find(kOptionHalfDuplexNumLock);
00125 setItemChecked(child, (index != options.end() && index->second != 0));
00126 child = getItem(hwnd, IDC_ADD_HD_SCROLL_CHECK);
00127 index = options.find(kOptionHalfDuplexScrollLock);
00128 setItemChecked(child, (index != options.end() && index->second != 0));
00129
00130
00131 for (UInt32 i = 0; i < sizeof(s_modifiers) /
00132 sizeof(s_modifiers[0]); ++i) {
00133 child = getItem(hwnd, s_modifiers[i].m_ctrlID);
00134
00135
00136 for (UInt32 j = 0; j < sizeof(s_modifiers) /
00137 sizeof(s_modifiers[0]); ++j) {
00138 SendMessage(child, CB_ADDSTRING, 0,
00139 (LPARAM)s_modifiers[j].m_name);
00140 }
00141
00142
00143 index = options.find(s_modifiers[i].m_optionID);
00144 KeyModifierID id = s_modifiers[i].m_modifierID;
00145 if (index != options.end()) {
00146 id = index->second;
00147 }
00148 SendMessage(child, CB_SETCURSEL, id - baseModifier, 0);
00149 }
00150
00151
00152 UInt32 corners = 0;
00153 index = options.find(kOptionScreenSwitchCorners);
00154 if (index != options.end()) {
00155 corners = index->second;
00156 }
00157 child = getItem(hwnd, IDC_ADD_DC_TOP_LEFT);
00158 setItemChecked(child, (corners & kTopLeftMask) != 0);
00159 child = getItem(hwnd, IDC_ADD_DC_TOP_RIGHT);
00160 setItemChecked(child, (corners & kTopRightMask) != 0);
00161 child = getItem(hwnd, IDC_ADD_DC_BOTTOM_LEFT);
00162 setItemChecked(child, (corners & kBottomLeftMask) != 0);
00163 child = getItem(hwnd, IDC_ADD_DC_BOTTOM_RIGHT);
00164 setItemChecked(child, (corners & kBottomRightMask) != 0);
00165 index = options.find(kOptionScreenSwitchCornerSize);
00166 SInt32 size = 0;
00167 if (index != options.end()) {
00168 size = index->second;
00169 }
00170 char buffer[20];
00171 sprintf(buffer, "%d", size);
00172 child = getItem(hwnd, IDC_ADD_DC_SIZE);
00173 SendMessage(child, WM_SETTEXT, 0, (LPARAM)buffer);
00174 }
00175
00176 bool
00177 CAddScreen::save(HWND hwnd)
00178 {
00179
00180 CStringList oldAliases;
00181 getAliases(oldAliases);
00182 CConfig::CScreenOptions options;
00183 getOptions(options);
00184
00185
00186 CString newName;
00187 HWND child = getItem(hwnd, IDC_ADD_SCREEN_NAME_EDIT);
00188 newName = getWindowText(child);
00189 CStringList newAliases;
00190 child = getItem(hwnd, IDC_ADD_ALIASES_EDIT);
00191 tokenize(newAliases, getWindowText(child));
00192
00193
00194 if (!m_config->isValidScreenName(newName)) {
00195 showError(hwnd, CStringUtil::format(
00196 getString(IDS_INVALID_SCREEN_NAME).c_str(),
00197 newName.c_str()));
00198 return false;
00199 }
00200
00201
00202 for (CStringList::const_iterator index = newAliases.begin();
00203 index != newAliases.end(); ++index) {
00204 if (!m_config->isValidScreenName(*index)) {
00205 showError(hwnd, CStringUtil::format(
00206 getString(IDS_INVALID_SCREEN_NAME).c_str(),
00207 index->c_str()));
00208 return false;
00209 }
00210 }
00211
00212
00213 if (isNameInList(newAliases, newName)) {
00214 showError(hwnd, CStringUtil::format(
00215 getString(IDS_SCREEN_NAME_IS_ALIAS).c_str(),
00216 newName.c_str()));
00217 return false;
00218 }
00219
00220
00221
00222
00223 if (m_config->isScreen(newName) &&
00224 !CStringUtil::CaselessCmp::equal(newName, m_name) &&
00225 !isNameInList(oldAliases, newName)) {
00226 showError(hwnd, CStringUtil::format(
00227 getString(IDS_DUPLICATE_SCREEN_NAME).c_str(),
00228 newName.c_str()));
00229 return false;
00230 }
00231
00232
00233
00234 for (CStringList::const_iterator index = newAliases.begin();
00235 index != newAliases.end(); ++index) {
00236 if (m_config->isScreen(*index) &&
00237 !CStringUtil::CaselessCmp::equal(*index, m_name) &&
00238 !isNameInList(oldAliases, *index)) {
00239 showError(hwnd, CStringUtil::format(
00240 getString(IDS_DUPLICATE_SCREEN_NAME).c_str(),
00241 index->c_str()));
00242 return false;
00243 }
00244 }
00245
00246
00247 child = getItem(hwnd, IDC_ADD_DC_SIZE);
00248 CString valueString = getWindowText(child);
00249 int cornerSize = atoi(valueString.c_str());
00250 if (cornerSize < 0) {
00251 showError(hwnd, CStringUtil::format(
00252 getString(IDS_INVALID_CORNER_SIZE).c_str(),
00253 valueString.c_str()));
00254 SetFocus(child);
00255 return false;
00256 }
00257
00258
00259 child = getItem(hwnd, IDC_ADD_HD_CAPS_CHECK);
00260 if (isItemChecked(child)) {
00261 options[kOptionHalfDuplexCapsLock] = 1;
00262 }
00263 else {
00264 options.erase(kOptionHalfDuplexCapsLock);
00265 }
00266 child = getItem(hwnd, IDC_ADD_HD_NUM_CHECK);
00267 if (isItemChecked(child)) {
00268 options[kOptionHalfDuplexNumLock] = 1;
00269 }
00270 else {
00271 options.erase(kOptionHalfDuplexNumLock);
00272 }
00273 child = getItem(hwnd, IDC_ADD_HD_SCROLL_CHECK);
00274 if (isItemChecked(child)) {
00275 options[kOptionHalfDuplexScrollLock] = 1;
00276 }
00277 else {
00278 options.erase(kOptionHalfDuplexScrollLock);
00279 }
00280
00281
00282 for (UInt32 i = 0; i < sizeof(s_modifiers) /
00283 sizeof(s_modifiers[0]); ++i) {
00284 child = getItem(hwnd, s_modifiers[i].m_ctrlID);
00285 KeyModifierID id = static_cast<KeyModifierID>(
00286 SendMessage(child, CB_GETCURSEL, 0, 0) +
00287 baseModifier);
00288 if (id != s_modifiers[i].m_modifierID) {
00289 options[s_modifiers[i].m_optionID] = id;
00290 }
00291 else {
00292 options.erase(s_modifiers[i].m_optionID);
00293 }
00294 }
00295
00296
00297 UInt32 corners = 0;
00298 if (isItemChecked(getItem(hwnd, IDC_ADD_DC_TOP_LEFT))) {
00299 corners |= kTopLeftMask;
00300 }
00301 if (isItemChecked(getItem(hwnd, IDC_ADD_DC_TOP_RIGHT))) {
00302 corners |= kTopRightMask;
00303 }
00304 if (isItemChecked(getItem(hwnd, IDC_ADD_DC_BOTTOM_LEFT))) {
00305 corners |= kBottomLeftMask;
00306 }
00307 if (isItemChecked(getItem(hwnd, IDC_ADD_DC_BOTTOM_RIGHT))) {
00308 corners |= kBottomRightMask;
00309 }
00310 options[kOptionScreenSwitchCorners] = corners;
00311 options[kOptionScreenSwitchCornerSize] = cornerSize;
00312
00313
00314 if (m_name.empty()) {
00315
00316 m_config->addScreen(newName);
00317 }
00318 else {
00319
00320 m_config->removeAliases(m_name);
00321 m_config->removeOptions(m_name);
00322 m_config->renameScreen(m_name, newName);
00323 }
00324 m_name = newName;
00325 for (CStringList::const_iterator index = newAliases.begin();
00326 index != newAliases.end(); ++index) {
00327 m_config->addAlias(m_name, *index);
00328 }
00329 for (CConfig::CScreenOptions::const_iterator
00330 index = options.begin();
00331 index != options.end(); ++index) {
00332 m_config->addOption(m_name, index->first, index->second);
00333 }
00334
00335 return true;
00336 }
00337
00338 BOOL
00339 CAddScreen::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM)
00340 {
00341 switch (message) {
00342 case WM_INITDIALOG:
00343 init(hwnd);
00344 return TRUE;
00345
00346 case WM_COMMAND:
00347 switch (LOWORD(wParam)) {
00348 case IDOK:
00349 if (save(hwnd)) {
00350 EndDialog(hwnd, 1);
00351 }
00352 return TRUE;
00353
00354 case IDCANCEL:
00355 EndDialog(hwnd, 0);
00356 return TRUE;
00357 }
00358 break;
00359
00360 default:
00361 break;
00362 }
00363
00364 return FALSE;
00365 }
00366
00367 BOOL CALLBACK
00368 CAddScreen::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
00369 {
00370 return s_singleton->doDlgProc(hwnd, message, wParam, lParam);
00371 }
00372
00373 void
00374 CAddScreen::getAliases(CStringList& aliases) const
00375 {
00376 for (CConfig::all_const_iterator index = m_config->beginAll();
00377 index != m_config->endAll(); ++index) {
00378 if (CStringUtil::CaselessCmp::equal(index->second, m_name) &&
00379 !CStringUtil::CaselessCmp::equal(index->second, index->first)) {
00380 aliases.push_back(index->first);
00381 }
00382 }
00383 }
00384
00385 void
00386 CAddScreen::getOptions(CConfig::CScreenOptions& optionsOut) const
00387 {
00388 const CConfig::CScreenOptions* options = m_config->getOptions(m_name);
00389 if (options == NULL) {
00390 optionsOut = CConfig::CScreenOptions();
00391 }
00392 else {
00393 optionsOut = *options;
00394 }
00395 }
00396
00397 void
00398 CAddScreen::tokenize(CStringList& tokens, const CString& src)
00399 {
00400
00401 CString::size_type x = src.find_first_not_of(" \t\r\n");
00402 if (x == CString::npos) {
00403 return;
00404 }
00405
00406
00407 do {
00408 CString::size_type y = src.find_first_of(" \t\r\n", x);
00409 if (y == CString::npos) {
00410 y = src.size();
00411 }
00412 tokens.push_back(src.substr(x, y - x));
00413 x = src.find_first_not_of(" \t\r\n", y);
00414 } while (x != CString::npos);
00415 }
00416
00417 bool
00418 CAddScreen::isNameInList(const CStringList& names, const CString& name)
00419 {
00420 for (CStringList::const_iterator index = names.begin();
00421 index != names.end(); ++index) {
00422 if (CStringUtil::CaselessCmp::equal(name, *index)) {
00423 return true;
00424 }
00425 }
00426 return false;
00427 }