bug 404855 - crash reporter UI review, round 2--win32+strings changes. r=dcamp

This commit is contained in:
ted.mielczarek%gmail.com 2008-01-22 01:07:20 +00:00
Родитель 00cad89ded
Коммит 0ad5517a64
7 изменённых файлов: 388 добавлений и 127 удалений

Двоичные данные
toolkit/crashreporter/client/Throbber-small.avi Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -6,7 +6,7 @@
name="CrashReporter"
type="win32"
/>
<description>Updater</description>
<description>Crash Reporter</description>
<dependency>
<dependentAssembly>
<assemblyIdentity

Просмотреть файл

@ -15,6 +15,8 @@
#include <iostream>
#include <fstream>
#define MAX_COMMENT_LENGTH 500
#if defined(XP_WIN32)
#include <windows.h>
@ -35,19 +37,27 @@ typedef std::map<std::string, std::string> StringTable;
#define ST_CRASHREPORTERTITLE "CrashReporterTitle"
#define ST_CRASHREPORTERVENDORTITLE "CrashReporterVendorTitle"
#define ST_CRASHREPORTERERROR "CrashReporterError"
#define ST_CRASHREPORTERERROR "CrashReporterErrorText"
#define ST_CRASHREPORTERPRODUCTERROR "CrashReporterProductError"
#define ST_CRASHREPORTERHEADER "CrashReporterHeader"
#define ST_CRASHREPORTERDESCRIPTION "CrashReporterDescription"
#define ST_CRASHREPORTERHEADER "CrashReporterSorry"
#define ST_CRASHREPORTERDESCRIPTION "CrashReporterDescriptionText"
#define ST_CRASHREPORTERDEFAULT "CrashReporterDefault"
#define ST_VIEWREPORT "ViewReport"
#define ST_VIEWREPORT "Details"
#define ST_VIEWREPORTTITLE "ViewReportTitle"
#define ST_COMMENTGRAYTEXT "CommentGrayText"
#define ST_EXTRAREPORTINFO "ExtraReportInfo"
#define ST_CHECKSUBMIT "CheckSubmit"
#define ST_CHECKURL "CheckURL"
#define ST_CHECKEMAIL "CheckEmail"
#define ST_CLOSE "Close"
#define ST_CHECKSUBMIT "CheckSendReport"
#define ST_CHECKURL "CheckIncludeURL"
#define ST_CHECKEMAIL "CheckSendEmail"
#define ST_EMAILGRAYTEXT "EmailGrayText"
#define ST_REPORTPRESUBMIT "ReportPreSubmit"
#define ST_REPORTDURINGSUBMIT "ReportDuringSubmit"
#define ST_REPORTSUBMITSUCCESS "ReportSubmitSuccess"
#define ST_SUBMITFAILED "ReportSubmitFailed"
#define ST_QUIT "Quit"
#define ST_RESTART "Restart"
#define ST_SUBMITFAILED "SubmitFailed"
#define ST_OK "Ok"
#define ST_CLOSE "Close"
#define ST_ERROR_BADARGUMENTS "ErrorBadArguments"
#define ST_ERROR_EXTRAFILEEXISTS "ErrorExtraFileExists"

Просмотреть файл

