FreeCAD

Форк
0
/
DlgCustomizeSpaceball.cpp 
922 строки · 28.9 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2011 Thomas Anderson <ta@nextgenengineering>            *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
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.      *
10
 *                                                                         *
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.                  *
15
 *                                                                         *
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                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#ifndef _PreComp_
26
#include <QComboBox>
27
#include <QHBoxLayout>
28
#include <QHeaderView>
29
#include <QLabel>
30
#include <QPainter>
31
#include <QPrintDialog>
32
#include <QPrinter>
33
#include <QPushButton>
34
#include <QSplitter>
35
#include <QTableView>
36
#include <QVBoxLayout>
37
#endif
38

39
#include "Base/Console.h"
40

41
#include "Command.h"
42
#include "DlgCustomizeSpaceball.h"
43
#include "Application.h"
44
#include "BitmapFactory.h"
45
#include "GuiApplicationNativeEventAware.h"
46
#include "SpaceballEvent.h"
47

48

49
using GroupVector = std::vector<Base::Reference<ParameterGrp> >;
50

51
using namespace Gui::Dialog;
52

53
ButtonView::ButtonView(QWidget *parent) : QListView(parent)
54
{
55

56
}
57

58
void ButtonView::selectButton(int number)
59
{
60
    this->selectionModel()->select(this->model()->index(number, 0), QItemSelectionModel::ClearAndSelect);
61
    this->scrollTo(this->model()->index(number, 0), QAbstractItemView::EnsureVisible);
62
}
63

64
void ButtonView::goSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
65
{
66
    Q_UNUSED(deselected);
67
    if (selected.indexes().isEmpty())
68
        return;
69
    QModelIndex select(selected.indexes().at(0));
70
    Q_EMIT changeCommandSelection(this->model()->data(select, Qt::UserRole).toString());
71
}
72

73
void ButtonView::goChangedCommand(const QString& commandName)
74
{
75
    QModelIndex index(this->currentIndex());
76
    auto model = dynamic_cast<ButtonModel*>(this->model());
77
    if (model && index.isValid())
78
        model->setCommand(index.row(), commandName);
79
}
80

81
///////////////////////////////////////////////////////////////////////////////////////
82

83
ButtonModel::ButtonModel(QObject *parent) : QAbstractListModel(parent)
84
{
85
   //load3DConnexionButtons("SpacePilot Pro");
86
}
87

88
// Process the given Mapping tree to load in the Button mappings.
89
void ButtonModel::load3DConnexionButtonMapping(boost::property_tree::ptree ButtonMapTree)
90
{
91
   spaceballButtonGroup()->Clear();
92

93
   BOOST_FOREACH(const boost::property_tree::ptree::value_type &Map, ButtonMapTree.get_child("Mapping"))
94
   {
95
      if ("Map" == Map.first)
96
      {
97
         std::string ButtonDescription;
98
         std::string ButtonCode;
99
         std::string ButtonCommand;
100
         std::string ButtonDownTime;
101

102
         // Inspect Map attributes
103
         BOOST_FOREACH(const boost::property_tree::ptree::value_type &kv, Map.second.get_child("<xmlattr>"))
104
         {
105
            std::string Attribute;
106
            std::string Value;
107

108
            Attribute = kv.first.data();
109
            Value = kv.second.data();
110

111
            if (0 == Attribute.compare("Description"))
112
            {
113
               ButtonDescription = Value;
114
            }
115
            if (0 == Attribute.compare("KeyCode"))
116
            {
117
               ButtonCode = Value;
118
            }
119
            if (0 == Attribute.compare("DownTime"))
120
            {
121
               ButtonDownTime = Value;
122
            }
123
            if (0 == Attribute.compare("Command"))
124
            {
125
               ButtonCommand = Value;
126
            }
127
         }
128

129
         // ButtonCode is mandatory, the remaining attributes optional.
130
         if (!ButtonCode.empty())
131
         {
132
            Base::Reference<ParameterGrp> newGroup;
133

134
            newGroup = spaceballButtonGroup()->GetGroup(ButtonCode.c_str());
135
            newGroup->SetASCII("Command", ButtonCommand.c_str());
136
            newGroup->SetASCII("Description", ButtonDescription.c_str());
137
         }
138
      }
139
   }
140
}
141

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)
145
{
146
   try
147
   {
148
      boost::property_tree::ptree tree;
149
      boost::property_tree::ptree DeviceTree;
150

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);
155

156
      BOOST_FOREACH(const boost::property_tree::ptree::value_type &ButtonMap, tree.get_child(""))
157
      {
158
         if ("ButtonMap" == ButtonMap.first)
159
         {
160
            // Inspect ButtonMap attributes for DeviceName
161
            BOOST_FOREACH(const boost::property_tree::ptree::value_type &kv, ButtonMap.second.get_child("<xmlattr>"))
162
            {
163
               std::string Attribute;
164
               std::string Value;
165

166
               Attribute = kv.first.data();
167
               Value = kv.second.data();
168

169
               if (0 == Attribute.compare("DeviceName"))
170
               {
171
                  if (0 == Value.compare(RequiredDeviceName))
172
                  {
173
                     // We found the ButtonMap we want to load up
174
                     DeviceTree = ButtonMap.second;
175
                  }
176
               }
177
            }
178
         }
179
      }
180
      // If we found the required devices ButtonMap
181
      if (!DeviceTree.empty())
182
      {
183
         load3DConnexionButtonMapping(DeviceTree);
184
      }
185
   }
