Exteor/src/dialog/InsertCstDlg.cpp

178 lines
4.6 KiB
C++
Raw Normal View History

2024-06-07 20:30:06 +03:00
#include "stdafx.h"
#include "xtr/dialog/InsertCstDlg.h"
#include "resource.h"
#include "xtr/ExteorOptions.h"
#include "xtr/cclDescriptor.h"
#include "ccl/semantic/CstFilters.hpp"
namespace xtr::dialog {
using ccl::semantic::RSCore;
InsertCstDlg::InsertCstDlg(const RSCore& context, const CPoint pos,
const CString hint, CWnd* pParent)
: CDialog(IXTRD_AUTOCOMPLETE, pParent),
context{ context }, position{ pos }, hint{ hint } {}
void InsertCstDlg::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
::DDX_Control(pDX, IXTRC_AC_LIST1, pickerControl);
}
BOOL InsertCstDlg::OnInitDialog() {
CDialog::OnInitDialog();
if (!hint.IsEmpty()) {
UpdateContextNameList();
}
if (std::empty(typifications)) {
UpdateTypingNameList();
} else {
state = DS_CSTS;
}
pickerControl.SetFont(&XTROptions::App().fontMathTT);
pickerControl.SetCurSel(0);
FitDialogSize();
return TRUE;
}
BOOL InsertCstDlg::PreTranslateMessage(MSG* pMsg) {
if (pMsg->hwnd == pickerControl.GetSafeHwnd()) {
switch (state) {
case DS_DEFAULT:
if (pMsg->message == WM_LBUTTONDBLCLK ||
(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)) {
OnSelectTyping(); return TRUE;
}
break;
case DS_CSTS:
if (pMsg->message == WM_LBUTTONDBLCLK ||
(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)) {
OnSelectCst(); return TRUE;
}
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
void InsertCstDlg::OnSelectTyping() {
const auto selected = pickerControl.GetCurSel();
choice = typifications.at(selected);
VectorOfEntities filteredIDs{};
if (selected == 0) {
std::copy(std::begin(context.List()), std::end(context.List()), std::back_inserter(filteredIDs));
} else {
const auto filter = [&typeStr = this->choice, &schema = this->context] (const auto uid)
-> std::optional<EntityUID> {
const auto* cstType = schema.GetParse(uid).TypePtr();
if (cstType != nullptr && typeStr == info::Label(cstType)) {
return uid;
} else {
return std::nullopt;
}
};
filteredIDs = ccl::semantic::FilterCst(context, filter);
}
typifications.clear();
pickerControl.ResetContent();
CString listItem{};
for (const auto uid : filteredIDs) {
const auto& rsCst = context.GetRS(uid);
typifications.emplace_back(mfc::ToMFC(rsCst.alias));
listItem = mfc::ToMFC(rsCst.alias);
listItem += LR"(: )";
listItem += mfc::ToMFC(context.GetText(uid).term.Nominal());
pickerControl.AddString(listItem);
}
pickerControl.SetCurSel(0);
pickerControl.SetFocus();
FitDialogSize();
state = DS_CSTS;
}
void InsertCstDlg::OnSelectCst() {
cstName = typifications.at(pickerControl.GetCurSel());
OnOK();
}
void InsertCstDlg::FitDialogSize() {
static constexpr auto MAX_WIDTH = 600;
auto h = 0;
auto width1 = 0;
CString str{};
CSize sz{};
auto* pDC1 = pickerControl.GetDC();
pDC1->SelectObject(pickerControl.GetFont());
for (auto i = 0; i < pickerControl.GetCount(); ++i) {
if (i < 10) {
h += pickerControl.GetItemHeight(i);
}
pickerControl.GetText(i, str);
sz = pDC1->GetTextExtent(str);
if (sz.cx > width1) {
width1 = sz.cx;
}
}
pickerControl.ReleaseDC(pDC1);
width1 = std::min(width1 + 5, MAX_WIDTH) + GetSystemMetrics(SM_CXVSCROLL);
h += 4;
SetWindowPos(nullptr, position.x, position.y, width1, h, SWP_SHOWWINDOW);
pickerControl.SetWindowPos(&wndTop, 0, 0, width1, h, SWP_SHOWWINDOW);
pickerControl.SetColumnWidth(width1);
}
void InsertCstDlg::UpdateTypingNameList() {
static auto selectAll = mfc::LoadSID(IXTRS_SELECT_ALL);
pickerControl.ResetContent();
typifications.clear();
typifications.emplace_back(selectAll);
pickerControl.AddString(selectAll);
std::set<CString> steps{};
for (const auto uid : context.List()) {
steps.insert(info::Label(context.GetParse(uid).TypePtr()));
}
for (const auto& aName : steps) {
typifications.emplace_back(aName);
pickerControl.AddString(aName);
}
}
void InsertCstDlg::UpdateContextNameList() {
pickerControl.ResetContent();
typifications.clear();
const auto inputs = context.Texts().Context().MatchingTerms(mfc::ToSTL(hint));
CString listItem{};
for (const auto uid : context.List()) {
const auto& alias = context.GetText(uid).alias;
if (inputs.contains(alias)) {
const auto& title = inputs.at(alias);
typifications.emplace_back(mfc::ToMFC(alias));
listItem = mfc::ToMFC(alias);
listItem += LR"(: )";
listItem += mfc::ToMFC(title);
pickerControl.AddString(listItem);
}
}
}
} // namespace xtr::dialog