1 // Qt4Gui.cpp: KDE4/Qt4 Gui implementation for Gnash window
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
4 // 2011 Free Software Foundation, Inc
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "gnashconfig.h"
27 #include <QMainWindow>
33 #include <QApplication>
35 #include <QMouseEvent>
36 #include <QResizeEvent>
40 #include <QDialogButtonBox>
42 #include <QPushButton>
43 #include <QTreeWidget>
44 #include <QTreeWidgetItem>
56 #include <QDesktopWidget>
57 #include <QMessageBox>
61 #include "movie_definition.h"
68 #include "RunResources.h"
69 #include "GnashException.h"
71 // Macro for using gettext strings where Qt expects QStrings
72 #define _q(Str) QString::fromUtf8(_(Str))
81 Qt4Gui::Qt4Gui(unsigned long xid
, float scale
, bool loop
, RunResources
& r
)
83 Gui(xid
, scale
, loop
, r
),
90 , propertiesAction(NULL
)
93 , preferencesAction(NULL
)
94 , movieControlMenu(NULL
)
100 , refreshAction(NULL
)
101 , fullscreenAction(NULL
)
111 Qt4Gui::setClipboard(const std::string
& copy
)
113 QClipboard
* cb
= QApplication::clipboard();
115 cb
->setText(QString::fromStdString(copy
));
119 Qt4Gui::init(int /*argc*/, char ** /*argv*/[])
123 _application
.reset(new QApplication(_numArgs
, r
));
124 _window
.reset(new QMainWindow());
125 _embedWidget
= new EmbedWidget(*this);
126 _drawingWidget
= _embedWidget
->drawingWidget();
128 std::string renderer
= _runResources
.getRenderBackend();
130 if (renderer
== "cairo") {
131 #ifdef RENDERER_CAIRO
132 log_debug("Using Cairo renderer");
133 _glue
.reset(new Qt4CairoGlue());
135 log_error(_("Cairo renderer not supported!"));
138 } else if (renderer
== "opengl") {
139 #ifdef RENDERER_OPENGL
140 log_debug("Using OpenGL renderer");
141 _glue
.reset(new Qt4OglGlue());
143 log_error(_("OpenGL renderer not supported!"));
146 } else if (renderer
== "agg") {
148 log_debug("Using AGG renderer");
149 _glue
.reset(new Qt4AggGlue());
151 log_error(_("AGG renderer not supported!"));
156 boost::format fmt
= boost::format("Non-existent renderer %1% "
157 "specified") % renderer
;
158 throw gnash::GnashException(fmt
.str());
168 // Make sure key events are ready to be passed
169 // before the widget can receive them.
178 return _application
->exec();
182 Qt4Gui::createWindow(const char* windowtitle
, int width
, int height
,
183 int xPosition
, int yPosition
)
188 _drawingWidget
->setMinimumSize(_width
, _height
);
190 // Enable receiving of mouse events.
191 _drawingWidget
->setMouseTracking(true);
192 _drawingWidget
->setFocusPolicy(Qt::StrongFocus
);
193 _window
->setWindowTitle(windowtitle
);
194 _window
->setWindowIcon(QIcon(PKGDATADIR
"/GnashG.png"));
197 _embedWidget
->embedInto(_xid
);
198 _embedWidget
->show();
199 // Adjust width and height to the window we're being embedded into...
200 XWindowAttributes winAttributes
;
201 XGetWindowAttributes(QX11Info::display(), _xid
, &winAttributes
);
202 _width
=winAttributes
.width
;
203 _height
=winAttributes
.height
;
205 // The QMainWindow takes ownership of the widgets.
206 _window
->setCentralWidget(_embedWidget
);
207 if (xPosition
> -1 || yPosition
> -1)
208 _window
->move(xPosition
, yPosition
);
212 _glue
->prepDrawingArea(_drawingWidget
);
214 _renderer
.reset(_glue
->createRenderHandler());
216 if (!_renderer
.get()) {
220 _validbounds
.setTo(0, 0, _width
, _height
);
221 _glue
->initBuffer(_width
, _height
);
223 // log_debug("Setting renderer");
225 _runResources
.setRenderer(_renderer
);
227 // log_debug("Set renderer");
234 Qt4Gui::resizeWindow(int width
, int height
)
239 _drawingWidget
->setMinimumSize(_width
, _height
);
243 Qt4Gui::popupMenu(const QPoint
& point
)
245 QMenu
popupMenu(_drawingWidget
);
246 popupMenu
.addMenu(fileMenu
);
247 popupMenu
.addMenu(editMenu
);
248 popupMenu
.addMenu(movieControlMenu
);
249 popupMenu
.addMenu(viewMenu
);
250 popupMenu
.exec(point
);
255 Qt4Gui::renderBuffer()
258 for (DrawBounds::const_iterator i
= _drawbounds
.begin(),
259 e
= _drawbounds
.end(); i
!= e
; ++i
) {
261 // it may happen that a particular range is out of the screen, which
262 // will lead to bounds==null.
263 if (i
->isNull()) continue;
265 assert(i
->isFinite());
267 _drawingWidget
->update(i
->getMinX(), i
->getMinY(),
268 i
->width(), i
->height());
274 Qt4Gui::renderWidget(const QRect
& updateRect
)
276 // This call renders onto the widget using a QPainter,
277 // which *must only happen inside a paint event*.
278 _glue
->render(updateRect
);
282 Qt4Gui::setInvalidatedRegions(const InvalidatedRanges
& ranges
)
284 _renderer
->set_invalidated_regions(ranges
);
288 for (size_t i
= 0, e
= ranges
.size(); i
!= e
; ++i
) {
290 geometry::Range2d
<int> bounds
= Intersection(
291 _renderer
->world_to_pixel(ranges
.getRange(i
)),
294 // It may happen that a particular range is out of the screen, which
295 // will lead to bounds==null.
296 if (bounds
.isNull()) continue;
298 assert(bounds
.isFinite());
300 _drawbounds
.push_back(bounds
);
306 Qt4Gui::setTimeout(unsigned int timeout
)
308 // This must go through Gui::quit() to make sure screenshots are
309 // handled if necessary.
310 QTimer::singleShot(timeout
, _drawingWidget
, SLOT(quit()));
314 Qt4Gui::setInterval(unsigned int interval
)
316 _interval
= interval
;
317 _advanceTimer
= _drawingWidget
->startTimer(_interval
);
321 Qt4Gui::setCursor(gnash_cursor_type newcursor
)
323 if (! _mouseShown
) return;
327 _drawingWidget
->setCursor(Qt::PointingHandCursor
);
330 _drawingWidget
->setCursor(Qt::IBeamCursor
);
333 _drawingWidget
->unsetCursor();
338 Qt4Gui::showMouse(bool show
)
340 bool prevState
= _mouseShown
;
344 _drawingWidget
->unsetCursor();
347 _drawingWidget
->setCursor(Qt::BlankCursor
);
354 Qt4Gui::setFullscreen()
357 fullscreenAction
->setChecked(_fullscreen
);
359 _embedWidget
->setWindowFlags(Qt::Window
);
360 _embedWidget
->showFullScreen();
364 Qt4Gui::unsetFullscreen()
367 fullscreenAction
->setChecked(_fullscreen
);
369 if (_embedWidget
->isFullScreen()) {
370 _embedWidget
->setWindowFlags(Qt::Widget
);
371 _embedWidget
->showNormal();
373 _embedWidget
->embedInto(_xid
);
379 Qt4Gui::getScreenDPI() const
381 assert(_drawingWidget
);
382 // Should this be logical or physical DPI?
383 return _drawingWidget
->logicalDpiX();
387 Qt4Gui::screenResolution() const
389 QDesktopWidget
* d
= QApplication::desktop();
392 const QRect c
= d
->screenGeometry();
393 return std::make_pair(c
.width(), c
.height());
397 Qt4Gui::qtToGnashKey(QKeyEvent
*event
)
400 // This should be initialized by now.
401 assert (!_keyMap
.empty());
403 // Gnash uses its own keycodes to map key events
404 // to the three sometimes weird and confusing values that flash movies
405 // can refer to. See GnashKey.h for the keycodes and map.
407 // Gnash's keycodes are gnash::key::code. They are mainly in ascii order.
408 // Standard ascii characters (32-127) have the same value. Extended ascii
409 // characters (160-254) are in ascii order but correspond to
411 // 169-263. Non-character values must normally be mapped separately.
413 const int key
= event
->key();
415 if (key
>= Qt::Key_0
&& key
<= Qt::Key_9
) {
416 return static_cast<gnash::key::code
>(
417 key
- Qt::Key_0
+ gnash::key::_0
);
420 // All other characters between ascii 32 and 126 are simple.
421 // From space (32) to slash (47):
422 else if (key
>= Qt::Key_Space
&& key
<= Qt::Key_AsciiTilde
) {
423 return static_cast<gnash::key::code
>(
424 key
- Qt::Key_Space
+ gnash::key::SPACE
);
428 else if (key
>= Qt::Key_F1
&& key
<= Qt::Key_F15
) {
429 return static_cast<gnash::key::code
>(
430 key
- Qt::Key_F1
+ gnash::key::F1
);
433 // Extended ascii from non-breaking (160) space to ÿ (264) is in the same
435 else if (key
>= Qt::Key_nobreakspace
&& key
<= Qt::Key_ydiaeresis
) {
436 return static_cast<gnash::key::code
>(
437 key
- Qt::Key_nobreakspace
+ gnash::key::NOBREAKSPACE
);
440 const KeyMap::const_iterator it
= _keyMap
.find(key
);
442 if (it
== _keyMap
.end()) return gnash::key::INVALID
;
449 Qt4Gui::qtToGnashModifier(const Qt::KeyboardModifiers modifiers
)
451 int gnashModifier
= gnash::key::GNASH_MOD_NONE
;
453 if (modifiers
& Qt::ShiftModifier
)
454 gnashModifier
= gnashModifier
| gnash::key::GNASH_MOD_SHIFT
;
455 if (modifiers
& Qt::ControlModifier
)
456 gnashModifier
= gnashModifier
| gnash::key::GNASH_MOD_CONTROL
;
457 if (modifiers
& Qt::AltModifier
)
458 gnashModifier
= gnashModifier
| gnash::key::GNASH_MOD_ALT
;
460 return gnashModifier
;
464 Qt4Gui::handleKeyEvent(QKeyEvent
*event
, bool down
)
466 gnash::key::code c
= qtToGnashKey(event
);
467 int mod
= qtToGnashModifier(event
->modifiers());
468 notify_key_event(c
, mod
, down
);
472 Qt4Gui::resize(int width
, int height
)
474 _glue
->resize(width
, height
);
475 resize_view(width
, height
);
479 Qt4Gui::showProperties()
481 QDialog
* propsDialog
= new QDialog(_drawingWidget
);
482 propsDialog
->setWindowTitle(_q("Movie properties"));
483 propsDialog
->setAttribute(Qt::WA_DeleteOnClose
);
484 propsDialog
->resize(500, 300);
486 QDialogButtonBox
*dialogButtons
= new QDialogButtonBox(
487 QDialogButtonBox::Close
, Qt::Horizontal
, propsDialog
);
488 dialogButtons
->button(QDialogButtonBox::Close
)->setDefault(true);
490 QVBoxLayout
* layout
= new QVBoxLayout(propsDialog
);
491 propsDialog
->connect(dialogButtons
->button(QDialogButtonBox::Close
),
492 SIGNAL(clicked()), SLOT(close()));
495 std::unique_ptr
<movie_root::InfoTree
> infoptr
= getMovieInfo();
496 const movie_root::InfoTree
& info
= *infoptr
;
498 QTreeWidget
*tree
= new QTreeWidget();
499 tree
->setColumnCount(2);
500 QStringList treeHeader
;
501 treeHeader
.append(_q("Variable"));
502 treeHeader
.append(_q("Value"));
503 tree
->setHeaderLabels(treeHeader
);
505 QList
<QTreeWidgetItem
*> items
;
508 QStack
<QTreeWidgetItem
*> stack
;
509 for (movie_root::InfoTree::iterator i
= info
.begin(), e
= info
.end();
512 const movie_root::InfoTree::value_type
& p
= *i
;
515 cols
.append(p
.first
.c_str());
516 cols
.append(p
.second
.c_str());
517 QTreeWidgetItem
* item
= new QTreeWidgetItem(cols
);
519 int newDepth
= info
.depth(i
);
522 // Insert top level entries directly into the tree widget.
526 // The position to insert the new row.
527 QTreeWidgetItem
* parent
= NULL
;
529 if (newDepth
== prevDepth
) {
530 // Pop an extra time if there is a sibling on the stack.
531 int size
= stack
.size();
532 if (size
+ 1 > newDepth
)
535 parent
= stack
.pop();
536 } else if (newDepth
> prevDepth
) {
537 parent
= stack
.pop();
538 } else if (newDepth
< prevDepth
) {
539 // Pop until the stack has the right depth.
540 int size
= stack
.size();
541 for (int j
= 0; j
< (size
+ 1) - newDepth
; ++j
) {
542 parent
= stack
.pop();
546 parent
->addChild(item
);
551 prevDepth
= newDepth
;
553 tree
->insertTopLevelItems(0, items
);
554 layout
->addWidget(tree
);
556 #endif // USE_SWFTREE
557 layout
->addWidget(dialogButtons
);
560 propsDialog
->activateWindow();
564 Qt4Gui::showPreferences()
566 Qt4GuiPrefs::PreferencesDialog
* prefsDialog
= new Qt4GuiPrefs::PreferencesDialog(_drawingWidget
);
568 prefsDialog
->setAttribute(Qt::WA_DeleteOnClose
);
570 prefsDialog
->raise();
571 prefsDialog
->activateWindow();
575 Qt4Gui::yesno(const std::string
& question
)
577 _drawingWidget
->killTimer(_advanceTimer
);
579 QMessageBox
* dialog
= new QMessageBox(_drawingWidget
);
580 dialog
->setText(QString::fromStdString(question
));
581 dialog
->setStandardButtons(QMessageBox::Yes
| QMessageBox::No
);
582 dialog
->setDefaultButton(QMessageBox::Yes
);
583 const int ret
= dialog
->exec();
585 _advanceTimer
= _drawingWidget
->startTimer(_interval
);
588 if (ret
== QMessageBox::Yes
) return true;
595 _application
->quit();
599 Qt4Gui::setupActions()
603 propertiesAction
= new QAction(_q("Properties"), _window
.get());
604 _drawingWidget
->connect(propertiesAction
, SIGNAL(triggered()),
605 _drawingWidget
, SLOT(properties()));
607 quitAction
= new QAction(_q("Quit Gnash"), _window
.get());
608 // This must go through Gui::quit() to make sure we don't exit
609 // before doing whatever the Gui wants to do on exit.
610 _drawingWidget
->connect(quitAction
, SIGNAL(triggered()),
611 _drawingWidget
, SLOT(quit()));
614 preferencesAction
= new QAction(_q("Preferences"), _window
.get());
615 _drawingWidget
->connect(preferencesAction
, SIGNAL(triggered()),
616 _drawingWidget
, SLOT(preferences()));
618 // Movie Control Menu actions
619 playAction
= new QAction(_q("Play"), _window
.get());
620 _drawingWidget
->connect(playAction
, SIGNAL(triggered()),
621 _drawingWidget
, SLOT(play()));
623 pauseAction
= new QAction(_q("Pause"), _window
.get());
624 _drawingWidget
->connect(pauseAction
, SIGNAL(triggered()),
625 _drawingWidget
, SLOT(pause()));
627 stopAction
= new QAction(_q("Stop"), _window
.get());
628 _drawingWidget
->connect(stopAction
, SIGNAL(triggered()),
629 _drawingWidget
, SLOT(stop()));
631 restartAction
= new QAction(_q("Restart"), _window
.get());
632 _drawingWidget
->connect(restartAction
, SIGNAL(triggered()),
633 _drawingWidget
, SLOT(restart()));
636 refreshAction
= new QAction(_q("Refresh"), _window
.get());
637 _drawingWidget
->connect(refreshAction
, SIGNAL(triggered()),
638 _drawingWidget
, SLOT(refresh()));
640 fullscreenAction
= new QAction(_q("Fullscreen"), _window
.get());
641 fullscreenAction
->setCheckable(true);
642 _drawingWidget
->connect(fullscreenAction
, SIGNAL(toggled(bool)),
643 _drawingWidget
, SLOT(fullscreen(bool)));
650 /// The menus are children of the QMainWindow so that
651 /// they are destroyed on exit. The QMainWindow already has
652 /// ownership of the main QMenuBar.
654 // Set up the File menu.
655 fileMenu
= new QMenu(_q("File"), _window
.get());
656 fileMenu
->addAction(propertiesAction
);
657 fileMenu
->addAction(quitAction
);
659 // Set up the Edit menu.
660 editMenu
= new QMenu(_q("Edit"), _window
.get());
661 editMenu
->addAction(preferencesAction
);
663 // Set up the Movie Control menu
664 movieControlMenu
= new QMenu(_q("Movie Control"), _window
.get());
665 movieControlMenu
->addAction(playAction
);
666 movieControlMenu
->addAction(pauseAction
);
667 movieControlMenu
->addAction(stopAction
);
668 movieControlMenu
->addAction(restartAction
);
670 // Set up the View menu
671 viewMenu
= new QMenu(_q("View"), _window
.get());
672 viewMenu
->addAction(refreshAction
);
673 viewMenu
->addAction(fullscreenAction
);
678 Qt4Gui::createMainMenu()
680 std::unique_ptr
<QMenuBar
> mainMenu(new QMenuBar
);
682 // Set up the menu bar.
683 mainMenu
->addMenu(fileMenu
);
684 mainMenu
->addMenu(editMenu
);
685 mainMenu
->addMenu(movieControlMenu
);
686 mainMenu
->addMenu(viewMenu
);
688 // The QMainWindow::setMenuBar transfers ownership
690 _window
->setMenuBar(mainMenu
.release());
695 Qt4Gui::setupKeyMap()
697 // We only want to do this once, although it would not
698 // be harmful to do it more.
699 assert (_keyMap
.empty());
702 {Qt::Key_Backspace
, gnash::key::BACKSPACE
},
703 {Qt::Key_Tab
, gnash::key::TAB
},
704 {Qt::Key_Clear
, gnash::key::CLEAR
},
705 {Qt::Key_Return
, gnash::key::ENTER
},
706 {Qt::Key_Enter
, gnash::key::ENTER
},
707 {Qt::Key_Shift
, gnash::key::SHIFT
},
708 {Qt::Key_Control
, gnash::key::CONTROL
},
709 {Qt::Key_Alt
, gnash::key::ALT
},
710 {Qt::Key_CapsLock
, gnash::key::CAPSLOCK
},
711 {Qt::Key_Escape
, gnash::key::ESCAPE
},
712 {Qt::Key_Space
, gnash::key::SPACE
},
713 {Qt::Key_PageDown
, gnash::key::PGDN
},
714 {Qt::Key_PageUp
, gnash::key::PGUP
},
715 {Qt::Key_Home
, gnash::key::HOME
},
716 {Qt::Key_End
, gnash::key::END
},
717 {Qt::Key_Left
, gnash::key::LEFT
},
718 {Qt::Key_Up
, gnash::key::UP
},
719 {Qt::Key_Right
, gnash::key::RIGHT
},
720 {Qt::Key_Down
, gnash::key::DOWN
},
721 {Qt::Key_Insert
, gnash::key::INSERT
},
722 {Qt::Key_Delete
, gnash::key::DELETEKEY
},
723 {Qt::Key_Help
, gnash::key::HELP
},
724 {Qt::Key_NumLock
, gnash::key::NUM_LOCK
},
725 {Qt::Key_Semicolon
, gnash::key::SEMICOLON
},
726 {Qt::Key_Equal
, gnash::key::EQUALS
},
727 {Qt::Key_Minus
, gnash::key::MINUS
},
728 {Qt::Key_Slash
, gnash::key::SLASH
},
729 {Qt::Key_BracketLeft
, gnash::key::LEFT_BRACKET
},
730 {Qt::Key_Backslash
, gnash::key::BACKSLASH
},
731 {Qt::Key_BracketRight
, gnash::key::RIGHT_BRACKET
},
732 {Qt::Key_QuoteDbl
, gnash::key::DOUBLE_QUOTE
} };
738 _embedWidget
->hidePlayButton();
744 _embedWidget
->showPlayButton();
747 /// EmbedWidget implementation
749 EmbedWidget::EmbedWidget(Qt4Gui
& gui
)
752 _drawingWidget
= new DrawingWidget(gui
);
753 _playButton
= new QPushButton(_q("Click to Play"), this);
755 QVBoxLayout
* layout
= new QVBoxLayout(this);
756 layout
->setContentsMargins(0,0,0,0);
757 layout
->setSpacing(0);
758 layout
->addWidget(_playButton
);
759 layout
->addWidget(_drawingWidget
);
762 connect(_playButton
, SIGNAL(clicked()), this, SLOT(hidePlayButton()));
763 connect(_playButton
, SIGNAL(clicked()), _drawingWidget
, SLOT(play()));
767 EmbedWidget::hidePlayButton()
773 EmbedWidget::showPlayButton()
778 namespace Qt4GuiPrefs
{
780 PreferencesDialog::PreferencesDialog(QWidget
* parent
)
783 _rcfile(RcInitFile::getDefaultInstance())
785 setWindowTitle(_q("Gnash preferences"));
786 setAttribute(Qt::WA_DeleteOnClose
);
788 QDialogButtonBox
*buttons
= new QDialogButtonBox(
789 QDialogButtonBox::Ok
| QDialogButtonBox::Cancel
);
791 QVBoxLayout
*vLayout
= new QVBoxLayout(this);
795 // Make notebook pages.
796 QTabWidget
*tabs
= new QTabWidget
;
799 QFrame
* loggingTab
= new QFrame();
800 tabs
->addTab(loggingTab
, _q("Logging"));
801 QVBoxLayout
* layout
= new QVBoxLayout (loggingTab
);
803 tmpLabel
= new QLabel(_q("<b>Logging options</b>"), loggingTab
);
804 layout
->addWidget(tmpLabel
);
806 tmpLabel
= new QLabel(_q("Verbosity level"), loggingTab
);
807 layout
->addWidget(tmpLabel
);
809 QLCDNumber
* lcd
= new QLCDNumber(loggingTab
);
810 lcd
->display(_rcfile
.verbosityLevel());
811 lcd
->setNumDigits(2);
812 layout
->addWidget(lcd
);
814 _verbositySlider
= new QSlider(loggingTab
);
815 _verbositySlider
->setOrientation(Qt::Horizontal
);
816 _verbositySlider
->setMaximum(10);
817 _verbositySlider
->setSingleStep(1);
818 _verbositySlider
->setPageStep(1);
819 _verbositySlider
->setValue(_rcfile
.verbosityLevel());
820 connect(_verbositySlider
, SIGNAL(valueChanged(int)),
821 lcd
, SLOT(display(int)));
822 layout
->addWidget(_verbositySlider
);
824 _logToFileToggle
= new QCheckBox(_q("Log to file"), loggingTab
);
825 _logToFileToggle
->setChecked(_rcfile
.useWriteLog());
826 layout
->addWidget(_logToFileToggle
);
828 _logFileName
= new QLineEdit(_rcfile
.getDebugLog().c_str(), loggingTab
);
829 layout
->addWidget(_logFileName
);
831 _parserDumpToggle
= new QCheckBox(_q("Log parser output"), loggingTab
);
832 _parserDumpToggle
->setChecked(_rcfile
.useParserDump());
833 layout
->addWidget(_parserDumpToggle
);
835 _actionDumpToggle
= new QCheckBox(_q("Log SWF actions"), loggingTab
);
836 _actionDumpToggle
->setChecked(_rcfile
.useActionDump());
837 layout
->addWidget(_actionDumpToggle
);
839 _malformedSWFToggle
= new QCheckBox(_q("Log malformed SWF errors"),
841 _malformedSWFToggle
->setChecked(_rcfile
.showMalformedSWFErrors());
842 layout
->addWidget(_malformedSWFToggle
);
844 _ASCodingErrorToggle
= new QCheckBox(_q("Log ActionScript coding errors"),
846 _ASCodingErrorToggle
->setChecked(_rcfile
.showASCodingErrors());
847 layout
->addWidget(_ASCodingErrorToggle
);
850 QFrame
* securityTab
= new QFrame(tabs
);
851 tabs
->addTab(securityTab
, _q("Security"));
852 layout
= new QVBoxLayout (securityTab
);
854 tmpLabel
= new QLabel(_q("<b>Network connections</b>"), securityTab
);
855 layout
->addWidget(tmpLabel
);
857 _localHostToggle
= new QCheckBox(_q("Connect only to local host"),
859 _localHostToggle
->setChecked(_rcfile
.useLocalHost());
860 layout
->addWidget(_localHostToggle
);
862 _localDomainToggle
= new QCheckBox(_q("Connect only to local domain"),
864 _localDomainToggle
->setChecked(_rcfile
.useLocalDomain());
865 layout
->addWidget(_localDomainToggle
);
867 _insecureSSLToggle
= new QCheckBox(_q("Disable SSL verification"),
869 _insecureSSLToggle
->setChecked(_rcfile
.insecureSSL());
870 layout
->addWidget(_insecureSSLToggle
);
872 tmpLabel
= new QLabel(_q("<b>Privacy</b>"), securityTab
);
873 layout
->addWidget(tmpLabel
);
875 tmpLabel
= new QLabel(_q("Shared objects directory:"), securityTab
);
876 layout
->addWidget(tmpLabel
);
877 _solSandboxDir
= new QLineEdit(_rcfile
.getSOLSafeDir().c_str(),
879 layout
->addWidget(_solSandboxDir
);
881 _solReadOnlyToggle
= new QCheckBox(_q("Do not write Shared Object files"),
883 _solReadOnlyToggle
->setChecked(_rcfile
.getSOLReadOnly());
884 layout
->addWidget(_solReadOnlyToggle
);
886 _solLocalDomainToggle
= new QCheckBox(
887 _q("Only access local Shared Object files"), securityTab
);
888 _solLocalDomainToggle
->setChecked(_rcfile
.getSOLLocalDomain());
889 layout
->addWidget(_solLocalDomainToggle
);
891 _localConnectionToggle
= new QCheckBox(
892 _q("Disable Local Connection object"), securityTab
);
893 _localConnectionToggle
->setChecked(_rcfile
.getLocalConnection());
894 layout
->addWidget(_localConnectionToggle
);
895 layout
->addStretch();
898 QFrame
* networkTab
= new QFrame(tabs
);
899 tabs
->addTab(networkTab
, _q("Network"));
900 layout
= new QVBoxLayout (networkTab
);
902 tmpLabel
= new QLabel(_q("<b>Network preferences</b>"), networkTab
);
903 layout
->addWidget(tmpLabel
);
905 tmpLabel
= new QLabel(_q("Network timeout in seconds"), networkTab
);
906 layout
->addWidget(tmpLabel
);
908 _streamsTimeoutScale
= new QSpinBox(networkTab
);
909 _streamsTimeoutScale
->setMinimum(0);
910 _streamsTimeoutScale
->setMaximum(300);
911 _streamsTimeoutScale
->setValue(_rcfile
.getStreamsTimeout());
912 layout
->addWidget(_streamsTimeoutScale
);
913 layout
->addStretch();
916 QFrame
* mediaTab
= new QFrame(tabs
);
917 tabs
->addTab(mediaTab
, _q("Media"));
918 layout
= new QVBoxLayout (mediaTab
);
920 tmpLabel
= new QLabel(_q("<b>Sound</b>"), mediaTab
);
921 layout
->addWidget(tmpLabel
);
923 _soundToggle
= new QCheckBox(_q("Use sound handler"), mediaTab
);
924 _soundToggle
->setChecked(_rcfile
.useSound());
925 layout
->addWidget(_soundToggle
);
927 _saveStreamingMediaToggle
= new QCheckBox(_q("Save media streams to disk"),
929 _saveStreamingMediaToggle
->setChecked(_rcfile
.saveStreamingMedia());
930 layout
->addWidget(_saveStreamingMediaToggle
);
932 _saveLoadedMediaToggle
= new QCheckBox(
933 _q("Save dynamically loaded media to disk"), mediaTab
);
934 _saveLoadedMediaToggle
->setChecked(_rcfile
.saveLoadedMedia());
935 layout
->addWidget(_saveLoadedMediaToggle
);
937 tmpLabel
= new QLabel(_q("Saved media directory:"), mediaTab
);
938 layout
->addWidget(tmpLabel
);
940 _mediaDir
= new QLineEdit(_rcfile
.getMediaDir().c_str(), mediaTab
);
941 layout
->addWidget(_mediaDir
);
942 layout
->addStretch();
945 QFrame
* playerTab
= new QFrame(tabs
);
946 tabs
->addTab(playerTab
, _q("Player"));
947 layout
= new QVBoxLayout (playerTab
);
949 tmpLabel
= new QLabel(_q("<b>Player description</b>"), playerTab
);
950 layout
->addWidget(tmpLabel
);
952 tmpLabel
= new QLabel(_q("Player version:"), playerTab
);
953 layout
->addWidget(tmpLabel
);
954 _versionText
= new QLineEdit(_rcfile
.getFlashVersionString().c_str(),
956 layout
->addWidget(_versionText
);
958 tmpLabel
= new QLabel(_q("Operating system:"), playerTab
);
959 layout
->addWidget(tmpLabel
);
961 _osText
= new QLineEdit(playerTab
);
962 if (_rcfile
.getFlashSystemOS().empty()) {
963 _osText
->setText(_q("<Autodetect>"));
965 _osText
->setText(_rcfile
.getFlashSystemOS().c_str());
967 layout
->addWidget(_osText
);
969 tmpLabel
= new QLabel(_q("URL opener:"), playerTab
);
970 layout
->addWidget(tmpLabel
);
972 _urlOpenerText
= new QLineEdit(_rcfile
.getURLOpenerFormat().c_str(),
974 layout
->addWidget(_urlOpenerText
);
976 tmpLabel
= new QLabel(_q("<b>Performance</b>"), playerTab
);
977 layout
->addWidget(tmpLabel
);
979 tmpLabel
= new QLabel(_q("Max size of movie library:"), playerTab
);
980 layout
->addWidget(tmpLabel
);
982 _librarySize
= new QSpinBox(playerTab
);
983 _librarySize
->setMinimum(0);
984 _librarySize
->setMaximum(100);
985 _librarySize
->setValue(_rcfile
.getMovieLibraryLimit());
986 layout
->addWidget(_librarySize
);
988 _startStoppedToggle
= new QCheckBox(_q("Start Gnash in pause mode"),
990 _startStoppedToggle
->setChecked(_rcfile
.startStopped());
991 layout
->addWidget(_startStoppedToggle
);
992 layout
->addStretch();
993 // End of notebook tabs
995 vLayout
->addWidget(tabs
);
996 vLayout
->addStretch();
997 vLayout
->addWidget(buttons
);
999 // Connect the dialog buttons.
1000 connect(buttons
, SIGNAL(accepted()), this, SLOT(savePreferences()));
1001 connect(buttons
, SIGNAL(rejected()), this, SLOT(reject()));
1005 PreferencesDialog::savePreferences()
1007 // Logging tab widgets
1008 _rcfile
.verbosityLevel(_verbositySlider
->value());
1009 _rcfile
.useWriteLog(_logToFileToggle
->isChecked());
1010 _rcfile
.setDebugLog(_logFileName
->text().toStdString());
1011 _rcfile
.useParserDump(_parserDumpToggle
->isChecked());
1012 _rcfile
.useActionDump(_actionDumpToggle
->isChecked());
1013 _rcfile
.showMalformedSWFErrors(_malformedSWFToggle
->isChecked());
1014 _rcfile
.showASCodingErrors(_ASCodingErrorToggle
->isChecked());
1016 // Security tab widgets
1017 _rcfile
.useLocalHost(_localHostToggle
->isChecked());
1018 _rcfile
.useLocalDomain(_localDomainToggle
->isChecked());
1019 _rcfile
.insecureSSL(_insecureSSLToggle
->isChecked());
1020 _rcfile
.setSOLSafeDir(_solSandboxDir
->text().toStdString());
1021 _rcfile
.setSOLReadOnly(_solReadOnlyToggle
->isChecked());
1022 _rcfile
.setSOLLocalDomain(_solLocalDomainToggle
->isChecked());
1023 _rcfile
.setLocalConnection(_localConnectionToggle
->isChecked());
1025 // Network tab widgets
1026 _rcfile
.setStreamsTimeout(_streamsTimeoutScale
->value());
1028 // Media tab widgets
1029 _rcfile
.useSound(_soundToggle
->isChecked());
1030 _rcfile
.saveStreamingMedia(_saveStreamingMediaToggle
->isChecked());
1031 _rcfile
.saveLoadedMedia(_saveLoadedMediaToggle
->isChecked());
1032 _rcfile
.setMediaDir(_mediaDir
->text().toStdString());
1034 // Player tab widgets
1035 _rcfile
.setFlashVersionString(_versionText
->text().toStdString());
1036 if (_osText
->text() != _q("<Autodetect>")) {
1037 _rcfile
.setFlashSystemOS(_osText
->text().toStdString());
1039 _rcfile
.setURLOpenerFormat(_urlOpenerText
->text().toStdString());
1040 _rcfile
.setMovieLibraryLimit(_librarySize
->value());
1041 _rcfile
.startStopped(_startStoppedToggle
->isChecked());
1044 _rcfile
.updateFile();
1046 // Allow the dialog to close normally.
1050 } // End of Qt4GuiPrefs namespace