File indexing completed on 2024-04-28 05:38:13
0001 /*************************************************************************** 0002 * Copyright (C) 2007 by Romain Campioni * 0003 * Copyright (C) 2009 by Renaud Guezennec * 0004 * https://rolisteam.org/contact * 0005 * * 0006 * rolisteam is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 * This program is distributed in the hope that it will be useful, * 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0014 * GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License * 0017 * along with this program; if not, write to the * 0018 * Free Software Foundation, Inc., * 0019 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0020 ***************************************************************************/ 0021 0022 #include <QDebug> 0023 #include <QScrollBar> 0024 #include <QShortcut> 0025 #include <QtGui> 0026 0027 #include "controller/view_controller/imagecontroller.h" 0028 #include "image.h" 0029 #include "network/clientconnection.h" 0030 #include "network/networkmessagewriter.h" 0031 //#include "widgets/onlinepicturedialog.h" 0032 0033 /********************************************************************/ 0034 /* Constructeur */ 0035 /********************************************************************/ 0036 Image::Image(ImageController* ctrl, QWidget* parent) 0037 : MediaContainer(ctrl, MediaContainer::ContainerType::ImageContainer, parent) 0038 , m_ctrl(ctrl) 0039 , m_imageLabel(new QLabel()) 0040 , m_widgetArea(new QScrollArea()) 0041 , m_NormalSize(0, 0) 0042 { 0043 setObjectName("Image"); 0044 connect(m_ctrl, &ImageController::zoomLevelChanged, this, &Image::resizeLabel); 0045 connect(m_ctrl, &ImageController::fitWindowChanged, this, &Image::fitWindow); 0046 connect(m_ctrl, &ImageController::pixmapChanged, this, &Image::initImage); 0047 connect(m_ctrl, &ImageController::cursorChanged, this, [this]() { m_imageLabel->setCursor(m_ctrl->cursor()); }); 0048 0049 setWindowIcon(QIcon::fromTheme("image-x-generic")); 0050 createActions(); 0051 0052 if(m_ctrl && m_ctrl->isMovie()) 0053 addAction(m_playAct); 0054 0055 connect(m_ctrl, &ImageController::nameChanged, this, 0056 [this]() { setWindowTitle(tr("%1 - Image").arg(m_ctrl->name())); }); 0057 0058 m_widgetArea->setAlignment(Qt::AlignCenter); 0059 m_imageLabel->setLineWidth(0); 0060 m_imageLabel->setFrameStyle(QFrame::NoFrame); 0061 m_widgetArea->setWidget(m_imageLabel); 0062 m_fitWindowAct->setChecked(m_preferences->value("PictureAdjust", true).toBool()); 0063 setWidget(m_widgetArea.get()); 0064 initImage(); 0065 if(m_ctrl) 0066 setWindowTitle(tr("%1 - Image").arg(m_ctrl->name())); 0067 } 0068 0069 Image::~Image()= default; 0070 0071 void Image::initImage() 0072 { 0073 if(!m_ctrl || m_ctrl->pixmap().isNull()) 0074 return; 0075 0076 auto pixmap= m_ctrl->pixmap(); 0077 0078 m_imageLabel->setPixmap(m_ctrl->scaledPixmap()); 0079 m_imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); 0080 m_imageLabel->setScaledContents(true); 0081 m_imageLabel->resize(pixmap.size()); 0082 fitWorkSpace(); 0083 fitWindow(); 0084 } 0085 0086 void Image::mousePressEvent(QMouseEvent* event) 0087 { 0088 if(event->button() == Qt::LeftButton) 0089 { 0090 m_allowedMove= true; 0091 m_startingPoint= event->pos(); 0092 m_horizontalStart= m_widgetArea->horizontalScrollBar()->value(); 0093 m_verticalStart= m_widgetArea->verticalScrollBar()->value(); 0094 } 0095 QMdiSubWindow::mousePressEvent(event); 0096 } 0097 0098 void Image::mouseReleaseEvent(QMouseEvent* event) 0099 { 0100 if(event->button() == Qt::LeftButton) 0101 { 0102 m_allowedMove= false; 0103 } 0104 0105 QMdiSubWindow::mouseReleaseEvent(event); 0106 } 0107 0108 void Image::mouseMoveEvent(QMouseEvent* event) 0109 { 0110 if(m_allowedMove) 0111 { 0112 QPoint diff= m_startingPoint - event->pos(); 0113 m_widgetArea->horizontalScrollBar()->setValue(m_horizontalStart + diff.x()); 0114 m_widgetArea->verticalScrollBar()->setValue(m_verticalStart + diff.y()); 0115 } 0116 QMdiSubWindow::mouseMoveEvent(event); 0117 } 0118 0119 void Image::resizeLabel() 0120 { 0121 if(m_fitWindowAct->isChecked()) 0122 { 0123 int w= m_widgetArea->viewport()->rect().width(); 0124 int h= m_widgetArea->viewport()->rect().height(); 0125 if(w > h * m_ctrl->ratioV()) 0126 { 0127 m_imageLabel->resize(static_cast<int>(h * m_ctrl->ratioV()), h); 0128 } 0129 else 0130 { 0131 m_imageLabel->resize(w, static_cast<int>(w * m_ctrl->ratioH())); 0132 } 0133 } 0134 else if((m_NormalSize.height() != 0) && (m_NormalSize.width() != 0)) 0135 { 0136 m_imageLabel->resize(m_ctrl->zoomLevel() * m_NormalSize); 0137 } 0138 else 0139 { 0140 m_imageLabel->resize(m_ctrl->zoomLevel() * m_ctrl->pixmap().size()); 0141 m_NormalSize= widget()->size(); 0142 } 0143 } 0144 0145 void Image::fitWorkSpace() 0146 { 0147 /* Better computation 0148 * if(nullptr!=parentWidget()) 0149 { 0150 QSize windowsize = parentWidget()->size();//right size 0151 while((windowsize.height()<(m_zoomLevel * m_pixMap.height()))||(windowsize.width()<(m_zoomLevel * 0152 m_pixMap.width()))) 0153 { 0154 m_zoomLevel -= 0.05; 0155 } 0156 setGeometry(0,0,m_pixMap.width()*m_zoomLevel,m_pixMap.height()*m_zoomLevel); 0157 m_imageLabel->resize(m_pixMap.size()); 0158 m_NormalSize = QSize(0,0); 0159 resizeLabel(); 0160 m_zoomLevel = 1.0; 0161 }*/ 0162 0163 if(nullptr == parentWidget() || m_ctrl->isMovie()) 0164 return; 0165 0166 auto pixmap= m_ctrl->pixmap(); 0167 0168 QSize windowsize= parentWidget()->size(); // right size 0169 while((windowsize.height() < (m_ctrl->zoomLevel() * pixmap.height())) 0170 || (windowsize.width() < (m_ctrl->zoomLevel() * pixmap.width()))) 0171 { 0172 m_ctrl->zoomOut(0.1); 0173 } 0174 m_imageLabel->resize(pixmap.size()); 0175 m_NormalSize= QSize(0, 0); 0176 resizeLabel(); 0177 setGeometry(m_imageLabel->rect().adjusted(0, 0, 4, 4)); 0178 m_ctrl->setZoomLevel(1.0); 0179 } 0180 void Image::wheelEvent(QWheelEvent* event) 0181 { 0182 if(event->modifiers() == Qt::ControlModifier) 0183 { 0184 int delta= event->angleDelta().y(); 0185 (delta > 0) ? m_ctrl->zoomIn() : m_ctrl->zoomOut(); 0186 event->ignore(); 0187 } 0188 QMdiSubWindow::wheelEvent(event); 0189 } 0190 0191 void Image::paintEvent(QPaintEvent* event) 0192 { 0193 QMdiSubWindow::paintEvent(event); 0194 if(m_ctrl->fitWindow()) 0195 { 0196 resizeLabel(); 0197 } 0198 else if((m_NormalSize * m_ctrl->zoomLevel()) != m_imageLabel->size()) 0199 { 0200 m_NormalSize= m_imageLabel->size() / m_ctrl->zoomLevel(); 0201 m_windowSize= size(); 0202 } 0203 } 0204 0205 void Image::updateTitle() 0206 { 0207 setWindowTitle(tr("%1 - (Picture)").arg(m_ctrl->name())); 0208 } 0209 0210 void Image::createActions() 0211 { 0212 m_actionZoomIn= new QAction(tr("Zoom In"), this); 0213 m_actionZoomIn->setToolTip(tr("increase zoom level")); 0214 m_actionZoomIn->setIcon(QIcon::fromTheme("zoom-in-32")); 0215 connect(m_actionZoomIn, &QAction::triggered, this, [this] { m_ctrl->zoomIn(); }); 0216 0217 m_zoomInShort= new QShortcut(QKeySequence(tr("Ctrl++", "Zoom In")), this); 0218 m_zoomInShort->setContext(Qt::WidgetWithChildrenShortcut); 0219 connect(m_zoomInShort, &QShortcut::activated, this, [this] { m_ctrl->zoomIn(); }); 0220 m_actionZoomIn->setShortcut(m_zoomInShort->key()); 0221 0222 m_actionZoomOut= new QAction(tr("Zoom out"), this); 0223 m_actionZoomOut->setIcon(QIcon::fromTheme("zoom-out-32")); 0224 m_actionZoomOut->setToolTip(tr("Reduce zoom level")); 0225 connect(m_actionZoomOut, &QAction::triggered, this, [this] { m_ctrl->zoomOut(); }); 0226 0227 m_zoomOutShort= new QShortcut(QKeySequence(tr("Ctrl+-", "Zoom Out")), this); 0228 m_zoomOutShort->setContext(Qt::WidgetWithChildrenShortcut); 0229 connect(m_zoomOutShort, &QShortcut::activated, this, [this] { m_ctrl->zoomOut(); }); 0230 m_actionZoomOut->setShortcut(m_zoomOutShort->key()); 0231 0232 auto fitWorkspace= [this] { 0233 m_imageLabel->resize(parentWidget()->size()); 0234 fitWorkSpace(); 0235 }; 0236 0237 m_actionfitWorkspace= new QAction(tr("Fit the workspace"), this); 0238 m_actionfitWorkspace->setIcon(QIcon::fromTheme("fit-page")); 0239 m_actionfitWorkspace->setToolTip(tr("The window and the image fit the workspace")); 0240 connect(m_actionfitWorkspace, &QAction::triggered, this, fitWorkspace); 0241 0242 m_fitShort= new QShortcut(QKeySequence(tr("Ctrl+m", "Fit the workspace")), this); 0243 m_fitShort->setContext(Qt::WidgetWithChildrenShortcut); 0244 connect(m_fitShort, &QShortcut::activated, this, fitWorkspace); 0245 m_actionfitWorkspace->setShortcut(m_fitShort->key()); 0246 0247 auto setFitWindow= [this] { m_ctrl->setFitWindow(!m_ctrl->fitWindow()); }; 0248 0249 m_fitWindowAct= new QAction(tr("Fit Window"), this); 0250 m_fitWindowAct->setCheckable(true); 0251 connect(m_ctrl, &ImageController::fitWindowChanged, this, 0252 [this] { m_fitWindowAct->setChecked(m_ctrl->fitWindow()); }); 0253 m_fitWindowAct->setIcon(QIcon::fromTheme("fit-window")); 0254 m_fitWindowAct->setToolTip(tr("Image will take the best dimension to fit the window.")); 0255 connect(m_fitWindowAct, &QAction::triggered, this, setFitWindow); 0256 0257 m_fitWindowShort= new QShortcut(QKeySequence(tr("Ctrl+f", "Fit the window")), this); 0258 m_fitWindowShort->setContext(Qt::WidgetWithChildrenShortcut); 0259 connect(m_fitWindowShort, &QShortcut::activated, this, setFitWindow); 0260 m_fitWindowAct->setShortcut(m_fitWindowShort->key()); 0261 0262 auto zoomLittle= [this] { m_ctrl->setZoomLevel(0.2); }; 0263 0264 m_actionlittleZoom= new QAction(tr("Little"), this); 0265 m_actionlittleZoom->setToolTip(tr("Set the zoom level at 20% ")); 0266 connect(m_actionlittleZoom, &QAction::triggered, this, zoomLittle); 0267 0268 m_littleShort= new QShortcut(QKeySequence(tr("Ctrl+l", "Set the zoom level at 20%")), this); 0269 m_littleShort->setContext(Qt::WidgetWithChildrenShortcut); 0270 connect(m_littleShort, &QShortcut::activated, this, zoomLittle); 0271 m_actionlittleZoom->setShortcut(m_littleShort->key()); 0272 0273 auto zoomNormal= [this] { m_ctrl->setZoomLevel(1.0); }; 0274 0275 m_actionNormalZoom= new QAction(tr("Normal"), this); 0276 m_actionNormalZoom->setToolTip(tr("No Zoom")); 0277 connect(m_actionNormalZoom, &QAction::triggered, this, zoomNormal); 0278 0279 m_normalShort= new QShortcut(QKeySequence(tr("Ctrl+n", "Normal")), this); 0280 m_normalShort->setContext(Qt::WidgetWithChildrenShortcut); 0281 connect(m_normalShort, &QShortcut::activated, this, zoomNormal); 0282 m_actionNormalZoom->setShortcut(m_normalShort->key()); 0283 0284 auto zoomBig= [this] { m_ctrl->setZoomLevel(4.0); }; 0285 0286 m_actionBigZoom= new QAction(tr("Big"), this); 0287 m_actionBigZoom->setToolTip(tr("Set the zoom level at 400%")); 0288 connect(m_actionBigZoom, &QAction::triggered, this, zoomBig); 0289 0290 m_bigShort= new QShortcut(QKeySequence(tr("Ctrl+b", "Zoom Out")), this); 0291 m_bigShort->setContext(Qt::WidgetWithChildrenShortcut); 0292 connect(m_bigShort, &QShortcut::activated, this, zoomBig); 0293 m_actionBigZoom->setShortcut(m_bigShort->key()); 0294 0295 0296 m_rename = new QAction(tr("Rename"), this); 0297 m_rename->setShortcut(Qt::Key_F2); 0298 connect(m_rename, &QAction::triggered, this, [this](){ 0299 auto text = QInputDialog::getText(this, tr("Define the new name"), tr("New name:"),QLineEdit::Normal,m_ctrl->name()); 0300 if(text.isEmpty()) 0301 return; 0302 m_ctrl->setName(text); 0303 }); 0304 0305 m_playAct= new QAction(tr("Play"), this); 0306 m_playAct->setShortcut(Qt::Key_Space); 0307 m_stopAct= new QAction(tr("Stop"), this); 0308 0309 connect(m_ctrl, &ImageController::statusChanged, this, [this](ImageController::Status status) { 0310 switch(status) 0311 { 0312 case ImageController::Playing: 0313 m_playAct->setText(tr("Pause")); 0314 m_stopAct->setEnabled(true); 0315 break; 0316 case ImageController::Paused: 0317 m_playAct->setText(tr("Play")); 0318 m_stopAct->setEnabled(true); 0319 break; 0320 case ImageController::Stopped: 0321 m_stopAct->setEnabled(false); 0322 m_playAct->setText(tr("Play")); 0323 break; 0324 } 0325 }); 0326 0327 connect(m_playAct, &QAction::triggered, m_ctrl, &ImageController::play); 0328 connect(m_stopAct, &QAction::triggered, m_ctrl, &ImageController::stop); 0329 } 0330 void Image::contextMenuEvent(QContextMenuEvent* event) 0331 { 0332 QMenu menu(this); 0333 0334 if(m_ctrl->isMovie()) 0335 { 0336 menu.addAction(m_playAct); 0337 menu.addAction(m_stopAct); 0338 menu.addSeparator(); 0339 } 0340 0341 menu.addAction(m_rename); 0342 menu.addSeparator(); 0343 menu.addAction(m_actionZoomIn); 0344 menu.addAction(m_actionZoomOut); 0345 menu.addSeparator(); 0346 menu.addAction(m_actionfitWorkspace); 0347 menu.addAction(m_fitWindowAct); 0348 addActionToMenu(menu); 0349 menu.addSeparator(); 0350 menu.addAction(m_actionlittleZoom); 0351 menu.addAction(m_actionNormalZoom); 0352 menu.addAction(m_actionBigZoom); 0353 0354 menu.exec(event->globalPos() /*event->pos()*/); 0355 } 0356 void Image::fitWindow() 0357 { 0358 auto fit= m_fitWindowAct->isChecked(); 0359 resizeLabel(); 0360 if(fit) 0361 { 0362 m_widgetArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0363 m_widgetArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0364 } 0365 else 0366 { 0367 m_widgetArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); 0368 m_widgetArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); 0369 } 0370 m_actionZoomIn->setEnabled(!fit); 0371 m_actionZoomOut->setEnabled(!fit); 0372 m_actionlittleZoom->setEnabled(!fit); 0373 m_actionNormalZoom->setEnabled(!fit); 0374 m_actionBigZoom->setEnabled(!fit); 0375 0376 update(); 0377 } 0378 void Image::resizeEvent(QResizeEvent* event) 0379 { 0380 if(m_fitWindowAct->isChecked()) 0381 { 0382 resizeLabel(); 0383 } 0384 0385 QMdiSubWindow::resizeEvent(event); 0386 } 0387 0388 void Image::setParent(QWidget* parent) 0389 { 0390 QMdiSubWindow::setParent(parent); 0391 fitWorkSpace(); 0392 }