23#include <wx/clipbrd.h>
26#include <wx/settings.h>
27#include <wx/toplevel.h>
33#if wxUSE_ACCESSIBILITY
47 void SetCurrentCell(
int row,
int col);
49 bool GetRowCol(
int childId,
int & row,
int & col);
53 wxAccStatus GetChild(
int childId, wxAccessible **child)
override;
56 wxAccStatus GetChildCount(
int *childCount)
override;
64 wxAccStatus GetDefaultAction(
int childId, wxString *actionName)
override;
67 wxAccStatus GetDescription(
int childId, wxString *description)
override;
73 wxAccStatus GetFocus(
int *childId, wxAccessible **child)
override;
76 wxAccStatus GetHelpText(
int childId, wxString *helpText)
override;
80 wxAccStatus GetKeyboardShortcut(
int childId, wxString *shortcut)
override;
84 wxAccStatus GetLocation(wxRect & rect,
int elementId)
override;
87 wxAccStatus GetName(
int childId, wxString *
name)
override;
90 wxAccStatus GetParent(wxAccessible **parent)
override;
93 wxAccStatus GetRole(
int childId, wxAccRole *role)
override;
103 wxAccStatus GetSelections(wxVariant *selections)
override;
106 wxAccStatus GetState(
int childId,
long* state)
override;
110 wxAccStatus GetValue(
int childId, wxString* strValue)
override;
112#if defined(__WXMAC__)
114 wxAccStatus Select(
int childId, wxAccSelectionFlags selectFlags)
override;
127 : mContext { context }
129 mType = std::move(type);
153 wxGridCellEditor::Create(parent,
id,
handler);
158 wxSize
size = m_control->GetSize();
161 int x = rect.x + ((rect.width / 2) - (
size.x / 2)) + 1;
162 int y = rect.y + ((rect.height / 2) - (
size.y / 2)) + 1;
164 m_control->Move(x, y);
169 wxGridTableBase *table = grid->GetTable();
175 control->SetValue(
mOld);
176 control->EnableMenu();
182bool NumericEditor::EndEdit(
int WXUNUSED(row),
int WXUNUSED(col),
const wxGrid *WXUNUSED(grid),
const wxString &WXUNUSED(oldval), wxString *newval)
185 bool changed = newtime !=
mOld;
207 if (wxGridCellEditor::IsAcceptedKey(event)) {
208 if (event.GetKeyCode() == WXK_RETURN) {
242 wxGridCellAttr &attr,
249 wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
251 wxGridTableBase *table = grid.GetTable();
259 table->
GetValue(row, col).ToDouble(&value);
266 wxPoint(10000, 10000));
272 dc.SetBackgroundMode(wxTRANSPARENT);
274 if (grid.IsEnabled())
278 dc.SetTextBackground(grid.GetSelectionBackground());
279 dc.SetTextForeground(grid.GetSelectionForeground());
283 dc.SetTextBackground(attr.GetBackgroundColour());
284 dc.SetTextForeground(attr.GetTextColour());
289 dc.SetTextBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
290 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT));
293 dc.SetFont(attr.GetFont());
297 attr.GetAlignment(&hAlign, &vAlign);
299 grid.DrawTextRectangle(dc, tstr, rect, hAlign, vAlign);
303 wxGridCellAttr & WXUNUSED(attr),
308 wxGridTableBase *table = grid.GetTable();
315 table->
GetValue(row, col).ToDouble(&value);
321 wxPoint(10000, 10000));
340 for (
size_t n = 0; n < count; n++) {
365 m_control =
safenew wxChoice(parent,
371 wxGridCellEditor::Create(parent,
id, evtHandler);
377 wxSize
size = m_control->GetSize();
380 int x = rect.x + ((rect.width / 2) - (
size.x / 2)) + 1;
381 int y = rect.y + ((rect.height / 2) - (
size.y / 2)) + 1;
383 m_control->Move(x, y);
391 mOld = grid->GetTable()->GetValue(row, col);
402 bool changed =
EndEdit(row, col, grid,
mOld, &newvalue);
410 const wxGrid* WXUNUSED(grid),
411 const wxString &WXUNUSED(oldval), wxString *newval)
413 int sel =
Choice()->GetSelection();
416 if ((sel < 0) || (sel >= (
int)(
mChoices.size())))
422 bool changed = val !=
mOld;
457BEGIN_EVENT_TABLE(
Grid, wxGrid)
471 const wxString&
name)
472: wxGrid(parent,
id, pos,
size, style | wxWANTS_CHARS,
name), mContext(context)
474#if wxUSE_ACCESSIBILITY
475 GetGridWindow()->SetAccessible(mAx =
safenew GridAx(mContext,
this));
493 safenew wxGridCellStringRenderer,
498 SetSelectionForeground(GetDefaultCellTextColour());
499 SetSelectionBackground(GetDefaultCellBackgroundColour());
504#if wxUSE_ACCESSIBILITY
505 int cnt = mChildren.size();
509 mChildren.pop_back();
518#if wxUSE_ACCESSIBILITY
519 mAx->SetCurrentCell(GetGridCursorRow(), GetGridCursorCol());
527 MakeCellVisible(event.GetRow(), event.GetCol());
529#if wxUSE_ACCESSIBILITY
530 mAx->SetCurrentCell(event.GetRow(), event.GetCol());
540 SelectRow(GetGridCursorRow());
545 auto keyCode =
event.GetKeyCode();
546 int crow = GetGridCursorRow();
547 int ccol = GetGridCursorCol();
549 if (event.CmdDown() && crow != wxGridNoCellCoords.GetRow() && ccol != wxGridNoCellCoords.GetCol())
551 wxClipboardLocker cb;
557 wxTextDataObject *data =
safenew wxTextDataObject(GetCellValue(crow, ccol));
565 wxTextDataObject *data =
safenew wxTextDataObject(GetCellValue(crow, ccol));
567 SetCellValue(crow, ccol,
"" );
576 wxTextDataObject data;
579 SetCellValue(crow, ccol, data.GetText());
593 int rows = GetNumberRows();
594 int cols = GetNumberCols();
596 const bool has_cells = rows > 0 && cols > 0;
599 int crow = GetGridCursorRow();
600 int ccol = GetGridCursorCol();
602 const bool has_no_selection = crow == wxGridNoCellCoords.GetRow() || ccol == wxGridNoCellCoords.GetCol();
604 if (has_no_selection) {
607 else if (event.GetKeyCode() == WXK_LEFT) {
608 if (crow == 0 && ccol == 0) {
611 else if (ccol == 0) {
612 SetGridCursor(crow - 1, cols - 1);
615 SetGridCursor(crow, ccol - 1);
619 if (crow == rows - 1 && ccol == cols - 1) {
622 else if (ccol == cols - 1) {
623 SetGridCursor(crow + 1, 0);
626 SetGridCursor(crow, ccol + 1);
631#if wxUSE_ACCESSIBILITY
633 mAx->SetCurrentCell(GetGridCursorRow(), GetGridCursorCol());
640 if (event.ControlDown()) {
641 int flags = wxNavigationKeyEvent::FromTab |
642 (
event.ShiftDown() ?
643 wxNavigationKeyEvent::IsBackward :
644 wxNavigationKeyEvent::IsForward );
649 int rows = GetNumberRows();
650 int cols = GetNumberCols();
651 int crow = GetGridCursorRow();
652 int ccol = GetGridCursorCol();
654 const auto is_empty = rows <= 0 || cols <= 0;
655 const auto has_no_selection = crow == wxGridNoCellCoords.GetRow() || ccol == wxGridNoCellCoords.GetCol();
657 if (event.ShiftDown()) {
659 Navigate(wxNavigationKeyEvent::FromTab | wxNavigationKeyEvent::IsBackward);
663 if (crow == 0 && ccol == 0) {
664 Navigate(wxNavigationKeyEvent::FromTab | wxNavigationKeyEvent::IsBackward);
668 if (has_no_selection) {
669 SetGridCursor(rows -1, cols - 1);
671 else if (ccol == 0) {
672 SetGridCursor(crow - 1, cols - 1);
675 SetGridCursor(crow, ccol - 1);
680 Navigate(wxNavigationKeyEvent::FromTab | wxNavigationKeyEvent::IsForward);
684 if (crow == rows - 1 && ccol == cols - 1) {
685 Navigate(wxNavigationKeyEvent::FromTab | wxNavigationKeyEvent::IsForward);
689 if (has_no_selection) {
692 else if (ccol == cols - 1) {
693 SetGridCursor(crow + 1, 0);
696 SetGridCursor(crow, ccol + 1);
700 MakeCellVisible(GetGridCursorRow(), GetGridCursorCol());
702#if wxUSE_ACCESSIBILITY
704 mAx->SetCurrentCell(GetGridCursorRow(), GetGridCursorCol());
710 case WXK_NUMPAD_ENTER:
712 if (!IsCellEditControlShown()) {
713 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(
this), wxTopLevelWindow);
714 wxWindow *def = tlw->GetDefaultItem();
715 if (def && def->IsEnabled()) {
718 cevent.SetEventObject( def );
719 GetParent()->GetEventHandler()->ProcessEvent(cevent);
723 wxGrid::OnKeyDown(event);
728 SetGridCursor(GetGridCursorRow(), GetGridCursorCol());
734 wxGrid::OnKeyDown(event);
739#if wxUSE_ACCESSIBILITY
740void Grid::ClearGrid()
749bool Grid::InsertRows(
int pos,
int numRows,
bool updateLabels)
751 bool res = wxGrid::InsertRows(pos, numRows, updateLabels);
758bool Grid::AppendRows(
int numRows,
bool updateLabels)
760 bool res = wxGrid::AppendRows(numRows, updateLabels);
767bool Grid::DeleteRows(
int pos,
int numRows,
bool updateLabels)
769 bool res = wxGrid::DeleteRows(pos, numRows, updateLabels);
776bool Grid::InsertCols(
int pos,
int numCols,
bool updateLabels)
778 bool res = wxGrid::InsertCols(pos, numCols, updateLabels);
785bool Grid::AppendCols(
int numCols,
bool updateLabels)
787 bool res = wxGrid::AppendCols(numCols, updateLabels);
794bool Grid::DeleteCols(
int pos,
int numCols,
bool updateLabels)
796 bool res = wxGrid::DeleteCols(pos, numCols, updateLabels);
811void GridAx::TableUpdated()
813 NotifyEvent(wxACC_EVENT_OBJECT_REORDER,
814 mGrid->GetGridWindow(),
819void GridAx::SetCurrentCell(
int row,
int col)
821 int id = (((row * mGrid->GetNumberCols()) + col) + 1);
824 NotifyEvent(wxACC_EVENT_OBJECT_SELECTIONREMOVE,
825 mGrid->GetGridWindow(),
831 NotifyEvent(wxACC_EVENT_OBJECT_FOCUS,
832 mGrid->GetGridWindow(),
837 NotifyEvent(wxACC_EVENT_OBJECT_SELECTION,
838 mGrid->GetGridWindow(),
845bool GridAx::GetRowCol(
int childId,
int & row,
int & col)
847 if (childId == wxACC_SELF) {
851 int cols = mGrid->GetNumberCols();
852 int id = childId - 1;
862wxAccStatus GridAx::GetChild(
int childId, wxAccessible** child)
864 if (childId == wxACC_SELF) {
875wxAccStatus GridAx::GetChildCount(
int *childCount)
877 *childCount = mGrid->GetNumberRows() * mGrid->GetNumberCols();
888wxAccStatus GridAx::GetDefaultAction(
int WXUNUSED(childId), wxString *actionName)
896wxAccStatus GridAx::GetDescription(
int WXUNUSED(childId), wxString *description)
898 description->clear();
904wxAccStatus GridAx::GetHelpText(
int WXUNUSED(childId), wxString *helpText)
913wxAccStatus GridAx::GetKeyboardShortcut(
int WXUNUSED(childId), wxString *shortcut)
922wxAccStatus GridAx::GetLocation(wxRect & rect,
int elementId)
928 if (GetRowCol(elementId, row, col)) {
929 rect = mGrid->CellToRect(row, col);
930 rect.SetPosition(mGrid->CalcScrolledPosition(rect.GetPosition()));
931 rect.SetPosition(mGrid->GetGridWindow()->ClientToScreen(rect.GetPosition()));
934 rect = mGrid->GetRect();
935 rect.SetPosition(mGrid->GetParent()->ClientToScreen(rect.GetPosition()));
942wxAccStatus GridAx::GetName(
int childId, wxString *
name)
947 if (GetRowCol(childId, row, col)) {
948 wxString n = mGrid->GetColLabelValue(col);
949 wxString v = mGrid->GetCellValue(row, col);
960 static_cast<NumericEditor *
>(mGrid->GetCellEditor(row, col));
962 if (c && dt && df && ( c == dt || c == df)) {
969 v = converter.GetString();
985wxAccStatus GridAx::GetParent(wxAccessible ** WXUNUSED(parent))
987 return wxACC_NOT_IMPLEMENTED;
991wxAccStatus GridAx::GetRole(
int childId, wxAccRole *role)
993 if (childId == wxACC_SELF) {
994#if defined(__WXMSW__)
995 *role = wxROLE_SYSTEM_TABLE;
998#if defined(__WXMAC__)
999 *role = wxROLE_SYSTEM_GROUPING;
1003 *role = wxROLE_SYSTEM_TEXT;
1017wxAccStatus GridAx::GetSelections(wxVariant * WXUNUSED(selections))
1019 return wxACC_NOT_IMPLEMENTED;
1023wxAccStatus GridAx::GetState(
int childId,
long *state)
1025 int flag = wxACC_STATE_SYSTEM_FOCUSABLE |
1026 wxACC_STATE_SYSTEM_SELECTABLE;
1030 if (!GetRowCol(childId, row, col)) {
1035#if defined(__WXMSW__)
1036 flag |= wxACC_STATE_SYSTEM_FOCUSED |
1037 wxACC_STATE_SYSTEM_SELECTED;
1039 if (mGrid->IsReadOnly(row, col)) {
1043 flag = wxACC_STATE_SYSTEM_UNAVAILABLE | wxACC_STATE_SYSTEM_FOCUSED;
1047#if defined(__WXMAC__)
1048 if (mGrid->IsInSelection(row, col)) {
1049 flag |= wxACC_STATE_SYSTEM_SELECTED;
1052 if (mGrid->GetGridCursorRow() == row && mGrid->GetGridCursorCol() == col) {
1053 flag |= wxACC_STATE_SYSTEM_FOCUSED;
1056 if (mGrid->IsReadOnly(row, col)) {
1057 flag |= wxACC_STATE_SYSTEM_UNAVAILABLE;
1068#if defined(__WXMAC__)
1069wxAccStatus GridAx::GetValue(
int childId, wxString *strValue)
1071wxAccStatus GridAx::GetValue(
int WXUNUSED(childId), wxString *strValue)
1076#if defined(__WXMSW__)
1080#if defined(__WXMAC__)
1081 return GetName(childId, strValue);
1085#if defined(__WXMAC__)
1087wxAccStatus GridAx::Select(
int childId, wxAccSelectionFlags selectFlags)
1092 if (GetRowCol(childId, row, col)) {
1094 if (selectFlags & wxACC_SEL_TAKESELECTION) {
1095 mGrid->SetGridCursor(row, col);
1098 mGrid->SelectBlock(row, col, row, col, selectFlags & wxACC_SEL_ADDSELECTION);
1109wxAccStatus GridAx::GetFocus(
int * childId, wxAccessible **child)
1112 if (mGrid->GetNumberRows() * mGrid->GetNumberCols() == 0) {
1116 *childId = mGrid->GetGridCursorRow()*mGrid->GetNumberCols() +
1117 mGrid->GetGridCursorCol() + 1;
wxEVT_COMMAND_BUTTON_CLICKED
const TranslatableString name
#define GRID_VALUE_FREQUENCY
#define GRID_VALUE_CHOICE
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
const NumericConverterType & NumericConverterType_FREQUENCY()
const NumericConverterType & NumericConverterType_TIME()
void ConnectEvent(wxWindow *w)
void DisconnectEvent(wxWindow *w)
Modified version of wxGridChoiceEditor using wxChoice instead of wxComboBox.
wxChoice * Choice() const
void SetSize(const wxRect &rect) override
void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) override
bool EndEdit(int row, int col, wxGrid *grid)
void ApplyEdit(int row, int col, wxGrid *grid) override
wxGridCellEditor * Clone() const override
wxString GetValue() const override
ChoiceEditor::FocusHandler mHandler
ChoiceEditor(size_t count=0, const wxString choices[]=NULL)
void BeginEdit(int row, int col, wxGrid *grid) override
void SetChoices(const wxArrayString &choices)
const wxString & Internal() const
A context in which formatter operates.
Supplies an accessible grid based on wxGrid.
void OnKeyDown(wxKeyEvent &event)
void OnSelectCell(wxGridEvent &event)
void OnSetFocus(wxFocusEvent &event)
void OnEditorShown(wxGridEvent &event)
An explicitly nonlocalized string, not meant for the user to see.
NumericConverter provides the advanced formatting control used in the selection bar of Audacity.
wxGridCellEditor for the NumericTextCtrl.
NumericTextCtrl * GetNumericTextControl() const
wxString GetValue() const override
void ApplyEdit(int row, int col, wxGrid *grid) override
void SetFormat(const NumericFormatID &format)
void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *handler) override
NumericConverterType mType
FormatterContext mContext
bool IsAcceptedKey(wxKeyEvent &event) override
NumericEditor(const FormatterContext &context, NumericConverterType type, const NumericFormatID &format)
void SetSize(const wxRect &rect) override
NumericFormatID GetFormat() const
void BeginEdit(int row, int col, wxGrid *grid) override
bool EndEdit(int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval) override
wxGridCellEditor * Clone() const override
wxGridCellRenderer for the NumericTextCtrl.
FormatterContext mContext
wxGridCellRenderer * Clone() const override
~NumericRenderer() override
void Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected) override
NumericConverterType mType
wxSize GetBestSize(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, int row, int col) override
void SetValue(double newValue)
static const int UndefinedFrequency
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
AuthorizationHandler handler
Options & AutoPos(bool enable)