186
   catch (const std::exception& e)
187
   {
188
      // We don't mind not finding the file to be opened
189
      Base::Console().Warning("%s\n", e.what());
190
   }
191
}
192

193
int ButtonModel::rowCount (const QModelIndex &parent) const
194
{
195
    Q_UNUSED(parent);
196
    return spaceballButtonGroup()->GetGroups().size();
197
}
198

199
QVariant ButtonModel::data (const QModelIndex &index, int role) const
200
{
201
    GroupVector groupVector = spaceballButtonGroup()->GetGroups();
202
    if (index.row() >= (int)groupVector.size())
203
    {
204
        Base::Console().Log("index error in ButtonModel::data\n");
205
        return {};
206
    }
207
    if (role == Qt::DisplayRole)
208
        return {getLabel(index.row())};
209
    if (role == Qt::DecorationRole)
210
    {
211
        static QPixmap icon(BitmapFactory().pixmap("spaceball_button").scaled
212
                            (32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
213
        return {icon};
214
    }
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)};
219
    return {};
220
}
221

222
void ButtonModel::insertButtonRows(int number)
223
{
224
    int buttonCount = spaceballButtonGroup()->GetGroups().size();
225
    beginInsertRows(QModelIndex(), buttonCount, number-buttonCount+1);
226
    for (int index = buttonCount; index < number + 1; ++index)
227
    {
228
        QString groupName;
229
        groupName.setNum(index);
230
        Base::Reference<ParameterGrp> newGroup = spaceballButtonGroup()->GetGroup(groupName.toLatin1());//builds the group.
231
        newGroup->SetASCII("Command", "");
232
        newGroup->SetASCII("Description", "");
233
    }
234
    endInsertRows();
235
    return;
236
}
237

238
void ButtonModel::setCommand(int row, QString command)
239
{
240
    GroupVector groupVector = spaceballButtonGroup()->GetGroups();
241
    groupVector.at(row)->SetASCII("Command", command.toLatin1());
242
}
243

244
void ButtonModel::goButtonPress(int number)
245
{
246
    QString numberString;
247
    numberString.setNum(number);
248
    if (!spaceballButtonGroup()->HasGroup(numberString.toLatin1()))
249
        insertButtonRows(number);
250
}
251

