GME
13
|
00001 // AggregateTreeCtrl.cpp: implementation of the CAggregateTreeCtrl class. 00002 // 00004 00005 #include "stdafx.h" 00006 #include "gmeactivebrowser.h" 00007 #include "AggregateTreeCtrl.h" 00008 #include "ActiveBrowserPropertyPage.h" 00009 #include "..\gme\GMEOLEData.h" 00010 00011 #include <GdiPlus.h> 00012 #pragma comment(lib, "gdiplus.lib") 00013 #include "..\..\SDK\DecoratorLib\PathUtil.h" 00014 00015 #ifdef _DEBUG 00016 #undef THIS_FILE 00017 static char THIS_FILE[]=__FILE__; 00018 #define new DEBUG_NEW 00019 #endif 00020 00021 00023 // Construction/Destruction 00025 00026 CAggregateTreeCtrl::CAggregateTreeCtrl() 00027 { 00028 00029 m_bIsStateStored=FALSE; 00030 00031 } 00032 00033 CAggregateTreeCtrl::~CAggregateTreeCtrl() 00034 { 00035 00036 } 00037 00038 HTREEITEM CAggregateTreeCtrl::InsertItem(HTREEITEM hParent, CString strObjectName, LPUNKNOWN pUnknown, objtype_enum otObjectType, bool update) 00039 { 00040 if (update) 00041 { 00042 MGATREECTRL_LOGEVENT("CAggregateTreeCtrl::InsertItemUpdate "+strObjectName+"\r\n"); 00043 00044 HTREEITEM hTreeItem; 00045 if(m_MgaMap.LookupTreeItem(pUnknown,hTreeItem)) 00046 { 00047 return hTreeItem; 00048 } 00049 } 00050 else 00051 { 00052 MGATREECTRL_LOGEVENT("CAggregateTreeCtrl::InsertItem "+strObjectName+"\r\n"); 00053 00054 if (m_MgaMap.bIsInMap(pUnknown)) // Should not happen 00055 { 00056 TRACE(" Duplicate element found inserting a new element into the aggregation tree map.\n"); 00057 #ifdef _DEBUG 00058 m_MgaMap.Dump(afxDump); 00059 ASSERT(FALSE); 00060 #endif 00061 00062 return NULL; 00063 } 00064 } 00065 00066 00067 TVINSERTSTRUCT tvInsert; 00068 tvInsert.hParent = hParent; 00069 tvInsert.hInsertAfter = NULL; // FIXME: does this mean we're doing insertion sort? 00070 tvInsert.item.pszText = strObjectName.GetBuffer(0); 00071 00072 tvInsert.item.state=0; 00073 tvInsert.item.stateMask=0; 00074 tvInsert.item.lParam=NULL; 00075 00076 CAggregatePropertyPage* pParent=(CAggregatePropertyPage*)GetParent(); 00077 00078 int sourceControlImageOffset = 0; 00079 int sourceControlLatentState = 0; 00080 00081 if(pParent->m_Options.m_bIsDynamicLoading) 00082 { 00083 tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE|TVIF_CHILDREN; 00084 if(otObjectType==OBJTYPE_FOLDER || otObjectType==OBJTYPE_MODEL) 00085 { 00086 CComQIPtr<IMgaObject> ccpMgaObject(pUnknown); 00087 tvInsert.item.cChildren=pParent->reqHasDisplayedChild(ccpMgaObject); 00088 //sourceControlImageOffset = pParent->GetSourceControlStateOffset(ccpMgaObject, &sourceControlLatentState); 00089 } 00090 else 00091 { 00092 tvInsert.item.cChildren=0; 00093 } 00094 sourceControlImageOffset = pParent->GetSourceControlStateOffset(CComQIPtr<IMgaObject>( pUnknown), &sourceControlLatentState); 00095 } 00096 else 00097 { 00098 tvInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; 00099 } 00100 00101 if(hParent==NULL) // Root folder 00102 { 00103 00104 tvInsert.item.iImage=0+sourceControlImageOffset; 00105 tvInsert.item.iSelectedImage=0+sourceControlImageOffset; 00106 } 00107 else 00108 { 00109 tvInsert.item.iImage=(int)otObjectType+sourceControlImageOffset; 00110 tvInsert.item.iSelectedImage=(int)otObjectType+sourceControlImageOffset; 00111 } 00112 00113 if(otObjectType==OBJTYPE_FOLDER) 00114 { 00115 bool has_dep; 00116 if(IsLibrary(pUnknown, &has_dep)) 00117 { 00118 tvInsert.item.iImage=10 + sourceControlImageOffset; 00119 tvInsert.item.iSelectedImage=10 + sourceControlImageOffset; 00120 if( has_dep) 00121 { 00122 tvInsert.item.iImage=54; 00123 tvInsert.item.iSelectedImage=54; 00124 } 00125 } 00126 00127 00128 } 00129 00130 CComPtr<IMgaObject> ccpObject; 00131 QueryInterface(pUnknown, &ccpObject); 00132 GetCustomTreeIcon(ccpObject, tvInsert.item); 00133 00134 // Inserting item into the tree control 00135 HTREEITEM hItem = CTreeCtrl::InsertItem(&tvInsert); 00136 strObjectName.ReleaseBuffer(); 00137 00138 // tvInsert.item.iImage = 0; 00139 SetItemData(hItem,(DWORD)hItem); 00140 00141 CAggregateMgaObjectProxy ObjectProxy(pUnknown, otObjectType); 00142 CAggregateMgaObjectProxy& insertedProxy = m_MgaMap.AddEntry(hItem, ObjectProxy); 00143 00144 SetItemProperties(hItem, sourceControlLatentState, &insertedProxy); 00145 00146 return hItem; 00147 00148 } 00149 00150 00151 HTREEITEM CAggregateTreeCtrl::InsertItemUpdate(HTREEITEM hParent, CString strObjectName, LPUNKNOWN pUnknown, objtype_enum otObjectType) 00152 { 00153 return InsertItem(hParent, strObjectName, pUnknown, otObjectType, true); 00154 } 00155 00156 00157 void CAggregateTreeCtrl::MaintainRegistry() 00158 { 00159 BYTE nMaxStored=4; 00160 00161 HKEY hKey; // handle to key to enumerate 00162 DWORD dwIndex=0; // subkey index 00163 TCHAR szName[255]; // subkey name 00164 DWORD lName=254; // size of subkey buffer 00165 TCHAR szClass[255]; // class string buffer 00166 DWORD lClass=254; // size of class string buffer 00167 FILETIME ftLastWriteTime; // last write time 00168 00169 FILETIME ftOldestWriteTime; // oldest write time 00170 CString strOldestName; // Name of the oldest key 00171 00172 00173 // Initializing filetime with the current system time 00174 SYSTEMTIME stSystemTime; 00175 GetSystemTime(&stSystemTime); // gets current time 00176 // converts to file time format 00177 SystemTimeToFileTime(&stSystemTime, &ftOldestWriteTime); 00178 00179 // Getting the key of Tree Data 00180 hKey=AfxGetApp()->GetSectionKey(_T("TreeData")); 00181 00182 for(dwIndex=0; 00183 ERROR_NO_MORE_ITEMS!= 00184 RegEnumKeyEx(hKey,dwIndex,szName,&lName,NULL,szClass,&lClass,&ftLastWriteTime); 00185 dwIndex++,lName=254,lClass=254 00186 ) 00187 { 00188 // If the current is earlier 00189 if(::CompareFileTime(&ftLastWriteTime,&ftOldestWriteTime)==-1) 00190 { 00191 ftOldestWriteTime=ftLastWriteTime; 00192 strOldestName=szName; 00193 } 00194 } 00195 00196 if(dwIndex>nMaxStored) 00197 { 00198 // Deleting the oldest key 00199 ::RegDeleteKey(HKEY_CURRENT_USER,CString("Software\\")+ 00200 AfxGetApp()->m_pszRegistryKey+ 00201 AfxGetApp()->m_pszProfileName+ 00202 "\\TreeData\\"+strOldestName); 00203 } 00204 00205 ::RegCloseKey(hKey); 00206 } 00207 00208 00209 void CAggregateTreeCtrl::LoadItemStateFromRegistry(CString& strProjectName, HTREEITEM hItem) 00210 { 00211 00212 // Searching hte map for the Mga pointer 00213 LPUNKNOWN pUnknown; 00214 if(m_MgaMap.LookupObjectUnknown(hItem,pUnknown)) 00215 { 00216 CComQIPtr<IMgaObject>ccpMgaObject(pUnknown); 00217 if(ccpMgaObject) // succesful conversion 00218 { 00219 CComBSTR IDObj; 00220 COMTHROW(ccpMgaObject->get_ID(&IDObj)); 00221 00222 // Get Object id and item state in the registry 00223 CString strID(IDObj); 00224 UINT nItemState=AfxGetApp()->GetProfileInt(CString("TreeData\\")+strProjectName,strID,0xffffffff); 00225 00226 00227 if(nItemState!=0xffffffff) 00228 { 00229 __super::SetItemState(hItem,nItemState); 00230 } 00231 00232 } 00233 } 00234 } 00235 00236 00237 void CAggregateTreeCtrl::LoadTreeStateFromRegistry(CString& strProjectName) 00238 { 00239 00240 // If the key does not exist return 00241 HKEY hKey; 00242 if(ERROR_SUCCESS!=::RegOpenKeyEx(HKEY_CURRENT_USER, 00243 CString("Software\\")+ 00244 AfxGetApp()->m_pszRegistryKey+ 00245 "\\" + 00246 AfxGetApp()->m_pszProfileName+ 00247 "\\TreeData\\"+ 00248 strProjectName, 00249 0,KEY_ALL_ACCESS,&hKey)) 00250 { 00251 return; 00252 } 00253 else 00254 { 00255 ::RegCloseKey(hKey); 00256 } 00257 00258 00259 00260 // Traverse all items in tree control 00261 HTREEITEM hItem= GetRootItem(); 00262 00263 while ( hItem ) 00264 { 00265 /* Getting the items to the registry */ 00266 LoadItemStateFromRegistry(strProjectName,hItem); 00267 00268 // Get first child node 00269 HTREEITEM hNextItem = GetChildItem( hItem ); 00270 00271 if ( !hNextItem ) 00272 { 00273 // Get next sibling child 00274 hNextItem = GetNextSiblingItem( hItem ); 00275 00276 if ( !hNextItem ) 00277 { 00278 HTREEITEM hParentItem=hItem; 00279 while ( !hNextItem && hParentItem ) 00280 { 00281 // No more children: Get next sibling to parent 00282 hParentItem = GetParentItem( hParentItem ); 00283 hNextItem = GetNextSiblingItem( hParentItem ); 00284 } 00285 } 00286 } 00287 00288 hItem = hNextItem; 00289 } 00290 00291 // Deleting the key 00292 ::RegDeleteKey(HKEY_CURRENT_USER,CString("Software\\")+AfxGetApp()->m_pszRegistryKey+AfxGetApp()->m_pszProfileName+ 00293 "\\TreeData\\"+strProjectName); 00294 00295 return; 00296 00297 } 00298 00299 00300 00301 void CAggregateTreeCtrl::SaveTreeStateToRegistry(CString& strProjectName) 00302 { 00303 // Traverse all items in tree control 00304 HTREEITEM hItem= GetRootItem(); 00305 00306 while ( hItem ) 00307 { 00308 /* Saving the items to the registry */ 00309 // Getting item state 00310 UINT nItemState=CTreeCtrlEx::GetItemState(hItem,0xffffffff); 00311 nItemState = nItemState & ~TVIS_BOLD; 00312 00313 // Searching the map for the Mga pointer 00314 LPUNKNOWN pUnknown; 00315 if(m_MgaMap.LookupObjectUnknown(hItem,pUnknown)) 00316 { 00317 CComQIPtr<IMgaObject>ccpMgaObject(pUnknown); 00318 if(ccpMgaObject) // succesful conversion 00319 { 00320 CComBSTR IDObj; 00321 COMTHROW(ccpMgaObject->get_ID(&IDObj)); 00322 00323 // Put Object id and item state in the registry 00324 CString strID(IDObj); 00325 00326 AfxGetApp()->WriteProfileInt(CString("TreeData\\")+strProjectName,strID,nItemState); 00327 } 00328 } 00329 00330 // Get first child node 00331 HTREEITEM hNextItem = GetChildItem( hItem ); 00332 00333 if ( !hNextItem ) 00334 { 00335 // Get next sibling child 00336 hNextItem = GetNextSiblingItem( hItem ); 00337 00338 if ( !hNextItem ) 00339 { 00340 HTREEITEM hParentItem=hItem; 00341 while ( !hNextItem && hParentItem ) 00342 { 00343 // No more children: Get next sibling to parent 00344 hParentItem = GetParentItem( hParentItem ); 00345 hNextItem = GetNextSiblingItem( hParentItem ); 00346 } 00347 } 00348 } 00349 00350 hItem = hNextItem; 00351 } 00352 00353 // If there is too many project trees stored in the registry 00354 // we delete the oldest one 00355 MaintainRegistry(); 00356 return; 00357 00358 } 00359 00360 00361 void CAggregateTreeCtrl::StoreState() 00362 { 00363 00364 m_StateBuffer.RemoveAll(); 00365 00366 // Traverse all items in tree control 00367 HTREEITEM hItem= GetRootItem(); 00368 00369 while ( hItem ) 00370 { 00371 /* Saving the items to the state buffer */ 00372 // Getting item state 00373 UINT nItemState=CTreeCtrlEx::GetItemState(hItem,0x000000ff); 00374 CString strItemState; 00375 strItemState.Format(_T("%ul"),nItemState); 00376 00377 // Searching the map for the Mga pointer 00378 LPUNKNOWN pUnknown; 00379 if(m_MgaMap.LookupObjectUnknown(hItem,pUnknown)) 00380 { 00381 CComQIPtr<IMgaObject>ccpMgaObject(pUnknown); 00382 if(ccpMgaObject) // succesful conversion 00383 { 00384 CComBSTR IDObj; 00385 COMTHROW(ccpMgaObject->get_ID(&IDObj)); 00386 00387 // Put Object id and item state in the buffer 00388 CString strID(IDObj); 00389 m_StateBuffer.SetAt(strID,strItemState); 00390 00391 } 00392 } 00393 00394 // Get first child node 00395 HTREEITEM hNextItem = GetChildItem( hItem ); 00396 00397 if ( !hNextItem ) 00398 { 00399 // Get next sibling child 00400 hNextItem = GetNextSiblingItem( hItem ); 00401 00402 if ( !hNextItem ) 00403 { 00404 HTREEITEM hParentItem=hItem; 00405 while ( !hNextItem && hParentItem ) 00406 { 00407 // No more children: Get next sibling to parent 00408 hParentItem = GetParentItem( hParentItem ); 00409 hNextItem = GetNextSiblingItem( hParentItem ); 00410 } 00411 } 00412 } 00413 00414 hItem = hNextItem; 00415 } 00416 00417 m_bIsStateStored=TRUE; 00418 return; 00419 00420 } 00421 00422 00423 00424 void CAggregateTreeCtrl::RestoreState() 00425 { 00426 if(!m_bIsStateStored)return; 00427 00428 // Traverse all items in tree control 00429 HTREEITEM hItem= GetRootItem(); 00430 00431 while ( hItem ) 00432 { 00433 /* Getting the item from the map */ 00434 00435 // Searching the map for the Mga pointer 00436 LPUNKNOWN pUnknown; 00437 if(m_MgaMap.LookupObjectUnknown(hItem,pUnknown)) 00438 { 00439 CComQIPtr<IMgaObject>ccpMgaObject(pUnknown); 00440 if(ccpMgaObject) // succesful conversion 00441 { 00442 CComBSTR IDObj; 00443 COMTHROW(ccpMgaObject->get_ID(&IDObj)); 00444 00445 // Get Object id and item state from the map 00446 CString strID(IDObj); 00447 CString strItemState; 00448 if(m_StateBuffer.Lookup(strID,strItemState)) 00449 { 00450 TCHAR* pszEndPtr=NULL; 00451 UINT nItemState=_tcstoul(strItemState,&pszEndPtr,10); 00452 __super::SetItemState(hItem,nItemState); 00453 } 00454 } 00455 } 00456 00457 // Get first child node 00458 HTREEITEM hNextItem = GetChildItem( hItem ); 00459 00460 if ( !hNextItem ) 00461 { 00462 // Get next sibling child 00463 hNextItem = GetNextSiblingItem( hItem ); 00464 00465 if ( !hNextItem ) 00466 { 00467 HTREEITEM hParentItem=hItem; 00468 while ( !hNextItem && hParentItem ) 00469 { 00470 // No more children: Get next sibling to parent 00471 hParentItem = GetParentItem( hParentItem ); 00472 hNextItem = GetNextSiblingItem( hParentItem ); 00473 } 00474 } 00475 } 00476 00477 hItem = hNextItem; 00478 } 00479 00480 m_StateBuffer.RemoveAll(); 00481 m_bIsStateStored=FALSE; 00482 return; 00483 } 00484 00485 00486 00487 00488 00489 int CAggregateTreeCtrl::ItemCompareProc(LPARAM lParamItem1, LPARAM lParamItem2, LPARAM lParamSort) 00490 { 00491 00492 00493 CAggregateTreeCtrl* pTreeCtrl = (CAggregateTreeCtrl*) lParamSort; 00494 00495 HTREEITEM hItem1=(HTREEITEM) lParamItem1; 00496 HTREEITEM hItem2=(HTREEITEM) lParamItem2; 00497 00498 00499 CAggregatePropertyPage* pParent=(CAggregatePropertyPage*)pTreeCtrl->GetParent(); 00500 00501 switch(pParent->m_Options.m_soSortOptions) 00502 { 00503 case SORT_BYNAME: 00504 { 00505 CString strItem1 = pTreeCtrl->GetItemText(hItem1); 00506 CString strItem2 = pTreeCtrl->GetItemText(hItem2); 00507 return -_tcscmp(strItem2, strItem1); 00508 }break; 00509 case SORT_BYTYPE: 00510 { 00511 CAggregateMgaObjectProxy MgaObjectProxyItem1; 00512 CAggregateMgaObjectProxy MgaObjectProxyItem2; 00513 if( 00514 pTreeCtrl->m_MgaMap.LookupObjectProxy(hItem1,MgaObjectProxyItem1) && 00515 pTreeCtrl->m_MgaMap.LookupObjectProxy(hItem2,MgaObjectProxyItem2)) 00516 { 00517 // Same Type - Sort By Name 00518 if(MgaObjectProxyItem1.m_TypeInfo==MgaObjectProxyItem2.m_TypeInfo) 00519 { 00520 CString strItem1 = pTreeCtrl->GetItemText(hItem1); 00521 CString strItem2 = pTreeCtrl->GetItemText(hItem2); 00522 return -_tcscmp(strItem2, strItem1); 00523 00524 } 00525 00526 // Folder has a high priority 00527 if(MgaObjectProxyItem1.m_TypeInfo==OBJTYPE_FOLDER) 00528 { 00529 return -1; 00530 } 00531 00532 if(MgaObjectProxyItem2.m_TypeInfo==OBJTYPE_FOLDER) 00533 { 00534 return 1; 00535 } 00536 00537 return MgaObjectProxyItem1.m_TypeInfo-MgaObjectProxyItem2.m_TypeInfo; 00538 } 00539 else 00540 { 00541 // For dummy elements that are not in the map it does not matter 00542 return 0; 00543 } 00544 00545 }break; 00546 case SORT_BYCREATION: 00547 { 00548 00549 CAggregateMgaObjectProxy MgaObjectProxyItem1; 00550 CAggregateMgaObjectProxy MgaObjectProxyItem2; 00551 00552 if( 00553 pTreeCtrl->m_MgaMap.LookupObjectProxy(hItem1,MgaObjectProxyItem1) && 00554 pTreeCtrl->m_MgaMap.LookupObjectProxy(hItem2,MgaObjectProxyItem2)) 00555 { 00556 CComQIPtr<IMgaObject>ccpItem1(MgaObjectProxyItem1.m_pMgaObject); 00557 CComQIPtr<IMgaObject>ccpItem2(MgaObjectProxyItem2.m_pMgaObject); 00558 00559 if(ccpItem1 &&ccpItem2) 00560 { 00561 // Query the RelativeID 00562 long lRelID1,lRelID2; 00563 COMTHROW(ccpItem1->get_RelID(&lRelID1)); 00564 COMTHROW(ccpItem2->get_RelID(&lRelID2)); 00565 00566 return lRelID1-lRelID2; 00567 } 00568 else // Unsuccessful query of the objects 00569 { 00570 return 0; 00571 } 00572 00573 } 00574 else 00575 { 00576 // For dummy elements that are not in the map it does not matter 00577 return 0; 00578 } 00579 00580 }break; 00581 } 00582 return 0; 00583 } 00584 00585 void CAggregateTreeCtrl::SortItems(HTREEITEM hItem) 00586 { 00587 // Sort the tree control's items using 00588 // custom callback procedure. 00589 00590 // Traverse all items in tree control 00591 00592 if(hItem==NULL) 00593 { 00594 hItem= GetRootItem(); 00595 } 00596 00597 while ( hItem ) 00598 { 00599 TVSORTCB tvs; 00600 tvs.hParent = hItem; 00601 tvs.lpfnCompare = (PFNTVCOMPARE)ItemCompareProc; 00602 tvs.lParam = (LPARAM) this; 00603 00604 CTreeCtrl::SortChildrenCB(&tvs); 00605 00606 00607 // Get first child node 00608 HTREEITEM hNextItem = GetChildItem( hItem ); 00609 00610 if ( !hNextItem ) 00611 { 00612 // Get next sibling child 00613 hNextItem = GetNextSiblingItem( hItem ); 00614 00615 if ( !hNextItem ) 00616 { 00617 HTREEITEM hParentItem=hItem; 00618 while ( !hNextItem && hParentItem ) 00619 { 00620 // No more children: Get next sibling to parent 00621 hParentItem = GetParentItem( hParentItem ); 00622 hNextItem = GetNextSiblingItem( hParentItem ); 00623 } 00624 } 00625 } 00626 00627 hItem = hNextItem; 00628 } 00629 00630 } 00631 00632 00633 void CAggregateTreeCtrl::MakeSureGUIDIsUniqueForSmartCopy( CComPtr<IMgaFCO>& fco) 00634 { 00635 // this method prevents cloned objects having the same guid 00636 // as their original ones 00637 CComBSTR bstr; 00638 COMTHROW( fco->get_RegistryValue( CComBSTR( "guid"), &bstr)); 00639 if( bstr == 0 || bstr == "") return; // no guid present, no need to replace it 00640 00641 GUID t_guid = GUID_NULL; 00642 ::CoCreateGuid(&t_guid); 00643 00644 if (t_guid != GUID_NULL) 00645 { 00646 CString str_guid; 00647 str_guid.Format(_T("{%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}"), 00648 t_guid.Data1, t_guid.Data2, t_guid.Data3, 00649 t_guid.Data4[0], t_guid.Data4[1], t_guid.Data4[2], t_guid.Data4[3], 00650 t_guid.Data4[4], t_guid.Data4[5], t_guid.Data4[6], t_guid.Data4[7]); 00651 00652 // thus replace the old guid with a new one 00653 COMTHROW( fco->put_RegistryValue( CComBSTR( "guid"), CComBSTR(str_guid))); 00654 } 00655 00656 // store the previous guid in prev subnode 00657 COMTHROW( fco->put_RegistryValue( CComBSTR( "guid/prev"), bstr)); 00658 } 00659 00660 00661 00662 BOOL CAggregateTreeCtrl::IsRelevantDropTarget(CPoint point,CImageList* pDragImageList) 00663 { 00664 UINT uFlags; 00665 HTREEITEM hItem = HitTest(point, &uFlags); 00666 00667 if ((hItem != NULL) && (TVHT_ONITEM & uFlags)) 00668 { 00669 CAggregateMgaObjectProxy ObjectProxy; 00670 if(m_MgaMap.LookupObjectProxy(hItem,ObjectProxy)) // If it is in the map 00671 { 00672 if(ObjectProxy.m_TypeInfo==OBJTYPE_FOLDER || ObjectProxy.m_TypeInfo==OBJTYPE_MODEL) 00673 { 00674 return TRUE; 00675 } 00676 } 00677 } 00678 return FALSE; 00679 } 00680 00681 BOOL CAggregateTreeCtrl::DoDrop(eDragOperation doDragOp, COleDataObject *pDataObject, CPoint point) 00682 { 00683 MGATREECTRL_LOGEVENT("CAggregateTreeCtrl::DoDrop\r\n"); 00684 CString _t = ""; 00685 if( doDragOp == DRAGOP_REFERENCE) 00686 _t = " REFERENCE\r\n"; 00687 if( doDragOp == DRAGOP_SUBTYPE) 00688 _t = " DERIVE\r\n"; 00689 if( doDragOp == DRAGOP_INSTANCE) 00690 _t = " INSTANCE\r\n"; 00691 if( doDragOp == DRAGOP_COPY) 00692 _t = " COPY\r\n"; 00693 if( doDragOp == DRAGOP_MOVE) 00694 _t = " MOVE\r\n"; 00695 if( doDragOp == DRAGOP_CLOSURE) 00696 _t = " CLOSURE COPY\r\n"; 00697 if( doDragOp == DRAGOP_CLOSURE_MERGE) 00698 _t = " COPY MERGE\r\n"; 00699 MGATREECTRL_LOGEVENT( _t); 00700 00701 HTREEITEM hItem; 00702 if (point.x == 0 && point.y == 0) { 00703 hItem = GetSelectedItem(); 00704 } else { 00705 hItem = HitTest(point); 00706 } 00707 00708 CAggregateMgaObjectProxy MgaObjectProxy; 00709 00710 if(hItem==NULL || !m_MgaMap.LookupObjectProxy(hItem,MgaObjectProxy)) 00711 { 00712 ASSERT(FALSE); 00713 return FALSE; 00714 } 00715 00716 00717 CGMEActiveBrowserApp* pApp=(CGMEActiveBrowserApp*)AfxGetApp(); 00718 CMgaContext* pMgaContext=&pApp->m_CurrentProject.m_MgaContext; 00719 00720 // Setting up the drop target 00721 CComQIPtr<IMgaObject> ccpTargetObject(MgaObjectProxy.m_pMgaObject); 00722 if(!ccpTargetObject) 00723 { 00724 MessageBox(_T("Invalid target type."),_T("Error"),MB_OK|MB_ICONERROR); 00725 return FALSE; 00726 } 00727 00728 // PETER: Checking clipboard, paste XML clipboard. 00729 if (!CGMEDataSource::IsGmeNativeDataAvailable(pDataObject,pMgaContext->m_ccpProject)) 00730 { 00731 if (!CGMEDataSource::IsXMLDataAvailable(pDataObject)) { 00732 MessageBox(_T("Unknown clipboard format."),_T("Error"),MB_OK|MB_ICONERROR); 00733 return FALSE; 00734 } 00735 if (doDragOp != DRAGOP_COPY && doDragOp != DRAGOP_CLOSURE && doDragOp != DRAGOP_CLOSURE_MERGE) { 00736 MessageBox(_T("Only copy operation is supported on GME XML clipboard format."),_T("Error"),MB_OK|MB_ICONERROR); 00737 return FALSE; 00738 } 00739 00740 try { 00741 bool res = CGMEDataSource::ParseXMLData(pDataObject, ccpTargetObject, doDragOp == DRAGOP_CLOSURE_MERGE); 00742 return res?TRUE:FALSE; 00743 } catch (hresult_exception& e) { 00744 return FALSE; 00745 } 00746 } 00747 // PETER: end 00748 00749 00750 CComPtr<IDataObject> ccpDataObject = pDataObject->GetIDataObject(FALSE); 00751 CComPtr<IMgaDataSource> ccpMgaDataSource; 00752 COMTHROW(ccpDataObject.QueryInterface(&ccpMgaDataSource)); 00753 00754 CComPtr<IUnknown> ccpData; 00755 COMTHROW(ccpMgaDataSource->get_Data( &ccpData)); 00756 00757 CComPtr<IUnknown> ccpFolders; 00758 COMTHROW(ccpMgaDataSource->get_Folders( &ccpFolders)); 00759 00760 CComPtr<IMgaResolver> ccpMgaResolver; 00761 COMTHROW( ccpMgaResolver.CoCreateInstance(L"Mga.MgaResolver") ); 00762 00763 CComQIPtr<IMgaFCOs> ccpDroppedFCOs( ccpData); 00764 CComQIPtr<IMgaFolders> ccpDroppedFolders( ccpFolders); 00765 00766 if (!ccpDroppedFCOs && !ccpDroppedFolders) { 00767 BOOL bRetVal = FALSE; 00768 00769 MSGTRY { 00770 CComQIPtr<IMgaMetaRole> metaRole(ccpData); 00771 if (metaRole) { 00772 CComPtr<IMgaFCO> child; 00773 pMgaContext->BeginTransaction(FALSE); // Read/Write Transaction 00774 if (MgaObjectProxy.m_TypeInfo == OBJTYPE_MODEL) { // If the drop target is a model 00775 CComQIPtr<IMgaModel> ccpTargetModel(MgaObjectProxy.m_pMgaObject); 00776 switch (doDragOp) { 00777 case DRAGOP_MOVE: 00778 case DRAGOP_COPY: 00779 { 00780 COMTHROW(ccpTargetModel->CreateChildObject(metaRole, &child)); 00781 } break; 00782 } // switch 00783 } else if (MgaObjectProxy.m_TypeInfo == OBJTYPE_FOLDER) { // If the drop target is a folder 00784 CComQIPtr<IMgaFolder> ccpTargetFolder(MgaObjectProxy.m_pMgaObject); 00785 switch (doDragOp) { 00786 case DRAGOP_MOVE: 00787 case DRAGOP_COPY: 00788 { 00789 CComPtr<IMgaMetaFCO> metaFCO; 00790 COMTHROW(metaRole->get_Kind(&metaFCO)); 00791 if (metaFCO) 00792 COMTHROW(ccpTargetFolder->CreateRootObject(metaFCO, &child)); 00793 } break; 00794 } // switch 00795 } 00796 if (child) { 00797 CComBSTR nm; 00798 COMTHROW(metaRole->get_DisplayedName(&nm)); 00799 COMTHROW(child->put_Name(nm)); 00800 } 00801 pMgaContext->CommitTransaction (); 00802 } 00803 } MSGCATCH (_T("Error completing PartBrowser drop operation"), pMgaContext->AbortTransaction ();) 00804 00805 return bRetVal; 00806 } 00807 00808 // ccpDroppedFCOs can't be null since every copier creates the Mga.MgaFCOs collection even if no element is added 00809 // ccpDroppedFolders might be null i.e. GMEDoc does not create the Mga.MgaFolders collection 00810 // when an fco is dragged from the GMEView to the ActiveBrowser 00811 00812 BOOL bRetVal=FALSE; 00813 00814 MSGTRY{ 00815 pMgaContext->BeginTransaction(TRANSACTION_NON_NESTED); // Read/Write Transaction 00816 if(MgaObjectProxy.m_TypeInfo==OBJTYPE_FOLDER) // If the drop target is a folder 00817 { 00818 CComQIPtr<IMgaFolder> ccpTargetFolder(MgaObjectProxy.m_pMgaObject); 00819 00820 switch(doDragOp) 00821 { 00822 case DRAGOP_MOVE: 00823 { 00824 CComPtr<IMgaFolders> ccpNewFolders; 00825 CComPtr<IMgaFCOs> ccpNewFCOs; 00826 00827 // first move the selected folders. The order matters 00828 // since the NEWCHILD event must be the last one. 00829 if (ccpDroppedFolders) 00830 ccpTargetFolder->__MoveFolders(ccpDroppedFolders, &ccpNewFolders); 00831 00832 // then move the selected fcos 00833 ccpTargetFolder->__MoveFCOs(ccpDroppedFCOs, &ccpNewFCOs); 00834 00835 // this ensures that the new parent is notified in the right time and place 00836 // a NEWCHILD event is sent to the target folder 00837 COMTHROW( ccpTargetFolder->RefreshParent( ccpTargetFolder)); 00838 00839 bRetVal=TRUE; 00840 }break; 00841 case DRAGOP_COPY: 00842 { 00843 CComPtr<IMgaFolders> ccpNewFolders; 00844 if (ccpDroppedFolders) 00845 ccpTargetFolder->__CopyFolders(ccpDroppedFolders,&ccpNewFolders); 00846 00847 CComPtr<IMgaFCOs> ccpNewFCOs; 00848 ccpTargetFolder->__CopyFCOs(ccpDroppedFCOs,&ccpNewFCOs); 00849 00850 MGACOLL_ITERATE(IMgaFCO, ccpNewFCOs) { // for smart copy related entries 00851 MakeSureGUIDIsUniqueForSmartCopy( CComPtr<IMgaFCO>( MGACOLL_ITER) ); 00852 } MGACOLL_ITERATE_END; 00853 00854 bRetVal=TRUE; 00855 }break; 00856 case DRAGOP_REFERENCE: 00857 { 00859 bRetVal=FALSE; 00860 }break; 00861 case DRAGOP_INSTANCE: 00862 { 00863 MGACOLL_ITERATE(IMgaFCO,ccpDroppedFCOs) 00864 { 00865 CComPtr<IMgaFCO> ccpNewFco; 00866 HRESULT hr; 00867 if( ( hr = ccpTargetFolder->DeriveRootObject(MGACOLL_ITER,VARIANT_TRUE,&ccpNewFco)) != S_OK) { 00868 if( hr == E_MGA_NOT_DERIVABLE) // typical failure code when subtyping/instantiating 00869 { 00870 CComBSTR msg( L"Object '"), nm; 00871 COMTHROW( MGACOLL_ITER->get_Name( &nm)); 00872 COMTHROW(msg.Append( nm)); 00873 COMTHROW(msg.Append( _T("' could not be derived. Some of its ancestors or descendants may be already derived! [Error code E_MGA_NOT_DERIVABLE]"))); 00874 Utils::put2Console( Utils::get_GME( pMgaContext->m_ccpProject), msg, MSG_ERROR); 00875 pMgaContext->AbortTransaction();//COMTHROW( hr); 00876 return FALSE;//break; // although it was inside a MGACOLL_ITERATE, we aborted the trans 00877 } 00878 COMTHROW( hr); // otherwise 00879 break; 00880 } 00881 } 00882 MGACOLL_ITERATE_END; 00883 bRetVal=TRUE; 00884 }break; 00885 case DRAGOP_SUBTYPE: 00886 { 00887 MGACOLL_ITERATE(IMgaFCO,ccpDroppedFCOs) 00888 { 00889 CComPtr<IMgaFCO> ccpNewFco; 00890 HRESULT hr; 00891 if( ( hr = ccpTargetFolder->DeriveRootObject(MGACOLL_ITER,VARIANT_FALSE,&ccpNewFco)) != S_OK) { 00892 //MGATREECTRL_LOGEVENT(" "+fcoName+" cannot be derived.\r\n"); 00893 if( hr == E_MGA_NOT_DERIVABLE) // typical failure code when subtyping/instantiating 00894 { 00895 CComBSTR msg( L"Object '"), nm; 00896 COMTHROW( MGACOLL_ITER->get_Name( &nm)); 00897 COMTHROW(msg.Append( nm)); 00898 COMTHROW(msg.Append( L"' could not be derived. Some of its ancestors or descendants may be already derived! [Error code E_MGA_NOT_DERIVABLE]")); 00899 Utils::put2Console( Utils::get_GME( pMgaContext->m_ccpProject), msg, MSG_ERROR); 00900 pMgaContext->AbortTransaction();//COMTHROW( hr); 00901 return FALSE;//break; // although it was inside a MGACOLL_ITERATE, we aborted the trans 00902 } 00903 COMTHROW( hr); // otherwise 00904 break; 00905 } 00906 } 00907 MGACOLL_ITERATE_END; 00908 00909 bRetVal=TRUE; 00910 }break; 00911 00912 00913 } 00914 } 00915 else if(MgaObjectProxy.m_TypeInfo==OBJTYPE_MODEL) // If the drop target is a model 00916 { 00917 long fol_cnt = 0; 00918 if( ccpDroppedFolders) 00919 { 00920 COMTHROW( ccpDroppedFolders->get_Count( &fol_cnt)); 00921 if ( fol_cnt > 0) 00922 AfxMessageBox(_T("Cannot insert folders into a model")); 00923 } 00924 00925 CComQIPtr<IMgaModel> ccpTargetModel(MgaObjectProxy.m_pMgaObject); 00926 switch(doDragOp) 00927 { 00928 case DRAGOP_MOVE: 00929 { 00930 #if(0) // plain old version 00931 CComPtr<IMgaFCOs> ccpNewFCOs; 00932 00933 CComPtr<IMgaMetaRoles> ccpMetaRoles; 00934 COMTHROW(ccpMetaRoles.CoCreateInstance(OLESTR("Mga.MgaMetaRoles"))); 00935 00936 MGACOLL_ITERATE(IMgaFCO, ccpDroppedFCOs) 00937 { 00938 CComPtr<IMgaFCO> ccpFCO; 00939 COMTHROW(pMgaContext->m_ccpTerritory->OpenFCO(MGACOLL_ITER, &ccpFCO)); 00940 CComPtr<IMgaMetaRole> ccpMetaRole; 00941 COMTHROW(ccpFCO->get_MetaRole(&ccpMetaRole)); 00942 CComPtr<IMgaMetaFCO> ccpKind; 00943 COMTHROW(ccpFCO->get_Meta(&ccpKind)); 00944 CComPtr<IMgaMetaRole> ccpNewRole; 00945 00946 COMTHROW(ccpMgaResolver->get_RoleByMeta(ccpTargetModel,ccpKind,OBJTYPE_NULL,ccpMetaRole,NULL,&ccpNewRole)); 00947 COMTHROW(ccpMetaRoles->Append(ccpNewRole)); 00948 } 00949 MGACOLL_ITERATE_END; 00950 COMTHROW( ccpTargetModel->MoveFCOs(ccpDroppedFCOs,ccpMetaRoles,&ccpNewFCOs) ); 00951 00952 bRetVal = TRUE; 00953 #else // check if the target = source 00954 CComPtr<IMgaFCOs> ccpNewFCOs; 00955 00956 CComPtr<IMgaMetaRoles> ccpMetaRoles; 00957 COMTHROW(ccpMetaRoles.CoCreateInstance(OLESTR("Mga.MgaMetaRoles"))); 00958 00959 long fco_cnt = 0; 00960 COMTHROW( ccpDroppedFCOs->get_Count( &fco_cnt)); 00961 if ( fco_cnt > 0) 00962 { 00963 bool valid = true; 00964 if ( fco_cnt == 1) 00965 { 00966 valid = false; 00967 CComPtr<IMgaFCO> one_fco; 00968 MGACOLL_ITERATE(IMgaFCO, ccpDroppedFCOs) { 00969 one_fco = MGACOLL_ITER; 00970 } MGACOLL_ITERATE_END; 00971 VARIANT_BOOL is_equal; 00972 COMTHROW( one_fco->get_IsEqual( ccpTargetModel, &is_equal)); 00973 00974 if (is_equal == VARIANT_FALSE) // not equal 00975 valid = true; 00976 } 00977 00978 if ( valid) 00979 { 00980 MGACOLL_ITERATE(IMgaFCO, ccpDroppedFCOs) 00981 { 00982 CComPtr<IMgaFCO> ccpFCO; 00983 COMTHROW(pMgaContext->m_ccpTerritory->OpenFCO(MGACOLL_ITER, &ccpFCO)); 00984 CComPtr<IMgaMetaRole> ccpMetaRole; 00985 COMTHROW(ccpFCO->get_MetaRole(&ccpMetaRole)); 00986 CComPtr<IMgaMetaFCO> ccpKind; 00987 COMTHROW(ccpFCO->get_Meta(&ccpKind)); 00988 00989 IMgaMetaRolePtr ccpNewRole = ccpMgaResolver->RoleByMeta[ccpTargetModel,ccpKind,OBJTYPE_NULL,ccpMetaRole,NULL]; 00990 COMTHROW(ccpMetaRoles->Append(ccpNewRole)); 00991 } 00992 MGACOLL_ITERATE_END; 00993 00994 COMTHROW( ccpTargetModel->MoveFCOs(ccpDroppedFCOs,ccpMetaRoles,&ccpNewFCOs) ); 00995 bRetVal = TRUE; 00996 } 00997 else bRetVal = FALSE; 00998 } 00999 else bRetVal=FALSE; //? 01000 #endif 01001 01002 }break; 01003 case DRAGOP_COPY: 01004 { 01005 CComPtr<IMgaFCOs> ccpNewFCOs; 01006 01007 CComPtr<IMgaMetaRoles> ccpMetaRoles; 01008 COMTHROW(ccpMetaRoles.CoCreateInstance(OLESTR("Mga.MgaMetaRoles"))); 01009 01010 MGACOLL_ITERATE(IMgaFCO, ccpDroppedFCOs) 01011 { 01012 CComPtr<IMgaFCO> ccpFCO; 01013 COMTHROW(pMgaContext->m_ccpTerritory->OpenFCO(MGACOLL_ITER, &ccpFCO)); 01014 CComPtr<IMgaMetaRole> ccpMetaRole; 01015 COMTHROW(ccpFCO->get_MetaRole(&ccpMetaRole)); 01016 CComPtr<IMgaMetaFCO> ccpKind; 01017 COMTHROW(ccpFCO->get_Meta(&ccpKind)); 01018 IMgaMetaRolePtr ccpNewRole; 01019 01020 ccpNewRole = ccpMgaResolver->RoleByMeta[ccpTargetModel,ccpKind,OBJTYPE_NULL,ccpMetaRole,NULL]; 01021 COMTHROW(ccpMetaRoles->Append(ccpNewRole)); 01022 } 01023 MGACOLL_ITERATE_END; 01024 COMTHROW( ccpTargetModel->CopyFCOs(ccpDroppedFCOs,ccpMetaRoles,&ccpNewFCOs) ); 01025 01026 MGACOLL_ITERATE(IMgaFCO, ccpNewFCOs) { // for smart copy related entries 01027 MakeSureGUIDIsUniqueForSmartCopy( CComPtr<IMgaFCO>( MGACOLL_ITER) ); 01028 } MGACOLL_ITERATE_END; 01029 01030 bRetVal=TRUE; 01031 01032 }break; 01033 case DRAGOP_REFERENCE: 01034 { 01035 01036 CComBSTR bszSourceName; 01037 01038 MGACOLL_ITERATE(IMgaFCO,ccpDroppedFCOs) 01039 { 01040 //-acquiring a pointer in the active territory for MGACOLL_ITER 01041 CComPtr<IMgaFCO> ccpFCO; 01042 COMTHROW(pMgaContext->m_ccpTerritory->OpenFCO(MGACOLL_ITER, &ccpFCO)); 01043 01044 CComPtr<IMgaConnection> conn; 01045 if(ccpFCO.QueryInterface(&conn) != S_OK) { // skip connections, they cannot be referenced 01046 CComPtr<IMgaMetaRole> ccpNewMetaRole; 01047 COMTHROW( ccpMgaResolver->get_RefRoleByMeta(ccpTargetModel, NULL, ccpFCO, &ccpNewMetaRole) ); 01048 01049 if(ccpNewMetaRole == 0) 01050 { 01051 MGATREECTRL_LOGEVENT(" Cannot create reference.\r\n"); 01052 } 01053 else { 01054 CComPtr<IMgaFCO> ccpNewFCO; 01055 COMTHROW( ccpTargetModel->CreateReference(ccpNewMetaRole,ccpFCO,&ccpNewFCO) ); 01056 ASSERT(ccpNewFCO != NULL); 01057 01058 // Creating name for the new reference: 01059 bszSourceName.Empty(); 01060 COMTHROW( ccpFCO->get_Name(&bszSourceName) ); 01061 /* 01062 // ReferencedName+"Ref" 01063 CString strSourceName(bszSourceName); 01064 strSourceName += "Ref"; 01065 bszSourceName = strSourceName;*/ // commented by zolmol according to DoPasteNative() logic in GMEView.cpp 01066 01067 //Rename 01068 COMTHROW( ccpNewFCO->put_Name(bszSourceName)); 01069 } 01070 } 01071 }MGACOLL_ITERATE_END; 01072 01073 bRetVal=TRUE; 01074 }break; 01075 case DRAGOP_INSTANCE: 01076 case DRAGOP_SUBTYPE: 01077 { 01078 HRESULT hr = S_OK; 01079 bool excep_handled = false; 01080 MGACOLL_ITERATE(IMgaFCO,ccpDroppedFCOs) { 01081 01082 //-acquiring a pointer in the active territory for MGACOLL_ITER 01083 CComPtr<IMgaFCO> ccpFCO; 01084 COMTHROW(pMgaContext->m_ccpTerritory->OpenFCO(MGACOLL_ITER, &ccpFCO)); 01085 01086 CComBSTR bstr; 01087 COMTHROW(ccpFCO->get_Name(&bstr)); 01088 CString fcoName; 01089 CopyTo(bstr,fcoName); 01090 01091 CComPtr<IMgaMetaFCO> ccpMetaFCO; 01092 COMTHROW( ccpFCO->get_Meta(&ccpMetaFCO) ); 01093 ASSERT( ccpMetaFCO != NULL); 01094 01095 // Old role can be NULL 01096 CComPtr<IMgaMetaRole> ccpOldMetaRole; 01097 COMTHROW( ccpFCO->get_MetaRole(&ccpOldMetaRole) ); 01098 01099 CComPtr<IMgaMetaRole> ccpNewMetaRole; 01100 COMTHROW( ccpMgaResolver->get_RoleByMeta(ccpTargetModel, ccpMetaFCO, OBJTYPE_NULL, ccpOldMetaRole, NULL, &ccpNewMetaRole) ); 01101 if(ccpNewMetaRole == 0) 01102 { 01103 MGATREECTRL_LOGEVENT(" Cannot insert object derived from "+fcoName+"\r\n"); 01104 } 01105 else { 01106 CComPtr<IMgaFCO> ccpNewFCO; 01107 VARIANT_BOOL inst = doDragOp == DRAGOP_INSTANCE? VARIANT_TRUE : VARIANT_FALSE; 01108 if((hr = ccpTargetModel->DeriveChildObject(ccpFCO,ccpNewMetaRole, inst ,&ccpNewFCO)) != S_OK) { 01109 MGATREECTRL_LOGEVENT(" "+fcoName+" cannot be derived.\r\n"); 01110 if( hr == E_MGA_NOT_DERIVABLE) // typical failure code when subtyping/instantiating 01111 { 01112 CComBSTR msg( L"Object '"), nm; 01113 COMTHROW( ccpFCO->get_Name( &nm)); 01114 COMTHROW(msg.Append( nm)); 01115 COMTHROW(msg.Append( L"' could not be derived. Some of its ancestors or descendants may be already derived! [Error code E_MGA_NOT_DERIVABLE]")); 01116 Utils::put2Console( Utils::get_GME( pMgaContext->m_ccpProject), msg, MSG_ERROR); 01117 01118 pMgaContext->AbortTransaction();//COMTHROW( hr); 01119 return FALSE;//break; // although it was inside a MGACOLL_ITERATE, we aborted the trans 01120 } 01121 COMTHROW( hr); // otherwise 01122 break; 01123 } 01124 } 01125 01126 } 01127 MGACOLL_ITERATE_END; 01128 bRetVal=TRUE; 01129 }break; 01130 01131 } 01132 } 01133 pMgaContext->CommitTransaction(); 01134 01135 }MSGCATCH(_T("Error completing drop operation"), pMgaContext->AbortTransaction();) 01136 01137 01138 01139 return bRetVal; 01140 } 01141 01142 BOOL CAggregateTreeCtrl::DoDropWithoutChecking(eDragOperation doDragOp, COleDataObject *pDataObject, CPoint point) 01143 { 01144 MGATREECTRL_LOGEVENT("CAggregateTreeCtrl::DoDropWithoutChecking\r\n"); 01145 01146 CGMEActiveBrowserApp* pApp = (CGMEActiveBrowserApp*)AfxGetApp(); 01147 CMgaContext* pMgaContext = &pApp->m_CurrentProject.m_MgaContext; 01148 01149 CComPtr<IMgaComponentEx> constrMgr; 01150 if (pMgaContext) 01151 constrMgr = pMgaContext->FindConstraintManager(); 01152 if (constrMgr) 01153 COMTHROW(constrMgr->Enable(false)); 01154 BOOL res = DoDrop( doDragOp, pDataObject, point); 01155 if (constrMgr) { 01156 COMTHROW(constrMgr->Enable(true)); 01157 // constrMgr.Release(); 01158 } 01159 01160 return res; 01161 } 01162 01163 static void ImageList_AddGdiplusBitmap(HIMAGELIST imageList, Gdiplus::Bitmap& bmp, Gdiplus::Color color=Gdiplus::Color(Gdiplus::Color::White)) 01164 { 01165 using namespace Gdiplus; 01166 RectF bounds; 01167 Unit unit(UnitPixel); 01168 VERIFY(bmp.GetBounds(&bounds, &unit) == Ok); 01169 HBITMAP hBmp; 01170 01171 if (bounds.X == 16 && bounds.Y == 16) 01172 { 01173 VERIFY(bmp.GetHBITMAP(color, &hBmp) == Ok); 01174 } 01175 else 01176 { 01177 Image* thumb = bmp.GetThumbnailImage(16, 16); 01178 Bitmap bmpThumb(16, 16); 01179 Graphics* graphics = Graphics::FromImage(&bmpThumb); 01180 VERIFY(graphics->GetLastStatus() == Ok); 01181 VERIFY(graphics->Clear(color) == Ok); 01182 VERIFY(graphics->DrawImage(thumb, 0, 0, 0, 0, 16, 16, UnitPixel) == Ok); 01183 VERIFY(bmpThumb.GetHBITMAP(color, &hBmp) == Ok); 01184 delete thumb; 01185 delete graphics; 01186 } 01187 01188 ImageList_Add(imageList, hBmp, 0); 01189 DeleteObject(hBmp); 01190 } 01191 01192 void CAggregateTreeCtrl::GetCustomTreeIcon(IMgaObject* ccpMgaObject, TVITEM& tvItem) 01193 { 01194 CGMEActiveBrowserApp* pApp=(CGMEActiveBrowserApp*)AfxGetApp(); 01195 CMgaContext* pMgaContext=&pApp->m_CurrentProject.m_MgaContext; 01196 pMgaContext->BeginTransaction(); 01197 CComPtr<IMgaMetaBase> meta; 01198 COMTHROW(ccpMgaObject->get_MetaBase(&meta)); 01199 _bstr_t treeIcon; 01200 meta->get_RegistryValue(CComBSTR(L"treeIcon"), treeIcon.GetAddress()); 01201 _bstr_t expandedTreeIcon; 01202 meta->get_RegistryValue(CComBSTR(L"expandedTreeIcon"), expandedTreeIcon.GetAddress()); 01203 pMgaContext->CommitTransaction(); 01204 01205 01206 CComPtr<IMgaProject> project; 01207 COMTHROW(ccpMgaObject->get_Project(&project)); 01208 PathUtil pathUtil; 01209 01210 std::unique_ptr<Gdiplus::Bitmap> treeIconBmp(nullptr); 01211 std::unique_ptr<Gdiplus::Bitmap> expandedTreeIconBmp(nullptr); 01212 if (treeIcon.length()) 01213 { 01214 auto it = treeIcons.find(treeIcon); 01215 if (it != treeIcons.end() && it->second != 0) 01216 { 01217 tvItem.iSelectedImage = tvItem.iImage = it->second; 01218 return; 01219 } 01220 } 01221 01222 if (treeIcon.length() && pathUtil.loadPaths(project, true)) 01223 { 01224 std::vector<CString> paths = pathUtil.getPaths(); 01225 for (auto pathsIt = paths.begin(); pathsIt != paths.end(); pathsIt++) 01226 { 01227 if (treeIconBmp == nullptr) 01228 { 01229 treeIconBmp = 01230 std::unique_ptr<Gdiplus::Bitmap>(Gdiplus::Bitmap::FromFile(*pathsIt + L"\\" + static_cast<const wchar_t*>(treeIcon))); 01231 if (treeIconBmp->GetLastStatus() != Gdiplus::Ok) 01232 { 01233 treeIconBmp = nullptr; 01234 } 01235 } 01236 if (expandedTreeIcon.length() != 0 && expandedTreeIconBmp == nullptr) 01237 { 01238 expandedTreeIconBmp = 01239 std::unique_ptr<Gdiplus::Bitmap>(Gdiplus::Bitmap::FromFile(*pathsIt + L"\\" + static_cast<const wchar_t*>(expandedTreeIcon))); 01240 if (expandedTreeIconBmp->GetLastStatus() != Gdiplus::Ok) 01241 { 01242 expandedTreeIconBmp = nullptr; 01243 } 01244 } 01245 } 01246 } 01247 if (treeIconBmp != nullptr) 01248 { 01249 CImageList* imageList = GetImageList(TVSIL_NORMAL); 01250 01251 ImageList_AddGdiplusBitmap(static_cast<HIMAGELIST>(*imageList), *treeIconBmp.get()); 01252 ImageList_AddGdiplusBitmap(static_cast<HIMAGELIST>(*imageList), expandedTreeIconBmp != nullptr ? *expandedTreeIconBmp.get() : *treeIconBmp.get()); 01253 01254 tvItem.iSelectedImage = tvItem.iImage = imageList->GetImageCount() - 2; 01255 treeIcons.insert(std::make_pair(treeIcon, imageList->GetImageCount() - 2)); 01256 if (expandedTreeIcon.length() != 0) 01257 treeIcons.insert(std::make_pair(treeIcon, imageList->GetImageCount())); 01258 } 01259 else 01260 { 01261 treeIcons.insert(std::make_pair(treeIcon, 0)); 01262 } 01263 01264 } 01265 01266 01267 void CAggregateTreeCtrl::SetItemProperties(HTREEITEM hItem, int p_fileLatentState, CAggregateMgaObjectProxy* insertedProxy) 01268 { 01269 01270 01271 CAggregateMgaObjectProxy ObjectProxy; 01272 01273 if(!m_MgaMap.LookupObjectProxy(hItem, ObjectProxy)) 01274 return; 01275 01276 CComQIPtr<IMgaObject> ccpObject(ObjectProxy.m_pMgaObject); 01277 01278 if(!ccpObject) 01279 return; // Not an MgaObject 01280 01281 01282 BYTE cState=0; 01283 01284 CGMEActiveBrowserApp* pApp=(CGMEActiveBrowserApp*)AfxGetApp(); 01285 CMgaContext* pMgaContext=&pApp->m_CurrentProject.m_MgaContext; 01286 01287 pMgaContext->BeginTransaction(); 01288 01289 01290 // Checking access rights 01291 VARIANT_BOOL vtbIsWritable=VARIANT_FALSE; 01292 VARIANT_BOOL vtbIsReadOnly=VARIANT_FALSE; 01293 COMTHROW( ccpObject->get_IsWritable(&vtbIsWritable)); 01294 COMTHROW( ccpObject->HasReadOnlyAccess( &vtbIsReadOnly)); 01295 01296 if (vtbIsWritable != VARIANT_TRUE || vtbIsReadOnly == VARIANT_TRUE || p_fileLatentState != 0) 01297 { 01298 // Read only object 01299 cState|=0x0001; 01300 } 01301 else 01302 { 01303 // If the object is writable 01304 01305 01306 } 01307 01308 01309 VARIANT_BOOL vtbIsLibObject=VARIANT_FALSE;; 01310 COMTHROW(ccpObject->get_IsLibObject(&vtbIsLibObject)); 01311 01312 if(vtbIsLibObject!=VARIANT_TRUE) 01313 { 01314 // Not a LibObject 01315 } 01316 else 01317 { 01318 // LibObject 01319 cState|=0x0002; 01320 01321 } 01322 01323 01324 CComQIPtr<IMgaObject> ccpMgaObject(ObjectProxy.m_pMgaObject); 01325 if (ccpMgaObject) 01326 { 01327 CComBSTR id; 01328 ccpMgaObject->get_ID(&id); 01329 auto it = m_highlightedObjects.find(id); 01330 if (it != m_highlightedObjects.end()) 01331 { 01332 CTreeCtrl::SetItemState(hItem, TVIS_BOLD, TVIS_BOLD); 01333 } 01334 else 01335 { 01336 CTreeCtrl::SetItemState(hItem, 0, TVIS_BOLD); 01337 } 01338 } 01339 01341 // If not an Folder deal with Subtype/instance flags 01342 if(ObjectProxy.m_TypeInfo!=OBJTYPE_FOLDER) 01343 { 01344 CComQIPtr<IMgaFCO> ccpMgaFCO(ObjectProxy.m_pMgaObject); 01345 if(!ccpMgaFCO) 01346 return; // Not an FCO 01347 01348 // Is it instance? 01349 VARIANT_BOOL vtbIsInstance=VARIANT_FALSE; 01350 COMTHROW(ccpMgaFCO->get_IsInstance(&vtbIsInstance)); 01351 01352 if(vtbIsInstance!=VARIANT_TRUE) 01353 { 01354 CComPtr<IMgaFCO> ccpBaseType; 01355 COMTHROW(ccpMgaFCO->get_BaseType(&ccpBaseType)); 01356 01357 if(!ccpBaseType) 01358 { 01359 // Not derived 01360 } 01361 else 01362 { 01363 // Derived 01364 cState|=0x0008; 01365 } 01366 01367 } 01368 else 01369 { 01370 // Instance 01371 cState|=0x0004; 01372 01373 } 01374 01375 } // if not folder 01376 pMgaContext->CommitTransaction(); 01377 01378 01379 if(cState) 01380 { 01381 CTreeCtrl::SetItemState( hItem,INDEXTOSTATEIMAGEMASK(cState), TVIS_STATEIMAGEMASK ); 01382 } 01383 else 01384 { 01385 CTreeCtrl::SetItemState( hItem,0, TVIS_STATEIMAGEMASK ); 01386 } 01387 } 01388 01389 01390 01391 BOOL CAggregateTreeCtrl::IsLibrary(LPUNKNOWN pUnknown, bool *p_ptrHasAnyDependency /*= 0*/) 01392 { 01393 01394 CComQIPtr<IMgaFolder> ccpFolder(pUnknown); 01395 01396 if(!ccpFolder)return FALSE; 01397 01398 01399 CGMEActiveBrowserApp* pApp=(CGMEActiveBrowserApp*)AfxGetApp(); 01400 CMgaContext* pMgaContext=&pApp->m_CurrentProject.m_MgaContext; 01401 01402 pMgaContext->BeginTransaction(); 01403 01404 CComBSTR bszLibName; 01405 COMTHROW(ccpFolder->get_LibraryName(&bszLibName)); 01406 01407 if( bszLibName && p_ptrHasAnyDependency) // user interested in the dependency status 01408 { 01409 *p_ptrHasAnyDependency = IsUngroupedLibrary( ccpFolder); 01410 } 01411 01412 pMgaContext->CommitTransaction(); 01413 01414 if(!bszLibName) 01415 { 01416 return FALSE; 01417 } 01418 01419 return TRUE; 01420 01421 } 01422 01423 //static 01424 bool CAggregateTreeCtrl::IsUngroupedLibrary(CComPtr<IMgaFolder> pLibPtr) 01425 { 01426 ASSERT( pLibPtr); 01427 if( !pLibPtr) return false; 01428 01429 bool retv = true; 01430 CComPtr<IMgaFolders> c1, c2; 01431 COMTHROW( pLibPtr->GetVirtuallyIncludedBy( &c1)); 01432 COMTHROW( pLibPtr->GetVirtuallyIncludes( &c2)); 01433 long l1( 0), l2( 0); 01434 if( c1) COMTHROW( c1->get_Count( &l1)); 01435 if( c2) COMTHROW( c2->get_Count( &l2)); 01436 if( l1 == 0 && l2 == 0) 01437 { 01438 retv = false; 01439 } 01440 01441 return retv; 01442 } 01443