VideoVis  0.9
Generates a volume visualisation of a video
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
arthurwidgets.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the demonstration applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "arthurwidgets.h"
43 #include <QApplication>
44 #include <QPainter>
45 #include <QPainterPath>
46 #include <QPixmapCache>
47 #include <QtEvents>
48 #include <QTextDocument>
49 #include <QAbstractTextDocumentLayout>
50 #include <QFile>
51 #include <QTextBrowser>
52 #include <QBoxLayout>
53 
54 extern QPixmap cached(const QString &img);
55 
56 ArthurFrame::ArthurFrame(QWidget *parent)
57  : QWidget(parent)
58  , m_prefer_image(false)
59 {
60 #ifdef QT_OPENGL_SUPPORT
61  glw = 0;
62  m_use_opengl = false;
63  QGLFormat f = QGLFormat::defaultFormat();
64  f.setSampleBuffers(true);
65  f.setStencil(true);
66  f.setAlpha(true);
67  f.setAlphaBufferSize(8);
68  QGLFormat::setDefaultFormat(f);
69 #endif
70  m_document = 0;
71  m_show_doc = false;
72 
73  m_tile = QPixmap(128, 128);
74  m_tile.fill(Qt::white);
75  QPainter pt(&m_tile);
76  QColor color(230, 230, 230);
77  pt.fillRect(0, 0, 64, 64, color);
78  pt.fillRect(64, 64, 64, 64, color);
79  pt.end();
80 
81 // QPalette pal = palette();
82 // pal.setBrush(backgroundRole(), m_tile);
83 // setPalette(pal);
84 }
85 
86 
87 #ifdef QT_OPENGL_SUPPORT
88 void ArthurFrame::enableOpenGL(bool use_opengl)
89 {
90  if (m_use_opengl == use_opengl)
91  return;
92 
93  if (!glw && use_opengl) {
94  glw = new GLWidget(this);
95  glw->setAutoFillBackground(false);
96  glw->disableAutoBufferSwap();
97  QApplication::postEvent(this, new QResizeEvent(size(), size()));
98  }
99 
100  m_use_opengl = use_opengl;
101  if (use_opengl) {
102  glw->show();
103  } else {
104  if (glw)
105  glw->hide();
106  }
107 
108  update();
109 }
110 #endif
111 
112 void ArthurFrame::paintEvent(QPaintEvent *e)
113 {
114  static QImage *static_image = 0;
115  QPainter painter;
116  if (preferImage()
117 #ifdef QT_OPENGL_SUPPORT
118  && !m_use_opengl
119 #endif
120  ) {
121  if (!static_image || static_image->size() != size()) {
122  delete static_image;
123  static_image = new QImage(size(), QImage::Format_RGB32);
124  }
125  painter.begin(static_image);
126 
127  int o = 10;
128 
129  QBrush bg = palette().brush(QPalette::Background);
130  painter.fillRect(0, 0, o, o, bg);
131  painter.fillRect(width() - o, 0, o, o, bg);
132  painter.fillRect(0, height() - o, o, o, bg);
133  painter.fillRect(width() - o, height() - o, o, o, bg);
134  } else {
135 #ifdef QT_OPENGL_SUPPORT
136  if (m_use_opengl) {
137  painter.begin(glw);
138  painter.fillRect(QRectF(0, 0, glw->width(), glw->height()), palette().color(backgroundRole()));
139  } else {
140  painter.begin(this);
141  }
142 #else
143  painter.begin(this);
144 #endif
145  }
146 
147  painter.setClipRect(e->rect());
148 
149  painter.setRenderHint(QPainter::Antialiasing);
150 
151  QPainterPath clipPath;
152 
153  QRect r = rect();
154  qreal left = r.x() + 1;
155  qreal top = r.y() + 1;
156  qreal right = r.right();
157  qreal bottom = r.bottom();
158  qreal radius2 = 8 * 2;
159 
160  clipPath.moveTo(right - radius2, top);
161  clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90);
162  clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90);
163  clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90);
164  clipPath.arcTo(left, top, radius2, radius2, 180, -90);
165  clipPath.closeSubpath();
166 
167  painter.save();
168  painter.setClipPath(clipPath, Qt::IntersectClip);
169 
170  painter.drawTiledPixmap(rect(), m_tile);
171 
172  // client painting
173 
174  paint(&painter);
175 
176  painter.restore();
177 
178  painter.save();
179  if (m_show_doc)
180  paintDescription(&painter);
181  painter.restore();
182 
183  int level = 180;
184  painter.setPen(QPen(QColor(level, level, level), 2));
185  painter.setBrush(Qt::NoBrush);
186  painter.drawPath(clipPath);
187 
188  if (preferImage()
189 #ifdef QT_OPENGL_SUPPORT
190  && !m_use_opengl
191 #endif
192  ) {
193  painter.end();
194  painter.begin(this);
195  painter.drawImage(e->rect(), *static_image, e->rect());
196  }
197 
198 #ifdef QT_OPENGL_SUPPORT
199  if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
200  glw->swapBuffers();
201 #endif
202 }
203 
204 void ArthurFrame::resizeEvent(QResizeEvent *e)
205 {
206 #ifdef QT_OPENGL_SUPPORT
207  if (glw)
208  glw->setGeometry(0, 0, e->size().width()-1, e->size().height()-1);
209 #endif
210  QWidget::resizeEvent(e);
211 }
212 
214 {
215  if (m_show_doc != enabled) {
216  m_show_doc = enabled;
218  update();
219  }
220 }
221 
222 void ArthurFrame::loadDescription(const QString &fileName)
223 {
224  QFile textFile(fileName);
225  QString text;
226  if (!textFile.open(QFile::ReadOnly))
227  text = QString("Unable to load resource file: '%1'").arg(fileName);
228  else
229  text = textFile.readAll();
230  setDescription(text);
231 }
232 
233 
234 void ArthurFrame::setDescription(const QString &text)
235 {
236  m_document = new QTextDocument(this);
237  m_document->setHtml(text);
238 }
239 
240 void ArthurFrame::paintDescription(QPainter *painter)
241 {
242  if (!m_document)
243  return;
244 
245  int pageWidth = qMax(width() - 100, 100);
246  int pageHeight = qMax(height() - 100, 100);
247  if (pageWidth != m_document->pageSize().width()) {
248  m_document->setPageSize(QSize(pageWidth, pageHeight));
249  }
250 
251  QRect textRect(width() / 2 - pageWidth / 2,
252  height() / 2 - pageHeight / 2,
253  pageWidth,
254  pageHeight);
255  int pad = 10;
256  QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad);
257  painter->setPen(Qt::NoPen);
258  painter->setBrush(QColor(0, 0, 0, 63));
259  int shade = 10;
260  painter->drawRect(clearRect.x() + clearRect.width() + 1,
261  clearRect.y() + shade,
262  shade,
263  clearRect.height() + 1);
264  painter->drawRect(clearRect.x() + shade,
265  clearRect.y() + clearRect.height() + 1,
266  clearRect.width() - shade + 1,
267  shade);
268 
269  painter->setRenderHint(QPainter::Antialiasing, false);
270  painter->setBrush(QColor(255, 255, 255, 220));
271  painter->setPen(Qt::black);
272  painter->drawRect(clearRect);
273 
274  painter->setClipRegion(textRect, Qt::IntersectClip);
275  painter->translate(textRect.topLeft());
276 
277  QAbstractTextDocumentLayout::PaintContext ctx;
278 
279  QLinearGradient g(0, 0, 0, textRect.height());
280  g.setColorAt(0, Qt::black);
281  g.setColorAt(0.9, Qt::black);
282  g.setColorAt(1, Qt::transparent);
283 
284  QPalette pal = palette();
285  pal.setBrush(QPalette::Text, g);
286 
287  ctx.palette = pal;
288  ctx.clip = QRect(0, 0, textRect.width(), textRect.height());
289  m_document->documentLayout()->draw(painter, ctx);
290 }
291 
292 void ArthurFrame::loadSourceFile(const QString &sourceFile)
293 {
294  m_sourceFileName = sourceFile;
295 }
296 
298 {
299  // Check for existing source
300  if (findChild<QTextBrowser *>())
301  return;
302 
303  QString contents;
304  if (m_sourceFileName.isEmpty()) {
305  contents = QString("No source for widget: '%1'").arg(objectName());
306  } else {
307  QFile f(m_sourceFileName);
308  if (!f.open(QFile::ReadOnly))
309  contents = QString("Could not open file: '%1'").arg(m_sourceFileName);
310  else
311  contents = f.readAll();
312  }
313 
314  contents.replace('&', "&amp;");
315  contents.replace('<', "&lt;");
316  contents.replace('>', "&gt;");
317 
318  QStringList keywords;
319  keywords << "for " << "if " << "switch " << " int " << "#include " << "const"
320  << "void " << "uint " << "case " << "double " << "#define " << "static"
321  << "new" << "this";
322 
323  foreach (QString keyword, keywords)
324  contents.replace(keyword, QLatin1String("<font color=olive>") + keyword + QLatin1String("</font>"));
325  contents.replace("(int ", "(<font color=olive><b>int </b></font>");
326 
327  QStringList ppKeywords;
328  ppKeywords << "#ifdef" << "#ifndef" << "#if" << "#endif" << "#else";
329 
330  foreach (QString keyword, ppKeywords)
331  contents.replace(keyword, QLatin1String("<font color=navy>") + keyword + QLatin1String("</font>"));
332 
333  contents.replace(QRegExp("(\\d\\d?)"), QLatin1String("<font color=navy>\\1</font>"));
334 
335  QRegExp commentRe("(//.+)\\n");
336  commentRe.setMinimal(true);
337  contents.replace(commentRe, QLatin1String("<font color=red>\\1</font>\n"));
338 
339  QRegExp stringLiteralRe("(\".+\")");
340  stringLiteralRe.setMinimal(true);
341  contents.replace(stringLiteralRe, QLatin1String("<font color=green>\\1</font>"));
342 
343  QString html = contents;
344  html.prepend("<html><pre>");
345  html.append("</pre></html>");
346 
347  QTextBrowser *sourceViewer = new QTextBrowser(0);
348  sourceViewer->setWindowTitle("Source: " + m_sourceFileName.mid(5));
349  sourceViewer->setParent(this, Qt::Dialog);
350  sourceViewer->setAttribute(Qt::WA_DeleteOnClose);
351  sourceViewer->setLineWrapMode(QTextEdit::NoWrap);
352  sourceViewer->setHtml(html);
353  sourceViewer->resize(600, 600);
354  sourceViewer->show();
355 }