LibreCAD
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
clicommand.cpp
Go to the documentation of this file.
1 #include "clicommand.h"
2 #include "ui_clicommand.h"
3 #include <cad/settings.h>
4 #include <memory>
5 #include <iterator>
6 #include <unordered_map>
7 
8 CliCommand::CliCommand(QWidget* parent) :
9  QDockWidget(parent),
10  ui(new Ui::CliCommand),
11  _returnText(false),
12  _historySize(10),
13  _historyIndex(-1)
14 {
15  ui->setupUi(this);
16 
17  connect(ui->command, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
18 
19  _commands = std::make_shared<QStringListModel>();
20  _completer = std::make_shared<QCompleter>();
21 
22  _completer->setCaseSensitivity(Qt::CaseInsensitive);
23  _completer->setCompletionMode(QCompleter::InlineCompletion);
24  _completer->setModel(_commands.get());
25 
26  ui->command->setCompleter(_completer.get());
27 }
28 
30  delete ui;
31 }
32 
33 bool CliCommand::addCommand(std::string name) {
34  if(_commands->stringList().indexOf(name.c_str()) == -1) {
35  auto newList = _commands->stringList();
36  newList << QString(name.c_str());
37  _commands->setStringList(newList);
38  return true;
39  }
40  else {
41  return false;
42  }
43 }
44 
45 void CliCommand::write(QString message) {
46  ui->history->addItem(message);
47  if(ui->history->count() > _historySize) {
48  delete ui->history->takeItem(0);
49  }
50 }
51 
53  auto text = ui->command->text();
54  bool isNumber;
55  QStringList varFind;
56  QRegularExpression re("^([a-zA-Z]{1,10}+)=([0-9]{1,50}.[0-9]{1,50})|([0-9]{1,50})$");
57  QRegularExpressionMatch match = re.match(text, 0, QRegularExpression::PartialPreferCompleteMatch);
58  bool hasMatch = match.hasMatch();
59 
60  if(_returnText) {
61  emit textEntered(text);
62  }
63  else if(text != "") {
64  _history.push_front(text);
65 
66  if (_history.size() > _historySize) {
67  _history.pop_back();
68  }
69 
70  auto number = text.toDouble(&isNumber);
71  if (isNumber) {
72  enterNumber(number);
73  }
74  else if (text.indexOf(";") != -1 || text.indexOf(",") != -1) {
75  enterCoordinate(text);
76  }
77  else if(hasMatch) {
78  varFind = text.split("=");
79  Settings::inst = Settings::instance();
80  std::unordered_map<std::string, double>::iterator it1;
81 
82  if(checkParam(varFind[0])) {
83  write(QString("Value of %1 = %2").arg(varFind[0]).arg(varFind[1].toFloat()));
84  Settings::setVal(varFind[0].toStdString(),varFind[1].toFloat());
85  }
86  else {
87  write(QString("No such variable."));
88  }
89  }
90  else {
91  enterCommand(text);
92  }
93  }
94 
95  _historyIndex = -1;
96  ui->command->clear();
97 }
98 
99 void CliCommand::keyPressEvent(QKeyEvent *event) {
100  onKeyPressed(event);
101 }
102 
103 void CliCommand::enterCommand(QString command) {
104  auto completion = _completer->currentCompletion();
105 
106  if(command.compare(completion, Qt::CaseInsensitive) == 0) {
107  write("Command: " + completion);
108  emit commandEntered(completion);
109  }
110  else {
111  if(checkParam(command)) {
112  write(QString("Value of %1=%2").arg(command).arg(Settings::val(command.toStdString())));
113  }
114  else
115  {
116  write("Command " + command + " not found");
117  ui->history->item(ui->history->count() - 1)->setForeground(Qt::red);
118  }
119  }
120 }
121 
122 bool CliCommand::checkParam(QString command) {
123  return Settings::exists(command.toStdString());
124 }
125 
126 void CliCommand::enterCoordinate(QString coordinate) {
127  lc::geo::Coordinate point;
128  QStringList numbers;
129  bool isRelative = false;
130 
131  if(coordinate.indexOf("@") != -1) {
132  isRelative = true;
133  coordinate.remove("@");
134  }
135 
136  if(coordinate.indexOf(";") != -1) {
137  numbers = coordinate.split(";");
138  }
139  else {
140  numbers = coordinate.split(",");
141  }
142 
143 
144  if(numbers.size() > 2) {
145  point = lc::geo::Coordinate(numbers[0].toFloat(), numbers[1].toFloat(), numbers[2].toFloat());
146  }
147  else {
148  point = lc::geo::Coordinate(numbers[0].toFloat(), numbers[1].toFloat());
149  }
150 
151  auto message = QString("Coordinate: x=%1; y=%2; z=%3").arg(point.x()).arg(point.y()).arg(point.z());
152  write(message);
153 
154  if(isRelative) {
155  emit relativeCoordinateEntered(point);
156  }
157  else {
158  emit coordinateEntered(point);
159  }
160 }
161 
162 void CliCommand::enterNumber(double number) {
163  write(QString("Number: %1").arg(number));
164  emit numberEntered(number);
165 }
166 
167 void CliCommand::onKeyPressed(QKeyEvent *event) {
168  switch(event->key()) {
169  case Qt::Key_Up:
170 
171  if(_historyIndex + 1 < _history.size()) {
172  _historyIndex++;
173  ui->command->setText(_history[_historyIndex]);
174  }
175  break;
176 
177  case Qt::Key_Down:
178  if(_historyIndex > 0) {
179  _historyIndex--;
180  ui->command->setText(_history[_historyIndex]);
181  }
182  else {
183  _historyIndex = -1;
184  ui->command->clear();
185  }
186  break;
187 
188  default:
189  ui->command->event(event);
190  break;
191  }
192 }
193 
194 void CliCommand::setText(QString text) {
195  ui->command->setText(text);
196 }
197 
198 void CliCommand::returnText(bool returnText) {
200 }
CliCommand(QWidget *parent=0)
Create widget.
Definition: clicommand.cpp:8
bool addCommand(std::string name)
Add a new command.
Definition: clicommand.cpp:33
void enterCoordinate(QString coordinate)
Definition: clicommand.cpp:126
std::shared_ptr< QCompleter > _completer
Definition: clicommand.h:87
Command line widget.
Definition: clicommand.h:20
void onKeyPressed(QKeyEvent *event)
Process key events. Browse history if up or down key is pressed. This is a slot to allow getting key ...
Definition: clicommand.cpp:167
void textEntered(QString text)
int _historyIndex
Definition: clicommand.h:93
std::shared_ptr< QStringListModel > _commands
Definition: clicommand.h:88
int _historySize
Definition: clicommand.h:92
Ui::CliCommand * ui
Definition: clicommand.h:86
void coordinateEntered(lc::geo::Coordinate coordinate)
void write(QString message)
Write a message in the logs.
Definition: clicommand.cpp:45
QStringList _history
Definition: clicommand.h:91
void numberEntered(double number)
bool checkParam(QString command)
Definition: clicommand.cpp:122
void onReturnPressed()
Parse entered text. Check if the text is a number, a coordinate or a command and emit the right signa...
Definition: clicommand.cpp:52
void commandEntered(QString command)
void setText(QString text)
Write text in input.
Definition: clicommand.cpp:194
void enterCommand(QString command)
Definition: clicommand.cpp:103
void returnText(bool returnText)
Return raw text to Lua.
Definition: clicommand.cpp:198
bool _returnText
Definition: clicommand.h:89
void enterNumber(double number)
Definition: clicommand.cpp:162
void relativeCoordinateEntered(lc::geo::Coordinate coordinate)
void keyPressEvent(QKeyEvent *event)
Definition: clicommand.cpp:99