//=============================================================================
//
// OpenFlipper
// Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
// www.openflipper.org
//
//-----------------------------------------------------------------------------
//
// License
//
// OpenFlipper is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenFlipper is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see .
//
//-----------------------------------------------------------------------------
//
// $Revision$
// $Author$
// $Date$
//
//=============================================================================
//=============================================================================
//
// CLASS MViewWidget - IMPLEMENTATION
//
//=============================================================================
//== INCLUDES =================================================================
// -------------------- mview
#include "CoreWidget.hh"
// -------------------- OpenFlipper Includes
#include
#include
#include
#include
#include
#define WIDGET_HEIGHT 800
#define WIDGET_WIDTH 800
//== IMPLEMENTATION ==========================================================
/** \brief Constuctor for the Core Widget
*
*/
CoreWidget::
CoreWidget( QVector& _viewModes,
std::vector& _plugins ) :
QMainWindow(),
viewModes_(_viewModes),
dockViewMode_(0),
viewModeButton_(0),
viewModeMenu_(0),
viewGroup_(0),
examiner_widget_(0),
splitter_(0),
textedit_(0),
recentFilesMenu_(0),
pluginsMenu_(0),
fileMenu_(0),
viewMenu_(0),
fileMenuEnd_(0),
contextMenu_(0),
contextSelectionMenu_(0),
stackMenu_(0),
stackedWidget_(0),
helpBrowserDeveloper_(0),
helpBrowserUser_(0),
aboutWidget_(0),
optionsWidget_(0),
plugins_(_plugins)
{
setupStatusBar();
splitter_ = new QSplitter(Qt::Vertical,this);
setCentralWidget(splitter_);
stackedWidget_ = new QStackedWidget(splitter_);
// ======================================================================
// Set up the logging window
// ======================================================================
textedit_ = new QTextEdit(splitter_);
textedit_->setReadOnly(true);
textedit_->setSizePolicy( QSizePolicy ( QSizePolicy::Preferred , QSizePolicy::Preferred ) );
textedit_->resize( splitter_->width() ,120);
textedit_->setLineWrapMode( QTextEdit::NoWrap );
originalLoggerSize_ = 0;
QList wsizes( splitter_->sizes() );
if (OpenFlipper::Options::hideLogger()) {
wsizes[1] = 0;
splitter_->setSizes(wsizes);
}
// ======================================================================
// Create examiner
// ======================================================================
QGLFormat format;
QGLFormat::setDefaultFormat(format);
format.setStereo( OpenFlipper::Options::stereo() );
examiner_widget_ = new ACG::QtWidgets::QtExaminerViewer(stackedWidget_,
"Examiner Widget",
statusBar_ ,
&format);
examiner_widget_->sceneGraph( PluginFunctions::getSceneGraphRootNode() );
examiner_widget_->enablePopupMenu(false);
stackedWidget_->addWidget(examiner_widget_);
// ======================================================================
// Setup dragging for examiner widget
// ======================================================================
examiner_widget_->setExternalDrag(true);
connect( examiner_widget_, SIGNAL(startDragEvent( QMouseEvent*)),
this, SLOT(startDrag(QMouseEvent* )));
connect( examiner_widget_, SIGNAL(dragEnterEvent( QDragEnterEvent*)),
this, SLOT(dragEnterEvent(QDragEnterEvent* )));
connect( examiner_widget_, SIGNAL(dropEvent( QDropEvent*)),
this, SLOT(dropEvent(QDropEvent* )));
// ======================================================================
// Create main Toolbar
// ======================================================================
mainToolbar_ = new QToolBar("Main Toolbar");
mainToolbar_->setWindowTitle("Main Toolbar");
mainToolbar_->setObjectName("MainToolbar");
slotAddToolbar(mainToolbar_);
// ======================================================================
// Get Toolbar from examiner and integrate it into main window
// ======================================================================
// Take control over the toolbar
viewerToolbar_ = examiner_widget_->removeToolBar();
addToolBar(Qt::TopToolBarArea,viewerToolbar_);
viewerToolbar_->setParent(this);
viewerToolbar_->setAllowedAreas(Qt::AllToolBarAreas);
viewerToolbar_->setIconSize(QSize(20,20));
viewerToolbar_->setObjectName("ViewerToolbar");
// Set our own Icons
QList actions = viewerToolbar_->actions();
for ( int i = 0 ; i < actions.size(); ++i ) {
if ( actions[i]->text() == "Move" ) {
QIcon icon;
icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"transform-move.png");
QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
button->setIcon(icon);
} else if ( actions[i]->text() == "Home" ) {
QIcon icon;
icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-home.png");
QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
button->setIcon(icon);
} else if ( actions[i]->text() == "Set Home" ) {
QIcon icon;
icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"set-home.png");
QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
button->setIcon(icon);
} else if ( actions[i]->text() == "Light" ) {
QIcon icon;
icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"light-mode.png");
QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
button->setIcon(icon);
} else if ( actions[i]->text() == "Question" ) {
QIcon icon;
icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"help-about.png");
QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
button->setIcon(icon);
} else if ( actions[i]->text() == "SceneGraph" ) {
QIcon icon;
icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"scenegraph.png");
QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
button->setIcon(icon);
} else if ( actions[i]->text() == "Pick" ) {
// QIcon icon;
// icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"scenegraph.png");
//
// QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
// button->setIcon(icon);
} else if ( actions[i]->text() == "View All" ) {
// QIcon icon;
// icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"scenegraph.png");
//
// QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
// button->setIcon(icon);
} else if ( actions[i]->text() == "Projection" ) {
// QIcon icon;
// icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"scenegraph.png");
//
// QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
// button->setIcon(icon);
} else if ( actions[i]->text() == "Stereo" ) {
// QIcon icon;
// icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"scenegraph.png");
//
// QToolButton * button = qobject_cast( viewerToolbar_->widgetForAction ( actions[i] ) );
// button->setIcon(icon);
}
// else
// std::cerr << actions[i]->text().toStdString() << std::endl;
}
stackWidgetList_.push_back( StackWidgetInfo( false, "3D Examiner Widget", examiner_widget_ ) );
// Remember logger size
wsizes = splitter_->sizes();
originalLoggerSize_ = wsizes[1];
// ======================================================================
// Create Upper DockWidget for ToolWidget control
// ======================================================================
dockViewMode_ = new QDockWidget("ViewMode" , this );
dockViewMode_->setObjectName("DockViewMode");
QPushButton* button = new QPushButton("Change View Mode");
dockViewMode_->setWidget(button);
button->setParent(dockViewMode_);
dockViewMode_->setFeatures( QDockWidget::NoDockWidgetFeatures );
button->show();
addDockWidget(Qt::RightDockWidgetArea,dockViewMode_);
connect(button, SIGNAL(clicked()), this, SLOT(slotViewModeDialog()));
dockViewMode_->setVisible(false);
// ======================================================================
// Context menu setup
// ======================================================================
connect( examiner_widget_ , SIGNAL(signalCustomContextMenuRequested( const QPoint&) ) ,
this , SLOT( slotCustomContextMenu( const QPoint&) ) );
contextMenu_ = new QMenu(0);
contextSelectionMenu_ = new QMenu("Selection",0);
setupMenuBar();
updateRecent();
statusBar_->showMessage("Ready", 5000);
//register keys for coreWidget
connect(this,SIGNAL( registerKey(int, Qt::KeyboardModifiers, QString) ),
this,SLOT(slotRegisterKey(int, Qt::KeyboardModifiers, QString)) );
emit registerKey(Qt::Key_S,Qt::ControlModifier, "Save Object");
emit registerKey(Qt::Key_O,Qt::ControlModifier, "Open Object");
emit registerKey(Qt::Key_Escape,Qt::NoModifier, "Switch to last action mode ( Move,Picking,Light or Info Mode)");
}
//-----------------------------------------------------------------------------
CoreWidget::~CoreWidget() {
}
//-----------------------------------------------------------------------------
/** Set viewer to Fullscreen Mode and back
*/
void
CoreWidget::toggleFullscreen() {
setWindowState( windowState() ^ Qt::WindowFullScreen);
OpenFlipper::Options::fullScreen( bool( windowState() & Qt::WindowFullScreen) );
show();
}
//-----------------------------------------------------------------------------
/** Enable or disable Fullscreen Mode
*/
void
CoreWidget::setFullscreen(bool _state ) {
if ( _state )
setWindowState( windowState() | Qt::WindowFullScreen);
else {
if ( windowState() & Qt::WindowFullScreen )
setWindowState( windowState() ^ Qt::WindowFullScreen);
}
OpenFlipper::Options::fullScreen( bool( windowState() & Qt::WindowFullScreen) );
show();
}
//-----------------------------------------------------------------------------
/** Hide or show logger
*/
void
CoreWidget::toggleLogger() {
// toggle
OpenFlipper::Options::hideLogger( !OpenFlipper::Options::hideLogger() );
// Hide/Show Logger
showLogger( !OpenFlipper::Options::hideLogger() );
}
/** Hide or show logger
*/
void
CoreWidget::showLogger(bool _state) {
//Hide Logger
if ( !_state ) {
QList wsizes( splitter_->sizes() );
// Remember old size
originalLoggerSize_ = wsizes[1];
wsizes[0] = wsizes[0]+wsizes[1];
wsizes[1] = 0;
splitter_->setSizes(wsizes);
} else {
if ( originalLoggerSize_ == 0)
originalLoggerSize_ = 240;
QList wsizes( splitter_->sizes() );
if (wsizes[0] == 0)
wsizes[0] = height();
wsizes[0] = wsizes[0]+wsizes[1] - originalLoggerSize_;
wsizes[1] = originalLoggerSize_;
splitter_->setSizes(wsizes);
}
}
//-----------------------------------------------------------------------------
/** Hide or show toolbox
*/
void
CoreWidget::toggleToolbox() {
//toggle
showToolbox( OpenFlipper::Options::hideToolbox() );
}
//-----------------------------------------------------------------------------
/** Hide or show toolbox
*/
void
CoreWidget::showToolbox( bool _state ) {
//toggle
OpenFlipper::Options::hideToolbox( !_state );
if ( OpenFlipper::Options::hideToolbox() ){
//hide all toolWidgets
for (uint p=0; p < plugins_.size(); p++)
if (plugins_[p].widget)
plugins_[p].widget->setVisible(false);
//hide ViewMode Selection Widget
dockViewMode_->setVisible(false);
}else{
//reset last ViewMode
if (OpenFlipper::Options::defaultToolboxMode().trimmed() == "")
setViewMode("All");
else
setViewMode( OpenFlipper::Options::defaultToolboxMode() );
}
}
//-----------------------------------------------------------------------------
/** Handles keypress events or passes them to plugins
*/
void
CoreWidget::keyPressEvent(QKeyEvent* _e)
{
if (_e->modifiers() == Qt::ControlModifier ) {
switch (_e->key())
{
case Qt::Key_F :
toggleFullscreen();
return;
case Qt::Key_L :
toggleLogger();
return;
case Qt::Key_T :
toggleToolbox();
return;
// Send remaining events to plugins
default:
mapKeyPressEvent(_e);
return;
}
}
switch (_e->key())
{
// Send remaining events to plugins
default:
mapKeyPressEvent(_e);
break;
}
}
//-----------------------------------------------------------------------------
/** Handle Key Release Events */
void
CoreWidget::keyReleaseEvent(QKeyEvent* _e) {
mapKeyReleaseEvent(_e);
}
//-----------------------------------------------------------------------------
/** Map Key Press Events to Plugins */
void
CoreWidget::mapKeyPressEvent(QKeyEvent* _e){
//find the first plugin which wants to handle that key
for (uint i=0; i < plugins_.size(); i++)
for (int k=0; k < plugins_[i].keys.count(); k++)
if ( plugins_[i].keys[k].key == _e->key()
&& plugins_[i].keys[k].modifiers == _e->modifiers() ){
KeyInterface* keyPlugin = qobject_cast< KeyInterface * >(plugins_[i].plugin);
if (keyPlugin){
// if ( checkSlot( plugins_[i].plugin , "slotKeyEvent(QKeyEvent*)" ) )
keyPlugin->slotKeyEvent(_e);
}
//only inform further plugins if this is a multiUse key
if (!plugins_[i].keys[k].multiUse)
return;
}
}
//-----------------------------------------------------------------------------
/** Map Key Release Events to Plugins */
void
CoreWidget::mapKeyReleaseEvent(QKeyEvent* _e){
if (_e->isAutoRepeat()) return; //consider only "real" release events
//find the first plugin which wants to handle that key
for (uint i=0; i < plugins_.size(); i++)
for (int k=0; k < plugins_[i].keys.count(); k++)
if ( plugins_[i].keys[k].key == _e->key()
&& plugins_[i].keys[k].modifiers == _e->modifiers() ){
KeyInterface* keyPlugin = qobject_cast< KeyInterface * >(plugins_[i].plugin);
if (keyPlugin){
// if ( checkSlot( plugins_[i].plugin , "slotKeyReleaseEvent(QKeyEvent*)" ) )
keyPlugin->slotKeyReleaseEvent(_e);
}
//only inform further plugins if this is a multiUse key
if (!plugins_[i].keys[k].multiUse)
return;
}
}
//-----------------------------------------------------------------------------
/** Register a key to a plugin */
void
CoreWidget::slotRegisterKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description, bool _multiUse){
//first check if the key is already registered by the coreWidget
bool found = false;
bool multi = false;
for (uint i=0; i < coreKeys_.size(); i++)
if (coreKeys_[i].key == _key && coreKeys_[i].modifiers == _modifiers){
found = true;
multi = coreKeys_[i].multiUse;
break;
}
//then check if the key is already registered by a different plugin
if (!found)
for (uint i=0; i < plugins_.size(); i++)
for (int k=0; k < plugins_[i].keys.count(); k++)
if (plugins_[i].keys[k].key == _key
&& plugins_[i].keys[k].modifiers == _modifiers){
found = true;
multi = plugins_[i].keys[k].multiUse;
break;
}
if (found)
emit log(LOGERR, "Key already registered elsewhere.");
//check if its a key for the core
if (sender() == this){
KeyBinding kb;
kb.key = _key;
kb.modifiers = _modifiers;
kb.description = _description;
kb.multiUse = multi || _multiUse;
if (multi && !_multiUse)
log(LOGWARN, "Key registered as multiUse key.");
coreKeys_.push_back( kb );
return;
}
//find plugin
PluginInfo* pluginInfo = 0;
for (uint i=0; i < plugins_.size(); i++)
if (plugins_[i].plugin == sender())
pluginInfo = &plugins_[i];
if (pluginInfo == 0){
emit log(LOGERR, "Unable to register key. Plugin not found!");
return;
}
KeyBinding kb;
kb.key = _key;
kb.modifiers = _modifiers;
kb.description = _description;
kb.multiUse = multi || _multiUse;
if (multi && !_multiUse)
log(LOGWARN, "Key registered as multiUse key.");
pluginInfo->keys.append( kb );
}
//=============================================================================
void
CoreWidget::addRecent(QString _filename, DataType _type)
{
//dont add objects to recentMenu while loadind Settings
if ( OpenFlipper::Options::loadingSettings() ) return;
OpenFlipper::Options::addRecentFile(_filename, _type);
updateRecent();
}
//=============================================================================
void
CoreWidget::updateRecent()
{
if ( recentFilesMenu_ == NULL)
return;
recentFilesMenu_->clear();
QVector< OpenFlipper::Options::RecentFile > recentFiles = OpenFlipper::Options::recentFiles();
for (int i = 0 ; i < recentFiles.size() ; ++i ) {
QString path = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
switch(recentFiles[i].type){
case DATA_TRIANGLE_MESH:
path += "TriangleType.png"; break;
case DATA_POLY_MESH:
path += "PolyType.png"; break;
case DATA_POLY_LINE:
path += "PolyLineType.png"; break;
case DATA_BSPLINE_CURVE:
path += "BSplineCurveType.png"; break;
case DATA_NONE:
path += "Settings-Icon.png"; break;
default: path = "";
}
recentFilesMenu_->addAction(QIcon(path), recentFiles[i].filename);
}
}
void
CoreWidget::closeEvent ( QCloseEvent * /* event */ ) {
emit exit();
}
void CoreWidget::showOptionsWidget() {
if ( OpenFlipper::Options::nogui() )
return;
if ( optionsWidget_ == 0 ) {
optionsWidget_ = new OptionsWidget(plugins_, coreKeys_, 0);
connect(optionsWidget_,SIGNAL(applyOptions()),this,SIGNAL(applyOptions()));
connect(optionsWidget_,SIGNAL(saveOptions()),this,SIGNAL(saveOptions()));
}
//show the optionsWidget centered
QPoint center;
center.setX( x() + width() / 2 );
center.setY( y() + height() / 2 );
optionsWidget_->setGeometry(center.x() - optionsWidget_->width() / 2,
center.y() - optionsWidget_->height()/ 2, optionsWidget_->width(), optionsWidget_->height());
optionsWidget_->show();
}
//=============================================================================