File indexing completed on 2024-05-26 04:59:15

0001 /***************************************************************************
0002  *   Copyright (C) 2005-2017 by Linuxstopmotion contributors;              *
0003  *   see the AUTHORS file for details.                                     *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 
0021 #include "scenethumbview.h"
0022 
0023 #include "logger.h"
0024 #include "thumbdragger.h"
0025 #include "filenamesfromurlsiterator.h"
0026 #include "framebar.h"
0027 #include "scenearrowbutton.h"
0028 #include "thumbview.h"
0029 #include "graphics/icons/clapper.xpm"
0030 #include "src/domain/domainfacade.h"
0031 
0032 #include <QApplication>
0033 #include <QDropEvent>
0034 #include <QIcon>
0035 #include <QImage>
0036 #include <QList>
0037 #include <QMimeData>
0038 #include <QMouseEvent>
0039 #include <QPaintEvent>
0040 #include <QPainter>
0041 #include <QPixmap>
0042 #include <QPushButton>
0043 #include <QStringList>
0044 #include <QUrl>
0045 
0046 class QWidget;
0047 
0048 SceneThumbView::SceneThumbView(FrameBar *frameBar, QWidget *parent, int number,
0049         const char * name)
0050         : ThumbView(frameBar, parent, number, name) {
0051     this->isOpened = false;
0052 
0053     arrowButton = new SceneArrowButton(this);
0054     int width = getFrameBar()->getFrameWidth();
0055     int height = getFrameBar()->getFrameHeight();
0056     arrowButton->setGeometry( width - width / 4, height / 9, width / 6, width / 6 );
0057     arrowButton->show();
0058     QObject::connect( arrowButton, SIGNAL(clicked()), this, SLOT(closeScene()) );
0059 
0060     f.setPointSize(12);
0061     centerIcon = QPixmap(clapper);
0062 }
0063 
0064 
0065 SceneThumbView::~SceneThumbView() {
0066 }
0067 
0068 
0069 void SceneThumbView::setOpened( bool isOpened ) {
0070     this->isOpened = isOpened;
0071     arrowButton->setOpened(isOpened);
0072     DomainFacade* facade = DomainFacade::getFacade();
0073     if (!isOpened && (facade->getSceneSize(getNumber()) > 0)) {
0074         const char *path = facade->getImagePath(getNumber(), 0);
0075         if (path) {
0076             QImage half = QImage(path).scaled(width() / 2, height() / 2);
0077             centerIcon = QPixmap::fromImage(half);
0078         }
0079     } else {
0080         centerIcon = QPixmap(clapper);
0081     }
0082     this->update();
0083 }
0084 
0085 
0086 bool SceneThumbView::getIsOpened() const {
0087     return isOpened;
0088 }
0089 
0090 
0091 /**
0092  * @todo the width can be cached somewhere so that the function width() don't have
0093  * to be called for every frame and scene thumbview.
0094  */
0095 void SceneThumbView::paintEvent ( QPaintEvent * ) {
0096     int width = this->width();
0097 
0098     QPainter paint(this);
0099     paint.setPen(Qt::black);
0100     paint.setFont(f);
0101     paint.drawText( 7, width / 4, QString("%1").arg(getNumber() + 1) );
0102 
0103     if (!isOpened && (DomainFacade::getFacade()->getSceneSize(getNumber()) > 0) ) {
0104         paint.drawPixmap(width / 4, width / 3, centerIcon);
0105     }
0106     else {
0107         paint.drawPixmap(width / 2 - 16, width / 2 - 10, centerIcon);
0108     }
0109 }
0110 
0111 
0112 void SceneThumbView::mousePressEvent(QMouseEvent *e) {
0113     //For calculating the manhattan length to avoid unwanted drags.
0114     dragPos = e->pos();
0115 }
0116 
0117 
0118 void SceneThumbView::mouseReleaseEvent( QMouseEvent * ) {
0119     getFrameBar()->updateNewActiveScene(getNumber());
0120 }
0121 
0122 
0123 void SceneThumbView::mouseMoveEvent(QMouseEvent * me) {
0124     // it should probably be me->button() here...
0125     if (me->buttons() & Qt::LeftButton) {
0126         int distance = (me->pos() - dragPos).manhattanLength();
0127         if (distance > QApplication::startDragDistance()) {
0128             startDrag();
0129         }
0130     }
0131     QLabel::mouseMoveEvent(me);
0132 }
0133 
0134 
0135 void SceneThumbView::startDrag() {
0136     Logger::get().logDebug("Starting drag of the scene");
0137     getFrameBar()->setMovingScene(getNumber());
0138 
0139     QDrag *drag = new ThumbDragger(this);
0140     QMimeData *mimeData = new QMimeData;
0141     QList<QUrl> urls;
0142     mimeData->setUrls(urls);
0143     drag->setMimeData(mimeData);
0144     drag->setPixmap(centerIcon);
0145 
0146     drag->exec(Qt::MoveAction);
0147 }
0148 
0149 
0150 void SceneThumbView::closeScene() {
0151     if ( getNumber() >= 0) {
0152         if (getFrameBar()->getActiveScene() == getNumber() && getNumber() > 0) {
0153             getFrameBar()->updateNewActiveScene(getNumber() - 1);
0154         } else {
0155             getFrameBar()->updateNewActiveScene(getNumber());
0156         }
0157     }
0158 }
0159 
0160 
0161 /**
0162  * Scenes should be dropped after this frame if moving right or before if
0163  * moving left. This makes sense to users, who expect the dropped scene to
0164  * appear where they dropped it. Frames should always move to the start of the
0165  * scene they are dropped in.
0166  */
0167 void SceneThumbView::contentsDropped(QDropEvent *event) {
0168     DomainFacade* facade = DomainFacade::getFacade();
0169     int sceneNumber = getNumber();
0170     int movingScene = getFrameBar()->getMovingScene();
0171     int activeScene= getFrameBar()->getActiveScene();
0172     if (event->source() == 0) {
0173         if ( event->mimeData()->hasUrls() ) {
0174             QList<QUrl> urls = event->mimeData()->urls();
0175             FileNamesFromUrlsIterator fNames(urls.begin(), urls.end());
0176             DomainFacade::getFacade()->addFrames(getNumber(), 0, fNames);
0177         }
0178     } else if (movingScene == -1) {
0179         // moving frames into a scene
0180         int selectionFrame = getFrameBar()->getSelectionAnchor();
0181         int activeFrame = getFrameBar()->getActiveFrame();
0182         int highend = (selectionFrame > activeFrame)?
0183                 selectionFrame : activeFrame;
0184         int lowend = (selectionFrame < activeFrame )?
0185                 selectionFrame : activeFrame;
0186         bool movingRight = activeScene < sceneNumber;
0187         if (movingRight || sceneNumber == 0) {
0188             facade->moveFrames(activeScene, lowend,
0189                     highend - lowend + 1, sceneNumber, 0);
0190         } else {
0191             int sceneDest = sceneNumber - 1;
0192             int sceneSize = DomainFacade::getFacade()->getSceneSize(sceneDest);
0193             facade->moveFrames(activeScene, lowend,
0194                     highend - lowend + 1, sceneDest, sceneSize);
0195         }
0196     } else if (movingScene != sceneNumber) {
0197         Logger::get().logDebug("Moving scene");
0198         int destination = movingScene < sceneNumber?
0199                 sceneNumber + 1 : sceneNumber;
0200         facade->moveScene(movingScene, destination);
0201     }
0202 }