26 template <
typename T,
typename Inst,
typename FuncType>
27 void assign_if_changed_notify(T &oldVal,
const T &newVal, Inst *inst,
37 class FileAssociationWrap
47 explicit FileAssociationWrap(
const QString &new_extension) : m_state(efsSAVE)
49 m_fa.extension = new_extension;
53 m_fa(
std::move(fa)) {}
55 unsigned int GetIDx(
void)
const {
return m_fa.id; }
56 QString GetExtension(
void)
const {
return m_fa.extension; }
57 QString GetCommand(
void)
const {
return m_fa.playcommand; }
58 bool GetDefault(
void)
const {
return m_fa.use_default; }
59 bool GetIgnore(
void)
const {
return m_fa.ignore; }
61 FA_State
GetState()
const {
return m_state; }
87 void MarkForDeletion()
92 void SetDefault(
bool yes_or_no)
94 assign_if_changed_notify(m_fa.use_default, yes_or_no,
this,
95 std::mem_fn(&FileAssociationWrap::SetChanged));
98 void SetIgnore(
bool yes_or_no)
100 assign_if_changed_notify(m_fa.ignore, yes_or_no,
this,
101 std::mem_fn(&FileAssociationWrap::SetChanged));
104 void SetCommand(
const QString &new_command)
106 assign_if_changed_notify(m_fa.playcommand, new_command,
this,
107 std::mem_fn(&FileAssociationWrap::SetChanged));
111 void SetChanged() { m_state = efsSAVE; }
115 FA_State m_state {efsNONE};
118 class BlockSignalsGuard
121 void Block(QObject *o)
123 o->blockSignals(
true);
124 m_objects.push_back(o);
129 for (
auto & obj : m_objects)
130 obj->blockSignals(
false);
134 using list_type = std::vector<QObject *>;
142 using UID_type =
unsigned int;
144 UIDToFAPair() =
default;
146 UIDToFAPair(UID_type uid, FileAssociationWrap *assoc) :
147 m_uid(uid), m_fileAssoc(assoc) {}
150 FileAssociationWrap *m_fileAssoc {
nullptr};
154 bool operator<(
const UIDToFAPair lhs,
const UIDToFAPair rhs)
156 if (lhs.m_fileAssoc && rhs.m_fileAssoc)
157 return QString::localeAwareCompare(lhs.m_fileAssoc->GetExtension(),
158 rhs.m_fileAssoc->GetExtension()) < 0;
160 return rhs.m_fileAssoc;
186 fa.second->CommitChanges();
189 bool AddExtension(
const QString& newExtension, UIDToFAPair::UID_type &new_id)
191 if (!newExtension.isEmpty())
195 new FileAssociationWrap(newExtension)));
207 p->second->MarkForDeletion();
221 auto deleted = std::remove_if(ret.begin(),
224 if (deleted != ret.end())
225 ret.erase(deleted, ret.end());
227 std::sort(ret.begin(), ret.end());
237 auto key = item->
GetData().value<UIDToFAPair>();
240 return key.m_fileAssoc;
258 using FA_collection = std::map<UIDToFAPair::UID_type, FileAssociationWrap *>;
264 const FileAssocDialogPrivate::FA_collection::value_type from)
266 return {from.first, from.second};
270 template <FileAssociationWrap::FA_State against>
275 return item.m_fileAssoc && item.m_fileAssoc->GetState() == against;
281 using tmp_fa_list = std::vector<UIDToFAPair>;
286 tmp_fa.reserve(fa_list.size());
288 auto newpair = [
this](
const auto & fa)
289 {
return UIDToFAPair(++
m_nextFAID,
new FileAssociationWrap(fa)); };
290 std::transform(fa_list.cbegin(), fa_list.cend(), std::back_inserter(tmp_fa), newpair);
292 std::shuffle(tmp_fa.begin(), tmp_fa.end(),
293 std::mt19937(std::random_device()()));
295 for (
const auto& fa : tmp_fa)
303 LOG(VB_GENERAL, LOG_ERR,
304 QString(
"%1: Couldn't get any filetypes from your database.")
318 const QString &lname) :
346 LOG(VB_GENERAL, LOG_ERR,
"Cannot load screen 'file_associations'");
363 "to modify or delete its settings."));
365 "of file. To use MythTV's Internal player, "
366 "use \"Internal\" as the player. For all other "
367 "players, you can use %s to substitute the filename."));
369 "to be ignored in scans of your library."));
371 "settings to override this one."));
421 auto key = item->
GetData().value<UIDToFAPair>();
433 QString message = tr(
"Enter the new extension:");
437 if (newextdialog->Create())
446 UIDToFAPair::UID_type new_sel = 0;
456 BlockSignalsGuard bsg;
465 if (tmp_list.empty())
475 UIDToFAPair::UID_type selected_id = 0;
479 auto key = current_item->
GetData().value<UIDToFAPair>();
482 selected_id = key.m_uid;
486 if (useSelectionOverride)
493 for (
auto & fad : tmp_list)
500 fad.m_fileAssoc->GetExtension(),
501 QVariant::fromValue(fad));
502 if (selected_id && fad.m_uid == selected_id)
510 auto key = current_item->
GetData().value<UIDToFAPair>();