#include "FileZilla.h"
#include "chmoddialog.h"
BEGIN_EVENT_TABLE(CChmodDialog, wxDialogEx)
EVT_BUTTON(XRCID("wxID_OK"), CChmodDialog::OnOK)
EVT_BUTTON(XRCID("wxID_CANCEL"), CChmodDialog::OnCancel)
EVT_TEXT(XRCID("ID_NUMERIC"), CChmodDialog::OnNumericChanged)
EVT_CHECKBOX(XRCID("ID_RECURSE"), CChmodDialog::OnRecurseChanged)
END_EVENT_TABLE();
bool CChmodDialog::Create(wxWindow* parent, int fileCount, int dirCount,
const wxString& name, const char permissions[9])
{
m_noUserTextChange = false;
lastChangedNumeric = false;
memcpy(m_permissions, permissions, 9);
SetExtraStyle(wxWS_EX_BLOCK_EVENTS);
SetParent(parent);
wxString title;
if (!dirCount)
{
if (fileCount == 1)
{
title = wxString::Format(_("Please select the new attributes for the file \"%s\"."), name.c_str());
}
else
title = _("Please select the new attributes for the selected files.");
}
else
{
if (!fileCount)
{
if (dirCount == 1)
{
title = wxString::Format(_("Please select the new attributes for the directory \"%s\"."), name.c_str());
}
else
title = _("Please select the new attributes for the selected directories.");
}
else
title = _("Please select the new attributes for the selected files and directories.");
}
if (!wxXmlResource::Get()->LoadDialog(this, parent, _T("ID_CHMODDIALOG")))
return false;
if (!WrapText(this, XRCID("ID_DESC"), 300))
{
wxFAIL_MSG(_T("Wrapping of ID_DESC failed"));
}
if (!XRCCTRL(*this, "wxID_OK", wxButton))
return false;
if (!XRCCTRL(*this, "wxID_CANCEL", wxButton))
return false;
if (!XRCCTRL(*this, "ID_NUMERIC", wxTextCtrl))
return false;
if (!WrapText(this, XRCID("ID_NUMERICTEXT"), 300))
{
wxFAIL_MSG(_T("Wrapping of ID_NUMERICTEXT failed"));
}
wxCheckBox* pRecurse = XRCCTRL(*this, "ID_RECURSE", wxCheckBox);
wxRadioButton* pApplyAll = XRCCTRL(*this, "ID_APPLYALL", wxRadioButton);
wxRadioButton* pApplyFiles = XRCCTRL(*this, "ID_APPLYFILES", wxRadioButton);
wxRadioButton* pApplyDirs = XRCCTRL(*this, "ID_APPLYDIRS", wxRadioButton);
if (!pRecurse || !pApplyAll || !pApplyFiles || !pApplyDirs)
return false;
if (!dirCount)
{
pRecurse->Hide();
pApplyAll->Hide();
pApplyFiles->Hide();
pApplyDirs->Hide();
}
pApplyAll->Enable(false);
pApplyFiles->Enable(false);
pApplyDirs->Enable(false);
const wxChar* IDs[9] = { _T("ID_OWNERREAD"), _T("ID_OWNERWRITE"), _T("ID_OWNEREXECUTE"),
_T("ID_GROUPREAD"), _T("ID_GROUPWRITE"), _T("ID_GROUPEXECUTE"),
_T("ID_PUBLICREAD"), _T("ID_PUBLICWRITE"), _T("ID_PUBLICEXECUTE")
};
for (int i = 0; i < 9; i++)
{
int id = wxXmlResource::GetXRCID(IDs[i]);
m_checkBoxes[i] = wxDynamicCast(FindWindow(id), wxCheckBox);
if (!m_checkBoxes[i])
return false;
Connect(id, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CChmodDialog::OnCheckboxClick));
switch (permissions[i])
{
default:
case 0:
m_checkBoxes[i]->Set3StateValue(wxCHK_UNDETERMINED);
break;
case 1:
m_checkBoxes[i]->Set3StateValue(wxCHK_UNCHECKED);
break;
case 2:
m_checkBoxes[i]->Set3StateValue(wxCHK_CHECKED);
break;
}
}
GetSizer()->Fit(this);
GetSizer()->SetSizeHints(this);
wxCommandEvent evt;
OnCheckboxClick(evt);
return true;
}
void CChmodDialog::OnOK(wxCommandEvent& event)
{
wxCheckBox* pRecurse = XRCCTRL(*this, "ID_RECURSE", wxCheckBox);
m_recursive = pRecurse->GetValue();
wxRadioButton* pApplyFiles = XRCCTRL(*this, "ID_APPLYFILES", wxRadioButton);
wxRadioButton* pApplyDirs = XRCCTRL(*this, "ID_APPLYDIRS", wxRadioButton);
if (pApplyFiles->GetValue())
m_applyType = 1;
else if (pApplyDirs->GetValue())
m_applyType = 2;
else
m_applyType = 0;
EndModal(wxID_OK);
}
void CChmodDialog::OnCancel(wxCommandEvent& event)
{
EndModal(wxID_CANCEL);
}
void CChmodDialog::OnCheckboxClick(wxCommandEvent& event)
{
lastChangedNumeric = false;
for (int i = 0; i < 9; i++)
{
wxCheckBoxState state = m_checkBoxes[i]->Get3StateValue();
switch (state)
{
default:
case wxCHK_UNDETERMINED:
m_permissions[i] = 0;
break;
case wxCHK_UNCHECKED:
m_permissions[i] = 1;
break;
case wxCHK_CHECKED:
m_permissions[i] = 2;
break;
}
}
wxString numericValue;
for (int i = 0; i < 3; i++)
{
if (!m_permissions[i * 3] || !m_permissions[i * 3 + 1] || !m_permissions[i * 3 + 2])
{
numericValue += 'x';
continue;
}
numericValue += wxString::Format(_T("%d"), (m_permissions[i * 3] - 1) * 4 + (m_permissions[i * 3 + 1] - 1) * 2 + (m_permissions[i * 3 + 2] - 1) * 1);
}
wxTextCtrl *pTextCtrl = XRCCTRL(*this, "ID_NUMERIC", wxTextCtrl);
wxString oldValue = pTextCtrl->GetValue();
m_noUserTextChange = true;
pTextCtrl->SetValue(oldValue.Left(oldValue.Length() - 3) + numericValue);
m_noUserTextChange = false;
oldNumeric = numericValue;
}
void CChmodDialog::OnNumericChanged(wxCommandEvent& event)
{
if (m_noUserTextChange)
return;
lastChangedNumeric = true;
wxTextCtrl *pTextCtrl = XRCCTRL(*this, "ID_NUMERIC", wxTextCtrl);
wxString numeric = pTextCtrl->GetValue();
if (numeric.Length() < 3)
return;
numeric = numeric.Right(3);
for (int i = 0; i < 3; i++)
{
if ((numeric[i] < '0' || numeric[i] > '9') && numeric[i] != 'x')
return;
}
for (int i = 0; i < 3; i++)
{
if (oldNumeric != _T("") && numeric[i] == oldNumeric[i])
continue;
if (numeric[i] == 'x')
{
m_permissions[i * 3] = 0;
m_permissions[i * 3 + 1] = 0;
m_permissions[i * 3 + 2] = 0;
}
else
{
int value = numeric[i] - '0';
m_permissions[i * 3] = (value & 4) ? 2 : 1;
m_permissions[i * 3 + 1] = (value & 2) ? 2 : 1;
m_permissions[i * 3 + 2] = (value & 1) ? 2 : 1;
}
}
oldNumeric = numeric;
for (int i = 0; i < 9; i++)
{
switch (m_permissions[i])
{
default:
case 0:
m_checkBoxes[i]->Set3StateValue(wxCHK_UNDETERMINED);
break;
case 1:
m_checkBoxes[i]->Set3StateValue(wxCHK_UNCHECKED);
break;
case 2:
m_checkBoxes[i]->Set3StateValue(wxCHK_CHECKED);
break;
}
}
}
wxString CChmodDialog::GetPermissions(const char* previousPermissions)
{
// Construct a new permission string
wxTextCtrl *pTextCtrl = XRCCTRL(*this, "ID_NUMERIC", wxTextCtrl);
wxString numeric = pTextCtrl->GetValue();
if (numeric.Length() < 3)
return numeric;
for (unsigned int i = numeric.Length() - 3; i < numeric.Length(); i++)
{
if ((numeric[i] < '0' || numeric[i] > '9') && numeric[i] != 'x')
return numeric;
}
if (!previousPermissions)
{
// Use default of (0...0)755
if (numeric[numeric.Length() - 1] == 'x')
numeric[numeric.Length() - 1] = 5;
if (numeric[numeric.Length() - 2] == 'x')
numeric[numeric.Length() - 2] = 5;
if (numeric[numeric.Length() - 3] == 'x')
numeric[numeric.Length() - 3] = 7;
numeric.Replace(_T("x"), _T("0"));
return numeric;
}
const char defaultPerms[9] = { 2, 2, 2, 1, 0, 1, 1, 0, 1 };
char perms[9];
memcpy(perms, m_permissions, 9);
wxString permission = numeric.Left(numeric.Length() - 3);
unsigned int k = 0;
for (unsigned int i = numeric.Length() - 3; i < numeric.Length(); i++, k++)
{
for (unsigned int j = k * 3; j < k * 3 + 3; j++)
{
if (!perms[j])
{
if (previousPermissions[j])
perms[j] = previousPermissions[j];
else
perms[j] = defaultPerms[j];
}
}
permission += wxString::Format(_T("%d"), (int)(perms[k * 3] - 1) * 4 + (perms[k * 3 + 1] - 1) * 2 + (perms[k * 3 + 2] - 1) * 1);
}
return permission;
}
bool CChmodDialog::Recursive() const
{
return m_recursive;
}
void CChmodDialog::OnRecurseChanged(wxCommandEvent& event)
{
wxCheckBox* pRecurse = XRCCTRL(*this, "ID_RECURSE", wxCheckBox);
wxRadioButton* pApplyAll = XRCCTRL(*this, "ID_APPLYALL", wxRadioButton);
wxRadioButton* pApplyFiles = XRCCTRL(*this, "ID_APPLYFILES", wxRadioButton);
wxRadioButton* pApplyDirs = XRCCTRL(*this, "ID_APPLYDIRS", wxRadioButton);
pApplyAll->Enable(pRecurse->GetValue());
pApplyFiles->Enable(pRecurse->GetValue());
pApplyDirs->Enable(pRecurse->GetValue());
}
bool CChmodDialog::ConvertPermissions(const wxString rwx, char* permissions)
{
if (!permissions)
return false;
const unsigned char permchars[3] = {'r', 'w', 'x'};
if (rwx.Length() != 10)
return false;
for (int i = 0; i < 9; i++)
{
bool set = rwx[i + 1] == permchars[i % 3];
permissions[i] = set ? 2 : 1;
}
return true;
}
syntax highlighted by Code2HTML, v. 0.9.1