1
/***************************************************************************
2
* Copyright (c) 2011 Thomas Anderson <ta@nextgenengineering> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library 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 Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
31
#include <QPrintDialog>
39
#include "Base/Console.h"
42
#include "DlgCustomizeSpaceball.h"
43
#include "Application.h"
44
#include "BitmapFactory.h"
45
#include "GuiApplicationNativeEventAware.h"
46
#include "SpaceballEvent.h"
49
using GroupVector = std::vector<Base::Reference<ParameterGrp> >;
51
using namespace Gui::Dialog;
53
ButtonView::ButtonView(QWidget *parent) : QListView(parent)
58
void ButtonView::selectButton(int number)
60
this->selectionModel()->select(this->model()->index(number, 0), QItemSelectionModel::ClearAndSelect);
61
this->scrollTo(this->model()->index(number, 0), QAbstractItemView::EnsureVisible);
64
void ButtonView::goSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
67
if (selected.indexes().isEmpty())
69
QModelIndex select(selected.indexes().at(0));
70
Q_EMIT changeCommandSelection(this->model()->data(select, Qt::UserRole).toString());
73
void ButtonView::goChangedCommand(const QString& commandName)
75
QModelIndex index(this->currentIndex());
76
auto model = dynamic_cast<ButtonModel*>(this->model());
77
if (model && index.isValid())
78
model->setCommand(index.row(), commandName);
81
///////////////////////////////////////////////////////////////////////////////////////
83
ButtonModel::ButtonModel(QObject *parent) : QAbstractListModel(parent)
85
//load3DConnexionButtons("SpacePilot Pro");
88
// Process the given Mapping tree to load in the Button mappings.
89
void ButtonModel::load3DConnexionButtonMapping(boost::property_tree::ptree ButtonMapTree)
91
spaceballButtonGroup()->Clear();
93
BOOST_FOREACH(const boost::property_tree::ptree::value_type &Map, ButtonMapTree.get_child("Mapping"))
95
if ("Map" == Map.first)
97
std::string ButtonDescription;
98
std::string ButtonCode;
99
std::string ButtonCommand;
100
std::string ButtonDownTime;
102
// Inspect Map attributes
103
BOOST_FOREACH(const boost::property_tree::ptree::value_type &kv, Map.second.get_child("<xmlattr>"))
105
std::string Attribute;
108
Attribute = kv.first.data();
109
Value = kv.second.data();
111
if (0 == Attribute.compare("Description"))
113
ButtonDescription = Value;
115
if (0 == Attribute.compare("KeyCode"))
119
if (0 == Attribute.compare("DownTime"))
121
ButtonDownTime = Value;
123
if (0 == Attribute.compare("Command"))
125
ButtonCommand = Value;
129
// ButtonCode is mandatory, the remaining attributes optional.
130
if (!ButtonCode.empty())
132
Base::Reference<ParameterGrp> newGroup;
134
newGroup = spaceballButtonGroup()->GetGroup(ButtonCode.c_str());
135
newGroup->SetASCII("Command", ButtonCommand.c_str());
136
newGroup->SetASCII("Description", ButtonDescription.c_str());
142
// Optionally preload Button model with 3DConnexion configuration to match Solidworks
143
// For now the Button mapping file (3DConnexion.xml) is held the same folder as the FreeCAD executable.
144
void ButtonModel::load3DConnexionButtons(const char *RequiredDeviceName)
148
boost::property_tree::ptree tree;
149
boost::property_tree::ptree DeviceTree;
151
// exception thrown if no file found
152
std::string path = App::Application::getResourceDir();
153
path += "3Dconnexion/3DConnexion.xml";
154
read_xml(path.c_str(), tree);
156
BOOST_FOREACH(const boost::property_tree::ptree::value_type &ButtonMap, tree.get_child(""))
158
if ("ButtonMap" == ButtonMap.first)
160
// Inspect ButtonMap attributes for DeviceName
161
BOOST_FOREACH(const boost::property_tree::ptree::value_type &kv, ButtonMap.second.get_child("<xmlattr>"))
163
std::string Attribute;
166
Attribute = kv.first.data();
167
Value = kv.second.data();
169
if (0 == Attribute.compare("DeviceName"))
171
if (0 == Value.compare(RequiredDeviceName))
173
// We found the ButtonMap we want to load up
174
DeviceTree = ButtonMap.second;
180
// If we found the required devices ButtonMap
181
if (!DeviceTree.empty())
183
load3DConnexionButtonMapping(DeviceTree);
186
catch (const std::exception& e)
188
// We don't mind not finding the file to be opened
189
Base::Console().Warning("%s\n", e.what());
193
int ButtonModel::rowCount (const QModelIndex &parent) const
196
return spaceballButtonGroup()->GetGroups().size();
199
QVariant ButtonModel::data (const QModelIndex &index, int role) const
201
GroupVector groupVector = spaceballButtonGroup()->GetGroups();
202
if (index.row() >= (int)groupVector.size())
204
Base::Console().Log("index error in ButtonModel::data\n");
207
if (role == Qt::DisplayRole)
208
return {getLabel(index.row())};
209
if (role == Qt::DecorationRole)
211
static QPixmap icon(BitmapFactory().pixmap("spaceball_button").scaled
212
(32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
215
if (role == Qt::UserRole)
216
return {QString::fromStdString(groupVector.at(index.row())->GetASCII("Command"))};
217
if (role == Qt::SizeHintRole)
218
return {QSize(32, 32)};
222
void ButtonModel::insertButtonRows(int number)
224
int buttonCount = spaceballButtonGroup()->GetGroups().size();
225
beginInsertRows(QModelIndex(), buttonCount, number-buttonCount+1);
226
for (int index = buttonCount; index < number + 1; ++index)
229
groupName.setNum(index);
230
Base::Reference<ParameterGrp> newGroup = spaceballButtonGroup()->GetGroup(groupName.toLatin1());//builds the group.
231
newGroup->SetASCII("Command", "");
232
newGroup->SetASCII("Description", "");
238
void ButtonModel::setCommand(int row, QString command)
240
GroupVector groupVector = spaceballButtonGroup()->GetGroups();
241
groupVector.at(row)->SetASCII("Command", command.toLatin1());
244
void ButtonModel::goButtonPress(int number)
246
QString numberString;
247
numberString.setNum(number);
248
if (!spaceballButtonGroup()->HasGroup(numberString.toLatin1()))
249
insertButtonRows(number);
252
void ButtonModel::goMacroRemoved(const QByteArray& macroName)
254
GroupVector groupVector = spaceballButtonGroup()->GetGroups();
255
for (auto & it : groupVector)
256
if (std::string(macroName.data()) == it->GetASCII("Command"))
257
it->SetASCII("Command", "");
260
void ButtonModel::goClear()
262
if (this->rowCount() < 1)
264
this->beginRemoveRows(QModelIndex(), 0, this->rowCount()-1);
265
spaceballButtonGroup()->Clear();
266
this->endRemoveRows();
269
ParameterGrp::handle ButtonModel::spaceballButtonGroup() const
271
static ParameterGrp::handle group = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
272
GetGroup("Spaceball")->GetGroup("Buttons");
276
QString ButtonModel::getLabel(const int &number) const
278
if (number > -1 && number < 32) {
279
QString numberString;
280
numberString.setNum(number);
281
QString desc = QString::fromStdString(spaceballButtonGroup()->
282
GetGroup(numberString.toLatin1())->
283
GetASCII("Description",""));
285
desc = QString::fromUtf8(" \"") + desc + QString::fromUtf8("\"");
286
return tr("Button %1").arg(number + 1) + desc;
288
return tr("Out Of Range");
291
void ButtonModel::loadConfig(const char *RequiredDeviceName)
294
if (!RequiredDeviceName) {
297
load3DConnexionButtons(RequiredDeviceName);
300
//////////////////////////////////////////////////////////////////////////////////////////
302
CommandView::CommandView(QWidget *parent) : QTreeView(parent)
304
this->setEnabled(false);
305
connect(this, &QTreeView::clicked, this, &CommandView::goClicked);
308
void CommandView::goChangeCommandSelection(const QString& commandName)
310
if (!this->isEnabled())
311
this->setEnabled(true);
312
this->selectionModel()->clear();
314
if (commandName.isEmpty())
316
QModelIndexList index(this->model()->match(this->model()->index(0,0), Qt::UserRole, QVariant(commandName), 1,
317
Qt::MatchWrap | Qt::MatchRecursive));
320
this->expand(index.at(0));
321
this->setCurrentIndex(index.at(0));
324
void CommandView::goClicked(const QModelIndex &index)
326
if (index.flags() & Qt::ItemIsSelectable)
328
QString commandName = this->model()->data(index, Qt::UserRole).toString();
329
if (commandName.isEmpty())
331
Q_EMIT changedCommand(commandName);
335
/////////////////////////////////////////////////////////////////////////////////////////
337
CommandNode::CommandNode(NodeType typeIn)
347
CommandNode::~CommandNode()
349
qDeleteAll(children);
352
/////////////////////////////////////////////////////////////////////////////////////////
354
CommandModel::CommandModel(QObject *parent) : QAbstractItemModel(parent)
362
CommandModel::~CommandModel()
368
QModelIndex CommandModel::index(int row, int column, const QModelIndex &parent) const
372
if (!parent.isValid())
373
return createIndex(row, column, rootNode->children.at(row));
375
CommandNode *parentNode = nodeFromIndex(parent);
378
return createIndex(row, column, parentNode->children.at(row));
381
QModelIndex CommandModel::parent(const QModelIndex &index) const
383
CommandNode *base = nodeFromIndex(index);
386
CommandNode *parentNode = base->parent;
389
CommandNode *grandParentNode = parentNode->parent;
390
if (!grandParentNode)
393
int row = grandParentNode->children.indexOf(parentNode);
396
return createIndex(row, index.column(), parentNode);
399
int CommandModel::rowCount(const QModelIndex &parent) const
401
if (!parent.isValid())
402
return rootNode->children.size();
404
CommandNode *parentNode = nodeFromIndex(parent);
407
return parentNode->children.count();
410
int CommandModel::columnCount(const QModelIndex &parent) const
416
QVariant CommandModel::data(const QModelIndex &index, int role) const
418
CommandNode *node = nodeFromIndex(index);
421
if (role == Qt::DisplayRole)
423
if (node->nodeType == CommandNode::CommandType)
424
return {qApp->translate(node->aCommand->className(), node->aCommand->getMenuText())};
425
if (node->nodeType == CommandNode::GroupType)
427
if (node->children.empty())
429
CommandNode *childNode = node->children.at(0);
430
return {qApp->translate(childNode->aCommand->className(), childNode->aCommand->getGroupName())};
434
if (role == Qt::DecorationRole)
436
if (node->nodeType == CommandNode::CommandType)
438
if (node->aCommand->getPixmap())
439
return QVariant(BitmapFactory().pixmap(node->aCommand->getPixmap()).scaled
440
(32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
443
if (role == Qt::SizeHintRole) {
444
if (node->nodeType == CommandNode::CommandType)
445
return {QSize(32, 32)};
447
if (role == Qt::UserRole)
449
if (node->nodeType == CommandNode::CommandType)
450
return {QString::fromLatin1(node->aCommand->getName())};
451
if (node->nodeType == CommandNode::GroupType)
453
if (node->children.empty())
455
CommandNode *childNode = node->children.at(0);
456
return {QString::fromLatin1(childNode->aCommand->getGroupName())};
460
if (role == Qt::ToolTipRole) {
461
if (node->nodeType == CommandNode::CommandType)
462
return {QString::fromLatin1(node->aCommand->getToolTipText())};
467
QVariant CommandModel::headerData(int section, Qt::Orientation orientation, int role) const
469
if (role == Qt::DisplayRole && orientation == Qt::Horizontal && section == 0)
470
return {tr("Commands")};
474
Qt::ItemFlags CommandModel::flags (const QModelIndex &index) const
476
if (!index.isValid())
477
return Qt::NoItemFlags;
478
CommandNode *node = nodeFromIndex(index);
480
return Qt::NoItemFlags;
481
if (node->nodeType == CommandNode::CommandType)
482
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
483
return Qt::NoItemFlags;
486
CommandNode* CommandModel::nodeFromIndex(const QModelIndex &index) const
489
return static_cast<CommandNode *>(index.internalPointer());
493
void CommandModel::goAddMacro(const QByteArray ¯oName)
495
QModelIndexList indexList(this->match(this->index(0,0), Qt::UserRole, QVariant(QString::fromLatin1("Macros")),
496
1, Qt::MatchWrap | Qt::MatchRecursive));
497
QModelIndex macrosIndex;
498
if (indexList.empty())
500
//this is the first macro and we have to add the Macros item.
501
//figure out where to insert it. Should be in the command groups now.
502
QStringList groups = orderedGroups();
503
int location(groups.indexOf(QString::fromLatin1("Macros")));
505
location = groups.size();
507
this->beginInsertRows(QModelIndex(), location, location);
508
auto macroNode = new CommandNode(CommandNode::GroupType);
509
macroNode->parent = rootNode;
510
rootNode->children.insert(location, macroNode);
511
this->endInsertRows();
512
macrosIndex = this->index(location, 0);
515
macrosIndex = indexList.at(0);
517
Command *command = nullptr;
518
command = Application::Instance->commandManager().getCommandByName(macroName);
522
CommandNode *parentNode = nodeFromIndex(macrosIndex);
526
this->beginInsertRows(macrosIndex, parentNode->children.size(), parentNode->children.size());
527
auto childNode = new CommandNode(CommandNode::CommandType);
528
childNode->parent = parentNode;
529
parentNode->children.push_back(childNode);
530
childNode->aCommand = command;
531
this->endInsertRows();
534
void CommandModel::goRemoveMacro(const QByteArray ¯oName)
536
QModelIndexList macroList(this->match(this->index(0,0), Qt::UserRole, QVariant(QString::fromLatin1(macroName.data())),
537
1, Qt::MatchWrap | Qt::MatchRecursive));
538
if (macroList.isEmpty())
541
QModelIndex childIndex(macroList.at(0));
542
QModelIndex parentIndex(this->parent(childIndex));
543
if (!childIndex.isValid() || !parentIndex.isValid())
546
CommandNode *parentNode = nodeFromIndex(parentIndex);
550
this->beginRemoveRows(parentIndex, childIndex.row(), childIndex.row());
551
delete parentNode->children.takeAt(childIndex.row());
552
this->endRemoveRows();
553
if (parentNode->children.isEmpty())
555
QModelIndex grandParentIndex(this->parent(parentIndex));//this should be root.
556
CommandNode *grandParentNode = nodeFromIndex(grandParentIndex);
557
this->beginRemoveRows(grandParentIndex, parentIndex.row(), parentIndex.row());
558
delete grandParentNode->children.takeAt(parentIndex.row());
559
this->endRemoveRows();
563
void CommandModel::initialize()
565
rootNode = new CommandNode(CommandNode::RootType);
566
QStringList groups(orderedGroups());
567
for (const auto & group : groups)
568
groupCommands(group);
571
void CommandModel::groupCommands(const QString& groupName)
573
auto parentNode = new CommandNode(CommandNode::GroupType);
574
parentNode->parent = rootNode;
575
rootNode->children.push_back(parentNode);
576
std::vector <Command*> commands = Application::Instance->commandManager().getGroupCommands(groupName.toLatin1());
577
for (const auto & command : commands)
579
auto childNode = new CommandNode(CommandNode::CommandType);
580
childNode->parent = parentNode;
581
parentNode->children.push_back(childNode);
582
childNode->aCommand = command;
586
QStringList CommandModel::orderedGroups()
589
std::vector <Command*> commands = Application::Instance->commandManager().getAllCommands();
590
for (const auto & command : commands)
592
QString groupName(QString::fromLatin1(command->getGroupName()));
593
if (!groups.contains(groupName))
601
///////////////////////////////////////////////////////////////////////////////////////
603
PrintModel::PrintModel(QObject *parent, ButtonModel *buttonModelIn, CommandModel *commandModelIn) : QAbstractTableModel(parent)
606
buttonModel = buttonModelIn;
607
commandModel = commandModelIn;
611
int PrintModel::rowCount(const QModelIndex &parent) const
614
return buttonModel->rowCount();
617
int PrintModel::columnCount(const QModelIndex &parent) const
623
QVariant PrintModel::data(const QModelIndex &index, int role) const
625
if (index.column() == 0)
628
return buttonModel->data(buttonModel->index(index.row(), 0), role);
631
if (index.column() == 1)
634
QString commandName(buttonModel->data(buttonModel->index(index.row(), 0), Qt::UserRole).toString());
635
if (commandName.isEmpty())
638
QModelIndexList indexList(commandModel->match(commandModel->index(0,0), Qt::UserRole, QVariant(commandName), 1,
639
Qt::MatchWrap | Qt::MatchRecursive));
640
if (indexList.isEmpty())
643
return commandModel->data(indexList.at(0), role);
648
QVariant PrintModel::headerData(int section, Qt::Orientation orientation, int role) const
650
if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
653
return {tr("Button")};
655
return {tr("Command")};
660
///////////////////////////////////////////////////////////////////////////////////////
662
DlgCustomizeSpaceball::DlgCustomizeSpaceball(QWidget *parent)
663
: CustomizeActionPage(parent)
664
, buttonView(nullptr)
665
, buttonModel(nullptr)
666
, commandView(nullptr)
667
, commandModel(nullptr)
668
, clearButton(nullptr)
669
, printReference(nullptr)
672
this->setWindowTitle(tr("Spaceball Buttons"));
673
auto app = qobject_cast<GUIApplicationNativeEventAware *>(QApplication::instance());
676
if (!app->isSpaceballPresent())
678
this->setMessage(tr("No Spaceball Present"));
682
setupButtonModelView();
683
setupCommandModelView();
684
connect(buttonView, &ButtonView::changeCommandSelection,
685
commandView, &CommandView::goChangeCommandSelection);
686
connect(commandView, &CommandView::changedCommand,
687
buttonView, &ButtonView::goChangedCommand);
689
connect(clearButton, &QPushButton::clicked, this, &DlgCustomizeSpaceball::goClear);
690
connect(printReference, &QPushButton::clicked, this, &DlgCustomizeSpaceball::goPrint);
693
DlgCustomizeSpaceball::~DlgCustomizeSpaceball() = default;
695
void DlgCustomizeSpaceball::setMessage(const QString& message)
697
auto messageLabel = new QLabel(message,this);
698
auto layout = new QVBoxLayout();
699
auto layout2 = new QHBoxLayout();
700
layout2->addStretch();
701
layout2->addWidget(messageLabel);
702
layout2->addStretch();
703
layout->addItem(layout2);
704
this->setLayout(layout);
707
void DlgCustomizeSpaceball::setupButtonModelView()
709
buttonModel = new ButtonModel(this);
710
buttonView = new ButtonView(this);
711
buttonView->setModel(buttonModel);
713
//had to do this here as the views default selection model is not created until after construction.
714
connect(buttonView->selectionModel(), &QItemSelectionModel::selectionChanged,
715
buttonView, &ButtonView::goSelectionChanged);
718
void DlgCustomizeSpaceball::setupCommandModelView()
720
commandModel = new CommandModel(this);
721
commandView = new CommandView(this);
722
commandView->setModel(commandModel);
725
void DlgCustomizeSpaceball::setupLayout()
727
auto buttonLabel = new QLabel(tr("Buttons"), this);
728
clearButton = new QPushButton(tr("Reset"), this);
729
devModel = new QComboBox(this);
731
// Load the devModel(s) from the config xml file
732
devModel->addItems(getModels());
734
// Select the current preference or the first entry
735
QString model = QString::fromStdString(App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
736
GetGroup("Spaceball")->GetASCII("Model",""));
737
if (model.length() > 0) {
738
devModel->setCurrentIndex(devModel->findText(model));
740
devModel->setCurrentIndex(0);
743
auto buttonGroup = new QVBoxLayout();
744
buttonGroup->addWidget(buttonLabel);
745
buttonGroup->addWidget(buttonView);
746
auto clearLayout = new QHBoxLayout();
747
clearLayout->addWidget(devModel);
748
clearLayout->addWidget(clearButton);
749
clearLayout->addStretch();
750
buttonGroup->addLayout(clearLayout);
752
auto splitter = new QSplitter(this);
753
auto leftPane = new QWidget(this);
754
leftPane->setLayout(buttonGroup);
755
splitter->addWidget(leftPane);
756
splitter->addWidget(commandView);
758
printReference = new QPushButton(tr("Print Reference"), this);
759
auto printLayout = new QHBoxLayout();
760
printLayout->addStretch();
761
printLayout->addWidget(printReference);
763
auto layout = new QVBoxLayout();
764
layout->addWidget(splitter);
765
layout->addLayout(printLayout);
767
this->setLayout(layout);
770
sizes << this->size().width()*0.40;
771
sizes << this->size().width()-sizes.at(0);
772
splitter->setSizes(sizes);
775
void DlgCustomizeSpaceball::goClear()
777
commandView->clearSelection();
778
commandView->collapseAll();
779
commandView->setDisabled(true);
780
//buttonModel->goClear();
782
QByteArray currentDevice = devModel->currentText().toLocal8Bit();
783
App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
784
GetGroup("Spaceball")->SetASCII("Model", currentDevice.data());
785
buttonModel->loadConfig(currentDevice.data());
788
void DlgCustomizeSpaceball::goPrint()
790
auto view = new QTableView(this);
791
auto model = new PrintModel(this, buttonModel, commandModel);
792
view->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
793
view->setModel(model);
794
view->horizontalHeader()->resizeSection(0, 150);
795
view->horizontalHeader()->resizeSection(1, 300);
796
view->resize(600, 600);
799
QPrintDialog printDialog(&printer, this);
800
if (printDialog.exec() == QDialog::Accepted)
802
QPainter p(&printer);
807
bool DlgCustomizeSpaceball::event(QEvent *event)
809
if (event->type() != Spaceball::ButtonEvent::ButtonEventType)
810
return CustomizeActionPage::event(event);
811
auto buttonEvent = dynamic_cast<Spaceball::ButtonEvent *>(event);
814
buttonEvent->setHandled(true);
815
if (buttonEvent->buttonStatus() == Spaceball::BUTTON_PRESSED)
816
buttonModel->goButtonPress(buttonEvent->buttonNumber());
817
buttonView->selectButton(buttonEvent->buttonNumber());
822
void DlgCustomizeSpaceball::hideEvent(QHideEvent *event)
824
//having a crash with the last item of the macro command list
825
//being selected and that macro is removed from the macro tab. Hopefully
826
//clearing the selection will cure the problem.
828
buttonView->selectionModel()->clear();
830
commandView->selectionModel()->clear();
831
commandView->collapseAll();
832
commandView->setEnabled(false);
835
CustomizeActionPage::hideEvent(event);
838
void DlgCustomizeSpaceball::showEvent (QShowEvent *event)
841
buttonView->setFocus();
843
CustomizeActionPage::showEvent(event);
846
void DlgCustomizeSpaceball::changeEvent(QEvent *e)
848
if (e->type() == QEvent::LanguageChange)
850
//I don't think I need do anything here. Qt should take care of it?
851
// this->setWindowTitle(tr("Spaceball"));
853
QWidget::changeEvent(e);
856
void DlgCustomizeSpaceball::onAddMacroAction(const QByteArray ¯oName)
858
//need to get the new macro to model.
860
commandModel->goAddMacro(macroName);
863
void DlgCustomizeSpaceball::onRemoveMacroAction(const QByteArray ¯oName)
865
//need to remove macro from model.
867
commandModel->goRemoveMacro(macroName);
868
//need to change any button mapped to macro to an empty string.
870
buttonModel->goMacroRemoved(macroName);
873
void DlgCustomizeSpaceball::onModifyMacroAction(const QByteArray ¯oName)
875
//don't think I need to do anything here.
879
QStringList DlgCustomizeSpaceball::getModels()
881
QStringList modelList;
884
boost::property_tree::ptree tree;
885
boost::property_tree::ptree DeviceTree;
887
// exception thrown if no file found
888
std::string path = App::Application::getResourceDir();
889
path += "3Dconnexion/3DConnexion.xml";
890
read_xml(path.c_str(), tree);
892
BOOST_FOREACH(const boost::property_tree::ptree::value_type &ButtonMap, tree.get_child(""))
894
if ("ButtonMap" == ButtonMap.first)
896
// Inspect ButtonMap attributes for DeviceName
897
BOOST_FOREACH(const boost::property_tree::ptree::value_type &kv, ButtonMap.second.get_child("<xmlattr>"))
899
std::string Attribute;
902
Attribute = kv.first.data();
903
Value = kv.second.data();
905
if (0 == Attribute.compare("DeviceName"))
907
modelList << QString::fromStdString(Value);
913
catch (const std::exception& e)
915
// We don't mind not finding the file to be opened
916
Base::Console().Warning("%s\n", e.what());
922
#include "moc_DlgCustomizeSpaceball.cpp"