GME
13
|
00001 #include "stdafx.h" 00002 00003 #include <stdio.h> 00004 #define _USE_MATH_DEFINES 00005 #include <math.h> 00006 #include "GMEApp.h" 00007 #include "GMEstd.h" 00008 #include "GMEOLEData.h" 00009 #include "PendingObjectPosRequest.h" 00010 #include "GMEView.h" 00011 #include "GraphicsUtil.h" 00012 #include "GuiMeta.h" 00013 #include "GuiObject.h" 00014 #include "ModelGrid.h" 00015 #include "DecoratorEventSink.h" 00016 #include "AnnotatorEventSink.h" 00017 00018 #include "AutoRoute/AutoRouterGraph.h" 00019 #include "AutoRoute/AutoRouter.h" 00020 #include "AutoRoute/AutoRouterPath.h" 00021 00022 #include "GMEEventLogger.h" 00023 #include "MainFrm.h" 00024 00025 00026 CModelGrid modelGrid; 00027 00029 00030 static void SetSize(CRect& location, CSize s) 00031 { 00032 location.left = max(GME_GRID_SIZE, location.left / GME_GRID_SIZE * GME_GRID_SIZE); 00033 location.top = max(GME_GRID_SIZE, location.top / GME_GRID_SIZE * GME_GRID_SIZE); 00034 location.right = location.left + s.cx; 00035 location.bottom = location.top + s.cy; 00036 } 00037 00038 void SetLocation(CRect& location, CPoint pt) 00039 { 00040 CSize s = location.Size(); 00041 location.top = pt.y; 00042 location.left = pt.x; 00043 SetSize(location, s); 00044 } 00045 00047 00049 // Non-virtual methods of CGuiAspect 00051 CGuiAspect::CGuiAspect(CGuiMetaAspect* meta, CGuiObject* p, int ind, int pind, CComPtr<IMgaDecorator>& decor, 00052 CComPtr<IMgaElementDecorator>& newDecor, CComObjPtr<CDecoratorEventSink>& decorEventSink): 00053 guiMeta(meta), 00054 parent(p), 00055 index(ind), 00056 parentIndex(pind), 00057 decorator(decor), 00058 newDecorator(newDecor), 00059 decoratorEventSink(decorEventSink), 00060 routerBox(0), 00061 routerNameBox(0) 00062 { 00063 try { 00064 COMTHROW(decor->GetFeatures(&features)); 00065 } 00066 catch (hresult_exception &) { 00067 features = 0UL; 00068 } 00069 name = meta->name; 00070 if (parent->IsReal()) { 00071 InitPorts(); 00072 } 00073 00074 if (features & F_ANIMATION) { 00075 parent->IncrementAnimRefCnt(); 00076 } 00077 } 00078 00079 CGuiAspect::~CGuiAspect() 00080 { 00081 if (newDecorator) { 00082 COMTHROW(newDecorator->Destroy()); 00083 newDecorator.Release(); 00084 newDecorator = NULL; 00085 } else { 00086 COMTHROW(decorator->Destroy()); 00087 } 00088 decorator.Release(); 00089 decorator = NULL; 00090 if (decoratorEventSink != NULL) { 00091 decoratorEventSink.Release(); 00092 decoratorEventSink = NULL; 00093 } 00094 POSITION pos = ports.GetHeadPosition(); 00095 while(pos) { 00096 delete ports.GetNext(pos); 00097 } 00098 if (features & F_ANIMATION) { 00099 parent->DecrementAnimRefCnt(); 00100 } 00101 } 00102 00103 void CGuiAspect::InitPorts() 00104 { 00105 CComPtr<IMgaFCOs> portFcos; 00106 COMTHROW(decorator->GetPorts(&portFcos)); 00107 if (portFcos) { 00108 CComPtr<IMgaFCO> fco; 00109 MGACOLL_ITERATE(IMgaFCO,portFcos) { 00110 fco = MGACOLL_ITER; 00111 CGuiPort *p = new CGuiPort(this,fco); 00112 ports.AddTail(p); 00113 } 00114 MGACOLL_ITERATE_END; 00115 } 00116 CGuiPort *p = new CGuiPort(this,parent->mgaFco); 00117 ports.AddTail(p); 00118 00119 } 00120 00121 void CGuiAspect::SetLocation(const CRect& location) 00122 { 00123 loc = location; 00124 00125 try { 00126 COMTHROW(decorator->SetLocation(location.left, location.top, location.right, location.bottom)); 00127 long sx, sy, ex, ey; 00128 COMTHROW(decorator->GetLabelLocation(&sx, &sy, &ex, &ey)); 00129 00130 /* 00131 sx = min(sx, location.right-1); 00132 ex = max(ex, location.left+1); 00133 sy = min(sy, location.bottom-1); 00134 ey = max(ey, location.top+1); 00135 */ 00136 if (sx != 0 && ex != 0 && sy != 0 && ey != 0) { 00137 sx = min(sx, location.right+1); 00138 ex = max(ex, location.left-1); 00139 sy = min(sy, location.bottom+1); 00140 ey = max(ey, location.top-1); 00141 } 00142 nameLoc.SetRect(sx, sy, ex, ey); 00143 } catch (hresult_exception &) { 00144 ASSERT(false); 00145 } 00146 } 00148 // Static methods of CGuiAspect 00150 00152 // Virtual methods of CGuiAspect 00154 00155 00157 00159 // Non-virtual methods of CGuiPort 00161 CGuiPort::CGuiPort(CGuiAspect* asp, CComPtr<IMgaFCO> fco) : parent(asp), mgaFco(fco) 00162 { 00163 CComBSTR bstr; 00164 COMTHROW(fco->get_Name(&bstr)); 00165 CopyTo(bstr,name); 00166 00167 bstr.Empty(); 00168 COMTHROW(fco->get_ID(&bstr)); 00169 CopyTo(bstr,id); 00170 00171 COMTHROW(fco->get_Meta(&metaFco)); 00172 00173 COMTHROW(fco->get_MetaRole(&metaRole)); 00174 00175 if (!IsRealPort()) { 00176 ReadARPreferences(); 00177 } 00178 00179 } 00180 00181 bool CGuiPort::GetPreference(CString &val, CString path) 00182 { 00183 VERIFY(mgaFco); 00184 CComBSTR pathBstr; 00185 CopyTo(path, pathBstr); 00186 CComBSTR bstrVal; 00187 COMTHROW(mgaFco->get_RegistryValue(pathBstr,&bstrVal)); 00188 CopyTo(bstrVal, val); 00189 return !val.IsEmpty(); 00190 } 00191 00192 00193 00194 void CGuiPort::ReadARPreferences() 00195 { 00196 CString val; 00197 if (GetPreference(val, AUTOROUTER_PREF)) { 00198 autorouterPrefs[GME_START_NORTH] = (val.Find(_T("N")) != -1); 00199 autorouterPrefs[GME_START_EAST] = (val.Find(_T("E")) != -1); 00200 autorouterPrefs[GME_START_SOUTH] = (val.Find(_T("S")) != -1); 00201 autorouterPrefs[GME_START_WEST] = (val.Find(_T("W")) != -1); 00202 autorouterPrefs[GME_END_NORTH] = (val.Find(_T("n")) != -1); 00203 autorouterPrefs[GME_END_EAST] = (val.Find(_T("e")) != -1); 00204 autorouterPrefs[GME_END_SOUTH] = (val.Find(_T("s")) != -1); 00205 autorouterPrefs[GME_END_WEST] = (val.Find(_T("w")) != -1); 00206 } 00207 else { 00208 if (parent->GetParent()->dynamic_cast_CGuiCompound() != NULL) { 00209 autorouterPrefs[GME_START_NORTH] = true; 00210 autorouterPrefs[GME_START_EAST] = false; 00211 autorouterPrefs[GME_START_SOUTH] = true; 00212 autorouterPrefs[GME_START_WEST] = false; 00213 autorouterPrefs[GME_END_NORTH] = true; 00214 autorouterPrefs[GME_END_EAST] = false; 00215 autorouterPrefs[GME_END_SOUTH] = true; 00216 autorouterPrefs[GME_END_WEST] = false; 00217 } else { 00218 autorouterPrefs[GME_START_NORTH] = true; 00219 autorouterPrefs[GME_START_EAST] = true; 00220 autorouterPrefs[GME_START_SOUTH] = true; 00221 autorouterPrefs[GME_START_WEST] = true; 00222 autorouterPrefs[GME_END_NORTH] = true; 00223 autorouterPrefs[GME_END_EAST] = true; 00224 autorouterPrefs[GME_END_SOUTH] = true; 00225 autorouterPrefs[GME_END_WEST] = true; 00226 } 00227 } 00228 } 00229 00230 bool CGuiPort::GetARPref(int dir) 00231 { 00232 if (IsRealPort()) { 00233 CRect parentLoc = parent->GetLocation(); 00234 if (GetLocation().CenterPoint().x < (parentLoc.Size().cx / 2)) { 00235 autorouterPrefs[GME_START_NORTH] = false; 00236 autorouterPrefs[GME_START_EAST] = false; 00237 autorouterPrefs[GME_START_SOUTH] = false; 00238 autorouterPrefs[GME_START_WEST] = true; 00239 autorouterPrefs[GME_END_NORTH] = false; 00240 autorouterPrefs[GME_END_EAST] = false; 00241 autorouterPrefs[GME_END_SOUTH] = false; 00242 autorouterPrefs[GME_END_WEST] = true; 00243 } else { 00244 autorouterPrefs[GME_START_NORTH] = false; 00245 autorouterPrefs[GME_START_EAST] = true; 00246 autorouterPrefs[GME_START_SOUTH] = false; 00247 autorouterPrefs[GME_START_WEST] = false; 00248 autorouterPrefs[GME_END_NORTH] = false; 00249 autorouterPrefs[GME_END_EAST] = true; 00250 autorouterPrefs[GME_END_SOUTH] = false; 00251 autorouterPrefs[GME_END_WEST] = false; 00252 00253 } 00254 } 00255 return autorouterPrefs[dir]; 00256 } 00257 00258 00259 bool CGuiPort::IsVisible() // called on a tmp obj that only exists to get this info 00260 { 00261 bool visible = true; 00262 VERIFY(parent); 00263 VERIFY(parent->parent); 00264 CComPtr<IMgaFCO> fco = parent->parent->mgaFco; 00265 CComBSTR bstr = L"GME/ports"; 00266 CComPtr<IMgaRegNode> root; 00267 COMTHROW(fco->get_RegistryNode(bstr,&root)); 00268 CComPtr<IMgaRegNodes> nodes; 00269 00270 VARIANT_BOOL vb = VARIANT_TRUE; 00271 COMTHROW(root->get_SubNodes(vb,&nodes)); 00272 MGACOLL_ITERATE(IMgaRegNode,nodes) { 00273 CComPtr<IMgaRegNode> reg; 00274 reg = MGACOLL_ITER; 00275 CComPtr<IMgaFCO> portFco; 00276 COMTHROW(reg->get_FCOValue(&portFco)); 00277 if(IsEqualObject(portFco,mgaFco)) { 00278 CComPtr<IMgaRegNode> subreg; 00279 CComBSTR path = L"visible"; 00280 COMTHROW(reg->get_SubNodeByName(path,&subreg)); 00281 if(subreg != 0) { 00282 CComBSTR val; 00283 COMTHROW(subreg->get_Value(&val)); 00284 CString value; 00285 CopyTo(val,value); 00286 int v; 00287 if(_stscanf((LPCTSTR)value,_T("%d"),&v) > 0) 00288 visible = v ? true : false; 00289 } 00290 break; 00291 } 00292 } 00293 MGACOLL_ITERATE_END; 00294 return visible; 00295 } 00296 00297 void CGuiPort::SetVisible(bool v) // called on a tmp obj that only exists to set this info 00298 { 00299 VERIFY(parent); 00300 VERIFY(parent->parent); 00301 CComPtr<IMgaFCO> fco = parent->parent->mgaFco; 00302 CComBSTR id; 00303 CComBSTR bstr = L"GME/ports/"; 00304 COMTHROW(mgaFco->get_ID(&id)); 00305 bstr += id; 00306 CComPtr<IMgaRegNode> reg; 00307 COMTHROW(fco->get_RegistryNode(bstr,®)); 00308 COMTHROW(reg->put_FCOValue(mgaFco)); 00309 CComBSTR path = L"visible"; 00310 CComPtr<IMgaRegNode> subreg; 00311 COMTHROW(reg->get_SubNodeByName(path,&subreg)); 00312 CComBSTR bstrval = v ? L"1" : L"0"; 00313 COMTHROW(subreg->put_Value(bstrval)); 00314 } 00315 00316 CRect CGuiPort::GetLocation() 00317 { 00318 long sx = 0; 00319 long sy = 0; 00320 long ex = 0; 00321 long ey = 0; 00322 if (!IsRealPort()) { 00323 CSize size = parent->GetLocation().Size(); 00324 sx = sy = 0; 00325 ex = size.cx; 00326 ey = size.cy; 00327 } 00328 else { 00329 try { 00330 parent->GetDecorator()->GetPortLocation(mgaFco, &sx, &sy, &ex, &ey); 00331 } 00332 catch(hresult_exception& e) { 00333 if (e.hr != E_DECORATOR_PORTNOTFOUND) { 00334 throw e; 00335 } 00336 } 00337 } 00338 return CRect(sx, sy, ex, ey); 00339 } 00340 00341 bool CGuiPort::IsRealPort() { 00342 return !mgaFco.IsEqualObject(parent->GetParent()->mgaFco); 00343 } 00344 00346 // Static methods of CGuiPort 00348 00350 // Virtual methods of CGuiPort 00352 00354 00355 AnnotatorDecoratorData::AnnotatorDecoratorData() 00356 { 00357 decorator = NULL; 00358 annotatorEventSink = NULL; 00359 } 00360 00361 AnnotatorDecoratorData::AnnotatorDecoratorData(CComPtr<IMgaElementDecorator>& nD, CComObjPtr<CAnnotatorEventSink>& aES, 00362 const CRect& loc): 00363 decorator(nD), 00364 annotatorEventSink(aES), 00365 location(loc) 00366 { 00367 } 00368 00369 AnnotatorDecoratorData::~AnnotatorDecoratorData() 00370 { 00371 } 00372 00373 00375 00377 // Non-virtual methods of CGuiAnnotator 00379 CGuiAnnotator::CGuiAnnotator(CComPtr<IMgaModel>& pModel, CComPtr<IMgaRegNode>& mRootNode, CGMEView* vw, int numAsp) 00380 { 00381 model = pModel; 00382 rootNode = mRootNode; 00383 numParentAspects = numAsp; 00384 parentAspect = 0; 00385 grayedOut = false; 00386 view = vw; 00387 special = false; 00388 00389 for (int i = 0; i < numAsp; i++) { 00390 decoratorData.push_back(new AnnotatorDecoratorData()); 00391 } 00392 00393 try { 00394 CComBSTR bName; 00395 COMTHROW(rootNode->get_Name(&bName)); 00396 name = bName; 00397 00398 long st; // if main node status is inherited it means it is a special node 00399 COMTHROW(rootNode->get_Status( &st)); 00400 if( st > ATTSTATUS_HERE) 00401 special = true; 00402 00403 id = view->name + _T(":") + name; // Fake id 00404 00405 CComPtr<IMgaRegNode> aspRootNode; 00406 CComBSTR aspRootName(AN_ASPECTS); 00407 COMTHROW(rootNode->get_SubNodeByName(aspRootName, &aspRootNode)); 00408 00409 if (aspRootNode) { 00410 CComPtr<IMgaRegNodes> aspNodes; 00411 COMTHROW(aspRootNode->get_SubNodes(VARIANT_TRUE, &aspNodes)); 00412 MGACOLL_ITERATE(IMgaRegNode, aspNodes) { 00413 CComPtr<IMgaRegNode> aspNode; 00414 aspNode = MGACOLL_ITER; 00415 CComBSTR aspName; 00416 COMTHROW(aspNode->get_Name(&aspName)); 00417 CString aspNameStr(aspName); 00418 if (aspNameStr != AN_DEFASPECT) { 00419 CGuiMetaAspect *guiMetaAsp = view->guiMeta->FindAspect(aspNameStr); 00420 if (guiMetaAsp) { 00421 ReadLocation(guiMetaAsp->index, aspNode); 00422 InitDecorator(guiMetaAsp->index); 00423 } 00424 } 00425 } 00426 MGACOLL_ITERATE_END; 00427 00428 CComPtr<IMgaRegNode> defAspNode; 00429 CComBSTR defAspName(AN_DEFASPECT); 00430 COMTHROW(aspRootNode->get_SubNodeByName(defAspName, &defAspNode)); 00431 long status; 00432 COMTHROW(defAspNode->get_Status(&status)); 00433 if (status != ATTSTATUS_UNDEFINED) { 00434 for (int i = 0; i < numParentAspects; i++) { 00435 if (decoratorData[i]->decorator == NULL) { 00436 ReadLocation(i, defAspNode); 00437 InitDecorator(i); 00438 } 00439 } 00440 } 00441 } 00442 } 00443 catch(hresult_exception &e) { 00444 for (std::vector<AnnotatorDecoratorData*>::iterator ii = decoratorData.begin(); ii != decoratorData.end(); ++ii) { 00445 if ((*ii)->decorator != NULL) { 00446 COMTHROW((*ii)->decorator->Destroy()); 00447 (*ii)->decorator.Release(); 00448 (*ii)->decorator = NULL; 00449 } 00450 if ((*ii)->annotatorEventSink != NULL) { 00451 (*ii)->annotatorEventSink.Release(); 00452 (*ii)->annotatorEventSink = NULL; 00453 } 00454 delete (*ii); 00455 } 00456 decoratorData.clear(); 00457 00458 numParentAspects = 0; 00459 parentAspect = 0; 00460 throw hresult_exception(e.hr); 00461 return; 00462 } 00463 } 00464 00465 CGuiAnnotator::~CGuiAnnotator() 00466 { 00467 for (std::vector<AnnotatorDecoratorData*>::iterator ii = decoratorData.begin(); ii != decoratorData.end(); ++ii) { 00468 if ((*ii)->decorator != NULL) { 00469 COMTHROW((*ii)->decorator->Destroy()); 00470 (*ii)->decorator.Release(); 00471 (*ii)->decorator = NULL; 00472 } 00473 if ((*ii)->annotatorEventSink != NULL) { 00474 (*ii)->annotatorEventSink.Release(); 00475 (*ii)->annotatorEventSink = NULL; 00476 } 00477 delete (*ii); 00478 } 00479 decoratorData.clear(); 00480 } 00481 00482 void CGuiAnnotator::InitDecorator(int asp) 00483 { 00484 try { 00485 CString progId = AN_DECORATOR_PROGID; 00486 COMTHROW(decoratorData[asp]->decorator.CoCreateInstance(PutInBstr(progId))); 00487 00488 CComPtr<IMgaElementDecoratorEvents> annotatorEventSinkIface; 00489 ::CreateComObject(decoratorData[asp]->annotatorEventSink); 00490 HRESULT hr = ::QueryInterface((IMgaElementDecoratorEvents*)(decoratorData[asp]->annotatorEventSink.p), 00491 &annotatorEventSinkIface); 00492 if (SUCCEEDED(hr)) { 00493 decoratorData[asp]->annotatorEventSink->SetView(view); 00494 decoratorData[asp]->annotatorEventSink->SetGuiAnnotator(this); 00495 } 00496 CComBSTR param(AN_PARAM_ROOTNODE); 00497 CComVariant value(rootNode); 00498 COMTHROW(decoratorData[asp]->decorator->SetParam(param, value)); 00499 00500 COMTHROW(decoratorData[asp]->decorator->InitializeEx(theApp.mgaProject, NULL, NULL, annotatorEventSinkIface, (ULONGLONG)view->m_hWnd)); 00501 00502 long sx, sy; 00503 COMTHROW(decoratorData[asp]->decorator->GetPreferredSize(&sx, &sy)); 00504 decoratorData[asp]->location.right = decoratorData[asp]->location.left + sx; 00505 decoratorData[asp]->location.bottom = decoratorData[asp]->location.top + sy; 00506 00507 COMTHROW(decoratorData[asp]->decorator->SetLocation(decoratorData[asp]->location.left, decoratorData[asp]->location.top, 00508 decoratorData[asp]->location.right, decoratorData[asp]->location.bottom)); 00509 } 00510 catch (hresult_exception &) { 00511 AfxMessageBox(_T("Cannot initialize annotator for annotation: ") + name, MB_OK | MB_ICONSTOP); 00512 decoratorData[asp]->decorator = NULL; 00513 } 00514 } 00515 00516 bool CGuiAnnotator::IsVisible(int aspect) 00517 { 00518 if (aspect < 0) { 00519 aspect = parentAspect; 00520 } 00521 return (decoratorData[aspect]->decorator != NULL); 00522 } 00523 00524 bool CGuiAnnotator::IsResizable(void) const 00525 { 00526 if (decoratorData[parentAspect]->decorator) { 00527 try { 00528 feature_code fc = 0; 00529 COMTHROW(decoratorData[parentAspect]->decorator->GetFeatures(&fc)); 00530 return ((fc & F_RESIZABLE) != 0); 00531 } 00532 catch (hresult_exception &) { 00533 AfxMessageBox(_T("Error in annotator [method IsResizable()]")); 00534 } 00535 } 00536 00537 return false; 00538 } 00539 00540 void CGuiAnnotator::Draw(HDC pDC, Gdiplus::Graphics* gdip) 00541 { 00542 ASSERT(sizeof(ULONG) == sizeof(HDC)); 00543 if (decoratorData[parentAspect]->decorator) { 00544 try { 00545 COMTHROW(decoratorData[parentAspect]->decorator->DrawEx((ULONG)pDC, (ULONGLONG)gdip)); 00546 } 00547 catch (hresult_exception &) { 00548 AfxMessageBox(_T("Error in annotator [method Draw()]")); 00549 } 00550 } 00551 } 00552 00553 void CGuiAnnotator::GrayOut(bool set) 00554 { 00555 if (decoratorData[parentAspect]->decorator) { 00556 grayedOut = set; 00557 try { 00558 COMTHROW(decoratorData[parentAspect]->decorator->SetActive(set ? VARIANT_FALSE : VARIANT_TRUE)); 00559 } 00560 catch (hresult_exception &) { 00561 } 00562 } 00563 } 00564 00565 const CRect& CGuiAnnotator::GetLocation(int aspect) 00566 { 00567 if (aspect < 0) { 00568 aspect = parentAspect; 00569 } 00570 return decoratorData[aspect]->location; 00571 } 00572 00573 void CGuiAnnotator::SetLocation(const CRect& toLoc, int aspect, bool doMga) 00574 { 00575 if (aspect < 0) { 00576 aspect = parentAspect; 00577 } 00578 00579 CRect loc(toLoc); 00580 if (loc.left < 0) { 00581 loc.right += -loc.left; 00582 loc.left = 0; 00583 } 00584 if (loc.top < 0) { 00585 loc.bottom += -loc.top; 00586 loc.top = 0; 00587 } 00588 00589 decoratorData[aspect]->location = loc; 00590 try { 00591 COMTHROW(decoratorData[aspect]->decorator->SetLocation(loc.left, loc.top, loc.right, loc.bottom)); 00592 } 00593 catch (hresult_exception &) { 00594 AfxMessageBox(_T("Cannot set location of annotation ") + name); 00595 } 00596 00597 if (doMga) { 00598 WriteLocation(aspect); 00599 } 00600 } 00601 00602 void CGuiAnnotator::ReadLocation(int aspect, CComPtr<IMgaRegNode>& aspNode) 00603 { 00604 decoratorData[aspect]->location.left = 0; 00605 decoratorData[aspect]->location.top = 0; 00606 00607 try { 00608 CComBSTR bstr; 00609 COMTHROW(aspNode->get_Value(&bstr)); 00610 CString str(bstr); 00611 long lx, ly; 00612 if(_stscanf(str,_T("%d,%d"), &lx, &ly) == 2) { 00613 decoratorData[aspect]->location.left = lx; 00614 decoratorData[aspect]->location.top = ly; 00615 return; 00616 } 00617 } 00618 catch (hresult_exception &) { 00619 } 00620 try { 00621 CComPtr<IMgaRegNode> rootNode; 00622 COMTHROW(aspNode->get_ParentNode(&rootNode)); 00623 CComBSTR bstrRoot; 00624 COMTHROW(rootNode->get_Value(&bstrRoot)); 00625 CString strRoot(bstrRoot); 00626 long lxr, lyr; 00627 if(_stscanf(strRoot,_T("%d,%d"), &lxr, &lyr) == 2) { 00628 decoratorData[aspect]->location.left = lxr; 00629 decoratorData[aspect]->location.top = lyr; 00630 return; 00631 } 00632 } 00633 catch (hresult_exception &) { 00634 } 00635 } 00636 00637 void CGuiAnnotator::WriteLocation(int aspect) 00638 { 00639 if (aspect < 0) { 00640 aspect = parentAspect; 00641 } 00642 00643 OLECHAR bbc[40]; 00644 _snwprintf(bbc, 40, OLESTR("%ld,%ld"), decoratorData[aspect]->location.left, decoratorData[aspect]->location.top); 00645 CComBSTR bb(bbc); 00646 00647 00648 CComPtr<IMgaRegNode> aspRoot; 00649 CComBSTR aspRootName(AN_ASPECTS); 00650 COMTHROW(rootNode->get_SubNodeByName(aspRootName, &aspRoot)); 00651 00652 CComPtr<IMgaRegNode> aspNode; 00653 CComBSTR aspName(view->guiMeta->FindAspect(aspect)->name); 00654 COMTHROW(aspRoot->get_SubNodeByName(aspName, &aspNode)); 00655 00656 COMTHROW(aspNode->put_Value(bb)); 00657 } 00658 00660 // Static methods of CGuiAnnotator 00662 void CGuiAnnotator::SetAspect(CGuiAnnotatorList& list, int asp) 00663 { 00664 POSITION pos = list.GetHeadPosition(); 00665 while (pos) { 00666 list.GetNext(pos)->SetAspect(asp); 00667 } 00668 } 00669 00670 void CGuiAnnotator::GrayOutAnnotations(CGuiAnnotatorList& list, bool set) 00671 { 00672 POSITION pos = list.GetHeadPosition(); 00673 while (pos) { 00674 list.GetNext(pos)->GrayOut(set); 00675 } 00676 } 00677 00678 00679 void CGuiAnnotator::NudgeAnnotations(CGuiAnnotatorList& annotatorList, int right, int down) 00680 { 00681 CGMEEventLogger::LogGMEEvent(_T("CGuiAnnotator::NudgeAnnotations ")); 00682 GMEEVENTLOG_GUIANNOTATORS(annotatorList); 00683 ASSERT(right == 0 || down == 0); // cannot nudge diagonally for now 00684 POSITION pos = annotatorList.GetHeadPosition(); 00685 while(pos) { 00686 CGuiAnnotator* ann = annotatorList.GetNext(pos); 00687 VERIFY(ann->IsVisible()); 00688 CRect rect = ann->GetLocation(); 00689 rect.top += down * GME_GRID_SIZE; 00690 rect.bottom += down * GME_GRID_SIZE; 00691 rect.left += right * GME_GRID_SIZE; 00692 rect.right += right * GME_GRID_SIZE; 00693 ann->SetLocation(rect); 00694 } 00695 } 00696 00697 void CGuiAnnotator::GetExtent(CGuiAnnotatorList& annotatorList, CRect& rect) 00698 { 00699 CGuiAnnotator* ann; 00700 CRect cur1, cur2; 00701 POSITION pos = annotatorList.GetHeadPosition(); 00702 rect = CRect(0,0,0,0); 00703 while(pos) { 00704 ann = annotatorList.GetNext(pos); 00705 if(ann && ann->IsVisible()) { 00706 cur2 = ann->GetLocation(); 00707 cur1 = rect; 00708 rect.UnionRect(&cur1, &cur2); 00709 } 00710 } 00711 } 00712 00713 void CGuiAnnotator::GetRectList(CGuiAnnotatorList &annotatorList, CRectList &annRects) 00714 { 00715 POSITION pos = annotatorList.GetHeadPosition(); 00716 while(pos) { 00717 CRect* rect = new CRect(annotatorList.GetNext(pos)->GetLocation()); 00718 annRects.AddTail(rect); 00719 } 00720 } 00721 00722 00723 void CGuiAnnotator::FindUpperLeft(CGuiAnnotatorList& anns, int& left, int& top) 00724 { 00725 bool start = true; 00726 POSITION pos = anns.GetHeadPosition(); 00727 CGuiAnnotator* ann; 00728 CRect r; 00729 while(pos) { 00730 ann = anns.GetNext(pos); 00731 if(ann->IsVisible()) { 00732 r = ann->GetLocation(); 00733 if(start) { 00734 left = r.left; 00735 top = r.top; 00736 start = false; 00737 } 00738 else { 00739 if(r.left < left) 00740 left = r.left; 00741 if(r.top < top) 00742 top = r.top; 00743 } 00744 } 00745 } 00746 } 00747 00748 void CGuiAnnotator::ShiftAnnotations(CGuiAnnotatorList& annList, CPoint& shiftBy) 00749 { 00750 CGMEEventLogger::LogGMEEvent(_T("CGuiAnnotator::ShiftAnnotations ")); 00751 GMEEVENTLOG_GUIANNOTATORS(annList); 00752 POSITION pos = annList.GetHeadPosition(); 00753 while(pos) { 00754 CGuiAnnotator* ann = annList.GetNext(pos); 00755 VERIFY(ann->IsVisible()); 00756 CRect newLoc = ann->GetLocation(); 00757 newLoc.OffsetRect(shiftBy); 00758 ann->SetLocation(newLoc); 00759 } 00760 } 00761 00762 // static 00763 int CGuiAnnotator::Hide(CComPtr<IMgaRegNode>& mRootNode ) 00764 { 00765 CComBSTR val; 00766 COMTHROW(mRootNode->get_Value( &val)); 00767 COMTHROW(mRootNode->put_Value( val)); 00768 // thus we made the value of the annotator defined 'HERE' 00769 // which will decide whether an annotation regnode is virtual (inherited) or not 00770 00771 CComBSTR bstr(L"1"); 00772 00773 // hidden node set to true 00774 CComPtr<IMgaRegNode> hideNode; 00775 CComBSTR hideNm(AN_HIDDEN); 00776 COMTHROW(mRootNode->get_SubNodeByName( hideNm, &hideNode)); 00777 COMTHROW( hideNode->put_Value( bstr)); 00778 00779 return S_OK; 00780 } 00781 00782 // static 00783 bool CGuiAnnotator::Showable( CComPtr<IMgaRegNode>& mRootNode, CComPtr<IMgaFCO>& baseType ) 00784 { // decides whether an annotation should be displayed in case of a subtype/instance 00785 // Subtype/instance may have: owned annotations (not present in the ancestor) -> main status = ATTSTATUS_HERE 00786 // inherited annotations -> main status = ATTSTATUS_INHERITED1,2,... 00787 // inherited, but modified annotations -> main status = ATTSTATUS_HERE 00788 try { 00789 CComBSTR bName; 00790 COMTHROW(mRootNode->get_Name(&bName)); 00791 00792 bool hidden_set = false; 00793 CComPtr<IMgaRegNode> hideNode; 00794 CComBSTR hideNm(AN_HIDDEN); 00795 COMTHROW(mRootNode->get_SubNodeByName( hideNm, &hideNode)); 00796 if (hideNode) 00797 { 00798 long hideStatus; 00799 COMTHROW( hideNode->get_Status( &hideStatus)); 00800 if( hideStatus != ATTSTATUS_UNDEFINED) // meta, here or inherited 00801 { 00802 CComBSTR bstr; 00803 COMTHROW( hideNode->get_Value( &bstr)); 00804 if( bstr == L"1") 00805 return false; 00806 } 00807 } 00808 00809 if (baseType->GetRegistryValue(mRootNode->Path).length()) 00810 { 00811 CComPtr<IMgaRegNode> inheritNode; 00812 CComBSTR inhName(AN_INHERITABLE); 00813 COMTHROW(mRootNode->get_SubNodeByName( inhName, &inheritNode)); 00814 00815 if (inheritNode) { 00816 CComBSTR bstr; 00817 COMTHROW(inheritNode->get_Value( &bstr)); 00818 if (bstr == L"1") // if "inheritable" is 1 show it 00819 return true; 00820 } 00821 } 00822 else 00823 { 00824 return true; 00825 } 00826 } 00827 catch(hresult_exception &e) { 00828 throw hresult_exception(e.hr); 00829 return false; 00830 } 00831 00832 return false; 00833 } 00834 00836 // Virtual methods of CGuiAnnotator 00838 00839 00840 00842 00844 // Non-virtual methods of CGuiFco 00846 00847 CGuiFco::CGuiFco(CComPtr<IMgaFCO>& pt, CComPtr<IMgaMetaRole>& role, CGMEView* vw, int numAsp) : 00848 CGuiBase(), 00849 mgaFco(pt), 00850 metaRole(role), 00851 view(vw), 00852 numParentAspects(numAsp), 00853 parentAspect(0), 00854 grayedOut(false), 00855 isType(false) 00856 { 00857 { 00858 CComBSTR bstr; 00859 COMTHROW(role->get_Name(&bstr)); 00860 CopyTo(bstr, roleName); 00861 } 00862 { 00863 CComBSTR bstr; 00864 COMTHROW(role->get_DisplayedName(&bstr)); 00865 CopyTo(bstr, roleDisplayedName); 00866 } 00867 { 00868 COMTHROW(role->get_Kind(&metaFco)); 00869 } 00870 { 00871 CComBSTR bstr; 00872 COMTHROW(metaFco->get_Name(&bstr)); 00873 CopyTo(bstr, kindName); 00874 } 00875 { 00876 CComBSTR bstr; 00877 COMTHROW(metaFco->get_DisplayedName(&bstr)); 00878 CopyTo(bstr, kindDisplayedName); 00879 } 00880 if (pt) { 00881 CComBSTR bstr; 00882 COMTHROW(mgaFco->get_ID(&bstr)); 00883 CopyTo(bstr, id); 00884 } 00885 if (pt) { 00886 CComBSTR bstr; 00887 COMTHROW(mgaFco->get_Name(&bstr)); 00888 CopyTo(bstr, name); 00889 } 00890 00891 metaref_type metaRef; 00892 COMTHROW(metaFco->get_MetaRef(&metaRef)); 00893 guiMeta = CGuiMetaProject::theInstance->GetGuiMetaFco(metaRef); 00894 } 00895 00896 metaref_type CGuiFco::GetRoleMetaRef() 00897 { 00898 metaref_type tp; 00899 VERIFY(metaRole); 00900 COMTHROW(metaRole->get_MetaRef(&tp)); 00901 return tp; 00902 } 00903 00904 bool CGuiFco::IsPrimary(CGuiMetaModel* guiMetaModel, int aspectInd) 00905 { 00906 bool prim = false; 00907 CGuiMetaAspect *aspect = guiMetaModel->FindAspect(aspectInd); 00908 if(aspect) 00909 prim = CGuiFco::IsPrimary(guiMetaModel, aspect, metaRole); 00910 return prim; 00911 } 00912 00913 bool CGuiFco::IsPrimary(CGuiMetaModel* guiMetaModel, CGuiMetaAspect* aspect) 00914 { 00915 return CGuiFco::IsPrimary(guiMetaModel, aspect, metaRole); 00916 } 00917 00918 bool CGuiFco::GetPreference(CString& val, CString path) 00919 { 00920 CComBSTR pathBstr; 00921 CopyTo(path, pathBstr); 00922 CComBSTR bstrVal; 00923 if (mgaFco) { 00924 COMTHROW(mgaFco->get_RegistryValue(pathBstr, &bstrVal)); 00925 } 00926 else { 00927 COMTHROW(metaFco->get_RegistryValue(pathBstr, &bstrVal)); 00928 } 00929 CopyTo(bstrVal, val); 00930 return !val.IsEmpty(); 00931 } 00932 00933 00934 bool CGuiFco::GetPreference(int& val, CString path, bool hex) 00935 { 00936 CComBSTR pathBstr; 00937 CopyTo(path, pathBstr); 00938 CComBSTR bstrVal; 00939 if(mgaFco == 0) { 00940 COMTHROW(metaFco->get_RegistryValue(pathBstr, &bstrVal)); 00941 } 00942 else { 00943 COMTHROW(mgaFco->get_RegistryValue(pathBstr, &bstrVal)); 00944 } 00945 CString strVal; 00946 CopyTo(bstrVal,strVal); 00947 return (_stscanf(strVal,hex ? _T("%x") : _T("%d"),&val) == 1); 00948 } 00949 00950 bool CGuiFco::GetColorPreference(unsigned long& color, CString path) 00951 { 00952 int i; 00953 if(GetPreference(i,path,true)) { 00954 unsigned int r = (i & 0xff0000) >> 16; 00955 unsigned int g = (i & 0xff00) >> 8; 00956 unsigned int b = i & 0xff; 00957 color = RGB(r,g,b); 00958 return true; 00959 } 00960 return false; 00961 } 00962 00963 CGuiMetaModel *CGuiFco::GetGuiMetaParent() 00964 { 00965 CComPtr<IMgaMetaModel> metaParent; 00966 COMTHROW(metaRole->get_ParentModel(&metaParent)); 00967 VERIFY(metaParent); 00968 metaref_type metaRef; 00969 COMTHROW(metaParent->get_MetaRef(&metaRef)); 00970 return CGuiMetaProject::theInstance->GetGuiMetaModel(metaRef); 00971 00972 } 00973 00975 // Static methods of CGuiFco 00977 bool CGuiFco::IsPrimary(CGuiMetaModel* guiMetaModel, CGuiMetaAspect* guiAspect, CComPtr<IMgaMetaRole>& metaRole) 00978 { 00979 VARIANT_BOOL prim = VARIANT_FALSE; 00980 CComPtr<IMgaMetaAspect> mAspect; 00981 guiAspect->GetMetaAspect(mAspect); 00982 CComPtr<IMgaMetaPart> part; 00983 guiMetaModel->GetPartByRole(metaRole, mAspect, part); 00984 if(part != 0) 00985 COMTHROW(part->get_IsPrimary(&prim)); 00986 return prim != VARIANT_FALSE; 00987 } 00988 00989 void CGuiFco::SetAspect(CGuiFcoList& modelList, int asp) 00990 { 00991 POSITION pos = modelList.GetHeadPosition(); 00992 while(pos) 00993 modelList.GetNext(pos)->SetAspect(asp); 00994 } 00995 00996 CGuiObject* CGuiFco::FindObject(CComPtr<IMgaFCO>& fco, CGuiFcoList& fcoList) 00997 { 00998 POSITION pos = fcoList.GetHeadPosition(); 00999 while(pos) { 01000 CGuiFco* ofco = fcoList.GetNext(pos); 01001 ASSERT(ofco != NULL); 01002 CGuiObject* obj = ofco->dynamic_cast_CGuiObject(); 01003 if (obj) { 01004 VARIANT_BOOL b; 01005 COMTHROW(obj->mgaFco->get_IsEqual(fco, &b)); 01006 if (b) 01007 return obj; 01008 } 01009 } 01010 return 0; 01011 } 01012 01013 CGuiConnection* CGuiFco::FindConnection(CComPtr<IMgaFCO>& fco, CGuiConnectionList& conns) 01014 { 01015 POSITION pos = conns.GetHeadPosition(); 01016 while(pos) { 01017 CGuiConnection* conn = conns.GetNext(pos); 01018 VARIANT_BOOL b; 01019 COMTHROW(conn->mgaFco->get_IsEqual(fco, &b)); 01020 if(b != VARIANT_FALSE) 01021 return conn; 01022 } 01023 return 0; 01024 } 01025 01026 01027 void CGuiFco::GrayOutFcos(CGuiFcoList& list, bool set) 01028 { 01029 POSITION pos = list.GetHeadPosition(); 01030 while(pos) 01031 list.GetNext(pos)->GrayOut(set); 01032 } 01033 01034 void CGuiFco::GrayOutFcos(CGuiConnectionList& list, bool set) 01035 { 01036 POSITION pos = list.GetHeadPosition(); 01037 while(pos) 01038 list.GetNext(pos)->GrayOut(set); 01039 } 01040 01041 void CGuiFco::GrayOutNonInternalConnections(CGuiConnectionList& list) 01042 { 01043 POSITION pos = list.GetHeadPosition(); 01044 while(pos) { 01045 CGuiConnection *conn = list.GetNext(pos); 01046 if(conn->src && conn->dst) 01047 conn->GrayOut(conn->src->grayedOut || conn->dst->grayedOut); 01048 } 01049 } 01050 01051 void CGuiFco::ResetFlags(CGuiFcoList& list) 01052 { 01053 POSITION pos = list.GetHeadPosition(); 01054 while(pos) 01055 list.GetNext(pos)->flag = 0; 01056 } 01057 01059 // Virtual methods of CGuiFco 01061 01062 01063 CGuiMetaAttributeList *CGuiFco::GetMetaAttributes() 01064 { 01065 return &guiMeta->attrs; 01066 } 01067 01068 01070 01072 // Non-virtual methods of CGuiObject 01074 CGuiObject::CGuiObject(CComPtr<IMgaFCO>& pt, CComPtr<IMgaMetaRole>& role, CGMEView* vw, int numAsp) : CGuiFco(pt, role, vw, numAsp) 01075 { 01076 guiAspects.SetSize(numAsp); 01077 for (int i = 0; i<numAsp; i++) { 01078 guiAspects[i] = NULL; 01079 } 01080 } 01081 01082 void CGuiObject::InitObject(CWnd* viewWnd) 01083 { 01084 try { 01085 CComPtr<IMgaMetaParts> mmParts; 01086 COMTHROW(metaRole->get_Parts(&mmParts)); 01087 MGACOLL_ITERATE(IMgaMetaPart,mmParts) { 01088 CComPtr<IMgaMetaPart> mmPart; 01089 mmPart = MGACOLL_ITER; 01090 CComPtr<IMgaMetaAspect> mmAspect; 01091 COMTHROW(mmPart->get_ParentAspect(&mmAspect)); 01092 CComBSTR bstr; 01093 COMTHROW(mmAspect->get_Name(&bstr)); 01094 CString aspName; 01095 CopyTo(bstr,aspName); 01096 CGuiMetaAspect *guiMetaAsp = GetGuiMetaParent()->FindAspect(aspName); 01097 VERIFY(guiMetaAsp); 01098 VERIFY(guiMetaAsp->index < numParentAspects); 01099 CString decoratorStr; 01100 GetDecoratorStr(decoratorStr); 01101 InitAspect(guiMetaAsp->index, mmPart, decoratorStr, viewWnd); 01102 } 01103 MGACOLL_ITERATE_END; 01104 01105 CString hotspotPref; 01106 GetPreference(hotspotPref, HOTSPOT_PREF); 01107 if (hotspotPref == HOTSPOT_FALSE) { 01108 isHotspotEnabled = false; 01109 } 01110 else { 01111 isHotspotEnabled = true; 01112 } 01113 } 01114 catch(hresult_exception &e) { 01115 numParentAspects = 0; 01116 parentAspect = 0; 01117 throw hresult_exception(e.hr); 01118 return; 01119 } 01120 if (IsReal()) { 01121 ReadAllLocations(); 01122 } 01123 else { 01124 SetAllSizesToNative(); 01125 } 01126 } 01127 01128 CGuiObject::~CGuiObject() 01129 { 01130 if (view) { 01131 POSITION ppos = view->pendingRequests.GetHeadPosition(); 01132 while (ppos) { 01133 POSITION tmp = ppos; 01134 CPendingObjectPosRequest *req = dynamic_cast<CPendingObjectPosRequest*> (view->pendingRequests.GetNext(ppos)); 01135 if (req) { 01136 if ( req->object == this ) { 01137 view->pendingRequests.RemoveAt(tmp); 01138 delete req; 01139 } 01140 } 01141 } 01142 } 01143 01144 for (int i = 0; i < guiAspects.GetSize(); i++) { 01145 delete guiAspects[i]; 01146 } 01147 guiAspects.RemoveAll(); 01148 } 01149 01150 void CGuiObject::InitAspect(int asp, CComPtr<IMgaMetaPart>& metaPart, CString& decorStr, CWnd* viewWnd) 01151 { 01152 VERIFY(asp < numParentAspects); 01153 CGuiMetaAspect* metaAspect = GetKindAspect(metaPart); 01154 VERIFY(metaAspect); 01155 01156 CString progId; 01157 CStringList params; 01158 CStringList values; 01159 01160 if (!decorStr.IsEmpty()) { // no decorator progId and no paarmeters => use default box decorator later 01161 if (decorStr.FindOneOf(_T("\n\t ,=")) == -1) { // just a progId, no parameters 01162 progId = decorStr; 01163 } else { // there is some parameter 01164 LPTSTR lpsz = new TCHAR[decorStr.GetLength()+1]; 01165 LPTSTR tok = new TCHAR[decorStr.GetLength()+1]; 01166 _tcscpy(lpsz, decorStr); 01167 int curpos = 0, tokpos = 0; 01168 int state = 0; // 0:progid, 1:var, 2:val 01169 bool gotOne = false; 01170 TCHAR ch; 01171 01172 while ( (ch = lpsz[curpos++]) != 0) { 01173 if (ch == _T('\n') || ch == _T('\t') || ch == _T(' ')) { 01174 if (gotOne) { 01175 state = 1; 01176 gotOne = false; 01177 tok[tokpos] = 0; 01178 progId = tok; 01179 tokpos = 0; 01180 } 01181 continue; 01182 } 01183 switch (state) { 01184 case 0: 01185 gotOne = true; 01186 tok[tokpos++] = ch; 01187 break; 01188 case 1: 01189 if (ch == _T('=')) { 01190 state = 2; 01191 tok[tokpos] = 0; 01192 params.AddTail(tok); 01193 tokpos = 0; 01194 } 01195 else { 01196 tok[tokpos++] = ch; 01197 } 01198 break; 01199 case 2: 01200 if (ch == _T(',')) { 01201 state = 1; 01202 tok[tokpos] = 0; 01203 values.AddTail(tok); 01204 tokpos = 0; 01205 } 01206 else { 01207 tok[tokpos++] = ch; 01208 } 01209 break; 01210 } 01211 } 01212 if (state == 0) { 01213 tok[tokpos] = 0; 01214 progId = tok; 01215 } 01216 if (state == 2) { 01217 tok[tokpos] = 0; 01218 values.AddTail(tok); 01219 } 01220 01221 delete [] lpsz; // WAS: delete lpsz; 01222 delete [] tok;; // WAS: delete tok;; 01223 } 01224 } 01225 01226 if (progId.IsEmpty()) { 01227 progId = GME_DEFAULT_DECORATOR; 01228 } 01229 CComPtr<IMgaDecorator> decor; 01230 CComPtr<IMgaElementDecorator> newDecor; 01231 01232 CComObjPtr<CDecoratorEventSink> decoratorEventSink; 01233 try { 01234 CComPtr<IMgaElementDecoratorEvents> decoratorEventSinkIface; 01235 HRESULT hres = newDecor.CoCreateInstance(PutInBstr(progId)); 01236 if (FAILED(hres) && hres != CO_E_CLASSSTRING) { // might be an old decorator 01237 hres = decor.CoCreateInstance(PutInBstr(progId)); 01238 } 01239 if (FAILED(hres)) { // fall back to default decorator 01240 if (this->view->uncreatableDecorators.find(progId) == this->view->uncreatableDecorators.end()) 01241 { 01242 CMainFrame::theInstance->m_console.Message(_T("Cannot create ") + progId + _T(" decorator! Trying default (") + GME_DEFAULT_DECORATOR + _T(") decorator."), 3); 01243 this->view->uncreatableDecorators.insert(progId); 01244 } 01245 progId = GME_DEFAULT_DECORATOR; 01246 COMTHROW(newDecor.CoCreateInstance(PutInBstr(progId))); 01247 } 01248 01249 if (newDecor) { 01250 ::CreateComObject(decoratorEventSink); 01251 HRESULT hr = ::QueryInterface((IMgaElementDecoratorEvents*)decoratorEventSink.p, &decoratorEventSinkIface); 01252 if (SUCCEEDED(hr)) { 01253 decoratorEventSink->SetView(view); 01254 decoratorEventSink->SetGuiObject(this); 01255 } else { 01256 ASSERT(false); 01257 } 01258 decor = CComQIPtr<IMgaDecorator>(newDecor); 01259 } 01260 01261 // It seems that SetParam fails before InitializeEx, so this was probably never tested... 01262 POSITION ppos = params.GetHeadPosition(); 01263 POSITION vpos = values.GetHeadPosition(); 01264 while (ppos && vpos) { 01265 CComBSTR param(params.GetNext(ppos)); 01266 CComVariant value(values.GetNext(vpos)); 01267 COMTHROW(decor->SetParam(param, value)); 01268 } 01269 // ************************************************************************************* 01270 01271 if (newDecor) 01272 COMTHROW(newDecor->InitializeEx(theApp.mgaProject, metaPart, mgaFco, decoratorEventSinkIface, (ULONGLONG)viewWnd->m_hWnd)); 01273 else 01274 COMTHROW(decor->Initialize(theApp.mgaProject, metaPart, mgaFco)); 01275 01276 if (CGMEView::showConnectedPortsOnly ) 01277 { 01278 CComVariant value(VARIANT_TRUE); 01279 CComBSTR param(DEC_CONNECTED_PORTS_ONLY_PARAM); 01280 COMTHROW(decor->SetParam(param,value)); 01281 } 01282 } 01283 catch (hresult_exception&) { 01284 CMainFrame::theInstance->m_console.Message(_T("Cannot create ") + progId + _T(" decorator."), 3); 01285 } 01286 guiAspects[asp] = new CGuiAspect(metaAspect, this, metaAspect->index, asp, decor, newDecor, decoratorEventSink); 01287 parentAspect = 0; 01288 } 01289 01290 void CGuiObject::GetDecoratorStr(CString& decorStr) 01291 { 01292 if (!GetPreference(decorStr, DECORATOR_PREF)) 01293 decorStr = GME_DEFAULT_DECORATOR; 01294 } 01295 01296 void CGuiObject::SetObjectLocation(CRect& rect, int aspect, bool doMga) 01297 { 01298 if(aspect < 0) 01299 aspect = parentAspect; 01300 VERIFY(aspect >= 0); 01301 VERIFY(guiAspects[aspect] != NULL); 01302 CRect loc = guiAspects[aspect]->GetLocation(); 01303 // if (IsReal()) { 01304 loc.MoveToXY(rect.left, rect.top); 01305 guiAspects[aspect]->SetLocation(loc); 01306 if(IsReal() && doMga) 01307 WriteLocation(aspect); 01308 } 01309 01310 void CGuiObject::SetSize(CSize& s, int aspect, bool doMga) 01311 { 01312 if(aspect < 0) 01313 aspect = parentAspect; 01314 VERIFY(aspect >= 0); 01315 VERIFY(guiAspects[aspect] != NULL); 01316 CRect loc = guiAspects[aspect]->GetLocation(); 01317 ::SetSize(loc,s); 01318 guiAspects[aspect]->SetLocation(loc); 01319 if(IsReal() && doMga) 01320 WriteLocation(aspect); 01321 } 01322 01323 void CGuiObject::SetAllSizes(CSize& s, bool doMga) 01324 { 01325 for(int i = 0; i < numParentAspects; i++) 01326 if(guiAspects[i] != NULL) 01327 SetSize(s,i,doMga); 01328 } 01329 01330 void CGuiObject::SetLocation(CRect& r, int aspect, bool doMga/*, bool savePreferredSize*/) 01331 { 01332 if(aspect < 0) 01333 aspect = parentAspect; 01334 VERIFY(aspect >= 0); 01335 VERIFY(guiAspects[aspect] != NULL); 01336 guiAspects[aspect]->SetLocation(r); 01337 if(IsReal() && doMga) 01338 WriteLocation(aspect/*, savePreferredSize*/); 01339 } 01340 01341 CSize CGuiObject::GetNativeSize(int aspect) 01342 { 01343 if(aspect < 0) 01344 aspect = parentAspect; 01345 VERIFY(aspect >= 0); 01346 if(guiAspects[aspect] == NULL) 01347 return CSize(0,0); 01348 try { 01349 long sizex, sizey; 01350 COMTHROW(guiAspects[aspect]->GetDecorator()->GetPreferredSize(&sizex, &sizey)); 01351 return CSize(sizex, sizey); 01352 } 01353 catch (hresult_exception &) { 01354 return false; 01355 } 01356 //return true;// unreachable code 01357 } 01358 01359 01360 void CGuiObject::SetAllSizesToNative() 01361 { 01362 CSize s; 01363 for(int i = 0; i < numParentAspects; i++) { 01364 if(guiAspects[i]) { 01365 s=GetNativeSize(i); 01366 CRect loc(0, 0, 0, 0); 01367 guiAspects[i]->SetLocation(loc); 01368 SetSize(s, i, false); 01369 } 01370 } 01371 } 01372 01373 void CGuiObject::GetNeighbors(CGuiFcoList& list) 01374 { 01375 VERIFY(GetCurrentAspect()); 01376 CGuiPortList& portList = GetCurrentAspect()->GetPortList(); 01377 POSITION ppos = portList.GetHeadPosition(); 01378 while (ppos) { 01379 CGuiPort *port = portList.GetNext(ppos); 01380 POSITION cpos = port->GetInConns().GetHeadPosition(); 01381 while(cpos) { 01382 CGuiConnection *conn = port->GetInConns().GetNext(cpos); 01383 if(conn->src->flag == 0) { 01384 list.AddTail(conn->src); 01385 conn->src->flag = 1; 01386 } 01387 } 01388 cpos = port->GetOutConns().GetHeadPosition(); 01389 while(cpos) { 01390 CGuiConnection *conn = port->GetOutConns().GetNext(cpos); 01391 if(conn->dst->flag == 0) { 01392 list.AddTail(conn->dst); 01393 conn->dst->flag = 1; 01394 } 01395 } 01396 } 01397 } 01398 01399 void CGuiObject::GetRelationsInOut(CGuiConnectionList& p_list, bool p_inOrOut) 01400 { 01401 VERIFY(GetCurrentAspect()); 01402 01403 // acquire ports 01404 CGuiPortList& portList = GetCurrentAspect()->GetPortList(); 01405 POSITION ppos = portList.GetHeadPosition(); 01406 while (ppos) 01407 { 01408 // one port 01409 CGuiPort *port = portList.GetNext(ppos); 01410 01411 ASSERT( port); 01412 if( !port) continue; 01413 01414 // acquire the in/out connections through the current port 01415 POSITION cpos = p_inOrOut? port->GetInConns().GetHeadPosition(): port->GetOutConns().GetHeadPosition(); 01416 while(cpos) 01417 { 01418 // one connection 01419 CGuiConnection* conn = p_inOrOut? port->GetInConns().GetNext(cpos): port->GetOutConns().GetNext(cpos); 01420 01421 ASSERT( conn); 01422 if( !conn) continue; 01423 01424 // store it 01425 p_list.AddTail( conn); 01426 } 01427 } 01428 } 01429 01430 void CGuiObject::ReadAllLocations() 01431 { 01432 try { 01433 CComPtr<IMgaMetaParts> mmParts; 01434 CComPtr<IMgaMetaPart> mmPart; 01435 COMTHROW(metaRole->get_Parts(&mmParts)); 01436 MGACOLL_ITERATE(IMgaMetaPart,mmParts) { 01437 mmPart = MGACOLL_ITER; 01438 CComPtr<IMgaMetaAspect> mmAspect; 01439 COMTHROW(mmPart->get_ParentAspect(&mmAspect)); 01440 CComBSTR bstr; 01441 COMTHROW(mmAspect->get_Name(&bstr)); 01442 CString aspName; 01443 CopyTo(bstr,aspName); 01444 CGuiMetaAspect *guiMetaAsp = GetGuiMetaParent()->FindAspect(aspName); 01445 VERIFY(guiMetaAsp); 01446 VERIFY(guiMetaAsp->index < numParentAspects); 01447 int aspIndex = guiMetaAsp->index; 01448 VERIFY(aspIndex >= 0); 01449 CComPtr<IMgaPart> part; 01450 COMTHROW(mgaFco->get_Part(mmAspect,&part)); 01451 CComBSTR icon; 01452 long x; 01453 long y; 01454 01455 CRect loc(0, 0, 0, 0); 01456 CSize s = GetNativeSize(aspIndex); 01457 ::SetSize(loc,s); 01458 01459 if(part->GetGmeAttrs(0, &x, &y) == S_OK) { 01460 ::SetLocation(loc, CPoint(x, y)); 01461 guiAspects[aspIndex]->SetLocation(loc); 01462 } 01463 else { // unparsable integer pair found, use (-1, -1) like in CMgaPart::GetGmeAttrs 01464 ::SetLocation(loc,CPoint(-1, -1)); 01465 guiAspects[aspIndex]->SetLocation(loc); 01466 } 01467 } 01468 MGACOLL_ITERATE_END; 01469 } 01470 catch(hresult_exception &e) { 01471 throw hresult_exception(e.hr); 01472 } 01473 } 01474 01475 void CGuiObject::WriteLocation(int aspect) 01476 { 01477 VERIFY(IsReal()); 01478 if(aspect < 0) 01479 aspect = parentAspect; 01480 VERIFY(aspect >= 0); 01481 VERIFY(guiAspects[aspect]); 01482 try { 01483 view->BeginTransaction(); 01484 CComPtr<IMgaPart> part; 01485 CGuiMetaAspect *guiAsp = GetGuiMetaParent()->FindAspect(aspect); 01486 CComPtr<IMgaMetaBase> mBase = guiAsp->mgaMeta; 01487 CComPtr<IMgaMetaAspect> mAspect; 01488 COMTHROW(mBase.QueryInterface(&mAspect)); 01489 COMTHROW(mgaFco->get_Part(mAspect,&part)); 01490 CRect r = guiAspects[aspect]->GetLocation(); 01491 // Save position part 01492 CPoint pt = r.TopLeft(); 01493 COMTHROW(part->SetGmeAttrs(0, pt.x, pt.y)); 01494 // This would be too agressive: to delete any connecting connections customizations if the box is moved 01495 // DeleteCustomizationOfInOutConnections(aspect); 01496 view->CommitTransaction(); 01497 } 01498 catch(hresult_exception &e) { 01499 view->AbortTransaction(e.hr); 01500 } 01501 } 01502 01503 void CGuiObject::DeleteCustomizationOfConnections(CGuiConnectionList& conns, long aspect) 01504 { 01505 POSITION pos = conns.GetHeadPosition(); 01506 while(pos) { 01507 CGuiConnection* conn = conns.GetNext(pos); 01508 if (conn->HasPathCustomization()) 01509 if (conn->DeleteAllPathCustomizationsForAnAspect(aspect)) 01510 conn->WriteCustomPathData(false); 01511 } 01512 } 01513 01514 void CGuiObject::DeleteCustomizationOfInOutConnections(long aspect) 01515 { 01516 CGuiConnectionList inConns; 01517 GetRelationsInOut(inConns, true); 01518 DeleteCustomizationOfConnections(inConns, aspect); 01519 CGuiConnectionList outConns; 01520 GetRelationsInOut(outConns, false); 01521 DeleteCustomizationOfConnections(outConns, aspect); 01522 } 01523 01524 void CGuiObject::GrayOutNeighbors() 01525 { 01526 CGuiFcoList neighbors; 01527 GetNeighbors(neighbors); 01528 GrayOutFcos(neighbors, grayedOut); 01529 ResetFlags(neighbors); 01530 } 01531 01532 bool CGuiObject::IsInside(CPoint& pt, bool lookNearToo) 01533 { 01534 CRect loc = GetLocation(); 01535 if (lookNearToo) 01536 loc.InflateRect(3, 3); 01537 return (loc.PtInRect(pt) == TRUE); 01538 } 01539 01540 bool CGuiObject::IsLabelInside(CPoint& pt, bool lookNearToo) 01541 { 01542 CRect loc = GetNameLocation(); 01543 if (lookNearToo) 01544 loc.InflateRect(3, 3); 01545 return (loc.PtInRect(pt) == TRUE); 01546 } 01547 01548 CGuiPort* CGuiObject::FindPort(CPoint& pt, bool lookNearToo) 01549 { 01550 CGuiPort* found = NULL; 01551 CSize foundSize(0, 0); 01552 VERIFY(GetCurrentAspect()); 01553 CGuiPortList& portList = GetCurrentAspect()->GetPortList(); 01554 POSITION pos = portList.GetHeadPosition(); 01555 while(pos) { 01556 CGuiPort* port = portList.GetNext(pos); 01557 // The last one in the list is weird one: fco is the object's fco, skip that. 01558 // See CGuiAspect::InitPorts 01559 if (!mgaFco.IsEqualObject(port->mgaFco)) 01560 { 01561 CRect r = port->GetLocation() + GetLocation().TopLeft(); 01562 r.InflateRect(1, 1); // consider mouseover on red outline too 01563 CRect rInflated = r; 01564 rInflated.InflateRect(3, 3); 01565 if (r.PtInRect(pt) == TRUE || (lookNearToo && rInflated.PtInRect(pt) == TRUE)) 01566 { 01567 CSize psize = port->GetLocation().Size(); 01568 if (found) 01569 { 01570 if (psize.cx < foundSize.cx && psize.cy < foundSize.cy ) { 01571 foundSize = psize; 01572 found = port; 01573 } 01574 } 01575 else 01576 { 01577 foundSize = psize; 01578 found = port; 01579 } 01580 } 01581 } 01582 } 01583 return found; 01584 } 01585 01586 CGuiPort* CGuiObject::FindPort(CComPtr<IMgaFCO> mgaFco) 01587 { 01588 ASSERT(GetCurrentAspect()); 01589 CGuiPortList& portList = GetCurrentAspect()->GetPortList(); 01590 POSITION pos = portList.GetHeadPosition(); 01591 while(pos) { 01592 CGuiPort* port = portList.GetNext(pos); 01593 VARIANT_BOOL b; 01594 COMTHROW(port->mgaFco->get_IsEqual(mgaFco, &b)); 01595 if (b) 01596 return port; 01597 } 01598 return 0; 01599 } 01600 01601 void CGuiObject::IncrementAnimRefCnt() 01602 { 01603 if (view) { 01604 if (!(view->animRefCnt++)) { 01605 view->timerID = view->SetTimer(GME_ANIM_EVENT_ID, GME_ANIM_INTERVAL, NULL); 01606 } 01607 } 01608 } 01609 01610 void CGuiObject::DecrementAnimRefCnt() 01611 { 01612 if (view) { 01613 ASSERT(view->animRefCnt); 01614 if (!(--view->animRefCnt)) { 01615 if (view->timerID) { 01616 view->KillTimer(view->timerID); 01617 view->timerID = 0; 01618 } 01619 } 01620 } 01621 } 01622 01623 01625 // Static methods of CGuiObject 01627 01628 void CGuiObject::GetExtent(CGuiFcoList& objectList, CRect& rect) 01629 { 01630 CGuiObject* obj; 01631 CRect cur1, cur2; 01632 POSITION pos = objectList.GetHeadPosition(); 01633 rect = CRect(0, 0, 10, 10); 01634 while (pos) { 01635 CGuiFco* fco = objectList.GetNext(pos); 01636 ASSERT(fco != NULL); 01637 obj = fco->dynamic_cast_CGuiObject(); 01638 if(obj && obj->IsVisible()) { 01639 cur2 = obj->GetLocation(); 01640 cur1 = rect; 01641 rect.UnionRect(&cur1, &cur2); 01642 } 01643 } 01644 } 01645 01646 void CGuiObject::GetExtent(CGuiObjectList& objectList, CRect& rect) 01647 { 01648 CGuiObject* obj; 01649 CRect cur1, cur2; 01650 POSITION pos = objectList.GetHeadPosition(); 01651 rect = CRect(0, 0, 0, 0); 01652 while(pos) { 01653 obj = objectList.GetNext(pos); 01654 if(obj && obj->IsVisible()) { 01655 cur2 = obj->GetLocation(); 01656 cur1 = rect; 01657 rect.UnionRect(&cur1, &cur2); 01658 } 01659 } 01660 } 01661 01662 void CGuiObject::MoveObjects(CGuiFcoList& fcoList, CPoint& pt) 01663 { 01664 CGuiObjectList objs; 01665 POSITION pos = fcoList.GetHeadPosition(); 01666 while(pos) { 01667 CGuiFco* fco = fcoList.GetNext(pos); 01668 ASSERT(fco != NULL); 01669 CGuiObject* obj = fco->dynamic_cast_CGuiObject(); 01670 if (obj) 01671 objs.AddTail(obj); 01672 } 01673 MoveObjects(objs, pt); 01674 } 01675 01676 void CGuiObject::MoveObjects(CGuiObjectList& objList, CPoint& pt) 01677 { 01678 int left, top; 01679 FindUpperLeft(objList, left, top); 01680 CPoint diff = pt - CPoint(left, top); 01681 ShiftModels(objList, diff); 01682 } 01683 01684 01685 void CGuiObject::FindUpperLeft(CGuiObjectList& objs, int& left, int& top) 01686 { 01687 bool start = true; 01688 POSITION pos = objs.GetHeadPosition(); 01689 CGuiObject* obj; 01690 CRect r; 01691 while(pos) { 01692 obj = objs.GetNext(pos); 01693 if(obj->IsVisible()) { 01694 r = obj->GetLocation(); 01695 if(start) { 01696 left = r.left; 01697 top = r.top; 01698 start = false; 01699 } 01700 else { 01701 if(r.left < left) 01702 left = r.left; 01703 if(r.top < top) 01704 top = r.top; 01705 } 01706 } 01707 } 01708 } 01709 01710 void CGuiObject::ShiftModels(CGuiObjectList& objList, CPoint& shiftBy) 01711 { 01712 CGMEEventLogger::LogGMEEvent(_T("CGuiObject::ShiftModels ")); 01713 GMEEVENTLOG_GUIOBJS(objList); 01714 01715 CGuiObject* first_obj = objList.IsEmpty() ? 0 : objList.GetHead(); 01716 if( first_obj && first_obj->GetView() && first_obj->GetView() != modelGrid.GetSource()) 01717 { 01718 // if the view where the object was moved and the view of the grid 01719 // do not correspond, we must clear & update the grid. 01720 // possible because if a port is moved inside a model, then the model 01721 // is redrawn as well, and modelGrid is a global variable. 01722 // clearing only the grid would be too dangerous, would allow any movement 01723 // because other objects will disappear from the radar 01724 // but a Clear with a FillModelGrid will do the correct update 01725 modelGrid.Clear(); 01726 first_obj->GetView()->FillModelGrid(); 01727 } 01728 01729 POSITION pos = objList.GetHeadPosition(); 01730 while(pos) { 01731 CGuiObject* obj = objList.GetNext(pos); 01732 modelGrid.Reset(obj); 01733 } 01734 pos = objList.GetHeadPosition(); 01735 while(pos) { 01736 CGuiObject* obj = objList.GetNext(pos); 01737 VERIFY(obj->IsVisible()); 01738 CRect rect = obj->GetLocation(); 01739 rect.MoveToXY(rect.left + shiftBy.x, rect.top + shiftBy.y); 01740 if(!modelGrid.GetClosestAvailable(obj, rect)) { 01741 //AfxMessageBox(_T("Too Many Models! Internal Program Error!"),MB_OK | MB_ICONSTOP); 01742 //return; 01743 } 01744 obj->SetLocation(rect); 01745 modelGrid.Set(obj); 01746 } 01747 } 01748 01749 void CGuiObject::ResizeObject(const CRect& newLocation/*, bool doMga*/) 01750 { 01751 CGMEEventLogger::LogGMEEvent(_T("CGuiObject::ResizeObject\n")); 01752 01753 VERIFY(IsVisible()); 01754 SetLocation((CRect)newLocation, -1, false/*doMga, true*/); 01755 // Note: there's no need to update modelgrid now, because after finishing the resize operation 01756 // there will be a full GMEView::Reset induced by the transaction commit 01757 } 01758 01759 bool CGuiObject::NudgeObjects(CGuiObjectList& modelList, int right, int down) 01760 { 01761 CGMEEventLogger::LogGMEEvent(_T("CGuiObject::NudgeObjects ")); 01762 GMEEVENTLOG_GUIOBJS(modelList); 01763 ASSERT(right == 0 || down == 0); // cannot nudge diagonally for now 01764 01765 CGuiObject* first_obj = modelList.IsEmpty() ? 0 : modelList.GetHead(); 01766 if( first_obj && first_obj->GetView() && first_obj->GetView() != modelGrid.GetSource()) 01767 { 01768 // if the view where the object was nudged and the view of the grid 01769 // do not correspond, we must clear & update the grid 01770 // possible because if a port is moved inside a model, then the model 01771 // is redrawn as well, and modelGrid is a global variable. 01772 // clearing only the grid would be too dangerous, would allow nudging always 01773 // because other objects will not seem to sit in their places 01774 // but a Clear with a FillModelGrid will do the correct update 01775 modelGrid.Clear(); 01776 first_obj->GetView()->FillModelGrid(); 01777 } 01778 01779 POSITION pos = modelList.GetHeadPosition(); 01780 while(pos) { 01781 CGuiObject* model = modelList.GetNext(pos); 01782 VERIFY(model->IsVisible()); 01783 modelGrid.Reset(model); 01784 } 01785 bool canDo = true; 01786 pos = modelList.GetHeadPosition(); 01787 while(pos) { 01788 CGuiObject* model = modelList.GetNext(pos); 01789 if(!modelGrid.CanNudge(model, right, down)) { 01790 canDo = false; 01791 break; 01792 } 01793 } 01794 if(canDo) { 01795 POSITION pos = modelList.GetHeadPosition(); 01796 while(pos) { 01797 CGuiObject *model = modelList.GetNext(pos); 01798 CRect loc = model->GetLocation(); 01799 loc.OffsetRect(CPoint(right * GME_GRID_SIZE, down * GME_GRID_SIZE)); 01800 model->SetLocation(loc); 01801 ASSERT(modelGrid.IsAvailable(model)); 01802 modelGrid.Set(model); 01803 } 01804 } 01805 else { 01806 POSITION pos = modelList.GetHeadPosition(); 01807 while(pos) { 01808 CGuiObject* model = modelList.GetNext(pos); 01809 modelGrid.Set(model); 01810 } 01811 } 01812 return canDo; 01813 } 01814 01815 void CGuiObject::GetRectList(CGuiObjectList& objList, CRectList& rects) 01816 { 01817 POSITION pos = objList.GetHeadPosition(); 01818 while(pos) { 01819 CRect* rect = new CRect(objList.GetNext(pos)->GetLocation()); 01820 rects.AddTail(rect); 01821 } 01822 } 01823 01824 bool CGuiObject::IsResizable(void) 01825 { 01826 VERIFY(parentAspect >= 0); 01827 VERIFY(GetCurrentAspect()); 01828 01829 try { 01830 feature_code fc = 0; 01831 CGuiAspect* aspect = GetCurrentAspect(); 01832 if (aspect->GetNewDecorator()) 01833 COMTHROW(GetCurrentAspect()->GetNewDecorator()->GetFeatures(&fc)); 01834 else 01835 COMTHROW(GetCurrentAspect()->GetDecorator()->GetFeatures(&fc)); 01836 return ((fc & F_RESIZABLE) != 0); 01837 } 01838 catch (hresult_exception &) { 01839 AfxMessageBox(_T("Error in CGuiObject [method IsResizable()]")); 01840 } 01841 01842 return false; 01843 } 01844 01845 01847 // Virtual methods of CGuiObject 01849 void CGuiObject::Draw(HDC pDC, Gdiplus::Graphics* gdip) 01850 { 01851 VERIFY(parentAspect >= 0); 01852 VERIFY(GetCurrentAspect()); 01853 01854 try { 01855 CGuiAspect* aspect = GetCurrentAspect(); 01856 if (aspect->GetNewDecorator()) 01857 COMTHROW(GetCurrentAspect()->GetNewDecorator()->DrawEx((ULONG)pDC, (ULONGLONG)gdip)); 01858 else 01859 COMTHROW(GetCurrentAspect()->GetDecorator()->Draw((ULONG)pDC)); 01860 } 01861 catch (hresult_exception &e) { 01862 CComQIPtr<ISupportErrorInfo> errorInfo = GetCurrentAspect()->GetDecorator(); 01863 _bstr_t error; 01864 if (errorInfo) { 01865 GetErrorInfo(error.GetAddress()); 01866 } else { 01867 GetErrorInfo(e.hr, error.GetAddress()); 01868 } 01869 // FIXME: KMS: won't Draw() be called after the MessageBox is dismissed? 01870 AfxMessageBox(CString(_T("Error in decorator [method Draw()]: ")) + static_cast<const TCHAR*>(error)); 01871 } 01872 01873 // #define _ARDEBUG 01874 #ifdef _ARDEBUG 01875 CPen arPen(PS_DOT, 1, 0x000000ff); 01876 CPen *oldPen = pDC->SelectObject(&arPen); 01877 pDC->SelectStockObject(HOLLOW_BRUSH); 01878 //pDC->Rectangle(GetCurrentAspect()->GetLocation()); 01879 //pDC->Rectangle(GetCurrentAspect()->GetNameLocation()); 01880 if (GetRouterBox()) { 01881 pDC->Rectangle(GetRouterBox()->GetRect()); 01882 } 01883 if (GetRouterNameBox()) { 01884 pDC->Rectangle(GetRouterNameBox()->GetRect()); 01885 } 01886 pDC->SelectObject(oldPen); 01887 #endif 01888 01889 } 01890 01891 void CGuiObject::GrayOut(bool set) 01892 { 01893 CGuiFco::GrayOut(set); 01894 01895 for (int i = 0; i< guiAspects.GetSize(); i++) { 01896 if (IsVisible(i)) { 01897 COMTHROW(guiAspects[i]->GetDecorator()->SetActive(set ? VARIANT_FALSE : VARIANT_TRUE)); 01898 } 01899 } 01900 } 01901 01902 01903 01904 CGuiMetaAspect *CGuiObject::GetKindAspect(CComPtr<IMgaMetaPart> metaPart) 01905 { 01906 // Kindaspect is the same as parentaspect in regular objects 01907 CComBSTR bstr; 01908 CComPtr<IMgaMetaAspect> pAspect; 01909 COMTHROW(metaPart->get_ParentAspect(&pAspect)); 01910 COMTHROW(pAspect->get_Name(&bstr)); 01911 CString aspName; 01912 CopyTo(bstr, aspName); 01913 return GetGuiMetaParent()->FindAspect(aspName); 01914 } 01915 01917 01919 // Non-virtual methods of CGuiCompound 01921 01923 // Static methods of CGuiCompound 01925 01927 // Virtual methods of CGuiCompound 01929 01930 01932 01934 // Non-virtual methods of CGuiModel 01936 CGuiModel::CGuiModel(CComPtr<IMgaFCO>& pt, CComPtr<IMgaMetaRole>& role,CGMEView* vw, int numAsp) : CGuiCompound(pt, role, vw, numAsp) 01937 { 01938 if (IsReal()) { 01939 VARIANT_BOOL inst; 01940 COMTHROW(pt->get_IsInstance(&inst)); 01941 isType = (inst == VARIANT_FALSE); 01942 } 01943 } 01944 01946 // Static methods of CGuiModel 01948 01950 // Virtual methods of CGuiModel 01952 CGuiMetaAttributeList* CGuiModel::GetMetaAttributes() 01953 { 01954 return &(GetCurrentAspect()->guiMeta->attrs); 01955 } 01956 01957 CGuiMetaAspect* CGuiModel::GetKindAspect(CComPtr<IMgaMetaPart> metaPart) 01958 { 01959 CGuiMetaModel* guiMetaModel = dynamic_cast<CGuiMetaModel*>(guiMeta); 01960 VERIFY(guiMetaModel); 01961 CGuiMetaAspect* metaAspect = NULL; 01962 CComBSTR bstr; 01963 COMTHROW(metaPart->get_KindAspect(&bstr)); 01964 CString kindAspect; 01965 CopyTo(bstr, kindAspect); 01966 if (kindAspect.IsEmpty()) { 01967 CComBSTR bstr; 01968 CComPtr<IMgaMetaAspect> pAspect; 01969 COMTHROW(metaPart->get_ParentAspect(&pAspect)); 01970 COMTHROW(pAspect->get_Name(&bstr)); 01971 CopyTo(bstr, kindAspect); 01972 metaAspect = guiMetaModel->FindAspect(kindAspect); 01973 if(!metaAspect) { 01974 metaAspect = guiMetaModel->GetFirstAspect(); 01975 /* 01976 CComBSTR bstr; 01977 COMTHROW(metaRole->get_Name(&bstr)); 01978 CString roleName; 01979 CopyTo(bstr,roleName); 01980 AfxMessageBox(_T("Missing aspect mapping specification for model ") + name + _T(" aspect ") + kindAspect + 01981 _T(" role ") + roleName + _T("!\nFirst aspect ") + metaAspect->name + _T(" is used!")); 01982 */ 01983 } 01984 } 01985 else { 01986 metaAspect = guiMetaModel->FindAspect(kindAspect); 01987 } 01988 return metaAspect; 01989 } 01991 01993 // Non-virtual methods of CReference 01995 01996 CReference::CReference(CComPtr<IMgaFCO> mgaRefd, CComPtr<IMgaFCO> mgaTermRefd) : mgaReferee(mgaRefd), mgaTerminalReferee(mgaTermRefd) 01997 { 01998 mgaReferee = mgaRefd; 01999 mgaTerminalReferee = mgaTermRefd; 02000 if(!IsNull()) { 02001 { 02002 CComBSTR bstr; 02003 COMTHROW(mgaRefd->get_Name(&bstr)); 02004 CopyTo(bstr,targetName); 02005 } 02006 { 02007 CComPtr<IMgaMetaFCO> meta; 02008 COMTHROW(mgaRefd->get_Meta(&meta)); 02009 CComBSTR bstr; 02010 COMTHROW(meta->get_DisplayedName(&bstr)); 02011 CopyTo(bstr, targetKindDisplayedName); 02012 } 02013 } 02014 } 02015 02016 CString CReference::GetInfoText(CString &name) 02017 { 02018 CString txt; 02019 if(IsNull()) 02020 txt = name + L" \u2192 null "; 02021 else 02022 txt.Format(L"%s \u2192 %s (%s) ", name, targetName, targetKindDisplayedName); 02023 return CString(txt); 02024 } 02026 // Static methods of CReference 02028 02030 // Virtual methods of CReference 02032 02034 02036 // Non-virtual methods of CGuiReference 02039 // Static methods of CGuiReference 02042 // Virtual methods of CGuiReference 02044 02045 02048 // Non-virtual methods of CGuiCompoundReference 02050 02052 // Static methods of CGuiCompoundReference 02054 02056 // Virtual methods of CGuiCompoundReference 02058 02059 CGuiMetaAttributeList* CGuiCompoundReference::GetMetaAttributes() 02060 { 02061 return &guiMeta->attrs; 02062 } 02063 02064 CGuiMetaAspect* CGuiCompoundReference::GetKindAspect(CComPtr<IMgaMetaPart> metaPart) 02065 { 02066 CComPtr<IMgaMetaFCO> metaFcoForAM; 02067 COMTHROW(GetTerminalReferee()->get_Meta(&metaFcoForAM)); 02068 metaref_type metaRef; 02069 COMTHROW(metaFcoForAM->get_MetaRef(&metaRef)); 02070 CGuiMetaModel* guiMetaModel = CGuiMetaProject::theInstance->GetGuiMetaModel(metaRef); 02071 VERIFY(guiMetaModel); 02072 02073 CGuiMetaAspect* metaAspect = NULL; 02074 CComBSTR bstr; 02075 COMTHROW(metaPart->get_KindAspect(&bstr)); 02076 CString kindAspect; 02077 CopyTo(bstr, kindAspect); 02078 if (kindAspect.IsEmpty()) { 02079 CComBSTR bstr; 02080 CComPtr<IMgaMetaAspect> pAspect; 02081 COMTHROW(metaPart->get_ParentAspect(&pAspect)); 02082 COMTHROW(pAspect->get_Name(&bstr)); 02083 CopyTo(bstr, kindAspect); 02084 metaAspect = guiMetaModel->FindAspect(kindAspect); 02085 if(!metaAspect) { 02086 metaAspect = guiMetaModel->GetFirstAspect(); 02087 /* 02088 CComBSTR bstr; 02089 COMTHROW(metaRole->get_Name(&bstr)); 02090 CString roleName; 02091 CopyTo(bstr,roleName); 02092 AfxMessageBox(_T("Missing aspect mapping specification for model ") + name + _T(" aspect ") + kindAspect + 02093 _T(" role ") + roleName + _T("!\nFirst aspect ") + metaAspect->name + _T(" is used!")); 02094 */ 02095 } 02096 } 02097 else { 02098 metaAspect = guiMetaModel->FindAspect(kindAspect); 02099 } 02100 return metaAspect; 02101 } 02102 02103 02105 02107 // Non-virtual methods of CGuiSet 02109 02110 void CGuiSet::Init(CGuiFcoList& objs, CGuiConnectionList& conns) 02111 { 02112 if (!IsReal()) { 02113 return; 02114 } 02115 CComPtr<IMgaSet> mgaSet; 02116 COMTHROW(mgaFco.QueryInterface(&mgaSet)); 02117 02118 CComPtr<IMgaFCOs> fcos; 02119 COMTHROW(mgaSet->get_Members(&fcos)); 02120 MGACOLL_ITERATE(IMgaFCO,fcos) { 02121 CComPtr<IMgaFCO> member; 02122 member = MGACOLL_ITER; 02123 CGuiFco* obj = CGuiFco::FindObject(member, objs); 02124 if(!obj) 02125 obj = CGuiFco::FindConnection(member, conns); 02126 VERIFY(obj); 02127 members.AddTail(obj); 02128 } 02129 MGACOLL_ITERATE_END; 02130 } 02131 02132 bool CGuiSet::CheckMember(CGuiFco* fco) 02133 { 02134 CComPtr<IMgaMetaSet> metaSet; 02135 COMTHROW(metaFco.QueryInterface(&metaSet)); 02136 02137 metaref_type mr = fco->GetRoleMetaRef(); 02138 CString path; 02139 path.Format(_T("%d"), mr); 02140 CComBSTR bstr; 02141 CopyTo(path, bstr); 02142 02143 VARIANT_BOOL ok = VARIANT_FALSE; 02144 COMTHROW(metaSet->CheckPath(bstr, &ok)); 02145 02146 return (ok != VARIANT_FALSE); 02147 } 02148 02149 bool CGuiSet::ToggleMember(CGuiFco* member) 02150 { 02151 VERIFY(mgaFco); 02152 CComPtr<IMgaSet> mgaSet; 02153 COMTHROW(mgaFco.QueryInterface(&mgaSet)); 02154 POSITION pos = members.Find(member); 02155 if(pos) { 02156 COMTHROW(mgaSet->RemoveMember(member->mgaFco)); 02157 } 02158 else { 02159 COMTHROW(mgaSet->AddMember(member->mgaFco)); 02160 } 02161 return pos == 0; 02162 } 02163 02164 02166 // Static methods of CGuiSet 02168 02170 // Virtual methods of CGuiSet 02172 02174 02175 CGuiConnectionLabel::CGuiConnectionLabel(): 02176 alignment(TA_BASELINE | TA_CENTER), 02177 primary(false) 02178 { 02179 } 02180 02181 CGuiConnectionLabel::~CGuiConnectionLabel() 02182 { 02183 } 02184 02185 void CGuiConnectionLabel::SetLabel(const CString& l) 02186 { 02187 label = l; 02188 } 02189 02190 void CGuiConnectionLabel::SetPrimary(bool prim) 02191 { 02192 primary = prim; 02193 } 02194 02195 void CGuiConnectionLabel::SetLocation(const CPoint& endPoint, const CPoint& nextPoint, const CRect& box) 02196 { 02197 if (label.IsEmpty()) 02198 return; 02199 02200 int diffx = 3; 02201 int diffy = 3; 02202 BOOL f_center = box.IsRectNull(); 02203 02204 loc = endPoint; 02205 CPoint center = box.CenterPoint(); 02206 02207 bool skew = (endPoint.x != nextPoint.x && endPoint.y != nextPoint.y); 02208 double alpha = 0.0; 02209 bool moreVerticalThanHorizontal = true; 02210 if (skew) { 02211 alpha = atan2(-((double)nextPoint.y - endPoint.y), (double)nextPoint.x - endPoint.x); 02212 moreVerticalThanHorizontal = (alpha >= -3 * M_PI_4 && alpha < -M_PI_4) || (alpha < 3 * M_PI_4 && alpha >= M_PI_4); 02213 } 02214 RoutingDirection lineDir = Dir_None; 02215 if (!f_center) 02216 lineDir = PointOnSide(endPoint, box); 02217 02218 if (f_center) 02219 { 02220 if (endPoint.x == nextPoint.x || skew && moreVerticalThanHorizontal) // vertical line 02221 { 02222 alignment = TA_BASELINE | (primary ? TA_RIGHT : TA_LEFT); 02223 loc.x += primary ? -diffx : diffx; 02224 } 02225 else if (endPoint.y == nextPoint.y || skew && !moreVerticalThanHorizontal) // horizontal line 02226 { 02227 alignment = TA_CENTER | (primary ? TA_BOTTOM : TA_TOP); 02228 } 02229 else 02230 { 02231 ASSERT(false); 02232 } 02233 } 02234 else 02235 { 02236 switch(lineDir) { 02237 case Dir_Top: // up 02238 { 02239 loc.y -= diffy; 02240 loc.x += primary ? -diffx : diffx; 02241 alignment = TA_BOTTOM | (primary ? TA_RIGHT : TA_LEFT); 02242 } 02243 break; 02244 case Dir_Bottom: // down 02245 { 02246 loc.y += diffy; 02247 loc.x += primary ? -diffx : diffx; 02248 alignment = TA_TOP | (primary ? TA_RIGHT : TA_LEFT); 02249 } 02250 break; 02251 case Dir_Left: // left 02252 { 02253 loc.x -= diffx; 02254 alignment = TA_RIGHT | (primary ? TA_BOTTOM : TA_TOP); 02255 } 02256 break; 02257 default: 02258 ASSERT(false); 02259 case Dir_Skew: // TODO? 02260 case Dir_Right: // right 02261 { 02262 loc.x += diffx; 02263 alignment = TA_LEFT | (primary ? TA_BOTTOM : TA_TOP); 02264 } 02265 break; 02266 } 02267 } 02268 } 02269 02270 void CGuiConnectionLabel::Draw(Gdiplus::Graphics* gdip, COLORREF color, CGuiConnection* conn) 02271 { 02272 if (label.IsEmpty()) 02273 return; 02274 02275 label.Replace(_T("%name%"), conn->name); 02276 label.Replace(_T("%kind%"), conn->kindDisplayedName); 02277 label.Replace(_T("%role%"), conn->roleDisplayedName); 02278 02279 CGuiMetaAttributeList *metaAttrs = conn->GetMetaAttributes(); 02280 POSITION pos = metaAttrs->GetHeadPosition(); 02281 while (pos) { 02282 CGuiMetaAttribute *metaAttr = metaAttrs->GetNext(pos); 02283 CString attrName; 02284 attrName += _T("%"); 02285 attrName += metaAttr->name; 02286 attrName += _T("%"); 02287 label.Replace(attrName, conn->attributeCache[metaAttr->name]); 02288 } 02289 02290 if (label.IsEmpty()) 02291 return; 02292 graphics.DrawGdipText(gdip, label, loc, graphics.GetGdipFont(GME_CONNLABEL_FONT), color, alignment); 02293 } 02294 02295 CPoint CGuiConnectionLabel::GetLocation(void) const 02296 { 02297 return loc; 02298 } 02299 02300 int CGuiConnectionLabel::GetAlignment(void) const 02301 { 02302 return alignment; 02303 } 02304 02305 CString CGuiConnectionLabel::GetLabel(void) const 02306 { 02307 return label; 02308 } 02309 02311 02312 CGuiConnectionLabelSet::CGuiConnectionLabelSet() 02313 { 02314 labels[GME_CONN_SRC_LABEL1].SetPrimary(false); 02315 labels[GME_CONN_SRC_LABEL2].SetPrimary(true); 02316 labels[GME_CONN_DST_LABEL1].SetPrimary(false); 02317 labels[GME_CONN_DST_LABEL2].SetPrimary(true); 02318 labels[GME_CONN_MAIN_LABEL].SetPrimary(true); 02319 } 02320 02321 CGuiConnectionLabelSet::~CGuiConnectionLabelSet() 02322 { 02323 } 02324 02325 void CGuiConnectionLabelSet::SetLabel(int index, const CString& label) 02326 { 02327 if (index < 0 || index >= GME_CONN_LABEL_NUM) 02328 return; 02329 labels[index].SetLabel(label); 02330 } 02331 02332 void CGuiConnectionLabelSet::SetLocation(int index, const CPoint& endPoint, const CPoint& nextPoint, const CRect& box) 02333 { 02334 if (index < 0 || index >= GME_CONN_LABEL_NUM) 02335 return; 02336 labels[index].SetLocation(endPoint, nextPoint, box); 02337 } 02338 02339 void CGuiConnectionLabelSet::Draw(Gdiplus::Graphics* gdip, COLORREF color, CGuiConnection* conn) 02340 { 02341 for(int i = 0; i < GME_CONN_LABEL_NUM; i++) 02342 labels[i].Draw(gdip, color, conn); 02343 } 02344 02345 CPoint CGuiConnectionLabelSet::GetLocation(int index) const 02346 { 02347 CPoint pt(-1, -1); 02348 if (index >= 0 && index < GME_CONN_LABEL_NUM) 02349 pt = labels[index].GetLocation(); 02350 return pt; 02351 } 02352 02353 int CGuiConnectionLabelSet::GetAlignment(int index) const 02354 { 02355 int alignment = 0; 02356 if (index >= 0 && index < GME_CONN_LABEL_NUM) 02357 alignment = labels[index].GetAlignment(); 02358 return alignment; 02359 } 02360 02361 CString CGuiConnectionLabelSet::GetLabel(int index) const 02362 { 02363 CString label; 02364 if (index >= 0 && index < GME_CONN_LABEL_NUM) 02365 label = labels[index].GetLabel(); 02366 return label; 02367 } 02368 02369 02371 02373 // Non-virtual methods of CGuiConnection 02375 02376 CGuiConnection::CGuiConnection(CComPtr<IMgaFCO>& pt, CComPtr<IMgaMetaRole>& role, CGMEView* vw, int numAsp, bool resolve): 02377 CGuiFco(pt, role, vw, numAsp), 02378 src (NULL), 02379 srcPort (NULL), 02380 dst (NULL), 02381 dstPort (NULL), 02382 hovered (false), 02383 selected (false), 02384 connRegAutoRouteNotSet (true), 02385 isAutoRouted (theApp.useAutoRouting) 02386 { 02387 routerPath = NULL; 02388 02389 if (resolve) 02390 Resolve(); 02391 02392 { 02393 CString pref; 02394 GetPreference(pref, CONN_LINE_TYPE_PREF); 02395 lineType = (pref == _T("dash")) ? GME_LINE_DASH : GME_LINE_SOLID; 02396 } 02397 { 02398 CString pref; 02399 GetPreference(pref, CONN_SRC_END_STYLE_PREF); 02400 if ( pref == _T("arrow") ) 02401 srcStyle = GME_ARROW_END; 02402 else if ( pref == _T("diamond") ) 02403 srcStyle = GME_DIAMOND_END; 02404 else if ( pref == _T("empty diamond") ) 02405 srcStyle = GME_EMPTYDIAMOND_END; 02406 else if ( pref == _T("apex") ) 02407 srcStyle = GME_APEX_END; 02408 else if ( pref == _T("empty apex") ) 02409 srcStyle = GME_EMPTYAPEX_END; 02410 else if ( pref == _T("bullet") ) 02411 srcStyle = GME_BULLET_END; 02412 else if ( pref == _T("empty bullet") ) 02413 srcStyle = GME_EMPTYBULLET_END; 02414 else if ( pref == _T("left half arrow") ) 02415 srcStyle = GME_HALFARROWLEFT_END; 02416 else if ( pref == _T("right half arrow") ) 02417 srcStyle = GME_HALFARROWRIGHT_END; 02418 else 02419 srcStyle = GME_BUTT_END; 02420 } 02421 { 02422 CString pref; 02423 GetPreference(pref, CONN_DST_END_STYLE_PREF); 02424 if ( pref == _T("arrow") ) 02425 dstStyle = GME_ARROW_END; 02426 else if ( pref == _T("diamond") ) 02427 dstStyle = GME_DIAMOND_END; 02428 else if ( pref == _T("empty diamond") ) 02429 dstStyle = GME_EMPTYDIAMOND_END; 02430 else if ( pref == _T("apex") ) 02431 dstStyle = GME_APEX_END; 02432 else if ( pref == _T("empty apex") ) 02433 dstStyle = GME_EMPTYAPEX_END; 02434 else if ( pref == _T("bullet") ) 02435 dstStyle = GME_BULLET_END; 02436 else if ( pref == _T("empty bullet") ) 02437 dstStyle = GME_EMPTYBULLET_END; 02438 else if ( pref == _T("left half arrow") ) 02439 dstStyle = GME_HALFARROWLEFT_END; 02440 else if ( pref == _T("right half arrow") ) 02441 dstStyle = GME_HALFARROWRIGHT_END; 02442 else 02443 dstStyle = GME_BUTT_END; 02444 } 02445 02446 { 02447 ReadARPreferences(); 02448 } 02449 { 02450 CString pref; 02451 02452 GetPreference(pref,CONN_LABEL_FORMATSTR_PREF); 02453 labelset.SetLabel(GME_CONN_MAIN_LABEL, pref); 02454 GetPreference(pref,CONN_SRC_LABEL1_PREF); 02455 labelset.SetLabel(GME_CONN_SRC_LABEL1, pref); 02456 GetPreference(pref,CONN_SRC_LABEL2_PREF); 02457 labelset.SetLabel(GME_CONN_SRC_LABEL2, pref); 02458 GetPreference(pref,CONN_DST_LABEL1_PREF); 02459 labelset.SetLabel(GME_CONN_DST_LABEL1, pref); 02460 GetPreference(pref,CONN_DST_LABEL2_PREF); 02461 labelset.SetLabel(GME_CONN_DST_LABEL2, pref); 02462 } 02463 if (!GetColorPreference(color, COLOR_PREF)) { 02464 color = GME_BLACK_COLOR; 02465 } 02466 if (!GetColorPreference(nameColor, NAME_COLOR_PREF)) { 02467 nameColor = GME_BLACK_COLOR; 02468 } 02469 ReadCustomPathData(); 02470 SetAutoRouted(ReadAutoRouteState()); 02471 RefreshAttributeCache(); 02472 } 02473 02474 void CGuiConnection::GiveConnectionEndErroMessage(const TCHAR* mainMsg, const TCHAR* srcOrDst, const CGuiPort* otherPort) const 02475 { 02476 if (!view->ShouldSupressConnectionCheckAlert()) { 02477 CString msgEx; 02478 msgEx.Append(_T("Connection properties:\n")); 02479 msgEx.Append(_T("\nName: ")); 02480 msgEx.Append(name); 02481 msgEx.Append(_T("\nKind Name: ")); 02482 msgEx.Append(kindDisplayedName); 02483 msgEx.Append(_T("\nRole Name: ")); 02484 msgEx.Append(roleDisplayedName); 02485 msgEx.Append(_T("\nID: ")); 02486 msgEx.Append(id); 02487 msgEx.Append(_T("\nDirection: ")); 02488 msgEx.Append(srcOrDst); 02489 msgEx.Append(_T("\nOther endpoint properties:")); 02490 if (otherPort) { 02491 msgEx.Append(_T("\n\tName: ")); 02492 msgEx.Append(otherPort->name); 02493 msgEx.Append(_T("\n\tID: ")); 02494 msgEx.Append(otherPort->id); 02495 } else { 02496 msgEx.Append(_T("\n\tOther Endpoint is also null.")); 02497 } 02498 msgEx.Append(_T("\nMissing endpoints sometimes can be generated by UDM based interpreters.")); 02499 msgEx.Append(_T("\nCancel button supress further connection error messages like this.")); 02500 int retVal = view->MessageBox(msgEx, mainMsg, MB_OKCANCEL | MB_ICONERROR); 02501 if (retVal == IDCANCEL) 02502 view->SupressConnectionCheckAlert(); 02503 } 02504 } 02505 02506 void CGuiConnection::Resolve() 02507 { 02508 try { 02509 view->BeginTransaction(TRANSACTION_READ_ONLY); 02510 CComPtr<IMgaSimpleConnection> conn; 02511 mgaFco.QueryInterface(&conn); 02512 VERIFY(conn); 02513 02514 // Compute visibility 02515 visible = std::unique_ptr<bool[]>(new bool[numParentAspects]); 02516 memset(visible.get(), 0, numParentAspects * sizeof(bool)); 02517 CComPtr<IMgaMetaParts> mmParts; 02518 COMTHROW(metaRole->get_Parts(&mmParts)); 02519 MGACOLL_ITERATE(IMgaMetaPart,mmParts) { 02520 CComPtr<IMgaMetaPart> mmPart; 02521 mmPart = MGACOLL_ITER; 02522 CComPtr<IMgaMetaAspect> mmAspect; 02523 COMTHROW(mmPart->get_ParentAspect(&mmAspect)); 02524 CComBSTR bstr; 02525 COMTHROW(mmAspect->get_Name(&bstr)); 02526 CString aspName; 02527 CopyTo(bstr,aspName); 02528 CGuiMetaAspect *guiMetaAsp = view->guiMeta->FindAspect(aspName); 02529 VERIFY(guiMetaAsp); 02530 VERIFY(guiMetaAsp->index < numParentAspects); 02531 visible[guiMetaAsp->index] = true; 02532 } 02533 MGACOLL_ITERATE_END; 02534 02535 srcPort = NULL; 02536 dstPort = NULL; 02537 if(visible[parentAspect]) { 02538 CComPtr<IMgaFCO> mgaSrc; 02539 02540 // Lookup first conn. reference first 02541 CComPtr<IMgaFCOs> mgaSrcRefs; 02542 bool src_err = false; 02543 HRESULT src_hr = S_OK; 02544 { 02545 try { 02546 src_hr = conn->get_SrcReferences(&mgaSrcRefs); 02547 } 02548 catch(hresult_exception &e) 02549 { 02550 ASSERT(FAILED(e.hr)); 02551 SetErrorInfo(e.hr); 02552 src_hr = e.hr; 02553 } 02554 } 02555 if (SUCCEEDED(src_hr) || mgaSrcRefs) { 02556 long nSrcRef = 0; 02557 COMTHROW(mgaSrcRefs->get_Count(&nSrcRef)); 02558 if (nSrcRef > 0) { 02559 COMTHROW(mgaSrcRefs->get_Item(1, &mgaSrc)); 02560 } 02561 else { 02562 COMTHROW(conn->get_Src(&mgaSrc)); 02563 } 02564 02565 POSITION pos = view->children.GetHeadPosition(); 02566 while (pos) { 02567 CGuiFco* fco = view->children.GetNext(pos); 02568 ASSERT(fco != NULL); 02569 CGuiObject* srcObj = fco->dynamic_cast_CGuiObject(); 02570 if (srcObj && srcObj->IsVisible()) { 02571 srcPort = srcObj->FindPort(mgaSrc); 02572 if (srcPort) { 02573 CGuiCompoundReference* modelRefObj = srcObj->dynamic_cast_CGuiCompoundReference(); 02574 if (modelRefObj) { 02575 CComPtr<IMgaFCO> mgaSrcPort; 02576 COMTHROW(conn->get_Src(&mgaSrcPort)); 02577 CGuiPort *srcFPort = srcObj->FindPort(mgaSrcPort); 02578 srcPort = srcFPort ? srcFPort : srcPort; 02579 if ((srcPort->IsRealPort()) && (!nSrcRef) ) { 02580 continue; 02581 } 02582 } 02583 src = srcPort->parent->GetParent(); 02584 VERIFY(src); 02585 break; 02586 } 02587 } 02588 } 02589 if (!srcPort) { 02590 visible[parentAspect] = false; 02591 } 02592 } else { 02593 src_err = true; 02594 } 02595 02596 CComPtr<IMgaFCO> mgaDst; 02597 02598 // Lookup first conn. reference first 02599 HRESULT dst_hr = S_OK; 02600 CComPtr<IMgaFCOs> mgaDstRefs; 02601 bool dst_err = false; 02602 { 02603 try { 02604 dst_hr = conn->get_DstReferences(&mgaDstRefs); 02605 } 02606 catch(hresult_exception &e) 02607 { 02608 ASSERT(FAILED(e.hr)); 02609 SetErrorInfo(e.hr); 02610 dst_hr = e.hr; 02611 } 02612 } 02613 if (SUCCEEDED(dst_hr) && mgaDstRefs) { 02614 long nDstRef = 0; 02615 COMTHROW(mgaDstRefs->get_Count(&nDstRef)); 02616 if (nDstRef > 0) { 02617 COMTHROW(mgaDstRefs->get_Item(1, &mgaDst)); 02618 } 02619 else { 02620 COMTHROW(conn->get_Dst(&mgaDst)); 02621 } 02622 02623 POSITION pos = view->children.GetHeadPosition(); 02624 while (pos) { 02625 CGuiFco* fco = view->children.GetNext(pos); 02626 ASSERT(fco != NULL); 02627 CGuiObject* dstObj = fco->dynamic_cast_CGuiObject(); 02628 if (dstObj && dstObj->IsVisible()) { 02629 dstPort = dstObj->FindPort(mgaDst); 02630 if (dstPort) { 02631 CGuiCompoundReference* modelRefObj = dstObj->dynamic_cast_CGuiCompoundReference(); 02632 if (modelRefObj) { 02633 CComPtr<IMgaFCO> mgaDstPort; 02634 COMTHROW(conn->get_Dst(&mgaDstPort)); 02635 CGuiPort *dstFPort = dstObj->FindPort(mgaDstPort); 02636 dstPort = dstFPort ? dstFPort : dstPort; 02637 if ((dstPort->IsRealPort()) && (!nDstRef) ) { 02638 continue; 02639 } 02640 } 02641 dst = dstPort->parent->GetParent(); 02642 VERIFY(dst); 02643 break; 02644 } 02645 } 02646 } 02647 if (!dstPort) { 02648 visible[parentAspect] = false; 02649 } 02650 } else { 02651 dst_err = true; 02652 } 02653 if (src_err || dst_err) { 02654 if (src_err) { 02655 GiveConnectionEndErroMessage(_T("Source endpoint error"), _T("src"), dstPort); 02656 } else if (dst_err) { 02657 GiveConnectionEndErroMessage(_T("Destination endpoint error"), _T("dst"), srcPort); 02658 } 02659 } else 02660 02661 if (visible[parentAspect]) { 02662 if( !srcPort->outConns.Find( this)) // WAS: outConns.AddTail(this); and as a result as aspects have cycled the collection got bigger and bigger 02663 srcPort->outConns.AddTail(this);// NOW: added only if ptr was not already stored in outConns 02664 02665 if( !dstPort->inConns.Find( this)) // WAS: inConns.AddTail(this); 02666 dstPort->inConns.AddTail(this);// NOW: added only if ptr was not already stored in inConns 02667 } 02668 02669 } 02670 view->CommitTransaction(); 02671 } 02672 catch (hresult_exception e) { 02673 view->AbortTransaction(e.hr); 02674 } 02675 } 02676 02677 void CGuiConnection::Draw(HDC pDC, Gdiplus::Graphics* gdip) 02678 { 02679 if(!IsVisible()) 02680 return; 02681 if (!src || !dst) 02682 return; 02683 VERIFY(src->IsVisible()); 02684 VERIFY(dst->IsVisible()); 02685 02686 CPointList points; 02687 GetPointList(points); 02688 02689 if (points.GetSize() <= 0) { 02690 ASSERT(false); 02691 return; 02692 } 02693 02694 std::vector<long> customizedEdgeIndexes; 02695 if (selected && IsAutoRouted()) 02696 customizedEdgeIndexes = GetRelevantCustomizedEdgeIndexes(); 02697 int width = selected ? 3 : hovered ? 5 : 1; 02698 if (selected && view->m_zoomVal < ZOOM_NO) 02699 { 02700 // selection was hard to see at <100% zoom. Magic numbers determined by experimentation 02701 width = (int)((float)((ZOOM_NO - 25) / max(10, view->m_zoomVal) + 0.2) * width + 0.5f); 02702 } 02703 graphics.DrawConnection(gdip, points, customizedEdgeIndexes, grayedOut ? GME_GRAYED_OUT_COLOR : color, 02704 lineType, srcStyle, dstStyle, view->m_zoomVal > ZOOM_NO, !IsAutoRouted() && selected, 02705 width); 02706 02707 if (points.GetSize() < 2) { 02708 ASSERT(false); 02709 return; 02710 } 02711 02712 POSITION pos = points.GetHeadPosition(); 02713 CPoint start = points.GetNext(pos); 02714 CPoint start2 = points.GetNext(pos); 02715 pos = points.GetTailPosition(); 02716 CPoint end = points.GetPrev(pos); 02717 CPoint end2 = points.GetPrev(pos); 02718 02719 // Get the center position of the whole connection 02720 02721 int segments = points.GetCount(); 02722 pos = points.FindIndex((int)(segments/2)-1); 02723 CPoint middle = points.GetNext(pos); 02724 CPoint middle2 = points.GetNext(pos); 02725 CRect tmpRect(middle, middle2); 02726 middle = tmpRect.CenterPoint(); 02727 02728 const CRect srcRect = src->GetLocation(); 02729 const CRect dstRect = dst->GetLocation(); 02730 02731 CRect box; 02732 box = src->GetLocation(); 02733 if (srcPort != NULL && srcPort->IsRealPort()) 02734 box = srcPort->GetLocation() + box.TopLeft(); 02735 labelset.SetLocation(0, start, start2, box); 02736 labelset.SetLocation(1, start, start2, box); 02737 box = dst->GetLocation(); 02738 if (dstPort != NULL && dstPort->IsRealPort()) 02739 box = dstPort->GetLocation() + box.TopLeft(); 02740 labelset.SetLocation(2, end, end2, box); 02741 labelset.SetLocation(3, end, end2, box); 02742 box = CRect(0, 0, 0, 0); 02743 labelset.SetLocation(GME_CONN_MAIN_LABEL, middle, middle2, box); 02744 02745 02746 labelset.Draw(gdip, (grayedOut ? GME_GRAYED_OUT_COLOR : nameColor), this); 02747 } 02748 02749 void CGuiConnection::RemoveFromRouter(CAutoRouter &router) 02750 { 02751 router.DeleteConnection(this); 02752 } 02753 02754 void CGuiConnection::GrayOutEndPoints() 02755 { 02756 src->GrayOut(grayedOut); 02757 dst->GrayOut(grayedOut); 02758 } 02759 02760 void CGuiConnection::RefreshAttributeCache() 02761 { 02762 attributeCache.RemoveAll(); 02763 02764 CGuiMetaAttributeList* guiMetaAttrs = GetMetaAttributes(); 02765 POSITION pos = guiMetaAttrs->GetHeadPosition(); 02766 02767 while (pos) { 02768 CGuiMetaAttribute* guiMetaAttr = guiMetaAttrs->GetNext(pos); 02769 CComPtr<IMgaAttribute> attr; 02770 CComPtr<IMgaMetaAttribute> metaAttr; 02771 attval_enum tp; 02772 COMTHROW(guiMetaAttr->mgaMeta.QueryInterface(&metaAttr)); 02773 COMTHROW(metaAttr->get_ValueType(&tp)); 02774 COMTHROW(mgaFco->get_Attribute(metaAttr, &attr)); 02775 CComVariant attrValue; 02776 COMTHROW(attr->get_Value(&attrValue)); 02777 02778 CString aval; 02779 CString aname = guiMetaAttr->name; 02780 02781 if (tp == ATTVAL_BOOLEAN) { 02782 VERIFY(attrValue.vt == VT_BOOL); 02783 aval = attrValue.boolVal ? _T("True") : _T("False"); 02784 } 02785 else if (tp == ATTVAL_REFERENCE) { 02786 aval = _T("Reference attr. label not supported"); // Sorry, maybe later 02787 } 02788 else if (tp == _attval_enum) { 02789 VERIFY(attrValue.vt == VT_BSTR); 02790 CString attrValueStr(attrValue.bstrVal); 02791 /* CGuiMenuCtrl *guiMenuCtrl = dynamic_cast<CGuiMenuCtrl *>(guiMetaAttr->depCtrl); 02792 if (guiMenuCtrl) { 02793 aval = attrValue.bstrVal; 02794 int idx = guiMenuCtrl->FindItemByValue(aval); 02795 if (idx != -1) 02796 aval = (guiMenuCtrl->items[idx]).label; 02797 else 02798 aval = _T("N/A"); 02799 } 02800 else { 02801 aval = _T("N/A"); 02802 } */ 02803 aval = _T("N/A"); 02804 CComPtr<IMgaMetaEnumItems> metaEnumItems; 02805 COMTHROW(metaAttr->get_EnumItems(&metaEnumItems)); 02806 02807 MGACOLL_ITERATE(IMgaMetaEnumItem,metaEnumItems) 02808 { 02809 CComBSTR bstrItemLabel; 02810 CComBSTR bstrItemValue; 02811 COMTHROW(MGACOLL_ITER->get_DisplayedName(&bstrItemLabel)); 02812 COMTHROW(MGACOLL_ITER->get_Value(&bstrItemValue)); 02813 02814 CString strItemValue(bstrItemValue); 02815 if (strItemValue == attrValueStr) { 02816 aval = bstrItemLabel; 02817 } 02818 } 02819 MGACOLL_ITERATE_END; 02820 02821 } 02822 else { 02823 if (attrValue.vt != VT_BSTR) 02824 attrValue.ChangeType(VT_BSTR); 02825 aval = attrValue.bstrVal; 02826 } 02827 attributeCache[aname] = aval; 02828 } 02829 } 02830 02831 void CGuiConnection::ReadARPreferences() 02832 { 02833 CString val; 02834 if (GetPreference(val, AUTOROUTER_PREF)) { 02835 autorouterPrefs[GME_START_NORTH] = (val.Find(_T("N")) != -1); 02836 autorouterPrefs[GME_START_EAST] = (val.Find(_T("E")) != -1); 02837 autorouterPrefs[GME_START_SOUTH] = (val.Find(_T("S")) != -1); 02838 autorouterPrefs[GME_START_WEST] = (val.Find(_T("W")) != -1); 02839 autorouterPrefs[GME_END_NORTH] = (val.Find(_T("n")) != -1); 02840 autorouterPrefs[GME_END_EAST] = (val.Find(_T("e")) != -1); 02841 autorouterPrefs[GME_END_SOUTH] = (val.Find(_T("s")) != -1); 02842 autorouterPrefs[GME_END_WEST] = (val.Find(_T("w")) != -1); 02843 } else { 02844 autorouterPrefs[GME_START_NORTH] = false; 02845 autorouterPrefs[GME_START_EAST] = false; 02846 autorouterPrefs[GME_START_SOUTH] = false; 02847 autorouterPrefs[GME_START_WEST] = false; 02848 autorouterPrefs[GME_END_NORTH] = false; 02849 autorouterPrefs[GME_END_EAST] = false; 02850 autorouterPrefs[GME_END_SOUTH] = false; 02851 autorouterPrefs[GME_END_WEST] = false; 02852 } 02853 } 02854 02855 void CGuiConnection::GetPointList(CPointList& points) const 02856 { 02857 if (routerPath != NULL) 02858 { 02859 CPointListPath& pointList = routerPath->GetPointList(); 02860 POSITION pos = pointList.GetHeadPosition(); 02861 while( pos != NULL ) 02862 { 02863 points.AddTail(pointList.GetNext(pos)); 02864 } 02865 } 02866 02867 if (!routerPath || points.GetSize() <= 0) 02868 { 02869 if (srcPort != NULL) { 02870 CPoint start = srcPort->GetLocation().CenterPoint() + src->GetLocation().TopLeft(); 02871 points.AddHead(start); 02872 } 02873 if (dstPort != NULL) { 02874 CPoint end = dstPort->GetLocation().CenterPoint() + dst->GetLocation().TopLeft(); 02875 points.AddTail(end); 02876 } 02877 } 02878 } 02879 02880 int CGuiConnection::GetEdgeCount(void) const 02881 { 02882 CPointList points; 02883 GetPointList(points); 02884 return points.GetSize() - 1; 02885 } 02886 02887 CRect CGuiConnection::GetBounds(void) const 02888 { 02889 CPointList points; 02890 GetPointList(points); 02891 02892 POSITION pos = points.GetHeadPosition(); 02893 long xmin = LONG_MAX; 02894 long xmax = LONG_MIN; 02895 long ymin = LONG_MAX; 02896 long ymax = LONG_MIN; 02897 CRect bounds; 02898 bounds.SetRectEmpty(); 02899 if (pos) { 02900 while (pos) { 02901 CPoint& pt = points.GetNext(pos); 02902 if (pt.x > xmax) 02903 xmax = pt.x; 02904 if (pt.x < xmin) 02905 xmin = pt.x; 02906 if (pt.y > ymax) 02907 ymax = pt.y; 02908 if (pt.y < ymin) 02909 ymin = pt.y; 02910 } 02911 bounds = CRect(xmin, ymin, xmax, ymax); 02912 } 02913 02914 return bounds; 02915 } 02916 02917 CPoint CGuiConnection::GetCenter(void) const 02918 { 02919 CRect bounds = GetBounds(); 02920 return bounds.CenterPoint(); 02921 } 02922 02923 bool CGuiConnection::AdjustCoordLimits(CPointList& points, int edgeIndex, bool isPathEnd, bool xOrY, POSITION pos, 02924 int ptCoord, int lastlastCoord, long& coordMinLimit, long& coordMaxLimit) const 02925 { 02926 if (!isPathEnd) { 02927 // Internal edge 02928 CPoint nextPt = points.GetNext(pos); 02929 int nextPtCoord = xOrY ? nextPt.x : nextPt.y; 02930 if (ptCoord < nextPtCoord && ptCoord < lastlastCoord) 02931 coordMinLimit = LONG_MIN; 02932 else 02933 coordMinLimit = min(nextPtCoord, lastlastCoord); 02934 if (ptCoord > nextPtCoord && ptCoord > lastlastCoord) 02935 coordMaxLimit = LONG_MAX; 02936 else 02937 coordMaxLimit = max(nextPtCoord, lastlastCoord); 02938 } else { 02939 // Inspect entities at the end to calculate limits 02940 CRect portRect; 02941 portRect.SetRectEmpty(); 02942 if (edgeIndex == 0) { 02943 if (srcPort != NULL && srcPort->IsRealPort()) { 02944 return true; 02945 } else if (src != NULL) { 02946 portRect = src->GetLocation(); 02947 } 02948 } else { 02949 if (dstPort != NULL && dstPort->IsRealPort()) { 02950 return true; 02951 } else if (dst != NULL) { 02952 portRect = dst->GetLocation(); 02953 } 02954 } 02955 02956 if (!portRect.IsRectEmpty()) { 02957 if (xOrY) { 02958 coordMinLimit = portRect.left; 02959 coordMaxLimit = portRect.right; 02960 } else { 02961 coordMinLimit = portRect.top; 02962 coordMaxLimit = portRect.bottom; 02963 } 02964 } else { 02965 ASSERT(false); 02966 return true; 02967 } 02968 } 02969 02970 return false; 02971 } 02972 02973 int CGuiConnection::GetEdgeIndex(const CPoint& point, CPoint& startPoint, CPoint& endPoint, CPoint& thirdPoint, 02974 ConnectionPartMoveType& connectionMoveMethod, bool& horizontalOrVerticalEdge, 02975 bool& isPartFixed, long& xMinLimit, long& xMaxLimit, long& yMinLimit, long& yMaxLimit, 02976 bool checkPointOnEdge) const 02977 { 02978 CPointList points; 02979 GetPointList(points); 02980 02981 int numEdges = points.GetSize() - 1; 02982 if (numEdges == -1 || routerPath == NULL) 02983 return -1; 02984 CPoint last = emptyPoint; 02985 CPoint lastlast = emptyPoint; 02986 POSITION pos = points.GetHeadPosition(); 02987 int i = 0; 02988 CAutoRouterGraph* ag = routerPath->GetOwner(); 02989 ASSERT(ag != NULL); 02990 if (pos) { 02991 CPoint pt = points.GetNext(pos); 02992 last = pt; 02993 while (pos) { 02994 pt = points.GetNext(pos); 02995 if (IsAutoRouted()) { 02996 bool moveAction = false; 02997 if (last.x == pt.x) { // vertical edge, horizontal move 02998 if (abs(pt.x - point.x) <= 3 && 02999 (point.y >= min(last.y, pt.y) - 3 || 03000 point.y <= max(last.y, pt.y) + 3)) 03001 { 03002 connectionMoveMethod = HorizontalEdgeMove; 03003 horizontalOrVerticalEdge = false; 03004 moveAction = true; 03005 } 03006 } else if (last.y == pt.y) { // horizontal line, vertical move 03007 if (abs(pt.y - point.y) <= 3 && 03008 (point.x >= min(last.x, pt.x) - 3 || 03009 point.x <= max(last.x, pt.x) + 3)) 03010 { 03011 connectionMoveMethod = VerticalEdgeMove; 03012 horizontalOrVerticalEdge = true; 03013 moveAction = true; 03014 } 03015 } else { 03016 // There mustn't be any skew edge in case of auto routed connection 03017 ASSERT(false); 03018 } 03019 if (i < numEdges - 1 && // We can't drag two connected edges at the last point! 03020 abs(pt.x - point.x) <= 3 && 03021 abs(pt.y - point.y) <= 3) 03022 { 03023 connectionMoveMethod = AdjacentEdgeMove; 03024 } 03025 if (moveAction) { 03026 isPartFixed = ag->IsEdgeFixed(routerPath, last, pt); 03027 03028 startPoint = last; 03029 endPoint = pt; 03030 bool isPathEnd = (i == 0 || i == numEdges - 1); 03031 03032 bool isPartFixed2 = false; 03033 bool pointOnEdge = false; 03034 if (connectionMoveMethod == HorizontalEdgeMove) { 03035 isPartFixed2 = AdjustCoordLimits(points, i, isPathEnd, true, pos, 03036 pt.x, lastlast.x, xMinLimit, xMaxLimit); 03037 if (checkPointOnEdge) 03038 pointOnEdge = point.y >= min(startPoint.y, endPoint.y) - 3 && point.y <= max(startPoint.y, endPoint.y) + 3; 03039 } else if (connectionMoveMethod == VerticalEdgeMove) { 03040 isPartFixed2 = AdjustCoordLimits(points, i, isPathEnd, false, pos, 03041 pt.y, lastlast.y, yMinLimit, yMaxLimit); 03042 if (checkPointOnEdge) 03043 pointOnEdge = point.x >= min(startPoint.x, endPoint.x) - 3 && point.x <= max(startPoint.x, endPoint.x) + 3; 03044 } else if (connectionMoveMethod == AdjacentEdgeMove) { 03045 POSITION nextPos = pos; 03046 CPoint nextPt = points.GetNext(nextPos); 03047 thirdPoint = nextPt; 03048 if (horizontalOrVerticalEdge) { 03049 isPartFixed2 = AdjustCoordLimits(points, i, isPathEnd, false, pos, 03050 pt.y, lastlast.y, yMinLimit, yMaxLimit); 03051 if (checkPointOnEdge) 03052 pointOnEdge = point.x >= min(startPoint.x, endPoint.x) - 3 && point.x <= max(startPoint.x, endPoint.x) + 3; 03053 if (isPartFixed2) { 03054 connectionMoveMethod = HorizontalEdgeMove; 03055 isPartFixed2 = false; 03056 } 03057 isPartFixed2 = AdjustCoordLimits(points, i + 1, i >= numEdges - 2, true, nextPos, 03058 nextPt.x, last.x, xMinLimit, xMaxLimit); 03059 if (checkPointOnEdge) 03060 pointOnEdge = pointOnEdge && (point.y >= min(endPoint.y, nextPt.y) - 3 && point.y <= max(endPoint.y, nextPt.y) + 3); 03061 if (isPartFixed2) { 03062 if (connectionMoveMethod != HorizontalEdgeMove) { 03063 connectionMoveMethod = VerticalEdgeMove; 03064 isPartFixed2 = false; 03065 } 03066 } 03067 } else { 03068 isPartFixed2 = AdjustCoordLimits(points, i, isPathEnd, true, pos, 03069 pt.x, lastlast.x, xMinLimit, xMaxLimit); 03070 if (checkPointOnEdge) 03071 pointOnEdge = point.y >= min(startPoint.y, endPoint.y) - 3 && point.y <= max(startPoint.y, endPoint.y) + 3; 03072 if (isPartFixed2) { 03073 connectionMoveMethod = VerticalEdgeMove; 03074 isPartFixed2 = false; 03075 } 03076 isPartFixed2 = AdjustCoordLimits(points, i + 1, i >= numEdges - 2, false, nextPos, 03077 nextPt.y, last.y, yMinLimit, yMaxLimit); 03078 if (checkPointOnEdge) 03079 pointOnEdge = pointOnEdge && (point.x >= min(endPoint.x, nextPt.x) - 3 && point.x <= max(endPoint.x, nextPt.x) + 3); 03080 if (isPartFixed2) { 03081 if (connectionMoveMethod != VerticalEdgeMove) { 03082 connectionMoveMethod = HorizontalEdgeMove; 03083 isPartFixed2 = false; 03084 } 03085 } 03086 } 03087 } 03088 isPartFixed |= isPartFixed2; 03089 03090 if (!checkPointOnEdge || pointOnEdge) 03091 return i; 03092 } 03093 } else { 03094 if (abs(pt.x - point.x) <= 3 && abs(pt.y - point.y) <= 3) { 03095 startPoint = last; 03096 CPoint next = points.GetNext(pos); 03097 endPoint = next; 03098 03099 connectionMoveMethod = ModifyExistingCustomPoint; 03100 isPartFixed = false; 03101 return i; 03102 } else { 03103 if (IsOnEdge(last, pt, point)) 03104 { 03105 startPoint = last; 03106 endPoint = pt; 03107 03108 connectionMoveMethod = InsertNewCustomPoint; 03109 isPartFixed = false; 03110 return i; 03111 } 03112 } 03113 } 03114 03115 i++; 03116 lastlast = last; 03117 last = pt; 03118 } 03119 } 03120 03121 return -1; 03122 } 03123 03124 int CGuiConnection::IsPathAt(const CPoint& point, ConnectionPartMoveType& connectionMoveMethod, 03125 bool& horizontalOrVerticalEdge, bool& isPartFixed) const 03126 { 03127 CPoint customizeConnectionEdgeStartPoint; 03128 CPoint customizeConnectionEdgeEndPoint; 03129 CPoint customizeConnectionEdgeThirdPoint; 03130 long customizeConnectionEdgeXMinLimit; 03131 long customizeConnectionEdgeXMaxLimit; 03132 long customizeConnectionEdgeYMinLimit; 03133 long customizeConnectionEdgeYMaxLimit; 03134 03135 return GetEdgeIndex(point, customizeConnectionEdgeStartPoint, customizeConnectionEdgeEndPoint, customizeConnectionEdgeThirdPoint, 03136 connectionMoveMethod, horizontalOrVerticalEdge, 03137 isPartFixed, customizeConnectionEdgeXMinLimit, customizeConnectionEdgeXMaxLimit, 03138 customizeConnectionEdgeYMinLimit, customizeConnectionEdgeYMaxLimit); 03139 } 03140 03141 long CGuiConnection::IsPointOnSectionAndDeletable(long edgeIndex, const CPoint& point) 03142 { 03143 CPointList points; 03144 GetPointList(points); 03145 03146 CPoint last; 03147 CPoint lastlast; 03148 POSITION pos = points.GetHeadPosition(); 03149 int i = 0; 03150 if (pos) { 03151 CPoint pt = points.GetNext(pos); 03152 last = pt; 03153 while (pos) { 03154 pt = points.GetNext(pos); 03155 03156 if (i == edgeIndex) { 03157 if (pos) { 03158 CPoint next = points.GetNext(pos); 03159 03160 if (IsOnEdge(last, next, point, 5)) { 03161 return i; 03162 } 03163 } 03164 return -1; 03165 } 03166 03167 i++; 03168 lastlast = last; 03169 last = pt; 03170 } 03171 } 03172 03173 return -1; 03174 } 03175 03176 std::vector<long> CGuiConnection::GetRelevantCustomizedEdgeIndexes(void) 03177 { 03178 int edgeCount = GetEdgeCount(); 03179 long asp = view->currentAspect->index; 03180 std::vector<long> customizedEdgeIndexes; 03181 std::vector<CustomPathData>::iterator ii = customPathData.begin(); 03182 while (ii != customPathData.end() && edgeCount > 0) { 03183 if ((*ii).GetAspect() == asp || asp == -1) { 03184 if (IsAutoRouted() && (*ii).GetType() == SimpleEdgeDisplacement && (*ii).GetEdgeCount() == edgeCount || 03185 !IsAutoRouted() && (*ii).GetType() != SimpleEdgeDisplacement) 03186 { 03187 customizedEdgeIndexes.push_back((*ii).GetEdgeIndex()); 03188 } 03189 } 03190 ++ii; 03191 } 03192 return customizedEdgeIndexes; 03193 } 03194 03195 void CGuiConnection::FillOutCustomPathData(CustomPathData& pathData, PathCustomizationType custType, long asp, 03196 int newPosX, int newPosY, int edgeIndex, int edgeCount, bool horizontalOrVerticalEdge) 03197 { 03198 pathData.SetVersion (CONNECTIONCUSTOMIZATIONDATAVERSION); 03199 pathData.SetAspect (asp); 03200 pathData.SetEdgeIndex (edgeIndex); 03201 pathData.SetEdgeCount (edgeCount < 0 ? GetEdgeCount() : edgeCount); 03202 pathData.SetType (custType); 03203 pathData.SetHorizontalOrVertical (horizontalOrVerticalEdge); 03204 if (custType == SimpleEdgeDisplacement) { 03205 pathData.SetX (!horizontalOrVerticalEdge ? newPosX : 0); 03206 pathData.SetY (horizontalOrVerticalEdge ? newPosY : 0); 03207 } else { 03208 pathData.SetX (newPosX); 03209 pathData.SetY (newPosY); 03210 } 03211 } 03212 03213 std::vector<CustomPathData> CGuiConnection::GetCurrentPathCustomizations(void) 03214 { 03215 std::vector<CustomPathData> cd; 03216 for (std::vector<CustomPathData>::iterator ii = customPathData.begin(); ii != customPathData.end(); ++ii) { 03217 if ((*ii).GetAspect() == parentAspect) 03218 cd.push_back(*ii); 03219 } 03220 return cd; 03221 } 03222 03223 bool CGuiConnection::HasPathCustomization(void) const 03224 { 03225 return customPathData.size() > 0; 03226 } 03227 03228 bool CGuiConnection::HasPathCustomizationForCurrentAspect(int edgeIndex) const 03229 { 03230 return HasPathCustomizationForAspect(view->currentAspect->index, edgeIndex); 03231 } 03232 03233 bool CGuiConnection::HasPathCustomizationForAspect(long asp, int edgeIndex) const 03234 { 03235 return HasPathCustomizationForTypeAndAspect(asp, Invalid, edgeIndex); 03236 } 03237 03238 bool CGuiConnection::HasPathCustomizationForTypeAndCurrentAspect(PathCustomizationType custType, int edgeIndex) const 03239 { 03240 return HasPathCustomizationForTypeAndAspect(view->currentAspect->index, custType, edgeIndex); 03241 } 03242 03243 bool CGuiConnection::HasPathCustomizationForTypeAndAspect(long asp, PathCustomizationType custType, int edgeIndex) const 03244 { 03245 for (std::vector<CustomPathData>::const_iterator ii = customPathData.begin(); ii != customPathData.end(); ++ii) { 03246 if ((*ii).GetAspect() == asp && 03247 ((*ii).GetEdgeIndex() == edgeIndex || edgeIndex == -1) && 03248 ((*ii).GetType() == custType || custType == Invalid)) 03249 { 03250 return true; 03251 } 03252 } 03253 return false; 03254 } 03255 03256 void CGuiConnection::ReadCustomPathData(void) 03257 { 03258 customPathData.clear(); 03259 CString pref; 03260 if (GetPreference(pref, CUSTOMCONNECTIONDATA)) { 03261 if (pref != EMPTYCONNECTIONCUSTOMIZATIONDATAMAGIC) { // -1 is a magic number for deleted data 03262 CString subStr; 03263 int curPos = 0; 03264 subStr = pref.Tokenize(_T(";"), curPos); 03265 while (subStr != _T("")) { 03266 CustomPathData pathData; 03267 if (pathData.Deserialize(subStr)) 03268 customPathData.push_back(pathData); 03269 subStr = pref.Tokenize(_T(";"), curPos); 03270 } 03271 } 03272 } 03273 } 03274 03275 void CGuiConnection::WriteCustomPathData(bool handleTransaction) 03276 { 03277 CString valStr; 03278 for (std::vector<CustomPathData>::iterator ii = customPathData.begin(); ii != customPathData.end(); ++ii) { 03279 CString edgeStr; 03280 (*ii).Serialize(edgeStr); 03281 if (valStr != _T("")) 03282 valStr.Append(_T(";")); 03283 valStr.Append(edgeStr); 03284 } 03285 VERIFY(mgaFco); 03286 CComBSTR pathBstr = CUSTOMCONNECTIONDATA; 03287 CComBSTR bstrVal; 03288 if (valStr == _T("")) 03289 bstrVal = EMPTYCONNECTIONCUSTOMIZATIONDATAMAGIC; 03290 else 03291 CopyTo(valStr, bstrVal); 03292 03293 if (handleTransaction) 03294 view->BeginTransaction(); 03295 03296 if (valStr == _T("")) { 03297 CComPtr<IMgaRegNode> ccpMgaRegNode; 03298 COMTHROW(mgaFco->get_RegistryNode(pathBstr, &ccpMgaRegNode)); 03299 COMTHROW(ccpMgaRegNode->RemoveTree()); 03300 } else { 03301 COMTHROW(mgaFco->put_RegistryValue(pathBstr, bstrVal)); 03302 } 03303 03304 if (handleTransaction) 03305 view->CommitTransaction(); 03306 } 03307 03308 void CGuiConnection::InsertCustomPathData(const CustomPathData& pathData) 03309 { 03310 // Note: 03311 // We assume that element are in ascending order by edgeIndexes 03312 // Types and aspects can be mixed up, but edgeIndexes should be in order within an aspect and type 03313 03314 // Update indexes 03315 std::vector<CustomPathData>::iterator jj; // insertion point 03316 bool found = false; 03317 for (std::vector<CustomPathData>::iterator ii = customPathData.begin(); ii != customPathData.end(); ++ii) { 03318 ASSERT((*ii).GetVersion() == pathData.GetVersion()); 03319 if ((*ii).GetAspect() == pathData.GetAspect() && 03320 (*ii).GetType() == pathData.GetType() && 03321 (!IsAutoRouted() || (*ii).GetEdgeCount() == pathData.GetEdgeCount()) && 03322 (*ii).GetEdgeIndex() >= pathData.GetEdgeIndex()) 03323 { 03324 if (!found) 03325 jj = ii; 03326 found = true; 03327 if (pathData.GetType() == CustomPointCustomization) 03328 (*ii).SetEdgeIndex((*ii).GetEdgeIndex() + 1); 03329 else if (pathData.GetType() == SimpleEdgeDisplacement) 03330 break; 03331 // TODO: other cases 03332 } 03333 } 03334 if (found) 03335 // Insert 03336 customPathData.insert(jj, pathData); 03337 else 03338 // If we didn't find elements with bigger or equal edgeIndexes, then we should insert it as last one (ascending order) 03339 customPathData.push_back(pathData); 03340 } 03341 03342 void CGuiConnection::UpdateCustomPathData(const CustomPathData& pathData) 03343 { 03344 for (std::vector<CustomPathData>::iterator ii = customPathData.begin(); ii != customPathData.end(); ++ii) { 03345 ASSERT((*ii).GetVersion() == pathData.GetVersion()); 03346 if ((*ii).GetAspect() == pathData.GetAspect() && 03347 (*ii).GetType() == pathData.GetType() && 03348 (!IsAutoRouted() || (*ii).GetEdgeCount() == pathData.GetEdgeCount()) && 03349 (*ii).GetEdgeIndex() == pathData.GetEdgeIndex()) 03350 { 03351 (*ii) = pathData; 03352 return; 03353 } 03354 } 03355 03356 // not found => insert it, preserving order 03357 InsertCustomPathData(pathData); 03358 } 03359 03360 void CGuiConnection::DeletePathCustomization(const CustomPathData& pathData) 03361 { 03362 long fullCustomEdgeCounter = 0; 03363 bool found = false; 03364 for (std::vector<CustomPathData>::iterator ii = customPathData.begin(); ii != customPathData.end(); ++ii) { 03365 ASSERT((*ii).GetVersion() == pathData.GetVersion()); 03366 if ((*ii).GetAspect() == pathData.GetAspect() && 03367 (*ii).GetType() == pathData.GetType()) 03368 { 03369 if (pathData.GetType() == SimpleEdgeDisplacement) { 03370 if ((*ii).GetEdgeIndex() == pathData.GetEdgeIndex() && 03371 (*ii).GetEdgeCount() == pathData.GetEdgeCount()) 03372 { 03373 ASSERT((*ii).IsHorizontalOrVertical() == pathData.IsHorizontalOrVertical()); 03374 ii = customPathData.erase(ii); 03375 found = true; 03376 return; 03377 } 03378 } else if (pathData.GetType() == CustomPointCustomization) { 03379 // in case of CustomPointCustomization delete by array index and not edgeIndex 03380 if (fullCustomEdgeCounter == pathData.GetEdgeIndex()) { 03381 ii = customPathData.erase(ii); 03382 found = true; 03383 break; 03384 } 03385 fullCustomEdgeCounter++; 03386 } else { 03387 // TODO: other checks for other types 03388 } 03389 } 03390 } 03391 // update indexes in case of full customization 03392 if (pathData.GetType() == CustomPointCustomization) { 03393 for (std::vector<CustomPathData>::iterator ii = customPathData.begin(); ii != customPathData.end(); ++ii) { 03394 ASSERT((*ii).GetVersion() == pathData.GetVersion()); 03395 if ((*ii).GetAspect() == pathData.GetAspect() && 03396 (*ii).GetType() == pathData.GetType()) 03397 { 03398 ASSERT((*ii).GetEdgeIndex() != pathData.GetEdgeIndex()); // because we just deleted it 03399 if ((*ii).GetEdgeIndex() > pathData.GetEdgeIndex()) { 03400 (*ii).SetEdgeIndex((*ii).GetEdgeIndex() - 1); 03401 } 03402 } 03403 } 03404 } 03405 // not found 03406 ASSERT(found); 03407 } 03408 03409 bool CGuiConnection::DeleteAllPathCustomizationsForAnAspect(long asp) 03410 { 03411 bool wereThereAnyDeletion = false; 03412 std::vector<CustomPathData>::iterator ii = customPathData.begin(); 03413 while (ii != customPathData.end()) { 03414 if ((*ii).GetAspect() == asp && 03415 (IsAutoRouted() && (*ii).GetType() == SimpleEdgeDisplacement || 03416 !IsAutoRouted() && (*ii).GetType() != SimpleEdgeDisplacement)) 03417 { 03418 wereThereAnyDeletion = true; 03419 ii = customPathData.erase(ii); 03420 } else { 03421 ++ii; 03422 } 03423 } 03424 return wereThereAnyDeletion; 03425 } 03426 03427 bool CGuiConnection::DeleteAllPathCustomizationsForCurrentAspect(void) 03428 { 03429 return DeleteAllPathCustomizationsForAnAspect(view->currentAspect->index); 03430 } 03431 03432 void CGuiConnection::DeleteAllPathCustomizationsForAllAspects(void) 03433 { 03434 customPathData.clear(); 03435 } 03436 03437 void CGuiConnection::RemoveDeletedPathCustomizations(const std::vector<CustomPathData>& customPathDat) 03438 { 03439 std::vector<CustomPathData>::const_iterator ii = customPathDat.begin(); 03440 while (ii != customPathDat.end()) { 03441 std::vector<CustomPathData>::iterator jj = customPathData.begin(); 03442 while (jj != customPathData.end()) { 03443 if ((*ii).GetAspect() == (*jj).GetAspect() && 03444 (*ii).GetEdgeIndex() == (*jj).GetEdgeIndex() && 03445 (*ii).GetType() == (*jj).GetType() && 03446 ((*ii).GetType() == CustomPointCustomization || (*ii).GetEdgeCount() == (*jj).GetEdgeCount())) 03447 { 03448 jj = customPathData.erase(jj); 03449 } else { 03450 ++jj; 03451 } 03452 } 03453 ++ii; 03454 } 03455 } 03456 03457 void CGuiConnection::SnapCoordIfApplicable(CustomPathData* coordToSet, const CPoint& last, const CPoint& pt) 03458 { 03459 double radEps = 4.0 / 360.0 * 2 * M_PI; 03460 RoutingDirection dir = GetDir(last - pt); 03461 if (dir == Dir_Skew) { 03462 bool modify = false; 03463 RoutingDirection dirToGo = GetSkewDir(last - pt); 03464 if ((dirToGo == Dir_Left || dirToGo == Dir_Right) && last.y != pt.y) { 03465 if (abs(last.y - pt.y) <= 3) { 03466 modify = true; 03467 } else if (last.x != pt.x) { 03468 double alpha = atan2(-((double)pt.y - last.y), (double)pt.x - last.x); 03469 TRACE(_T("Horizontal alpha %lf %lf\n"), alpha / M_PI * 180.0, alpha); 03470 if (abs(alpha + M_PI) < radEps || abs(alpha) < radEps || abs(alpha - M_PI) < radEps) 03471 modify = true; 03472 } 03473 if (modify) 03474 coordToSet->SetY(last.y); 03475 } else if (last.x != pt.x) { // dirToGo == Dir_Top || dirToGo == Dir_Bottom (also can be Dir_Skew but this would be error and no_dir in case of singularity) 03476 if (abs(last.x - pt.x) <= 3) { 03477 modify = true; 03478 } else if (last.y != pt.y) { 03479 double alpha = atan2((double)pt.x - last.x, -((double)pt.y - last.y)); 03480 TRACE(_T("Vertical alpha %lf %lf\n"), alpha / M_PI * 180.0, alpha); 03481 if (abs(alpha + M_PI) < radEps || abs(alpha) < radEps || abs(alpha - M_PI) < radEps) 03482 modify = true; 03483 } 03484 if (modify) 03485 coordToSet->SetX(last.x); 03486 } 03487 } 03488 } 03489 03490 bool CGuiConnection::VerticalAndHorizontalSnappingOfConnectionLineSegments(long asp, int edgeIndex) 03491 { 03492 if (IsAutoRouted() && customPathData.size() < 1) 03493 return false; 03494 03495 CPointList points; 03496 GetPointList(points); 03497 03498 int i = 0; 03499 CustomPathData* lastData = NULL; 03500 for (std::vector<CustomPathData>::iterator ii = customPathData.begin(); ii != customPathData.end(); ++ii) { 03501 ASSERT((*ii).GetVersion() == CONNECTIONCUSTOMIZATIONDATAVERSION); 03502 if ((*ii).GetAspect() == asp) { 03503 if ((*ii).GetType() == CustomPointCustomization) { 03504 CPoint pt((*ii).GetX(), (*ii).GetY()); 03505 CPoint last; 03506 if (lastData != NULL) { 03507 last = CPoint(lastData->GetX(), lastData->GetY()); 03508 } else { 03509 last = points.GetHead(); 03510 } 03511 if (edgeIndex == -1 || i == edgeIndex || i == edgeIndex + 1) // Apply snapping only to the point neighbour edges 03512 SnapCoordIfApplicable(&(*ii), last, pt); 03513 lastData = &(*ii); 03514 i++; 03515 } 03516 } 03517 } 03518 // see the very last connection line segment 03519 if (lastData != NULL && (edgeIndex == -1 || i == edgeIndex || i == edgeIndex + 1)) { 03520 CPoint pt(lastData->GetX(), lastData->GetY()); 03521 CPoint last = points.GetTail(); 03522 SnapCoordIfApplicable(lastData, last, pt); 03523 } 03524 03525 return false; 03526 } 03527 03528 bool CGuiConnection::IsAutoRouted(void) const 03529 { 03530 if (view->needsConnConversion && connRegAutoRouteNotSet) 03531 return true; 03532 03533 return isAutoRouted; 03534 } 03535 03536 void CGuiConnection::SetAutoRouted(bool autoRouteState) 03537 { 03538 isAutoRouted = autoRouteState; 03539 } 03540 03541 bool CGuiConnection::NeedsRouterPathConversion(bool expectedAutoRouterState) 03542 { 03543 TRACE(_T("NeedsRouterPathConversion %d %d %d\n"), connRegAutoRouteNotSet, isAutoRouted, 03544 !HasPathCustomizationForTypeAndCurrentAspect(CustomPointCustomization)); 03545 return (connRegAutoRouteNotSet && isAutoRouted == expectedAutoRouterState && 03546 !HasPathCustomizationForTypeAndCurrentAspect(CustomPointCustomization)); 03547 } 03548 03549 void CGuiConnection::ConvertAutoRoutedPathToCustom(long asp, bool handleTransaction, bool expectedAutoRouterState) 03550 { 03551 if (NeedsRouterPathConversion(expectedAutoRouterState)) { 03552 CPointList points; 03553 GetPointList(points); 03554 int numPoints = points.GetSize(); 03555 03556 bool wasThereDataToWrite = false; 03557 if (numPoints > 2) { 03558 POSITION pos = points.GetHeadPosition(); 03559 int i = 0; 03560 while (pos) { 03561 CPoint pt = points.GetNext(pos); 03562 if (i > 0 && i < numPoints - 1) { // do not include the start and end point 03563 CustomPathData pathData; 03564 FillOutCustomPathData(pathData, CustomPointCustomization, asp, pt.x, pt.y, i - 1, numPoints - 1, true); 03565 wasThereDataToWrite = true; 03566 UpdateCustomPathData(pathData); 03567 } 03568 i++; 03569 } 03570 } 03571 03572 if (wasThereDataToWrite) 03573 WriteCustomPathData(handleTransaction); 03574 } 03575 } 03576 03577 bool CGuiConnection::ReadAutoRouteState(void) 03578 { 03579 CString autoRoutingStateStr; 03580 03581 // The parent model's setting overrides the global (theApp.useAutoRouting) settings 03582 bool connRegAutoRoute = view->isModelAutoRouted; 03583 // The connection setting overrides the global or model settings 03584 if (GetPreference(autoRoutingStateStr, CONNECTIONAUTOROUTING)) { 03585 if (autoRoutingStateStr == _T("false")) 03586 connRegAutoRoute = false; 03587 else 03588 connRegAutoRoute = true; 03589 connRegAutoRouteNotSet = false; 03590 } else { 03591 connRegAutoRouteNotSet = true; 03592 } 03593 return connRegAutoRoute; 03594 } 03595 03596 void CGuiConnection::WriteAutoRouteState(bool handleTransaction) 03597 { 03598 VERIFY(mgaFco); 03599 CComBSTR pathBstr = CONNECTIONAUTOROUTING; 03600 CString valStr = isAutoRouted ? _T("true") : _T("false"); 03601 CComBSTR bstrVal; 03602 CopyTo(valStr, bstrVal); 03603 if (handleTransaction) 03604 view->BeginTransaction(); 03605 COMTHROW(mgaFco->put_RegistryValue(pathBstr, bstrVal)); 03606 if (handleTransaction) 03607 view->CommitTransaction(); 03608 } 03609 03610 CGuiConnectionLabelSet& CGuiConnection::GetLabelSet(void) 03611 { 03612 return labelset; 03613 } 03614 03616 // Static methods of CGuiConnection 03618 03620 // Virtual methods of CGuiConnection 03622 03623 03624