252
void ButtonModel::goMacroRemoved(const QByteArray& macroName)
253
{
254
    GroupVector groupVector = spaceballButtonGroup()->GetGroups();
255
    for (auto & it : groupVector)
256
        if (std::string(macroName.data()) == it->GetASCII("Command"))
257
            it->SetASCII("Command", "");
258
}
259

260
void ButtonModel::goClear()
261
{
262
    if (this->rowCount() < 1)
263
        return;
264
    this->beginRemoveRows(QModelIndex(), 0, this->rowCount()-1);
265
    spaceballButtonGroup()->Clear();
266
    this->endRemoveRows();
267
}
268

269
ParameterGrp::handle ButtonModel::spaceballButtonGroup() const
270
{
271
    static ParameterGrp::handle group = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
272
            GetGroup("Spaceball")->GetGroup("Buttons");
273
    return group;
274
}
275

276
QString ButtonModel::getLabel(const int &number) const
277
{
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",""));
284
        if (desc.length())
285
            desc = QString::fromUtf8(" \"") + desc + QString::fromUtf8("\"");
286
        return tr("Button %1").arg(number + 1) + desc;
287
    } else
288
        return tr("Out Of Range");
289
}
290

291
void ButtonModel::loadConfig(const char *RequiredDeviceName)
292
{
293
    goClear();
294
    if (!RequiredDeviceName) {
295
        return;
296
    }
297
    load3DConnexionButtons(RequiredDeviceName);
298
}
299

300
//////////////////////////////////////////////////////////////////////////////////////////
301

302
CommandView::CommandView(QWidget *parent) : QTreeView(parent)
303
{
304
    this->setEnabled(false);
305
    connect(this, &QTreeView::clicked, this, &CommandView::goClicked);
306
}
307

308
void CommandView::goChangeCommandSelection(const QString& commandName)
309
{
310
    if (!this->isEnabled())
311
        this->setEnabled(true);
312
    this->selectionModel()->clear();
313
    this->collapseAll();
314
    if (commandName.isEmpty())
315
        return;
316
    QModelIndexList index(this->model()->match(this->model()->index(0,0), Qt::UserRole, QVariant(commandName), 1,
317
                                               Qt::MatchWrap | Qt::MatchRecursive));
318
    if (index.empty())
319
        return;
320
    this->expand(index.at(0));
321
    this->setCurrentIndex(index.at(0));
322
}
323

324
void CommandView::goClicked(const QModelIndex &index)
325
{
326
    if (index.flags() & Qt::ItemIsSelectable)
327
    {
328
        QString commandName = this->model()->data(index, Qt::UserRole).toString();
329
        if (commandName.isEmpty())
330
            return;
331
        Q_EMIT changedCommand(commandName);
332
    }
333
}
334

335
/////////////////////////////////////////////////////////////////////////////////////////
336

337
CommandNode::CommandNode(NodeType typeIn)
338
{
339
    //NOLINTBEGIN
340
    nodeType = typeIn;
341
    parent = nullptr;
342
    children.clear();
343
    aCommand = nullptr;
344
    //NOLINTEND
345
}
346

347
CommandNode::~CommandNode()
348
{
349
    qDeleteAll(children);
350
}
351

352
/////////////////////////////////////////////////////////////////////////////////////////
353

354
CommandModel::CommandModel(QObject *parent) : QAbstractItemModel(parent)
355
{
356
    //NOLINTBEGIN
357
    rootNode = nullptr;
358
    initialize();
359
    //NOLINTEND
360
}
361

362
CommandModel::~CommandModel()
363
{
364
    delete rootNode;
365
    rootNode = nullptr;
366
}
367

368
QModelIndex CommandModel::index(int row, int column, const QModelIndex &parent) const
369
{
370
    if (!rootNode)
371
        return {};
372
    if (!parent.isValid())
373
        return createIndex(row, column, rootNode->children.at(row));
374

375
    CommandNode *parentNode = nodeFromIndex(parent);
376
    if (!parentNode)
377
        return {};
378
    return createIndex(row, column, parentNode->children.at(row));
379
}
380

