178 lines
4.6 KiB
C++
178 lines
4.6 KiB
C++
![]() |
#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
|