annotate foosdk/sdk/foobar2000/foo_sample/rating.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "stdafx.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 /*
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 ========================================================================
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 Sample implementation of metadb_index_client and a rating database.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 ========================================================================
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 The rating data is all maintained by metadb backend, we only present and alter it when asked to.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 Relevant classes:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 metadb_index_client_impl - turns track info into a database key to which our data gets pinned.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 init_stage_callback_impl - initializes ourselves at the proper moment of the app lifetime.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 initquit_imp - clean up cached objects on app shutdown
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 metadb_display_field_provider_impl - publishes our %foo_sample_...% fields via title formatting.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 contextmenu_rating - context menu command to cycle rating values.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 mainmenu_rating - main menu command to show a dump of all present ratings.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 track_property_provider_impl - serves info for the Properties dialog
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 // I am foo_sample and these are *my* GUIDs.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 // Replace with your own when reusing.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 // Always recreate guid_foo_sample_rating_index if your metadb_index_client_impl hashing semantics changed or else you run into inconsistent/nonsensical data.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 static const GUID guid_foo_sample_track_rating_index = { 0x88cf3f09, 0x26a8, 0x42ef,{ 0xb7, 0xb8, 0x42, 0x21, 0xb9, 0x62, 0x26, 0x78 } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 static const GUID guid_foo_sample_album_rating_index = { 0xd94ba576, 0x7fab, 0x4f1b,{ 0xbe, 0x5e, 0x4f, 0x8e, 0x9d, 0x5f, 0x30, 0xf1 } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 static const GUID guid_foo_sample_rating_contextmenu1 = { 0x5d71c93, 0x5d38, 0x4e63,{ 0x97, 0x66, 0x8f, 0xb7, 0x6d, 0xc7, 0xc5, 0x9e } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 static const GUID guid_foo_sample_rating_contextmenu2 = { 0xf3972846, 0x7c32, 0x44fa,{ 0xbd, 0xa, 0x68, 0x86, 0x65, 0x69, 0x4b, 0x7d } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 static const GUID guid_foo_sample_rating_contextmenu3 = { 0x67a6d984, 0xe499, 0x4f86,{ 0xb9, 0xcb, 0x66, 0x8e, 0x59, 0xb8, 0xd0, 0xe6 } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 static const GUID guid_foo_sample_rating_contextmenu4 = { 0x4541dfa5, 0x7976, 0x43aa,{ 0xb9, 0x73, 0x10, 0xc3, 0x26, 0x55, 0x5a, 0x5c } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 static const GUID guid_foo_sample_contextmenu_group = { 0x572de7f4, 0xcbdf, 0x479a,{ 0x97, 0x26, 0xa, 0xb0, 0x97, 0x47, 0x69, 0xe3 } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 static const GUID guid_foo_sample_rating_mainmenu = { 0x53327baa, 0xbaa4, 0x478e,{ 0x87, 0x24, 0xf7, 0x38, 0x4, 0x15, 0xf7, 0x27 } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 static const GUID guid_foo_sample_mainmenu_group = { 0x44963e7a, 0x4b2a, 0x4588,{ 0xb0, 0x17, 0xa8, 0x69, 0x18, 0xcb, 0x8a, 0xa5 } };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 // Patterns by which we pin our data to.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 // If multiple songs in the library evaluate to the same string, they will be considered the same by our component,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 // and data applied to one will also show up with the rest.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 // Always recreate relevant index GUIDs if you change these
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 static const char strTrackRatingPinTo[] = "%artist% - %title%";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 static const char strAlbumRatingPinTo[] = "%album artist% - %album%";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 // Our group in Properties dialog / Details tab, see track_property_provider_impl
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 static const char strPropertiesGroup[] = "Sample Component";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 // Retain pinned data for four weeks if there are no matching items in library
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 static const t_filetimestamp retentionPeriod = system_time_periods::week * 4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 // A class that turns metadata + location info into hashes to which our data gets pinned by the backend.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 class metadb_index_client_impl : public metadb_index_client {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 metadb_index_client_impl( const char * pinTo ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 static_api_ptr_t<titleformat_compiler>()->compile_force(m_keyObj, pinTo);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 metadb_index_hash transform(const file_info & info, const playable_location & location) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 pfc::string_formatter str;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 m_keyObj->run_simple( location, &info, str );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 // Make MD5 hash of the string, then reduce it to 64-bit metadb_index_hash
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 return static_api_ptr_t<hasher_md5>()->process_single_string( str ).xorHalve();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 titleformat_object::ptr m_keyObj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 static metadb_index_client_impl * clientByGUID( const GUID & guid ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 // Static instances, never destroyed (deallocated with the process), created first time we get here
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 // Using service_impl_single_t, reference counting disabled
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 // This is somewhat ugly, operating on raw pointers instead of service_ptr, but OK for this purpose
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 static metadb_index_client_impl * g_clientTrack = new service_impl_single_t<metadb_index_client_impl>(strTrackRatingPinTo);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 static metadb_index_client_impl * g_clientAlbum = new service_impl_single_t<metadb_index_client_impl>(strAlbumRatingPinTo);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 PFC_ASSERT( guid == guid_foo_sample_album_rating_index || guid == guid_foo_sample_track_rating_index );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 return (guid == guid_foo_sample_album_rating_index ) ? g_clientAlbum : g_clientTrack;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 // Static cached ptr to metadb_index_manager
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 // Cached because we'll be calling it a lot on per-track basis, let's not pass it everywhere to low level functions
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 // Obtaining the pointer from core is reasonably efficient - log(n) to the number of known service classes, but not good enough for something potentially called hundreds of times
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 static metadb_index_manager::ptr theAPI() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 // Raw ptr instead service_ptr, don't release on DLL unload, would cause issues
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 static metadb_index_manager * cached = metadb_index_manager::get().detach();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 return cached;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 // An init_stage_callback to hook ourselves into the metadb
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 // We need to do this properly early to prevent dispatch_global_refresh() from new fields that we added from hammering playlists etc
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 class init_stage_callback_impl : public init_stage_callback {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 void on_init_stage(t_uint32 stage) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 if (stage == init_stages::before_config_read) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 auto api = theAPI();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 // Important, handle the exceptions here!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 // This will fail if the files holding our data are somehow corrupted.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 api->add(clientByGUID(guid_foo_sample_track_rating_index), guid_foo_sample_track_rating_index, retentionPeriod);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 api->add(clientByGUID(guid_foo_sample_album_rating_index), guid_foo_sample_album_rating_index, retentionPeriod);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 } catch (std::exception const & e) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 api->remove(guid_foo_sample_track_rating_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 api->remove(guid_foo_sample_album_rating_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 FB2K_console_formatter() << "[foo_sample rating] Critical initialization failure: " << e;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 api->dispatch_global_refresh();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 static service_factory_single_t<init_stage_callback_impl> g_init_stage_callback_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 typedef uint32_t rating_t;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 static const rating_t rating_invalid = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 static const rating_t rating_max = 5;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 struct record_t {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 rating_t m_rating = rating_invalid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 pfc::string8 m_comment;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 static record_t record_get(const GUID & indexID, metadb_index_hash hash) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 mem_block_container_impl temp; // this will receive our BLOB
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 theAPI()->get_user_data( indexID, hash, temp );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 if ( temp.get_size() > 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 // Parse the BLOB using stream formatters
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 stream_reader_formatter_simple_ref< /* using big endian data? nope */ false > reader(temp.get_ptr(), temp.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 record_t ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 reader >> ret.m_rating; // little endian uint32 got
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 if ( reader.get_remaining() > 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 // more data left in the stream?
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 // note that this is a stream_reader_formatter_simple_ref method, regular stream formatters do not know the size or seek around, only read the stream sequentially
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 reader >> ret.m_comment; // this reads uint32 prefix indicating string size in bytes, then the actual string in UTF-8 characters }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 } // otherwise we leave the string empty
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 // if we attempted to read past the EOF, we'd land in the exception_io_data handler below
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 } catch (exception_io_data const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 // we get here as a result of stream formatter data error
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 // fall thru to return a blank record
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 return record_t();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 void record_set( const GUID & indexID, metadb_index_hash hash, const record_t & record) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 stream_writer_formatter_simple< /* using bing endian data? nope */ false > writer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 writer << record.m_rating;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 if ( record.m_comment.length() > 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 // bother with this only if the comment is not blank
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 writer << record.m_comment; // uint32 size + UTF-8 bytes
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 theAPI()->set_user_data( indexID, hash, writer.m_buffer.get_ptr(), writer.m_buffer.get_size() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 static rating_t rating_get( const GUID & indexID, metadb_index_hash hash) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 return record_get(indexID, hash).m_rating;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 // Returns true if the value was actually changed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 static bool rating_set( const GUID & indexID, metadb_index_hash hash, rating_t rating) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 bool bChanged = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 auto rec = record_get(indexID, hash);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 if ( rec.m_rating != rating ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 rec.m_rating = rating;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 record_set( indexID, hash, rec);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 bChanged = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 return bChanged;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 static bool comment_set( const GUID & indexID, metadb_index_hash hash, const char * strComment ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 auto rec = record_get(indexID, hash );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 bool bChanged = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 if ( ! rec.m_comment.equals( strComment ) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 rec.m_comment = strComment;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 record_set(indexID, hash, rec);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 bChanged = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 return bChanged;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 // Provider of our title formatting fields.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 class metadb_display_field_provider_impl : public metadb_display_field_provider_v2 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 t_uint32 get_field_count() override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 return 6;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 void get_field_name(t_uint32 index, pfc::string_base & out) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 PFC_ASSERT(index < get_field_count());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 switch(index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 case 0:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 out = "foo_sample_track_rating"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 case 1:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 out = "foo_sample_album_rating"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 case 2:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 out = "foo_sample_track_comment"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 case 3:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 out = "foo_sample_album_comment"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 case 4:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 out = "foo_sample_track_hash"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 case 5:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 out = "foo_sample_album_hash"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 PFC_ASSERT(!"Should never get here");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 bool process_field(t_uint32 index, metadb_handle* handle, titleformat_text_out* out) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 return process_field_v2(index, handle, handle->query_v2_(), out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 bool process_field_v2(t_uint32 index, metadb_handle * handle, metadb_v2::rec_t const& metarec, titleformat_text_out * out) override {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 PFC_ASSERT( index < get_field_count() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 const GUID whichID = ((index%2) == 1) ? guid_foo_sample_album_rating_index : guid_foo_sample_track_rating_index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 if (!metarec.info.is_valid()) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 record_t rec;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 const auto hash = clientByGUID(whichID)->transform(metarec.info->info(), handle->get_location());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 if ( index < 4 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 rec = record_get(whichID, hash);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 if ( index < 2 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 // rating
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 if (rec.m_rating == rating_invalid) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 out->write_int(titleformat_inputtypes::meta, rec.m_rating);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 } else if ( index < 4 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 // comment
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 if ( rec.m_comment.length() == 0 ) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 out->write( titleformat_inputtypes::meta, rec.m_comment.c_str() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 out->write(titleformat_inputtypes::meta, pfc::format_hex(hash,16) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 static service_factory_single_t<metadb_display_field_provider_impl> g_metadb_display_field_provider_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 static void cycleRating( const GUID & whichID, metadb_handle_list_cref tracks) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 const size_t count = tracks.get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 if (count == 0) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 auto client = clientByGUID(whichID);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 rating_t rating = rating_invalid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 // Sorted/dedup'd set of all hashes of p_data items.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 // pfc::avltree_t<> is pfc equivalent of std::set<>.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 // We go the avltree_t<> route because more than one track in p_data might produce the same hash value, see metadb_index_client_impl / strPinTo
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 pfc::avltree_t<metadb_index_hash> allHashes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 for (size_t w = 0; w < count; ++w) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 metadb_index_hash hash;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 if (client->hashHandle(tracks[w], hash)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 allHashes += hash;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 // Take original rating to increment from the first selected song
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 if (w == 0) rating = rating_get(whichID, hash);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 if (allHashes.get_count() == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 FB2K_console_formatter() << "[foo_sample rating] Could not hash any of the tracks due to unavailable metadata, bailing";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 // Now cycle the rating value
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 if (rating == rating_invalid) rating = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 else if (rating >= rating_max) rating = rating_invalid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 else ++rating;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 // Now set the new rating
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 pfc::list_t<metadb_index_hash> lstChanged; // Linear list of hashes that actually changed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 for (auto iter = allHashes.first(); iter.is_valid(); ++iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 const metadb_index_hash hash = *iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 if (rating_set(whichID, hash, rating) ) { // rating_set returns true if the value actually changed, false if old equals new and no change was made
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 lstChanged += hash;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 FB2K_console_formatter() << "[foo_sample rating] " << lstChanged.get_count() << " entries updated";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 if (lstChanged.get_count() > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 // This gracefully tells everyone about what just changed, in one pass regardless of how many items got altered
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 theAPI()->dispatch_refresh(whichID, lstChanged);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 static void cycleComment( const GUID & whichID, metadb_handle_list_cref tracks ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 const size_t count = tracks.get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 if (count == 0) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 auto client = clientByGUID(whichID);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 pfc::string8 comment;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 // Sorted/dedup'd set of all hashes of p_data items.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 // pfc::avltree_t<> is pfc equivalent of std::set<>.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 // We go the avltree_t<> route because more than one track in p_data might produce the same hash value, see metadb_index_client_impl / strPinTo
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 pfc::avltree_t<metadb_index_hash> allHashes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 for (size_t w = 0; w < count; ++w) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 metadb_index_hash hash;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 if (client->hashHandle(tracks[w], hash)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 allHashes += hash;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 // Take original rating to increment from the first selected song
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 if (w == 0) comment = record_get(whichID, hash).m_comment;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 if (allHashes.get_count() == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 FB2K_console_formatter() << "[foo_sample rating] Could not hash any of the tracks due to unavailable metadata, bailing";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 // Now cycle the comment value
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 if ( comment.equals("") ) comment = "foo";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 else if ( comment.equals("foo") ) comment = "bar";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 else comment = "";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 // Now apply the new comment
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 pfc::list_t<metadb_index_hash> lstChanged; // Linear list of hashes that actually changed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 for (auto iter = allHashes.first(); iter.is_valid(); ++iter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 const metadb_index_hash hash = *iter;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 if ( comment_set(whichID, hash, comment) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 lstChanged += hash;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 FB2K_console_formatter() << "[foo_sample rating] " << lstChanged.get_count() << " entries updated";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 if (lstChanged.get_count() > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 // This gracefully tells everyone about what just changed, in one pass regardless of how many items got altered
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 theAPI()->dispatch_refresh(whichID, lstChanged);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 class contextmenu_rating : public contextmenu_item_simple {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 GUID get_parent() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 return guid_foo_sample_contextmenu_group;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 unsigned get_num_items() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 return 4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 void get_item_name(unsigned p_index, pfc::string_base & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 PFC_ASSERT( p_index < get_num_items() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 switch(p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 case 0:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 p_out = "Cycle track rating"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 case 1:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 p_out = "Cycle album rating"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 case 2:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 p_out = "Cycle track comment"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 case 3:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 p_out = "Cycle album comment"; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 void context_command(unsigned p_index, metadb_handle_list_cref p_data, const GUID& p_caller) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 PFC_ASSERT( p_index < get_num_items() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 const GUID whichID = ((p_index%2) == 1) ? guid_foo_sample_album_rating_index : guid_foo_sample_track_rating_index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 if ( p_index < 2 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 // rating
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 cycleRating( whichID, p_data );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 cycleComment( whichID, p_data );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 GUID get_item_guid(unsigned p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 switch(p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 case 0: return guid_foo_sample_rating_contextmenu1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 case 1: return guid_foo_sample_rating_contextmenu2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 case 2: return guid_foo_sample_rating_contextmenu3;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 case 3: return guid_foo_sample_rating_contextmenu4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400 default: uBugCheck();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 bool get_item_description(unsigned p_index, pfc::string_base & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 PFC_ASSERT( p_index < get_num_items() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 switch( p_index ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 case 0:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 p_out = "Alters foo_sample's track rating on one or more selected tracks. Use %foo_sample_track_rating% to display the rating.";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 case 1:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 p_out = "Alters foo_sample's album rating on one or more selected tracks. Use %foo_sample_album_rating% to display the rating.";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 case 2:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 p_out = "Alters foo_sample's track comment on one or more selected tracks. Use %foo_sample_track_comment% to display the comment.";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 case 3:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 p_out = "Alters foo_sample's album comment on one or more selected tracks. Use %foo_sample_album_comment% to display the comment.";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 PFC_ASSERT(!"Should not get here");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 static contextmenu_item_factory_t< contextmenu_rating > g_contextmenu_rating;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 static pfc::string_formatter formatRatingDump(const GUID & whichID) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 auto api = theAPI();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 pfc::list_t<metadb_index_hash> hashes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 api->get_all_hashes(whichID, hashes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 pfc::string_formatter message;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 message << "The database contains " << hashes.get_count() << " hashes.\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 for( size_t hashWalk = 0; hashWalk < hashes.get_count(); ++ hashWalk ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 auto hash = hashes[hashWalk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 message << pfc::format_hex( hash, 8 ) << " : ";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436 auto rec = record_get(whichID, hash);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 if ( rec.m_rating == rating_invalid ) message << "no rating";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 else message << "rating " << rec.m_rating;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 if ( rec.m_comment.length() > 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 message << ", comment: " << rec.m_comment;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443 metadb_handle_list tracks;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 // Note that this returns only handles present in the media library
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 // Extra work is required if the user has no media library but only playlists,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 // have to walk the playlists and match hashes by yourself instead of calling this method
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 api->get_ML_handles(whichID, hash, tracks);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 if ( tracks.get_count() == 0 ) message << ", no matching tracks in Media Library\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454 message << ", " << tracks.get_count() << " matching track(s)\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 for( size_t w = 0; w < tracks.get_count(); ++ w ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 // pfc string formatter operator<< for metadb_handle prints the location
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 message << tracks[w] << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462 return message;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 class mainmenu_rating : public mainmenu_commands {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467 t_uint32 get_command_count() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468 return 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 GUID get_command(t_uint32 p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471 return guid_foo_sample_rating_mainmenu;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 void get_name(t_uint32 p_index, pfc::string_base & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474 PFC_ASSERT( p_index == 0 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 p_out = "Dump rating database";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 bool get_description(t_uint32 p_index, pfc::string_base & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 PFC_ASSERT(p_index == 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 p_out = "Shows a dump of the foo_sample rating database."; return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 GUID get_parent() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 return guid_foo_sample_mainmenu_group;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 void execute(t_uint32 p_index, service_ptr_t<service_base> p_callback) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 PFC_ASSERT( p_index == 0 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489 pfc::string_formatter dump;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 dump << "==== TRACK RATING DUMP ====\n" << formatRatingDump( guid_foo_sample_track_rating_index ) << "\n\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 dump << "==== ALBUM RATING DUMP ====\n" << formatRatingDump( guid_foo_sample_album_rating_index ) << "\n\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493 popup_message::g_show(dump, "foo_sample rating dump");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 } catch(std::exception const & e) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495 // should not really get here
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 popup_message::g_complain("Rating dump failed", e);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
498 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
499 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500 static service_factory_single_t<mainmenu_rating> g_mainmenu_rating;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 // This class provides our information for the properties dialog
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504 class track_property_provider_impl : public track_property_provider_v2 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506 void workThisIndex(GUID const & whichID, const char * whichName, double priorityBase, metadb_handle_list_cref p_tracks, track_property_callback & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507 auto client = clientByGUID( whichID );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
508 pfc::avltree_t<metadb_index_hash> hashes;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
509 const size_t trackCount = p_tracks.get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 for (size_t trackWalk = 0; trackWalk < trackCount; ++trackWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511 metadb_index_hash hash;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512 if (client->hashHandle(p_tracks[trackWalk], hash)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513 hashes += hash;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
515 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
516
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
517 pfc::string8 strAverage = "N/A", strMin = "N/A", strMax = "N/A";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
518 pfc::string8 strComment;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
519
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
520 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
521 size_t count = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
522 rating_t minval = rating_invalid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
523 rating_t maxval = rating_invalid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
524 uint64_t accum = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
525 bool bFirst = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
526 bool bVarComments = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
527 for (auto i = hashes.first(); i.is_valid(); ++i) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
528 auto rec = record_get(whichID, *i);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
529 auto r = rec.m_rating;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
530 if (r != rating_invalid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
531 ++count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
532 accum += r;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
533
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
534 if (minval == rating_invalid || minval > r) minval = r;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
535 if (maxval == rating_invalid || maxval < r) maxval = r;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
536 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
537
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
538
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
539 if ( bFirst ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
540 strComment = rec.m_comment;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
541 } else if ( ! bVarComments ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
542 if ( strComment != rec.m_comment ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
543 bVarComments = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
544 strComment = "<various>";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
545 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
546 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
547
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
548 bFirst = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
549 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
550
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
551
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
552 if (count > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
553 strMin = pfc::format_uint(minval);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
554 strMax = pfc::format_uint(maxval);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
555 strAverage = pfc::format_float((double)accum / (double)count, 0, 3);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
556 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
557 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
558
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
559 p_out.set_property(strPropertiesGroup, priorityBase + 0, PFC_string_formatter() << "Average " << whichName << " Rating", strAverage);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
560 p_out.set_property(strPropertiesGroup, priorityBase + 1, PFC_string_formatter() << "Minimum " << whichName << " Rating", strMin);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
561 p_out.set_property(strPropertiesGroup, priorityBase + 2, PFC_string_formatter() << "Maximum " << whichName << " Rating", strMax);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
562 if ( strComment.length() > 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
563 p_out.set_property(strPropertiesGroup, priorityBase + 3, PFC_string_formatter() << whichName << " Comment", strComment);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
564 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
565 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
566 void enumerate_properties(metadb_handle_list_cref p_tracks, track_property_callback & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
567 workThisIndex( guid_foo_sample_track_rating_index, "Track", 0, p_tracks, p_out );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
568 workThisIndex( guid_foo_sample_album_rating_index, "Album", 10, p_tracks, p_out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
569 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
570 void enumerate_properties_v2(metadb_handle_list_cref p_tracks, track_property_callback_v2 & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
571 if ( p_out.is_group_wanted( strPropertiesGroup ) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
572 enumerate_properties( p_tracks, p_out );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
573 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
574 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
575
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
576 bool is_our_tech_info(const char * p_name) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
577 // If we do stuff with tech infos read from the file itself (see file_info::info_* methods), signal whether this field belongs to us
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
578 // We don't do any of this, hence false
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
579 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
580 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
581
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
582 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
583
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
584
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
585 static service_factory_single_t<track_property_provider_impl> g_track_property_provider_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
586 }