381
QModelIndex CommandModel::parent(const QModelIndex &index) const
382
{
383
    CommandNode *base = nodeFromIndex(index);
384
    if (!base)
385
        return {};
386
    CommandNode *parentNode = base->parent;
387
    if (!parentNode)
388
        return {};
389
    CommandNode *grandParentNode = parentNode->parent;
390
    if (!grandParentNode)
391
        return {};
392

393
    int row = grandParentNode->children.indexOf(parentNode);
394
    if (row == -1)
395
        return {};
396
    return createIndex(row, index.column(), parentNode);
397
}
398

399
int CommandModel::rowCount(const QModelIndex &parent) const
400
{
401
    if (!parent.isValid())
402
        return rootNode->children.size();
403

404
    CommandNode *parentNode = nodeFromIndex(parent);
405
    if (!parentNode)
406
        return 0;
407
    return parentNode->children.count();
408
}
409

410
int CommandModel::columnCount(const QModelIndex &parent) const
411
{
412
    Q_UNUSED(parent);
413
    return 1;
414
}
415

416
QVariant CommandModel::data(const QModelIndex &index, int role) const
417
{
418
    CommandNode *node = nodeFromIndex(index);
419
    if (!node)
420
        return {};
421
    if (role == Qt::DisplayRole)
422
    {
423
        if (node->nodeType == CommandNode::CommandType)
424
            return {qApp->translate(node->aCommand->className(), node->aCommand->getMenuText())};
425
        if (node->nodeType == CommandNode::GroupType)
426
        {
427
            if (node->children.empty())
428
                return {};
429
            CommandNode *childNode = node->children.at(0);
430
            return {qApp->translate(childNode->aCommand->className(), childNode->aCommand->getGroupName())};
431
        }
432
        return {};
433
    }
434
    if (role == Qt::DecorationRole)
435
    {
436
        if (node->nodeType == CommandNode::CommandType)
437
        {
438
            if (node->aCommand->getPixmap())
439
                return QVariant(BitmapFactory().pixmap(node->aCommand->getPixmap()).scaled
440
                                (32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
441
        }
442
    }
443
    if (role == Qt::SizeHintRole) {
444
        if (node->nodeType == CommandNode::CommandType)
445
            return {QSize(32, 32)};
446
    }
447
    if (role == Qt::UserRole)
448
    {
449
        if (node->nodeType == CommandNode::CommandType)
450
            return {QString::fromLatin1(node->aCommand->getName())};
451
        if (node->nodeType == CommandNode::GroupType)
452
        {
453
            if (node->children.empty())
454
                return {};
455
            CommandNode *childNode = node->children.at(0);
456
            return {QString::fromLatin1(childNode->aCommand->getGroupName())};
457
        }
458
        return {};
459
    }
460
    if (role == Qt::ToolTipRole) {
461
        if (node->nodeType == CommandNode::CommandType)
462
            return {QString::fromLatin1(node->aCommand->getToolTipText())};
463
    }
464
    return {};
465
}
466

467
QVariant CommandModel::headerData(int section, Qt::Orientation orientation, int role) const
468
{
469
    if (role == Qt::DisplayRole && orientation == Qt::Horizontal && section == 0)
470
        return {tr("Commands")};
471
    return {};
472
}
473

474
Qt::ItemFlags CommandModel::flags (const QModelIndex &index) const
475
{
476
    if (!index.isValid())
477
        return Qt::NoItemFlags;
478
    CommandNode *node = nodeFromIndex(index);
479
    if (!node)
480
        return Qt::NoItemFlags;
481
    if (node->nodeType == CommandNode::CommandType)
482
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
483
    return Qt::NoItemFlags;
484
}
485

486
CommandNode* CommandModel::nodeFromIndex(const QModelIndex &index) const
487
{
488
    if (index.isValid())
489
        return static_cast<CommandNode *>(index.internalPointer());
490
    return rootNode;
491
}
492

493
void CommandModel::goAddMacro(const QByteArray &macroName)
494
{
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())
499
    {
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")));
504
        if (location == -1)
505
            location = groups.size();
506
        //add row
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);
513
    }
514
    else
515
        macrosIndex = indexList.at(0);
516

517
    Command *command = nullptr;
518
    command = Application::Instance->commandManager().getCommandByName(macroName);
519
    if (!command)
520
        return;
521

522
    CommandNode *parentNode = nodeFromIndex(macrosIndex);
523
    if (!parentNode)
524
        return;
525

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();
532
}
533