@ -54,30 +54,49 @@ END
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_DIALOG ICON "crashreporter.ico"
IDI_MAINICON ICON "crashreporter.ico"
/////////////////////////////////////////////////////////////////////////////
//
// AVI
//
IDR_THROBBER AVI "Throbber-small.avi"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_SENDDIALOG DIALOGEX 0, 0, 241, 126
IDD_SENDDIALOG DIALOGEX 0, 0, 241, 187
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Sending Crash Report..."
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_DESCRIPTIONTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY,7,7,226,12,WS_EX_TRANSPARENT
CONTROL "view report",IDC_VIEWREPORTCHECK,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP,12,24,54,12
CONTROL "",IDC_VIEWREPORTTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY | NOT WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP,12,38,222,56
CONTROL "submit a crash report to mozilla",IDC_SUBMITREPORTCHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,42,222,10
CONTROL "include the URL in the crash report",IDC_INCLUDEURLCHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,57,222,10
CONTROL "email me when the problem is fixed",IDC_EMAILMECHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,70,222,10
EDITTEXT IDC_EMAILTEXT,26,83,208,14,ES_AUTOHSCROLL
PUSHBUTTON "close",IDC_CLOSEBUTTON,111,105,50,14
DEFPUSHBUTTON "restart firefox",IDC_RESTARTBUTTON,166,105,68,14
CONTROL "",IDC_DESCRIPTIONTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY,8,7,226,12,WS_EX_TRANSPARENT
CONTROL "tell mozilla about this crash so they can fix it",IDC_SUBMITREPORTCHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,25,222,10
CHECKBOX "details...",IDC_VIEWREPORTBUTTON,24,40,54,14,BS_PUSHLIKE
EDITTEXT IDC_COMMENTTEXT,24,59,210,43,ES_MULTILINE | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
CONTROL "include the address of the page i was on",IDC_INCLUDEURLCHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,107,210,10
CONTROL "tell mozilla to email me with more information",IDC_EMAILMECHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,120,210,10
EDITTEXT IDC_EMAILTEXT,36,133,198,14,ES_AUTOHSCROLL
CONTROL "",IDC_THROBBER,"SysAnimate32",ACS_TRANSPARENT | NOT WS_VISIBLE | WS_TABSTOP,4,152,16,16
LTEXT "your crash report will be submitted when you restart",IDC_PROGRESSTEXT,24,152,210,10,SS_NOPREFIX
PUSHBUTTON "quit without sending",IDC_CLOSEBUTTON,84,166,77,14
DEFPUSHBUTTON "restart firefox",IDC_RESTARTBUTTON,166,166,68,14
END
IDD_VIEWREPORTDIALOG DIALOGEX 0, 0, 208, 126
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
CAPTION "view report"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_VIEWREPORTTEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY | WS_BORDER | WS_VSCROLL | WS_TABSTOP,7,7,194,92
DEFPUSHBUTTON "OK",IDOK,151,105,50,14
END
@ -91,9 +110,17 @@ GUIDELINES DESIGNINFO
BEGIN
IDD_SENDDIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
LEFTMARGIN, 8
RIGHTMARGIN, 234
TOPMARGIN, 7
BOTTOMMARGIN, 180
END
IDD_VIEWREPORTDIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 201
TOPMARGIN, 7
BOTTOMMARGIN, 119
END
END

Просмотреть файл

