1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-25 08:38:39 +02:00
audacity/src/prefs/ExtImportPrefs.cpp
Paul Licameli 4d09705a73 Change XO to XXO in many more places, with no effects at all...
... because the two macros have the same expansion, and are both checked for
in the --keyword arguments passed to msgfmt by locale/update_po_files.sh.

This commit makes ONLY such changes, and comments in Internat.h.  It is big
but quite harmless.

The intention is to introduce a type distinction in a later release, by defining
XXO differently.  XXO is used where & characters in strings (for hotkeys of menu
items or control prompts) are permitted, XO where not.
2020-05-22 13:07:50 -04:00

856 lines
22 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
ExtImportPrefs.cpp
LRN
*******************************************************************//**
\class ExtImportPrefs
\brief A PrefsPanel used to select extended import filter options.
*//*******************************************************************/
#include "../Audacity.h"
#include "ExtImportPrefs.h"
#include <wx/defs.h>
#include <wx/listctrl.h>
#include <wx/dnd.h>
#include "../Prefs.h"
#include "../ShuttleGui.h"
#include "../import/Import.h"
#include "../widgets/AudacityMessageBox.h"
#include "../widgets/Grid.h"
#define EXTIMPORT_MIME_SUPPORT 0
enum ExtImportPrefsControls
{
EIPPluginList = 20000,
EIPRuleTable,
EIPAddRule,
EIPDelRule,
EIPMoveRuleUp,
EIPMoveRuleDown,
EIPMoveFilterUp,
EIPMoveFilterDown
};
BEGIN_EVENT_TABLE(ExtImportPrefs, PrefsPanel)
EVT_LIST_KEY_DOWN(EIPPluginList,ExtImportPrefs::OnPluginKeyDown)
EVT_LIST_BEGIN_DRAG(EIPPluginList,ExtImportPrefs::OnPluginBeginDrag)
EVT_KEY_DOWN (ExtImportPrefs::OnRuleTableKeyDown)
EVT_GRID_CELL_LEFT_CLICK (ExtImportPrefs::OnRuleTableCellClick)
EVT_GRID_EDITOR_HIDDEN (ExtImportPrefs::OnRuleTableEdit)
EVT_GRID_SELECT_CELL (ExtImportPrefs::OnRuleTableSelect)
EVT_GRID_RANGE_SELECT (ExtImportPrefs::OnRuleTableSelectRange)
EVT_BUTTON(EIPAddRule,ExtImportPrefs::OnAddRule)
EVT_BUTTON(EIPDelRule,ExtImportPrefs::OnDelRule)
EVT_BUTTON(EIPMoveRuleUp,ExtImportPrefs::OnRuleMoveUp)
EVT_BUTTON(EIPMoveRuleDown,ExtImportPrefs::OnRuleMoveDown)
EVT_BUTTON(EIPMoveFilterUp,ExtImportPrefs::OnFilterMoveUp)
EVT_BUTTON(EIPMoveFilterDown,ExtImportPrefs::OnFilterMoveDown)
END_EVENT_TABLE()
ExtImportPrefs::ExtImportPrefs(wxWindow * parent, wxWindowID winid)
/* i18n-hint: Title of dialog governing "Extended", or "advanced,"
* audio file import options */
: PrefsPanel(parent, winid, XO("Extended Import")), RuleTable(NULL),
PluginList(NULL), mCreateTable (false), mDragFocus (NULL),
mFakeKeyEvent (false), mStopRecursiveSelection (false), last_selected (-1)
{
Populate();
// See bug #2315 for discussion
// This should be reviewed and (possibly) removed after wx3.1.3.
Bind(wxEVT_SHOW, &ExtImportPrefs::OnShow, this);
}
ExtImportPrefs::~ExtImportPrefs()
{
}
ComponentInterfaceSymbol ExtImportPrefs::GetSymbol()
{
return EXT_IMPORT_PREFS_PLUGIN_SYMBOL;
}
TranslatableString ExtImportPrefs::GetDescription()
{
return XO("Preferences for ExtImport");
}
wxString ExtImportPrefs::HelpPageName()
{
return "Extended_Import_Preferences";
}
/// Creates the dialog and its contents.
void ExtImportPrefs::Populate()
{
//------------------------- Main section --------------------
// Now construct the GUI itself.
// Use 'eIsCreatingFromPrefs' so that the GUI is
// initialised with values from gPrefs.
ShuttleGui S(this, eIsCreatingFromPrefs);
PopulateOrExchange(S);
// ----------------------- End of main section --------------
}
void ExtImportPrefs::PopulateOrExchange(ShuttleGui & S)
{
S.SetBorder(2);
S.StartScroller();
S.TieCheckBox(XXO("A&ttempt to use filter in OpenFile dialog first"),
{wxT("/ExtendedImport/OverrideExtendedImportByOpenFileDialogChoice"),
true});
S.StartStatic(XO("Rules to choose import filters"), 1);
{
S.SetSizerProportion(1);
S.StartHorizontalLay (wxEXPAND, 1);
{
bool fillRuleTable = false;
if (RuleTable == NULL)
{
RuleTable = safenew Grid(S.GetParent(),EIPRuleTable);
RuleTable->SetColLabelSize(RuleTable->GetDefaultRowSize());
#if EXTIMPORT_MIME_SUPPORT
RuleTable->CreateGrid (0, 2, wxGrid::wxGridSelectRows);
#else
RuleTable->CreateGrid (0, 1, wxGrid::wxGridSelectRows);
#endif
RuleTable->DisableDragColMove ();
RuleTable->DisableDragRowSize ();
RuleTable->SetDefaultCellAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
RuleTable->SetColLabelValue (0, _("File extensions"));
#if EXTIMPORT_MIME_SUPPORT
RuleTable->SetColLabelValue (1, _("Mime-types"));
#endif
RuleTable->SetRowLabelSize (0);
RuleTable->SetSelectionMode (wxGrid::wxGridSelectRows);
// call SetMinSize to enable scrolling on large content
RuleTable->Fit();
RuleTable->SetMinSize(RuleTable->GetSize());
ExtImportPrefsDropTarget *dragtarget1 {};
RuleTable->SetDropTarget (
dragtarget1 = safenew ExtImportPrefsDropTarget(
dragtext1 = safenew wxTextDataObject(wxT(""))
)
);
dragtarget1->SetPrefs (this);
RuleTable->EnableDragCell (true);
fillRuleTable = true;
}
S.Position(wxEXPAND | wxALL)
.AddWindow(RuleTable);
PluginList = S.Id(EIPPluginList).AddListControl(
{ { XO("Importer order"), wxLIST_FORMAT_LEFT,
wxLIST_AUTOSIZE_USEHEADER } },
wxLC_REPORT | wxLC_SINGLE_SEL
);
if (fillRuleTable)
{
ExtImportPrefsDropTarget *dragtarget2 {};
PluginList->SetDropTarget (
dragtarget2 = safenew ExtImportPrefsDropTarget(
dragtext2 = safenew wxTextDataObject(wxT(""))
)
);
dragtarget2->SetPrefs (this);
auto &items = Importer::Get().GetImportItems();
{
int i = -1;
for (const auto &item : items)
AddItemToTable (++i, item.get());
}
if (!items.empty())
{
RuleTable->SelectRow(0);
RuleTable->SetGridCursor(0,0);
}
}
}
S.EndHorizontalLay();
S.StartHorizontalLay (wxSHRINK, 0);
{
MoveRuleUp = S.Id (EIPMoveRuleUp).AddButton(XXO("Move rule &up"));
MoveRuleDown = S.Id (EIPMoveRuleDown).AddButton(
XXO("Move rule &down"));
MoveFilterUp = S.Id (EIPMoveFilterUp).AddButton(
XXO("Move f&ilter up"));
MoveFilterDown = S.Id (EIPMoveFilterDown).AddButton(
XXO("Move &filter down"));
}
S.EndHorizontalLay();
S.StartHorizontalLay (wxSHRINK, 0);
{
AddRule = S.Id (EIPAddRule).AddButton(XXO("&Add new rule"));
DelRule = S.Id (EIPDelRule).AddButton(XXO("De&lete selected rule"));
}
S.EndHorizontalLay();
}
S.EndStatic();
S.EndScroller();
Layout();
Fit();
SetMinSize(GetSize());
}
bool ExtImportPrefs::Commit()
{
ShuttleGui S(this, eIsSavingToPrefs);
PopulateOrExchange(S);
return true;
}
// See bug #2315 for discussion. This should be reviewed
// and (possibly) removed after wx3.1.3.
void ExtImportPrefs::OnShow(wxShowEvent &event)
{
event.Skip();
if (event.IsShown())
{
RuleTable->Refresh();
PluginList->Refresh();
}
}
void ExtImportPrefs::OnPluginKeyDown(wxListEvent& event)
{
for (int i = 0; i < 1; i++)
{
#ifdef __WXMAC__
if (!mFakeKeyEvent && !wxGetKeyState(WXK_COMMAND))
break;
#else
if (!mFakeKeyEvent && !wxGetKeyState(WXK_CONTROL))
break;
#endif
if (DoOnPluginKeyDown (event.GetKeyCode()))
event.Skip();
}
}
void ExtImportPrefs::SwapPluginRows (int row1, int row2)
{
wxString t, t2;
long d, d2;
ImportPlugin *ip1, *ip2;
auto &items = Importer::Get().GetImportItems();
ExtImportItem *item = NULL;
if( last_selected >= 0 )
item = items[last_selected].get();
t = PluginList->GetItemText (row1);
d = PluginList->GetItemData (row1);
d2 = PluginList->GetItemData (row2);
PluginList->SetItemText (row1, PluginList->GetItemText (row2));
PluginList->SetItemText (row2, t);
if (d == -1 || d2 == -1)
{
PluginList->SetItemData (row1, PluginList->GetItemData (row2));
PluginList->SetItemData (row2, d);
if( !item )
return;
if (d == -1)
{
item->divider = row2;
}
else if (d2 == -1)
{
item->divider = row1;
}
}
else
{
if( !item )
return;
ip1 = item->filter_objects[d];
ip2 = item->filter_objects[d2];
item->filter_objects[d] = ip2;
item->filter_objects[d2] = ip1;
t = item->filters[d];
t2 = item->filters[d2];
item->filters[d] = t2;
item->filters[d2] = t;
}
}
bool ExtImportPrefs::DoOnPluginKeyDown (int code)
{
if (code != WXK_UP && code != WXK_DOWN)
return false;
long itemIndex = -1;
long itemIndex2 = -1;
itemIndex = PluginList->GetNextItem(itemIndex,
wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (itemIndex == -1)
return false;
if (last_selected == -1)
return false;
auto &items = Importer::Get().GetImportItems();
ExtImportItem *item = items[last_selected].get();
if (code == WXK_UP && itemIndex == 0)
return false;
else if (code == WXK_DOWN && itemIndex == PluginList->GetItemCount() - 1)
return false;
if (code == WXK_UP)
{
itemIndex2 = itemIndex - 1;
}
else if (code == WXK_DOWN)
{
itemIndex2 = itemIndex + 1;
}
SwapPluginRows (itemIndex, itemIndex2);
if (mFakeKeyEvent)
{
PluginList->SetItemState (itemIndex, 0, wxLIST_STATE_SELECTED);
PluginList->SetItemState (itemIndex2, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
int fcount = item->filter_objects.size();
if (item->divider >= fcount)
{
item->divider = -1;
}
if (item->divider < -1)
item->divider = item->filter_objects.size() - 1;
return true;
}
void ExtImportPrefs::SwapRows (int row1, int row2)
{
int t;
wxString ts;
if (row1 == row2)
return;
if (row1 > row2)
{
t = row1;
row1 = row2;
row2 = t;
}
auto &items = Importer::Get().GetImportItems();
auto &t1 = items[row1];
auto &t2 = items[row2];
std::swap(t1, t2);
for (int i = 0; i < RuleTable->GetNumberCols(); i++)
{
ts = RuleTable->GetCellValue (row2, i);
RuleTable->SetCellValue (row2, i, RuleTable->GetCellValue (row1, i));
RuleTable->SetCellValue (row1, i, ts);
}
}
void ExtImportPrefs::OnPluginBeginDrag(wxListEvent& WXUNUSED(event))
{
wxDropSource dragSource(this);
dragtext2->SetText(wxT(""));
dragSource.SetData(*dragtext2);
mDragFocus = PluginList;
if( mDragFocus == NULL )
return;
wxDragResult result = dragSource.DoDragDrop(wxDrag_DefaultMove);
mDragFocus = NULL;
switch (result)
{
case wxDragCopy:
case wxDragMove:
case wxDragNone:
return;
break;
default:
break;
}
}
void ExtImportPrefs::OnRuleTableKeyDown(wxKeyEvent& event)
{
int mods = event.GetModifiers();
if (mods & wxMOD_CMD && (event.GetKeyCode() == WXK_UP ||
event.GetKeyCode() == WXK_DOWN))
{
DoOnRuleTableKeyDown (event.GetKeyCode());
}
else
{
event.Skip();
}
}
void ExtImportPrefs::DoOnRuleTableKeyDown (int keycode)
{
int selrow = RuleTable->GetGridCursorRow ();
wxString ts;
if (keycode == WXK_UP)
{
if (selrow <= 0)
return;
SwapRows (selrow - 1, selrow);
RuleTable->MoveCursorUp (false);
RuleTable->SelectRow (selrow - 1);
}
else if (keycode == WXK_DOWN)
{
if (selrow == RuleTable->GetNumberRows() - 1)
return;
SwapRows (selrow, selrow + 1);
RuleTable->MoveCursorDown (false);
RuleTable->SelectRow (selrow + 1);
}
}
void ExtImportPrefs::OnRuleTableSelect (wxGridEvent& event)
{
int toprow;
event.Skip();
if (!event.Selecting() || mStopRecursiveSelection)
return;
toprow = event.GetRow();
if (toprow < 0)
return;
DoOnRuleTableSelect (toprow);
}
void ExtImportPrefs::OnRuleTableSelectRange (wxGridRangeSelectEvent& event)
{
int toprow;
event.Skip();
if (!event.Selecting() || mStopRecursiveSelection)
return;
toprow = event.GetTopRow();
if (toprow < 0)
return;
DoOnRuleTableSelect (toprow);
mStopRecursiveSelection = true;
RuleTable->SelectRow (toprow);
mStopRecursiveSelection = false;
RuleTable->SetGridCursor (toprow, 0);
}
void ExtImportPrefs::DoOnRuleTableSelect (int toprow)
{
auto &items = Importer::Get().GetImportItems();
if (toprow < 0 || toprow > (int)items.size())
{
return;
}
ExtImportItem *item = items[toprow].get();
PluginList->DeleteAllItems();
int fcount;
fcount = item->filters.size();
int shift = 0;
for (int i = 0; i < fcount; i++)
{
if (item->divider == i)
{
PluginList->InsertItem (i, _("Unused filters:"));
PluginList->SetItemData (i, -1);
shift = 1;
}
if (item->filter_objects[i] != NULL)
{
PluginList->InsertItem (i + shift,
item->filter_objects[i]->GetPluginFormatDescription().Translation());
}
else
{
PluginList->InsertItem (i + shift, item->filters[i]);
}
PluginList->SetItemData (i + shift, i);
}
if (item->divider == -1)
{
PluginList->InsertItem (fcount, _("Unused filters:"));
PluginList->SetItemData (fcount, -1);
}
wxListItem info;
info.SetId (0);
info.SetColumn (0);
info.SetStateMask (wxLIST_STATE_SELECTED);
info.SetState (wxLIST_STATE_SELECTED);
info.SetMask (wxLIST_MASK_STATE);
PluginList->SetItem (info);
PluginList->SetColumnWidth (0, wxLIST_AUTOSIZE);
last_selected = toprow;
}
void ExtImportPrefs::OnRuleTableEdit (wxGridEvent& event)
{
int row = event.GetRow();
int col = event.GetCol();
auto &items = Importer::Get().GetImportItems();
ExtImportItem *item = items[row].get();
RuleTable->SaveEditControlValue();
wxString val = RuleTable->GetCellValue (row, col);
int fixSpaces = wxNO;
bool askedAboutSpaces = false;
wxArrayString vals;
wxString delims(wxT(":"));
Importer::Get().StringToList (val, delims, vals);
switch (col)
{
case 0:
item->extensions.clear();
break;
case 1:
item->mime_types.clear();
break;
}
for (size_t i = 0; i < vals.size(); i++)
{
wxString trimmed = vals[i];
trimmed.Trim().Trim(false);
if (trimmed != vals[i])
{
if (!askedAboutSpaces)
{
fixSpaces = AudacityMessageBox(
XO(
"There are space characters (spaces, newlines, tabs or linefeeds) in one of \
the items. They are likely to break the pattern matching. Unless you know \
what you are doing, it is recommended to trim spaces. Do you want \
Audacity to trim spaces for you?"),
XO("Spaces detected"),
wxYES_NO);
askedAboutSpaces = true;
}
if (fixSpaces != wxYES)
{
trimmed = vals[i];
}
else
{
vals[i] = trimmed;
}
}
switch (col)
{
case 0:
item->extensions.push_back(trimmed);
break;
case 1:
item->mime_types.push_back(trimmed);
break;
}
}
if (fixSpaces == wxYES)
{
wxString vals_as_string;
for (size_t i = 0; i < vals.size(); i++)
{
if (i > 0)
vals_as_string.Append (wxT(":"));
vals_as_string.Append (vals[i]);
}
RuleTable->SetCellValue (row, col, vals_as_string);
}
RuleTable->AutoSizeColumns ();
}
void ExtImportPrefs::AddItemToTable (int index, const ExtImportItem *item)
{
wxString extensions, mime_types;
if (item->extensions.size() > 0)
{
extensions.Append (item->extensions[0]);
for (unsigned int i = 1; i < item->extensions.size(); i++)
{
extensions.Append (wxT(":"));
extensions.Append (item->extensions[i]);
}
}
if (item->mime_types.size() > 0)
{
mime_types.Append (item->mime_types[0]);
for (unsigned int i = 1; i < item->mime_types.size(); i++)
{
mime_types.Append (wxT(":"));
mime_types.Append (item->mime_types[i]);
}
}
RuleTable->InsertRows (index, 1);
RuleTable->SetCellValue (index, 0, extensions);
#if EXTIMPORT_MIME_SUPPORT
RuleTable->SetCellValue (index, 1, mime_types);
#endif
RuleTable->AutoSizeColumns ();
}
void ExtImportPrefs::OnAddRule(wxCommandEvent& WXUNUSED(event))
{
auto &items = Importer::Get().GetImportItems();
auto uitem = Importer::Get().CreateDefaultImportItem();
auto item = uitem.get();
items.push_back(std::move(uitem));
AddItemToTable (RuleTable->GetNumberRows (), item);
RuleTable->SelectRow(RuleTable->GetNumberRows () - 1);
RuleTable->SetGridCursor (RuleTable->GetNumberRows () - 1, 0);
RuleTable->SetFocus();
}
void ExtImportPrefs::OnDelRule(wxCommandEvent& WXUNUSED(event))
{
if (last_selected < 0)
return;
auto &items = Importer::Get().GetImportItems();
int msgres = AudacityMessageBox (
XO("Do you really want to delete selected rule?"),
XO("Rule deletion confirmation"),
wxYES_NO,
RuleTable);
// Yes or no, there is no third!
if (msgres != wxYES)
return;
RuleTable->DeleteRows (last_selected);
items.erase (items.begin() + last_selected);
RuleTable->AutoSizeColumns ();
if (last_selected >= RuleTable->GetNumberRows ())
last_selected = RuleTable->GetNumberRows () - 1;
if (last_selected >= 0)
{
RuleTable->SelectRow(last_selected);
RuleTable->SetGridCursor (last_selected, 0);
}
}
void ExtImportPrefs::OnRuleMoveUp(wxCommandEvent& WXUNUSED(event))
{
DoOnRuleTableKeyDown (WXK_UP);
}
void ExtImportPrefs::OnRuleMoveDown(wxCommandEvent& WXUNUSED(event))
{
DoOnRuleTableKeyDown (WXK_DOWN);
}
void ExtImportPrefs::FakeOnPluginKeyDown (int keycode)
{
wxListEvent fakeevent(wxEVT_COMMAND_LIST_KEY_DOWN, EIPPluginList);
fakeevent.SetEventObject(this);
fakeevent.m_code = keycode;
mFakeKeyEvent = true;
GetEventHandler()->ProcessEvent (fakeevent);
mFakeKeyEvent = false;
}
void ExtImportPrefs::OnFilterMoveUp(wxCommandEvent& WXUNUSED(event))
{
FakeOnPluginKeyDown (WXK_UP);
}
void ExtImportPrefs::OnFilterMoveDown(wxCommandEvent& WXUNUSED(event))
{
FakeOnPluginKeyDown (WXK_DOWN);
}
void ExtImportPrefs::OnRuleTableCellClick (wxGridEvent& event)
{
int row = event.GetRow();
RuleTable->SelectRow (row, false);
RuleTable->SetGridCursor (row, 0);
wxDropSource dragSource(this);
dragtext1->SetText(wxT(""));
dragSource.SetData(*dragtext1);
mDragFocus = RuleTable;
wxDragResult result = dragSource.DoDragDrop(wxDrag_DefaultMove);
mDragFocus = NULL;
switch (result)
{
case wxDragCopy: /* copy the data */
case wxDragMove:
case wxDragNone:
return;
break;
default: /* do nothing */ break;
}
event.Skip();
}
ExtImportPrefsDropTarget::ExtImportPrefsDropTarget(wxDataObject *dataObject)
: wxDropTarget(dataObject)
{
mPrefs = NULL;
}
ExtImportPrefsDropTarget::~ExtImportPrefsDropTarget ()
{
}
void ExtImportPrefsDropTarget::SetPrefs (ExtImportPrefs *prefs)
{
mPrefs = prefs;
}
wxDragResult ExtImportPrefsDropTarget::OnData(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
wxDragResult def)
{
return def;
}
#if defined(__WXMSW__)
/* wxListCtrl::FindItem() in wxPoint()-taking mode works only for lists in
* Small/Large-icon mode
* wxListCtrl::HitTest() on Windows only hits item label rather than its whole
* row, which makes it difficult to drag over items with short or non-existent
* labels.
*/
long wxCustomFindItem(wxListCtrl *list, int x, int y)
{
long count = list->GetItemCount();
wxRect r;
for (long i = 0; i < count; i++)
{
if (list->GetItemRect (i, r))
{
if (r.Contains (x, y))
return i;
}
}
return -1;
}
#endif
bool ExtImportPrefsDropTarget::OnDrop(wxCoord x, wxCoord y)
{
if (mPrefs == NULL)
return false;
wxListCtrl *PluginList = mPrefs->GetPluginList();
Grid *RuleTable = mPrefs->GetRuleTable();
if (mPrefs->GetDragFocus() == RuleTable)
{
if (RuleTable->YToRow(
RuleTable->CalcUnscrolledPosition(wxPoint(x, y)).y) == wxNOT_FOUND)
return false;
}
else if (mPrefs->GetDragFocus() == PluginList)
{
#if defined(__WXMSW__)
long item = wxCustomFindItem (PluginList, x, y);
#else
int flags = 0;
long item = PluginList->HitTest (wxPoint (x, y), flags, NULL);
#endif
if (item < 0)
return false;
}
return true;
}
wxDragResult ExtImportPrefsDropTarget::OnEnter(wxCoord x, wxCoord y,
wxDragResult def)
{
return OnDragOver(x, y, def);
}
wxDragResult ExtImportPrefsDropTarget::OnDragOver(wxCoord x, wxCoord y,
wxDragResult WXUNUSED(def))
{
if (mPrefs == NULL)
return wxDragNone;
wxListCtrl *PluginList = mPrefs->GetPluginList();
Grid *RuleTable = mPrefs->GetRuleTable();
if (mPrefs->GetDragFocus() == RuleTable)
{
int row;
row = RuleTable->YToRow(RuleTable->CalcUnscrolledPosition(wxPoint(x, y)).y);
if (row == wxNOT_FOUND)
return wxDragNone;
int cRow = RuleTable->GetGridCursorRow ();
if (row != cRow)
{
mPrefs->SwapRows (cRow, row);
RuleTable->SetGridCursor (row, 0);
RuleTable->SelectRow (row);
}
}
else if (mPrefs->GetDragFocus() == PluginList)
{
#if defined(__WXMSW__)
long item = wxCustomFindItem (PluginList, x, y);
#else
int flags = 0;
long item = PluginList->HitTest (wxPoint (x, y), flags, NULL);
#endif
if (item < 0)
return wxDragNone;
long selected = -1;
selected = PluginList->GetNextItem(selected,
wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (selected == -1)
return wxDragNone;
if (item != selected)
{
mPrefs->SwapPluginRows(selected, item);
PluginList->SetItemState (selected, 0, wxLIST_STATE_SELECTED);
PluginList->SetItemState (item, wxLIST_STATE_SELECTED,
wxLIST_STATE_SELECTED);
}
}
return wxDragMove;
}
void ExtImportPrefsDropTarget::OnLeave()
{
}
namespace{
PrefsPanel::Registration sAttachment{ "ExtImport",
[](wxWindow *parent, wxWindowID winid, AudacityProject *)
{
wxASSERT(parent); // to justify safenew
return safenew ExtImportPrefs(parent, winid);
},
false,
// Place as a lower level of the tree of pages:
{ "ImportExport" }
};
}