image_strip_scene.cpp 6.08 KB
Newer Older
1 2 3
/*
 *  Copyright (c) 2011 Silvio Heinrich <plassy@web.de>
 *
4
 *  This library is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU Lesser General Public License as published by
6
 *  the Free Software Foundation; version 2.1 of the License.
7
 *
8
 *  This library is distributed in the hope that it will be useful,
9 10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU Lesser General Public License for more details.
12 13 14 15 16 17
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

18
#include "image_strip_scene.h"
19

20 21
#include <KoIcon.h>

22
#include <QApplication>
23 24 25 26 27 28 29
#include <QDir>
#include <QPainter>
#include <QHash>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsLinearLayout>
#include <QGraphicsWidget>
#include <QMutexLocker>
30
#include <QDebug>
31 32

/////////////////////////////////////////////////////////////////////////////////////////////
33
// ------------- ImageLoader ---------------------------------------------------------- //
34

35 36 37 38 39 40 41
ImageLoader::ImageLoader(float size)
    : m_size(size)
    , m_run(true)
{
    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(stopExecution()));
}

42
void ImageLoader::run()
43
{
44
    typedef QHash<ImageItem*,Data>::iterator Iterator;
45
    
46 47 48 49
    for (Iterator data = m_data.begin(); data != m_data.end() && m_run; ++data) {
        QImage img = QImage(data->path);
        if (!img.isNull()) {
            data->image = img.scaled(m_size, m_size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
50
        }
51
        //qDebug() << "Loaded" << data->path;
52 53 54
        data->isLoaded = true;
        emit sigItemContentChanged(data.key());
    }
55 56 57 58 59
}

void ImageLoader::stopExecution()
{
    m_run = false;
60 61 62 63
}


/////////////////////////////////////////////////////////////////////////////////////////////
64
// ------------- ImageItem ------------------------------------------------------------ //
65

66
void ImageItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
67 68 69 70
{
    Q_UNUSED(option);
    Q_UNUSED(widget);
    
71
    if (m_loader->isImageLoaded(this)) {
72 73
        QImage  image = m_loader->getImage(this);
        
74
        if (!image.isNull()) {
75 76 77 78
            QPointF offset((m_size-image.width()) / 2.0, (m_size-image.height()) / 2.0);
            painter->drawImage(offset, image);
        }
        else {
79
            QIcon   icon = koIcon("image-missing");
80 81 82 83 84 85
            QRect   rect = boundingRect().toRect();
            QPixmap img  = icon.pixmap(rect.size());
            painter->drawPixmap(rect, img, img.rect());
        }
    }
    else {
86
        QIcon   icon = koIcon("image-loading");
87 88 89 90 91
        QRect   rect = boundingRect().toRect();
        QPixmap img  = icon.pixmap(rect.size());
        painter->drawPixmap(rect, img, img.rect());
    }
    
92
    if (isSelected()) {
93 94 95 96
        painter->setCompositionMode(QPainter::CompositionMode_HardLight);
        painter->setOpacity(0.50);
        painter->fillRect(boundingRect().toRect(), palette().color(QPalette::Active, QPalette::Highlight));
        painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
97 98 99
        QPen pen(palette().color(QPalette::Active, QPalette::Highlight), 3);
        painter->setPen(pen);
    }
100 101 102 103
    
    painter->drawRect(boundingRect());
}

104
QSizeF ImageItem::sizeHint(Qt::SizeHint /*which*/, const QSizeF& /*constraint*/) const
105 106 107 108 109 110
{
    return QSizeF(m_size, m_size);
}


/////////////////////////////////////////////////////////////////////////////////////////////
111
// ------------- ImageStripScene ------------------------------------------------------ //
112

113
ImageStripScene::ImageStripScene():
Boudewijn Rempt's avatar
Boudewijn Rempt committed
114 115 116 117 118 119 120 121 122
    m_imgSize(80)
  , m_loader(0)
{
}

ImageStripScene::~ImageStripScene()
{
    delete m_loader;
}
123

124
bool ImageStripScene::setCurrentDirectory(const QString& path)
125
{
126
    m_path = path;
127 128 129 130
    QMutexLocker locker(&m_mutex);
    QDir         directory(path);
    QImageReader reader;
    
131
    if (directory.exists()) {
132 133
        clear();
        
134
        if (m_loader) {
135 136 137
            m_loader->disconnect(this);
            m_loader->stopExecution();
            
138
            if (!m_loader->wait(500)) {
139 140 141 142 143 144 145 146
                m_loader->terminate();
                m_loader->wait();
            }
        }
        
        delete m_loader;
        
        m_numItems = 0;
147 148
        m_loader   = new ImageLoader(m_imgSize);
        connect(m_loader, SIGNAL(sigItemContentChanged(ImageItem*)), SLOT(slotItemContentChanged(ImageItem*)));
149 150 151 152
        
        QStringList            files  = directory.entryList(QDir::Files);
        QGraphicsLinearLayout* layout = new QGraphicsLinearLayout();
        
153
        for (QStringList::iterator name=files.begin(); name!=files.end(); ++name) {
154
            QString path = directory.absoluteFilePath(*name);
155 156 157 158 159 160 161
            QString fileExtension = QFileInfo(path).suffix();

            if (!fileExtension.compare("DNG", Qt::CaseInsensitive)) {
                qWarning() << "WARNING: Qt is known to crash when trying to open a DNG file. Skip it";
                continue;
            }

162
            reader.setFileName(path);
163 164

            if(reader.canRead()) {
165
                ImageItem* item = new ImageItem(m_imgSize, path, m_loader);
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
                m_loader->addPath(item, path);
                layout->addItem(item);
                ++m_numItems;
            }
        }
        
        QGraphicsWidget* widget = new QGraphicsWidget();
        widget->setLayout(layout);
        widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        
        addItem(widget);
        setSceneRect(widget->boundingRect());
        
        m_loader->start(QThread::LowPriority);
        return true;
    }
    
    return false;
}

186
void ImageStripScene::slotItemContentChanged(ImageItem* item)
187 188 189 190 191
{
    QMutexLocker locker(&m_mutex);
    item->update();
}

192
void ImageStripScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
193
{
194
    ImageItem* item = static_cast<ImageItem*>(itemAt(event->scenePos()));
195
    
196
    if (item)
197 198
        emit sigImageActivated(item->path());
}
199