]> git.sesse.net Git - kdenlive/blob - src/abstractmonitor.cpp
Merge branch 'master' into effectstack
[kdenlive] / src / abstractmonitor.cpp
1 /***************************************************************************
2  *   Copyright (C) 2011 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
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 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20
21 #include "abstractmonitor.h"
22 #include "kdenlivesettings.h"
23 #include "monitormanager.h"
24
25 #include <KDebug>
26
27 #include <QPaintEvent>
28 #include <QDesktopWidget>
29 #include <QVBoxLayout>
30
31
32 AbstractMonitor::AbstractMonitor(Kdenlive::MONITORID id, MonitorManager *manager, QWidget *parent): 
33     QWidget(parent),
34     videoSurface(NULL),
35     m_id(id),
36     m_monitorManager(manager)
37 {
38     videoBox = new VideoContainer(this);
39 }
40
41
42 AbstractMonitor::~AbstractMonitor()
43 {
44     if (videoSurface)
45         delete videoSurface;
46 }
47
48 void AbstractMonitor::createVideoSurface()
49 {
50     QVBoxLayout *lay = new QVBoxLayout;
51     lay->setContentsMargins(0, 0, 0, 0);
52     videoSurface = new VideoSurface;
53     lay->addWidget(videoSurface);
54     videoBox->setLayout(lay);
55 }
56
57 bool AbstractMonitor::isActive() const
58 {
59     return m_monitorManager->isActive(m_id);
60 }
61
62 bool AbstractMonitor::slotActivateMonitor()
63 {
64     return m_monitorManager->activateMonitor(m_id);
65 }
66
67 VideoContainer::VideoContainer(AbstractMonitor* monitor, QWidget *parent) :
68     QFrame(parent)
69     , m_monitor(monitor)
70 {
71     setFrameShape(QFrame::NoFrame);
72     setFocusPolicy(Qt::ClickFocus);
73     //setEnabled(false);
74     setContentsMargins(0, 0, 0, 0);
75     setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
76 }
77
78 // virtual
79 void VideoContainer::mouseReleaseEvent(QMouseEvent * event)
80 {
81     if (event->button() != Qt::RightButton) {
82         if (m_monitor->isActive()) {
83             m_monitor->slotPlay();
84         }
85     }
86 }
87
88 // virtual
89 void VideoContainer::keyPressEvent(QKeyEvent *event)
90 {
91     // Exit fullscreen with Esc key
92     if (event->key() == Qt::Key_Escape && isFullScreen()) {
93         switchFullScreen();
94         event->setAccepted(true);
95     } else event->setAccepted(false);
96 }
97
98 // virtual
99 void VideoContainer::wheelEvent(QWheelEvent * event)
100 {
101     m_monitor->slotMouseSeek(event->delta(), event->modifiers() == Qt::ControlModifier);
102     event->accept();
103 }
104
105 void VideoContainer::mouseDoubleClickEvent(QMouseEvent * event)
106 {
107     if (!KdenliveSettings::openglmonitors())
108         switchFullScreen();
109     event->accept();
110 }
111
112 void VideoContainer::switchFullScreen()
113 {
114     // TODO: disable screensaver?
115     Qt::WindowFlags flags = windowFlags();
116     if (!isFullScreen()) {
117         // Check if we ahave a multiple monitor setup
118         setUpdatesEnabled(false);
119 #if QT_VERSION >= 0x040600
120         int monitors = QApplication::desktop()->screenCount();
121 #else
122         int monitors = QApplication::desktop()->numScreens();
123 #endif
124         if (monitors > 1) {
125             QRect screenres;
126             // Move monitor widget to the second screen (one screen for Kdenlive, the other one for the Monitor widget
127             int currentScreen = QApplication::desktop()->screenNumber(this);
128             if (currentScreen < monitors - 1)
129                 screenres = QApplication::desktop()->screenGeometry(currentScreen + 1);
130             else
131                 screenres = QApplication::desktop()->screenGeometry(currentScreen - 1);
132             move(QPoint(screenres.x(), screenres.y()));
133             resize(screenres.width(), screenres.height());
134         }
135
136         m_baseFlags = flags & (Qt::Window | Qt::SubWindow);
137         flags |= Qt::Window;
138         flags ^= Qt::SubWindow;
139         setWindowFlags(flags);
140 #ifdef Q_WS_X11
141         // This works around a bug with Compiz
142         // as the window must be visible before we can set the state
143         show();
144         raise();
145         setWindowState(windowState() | Qt::WindowFullScreen);   // set
146 #else
147         setWindowState(windowState() | Qt::WindowFullScreen);   // set
148         setUpdatesEnabled(true);
149         show();
150 #endif
151         setEnabled(true);
152     } else {
153         setUpdatesEnabled(false);
154         flags ^= (Qt::Window | Qt::SubWindow); //clear the flags...
155         flags |= m_baseFlags; //then we reset the flags (window and subwindow)
156         setWindowFlags(flags);
157         setWindowState(windowState()  ^ Qt::WindowFullScreen);   // reset
158         setUpdatesEnabled(true);
159         setEnabled(false);
160         show();
161     }
162 }
163
164 VideoSurface::VideoSurface(QWidget* parent) :
165     QWidget(parent)
166 {
167     // MonitorRefresh is used as container for the SDL display (it's window id is passed to SDL)
168     setAttribute(Qt::WA_PaintOnScreen);
169     setAttribute(Qt::WA_OpaquePaintEvent);
170     setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
171     setAttribute(Qt::WA_NoSystemBackground);
172     setUpdatesEnabled(false);
173 }
174
175 void VideoSurface::paintEvent(QPaintEvent *event)
176 {
177     Q_UNUSED(event);
178     //WARNING: This might trigger unnecessary refreshes from MLT's producer, but without this,
179     // as soon as monitor is covered by a popup menu or another window, image is corrupted.
180     emit refreshMonitor();
181 }
182