blob: 6a4bf12c90425419eb15f1cdb69ab815b0771563 [file] [log] [blame]
// wxGUI.cpp
#include "StdAfx.h"
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#undef _WIN32
#ifdef __WXMAC__
#define UInt32 max_UInt32
#include <ApplicationServices/ApplicationServices.h>
#undef UInt32
#endif
#define static const
#include "../GUI/p7zip_32.xpm"
#undef static
#undef ACTIVATE_DIALOG_TESTS
#ifdef _WIN32
#error 5
#endif
#include "Windows/Window.h"
#include "Windows/Control/DialogImpl.h"
// FIXME
static pthread_t g_main_thread;
bool is_main_thread(void)
{
return ( g_main_thread == pthread_self() );
}
void verify_main_thread(void)
{
if ( ! is_main_thread() )
{
printf("verify_main_thread-wxGUI\n");
abort();
}
}
int Main1(int argc,TCHAR **argv);
#include "Windows/Registry.h"
using namespace NWindows;
using namespace NRegistry;
#include "Common/StringConvert.h"
#include "Windows/FileDir.h"
#include "Windows/Synchronization.h"
#include "ExtractRes.h"
#include "../Explorer/MyMessages.h"
#include "../FileManager/resourceGui.h"
#include "ExtractGUI.h"
#include "UpdateGUI.h"
#include "BenchmarkDialog.h"
#include "../FileManager/RegistryUtils.h"
using namespace NWindows;
using namespace NFile;
#include "../FileManager/ProgramLocation.h"
static LPCWSTR kHelpFileName = L"help/";
void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile)
{
UString path;
if (!::GetProgramFolderPath(path))
return;
path += kHelpFileName;
path += topicFile;
printf("ShowHelpWindow(%p,%ls)=>%ls\n",hwnd,topicFile,(const wchar_t *)path);
// HtmlHelp(hwnd, GetSystemString(path), HH_DISPLAY_TOPIC, NULL);
wxString path2(path);
wxLaunchDefaultBrowser(path2);
}
////////////////////////////// TRIES ///////////////////////////////////
#ifdef ACTIVATE_DIALOG_TESTS
static void ErrorMessage(const wchar_t *message)
{
MessageBox(0,message, wxT("7-Zip GUI"),wxICON_ERROR);
}
#include "../FileManager/PasswordDialog.h"
#include "../FileManager/MessagesDialog.h"
#include "../FileManager/OverwriteDialog.h"
#include "Windows/Thread.h"
void myErrorMsg(const wchar_t *message)
{
MessageBox(0,message, wxT("Message"),wxICON_ERROR);
}
void testCMessagesDialog()
{
UStringVector Messages;
Messages.Add(L"message 1");
Messages.Add(L"message 2");
Messages.Add(L"message 3");
Messages.Add(L"message 4");
Messages.Add(L"message 5");
Messages.Add(L"message 6");
Messages.Add(L"message 7");
Messages.Add(L"message 8");
Messages.Add(L"message 9");
CMessagesDialog messagesDialog;
messagesDialog.Messages = &Messages;
int ret = messagesDialog.Create( 0 ); // ParentWindow
if (ret == IDOK) myErrorMsg(wxT("CMessagesDialog => IDOK"));
else if (ret == IDCANCEL) myErrorMsg(wxT("CMessagesDialog => IDCANCEL"));
else myErrorMsg(wxT("CMessagesDialog => ?"));
}
void testCOverwriteDialog()
{
SYSTEMTIME systemTime;
GetSystemTime( &systemTime );
const wchar_t *existName = L"existName";
FILETIME data_existTime;
FILETIME *existTime = &data_existTime ;
UInt64 data_existSize = 1234;
UInt64 *existSize = &data_existSize;
const wchar_t *newName = L"newName";
FILETIME data_newTime;
FILETIME *newTime = &data_newTime;
UInt64 data_newSize = 45678;
UInt64 *newSize = &data_newSize;
Int32 data_answer=0;
Int32 *answer = &data_answer;
SystemTimeToFileTime( &systemTime , &data_existTime);
SystemTimeToFileTime( &systemTime , &data_newTime);
COverwriteDialog dialog;
dialog.OldFileInfo.Time = *existTime;
dialog.OldFileInfo.TimeIsDefined = true; // FIXME : look again at the sample !
dialog.OldFileInfo.SizeIsDefined = (existSize != NULL);
if (dialog.OldFileInfo.SizeIsDefined)
dialog.OldFileInfo.Size = *existSize;
dialog.OldFileInfo.Name = existName;
if (newTime == 0)
dialog.NewFileInfo.TimeIsDefined = false;
else
{
dialog.NewFileInfo.TimeIsDefined = true;
dialog.NewFileInfo.Time = *newTime;
}
dialog.NewFileInfo.SizeIsDefined = (newSize != NULL);
if (dialog.NewFileInfo.SizeIsDefined)
dialog.NewFileInfo.Size = *newSize;
dialog.NewFileInfo.Name = newName;
/*
NOverwriteDialog::NResult::EEnum writeAnswer =
NOverwriteDialog::Execute(oldFileInfo, newFileInfo);
*/
INT_PTR writeAnswer = dialog.Create(NULL); // ParentWindow doesn't work with 7z
switch(writeAnswer)
{
case IDCANCEL: myErrorMsg(wxT("COverwriteDialog => IDCANCEL")); break;
case IDNO: myErrorMsg(wxT("COverwriteDialog => IDNO")); break;
case IDC_BUTTON_OVERWRITE_NO_TO_ALL: myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_NO_TO_ALL")); break;
case IDC_BUTTON_OVERWRITE_YES_TO_ALL:myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_YES_TO_ALL")); break;
case IDC_BUTTON_OVERWRITE_AUTO_RENAME:myErrorMsg(wxT("COverwriteDialog => IDC_BUTTON_OVERWRITE_AUTO_RENAME")); break;
case IDYES: myErrorMsg(wxT("COverwriteDialog => IDYES")); break;
default: myErrorMsg(wxT("COverwriteDialog => default")); break;
}
}
void testCPasswordDialog()
{
CPasswordDialog dialog;
int ret = dialog.Create(0);
if (ret == IDOK) {
UString Password = dialog.Password;
UString msg = wxT("CPasswordDialog => IDOK password=\"");
msg += Password;
msg += wxT("\"");
myErrorMsg(msg);
}
else if (ret == IDCANCEL) myErrorMsg(wxT("CPasswordDialog => IDCANCEL"));
else myErrorMsg(wxT("CPasswordDialog => ?"));
}
struct CThreadProgressDialog
{
CProgressDialog * ProgressDialog;
static THREAD_FUNC_DECL MyThreadFunction(void *param)
{
((CThreadProgressDialog *)param)->Result = ((CThreadProgressDialog *)param)->Process();
return 0;
}
HRESULT Result;
HRESULT Process()
{
Sleep(1000);
int total = 1000;
ProgressDialog->ProgressSynch.SetTitleFileName(L"SetTitleFileName");
ProgressDialog->ProgressSynch.SetNumFilesTotal(100);
ProgressDialog->ProgressSynch.SetNumFilesCur(1);
ProgressDialog->ProgressSynch.SetProgress(total, 0);
// ProgressDialog.ProgressSynch.SetRatioInfo(inSize, outSize);
// ProgressDialog.ProgressSynch.SetCurrentFileName(name);
ProgressDialog->ProgressSynch.SetPos(total/10);
ProgressDialog->ProgressSynch.SetCurrentFileName(L"File1");
Sleep(1000);
ProgressDialog->ProgressSynch.SetPos(total/2);
ProgressDialog->ProgressSynch.SetCurrentFileName(L"File2");
Sleep(1000);
ProgressDialog->ProgressSynch.SetPos(total);
ProgressDialog->ProgressSynch.SetCurrentFileName(L"File3");
Sleep(1000);
ProgressDialog->MyClose();
return 0;
}
};
void testCProgressDialog()
{
CProgressDialog ProgressDialog;
CThreadProgressDialog benchmarker;
benchmarker.ProgressDialog = &ProgressDialog;
NWindows::CThread thread;
thread.Create(CThreadProgressDialog::MyThreadFunction, &benchmarker);
// void StartProgressDialog(const UString &title)
int ret = ProgressDialog.Create(L"testCProgressDialog", 0);
if (ret == IDOK) myErrorMsg(wxT("CProgressDialog => IDOK"));
else if (ret == IDCANCEL) myErrorMsg(wxT("CProgressDialog => IDCANCEL"));
else myErrorMsg(wxT("CProgressDialog => ?"));
}
void testDialog(int num)
{
NWindows::NControl::CModalDialog dialog;
printf("Generic Dialog(%d)\n",num);
int ret = dialog.Create(num, 0);
if (ret == IDOK) myErrorMsg(wxT("Generic Dialog => IDOK"));
else if (ret == IDCANCEL) myErrorMsg(wxT("Generic Dialog => IDCANCEL"));
else myErrorMsg(wxT("Generic Dialog => ?"));
}
void testMessageBox()
{
int ret = MessageBoxW(0, L"test yes/no/cancel",
L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL);
if (ret == IDYES) myErrorMsg(wxT("MessageBoxW => IDYES"));
else if (ret == IDNO) myErrorMsg(wxT("MessageBoxW => IDNO"));
else if (ret == IDCANCEL) myErrorMsg(wxT("MessageBoxW => IDCANCEL"));
else myErrorMsg(wxT("MessageBoxW => ?"));
}
static void testRegistry()
{
SaveRegLang(L"fr");
UString langFile;
ReadRegLang(langFile);
printf("testRegistry : -%ls-\n",(const wchar_t *)langFile);
}
int Main2(int argc,TCHAR **argv);
int Main3(int argc,wxChar **argv)
{
testRegistry();
int num = -1;
if (argc >=2 )
{
num = argv[1][0] - L'0';
}
printf("num=%d\n",num);
switch(num)
{
case 0:
{
TCHAR **argv2 = (TCHAR **)calloc(argc,sizeof(*argv));
argv2[0] = argv[0];
for(int i = 2; i < argc; i++) argv2[i-1] = argv[i];
return Main2(argc-1,argv2);
}
// TODO Benchmark
// TODO CCompressDialog
// TODO CExtractDialog ?
case 1 : testCMessagesDialog(); break;
case 2 : testCOverwriteDialog(); break;
case 3 : testCPasswordDialog(); break;
case 4 : testCProgressDialog(); break;
case 5 : testMessageBox(); break;
case 9 :
if (argc >= 3)
{
AString str = GetAnsiString(argv[2]);
int num = atoi((const char*)str);
testDialog(num);
}
else
{
printf("usage : 7zG 9 <windowID>\n");
}
break;
default :
printf("usage : 7zG number\n");
};
return 0;
}
#endif // ACTIVATE_DIALOG_TESTS
static const TCHAR *kCUBasePath = TEXT("Software/7-ZIP");
static const WCHAR *kLangValueName = L"Lang";
void SaveRegLang(const UString &langFile)
{
CKey key;
key.Create(HKEY_CURRENT_USER, kCUBasePath);
key.SetValue(kLangValueName, langFile);
}
void ReadRegLang(UString &langFile)
{
langFile.Empty();
CKey key;
if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS)
key.QueryValue(kLangValueName, langFile);
}
//////////////////////////////////
#define NEED_NAME_WINDOWS_TO_UNIX
#include "myPrivate.h" // global_use_utf16_conversion
void mySplitCommandLineW(int numArguments, TCHAR **arguments,UStringVector &parts) {
parts.Clear();
for(int ind=0;ind < numArguments; ind++) {
UString tmp = arguments[ind];
// tmp.Trim(); " " is a valid filename ...
if (!tmp.IsEmpty()) {
parts.Add(tmp);
// DEBUG printf("ARG %d : '%ls'\n",ind,(const wchar_t *)tmp);
}
}
}
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
// Define a new frame type
class MyFrame: public wxFrame
{
public:
// ctor
MyFrame(wxFrame *frame, const wxString& title, int x, int y, int w, int h);
// virtual ~MyFrame();
// operations
void WriteText(const wxString& text) { m_txtctrl->WriteText(text); }
protected:
// callbacks
void OnWorkerEvent(wxCommandEvent& event);
private:
// just some place to put our messages in
wxTextCtrl *m_txtctrl;
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(WORKER_EVENT, MyFrame::OnWorkerEvent)
// EVT_IDLE(MyFrame::OnIdle)
END_EVENT_TABLE()
// My frame constructor
MyFrame::MyFrame(wxFrame *frame, const wxString& title,
int x, int y, int w, int h)
: wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h))
{
this->SetIcon(wxICON(p7zip_32));
#if wxUSE_STATUSBAR
CreateStatusBar(2);
#endif // wxUSE_STATUSBAR
m_txtctrl = new wxTextCtrl(this, wxID_ANY, _T(""), wxPoint(0, 0), wxSize(0, 0), wxTE_MULTILINE | wxTE_READONLY);
}
void myCreateHandle(int n);
wxWindow * g_window=0;
void MyFrame::OnWorkerEvent(wxCommandEvent& event)
{
int n = event.GetInt();
myCreateHandle(n);
}
// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
public:
// override base class virtuals
// ----------------------------
// this one is called on application startup and is a good place for the app
// initialization (doing it here and not in the ctor allows to have an error
// return: if OnInit() returns false, the application terminates)
virtual bool OnInit();
};
// Create a new application object: this macro will allow wxWidgets to create
// the application object during program execution (it's better than using a
// static object for many reasons) and also implements the accessor function
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
// not wxApp)
IMPLEMENT_APP(MyApp)
time_t g_T0 = 0;
/* FIXME : to erase ?
class MyThread : public wxThread
{
int _argc;
TCHAR **_argv;
public:
MyThread(int argc,TCHAR **argv): wxThread(),_argc(argc), _argv(argv) {}
// thread execution starts here
virtual void *Entry()
{
#ifdef ACTIVATE_DIALOG_TESTS
int ret = Main3(_argc,_argv);
#else
int ret = Main1(_argc,_argv);
#endif
exit(ret);
}
};
*/
// 'Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
// don't parse the command-line options !
// : if ( !wxApp::OnInit() ) return false;
#ifdef __WXMAC__
ProcessSerialNumber PSN;
GetCurrentProcess(&PSN);
TransformProcessType(&PSN,kProcessTransformToForegroundApplication);
#endif
g_main_thread = pthread_self();
{ // define P7ZIP_HOME_DIR
extern void my_windows_split_path(const AString &p_path, AString &dir , AString &base);
static char p7zip_home_dir[MAX_PATH];
UString fullPath;
NDirectory::MyGetFullPathName(wxApp::argv[0], fullPath);
AString afullPath = GetAnsiString(fullPath);
AString dir,name;
my_windows_split_path(afullPath,dir,name);
const char *dir2 = nameWindowToUnix((const char *)dir);
snprintf(p7zip_home_dir,sizeof(p7zip_home_dir),"P7ZIP_HOME_DIR=%s/",dir2);
p7zip_home_dir[sizeof(p7zip_home_dir)-1] = 0;
putenv(p7zip_home_dir);
// DEBUG printf("putenv(%s)\n",p7zip_home_dir);
}
global_use_utf16_conversion = 1; // UNICODE !
g_T0 = time(0);
// DEBUG printf("MAIN Thread : 0x%lx\n",wxThread::GetCurrentId());
// Create the main frame window
MyFrame *frame = new MyFrame((wxFrame *)NULL, _T("7-zip Main Window"), 50, 50, 450, 340);
// Don't Show the frame !
// frame->Show(true);
g_window = frame;
SetTopWindow(frame);
/* FIXME ?
MyThread *thread = new MyThread(wxApp::argc,wxApp::argv);
thread->Create(); // != wxTHREAD_NO_ERROR
thread->Run();
// success: wxApp::OnRun() will be called which will enter the main message
// loop and the application will run. If we returned false here, the
// application would exit immediately.
return true;
*/
int ret = Main1(wxApp::argc,wxApp::argv);
exit(ret);
return false;
}
DWORD WINAPI GetTickCount(VOID) {
static wxStopWatch sw;
return sw.Time();
}
//////////////////////////////////////////
#include "resource2.h"
#include "ExtractRes.h"
static CStringTable g_stringTable[] =
{
/* resource.rc */
/***************/
{ IDS_PROGRESS_COMPRESSING, L"Compressing" },
{ IDS_PROGRESS_TESTING, L"Testing" },
{ IDS_MESSAGE_NO_ERRORS, L"There are no errors" },
{ IDS_FILES_COLON, L"Files:" },
{ IDS_FOLDERS_COLON, L"Folders:" },
{ IDS_SIZE_COLON, L"Size:" },
{ IDS_COMPRESSED_COLON, L"Compressed size:" },
{ IDS_ARCHIVES_COLON, L"Archives:" },
/* Extract.rc */
/**************/
{ IDS_CANNOT_CREATE_FOLDER , L"Cannot create folder '{0}'"},
{ IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE, L"File is not supported archive."},
{ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC , L"CRC failed in '{0}'. File is broken."},
{ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR , L"Data error in '{0}'. File is broken"},
{ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD , L"Unsupported compression method for '{0}'."},
{ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED , L"CRC failed in encrypted file '{0}'. Wrong password?"},
{ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED , L"Data error in encrypted file '{0}'. Wrong password?"},
{ IDS_EXTRACT_SET_FOLDER , L"Specify a location for extracted files."},
{ IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE, L"Can not open output file '{0}'."},
{ IDS_PROGRESS_EXTRACTING, L"Extracting" },
{ IDS_CANT_OPEN_ARCHIVE , L"Can not open file '{0}' as archive"},
{ IDS_CANT_OPEN_ENCRYPTED_ARCHIVE , L"Can not open encrypted archive '{0}'. Wrong password?"},
{ 0 , 0 }
};
REGISTER_STRINGTABLE(g_stringTable)