1 /*qAllInOne is a free open-source software built using Qt to provide users an All-In-One media player, so it can view images, play videos and audio.
2 qAllInOne Copyright (C) 2013 Mahmoud Jaoune
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.*/
20 #include "ui_mainwindow.h"
21 #include <QMainWindow>
27 #include <QMediaPlayer>
28 #include <QMediaPlaylist>
29 #include <QVideoWidget>
31 #include <QGraphicsVideoItem>
32 #include <QGraphicsView>
33 #include <QMediaObject>
34 #include <QMessageBox>
35 #include <QDesktopWidget>
36 #include <QMediaResource>
37 #include <QMediaMetaData>
38 #include <QResizeEvent>
39 #include <QAbstractVideoSurface>
40 #include "MediaToolbars.h"
42 #include <QMouseEvent>
43 #include <QScrollArea>
45 #include "ImageViewerContents.h"
53 class MainWindow
: public QMainWindow
60 JPG
,PNG
,GIF
,WMV
,MP3
,MP4
,BMP
,AVI
66 QGraphicsVideoItem
* VideoInfo
;
67 QVideoWidget
* VideoScreen
;
68 QMediaPlayer
* VideoPlayer
;
69 QMediaPlayer
* AudioPlayer
;
75 ImageViewerToolBar
*Toolb
;
76 VideoToolBar
* VToolb
;
77 AudioToolBar
* AToolb
;
79 MiniImage
* ScaleImage
;
84 QStringList ScanDirectory
;
87 int ImageShiftCounter
;
90 QList
<QImage
> ScaledImageList
;
95 explicit MainWindow(QWidget
*parent
= 0);
99 int AIO_ProcessMedia(QString Filename
, MMFiles Filetype
);
101 QString
IntToTime(int seconds
);
105 //Audio Slots and settings
107 void AMediaStatus(QMediaPlayer::MediaStatus status
)
109 if(status
== QMediaPlayer::LoadedMedia
)
117 void AmetaDataAvailable(bool Available
)
119 if(Available
== true)
121 //Obtaining Video information
122 QVariant CoverImage
= (AudioPlayer
->metaData(QMediaMetaData::CoverArtImage
));
123 QString Title
= (AudioPlayer
->metaData(QMediaMetaData::Title
).toString());
124 qint64 DurationMS
= (AudioPlayer
->metaData(QMediaMetaData::Duration
).toInt());
125 int Duration
= DurationMS
/ 1000;
129 this->setWindowTitle(Title
);
131 else this->setWindowTitle("qAllInOne - (" + CurrentAudio
+ ")");
133 //Set VideoScreen size
134 //Screen->setGeometry(VideoScreen->x(),VideoScreen->y(),OWidth,OHeight);
135 Screen
->setPixmap(QPixmap::fromImage(CoverImage
.value
<QImage
>()));
139 AToolb
->TimeSlider
->setMaximum(Duration
);
141 AToolb
->TotalTimeLabel
->setText(IntToTime(Duration
));
146 //In case the metadata was not found, use default properties
147 QVariant CoverImage
= (AudioPlayer
->metaData(QMediaMetaData::CoverArtImage
));
148 QString Title
= CurrentAudio
;
149 qint64 DurationMS
= 0;
150 int Duration
= DurationMS
/ 1000;
154 this->setWindowTitle(Title
);
156 else this->setWindowTitle("qAllInOne - (" + CurrentAudio
+ ")");
158 //Set VideoScreen size
159 //Screen->setGeometry(VideoScreen->x(),VideoScreen->y(),OWidth,OHeight);
163 AToolb
->TimeSlider
->setMaximum(Duration
);
165 AToolb
->TotalTimeLabel
->setText(IntToTime(Duration
));
175 AudioPlayer
->pause();
180 AudioPlayer
->pause();
181 /*if(AudioPlayer->position() != AudioPlayer->duration())
183 AudioPlayer->pause();
184 AudioPlayer->setPosition(0);
185 AudioPlayer->pause();
189 void AelapsedTimeChanged(qint64 mseconds
)
191 int Seconds
= mseconds
/ 1000;
193 AToolb
->ElapsedTimeLabel
->setText(IntToTime(Seconds
));
194 AToolb
->TimeSlider
->setValue(Seconds
);
197 void AchangePosition(int mseconds
)
199 if(AudioPlayer
->state() == QMediaPlayer::PausedState
)
201 AudioPlayer
->setPosition(mseconds
* 1000);
205 void AplayAfterChangePosition()
207 if(AudioPlayer
->state() == QMediaPlayer::PausedState
)
213 void ApauseBeforeChangePosition()
215 if(AudioPlayer
->state() != QMediaPlayer::PausedState
)
217 AudioPlayer
->pause();
221 void AchangeVolume(int vol
)
223 AudioPlayer
->setVolume(vol
);
224 AToolb
->VolumeLabel
->setText(QString::number(vol
) + "%");
226 //End of Audio Slots and Settings
228 //Video Slots and settings
229 void VMediaStatus(QMediaPlayer::MediaStatus status
)
231 if(status
== QMediaPlayer::LoadedMedia
)
239 void VmetaDataAvailable(bool Available
)
241 if(Available
== true)
243 //Obtaining Video information
244 int OWidth
= (VideoPlayer
->metaData(QMediaMetaData::Resolution
).toSize()).width();
245 int OHeight
= (VideoPlayer
->metaData(QMediaMetaData::Resolution
).toSize()).height();
246 QString Title
= (VideoPlayer
->metaData(QMediaMetaData::Title
).toString());
247 qint64 DurationMS
= (VideoPlayer
->metaData(QMediaMetaData::Duration
).toInt());
248 int Duration
= DurationMS
/ 1000;
252 this->setWindowTitle(Title
);
254 else this->setWindowTitle("qAllInOne - (" + CurrentVideo
+ ")");
256 //Calculate screen center and set MainWindow to center
257 QDesktopWidget
*desktop
= QApplication::desktop();
258 int CenterWidth
= ((desktop
->width() - OWidth
) / 2);
259 int CenterHeight
= ((desktop
->height() - OHeight
) / 2);
260 //Set MainWindow in Center
261 this->setGeometry(CenterWidth
,CenterHeight
,OWidth
,OHeight
+ ToolBarSpace
);
263 //Set VideoScreen size
264 VideoScreen
->setGeometry(VideoScreen
->x(),VideoScreen
->y(),OWidth
,OHeight
);
266 VToolb
->TimeSlider
->setMaximum(Duration
);
268 VToolb
->TotalTimeLabel
->setText(IntToTime(Duration
));
273 //In case the metadata was not found, use default properties
276 QString Title
= CurrentVideo
;
277 qint64 DurationMS
= 0;
278 int Duration
= DurationMS
/ 1000;
282 this->setWindowTitle(Title
);
284 else this->setWindowTitle("qAllInOne - (" + CurrentVideo
+ ")");
286 //Calculate screen center and set MainWindow to center
287 QDesktopWidget
*desktop
= QApplication::desktop();
288 int CenterWidth
= ((desktop
->width() - OWidth
) / 2);
289 int CenterHeight
= ((desktop
->height() - OHeight
) / 2);
290 //Set MainWindow in Center
291 this->setGeometry(CenterWidth
,CenterHeight
,OWidth
,OHeight
+ ToolBarSpace
);
293 //Set VideoScreen size
294 VideoScreen
->setGeometry(VideoScreen
->x(),VideoScreen
->y(),OWidth
,OHeight
);
296 VToolb
->TimeSlider
->setMaximum(Duration
);
298 VToolb
->TotalTimeLabel
->setText(IntToTime(Duration
));
308 VideoPlayer
->pause();
313 VideoPlayer
->pause();
314 /*if(VideoPlayer->position() != VideoPlayer->duration())
316 VideoPlayer->pause();
317 VideoPlayer->setPosition(0);
318 VideoPlayer->pause();
322 void VelapsedTimeChanged(qint64 mseconds
)
324 int Seconds
= mseconds
/ 1000;
326 VToolb
->ElapsedTimeLabel
->setText(IntToTime(Seconds
));
327 VToolb
->TimeSlider
->setValue(Seconds
);
330 void VchangePosition(int mseconds
)
332 if(VideoPlayer
->state() == QMediaPlayer::PausedState
)
334 VideoPlayer
->setPosition(mseconds
* 1000);
338 void VplayAfterChangePosition()
340 if(VideoPlayer
->state() == QMediaPlayer::PausedState
)
346 void VpauseBeforeChangePosition()
348 if(VideoPlayer
->state() != QMediaPlayer::PausedState
)
350 VideoPlayer
->pause();
354 void VchangeVolume(int vol
)
356 VideoPlayer
->setVolume(vol
);
358 VToolb
->VolumeLabel
->setText(QString::number(vol
) + "%");
360 //End of Video Slots and Settings
366 //Image viewer settings
367 //Code of PreviousImage() and NextImage() is influenced by GenCore software
368 //http://gen-core.sourceforge.net/
369 //The code actually gets the list of file in the same folder of the current image and then selects the one before it
370 //or after it depending on the button clicked.
374 if(ImageShiftCounter
== -1)
378 ScanDirectory
.clear();
380 QFileInfo
FileInfo(CurrentImage
);
382 FileString
= FileInfo
.absolutePath();
383 Dirlist
.push_back(FileString
);
384 DirStack
.push_back(Dirlist
.takeFirst());
385 ScanDirs
.setPath(DirStack
);
386 ScanDirectory
= ScanDirs
.entryList(QDir::Files
| QDir::Hidden
| QDir::NoDotAndDotDot
| QDir::NoSymLinks
,QDir::Name
);
388 for (int i
= 0; i
< ScanDirectory
.count(); i
++)
390 QString
FileStack(FileString
+ "/" + ScanDirectory
.at(i
));
391 if(FileStack
== CurrentImage
)
393 ImageShiftCounter
= i
;
400 while(!ScanDirectory
.isEmpty())
403 if(ImageShiftCounter
< ScanDirectory
.count() - 1)
405 ImageShiftCounter
+= 1;
406 FileName
.push_back(ScanDirectory
.at(ImageShiftCounter
));
408 else if(ImageShiftCounter
== ScanDirectory
.count() - 1)
410 ImageShiftCounter
= 0;
411 FileName
.push_back(ScanDirectory
.at(ImageShiftCounter
));
417 QString
FileStack(FileString
+ "/" + FileName
);
419 if(FileStack
!= CurrentImage
)
421 if(FileName
.endsWith(".jpg",Qt::CaseInsensitive
) || FileName
.endsWith(".jpeg",Qt::CaseInsensitive
))
423 AIO_ProcessMedia(FileStack
, JPG
);
426 else if(FileName
.endsWith(".png",Qt::CaseInsensitive
))
428 AIO_ProcessMedia(FileStack
, PNG
);
431 else if(FileName
.endsWith(".gif",Qt::CaseInsensitive
))
433 AIO_ProcessMedia(FileStack
, GIF
);
436 else if(FileName
.endsWith(".bmp",Qt::CaseInsensitive
))
438 AIO_ProcessMedia(FileStack
, BMP
);
450 if(ImageShiftCounter
== -1)
454 ScanDirectory
.clear();
456 QFileInfo
FileInfo(CurrentImage
);
458 FileString
= FileInfo
.absolutePath();
459 Dirlist
.push_back(FileString
);
460 DirStack
.push_back(Dirlist
.takeFirst());
461 ScanDirs
.setPath(DirStack
);
462 ScanDirectory
= ScanDirs
.entryList(QDir::Files
| QDir::Hidden
| QDir::NoDotAndDotDot
| QDir::NoSymLinks
,QDir::Name
);
464 for (int i
= 0; i
< ScanDirectory
.count(); i
++)
466 QString
FileStack(FileString
+ "/" + ScanDirectory
.at(i
));
467 if(FileStack
== CurrentImage
)
469 ImageShiftCounter
= i
;
475 while(!ScanDirectory
.isEmpty())
479 if(ImageShiftCounter
> 0)
481 ImageShiftCounter
-= 1;
482 FileName
.push_back(ScanDirectory
.at(ImageShiftCounter
));
484 else if(ImageShiftCounter
<= 0)
486 ImageShiftCounter
= ScanDirectory
.count() - 1;
487 FileName
.push_back(ScanDirectory
.at(ImageShiftCounter
));
493 QString
FileStack(FileString
+ "/" + FileName
);
495 if(FileStack
!= CurrentImage
)
497 if(FileName
.endsWith(".jpg",Qt::CaseInsensitive
) || FileName
.endsWith(".jpeg",Qt::CaseInsensitive
))
499 AIO_ProcessMedia(FileStack
, JPG
);
502 else if(FileName
.endsWith(".png",Qt::CaseInsensitive
))
504 AIO_ProcessMedia(FileStack
, PNG
);
507 else if(FileName
.endsWith(".gif",Qt::CaseInsensitive
))
509 AIO_ProcessMedia(FileStack
, GIF
);
512 else if(FileName
.endsWith(".bmp",Qt::CaseInsensitive
))
514 AIO_ProcessMedia(FileStack
, BMP
);
522 //End of Image Viewer settings
524 //Experimental code of the MiniImage and MiniFrame featured (Unimplemented)
526 void MovePicture(QPoint pos)
528 Screen->setGeometry(-1 * (ScaleImage->MiniFrame->x() * (Screen->width() / ScaleImage->width())),(-1 * (ScaleImage->MiniFrame->y() * (Screen->height() / ScaleImage->height()))),Screen->width(),Screen->height());
533 void processVideo(MMFiles format
,QString Filename
)
535 //Everything is done using Signals and Slots
536 //If Video Toolbar is not already setup, setup it
537 if(VToolb
->isHidden())
539 VToolb
->setGeometry(0,this->height() - ToolBarSpace
,this->width(),ToolBarSpace
);
540 VToolb
->SetupToolbar();
542 VToolb
->VolumeSlider
->setMaximum(100);
543 VToolb
->VolumeSlider
->setValue(VideoPlayer
->volume());
547 //End of Video Toolbar setup
549 CurrentVideo
= Filename
;
551 //Hide the Image Screen
552 Screen
->setHidden(true);
554 //Load the media and setup the video screen
555 VideoPlayer
->setMedia(QUrl::fromLocalFile(Filename
));
557 VideoPlayer
->setVideoOutput(VideoScreen
);
562 void processImage(MMFiles format
,QString Filename
)
566 this->setWindowTitle("qAllInOne - Loading image...");
568 //Load the GIF as a QMovie
569 //Note Loading the file as QFile and then getting its name will return a Cross-platfrom filename
570 QFile
ImageFile(Filename
);
571 ImageFile
.open(QFile::ReadOnly
);
574 QMovie
* MvImage
= new QMovie(ImageFile
.fileName(),QByteArray(),ui
->MainWidget
);
575 //Set the GIF Image to the label
576 Screen
->setMovie(MvImage
);
577 CurrentImage
= ImageFile
.fileName();
579 //Start playing the Gif Image
581 //If the GIF Image is bigger than 1280x800 scale it to 1280x800
582 if(MvImage
->currentImage().width() > 1280 || MvImage
->currentImage().height() > 800)
584 QSize
ScreenSize(1280,800);
585 MvImage
->setScaledSize(ScreenSize
);
588 //Process the scales of the image (For zooming)
591 ORImage
= MvImage
->currentImage();
593 //Add the original image first to be at index 0
595 ScaledImageList
.push_back(ORImage
);
597 //Scale the image to increase the width and height with the width and height of the original image divided by 8
598 //Do this process 9 times and the scaled image to the ScaledImageList each time
600 for(int i
=0;i
< 9; i
++)
602 ORImage
= ORImage
.scaled(ORImage
.width() + MvImage
->currentImage().width()/8,ORImage
.height() + MvImage
->currentImage().height()/8,Qt::KeepAspectRatio
,Qt::SmoothTransformation
);
603 ScaledImageList
.push_back(ORImage
);
606 //End of scale processing
609 QDesktopWidget
*desktop
= QApplication::desktop();
610 int CenterWidth
= ((desktop
->width() - (MvImage
->currentImage().width() + ImageMargin
)) / 2);
611 int CenterHeight
= ((desktop
->height() - (MvImage
->currentImage().height())) / 2);
613 //Set MainWindow in Center and add a 60x60 Margin
614 //If MainWindow is not maximized
615 if(!this->isMaximized())
617 //Lock MainWindow sizes
618 this->setMinimumSize(MvImage
->currentImage().width() + ImageMargin
,MvImage
->currentImage().height() + ToolBarSpace
+ ui
->menuBar
->height());
619 //Set MainWindow to Center and set the size with a 60x60 margin
620 this->setGeometry(CenterWidth
,CenterHeight
- (ToolBarSpace
/ 2),MvImage
->currentImage().width() + ImageMargin
,MvImage
->currentImage().height() + ToolBarSpace
+ ui
->menuBar
->height());
623 //If Image Toolbar is not already setup then setup it
624 if(Toolb
->isHidden())
626 Toolb
->setGeometry(0,this->height() - ToolBarSpace
,this->width(),ToolBarSpace
);
627 Toolb
->SetupToolbar();
631 //Set the MainWidget to the center of MainWindow
632 ui
->MainWidget
->setGeometry(0,0,this->width(),this->height() - ToolBarSpace
- ui
->menuBar
->height());
633 //Scale the Screen Label to the same size of the GIF image
634 Screen
->setGeometry((ui
->MainWidget
->width() / 2) - (MvImage
->currentImage().width() / 2),(ui
->MainWidget
->height() / 2) - (MvImage
->currentImage().height() / 2),MvImage
->currentImage().width(),MvImage
->currentImage().height());
636 //Set MainWindow title and add file path
637 this->setWindowTitle("qAllInOne - (" + Filename
+ ")");
639 VideoScreen
->setHidden(true);
643 this->setWindowTitle("qAllInOne - Loading image...");
645 //Intialize QImage and load the file
647 //Note Loading the file as QFile and then getting its name will return a Cross-platfrom filename
648 QFile
ImageFile(Filename
);
649 ImageFile
.open(QFile::ReadOnly
);
652 PrcImage
.load(ImageFile
.fileName(),0);
653 CurrentImage
= ImageFile
.fileName();
655 //If the image height is larger than 768 scale it to 768
656 if(PrcImage
.height() > 768)
658 PrcImage
= PrcImage
.scaledToHeight(768,Qt::SmoothTransformation
);
661 //Process the scales of the image (For zooming)
666 //Add the original image first to be at index 0
668 ScaledImageList
.push_back(ORImage
);
670 //Scale the image to increase the width and height with the width and height of the original image divided by 8
671 //Do this process 9 times and the scaled image to the ScaledImageList each time
673 for(int i
=0;i
< 9; i
++)
675 ORImage
= ORImage
.scaled(ORImage
.width() + PrcImage
.width()/8,ORImage
.height() + PrcImage
.height()/8,Qt::KeepAspectRatio
,Qt::SmoothTransformation
);
676 ScaledImageList
.push_back(ORImage
);
679 //End of scale processing
683 QDesktopWidget
*desktop
= QApplication::desktop();
684 int CenterWidth
= ((desktop
->width() - (PrcImage
.width() + ImageMargin
)) / 2);
685 int CenterHeight
= ((desktop
->height() - (PrcImage
.height())) / 2);
687 //Set MainWindow in Center and add a 60x60 Margin
688 //If MainWindow is not maximized
689 if(!this->isMaximized())
691 //Lock MainWindow sizes
692 this->setMinimumSize(PrcImage
.width() + ImageMargin
,PrcImage
.height() + ToolBarSpace
+ ui
->menuBar
->height());
693 //Set MainWindow to Center and set the size with a 60x60 margin
694 this->setGeometry(CenterWidth
,CenterHeight
- (ToolBarSpace
/ 2),PrcImage
.width() + ImageMargin
,PrcImage
.height() + ToolBarSpace
+ ui
->menuBar
->height());
697 //If Image Toolbar is not already setup then setup it
698 if(Toolb
->isHidden())
700 Toolb
->setGeometry(0,this->height() - ToolBarSpace
,this->width(),ToolBarSpace
);
701 Toolb
->SetupToolbar();
705 //Put the MainWidget in the center and resize it to the Image's size
706 ui
->MainWidget
->setGeometry(0,0,this->width(),this->height() - ToolBarSpace
- ui
->menuBar
->height());
708 //Resize the Scroll Screen and Screen Label to the Image size and load the image to it
709 Screen
->setGeometry((ui
->MainWidget
->width() / 2) - (PrcImage
.width() / 2),(ui
->MainWidget
->height() / 2) - (PrcImage
.height() / 2),PrcImage
.width(),PrcImage
.height());
711 Screen
->setPixmap(QPixmap::fromImage(PrcImage
,Qt::AutoColor
));
713 //Set MainWindow title and add file path
714 this->setWindowTitle("qAllInOne - (" + Filename
+ ")");
716 VideoScreen
->setHidden(true);
720 void processAudio(MMFiles format
,QString Filename
)
722 //Everything is done using Signals and Slots
723 //If Audio Toolbar is not already setup, setup it
724 if(AToolb
->isHidden())
726 AToolb
->setGeometry(0,this->height() - ToolBarSpace
,this->width(),ToolBarSpace
);
727 AToolb
->SetupToolbar();
729 AToolb
->VolumeSlider
->setMaximum(100);
730 AToolb
->VolumeSlider
->setValue(AudioPlayer
->volume());
734 //End of Video Toolbar setup
736 CurrentAudio
= Filename
;
738 //Hide the Image Screen
739 Screen
->setHidden(true);
742 AudioPlayer
->setMedia(QUrl::fromLocalFile(Filename
));
751 void resizeEvent(QResizeEvent
* event
);
752 void wheelEvent(QWheelEvent
*event
);
758 void visitHomepage();
761 #endif // MAINWINDOW_H