Ticket #341: dbupdate5.patch
File dbupdate5.patch, 34.3 KB (added by , 19 years ago) |
---|
-
mythtv/libs/libmyth/lcddevice.cpp
191 191 #endif 192 192 // Just stream the text out the socket 193 193 194 os << someText << "\n" ;194 os << someText << "\n" << flush; 195 195 } 196 196 else 197 197 { … … 376 376 sendToServer("SET_CHANNEL_PROGRESS " + QString().setNum(value)); 377 377 } 378 378 379 void LCD::setGenericProgress( float value)379 void LCD::setGenericProgress(bool busy, float value) 380 380 { 381 381 if (!lcd_ready || !lcd_showgeneric) 382 382 return; … … 386 386 else if (value > 1.0) 387 387 value = 1.0; 388 388 389 sendToServer("SET_GENERIC_PROGRESS " + QString().setNum(value)); 389 sendToServer("SET_GENERIC_PROGRESS " + QString().setNum (busy) + 390 " " + QString().setNum(value)); 390 391 } 391 392 392 393 void LCD::setMusicProgress(QString time, float value) -
mythtv/libs/libmyth/mythdialogs.cpp
1558 1558 1559 1559 void MythProgressDialog::setProgress(int curprogress) 1560 1560 { 1561 progress->setProgress(curprogress); 1562 if (curprogress % steps == 0) 1563 { 1564 qApp->processEvents(); 1561 if (m_totalSteps <= 0) { 1562 progress->setProgress (progress->progress () + 1); 1565 1563 if (LCD * lcddev = LCD::Get()) 1566 1564 { 1567 float fProgress = (float)curprogress / m_totalSteps; 1568 lcddev->setGenericProgress(fProgress); 1565 lcddev->setGenericProgress(true, 0.0); 1569 1566 } 1567 } else { 1568 progress->setProgress(curprogress); 1569 if (curprogress % steps == 0) 1570 { 1571 qApp->processEvents(); 1572 if (LCD * lcddev = LCD::Get()) 1573 { 1574 float fProgress = (float)curprogress / m_totalSteps; 1575 lcddev->setGenericProgress(false, fProgress); 1576 } 1577 } 1570 1578 } 1571 1579 } 1572 1580 … … 1588 1596 MythDialog::keyPressEvent(e); 1589 1597 } 1590 1598 1599 MythBusyIndicator::MythBusyIndicator (const QString &title, bool autonomous) { 1600 done = false; 1601 progress = new MythProgressDialog (title); 1602 if (autonomous) { 1603 start (); 1604 } 1605 } 1606 1607 MythBusyIndicator::~MythBusyIndicator () { 1608 Close (); 1609 delete progress; 1610 } 1611 1612 void 1613 MythBusyIndicator::Close () { 1614 if (!done) { 1615 done = true; 1616 wait (); 1617 } 1618 } 1619 1620 void 1621 MythBusyIndicator::run () { 1622 sleep (1); 1623 while (!done) { 1624 progress->setProgress (); 1625 msleep (300); 1626 } 1627 progress->Close (); 1628 } 1629 1591 1630 MythThemedDialog::MythThemedDialog(MythMainWindow *parent, QString window_name, 1592 1631 QString theme_filename, const char* name, 1593 1632 bool setsize) -
mythtv/libs/libmyth/lcddevice.h
147 147 // define the screen, row, and alignment of the text 148 148 void switchToGeneric(QPtrList<LCDTextItem> *textItems); 149 149 150 // Do a progress bar with the generic level between 0 and 1.0 151 void setGenericProgress(float generic_progress); 150 /** Update the generic progress bar. 151 @param busy if true, display a busy indicator instead of progress bar 152 @param generic_progress a value between 0 and 1.0 153 */ 154 void setGenericProgress(bool busy, float generic_progress); 152 155 153 156 // Do a music progress bar with the generic level between 0 and 1.0 154 157 void setMusicProgress(QString time, float generic_progress); -
mythtv/libs/libmyth/mythdialogs.h
11 11 #include <qevent.h> 12 12 #include <qvaluevector.h> 13 13 #include <qscrollview.h> 14 #include <qthread.h> 14 15 15 16 #include <vector> 16 17 using namespace std; … … 229 230 bool arrowAccel; 230 231 }; 231 232 233 /** The MythTV progress bar dialog. 234 235 This dialog is responsible for displaying a progress bar box on 236 the screen. It can display either a progressive progress bar or a 237 spinner busy indicator, depending on the totalSteps value passed 238 to the constructor. 239 240 If created as a busy indicator, calls to setProgress ignore the 241 value passed, and simply 'spin' the indicator. 242 243 The dialog widget also updates the LCD display if present. 244 245 */ 232 246 class MythProgressDialog: public MythDialog 233 247 { 234 248 public: 235 MythProgressDialog(const QString& message, int totalSteps); 249 /** Create a progress bar dialog. 250 251 @param message the title string to appear in the progress dialog. 252 @param totalSteps the total number of steps, default value is -1 for busy indicator. 253 */ 254 MythProgressDialog(const QString& message, int totalSteps = 0); 236 255 237 256 void Close(void); 238 void setProgress(int curprogress );257 void setProgress(int curprogress = 0); 239 258 void keyPressEvent(QKeyEvent *); 240 259 241 260 private: … … 247 266 int m_totalSteps; 248 267 }; 249 268 269 /** The MythTV busy indicator 270 271 @note This is not a MythDialog widget, but a thread object that 272 displays a @p MythProgressDialog until it's closed or destroyed. 273 274 This thread will wait for 1 second, and if it hasn't been asked to 275 stop (or destroyed), it will start displaying a `busy spinner' 276 style @p MythProgressDialog. 277 278 If objects constructor/destroctor are responsible for 279 starting/stopping the thread handling the spinner, a call to 280 stop() can be called to end the spinner. 281 */ 282 class MythBusyIndicator : public QThread { 283 public: 284 /** Create the busy indicator. 285 @param title the title to appear in the progress bar dialog. 286 @param autonomous if true, whether a instance manages threads itself 287 */ 288 MythBusyIndicator (const QString &title, bool autonomous=true); 289 ~MythBusyIndicator (); 290 291 /** Close the dialog. 292 This will also stop the thread and wait for it to finish. 293 */ 294 void Close (); 295 virtual void run (); 296 private: 297 bool done; 298 MythProgressDialog *progress; 299 }; 300 250 301 class MythThemedDialog : public MythDialog 251 302 { 252 303 Q_OBJECT -
mythtv/programs/mythlcdserver/lcdprocclient.cpp
959 959 void LCDProcClient::startMusic(QString artist, QString album, QString track) 960 960 { 961 961 QString aString; 962 music_progress = 0.0; 962 963 if (lcd_showmusic) 963 964 setPriority("Music", HIGH); 964 965 aString = artist; … … 1016 1017 QString aString; 1017 1018 1018 1019 if (lcd_showgeneric) 1019 setPriority("Generic", HIGH);1020 setPriority("Generic", TOP); 1020 1021 1021 1022 // Clear out the LCD. Do this before checking if its empty incase the user 1022 1023 // wants to just clear the lcd … … 1029 1030 return; 1030 1031 1031 1032 activeScreen = "Generic"; 1033 1034 busy_progress = false; 1035 busy_pos = 1; 1036 busy_direction = 1; 1037 busy_indicator_size = 2.0; 1032 1038 generic_progress = 0.0; 1033 1039 1034 1040 // Return if there are no more items … … 1505 1511 outputChannel(); 1506 1512 } 1507 1513 1508 void LCDProcClient::setGenericProgress( float value)1514 void LCDProcClient::setGenericProgress(bool b, float value) 1509 1515 { 1510 1516 if (!lcd_ready) 1511 1517 return; … … 1517 1523 else if (generic_progress > 1.0) 1518 1524 generic_progress = 1.0; 1519 1525 1526 // Note, this will let us switch to/from busy indicator by alternating between 1527 // being passed true or false for b. 1528 busy_progress = b; 1529 if (busy_progress) { 1530 // If we're at either end of the line, switch direction 1531 if (busy_pos + busy_direction > (signed int)lcdWidth - busy_indicator_size || 1532 busy_pos + busy_direction < 1) { 1533 busy_direction = -busy_direction; 1534 } 1535 busy_pos += busy_direction; 1536 generic_progress = busy_indicator_size / (float)lcdWidth; 1537 } else { 1538 busy_pos = 1; 1539 } 1540 1520 1541 outputGeneric(); 1521 1542 } 1522 1543 … … 1794 1815 void LCDProcClient::outputGeneric() 1795 1816 { 1796 1817 QString aString; 1797 aString = "widget_set Generic progressBar 1 "; 1818 aString = "widget_set Generic progressBar "; 1819 aString += QString::number (busy_pos); 1820 aString += " "; 1798 1821 aString += QString::number(lcdHeight); 1799 1822 aString += " "; 1800 1823 aString += QString::number((int)rint(generic_progress * lcdWidth * … … 2003 2026 "- is the master server running?\n\t\t\t" 2004 2027 "Will retry in 30 seconds"); 2005 2028 QTimer::singleShot(30 * 1000, this, SLOT(updateRecordingList())); 2006 switchToTime(); 2029 2030 // If we can't get the recording status and we're showing 2031 // it, switch back to time. Maybe it would be even better 2032 // to show that the backend is unreachable ? 2033 if (activeScreen == "RecStatus") 2034 switchToTime(); 2007 2035 return; 2008 2036 } 2009 2037 } -
mythtv/programs/mythlcdserver/lcdserver.cpp
577 577 578 578 QString flat = tokens.join(" "); 579 579 580 if (tokens.count() != 2)580 if (tokens.count() != 3) 581 581 { 582 582 VERBOSE(VB_IMPORTANT, "LCDServer: bad SET_GENERIC_PROGRESS command: " 583 583 << flat); … … 586 586 } 587 587 588 588 bool bOK; 589 float progress = tokens[1].toFloat(&bOK);589 bool busy = tokens[1].toInt (&bOK); 590 590 if (!bOK) 591 591 { 592 VERBOSE(VB_IMPORTANT, "LCDServer: bad bool value in " 593 "SET_GENERIC_PROGRESS command: %1 %2" << tokens[1] << tokens[2]); 594 sendMessage(socket, "HUH?"); 595 return; 596 } 597 float progress = tokens[2].toFloat(&bOK); 598 if (!bOK) 599 { 592 600 VERBOSE(VB_IMPORTANT, "LCDServer: bad float value in " 593 601 "SET_GENERIC_PROGRESS command: %1" << tokens[1]); 594 602 sendMessage(socket, "HUH?"); … … 596 604 } 597 605 598 606 if (m_lcd) 599 m_lcd->setGenericProgress( progress);607 m_lcd->setGenericProgress(busy, progress); 600 608 601 609 sendMessage(socket, "OK"); 602 610 } -
mythtv/programs/mythlcdserver/lcdprocclient.h
49 49 bool popMenu = true); 50 50 51 51 void switchToGeneric(QPtrList<LCDTextItem> *textItems); 52 void setGenericProgress( float generic_progress);52 void setGenericProgress(bool busy, float generic_progress); 53 53 54 54 void switchToVolume(QString app_name); 55 55 void setVolumeLevel(float volume_level); … … 162 162 163 163 float EQlevels[10]; 164 164 float progress; 165 /** TRUE if the generic progress indicator is a busy (ie. doesn't have a known total steps */ 166 bool busy_progress; 167 /** Current position of the busy indicator, used if @p busy_progress is true. */ 168 int busy_pos; 169 /** How many "blocks" the busy indicator must be, used if @p busy_progress is true. */ 170 float busy_indicator_size; 171 /** Dicrection of the busy indicator on the, -1 or 1, used if @p busy_progress is true. */ 172 int busy_direction; 165 173 float generic_progress; 166 174 float volume_level; 167 175 -
mythplugins/mythmusic/mythmusic/decoder.h
8 8 #include <qptrlist.h> 9 9 10 10 class Metadata; 11 class MetaIO; 11 12 class Decoder; 12 13 class DecoderFactory; 13 14 … … 79 80 static Decoder *create(const QString &, QIODevice *, AudioOutput *, 80 81 bool = FALSE); 81 82 82 virtual Metadata *getMetadata() = 0; 83 virtual void commitMetadata(Metadata *mdata) = 0; 83 /** Read the metadata from @p filename directly. 84 85 Creates a @p MetaIO object using @p ::doCreateTagger and uses 86 the MetaIO object to read the metadata. 87 88 @returns an instance of @p Metadata owned by the caller 89 */ 90 virtual Metadata *readMetadata(); 84 91 92 /** Get the metadata for @p filename 93 94 Tries first to read the metadata from the database. If there 95 is no database entry, it'll call @p ::readMetadata 96 97 @returns an instance of @p Metadata owned by the caller 98 */ 99 virtual Metadata *getMetadata(); 100 101 /** Create a @p MetaIO object for the format. 102 103 This method should be overwritten by subclasses to return an 104 instance of the appropriate MetaIO subtype. It is used by @p 105 ::getMetadata, @p ::readMetadata and @p ::commitMetadata. 106 107 The default implementation returns a NULL pointer, which 108 essentially means, that if the decoder does not overrider this 109 method or all of the users (see previous paragraph), files 110 that the decoder supports cannot be indexed using metadata in 111 the file. 112 113 Eg. the mp3 decoder (@p MadDecoder) implements this, whereas 114 the audio CD decoder (@p CdDecoder) does not. 115 116 @returns an instance of @p MetaIO owned by the caller 117 */ 118 virtual MetaIO *doCreateTagger (); 119 120 /** Write the given metadata to the @p filename. 121 122 Creates a @p MetaIO object using @p ::createTagger and asks 123 the MetaIO object to write the contents of mdata to @p 124 filename. 125 126 @params mdata the metadata to write to the disk 127 */ 128 virtual void commitMetadata(Metadata *mdata); 129 85 130 static void SetLocationFormatUseTags(void); 86 131 87 132 QString getFilename(void) { return filename; } -
mythplugins/mythmusic/mythmusic/aacdecoder.cpp
614 614 deinit(); 615 615 } 616 616 617 Meta data* aacDecoder::getMetadata()617 MetaIO* aacDecoder::doCreateTagger() 618 618 { 619 620 Metadata *mdata = new Metadata(filename); 621 if (mdata->isInDatabase(musiclocation)) 622 { 623 return mdata; 624 } 625 626 delete mdata; 627 628 MetaIOMP4* p_tagger = new MetaIOMP4; 629 if (ignore_id3) { 630 mdata = p_tagger->readFromFilename(filename); 631 } else { 632 mdata = p_tagger->read(filename); 633 } 634 635 delete p_tagger; 636 637 if (mdata) 638 mdata->dumpToDatabase(musiclocation); 639 else 640 error(QString("aacdecoder.o: Could not read metadata from \"%1\"").arg(filename.local8Bit())); 641 642 return mdata; 643 } 644 645 void aacDecoder::commitMetadata(Metadata *mdata) 646 { 647 MetaIOMP4* p_tagger = new MetaIOMP4; 648 p_tagger->write(mdata); 649 delete p_tagger; 619 return new MetaIOMP4; 650 620 } 651 621 652 622 uint32_t aacDecoder::aacRead(char *buffer, uint32_t length) -
mythplugins/mythmusic/mythmusic/metadata.cpp
148 148 playcount = query.value(10).toInt(); 149 149 lastplay = query.value(11).toString(); 150 150 compilation = (query.value(12).toInt() > 0); 151 151 152 152 retval = true; 153 153 } 154 154 … … 194 194 return; 195 195 196 196 query.prepare("INSERT INTO musicmetadata (artist,compilation_artist,album,title," 197 "genre,year,tracknum,length,filename,compilation,date_added) VALUES " 197 "genre,year,tracknum,length,filename,compilation,date_added," 198 "date_modified) VALUES " 198 199 "(:ARTIST, :COMPILATION_ARTIST, :ALBUM, :TITLE, :GENRE, :YEAR, :TRACKNUM, " 199 ":LENGTH, :FILENAME, :COMPILATION, :DATE_ADDED );");200 ":LENGTH, :FILENAME, :COMPILATION, :DATE_ADDED, :DATE_MODIFIED );"); 200 201 query.bindValue(":ARTIST", artist.utf8()); 201 202 query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8()); 202 203 query.bindValue(":ALBUM", album.utf8()); … … 207 208 query.bindValue(":LENGTH", length); 208 209 query.bindValue(":FILENAME", sqlfilename.utf8()); 209 210 query.bindValue(":COMPILATION", compilation); 210 query.bindValue(":DATE_ADDED", QDate::currentDate()); 211 query.bindValue(":DATE_ADDED", QDateTime::currentDateTime()); 212 query.bindValue(":DATE_MODIFIED", QDateTime::currentDateTime()); 211 213 212 214 query.exec(); 213 215 … … 364 366 "compilation_artist = :COMPILATION_ARTIST, " 365 367 "title = :TITLE, genre = :GENRE, year = :YEAR, " 366 368 "tracknum = :TRACKNUM, rating = :RATING, " 367 "compilation = :COMPILATION " 369 "compilation = :COMPILATION, " 370 "date_modified= :DATE_MODIFIED " 368 371 "WHERE intid = :ID;"); 369 372 query.bindValue(":ARTIST", artist.utf8()); 370 373 query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8()); … … 375 378 query.bindValue(":TRACKNUM", tracknum); 376 379 query.bindValue(":RATING", rating); 377 380 query.bindValue(":COMPILATION", compilation); 381 query.bindValue(":DATE_MODIFIED", QDateTime::currentDateTime()); 378 382 query.bindValue(":ID", id); 379 383 380 384 if (!query.exec()) … … 1193 1197 if( *it != "genre" && 1194 1198 *it != "artist" && 1195 1199 *it != "splitartist" && 1200 *it != "splitartist1" && 1196 1201 *it != "album" && 1197 1202 *it != "title") 1198 1203 { -
mythplugins/mythmusic/mythmusic/cdrip.cpp
862 862 if (class LCD * lcd = LCD::Get()) 863 863 { 864 864 float fProgress = (float)(totalSectorsDone + (curpos - start))/totalSectors; 865 lcd->setGenericProgress(f Progress);865 lcd->setGenericProgress(false, fProgress); 866 866 } 867 867 qApp->processEvents(); 868 868 } -
mythplugins/mythmusic/mythmusic/decoder.cpp
6 6 7 7 #include "decoder.h" 8 8 #include "constants.h" 9 #include "metadata.h" 10 #include "metaio.h" 9 11 #include <mythtv/output.h> 10 12 #include <mythtv/visual.h> 11 13 … … 87 89 listeners.remove(object); 88 90 } 89 91 92 Metadata *Decoder::readMetadata () { 93 Metadata *mdata = NULL; 94 MetaIO* p_tagger = doCreateTagger (); 90 95 96 if (p_tagger) { 97 if (ignore_id3) 98 mdata = p_tagger->readFromFilename(filename); 99 else 100 mdata = p_tagger->read(filename); 101 102 delete p_tagger; 103 } else { 104 if (!mdata) 105 cerr << "maddecoder.o: Could not read metadata from " << filename.local8Bit() << endl; 106 } 107 108 return mdata; 109 } 110 111 Metadata* Decoder::getMetadata() 112 { 113 114 Metadata *mdata = new Metadata(filename); 115 if (mdata->isInDatabase(musiclocation)) 116 { 117 return mdata; 118 } 119 120 delete mdata; 121 122 return readMetadata (); 123 } 124 125 void Decoder::commitMetadata(Metadata *mdata) 126 { 127 MetaIO* p_tagger = doCreateTagger (); 128 if (p_tagger) { 129 p_tagger->write(mdata); 130 delete p_tagger; 131 } 132 } 133 134 MetaIO *Decoder::doCreateTagger () { 135 return NULL; 136 } 137 91 138 // static methods 92 139 93 140 int Decoder::ignore_id3 = 0; -
mythplugins/mythmusic/mythmusic/aacdecoder.h
29 29 void seek(double); 30 30 void stop(); 31 31 32 Metadata *getMetadata(); 33 void commitMetadata(Metadata *mdata); 32 MetaIO *doCreateTagger(); 34 33 35 34 bool initializeMP4(); 36 35 int getAACTrack(mp4ff_t *infile); -
mythplugins/mythmusic/mythmusic/vorbisdecoder.cpp
293 293 deinit(); 294 294 } 295 295 296 Meta data *VorbisDecoder::getMetadata()296 MetaIO *VorbisDecoder::doCreateTagger() 297 297 { 298 Metadata *mdata = new Metadata(filename); 299 if (mdata->isInDatabase(musiclocation)) 300 { 301 return mdata; 302 } 303 304 delete mdata; 305 306 307 MetaIOOggVorbisComment* p_tagger = new MetaIOOggVorbisComment; 308 if (ignore_id3) 309 mdata = p_tagger->readFromFilename(filename); 310 else 311 mdata = p_tagger->read(filename); 312 313 delete p_tagger; 314 315 if (mdata) 316 mdata->dumpToDatabase(musiclocation); 317 else 318 cerr << "vorbisdecoder.o: Could not read metadata from " << filename.local8Bit() << endl; 319 320 return mdata; 321 } 322 323 void VorbisDecoder::commitMetadata(Metadata *mdata) 324 { 325 MetaIOOggVorbisComment* p_tagger = new MetaIOOggVorbisComment; 326 p_tagger->write(mdata); 327 delete p_tagger; 298 return new MetaIOOggVorbisComment; 328 299 } 329 300 330 301 -
mythplugins/mythmusic/mythmusic/flacdecoder.h
22 22 void doWrite(const FLAC__Frame *frame, const FLAC__int32 * const buffer[]); 23 23 void setFlacMetadata(const FLAC__StreamMetadata *metadata); 24 24 25 Metadata *getMetadata(); 26 void commitMetadata(Metadata *mdata); 25 MetaIO *doCreateTagger(); 27 26 28 27 private: 29 28 void run(); -
mythplugins/mythmusic/mythmusic/avfdecoder.cpp
357 357 deinit(); 358 358 } 359 359 360 Meta data* avfDecoder::getMetadata()360 MetaIO* avfDecoder::doCreateTagger() 361 361 { 362 Metadata *mdata = new Metadata(filename); 363 if (mdata->isInDatabase(musiclocation)) 364 { 365 return mdata; 366 } 367 368 delete mdata; 369 370 371 MetaIOAVFComment* p_tagger = new MetaIOAVFComment; 372 if (ignore_id3) 373 mdata = p_tagger->readFromFilename(filename); 374 else 375 mdata = p_tagger->read(filename); 376 377 delete p_tagger; 378 379 if (mdata) 380 mdata->dumpToDatabase(musiclocation); 381 else 382 cerr << "avfdecoder.o: Could not read metadata from " << filename << endl; 383 384 return mdata; 362 return new MetaIOAVFComment; 385 363 } 386 364 387 void avfDecoder::commitMetadata(Metadata *mdata)388 {389 MetaIOAVFComment* p_tagger = new MetaIOAVFComment;390 p_tagger->write(mdata);391 delete p_tagger;392 }393 394 365 bool avfDecoderFactory::supports(const QString &source) const 395 366 { 396 367 return (source.right(extension().length()).lower() == extension()); -
mythplugins/mythmusic/mythmusic/main.cpp
6 6 #include <qapplication.h> 7 7 #include <qsqldatabase.h> 8 8 #include <qregexp.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 9 11 #include <unistd.h> 10 12 11 13 #include <cdaudio.h> … … 65 67 return decoder; 66 68 } 67 69 68 void CheckFile(const QString &filename) 70 // Add a file to the database 71 void CheckFile(const QString &directory, const QString &filename) 69 72 { 70 73 Decoder *decoder = getDecoder(filename); 71 74 72 75 if (decoder) 73 76 { 74 77 Metadata *data = decoder->getMetadata(); 75 if (data) 78 if (data) 79 { 80 data->dumpToDatabase(directory); 76 81 delete data; 82 } 83 delete decoder; 84 } 85 } 77 86 87 // Remove a file from the database 88 void RemoveFile (const QString &directory, const QString &filename) 89 { 90 QString name(filename); 91 name.remove(0, directory.length()); 92 MSqlQuery query(MSqlQuery::InitCon()); 93 query.prepare("DELETE FROM musicmetadata WHERE " 94 "filename = :NAME ;"); 95 query.bindValue(":NAME", name.utf8()); 96 query.exec(); 97 } 98 99 // Update a file's metadata in the database, preserving it's id 100 void UpdateFile (const QString &directory, const QString &filename) 101 { 102 Decoder *decoder = getDecoder (filename); 103 104 if (decoder) 105 { 106 Metadata *db_meta = decoder->getMetadata (); 107 Metadata *disk_meta = decoder->readMetadata (); 108 109 if (db_meta && disk_meta) 110 { 111 disk_meta->setID (db_meta->ID ()); 112 disk_meta->updateDatabase (directory); 113 } 114 115 if (disk_meta) 116 delete disk_meta; 117 118 if (db_meta) 119 delete db_meta; 120 78 121 delete decoder; 79 122 } 80 123 } … … 83 126 { 84 127 kFileSystem, 85 128 kDatabase, 86 k Both129 kNeedUpdate, 87 130 }; 88 131 89 132 typedef QMap <QString, MusicFileLocation> MusicLoadedMap; … … 102 145 QFileInfoListIterator it(*list); 103 146 QFileInfo *fi; 104 147 148 /* Recursively traverse directory */ 105 149 while ((fi = it.current()) != 0) 106 150 { 107 151 ++it; … … 111 155 if (fi->isDir()) 112 156 BuildFileList(filename, music_files); 113 157 else 114 music_files[filename] = kFileSystem; 158 music_files[filename] = kFileSystem; 115 159 } 116 160 } 117 161 162 /* Check if the file's mdate is after the date_modified */ 163 bool HasFileChanged (const QString &filename, const QString &date_modified) 164 { 165 struct stat sbuf; 166 if (stat (filename.ascii (), &sbuf) == 0) { 167 if (sbuf.st_mtime > (time_t)QDateTime::fromString (date_modified, Qt::ISODate).toTime_t ()) { 168 return true; 169 } 170 } 171 return false; 172 } 173 118 174 void SavePending(int pending) 119 175 { 120 176 // Temporary Hack until mythmusic … … 176 232 { 177 233 MusicLoadedMap music_files; 178 234 MusicLoadedMap::Iterator iter; 235 236 { 237 /* Let the user know we're doing something, since ie. building 238 the filelist over NFS can take quite a while, so progress 239 bar now... 240 */ 241 MythBusyIndicator busy (QObject::tr("Searching for music files")); 242 BuildFileList(directory, music_files); 243 } 179 244 180 BuildFileList(directory, music_files);181 182 245 MSqlQuery query(MSqlQuery::InitCon()); 183 query.exec("SELECT filename FROM musicmetadata "246 query.exec("SELECT filename, date_modified FROM musicmetadata " 184 247 "WHERE filename NOT LIKE ('%://%');"); 185 248 249 MythProgressDialog *progress; 250 progress = new MythProgressDialog(QObject::tr("Scanning music files"), 251 query.numRowsAffected()); 252 186 253 int counter = 0; 187 254 188 MythProgressDialog *file_checking;189 file_checking = new MythProgressDialog(QObject::tr("Searching for music files"),190 query.numRowsAffected());191 192 255 if (query.isActive() && query.size() > 0) 193 256 { 194 257 while (query.next()) … … 196 259 QString name = directory + QString::fromUtf8(query.value(0).toString()); 197 260 if (name != QString::null) 198 261 { 199 if ((iter = music_files.find(name)) != music_files.end()) 200 music_files.remove(iter); 201 else 262 if ((iter = music_files.find(name)) != music_files.end()) { 263 if (HasFileChanged (name, query.value (1).toString ())) { 264 music_files[name] = kNeedUpdate; 265 } else { 266 music_files.remove(iter); 267 } 268 } else { 202 269 music_files[name] = kDatabase; 270 } 203 271 } 204 file_checking->setProgress(++counter);272 progress->setProgress(++counter); 205 273 } 206 274 } 207 275 208 file_checking->Close();209 delete file_checking;276 progress->Close(); 277 delete progress; 210 278 211 file_checking = new MythProgressDialog(QObject::tr("Updating music database"), 279 counter = 0; 280 progress = new MythProgressDialog(QObject::tr("Updating music database"), 212 281 music_files.size()); 213 282 214 283 QRegExp quote_regex("\""); 215 284 for (iter = music_files.begin(); iter != music_files.end(); iter++) 216 285 { 217 if (*iter == kFileSystem) 218 { 219 CheckFile(iter.key()); 286 switch (*iter) { 287 case kFileSystem: 288 CheckFile(directory, iter.key()); 289 break; 290 case kDatabase: 291 RemoveFile (directory, iter.key()); 292 break; 293 case kNeedUpdate: 294 UpdateFile (directory, iter.key ()); 295 break; 220 296 } 221 else if (*iter == kDatabase) 222 { 223 QString name(iter.key()); 224 name.remove(0, directory.length()); 225 226 query.prepare("DELETE FROM musicmetadata WHERE " 227 "filename = :NAME ;"); 228 query.bindValue(":NAME", name.utf8()); 229 query.exec(); 230 } 231 232 file_checking->setProgress(++counter); 297 progress->setProgress(++counter); 233 298 } 234 file_checking->Close();235 delete file_checking;299 progress->Close(); 300 delete progress; 236 301 } 237 302 238 303 void startPlayback(PlaylistsContainer *all_playlists, AllMusic *all_music) … … 302 367 // Reconcile with the database 303 368 SearchDir(mdata->startdir); 304 369 // Tell the metadata to reset itself 370 MythBusyIndicator busy (QObject::tr("Rebuilding music tree")); 305 371 mdata->all_music->resync(); 306 372 mdata->all_playlists->postLoad(); 307 373 } … … 311 377 if ("" != mdata->startdir) 312 378 { 313 379 SearchDir(mdata->startdir); 380 MythBusyIndicator busy (QObject::tr("Rebuilding music tree")); 314 381 mdata->all_music->resync(); 315 382 mdata->all_playlists->postLoad(); 316 383 } … … 554 621 // if startRipper returns true, then new files should be present 555 622 // so we should look for them. 556 623 SearchDir(mdata.startdir); 624 MythBusyIndicator busy (QObject::tr("Rebuilding music tree")); 557 625 mdata.all_music->resync(); 558 626 mdata.all_playlists->postLoad(); 559 627 } -
mythplugins/mythmusic/mythmusic/flacdecoder.cpp
385 385 char *field_value; 386 386 } Argument_VcField; 387 387 388 Meta data *FlacDecoder::getMetadata()388 MetaIO *FlacDecoder::doCreateTagger() 389 389 { 390 Metadata *mdata = new Metadata(filename); 391 if (mdata->isInDatabase(musiclocation)) 392 { 393 return mdata; 394 } 390 return new MetaIOFLACVorbisComment; 391 } 395 392 396 delete mdata;397 393 398 MetaIOFLACVorbisComment* p_tagger = new MetaIOFLACVorbisComment;399 if (ignore_id3)400 mdata = p_tagger->readFromFilename(filename);401 else402 mdata = p_tagger->read(filename);403 404 delete p_tagger;405 406 if (mdata)407 mdata->dumpToDatabase(musiclocation);408 else409 cerr << "flacdecoder.o: Could not read metadata from " << filename.local8Bit() << endl;410 411 return mdata;412 }413 414 void FlacDecoder::commitMetadata(Metadata *mdata)415 {416 MetaIOFLACVorbisComment* p_tagger = new MetaIOFLACVorbisComment;417 p_tagger->write(mdata);418 delete p_tagger;419 }420 421 422 394 bool FlacDecoderFactory::supports(const QString &source) const 423 395 { 424 396 return (source.right(extension().length()).lower() == extension()); -
mythplugins/mythmusic/mythmusic/maddecoder.h
24 24 static const int maxFrameCheck; 25 25 static const int initialFrameSize; 26 26 27 Metadata *getMetadata(); 28 void commitMetadata(Metadata *mdata); 27 MetaIO *doCreateTagger(); 29 28 30 29 private: 31 30 void run(); -
mythplugins/mythmusic/mythmusic/vorbisdecoder.h
18 18 void seek(double); 19 19 void stop(); 20 20 21 Metadata *getMetadata(); 22 void commitMetadata(Metadata *mdata); 21 MetaIO *doCreateTagger(); 23 22 24 23 private: 25 24 void run(); -
mythplugins/mythmusic/mythmusic/avfdecoder.h
18 18 void seek(double); 19 19 void stop(); 20 20 21 Metadata *getMetadata(); 22 void commitMetadata(Metadata *mdata); 21 MetaIO *doCreateTagger(); 23 22 24 23 private: 25 24 void run(); -
mythplugins/mythmusic/mythmusic/maddecoder.cpp
512 512 return MAD_FLOW_STOP; 513 513 } 514 514 515 Meta data *MadDecoder::getMetadata()515 MetaIO *MadDecoder::doCreateTagger() 516 516 { 517 Metadata *mdata = new Metadata(filename); 518 if (mdata->isInDatabase(musiclocation)) 519 { 520 return mdata; 521 } 522 523 delete mdata; 524 525 526 MetaIOID3v2* p_tagger = new MetaIOID3v2; 527 if (ignore_id3) 528 mdata = p_tagger->readFromFilename(filename); 529 else 530 mdata = p_tagger->read(filename); 531 532 delete p_tagger; 533 534 if (mdata) 535 mdata->dumpToDatabase(musiclocation); 536 else 537 cerr << "maddecoder.o: Could not read metadata from " << filename.local8Bit() << endl; 538 539 return mdata; 517 return new MetaIOID3v2; 540 518 } 541 519 542 void MadDecoder::commitMetadata(Metadata *mdata)543 {544 MetaIOID3v2* p_tagger = new MetaIOID3v2;545 p_tagger->write(mdata);546 delete p_tagger;547 }548 549 520 bool MadDecoderFactory::supports(const QString &source) const 550 521 { 551 522 bool res = false;