summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilherme Lepsch <lepsch@expertisesolutions.com.br>2014-12-03 16:35:00 -0200
committerLarry <larry.olj@gmail.com>2014-12-08 13:40:33 -0200
commit0c367328ddd22971c1f19f9a8479db8163940d57 (patch)
tree78437aa557521ea6e7058b80381728fe9b9323df
parent5657f68366c44fd96d8e0a9c8581f4f4d5805315 (diff)
* Scanning media files working;
* POC: Populating database is working, but must do a ruge refactoring, toug
-rw-r--r--src/audiolistmodel.cc352
-rw-r--r--src/audiolistmodel.hh34
-rw-r--r--src/emc.cc27
-rw-r--r--src/file_scanner.cc45
-rw-r--r--src/file_scanner.hh15
-rw-r--r--src/settingsctrl.hh5
6 files changed, 452 insertions, 26 deletions
diff --git a/src/audiolistmodel.cc b/src/audiolistmodel.cc
index 6ff5aea..8bf775f 100644
--- a/src/audiolistmodel.cc
+++ b/src/audiolistmodel.cc
@@ -5,10 +5,49 @@
5 5
6#include "audiolistmodel.hh" 6#include "audiolistmodel.hh"
7 7
8#include <functional>
9#include <utility>
10
8#include <eina_accessor.hh> 11#include <eina_accessor.hh>
9 12
10#include "database_schema.hh" 13#include "database_schema.hh"
11 14
15namespace {
16 template<typename T, typename... Args>
17 std::unique_ptr<T> make_unique(Args&&... args)
18 {
19 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
20 }
21
22 template<class T>
23 bool get_property(const ::emodel &model, const std::string &property, T &value)
24 {
25 ::efl::eina::value property_value;
26 if (!model.property_get(property, property_value.native_handle()))
27 {
28 std::cout << "Error trying to get " << property << " property" << std::endl;
29 return false;
30 }
31
32 value = ::efl::eina::get<T>(property_value);
33 return true;
34 }
35
36 template<>
37 bool get_property<int64_t>(const ::emodel &model, const std::string &property, int64_t &value)
38 {
39 ::efl::eina::value property_value;
40 if (!model.property_get(property, property_value.native_handle()))
41 {
42 std::cout << "Error trying to get " << property << " property" << std::endl;
43 return false;
44 }
45
46 eina_value_get(property_value.native_handle(), &value);
47 return true;
48 }
49}
50
12namespace emc { 51namespace emc {
13 52
14audiolistmodel::audiolistmodel() 53audiolistmodel::audiolistmodel()
@@ -17,7 +56,10 @@ audiolistmodel::audiolistmodel()
17 albums(nullptr), 56 albums(nullptr),
18 tracks(nullptr), 57 tracks(nullptr),
19 init_connection(nullptr), 58 init_connection(nullptr),
20 db_table_created_connection(nullptr) 59 db_table_created_connection(nullptr),
60 scanner(std::bind(&audiolistmodel::media_file_add_cb, this, std::placeholders::_1)),
61 maps_ready(false),
62 processing_tag(false)
21{ 63{
22 // TODO: Configure database path to user data 64 // TODO: Configure database path to user data
23 database = esql::model(database.esql_model_constructor("./emc.db", "", "", "")); 65 database = esql::model(database.esql_model_constructor("./emc.db", "", "", ""));
@@ -104,7 +146,7 @@ audiolistmodel::load_tables()
104 std::cout << "Starting file scanner..." << std::endl; 146 std::cout << "Starting file scanner..." << std::endl;
105 scanner.start(); 147 scanner.start();
106 148
107 // TODO: Check new/old files and tracks against db/filesystem 149 populate_maps();
108 150
109 return false; 151 return false;
110} 152}
@@ -186,4 +228,310 @@ audiolistmodel::album_tracks_get(esql::model_row& album)
186 return tracks; 228 return tracks;
187} 229}
188 230
231void
232audiolistmodel::media_file_add_cb(const tag &tag)
233{
234 using namespace std;
235 cout << "file - \"" << tag.file << "\"" << endl;
236 //cout << "title - \"" << tag.title << "\"" << endl;
237 //cout << "artist - \"" << tag.artist << "\"" << endl;
238 //cout << "album - \"" << tag.album << "\"" << endl;
239 //cout << "year - \"" << tag.year << "\"" << endl;
240 //cout << "track - \"" << tag.track << "\"" << endl;
241 //cout << "genre - \"" << tag.genre << "\"" << endl;
242
243 pending_tags.push(tag);
244
245 if (maps_ready)
246 process_pending_tags();
247}
248
249void
250audiolistmodel::populate_maps()
251{
252 populate_map(artists, "name", artist_map);
253 populate_map(albums, "name", album_map);
254 populate_map(tracks, "file", track_map);
255
256 maps_ready = true;
257 process_pending_tags();
258}
259
260void
261audiolistmodel::populate_map(const esql::model_table &table, const std::string &key, std::unordered_map<std::string, esql::model_row> &map)
262{
263 std::cout << "Populating map..." << std::endl;
264 Eina_Accessor *_ac = nullptr;
265 table.children_slice_get(0, 0, &_ac);
266 if (nullptr == _ac) return;
267
268 // FIXME: Use EINA-CXX
269 Eo *child;
270 unsigned int i = 0;
271 EINA_ACCESSOR_FOREACH(_ac, i, child)
272 {
273 esql::model_row row(::eo_ref(child));
274
275 std::string value;
276 if (!get_property(table, key, value)) continue;
277 map.insert(std::make_pair(value, row));
278 }
279}
280
281void
282audiolistmodel::process_pending_tags()
283{
284 if (processing_tag)
285 return;
286
287 std::cout << "Processing " << pending_tags.size() << " pending tags..." << std::endl;
288 while (!processing_tag && !pending_tags.empty())
289 {
290 tag tag = pending_tags.front();
291 pending_tags.pop();
292 processing_tag = process_tag(tag);
293 }
294}
295
296bool
297audiolistmodel::process_tag(const tag &tag)
298{
299 std::cout << "Processing tag..." << std::endl;
300 return check_artist(tag) || check_album(tag) || check_track(tag);
301}
302
303bool
304audiolistmodel::check_artist(const tag &tag)
305{
306 std::cout << "Checking artist: " << tag.artist << std::endl;
307 if (tag.artist.empty())
308 return false;
309
310 auto it = artist_map.find(tag.artist);
311 if (end(artist_map) != it)
312 {
313 std::cout << "Artist found: " << tag.artist << std::endl;
314 return false;
315 }
316
317 std::cout << "Artist not found, creating artist and postponing album and track: " << tag.artist << std::endl;
318 // create artist and postopone album/track
319 auto obj = artists.child_add();
320 esql::model_row row(::eo_ref(obj._eo_ptr()));
321 auto connection = std::make_shared<::efl::eo::signal_connection>(nullptr);
322 *connection = row.callback_load_status_add(std::bind(&audiolistmodel::new_artist_row_properties_loaded, this, connection, tag, row, std::placeholders::_3));
323 row.properties_load();
324 return true;
325}
326
327bool
328audiolistmodel::new_artist_row_properties_loaded(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void *info)
329{
330 const Emodel_Load &st = *static_cast<Emodel_Load*>(info);
331 if (st.status & EMODEL_LOAD_STATUS_ERROR)
332 {
333 connection->disconnect();
334 std::cout << "Error loading new artist row properties: " << tag.artist << std::endl;
335 return false;
336 }
337
338 if(!(st.status & EMODEL_LOAD_STATUS_LOADED_PROPERTIES))
339 return true;
340
341 connection->disconnect();
342
343 std::cout << "New artist ready to set values: " << tag.artist << std::endl;
344 // TODO: Error callback
345 auto new_connection = std::make_shared<::efl::eo::signal_connection>(nullptr);
346 *new_connection = row.callback_properties_changed_add(std::bind(&audiolistmodel::artist_row_inserted, this, new_connection, tag, row, std::placeholders::_3));
347 ::efl::eina::value name(tag.artist);
348 row.property_set("name", *name.native_handle());
349 return false;
350}
351
352bool
353audiolistmodel::artist_row_inserted(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void *info)
354{
355 std::cout << "New artist values have been set: " << tag.artist << std::endl;
356 connection->disconnect();
357
358 artist_map.insert(std::make_pair(tag.artist, row));
359
360 processing_tag = check_album(tag) || check_track(tag);
361 process_pending_tags();
362 return false;
363}
364
365bool
366audiolistmodel::check_album(const tag &tag)
367{
368 std::cout << "Checking album: " << tag.album << std::endl;
369 if (tag.album.empty())
370 return false;
371
372 auto it = album_map.find(tag.album);
373 if (end(album_map) != it)
374 {
375 std::cout << "Album found: " << tag.album << std::endl;
376 return false;
377 }
378
379 std::cout << "Album not found, creating album and postponing track: " << tag.album << std::endl;
380 // create album and postopone album/track
381 auto obj = albums.child_add();
382 esql::model_row row(::eo_ref(obj._eo_ptr()));
383 auto connection = std::make_shared<::efl::eo::signal_connection>(nullptr);
384 *connection = row.callback_load_status_add(std::bind(&audiolistmodel::new_album_row_properties_loaded, this, connection, tag, row, std::placeholders::_3));
385 row.properties_load();
386 return true;
387}
388
389bool
390audiolistmodel::new_album_row_properties_loaded(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void *info)
391{
392 const Emodel_Load &st = *static_cast<Emodel_Load*>(info);
393
394 if (st.status & EMODEL_LOAD_STATUS_ERROR)
395 {
396 connection->disconnect();
397 std::cout << "Error loading new album row properties: " << tag.album << std::endl;
398 return false;
399 }
400
401 if(!(st.status & EMODEL_LOAD_STATUS_LOADED_PROPERTIES))
402 return true;
403
404 connection->disconnect();
405
406 int64_t id_artist = 0;
407 auto it = artist_map.find(tag.artist);
408 if (end(artist_map) != it)
409 {
410 std::cout << "Getting artist id for: " << tag.artist << std::endl;
411 get_property(it->second, "id", id_artist);
412 std::cout << "Artist id=" << id_artist << std::endl;
413 }
414
415 std::cout << "New album ready to set values: " << tag.album << std::endl;
416 auto new_connection = std::make_shared<::efl::eo::signal_connection>(nullptr);
417 *new_connection = row.callback_properties_changed_add(std::bind(&audiolistmodel::album_row_inserted, this, new_connection, tag, row, std::placeholders::_3));
418 ::efl::eina::value name(tag.album);
419 row.property_set("name", *name.native_handle());
420 if (id_artist > 0)
421 {
422 ::efl::eina::value artist(id_artist);
423 row.property_set("id_artist", *artist.native_handle());
424 }
425 ::efl::eina::value genre(tag.genre);
426 row.property_set("genre", *genre.native_handle());
427 ::efl::eina::value year(tag.year);
428 row.property_set("year", *year.native_handle());
429 return false;
430}
431
432bool
433audiolistmodel::album_row_inserted(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void *info)
434{
435 std::cout << "New album values have been set: " << tag.album << std::endl;
436 connection->disconnect();
437
438 album_map.insert(std::make_pair(tag.album, row));
439
440 processing_tag = check_track(tag);
441 process_pending_tags();
442 return false;
443}
444
445bool
446audiolistmodel::check_track(const tag &tag)
447{
448 std::cout << "Checking track: " << tag.file << std::endl;
449 if (tag.file.empty())
450 return false;
451
452 auto it = track_map.find(tag.file);
453 if (end(track_map) != it)
454 {
455 std::cout << "track found: " << tag.file << std::endl;
456 return false;
457 }
458
459 std::cout << "track not found, creating track: " << tag.file << std::endl;
460 // create track
461 auto obj = tracks.child_add();
462 esql::model_row row(::eo_ref(obj._eo_ptr()));
463 auto connection = std::make_shared<::efl::eo::signal_connection>(nullptr);
464 *connection = row.callback_load_status_add(std::bind(&audiolistmodel::new_track_row_properties_loaded, this, connection, tag, row, std::placeholders::_3));
465 row.properties_load();
466 return true;
467}
468
469bool
470audiolistmodel::new_track_row_properties_loaded(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void *info)
471{
472 const Emodel_Load &st = *static_cast<Emodel_Load*>(info);
473
474 if (st.status & EMODEL_LOAD_STATUS_ERROR)
475 {
476 connection->disconnect();
477 std::cout << "Error loading new track row properties: " << tag.file << std::endl;
478 return false;
479 }
480
481 if(!(st.status & EMODEL_LOAD_STATUS_LOADED_PROPERTIES))
482 return true;
483
484 connection->disconnect();
485
486 int64_t id_artist = -1;
487 auto artist_it = artist_map.find(tag.artist);
488 if (end(artist_map) != artist_it)
489 {
490 std::cout << "Getting artist id for: " << tag.artist << std::endl;
491 get_property(artist_it->second, "id", id_artist);
492 std::cout << "Artist id=" << id_artist << std::endl;
493 }
494 int64_t id_album = -1;
495 auto album_it = album_map.find(tag.album);
496 if (end(album_map) != album_it)
497 {
498 std::cout << "Getting album id for: " << tag.album << std::endl;
499 get_property(album_it->second, "id", id_album);
500 std::cout << "Album id=" << id_artist << std::endl;
501 }
502
503 std::cout << "New track ready to set values: " << tag.file << std::endl;
504 auto new_connection = std::make_shared<::efl::eo::signal_connection>(nullptr);
505 *new_connection = row.callback_properties_changed_add(std::bind(&audiolistmodel::track_row_inserted, this, new_connection, tag, row, std::placeholders::_3));
506 ::efl::eina::value file(tag.file);
507 row.property_set("file", *file.native_handle());
508 if (id_artist != -1)
509 {
510 ::efl::eina::value artist(id_artist);
511 row.property_set("id_artist", *artist.native_handle());
512 }
513 if (id_album != -1)
514 {
515 ::efl::eina::value album(id_album);
516 row.property_set("id_album", *album.native_handle());
517 }
518 ::efl::eina::value name(tag.title);
519 row.property_set("name", *name.native_handle());
520 //row.property_set("track", *track.native_handle());
521 return false;
522}
523
524bool
525audiolistmodel::track_row_inserted(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void *info)
526{
527 std::cout << "New track values have been set: " << tag.file << std::endl;
528 connection->disconnect();
529
530 track_map.insert(std::make_pair(tag.file, row));
531 processing_tag = false;
532 process_pending_tags();
533 return false;
534}
535
536
189} //emc 537} //emc
diff --git a/src/audiolistmodel.hh b/src/audiolistmodel.hh
index 1fcba24..56085cc 100644
--- a/src/audiolistmodel.hh
+++ b/src/audiolistmodel.hh
@@ -1,7 +1,12 @@
1#ifndef _AUDIOLIST_MODEL_HH 1 #ifndef _AUDIOLIST_MODEL_HH
2#define _AUDIOLIST_MODEL_HH 2#define _AUDIOLIST_MODEL_HH
3 3
4#include <iostream> 4#include <iostream>
5#include <memory>
6#include <queue>
7#include <unordered_map>
8#include <vector>
9
5#include <eo_event.hh> 10#include <eo_event.hh>
6#include <Emodel.h> 11#include <Emodel.h>
7#include <Emodel.hh> 12#include <Emodel.hh>
@@ -17,6 +22,8 @@ extern "C"
17 22
18namespace emc { 23namespace emc {
19 24
25class tag;
26
20class audiolistmodel 27class audiolistmodel
21{ 28{
22 std::string video_dir; 29 std::string video_dir;
@@ -30,9 +37,34 @@ class audiolistmodel
30 ::efl::eo::signal_connection init_connection; 37 ::efl::eo::signal_connection init_connection;
31 ::efl::eo::signal_connection db_table_created_connection; 38 ::efl::eo::signal_connection db_table_created_connection;
32 39
40 std::queue<tag> pending_tags;
41
42 bool maps_ready;
43 bool processing_tag;
44 std::unordered_map<std::string, esql::model_row> track_map;
45 std::unordered_map<std::string, esql::model_row> artist_map;
46 std::unordered_map<std::string, esql::model_row> album_map;
47
33 bool init(void * info); 48 bool init(void * info);
34 bool db_table_created(void * info); 49 bool db_table_created(void * info);
35 bool load_tables(); 50 bool load_tables();
51 void media_file_add_cb(const tag &tag);
52 void populate_maps();
53 void populate_map(const esql::model_table &table, const std::string &key, std::unordered_map<std::string, esql::model_row> &map);
54 void process_pending_tags();
55 bool process_tag(const tag &tag);
56
57 bool check_artist(const tag &tag);
58 bool new_artist_row_properties_loaded(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void * info);
59 bool artist_row_inserted(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void * info);
60
61 bool check_album(const tag &tag);
62 bool new_album_row_properties_loaded(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void * info);
63 bool album_row_inserted(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void * info);
64
65 bool check_track(const tag &tag);
66 bool new_track_row_properties_loaded(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void * info);
67 bool track_row_inserted(std::shared_ptr<::efl::eo::signal_connection> connection, tag tag, esql::model_row row, void * info);
36 68
37 public: 69 public:
38 audiolistmodel(); 70 audiolistmodel();
diff --git a/src/emc.cc b/src/emc.cc
index 318ed73..7cc07c8 100644
--- a/src/emc.cc
+++ b/src/emc.cc
@@ -33,19 +33,20 @@ elm_main(int argc, char **argv)
33 return EXIT_FAILURE; 33 return EXIT_FAILURE;
34 } 34 }
35 35
36 { 36 //eina_log_domain_level_set("esskyuehl", EINA_LOG_LEVEL_DBG);
37 ::elm_win win(elm_win_util_standard_add("emc-window","Enlightenment Media Center - EMC")); 37 eina_log_domain_level_set("esql_model", EINA_LOG_LEVEL_DBG);
38 ::elm_layout layout(efl::eo::parent = win); 38
39 win.callback_delete_request_add(std::bind([]{elm_exit();})); 39 ::elm_win win(elm_win_util_standard_add("emc-window","Enlightenment Media Center - EMC"));
40 40 //win.autodel_set(true);
41 emc::settingsmodel settings(win, layout); 41 ::elm_layout layout(efl::eo::parent = win);
42 emc::mainctrl mctrl(settings); 42 win.callback_delete_request_add(std::bind([]{elm_exit();}));
43 mctrl.active(); 43
44 44 emc::settingsmodel settings(win, layout);
45 elm_run(); 45 emc::mainctrl mctrl(settings);
46 win._release(); 46 mctrl.active();
47 } 47
48 elm_shutdown(); 48 elm_run();
49 win._release();
49 50
50 return EXIT_SUCCESS; 51 return EXIT_SUCCESS;
51} 52}
diff --git a/src/file_scanner.cc b/src/file_scanner.cc
index 5fcc914..39e3d6e 100644
--- a/src/file_scanner.cc
+++ b/src/file_scanner.cc
@@ -32,7 +32,8 @@ namespace {
32 32
33namespace emc { 33namespace emc {
34 34
35file_scanner::file_scanner() 35file_scanner::file_scanner(std::function<void(const tag&)> media_file_add_cb)
36 : media_file_add_cb(media_file_add_cb)
36{} 37{}
37 38
38file_scanner::~file_scanner() 39file_scanner::~file_scanner()
@@ -61,6 +62,7 @@ std::vector<std::string> file_scanner::get_configured_paths() const
61 62
62void file_scanner::scan_path(const std::string &path) 63void file_scanner::scan_path(const std::string &path)
63{ 64{
65 //return;
64 std::cout << "Scanning path: " << path << std::endl; 66 std::cout << "Scanning path: " << path << std::endl;
65 std::unique_ptr<eio::model> file_model(new eio::model()); 67 std::unique_ptr<eio::model> file_model(new eio::model());
66 file_model->path_set(path); 68 file_model->path_set(path);
@@ -70,8 +72,13 @@ void file_scanner::scan_path(const std::string &path)
70 files.push_back(move(file_model)); 72 files.push_back(move(file_model));
71} 73}
72 74
75static int count = -1;
76const auto MAX_COUNT = 20;
77
73bool file_scanner::file_found(eio::model &file_model, void *info) 78bool file_scanner::file_found(eio::model &file_model, void *info)
74{ 79{
80 if (count > MAX_COUNT) return true;
81
75 auto item_count = *static_cast<unsigned int*>(info); 82 auto item_count = *static_cast<unsigned int*>(info);
76 std::cout << "Number of items found: " << item_count << std::endl; 83 std::cout << "Number of items found: " << item_count << std::endl;
77 if (0 == item_count) 84 if (0 == item_count)
@@ -96,6 +103,8 @@ bool file_scanner::file_found(eio::model &file_model, void *info)
96 103
97bool file_scanner::file_status(eio::model &file, void *info) 104bool file_scanner::file_status(eio::model &file, void *info)
98{ 105{
106 if (count > MAX_COUNT) return false;
107
99 const auto load = *static_cast<Emodel_Load*>(info); 108 const auto load = *static_cast<Emodel_Load*>(info);
100 if (!(EMODEL_LOAD_STATUS_LOADED_PROPERTIES & load.status)) 109 if (!(EMODEL_LOAD_STATUS_LOADED_PROPERTIES & load.status))
101 return true; 110 return true;
@@ -123,21 +132,39 @@ bool file_scanner::file_status(eio::model &file, void *info)
123 132
124void file_scanner::check_media_file(const std::string &path) 133void file_scanner::check_media_file(const std::string &path)
125{ 134{
135 // TODO: Read file tag in background
136
126 std::cout << "Checking if filename is a recognized media type: " << path << std::endl; 137 std::cout << "Checking if filename is a recognized media type: " << path << std::endl;
127 138
128 TagLib::FileRef file(path.c_str()); 139 TagLib::FileRef file(path.c_str());
129 if (file.isNull() || !file.tag()) 140 if (file.isNull() || !file.tag())
130 return; 141 return;
131 142
132 using namespace std; 143 if (count == -1)
144 count = 0;
145 else
146 ++count;
147
133 TagLib::Tag *tag = file.tag(); 148 TagLib::Tag *tag = file.tag();
134 cout << "title - \"" << tag->title() << "\"" << endl; 149
135 cout << "artist - \"" << tag->artist() << "\"" << endl; 150 auto to_string = [](const TagLib::String &str) -> std::string
136 cout << "album - \"" << tag->album() << "\"" << endl; 151 {
137 cout << "year - \"" << tag->year() << "\"" << endl; 152 if (str == TagLib::String::null)
138 cout << "comment - \"" << tag->comment() << "\"" << endl; 153 return "";
139 cout << "track - \"" << tag->track() << "\"" << endl; 154
140 cout << "genre - \"" << tag->genre() << "\"" << endl; 155 const auto UNICODE = true;
156 return str.to8Bit(UNICODE);
157 };
158
159 ::emc::tag new_tag;
160 new_tag.file = path;
161 new_tag.title = to_string(tag->title());
162 new_tag.track = tag->track();
163 new_tag.artist = to_string(tag->artist());
164 new_tag.album = to_string(tag->album());
165 new_tag.genre = to_string(tag->genre());
166 new_tag.year = tag->year();
167 media_file_add_cb(new_tag);
141} 168}
142 169
143} 170}
diff --git a/src/file_scanner.hh b/src/file_scanner.hh
index ec51baa..0c5f473 100644
--- a/src/file_scanner.hh
+++ b/src/file_scanner.hh
@@ -6,6 +6,7 @@
6#include <Emodel.hh> 6#include <Emodel.hh>
7#include <eio_model.eo.hh> 7#include <eio_model.eo.hh>
8 8
9#include <functional>
9#include <memory> 10#include <memory>
10#include <string> 11#include <string>
11#include <vector> 12#include <vector>
@@ -14,10 +15,21 @@ namespace emc {
14 15
15class settingsmodel; 16class settingsmodel;
16 17
18struct tag
19{
20 std::string file;
21 std::string title;
22 int track;
23 std::string artist;
24 std::string album;
25 std::string genre;
26 int year;
27};
28
17class file_scanner 29class file_scanner
18{ 30{
19public: 31public:
20 file_scanner(); 32 file_scanner(std::function<void(const tag&)> media_file_add_cb);
21 ~file_scanner(); 33 ~file_scanner();
22 34
23 void start(); 35 void start();
@@ -31,6 +43,7 @@ private:
31 43
32private: 44private:
33 std::vector<std::unique_ptr<eio::model>> files; 45 std::vector<std::unique_ptr<eio::model>> files;
46 std::function<void(const tag&)> media_file_add_cb;
34}; 47};
35 48
36} 49}
diff --git a/src/settingsctrl.hh b/src/settingsctrl.hh
index 75e1994..717127e 100644
--- a/src/settingsctrl.hh
+++ b/src/settingsctrl.hh
@@ -2,6 +2,11 @@
2#define _SETTINGS_CTRL_HH 2#define _SETTINGS_CTRL_HH
3 3
4#include <iostream> 4#include <iostream>
5
6extern "C"
7{
8#include "elm_interface_atspi_text.h"
9}
5#include <Elementary.h> 10#include <Elementary.h>
6 11
7#include "basectrl.hh" 12#include "basectrl.hh"