X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-redboot.git;a=blobdiff_plain;f=tools%2Fsrc%2Ftools%2Fconfigtool%2Fcommon%2Fwin32%2FFailingRulesDialog.cpp;fp=tools%2Fsrc%2Ftools%2Fconfigtool%2Fcommon%2Fwin32%2FFailingRulesDialog.cpp;h=bcd05c91396862306d0ee3e0f224988b32c95c6c;hp=0000000000000000000000000000000000000000;hb=2b5bec7716c03d42cfb16d8c98c9cea573bf6722;hpb=47412fc4bd1aefc0d5498bcb3860a9d727196f16 diff --git a/tools/src/tools/configtool/common/win32/FailingRulesDialog.cpp b/tools/src/tools/configtool/common/win32/FailingRulesDialog.cpp new file mode 100644 index 00000000..bcd05c91 --- /dev/null +++ b/tools/src/tools/configtool/common/win32/FailingRulesDialog.cpp @@ -0,0 +1,436 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +// FailingRulesDialog.cpp : implementation file +// + +#include "stdafx.h" +#ifndef PLUGIN +#include "BCMenu.h" +#endif +#include "FailingRulesDialog.h" +#include "ConfigItem.h" +#include "ConfigTool.h" +#include "ConfigToolDoc.h" +#include "ControlView.h" +#include "CTUtils.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CFailingRulesDialog dialog + + +CFailingRulesDialog::CFailingRulesDialog(std::list conflicts,CdlTransaction transaction/*=NULL*/,CPtrArray *parConflictsOfInterest/*=NULL*/) + : CeCosDialog(CFailingRulesDialog::IDD, NULL), + m_conflicts(conflicts), + m_Transaction(transaction), + m_parConflictsOfInterest(parConflictsOfInterest) +{ + for (std::list::const_iterator conf_i= m_conflicts.begin (); conf_i != m_conflicts.end (); conf_i++) { // for each conflict + int nSolutions=(*conf_i)->get_solution().size(); + SolutionInfo *pInfo=(SolutionInfo *)malloc(sizeof(SolutionInfo)+(nSolutions-1)*sizeof(int)); + pInfo->nCount=nSolutions; + for(int i=0;iarItem[i]=SolutionInfo::CHECKED; + } + m_Map.SetAt(*conf_i,pInfo); + } + + //{{AFX_DATA_INIT(CFailingRulesDialog) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + +CFailingRulesDialog::~CFailingRulesDialog() +{ + for(POSITION pos = m_Map.GetStartPosition(); pos != NULL; ){ + CdlConflict conflict; + SolutionInfo *pInfo=NULL; + m_Map.GetNextAssoc(pos, (void *&)conflict, (void *&)pInfo); + free(pInfo); + } +} + +void CFailingRulesDialog::DoDataExchange(CDataExchange* pDX) +{ + CeCosDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CFailingRulesDialog) + DDX_Control(pDX, IDC_LIST2, m_List); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CFailingRulesDialog, CeCosDialog) + //{{AFX_MSG_MAP(CFailingRulesDialog) + ON_BN_CLICKED(IDC_RESET, OnReset) + ON_BN_CLICKED(IDC_CONFLICTS_NONE, OnConflictsNone) + ON_BN_CLICKED(ID_RESOLVE_CONFLICTS_CONTINUE, OnOK) + ON_BN_CLICKED(ID_RESOLVE_CONFLICTS_CANCEL,OnCancel) + ON_COMMAND(ID_LOCATE,OnLocate) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CFailingRulesDialog message handlers + +BOOL CFailingRulesDialog::OnInitDialog() +{ + CeCosDialog::OnInitDialog(); + m_List.SetExtendedStyle(LVS_EX_CHECKBOXES); + m_List.InsertColumn(0,_T("Item")); + m_List.InsertColumn(1,_T("Value")); + + CRect rect; + GetDlgItem(IDC_LIST1)->GetWindowRect(rect); + ScreenToClient(rect); + + m_RulesList.CreateEx(WS_EX_CLIENTEDGE,WC_LISTVIEW,NULL,WS_VISIBLE|WS_CHILD|LVS_SHOWSELALWAYS,rect,this,IDC_LIST1); + // Select the first item and fill the solution set + m_RulesList.AddConflicts(m_conflicts); + + if(m_parConflictsOfInterest && m_parConflictsOfInterest->GetSize()>0){ + CPtrArray &arConflictsOfInterest=*m_parConflictsOfInterest; + for(int i=m_RulesList.GetItemCount()-1;i>=0;--i){ + for(int j=arConflictsOfInterest.GetSize()-1;j>=0;--j){ + CdlConflict conflict=(CdlConflict)m_RulesList.GetItemData(i); + if(arConflictsOfInterest[j]==conflict){ + m_RulesList.SetItemState(i,LVIS_SELECTED, LVIS_SELECTED); + m_RulesList.EnsureVisible(i,false); + arConflictsOfInterest.RemoveAt(j); + break; + } + } + } + } else { + for(int i=m_RulesList.GetItemCount()-1;i>=0;--i){ + m_RulesList.SetItemState(i,LVIS_SELECTED, LVIS_SELECTED); + } + } + SetButtons(); + return false; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void CFailingRulesDialog::OnCancel() +{ + CeCosDialog::OnCancel(); +} + +void CFailingRulesDialog::OnOK() +{ + // Ensure we have the current conflict check array + for(POSITION pos = m_RulesList.GetFirstSelectedItemPosition();pos;){ + int nItem = m_RulesList.GetNextSelectedItem(pos); + RemoveConflictSolutions((CdlConflict)m_RulesList.GetItemData(nItem)); + } + + // Dismiss the window + CeCosDialog::OnOK(); + + for (std::list::const_iterator conf_i= m_conflicts.begin (); conf_i != m_conflicts.end (); conf_i++) { // for each conflict + CdlConflict conflict=*conf_i; + //int nSolutions=conflict->get_solution().size(); + SolutionInfo &info=Info(conflict); + int nIndex=0; + const std::vector >&Solution=conflict->get_solution(); + for (std::vector >::const_iterator soln_i = Solution.begin();soln_i != Solution.end(); soln_i++) { + if(SolutionInfo::CHECKED==info.arItem[nIndex++]){ + CdlValuable valuable = soln_i->first; + CdlValue value=soln_i->second; + CdlValueFlavor flavor = valuable->get_flavor(); + const CString strName(valuable->get_name().c_str()); + const CString strValue(value.get_value().c_str()); + bool rc=true; + CString str; + try { + switch(flavor) { + case CdlValueFlavor_None : + str=_T("set CdlValueFlavor_None"); + rc=false; + break; + case CdlValueFlavor_Bool : + str.Format(_T("%s %s\n"),value.is_enabled()?_T("disable"):_T("enable"),strName); + valuable->set_enabled (m_Transaction, value.is_enabled(), CdlValueSource_User); + break; + case CdlValueFlavor_BoolData : + { + bool bEnabled=value.is_enabled(); + str.Format(_T("%s %s and set value to %s\n"),bEnabled?_T("disable"):_T("enable"),strName,strValue); + // This is wrong: it should set the NEW value. This is the cause of a long-standing bug... + // CdlSimpleValue simple_value = valuable->get_simple_value (); + //valuable->set_enabled_and_value (m_Transaction, bEnabled, simple_value, CdlValueSource_User); + valuable->set_enabled_and_value (m_Transaction, bEnabled, CUtils::UnicodeToStdStr (strValue), CdlValueSource_User); + + } + break; + case CdlValueFlavor_Data : + str.Format(_T("set %s to %s\n"),strName,strValue); + valuable->set_value (m_Transaction, CUtils::UnicodeToStdStr (strValue), CdlValueSource_User); + break; + } + } + catch(...){ + rc=false; + } + if(rc){ + CConfigTool::GetConfigToolDoc()->SetModifiedFlag(); + } else { + CUtils::MessageBoxF(_T("Failed to %s\n"),str); + } + } + } + } +} + +void CFailingRulesDialog::SetAll(bool bOnOff) +{ + for(int i=m_List.GetItemCount()-1;i>=0;--i){ + m_List.SetCheck(i,bOnOff); + } +} + +void CFailingRulesDialog::OnReset() +{ + SetAll(true); +} + +void CFailingRulesDialog::OnConflictsNone() +{ + SetAll(false); +} + +BOOL CFailingRulesDialog::OnItemChanged(UINT, LPNMLISTVIEW pnmv, LRESULT* pResult) +{ + bool bWasSelected=(pnmv->uOldState & LVIS_SELECTED); + bool bIsSelected =(pnmv->uNewState & LVIS_SELECTED); + + if(bWasSelected != bIsSelected) { + CdlConflict conflict=(CdlConflict) m_RulesList.GetItemData(pnmv->iItem); + if(bIsSelected){ + if(1==m_List.GetSelectedCount()){ + GetDlgItem(IDC_STATIC1)->ShowWindow(SW_HIDE); + m_List.ShowWindow(SW_SHOW); + } + AddConflictSolutions(conflict); + } else { + RemoveConflictSolutions(conflict); + } + } + *pResult = 0; + return false; +} + +// We need to use this because the OnItemChanged handler successive receives "not selected" followed by "selected" +// notifications. The result is that the "Select one or more conflicts to display available solutions" message +// would be seen briefly when clicking from one selection to another. +BOOL CFailingRulesDialog::OnClick(UINT,LPNMLISTVIEW pnmv, LRESULT* pResult) +{ + if(-1==pnmv->iItem && 0==m_List.GetSelectedCount()){ + SetDlgItemText(IDC_STATIC1,_T("Select one or more conflicts to display available solutions")); + m_List.ShowWindow(SW_HIDE); + GetDlgItem(IDC_STATIC1)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_RESET)->EnableWindow(false); + GetDlgItem(IDC_CONFLICTS_NONE)->EnableWindow(false); + } + *pResult = 0; + return false; // not handled +} + +void CFailingRulesDialog::RemoveConflictSolutions(CdlConflict conflict) +{ + SolutionInfo &info=Info(conflict); + for(int i=0;i=0); + info.arItem[i]=(1==m_List.GetCheck(nItem)?SolutionInfo::CHECKED:SolutionInfo::UNCHECKED); + int nRefs=m_List.GetItemData(nItem); + if(1==nRefs){ + m_List.DeleteItem(nItem); + for(int i=0;inItem){ + info.arItem[j]--; + } + } + } + } else { + m_List.SetItemData(nItem,nRefs-1); + } + } +} + +void CFailingRulesDialog::AddConflictSolutions(CdlConflict conflict) +{ + SolutionInfo &info=Info(conflict); + + const std::vector >&Solution=conflict->get_solution(); + + int i=0; + for (std::vector >::const_iterator soln_i = Solution.begin(); + soln_i != Solution.end(); soln_i++) { + CdlValuable valuable = soln_i->first; + CdlValue value=soln_i->second; + CdlValueFlavor flavor = valuable->get_flavor(); + + CString strValue; + switch(flavor) { + case CdlValueFlavor_None : + break; + case CdlValueFlavor_Bool : + strValue=value.is_enabled() ? _T("Enabled") : _T("Disabled"); + break; + case CdlValueFlavor_BoolData : + strValue.Format(_T("%s, %s"), value.is_enabled() ? _T("Enabled") : _T("Disabled"), CString(value.get_value().c_str())); + break; + case CdlValueFlavor_Data : + strValue=value.get_value().c_str(); + break; + } + + const CString strName(soln_i->first->get_name().c_str()); + LVFINDINFO fi; + fi.flags=LVFI_STRING; + fi.psz=strName; + int nIndex=m_List.FindItem(&fi); + if(-1==nIndex || strValue!=m_List.GetItemText(nIndex,1)){ + // We don't have an existing solution that matches this one + nIndex=m_List.GetItemCount(); + m_List.InsertItem(nIndex,strName); + m_List.SetItemData(nIndex,1); + m_List.SetItemText(nIndex,1,strValue); + ASSERT(info.arItem[i]<0); + m_List.SetCheck(nIndex,SolutionInfo::CHECKED==info.arItem[i]); + } else { + // We do - to avoid duplicates, increment the "ref count" + m_List.SetItemData(nIndex,m_List.GetItemData(nIndex)+1); + } + info.arItem[i++]=nIndex; + } + if(0==i){ + SetDlgItemText(IDC_STATIC1,_T("No solution is available for this conflict")); + m_List.ShowWindow(SW_HIDE); + } else { + SetDlgItemText(IDC_STATIC1,_T("Proposed solution:")); + m_List.ShowWindow(SW_SHOW); + m_List.SetColumnWidth(0,LVSCW_AUTOSIZE); + CRect rect; + m_List.GetClientRect(rect); + m_List.SetColumnWidth(1,rect.Width()-m_List.GetColumnWidth(0)); + } +} + +BOOL CFailingRulesDialog::OnSolutionItemChanged(UINT,LPNMLISTVIEW, LRESULT*) +{ + SetButtons(); + return false; // not handled +} + +CFailingRulesDialog::SolutionInfo & CFailingRulesDialog::Info(const CdlConflict conflict) +{ + SolutionInfo *pInfo; + VERIFY(m_Map.Lookup(conflict,(void *&)pInfo)); + return *pInfo; +} + +BOOL CFailingRulesDialog::OnRClick(UINT, LPNMITEMACTIVATE pnmv, LRESULT* pResult) +{ + DWORD dwPos=GetMessagePos(); + CPoint pt(GET_X_LPARAM(dwPos),GET_Y_LPARAM(dwPos)); + m_nContextItem=pnmv->iItem; + m_nContextRow=pnmv->iSubItem; + if(-1!=m_nContextItem){ + //m_RulesList.SetItemState(m_nContextItem,LVIS_SELECTED,LVIS_SELECTED); + Menu menu; + menu.CreatePopupMenu(); + menu.AppendMenu(1==m_RulesList.GetSelectedCount() && m_RulesList.AssociatedItem(m_nContextItem,m_nContextRow)?MF_STRING:(MF_STRING|MF_GRAYED),ID_LOCATE,_T("&Locate")); +#ifndef PLUGIN + SuppressNextContextMenuMessage(); +#endif + menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, pt.x,pt.y,this); + } + + *pResult = 0; + return TRUE; // handled +} + +void CFailingRulesDialog::OnLocate() +{ + CConfigItem *pItem=m_RulesList.AssociatedItem(m_nContextItem,m_nContextRow); + if (pItem) { + CConfigTool::GetControlView()->SelectItem(pItem); + } +} + + +void CFailingRulesDialog::SetButtons() +{ + int nCheckCount=0; + int nItemCount=m_List.GetItemCount(); + for(int i=nItemCount-1;i>=0;--i){ + nCheckCount+=m_List.GetCheck(i); + } + GetDlgItem(IDC_RESET)->EnableWindow(nItemCount>0 && nCheckCountEnableWindow(nItemCount>0 && nCheckCount>0); +} + +// We have to dispatch our own notify messages because the multiple inheritance of CCSHDialog prevents +// the message map from compiling properly for ON_NOTIFY messages. +BOOL CFailingRulesDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult ) +{ + LPNMHDR pHdr=(LPNMHDR)lParam; + bool bHandled=false; + switch(pHdr->idFrom){ + case IDC_LIST1: + switch (pHdr->code) { + case LVN_ITEMCHANGED: + bHandled=OnItemChanged(wParam, (LPNMLISTVIEW)lParam, pResult); + break; + case NM_CLICK: + bHandled=OnClick(wParam, (LPNMLISTVIEW)lParam, pResult); + break; + case NM_RCLICK: + bHandled=OnRClick(wParam, (LPNMITEMACTIVATE)lParam, pResult); + break; + default: + break; + } + break; + case IDC_LIST2: + switch (pHdr->code) { + case LVN_ITEMCHANGED: + bHandled=OnSolutionItemChanged(wParam,(LPNMLISTVIEW)lParam, pResult); + break; + default: + break; + } + break; + } + return bHandled || CeCosDialog::OnNotify(wParam,lParam,pResult); +}