534
void CommandModel::goRemoveMacro(const QByteArray &macroName)
535
{
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())
539
        return;
540

541
    QModelIndex childIndex(macroList.at(0));
542
    QModelIndex parentIndex(this->parent(childIndex));
543
    if (!childIndex.isValid() || !parentIndex.isValid())
544
        return;
545

546
    CommandNode *parentNode = nodeFromIndex(parentIndex);
547
    if (!parentNode)
548
        return;
549

550
    this->beginRemoveRows(parentIndex, childIndex.row(), childIndex.row());
551
    delete parentNode->children.takeAt(childIndex.row());
552
    this->endRemoveRows();
553
    if (parentNode->children.isEmpty())
554
    {
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();
560
    }
561
}
562

563
void CommandModel::initialize()
564
{
565
    rootNode = new CommandNode(CommandNode::RootType);
566
    QStringList groups(orderedGroups());
567
    for (const auto & group : groups)
568
        groupCommands(group);
569
}
570

571
void CommandModel::groupCommands(const QString& groupName)
572
{
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)
578
    {
579
        auto childNode = new CommandNode(CommandNode::CommandType);
580
        childNode->parent = parentNode;
581
        parentNode->children.push_back(childNode);
582
        childNode->aCommand = command;
583
    }
584
}
585

586
QStringList CommandModel::orderedGroups()
587
{
588
    QStringList groups;
589
    std::vector <Command*> commands = Application::Instance->commandManager().getAllCommands();
590
    for (const auto & command : commands)
591
    {
592
        QString groupName(QString::fromLatin1(command->getGroupName()));
593
        if (!groups.contains(groupName))
594
            groups << groupName;
595
    }
596
    //how to sort?
597
    groups.sort();
598
    return groups;
599
}
600

601
///////////////////////////////////////////////////////////////////////////////////////
602

603
PrintModel::PrintModel(QObject *parent, ButtonModel *buttonModelIn, CommandModel *commandModelIn) : QAbstractTableModel(parent)
604
{
605
    //NOLINTBEGIN
606
    buttonModel = buttonModelIn;
607
    commandModel = commandModelIn;
608
    //NOLINTEND
609
}
610

611
int PrintModel::rowCount(const QModelIndex &parent) const
612
{
613
    Q_UNUSED(parent);
614
    return buttonModel->rowCount();
615
}
616

617
int PrintModel::columnCount(const QModelIndex &parent) const
618
{
619
    Q_UNUSED(parent);
620
    return 2;
621
}
622

623
QVariant PrintModel::data(const QModelIndex &index, int role) const
624
{
625
    if (index.column() == 0)
626
    {
627
        //button column;
628
        return buttonModel->data(buttonModel->index(index.row(), 0), role);
629
    }
630

631
    if (index.column() == 1)
632
    {
633
        //command column;
634
        QString commandName(buttonModel->data(buttonModel->index(index.row(), 0), Qt::UserRole).toString());
635
        if (commandName.isEmpty())
636
            return {};
637

638
        QModelIndexList indexList(commandModel->match(commandModel->index(0,0), Qt::UserRole, QVariant(commandName), 1,
639
                                                   Qt::MatchWrap | Qt::MatchRecursive));
640
        if (indexList.isEmpty())
641
            return {};
642

643
        return commandModel->data(indexList.at(0), role);
644
    }
645
    return {};
646
}
647

