GME  13
InPlaceManager.cpp
Go to the documentation of this file.
00001 // InPlaceManager.cpp: implementation of the CInPlaceManager class.
00002 //
00004 
00005 #include "stdafx.h"
00006 #include "InspectorList.h"
00007 #include "objectinspector.h"
00008 #include "InPlaceManager.h"
00009 #include "CompassCheckDlg.h"
00010 #include "CompassOptDlg.h"
00011 #include "ComboBoxSelectDlg.h"
00012 #include "ColourPopup.h"
00013 #include "MgaUtil.h"
00014 
00015 #ifdef _DEBUG
00016 #undef THIS_FILE
00017 static char THIS_FILE[]=__FILE__;
00018 #define new DEBUG_NEW
00019 #endif
00020 
00022 // Construction/Destruction
00024 
00025 CInPlaceManager::CInPlaceManager(CInspectorList* pInspectorList)
00026 {
00027         m_pInspectorList=pInspectorList;
00028 }
00029 
00030 CInPlaceManager::~CInPlaceManager()
00031 {
00032 
00033 }
00034 
00035 void CInPlaceManager::ShowInPlace(CRect rectInPlace, int nIndex)
00036 {
00037 
00038         HideAllInPlace();
00039         int nSelCount=m_pInspectorList->GetSelCount();
00040         if(nSelCount!=1)
00041         {
00042                 return;
00043         }
00044 
00045         m_nCurrentIndex=nIndex;
00046 
00047         CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(nIndex);
00048 
00049         ListItem.Value.toString();
00050         switch(ListItem.Value.dataType)
00051         {
00052         case ITEMDATA_NULL:
00053                 {
00054 
00055                 }break;
00056 
00057         case ITEMDATA_STRING:
00058                 {
00059                         if(ListItem.Value.cLineNum>1)
00060                         {
00061                                 if(!ListItem.bIsReadOnly) {
00062                                         DisplayEditorButton(rectInPlace);
00063                                 }
00064 
00065                                 DisplayMultilineEdit(rectInPlace, ListItem.bIsReadOnly);
00066                                 CString strText; // zolmol modification
00067                                 int uLim = ListItem.Value.stringVal.GetUpperBound(); // if empty uLim == -1
00068                                 for(int i=0;i<=uLim;i++)
00069                                 {
00070                                         strText+=ListItem.Value.stringVal[i];
00071                                         if( i != uLim)
00072                                                 strText+=_T("\r\n");
00073                                 }
00074                                 // there is no newline at the end of the last line
00075                                 m_MultiEditCtrl.SetWindowText(strText);//WAS: strText.Left(strText.GetLength()-2)
00076                                 m_MultiEditCtrl.SetFocus();
00077                                 
00078                         }
00079                         else
00080                         {
00081                                 DisplaySingleLineEdit(rectInPlace, ListItem.bIsReadOnly);
00082 
00083                                 m_SingleEditCtrl.SetWindowText(ListItem.Value.stringVal[0]);
00084 
00085                                 int nLength=ListItem.Value.stringVal[0].GetLength();
00086                                 m_SingleEditCtrl.SetSel(nLength,nLength);
00087                         }
00088 
00089                 }break;
00090 
00091 
00092         case ITEMDATA_FIXED_LIST:
00093                 {
00094                         if(!ListItem.bIsReadOnly) {
00095                                 DisplayArrowButton(rectInPlace);
00096                         }
00097 
00098                 }break;
00099 
00100 
00101         case ITEMDATA_INTEGER:
00102                 {
00103                         DisplaySingleLineEdit(rectInPlace, ListItem.bIsReadOnly);
00104 
00105                         m_SingleEditCtrl.SetWindowText(ListItem.Value.stringVal[0]);
00106                         int nLength=ListItem.Value.stringVal[0].GetLength();
00107                         m_SingleEditCtrl.SetSel(nLength,nLength);
00108 
00109 
00110                 }break;
00111         case ITEMDATA_DOUBLE:
00112                 {
00113                         DisplaySingleLineEdit(rectInPlace, ListItem.bIsReadOnly);
00114 
00115                         m_SingleEditCtrl.SetWindowText(ListItem.Value.stringVal[0]);
00116                         int nLength=ListItem.Value.stringVal[0].GetLength();
00117                         m_SingleEditCtrl.SetSel(nLength,nLength);
00118 
00119 
00120                 }break;
00121         case ITEMDATA_BOOLEAN:
00122                 {
00123                         if(!ListItem.bIsReadOnly) {
00124                                 DisplayArrowButton(rectInPlace);
00125                         }
00126                 }break;
00127 
00128         case ITEMDATA_COLOR     :
00129                 {
00130                         if(!ListItem.bIsReadOnly) {
00131                                 DisplayArrowButton(rectInPlace);
00132                         }
00133                 }break;
00134 
00135         case ITEMDATA_COMPASS:
00136                 {
00137                         if(!ListItem.bIsReadOnly) {
00138                                 DisplayArrowButton(rectInPlace);
00139                         }
00140                 }break;
00141 
00142         case ITEMDATA_COMPASS_EXCL:
00143                 {
00144                         if(!ListItem.bIsReadOnly) {
00145                                 DisplayArrowButton(rectInPlace);
00146                         }
00147                 }break;
00148         }
00149 }
00150 
00151 void CInPlaceManager::DisplayMultilineEdit(CRect rectBound, bool readOnly)
00152 {
00153 
00154         rectBound.bottom--;
00155         rectBound.bottom--;
00156 
00157         if(!::IsWindow(m_MultiEditCtrl.GetSafeHwnd()))
00158         {
00159                 m_MultiEditCtrl.Create(ES_WANTRETURN|ES_AUTOVSCROLL |WS_VSCROLL|ES_MULTILINE | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE |ES_LEFT,rectBound,m_pInspectorList,IDC_EDITBOX_MULTILINE);
00160 
00161 
00162                 m_MultiEditCtrl.SetFont(&m_pInspectorList->m_entryFont);
00163                 m_MultiEditCtrl.SetFocus();
00164         }
00165         else
00166         {
00167                 if(!m_MultiEditCtrl.IsWindowVisible())
00168                 {
00169                         m_MultiEditCtrl.MoveWindow(rectBound.left,rectBound.top,rectBound.Width(),rectBound.Height());
00170                         m_MultiEditCtrl.ShowWindow(SW_SHOW);
00171                         // m_MultiEditCtrl.SetFocus();
00172                 }
00173                 else
00174                 {
00175                         m_MultiEditCtrl.SetFocus();
00176                         m_MultiEditCtrl.Invalidate();
00177                 }
00178         }
00179         m_MultiEditCtrl.SetReadOnly(readOnly ? TRUE : FALSE);
00180 }
00181 
00182 
00183 void CInPlaceManager::DisplaySingleLineEdit(CRect rectBound, bool readOnly)
00184 {
00185 
00186         rectBound.bottom--;
00187         rectBound.bottom--;
00188 
00189         if(!::IsWindow(m_SingleEditCtrl.GetSafeHwnd()))
00190         {
00191                 m_SingleEditCtrl.Create(WS_CHILD| WS_VISIBLE|ES_AUTOHSCROLL|ES_LEFT,rectBound,m_pInspectorList,IDC_EDITBOX_SINGLELINE);
00192                 
00193                 
00194                 m_SingleEditCtrl.SetFont(&m_pInspectorList->m_entryFont);
00195                 m_SingleEditCtrl.SetFocus();
00196 
00197         }
00198         else
00199         {
00200                 if(!m_SingleEditCtrl.IsWindowVisible())
00201                 {
00202                         m_SingleEditCtrl.SetWindowText(_T(""));
00203                         m_SingleEditCtrl.MoveWindow(rectBound.left,rectBound.top,rectBound.Width(),rectBound.Height());
00204                         m_SingleEditCtrl.ShowWindow(SW_SHOW);
00205                         m_SingleEditCtrl.SetFocus();
00206                 }
00207                 else
00208                 {
00209                         m_SingleEditCtrl.SetFocus();
00210                         m_SingleEditCtrl.Invalidate();
00211                 }
00212         }
00213         m_SingleEditCtrl.SetReadOnly(readOnly ? TRUE : FALSE);
00214 }
00215 
00216 void CInPlaceManager::DisplayColorCombo(CRect rectBound, bool rightSideClick)
00217 {
00218         m_pInspectorList->ClientToScreen(rectBound);
00219 
00220         CListItem &ListItem= m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex);
00221 
00222         CColourPopup dlg(m_pInspectorList);
00223         dlg.SetParameters(rectBound,                            // rect to display popup
00224                                           ListItem.Value.colorVal,      // Selected colour
00225                                           rightSideClick,                       // summoned by arrow button click or right side click
00226                                           _T("Default"),                        // "Default" text area
00227                                           _T("More Colors.."));         // Custom Text
00228 
00229         if(dlg.DoModal()==IDOK)
00230         {
00231                 if (dlg.m_nCurrentSel == DEFAULT_BOX_VALUE)
00232                 {
00233                         ListItem.RestoreDefault();
00234                 }
00235                 else
00236                 {
00237                         ListItem.Value.SetColorValue(dlg.GetSelectedColor());
00238                         ListItem.SetDirty();
00239                 }
00240 
00241                 m_pInspectorList->NotifyParent(m_nCurrentIndex);
00242 
00243                 m_pInspectorList->Invalidate();
00244         }
00245 
00246         m_pInspectorList->SetFocus();
00247 }
00248 
00249 
00250 
00251 
00252 
00253 void CInPlaceManager::HideAllInPlace()
00254 {
00255         HideEdit();
00256         HideArrowButton();
00257         HideEditorButton();
00258 }
00259 
00260 
00261 void CInPlaceManager::HideEdit()
00262 {
00263         if(::IsWindow(m_SingleEditCtrl.GetSafeHwnd()))
00264         {
00265                 m_SingleEditCtrl.ShowWindow(SW_HIDE);
00266         }
00267 
00268         if(::IsWindow(m_MultiEditCtrl.GetSafeHwnd()))
00269         {
00270                 m_MultiEditCtrl.ShowWindow(SW_HIDE);
00271         }
00272 }
00273 
00274 
00275 void CInPlaceManager::DisplayArrowButton(CRect rectBound)
00276 {
00277         rectBound.top--;
00278         rectBound.bottom--;
00279         rectBound.top--;
00280         rectBound.bottom--;
00281 
00282         rectBound.left=rectBound.right-rectBound.Height();
00283         if(!::IsWindow(m_ArrowButton.GetSafeHwnd()) )
00284         {
00285                 m_ArrowButton.Create(_T("ArrowButton"),WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,rectBound,m_pInspectorList,IDC_ARROW_BUTTON);
00286         }
00287         else
00288         {
00289                 m_ArrowButton.MoveWindow(rectBound.left,rectBound.top,rectBound.Width(),rectBound.Height());
00290                 m_ArrowButton.ShowWindow(SW_SHOW);
00291         }
00292 
00293         m_ArrowButton.Invalidate();
00294 }
00295 
00296 void CInPlaceManager::DisplayEditorButton(CRect rectBound)
00297 {
00298         // Get External Editor prefs and display editor button if needed
00299         CComPtr<IMgaRegistrar> registrar;
00300         try {
00301                 COMTHROW( registrar.CoCreateInstance(OLESTR("MGA.MgaRegistrar")) );
00302                 ASSERT( registrar != NULL );
00303 
00304                 VARIANT_BOOL extenable;
00305                 COMTHROW( registrar->get_ExternalEditorEnabled(REGACCESS_USER, &extenable) );
00306                 if (extenable == VARIANT_FALSE) {
00307                         return;
00308                 }
00309         } 
00310         catch (hresult_exception &) {
00311                 return;
00312         }
00313 
00314 
00315         CBitmap bm;
00316         bm.LoadMappedBitmap(IDB_BITMAP_EDITOR);
00317 
00318         CSize bmSize;
00319         BITMAP bmStruct;
00320         if (bm.GetBitmap(&bmStruct)) {
00321                 bmSize.cx = bmStruct.bmWidth;
00322                 bmSize.cy = bmStruct.bmHeight;
00323         }
00324 
00325         CRect rect;
00326         rect.top = rectBound.top;
00327         rect.bottom = rect.top + bmSize.cy;
00328         rect.right = rectBound.left - 2;                // Shift it
00329         rect.left = rect.right - bmSize.cx;
00330 
00331         if(!::IsWindow(m_EditorButton.GetSafeHwnd()) )
00332         {
00333                 m_EditorButton.Create(_T("EditorButton"),WS_CHILD|WS_VISIBLE|BS_BITMAP,rect,m_pInspectorList,IDC_EDITOR_BUTTON);
00334                 m_EditorButton.SetBitmap(bm);
00335                 bm.Detach();
00336 
00337         }
00338         else
00339         {
00340                 m_EditorButton.MoveWindow(rect.left,rect.top,rect.Width(),rect.Height());
00341                 m_EditorButton.ShowWindow(SW_SHOW);
00342         }
00343 
00344         m_EditorButton.Invalidate();
00345 }
00346 
00347 
00348 void CInPlaceManager::HideArrowButton()
00349 {
00350         if(::IsWindowVisible(m_ArrowButton.GetSafeHwnd()) )
00351         {
00352                 m_ArrowButton.ShowWindow(SW_HIDE);
00353         }
00354 }
00355 
00356 void CInPlaceManager::HideEditorButton()
00357 {
00358         if(::IsWindowVisible(m_EditorButton.GetSafeHwnd()) )
00359         {
00360                 m_EditorButton.ShowWindow(SW_HIDE);
00361         }
00362 }
00363 
00364 void CInPlaceManager::OnClickEditorButton()
00365 {
00366         CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex);
00367         ASSERT(ListItem.Value.dataType == ITEMDATA_STRING);
00368         ASSERT(ListItem.Value.cLineNum > 1);
00369 
00370         // Create temporary file
00371         TCHAR szTempPath[MAX_PATH];
00372         if (::GetTempPath(MAX_PATH, szTempPath) == 0) {
00373                 return;
00374         }
00375 
00376         TCHAR szTempFileName[MAX_PATH];
00377         if (::GetTempFileName(szTempPath, _T("GME"), 0, szTempFileName) == 0) {
00378                 ASSERT(("Unable to get temporary filename.", false));
00379                 return;
00380         }
00381         
00382         CString szAppPath;
00383         bool content_specific_editor = false;
00384 
00385         if( !ListItem.strContentType.IsEmpty())
00386         {
00387                 CString extension;
00388                 bool content_type_valid = true;
00389                 if( ListItem.strContentType.GetAt(0) == _T('.')) // starts with '.' -> interpret it as extension
00390                         extension = ListItem.strContentType;
00391                 else // interpret it as MIME type (Content-Type), and lookup the extension corresponding to it
00392                         content_type_valid = CInPlaceManager::findInfoInMimeDB( ListItem.strContentType, szAppPath, extension);
00393         
00394                 if( content_type_valid) // remove the file created above by GetTempFileName
00395                         CFile::Remove( szTempFileName);
00396 
00397                 content_specific_editor = true;
00398                 // if enough space, append the extension to the filename
00399                 if( content_type_valid && _tcslen( szTempFileName) + extension.GetLength() <= MAX_PATH - 1) // there is enough room for appending the extension
00400                         _tcscat( szTempFileName, extension);
00401                 else if( content_type_valid && extension.GetLength() == 4) // replace tailing .tmp with extension
00402                         _tcsncpy( szTempFileName + _tcslen( szTempFileName) - 4, extension, 4);
00403                 else // can't use the content_specific_editor because the extension is not appended
00404                         content_specific_editor = false;
00405 
00406                 // we could use findCommand (implemented at bottom of file) to locate the command
00407                 // assigned for open/edit verbs, but we choose to rely on the ShellExecute call
00408                 //if( content_type_valid)
00409                 //{
00410                 //      content_specific_editor = findCommand( extension, szAppPath);
00411                 //      if( szAppPath.Find( "%1") != -1) // if "%1" found in command string replace it with tempfilename
00412                 //              szAppPath.Replace( "%1", szTempFileName); 
00413                 //}
00414         }
00415 
00416         CStdioFile tempFile;
00417         if (tempFile.Open(szTempFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText) == 0) {
00418                 ASSERT(("Unable to create temporary file.", false));
00419                 return;
00420         }
00421 
00422         // write attribute value to the temporary file
00423         for(int i=0;i<=ListItem.Value.stringVal.GetUpperBound();i++)
00424         {
00425                 CString strLine = ListItem.Value.stringVal[i];
00426                 strLine.TrimRight(_T("\r\n"));
00427                 tempFile.WriteString(strLine + _T("\n"));
00428         }
00429 
00430         tempFile.Close();
00431 
00432         BOOL launched = FALSE;
00433         if( content_specific_editor)
00434         {
00435                 if( !szAppPath.IsEmpty()) // GMEEditor value found in MimeDB
00436                 {
00437                         CString szCommandLine = _T(" ");
00438                         szCommandLine += szTempFileName;
00439                         int nCommandLineLength = szCommandLine.GetLength();
00440 
00441                         // startup info for the redactor's process is taken similar to that
00442                         // of invoking application
00443                         STARTUPINFO startUpInfo;
00444                         PROCESS_INFORMATION processInfo;
00445                         ::GetStartupInfo(&startUpInfo);
00446 
00447                         // start pref'd editor with the file name as the command line parameter
00448                         launched = ::CreateProcess(szAppPath,szCommandLine.GetBuffer(nCommandLineLength),
00449                                 NULL,NULL,FALSE,0,NULL,NULL,&startUpInfo,&processInfo);
00450                         szCommandLine.ReleaseBuffer();
00451                         CloseHandle(processInfo.hProcess);
00452                         CloseHandle(processInfo.hThread);
00453                 }
00454 
00455                 if( !launched)
00456                 {
00457                         // success codes are strictly greater than 32
00458                         int retcode = (int) ShellExecute( (HWND) m_EditorButton, _T("edit"), szTempFileName, 0, 0, SW_SHOWNORMAL);
00459                         if( retcode == SE_ERR_NOASSOC) // failed because no such verb (edit) exists for this extension
00460                                 retcode = (int) ShellExecute( (HWND) m_EditorButton, _T("open"), szTempFileName, 0, 0, SW_SHOWNORMAL);
00461 
00462                         launched = retcode > 32;
00463                         // if it was not launched successfully, use the specified editor
00464                 }
00465         }
00466 
00467         if( !launched) // if not found a content specific one, or if it failed to launch
00468         {
00469                 // Get External Editor prefs and build command line for the editor application
00470                 CComPtr<IMgaRegistrar> registrar;
00471                 try {
00472                         COMTHROW( registrar.CoCreateInstance(OLESTR("MGA.MgaRegistrar")) );
00473                         ASSERT( registrar != NULL );
00474                         COMTHROW( registrar->get_ExternalEditor(REGACCESS_USER, PutOut(szAppPath)) );
00475                 } 
00476                 catch (hresult_exception &) {
00477                 }
00478 
00479                 CString szCommandLine = szAppPath + _T(" ");
00480                 szCommandLine += szTempFileName;
00481                 int nCommandLineLength = szCommandLine.GetLength();
00482 
00483                 // startup info for the redactor's process is taken similar to that
00484                 // of invoking application
00485                 STARTUPINFO startUpInfo;
00486                 PROCESS_INFORMATION processInfo;
00487                 ::GetStartupInfo(&startUpInfo);
00488 
00489                 // start notepad.exe with the XML file name as the command line parameter
00490 
00491                 launched = ::CreateProcess(NULL, szCommandLine.GetBuffer(nCommandLineLength),
00492                         NULL,NULL,FALSE,0,NULL,NULL,&startUpInfo,&processInfo);
00493                 szCommandLine.ReleaseBuffer();
00494                 CloseHandle(processInfo.hProcess);
00495                 CloseHandle(processInfo.hThread);
00496         }
00497 
00498         // DWORD h = ::WaitForSingleObject(processInfo.hProcess, INFINITE);
00499         if (launched)
00500         {
00501                 m_EditorButton.MessageBox(_T("Click OK to finish."), _T("Using External Text Editor"), MB_ICONINFORMATION);
00502         }
00503 
00504         // open temporary file
00505         if (tempFile.Open(szTempFileName, CFile::modeRead | CFile::typeText) == 0) {
00506                 ASSERT(("Unable to open temporary file.", false));
00507                 return;
00508         }
00509 
00510         // read attribute value from the temporary file
00511         ListItem.Value.stringVal.RemoveAll();
00512         CString strLine;
00513         while (tempFile.ReadString(strLine) == TRUE) {
00514                 strLine.TrimRight(_T("\r\n"));
00515                 ListItem.Value.stringVal.Add(strLine);
00516         }
00517 
00518         tempFile.Close();
00519 
00520         ListItem.SetDirty();
00521 
00522         m_pInspectorList->NotifyParent(m_nCurrentIndex);
00523 
00524         m_pInspectorList->SetFocus();
00525 
00526 
00527         
00528 }
00529 
00530 void CInPlaceManager::OnClickArrowButton(bool rightSideClick)
00531 {
00532 
00533         CRect rectArrow;
00534 
00535         m_ArrowButton.GetWindowRect(rectArrow);
00536         m_pInspectorList->ScreenToClient(rectArrow);
00537         CRect rectWnd(m_pInspectorList->m_Settings.m_nDivider,rectArrow.bottom-1,rectArrow.right,rectArrow.bottom-1);
00538 
00539         CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex);
00540 
00541 
00542         switch(ListItem.Value.dataType)
00543         {
00544         case ITEMDATA_COMPASS:
00545                 {
00546                         rectWnd.bottom+=100;
00547                         DisplayCompassCheck(rectWnd);
00548                 }break;
00549 
00550         case ITEMDATA_COMPASS_EXCL:
00551                 {
00552                         rectWnd.bottom+=100;
00553                         DisplayCompassOpt(rectWnd);
00554                 }break;
00555 
00556         case ITEMDATA_BOOLEAN:
00557                 {
00558                         rectWnd.bottom += 2 * m_pInspectorList->m_ComboboxLineHeight + 2;
00559                         DisplayCombo(rectWnd);
00560                 }break;
00561         case ITEMDATA_FIXED_LIST:
00562                 {
00563                         rectWnd.bottom += min(ListItem.Value.stringVal.GetSize(), 8) 
00564                                 * m_pInspectorList->m_ComboboxLineHeight + 2;
00565                         DisplayCombo(rectWnd);
00566                 }break;
00567 
00568         case ITEMDATA_COLOR:
00569                 {
00570                         DisplayColorCombo(rectWnd, rightSideClick);
00571                 }break;
00572 
00573         default:
00574                 {
00575                         // This should not happen here
00576                         ASSERT(0);
00577                 }
00578         }
00579 
00580         if(::IsWindowVisible(m_ArrowButton.GetSafeHwnd()) )
00581                 m_ArrowButton.Invalidate();
00582 }
00583 
00584 
00585 void CInPlaceManager::DisplayCompassCheck(CRect rectBound)
00586 {
00587         CCompassCheckDlg dlg(m_pInspectorList);
00588 
00589         CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex);
00590         UINT uCompassVal=ListItem.Value.compassVal;
00591         CPoint ptDlgTopRight(rectBound.right,rectBound.top);
00592         m_pInspectorList->ClientToScreen(&ptDlgTopRight);
00593         dlg.SetParameters(ptDlgTopRight, uCompassVal);
00594 
00595         if(dlg.DoModal()==IDOK)
00596         {
00597                 ListItem.Value.SetCompassValue(dlg.GetCompassVal());
00598 
00599                 ListItem.SetDirty();
00600 
00601                 m_pInspectorList->NotifyParent(m_nCurrentIndex);
00602         }
00603 
00604         m_pInspectorList->SetFocus();
00605 }
00606 
00607 void CInPlaceManager::DisplayCompassOpt(CRect rectBound)
00608 {
00609         CCompassOptDlg dlg(m_pInspectorList);
00610 
00611         CListItem& ListItem=m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex);
00612         UINT uCompassVal=ListItem.Value.compassVal;
00613         CPoint ptDlgTopRight(rectBound.right,rectBound.top);
00614         m_pInspectorList->ClientToScreen(&ptDlgTopRight);
00615         dlg.SetParameters(ptDlgTopRight, uCompassVal);
00616 
00617         if(dlg.DoModal()==IDOK)
00618         {
00619                 ListItem.Value.SetCompassExclValue(dlg.GetCompassVal());
00620                 ListItem.SetDirty();
00621 
00622                 m_pInspectorList->NotifyParent(m_nCurrentIndex);
00623         }
00624 
00625         m_pInspectorList->SetFocus();
00626 }
00627 
00628 
00629 void CInPlaceManager::DisplayCombo(CRect rectBound)
00630 {
00631         CComboBoxSelectDlg dlg(m_pInspectorList, m_pInspectorList->m_ComboboxLineHeight);
00632 
00633         CListItem& ListItem = m_pInspectorList->m_ListItemArray.ElementAt( m_nCurrentIndex );
00634         m_pInspectorList->ClientToScreen( &rectBound );
00635         dlg.SetParameters(rectBound, &ListItem, &m_pInspectorList->m_entryFont);
00636 
00637         if ( dlg.DoModal() == IDOK ) {
00638                 ListItem.SetDirty();
00639                 m_pInspectorList->NotifyParent( m_nCurrentIndex );
00640         }
00641 
00642         m_pInspectorList->SetFocus();
00643 }
00644 
00645 void CInPlaceManager::OnEditMultiLineEnd()
00646 {
00647         CListItem &ListItem= m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex);
00648 
00649         ASSERT(ListItem.Value.dataType==ITEMDATA_STRING);
00650 
00651         ASSERT(ListItem.Value.cLineNum>1);
00652 
00653         int nLines=m_MultiEditCtrl.GetLineCount();
00654         ASSERT( nLines); // nLines >= 1 always
00655 
00656 
00657         CString strLine;
00658         ListItem.Value.stringVal.RemoveAll();
00659         int nLineLength=m_MultiEditCtrl.GetWindowTextLength();
00660         // To Zoltan's comment:
00661         // http://groups.google.com/group/microsoft.public.vc.mfc/browse_thread/thread/f75d48b8655dde0e
00662         // There are two errors with CEdit GetLine
00663         // 1.: GetLine cannot return less than two characters, so if there's just one character, we should still supply
00664         //     a buffer for two characters (in ANSI: two bytes)
00665         // 2.: If the edit control is empty, the GetLine call returns two null terminators
00666         //     (this caused the phenomena Zoltan encountered)
00667         // ****
00668         // zolmol: avoid trimming in case when the field is cleared: nLineLength = 0 and nLines = 1 
00669         //         (corrupted strLine inserted into ListItem caused memory damage when released)
00670         if( nLineLength > 0 )
00671         {
00672                 for(int i=0;i<nLines;i++)
00673                 {
00674                         strLine = CEditGetLine(m_MultiEditCtrl, i);
00675                         strLine.TrimRight(_T("\r\n"));
00676                         ListItem.Value.stringVal.Add(strLine);
00677                 }
00678         }
00679 
00680         ListItem.SetDirty();
00681 
00682         m_pInspectorList->NotifyParent(m_nCurrentIndex);
00683 
00684         m_pInspectorList->Invalidate();
00685 }
00686 
00687 void CInPlaceManager::OnEditSingleLineEnd()
00688 {
00689         CListItem &ListItem= m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex);
00690 
00691 
00692         CString strText;
00693         m_SingleEditCtrl.GetWindowText(strText);
00694 
00695         switch(ListItem.Value.dataType)
00696         {
00697                 case ITEMDATA_STRING:
00698                         {
00699                                 ListItem.Value.SetStringValue(strText);
00700 
00701                                 if(!ListItem.Value.Validate()) {
00702                                         m_pInspectorList->MessageBox(_T("Invalid (non ASCII) string data: ")+strText,_T("Object Inspector"),MB_ICONERROR);
00703                                         m_pInspectorList->SetFocus();
00704                                 } 
00705                                 else {
00706                                         ListItem.SetDirty();
00707                                         m_pInspectorList->NotifyParent(m_nCurrentIndex);
00708 
00709                                         m_pInspectorList->Invalidate();
00710                                 }
00711                         }break;
00712 
00713                 case ITEMDATA_INTEGER:
00714                 {
00715                         ListItem.Value.stringVal[0]=strText;
00716 
00717                         if(!ListItem.Value.Validate())
00718                         {
00719                                 m_pInspectorList->MessageBox(_T("Invalid integer data: ")+strText,_T("Object Inspector"),MB_ICONERROR);
00720                                 // Restoring correct value
00721                                 ListItem.Value.toString();
00722                                 m_pInspectorList->SetFocus();
00723                         }
00724                         else
00725                         {
00726                                 ListItem.SetDirty();
00727 
00728                                 m_pInspectorList->NotifyParent(m_nCurrentIndex);
00729                         }
00730 
00731                 }break;
00732 
00733                 case ITEMDATA_DOUBLE:
00734                 {
00735                         ListItem.Value.stringVal[0]=strText;
00736 
00737                         if(!ListItem.Value.Validate())
00738                         {
00739                                 m_pInspectorList->MessageBox(_T("Invalid floating point data: ")+strText,_T("Object Inspector"),MB_ICONERROR);
00740                                 // Restoring correct value
00741                                 ListItem.Value.toString();
00742                                 m_pInspectorList->SetFocus();
00743                         }
00744                         else
00745                         {
00746                                 ListItem.SetDirty();
00747 
00748                                 m_pInspectorList->NotifyParent(m_nCurrentIndex);
00749                         }
00750 
00751                 }break;
00752 
00753                 default:
00754                 {
00755                         ASSERT(0); // Should not happen
00756                 }
00757         }
00758 
00759 
00760 }
00761 
00762 
00763 bool CInPlaceManager::OnRightItemClick(int nIndex, CRect rectInPlace)
00764 {
00765         // User request: color and direction selection popups and other popup should pop up not only by the
00766         //                               arrow click, but the right side line click too
00767         if(::IsWindowVisible(m_ArrowButton.GetSafeHwnd()) )
00768         {
00769                 if (nIndex == m_nCurrentIndex) {
00770                         OnClickArrowButton(true);
00771                         return true;
00772                 }
00773         }
00774 
00775         return false;
00776 }
00777 
00778 
00779 void CInPlaceManager::OnEditEnd()
00780 {
00781         CListItem &ListItem= m_pInspectorList->m_ListItemArray.ElementAt(m_nCurrentIndex);
00782         if(ListItem.Value.dataType==ITEMDATA_STRING&& ListItem.Value.cLineNum>1)
00783         {
00784                 OnEditMultiLineEnd();
00785         }
00786         else
00787         {
00788                 OnEditSingleLineEnd();
00789         }
00790 }
00791 
00792 /*static*/ bool CInPlaceManager::findInfoInMimeDB( const CString& pContentType, CString& pPrefApp, CString& pExtension)
00793 {
00794         // mime types (content types) are enumerated under:
00795         const TCHAR MIME_DB[] = _T("MIME\\Database\\Content Type\\");
00796         const TCHAR EXTENSION_VALUE[] = _T("Extension");
00797         const TCHAR GMEEDITOR_VALUE[] = _T("GMEEditor"); // a developer might introduce here a GME specific value (by an installer)
00798 
00799         CRegKey rk;
00800         LONG res = rk.Open( HKEY_CLASSES_ROOT, MIME_DB + pContentType, KEY_READ);
00801 
00802         if( res != ERROR_SUCCESS) // such a mime type not found
00803                 return false;
00804 
00805         // an Extension value exists hopefully
00806         ULONG buff_len = 32; // we don't expect wider extensions than 32
00807         CString ext(_T(' '), buff_len);
00808         TCHAR* buff = ext.GetBufferSetLength( buff_len);
00809         res = rk.QueryStringValue( EXTENSION_VALUE, buff, &buff_len);
00810         ext.ReleaseBufferSetLength( buff_len);
00811 
00812         if( res != ERROR_SUCCESS)
00813                 ext.Empty(); // will not return succesfully
00814 
00815         buff_len = MAX_PATH;
00816         CString pref_app(_T(' '), buff_len);
00817         buff = pref_app.GetBufferSetLength( buff_len);
00818         res = rk.QueryStringValue( GMEEDITOR_VALUE, buff, &buff_len);
00819         pref_app.ReleaseBufferSetLength( buff_len);
00820         rk.Close();
00821 
00822         if( res != ERROR_SUCCESS)
00823                 pref_app.Empty(); // this is not an error
00824 
00825         pPrefApp = pref_app;
00826         pExtension = ext;
00827         return !pExtension.IsEmpty();
00828 }
00829 
00830 // finds the Open/Edit verb defined for the file class (extension)
00831 // format of returned string pCommand
00832 // "C:\Program Files\Windows Media Player\wmplayer.exe" "%L"
00833 // "C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe" "%1"
00834 // "C:\Program Files\Opera8\Opera.exe" "%1"
00835 // "C:\Program Files\apps\Microsoft Office\Office10\msohtmed.exe" %1
00836 //
00838 //{
00839 //      if( pExtension.IsEmpty() || pExtension.GetAt(0) != '.') return false;
00840 //
00841 //      CRegKey rk;
00842 //      LONG res;
00843 //      res = rk.Open( HKEY_CLASSES_ROOT, pExtension , KEY_READ);
00844 //      if( res != ERROR_SUCCESS) // such an extension not found
00845 //              return false;
00846 //
00847 //      // for each extension a file class is created typically: .xls -> Excel.Sheet.8
00848 //      ULONG buff_len = 256; // it is enough long for a file class name
00849 //      CString file_class( ' ', buff_len); 
00850 //      TCHAR * buff = file_class.GetBufferSetLength( buff_len);
00851 //      res = rk.QueryStringValue( 0, buff, &buff_len);
00852 //      file_class.ReleaseBufferSetLength( buff_len);
00853 //
00854 //      rk.Close();
00855 //      if( res != ERROR_SUCCESS)
00856 //              return false;
00857 //
00858 //      file_class = buff;
00859 //
00860 //      res = rk.Open(HKEY_CLASSES_ROOT, file_class , KEY_READ);
00861 //      if( res != ERROR_SUCCESS) return false;
00862 //
00863 //      CRegKey sk;
00864 //      const TCHAR SHELL_EDIT_COMMAND[] = _T("SHELL\\EDIT\\COMMAND");
00865 //      const TCHAR SHELL_OPEN_COMMAND[] = _T("SHELL\\OPEN\\COMMAND");
00866 //
00867 //      res = sk.Open( rk, SHELL_EDIT_COMMAND, KEY_READ);
00868 //      if( res != ERROR_SUCCESS)
00869 //      {
00870 //              res = sk.Open( rk, SHELL_OPEN_COMMAND, KEY_READ); // this is the most common
00871 //              if( res != ERROR_SUCCESS)
00872 //                      return false;
00873 //      }
00874 //
00875 //      
00876 //      ULONG cmd_len = MAX_PATH;
00877 //      TCHAR * cmd = pCommand.GetBufferSetLength( cmd_len);
00878 //      res = sk.QueryStringValue( 0, cmd, &cmd_len);
00879 //      pCommand.ReleaseBufferSetLength( cmd_len);
00880 //      sk.Close();
00881 //
00882 //      if( res != ERROR_SUCCESS)
00883 //              return false;
00884 //
00885 //      return !pCommand.IsEmpty(); // return true only if something valuable found
00886 //}