23 template <
typename T,
typename Inst,
typename FuncType>
24 void assign_if_changed_notify(T &oldVal,
const T &newVal, Inst *inst,
34 class FileAssociationWrap
44 explicit FileAssociationWrap(
const QString &new_extension) : m_state(efsSAVE)
46 m_fa.extension = new_extension;
50 m_fa(std::move(fa)) {}
52 unsigned int GetIDx(
void)
const {
return m_fa.id; }
53 QString GetExtension(
void)
const {
return m_fa.extension; }
54 QString GetCommand(
void)
const {
return m_fa.playcommand; }
55 bool GetDefault(
void)
const {
return m_fa.use_default; }
56 bool GetIgnore(
void)
const {
return m_fa.ignore; }
58 FA_State
GetState()
const {
return m_state; }
84 void MarkForDeletion()
89 void SetDefault(
bool yes_or_no)
91 assign_if_changed_notify(m_fa.use_default, yes_or_no,
this,
92 std::mem_fn(&FileAssociationWrap::SetChanged));
95 void SetIgnore(
bool yes_or_no)
97 assign_if_changed_notify(m_fa.ignore, yes_or_no,
this,
98 std::mem_fn(&FileAssociationWrap::SetChanged));
101 void SetCommand(
const QString &new_command)
103 assign_if_changed_notify(m_fa.playcommand, new_command,
this,
104 std::mem_fn(&FileAssociationWrap::SetChanged));
108 void SetChanged() { m_state = efsSAVE; }
112 FA_State m_state {efsNONE};
115 class BlockSignalsGuard
118 void Block(QObject *o)
120 o->blockSignals(
true);
121 m_objects.push_back(o);
126 for (
auto & obj : m_objects)
127 obj->blockSignals(
false);
131 using list_type = std::vector<QObject *>;
139 using UID_type =
unsigned int;
141 UIDToFAPair() =
default;
143 UIDToFAPair(UID_type uid, FileAssociationWrap *assoc) :
144 m_uid(uid), m_fileAssoc(assoc) {}
147 FileAssociationWrap *m_fileAssoc {
nullptr};
151 bool operator<(
const UIDToFAPair lhs,
const UIDToFAPair rhs)
153 if (lhs.m_fileAssoc && rhs.m_fileAssoc)
154 return QString::localeAwareCompare(lhs.m_fileAssoc->GetExtension(),
155 rhs.m_fileAssoc->GetExtension()) < 0;
157 return rhs.m_fileAssoc;
183 fa.second->CommitChanges();
186 bool AddExtension(
const QString& newExtension, UIDToFAPair::UID_type &new_id)
188 if (!newExtension.isEmpty())
192 new FileAssociationWrap(newExtension)));
204 p->second->MarkForDeletion();
218 auto deleted = std::remove_if(ret.begin(),
221 if (deleted != ret.end())
222 ret.erase(deleted, ret.end());
224 std::sort(ret.begin(), ret.end());
234 auto key = item->
GetData().value<UIDToFAPair>();
237 return key.m_fileAssoc;
255 using FA_collection = std::map<UIDToFAPair::UID_type, FileAssociationWrap *>;
261 const FileAssocDialogPrivate::FA_collection::value_type from)
263 return {from.first, from.second};
267 template <FileAssociationWrap::FA_State against>
272 return item.m_fileAssoc && item.m_fileAssoc->GetState() == against;
278 using tmp_fa_list = std::vector<UIDToFAPair>;
283 tmp_fa.reserve(fa_list.size());
285 auto newpair = [
this](
const auto & fa)
286 {
return UIDToFAPair(++
m_nextFAID,
new FileAssociationWrap(fa)); };
287 std::transform(fa_list.cbegin(), fa_list.cend(), std::back_inserter(tmp_fa), newpair);
289 std::shuffle(tmp_fa.begin(), tmp_fa.end(),
290 std::mt19937(std::random_device()()));
292 for (
auto fa : tmp_fa)
300 LOG(VB_GENERAL, LOG_ERR,
301 QString(
"%1: Couldn't get any filetypes from your database.")
315 const QString &lname) :
343 LOG(VB_GENERAL, LOG_ERR,
"Cannot load screen 'file_associations'");
360 "to modify or delete its settings."));
362 "of file. To use MythTV's Internal player, "
363 "use \"Internal\" as the player. For all other "
364 "players, you can use %s to substitute the filename."));
366 "to be ignored in scans of your library."));
368 "settings to override this one."));
418 auto key = item->
GetData().value<UIDToFAPair>();
430 QString message = tr(
"Enter the new extension:");
434 if (newextdialog->Create())
443 UIDToFAPair::UID_type new_sel = 0;
453 BlockSignalsGuard bsg;
462 if (tmp_list.empty())
472 UIDToFAPair::UID_type selected_id = 0;
476 auto key = current_item->
GetData().value<UIDToFAPair>();
479 selected_id = key.m_uid;
483 if (useSelectionOverride)
490 for (
auto & fad : tmp_list)
497 fad.m_fileAssoc->GetExtension(),
498 QVariant::fromValue(fad));
499 if (selected_id && fad.m_uid == selected_id)
507 auto key = current_item->
GetData().value<UIDToFAPair>();