BOOL CReportCtrlEx2::StartEdit(int nItem, int nSubItem) { // Get the grid width and height if (!m_bAllowEdit || /*!_IsValidIndex(nItem) ||*/ nSubItem < 0 || nSubItem >= GetColumnCount()) return FALSE; if (m_ptEditting.x == nItem && m_ptEditting.y == nSubItem) return TRUE; EndItem(TRUE); m_ptEditting.x = nItem; m_ptEditting.y = nSubItem; SetAllItemStates(RC_ITEM_SELECTED, RC_ITEM_UNSELECTED); // unselect all //SetItemStates(m_ptEditting.x, RC_ITEM_SELECTED | RC_ITEM_FOCUSED); // determine editbox font and alignment const DWORD FMT = _GetHeaderTextFormat(nSubItem); if (FMT != m_dwPrevEditFmt) { m_dwPrevEditFmt = FMT; // Funny thing: // Changing CEdit style among ES_LEFT, ES_CENTER, ES_RIGHT at runtime works // sometimes and fails other times. It just cannot guarantee to be succeed. // So I decided to destroy and recreate the CEdit every time when the text // format changes. if (m_pWndEdit->GetSafeHwnd() != NULL) m_pWndEdit->DestroyWindow(); if (!m_pWndEdit->Create(ES_AUTOHSCROLL | ES_NOHIDESEL | WS_CHILD | WS_BORDER | FMT, CRect(0, 0, 1, 1), this, 0)) return FALSE; } else { if (m_pWndEdit->GetSafeHwnd() == NULL && !m_pWndEdit->Create(ES_AUTOHSCROLL | ES_NOHIDESEL | WS_CHILD | WS_BORDER | FMT, CRect(0, 0, 1, 1), this, 0)) { return FALSE; } } m_pWndEdit->SetFont(GetFont()); CRect rcEdit; ListView_GetSubItemRect(GetSafeHwnd(), m_ptEditting.x, m_ptEditting.y, LVIR_LABEL, &rcEdit); if (m_ptEditting.y > 0 && GetImageList() != NULL && GetItemImage(m_ptEditting.x, m_ptEditting.y) >= 0) rcEdit.DeflateRect(16, 0, 0, 0); // Move the editbox to that grid, obtain text from the grid, display the // editbox, and, finally, highlights all text in the editbox and set the // windows focus to the editbox. m_pWndEdit->MoveWindow(&rcEdit); m_pWndEdit->SetWindowText(GetItemText(m_ptEditting.x, m_ptEditting.y)); m_pWndEdit->ShowWindow(SW_SHOW); m_pWndEdit->SetSel(0, -1); m_pWndEdit->SetFocus(); return TRUE; }
void CReportCtrlEx2::_MouseClkMonitor(UINT nMsg, UINT nFlags, CPoint point, BOOL bTriggerEdit) { LVHITTESTINFO hti; hti.pt = point; const int IDX = SubItemHitTest(&hti); const BOOL BEFORE = CListCtrl::GetCheck(IDX) > 0; const BOOL WAS_EDIT = _IsEditVisible(); EndItem(TRUE); const BOOL WASACTIVE = bTriggerEdit ? ExamItemStates(IDX, RC_ITEM_FOCUSED | RC_ITEM_SELECTED) : FALSE; switch (nMsg) { case WM_LBUTTONDOWN: CListCtrl::OnLButtonDown(nFlags, point); break; case WM_LBUTTONDBLCLK: CListCtrl::OnLButtonDblClk(nFlags, point); break; case WM_MBUTTONDOWN: CListCtrl::OnMButtonDown(nFlags, point); break; case WM_MBUTTONDBLCLK: CListCtrl::OnMButtonDblClk(nFlags, point); break; case WM_RBUTTONDOWN: CListCtrl::OnRButtonDown(nFlags, point); break; case WM_RBUTTONDBLCLK: CListCtrl::OnRButtonDblClk(nFlags, point); break; default: break; } const BOOL STATSCHANGED = _ItemCheckMonitor(IDX, BEFORE, CListCtrl::GetCheck(IDX) > 0, nMsg); if (bTriggerEdit && m_bAllowEdit && !STATSCHANGED && !WAS_EDIT && WASACTIVE) { if (hti.iSubItem == 4 || hti.iSubItem == 5) { m_bEdit = FALSE; StartDateTimeCtrl(IDX, hti.iSubItem); } else { m_bEdit = TRUE; StartEdit(IDX, hti.iSubItem); } } }
BOOL CReportCtrlEx2::StartDateTimeCtrl(int nItem, int nSubItem) { // Get the grid width and height if (!m_bAllowEdit || /*!_IsValidIndex(nItem) ||*/ nSubItem < 0 || nSubItem >= GetColumnCount()) return FALSE; if (m_ptEditting.x == nItem && m_ptEditting.y == nSubItem) return TRUE; EndItem(TRUE); m_ptEditting.x = nItem; m_ptEditting.y = nSubItem; SetAllItemStates(RC_ITEM_SELECTED, RC_ITEM_UNSELECTED); // unselect all //SetItemStates(m_ptEditting.x, RC_ITEM_SELECTED | RC_ITEM_FOCUSED); if (m_pDateTimeCtrlReport->GetSafeHwnd() != NULL) m_pDateTimeCtrlReport->DestroyWindow(); CRect rcDateTimeCtrl; ListView_GetSubItemRect(GetSafeHwnd(), m_ptEditting.x, m_ptEditting.y, LVIR_BOUNDS, &rcDateTimeCtrl); m_pDateTimeCtrlReport->Create(WS_VISIBLE | WS_CHILD | WS_TABSTOP | /*DTS_SHOWNONE |*/ DTS_SHORTDATEFORMAT, rcDateTimeCtrl, this, 1006); CString strDate = CListCtrl::GetItemText(nItem, nSubItem); if (!strDate.IsEmpty()) { int iDay = atoi(strDate.Left(2)); int iMes = atoi(strDate.Mid(3, 2)); int iAgno = atoi(strDate.Right(4)); CTime date(iAgno, iMes, iDay, 0, 0, 0); m_pDateTimeCtrlReport->SetTime(&date); } m_pDateTimeCtrlReport->MoveWindow(&rcDateTimeCtrl); m_pDateTimeCtrlReport->ShowWindow(SW_SHOW); m_pDateTimeCtrlReport->SetFocus(); return TRUE; }
void Process(StrLen file_name) { SplitPath dev_name(file_name); SplitName path_name(dev_name.path); SplitExt name_ext(path_name.name); String in_name; if( !name_ext ) { in_name=StringCat(dev_name.dev,path_name.path,name_ext.name,".lang"); } else { in_name=file_name; } TrackStage("Load file #.q;",StrLen(Range(in_name))); CondLang clang(Range(in_name)); TrackStage("Build top lang"); TopLang top(clang); TrackStage("Run good test on top lang"); if( !RunGoodTest(top) ) return; TrackStage("Build bottom lang"); BottomLang bottom(clang); TrackStage("Extend bottom lang"); ExtLang ext_bottom(bottom); TrackStage("Process top lang"); ExtLang ext_top(top); LangDiagram diagram(ext_top); LangStateMachine<LR1Estimate,LR1MapContext> machine(ext_top,diagram,ext_bottom); StateCompress<LR1Estimate> compress(machine); TrackStage("LR1) #;",PrintCompressCounts(compress)); { ulen conflicts=0; for(auto &est : compress.getProps() ) conflicts+=est.hasConflict(); if( conflicts ) { String out_name=StringCat(dev_name.dev,path_name.path,name_ext.name,".bad.txt"); PrintFile out(Range(out_name)); Putobj(out,clang); PrintBad(out,ext_top,compress); Printf(Exception,"#; CONFLICTs detected. Not LR1 language.",conflicts); } else { TrackStage("No conflicts. LR1 language."); } } StateCompress<LR1Estimate,LR1PropNonEmpty> compress_ne(machine); TrackStage("NonEmpty) #;",PrintCompressCounts(compress_ne)); #if 0 StateCompress<LR1Estimate,LR1PropShiftSet> compress_shift(machine); TrackStage("Shift) #;",PrintCompressCounts(compress_shift)); StateCompress<LR1Estimate,LR1PropValidSet> compress_valid(machine); TrackStage("Valid) #;",PrintCompressCounts(compress_valid)); StateCompress<LR1Estimate,LR1PropRuleSet> compress_rules(machine); TrackStage("Rules) #;",PrintCompressCounts(compress_rules)); StateMap map(compress,compress_ne); String out_name=StringCat(dev_name.dev,path_name.path,"Result.txt"); PrintFile out(Range(out_name)); PrintFibres(out,compress,compress_ne,map); Putobj(out,BindOpt(ext_top,compress_ne)); #endif { String out_name=StringCat(dev_name.dev,path_name.path,name_ext.name,".txt"); PrintFile out(Range(out_name)); Putobj(out,clang); Putobj(out,BindOpt(ext_top,compress)); } { String out_name=StringCat(dev_name.dev,path_name.path,name_ext.name,".ddl"); PosPrint<PrintFile> out(Range(out_name)); Printf(out,"/* #;.ddl */\n\n",name_ext.name); Putobj(out,"//include <LangTypes.ddl>\n\n"); Putobj(out,"Lang lang=\n"); // lang { ListPrint<decltype(out)> lang_out(out); // atoms { ListPrint<decltype(lang_out)> atom_out(lang_out); for(auto &atom : clang.getAtoms() ) Printf(atom_out,"{ #; , #; , lang.elements+#; }#;",atom.index,StrLen(atom.name.inner(2,1)),atom.index,EndItem()); Putobj(atom_out,EndList()); } Putobj(lang_out,EndItem()); // synts { ListPrint<decltype(lang_out)> synt_out(lang_out); ulen element=clang.getAtomCount(); ulen top_index=0; for(auto &synt : clang.getSynts() ) { Printf(synt_out,"{ #; , #.q; ,",synt.index,synt.name); auto kinds=synt.kinds; if( !kinds ) { Indent indent(synt_out.getCol()); Printf(synt_out," { { #; , 0 , \"\" , lang.synts+#; , lang.elements+#; ,#;",top_index,synt.index,element++,AutoIndent()); auto &top_synt=top.getSynts()[top_index++]; ListPrint<decltype(synt_out)> rule_out(synt_out); for(auto &top_rule : top_synt.rules ) Printf(rule_out,"lang.top_rules+#;#;",top_rule.index,EndItem()); Putobj(rule_out,EndList()); Printf(synt_out,"#; }#; } ,#;",indent,indent,indent); } else { Indent indent(synt_out.getCol()); Putobj(synt_out,indent); ListPrint<decltype(synt_out)> kind_out(synt_out); for(auto &kind : kinds ) { Printf(kind_out,"{ #; , #; , #.q; , lang.synts+#; , lang.elements+#; ,#;",top_index,kind.index,kind.name,synt.index,element++,AutoIndent()); auto &top_synt=top.getSynts()[top_index++]; ListPrint<decltype(kind_out)> rule_out(kind_out); for(auto &top_rule : top_synt.rules ) Printf(rule_out,"lang.top_rules+#;#;",top_rule.index,EndItem()); Putobj(rule_out,EndList()); Printf(kind_out,"\n}#;",EndItem()); } Putobj(kind_out,EndList()); Putobj(synt_out," ,",indent); } ListPrint<decltype(synt_out)> rule_out(synt_out); for(auto &rule : synt.rules ) Printf(rule_out,"lang.rules+#;#;",rule.index,EndItem()); Putobj(rule_out,EndList()); Putobj(synt_out,"\n}",EndItem()); } Putobj(synt_out,EndList()); } Putobj(lang_out,EndItem()); // lang { ListPrint<decltype(lang_out)> synt_out(lang_out); for(auto &synt : clang.getSynts() ) if( synt.is_lang ) { Printf(synt_out,"lang.synts+#;",synt.index); } Putobj(synt_out,EndList()); } Putobj(lang_out,EndItem()); // elements { ListPrint<decltype(lang_out)> elem_out(lang_out); ulen element=0; for(auto &atom : clang.getAtoms() ) Printf(elem_out,"{ #; , lang.atoms+#; }#;",element++,atom.index,EndItem()); for(auto &synt : clang.getSynts() ) { auto len=synt.kinds.len; if( !len ) len=1; for(ulen i=0; i<len ;i++) { Printf(elem_out,"{ #; , lang.synts[#;].kinds+#; }#;",element++,synt.index,i,EndItem()); } } Putobj(elem_out,EndList()); } Putobj(lang_out,EndItem()); // rules { ListPrint<decltype(lang_out)> rule_out(lang_out); for(auto &rule : clang.getRules() ) { Printf(rule_out,"{ #; , #.q; , lang.synts[#;].kinds+#; ,#;",rule.index,rule.name,rule.ret->index,rule.getKindIndex(),AutoIndent()); ListPrint<decltype(rule_out)> arg_out(rule_out); for(auto &element : rule.args ) element.apply( [&] (const CondLangBase::AtomDesc *desc) { Printf(arg_out,"lang.atoms+#;#;",desc->index,EndItem()); } , [&] (const CondLangBase::SyntDesc *desc) { Printf(arg_out,"lang.synts+#;#;",desc->index,EndItem()); } ); Putobj(arg_out,EndList()); Putobj(rule_out,"\n}",EndItem()); } Putobj(rule_out,EndList()); } Putobj(lang_out,EndItem()); // top rules { ListPrint<decltype(lang_out)> rule_out(lang_out); for(auto &rule : top.getRules() ) { Printf(rule_out,"{ #; , #.q; , lang.rules+#; , lang.synts[#;].kinds+#; ,#;", rule.index,rule.name,rule.map_index,rule.ret->map_index,rule.ret->kind_index,AutoIndent()); ListPrint<decltype(rule_out)> arg_out(rule_out); for(auto &element : rule.args ) element.apply( [&] (const LangBase::AtomDesc *desc) { Printf(arg_out,"lang.atoms+#;#;",desc->index,EndItem()); } , [&] (const LangBase::SyntDesc *desc) { Printf(arg_out,"lang.synts[#;].kinds+#;#;",desc->map_index,desc->kind_index,EndItem()); } ); Putobj(arg_out,EndList()); Putobj(rule_out,"\n}",EndItem()); } Putobj(rule_out,EndList()); } Putobj(lang_out,EndItem()); // states { ListPrint<decltype(lang_out)> state_out(lang_out); for(auto &state : compress.getStateTable() ) { Printf(state_out,"{ #; , lang.finals+#; ,#;",state.index,state.prop_index,AutoIndent()); ListPrint<decltype(state_out)> trans_out(state_out); for(auto &trans : state.transitions ) Printf(trans_out,"{ lang.elements+#; , lang.states+#; }#;",trans.element,trans.dst->index,EndItem()); Putobj(trans_out,EndList()); Putobj(state_out,"\n}",EndItem()); } Putobj(state_out,EndList()); } Putobj(lang_out,EndItem()); // finals { ListPrint<decltype(lang_out)> final_out(lang_out); ulen atom_count=clang.getAtomCount(); ulen index=0; for(auto &final : compress.getProps() ) { Printf(final_out,"{ #; ,#;",index++,AutoIndent()); ListPrint<decltype(final_out)> action_out(final_out); if( final.hasNull() ) { Printf(action_out,"{ null , null }#;",EndItem()); } else { auto &alpha=final.getAlpha(); if( alpha.nonEmpty() ) { Printf(action_out,"{ null , lang.rules+#; }#;",alpha.getPtr()->getIndex()-atom_count,EndItem()); } } for(auto &rec : Range(final.getBeta()) ) { if( rec.object.shift ) { Printf(action_out,"{ lang.atoms+#; , null }#;",rec.index.getIndex(),EndItem()); } else { auto &rules=rec.object.rules; if( rules.nonEmpty() ) { Printf(action_out,"{ lang.atoms+#; , lang.rules+#; }#;",rec.index.getIndex(),rules.getPtr()->getIndex()-atom_count,EndItem()); } } } Putobj(action_out,EndList()); Putobj(final_out,"\n}",EndItem()); } Putobj(final_out,EndList()); } Putobj(lang_out,EndItem(),EndList()); } Putobj(out,";\n\n"); }
BOOL CReportCtrlEx2::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if (pMsg->message == WM_KEYDOWN) { if (!_IsEditVisible()) { // disable user from check/uncheck the checkboxes using space key // things get nasty if the user is HOLDING the space bar down if (pMsg->wParam == VK_SPACE) return TRUE; } else { POINT pt = m_ptEditting; switch (pMsg->wParam) { case VK_ESCAPE: // Cancel edit EndItem(FALSE); return TRUE; case VK_RETURN: // Commit edit EndItem(TRUE); return TRUE; case VK_TAB: // switch edit sub items if (pt.y == GetColumnCount() - 1) { pt.y = 0; if (pt.x < CListCtrl::GetItemCount() - 1) pt.x++; else pt.x = 0; } else pt.y++; EndItem(TRUE); // Si es el primer elemento hacemos el scroll hacia la izquierda if (pt.y == 0) SendMessage( WM_HSCROLL, SB_LEFT, 0 ); // Si llegamos al elemento no visible se hace scroll a la derecha if (pt.y == 8) SendMessage( WM_HSCROLL, SB_RIGHT, 0 ); EnsureVisible(pt.x, FALSE); if (pt.y == 4 || pt.y == 5) { m_bEdit = FALSE; StartDateTimeCtrl(pt.x, pt.y); } else { m_bEdit = TRUE; StartEdit(pt.x, pt.y); } //if (m_bEdit && !m_pWndEdit->IsWindowVisible()) // SendMessage( WM_HSCROLL, /*SB_LINERIGHT*/SB_RIGHT, 0 ); return TRUE; case VK_UP: // edit upper item if (pt.x > 0) { pt.x--; EndItem(TRUE); EnsureVisible(pt.x, FALSE); if (pt.y == 4 || pt.y == 5) { m_bEdit = FALSE; StartDateTimeCtrl(pt.x, pt.y); } else { m_bEdit = TRUE; StartEdit(pt.x, pt.y); } //EnsureVisible(pt.x, FALSE); return TRUE; } break; case VK_DOWN: // edit lower item if (pt.x < CListCtrl::GetItemCount() - 1) { pt.x++; EndItem(TRUE); EnsureVisible(pt.x, FALSE); if (pt.y == 4 || pt.y == 5) { m_bEdit = FALSE; StartDateTimeCtrl(pt.x, pt.y); } else { m_bEdit = TRUE; StartEdit(pt.x, pt.y); } //EnsureVisible(pt.x, FALSE); return TRUE; } break; case VK_RIGHT: // edit lower item // Si estamos en la columna de la descripcion no se puede navegar por el // liscontrol a la derecha puesto que nos movemos dentro del texto if (pt.y != 11) { if (pt.y < GetColumnCount() - 1) { pt.y++; } else { pt.y = 0; if (pt.x < CListCtrl::GetItemCount() - 1) pt.x++; else pt.x = 0; } EndItem(TRUE); // Si es el primer elemento hacemos el scroll hacia la izquierda if (pt.y == 0) SendMessage( WM_HSCROLL, SB_LEFT, 0); // Si llegamos al elemento no visible se hace scroll a la derecha if (pt.y == 8) SendMessage( WM_HSCROLL, SB_RIGHT, 0 ); EnsureVisible(pt.x, FALSE); if (pt.y == 4 || pt.y == 5) { m_bEdit = FALSE; StartDateTimeCtrl(pt.x, pt.y); } else { m_bEdit = TRUE; StartEdit(pt.x, pt.y); } return TRUE; } break; case VK_LEFT: // edit lower item // Si estamos en la columna de la descripcion no se puede navegar por el // liscontrol a la izquierda puesto que nos movemos dentro del texto if (pt.y != 11) { if (pt.y > 0) { pt.y--; } else { pt.y = GetColumnCount()-1; if (pt.x == 0) { pt.y = 0; pt.x = CListCtrl::GetItemCount()-1; } else pt.x--; } EndItem(TRUE); // Si estamos en el 3 elemento del CListCtrl se hace scroll a la izquierda // porque es el primero que deja de ser visible if (pt.y == 3) SendMessage( WM_HSCROLL, SB_LEFT, 0 ); // Si es el último elemento hacemos el scroll hacia la derecha if (pt.y == GetColumnCount()-1) SendMessage( WM_HSCROLL, SB_RIGHT, 0); EnsureVisible(pt.x, FALSE); if (pt.y == 4 || pt.y == 5) { m_bEdit = FALSE; StartDateTimeCtrl(pt.x, pt.y); } else { m_bEdit = TRUE; StartEdit(pt.x, pt.y); } return TRUE; } break; default: break; } } } return CListCtrl::PreTranslateMessage(pMsg); }
void CReportCtrlEx2::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { EndItem(TRUE); CWnd::OnHScroll(nSBCode, nPos, pScrollBar); }
BOOL CReportCtrlEx::StartCombo(int nItem, int nSubItem) { // Get the grid width and height if (!m_bAllowEdit || /*!_IsValidIndex(nItem) ||*/ nSubItem < 0 || nSubItem >= GetColumnCount()) return FALSE; if (m_ptEditting.x == nItem && m_ptEditting.y == nSubItem) return TRUE; /* CRect rectEditBox; m_pWndEdit->GetWindowRect(&rectEditBox);*/ EndItem(TRUE); m_ptEditting.x = nItem; m_ptEditting.y = nSubItem; SetAllItemStates(RC_ITEM_SELECTED, RC_ITEM_UNSELECTED); // unselect all //SetItemStates(m_ptEditting.x, RC_ITEM_SELECTED | RC_ITEM_FOCUSED); if (m_pWndCombo->GetSafeHwnd() != NULL) m_pWndCombo->DestroyWindow(); if (!m_pWndCombo->Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWN|CBS_SIMPLE/*CBS_DROPDOWNLIST*/, CRect(0, 0, 1, 1), this, 0)) return FALSE; m_pWndCombo->SetFont(GetFont()); CRect rcCombo; ListView_GetSubItemRect(GetSafeHwnd(), m_ptEditting.x, m_ptEditting.y, LVIR_BOUNDS, &rcCombo); rcCombo.bottom = rcCombo.bottom + 70; // Se añade espacio para la lista desplegable // Según la columna que sea se cargan unos datos u otro if (nSubItem == 3) { m_pWndCombo->AddString(ALQUILER); m_pWndCombo->AddString(VENTA); m_pWndCombo->AddString(OTROS); m_pWndCombo->AddString(ENTREGA); m_pWndCombo->AddString(RECOGIDA); } else if (nSubItem == 4) { // Si es el combo del tipo de Alquiler, sólo se activa si el tipo es Alquiler CString strTipo = GetItemText(nItem, 3); if (strTipo == ALQUILER) { m_pWndCombo->AddString(MENSUAL); m_pWndCombo->AddString(DIA_LABORABLE); m_pWndCombo->AddString(DIA_NATURAL); //m_pWndCombo->AddString("Sábado"); } } // Move the comboBox to that grid, obtain text from the grid, display the // comboBox, and, finally, highlights all text in the editbox and set the // windows focus to the editbox. m_pWndCombo->MoveWindow(&rcCombo); int iIndex = m_pWndCombo->FindString(0, GetItemText(m_ptEditting.x, m_ptEditting.y)); m_pWndCombo->SetCurSel(iIndex); m_pWndCombo->ShowWindow(SW_SHOW); m_pWndCombo->SetFocus(); return TRUE; }