648
QVariant PrintModel::headerData(int section, Qt::Orientation orientation, int role) const
649
{
650
    if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
651
        return {};
652
    if (section == 0)
653
        return {tr("Button")};
654
    if (section == 1)
655
        return {tr("Command")};
656
    else
657
        return {};
658
}
659

660
///////////////////////////////////////////////////////////////////////////////////////
661

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)
670
  , devModel(nullptr)
671
{
672
    this->setWindowTitle(tr("Spaceball Buttons"));
673
    auto app = qobject_cast<GUIApplicationNativeEventAware *>(QApplication::instance());
674
    if (!app)
675
        return;
676
    if (!app->isSpaceballPresent())
677
    {
678
        this->setMessage(tr("No Spaceball Present"));
679
        return;
680
    }
681

682
    setupButtonModelView();
683
    setupCommandModelView();
684
    connect(buttonView, &ButtonView::changeCommandSelection,
685
            commandView, &CommandView::goChangeCommandSelection);
686
    connect(commandView, &CommandView::changedCommand,
687
            buttonView, &ButtonView::goChangedCommand);
688
    setupLayout();
689
    connect(clearButton, &QPushButton::clicked, this, &DlgCustomizeSpaceball::goClear);
690
    connect(printReference, &QPushButton::clicked, this, &DlgCustomizeSpaceball::goPrint);
691
}
692

693
DlgCustomizeSpaceball::~DlgCustomizeSpaceball() = default;
694

695
void DlgCustomizeSpaceball::setMessage(const QString& message)
696
{
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);
705
}
706

707
void DlgCustomizeSpaceball::setupButtonModelView()
708
{
709
    buttonModel = new ButtonModel(this);
710
    buttonView = new ButtonView(this);
711
    buttonView->setModel(buttonModel);
712

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);
716
}
717

718
void DlgCustomizeSpaceball::setupCommandModelView()
719
{
720
    commandModel = new CommandModel(this);
721
    commandView = new CommandView(this);
722
    commandView->setModel(commandModel);
723
}
724

725
void DlgCustomizeSpaceball::setupLayout()
726
{
727
    auto buttonLabel = new QLabel(tr("Buttons"), this);
728
    clearButton = new QPushButton(tr("Reset"), this);
729
    devModel = new QComboBox(this);
730

731
    // Load the devModel(s) from the config xml file
732
    devModel->addItems(getModels());
733

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));
739
    } else {
740
        devModel->setCurrentIndex(0);
741
    }
742

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);
751

752
    auto splitter = new QSplitter(this);
753
    auto leftPane = new QWidget(this);
754
    leftPane->setLayout(buttonGroup);
755
    splitter->addWidget(leftPane);
756
    splitter->addWidget(commandView);
757

758
    printReference = new QPushButton(tr("Print Reference"), this);
759
    auto printLayout = new QHBoxLayout();
760
    printLayout->addStretch();
761
    printLayout->addWidget(printReference);
762

763
    auto layout = new QVBoxLayout();
764
    layout->addWidget(splitter);
765
    layout->addLayout(printLayout);
766

767
    this->setLayout(layout);
768

769
    QList<int> sizes;
770
    sizes << this->size().width()*0.40;
771
    sizes << this->size().width()-sizes.at(0);
772
    splitter->setSizes(sizes);
773
}
774

775
void DlgCustomizeSpaceball::goClear()
776
{
777
    commandView->clearSelection();
778
    commandView->collapseAll();
779
    commandView->setDisabled(true);
780
    //buttonModel->goClear();
781

782
    QByteArray currentDevice = devModel->currentText().toLocal8Bit();
783
    App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
784
            GetGroup("Spaceball")->SetASCII("Model", currentDevice.data());
785
    buttonModel->loadConfig(currentDevice.data());
786
}
787

788
void DlgCustomizeSpaceball::goPrint()
789
{
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);
797

798
    QPrinter printer;
799
    QPrintDialog printDialog(&printer, this);
