#include "stdafx.h" #include "MyClientUser.h" #include "MyFileSys.h" #include "PerforceClientServiceDlg.h" #include "Login.h" #include <stdarg.h> #include "p4api/include/p4/errornum.h" // ====================================================================== namespace MyClientUserNamespace { ClientApi ms_clientApi; void OutputDebugFormattedString(char const * const format, ...) { va_list va; va_start(va, format); char buffer[2048]; _vsnprintf_s(buffer, sizeof(buffer)-1, _TRUNCATE, format, va); buffer[sizeof(buffer)-1] = '\0'; OutputDebugString(buffer); va_end(va); } } using namespace MyClientUserNamespace; // ====================================================================== const MyClientUser::Action MyClientUser::ms_actionTable[FA_count][PS_count] = { { /* add, unknown */ &actionAdd, /* add, unchanged */ &actionEdit, /* add, add */ &actionIgnore, /* add, edit */ &actionRevertUnchanged, /* add, delete */ &actionRevertEdit, }, { /* modify, unknown */ &actionAdd, /* modify, unchanged */ &actionEdit, /* modify, add */ &actionIgnore, /* modify, edit */ &actionRevertUnchanged, /* modify, delete */ &actionRevertEdit, }, { /* delete, unknown */ &actionIgnore, /* delete, unchanged */ &actionDelete, /* delete, add */ &actionRevert, /* delete, edit */ &actionRevertDelete, /* delete, delete */ &actionIgnore, }, }; // ====================================================================== bool MyClientUser::install() { // Bring up the connection with perforce ms_clientApi.SetPort("1666"); Error e; ms_clientApi.Init(&e); if (e.Test()) { StrBuf msg; e.Fmt(&msg); MessageBox(NULL, msg.Text(), "P4 error", MB_ICONSTOP); return false; } ms_clientApi.SetProg("PerforceClientService"); return true; } // ---------------------------------------------------------------------- void MyClientUser::remove() { Error e; ms_clientApi.Final(&e); if (e.Test()) { StrBuf msg; e.Fmt(&msg); MessageBox(NULL, msg.Text(), "P4 error", MB_ICONSTOP); } } // ---------------------------------------------------------------------- MyClientUser::MyClientUser() : ClientUser(), m_fileAction(FA_add), m_fileName(NULL), m_perforceState(PS_unchanged), m_password(NULL) { // issue a command to make sure we're logged in runPerforceCommand("info", 0, NULL); } // ---------------------------------------------------------------------- MyClientUser::MyClientUser(FileAction const fileAction, char const * const fileName) : ClientUser(), m_fileAction(fileAction), m_fileName(fileName), m_perforceState(PS_unchanged), m_password(NULL) { } // ---------------------------------------------------------------------- void MyClientUser::Message(Error * const err) { // handle the user not being logged in if (err->Test() && err->GetSeverity() == E_FAILED && err->GetGeneric() == EV_CONFIG) { m_retry = true; return; } // handle fstat being called on a file that perforce knows nothing about if (err->Test() && err->GetSeverity() == E_WARN && err->GetGeneric() == EV_EMPTY) m_perforceState = PS_unknown; StrBuf msg; err->Fmt(&msg); CPerforceClientServiceDlg::Log("%s", msg.Text()); } // ---------------------------------------------------------------------- void MyClientUser::OutputError(const char * const errBuf) { CPerforceClientServiceDlg::Log("%s", errBuf); } // ---------------------------------------------------------------------- void MyClientUser::OutputInfo(char const level, const char * const data) { CPerforceClientServiceDlg::Log("%d %s", level, data); } // ---------------------------------------------------------------------- void MyClientUser::OutputBinary(const char * const data, int const length) { #ifdef _DEBUG OutputDebugFormattedString("ClientUser::OutputBinary %d\n", length); #endif } // ---------------------------------------------------------------------- void MyClientUser::OutputText(const char * const data, int const length) { #ifdef _DEBUG OutputDebugFormattedString("ClientUser::OutputText %d\n", length); #endif } // ---------------------------------------------------------------------- void MyClientUser::OutputStat(StrDict * const varList) { #ifdef _DEBUG OutputDebugString("ClientUser::OutputStat\n"); #endif StrRef var; StrRef val; for (int i = 0; varList->GetVar(i, var, val); ++i) { if (strcmp(var.Text(), "action") == 0) { if (strcmp(val.Text(), "edit") == 0) m_perforceState = PS_edit; else if (strcmp(val.Text(), "add") == 0) m_perforceState = PS_add; else if (strcmp(val.Text(), "delete") == 0) m_perforceState = PS_delete; } #ifdef _DEBUG OutputDebugFormattedString(" %s=%s\n", var.Text(), val.Text()); #endif } } // ---------------------------------------------------------------------- void MyClientUser::Prompt(StrPtr const & msg, StrBuf & rsp, int noEcho, Error * e) { if (m_password) rsp = m_password; else ClientUser::Prompt(msg, rsp, noEcho, e); } // ---------------------------------------------------------------------- FileSys * MyClientUser::File(FileSysType const type) { return new MyFileSys(type); } // ---------------------------------------------------------------------- void MyClientUser::UpdatePerforce() { // run fstat to see what the file in perforce is like { char * arguments[] = { const_cast<char *>(m_fileName) }; runPerforceCommand("fstat", sizeof(arguments) / sizeof(arguments[0]), arguments); } Action action = ms_actionTable[m_fileAction][m_perforceState]; (this->*action)(); #ifdef _DEBUG OutputDebugString("\n\n"); #endif } // ---------------------------------------------------------------------- void MyClientUser::runPerforceCommand(char const * commandName, int const argc, char const * const * const argv) { do { m_retry = false; ms_clientApi.SetArgv(argc, const_cast<char * const *>(argv)); ms_clientApi.Run(commandName, this); if (m_retry) { Login dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { m_password = dlg.m_password;; ms_clientApi.SetArgv(0, NULL); ms_clientApi.Run("login", this); m_password = NULL; } } } while (m_retry); } // ---------------------------------------------------------------------- void MyClientUser::actionIgnore() { #ifdef _DEBUG OutputDebugString("actionIgnore\n"); #endif } // ---------------------------------------------------------------------- void MyClientUser::actionAdd() { #ifdef _DEBUG OutputDebugString("actionAdd\n"); #endif char * arguments[] = { const_cast<char *>(m_fileName) }; runPerforceCommand("add", sizeof(arguments) / sizeof(arguments[0]), arguments); } // ---------------------------------------------------------------------- void MyClientUser::actionEdit() { #ifdef _DEBUG OutputDebugString("actionEdit\n"); #endif char * arguments[] = { const_cast<char *>(m_fileName) }; runPerforceCommand("edit", sizeof(arguments) / sizeof(arguments[0]), arguments); actionRevertUnchanged(); } // ---------------------------------------------------------------------- void MyClientUser::actionRevert() { #ifdef _DEBUG OutputDebugString("actionRevert\n"); #endif char * arguments[] = { const_cast<char *>(m_fileName) }; runPerforceCommand("revert", sizeof(arguments) / sizeof(arguments[0]), arguments); } // ---------------------------------------------------------------------- void MyClientUser::actionRevertUnchanged() { #ifdef _DEBUG OutputDebugString("actionRevertUnchanged\n"); #endif char * arguments[] = { "-a", const_cast<char *>(m_fileName) }; runPerforceCommand("revert", sizeof(arguments) / sizeof(arguments[0]), arguments); } // ---------------------------------------------------------------------- void MyClientUser::actionRevertEdit() { #ifdef _DEBUG OutputDebugString("actionRevertEdit\n"); #endif actionRevert(); actionEdit(); } // ---------------------------------------------------------------------- void MyClientUser::actionDelete() { #ifdef _DEBUG OutputDebugString("actionDelete\n"); #endif char * arguments[] = { const_cast<char *>(m_fileName) }; runPerforceCommand("delete", sizeof(arguments) / sizeof(arguments[0]), arguments); } // ---------------------------------------------------------------------- void MyClientUser::actionRevertDelete() { #ifdef _DEBUG OutputDebugString("actionRevertDelete\n"); #endif actionRevert(); actionDelete(); } // ======================================================================
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#2 | 7201 | Jeff Grills | Upgrade to VS2005 and the 2008.2 p4api | ||
#1 | 4963 | Jeff Grills |
Major clean up and code reorganization. Add new dialog to control the directories that are watched. Persist the watched directories in the windows registry. Restore the watched directories when the application is run again. Handle login correctly. Change the way error messages are examined to make them significantly more robust. Issue an "info" command at startup to make sure we can communicate with the server and get logged in. Change the icon to the standard P4 icon. Allow the dialog to be minimized to the systray. Clicking on the systray icon will show the dialog again. |