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 }