@ -95,12 +95,14 @@ static set<UINT> gAttachedBottom;
// Default set of items for gAttachedBottom
static const UINT kDefaultAttachedBottom[] = {
IDC_VIEWREPORTCHECK,
IDC_VIEWREPORTTEXT,
IDC_SUBMITCRASHCHECK,
IDC_SUBMITREPORTCHECK,
IDC_VIEWREPORTBUTTON,
IDC_COMMENTTEXT,
IDC_INCLUDEURLCHECK,
IDC_EMAILMECHECK,
IDC_EMAILTEXT,
IDC_PROGRESSTEXT,
IDC_THROBBER,
IDC_CLOSEBUTTON,
IDC_RESTARTBUTTON,
};
@ -271,13 +273,8 @@ static void GetRelativeRect(HWND hwnd, HWND hwndParent, RECT* r)
static void SetDlgItemVisible(HWND hwndDlg, UINT item, bool visible)
{
HWND hwnd = GetDlgItem(hwndDlg, item);
LONG style = GetWindowLong(hwnd, GWL_STYLE);
if (visible)
style |= WS_VISIBLE;
else
style &= ~WS_VISIBLE;
SetWindowLong(hwnd, GWL_STYLE, style);
ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE);
}
static void SetDlgItemDisabled(HWND hwndDlg, UINT item, bool disabled)
@ -375,6 +372,21 @@ static void MaybeSendReport(HWND hwndDlg)
return;
}
// disable all the form controls
EnableWindow(GetDlgItem(hwndDlg, IDC_SUBMITREPORTCHECK), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_COMMENTTEXT), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_CLOSEBUTTON), false);
EnableWindow(GetDlgItem(hwndDlg, IDC_RESTARTBUTTON), false);
SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT, Str(ST_REPORTDURINGSUBMIT).c_str());
// start throbber
// play entire AVI, and loop
Animate_Play(GetDlgItem(hwndDlg, IDC_THROBBER), 0, -1, -1);
SetDlgItemVisible(hwndDlg, IDC_THROBBER, true);
gThreadHandle = NULL;
gSendData.hDlg = hwndDlg;
gSendData.queryParameters = gQueryParameters;
@ -425,32 +437,6 @@ static void ShowReportInfo(HWND hwndDlg)
SetDlgItemText(hwndDlg, IDC_VIEWREPORTTEXT, description.c_str());
}
static void ShowHideReport(HWND hwndDlg)
{
// When resizing the dialog to show the report, these items should
// stay put
gAttachedBottom.erase(IDC_VIEWREPORTCHECK);
gAttachedBottom.erase(IDC_VIEWREPORTTEXT);
RECT r;
HWND hwnd = GetDlgItem(hwndDlg, IDC_VIEWREPORTTEXT);
GetWindowRect(hwnd, &r);
int diff = (r.bottom - r.top) + 10;
if (IsDlgButtonChecked(hwndDlg, IDC_VIEWREPORTCHECK)) {
SetDlgItemVisible(hwndDlg, IDC_VIEWREPORTTEXT, true);
} else {
SetDlgItemVisible(hwndDlg, IDC_VIEWREPORTTEXT, false);
diff = -diff;
}
StretchDialog(hwndDlg, diff);
// set these back to normal
gAttachedBottom.insert(IDC_VIEWREPORTCHECK);
gAttachedBottom.insert(IDC_VIEWREPORTTEXT);
}
static void UpdateURL(HWND hwndDlg)
{
if (IsDlgButtonChecked(hwndDlg, IDC_INCLUDEURLCHECK)) {
@ -466,11 +452,173 @@ static void UpdateEmail(HWND hwndDlg)
wchar_t email[MAX_EMAIL_LENGTH];
GetDlgItemText(hwndDlg, IDC_EMAILTEXT, email, sizeof(email));
gQueryParameters[L"Email"] = email;
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), true);
} else {
gQueryParameters.erase(L"Email");
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), false);
}
}
static void UpdateComment(HWND hwndDlg)
{
wchar_t comment[MAX_COMMENT_LENGTH + 1];
GetDlgItemText(hwndDlg, IDC_COMMENTTEXT, comment, sizeof(comment));
if (wcslen(comment) > 0)
gQueryParameters[L"Comments"] = comment;
else
gQueryParameters.erase(L"Comments");
}
/*
* Dialog procedure for the "view report" dialog.
*/
static BOOL CALLBACK ViewReportDialogProc(HWND hwndDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_INITDIALOG: {
SetWindowText(hwndDlg, Str(ST_VIEWREPORTTITLE).c_str());
SetDlgItemText(hwndDlg, IDOK, Str(ST_OK).c_str());
SendDlgItemMessage(hwndDlg, IDC_VIEWREPORTTEXT,
EM_SETTARGETDEVICE, (WPARAM)NULL, 0);
ShowReportInfo(hwndDlg);
SetFocus(GetDlgItem(hwndDlg, IDOK));
return FALSE;
}
case WM_COMMAND: {
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
EndDialog(hwndDlg, 0);
return FALSE;
}
}
return FALSE;
}
// Return the number of bytes this string will take encoded
// in UTF-8
static inline int BytesInUTF8(wchar_t* str)
{
// Just count size of buffer for UTF-8, minus one
// (we don't need to count the null terminator)
return WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL) - 1;
}
// Calculate the length of the text in this edit control (in bytes,
// in the UTF-8 encoding) after replacing the current selection
// with |insert|.
static int NewTextLength(HWND hwndEdit, wchar_t* insert)
{
wchar_t current[MAX_COMMENT_LENGTH + 1];
GetWindowText(hwndEdit, current, MAX_COMMENT_LENGTH + 1);
DWORD selStart, selEnd;
SendMessage(hwndEdit, EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd);
int selectionLength = 0;
if (selEnd - selStart > 0) {
wchar_t selection[MAX_COMMENT_LENGTH + 1];
wcsncpy_s(selection, current + selStart, selEnd - selStart);
selection[selEnd - selStart] = '\0';
selectionLength = BytesInUTF8(selection);
}
// current string length + replacement text length
// - replaced selection length
return BytesInUTF8(current) + BytesInUTF8(insert) - selectionLength;
}
// Window procedure for subclassing edit controls
static LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
static WNDPROC super = NULL;
if (super == NULL)
super = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
switch (uMsg) {
case WM_PAINT: {
HDC hdc;
PAINTSTRUCT ps;
RECT r;
wchar_t windowText[1024];
GetWindowText(hwnd, windowText, 1024);
// if the control contains text or is focused, draw it normally
if (GetFocus() == hwnd || windowText[0] != '\0')
return CallWindowProc(super, hwnd, uMsg, wParam, lParam);
GetClientRect(hwnd, &r);
hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &r, GetSysColorBrush(IsWindowEnabled(hwnd)
? COLOR_WINDOW : COLOR_BTNFACE));
SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
SelectObject(hdc, (HFONT)GetStockObject(DEFAULT_GUI_FONT));
SetBkMode(hdc, TRANSPARENT);
wchar_t* txt = (wchar_t*)GetProp(hwnd, L"PROP_GRAYTEXT");
// Get the actual edit control rect
CallWindowProc(super, hwnd, EM_GETRECT, 0, (LPARAM)&r);
if (txt)
DrawText(hdc, txt, wcslen(txt), &r,
DT_EDITCONTROL | DT_NOPREFIX | DT_WORDBREAK | DT_INTERNAL);
EndPaint(hwnd, &ps);
return 0;
}
// We handle WM_CHAR and WM_PASTE to limit the comment box to 500
// bytes in UTF-8.
case WM_CHAR: {
// Leave accelerator keys and non-printing chars (except LF) alone
if (wParam & (1<<24) || wParam & (1<<29) ||
(wParam < ' ' && wParam != '\n'))
break;
wchar_t ch[2] = { (wchar_t)wParam, 0 };
if (NewTextLength(hwnd, ch) > MAX_COMMENT_LENGTH)
return 0;
break;
}
case WM_PASTE: {
if (IsClipboardFormatAvailable(CF_UNICODETEXT) &&
OpenClipboard(hwnd)) {
HGLOBAL hg = GetClipboardData(CF_UNICODETEXT);
wchar_t* pastedText = (wchar_t*)GlobalLock(hg);
int newSize = 0;
if (pastedText)
newSize = NewTextLength(hwnd, pastedText);
GlobalUnlock(hg);
CloseClipboard();
if (newSize > MAX_COMMENT_LENGTH)
return 0;
}
break;
}
case WM_SETFOCUS:
case WM_KILLFOCUS: {
RECT r;
GetClientRect(hwnd, &r);
InvalidateRect(hwnd, &r, TRUE);
break;
}
case WM_DESTROY: {
// cleanup our property
HGLOBAL hData = RemoveProp(hwnd, L"PROP_GRAYTEXT");
if (hData)
GlobalFree(hData);
}
}
return CallWindowProc(super, hwnd, uMsg, wParam, lParam);
}
static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
@ -486,6 +634,10 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
sHeight = r.bottom - r.top;
SetWindowText(hwndDlg, Str(ST_CRASHREPORTERTITLE).c_str());
HICON hIcon = LoadIcon(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDI_MAINICON));
SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
SendDlgItemMessage(hwndDlg, IDC_DESCRIPTIONTEXT,
EM_SETEVENTMASK, (WPARAM)NULL,
@ -510,24 +662,33 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
// resize the "View Report" button based on the string length
RECT viewRect;
HWND hwndView = GetDlgItem(hwndDlg, IDC_VIEWREPORTCHECK);
HWND hwndView = GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON);
GetRelativeRect(hwndView, hwndDlg, &viewRect);
HDC hdc = GetDC(hwndView);
const wstring viewButtonText = Str(ST_VIEWREPORT);
SIZE size;
wchar_t oldViewButtonText[1024];
GetDlgItemText(hwndDlg, IDC_VIEWREPORTBUTTON, oldViewButtonText, 1024);
SIZE size, oldSize;
if (GetTextExtentPoint32(hdc, viewButtonText.c_str(),
viewButtonText.length(), &size)) {
// shift right by the amount the button should grow
int sizeDiff = size.cx - (viewRect.right - viewRect.left);
viewRect.right += sizeDiff;
MoveWindow(hwndView, viewRect.left, viewRect.top,
viewRect.right - viewRect.left,
viewRect.bottom - viewRect.top,
TRUE);
viewButtonText.length(), &size) &&
// default text on the button
GetTextExtentPoint32(hdc, oldViewButtonText,
wcslen(oldViewButtonText), &oldSize)) {
// grow right right by the amount it changed
int sizeDiff = size.cx - oldSize.cx;
// don't bother shrinking the button
if (sizeDiff > 0) {
viewRect.right += sizeDiff;
MoveWindow(hwndView, viewRect.left, viewRect.top,
viewRect.right - viewRect.left,
viewRect.bottom - viewRect.top,
TRUE);
}
}
SetDlgItemText(hwndDlg, IDC_VIEWREPORTCHECK, viewButtonText.c_str());
SendDlgItemMessage(hwndDlg, IDC_VIEWREPORTTEXT,
EM_SETTARGETDEVICE, (WPARAM)NULL, 0);
SetDlgItemText(hwndDlg, IDC_VIEWREPORTBUTTON, viewButtonText.c_str());
SetDlgItemText(hwndDlg, IDC_SUBMITREPORTCHECK,
@ -536,13 +697,29 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
SUBMIT_REPORT_VALUE, &enabled) &&
!enabled) {
CheckDlgButton(hwndDlg, IDC_SUBMITREPORTCHECK, BST_UNCHECKED);
EnableWindow(GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_COMMENTTEXT), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), enabled);
SetDlgItemVisible(hwndDlg, IDC_PROGRESSTEXT, enabled);
} else {
CheckDlgButton(hwndDlg, IDC_SUBMITREPORTCHECK, BST_CHECKED);
}
HWND hwndComment = GetDlgItem(hwndDlg, IDC_COMMENTTEXT);
WNDPROC OldWndProc = (WNDPROC)SetWindowLongPtr(hwndComment,
GWLP_WNDPROC,
(LONG_PTR)EditSubclassProc);
// Subclass comment edit control to get placeholder text
SetWindowLongPtr(hwndComment, GWLP_USERDATA, (LONG_PTR)OldWndProc);
wstring commentGrayText = Str(ST_COMMENTGRAYTEXT);
wchar_t* hMem = (wchar_t*)GlobalAlloc(GPTR, (commentGrayText.length() + 1)*sizeof(wchar_t));
wcscpy(hMem, commentGrayText.c_str());
SetProp(hwndComment, L"PROP_GRAYTEXT", hMem);
SetDlgItemText(hwndDlg, IDC_INCLUDEURLCHECK, Str(ST_CHECKURL).c_str());
// want this on by default
if (CheckBoolKey(gCrashReporterKey.c_str(), INCLUDE_URL_VALUE, &enabled) &&
@ -565,7 +742,19 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
SetDlgItemText(hwndDlg, IDC_EMAILTEXT, email.c_str());
}
SetDlgItemText(hwndDlg, IDC_CLOSEBUTTON, Str(ST_CLOSE).c_str());
// Subclass email edit control to get placeholder text
HWND hwndEmail = GetDlgItem(hwndDlg, IDC_EMAILTEXT);
OldWndProc = (WNDPROC)SetWindowLongPtr(hwndEmail,
GWLP_WNDPROC,
(LONG_PTR)EditSubclassProc);
SetWindowLongPtr(hwndEmail, GWLP_USERDATA, (LONG_PTR)OldWndProc);
wstring emailGrayText = Str(ST_EMAILGRAYTEXT);
hMem = (wchar_t*)GlobalAlloc(GPTR, (emailGrayText.length() + 1)*sizeof(wchar_t));
wcscpy(hMem, emailGrayText.c_str());
SetProp(hwndEmail, L"PROP_GRAYTEXT", hMem);
SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT, Str(ST_REPORTPRESUBMIT).c_str());
SetDlgItemText(hwndDlg, IDC_CLOSEBUTTON, Str(ST_QUIT).c_str());
RECT closeRect;
HWND hwndClose = GetDlgItem(hwndDlg, IDC_CLOSEBUTTON);
@ -616,22 +805,25 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
SetDlgItemVisible(hwndDlg, IDC_INCLUDEURLCHECK, false);
gAttachedBottom.erase(IDC_VIEWREPORTCHECK);
gAttachedBottom.erase(IDC_VIEWREPORTTEXT);
gAttachedBottom.erase(IDC_VIEWREPORTBUTTON);
gAttachedBottom.erase(IDC_SUBMITREPORTCHECK);
gAttachedBottom.erase(IDC_COMMENTTEXT);
StretchDialog(hwndDlg, urlCheckRect.top - emailCheckRect.top);
gAttachedBottom.insert(IDC_VIEWREPORTCHECK);
gAttachedBottom.insert(IDC_VIEWREPORTTEXT);
gAttachedBottom.insert(IDC_VIEWREPORTBUTTON);
gAttachedBottom.insert(IDC_SUBMITREPORTCHECK);
gAttachedBottom.insert(IDC_COMMENTTEXT);
}
// Open the AVI resource for the throbber
Animate_Open(GetDlgItem(hwndDlg, IDC_THROBBER),
MAKEINTRESOURCE(IDR_THROBBER));
UpdateURL(hwndDlg);
UpdateEmail(hwndDlg);
ShowReportInfo(hwndDlg);
SetFocus(GetDlgItem(hwndDlg, IDC_EMAILTEXT));
SetFocus(GetDlgItem(hwndDlg, IDC_SUBMITREPORTCHECK));
return FALSE;
}
case WM_SIZE: {
@ -662,33 +854,31 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
case WM_COMMAND: {
if (HIWORD(wParam) == BN_CLICKED) {
switch(LOWORD(wParam)) {
case IDC_VIEWREPORTCHECK:
ShowHideReport(hwndDlg);
case IDC_VIEWREPORTBUTTON:
DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_VIEWREPORTDIALOG), hwndDlg,
(DLGPROC)ViewReportDialogProc, 0);
break;
case IDC_SUBMITREPORTCHECK:
enabled = (IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK) != 0);
EnableWindow(GetDlgItem(hwndDlg, IDC_VIEWREPORTBUTTON), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_COMMENTTEXT), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_INCLUDEURLCHECK), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILMECHECK), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT), enabled);
EnableWindow(GetDlgItem(hwndDlg, IDC_EMAILTEXT),
enabled && (IsDlgButtonChecked(hwndDlg, IDC_EMAILMECHECK)
!= 0));
SetDlgItemVisible(hwndDlg, IDC_PROGRESSTEXT, enabled);
break;
case IDC_INCLUDEURLCHECK:
UpdateURL(hwndDlg);
ShowReportInfo(hwndDlg);
break;
case IDC_EMAILMECHECK:
UpdateEmail(hwndDlg);
ShowReportInfo(hwndDlg);
break;
case IDC_CLOSEBUTTON:
// Hide the dialog after "closing", but leave it around to coordinate
// with the upload thread
ShowWindow(hwndDlg, SW_HIDE);
MaybeSendReport(hwndDlg);
EndCrashReporterDialog(hwndDlg, 0);
break;
case IDC_RESTARTBUTTON:
// Hide the dialog after "closing", but leave it around to coordinate
// with the upload thread
ShowWindow(hwndDlg, SW_HIDE);
RestartApplication();
MaybeSendReport(hwndDlg);
break;
@ -696,13 +886,10 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
} else if (HIWORD(wParam) == EN_CHANGE) {
switch(LOWORD(wParam)) {
case IDC_EMAILTEXT:
wchar_t email[MAX_EMAIL_LENGTH];
if (GetDlgItemText(hwndDlg, IDC_EMAILTEXT, email, sizeof(email)) > 0)
CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_CHECKED);
else
CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_UNCHECKED);
UpdateEmail(hwndDlg);
ShowReportInfo(hwndDlg);
break;
case IDC_COMMENTTEXT:
UpdateComment(hwndDlg);
}
}
@ -712,15 +899,41 @@ static BOOL CALLBACK CrashReporterDialogProc(HWND hwndDlg, UINT message,
WaitForSingleObject(gThreadHandle, INFINITE);
success = (wParam == 1);
SendCompleted(success, WideToUTF8(gSendData.serverResponse));
if (!success) {
MessageBox(hwndDlg,
Str(ST_SUBMITFAILED).c_str(),
Str(ST_CRASHREPORTERTITLE).c_str(),
MB_OK | MB_ICONERROR);
}
EndCrashReporterDialog(hwndDlg, success ? 1 : 0);
// hide throbber
Animate_Stop(GetDlgItem(hwndDlg, IDC_THROBBER));
SetDlgItemVisible(hwndDlg, IDC_THROBBER, false);
SetDlgItemText(hwndDlg, IDC_PROGRESSTEXT,
success ?
Str(ST_REPORTSUBMITSUCCESS).c_str() :
Str(ST_SUBMITFAILED).c_str());
// close dialog after 5 seconds
SetTimer(hwndDlg, success ? 1 : 0, 5000, NULL);
//
return TRUE;
}
case WM_LBUTTONDOWN: {
HWND hwndEmail = GetDlgItem(hwndDlg, IDC_EMAILTEXT);
POINT p = { LOWORD(lParam), HIWORD(lParam) };
// if the email edit control is clicked, enable it,
// check the email checkbox, and focus the email edit control
if (ChildWindowFromPoint(hwndDlg, p) == hwndEmail &&
!IsWindowEnabled(hwndEmail) &&
IsDlgButtonChecked(hwndDlg, IDC_SUBMITREPORTCHECK) != 0) {
CheckDlgButton(hwndDlg, IDC_EMAILMECHECK, BST_CHECKED);
UpdateEmail(hwndDlg);
SetFocus(hwndEmail);
}
break;
}
case WM_TIMER: {
// wParam is the second parameter from SetTimer above
EndCrashReporterDialog(hwndDlg, wParam);
return FALSE;
}
case WM_CLOSE: {
EndCrashReporterDialog(hwndDlg, 0);
return FALSE;
@ -796,6 +1009,7 @@ bool UIInit()
}
DoInitCommonControls();
return true;
}

