#include "StdAfx.h" #include "FindReplacement.h" #include "SigmaDoc.h" #include "SigmaView.h" #include "SelectionDrawer.h" #include ".\actionmodifieditem.h" #include ".\actionbackupitem.h" #include "ActionListItem.h" wchar_t* AsciiToUnicodeChar(const char * str); static BOOL GetCurveAzimuth(CCurveEx* pCurve, double &azimuth); CFindReplacement::CFindReplacement(CSigmaDoc * pDoc) :m_bAddInResultList(FALSE), m_pDoc(pDoc), m_posCurrent(nullptr), //m_posFind(0), m_bMatch(FALSE), m_bCapitalLower(FALSE), m_numberFound(0) { m_selectionDrawer = new SelectionDrawer(pDoc); } CFindReplacement::~CFindReplacement(void) { delete m_selectionDrawer; m_selectionDrawer = 0; } void CFindReplacement::Start() { m_numberFound = 0; m_posCurrent = nullptr; } void CFindReplacement::ExtendOne(POSITION pos) { if(m_bAddInResultList) { //CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); //if(pmf) // pmf->m_pPaneResultList->Elements_InsertItem(pos); } else { m_pDoc->ClearSelection(); //GetDoc()->PushDC(); //找到One. COne* pOne= m_pDoc->GetDraw()->GetAt(pos); //<将COne居中。尺寸缩放到屏幕尺寸的1/4> CRect rt; //GetView()->GetClientRect(rt); rt = m_pDoc->GetView()->m_client; CRect8 rect=pOne->GetRect(); rect.InflateRect(rect.Width()/4, rect.Height()/4); m_pDoc->GetDC().Extend(rect,rt,EXTEND_MODE_DEFAULT); // //CPositionList list; //POSITION pos= m_pDoc->GetDraw()->Find(pOne); //if(pos) //{ //list.AddTail(pos); //GetDoc()->SetSelection(list); //} m_pDoc->Invalidate(); } } BOOL CFindReplacement::FindNextOnly(CString strFindWhat, int elementType, BOOL onlyEditable) { if (strFindWhat.IsEmpty()) return FALSE; if(!m_bCapitalLower) //不区分大小写 strFindWhat.MakeUpper(); BOOL bFind=FALSE; CPtrList* valueList = m_pDoc->GetDraw()->GetValueList(); POSITION pos = nullptr; // m_posCurrent 是上次找到的位置,如果没找到,直接从开头开始,否则从上次找到位置的下一个位置开始 if (m_posCurrent == nullptr) { Start(); pos = valueList->GetHeadPosition(); } else { pos = m_posCurrent; valueList->GetNext(pos); } for (; pos != nullptr; valueList->GetNext(pos)) { COne* pOne= m_pDoc->GetDraw()->GetAt(pos); // 只读判断 if (onlyEditable && !pOne->IsCanEdit()) { continue; } // 图元类型判断 if (elementType > 0 && pOne->GetType() != elementType) { continue; } CString name=pOne->GetName(); if(!m_bCapitalLower) //不区分大小写 name.MakeUpper(); if(m_bMatch) //全字匹配 { if(strFindWhat==name) { m_posCurrent = pos; return TRUE; } } else if (name.Find(strFindWhat) >= 0) { m_posCurrent = pos; return TRUE; } } //end while m_posCurrent = nullptr; return FALSE; } //0--找到了 1--第一次查找 但没找到 2--已经搜索完了 int CFindReplacement::FindNext(CString strFindWhat, BOOL bMath, BOOL bCapitalLower , int elementType, BOOL onlyEditable) { m_bMatch = bMath; m_bCapitalLower = bCapitalLower; BOOL bFind = FindNextOnly(strFindWhat, elementType, onlyEditable); if (m_numberFound == 0 && !bFind) //第一次查找,还没找到。 return 1; //如果m_numberFound == 0 则pos一定为TRUE 则(A)处m_numberFound一定大于0 //所以(A处) 的判断永为真 直接返回2 if (bFind) { ExtendOne(m_posCurrent); m_numberFound++; m_selectionDrawer->SetPostion(m_posCurrent); } if (bFind) { return 0; } //没找到 //if (m_numberFound > 0) //(A) return 2; //已经搜索完了 } void CFindReplacement::FindAll(CString strFindWhat, BOOL bMatch, BOOL bCapitalLower) { m_findResult.RemoveAll(); m_bMatch = bMatch; m_bCapitalLower = bCapitalLower; m_bAddInResultList=TRUE; CPtrList* pl=m_pDoc->GetDraw()->GetValueList(); m_posCurrent=pl->GetHeadPosition(); while (m_posCurrent) { if (FindNext(strFindWhat, bMatch, bCapitalLower) == 0) { m_findResult.AddTail(m_posCurrent); } } } //返回替换图元名称的数量 int CFindReplacement::ReplaceAll(CString strOld, CString strNew, BOOL bMath, BOOL bCapitalLower) { m_bMatch = bMath; m_bCapitalLower = bCapitalLower; CActionListItem* pActionList=new CActionListItem(m_pDoc, IDS_STRING_REPLACE_NAME_ALL); m_posCurrent=m_pDoc->GetDraw()->GetValueList()->GetHeadPosition(); int count=0; while(m_posCurrent) { if(!FindNextOnly(strOld)) break; COne* pOne = m_pDoc->GetDraw()->GetAt(m_posCurrent); CActionModifiedItem* pModifiedItem = new CActionModifiedItem(m_pDoc, IDS_STRING_REPLACE); pModifiedItem->BackupOldItem(m_posCurrent, pOne); if(Replace(m_posCurrent, strOld, strNew, NULL)) { pModifiedItem->BackupNewItem(); pActionList->AddTailItem(pModifiedItem); count++; } else { delete pModifiedItem; pModifiedItem = nullptr; } } if(count>0) { m_pDoc->Invalidate(); m_pDoc->SetActionItem(pActionList); } else { delete pActionList; } //CString str; //str.Format("Replace %d",count); //::AfxMessageBox(str); return count; } BOOL CFindReplacement::Replace(CString strOld, CString strNew, BOOL bMath, BOOL bCapitalLower) { if (m_numberFound == 0) //还没有查找或没找到 { return FALSE; } m_bMatch = bMath; m_bCapitalLower = bCapitalLower; m_bAddInResultList = FALSE; COne* pOne = m_pDoc->GetDraw()->GetAt(m_posCurrent); CActionModifiedItem* pModifiedItem = new CActionModifiedItem(m_pDoc, IDS_STRING_REPLACE); pModifiedItem->BackupOldItem(m_posCurrent, pOne); bool success = Replace(m_posCurrent, strOld, strNew, nullptr); if (success == true) { pModifiedItem->BackupNewItem(); } else { delete pModifiedItem; pModifiedItem = nullptr; } return success; } int CFindReplacement::GetCountOfElement() { return m_findResult.GetSize(); } void CFindReplacement::Draw(CDC * pCDC) { m_selectionDrawer->OnDraw(pCDC); } BOOL CFindReplacement::GetElement(int index, ElementInfo * eleInfoOut) { if (eleInfoOut == 0) return FALSE; memset(eleInfoOut, 0, sizeof(ElementInfo)); if (index < 0 || index >= m_findResult.GetSize()) return FALSE; POSITION pos = m_findResult.FindIndex(index); pos = m_findResult.GetAt(pos); //POSITION pos = m_findResult.GetHead(); if (m_pDoc == NULL || pos == NULL) return FALSE; COne* pOne = m_pDoc->GetDraw()->GetAt(pos); CString name; name = pOne->GetName(); eleInfoOut->name = AsciiToUnicodeChar(name); eleInfoOut->lenOfName = (int)wcslen(eleInfoOut->name); eleInfoOut->elementType = pOne->GetType(); CString layerName = pOne->GetLayer()->GetPathName(); eleInfoOut->layerName = AsciiToUnicodeChar(layerName); eleInfoOut->lenOfLayerName = (int)wcslen(eleInfoOut->layerName); switch (pOne->GetType()) { case DOUBLEFOX_CURVE: { CCurveEx* pCurve = (CCurveEx*)pOne->GetValue(); eleInfoOut->length = pCurve->Length(); //曲线坐标长度 eleInfoOut->area = pCurve->Area(); //曲线面积 double azimuth; if (GetCurveAzimuth(pCurve, azimuth)) //曲线方位角 { eleInfoOut->azimuth = azimuth; } } break; case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: { CPointNameEx* pPoint = (CPointNameEx*)pOne->GetValue(); if (pOne->GetLayer()->HowToViewPoint) { eleInfoOut->markName = AsciiToUnicodeChar(pOne->GetLayer()->HowToViewPoint->MarkName); eleInfoOut->lenOfMarkName = (int)wcslen(eleInfoOut->markName); } eleInfoOut->x = pPoint->x0; eleInfoOut->y = pPoint->y0; //if (m_pMesh) //??? //{ // double z0 = m_pMesh->GetValue(pPoint->x0, pPoint->y0); // double zmin, zmax; // m_pMesh->GetM(zmin, zmax); // if (!(z0zmax)) //当该Z值有效时才显示 // { // AfxGetPublicFunction()->FloatToString(txt, z0, decimal); m_wndListCtrl.SetItemText(sel, 10, txt); // } //} } break; case DOUBLEFOX_TEXT: break; } return TRUE; } BOOL CFindReplacement::Replace(POSITION pos, CString strOld, CString strNew, void* pActionList) { if (pos == NULL) return FALSE; if(strOld==strNew) return TRUE; COne* pOne=m_pDoc->GetDraw()->GetAt(pos); //if(!pOne->IsCanEdit()) // return FALSE; CString oneName=pOne->GetName(); CString oldName=oneName; //for action CString oneNameCopy=oneName; if(!m_bCapitalLower) //不区分大小写 { strOld.MakeUpper(); oneNameCopy.MakeUpper(); } int f= oneNameCopy.Find(strOld); while(f>=0) { oneName.Delete(f,strOld.GetLength()); oneName.Insert(f,strNew); f = oneName.Find(strOld, f+ strNew.GetLength()); } BOOL br=pOne->SetName(oneName); if(br) { m_pDoc->Modified(); //for undo,redo //if(pActionList) // ((CActionListItem*)pActionList)->AddReplaceNameItem(pOne, oldName, name); //else // GetDoc()->SetActionItem(new CActionReplaceNameItem(GetDoc(), IDS_STRING_REPLACE_NAME_ONE, pOne, oldName, name)); } return br; } static BOOL GetCurveAzimuth(CCurveEx* pCurve, double &azimuth) { CRect8 rect(1e100, -1e100, -1e100, 1e100); pCurve->GetRange(rect); double k, b; if (!AfxGetPublicFunction()->GetKB(pCurve->num, pCurve->x, pCurve->y, k, b)) return FALSE; rect.bottom = k * rect.left + b; rect.top = k * rect.right + b; azimuth = AfxGetPublicFunction()->GetAzimuth(rect.left, rect.bottom, rect.right, rect.top); return TRUE; }