GME
13
|
00001 #include <stdafx.h> 00002 #include <afxadv.h> 00003 #include "afxcoll.h" 00004 #include "afxtempl.h" 00005 #include "..\Interfaces\meta.h" 00006 #include "..\Interfaces\mga.h" 00007 #include "..\Interfaces\parser.h" 00008 00009 #include "..\GME\GMEstd.h" 00010 00011 #include "PartBrowserOLEData.h" 00012 00013 #include "PartBrowser_i.c" 00014 00015 CLIPFORMAT CPartBrowserDataSource::cfGMEDesc = (CLIPFORMAT)(RegisterClipboardFormat(_T("GME Descriptor"))); 00016 int CPartBrowserDataSource::myData = 0; 00017 00018 /* --------------------------- CPartBrowserDataDescriptor --------------------------- */ 00019 //static // called externally, to destruct certain lists 00020 void CPartBrowserDataDescriptor::destructList(CTypedPtrList<CPtrList, CRect*>& pList)// it is a CRectList 00021 { 00022 POSITION pos = pList.GetHeadPosition(); 00023 while (pos) 00024 delete pList.GetNext(pos); 00025 pList.RemoveAll(); 00026 } 00027 00028 CPartBrowserDataDescriptor::CPartBrowserDataDescriptor(CTypedPtrList<CPtrList, CRect*> &list, 00029 CTypedPtrList<CPtrList, CRect*> &annList, 00030 CPoint dragPoint, CPoint offs) 00031 { 00032 POSITION pos = list.GetHeadPosition(); 00033 while (pos) { 00034 CRect *rect = new CRect(list.GetNext(pos)); 00035 rect->OffsetRect(-dragPoint.x,-dragPoint.y); 00036 rects.AddTail(rect); 00037 } 00038 00039 pos = annList.GetHeadPosition(); 00040 while (pos) { 00041 CRect* rect = new CRect(annList.GetNext(pos)); 00042 rect->OffsetRect(-dragPoint.x,-dragPoint.y); 00043 annRects.AddTail(rect); 00044 } 00045 00046 offset = offs; 00047 pFile = 0; 00048 } 00049 00050 void CPartBrowserDataDescriptor::Reset() 00051 { 00052 POSITION pos = rects.GetHeadPosition(); 00053 while (pos) 00054 delete rects.GetNext(pos); 00055 rects.RemoveAll(); 00056 00057 pos = annRects.GetHeadPosition(); 00058 while (pos) 00059 delete annRects.GetNext(pos); 00060 annRects.RemoveAll(); 00061 } 00062 00063 void CPartBrowserDataDescriptor::Serialize(CArchive& ar) 00064 { 00065 if (ar.IsStoring()) { 00066 ar << rects.GetCount(); 00067 POSITION pos = rects.GetHeadPosition(); 00068 while (pos) 00069 ar << *(rects.GetNext(pos)); 00070 00071 ar << annRects.GetCount(); 00072 pos = annRects.GetHeadPosition(); 00073 while (pos) 00074 ar << *(annRects.GetNext(pos)); 00075 00076 ar << offset; 00077 } else { 00078 Reset(); 00079 int n; 00080 ar >> n; 00081 for(int i = 0; i < n; i++) { 00082 CRect* rect = new CRect(); 00083 ar >> *rect; 00084 rects.AddTail(rect); 00085 } 00086 00087 ar >> n; 00088 for(int j = 0; j < n; j++) { 00089 CRect* rect = new CRect(); 00090 ar >> *rect; 00091 annRects.AddTail(rect); 00092 } 00093 ar >> offset; 00094 } 00095 } 00096 00097 bool CPartBrowserDataDescriptor::Load(COleDataObject* pDataObject) 00098 { 00099 ASSERT(pDataObject != NULL); 00100 00101 if (pDataObject->IsDataAvailable(CPartBrowserDataSource::cfGMEDesc)) { 00102 ASSERT(pFile == 0); 00103 pFile = pDataObject->GetFileData(CPartBrowserDataSource::cfGMEDesc); 00104 ASSERT(pFile != NULL); 00105 CArchive ar(pFile, CArchive::load); 00106 Serialize(ar); 00107 return true; 00108 } 00109 return false; 00110 } 00111 00112 int CPartBrowserDataDescriptor::GetCount() 00113 { 00114 /* return (rects.GetCount() + annRects.GetCount()); */ 00115 return rects.GetCount(); 00116 } 00117 00118 void CPartBrowserDataDescriptor::Clean() 00119 { 00120 delete pFile; 00121 pFile = 0; 00122 } 00123 00124 void CPartBrowserDataDescriptor::Draw(CDC *pDC,CPoint &pt) 00125 { 00126 POSITION pos = rects.GetHeadPosition(); 00127 while (pos) { 00128 CRect rect = *(rects.GetNext(pos)); 00129 00130 rect.OffsetRect(pt); 00131 CPoint align = rect.CenterPoint(); 00132 00133 // Emulate the grid. 00134 long gs = GME_GRID_SIZE; 00135 align.x = (align.x % gs); 00136 align.y = (align.y % gs); 00137 00138 00139 rect.OffsetRect(-align.x, -align.y); 00140 // rect.OffsetRect(-offset.x, -offset.y); 00141 pDC->DrawFocusRect(&rect); 00142 00143 } 00144 00145 pos = annRects.GetHeadPosition(); 00146 while (pos) { 00147 CRect rect = *(annRects.GetNext(pos)); 00148 00149 rect.OffsetRect(pt); 00150 pDC->DrawFocusRect(&rect); 00151 } 00152 } 00153 00154 00155 // This function has been simplified for GMEActiveBrowser 00156 // No annotations and grid alignment 00157 void CPartBrowserDataDescriptor::SimpleDraw(CDC *pDC, CPoint &pt) 00158 { 00159 POSITION pos = rects.GetHeadPosition(); 00160 while (pos) { 00161 CRect rect = *(rects.GetNext(pos)); 00162 00163 rect.OffsetRect(pt); 00164 00165 pDC->DrawFocusRect(&rect); 00166 00167 } 00168 } 00169 00170 00171 void CPartBrowserDataDescriptor::GetBoundingRect(CRect &rBoundingRect) 00172 { 00173 rBoundingRect = CRect(0, 0, 0, 0); 00174 00175 CRect Rect; 00176 POSITION pos = rects.GetHeadPosition(); 00177 00178 while (pos) { 00179 Rect = *(rects.GetNext(pos)); 00180 rBoundingRect.UnionRect(rBoundingRect, Rect); 00181 } 00182 } 00183 00184 00185 /* --------------------------- CPartBrowserDataSource ------------------------------- */ 00186 00187 bool CPartBrowserDataSource::IsGmeNativeDataAvailable(COleDataObject *pDataObject, IMgaProject *project) 00188 { 00189 ASSERT( project != NULL ); 00190 00191 CComPtr<IDataObject> p = pDataObject->GetIDataObject(FALSE); 00192 CComPtr<IPartBrowserDataSource> source; 00193 if (p!= NULL && p.QueryInterface(&source) == S_OK) { 00194 CComPtr<IUnknown> unknown; 00195 COMTHROW(source->get_Project(&unknown)); 00196 ASSERT(unknown != NULL); 00197 00198 CComPtr<IMgaProject> source_project; 00199 COMTHROW(unknown.QueryInterface(&source_project)); 00200 ASSERT(source_project != NULL); 00201 00202 return source_project.IsEqualObject(project); 00203 } 00204 return false; 00205 } 00206 00207 bool CPartBrowserDataSource::IsXMLDataAvailable(COleDataObject *pDataObject) 00208 { 00209 ASSERT(pDataObject != NULL); 00210 00211 return pDataObject->IsDataAvailable(CF_TEXT) != FALSE; 00212 } 00213 00214 bool CPartBrowserDataSource::ParseXMLData(COleDataObject *pDataObject, IMgaObject *target, bool merge = false) 00215 { 00216 ASSERT(pDataObject != NULL); 00217 ASSERT(target != NULL); 00218 00219 // create a temporary filename 00220 char *fname = _tempnam("c:\\temp", "tmp"); 00221 CString filename = fname; 00222 free(fname); 00223 00224 try 00225 { 00226 // get the memory file 00227 CFile *memfile = pDataObject->GetFileData(CF_TEXT); 00228 if (memfile == NULL) 00229 return false; 00230 memfile->SeekToBegin(); 00231 00232 // copy 00233 CFile file; 00234 if(file.Open(filename, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary) == 0) 00235 return false; 00236 00237 const int buffsize = 10240; 00238 unsigned char buff[buffsize]; 00239 UINT c; 00240 do 00241 { 00242 c = memfile->Read(buff, buffsize); 00243 00244 UINT new_c = 0; // addition by ZolMol 00245 while (buff[new_c] != 0 && new_c < c) ++new_c; 00246 c = new_c; // end 00247 00248 file.Write(buff, c); 00249 } while(c == buffsize); 00250 file.Close(); 00251 00252 // clear the memory file 00253 delete memfile; 00254 00255 // parse 00256 CComPtr<IMgaParser> parser; 00257 COMTHROW(parser.CoCreateInstance(L"Mga.MgaParser")); 00258 ASSERT(parser != NULL); 00259 00260 CComBstrObj acckind, version; 00261 VARIANT_BOOL is_acc_target; 00262 COMTHROW(parser->GetClipXMLInfo(PutInBstr(filename), target, &is_acc_target, PutOut(acckind), PutOut( version))); 00263 CString ver = "0"; // defval 00264 if (version) // clipboard main token found, otherwise use defval 00265 CopyTo(version, ver); 00266 00267 00268 CComObjPtr<IMgaProject> t_project; 00269 COMTHROW(target->get_Project(PutOut(t_project))); 00270 CComPtr<IGMEOLEApp> t_GME = CPartBrowserDataSource::get_GME(t_project); 00271 00272 CComBSTR msg, done; 00273 done.Append("Done."); 00274 if (ver == "0") { 00275 msg.Append("Inserting XML data..."); 00276 if (t_GME) COMTHROW(t_GME->ConsoleMessage(msg, MSG_INFO)); 00277 COMTHROW(parser->ParseFCOs(target, PutInBstr(filename))); 00278 if (t_GME) COMTHROW(t_GME->ConsoleMessage(done, MSG_INFO)); 00279 } else if (ver == "4") { 00280 msg.Append("Inserting XML SmartCopied data..."); 00281 if (t_GME) COMTHROW(t_GME->ConsoleMessage(msg, MSG_INFO)); 00282 COMTHROW(parser->ParseClos4(target, PutInBstr(filename), merge ? MERGE:ADDITION)); 00283 if (t_GME) COMTHROW(t_GME->ConsoleMessage(done, MSG_INFO)); 00284 } else if (ver == "1" || ver == "") { 00285 msg.Append("Inserting XML CopyClosured data..."); 00286 if (t_GME) COMTHROW(t_GME->ConsoleMessage(msg, MSG_INFO)); 00287 COMTHROW(parser->ParseClos1(target, PutInBstr(filename))); 00288 if (t_GME) COMTHROW(t_GME->ConsoleMessage(done, MSG_INFO)); 00289 } else { 00290 msg.Append("Error: Unknown clipboard closure format"); 00291 if(t_GME) COMTHROW(t_GME->ConsoleMessage(msg, MSG_INFO)); 00292 00293 ASSERT(0); 00294 } 00295 00296 00297 CFile::Remove(filename); 00298 00299 return true; 00300 } 00301 catch(hresult_exception &e) 00302 { 00303 CFile::Remove(filename); 00304 00305 try 00306 { 00307 CComObjPtr<IErrorInfo> errinfo; 00308 COMTHROW(GetErrorInfo(0, PutOut(errinfo))); 00309 ASSERT(errinfo != NULL); 00310 00311 CString desc; 00312 COMTHROW(errinfo->GetDescription(PutOut(desc))); 00313 00314 AfxMessageBox(CString("Error while parsing XML file: ") + desc); 00315 } 00316 catch(hresult_exception &) 00317 { 00318 AfxMessageBox("Fatal error while parsing XML file!"); 00319 } 00320 00321 throw e; 00322 } 00323 00324 return false; 00325 } 00326 00327 void CPartBrowserDataSource::CacheDescriptor(CPartBrowserDataDescriptor* desc) 00328 { 00329 CacheGlobalData(cfGMEDesc, CreateDescriptor(desc)); 00330 DelayXMLDump(); 00331 } 00332 00333 HGLOBAL CPartBrowserDataSource::CreateDescriptor(CPartBrowserDataDescriptor* desc) 00334 { 00335 ASSERT(desc); 00336 00337 CSharedFile file; 00338 CArchive ar(&file, CArchive::store); 00339 desc->Serialize(ar); 00340 ar.Close(); 00341 return file.Detach(); 00342 } 00343 00344 void CPartBrowserDataSource::DelayXMLDump() 00345 { 00346 FORMATETC fe = { 00347 CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_ISTREAM|TYMED_HGLOBAL 00348 }; 00349 00350 DelayRenderFileData(CF_TEXT, &fe); 00351 } 00352 00353 BOOL CPartBrowserDataSource::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile) 00354 { 00355 if (lpFormatEtc->cfFormat == CF_TEXT) { 00356 ASSERT(pFile != NULL); 00357 00358 // TODO: we have to dump it directly to the shared memory file 00359 00360 try 00361 { 00362 char *fname = _tempnam("c:\\temp", "tmp"); 00363 CString filename = fname; 00364 free(fname); 00365 00366 CComPtr<IMgaDumper> dumper; 00367 COMTHROW(dumper.CoCreateInstance(L"Mga.MgaDumper")); 00368 00369 CComObjPtr<IMgaFCOs> fcos; 00370 if (data) // check whether it is set 00371 COMTHROW(::QueryInterface(data, fcos)); 00372 00373 CComObjPtr<IMgaFolders> folds; 00374 if (folders) // check whether it is set 00375 COMTHROW(::QueryInterface(folders, folds)); 00376 00377 CComObjPtr<IMgaRegNodes> regd; 00378 if (regdata) // check whether it is set 00379 COMTHROW(::QueryInterface(regdata, regd)); 00380 00381 COMTHROW(dumper->DumpFCOs(project, fcos, folds, regd, PutInBstr(filename))); 00382 00383 CFile file; 00384 if(file.Open(filename, CFile::modeRead | CFile::typeBinary) == 0) 00385 return FALSE; 00386 00387 const int buffsize = 10240; 00388 unsigned char buff[buffsize]; 00389 UINT c; 00390 do 00391 { 00392 c = file.Read(buff, buffsize); 00393 pFile->Write(buff, c); 00394 } while(c == buffsize); 00395 00396 buff[0] = 0; 00397 pFile->Write(buff, 1); 00398 00399 file.Close(); 00400 CFile::Remove(filename); 00401 } 00402 catch(hresult_exception &) 00403 { 00404 return FALSE; 00405 } 00406 catch(CFileException *) 00407 { 00408 return FALSE; 00409 } 00410 00411 return TRUE; 00412 } 00413 00414 return FALSE; 00415 } 00416 00417 // **************************************************************************************************** 00418 // ********************************* CPartBrowserClosureDataSource ***************************************** 00419 // **************************************************************************************************** 00420 BOOL CPartBrowserClosureDataSource::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile) 00421 { 00422 if (lpFormatEtc->cfFormat == CF_TEXT) { 00423 ASSERT(pFile != NULL); 00424 00425 // TODO: we have to dump it directly to the shared memory file 00426 00427 try 00428 { 00429 char *fname = _tempnam("c:\\temp", "tmp"); 00430 CString filename = fname; 00431 free(fname); 00432 00433 CComPtr<IMgaDumper> dumper; 00434 COMTHROW(dumper.CoCreateInstance(L"Mga.MgaDumper")); 00435 00436 CComObjPtr<IMgaFCOs> fcos; 00437 if (data) // is it set? 00438 COMTHROW(::QueryInterface(data, fcos)); 00439 00440 CComObjPtr<IMgaFolders> fols; 00441 if (folders) // is it set? 00442 COMTHROW(::QueryInterface(folders, fols)); 00443 00444 bool is_top_set = false; 00445 CComObjPtr<IMgaFCOs> top_fcos; 00446 CComObjPtr<IMgaFolders> top_folds; 00447 00448 if (m_topFcos) { 00449 COMTHROW(::QueryInterface( m_topFcos, top_fcos)); 00450 is_top_set = true; 00451 } 00452 00453 if (m_topFolders) { 00454 COMTHROW(::QueryInterface( m_topFolders, top_folds)); 00455 is_top_set = true; 00456 } 00457 00458 if (is_top_set) 00459 COMTHROW(dumper->DumpClosR(fcos, fols, PutInBstr(filename), top_fcos, top_folds, m_options, m_absPathPart, m_acceptingKinds)); 00460 else // if top objects are not set dump starting from RootFolder 00461 COMTHROW(dumper->DumpClos(fcos, fols, PutInBstr(filename), m_options)); 00462 00463 CFile file; 00464 if (file.Open(filename, CFile::modeRead | CFile::typeBinary) == 0) 00465 return FALSE; 00466 00467 const int buffsize = 10240; 00468 unsigned char buff[buffsize]; 00469 UINT c; 00470 do 00471 { 00472 c = file.Read(buff, buffsize); 00473 pFile->Write(buff, c); 00474 } while (c == buffsize); 00475 00476 buff[0] = 0; 00477 pFile->Write(buff, 1); 00478 00479 file.Close(); 00480 CFile::Remove(filename); 00481 } 00482 catch(hresult_exception &) 00483 { 00484 return FALSE; 00485 } 00486 catch(CFileException *) 00487 { 00488 return FALSE; 00489 } 00490 00491 return TRUE; 00492 } 00493 00494 return FALSE; 00495 } 00496 00497 BEGIN_MESSAGE_MAP(CPartBrowserDataSource, COleDataSource) 00498 //{{AFX_MSG_MAP(CPartBrowserDataSource) 00499 // NOTE - the ClassWizard will add and remove mapping macros here. 00500 //}}AFX_MSG_MAP 00501 END_MESSAGE_MAP() 00502 00503 // Interface Maps 00504 00505 BEGIN_DISPATCH_MAP(CPartBrowserDataSource, COleDataSource) 00506 //{{AFX_DISPATCH_MAP(CPartBrowserDataSource) 00507 DISP_PROPERTY_EX(CPartBrowserDataSource, "Data", DispGetData, DispSetData, VT_DISPATCH) 00508 DISP_PROPERTY_EX(CPartBrowserDataSource, "Folders", DispGetFolders, DispSetFolders, VT_DISPATCH) 00509 DISP_PROPERTY_EX(CPartBrowserDataSource, "RegistryData", DispGetRegistryData, DispSetRegistryData, VT_DISPATCH) 00510 DISP_PROPERTY_EX(CPartBrowserDataSource, "Project", DispGetProject, DispSetProject, VT_DISPATCH) 00511 //}}AFX_DISPATCH_MAP 00512 END_DISPATCH_MAP() 00513 00514 00515 BEGIN_INTERFACE_MAP(CPartBrowserDataSource, COleDataSource) 00516 INTERFACE_PART(CPartBrowserDataSource, IID_IPartBrowserDataSource, PartBrowserDataSource) 00517 DUAL_ERRORINFO_PART(CPartBrowserDataSource) 00518 END_INTERFACE_MAP() 00519 00520 DELEGATE_DUAL_INTERFACE(CPartBrowserDataSource, PartBrowserDataSource) 00521 00522 // Implement ISupportErrorInfo to indicate we support the 00523 // OLE Automation error handler. 00524 IMPLEMENT_DUAL_ERRORINFO(CPartBrowserDataSource, IID_IPartBrowserDataSource) 00525 00526 00527 STDMETHODIMP CPartBrowserDataSource::XPartBrowserDataSource::get_Data(IUnknown **p) 00528 { 00529 METHOD_PROLOGUE(CPartBrowserDataSource, PartBrowserDataSource) 00530 CHECK_OUT(p); 00531 00532 if (pThis->data != NULL) 00533 return pThis->data.QueryInterface(p); 00534 00535 return S_OK; 00536 } 00537 00538 STDMETHODIMP CPartBrowserDataSource::XPartBrowserDataSource::get_Folders(IUnknown **p) 00539 { 00540 METHOD_PROLOGUE(CPartBrowserDataSource, PartBrowserDataSource) 00541 CHECK_OUT(p); 00542 00543 if (pThis->folders != NULL) 00544 return pThis->folders.QueryInterface(p); 00545 00546 return S_OK; 00547 } 00548 00549 STDMETHODIMP CPartBrowserDataSource::XPartBrowserDataSource::get_RegistryData(IUnknown **p) 00550 { 00551 METHOD_PROLOGUE(CPartBrowserDataSource, PartBrowserDataSource) 00552 CHECK_OUT(p); 00553 00554 if (pThis->regdata != NULL) 00555 return pThis->regdata.QueryInterface(p); 00556 00557 return S_OK; 00558 } 00559 00560 STDMETHODIMP CPartBrowserDataSource::XPartBrowserDataSource::get_Project(IUnknown **p) 00561 { 00562 METHOD_PROLOGUE(CPartBrowserDataSource, PartBrowserDataSource) 00563 CHECK_OUT(p); 00564 00565 return pThis->project.QueryInterface(p); 00566 } 00567 00568 00569 00570 00571 /*static*/ CComPtr<IGMEOLEApp> CPartBrowserDataSource::get_GME(CComObjPtr<IMgaProject> project) 00572 { 00573 CComPtr<IGMEOLEApp> gme; 00574 if ( (project != NULL)) { 00575 CComBSTR bstrName("GME.Application"); 00576 CComPtr<IMgaClient> pClient; 00577 HRESULT hr = project->GetClientByName(bstrName, &pClient); 00578 if (SUCCEEDED(hr) && pClient) { 00579 CComPtr<IDispatch> pDispatch; 00580 hr = pClient->get_OLEServer(&pDispatch); 00581 if (SUCCEEDED(hr) && pDispatch) { 00582 hr = pDispatch.QueryInterface(&gme); 00583 if (FAILED(hr)) { 00584 gme = NULL; 00585 } 00586 } 00587 } 00588 } 00589 return gme; 00590 } 00591 00592 LPDISPATCH CPartBrowserDataSource::DispGetData() 00593 { 00594 CComPtr<IDispatch> p; 00595 if (data != NULL) { 00596 data.QueryInterface(&p); 00597 } 00598 00599 return p.Detach(); 00600 } 00601 00602 void CPartBrowserDataSource::DispSetData(LPDISPATCH) 00603 { 00604 SetNotSupported(); 00605 } 00606 00607 LPDISPATCH CPartBrowserDataSource::DispGetFolders() 00608 { 00609 CComPtr<IDispatch> p; 00610 if (folders != NULL) { 00611 folders.QueryInterface(&p); 00612 } 00613 00614 return p.Detach(); 00615 } 00616 00617 void CPartBrowserDataSource::DispSetFolders(LPDISPATCH) 00618 { 00619 SetNotSupported(); 00620 } 00621 00622 LPDISPATCH CPartBrowserDataSource::DispGetRegistryData() 00623 { 00624 CComPtr<IDispatch> p; 00625 if (regdata != NULL) { 00626 regdata.QueryInterface(&p); 00627 } 00628 00629 return p.Detach(); 00630 } 00631 00632 void CPartBrowserDataSource::DispSetRegistryData(LPDISPATCH) 00633 { 00634 SetNotSupported(); 00635 } 00636 00637 LPDISPATCH CPartBrowserDataSource::DispGetProject() 00638 { 00639 CComPtr<IDispatch> p; 00640 if (project != NULL) { 00641 project.QueryInterface(&p); 00642 } 00643 00644 return p.Detach(); 00645 } 00646 00647 void CPartBrowserDataSource::DispSetProject(LPDISPATCH) 00648 { 00649 SetNotSupported(); 00650 } 00651