Просмотреть файл

@ -3,27 +3,29 @@
// Used by crashreporter.rc
//
#define IDD_SENDDIALOG 102
#define IDR_THROBBER 103
#define IDD_VIEWREPORTDIALOG 104
#define IDI_MAINICON 105
#define IDC_PROGRESS 1003
#define IDC_DESCRIPTIONTEXT 1004
#define IDC_CLOSEBUTTON 1005
#define IDC_VIEWREPORTBUTTON 1006
#define IDC_SUBMITCRASHCHECK 1007
#define IDC_SUBMITREPORTCHECK 1007
#define IDC_EMAILMECHECK 1008
#define IDC_EMAILTEXT 1009
#define IDC_HEADERLABEL 1010
#define IDC_INCLUDEURLCHECK 1010
#define IDC_COMMENTTEXT 1011
#define IDC_RESTARTBUTTON 1012
#define IDC_DESCRIPTIONLABEL 1013
#define IDC_VIEWREPORTTEXT 1015
#define IDC_VIEWREPORTCHECK 1016
#define IDC_PROGRESSLABEL -1
#define IDC_PROGRESSTEXT 1014
#define IDC_THROBBER 1015
#define IDC_VIEWREPORTTEXT 1016
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1017
#define _APS_NEXT_SYMED_VALUE 101

