Ticket #7376: mythgallery.2009.10.21.rev22544.patch

File mythgallery.2009.10.21.rev22544.patch, 30.1 KB (added by trebor_s@…, 15 years ago)

New patch with improvements and fixes

  • mythgallery/glsingleview.cpp

    Kann nicht anzeigen: Dateityp ist als binÀr angegeben.
    svn:mime-type = application/octet-stream
     
    5252    QBoxLayout *l = new QVBoxLayout(this);
    5353    m_view = new GLSingleView(itemList, pos, slideShow, sortOrder, this);
    5454    l->addWidget(m_view);
     55    l->setContentsMargins (0, 0, 0, 0);
    5556
    5657    setFocusProxy(m_view);
    5758    m_view->setFocus();
  • mythgallery/galleryutil.h

     
    2121#define EXIFUTIL_H
    2222
    2323#include <QFileInfo>
    24 
    2524#include "iconview.h"
    2625
     26#ifdef EXIF_SUPPORT
     27#include <libexif/exif-data.h>
     28#include <libexif/exif-entry.h>
     29// include "exif.hpp"
     30#endif // EXIF_SUPPORT
     31
    2732class GalleryUtil
    2833{
    2934 public:
     
    3439    static bool IsImage(const QString &filePath);
    3540    static bool IsMovie(const QString &filePath);
    3641    static long GetNaturalRotation(const QString &filePath);
    37 
     42    static long GetNaturalRotationDB(const QString &filePath, bool *ok);
     43    static long GetDateTime(const QString &filePath);
     44    static long GetDateTimeDB(const QString &filePath, bool *ok);
    3845    static QString GetCaption(const QString &filePath);
    3946
     47    static void SetDateTimeDB(const QString &filePath, long dateTime);
     48    static void SetNaturalRotationDB(QString &filePath, long angle);
     49
     50#ifdef EXIF_SUPPORT
     51    static QString GetExifHeaderTag(const QString &filePathString, ExifTag exifHeaderTag);
     52#endif
     53
    4054    static bool LoadDirectory(ThumbList &itemList, const QString &dir,
    4155                              int sortorder, bool recurse,
    4256                              ThumbHash *itemHash, ThumbGenerator *thumbGen);
  • mythgallery/thumbview.cpp

     
    77
    88// MythTV plugin headers
    99#include <mythtv/mythdb.h>
     10#include "mythtv/mythcontext.h"
    1011
    1112// MythGallery headers
    1213#include "thumbview.h"
     
    6162
    6263void ThumbItem::SetRotationAngle(int angle)
    6364{
    64     MSqlQuery query(MSqlQuery::InitCon());
    65     query.prepare(
    66         "REPLACE INTO gallerymetadata "
    67         "SET image = :IMAGE, "
    68         "    angle = :ANGLE");
    69     query.bindValue(":IMAGE", m_path);
    70     query.bindValue(":ANGLE", angle);
    71 
    72     if (!query.exec())
    73         MythDB::DBError("set_rotation_angle", query);
    74 
     65    VERBOSE(VB_IMPORTANT, QString("ThumbItem::SetRotationAngle(angle): angle into database: '%1'").arg(angle));
     66    GalleryUtil::SetNaturalRotationDB(m_path, angle);
    7567    SetPixmap(NULL);
    7668}
    7769
     
    8274    m_pixmap = pixmap;
    8375}
    8476
     77
    8578long ThumbItem::GetRotationAngle(void)
    86 {
    87     MSqlQuery query(MSqlQuery::InitCon());
     79
     80    // Load the rotation in from the database. It should
     81    // have been set during the thumbnail creation phase
     82    bool ok = false;
     83    long angle = GalleryUtil::GetNaturalRotationDB(m_path, &ok);
    8884
    89     // first try to find the exact file
    90     query.prepare(
    91         "SELECT angle "
    92         "FROM gallerymetadata "
    93         "WHERE image = :PATH");
    94     query.bindValue(":PATH", m_path);
     85    return angle;
    9586
    96     if (!query.exec() || !query.isActive())
    97         MythDB::DBError("get_rotation_angle", query);
    98     else if (query.next())
    99         return query.value(0).toInt();
     87/*
     88    // Load the rotation in from the database to speed up
     89    // the rotation later. If the data is not available then
     90    // get the rotation information from the exif header.
     91    bool ok = false;
     92    long rotateAngle = GalleryUtil::GetNaturalRotationDB(m_path, &ok);
    10093
    101     // second try to find the first image in the same directory
    102     query.prepare(
    103         "SELECT angle, image "
    104         "FROM gallerymetadata "
    105         "WHERE image LIKE :PATH "
    106         "ORDER BY image");
    107     query.bindValue(":PATH", m_path + '%');
     94    if (rotateAngle == -1 || !ok)
     95    {
     96        // we dont have a value. try to get it from the exif header
     97        rotateAngle = GalleryUtil::GetNaturalRotation(m_path);
    10898
    109     if (!query.exec() || !query.isActive())
    110         MythDB::DBError("get_rotation_angle", query);
    111     else if (query.next())
    112         return query.value(0).toInt();
    113 
    114     return GalleryUtil::GetNaturalRotation(m_path);
     99        // if we have a value then update the database
     100        if ( rotateAngle != -1 )
     101            GalleryUtil::SetNaturalRotationDB(m_path, rotateAngle);
     102    }
     103    return rotateAngle;
     104*/
    115105}
    116106
     107
    117108QString ThumbItem::GetDescription(const QString &status,
    118109                                  const QSize &sz, int angle) const
    119110{
  • mythgallery/gallerysettings.cpp

     
    4242    gc->addSelection("Reverse Name (Z-A alpha)", QString::number(QDir::Name | QDir::DirsFirst | QDir::IgnoreCase | QDir::Reversed));
    4343    gc->addSelection("Mod Time (earliest first)", QString::number(QDir::Time | QDir::DirsFirst | QDir::IgnoreCase | QDir::Reversed));
    4444    gc->addSelection("Reverse Mod Time (most recent first)", QString::number(QDir::Time | QDir::DirsFirst | QDir::IgnoreCase));
     45#ifdef EXIF_SUPPORT
     46    gc->addSelection("Creation Time (earliest first)", QString::number( 0x1000 | QDir::Reversed) );
     47    gc->addSelection("Reverse Creation Time (most recent first)", QString::number( 0x1000 ) );
     48#endif
    4549    gc->setHelpText(QObject::tr("This is the sort order for the displayed "
    4650                    "picture thumbnails."));
    4751    return gc;
    4852};
    4953
     54static HostCheckBox *MythGalleryScaleMax()
     55{
     56    HostCheckBox *gc = new HostCheckBox("GalleryScaleMax");
     57    gc->setLabel(QObject::tr("Scale image to the maximum screen size"));
     58    gc->setHelpText(QObject::tr("Check this to scale the image to the maximum "
     59                                "No black borders will be visible."));
     60    return gc;
     61};
     62
    5063static HostLineEdit *MythGalleryMoviePlayerCmd()
    5164{
    5265    HostLineEdit *gc = new HostLineEdit("GalleryMoviePlayerCmd");
     
    205218        addChild(SlideshowDelay());
    206219        addChild(SlideshowRecursive());
    207220    }
    208 
    209221};
    210222
    211223
     
    215227    general->setLabel(QObject::tr("MythGallery Settings (General)"));
    216228    general->addChild(MythGalleryDir());
    217229    general->addChild(MythGalleryThumbnailLocation());
     230    general->addChild(MythGalleryScaleMax());
    218231    general->addChild(MythGallerySortOrder());
    219232    general->addChild(MythGalleryImportDirs());
    220233    general->addChild(MythGalleryMoviePlayerCmd());
  • mythgallery/iconview.cpp

     
    311311                            .arg(ThumbGenerator::getThumbcacheDir(m_currDir))
    312312                            .arg(item->GetName());
    313313
    314 //         int rotateAngle = 0;
    315 //
    316 //         rotateAngle = item->GetRotationAngle();
    317 //
    318 //         if (rotateAngle != 0)
    319 //         {
    320 //             QMatrix matrix;
    321 //             matrix.rotate(rotateAngle);
    322 //             image = image.xForm(matrix);
    323 //         }
    324314    item->SetImageFilename(imagePath);
    325315}
    326316
     
    414404    m_selectedImage->Load();
    415405}
    416406
    417 
    418407bool IconView::keyPressEvent(QKeyEvent *event)
    419408{
    420409    if (GetFocusWidget()->keyPressEvent(event))
     
    12321221    LoadDirectory(m_currDir);
    12331222}
    12341223
    1235 
    12361224void IconView::HandleRename(void)
    12371225{
    12381226    ThumbItem *thumbitem = GetCurrentThumb();
  • mythgallery/dbcheck.cpp

     
    1212// mythgallery
    1313#include "dbcheck.h"
    1414
    15 const QString currentDatabaseVersion = "1003";
     15const QString currentDatabaseVersion = "1004";
    1616
    1717static bool UpdateDBVersionNumber(const QString &newnumber)
    1818{
    19 
    2019    if (!gContext->SaveSettingOnHost("GalleryDBSchemaVer",newnumber,NULL))
    2120    {
    2221        VERBOSE(VB_IMPORTANT,
     
    4544        if (!query.exec(thequery))
    4645        {
    4746            QString msg =
    48                 QString("DB Error (Performing database upgrade): \n"
    49                         "Query was: %1 \nError was: %2 \nnew version: %3")
    50                 .arg(thequery)
    51                 .arg(MythDB::DBErrorMessage(query.lastError()))
    52                 .arg(version);
     47                    QString("DB Error (Performing database upgrade): \n"
     48                            "Query was: %1 \nError was: %2 \nnew version: %3")
     49                    .arg(thequery)
     50                    .arg(MythDB::DBErrorMessage(query.lastError()))
     51                    .arg(version);
    5352            VERBOSE(VB_IMPORTANT, msg);
    5453            return false;
    5554        }
     
    7877                "Inserting MythGallery initial database information.");
    7978
    8079        const QString updates[] = {
    81 "CREATE TABLE IF NOT EXISTS gallerymetadata ("
    82 "  image VARCHAR(255) NOT NULL PRIMARY KEY,"
    83 "  angle INTEGER NOT NULL"
    84 ");",
    85 "INSERT INTO settings VALUES ('GalleryDBSchemaVer', 1000, NULL);",
    86 ""
    87 };
     80            "CREATE TABLE IF NOT EXISTS gallerymetadata ("
     81                    "  image VARCHAR(255) NOT NULL PRIMARY KEY,"
     82                    "  angle INTEGER NOT NULL"
     83                    ");",
     84                    "INSERT INTO settings VALUES ('GalleryDBSchemaVer', 1000, NULL);",
     85                    ""
     86                };
    8887        if (!performActualUpdate(updates, "1000", dbver))
    8988            return false;
    9089    }
    9190
    92 
    93 
    9491    if (dbver == "1000")
    9592    {
    9693        const QString updates[] = {
    97 QString("ALTER DATABASE %1 DEFAULT CHARACTER SET latin1;")
    98         .arg(gContext->GetDatabaseParams().dbName),
    99 "ALTER TABLE gallerymetadata"
    100 "  MODIFY image varbinary(255) NOT NULL;",
    101 ""
    102 };
     94            QString("ALTER DATABASE %1 DEFAULT CHARACTER SET latin1;")
     95                    .arg(gContext->GetDatabaseParams().dbName),
     96                    "ALTER TABLE gallerymetadata"
     97                    "  MODIFY image varbinary(255) NOT NULL;",
     98                    ""
     99                };
    103100
    104101        if (!performActualUpdate(updates, "1001", dbver))
    105102            return false;
    106103    }
    107104
    108 
    109105    if (dbver == "1001")
    110106    {
    111107        const QString updates[] = {
    112 QString("ALTER DATABASE %1 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;")
    113         .arg(gContext->GetDatabaseParams().dbName),
    114 "ALTER TABLE gallerymetadata"
    115 "  DEFAULT CHARACTER SET default,"
    116 "  MODIFY image varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL;",
    117 ""
    118 };
     108            QString("ALTER DATABASE %1 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;")
     109                    .arg(gContext->GetDatabaseParams().dbName),
     110                    "ALTER TABLE gallerymetadata"
     111                    "  DEFAULT CHARACTER SET default,"
     112                    "  MODIFY image varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL;",
     113                    ""
     114                };
    119115
    120116        if (!performActualUpdate(updates, "1002", dbver))
    121117            return false;
     
    124120    if (dbver == "1002")
    125121    {
    126122        const QString updates[] = {
    127 "DELETE FROM keybindings "
    128 " WHERE action = 'DELETE' AND context = 'Gallery';",
    129 ""
    130 };
     123            "DELETE FROM keybindings "
     124                    " WHERE action = 'DELETE' AND context = 'Gallery';",
     125                    ""
     126                };
    131127
    132128        if (!performActualUpdate(updates, "1003", dbver))
    133129            return false;
    134130    }
    135131
     132    if (dbver == "1003")
     133    {
     134        const QString updates[] = {
     135            "ALTER TABLE `gallerymetadata` ADD `datetime` INT NOT NULL DEFAULT '0' AFTER `angle`;",
     136            "ALTER TABLE `gallerymetadata` CHANGE `angle` `angle` INT( 11 ) NOT NULL DEFAULT '0';",
     137            ""
     138        };
     139        if (!performActualUpdate(updates, "1004", dbver))
     140            return false;
     141    }
     142
    136143    return true;
    137144}
  • mythgallery/thumbgenerator.cpp

     
    320320    }
    321321    else
    322322    {
     323        QString filePath = fi.canonicalFilePath();
    323324#ifdef EXIF_SUPPORT
     325
    324326        // Try to get thumbnail from exif data
    325         ExifData *ed = exif_data_new_from_file(fi.absoluteFilePath()
    326                                                .toLocal8Bit().constData());
     327        ExifData *ed = exif_data_new_from_file(
     328                filePath.toLocal8Bit().constData());
     329
    327330        if (ed && ed->data)
    328         {
    329331            image.loadFromData(ed->data, ed->size);
    330         }
    331332
    332333        if (ed)
    333334            exif_data_free(ed);
     
    335336        if (image.width() > m_width && image.height() > m_height)
    336337            return;
    337338#endif
     339        // There was no thumbnail image in the exif header.
     340        // Load the image regularily.
     341        image.load(filePath);
    338342
    339         image.load(fi.absoluteFilePath());
     343        long angle = 0;
     344       
     345#ifdef EXIF_SUPPORT
     346       
     347        // This is the first time we create the thumbnail.
     348        // Load the rotation angle from the exif header
     349        angle = GalleryUtil::GetNaturalRotation(filePath);
     350
     351        // if we have an angle other than the default
     352        // of 0 degrees save it in the database.
     353        if ( angle != 0 )
     354            GalleryUtil::SetNaturalRotationDB(filePath, angle);
     355#endif
     356
     357        // rotate the thumbnail image
     358        if (angle != 0 )
     359        {
     360            QMatrix matrix;
     361            matrix.rotate(angle);
     362            image = image.transformed(matrix);
     363        }
    340364    }
    341365}
    342366
  • mythgallery/galleryutil.cpp

     
    3131#include "galleryutil.h"
    3232#include "thumbgenerator.h"
    3333
    34 #ifdef EXIF_SUPPORT
    35 #include <libexif/exif-data.h>
    36 #include <libexif/exif-entry.h>
    37 // include "exif.hpp"
    38 #endif // EXIF_SUPPORT
    39 
    4034#define LOC QString("GalleryUtil:")
    4135#define LOC_ERR QString("GalleryUtil, Error:")
    4236
     
    123117    return false;
    124118}
    125119
    126 long GalleryUtil::GetNaturalRotation(const QString &filePathString)
     120long GalleryUtil::GetNaturalRotation(const QString &filePath)
    127121{
     122    // default value if no value is found
    128123    long rotateAngle = 0;
     124
     125#ifdef EXIF_SUPPORT
     126    // get the value from the header. Check also with different languages
     127    // because the value depends on the language used by the camera
     128    QString value = GetExifHeaderTag( filePath, EXIF_TAG_ORIENTATION);
     129
     130    if (value == "left - bottom" ||
     131        value == "links - unten")
     132    {
     133        rotateAngle = -90;
     134    }
     135    else if (value == "right - top" ||
     136             value == "rechts - oben")
     137    {
     138        rotateAngle = 90;
     139    }
     140#endif
     141
     142    return rotateAngle;
     143}
     144
     145long GalleryUtil::GetNaturalRotationDB(const QString &filePath, bool *ok)
     146{
     147    // default value if no value is found
     148    long angle = 0;
     149
     150    *ok = false;
     151    MSqlQuery query(MSqlQuery::InitCon());
     152
     153    // first try to find the exact file
     154    query.prepare(
     155        "SELECT angle "
     156        "FROM gallerymetadata "
     157        "WHERE image = :PATH");
     158    query.bindValue(":PATH", filePath);
     159
     160    if (!query.exec() || !query.isActive())
     161    {
     162        MythDB::DBError("get_rotation_angle", query);
     163    }
     164    else if (query.next())
     165    {
     166        *ok = true;
     167        return query.value(0).toString().toLong();
     168    }
     169
     170    // second try to find the first image in the same directory
     171    query.prepare(
     172        "SELECT angle, image "
     173        "FROM gallerymetadata "
     174        "WHERE image LIKE :PATH "
     175        "ORDER BY image");
     176    query.bindValue(":PATH", filePath + '%');
     177
     178    if (!query.exec() || !query.isActive())
     179    {
     180        MythDB::DBError("get_rotation_angle", query);
     181    }
     182    else if (query.next())
     183    {
     184        *ok = true;
     185        return query.value(0).toString().toLong();
     186    }
     187
     188    return angle;
     189}
     190
     191QString GalleryUtil::GetCaption(const QString &filePath)
     192{
     193    QString caption("");
     194
     195#ifdef EXIF_SUPPORT
     196    // try to get the user comment
     197    caption = GetExifHeaderTag( filePath, EXIF_TAG_USER_COMMENT);
     198
     199    if(!caption.isEmpty())
     200        return caption;
     201
     202    // try to get the tag image description
     203    caption = GetExifHeaderTag( filePath, EXIF_TAG_IMAGE_DESCRIPTION);
     204    if(!caption.isEmpty())
     205        return caption;
     206#endif
     207
     208    return caption;
     209}
     210
     211long GalleryUtil::GetDateTime(const QString &filePath)
     212{
     213    // default value if no value is found
     214    long utcTime = 0;
     215
     216#ifdef EXIF_SUPPORT
     217    QString value = GetExifHeaderTag( filePath, EXIF_TAG_DATE_TIME);
     218
     219    // convert the string into the UTC time. We need to split
     220    // the exif time format, which is this: "2006:07:21 18:54:58"
     221    bool ok;
     222    QDateTime dateTime = QDateTime( QDate( value.mid(0,4).toInt(&ok, 10),
     223                                           value.mid(5,2).toInt(&ok, 10),
     224                                           value.mid(8,2).toInt(&ok, 10)),
     225                                    QTime( value.mid(11,2).toInt(&ok, 10),
     226                                           value.mid(14,2).toInt(&ok, 10),
     227                                           value.mid(17,2).toInt(&ok, 10), 0));
     228
     229    // convert it to the utc time so we can easily compare it later.
     230    utcTime = dateTime.toTime_t();
     231#endif
     232
     233    return utcTime;
     234}
     235
     236long GalleryUtil::GetDateTimeDB(const QString &filePath, bool *ok)
     237{
     238    // default value if no value is found
     239    long dateTime = 0;
     240
     241    *ok = false;
     242    MSqlQuery query(MSqlQuery::InitCon());
     243
     244    // first try to find the exact file
     245    query.prepare(
     246        "SELECT datetime "
     247        "FROM gallerymetadata "
     248        "WHERE image = :PATH");
     249    query.bindValue(":PATH", filePath);
     250
     251    if (!query.exec() || !query.isActive())
     252    {
     253        MythDB::DBError("get_datetime", query);
     254    }
     255    else if (query.next())
     256    {
     257        *ok = true;
     258        return query.value(0).toString().toLong();
     259    }
     260
     261    // second try to find the first image in the same directory
     262    query.prepare(
     263        "SELECT datetime, image "
     264        "FROM gallerymetadata "
     265        "WHERE image LIKE :PATH "
     266        "ORDER BY image");
     267    query.bindValue(":PATH", filePath + '%');
     268
     269    if (!query.exec() || !query.isActive())
     270    {
     271        MythDB::DBError("get_datetime", query);
     272     }
     273    else if (query.next())
     274    {
     275        *ok = true;
     276        return query.value(0).toString().toLong();
     277    }
     278
     279    // if everything fails return the default
     280    return dateTime;
     281}
     282
     283void GalleryUtil::SetDateTimeDB(const QString &filePath, long dateTime)
     284{
     285    MSqlQuery query(MSqlQuery::InitCon());
     286    query.prepare(
     287        "UPDATE gallerymetadata "
     288        "SET datetime = :DATETIME "
     289        "WHERE image = :IMAGE LIMIT 1");
     290    query.bindValue(":IMAGE", filePath);
     291    query.bindValue(":DATETIME", QString::number(dateTime,10));
     292
     293    if (!query.exec())
     294        MythDB::DBError("set_datetime", query);
     295
     296    // Check if the update failed because of a missing database
     297    // entry. In this case we need to insert a new dataset.
     298    if (query.numRowsAffected() == 0)
     299    {
     300        query.prepare(
     301            "REPLACE INTO gallerymetadata "
     302            "SET image    = :IMAGE, "
     303            "    datetime = :DATETIME");
     304        query.bindValue(":IMAGE", filePath);
     305        query.bindValue(":DATETIME", QString::number(dateTime, 10));
     306
     307        if (!query.exec())
     308            MythDB::DBError("set_datetime", query);
     309    }
     310}
     311
     312void GalleryUtil::SetNaturalRotationDB(QString &filePath, long angle)
     313{   
     314    MSqlQuery query(MSqlQuery::InitCon());
     315    query.prepare(
     316        "UPDATE gallerymetadata "
     317        "SET angle = :ANGLE "
     318        "WHERE image = :IMAGE LIMIT 1");
     319    query.bindValue(":IMAGE", filePath);
     320    query.bindValue(":ANGLE", QString::number(angle, 10));
     321
     322    if (!query.exec())
     323        MythDB::DBError("set_rotation_angle", query);
     324
     325    // Check if the update failed because of a missing database
     326    // entry. In this case we need to insert a new dataset.
     327    if (query.numRowsAffected() == 0)
     328    {
     329        query.prepare(
     330            "REPLACE INTO gallerymetadata "
     331            "SET image = :IMAGE, "
     332            "    angle = :ANGLE");
     333        query.bindValue(":IMAGE", filePath);
     334        query.bindValue(":ANGLE", QString::number(angle, 10));
     335
     336        if (!query.exec())
     337            MythDB::DBError("set_datetime", query);
     338    }
     339}
     340
     341#ifdef EXIF_SUPPORT
     342QString GalleryUtil::GetExifHeaderTag(const QString &filePathString, ExifTag exifHeaderTag)
     343{
     344    QString value("");
    129345    QByteArray filePathBA = filePathString.toLocal8Bit();
     346
    130347    const char *filePath = filePathBA.constData();
    131 
    132348    try
    133349    {
    134 #ifdef EXIF_SUPPORT
     350        // get the exif header from the specified file
    135351        char *exifvalue = new char[1024];
    136352        ExifData *data = exif_data_new_from_file (filePath);
    137353        if (data)
    138354        {
     355            // we have some data, go through all available header
     356            // tags and stop when we have reached the desired tag
    139357            for (int i = 0; i < EXIF_IFD_COUNT; i++)
    140358            {
    141                     ExifEntry *entry = exif_content_get_entry (data->ifd[i],
    142                                                         EXIF_TAG_ORIENTATION);
     359                    ExifEntry *entry = exif_content_get_entry (data->ifd[i], exifHeaderTag);
    143360                    if (entry)
    144361                    {
     362                        // there is data in the desired header tag now get the
     363                        // value either by the new or standard exif library method
    145364#if NEW_LIB_EXIF
    146365                        exif_entry_get_value(entry, exifvalue, 1023);
    147                         QString value = exifvalue;
     366                        value = exifvalue;
    148367#else
    149                         QString value = exif_entry_get_value(entry);
     368                        value = exif_entry_get_value(entry);
    150369#endif
    151                         if (value == "left - bottom")
    152                         {
    153                           rotateAngle = -90;
    154                         }
    155                         else if (value == "right - top")
    156                         {
    157                           rotateAngle = 90;
    158                         }
    159370                        break;
    160371                    }
    161372            }
     
    169380        }
    170381       
    171382        delete [] exifvalue;
    172        
    173         /*
    174         Exiv2::ExifData exifData;
    175          int rc = exifData.read(filePath);
    176         if (!rc)
    177         {
    178             Exiv2::ExifKey key = Exiv2::ExifKey("Exif.Image.Orientation");
    179             Exiv2::ExifData::iterator pos = exifData.findKey(key);
    180             if (pos != exifData.end())
    181             {
    182                 long orientation = pos->toLong();
    183                 switch (orientation)
    184                 {
    185                     case 6:
    186                         rotateAngle = 90;
    187                         break;
    188                     case 8:
    189                         rotateAngle = -90;
    190                         break;
    191                     default:
    192                         rotateAngle = 0;
    193                         break;
    194                 }
    195             }
    196         }
    197         */
    198 #endif // EXIF_SUPPORT
    199383    }
    200384    catch (...)
    201385    {
     
    204388                .arg(filePathString));
    205389    }
    206390
    207     return rotateAngle;
     391    return value;
    208392}
     393#endif
    209394
    210395bool GalleryUtil::LoadDirectory(ThumbList& itemList, const QString& dir,
    211396                                int sortorder, bool recurse,
    212397                                ThumbHash *itemHash, ThumbGenerator* thumbGen)
    213398{
    214     QString blah = dir;
    215     QDir d(blah);
     399    QDir d(dir);
    216400    QString currDir = d.absolutePath();
    217401
    218402    bool isGallery;
     
    224408    if (thumbGen)
    225409        thumbGen->getThumbcacheDir(currDir);
    226410
    227     QFileInfoList list = d.entryInfoList(GetMediaFilter(),
    228                                          QDir::Files | QDir::AllDirs,
    229                                          (QDir::SortFlag)sortorder);
     411    // these are used more than once so declare them here.
     412    QFileInfoList list;
     413    QFileInfoList::const_iterator it;
     414    const QFileInfo *fi;
    230415
     416#ifdef EXIF_SUPPORT
     417    // check if the directories and files should be
     418    // sorted by creation time (exif header information)
     419    if (sortorder < 4096 )
     420    {
     421#endif
     422        // sort the usual way
     423        list = d.entryInfoList(GetMediaFilter(),
     424                            QDir::Files | QDir::AllDirs,
     425                            (QDir::SortFlag)sortorder);
     426#ifdef EXIF_SUPPORT
     427    }
     428    else
     429    {
     430        // These are the lists that will temporarily
     431        // contain the directories and the sorted files.
     432        QFileInfoList dirList;
     433        QFileInfoList fileList;
     434        QFileInfoList fileListExif;
     435        QMap<long, QFileInfo> fileListMap;
     436
     437        // fallback sorting order
     438        int tempsortorder = QDir::Name | QDir::DirsFirst | QDir::IgnoreCase;
     439        list = d.entryInfoList(GetMediaFilter(),
     440                            QDir::Files | QDir::AllDirs,
     441                            (QDir::SortFlag)tempsortorder);
     442
     443        // go through the list and get the exif time for each file
     444        it = list.begin();
     445        while (it != list.end())
     446        {
     447            fi = &(*it);
     448            ++it;
     449
     450            // get the directories alphabetically in the dirlist and
     451            // the files that have time information in the filelistmap.
     452            // The files that have no time information go into the filelist.
     453            // They will later be combined to get the big list again.
     454            if ( fi->isDir() )
     455            {
     456                dirList.append(*fi);
     457            }
     458            else
     459            {
     460                // load the date time from the database to speed up
     461                // the loading and sorting time. If the data is not available
     462                // add the exif header value in the database.
     463                bool ok = false;
     464                long dateTime = GetDateTimeDB(fi->canonicalFilePath(), &ok);
     465
     466                if (dateTime == 0 || !ok)
     467                {
     468                    // we dont have a value. try to get it from the exif header
     469                    dateTime = GetDateTime(fi->canonicalFilePath());
     470
     471                    // if we have a value then update the database
     472                    if ( dateTime > 0 )
     473                        SetDateTimeDB(fi->canonicalFilePath(), dateTime);
     474                }
     475
     476                // if we have the exif time, place the fileinfo object in the qmap
     477                // the map will automatically sort the entries by the time
     478                if ( dateTime > 0 )
     479                    fileListMap.insert(dateTime, *fi);
     480                else
     481                    fileList.append(*fi);
     482            }
     483        }
     484
     485        // the files with the time information will be placed in
     486        // the list in the order specified in the settings screen
     487        QMap<long, QFileInfo>::const_iterator i = fileListMap.constBegin();
     488        while (i != fileListMap.constEnd())
     489        {
     490            if ( sortorder == 0x1000 )
     491                // sort the files oldest first
     492                fileListExif.append( i.value() );
     493            else
     494                // sort the files newest first
     495                fileListExif.prepend( i.value() );
     496
     497            ++i;
     498        }
     499
     500        // the list has already the sorted files with the time
     501        // information in it. save the directories in the front
     502        // and put the remaining files at the end.
     503        list.clear();
     504        list = list.operator +( dirList );
     505        list = list.operator +( fileListExif );
     506        list = list.operator +( fileList );
     507    }
     508#endif
     509
    231510    if (list.isEmpty())
    232511        return false;
    233512
    234     QFileInfoList::const_iterator it = list.begin();
    235     const QFileInfo *fi;
    236 
    237513    if (thumbGen)
    238514    {
    239515        thumbGen->cancel();
    240516        thumbGen->setDirectory(currDir, isGallery);
    241517    }
    242518
     519    it = list.begin();
    243520    while (it != list.end())
    244521    {
    245522        fi = &(*it);
     
    275552                thumbGen->addFile(item->GetName());
    276553        }
    277554    }
    278 
    279555    return isGallery;
    280556}
    281557
    282 QString GalleryUtil::GetCaption(const QString &filePath)
    283 {
    284     QString caption("");
    285 
    286     try
    287     {
    288 #ifdef EXIF_SUPPORT
    289         char *exifvalue = new char[1024];
    290         ExifData *data = exif_data_new_from_file(
    291             filePath.toLocal8Bit().constData());
    292         if (data)
    293         {
    294             for (int i = 0; i < EXIF_IFD_COUNT; i++)
    295             {
    296                 ExifEntry *entry = exif_content_get_entry (data->ifd[i],
    297                                                     EXIF_TAG_USER_COMMENT);
    298                 if (entry)
    299                 {
    300 #if NEW_LIB_EXIF
    301                     exif_entry_get_value(entry, exifvalue, 1023);
    302                     caption = exifvalue;
    303 #else
    304                     caption = exif_entry_get_value(entry);
    305 #endif
    306                     // Found one, done
    307                     if(!caption.isEmpty())
    308                        break;
    309                 }
    310 
    311                 entry = exif_content_get_entry (data->ifd[i],
    312                                                 EXIF_TAG_IMAGE_DESCRIPTION);
    313                 if (entry)
    314                 {
    315 #if NEW_LIB_EXIF
    316                     exif_entry_get_value(entry, exifvalue, 1023);
    317                     caption = exifvalue;
    318 #else
    319                     caption = exif_entry_get_value(entry);
    320 #endif
    321                     // Found one, done
    322                     if(!caption.isEmpty())
    323                        break;
    324                 }
    325             }
    326             exif_data_free(data);
    327         }
    328         else
    329         {
    330            VERBOSE(VB_FILE, LOC_ERR +
    331                    QString("Could not load exif data from '%1'")
    332                    .arg(filePath));
    333         }
    334 
    335         delete [] exifvalue;
    336 #endif // EXIF_SUPPORT
    337     }
    338     catch (...)
    339     {
    340         VERBOSE(VB_IMPORTANT, LOC_ERR +
    341                 QString("Failed to extract EXIF headers from '%1'")
    342                 .arg(filePath));
    343     }
    344 
    345     return caption;
    346 }
    347 
    348558bool GalleryUtil::Copy(const QFileInfo &src, QFileInfo &dst)
    349559{
    350560    if (src.isDir())