GME  13
SearchDlg.cpp
Go to the documentation of this file.
00001 // SearchDlg.cpp : implementation file
00002 //
00003 
00004 #include "stdafx.h"
00005 #include "Search.h"
00006 #include "SearchDlg.h"
00007 #include "SearchCtl.h"
00008 #include "Input.h"
00009 #include "SearchAlg.h"
00010 #include <string>
00011 #include <sstream>
00012 #include <stack>
00013 
00014 #include "..\Gme\GMEOLEData.h"
00015 
00016 #ifdef _DEBUG
00017 #define new DEBUG_NEW
00018 #undef THIS_FILE
00019 static char THIS_FILE[] = __FILE__;
00020 #endif
00021 
00022 
00023 BEGIN_MESSAGE_MAP(AutocompleteComboBox, CComboBox)
00024         ON_CONTROL_REFLECT(CBN_EDITCHANGE, OnEditChange)
00025 END_MESSAGE_MAP()
00026 
00027 LRESULT AutocompleteComboBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
00028 {
00029         if (message == WM_KEYDOWN && wParam == VK_DOWN)
00030         { // FIXME this doesn't work
00031                 this->ShowDropDown();
00032                 return 0;
00033         }
00034 
00035         return __super::WindowProc(message, wParam, lParam);
00036 }
00037 
00038 void AutocompleteComboBox::OnEditChange()
00039 {
00040         CString str;
00041         GetWindowTextW(str);
00042         DWORD sel = GetEditSel();
00043         if (m_previous.GetLength() >= str.GetLength() || wcsncmp(m_previous, str, m_previous.GetLength()) != 0)
00044         {
00045                 m_previous = str;
00046                 return;
00047         }
00048         auto substr_eq = [&str](const wchar_t* str2) { return wcsncmp(str, str2, str.GetLength()) == 0; };
00049         ResetContent();
00050         auto it = std::find_if(m_options.begin(), m_options.end(), substr_eq);
00051         auto first = it;
00052         for (; it != m_options.end() && substr_eq(*it); ++it)
00053         {
00054                 InsertString(-1, *it);
00055         }
00056         if (first != m_options.end())
00057         {
00058                 SetWindowTextW(*first);
00059                 SetEditSel(sel, -1);
00060         }
00061         else
00062         {
00063                 SetWindowTextW(str);
00064                 SetEditSel(sel, sel);
00065         }
00066         m_previous = str;
00067 }
00068 
00069 
00071 // CSearchDlg dialog
00072 
00073 
00074 CSearchDlg::CSearchDlg()
00075 : m_scopedCtrlEnabled( FALSE)
00076 , m_edtNameSecond(_T(""))
00077 , m_edtRoleNameSecond(_T(""))
00078 , m_edtKindNameSecond(_T(""))
00079 , m_edtAttributeSecond(_T(""))
00080 , m_radioScope(0)
00081 , m_searchResults(FALSE)
00082 , m_radioLogical(0)
00083 , m_edtNameFirst( _T(""))
00084 , m_edtKindNameFirst( _T(""))
00085 , m_edtRoleNameFirst( _T(""))
00086 , m_edtAttributeFirst( _T(""))
00087 , m_edtAttrValue ( _T(""))
00088 , m_chkAtom(TRUE)
00089 , m_chkFullWord(FALSE)
00090 , m_chkMod(TRUE)
00091 , m_chkRef (TRUE)
00092 , m_chkSet(TRUE)
00093 , m_chkConnection(TRUE)
00094 , m_chkLocate(FALSE)
00095 , m_chkMatchCase(TRUE)
00096 
00097 , m_chkSplSearch(FALSE)
00098 {
00099 }
00100 
00101 void CSearchDlg::DoDataExchange(CDataExchange* pDX)
00102 {
00103     CDialog::DoDataExchange(pDX);
00104     //{{AFX_DATA_MAP(CSearchDlg)
00105     DDX_Control(pDX, IDC_CHECK_CASESENS, m_chkMatchCaseCtrl);
00106     DDX_Control(pDX, IDC_CHECKFULLWORD, m_chkFullWordCtrl);
00107     DDX_Control(pDX, IDC_EDITNAME, m_edtNameCtrlFirst);
00108     DDX_Control(pDX, IDC_EDITKIND, m_edtKindNameCtrlFirst);
00109     DDX_Control(pDX, IDC_EDITROLE, m_edtRoleNameCtrlFirst);
00110     DDX_Control(pDX, IDC_EDITATTRNAME, m_edtAttributeCtrlFirst);
00111     DDX_Control(pDX, IDC_CHECKREF, m_chkRefCtrl);
00112     DDX_Control(pDX, IDC_PROGRESSSEARCH, m_pgsSearch);
00113     DDX_Control(pDX, IDC_CHECKATM, m_chkAtomCtrl);
00114     DDX_Control(pDX, IDC_CHECKSET, m_chkSetCtrl);
00115     DDX_Control(pDX, IDC_CHECKMOD, m_chkModCtrl);
00116     DDX_Control(pDX, IDC_BUTTON_GO, m_btnGO);
00117     DDX_Control(pDX, IDC_LISTRESULTS, m_lstResults);
00118     DDX_Text(pDX, IDC_EDITNAME, m_edtNameFirst);
00119     DDX_Text(pDX, IDC_EDITKIND, m_edtKindNameFirst);
00120     DDX_Text(pDX, IDC_EDITROLE, m_edtRoleNameFirst);
00121     DDX_Text(pDX, IDC_EDITATTRNAME, m_edtAttributeFirst);
00122     DDX_Check(pDX, IDC_CHECKATM, m_chkAtom);
00123     DDX_Check(pDX, IDC_CHECKFULLWORD, m_chkFullWord);
00124     DDX_Check(pDX, IDC_CHECKMOD, m_chkMod);
00125     DDX_Check(pDX, IDC_CHECKREF, m_chkRef);
00126     DDX_Check(pDX, IDC_CHECKSET, m_chkSet);
00127     DDX_Check(pDX, IDC_CHECK_CASESENS, m_chkMatchCase);
00128     DDX_Text(pDX, IDC_EDITNAME2, m_edtNameSecond);
00129     DDX_Text(pDX, IDC_EDITROLE2, m_edtRoleNameSecond);
00130     DDX_Text(pDX, IDC_EDITKIND2, m_edtKindNameSecond);
00131     DDX_Text(pDX, IDC_EDITATTRVALU2, m_edtAttributeSecond);
00132     DDX_Control(pDX, IDC_RADIOAND, m_logicalGrp);
00133     DDX_Radio(pDX, IDC_ENTIRESCOPE2, m_radioScope);
00134     DDX_Check(pDX, IDC_CHECK_RESULTS, m_searchResults);
00135     DDX_Radio(pDX, IDC_RADIOAND, m_radioLogical);
00136     DDX_Control(pDX, IDC_EDITNAME2, m_edtNameCtrlSecond);
00137     DDX_Control(pDX, IDC_EDITROLE2, m_edtRoleNameCtrlSecond);
00138     DDX_Control(pDX, IDC_EDITKIND2, m_edtKindNameCtrlSecond);
00139     DDX_Control(pDX, IDC_EDITATTRVALU2, m_edtAttributeCtrlSecond);
00140     DDX_Control(pDX, IDC_TREE_SEARCH_HISTORY, m_treeSearchHistory);
00141     DDX_Check(pDX, IDC_CHECKCON, m_chkConnection);
00142     DDX_Check(pDX, IDC_CHECKSPLSEARCH, m_chkSplSearch);
00143     DDX_Control(pDX, IDC_STATICREF, m_stcRefCtrl);
00144     DDX_Control(pDX, IDC_CHECKCON, m_chkConnCtrl);
00145 }
00146 
00147 BEGIN_MESSAGE_MAP(CSearchDlg, CDialog)
00148     //{{AFX_MSG_MAP(CSearchDlg)
00149     ON_BN_CLICKED(IDC_BUTTON_GO, OnButtonGo)
00150     ON_NOTIFY(NM_CLICK, IDC_LISTRESULTS, OnClickListResults)
00151     ON_NOTIFY(LVN_ITEMCHANGED, IDC_LISTRESULTS, OnClickListResults)
00152     ON_NOTIFY(NM_DBLCLK, IDC_LISTRESULTS, OnDblclkListResults)
00153     ON_NOTIFY(LVN_KEYDOWN, IDC_LISTRESULTS, OnKeyDownListResults)
00154     //}}AFX_MSG_MAP
00155     ON_WM_SIZE()
00156     ON_WM_SIZING()
00157     ON_WM_VSCROLL()
00158     ON_WM_HSCROLL()
00159     ON_WM_KEYDOWN()
00160     ON_NOTIFY(NM_DBLCLK, IDC_TREE_SEARCH_HISTORY, &CSearchDlg::OnNMDblclkTreeSearchHistory)
00161     ON_BN_CLICKED(IDC_CHECKSPLSEARCH, &CSearchDlg::OnCheckSplSearch)
00162     ON_NOTIFY(LVN_COLUMNCLICK, IDC_LISTRESULTS, &CSearchDlg::OnLvnColumnclickListresults)
00163     ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CSearchDlg::OnBnClickedButtonClear)
00164 END_MESSAGE_MAP()
00165 
00166 BOOL CSearchDlg::OnInitDialog()
00167 {
00168     CDialog::OnInitDialog();
00169 
00170     //initialize sort array
00171     ascending[0]=ascending[1]=ascending[2]=ascending[3]=true;
00172 
00173     //column headers
00174     m_lstResults.InsertColumn(1, _T("Object"), LVCFMT_LEFT, 100, 0);
00175     m_lstResults.InsertColumn(2, _T("Path"), LVCFMT_LEFT, 210, 1);
00176     m_lstResults.InsertColumn(3, _T("Kind"), LVCFMT_LEFT, 95, 2);
00177    // m_lstResults.InsertColumn(4, _T("Value"), LVCFMT_LEFT, 210, 3);
00178     m_lstResults.SetExtendedStyle(m_lstResults.GetExtendedStyle()|LVS_EX_FULLROWSELECT);
00179 
00180     specialSearchFCO = NULL;
00181 
00182     m_pgsSearch.SetRange(1,16000);
00183     m_pgsSearch.SetStep(1);
00184 
00185         InsertTextToControl(CString(L"_id="), m_edtAttributeCtrlFirst);
00186         InsertTextToControl(CString(L"_guid="), m_edtAttributeCtrlFirst);
00187         // InsertTextToControl(CString(L"_abspath="), m_edtAttributeCtrlFirst);
00188 
00189     //load search history from registry
00190     LoadSearchHistory();
00191 
00192         dropTarget.Register(this);
00193 
00194         return true;
00195 }
00196 
00198 // CSearchDlg message handlers
00199 
00200 
00202 //  These functions should be implemented to work with CSearchCtl
00203 
00204 // Must remove all search result
00205 void CSearchDlg::RemoveAll()
00206 {
00207     results = NULL;
00208     COMTHROW(results.CoCreateInstance(L"Mga.MgaFCOs"));
00209     DisplayResults();
00210         results = NULL;
00211 }
00212 
00213 // Must remove results belong to zombie objects
00214 void CSearchDlg::RemoveZombies()
00215 {
00216     bool zombieFound = false;
00217         if (results == NULL)
00218                 return;
00219 
00220     CSearchCtrl *TheCtrl = GetCtrl();
00221     TheCtrl->BeginTransaction();
00222 
00223     long position = 1; //IMgaFCOs is 1-based
00224     MGACOLL_ITERATE(IMgaFCO,results)
00225     {
00226         long oStatus;
00227         COMTHROW(MGACOLL_ITER->get_Status(&oStatus));
00228         if(oStatus != OBJECT_EXISTS)
00229         {
00230             COMTHROW(results->Remove(position));
00231             //removing the zombie causes the next item to have the same position
00232             //that the zombie just had, so don't advance the position counter
00233             zombieFound = true;
00234         }
00235         else
00236         {
00237             position++;
00238         }
00239 
00240     }MGACOLL_ITERATE_END;
00241 
00242     if(zombieFound) //only redraw if we had to remove a zombie
00243     {
00244         DisplayResults();
00245     }
00246 
00247     if(specialSearchFCO != NULL)
00248     {   //test if specialSearchFCO became a zombie
00249         long oStatus;
00250         COMTHROW(specialSearchFCO->get_Status(&oStatus));
00251         if(oStatus != OBJECT_EXISTS)
00252         {
00253             specialSearchFCO = NULL;
00254             m_stcRefCtrl.SetWindowText(_T("NULL References"));
00255                         m_stcRefCtrl.ShowWindow(TRUE);
00256         }
00257     }
00258 
00259     TheCtrl->CommitTransaction();
00260 }
00261 
00262 // Enable search 
00263 //enables all the  controls in the search dialog
00264 void CSearchDlg::EnableSearch()
00265 {
00266     //Iterate through all the child controls and enable it
00267     HWND hwnd = ::GetWindow( GetSafeHwnd(),
00268         GW_CHILD);
00269 
00270     while( hwnd )
00271     {
00272         ::EnableWindow(hwnd,true);
00273         // Get the next window. Use it.
00274         hwnd = ::GetWindow( hwnd, GW_HWNDNEXT |GW_HWNDFIRST);
00275     }
00276 }
00277 
00278 //disables all the  controls in the search dialog
00279 void CSearchDlg::DisableSearch()
00280 {
00281 
00282     //Iterate through all the child controls and disable it
00283     HWND hwnd = ::GetWindow( GetSafeHwnd(),
00284         GW_CHILD |GW_HWNDFIRST);
00285     while( hwnd )
00286     {
00287         ::EnableWindow(hwnd,false);
00288         // Get the next window. Use it.
00289         hwnd = ::GetWindow( hwnd, GW_HWNDNEXT );
00290     }
00291 }
00292 
00293 
00294 void CSearchDlg::OnButtonGo() 
00295 {
00296         // FIXME: why do neither ON_NOTIFY(LVN_ITEMACTIVATE nor NM_RETURN work?
00297         HWND h = ::GetFocus();
00298         while (h) {
00299                 if (h == GetDlgItem(IDC_LISTRESULTS)->GetSafeHwnd()) {
00300                         return itemDblClicked();
00301                 }
00302                 h = ::GetParent(h);
00303         }
00304     if(CWnd::UpdateData(TRUE))
00305     {
00306         if (m_searchResults)
00307         {
00308                         if (results != nullptr) // TODO: should probably EnableWindow(FALSE) the Search button instead
00309                         {
00310                                 SearchResults();
00311                                 CreateSearchHistory();
00312                         }
00313             return;
00314         }
00315 
00316         CSearchCtrl *TheCtrl = GetCtrl();
00317         CComPtr<IMgaProject> ccpProject = TheCtrl->GetProject();
00318 
00319         //show progress on especially long searches
00320         m_pgsSearch.ShowWindow(SW_RESTORE);
00321         RemoveAll();
00322         //              AfxMessageBox(_T("Searching"));
00323 
00324         TheCtrl->BeginTransaction();
00325         CComPtr<IMgaObjects> ccpObjectsInTerr = TheCtrl->PutInMyTerritory( TheCtrl->GetScopedL());
00326 
00327         //the CInput class is a legacy from the Search Add-on
00328         //it has functionality for local searching, 
00329         //which is not used here. (hence the NULL's and 0's below)
00330         CComPtr<IMgaFolder> rootInput;
00331         COMTHROW(ccpProject->get_RootFolder(&rootInput));
00332         CInput inp;
00333         try
00334         {
00335             //this might throw error related to regular expression
00336             inp.GetInput(m_edtNameFirst,m_edtRoleNameFirst,m_edtKindNameFirst,m_edtAttributeFirst,m_edtNameSecond,m_edtRoleNameSecond,m_edtKindNameSecond,m_edtAttributeSecond,m_edtAttrValue,
00337             m_chkMod,m_chkAtom,m_chkRef,m_chkSet,m_chkConnection,m_chkSplSearch,m_chkFullWord,NULL,0,m_chkMatchCase,m_radioScope,m_radioLogical);
00338 
00339                         if (results == NULL)
00340                                 COMTHROW(results.CoCreateInstance(L"Mga.MgaFCOs"));
00341                         CSearch searchGME(inp);
00342                         searchGME.Search(rootInput, ccpObjectsInTerr, specialSearchFCO,results,&m_pgsSearch);
00343                         DisplayResults();
00344 
00345                 }
00346         catch (std::tr1::regex_error& err)
00347         {
00348             m_pgsSearch.ShowWindow(SW_HIDE);
00349             m_pgsSearch.SetPos(1);
00350             AfxMessageBox(_T("Make sure your input is correct. If you are using")
00351                 _T(" regular expression elements\n like *, + etc make sure you are")
00352                 _T(" following proper syntax"));
00353             TheCtrl->AbortTransaction();
00354 
00355             return;
00356         }
00357 
00358         m_pgsSearch.ShowWindow(SW_HIDE);
00359         m_pgsSearch.SetPos(1);
00360 
00361         TheCtrl->CommitTransaction();
00362     }
00363     CreateSearchHistory();
00364     SaveSearchHistory();
00365 
00366 }
00367 
00368 // recursively build a path of names from the rootFCO to "named" used in the original call
00369 void CSearchDlg::BuildExtendedName(IMgaFCO *named, CString &extName)
00370 {
00371     if (named != NULL)
00372     {
00373         CComPtr<IMgaModel> parent;
00374         COMTHROW( named->get_ParentModel(&parent));
00375         if (parent != NULL)
00376         {
00377             BuildExtendedName(parent, extName);
00378             extName += _T(" : ");
00379         }
00380         else //parent is a Folder
00381         {
00382             CComPtr<IMgaFolder> parentFolder = NULL;
00383             COMTHROW( named->get_ParentFolder(&parentFolder));
00384             BuildExtendedName(parentFolder, extName);
00385             extName += _T(" : ");
00386         }
00387         CBstr bstr;
00388         COMTHROW( named->get_Name(bstr));
00389         extName += bstr;
00390     }
00391 
00392 }
00393 
00394 // Get the parent folders' names, too
00395 void CSearchDlg::BuildExtendedName(IMgaFolder *named, CString &extName)
00396 {
00397     if (named != NULL)
00398     {
00399         CComPtr<IMgaFolder> parent;
00400         COMTHROW( named->get_ParentFolder(&parent));
00401         if (parent != NULL)
00402         {
00403             BuildExtendedName(parent, extName);
00404             extName += _T(" : ");
00405         }
00406         CBstr bstr;
00407         COMTHROW( named->get_Name(bstr));
00408         extName += bstr;
00409     }
00410 }
00411 
00412 //display all found items at once
00413 void CSearchDlg::DisplayResults()
00414 {
00415     int count = 0;
00416     CString name;
00417     CString path, kind;
00418    
00419     if(!m_chkSplSearch) //only want to wipe this out on a regular search
00420         {
00421                 specialSearchFCO = NULL;
00422                 m_stcRefCtrl.SetWindowText(_T("NULL References"));
00423                 m_stcRefCtrl.ShowWindow(TRUE);
00424         }
00425 
00426 
00427     //Hide the window so it doesn't waste time redrawing each time we add an item
00428     m_lstResults.SetRedraw(FALSE);
00429     m_lstResults.DeleteAllItems();
00430 
00431     MGACOLL_ITERATE(IMgaFCO, results)
00432     {
00433         path = _T("");
00434         name = _T("");
00435         kind = _T("");
00436         
00437         CBstr bstr;
00438         COMTHROW( MGACOLL_ITER->get_Name(bstr) );
00439         name += bstr;
00440 
00441         BuildExtendedName(MGACOLL_ITER.p, path);
00442 
00443         //get the KindName, instead of displaying the type such as Model, Atom etc
00444         //the kind name will be shown
00445         CBstr bstrKindName;
00446         CComPtr<IMgaMetaFCO> cmeta;
00447         COMTHROW( MGACOLL_ITER->get_Meta(&cmeta) );
00448         COMTHROW( cmeta->get_Name(bstrKindName) );
00449 
00450         //set the kind to kind name
00451         kind = bstrKindName;
00452 
00453         //use LVITEM to insert item into list control, LVITEM is needed so that
00454         //lParam can be supplide which will be used during sort
00455         //Object
00456         LVITEM lvItem;
00457         lvItem.lParam = count;
00458         lvItem.iItem = count;
00459         lvItem.iSubItem = 0;
00460         lvItem.pszText=name.GetBuffer();
00461         lvItem.mask = LVIF_PARAM | LVIF_TEXT;
00462         m_lstResults.InsertItem(&lvItem);
00463         
00464         //don't supply lParam for subitems, if you do that the subitems won't get
00465         //displayed properly
00466         //path
00467         lvItem.mask = LVIF_TEXT;
00468         lvItem.iSubItem = 1;
00469         lvItem.pszText = path.GetBuffer();
00470         m_lstResults.SetItem(&lvItem);
00471  
00472         //kind
00473         lvItem.iSubItem = 2;
00474         lvItem.pszText = kind.GetBuffer();
00475         m_lstResults.SetItem(&lvItem);
00476       
00477         count++;
00478 
00479         //let the user know the searcher is still alive for especially long result lists
00480         //(before, when this function didn't hide the m_lstResults control while adding stuff, 
00481         //it would take much more time than the actual searching for long result lists)
00482         m_pgsSearch.StepIt();
00483 
00484     } MGACOLL_ITERATE_END;
00485 
00486     if (count==0)
00487     {
00488         m_lstResults.InsertItem(count, _T(""));
00489         m_lstResults.SetItemText(count, 1, _T("No Matching Results"));
00490     }
00491 
00492     //Now that everything is added, allow the display to redraw
00493     m_lstResults.SetRedraw(TRUE);
00494 }
00495 
00496 void CSearchDlg::OnClickListResults(NMHDR* pNMHDR, LRESULT* pResult) 
00497 {
00498     this->itemClicked(); *pResult = 0;
00499 }
00500 
00501 void CSearchDlg::OnDblclkListResults(NMHDR* pNMHDR, LRESULT* pResult) 
00502 {
00503     this->itemDblClicked(); *pResult = 0;
00504 }
00505 
00506 void CSearchDlg::OnKeyDownListResults(NMHDR* pNMHDR, LRESULT* pResult)
00507 {
00508         LV_KEYDOWN* pLVKeyDown = (LV_KEYDOWN*)pNMHDR;
00509         *pResult = 0;
00510 
00511         long count = 0;
00512     if (results)
00513                 COMTHROW(results->get_Count(&count));
00514 
00515         if (count > 0 && pLVKeyDown->wVKey == VK_DELETE)
00516     {
00517         CWnd::UpdateData(TRUE);
00518 
00519         CSearchCtrl *TheCtrl = GetCtrl();
00520                 try 
00521                 {
00522                         TheCtrl->BeginTransaction(TRANSACTION_GENERAL);
00523                 }
00524                 catch (const hresult_exception&)
00525                 {
00526                         return;
00527                 }
00528         try
00529         {
00530                         ForEachSelectedFCO([&](CComPtr<IMgaFCO> selectedFCO) {
00531                                 COMTHROW(selectedFCO->DestroyObject());
00532                         });
00533             TheCtrl->CommitTransaction();
00534                         // RemoveZombies
00535         }
00536         catch(...)
00537         {
00538             TheCtrl->AbortTransaction();
00539         }
00540 
00541     }
00542 
00543 }
00544 
00545 
00546 void CSearchDlg::OnSize(UINT nType, int cx, int cy)
00547 {
00548     CRect dialogRect;
00549     GetWindowRect( & dialogRect); ScreenToClient(&dialogRect);
00550 
00551     CDialog::OnSize(nType, cx, cy);
00552     const int bottomMargin = 10;
00553     const int rightMargin = 10;
00554     if( cx >= 0 && cy >= 0 && m_lstResults.GetSafeHwnd()&& m_treeSearchHistory.GetSafeHwnd())
00555     {
00556         int bottomPos = (cy - bottomMargin) > 0 ? (cy - bottomMargin) : 0;
00557 
00558         int rightPos = (cx - rightMargin) > 0? (cx - rightMargin) : 0;
00559         
00560         CRect rectResultsList; m_lstResults.GetWindowRect( &rectResultsList); ScreenToClient( &rectResultsList);
00561         CRect rectPrevSearches;m_treeSearchHistory.GetWindowRect(rectPrevSearches); ScreenToClient(rectPrevSearches);
00562         
00563         //set search history tree to fixed width, it  will move to reflect
00564         //resizing but would have fixed width
00565         rectPrevSearches.bottom = bottomPos;
00566         rectPrevSearches.left = rightPos - rectPrevSearches.Width();
00567         rectPrevSearches.right =  rightPos;
00568 
00569         m_treeSearchHistory.SetWindowPos(NULL, rectPrevSearches.left, rectPrevSearches.top, rectPrevSearches.Width(), 
00570         rectPrevSearches.Height(), SWP_NOZORDER|SWP_SHOWWINDOW);
00571 
00572         //set the title to appropriate position
00573         //because search history changed its position the title "Previous Searches"
00574         //also needs to be moved
00575         CRect rectPrevSearchesTitle; 
00576         CWnd *prevSrchTitle = GetDlgItem (IDC_PREVSRCH_TITLE);
00577         prevSrchTitle->GetWindowRect(&rectPrevSearchesTitle);ScreenToClient(&rectPrevSearchesTitle);
00578 
00579         int width = rectPrevSearchesTitle.Width();
00580         rectPrevSearchesTitle.left = rectPrevSearches.left;
00581         rectPrevSearchesTitle.right = rectPrevSearchesTitle.left + width;
00582         prevSrchTitle->SetWindowPos(NULL, rectPrevSearchesTitle.left, rectPrevSearchesTitle.top, rectPrevSearchesTitle.Width(),
00583             rectPrevSearchesTitle.Height(), SWP_NOZORDER | SWP_SHOWWINDOW);
00584 
00585         //compute width for search results based on search history's location
00586         //search results list will be resized to take all the width after search history
00587         // is placed
00588         rectResultsList.bottom = bottomPos;
00589         rectResultsList.right = rectPrevSearches.left - 10;
00590 
00591         m_lstResults.SetWindowPos( NULL, rectResultsList.left, rectResultsList.top, rectResultsList.Width() , rectResultsList.Height(), SWP_NOMOVE|SWP_NOZORDER|SWP_SHOWWINDOW);
00592     }
00593 }
00594 
00595 void CSearchDlg::OnSizing(UINT fwSide, LPRECT pRect)
00596 {
00597     CDialog::OnSizing(fwSide, pRect);
00598     // GMESearch::OnSizing() responsible for preventing shrinking the window too much
00599 }
00600 
00601 void CSearchDlg::clickGo()
00602 {
00603     this->OnButtonGo();
00604 }
00605 
00606 void CSearchDlg::itemClicked()
00607 {
00608     long count = 0;
00609     if( results) COMTHROW(results->get_Count(&count));
00610 
00611     if(count > 0 ) //don't want to grab stuff out of an empty list
00612     {
00613 
00614         CWnd::UpdateData(TRUE);
00615 
00616         CSearchCtrl *TheCtrl = GetCtrl();
00617         try
00618         {
00619             TheCtrl->BeginTransaction();
00620 
00621             int selected = m_lstResults.GetSelectionMark() + 1; //IMgaFCOs 1 based, GetSelectionMark 0 based
00622             long lParam = m_lstResults.GetItemData(selected-1);
00623             CComPtr<IMgaFCO> selectedFCO;
00624             // selected might be 0 because GetSelectionMark might have returned -1
00625             if( selected >= 1 && selected <= count)
00626             {
00627                 COMTHROW(results->get_Item(lParam+1, &selectedFCO)); // crashed probably when called with 0
00628 
00629                 //want to be able to search for references to this object in the special search
00630                 CBstr bstr;
00631                 CString name;
00632                 COMTHROW( selectedFCO->get_Name(bstr));
00633                 name = CString( bstr) + _T(" References");
00634                 m_stcRefCtrl.SetWindowText(name);
00635                                 m_stcRefCtrl.ShowWindow(TRUE);
00636                 specialSearchFCO = selectedFCO;
00637             }
00638 
00639                         CComPtr<IMgaObjects> selectedObjects;
00640                         COMTHROW(selectedObjects.CoCreateInstance(L"Mga.MgaObjects", 0, CLSCTX_INPROC));
00641                         ForEachSelectedFCO([&](CComPtr<IMgaFCO> selected) {
00642                                 CComQIPtr<IMgaObject> selectedObject(selected);
00643                                 selectedObjects->Append(selectedObject);
00644                         });
00645                         
00646             TheCtrl->CommitTransaction();
00647             TheCtrl->ClickOnObject(selectedObjects);
00648         }
00649         catch( ...)
00650         {
00651             TheCtrl->AbortTransaction();
00652         }
00653     }
00654 }
00655 
00656 void CSearchDlg::itemDblClicked()
00657 {
00658     long count = 0;
00659     if( results) COMTHROW(results->get_Count(&count));
00660 
00661 
00662     if(count > 0 ) //don't want to grab stuff out of an empty list
00663     {
00664         CWnd::UpdateData(TRUE);
00665 
00666         CSearchCtrl *TheCtrl = GetCtrl();
00667         try
00668         {
00669             // non-model children of Folders can't be shown, only located
00670             bool must_do_locate = false;
00671 
00672             TheCtrl->BeginTransaction();
00673 
00674             int selected = m_lstResults.GetSelectionMark() + 1; //IMgaFCOs 1 based, GetSelectionMark 0 based
00675             //LVITEM lvItem;
00676             long lParam = m_lstResults.GetItemData(selected-1);
00677            // m_lstResults.GetItem(&lvItem);
00678             CComPtr<IMgaFCO> selectedFCO;
00679             // selected might be 0 because GeSelectionMark might have returned -1
00680             if( selected >= 1 && selected <= count)
00681             {
00682                 COMTHROW(results->get_Item(lParam+1,&selectedFCO)); // crashed probably when called with 0
00683             }
00684 
00685             //CComPtr<IMgaObject> selectedObject = (IMgaObject *)(selectedFCO.p); // WAS this the scapegoat?
00686             CComQIPtr<IMgaObject> selectedObject( selectedFCO);
00687             TheCtrl->CommitTransaction();
00688             if( selectedObject)
00689             {
00690                 TheCtrl->LocateMgaObject(selectedObject);
00691             }
00692         }
00693         catch(...)
00694         {
00695             TheCtrl->AbortTransaction();
00696         }
00697 
00698     }
00699 }
00700 
00701 //save search history in registry
00702 void CSearchDlg::SaveSearchHistory()
00703 {
00704     CRegKey key;
00705     std::wstringstream stream;
00706 
00707     //delete the key first and save new one
00708     if(key.Open(HKEY_CURRENT_USER,_T("Software\\GME"),KEY_ALL_ACCESS)==ERROR_SUCCESS)
00709     {
00710         key.DeleteSubKey(_T("Search"));
00711     }
00712     key.Create(HKEY_CURRENT_USER,_T("Software\\GME\\Search"));
00713     HTREEITEM hItem=m_treeSearchHistory.GetRootItem();
00714     int i=0;
00715     while(hItem && i<10)
00716     {
00717         //the search history are stored as search0, search1 etc 
00718         //form key string
00719         stream<<_T("search")<<i;
00720 
00721         //set the key and the value
00722         key.SetStringValue(stream.str().c_str(), m_treeSearchHistory.GetItemText(hItem));
00723 
00724         //clear the string stream
00725         stream.str(_T(""));
00726 
00727         //get next item to be saved
00728         hItem=m_treeSearchHistory.GetNextSiblingItem(hItem);
00729         i++;
00730 
00731     }
00732     key.Close();
00733 }
00734 
00735 void CSearchDlg::LoadSearchHistory()
00736 {
00737     CRegKey key;
00738     std::wstring strKeyName;
00739     std::wstringstream stream(strKeyName);
00740     ULONG length;
00741     TCHAR strValue[1000];
00742     //CString strValue;
00743 
00744     int i=0;
00745     if(key.Open(HKEY_CURRENT_USER,_T("Software\\GME\\Search"),KEY_ALL_ACCESS)==ERROR_SUCCESS)
00746     {
00747         while(i<10)
00748         {
00749             //form the key
00750             strKeyName=_T("search");
00751             stream<<int(i);
00752 
00753             //buffer size
00754             length=sizeof(strValue)/sizeof(strValue[0]);
00755 
00756             strKeyName+=stream.str();
00757 
00758             //query the key
00759             if(key.QueryStringValue(strKeyName.c_str(),strValue,&length)!=ERROR_SUCCESS)
00760                 break;
00761 
00762             //insert it in the tree control and combo boxes
00763             InsertHistory(strValue);
00764             stream.str(_T(""));
00765             i++;
00766         }
00767     }
00768 }
00769 
00770 
00771 //create search history text and insert it intt the tree control
00772 //called after the user clicks the search button and results are available
00773 
00774 void CSearchDlg::CreateSearchHistory()
00775 {
00776     //variable to store if criteria is empty
00777     bool firstCriteriaEmpty=false,secondCriteriaEmpty=false;
00778 
00779     InsertTextToControl(m_edtNameFirst,m_edtNameCtrlFirst);
00780     InsertTextToControl(m_edtRoleNameFirst,m_edtKindNameCtrlFirst);
00781     InsertTextToControl(m_edtKindNameFirst,m_edtKindNameCtrlFirst);
00782     InsertTextToControl(m_edtAttributeFirst,m_edtAttributeCtrlFirst);
00783 
00784     InsertTextToControl(m_edtNameSecond,m_edtNameCtrlSecond);
00785     InsertTextToControl(m_edtRoleNameSecond,m_edtRoleNameCtrlSecond);
00786     InsertTextToControl(m_edtKindNameFirst,m_edtKindNameCtrlSecond);
00787     InsertTextToControl(m_edtAttributeSecond,m_edtAttributeCtrlSecond);
00788 
00789     //read the root item
00790     CString strFirstElement=m_treeSearchHistory.GetItemText(m_treeSearchHistory.GetRootItem());
00791     //insert an dummy item to the tree once the processing of search text is complete
00792     //it will be renamed to appropriate one
00793     HTREEITEM hItem=m_treeSearchHistory.InsertItem(_T("Dummy"),NULL,TVI_FIRST);
00794 
00795     CString strSearch;
00796 
00797     if(m_edtNameFirst!=_T("") || m_edtKindNameFirst!=_T("") || m_edtRoleNameFirst!=_T("") || m_edtAttributeFirst!=_T(""))
00798     {
00799         HTREEITEM hFirstCriteria=m_treeSearchHistory.InsertItem(_T("First Search Criteria"),hItem,TVI_FIRST);
00800         //First criteria
00801         PrepareHistoryString(_T("Name"),m_edtNameFirst,hFirstCriteria,strSearch);
00802         PrepareHistoryString(_T("Role"),m_edtRoleNameFirst,hFirstCriteria,strSearch);
00803         PrepareHistoryString(_T("Kind"),m_edtKindNameFirst,hFirstCriteria,strSearch);
00804         PrepareHistoryString(_T("Attribute"),m_edtAttributeFirst,hFirstCriteria,strSearch);
00805     }
00806     else
00807     {
00808         firstCriteriaEmpty=true;
00809     }
00810 
00811 
00812     //search criteria separator
00813 
00814     //strSearch.Append(_T(":"));
00815     if(m_edtNameSecond!=_T("") || m_edtKindNameSecond!=_T("") || m_edtRoleNameSecond!=_T("") || m_edtAttributeSecond!=_T(""))
00816     {
00817         HTREEITEM hSecondCriteria=m_treeSearchHistory.InsertItem(_T("Second Search Criteria"),hItem,TVI_LAST);
00818 
00819         //second criteria
00820         PrepareHistoryString(_T("Second Name"),m_edtNameSecond,hSecondCriteria,strSearch);
00821         PrepareHistoryString(_T("Second Role"),m_edtRoleNameSecond,hSecondCriteria,strSearch);
00822         PrepareHistoryString(_T("Second Kind"),m_edtKindNameSecond,hSecondCriteria,strSearch);
00823         PrepareHistoryString(_T("Second Attribute"),m_edtAttributeSecond,hSecondCriteria,strSearch);
00824     }
00825     else
00826     {
00827         secondCriteriaEmpty=true;
00828     }
00829 
00830     //others
00831     HTREEITEM hOtherCriteria=m_treeSearchHistory.InsertItem(_T("Others"),hItem,TVI_LAST);
00832     PrepareHistoryString(_T("Logical"),m_radioLogical,hOtherCriteria,strSearch);
00833     PrepareHistoryString(_T("Model"),m_chkMod,hOtherCriteria,strSearch);
00834     PrepareHistoryString(_T("Atom"),m_chkAtom,hOtherCriteria,strSearch);
00835     PrepareHistoryString(_T("Set"),m_chkSet,hOtherCriteria,strSearch);
00836     PrepareHistoryString(_T("Reference"),m_chkRef,hOtherCriteria,strSearch);
00837     PrepareHistoryString(_T("Connection"),m_chkConnection,hOtherCriteria,strSearch);
00838     PrepareHistoryString(_T("Special"),m_chkSplSearch,hOtherCriteria,strSearch);
00839     PrepareHistoryString(_T("Case"),m_chkMatchCase,hOtherCriteria,strSearch);
00840     PrepareHistoryString(_T("WholeWord"),m_chkFullWord,hOtherCriteria,strSearch);
00841     PrepareHistoryString(_T("Scope"),m_radioScope,hOtherCriteria,strSearch);
00842     PrepareHistoryString(_T("Results"),m_searchResults,hOtherCriteria,strSearch);
00843 
00844     m_treeSearchHistory.SetItemText(hItem,strSearch);
00845 
00846     //Get first element from the previous history or check if both the criteria
00847     //are empty, if they are same the history is not added
00848     if(strFirstElement==strSearch || (firstCriteriaEmpty && secondCriteriaEmpty))
00849     {
00850         m_treeSearchHistory.DeleteItem(hItem);
00851         return;
00852     }
00853 
00854     //for now it allows keeping unlimited history while the program is running
00855     //once the program is reloaded only 10 history items are allowed
00856 }
00857 
00858 //this is used for inserting history text to combo boxes
00859 //it first checks if the first element in the combobox is same
00860 //as the element to be inserted, if not it adds to the combo comtrol
00861 
00862 void CSearchDlg::InsertTextToControl(CString& strNewTerm,CComboBox& control)
00863 {
00864     CString strTerm;
00865     int n=control.GetLBTextLen(0);
00866     n=n==-1?1:n;
00867     control.GetLBText(0,strTerm.GetBuffer(n));
00868     if (strNewTerm!=_T("") && strNewTerm!=strTerm) control.InsertString(0,strNewTerm);
00869 }
00870 
00871 //prepares history string it is of the form
00872 //<name>=<search term/text>
00873 //combined with ',' for a seacrh criteria, search criterias are separated by ':'
00874 //it also adds child to the tree control
00875 void CSearchDlg::PrepareHistoryString(const CString &strCriteriaName,CString & strSearchValue,HTREEITEM hParent,CString &strSearch)
00876 {
00877     CString strNameValue;
00878     if(strSearchValue.Trim()==_T(""))
00879         return;
00880     if(strSearch.GetLength()>0)
00881         strSearch.Append(_T(", "));
00882 
00883     strNameValue.Append(strCriteriaName);
00884     strNameValue.Append(_T("="));
00885     strNameValue.Append(_T("\""));
00886     strNameValue.Append(strSearchValue);
00887     strNameValue.Append(_T("\""));
00888 
00889     strSearch.Append(strNameValue);
00890 
00891     m_treeSearchHistory.InsertItem(strNameValue,hParent,NULL);
00892 }
00893 
00894 void CSearchDlg::PrepareHistoryString(const CString &strCriteriaName,int & strSearchValue,HTREEITEM hParent,CString &strSearch)
00895 {
00896     TCHAR buffer[10];
00897     _itot(strSearchValue,buffer,10);
00898     PrepareHistoryString(strCriteriaName,CString(buffer),hParent,strSearch);
00899 
00900 }
00901 
00902 
00903 void CSearchDlg::InsertHistory(CString strHistory)
00904 {
00905     //insert at the top of combobox
00906 
00907     // For each combobox control check if the current text is not empty
00908     //and is current text equals previous search text.
00909     //if above consitions are true don't insert into combo history
00910     //otherwise insert. This doesn't stop from combo box containing same texts and multiple places
00911     //becaseu it doesn't check whole list of texts
00912     //if more than 10 elments exists in the combo box delete it as well
00913 
00914     CString readValue;
00915 
00916     HTREEITEM hItem=m_treeSearchHistory.InsertItem(_T("Dummy"),NULL,TVI_LAST);
00917     HTREEITEM hFirstCriteria=m_treeSearchHistory.InsertItem(_T("First Search Criteria"),hItem,TVI_FIRST);
00918     HTREEITEM hSecondCriteria=m_treeSearchHistory.InsertItem(_T("Second Search Criteria"),hItem,TVI_LAST);
00919     HTREEITEM hOtherCriteria=m_treeSearchHistory.InsertItem(_T("Other"),hItem,TVI_LAST);
00920 
00921     CString strSearch;
00922 
00923     ReadHistoryValue(_T("Name"),strHistory,readValue);
00924     InsertTextToControl(readValue,m_edtNameCtrlFirst);
00925     PrepareHistoryString(CString(_T("Name")),readValue,hFirstCriteria,strSearch);
00926 
00927     ReadHistoryValue(_T("Role"),strHistory,readValue);
00928     InsertTextToControl(readValue,m_edtRoleNameCtrlFirst);
00929     PrepareHistoryString(CString(_T("Role")),readValue,hFirstCriteria,strSearch);
00930 
00931     ReadHistoryValue(_T("Kind"),strHistory,readValue);
00932     InsertTextToControl(readValue,m_edtKindNameCtrlFirst);
00933     PrepareHistoryString(CString(_T("Kind")),readValue,hFirstCriteria,strSearch);
00934 
00935     ReadHistoryValue(_T("Attribute"),strHistory,readValue);
00936     InsertTextToControl(readValue,m_edtAttributeCtrlFirst);
00937     PrepareHistoryString(CString(_T("Attribute")),readValue,hFirstCriteria,strSearch);
00938 
00939     //if no first search criteria items are there delete it
00940     int length=strSearch.GetLength();
00941     if(length==0)
00942         m_treeSearchHistory.DeleteItem(hFirstCriteria);
00943 
00944     //search criteria separator
00945     //strSearch.Append(_T(":"));
00946 
00947     ReadHistoryValue(_T("Second Name"),strHistory,readValue);
00948     InsertTextToControl(readValue,m_edtNameCtrlSecond);
00949     PrepareHistoryString(CString(_T("Second Name")),readValue,hSecondCriteria,strSearch);
00950 
00951     ReadHistoryValue(_T("Second Role"),strHistory,readValue);
00952     InsertTextToControl(readValue,m_edtRoleNameCtrlSecond);
00953     PrepareHistoryString(CString(_T("Second Role")),readValue,hSecondCriteria,strSearch);
00954 
00955     ReadHistoryValue(_T("Second Kind"),strHistory,readValue);
00956     InsertTextToControl(readValue,m_edtKindNameCtrlSecond);
00957     PrepareHistoryString(CString(_T("Second Kind")),readValue,hSecondCriteria,strSearch);
00958 
00959     ReadHistoryValue(_T("Second Attribute"),strHistory,readValue);
00960     InsertTextToControl(readValue,m_edtAttributeCtrlSecond);
00961     PrepareHistoryString(CString(_T("Second Attribute")),readValue,hSecondCriteria,strSearch);
00962 
00963     //check if second search criteria has been added
00964     length=strSearch.GetLength()-length;
00965     if(length==0)
00966          m_treeSearchHistory.DeleteItem(hSecondCriteria);
00967 
00968 
00969     ReadHistoryValue(_T("Logical"),strHistory,m_radioLogical);
00970     PrepareHistoryString(_T("Logical"),m_radioLogical,hOtherCriteria,strSearch);
00971 
00972     ReadHistoryValue(_T("Model"),strHistory,m_chkMod);
00973     PrepareHistoryString(_T("Model"),m_chkMod,hOtherCriteria,strSearch);
00974 
00975     ReadHistoryValue(_T("Atom"),strHistory,m_chkAtom);
00976     PrepareHistoryString(_T("Atom"),m_chkAtom,hOtherCriteria,strSearch);
00977 
00978     ReadHistoryValue(_T("Set"),strHistory,m_chkSet);
00979     PrepareHistoryString(_T("Set"),m_chkSet,hOtherCriteria,strSearch);
00980 
00981     ReadHistoryValue(_T("Reference"),strHistory,m_chkRef);
00982     PrepareHistoryString(_T("Reference"),m_chkRef,hOtherCriteria,strSearch);
00983 
00984     ReadHistoryValue(_T("Connection"),strHistory,m_chkConnection);
00985     PrepareHistoryString(_T("Connection"),m_chkConnection,hOtherCriteria,strSearch);
00986 
00987     ReadHistoryValue(_T("Special"),strHistory,m_chkSplSearch);
00988     PrepareHistoryString(_T("Special"),m_chkSplSearch,hOtherCriteria,strSearch);
00989 
00990     ReadHistoryValue(_T("Case"),strHistory,m_chkMatchCase);
00991     PrepareHistoryString(_T("Case"),m_chkMatchCase,hOtherCriteria,strSearch);
00992 
00993     ReadHistoryValue(_T("WholeWord"),strHistory,m_chkFullWord);
00994     PrepareHistoryString(_T("WholeWord"),m_chkFullWord,hOtherCriteria,strSearch);
00995 
00996     ReadHistoryValue(_T("Scope"),strHistory,m_radioScope);
00997     PrepareHistoryString(_T("Scope"),m_radioScope,hOtherCriteria,strSearch);
00998 
00999     ReadHistoryValue(_T("Results"),strHistory,m_searchResults);
01000     PrepareHistoryString(_T("Results"),m_searchResults,hOtherCriteria,strSearch);
01001 
01002     m_treeSearchHistory.SetItemText(hItem,strSearch);
01003 
01004     UpdateData(FALSE); 
01005 }
01006 
01007 //parse the search string to read a particular value
01008 //first it looks for the criteria name
01009 //when found takes the string after that as the value
01010 //the quotes and commas are removed, 2 search criterias are differentiated by ':'
01011 void CSearchDlg::ReadHistoryValue(const CString &strCriteriaName, CString &strHistory, CString &strValue)
01012 {
01013     //clear the output string
01014     strValue=_T("");
01015     CString strTemp(strCriteriaName);
01016     strTemp.Append(_T("="));
01017     int indexText,indexComma;
01018     indexText=strHistory.Find(strTemp);
01019     if(indexText==-1) return;
01020     indexComma=strHistory.Find(_T(","),indexText);
01021     indexComma=indexComma==-1?strHistory.GetLength():indexComma;
01022     int start=indexText + strTemp.GetLength()+1;
01023     strValue=strHistory.Mid(start,indexComma-start-1);
01024 
01025 }
01026 
01027 void CSearchDlg::ReadHistoryValue(const CString &strCriteriaName,CString &strHistory, int &value)
01028 {
01029     CString strValue;
01030     ReadHistoryValue(strCriteriaName,strHistory,strValue);
01031     value=_ttoi(strValue.GetBuffer());
01032 }
01033 
01034 void CSearchDlg::SearchResults()
01035 {
01036         if (results == nullptr)
01037                 return;
01038     CSearchCtrl *TheCtrl = GetCtrl();
01039     CComPtr<IMgaProject> ccpProject = TheCtrl->GetProject();
01040     m_pgsSearch.ShowWindow(SW_RESTORE);
01041     TheCtrl->BeginTransaction();
01042 
01043     CComPtr<IMgaObjects> ccpObjectsInTerr = TheCtrl->PutInMyTerritory( TheCtrl->GetScopedL());
01044     CComPtr<IMgaFCOs> new_results;
01045     COMTHROW(new_results.CoCreateInstance(L"Mga.MgaFCOs"));;
01046     CInput inp;
01047     inp.GetInput(m_edtNameFirst,m_edtRoleNameFirst,m_edtKindNameFirst,m_edtAttributeFirst,m_edtNameSecond,m_edtRoleNameSecond,m_edtKindNameSecond,m_edtAttributeSecond,m_edtAttrValue,
01048         m_chkMod,m_chkAtom,m_chkRef,m_chkSet,m_chkConnection,m_chkSplSearch,m_chkFullWord,NULL,0,m_chkMatchCase,m_radioScope,m_radioLogical
01049         );
01050 
01051     CSearch searchGME(inp);
01052     searchGME.SearchResults(results,new_results,&m_pgsSearch);
01053     results=new_results;
01054     m_pgsSearch.ShowWindow(SW_HIDE);
01055     m_pgsSearch.SetPos(1);
01056     DisplayResults();
01057     TheCtrl->CommitTransaction();
01058 }
01059 
01060 CSearchDlg::~CSearchDlg()
01061 {
01062     specialSearchFCO = NULL;
01063 }
01064 
01065 void CSearchDlg::OnNMDblclkTreeSearchHistory(NMHDR *pNMHDR, LRESULT *pResult)
01066 {
01067     CString strSearchText;
01068     HTREEITEM hItem=m_treeSearchHistory.GetSelectedItem();
01069     HTREEITEM hParent=m_treeSearchHistory.GetParentItem(hItem);
01070     HTREEITEM hGrandParent=m_treeSearchHistory.GetParentItem(hParent);
01071 
01072     if(hGrandParent)
01073         strSearchText=m_treeSearchHistory.GetItemText(hGrandParent);
01074     else if(hParent)
01075         strSearchText=m_treeSearchHistory.GetItemText(hParent);
01076     else
01077         strSearchText=m_treeSearchHistory.GetItemText(hItem);
01078 
01079     //first search criteria
01080     ReadHistoryValue(_T("Name"),strSearchText,m_edtNameFirst);
01081     ReadHistoryValue(_T("Role"),strSearchText,m_edtRoleNameFirst);
01082     ReadHistoryValue(_T("Kind"),strSearchText,m_edtKindNameFirst);
01083     ReadHistoryValue(_T("Attribute"),strSearchText,m_edtAttributeFirst);
01084 
01085     //second search criteria
01086     ReadHistoryValue(_T("Second Name"),strSearchText,m_edtNameSecond);
01087     ReadHistoryValue(_T("Second Role"),strSearchText,m_edtRoleNameSecond);
01088     ReadHistoryValue(_T("Second Kind"),strSearchText,m_edtKindNameSecond);
01089     ReadHistoryValue(_T("Second Attribute"),strSearchText,m_edtAttributeSecond);
01090 
01091     //others ReadHistoryValue(_T("Logical"),strHistory,m_radioLogical);
01092     ReadHistoryValue(_T("Model"),strSearchText,m_chkMod);
01093     ReadHistoryValue(_T("Atom"),strSearchText,m_chkAtom);
01094     ReadHistoryValue(_T("Set"),strSearchText,m_chkSet);
01095     ReadHistoryValue(_T("Reference"),strSearchText,m_chkRef);
01096     ReadHistoryValue(_T("Connection"),strSearchText,m_chkConnection);
01097     ReadHistoryValue(_T("Special"),strSearchText,m_chkSplSearch);
01098     ReadHistoryValue(_T("Case"),strSearchText,m_chkMatchCase);
01099     ReadHistoryValue(_T("WholeWord"),strSearchText,m_chkFullWord);
01100     ReadHistoryValue(_T("Scope"),strSearchText,m_radioScope);
01101     ReadHistoryValue(_T("Results"),strSearchText,m_searchResults);
01102 
01103     UpdateData(FALSE);  
01104      // if special search is on disable search for others than reference
01105     if(m_chkSplSearch)
01106     {
01107         OnCheckSplSearch();
01108     }
01109     else
01110     {
01111         m_chkModCtrl.EnableWindow(TRUE);
01112                 m_chkAtomCtrl.EnableWindow(TRUE);
01113                 m_chkSetCtrl.EnableWindow(TRUE);
01114                 m_chkRefCtrl.EnableWindow(TRUE);
01115         m_chkConnCtrl.EnableWindow(TRUE);
01116     }
01117     *pResult = 0;
01118 }
01119 
01120 void CSearchDlg::OnCheckSplSearch()
01121 {
01122     CWnd::UpdateData(TRUE);
01123 
01124         if(m_chkSplSearch)
01125         {
01126                 m_chkMod = FALSE;
01127                 m_chkAtom = FALSE;
01128                 m_chkSet = FALSE;
01129         m_chkConnection = FALSE;
01130                 m_chkRef = TRUE;
01131 
01132                 m_chkModCtrl.EnableWindow(FALSE);
01133                 m_chkAtomCtrl.EnableWindow(FALSE);
01134                 m_chkSetCtrl.EnableWindow(FALSE);
01135                 m_chkRefCtrl.EnableWindow(FALSE);
01136         m_chkConnCtrl.EnableWindow(FALSE);
01137                 CWnd::UpdateData(FALSE);
01138         }
01139         else
01140         {
01141                 m_chkMod = TRUE;
01142                 m_chkAtom = TRUE;
01143                 m_chkSet = TRUE;
01144                 m_chkRef = TRUE;
01145         m_chkConnection=TRUE;
01146 
01147                 m_chkModCtrl.EnableWindow(TRUE);
01148                 m_chkAtomCtrl.EnableWindow(TRUE);
01149                 m_chkSetCtrl.EnableWindow(TRUE);
01150                 m_chkRefCtrl.EnableWindow(TRUE);
01151         m_chkConnCtrl.EnableWindow(TRUE);
01152                 CWnd::UpdateData(FALSE);
01153 
01154                 //reset special reference search to NULL
01155                 specialSearchFCO = NULL;
01156                 m_stcRefCtrl.SetWindowText(_T("NULL References"));
01157                 m_stcRefCtrl.ShowWindow(TRUE);
01158                 CWnd::UpdateData(TRUE);
01159         }
01160 }
01161 
01162 void CSearchDlg::OnLvnColumnclickListresults(NMHDR *pNMHDR, LRESULT *pResult)
01163 {
01164     LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
01165     
01166     //create the sort param that needs to be passed to sort function
01167     SortParam param(&m_lstResults,pNMLV->iSubItem,ascending[pNMLV->iSubItem]);
01168    
01169     //sort the items
01170     ListView_SortItemsEx(m_lstResults.GetSafeHwnd(), ListItemCompareProc, (LPARAM) &param);
01171 
01172    ascending[pNMLV->iSubItem] = !ascending[pNMLV->iSubItem];
01173     *pResult = 0;
01174 }
01175 
01176 void CSearchDlg::OnBnClickedButtonClear()
01177 {
01178     m_treeSearchHistory.DeleteAllItems();
01179     SaveSearchHistory();
01180 }
01181 
01182 DROPEFFECT CSearchDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
01183 {
01184         CSearchDlg *ctrl = STATIC_DOWNCAST(CSearchDlg, pWnd);
01185         CSearchCtrl *TheCtrl = ctrl->GetCtrl();
01186         if (CGMEDataSource::IsGmeNativeDataAvailable(pDataObject, TheCtrl->GetProject()))
01187         {
01188                 return DROPEFFECT_LINK;
01189         }
01190         return DROPEFFECT_NONE;
01191 }
01192 
01193 void CSearchDropTarget::OnDragLeave(CWnd* pWnd)
01194 {
01195 }
01196 
01197 DROPEFFECT CSearchDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
01198 {
01199         CSearchDlg *ctrl = STATIC_DOWNCAST(CSearchDlg, pWnd);
01200         CSearchCtrl *TheCtrl = ctrl->GetCtrl();
01201         if (CGMEDataSource::IsGmeNativeDataAvailable(pDataObject, TheCtrl->GetProject()))
01202         {
01203                 return DROPEFFECT_LINK;
01204         }
01205         return DROPEFFECT_NONE;
01206 }
01207 
01208 BOOL CSearchDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
01209 {
01210         COMTRY {
01211         CSearchDlg *ctrl = STATIC_DOWNCAST(CSearchDlg, pWnd);
01212         CSearchCtrl *TheCtrl = ctrl->GetCtrl();
01213         if (CGMEDataSource::IsGmeNativeDataAvailable(pDataObject, TheCtrl->GetProject()))
01214         {
01215                 
01216                 CComPtr<IDataObject> p = pDataObject->GetIDataObject(FALSE);
01217                 CComPtr<IMgaDataSource> pt;
01218                 COMTHROW(p.QueryInterface(&pt));
01219 
01220                 CComPtr<IUnknown> unk;
01221                 COMTHROW(pt->get_Data(&unk));
01222 
01223                 CComPtr<IMgaFCOs> fcos;
01224                 // CComPtr<IMgaMetaRole> metaRole; TODO: put Kind or Role based on partbrowser drag-n-drop
01225                 if (SUCCEEDED(unk.QueryInterface(&fcos)))
01226                 {
01227                         CComPtr<IMgaFCO> fco;
01228                         long count = 0;
01229                         if (SUCCEEDED(fcos->get_Count(&count)) && count > 0)
01230                         {
01231                                 COMTHROW(fcos->get_Item(1, &fco));
01232                         }
01233                         if (fco == nullptr)
01234                         {
01235                                 return FALSE;
01236                         }
01237 
01238                         CWnd *dropTarget = ctrl->ChildWindowFromPoint(point);
01239                         CWnd *editKind = STATIC_DOWNCAST(CButton, ctrl->GetDlgItem(IDC_EDITKIND));
01240                         CWnd *editRole = STATIC_DOWNCAST(CButton, ctrl->GetDlgItem(IDC_EDITROLE));
01241                         CWnd *editName = STATIC_DOWNCAST(CButton, ctrl->GetDlgItem(IDC_EDITNAME));
01242                         if (dropTarget->GetSafeHwnd() == editKind->GetSafeHwnd())
01243                         {
01244                                 TheCtrl->BeginTransaction();
01245                                 try
01246                                 {
01247                                         CComPtr<IMgaMetaFCO> meta;
01248                                         COMTHROW(fco->get_Meta(&meta));
01249                                         _bstr_t kind;
01250                                         COMTHROW(meta->get_Name(kind.GetAddress()));
01251                                         editKind->SetWindowTextW(static_cast<const wchar_t*>(kind));
01252                                         TheCtrl->CommitTransaction();
01253                                 }
01254                                 catch (hresult_exception)
01255                                 {
01256                                         TheCtrl->AbortTransaction();
01257                                         throw;
01258                                 }
01259                         }
01260                         else if (dropTarget->GetSafeHwnd() == editRole->GetSafeHwnd())
01261                         {
01262                                 try
01263                                 {
01264                                         TheCtrl->BeginTransaction();
01265                                         CComPtr<IMgaMetaRole> meta;
01266                                         COMTHROW(fco->get_MetaRole(&meta));
01267                                         _bstr_t rolename;
01268                                         COMTHROW(meta->get_Name(rolename.GetAddress()));
01269                                         editRole->SetWindowTextW(static_cast<const wchar_t*>(rolename));
01270                                         TheCtrl->CommitTransaction();
01271                                 }
01272                                 catch (hresult_exception)
01273                                 {
01274                                         TheCtrl->AbortTransaction();
01275                                         throw;
01276                                 }
01277                         }
01278                         else if (dropTarget->GetSafeHwnd() == editName->GetSafeHwnd())
01279                         {
01280                                 TheCtrl->BeginTransaction();
01281                                 try
01282                                 {
01283                                         _bstr_t name;
01284                                         COMTHROW(fco->get_Name(name.GetAddress()));
01285                                         editName->SetWindowTextW(static_cast<const wchar_t*>(name));
01286                                         TheCtrl->CommitTransaction();
01287                                 }
01288                                 catch (hresult_exception)
01289                                 {
01290                                         TheCtrl->AbortTransaction();
01291                                         throw;
01292                                 }
01293                         }
01294                         else
01295                         {
01296                                 ctrl->results = NULL;
01297                                 COMTHROW(ctrl->results.CoCreateInstance(L"Mga.MgaFCOs"));
01298                                 COMTHROW(ctrl->results->Append(fco));
01299                                 TheCtrl->BeginTransaction();
01300                                 try
01301                                 {
01302                                         ctrl->DisplayResults();
01303                                         TheCtrl->CommitTransaction();
01304                                         ctrl->m_lstResults.SetFocus();
01305                                         int ind = ctrl->m_lstResults.GetTopIndex();
01306                                         VERIFY(ctrl->m_lstResults.SetItemState(ind, LVIS_SELECTED, LVIS_SELECTED));
01307                                         ctrl->m_lstResults.SetSelectionMark(ind);
01308                                         ctrl->itemClicked();
01309                                         CButton *special_check = STATIC_DOWNCAST(CButton, ctrl->GetDlgItem(IDC_CHECKSPLSEARCH));
01310                                         special_check->SetCheck(TRUE);
01311                                         ctrl->OnCheckSplSearch();
01312                                 }
01313                                 catch (hresult_exception)
01314                                 {
01315                                         TheCtrl->AbortTransaction();
01316                                         throw;
01317                                 }
01318                         }
01319 
01320                         return TRUE;
01321                 }
01322         }
01323         return FALSE;
01324         } COMCATCH(return FALSE;)
01325 }