error(item.m_value);
break;
case ReGuiQueueItem::StatusLine:
- setStatusMessage(false, item.m_value);
+ setStatusMessage(LOG_INFO, item.m_value);
break;
default:
error("unknown item type: " + QString::number(item.m_type)
storage.store(ui->comboBoxDirPatterns, "comboBoxDirPatterns");
storage.close();
}
+
+/**
+ * Writes a message.
+ *
+ * @param level mode of the message, e.g. LOG_ERROR
+ * @param message the message
+ * @return <code>false</code>level is error or warning
+ */
+bool MainWindow::say(ReLoggerLevel level, const QString& message){
+ if (level == LOG_ERROR || level == LOG_WARNING)
+ error(message);
+ else
+ log(message);
+ return level >= LOG_INFO;
+}
+
/**
* Starts or stops the backup.
*
* @param mainWindow the GUI object
*/
CommandProcessor::CommandProcessor(MainWindow* mainWindow) :
- m_mainWindow(mainWindow)
+ m_mainWindow(mainWindow),
+ m_random()
{
+ m_random.modifySeed(ReRandomizer::nearTrueRandom());
}
+/**
+ * Destructor.
+ */
+CommandProcessor::~CommandProcessor()
+{
+
+}
+
+/**
+ * Interpret a script.
+ * @param text text with commands
+ */
void CommandProcessor::interpret(const QString& text)
{
+ QStringList lines = text.split('\n');
+ for (int lineNo = 0; lineNo < lines.count(); lineNo++){
+ statement(lineNo + 1, lines.at(lineNo));
+ }
+}
+
+/**
+ * Displays a message.
+ *
+ * @param message message to show
+ */
+void CommandProcessor::out(const QString& message)
+{
+ m_mainWindow->say(LOG_INFO, message);
+}
+
+/**
+ * Executes one statement.
+ *
+ * @param lineNo the line number (for error numbers)
+ * @param text the statement to execute
+ */
+void CommandProcessor::statement(int lineNo, const QString& text){
+ QString trimmed = text.trimmed();
+ if (trimmed.isEmpty() || trimmed.startsWith("#")){
+ // comment, nothing to do
+ } else {
+ m_mainWindow->say(LOG_INFO, trimmed);
+ QStringList args = trimmed.split(" ");
+ QString arg0 = args.at(0);
+ if (QString("eurojackpot").startsWith(arg0)){
+ euroJackpot(args);
+ } else if (QString("lotto").startsWith(arg0)){
+ lotto(args);
+ } else if (QString("time").startsWith(arg0)){
+ time(args);
+ } else {
+ QStringList dummy;
+ help("unknown command: " + arg0, dummy);
+ }
+ }
+}
+
+/**
+ * Calculates a event "take n elements of a set of m".
+ *
+ * Each result element is unique (once taken it is no more available).<br>
+ * The elements are numbered: [1..M].<br>
+ * The result set is randomly defined.
+ *
+ * @param n count of result elements
+ * @param m count of elements
+ * @param separator the separator between 2 elements in the result string
+ * @return a string containing the n element numbers, e.g. "2 5 9"
+ */
+QString CommandProcessor::calcNOfM(int n, int m, const QString& separator){
+ QString rc;
+ rc.reserve(m * 5);
+
+ QList<int> array;
+ for (int ix = 0; ix < n; ix++){
+ int value = m_random.nextInt(m, 1);
+ bool exists = false;
+ for (int ix2 = 0; ! exists && ix2 < array.count(); ix2++){
+ exists = array[ix2] == value;
+ }
+ if (exists)
+ ix--;
+ else
+ array.append(value);
+ }
+ qSort(array.begin(), array.end(), qLess<int>());
+ int width = 1;
+ if (m < 10)
+ width = 1;
+ else if (m < 100)
+ width = 2;
+ else if (m < 1000)
+ width = 3;
+ for (int ix = 0; ix < array.count(); ix++){
+ if (ix > 0)
+ rc.append(separator);
+ rc.append(QString("%1").arg(array.at(ix), width));
+ }
+ return rc;
+}
+
+/**
+ * Displays proposals for the Euro Jackpot.
+ *
+ * @param args the command arguments
+ */
+void CommandProcessor::euroJackpot(const QStringList& args){
+ uint count = 1;
+ if (args.count() > 1){
+ QString arg1 = args.at(1);
+ if (ReQStringUtils::lengthOfUInt(arg1, 0, 10, &count) != arg1.length()){
+ help("integer expected as parameter <count>", args);
+ count = 0;
+ }
+ }
+ if (count > 0){
+ QString line;
+ for (uint ix = 0; ix < count; ix++){
+ line = QString::number(ix + 1) + ": " + calcNOfM(5, 50)
+ + " | " + calcNOfM(2, 10);
+ out(line);
+ }
+ }
+}
+
+/**
+ * Displays an error message.
+ *
+ * @param errorMessage
+ * @param args
+ */
+void CommandProcessor::help(const QString& errorMessage, const QStringList& args)
+{
+ QString prefix = args.count() > 0 ? ": " + args.at(0) : "";
+ m_mainWindow->say(LOG_ERROR, prefix + errorMessage);
+}
+/**
+ * Displays proposals for the Euro Jackpot.
+ *
+ * @param args the command arguments
+ */
+void CommandProcessor::lotto(const QStringList& args){
+ uint count = 1;
+ if (args.count() > 1){
+ QString arg1 = args.at(1);
+ if (ReQStringUtils::lengthOfUInt(arg1, 0, 10, &count) != arg1.length()){
+ help("integer expected as parameter <count>", args);
+ count = 0;
+ }
+ }
+ if (count > 0){
+ QString line;
+ for (uint ix = 0; ix < count; ix++){
+ line = QString::number(ix + 1) + ": " + calcNOfM(5, 50)
+ + " | " + calcNOfM(1, 10);
+ out(line);
+ }
+ }
+}
+
+/**
+ * Displays a time expression
+ *
+ * @param args the command arguments
+ */
+void CommandProcessor::time(const QStringList& args){
}
{
public:
CommandProcessor(MainWindow* mainWindow);
+ virtual ~CommandProcessor();
public:
+ QString calcNOfM(int n, int m, const QString& separator = " ");
+ void euroJackpot(const QStringList& args);
+ void help(const QString& errorMessage, const QStringList& args);
void interpret(const QString& text);
+ void lotto(const QStringList& args);
+ void out(const QString& message);
+ void time(const QStringList& args);
+ void statement(int lineNo, const QString& text);
protected:
MainWindow* m_mainWindow;
+ ReKISSRandomizer m_random;
};
#endif // COMMANDPROCESSOR_HPP
#include "recommand.hpp"
+/**
+ * Constructor.
+ *
+ * @param homeDir "" or the home directory
+ * @param parent NULL ot the owner of the main window
+ */
MainWindow::MainWindow(const QString& homeDir, QWidget *parent) :
ReGuiApplication("recommand", homeDir, 2, 100100100, parent),
ReGuiValidator(),
ui(new Ui::MainWindow),
m_processor(NULL)
{
+ m_processor = new CommandProcessor(this);
ui->setupUi(this);
initializeGuiElements();
connect(ui->pushButtonRun, SIGNAL(clicked()), this, SLOT(onRun()));
- connect(ui->pushButtonClear, SIGNAL(clicked()), this, SLOT(onClear()));
+ connect(ui->pushButtonClearEdit, SIGNAL(clicked()), this, SLOT(onClearEdit()));
+ connect(ui->pushButtonClearList, SIGNAL(clicked()), this, SLOT(onClearList()));
+ connect(ui->pushButtonSave, SIGNAL(clicked()), this, SLOT(onSave()));
+ onLoad();
}
+/**
+ * Destructor.
+ */
MainWindow::~MainWindow()
{
+ delete m_processor;
delete ui;
}
/**
* Clears the result field.
*/
-void MainWindow::onClear()
+void MainWindow::onClearEdit()
{
- ui->textEditResult->clear();
+ ui->textEditResult->setText("");
+}
+
+/**
+ * Clears the result list.
+ */
+void MainWindow::onClearList()
+{
+ ui->listWidgetResult->clear();
}
/**
*/
void MainWindow::onRun()
{
+ QString text = ui->textEditPad->toPlainText();
+ int length = text.length();
+ int position = min(ui->textEditPad->textCursor().position(), length - 1);
+ int pos1;
+ for (pos1 = position; pos1 > 0; pos1--){
+ if (text.at(pos1) == '\n' && text.at(pos1 - 1) == '\n')
+ break;
+ }
+ if (pos1 > 0 && text.at(pos1 - 1) != '\n')
+ pos1--;
+ int pos2;
+ for (pos2 = position; pos2 < length - 1; pos2++){
+ if (text.at(pos2) == '\n' && text.at(pos2 + 1) == '\n')
+ break;
+ }
+ if (pos2 < length - 1 && text.at(pos2 + 1) != '\n')
+ pos2++;
+ ui->textEditResult->clear();
+ QString script = text.mid(pos1, pos2 - pos1 + 1);
+ if (script.length() > 10 || script.trimmed().length() > 0)
+ m_processor->interpret(script);
+}
+
+/**
+ * Saves the pad.
+ */
+void MainWindow::onLoad()
+{
+ QString fname = m_homeDir + "pad.txt";
+ QByteArray content;
+ ReFileUtils::readFromFile(I18N::s2b(fname).constData(), content);
+ ui->textEditPad->setText(QString::fromUtf8(content));
+}
+
+/**
+ * Saves the pad.
+ */
+void MainWindow::onSave()
+{
+ QString fname = m_homeDir + "pad.txt";
+ ReFileUtils::writeToFile(I18N::s2b(fname).constData(),
+ ui->textEditPad->toPlainText().toUtf8().constData());
}
/**
* @return <code>false</code>level is error or warning
*/
bool MainWindow::say(ReLoggerLevel level, const QString& message){
- QString edit = ui->textEditResult->toPlainText();
QString msg;
switch(level){
case LOG_WARNING:
- msg = "+++ ";
+ msg = "+ ";
break;
case LOG_ERROR:
- msg = "*** ";
+ msg = "! ";
break;
default:
break;
}
+ ui->listWidgetResult->addItem(msg + message);
+ ui->listWidgetResult->setCurrentRow(ui->listWidgetResult->count() - 1);
- if (! edit.endsWith("\n")){
+ QString edit = ui->textEditResult->toPlainText();
+ if (! edit.isEmpty() && ! edit.endsWith("\n")){
msg += "\n";
}
msg += message;
edit += msg;
- ui->textEditResult->setText(edit);
+ ui->textEditResult->setPlainText(edit);
return level >= LOG_INFO;
}
* The original sources can be found on https://github.com/republib.
*/
+#ifndef MAINWINDOW_HPP
+#define MAINWINDOW_HPP
#ifndef RECOMMAND_HPP
#include "recommand.hpp"
#endif
-#ifndef MAINWINDOW_HPP
-#define MAINWINDOW_HPP
#include <QMainWindow>
class MainWindow : public ReGuiApplication, public ReGuiValidator
{
Q_OBJECT
-
public:
explicit MainWindow(const QString& homeDir, QWidget *parent = 0);
virtual ~MainWindow();
public slots:
virtual void onGuiTimerUpdate();
+ void onClearEdit();
+ void onClearList();
+ void onLoad();
void onRun();
- void onClear();
+ void onSave();
public:
virtual bool say(ReLoggerLevel level, const QString& message);
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
</item>
<item>
<widget class="QPushButton" name="pushButtonSave">
- <property name="text">
- <string>Save</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QTextEdit" name="textEditPad"/>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="layoutWidget">
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Result:</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
+ <property name="minimumSize">
<size>
- <width>40</width>
- <height>20</height>
+ <width>125</width>
+ <height>0</height>
</size>
</property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="pushButtonClear">
<property name="text">
- <string>Clear</string>
+ <string>Save</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
- <widget class="QTextEdit" name="textEditResult"/>
+ <widget class="QTextEdit" name="textEditPad"/>
</item>
</layout>
</widget>
+ <widget class="QTabWidget" name="tabWidgetResult">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tabList">
+ <attribute name="title">
+ <string>Result as list</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonClearList">
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidgetResult"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tabEdit">
+ <attribute name="title">
+ <string>Result as edit field</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="minimumSize">
+ <size>
+ <width>125</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>From List</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonClearEdit">
+ <property name="minimumSize">
+ <size>
+ <width>125</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="textEditResult">
+ <property name="font">
+ <font>
+ <family>FreeMono</family>
+ </font>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
</widget>
</item>
</layout>