]> granicus.if.org Git - taglib/commitdiff
Add a mechanism for extending the file type resolution in JuK using FileRefs.
authorScott Wheeler <wheeler@kde.org>
Thu, 21 Jul 2005 17:45:23 +0000 (17:45 +0000)
committerScott Wheeler <wheeler@kde.org>
Thu, 21 Jul 2005 17:45:23 +0000 (17:45 +0000)
This is generally much better thought out than the current method of creating
FileRefs using the native mime system and also allows for extension to additional
file formats.

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@437382 283d02a7-25f6-0310-bc7c-ecb5cbfe19da

fileref.cpp
fileref.h
tests/toolkit-test.cpp
toolkit/tlist.h
toolkit/tlist.tcc

index 2da2e71ff2de780ceaf349b4a31a260496b82baf..6c12749d0ffdd0b1aa8ca0e70cc548038e8f4efc 100644 (file)
@@ -39,8 +39,11 @@ public:
   }
 
   File *file;
+  static List<const FileTypeResolver *> fileTypeResolvers;
 };
 
+List<const FileRef::FileTypeResolver *> FileRef::FileRefPrivate::fileTypeResolvers;
+
 ////////////////////////////////////////////////////////////////////////////////
 // public members
 ////////////////////////////////////////////////////////////////////////////////
@@ -92,6 +95,11 @@ bool FileRef::save()
   return d->file->save();
 }
 
+void FileRef::addFileTypeResolver(const FileTypeResolver *resolver) // static
+{
+  FileRefPrivate::fileTypeResolvers.prepend(resolver);
+}
+
 bool FileRef::isNull() const
 {
   return !d->file || !d->file->isValid();
index ffa7864fc37723bc00e04db569e09d4cc444bd51..b4e64eea6dc23d6fd9c905ffb42f592687487754 100644 (file)
--- a/fileref.h
+++ b/fileref.h
@@ -43,31 +43,60 @@ namespace TagLib {
    * across file types.
    *
    * Also note that it is probably a good idea to plug this into your mime
-   * type system rather than using the constructor that accepts a file name.
+   * type system rather than using the constructor that accepts a file name using
+   * the FileTypeResolver.
    *
-   * For example in KDE this could be done with:
+   * \see FileTypeResolver
+   * \see addFileTypeResolver()
+   */
+
+  class FileRef
+  {
+  public:
+
+  //! A class for pluggable file type resolution.
+
+  /*!
+   * This class is used to add extend TagLib's very basic file name based file
+   * type resolution.
+   *
+   * This can be accomplished with:
    *
    * \code
    *
-   * TagLib::FileRef createFileRef( const QString &fileName )
+   * class MyFileTypeResolver : FileTypeResolver
    * {
-   *   KMimeType::Ptr result = KMimeType::findByPath( fileName, 0, true );
-   *
-   *   if( result->name() == "audio/x-mp3" )
-   *     return FileRef( new MPEG::File( QFile::encodeName( fileName ).data() ) );
-   *
-   *   if( result->name() == "application/ogg" )
-   *     return FileRef( new Vorbis::File( QFile::encodeName( fileName ).data() ) );
-   *
-   *   return FileRef( 0 );
+   *   TagLib::File *createFile(const char *fileName)
+   *   {
+   *     if(someCheckForAnMP3File(fileName))
+   *       return new TagLib::MPEG::File(fileName);
+   *     return 0;
+   *   }
    * }
    *
+   * FileRef::addFileTypeResolver(new MyFileTypeResolver);
+   *
    * \endcode
+   *
+   * Naturally a less contrived example would be slightly more complex.  This
+   * can be used to plug in mime-type detection systems or to add new file types
+   * to TagLib.
    */
 
-  class FileRef
-  {
-  public:
+    class FileTypeResolver
+    {
+    public:
+      /*!
+       * This method must be overriden to provide an additional file type
+       * resolver.  If the resolver is able to determine the file type it should
+       * return a valid File object; if not it should return 0.
+       *
+       * \note The created file is then owned by the FileRef and should not be
+       * deleted.  Deletion will happen automatically when the FileRef passes
+       * out of scope.
+       */
+      virtual File *createFile(const char *fileName) = 0;
+    };
 
     FileRef();
 
@@ -139,6 +168,14 @@ namespace TagLib {
      */
     bool save();
 
+    /*!
+     * Adds a FileTypeResolver to the list of those used by TagLib.  Each
+     * additional FileTypeResolver is added to the front of a list of resolvers
+     * that are tried.  If the FileTypeResolver returns zero the next resolver
+     * is tried.
+     */
+    static void addFileTypeResolver(const FileTypeResolver *resolver);
+
     /*!
      * Returns true if the file (and as such other pointers) are null.
      */
index aa1042d20fda6a77bd8df246be0cb5a69a178eda..e5b8ae3f0562b6d096be4b41e4515352dcb718e1 100644 (file)
@@ -233,11 +233,11 @@ void testList()
   List<int> l1;
   List<int> l2;
   List<int> l3;
-  l1.append(1);
   l1.append(2);
   l2.append(3);
   l2.append(4);
   l1.append(l2);
+  l1.prepend(1);
   l3.append(1);
   l3.append(2);
   l3.append(3);
index 3ea7a669e0a3e7a52b2227081e80a2e4b482a92c..371543a501f4ebd2eabc771e9dae7aa11bbae2a2 100644 (file)
@@ -120,6 +120,9 @@ namespace TagLib {
      */
     List<T> &append(const List<T> &l);
 
+    List<T> &prepend(const T &item);
+    List<T> &prepend(const List<T> &l);
+
     /*!
      * Clears the list.  If auto deletion is enabled and this list contains a
      * pointer type the members are also deleted.
index ae3f9a220fd4d550969902493a179805b6cb4156..38a150a80c4f162719d9a896fe5675a5e1c9e5b3 100644 (file)
@@ -164,6 +164,22 @@ List<T> &List<T>::append(const List<T> &l)
   return *this;
 }
 
+template <class T>
+List<T> &List<T>::prepend(const T &item)
+{
+  detach();
+  d->list.push_front(item);
+  return *this;
+}
+
+template <class T>
+List<T> &List<T>::prepend(const List<T> &l)
+{
+  detach();
+  d->list.insert(d->list.begin(), l.begin(), l.end());
+  return *this;
+}
+
 template <class T>
 void List<T>::clear()
 {