Просмотреть файл

@ -3,24 +3,33 @@
CrashReporterTitle=Crash Reporter
# LOCALIZATION NOTE (CrashReporterVendorTitle): %s is replaced with the vendor name. (i.e. "Mozilla")
CrashReporterVendorTitle=%s Crash Reporter
# LOCALIZATION NOTE (CrashReporterError): %s is replaced with another string containing detailed information.
CrashReporterError=We're sorry, but the application hit an unexpected problem and crashed.\n\nUnfortunately the crash reporter is unable to submit a report for this crash.\n\nDetails: %s
# LOCALIZATION NOTE (CrashReporterProductError): The first %s is replaced with the product name (i.e. "Firefox"), the second is replaced with another string containing detailed information. These two substitutions can not be reordered!
CrashReporterProductError=We're sorry, but %s hit an unexpected problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nUnfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
CrashReporterHeader=Crash! Bang! Boom!
# LOCALIZATION NOTE (CrashReporterDescription): The %s is replaced with the product name.
CrashReporterDescription=We're sorry, but %s hit an unexpected problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nTo help us diagnose and repair this problem, you can send us a crash report.
# LOCALIZATION NOTE (CrashReporterErrorText): %s is replaced with another string containing detailed information.
CrashReporterErrorText=The application had problem and crashed.\n\nUnfortunately the crash reporter is unable to submit a report for this crash.\n\nDetails: %s
# LOCALIZATION NOTE (CrashReporterProductErrorText): The first %s is replaced with the product name (i.e. "Firefox"), the second is replaced with another string containing detailed information. These two substitutions can not be reordered!
CrashReporterProductError=%s had a problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nUnfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
CrashReporterSorry=We're Sorry
# LOCALIZATION NOTE (CrashReporterDescriptionText): The %s is replaced with the product name.
CrashReporterDescriptionText=%s hit an unexpected problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nTo help us diagnose and fix the problem, you can send us a crash report.
CrashReporterDefault=This application is run after a crash to report the problem to the application vendor. It should not be run directly.
ViewReport=View Report
ExtraReportInfo=This report also contains information about the state of the application when it crashed.
# LOCALIZATION NOTE (CheckSubmit): The %s is replaced with the vendor name.
CheckSubmit=Submit crash report to %s
CheckURL=Include the URL in the crash report
CheckEmail=Email me when the problem is fixed
Close=Close
Details=Details…
ViewReportTitle=Report Contents
CommentGrayText=Add a comment. Note: Comments are publicly visible
ExtraReportInfo=This report also contains technical information about the state of the application when it crashed.
# LOCALIZATION NOTE (CheckSendReport): The %s is replaced with the vendor name.
CheckSendReport=Tell %s about this crash so they can fix it
CheckIncludeURL=Include the address of the page I was on
CheckSendEmail=Email me when more information is available
EmailGrayText=Enter your email address here
ReportPreSubmit=Your crash report will be submitted when you restart.
ReportDuringSubmit=Submitting your report and restarting…
ReportSubmitSuccess=Report submitted successfully!
ReportSubmitFailed=There was a problem submitting your report.
Quit=Quit without sending
# LOCALIZATION NOTE (Restart): The %s is replaced with the product name.
Restart=Restart %s
SubmitFailed=Failed to submit crash report
Ok=OK
Close=Close
# LOCALIZATION NOTE (CrashID): The %s is replaced with the Crash ID from the server, which is a string like abc12345-6789-0abc-def1-23456abcdef1
CrashID=Crash ID: %s
# LOCALIZATION NOTE (CrashDetailsURL): The %s is replaced with a URL that the user can visit to view the crash details.
@ -35,4 +44,3 @@ ErrorNoProductName=The application did not identify itself.
ErrorNoServerURL=The application did not specify a crash reporting server.
ErrorNoSettingsPath=Couldn't find the crash reporter's settings.
ErrorCreateDumpDir=Couldn't create pending dump directory.