220 lines
6.0 KiB
C++
220 lines
6.0 KiB
C++
|
/*
|
||
|
* Copyright (C) 2015 Open Source Robotics Foundation
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <boost/range/adaptor/reversed.hpp>
|
||
|
|
||
|
#include "gazebo/transport/Node.hh"
|
||
|
|
||
|
#include "gazebo/gui/Actions.hh"
|
||
|
#include "gazebo/gui/UserCmdHistoryPrivate.hh"
|
||
|
#include "gazebo/gui/UserCmdHistory.hh"
|
||
|
|
||
|
using namespace gazebo;
|
||
|
using namespace gui;
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
UserCmdHistory::UserCmdHistory()
|
||
|
: dataPtr(new UserCmdHistoryPrivate)
|
||
|
{
|
||
|
if (!g_undoAct || !g_redoAct || !g_undoHistoryAct || !g_redoHistoryAct)
|
||
|
{
|
||
|
gzerr << "Action missing, not initializing UserCmdHistory" << std::endl;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Action groups
|
||
|
this->dataPtr->undoActions = new QActionGroup(this);
|
||
|
this->dataPtr->undoActions->setExclusive(false);
|
||
|
|
||
|
this->dataPtr->redoActions = new QActionGroup(this);
|
||
|
this->dataPtr->redoActions->setExclusive(false);
|
||
|
|
||
|
// Pub / sub
|
||
|
this->dataPtr->node = transport::NodePtr(new transport::Node());
|
||
|
this->dataPtr->node->TryInit(common::Time::Maximum());
|
||
|
|
||
|
this->dataPtr->undoRedoPub =
|
||
|
this->dataPtr->node->Advertise<msgs::UndoRedo>("~/undo_redo");
|
||
|
this->dataPtr->userCmdStatsSub =
|
||
|
this->dataPtr->node->Subscribe("~/user_cmd_stats",
|
||
|
&UserCmdHistory::OnUserCmdStatsMsg, this);
|
||
|
|
||
|
// Qt connections
|
||
|
connect(this, SIGNAL(StatsSignal()), this, SLOT(OnStatsSlot()));
|
||
|
|
||
|
connect(g_undoAct, SIGNAL(triggered()), this, SLOT(OnUndo()));
|
||
|
connect(g_redoAct, SIGNAL(triggered()), this, SLOT(OnRedo()));
|
||
|
connect(g_undoHistoryAct, SIGNAL(triggered()), this,
|
||
|
SLOT(OnUndoCmdHistory()));
|
||
|
connect(g_redoHistoryAct, SIGNAL(triggered()), this,
|
||
|
SLOT(OnRedoCmdHistory()));
|
||
|
|
||
|
connect(this->dataPtr->undoActions, SIGNAL(triggered(QAction *)), this,
|
||
|
SLOT(OnUndoCommand(QAction *)));
|
||
|
connect(this->dataPtr->undoActions, SIGNAL(hovered(QAction *)), this,
|
||
|
SLOT(OnUndoHovered(QAction *)));
|
||
|
|
||
|
connect(this->dataPtr->redoActions, SIGNAL(triggered(QAction *)), this,
|
||
|
SLOT(OnRedoCommand(QAction *)));
|
||
|
connect(this->dataPtr->redoActions, SIGNAL(hovered(QAction *)), this,
|
||
|
SLOT(OnRedoHovered(QAction *)));
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
UserCmdHistory::~UserCmdHistory()
|
||
|
{
|
||
|
delete this->dataPtr;
|
||
|
this->dataPtr = NULL;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnUndo()
|
||
|
{
|
||
|
this->OnUndoCommand(NULL);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnUndoCommand(QAction *_action)
|
||
|
{
|
||
|
msgs::UndoRedo msg;
|
||
|
msg.set_undo(true);
|
||
|
|
||
|
if (_action)
|
||
|
{
|
||
|
msg.set_id(_action->data().toUInt());
|
||
|
}
|
||
|
|
||
|
this->dataPtr->undoRedoPub->Publish(msg);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnUndoHovered(QAction *_action)
|
||
|
{
|
||
|
bool beforeThis = true;
|
||
|
for (auto action : this->dataPtr->undoActions->actions())
|
||
|
{
|
||
|
action->blockSignals(true);
|
||
|
action->setChecked(beforeThis);
|
||
|
action->blockSignals(false);
|
||
|
|
||
|
if (action->data() == _action->data())
|
||
|
beforeThis = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnRedo()
|
||
|
{
|
||
|
this->OnRedoCommand(NULL);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnRedoCommand(QAction *_action)
|
||
|
{
|
||
|
msgs::UndoRedo msg;
|
||
|
msg.set_undo(false);
|
||
|
|
||
|
if (_action)
|
||
|
{
|
||
|
msg.set_id(_action->data().toUInt());
|
||
|
}
|
||
|
|
||
|
this->dataPtr->undoRedoPub->Publish(msg);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnRedoHovered(QAction *_action)
|
||
|
{
|
||
|
bool beforeThis = true;
|
||
|
for (auto action : this->dataPtr->redoActions->actions())
|
||
|
{
|
||
|
action->blockSignals(true);
|
||
|
action->setChecked(beforeThis);
|
||
|
action->blockSignals(false);
|
||
|
|
||
|
if (action->data() == _action->data())
|
||
|
beforeThis = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnUserCmdStatsMsg(ConstUserCmdStatsPtr &_msg)
|
||
|
{
|
||
|
this->dataPtr->msg.Clear();
|
||
|
this->dataPtr->msg.CopyFrom(*_msg);
|
||
|
|
||
|
this->StatsSignal();
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnStatsSlot()
|
||
|
{
|
||
|
g_undoAct->setEnabled(this->dataPtr->msg.undo_cmd_count() > 0);
|
||
|
g_redoAct->setEnabled(this->dataPtr->msg.redo_cmd_count() > 0);
|
||
|
g_undoHistoryAct->setEnabled(this->dataPtr->msg.undo_cmd_count() > 0);
|
||
|
g_redoHistoryAct->setEnabled(this->dataPtr->msg.redo_cmd_count() > 0);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnUndoCmdHistory()
|
||
|
{
|
||
|
// Clear undo action group
|
||
|
for (auto action : this->dataPtr->undoActions->actions())
|
||
|
{
|
||
|
this->dataPtr->undoActions->removeAction(action);
|
||
|
}
|
||
|
|
||
|
// Create new menu
|
||
|
QMenu menu;
|
||
|
for (auto cmd : boost::adaptors::reverse(this->dataPtr->msg.undo_cmd()))
|
||
|
{
|
||
|
QAction *action = new QAction(QString::fromStdString(cmd.description()),
|
||
|
this);
|
||
|
action->setData(QVariant(cmd.id()));
|
||
|
action->setCheckable(true);
|
||
|
menu.addAction(action);
|
||
|
this->dataPtr->undoActions->addAction(action);
|
||
|
}
|
||
|
|
||
|
menu.exec(QCursor::pos());
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////
|
||
|
void UserCmdHistory::OnRedoCmdHistory()
|
||
|
{
|
||
|
// Clear redo action group
|
||
|
for (auto action : this->dataPtr->redoActions->actions())
|
||
|
{
|
||
|
this->dataPtr->redoActions->removeAction(action);
|
||
|
}
|
||
|
|
||
|
// Create new menu
|
||
|
QMenu menu;
|
||
|
for (auto cmd : boost::adaptors::reverse(this->dataPtr->msg.redo_cmd()))
|
||
|
{
|
||
|
QAction *action = new QAction(QString::fromStdString(cmd.description()),
|
||
|
this);
|
||
|
action->setData(QVariant(cmd.id()));
|
||
|
action->setCheckable(true);
|
||
|
menu.addAction(action);
|
||
|
this->dataPtr->redoActions->addAction(action);
|
||
|
}
|
||
|
|
||
|
menu.exec(QCursor::pos());
|
||
|
}
|
||
|
|