- // JobListDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "p4win.h"
- #include "JobListDlg.h"
- #include "JobView.h"
- #include "P4Job.h"
- #include "catchalldlg.h"
- #include "MainFrm.h"
- #include "StringUtil.h"
- #include "RegKeyEx.h"
- #include "hlp\p4win.hh"
- #include "ImageList.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- static LPCTSTR sRegKey = _T("Software\\Perforce\\P4Win\\Layout\\Job List");
- static LPCTSTR sRegValue_ColumnWidths = _T("Column Widths");
- static LPCTSTR sRegValue_SortColumns = _T("Sort Columns");
- #define UPDATE_STATUS(x) ((CMainFrame *)AfxGetMainWnd())->UpdateStatus(x)
- int CALLBACK JobListDlgSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
- #define IMG_INDEX(x) (x-IDB_PERFORCE)
- // Module global for use in sort callback
- CJobListDlg *pDlg;
- /////////////////////////////////////////////////////////////////////////////
- // CJobListDlg dialog
- CJobListDlg::CJobListDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CJobListDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CJobListDlg)
- //}}AFX_DATA_INIT
- m_SortAscending=FALSE;
- m_LastSortColumn=0;
- pDlg=this;
- m_InitRect.SetRect(0,0,100,100);
- m_WinPos.SetWindow( this, _T("JobListDlg") );
- for (int i = -1; ++i < MAX_SORT_COLUMNS; )
- m_SortColumns[i] = 0;
- }
- void CJobListDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CJobListDlg)
- DDX_Control(pDX, IDC_JOBSTATUS, m_JobStatus);
- DDX_Control(pDX, IDC_JOBLIST, m_JobListCtrl);
- DDX_Control(pDX, IDC_JOBDESC, m_JobDesc);
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CJobListDlg, CDialog)
- //{{AFX_MSG_MAP(CJobListDlg)
- ON_WM_SIZE()
- ON_WM_GETMINMAXINFO()
- ON_NOTIFY(LVN_ITEMCHANGED, IDC_JOBLIST, OnItemchangedJoblist)
- ON_NOTIFY(LVN_COLUMNCLICK, IDC_JOBLIST, OnColumnclickJoblist)
- ON_NOTIFY(NM_DBLCLK, IDC_JOBLIST, OnDblclickJoblist)
- ON_BN_CLICKED(IDHELP, OnHelp)
- ON_BN_CLICKED(IDC_FILTER, OnJobFilter)
- ON_BN_CLICKED(ID_CLEARFILTER, OnClearFilter)
- ON_WM_HELPINFO()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CJobListDlg message handlers
- BOOL CJobListDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- CP4Job *job;
- CString str;
- SetFont(m_Font);
- // Modify the list control style so that the entire selected row is highlighted
- DWORD dwStyle = ::SendMessage(m_JobListCtrl.m_hWnd,LVM_GETEXTENDEDLISTVIEWSTYLE,0,0);
- dwStyle |= LVS_EX_FULLROWSELECT;
- ::SendMessage(m_JobListCtrl.m_hWnd,LVM_SETEXTENDEDLISTVIEWSTYLE,0,dwStyle);
- // Make sure list control shows selection when not the focused control
- m_JobListCtrl.ModifyStyle(0, LVS_SHOWSELALWAYS, 0);
- // Set the imagelist
- m_JobListCtrl.SetImageList(TheApp()->GetImageList(), LVSIL_SMALL);
- // Get original size of control
- CRect rect;
- m_JobListCtrl.GetWindowRect(&rect);
- int colwidth[MAX_JOBS_COLUMNS]={90,80,60,90,200};
- // Record the initial window size, and then see if there is a registry preference
- GetWindowRect(&m_InitRect);
- m_WinPos.RestoreWindowPosition();
- // make sure OnSize gets called to reposition controls
- // if restored position is default, this won't happen unless
- // we force it
- GetClientRect(&rect);
- SendMessage(WM_SIZE, 0, MAKELONG(rect.Width(), rect.Height()));
- // Get new size of control after resized as specified in the registry
- m_JobListCtrl.GetWindowRect(&rect);
- // Get any saved column widths from registry
- RestoreSavedWidths(colwidth, MAX_JOBS_COLUMNS);
- // Make sure no column completely disappeared (because you can't get it back then)
- for (int i=-1; ++i < MAX_JOBS_COLUMNS; )
- {
- if (colwidth[i] < 5)
- colwidth[i] = 5;
- }
- // Show the current job filter
- CString txt;
- m_sFilter = PersistentJobFilter(KEY_READ);
- if(m_sFilter.GetLength() > 0)
- {
- txt.FormatMessage(IDS_JOBFILTERSTR, m_sFilter);
- }
- else
- {
- txt = LoadStringResource(IDS_ALLJOBS);
- GetDlgItem(ID_CLEARFILTER)->EnableWindow(FALSE);
- }
- GetDlgItem(IDC_FILTER_TEXT)->SetWindowText(txt);
- // Use the same font as the calling window
- m_JobListCtrl.SetFont(m_Font);
- // Insert the columns
- int maxcols = m_ColNames->GetSize();
- int width=GetSystemMetrics(SM_CXVSCROLL);;
- int retval;
- LV_COLUMN lvCol;
- int subItem;
- for(subItem=0; subItem < maxcols; subItem++)
- {
- lvCol.mask= LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT |LVCF_WIDTH;
- lvCol.fmt=LVCFMT_LEFT;
- lvCol.pszText=( LPTSTR )( LPCTSTR ) m_ColNames->GetAt( subItem );
- lvCol.iSubItem=subItem;
- if(subItem < maxcols-1)
- {
- lvCol.cx=colwidth[subItem];
- width+=lvCol.cx;
- }
- else
- lvCol.cx=rect.Width() - width - 4; // expand last column to fill window
- retval=m_JobListCtrl.InsertColumn(subItem, &lvCol);
- }
- // Add the data
- LV_ITEM lvItem;
- int iActualItem = -1;
- POSITION pos= m_pJobList->GetHeadPosition();
- int iItem;
- for(iItem=0; iItem < m_pJobList->GetCount(); iItem++)
- {
- job= (CP4Job *) m_pJobList->GetNext(pos);
- for(subItem=0; subItem < maxcols; subItem++)
- {
- lvItem.mask=LVIF_TEXT |
- ((subItem==0) ? LVIF_IMAGE : 0) |
- ((subItem==0) ? LVIF_PARAM : 0);
- lvItem.iItem= (subItem==0) ? iItem : iActualItem;
- ASSERT(lvItem.iItem != -1);
- lvItem.iSubItem= subItem;
- lvItem.iImage = CP4ViewImageList::VI_JOB;
- lvItem.lParam=(LPARAM) job;
- txt=PadCRs(job->GetJobField(subItem));
- lvItem.pszText = const_cast<LPTSTR>( (LPCTSTR ) txt);
- if(subItem==0)
- iActualItem=m_JobListCtrl.InsertItem(&lvItem);
- else
- m_JobListCtrl.SetItem(&lvItem);
- }
- }
- if(m_pJobList->GetCount())
- {
- // Sort the jobs list the same way the JobView is sorted
- m_JobListCtrl.SortItems( JobListDlgSort, m_LastSortColumn );
- // Find the job currently selected in the jobs pane
- iItem=0;
- if (!m_CurrJob->IsEmpty())
- {
- TCHAR cur[ LISTVIEWNAMEBUFSIZE + 1 ];
- TCHAR str[ LISTVIEWNAMEBUFSIZE + 1 ];
- lstrcpy(cur, m_CurrJob->GetBuffer(m_CurrJob->GetLength()+1));
- m_CurrJob->ReleaseBuffer(-1);
- for( ; iItem < ListView_GetItemCount( m_JobListCtrl.m_hWnd ); iItem++ )
- {
- ListView_GetItemText( m_JobListCtrl.m_hWnd, iItem, 0, str, LISTVIEWNAMEBUFSIZE );
- if( !Compare(cur, str) )
- break;
- }
- if (iItem >= ListView_GetItemCount( m_JobListCtrl.m_hWnd ))
- iItem = 0;
- }
- // Make sure the same job is selected and visible
- m_JobListCtrl.SetItemState(iItem, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
- m_JobListCtrl.EnsureVisible( iItem, FALSE );
- // Set change description to match selected item in list
- job= (CP4Job *) m_JobListCtrl.GetItemData(iItem);
- str= job->GetDescription();
- str.Replace(_T("\n"), _T("\r\n"));
- m_JobDesc.SetWindowText(str);
- }
- else if( m_sFilter.IsEmpty() )
- {
- AfxMessageBox(IDS_NO_JOBS_AVAILABLE_FOR_FIXING, MB_ICONEXCLAMATION);
- EndDialog(IDCANCEL);
- }
- else
- AddToStatus(LoadStringResource(IDS_USEJOBFILTERBUTTON), SV_MSG);
- if (!LoadJobStatusComboBox())
- {
- GetDlgItem(IDC_JOBSTATUSPROMPT)->ShowWindow( SW_HIDE );
- GetDlgItem(IDC_JOBSTATUS)->ShowWindow( SW_HIDE );
- }
- // And finally, set focus to the list control so that the first 'down'
- // keystroke can be used to scroll down
- m_JobListCtrl.SetFocus();
- return TRUE; // return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
- }
- CString CJobListDlg::PersistentJobFilter( REGSAM accessmask )
- {
- HKEY hKey = NULL;
- const CString sKey = _T("Software\\Perforce\\P4Win\\");
- const CString sEntry = _T("JobFilter");
- CString filter = _T("");
- DWORD disposition;
- if ( RegCreateKeyEx( HKEY_CURRENT_USER, sKey,
- 0, NULL,
- REG_OPTION_NON_VOLATILE,
- accessmask, NULL,
- &hKey, &disposition ) == ERROR_SUCCESS )
- {
- const DWORD lenFilter = 512;
- if ( accessmask == KEY_WRITE )
- {
- RegSetValueEx( hKey, sEntry, NULL, REG_SZ
- , (LPBYTE)(LPCTSTR) m_sFilter, m_sFilter.GetLength( ) * sizeof(TCHAR) + 1);
- }
- else
- {
- TCHAR buf[ lenFilter ];
- DWORD cbData = sizeof(buf);
- if ( (RegQueryValueEx( hKey, sEntry, NULL, NULL,
- (LPBYTE)buf, &cbData ) == ERROR_SUCCESS) && cbData )
- {
- if(!cbData)
- cbData = 1;
- buf[cbData-1] = _T('\0');
- filter = buf;
- }
- }
- RegCloseKey( hKey );
- }
- return filter;
- }
- BOOL CJobListDlg::LoadJobStatusComboBox()
- {
- int i;
- m_JobStatus.AddString(_T("(default)"));
- if (GET_SERVERLEVEL() < 10)
- return FALSE;
- i = m_pJobSpec->Find(_T("\nFields:\n\t"));
- if (i == -1)
- return FALSE;
- i = m_pJobSpec->Find(_T("\n\t102 "), i);
- if (i == -1)
- return FALSE;
- i += sizeof(_T("\n\t102 "))/sizeof(TCHAR) - 1;
- int j = m_pJobSpec->Find(_T(' '), i);
- if (j == -1)
- return FALSE;
- CString name = m_pJobSpec->Mid(i, j-i);
- i = m_pJobSpec->Find(_T("\nValues:"), j);
- if (i == -1)
- {
- CString dashed = _T("\nValues");
- dashed += _T("-") + name;
- i = m_pJobSpec->Find(dashed, j);
- if (i == -1)
- return FALSE;
- }
- i = m_pJobSpec->Find(name, i);
- if (i == -1)
- return FALSE;
- i += name.GetLength();
- while (1)
- {
- TCHAR c = m_pJobSpec->GetAt(++i);
- if ((c != _T(':')) && (c != _T(' ')) && (c != _T('\t')))
- break;
- }
- j = m_pJobSpec->Find(_T('\n'), i);
- if (j == -1)
- return FALSE;
- CString values = m_pJobSpec->Mid(i, j-i);
- while((i = values.Find(_T('/'))) != -1)
- {
- CString value = values.Mid(0,i);
- m_JobStatus.AddString(value);
- values = values.Mid(i+1);
- }
- m_JobStatus.AddString(values);
- return TRUE;
- }
- void CJobListDlg::SetJobList(CObList *joblist)
- {
- ASSERT_KINDOF(CObList,joblist);
- m_pJobList= joblist;
- }
- void CJobListDlg::SetJobSpec(CString *jobSpec)
- {
- m_pJobSpec= jobSpec;
- }
- void CJobListDlg::SetJobCols(CStringArray *jobCols)
- {
- m_ColNames= jobCols;
- }
- void CJobListDlg::SetJobCurr(CString *jobName)
- {
- m_CurrJob= jobName;
- }
- void CJobListDlg::OnOK()
- {
- int cursel = m_JobStatus.GetCurSel();
- if (cursel != CB_ERR)
- m_JobStatus.GetLBText(cursel, m_JobStatusValue);
- if (m_JobStatusValue == _T("(default)"))
- m_JobStatusValue.Empty();
- m_WinPos.SaveWindowPosition();
- m_SelectedJobs.RemoveAll();
- int nItem=m_JobListCtrl.GetNextItem( -1, LVNI_ALL | LVNI_SELECTED );
- while(nItem != -1)
- {
- TCHAR str[ LISTVIEWNAMEBUFSIZE + 1 ];
- ListView_GetItemText( m_JobListCtrl.m_hWnd, nItem, 0, str, LISTVIEWNAMEBUFSIZE );
- m_SelectedJobs.AddHead(str);
- nItem=m_JobListCtrl.GetNextItem( nItem, LVNI_ALL | LVNI_SELECTED );
- }
- EndDialog(IDOK);
- }
- void CJobListDlg::OnItemchangedJoblist(NMHDR* pNMHDR, LRESULT* pResult)
- {
- NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
- CString txt, txt1;
- // Update display of revision description
- if(pNMListView->uNewState==3)
- {
- txt=((CP4Job *) pNMListView->lParam)->GetDescription();
- txt.Replace(_T("\n"), _T("\r\n"));
- m_JobDesc.SetWindowText(txt);
- }
- *pResult = 0;
- }
- void CJobListDlg::OnCancel()
- {
- m_WinPos.SaveWindowPosition();
- CDialog::OnCancel();
- }
- void CJobListDlg::OnSize(UINT nType, int cx, int cy)
- {
- CDialog::OnSize(nType, cx, cy);
- // Slide the OK and Cancel buttons to the bottom of dlg
- CWnd *pOK = GetDlgItem(IDOK);
- CWnd *pCancel = GetDlgItem(IDCANCEL);
- CWnd *pHelp = GetDlgItem(IDHELP);
- CWnd *pFilter = GetDlgItem(IDC_FILTER);
- CWnd *pClear = GetDlgItem(ID_CLEARFILTER);
- if(!pOK)
- return;
- CRect rect;
- int fw, fh;
- int x = cx - 5;
- int y = cy - 5;
- pFilter->GetClientRect(&rect);
- pFilter->MoveWindow(x - (rect.Width()*2) - 5, 0,
- fw = rect.Width(), fh = rect.Height(), TRUE);
- pClear->GetClientRect(&rect);
- pClear->MoveWindow(x - rect.Width(), 0,
- rect.Width(), rect.Height(), TRUE);
- pHelp->GetClientRect(&rect);
- pHelp->MoveWindow(x - rect.Width(), y - rect.Height(),
- rect.Width(), rect.Height(), TRUE);
- x -= rect.Width() + 5;
- pCancel->GetClientRect(&rect);
- pCancel->MoveWindow(x - rect.Width(), y - rect.Height(),
- rect.Width(), rect.Height(), TRUE);
- x -= rect.Width() + 5;
- pOK->GetClientRect(&rect);
- pOK->MoveWindow(x - rect.Width(), y - rect.Height(),
- rect.Width(), rect.Height(), TRUE);
- // leave space between buttons and description edit control
- y -= rect.Height() + 5;
- // position the filter string
- CWnd *pFltTxt = GetDlgItem(IDC_FILTER_TEXT);
- pFltTxt->GetWindowRect(&rect);
- pFltTxt->MoveWindow(5, (fh-rect.Height())/2+1, cx - 10 - (fw*2) - 6, rect.Height(), TRUE);
- // position the label
- CWnd *pLabel = GetDlgItem(IDC_SUMMARYLABEL);
- pLabel->GetClientRect(&rect);
- int remainder = y - (rect.Height() + 5 + 5);
- // Position the text box
- CWnd *pText = GetDlgItem(IDC_JOBDESC);
- int h = remainder / 4;
- pText->MoveWindow(2, y - h, cx-4, h, TRUE);
- y -= h + 5;
- // position the label
- pLabel->GetClientRect(&rect);
- pLabel->MoveWindow(2, y - rect.Height(), rect.Width(), rect.Height(), TRUE);
- // Position the Job Status fields
- CWnd *pList = GetDlgItem(IDC_JOBSTATUS);
- pList->GetClientRect(&rect);
- x = cx - 2;
- pList->MoveWindow(x - rect.Width(), y - rect.Height(),
- rect.Width(), rect.Height(), TRUE);
- x -= rect.Width() + 1;
- pLabel = GetDlgItem(IDC_JOBSTATUSPROMPT);
- pLabel->GetClientRect(&rect);
- pLabel->MoveWindow(x - rect.Width(), y - rect.Height(),
- rect.Width(), rect.Height(), TRUE);
- y -= rect.Height() + 5;
- // Increase the size of the list
- pList = GetDlgItem(IDC_JOBLIST);
- pList->MoveWindow(0, fh+5, cx, y-fh-5, TRUE);
- RedrawWindow();
- }
- void CJobListDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
- {
- lpMMI->ptMinTrackSize.x= m_InitRect.Width();
- lpMMI->ptMinTrackSize.y= m_InitRect.Height();
- }
- void CJobListDlg::OnDblclickJoblist(NMHDR* pNMHDR, LRESULT* pResult)
- {
- *pResult = 0;
- OnOK();
- }
- void CJobListDlg::OnColumnclickJoblist(NMHDR* pNMHDR, LRESULT* pResult)
- {
- NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
- if(pNMListView->iSubItem != m_LastSortColumn)
- m_LastSortColumn=pNMListView->iSubItem;
- else
- m_SortAscending= !m_SortAscending;
- if(pNMListView->iItem == -1)
- m_JobListCtrl.SortItems( JobListDlgSort,(DWORD)pNMListView->iSubItem);
- *pResult = 0;
- }
- // Since a sort column can only appear once in our saved column array,
- // given the current column, we can determine the next column.
- // Note that incoming 'colnbr' is a non-negative 0-relative number and must be incremented
- // The return value is a signed 1-relative number; negative for descending, positive for ascending
- int CJobListDlg::NextSortColumn(int lastcol)
- {
- if (lastcol == 0)
- return 0; // 0 => no next column
- lastcol++;
- for (int i = -1; ++i < (MAX_SORT_COLUMNS-1); )
- {
- if (abs(m_SortColumns[i]) == lastcol)
- return m_SortColumns[i+1];
- }
- return 0; // 0 => no next column
- }
- int CALLBACK JobListDlgSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
- {
- CString txt1= ((CP4Job const *)lParam1)->GetJobField(lParamSort);
- CString txt2= ((CP4Job const *)lParam2)->GetJobField(lParamSort);
- int rc;
- int nextcol;
- if(pDlg->IsSortAscending())
- rc = txt1.Compare(txt2);
- else
- rc = txt2.Compare(txt1);
- // check for duplicate keys; if so, sort on next sort columns
- if (!rc && lParamSort && ((nextcol = pDlg->NextSortColumn(lParamSort)) != 0))
- {
- // nextcol now contains a value like 1 for col-0-ascending or like -1 for col-0-decending
- BOOL saveSortAscending = pDlg->IsSortAscending();
- if (nextcol < 0)
- {
- nextcol = 0 - nextcol;
- pDlg->SetSortAscending(FALSE);
- }
- else
- pDlg->SetSortAscending(TRUE);
- rc = JobListDlgSort(lParam1, lParam2, (LPARAM)(nextcol-1));
- pDlg->SetSortAscending(saveSortAscending);
- }
- return rc;
- }
- // Check the registry to see if we have recorded the
- // column widths lastused for the job pane's list view.
- // Note that "HKEY_CURRENT_USER\Software\perforce\P4win\Layout\JobListDlg\Column Widths"
- // is no longer used because we use the "...\Job List\Column Widths" now.
- void CJobListDlg::RestoreSavedWidths(int *width, int numcols)
- {
- CRegKeyEx key;
- if(ERROR_SUCCESS == key.Open(HKEY_CURRENT_USER, sRegKey, KEY_READ))
- {
- CString result = key.QueryValueString(sRegValue_ColumnWidths);
- CString sortCols = key.QueryValueString(sRegValue_SortColumns);
- if(!result.IsEmpty())
- {
- // things can go wrong with the registry setting of the
- // widths. Use the defaults if the entry is all zeroes.
- //
- if ( result != _T("0,0,0,0,0,0,0,0,0,0") )
- for(int i=0; i< numcols; i++)
- width[i]= GetPositiveNumber(result);
- }
- if(!sortCols.IsEmpty())
- {
- for(int i=0; i< MAX_SORT_COLUMNS; i++)
- {
- m_SortColumns[i]= GetANumber(sortCols);
- if(!i && !m_SortColumns[i])
- m_SortColumns[i] = 1;
- }
- m_LastSortColumn= abs(m_SortColumns[0]) - 1; // SortColumns are signed & 1-relative
- m_SortAscending = m_SortColumns[0] >= 0 ? TRUE : FALSE;
- }
- }
- }
- void CJobListDlg::OnJobFilter()
- {
- RECT rect;
- CJobFilter dlg;
- dlg.SetFilterString ( m_sFilter );
- GetWindowRect(&rect); // we want to position filter dialog box
- dlg.m_top = rect.top + GetSystemMetrics(SM_CYCAPTION)*2; // at the top left of this pane, so pass
- dlg.m_left = rect.left + 2; // it our current screen location
- dlg.m_right= rect.right;
- MainFrame()->DoNotAutoPoll();
- dlg.DoModal( );
- MainFrame()->ResumeAutoPoll();
- if ( m_sFilter != dlg.GetFilterString ( ) )
- {
- m_sFilter = dlg.GetFilterString ( );
- PersistentJobFilter( KEY_WRITE );
- // Turn off all painting in children of main window to prevent flashing
- EnumChildWindows(AfxGetMainWnd()->m_hWnd, ChildSetRedraw, FALSE);
- SET_BUSYCURSOR();
- EndDialog(IDRETRY);
- }
- }
- void CJobListDlg::OnClearFilter()
- {
- if (!m_sFilter.IsEmpty())
- {
- m_sFilter.Empty();
- PersistentJobFilter( KEY_WRITE );
- // Turn off all painting in children of main window to prevent flashing
- EnumChildWindows(AfxGetMainWnd()->m_hWnd, ChildSetRedraw, FALSE);
- SET_BUSYCURSOR();
- EndDialog(IDRETRY);
- }
- else
- {
- GotoDlgCtrl(GetDlgItem(IDC_JOBLIST));
- }
- }
- void CJobListDlg::OnHelp()
- {
- AfxGetApp()->WinHelp(TASK_CLOSING_JOBS_USING_CHANGELISTS);
- }
- BOOL CJobListDlg::OnHelpInfo(HELPINFO* pHelpInfo)
- {
- OnHelp();
- return TRUE;
- }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 19924 | YourUncleBob |
Populate -o //guest/perforce_software/p4win/... //guest/YourUncleBob/p4win/..... |
9 years ago | |
//guest/perforce_software/p4win/main/gui/JobListDlg.cpp | |||||
#1 | 16169 | perforce_software | Move files to follow new path scheme for branches. | 9 years ago | |
//guest/perforce_software/p4win/gui/JobListDlg.cpp | |||||
#1 | 8562 | Matt Attaway | These feet never stop running. Initial commit of the P4Win source code. To the be...st of our knowledge this compiles and runs using the 2013.3 P4 API and VS 2010. Expect a few changes as we refine the build process. Please post any build issues to the forums. « |
11 years ago |