Files
hrynco-kswitcher/src/ui_sync_conflicts.inl
T

81 lines
4.2 KiB
C++

struct SyncConflictView
{
HWND parent;
App *app;
std::vector<SyncConflict> conflicts;
std::map<size_t, bool> choices;
};
void showConflictValues(HWND w, SyncConflictView *v)
{
int selected = (int)SendDlgItemMessageW(w, 620, LB_GETCURSEL, 0, 0);
if (selected < 0 || selected >= (int)v->conflicts.size()) return;
const auto &c = v->conflicts[selected];
value(w, 621, syncValueText(c.local)); value(w, 622, syncValueText(c.remote));
}
LRESULT CALLBACK syncConflictsProc(HWND w, UINT msg, WPARAM wp, LPARAM lp)
{
if (msg == WM_DPICHANGED) { resizeForDpi(w, wp, lp); return 0; }
auto *v = reinterpret_cast<SyncConflictView *>(GetWindowLongPtrW(w, GWLP_USERDATA));
if (!v) return DefWindowProcW(w, msg, wp, lp);
try
{
if (msg == WM_COMMAND)
{
int id = LOWORD(wp);
if (id == 620 && HIWORD(wp) == LBN_SELCHANGE) { showConflictValues(w, v); return 0; }
if (id == 623 || id == 624)
{
int selected = (int)SendDlgItemMessageW(w, 620, LB_GETCURSEL, 0, 0);
if (selected < 0 || selected >= (int)v->conflicts.size()) return 0;
v->choices[selected] = id == 623;
auto text = v->conflicts[selected].label + (id == 623 ? L" [This PC]" : L" [Server]");
SendDlgItemMessageW(w, 620, LB_DELETESTRING, selected, 0);
SendDlgItemMessageW(w, 620, LB_INSERTSTRING, selected, (LPARAM)text.c_str());
SendDlgItemMessageW(w, 620, LB_SETCURSEL, selected, 0);
return 0;
}
if (id == IDOK)
{
if (v->choices.empty()) throw std::runtime_error("Select a setting and choose This PC or Server first.");
std::vector<SyncChoice> choices;
for (const auto &[index, local] : v->choices) choices.push_back({v->conflicts.at(index), local});
auto status = v->app->syncCommand(4, choices);
value(v->parent, 608, status);
if (status != L"Connecting to OpenBao...") throw std::runtime_error(utf8(status));
DestroyWindow(w); return 0;
}
if (id == IDCANCEL) { DestroyWindow(w); return 0; }
}
}
catch (const std::exception &e) { error(w, e); return 0; }
if (msg == WM_CLOSE) { DestroyWindow(w); return 0; }
if (msg == WM_NCDESTROY)
{
EnableWindow(v->parent, TRUE); SetForegroundWindow(v->parent);
disposeFont(w); delete v; SetWindowLongPtrW(w, GWLP_USERDATA, 0);
}
return DefWindowProcW(w, msg, wp, lp);
}
void showSyncConflicts(HWND parent, App &app)
{
auto conflicts = decodeSyncConflicts(app.syncConflictData());
if (conflicts.empty()) { value(parent, 608, L"No pending conflicts. Run Sync to check for changes."); return; }
HWND w = makeWindow(app, L"KSwitcher.SyncConflicts", L"Resolve individual settings", syncConflictsProc, 800, 560);
SetWindowLongPtrW(w, GWLP_HWNDPARENT, (LONG_PTR)parent);
auto *v = new SyncConflictView{parent, &app, std::move(conflicts), {}};
SetWindowLongPtrW(w, GWLP_USERDATA, (LONG_PTR)v);
label(w, L"Choose a value for each conflicting setting. Other changes are already synchronized.", 18, 16, 760);
control(w, L"LISTBOX", L"", WS_TABSTOP | WS_VSCROLL | LBS_NOTIFY | WS_BORDER, 620, 18, 48, 760, 130);
for (const auto &c : v->conflicts) SendDlgItemMessageW(w, 620, LB_ADDSTRING, 0, (LPARAM)c.label.c_str());
label(w, L"This PC", 18, 190, 360); label(w, L"Server", 410, 190, 368);
edit(w, 621, 18, 220, 368, 180, ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL | WS_VSCROLL);
edit(w, 622, 410, 220, 368, 180, ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL | WS_VSCROLL);
button(w, L"Use this &PC for selected setting", 623, 18, 412, 368);
button(w, L"Use &server for selected setting", 624, 410, 412, 368);
label(w, L"Unselected conflicts stay pending. Changed values will be checked again before saving.", 18, 454, 760);
button(w, L"&Apply choices", IDOK, 526, 488, 140);
button(w, L"&Cancel", IDCANCEL, 678, 488, 100);
SendDlgItemMessageW(w, 620, LB_SETCURSEL, 0, 0); showConflictValues(w, v);
EnableWindow(parent, FALSE); showRequestedWindow(w); SetForegroundWindow(w);
}