585 lines
14 KiB
C++
585 lines
14 KiB
C++
// Dialog.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
|
|
|
|
#include <wx/filename.h>
|
|
|
|
|
|
#undef _WIN32
|
|
|
|
#include "Windows/Control/DialogImpl.h"
|
|
#include "Windows/Synchronization.h"
|
|
|
|
// FIXME
|
|
class MyApp : public wxApp
|
|
{
|
|
public:
|
|
virtual bool OnInit();
|
|
};
|
|
|
|
DECLARE_APP(MyApp)
|
|
|
|
// #include "../GUI/p7zip_32.xpm"
|
|
extern const char * p7zip_32_xpm[];
|
|
|
|
const TCHAR * nameWindowToUnix(const TCHAR * lpFileName) {
|
|
if ((lpFileName[0] == wxT('c')) && (lpFileName[1] == wxT(':'))) return lpFileName+2;
|
|
return lpFileName;
|
|
}
|
|
|
|
|
|
extern time_t g_T0; // FIXME
|
|
|
|
#define DIALOG_ID_MESSAGEBOX 8100
|
|
#define DIALOG_ID_DIR_DIALOG 8101
|
|
#define DIALOG_ID_FILE_DIALOG 8102
|
|
#define DIALOG_ID_POST_DIALOG 8190
|
|
#define DIALOG_ID_END_DIALOG 8199
|
|
|
|
static struct
|
|
{
|
|
bool busy;
|
|
|
|
int id;
|
|
wxWindow *parentWindow;
|
|
|
|
// CreateDialog
|
|
NWindows::NControl::CModalDialog * dialog;
|
|
|
|
// EndModal
|
|
int value;
|
|
NWindows::NControl::CModalDialogImpl * window;
|
|
|
|
// MessageBox
|
|
const TCHAR * msg;
|
|
const TCHAR * title;
|
|
int flag;
|
|
|
|
//
|
|
LPCWSTR initialFolderOrFile;
|
|
|
|
wxSemaphore * sem;
|
|
int ret;
|
|
|
|
UString resultPath;
|
|
|
|
#define MAX_CREATE 16
|
|
} g_tabCreate[MAX_CREATE];
|
|
|
|
static int myCreateHandle2(int n);
|
|
|
|
static int findFreeInd()
|
|
{
|
|
static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
|
|
|
|
g_CriticalSection.Enter();
|
|
int ind = 0;
|
|
while (ind < MAX_CREATE)
|
|
{
|
|
if (g_tabCreate[ind].busy == false)
|
|
{
|
|
g_tabCreate[ind].busy = true;
|
|
break;
|
|
}
|
|
ind++;
|
|
}
|
|
g_CriticalSection.Leave();
|
|
|
|
return ind;
|
|
}
|
|
|
|
static int WaitInd(wxWindow * destWindow, int ind,int id,wxWindow * parent,UString &resultPath)
|
|
{
|
|
int ret = 0;
|
|
|
|
g_tabCreate[ind].id = id;
|
|
g_tabCreate[ind].parentWindow = parent;
|
|
g_tabCreate[ind].ret = 0;
|
|
g_tabCreate[ind].resultPath = wxEmptyString;
|
|
|
|
if (wxThread::IsMain())
|
|
{
|
|
ret = myCreateHandle2(ind);
|
|
resultPath = g_tabCreate[ind].resultPath;
|
|
}
|
|
else
|
|
{
|
|
if (destWindow == 0) {
|
|
extern wxWindow * g_window;
|
|
if (g_window == 0)
|
|
{
|
|
printf("INTERNAL ERROR : g_window and destWindow == NULL\n"); abort();
|
|
}
|
|
destWindow = g_window;
|
|
}
|
|
g_tabCreate[ind].sem = new wxSemaphore(0);
|
|
|
|
// create any type of command event here
|
|
wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT );
|
|
event.SetInt( ind );
|
|
|
|
// send in a thread-safe way
|
|
// DEBUG printf("T=0x%lx - %d : WaitInd(%d,%p): BEGIN\n", wxThread::GetCurrentId(),time(0)-g_T0,g_tabCreate[ind].id,g_tabCreate[ind].parentWindow);
|
|
wxPostEvent( destWindow, event );
|
|
|
|
g_tabCreate[ind].sem->Wait();
|
|
|
|
ret = g_tabCreate[ind].ret;
|
|
resultPath = g_tabCreate[ind].resultPath;
|
|
// DEBUG printf("T=0x%lx - %d : WaitInd(%d,%p): ret=%d\n", wxThread::GetCurrentId(),time(0)-g_T0,g_tabCreate[ind].id,g_tabCreate[ind].parentWindow,ret);
|
|
delete g_tabCreate[ind].sem;
|
|
g_tabCreate[ind].sem = 0;
|
|
}
|
|
|
|
g_tabCreate[ind].busy = false;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int WaitInd(wxWindow * destWindow,int ind,int id,wxWindow * parent)
|
|
{
|
|
UString resultPath;
|
|
return WaitInd(destWindow,ind,id,parent,resultPath);
|
|
}
|
|
|
|
void verify_main_thread(void);
|
|
|
|
class LockGUI
|
|
{
|
|
bool _IsMain;
|
|
public:
|
|
LockGUI() {
|
|
|
|
verify_main_thread();
|
|
|
|
_IsMain = wxThread::IsMain();
|
|
if (!_IsMain) {
|
|
// DEBUG
|
|
printf("GuiEnter-Dialog(0x%lx)\n",wxThread::GetCurrentId());
|
|
abort(); // FIXME wxMutexGuiEnter();
|
|
}
|
|
}
|
|
~LockGUI() {
|
|
if (!_IsMain) {
|
|
wxMutexGuiLeave();
|
|
// DEBUG printf("GuiLeave(0x%lx)\n",wxThread::GetCurrentId());
|
|
}
|
|
}
|
|
};
|
|
|
|
static const unsigned int kNumDialogsMax = 32;
|
|
static unsigned int g_NumDialogs = 0;
|
|
static const CDialogInfo *g_Dialogs[kNumDialogsMax];
|
|
|
|
void RegisterDialog(const CDialogInfo *dialogInfo)
|
|
{
|
|
// DEBUG printf("RegisterDialog : %d\n",dialogInfo->id);
|
|
if (g_NumDialogs < kNumDialogsMax)
|
|
g_Dialogs[g_NumDialogs++] = dialogInfo;
|
|
}
|
|
|
|
namespace NWindows {
|
|
|
|
UString MyLoadString(UINT resourceID)
|
|
{
|
|
for(unsigned i=0; i < g_NumDialogs; i++) {
|
|
if (g_Dialogs[i]->stringTable) {
|
|
int j = 0;
|
|
while(g_Dialogs[i]->stringTable[j].str) {
|
|
if (resourceID == g_Dialogs[i]->stringTable[j].id) {
|
|
return g_Dialogs[i]->stringTable[j].str;
|
|
}
|
|
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
printf("MyLoadString(resourceID=%u) : NOT FOUND\n",(unsigned)resourceID);
|
|
return L"FIXME-MyLoadStringW-";
|
|
}
|
|
|
|
void MyLoadString(UINT resourceID, UString &dest)
|
|
{
|
|
dest = MyLoadString(resourceID);
|
|
}
|
|
|
|
namespace NControl {
|
|
|
|
/////////////////////////////////////////// CModalDialog //////////////////////////////////
|
|
|
|
bool CModalDialog::CheckButton(int buttonID, UINT checkState)
|
|
{
|
|
LockGUI lock;
|
|
wxCheckBox* w = (wxCheckBox*)_window->FindWindow(buttonID);
|
|
if (w)
|
|
{
|
|
w->SetValue(checkState == BST_CHECKED);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
UINT CModalDialog::IsButtonChecked(int buttonID) const
|
|
{
|
|
LockGUI lock;
|
|
wxCheckBox* w = (wxCheckBox*)_window->FindWindow(buttonID);
|
|
if (w)
|
|
{
|
|
bool bret = w->GetValue();
|
|
if (bret) return BST_CHECKED;
|
|
}
|
|
return BST_UNCHECKED;
|
|
}
|
|
|
|
void CModalDialog::EnableItem(int id, bool state)
|
|
{
|
|
LockGUI lock;
|
|
wxWindow* w = _window->FindWindow(id);
|
|
if (w) w->Enable(state);
|
|
}
|
|
|
|
void CModalDialog::SetItemText(int id, const TCHAR *txt)
|
|
{
|
|
LockGUI lock;
|
|
wxWindow* w = _window->FindWindow(id);
|
|
if (w)
|
|
{
|
|
wxString label(txt);
|
|
w->SetLabel(label);
|
|
}
|
|
}
|
|
|
|
wxWindow * CModalDialog::GetItem(long id) const
|
|
{
|
|
LockGUI lock;
|
|
wxWindow * w = _window->FindWindow(id);
|
|
if (w == 0) printf("@@WARNING :GetItem(%ld)=NULL\n",id);
|
|
return w;
|
|
}
|
|
|
|
void CModalDialog::ShowItem(int itemID, int cmdShow) const
|
|
{
|
|
LockGUI lock;
|
|
// cmdShow = SW_HIDE or SW_SHOW (sometimes false or true !)
|
|
wxWindow* w = _window->FindWindow(itemID);
|
|
if (w)
|
|
{
|
|
// FIXME w->Show(cmdShow != SW_HIDE);
|
|
w->Enable(cmdShow != SW_HIDE);
|
|
}
|
|
}
|
|
|
|
UINT_PTR CModalDialog::SetTimer(UINT_PTR idEvent , unsigned milliseconds)
|
|
{
|
|
LockGUI lock;
|
|
return _window->SetTimer(idEvent , milliseconds);
|
|
}
|
|
|
|
void CModalDialog::KillTimer(UINT_PTR idEvent)
|
|
{
|
|
LockGUI lock;
|
|
_window->KillTimer(idEvent);
|
|
}
|
|
|
|
void CModalDialog::SetText(const TCHAR *_title) {
|
|
LockGUI lock;
|
|
_window->SetTitle(_title);
|
|
}
|
|
|
|
|
|
bool CModalDialog::GetText(CSysString &s) {
|
|
wxString str;
|
|
{
|
|
LockGUI lock;
|
|
str = _window->GetTitle();
|
|
}
|
|
s = str;
|
|
return true;
|
|
}
|
|
|
|
INT_PTR CModalDialog::Create(int id , HWND parentWindow)
|
|
{
|
|
int ind = findFreeInd();
|
|
|
|
g_tabCreate[ind].dialog = this;
|
|
|
|
return WaitInd(0, ind,id,parentWindow);
|
|
}
|
|
|
|
void CModalDialog::End(int result)
|
|
{
|
|
int ind = findFreeInd();
|
|
|
|
g_tabCreate[ind].window = _window;
|
|
g_tabCreate[ind].value = result;
|
|
|
|
WaitInd(this->_window,ind,DIALOG_ID_END_DIALOG,0);
|
|
}
|
|
|
|
void CModalDialog::PostMsg(UINT message)
|
|
{
|
|
int ind = findFreeInd();
|
|
|
|
g_tabCreate[ind].dialog = this;
|
|
g_tabCreate[ind].value = message;
|
|
|
|
WaitInd(this->_window,ind,DIALOG_ID_POST_DIALOG,0);
|
|
}
|
|
|
|
/////////////////////////////////////////// CModalDialogImpl ///////////////////////////////////////
|
|
|
|
CModalDialogImpl::CModalDialogImpl(CDialog *dialog, wxWindow* parent, wxWindowID id,
|
|
const wxString& title, const wxPoint& pos,
|
|
const wxSize& size, long style) :
|
|
wxDialog(parent, id, title , pos , size, style /* | wxDIALOG_NO_PARENT */ ) ,
|
|
_timer(this, TIMER_ID_IMPL), _dialog(dialog)
|
|
{
|
|
// set the frame icon
|
|
this->SetIcon(wxICON(p7zip_32));
|
|
}
|
|
|
|
void CModalDialogImpl::OnAnyButton(wxCommandEvent& event)
|
|
{
|
|
int id = event.GetId();
|
|
if (id == wxID_OK)
|
|
{
|
|
if (_dialog) _dialog->OnOK();
|
|
// event.Skip(true);
|
|
}
|
|
else if (id == wxID_CANCEL)
|
|
{
|
|
if (_dialog) _dialog->OnCancel();
|
|
// event.Skip(true);
|
|
}
|
|
else if (id == wxID_HELP)
|
|
{
|
|
if (_dialog) _dialog->OnHelp();
|
|
}
|
|
else
|
|
{
|
|
if (_dialog)
|
|
{
|
|
/* bool bret = */ _dialog->OnButtonClicked(id, FindWindow(id) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CModalDialogImpl::OnAnyChoice(wxCommandEvent &event)
|
|
{
|
|
int itemID = event.GetId();
|
|
if (_dialog) _dialog->OnCommand(CBN_SELCHANGE, itemID, 0);
|
|
}
|
|
|
|
void CModalDialogImpl::OnAnyTimer(wxTimerEvent &event)
|
|
{
|
|
int timerID = event.GetId();
|
|
if (_dialog) _dialog->OnTimer(timerID , 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////// myCreateHandle
|
|
|
|
|
|
static int myCreateHandle2(int n)
|
|
{
|
|
unsigned int id = g_tabCreate[n].id;
|
|
wxWindow * parentWindow = g_tabCreate[n].parentWindow;
|
|
NWindows::NControl::CModalDialogImpl * window = 0;
|
|
|
|
// DEBUG printf("T=0x%lx - %d : myCreateHandle(%d): BEGIN\n", wxThread::GetCurrentId(),time(0)-g_T0,n);
|
|
|
|
if (id == DIALOG_ID_END_DIALOG)
|
|
{
|
|
/* FIXME : the dialog must be shown before ending it ?
|
|
while (!g_tabCreate[n].window->IsShownOnScreen()) Sleep(200);
|
|
Sleep(200);
|
|
*/
|
|
g_tabCreate[n].window->EndModal(g_tabCreate[n].value);
|
|
return 0;
|
|
}
|
|
|
|
if (id == DIALOG_ID_POST_DIALOG)
|
|
{
|
|
g_tabCreate[n].dialog->OnMessage(g_tabCreate[n].value, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
if (id == DIALOG_ID_MESSAGEBOX)
|
|
{
|
|
long style = g_tabCreate[n].flag;
|
|
long decorated_style = style;
|
|
if ( ( style & ( wxICON_EXCLAMATION | wxICON_HAND | wxICON_INFORMATION |
|
|
wxICON_QUESTION ) ) == 0 )
|
|
{
|
|
decorated_style |= ( style & wxYES ) ? wxICON_QUESTION : wxICON_INFORMATION ;
|
|
}
|
|
wxMessageDialog dialog(parentWindow, g_tabCreate[n].msg, g_tabCreate[n].title, decorated_style);
|
|
// FIXME dialog.SetIcon(wxICON(p7zip_32));
|
|
int ret = dialog.ShowModal();
|
|
|
|
return ret;
|
|
}
|
|
|
|
if (id == DIALOG_ID_DIR_DIALOG)
|
|
{
|
|
wxString defaultDir = g_tabCreate[n].initialFolderOrFile;
|
|
wxDirDialog dirDialog(g_tabCreate[n].parentWindow,
|
|
g_tabCreate[n].title, defaultDir);
|
|
dirDialog.SetIcon(wxICON(p7zip_32));
|
|
int ret = dirDialog.ShowModal();
|
|
if (ret == wxID_OK) g_tabCreate[n].resultPath = dirDialog.GetPath();
|
|
return ret;
|
|
}
|
|
|
|
if (id == DIALOG_ID_FILE_DIALOG)
|
|
{
|
|
wxString defaultFilename = g_tabCreate[n].initialFolderOrFile;
|
|
|
|
wxFileName filename(defaultFilename);
|
|
|
|
wxString dir = filename.GetPath();
|
|
wxString name = filename.GetFullName();
|
|
|
|
|
|
// printf("DIALOG_ID_FILE_DIALOG = '%ls' => '%ls' '%ls'\n",&defaultFilename[0],&dir[0],&name[0]);
|
|
|
|
|
|
wxFileDialog fileDialog(g_tabCreate[n].parentWindow, g_tabCreate[n].title,
|
|
dir, name, wxT("All Files (*.*)|*.*"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
|
|
fileDialog.SetIcon(wxICON(p7zip_32));
|
|
int ret = fileDialog.ShowModal();
|
|
if (ret == wxID_OK) g_tabCreate[n].resultPath = fileDialog.GetPath();
|
|
return ret;
|
|
}
|
|
|
|
for(unsigned i=0; i < g_NumDialogs; i++) {
|
|
if (id == g_Dialogs[i]->id) {
|
|
// DEBUG printf("%d : Create(%d,%p): CreateDialog-1\n",time(0)-g_T0,id,parentWindow);
|
|
window = (g_Dialogs[i]->createDialog)(g_tabCreate[n].dialog,g_tabCreate[n].parentWindow);
|
|
// DEBUG printf("%d : Create(%d,%p): CreateDialog-2\n",time(0)-g_T0,id,parentWindow);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (window) {
|
|
|
|
// DEBUG printf("%d : Create(%d,%p): %p->ShowModal()\n",time(0)-g_T0,id,parentWindow,window);
|
|
|
|
// window->Show(true);
|
|
// wxGetApp().ProcessPendingEvents();
|
|
|
|
INT_PTR ret = window->ShowModal();
|
|
|
|
// DEBUG printf("%d : Create(%d,%p): %p->ShowModal() - ret=%d\n",time(0)-g_T0,id,parentWindow,window,ret);
|
|
window->Detach();
|
|
window->Destroy();
|
|
|
|
// DEBUG printf("%d : Create(%d,%p): END\n",time(0)-g_T0,id,parentWindow,window);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// FIXME
|
|
printf("INTERNAL ERROR : cannot find dialog %d\n",id);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void myCreateHandle(int n)
|
|
{
|
|
int ret = myCreateHandle2(n);
|
|
g_tabCreate[n].ret = ret;
|
|
g_tabCreate[n].sem->Post();
|
|
}
|
|
|
|
int MessageBoxW(wxWindow * parent, const TCHAR * msg, const TCHAR * title,int flag)
|
|
{
|
|
int ind = findFreeInd();
|
|
|
|
g_tabCreate[ind].msg = msg;
|
|
g_tabCreate[ind].title = title;
|
|
g_tabCreate[ind].flag = flag;
|
|
|
|
return WaitInd(parent,ind,DIALOG_ID_MESSAGEBOX,parent); // FIXME
|
|
}
|
|
|
|
|
|
|
|
// FIXME : should be in Windows/Shell.cpp
|
|
|
|
namespace NWindows{
|
|
namespace NShell{
|
|
|
|
bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath)
|
|
{
|
|
int ind = findFreeInd();
|
|
|
|
g_tabCreate[ind].title = title;
|
|
g_tabCreate[ind].initialFolderOrFile = nameWindowToUnix(initialFolder);
|
|
|
|
UString resTmp;
|
|
int ret = WaitInd(0,ind,DIALOG_ID_DIR_DIALOG,owner,resTmp); // FIXME
|
|
if(ret == wxID_OK)
|
|
{
|
|
resultPath = resTmp;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}}
|
|
|
|
/////////////////////////// CPP/Windows/CommonDialog.cpp
|
|
namespace NWindows
|
|
{
|
|
|
|
// OLD bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR /* FIXME initialDir */ , LPCWSTR fullFileName, LPCWSTR s, UString &resPath)
|
|
bool MyGetOpenFileName(HWND hwnd, LPCWSTR title,
|
|
LPCWSTR /* FIXME initialDir */ , // can be NULL, so dir prefix in filePath will be used
|
|
LPCWSTR filePath, // full path
|
|
LPCWSTR /* FIXME filterDescription */ , // like "All files (*.*)"
|
|
LPCWSTR filter, // like "*.exe"
|
|
UString &resPath
|
|
#ifdef UNDER_CE
|
|
, bool openFolder = false
|
|
#endif
|
|
)
|
|
{
|
|
int ind = findFreeInd();
|
|
|
|
g_tabCreate[ind].title = title;
|
|
g_tabCreate[ind].initialFolderOrFile = nameWindowToUnix(filePath);
|
|
|
|
UString resTmp;
|
|
int ret = WaitInd(0,ind,DIALOG_ID_FILE_DIALOG,hwnd,resTmp); // FIXME
|
|
if(ret == wxID_OK)
|
|
{
|
|
resPath = resTmp;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// From CPP/7zip/UI/FileManager/BrowseDialog.cpp
|
|
bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result)
|
|
{
|
|
result = path;
|
|
return true;
|
|
}
|
|
|