800
    if (printDialog.exec() == QDialog::Accepted)
801
    {
802
        QPainter p(&printer);
803
        view->render(&p);
804
    }
805
}
806

807
bool DlgCustomizeSpaceball::event(QEvent *event)
808
{
809
    if (event->type() != Spaceball::ButtonEvent::ButtonEventType)
810
        return CustomizeActionPage::event(event);
811
    auto buttonEvent = dynamic_cast<Spaceball::ButtonEvent *>(event);
812
    if (!buttonEvent)
813
        return true;
814
    buttonEvent->setHandled(true);
815
    if (buttonEvent->buttonStatus() == Spaceball::BUTTON_PRESSED)
816
        buttonModel->goButtonPress(buttonEvent->buttonNumber());
817
    buttonView->selectButton(buttonEvent->buttonNumber());
818

819
    return true;
820
}
821

822
void DlgCustomizeSpaceball::hideEvent(QHideEvent *event)
823
{
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.
827
    if (buttonView)
828
        buttonView->selectionModel()->clear();
829
    if (commandView) {
830
        commandView->selectionModel()->clear();
831
        commandView->collapseAll();
832
        commandView->setEnabled(false);
833
    }
834

835
    CustomizeActionPage::hideEvent(event);
836
}
837

838
void DlgCustomizeSpaceball::showEvent (QShowEvent *event)
839
{
840
    if (buttonView)
841
        buttonView->setFocus();
842

843
    CustomizeActionPage::showEvent(event);
844
}
845

846
void DlgCustomizeSpaceball::changeEvent(QEvent *e)
847
{
848
    if (e->type() == QEvent::LanguageChange)
849
    {
850
        //I don't think I need do anything here. Qt should take care of it?
851
//        this->setWindowTitle(tr("Spaceball"));
852
    }
853
    QWidget::changeEvent(e);
854
}
855

856
void DlgCustomizeSpaceball::onAddMacroAction(const QByteArray &macroName)
857
{
858
    //need to get the new macro to model.
859
    if (commandModel)
860
        commandModel->goAddMacro(macroName);
861
}
862

863
void DlgCustomizeSpaceball::onRemoveMacroAction(const QByteArray &macroName)
864
{
865
    //need to remove macro from model.
866
    if (commandModel)
867
        commandModel->goRemoveMacro(macroName);
868
    //need to change any button mapped to macro to an empty string.
869
    if (buttonModel)
870
        buttonModel->goMacroRemoved(macroName);
871
}
872

873
void DlgCustomizeSpaceball::onModifyMacroAction(const QByteArray &macroName)
874
{
875
    //don't think I need to do anything here.
876
    Q_UNUSED(macroName);
877
}
878

879
QStringList DlgCustomizeSpaceball::getModels()
880
{
881
    QStringList modelList;
882
    try
883
    {
884
       boost::property_tree::ptree tree;
885
       boost::property_tree::ptree DeviceTree;
886

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);
891

892
       BOOST_FOREACH(const boost::property_tree::ptree::value_type &ButtonMap, tree.get_child(""))
893
       {
894
          if ("ButtonMap" == ButtonMap.first)
895
          {
896
             // Inspect ButtonMap attributes for DeviceName
897
             BOOST_FOREACH(const boost::property_tree::ptree::value_type &kv, ButtonMap.second.get_child("<xmlattr>"))
898
             {
899
                std::string Attribute;
900
                std::string Value;
901

902
                Attribute = kv.first.data();
903
                Value = kv.second.data();
904

905
                if (0 == Attribute.compare("DeviceName"))
906
                {
907
                    modelList << QString::fromStdString(Value);
908
                }
909
             }
910
          }
911
       }
912
    }
913
    catch (const std::exception& e)
914
    {
915
       // We don't mind not finding the file to be opened
916
       Base::Console().Warning("%s\n", e.what());
917
    }
918

919
    return modelList;
920
}
921

922
#include "moc_DlgCustomizeSpaceball.cpp"
923

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.