File indexing completed on 2024-12-22 04:39:54

0001 /***************************************************************************
0002  *   Copyright (C) 2005-2014 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 #include "framethumbview.h"
0021 
0022 #include "framebar.h"
0023 #include "logger.h"
0024 #include "thumbdragger.h"
0025 #include "thumbview.h"
0026 #include "filenamesfromurlsiterator.h"
0027 #include "src/domain/domainfacade.h"
0028 #include "graphics/icons/note.xpm"
0029 
0030 #include <QApplication>
0031 #include <QPainter>
0032 #include <QStringList>
0033 #include <QMouseEvent>
0034 #include <QPixmap>
0035 #include <QPaintEvent>
0036 #include <QDropEvent>
0037 #include <QDrag>
0038 #include <QMimeData>
0039 #include <QList>
0040 #include <QUrl>
0041 
0042 class QWidget;
0043 
0044 
0045 FrameThumbView::FrameThumbView(FrameBar *frameBar, QWidget *parent, int number,
0046         const char *name)
0047         : ThumbView(frameBar, parent, number, name) {
0048     stringNumber = QString("%1").arg(number + 1);
0049     textWidth = 5 + stringNumber.length() * 8;
0050     selected = false;
0051     hasSounds = false;
0052 }
0053 
0054 
0055 FrameThumbView::~FrameThumbView() {
0056 }
0057 
0058 
0059 void FrameThumbView::mousePressEvent( QMouseEvent * e ) {
0060     if (e->button() == Qt::LeftButton) {
0061         if ( !getFrameBar()->isSelecting() ) {
0062             int selectionFrame = getFrameBar()->getSelectionAnchor();
0063             int activeScene = getFrameBar()->getActiveScene();
0064             int activeFrame = getFrameBar()->getActiveFrame();
0065             int highend = (selectionFrame > activeFrame ) ? selectionFrame : activeFrame;
0066             int lowend = (selectionFrame < activeFrame ) ? selectionFrame : activeFrame;
0067             
0068             // If the user presses inside the selection area this shouldn't trigger
0069             // setActiveFrame before the mouse button is released. The reason for this is
0070             // to give the user a chance to drag the items. See mouseReleaseEvent(...)
0071             if (getNumber() > highend || getNumber() < lowend) {
0072                 getFrameBar()->updateNewActiveFrame(activeScene, getNumber());
0073             }
0074             dragPos = e->pos();
0075         } else {
0076             getFrameBar()->setSelection(getNumber());
0077         }
0078     }
0079 }
0080 
0081 
0082 void FrameThumbView::mouseReleaseEvent( QMouseEvent * e ) {
0083     Logger::get().logDebug("Releasing mouse button inside thumbview");
0084     if (e->button() == Qt::LeftButton) {
0085         if ( !getFrameBar()->isSelecting() ) {
0086             int selectionFrame = getFrameBar()->getSelectionAnchor();
0087             int activeScene = getFrameBar()->getActiveScene();
0088             int activeFrame = getFrameBar()->getActiveFrame();
0089             int highend = (selectionFrame > activeFrame ) ? selectionFrame : activeFrame;
0090             int lowend = (selectionFrame < activeFrame ) ? selectionFrame : activeFrame;
0091             if (getNumber() <= highend || getNumber() >= lowend) {
0092                 getFrameBar()->updateNewActiveFrame(activeScene, getNumber());
0093             }
0094         }
0095     }
0096 }
0097 
0098 
0099 void FrameThumbView::mouseMoveEvent(QMouseEvent *me) {
0100     if (me->buttons() & Qt::LeftButton) {
0101         int distance = (me->pos() - dragPos).manhattanLength();
0102         if (distance > QApplication::startDragDistance()) {
0103             startDrag();
0104         }
0105     }
0106     QLabel::mouseMoveEvent(me);
0107 }
0108 
0109 
0110 void FrameThumbView::mouseDoubleClickEvent( QMouseEvent * ) {
0111     getFrameBar()->showPreferencesMenu();
0112 }
0113 
0114 
0115 void FrameThumbView::paintEvent (QPaintEvent * paintEvent) {
0116     QLabel::paintEvent(paintEvent);
0117     QPainter painter( this );
0118     
0119     if (selected) {
0120         painter.fillRect( 4, 5, textWidth, 14, QBrush(Qt::white) );
0121         painter.setPen( Qt::black );
0122     } else {
0123         painter.fillRect( 4, 5, textWidth, 14, QBrush(Qt::black) );
0124         painter.setPen( Qt::white );
0125     }
0126         
0127     painter.drawText(5, 17, stringNumber);
0128     
0129     if (this->hasSounds) {
0130         painter.drawPixmap( width() - 32, 0, QPixmap(note) );
0131     }
0132 }
0133     
0134 
0135 void FrameThumbView::startDrag() {
0136     // If the drag ends on a scene this tells the scene that it is frames that
0137     // are being moved.
0138     getFrameBar()->setMovingScene(-1);
0139 
0140     QList<QUrl> urls;
0141 
0142     int selectionFrame = getFrameBar()->getSelectionAnchor();
0143     int activeScene = getFrameBar()->getActiveScene();
0144     int activeFrame = getFrameBar()->getActiveFrame();
0145     int highend = (selectionFrame > activeFrame ) ? selectionFrame : activeFrame;
0146     int lowend = (selectionFrame < activeFrame ) ? selectionFrame : activeFrame;
0147     DomainFacade* facade = DomainFacade::getFacade();
0148     for (int i = lowend; i <= highend; ++i) {
0149         const char* imagePath = facade->getImagePath(activeScene, i);
0150         if (imagePath)
0151             urls.append(QUrl::fromLocalFile(imagePath));
0152     }
0153 
0154     QDrag *drag = new ThumbDragger(this);
0155     QMimeData *mimeData = new QMimeData;
0156 
0157     mimeData->setUrls(urls);
0158     drag->setMimeData(mimeData);
0159 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
0160     drag->setPixmap(pixmap(Qt::ReturnByValue));
0161 #else
0162     drag->setPixmap(*pixmap());
0163 #endif
0164 
0165     drag->exec(Qt::MoveAction);
0166 }
0167 
0168 
0169 void FrameThumbView::setHasSounds( bool hasSounds ) {
0170     this->hasSounds = hasSounds;
0171     update();
0172 }
0173 
0174 
0175 void FrameThumbView::setNumber( int number ) {
0176     ThumbView::setNumber(number);
0177     stringNumber = QString("%1").arg(number + 1);
0178     textWidth = 5 + stringNumber.length() * 8;
0179     update();
0180 }
0181 
0182 
0183 void FrameThumbView::setSelected(bool selected) {
0184     this->selected = selected;
0185     if (selected) {
0186         setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
0187         setLineWidth(5);
0188         setMidLineWidth(6);
0189     } else {
0190         setFrameShape(QFrame::NoFrame);
0191     }
0192 }
0193 
0194 /**
0195  * Moves the frames dropped to just after this frame if the frames are being
0196  * moved to the right, or just before this frame if the frames are being moved
0197  * to the left. This slightly bizarre behaviour feels right to users who expect
0198  * a moved frame to appear where they dropped it.
0199  */
0200 void FrameThumbView::contentsDropped(QDropEvent * event) {
0201     DomainFacade* facade = DomainFacade::getFacade();
0202     int activeScene = getFrameBar()->getActiveScene();
0203     if (event->source() == 0) {
0204         Logger::get().logDebug("Adding picture(s)");
0205         if ( event->mimeData()->hasUrls() ) {
0206             QList<QUrl> urls = event->mimeData()->urls();
0207             FileNamesFromUrlsIterator fNames(urls.begin(), urls.end());
0208             DomainFacade::getFacade()->addFrames(activeScene, getNumber(), fNames);
0209         }
0210     } else if (getFrameBar()->getMovingScene() == -1) {
0211         Logger::get().logDebug("Moving picture");
0212         int selectionFrame = getFrameBar()->getSelectionAnchor();
0213         int activeFrame = getFrameBar()->getActiveFrame();
0214         int highend = (selectionFrame > activeFrame)?
0215                 selectionFrame : activeFrame;
0216         int lowend = (selectionFrame < activeFrame )?
0217                 selectionFrame : activeFrame;
0218         int destination = activeFrame < getNumber()? getNumber() + 1 : getNumber();
0219         facade->moveFrames(activeScene, lowend,
0220                 highend - lowend + 1, activeScene, destination);
0221     }
0222 }