From 1ed968f75e42c8feed666c5bcff7ea967385ad2c Mon Sep 17 00:00:00 2001 From: dyma96 Date: Wed, 2 Jul 2014 16:09:50 +0400 Subject: [PATCH 01/14] empty project --- configurationServer/gui/gui/gui.pro | 20 ++++++++++++++++++ configurationServer/gui/gui/main.cpp | 11 ++++++++++ configurationServer/gui/gui/mainwindow.cpp | 14 +++++++++++++ configurationServer/gui/gui/mainwindow.h | 22 ++++++++++++++++++++ configurationServer/gui/gui/mainwindow.ui | 24 ++++++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 configurationServer/gui/gui/gui.pro create mode 100644 configurationServer/gui/gui/main.cpp create mode 100644 configurationServer/gui/gui/mainwindow.cpp create mode 100644 configurationServer/gui/gui/mainwindow.h create mode 100644 configurationServer/gui/gui/mainwindow.ui diff --git a/configurationServer/gui/gui/gui.pro b/configurationServer/gui/gui/gui.pro new file mode 100644 index 0000000..d5323b3 --- /dev/null +++ b/configurationServer/gui/gui/gui.pro @@ -0,0 +1,20 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-07-02T16:08:37 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = gui +TEMPLATE = app + + +SOURCES += main.cpp\ + mainwindow.cpp + +HEADERS += mainwindow.h + +FORMS += mainwindow.ui diff --git a/configurationServer/gui/gui/main.cpp b/configurationServer/gui/gui/main.cpp new file mode 100644 index 0000000..b48f94e --- /dev/null +++ b/configurationServer/gui/gui/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/configurationServer/gui/gui/mainwindow.cpp b/configurationServer/gui/gui/mainwindow.cpp new file mode 100644 index 0000000..49d64fc --- /dev/null +++ b/configurationServer/gui/gui/mainwindow.cpp @@ -0,0 +1,14 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/configurationServer/gui/gui/mainwindow.h b/configurationServer/gui/gui/mainwindow.h new file mode 100644 index 0000000..a3948a9 --- /dev/null +++ b/configurationServer/gui/gui/mainwindow.h @@ -0,0 +1,22 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/configurationServer/gui/gui/mainwindow.ui b/configurationServer/gui/gui/mainwindow.ui new file mode 100644 index 0000000..6050363 --- /dev/null +++ b/configurationServer/gui/gui/mainwindow.ui @@ -0,0 +1,24 @@ + + MainWindow + + + + 0 + 0 + 400 + 300 + + + + MainWindow + + + + + + + + + + + From fa5528a3db03823701c025133e9441f966af3112 Mon Sep 17 00:00:00 2001 From: IlyaNikiforov Date: Thu, 3 Jul 2014 12:03:31 +0400 Subject: [PATCH 02/14] added first version of server --- configurationServer/server/main.cpp | 11 + configurationServer/server/server.cpp | 180 +++++++++++++++ configurationServer/server/server.h | 50 +++++ configurationServer/server/server.pro | 23 ++ configurationServer/server/server.pro.user | 248 +++++++++++++++++++++ 5 files changed, 512 insertions(+) create mode 100644 configurationServer/server/main.cpp create mode 100644 configurationServer/server/server.cpp create mode 100644 configurationServer/server/server.h create mode 100644 configurationServer/server/server.pro create mode 100644 configurationServer/server/server.pro.user diff --git a/configurationServer/server/main.cpp b/configurationServer/server/main.cpp new file mode 100644 index 0000000..f728958 --- /dev/null +++ b/configurationServer/server/main.cpp @@ -0,0 +1,11 @@ +#include "server.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Server w; + w.show(); + + return a.exec(); +} diff --git a/configurationServer/server/server.cpp b/configurationServer/server/server.cpp new file mode 100644 index 0000000..2172801 --- /dev/null +++ b/configurationServer/server/server.cpp @@ -0,0 +1,180 @@ +#include +#include +#include "server.h" + +Server::Server(QWidget *parent) : + QDialog(parent), + tcpServer(0), + clientSocket(0), + networkSession(0), + blockSize(0) +{ + /// creating widgets: + statusLabel = new QLabel; + + allText = new QTextEdit; + allText ->setReadOnly(true); + + messageText = new QLineEdit; + + sendButton = new QPushButton(tr("Send")); + sendButton->setDisabled(true); + + quitButton = new QPushButton(tr("Quit")); + quitButton->setAutoDefault(false); + + QNetworkConfigurationManager manager; + if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) + { + // Get saved network configuration + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QtNetwork")); + const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString(); + settings.endGroup(); + + // If the saved network configuration is not currently discovered use the system default + QNetworkConfiguration config = manager.configurationFromIdentifier(id); + if ((config.state() & QNetworkConfiguration::Discovered) != QNetworkConfiguration::Discovered) + { + config = manager.defaultConfiguration(); + } + + networkSession = new QNetworkSession(config, this); + connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); + + statusLabel->setText(tr("Opening network session.")); + networkSession->open(); + } + else + { + sessionOpened(); + } + + /// connecting widgets: + connect(sendButton, SIGNAL(clicked()), this, SLOT(sendSettings())); + connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); + connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptClientConnection())); + + /// adding widgets into the window: + QHBoxLayout *messageLayout = new QHBoxLayout; + messageLayout->addWidget(messageText); + messageLayout->addWidget(sendButton); + + QHBoxLayout *quitLayout = new QHBoxLayout; + quitLayout->addStretch(1); + quitLayout->addWidget(quitButton); + quitLayout->addStretch(1); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(statusLabel); + mainLayout->addWidget(allText); + mainLayout->addLayout(messageLayout); + mainLayout->addLayout(quitLayout); + setLayout(mainLayout); + + setWindowTitle(tr("Chat Server")); +} + +void Server::sessionOpened() + { + // Save the used configuration + if (networkSession) + { + QNetworkConfiguration config = networkSession->configuration(); + QString id; + if (config.type() == QNetworkConfiguration::UserChoice) + id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); + else + id = config.identifier(); + + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QtNetwork")); + settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); + settings.endGroup(); + } + + tcpServer = new QTcpServer(this); + if (!tcpServer->listen(QHostAddress::LocalHost, tcpServer->serverPort())) + { + QMessageBox::critical(this, tr("Chat Server"), + tr("Unable to start the server: %1.") + .arg(tcpServer->errorString())); + close(); + return; + } + + statusLabel->setText(tr("The server is running on\n\nIP-adress: %1\nPort: %2\n\n" + "Run the Chat Client now.") + .arg(tcpServer->serverAddress().toString()).arg(tcpServer->serverPort())); + } + +void Server::acceptClientConnection() +{ + clientSocket = tcpServer->nextPendingConnection(); + + connect(clientSocket, SIGNAL(readyRead()), this, SLOT(receiveMessage())); + connect(clientSocket, SIGNAL(disconnected()), this, SLOT(disconnectedFromClient())); + connect(clientSocket, SIGNAL(disconnected()), clientSocket, SLOT(deleteLater())); + + allText->clear(); + allText->textCursor().insertText("Client connected!\n"); + + sendButton->setEnabled(true); +} + +//void Server::receiveMessage() +//{ +// QDataStream in(clientSocket); +// in.setVersion(QDataStream::Qt_5_2); + +// if (blockSize == 0) +// { +// if (clientSocket->bytesAvailable() < (int)sizeof(quint16)) +// return; + +// in >> blockSize; +// } + +// if (clientSocket->bytesAvailable() < blockSize) +// return; + +// blockSize = 0; +// QString newMessage; +// in >> newMessage; +// allText ->textCursor().insertText("Client: " + newMessage + '\n'); +//} + +//void Server::sendMessage() +//{ +// if(clientSocket) +// { +// if (messageText->text().isEmpty()) +// return; +// sendButton->setDisabled(true); + +// QByteArray block; +// QDataStream out(&block, QIODevice::WriteOnly); + +// out << (quint16)messageText->text().length(); +// out << messageText->text(); +// clientSocket->write(block); + +// allText ->textCursor().insertText("You: " + messageText->text() + '\n'); + +// messageText->clear(); + +// sendButton->setEnabled(true); +// } +//} + +void Server::sendSettings() +{ + +} + +void Server::clientDisconnected() +{ + sendButton->setDisabled(true); + QMessageBox::information(this, tr("Chat Server"), + tr("Client disconnected!")); +} diff --git a/configurationServer/server/server.h b/configurationServer/server/server.h new file mode 100644 index 0000000..e2df8c2 --- /dev/null +++ b/configurationServer/server/server.h @@ -0,0 +1,50 @@ +#ifndef SERVER_H +#define SERVER_H + +#include +#include +#include +#include +#include +#include + +namespace Ui { +class Server; +} + +class Server : public QDialog +{ + Q_OBJECT + +public: + explicit Server(QWidget *parent = 0); + +private slots: + void sessionOpened(); + void acceptClientConnection(); + //void sendMessage(); + void sendSettings(); + //void receiveMessage(); + void clientDisconnected(); + +private: + /// labels: + QLabel *statusLabel; + + /// text widgets: + QLineEdit *messageText; + QTextEdit *allText; + + /// buttons: + QPushButton *sendButton; + QPushButton *quitButton; + + + QTcpServer *tcpServer; + QTcpSocket *clientSocket; + QNetworkSession *networkSession; + + quint16 blockSize; +}; + +#endif // SERVER_H diff --git a/configurationServer/server/server.pro b/configurationServer/server/server.pro new file mode 100644 index 0000000..dcd6e0e --- /dev/null +++ b/configurationServer/server/server.pro @@ -0,0 +1,23 @@ +HEADERS = server.h + SOURCES = server.cpp \ + main.cpp + QT += network + QT += core gui widgets + + # install + target.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneserver + sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS fortuneserver.pro + sources.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneserver + INSTALLS += target sources + + symbian { + TARGET.UID3 = 0xA000E406 + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) + TARGET.CAPABILITY = "NetworkServices ReadUserData" + TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 + } + maemo5: include($$QT_SOURCE_TREE/examples/maemo5pkgrules.pri) + + symbian: warning(This example might not fully work on Symbian platform) + maemo5: warning(This example might not fully work on Maemo platform) + simulator: warning(This example might not fully work on Simulator platform) diff --git a/configurationServer/server/server.pro.user b/configurationServer/server/server.pro.user new file mode 100644 index 0000000..f714fcf --- /dev/null +++ b/configurationServer/server/server.pro.user @@ -0,0 +1,248 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + true + 1 + true + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.2.1 MinGW 32bit + Desktop Qt 5.2.1 MinGW 32bit + qt.521.win32_mingw48.essentials_kit + 0 + 0 + 0 + + C:/Programming/SummerSchool/tools/configurationServer/build-server-Desktop_Qt_5_2_1_MinGW_32bit-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Отладка + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + C:/Programming/SummerSchool/tools/configurationServer/build-server-Desktop_Qt_5_2_1_MinGW_32bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Выпуск + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Установка + + ProjectExplorer.BuildSteps.Deploy + + 1 + Локальная установка + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + server + + Qt4ProjectManager.Qt4RunConfiguration:C:/Programming/SummerSchool/tools/configurationServer/server/server.pro + + server.pro + false + false + + 3768 + true + false + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {b98c4ef7-5a11-4065-9906-b1f08baf52f0} + + + ProjectExplorer.Project.Updater.FileVersion + 15 + + From 4b8670d24874a7e641d8a773d047ef7ec4d456a8 Mon Sep 17 00:00:00 2001 From: IlyaNikiforov Date: Thu, 3 Jul 2014 14:36:09 +0400 Subject: [PATCH 03/14] new version of server --- configurationServer/server/server.cpp | 34 -------------- configurationServer/server/server.h.autosave | 49 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 configurationServer/server/server.h.autosave diff --git a/configurationServer/server/server.cpp b/configurationServer/server/server.cpp index 2172801..341f598 100644 --- a/configurationServer/server/server.cpp +++ b/configurationServer/server/server.cpp @@ -9,20 +9,6 @@ Server::Server(QWidget *parent) : networkSession(0), blockSize(0) { - /// creating widgets: - statusLabel = new QLabel; - - allText = new QTextEdit; - allText ->setReadOnly(true); - - messageText = new QLineEdit; - - sendButton = new QPushButton(tr("Send")); - sendButton->setDisabled(true); - - quitButton = new QPushButton(tr("Quit")); - quitButton->setAutoDefault(false); - QNetworkConfigurationManager manager; if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) { @@ -52,25 +38,8 @@ Server::Server(QWidget *parent) : /// connecting widgets: connect(sendButton, SIGNAL(clicked()), this, SLOT(sendSettings())); - connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptClientConnection())); - /// adding widgets into the window: - QHBoxLayout *messageLayout = new QHBoxLayout; - messageLayout->addWidget(messageText); - messageLayout->addWidget(sendButton); - - QHBoxLayout *quitLayout = new QHBoxLayout; - quitLayout->addStretch(1); - quitLayout->addWidget(quitButton); - quitLayout->addStretch(1); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(statusLabel); - mainLayout->addWidget(allText); - mainLayout->addLayout(messageLayout); - mainLayout->addLayout(quitLayout); - setLayout(mainLayout); setWindowTitle(tr("Chat Server")); } @@ -116,9 +85,6 @@ void Server::acceptClientConnection() connect(clientSocket, SIGNAL(disconnected()), this, SLOT(disconnectedFromClient())); connect(clientSocket, SIGNAL(disconnected()), clientSocket, SLOT(deleteLater())); - allText->clear(); - allText->textCursor().insertText("Client connected!\n"); - sendButton->setEnabled(true); } diff --git a/configurationServer/server/server.h.autosave b/configurationServer/server/server.h.autosave new file mode 100644 index 0000000..f6a5819 --- /dev/null +++ b/configurationServer/server/server.h.autosave @@ -0,0 +1,49 @@ +#ifndef SERVER_H +#define SERVER_H + +#include +#include +#include +#include +#include +#include + +namespace Ui { +class Server; +} + +class Server : public QDialog +{ + Q_OBJECT + +public: + explicit Server(QWidget *parent = 0); + +private slots: + void sessionOpened(); + void acceptClientConnection(); + void sendMessage(); + void receiveMessage(); + void clientDisconnected(); + +private: + /// labels: + QLabel *statusLabel; + + /// text widgets: + QLineEdit *messageText; + QTextEdit *allText; + + /// buttons: + QPushButton *sendButton; + QPushButton *quitButton; + + + QTcpServer *tcpServer; + QNetworkSession *networkSession; + QMap SClients; + + quint16 blockSize; +}; + +#endif // SERVER_H From 989e3b025e651ab51a48462f93484dffec862281 Mon Sep 17 00:00:00 2001 From: dyma96 Date: Thu, 3 Jul 2014 15:59:21 +0400 Subject: [PATCH 04/14] Window at the initial stage --- configurationServer/gui/.ini | 67 ++ .../gui/brandManager/brandManager.cpp | 51 ++ .../gui/brandManager/brandManager.h | 44 ++ .../gui/brandManager/brandManager.pri | 11 + configurationServer/gui/brandManager/fonts.h | 65 ++ .../gui/brandManager/fonts/Pfennig.ttf | Bin 0 -> 308868 bytes .../gui/brandManager/fonts/fonts.qrc | 5 + configurationServer/gui/brandManager/styles.h | 143 ++++ .../styles/startTab/background.js | 1 + .../brandManager/styles/startTab/button.js | 20 + .../brandManager/styles/startTab/header.js | 1 + .../styles/startTab/labelLevel1.js | 3 + .../styles/startTab/labelLevel2.js | 3 + .../startTab/projectsManagementBackground.js | 1 + .../startTab/recentProjectsBackground.js | 1 + .../brandManager/styles/startTab/substrate.js | 1 + .../gui/brandManager/styles/styles.qrc | 12 + configurationServer/gui/gui.pro | 75 ++ configurationServer/gui/gui.pro.user | 248 +++++++ configurationServer/gui/gui/gui.pro | 20 - configurationServer/gui/gui/main.cpp | 11 - configurationServer/gui/gui/mainwindow.cpp | 14 - configurationServer/gui/gui/mainwindow.h | 22 - configurationServer/gui/gui/mainwindow.ui | 24 - .../gui/hotKeyManager/hotKeyManager.cpp | 212 ++++++ .../gui/hotKeyManager/hotKeyManager.h | 77 ++ .../gui/hotKeyManager/hotKeyManager.pri | 12 + .../gui/hotKeyManager/hotKeyManagerPage.cpp | 224 ++++++ .../gui/hotKeyManager/hotKeyManagerPage.h | 44 ++ .../gui/hotKeyManager/hotKeyManagerPage.ui | 222 ++++++ .../gui/hotKeyManager/shortcutEdit.cpp | 34 + .../gui/hotKeyManager/shortcutEdit.h | 17 + configurationServer/gui/main.cpp | 15 + configurationServer/gui/preferencesDialog.cpp | 182 +++++ configurationServer/gui/preferencesDialog.h | 61 ++ configurationServer/gui/preferencesDialog.ui | 160 ++++ .../gui/preferencesPages/behaviourPage.cpp | 102 +++ .../gui/preferencesPages/behaviourPage.h | 37 + .../gui/preferencesPages/behaviourPage.ui | 198 +++++ .../gui/preferencesPages/debuggerPage.cpp | 48 ++ .../gui/preferencesPages/debuggerPage.h | 25 + .../gui/preferencesPages/debuggerPage.ui | 76 ++ .../gui/preferencesPages/editorPage.cpp | 205 ++++++ .../gui/preferencesPages/editorPage.h | 61 ++ .../gui/preferencesPages/editorPage.ui | 687 ++++++++++++++++++ .../gui/preferencesPages/featuresPage.cpp | 46 ++ .../gui/preferencesPages/featuresPage.h | 25 + .../gui/preferencesPages/featuresPage.ui | 98 +++ .../preferencesPages/miscellaniousPage.cpp | 81 +++ .../gui/preferencesPages/miscellaniousPage.h | 34 + .../gui/preferencesPages/miscellaniousPage.ui | 267 +++++++ .../gui/preferencesPages/preferencesPage.h | 50 ++ configurationServer/gui/qrkernel/Makefile | 311 ++++++++ .../gui/qrkernel/definitions.h | 14 + .../gui/qrkernel/exception/exception.cpp | 16 + .../gui/qrkernel/exception/exception.h | 26 + configurationServer/gui/qrkernel/ids.cpp | 195 +++++ configurationServer/gui/qrkernel/ids.h | 150 ++++ .../gui/qrkernel/kernelDeclSpec.h | 11 + configurationServer/gui/qrkernel/qrkernel.pri | 26 + configurationServer/gui/qrkernel/qrkernel.pro | 11 + configurationServer/gui/qrkernel/qrkernel.qrc | 5 + configurationServer/gui/qrkernel/roles.h | 26 + .../gui/qrkernel/settingsDefaultValues | 65 ++ .../gui/qrkernel/settingsManager.cpp | 125 ++++ .../gui/qrkernel/settingsManager.h | 88 +++ .../gui/qrkernel/timeMeasurer.cpp | 22 + .../gui/qrkernel/timeMeasurer.h | 33 + configurationServer/gui/qrkernel/version.cpp | 158 ++++ configurationServer/gui/qrkernel/version.h | 150 ++++ .../gui/qrutils/qRealDialog.cpp | 58 ++ configurationServer/gui/qrutils/qRealDialog.h | 40 + .../gui/qrutils/qRealFileDialog.cpp | 88 +++ .../gui/qrutils/qRealFileDialog.h | 59 ++ .../gui/qrutils/utilsDeclSpec.h | 11 + configurationServer/gui/ui_behaviourPage.h | 219 ++++++ configurationServer/gui/ui_debuggerPage.h | 113 +++ configurationServer/gui/ui_editorPage.h | 529 ++++++++++++++ configurationServer/gui/ui_featuresPage.h | 128 ++++ .../gui/ui_hotKeyManagerPage.h | 184 +++++ .../gui/ui_miscellaniousPage.h | 255 +++++++ .../gui/ui_preferencesDialog.h | 153 ++++ configurationServer/gui/ui_widget.h | 90 +++ configurationServer/gui/widget.cpp | 26 + configurationServer/gui/widget.h | 21 + configurationServer/gui/widget.ui | 95 +++ 86 files changed, 7553 insertions(+), 91 deletions(-) create mode 100644 configurationServer/gui/.ini create mode 100644 configurationServer/gui/brandManager/brandManager.cpp create mode 100644 configurationServer/gui/brandManager/brandManager.h create mode 100644 configurationServer/gui/brandManager/brandManager.pri create mode 100644 configurationServer/gui/brandManager/fonts.h create mode 100644 configurationServer/gui/brandManager/fonts/Pfennig.ttf create mode 100644 configurationServer/gui/brandManager/fonts/fonts.qrc create mode 100644 configurationServer/gui/brandManager/styles.h create mode 100644 configurationServer/gui/brandManager/styles/startTab/background.js create mode 100644 configurationServer/gui/brandManager/styles/startTab/button.js create mode 100644 configurationServer/gui/brandManager/styles/startTab/header.js create mode 100644 configurationServer/gui/brandManager/styles/startTab/labelLevel1.js create mode 100644 configurationServer/gui/brandManager/styles/startTab/labelLevel2.js create mode 100644 configurationServer/gui/brandManager/styles/startTab/projectsManagementBackground.js create mode 100644 configurationServer/gui/brandManager/styles/startTab/recentProjectsBackground.js create mode 100644 configurationServer/gui/brandManager/styles/startTab/substrate.js create mode 100644 configurationServer/gui/brandManager/styles/styles.qrc create mode 100644 configurationServer/gui/gui.pro create mode 100644 configurationServer/gui/gui.pro.user delete mode 100644 configurationServer/gui/gui/gui.pro delete mode 100644 configurationServer/gui/gui/main.cpp delete mode 100644 configurationServer/gui/gui/mainwindow.cpp delete mode 100644 configurationServer/gui/gui/mainwindow.h delete mode 100644 configurationServer/gui/gui/mainwindow.ui create mode 100644 configurationServer/gui/hotKeyManager/hotKeyManager.cpp create mode 100644 configurationServer/gui/hotKeyManager/hotKeyManager.h create mode 100644 configurationServer/gui/hotKeyManager/hotKeyManager.pri create mode 100644 configurationServer/gui/hotKeyManager/hotKeyManagerPage.cpp create mode 100644 configurationServer/gui/hotKeyManager/hotKeyManagerPage.h create mode 100644 configurationServer/gui/hotKeyManager/hotKeyManagerPage.ui create mode 100644 configurationServer/gui/hotKeyManager/shortcutEdit.cpp create mode 100644 configurationServer/gui/hotKeyManager/shortcutEdit.h create mode 100644 configurationServer/gui/main.cpp create mode 100644 configurationServer/gui/preferencesDialog.cpp create mode 100644 configurationServer/gui/preferencesDialog.h create mode 100644 configurationServer/gui/preferencesDialog.ui create mode 100644 configurationServer/gui/preferencesPages/behaviourPage.cpp create mode 100644 configurationServer/gui/preferencesPages/behaviourPage.h create mode 100644 configurationServer/gui/preferencesPages/behaviourPage.ui create mode 100644 configurationServer/gui/preferencesPages/debuggerPage.cpp create mode 100644 configurationServer/gui/preferencesPages/debuggerPage.h create mode 100644 configurationServer/gui/preferencesPages/debuggerPage.ui create mode 100644 configurationServer/gui/preferencesPages/editorPage.cpp create mode 100644 configurationServer/gui/preferencesPages/editorPage.h create mode 100644 configurationServer/gui/preferencesPages/editorPage.ui create mode 100644 configurationServer/gui/preferencesPages/featuresPage.cpp create mode 100644 configurationServer/gui/preferencesPages/featuresPage.h create mode 100644 configurationServer/gui/preferencesPages/featuresPage.ui create mode 100644 configurationServer/gui/preferencesPages/miscellaniousPage.cpp create mode 100644 configurationServer/gui/preferencesPages/miscellaniousPage.h create mode 100644 configurationServer/gui/preferencesPages/miscellaniousPage.ui create mode 100644 configurationServer/gui/preferencesPages/preferencesPage.h create mode 100644 configurationServer/gui/qrkernel/Makefile create mode 100644 configurationServer/gui/qrkernel/definitions.h create mode 100644 configurationServer/gui/qrkernel/exception/exception.cpp create mode 100644 configurationServer/gui/qrkernel/exception/exception.h create mode 100644 configurationServer/gui/qrkernel/ids.cpp create mode 100644 configurationServer/gui/qrkernel/ids.h create mode 100644 configurationServer/gui/qrkernel/kernelDeclSpec.h create mode 100644 configurationServer/gui/qrkernel/qrkernel.pri create mode 100644 configurationServer/gui/qrkernel/qrkernel.pro create mode 100644 configurationServer/gui/qrkernel/qrkernel.qrc create mode 100644 configurationServer/gui/qrkernel/roles.h create mode 100644 configurationServer/gui/qrkernel/settingsDefaultValues create mode 100644 configurationServer/gui/qrkernel/settingsManager.cpp create mode 100644 configurationServer/gui/qrkernel/settingsManager.h create mode 100644 configurationServer/gui/qrkernel/timeMeasurer.cpp create mode 100644 configurationServer/gui/qrkernel/timeMeasurer.h create mode 100644 configurationServer/gui/qrkernel/version.cpp create mode 100644 configurationServer/gui/qrkernel/version.h create mode 100644 configurationServer/gui/qrutils/qRealDialog.cpp create mode 100644 configurationServer/gui/qrutils/qRealDialog.h create mode 100644 configurationServer/gui/qrutils/qRealFileDialog.cpp create mode 100644 configurationServer/gui/qrutils/qRealFileDialog.h create mode 100644 configurationServer/gui/qrutils/utilsDeclSpec.h create mode 100644 configurationServer/gui/ui_behaviourPage.h create mode 100644 configurationServer/gui/ui_debuggerPage.h create mode 100644 configurationServer/gui/ui_editorPage.h create mode 100644 configurationServer/gui/ui_featuresPage.h create mode 100644 configurationServer/gui/ui_hotKeyManagerPage.h create mode 100644 configurationServer/gui/ui_miscellaniousPage.h create mode 100644 configurationServer/gui/ui_preferencesDialog.h create mode 100644 configurationServer/gui/ui_widget.h create mode 100644 configurationServer/gui/widget.cpp create mode 100644 configurationServer/gui/widget.h create mode 100644 configurationServer/gui/widget.ui diff --git a/configurationServer/gui/.ini b/configurationServer/gui/.ini new file mode 100644 index 0000000..81f777f --- /dev/null +++ b/configurationServer/gui/.ini @@ -0,0 +1,67 @@ +[General] +D2ModelWindowWasMaximized=true +LineType=-1 +OpenQRSProjectFileDialogLastDir=C:/TRIKStudio/examples +robotModel=3 +ResizeLabels=true +Autosave=true +showTitlesForRobots=false +DragArea=12 +PaletteIconsInARowCount=3 +PreferencesDialogLastPosition=@Point(225 23) +LabelsDistance=100 +toolbarSize=30 +ShowAlignment=true +ShowGrid=true +2dFollowingRobot=true +2dShowGrid=true +IndexGrid=25 +LoopEdgeBoundsIndent=1 +Splashscreen=true +recentProjectsLimit=0 +EmbeddedLinkerIndent=5 +port2SensorType=0 +temp=D:/proga/SummerSchool/qreal/bin/unsaved +touchMode=false +oldLineColor=magenta +D2ModelWindowLastPosition=@Point(-8 -8) +MoveLabels=true +pos=@Point(-8 -8) +EmbeddedLinkerSize=6 +version=3.0.0 \x3b1\x37 +CurrentIndex=0 +2d_displayVisible=true +autoscalingInterval=3000 +sensorUpdateInterval=50 +textUpdateInterval=500 +collectErgonomicValues=true +gestureDelay=1000 +ActivateGrid=true +Antialiasing=true +maximized=true +ActivateAlignment=true +tcpServer=192.168.1.8 +EditorsLoadedCount=1 +nxtFlashToolRunPolicy=0 +CustomFont=false +PaletteTabSwitching=true +2DModelRealisticPhysics=true +%U0414%U0438%U0430%U0433%U0440%U0430%U043C%U043C%U0430%20%U043F%U043E%U0432%U0435%U0434%U0435%U043D%U0438%U044F%20%U0440%U043E%U0431%U043E%U0442%U0430=true +valueOfCommunication=tcp +usabilityTestingMode=false +pathToImages=./images/iconset1 +bluetoothPortName= +PreferencesDialogLastSize=@Size(892 593) +2dCursorType=1 +recentProjects="C:\\Users\\Admin\\Downloads\\WFABTree (1).qrs;C:\\Users\\Admin\\Downloads\\125_97_2-___2_2.qrs;C:/TRIKStudio/examples/smiles.qrs;C:/TRIKStudio/examples/alongTheLineByCam.qrs;C:/TRIKStudio/examples/smile_wall.qrs;C:/TRIKStudio/examples/helloworld.qrs;C:/TRIKStudio/examples/thewall.qrs;C:/TRIKStudio/examples/simpleSayExample.qrs;" +PaletteRepresentation=false +enableNoiseOfSensors=false +D2ModelWindowLastSize=@Size(1366 706) +port1SensorType=0 +PreferencesDialogWasMaximized=false +enableNoiseOfMotors=false +GridWidth=10 +size=@Size(1366 706) +SelectedModelFortrikKit=TwoDRobotModelForTrikRealRobotModelV6 +AutosaveInterval=60 +PaintOldEdgeMode=true diff --git a/configurationServer/gui/brandManager/brandManager.cpp b/configurationServer/gui/brandManager/brandManager.cpp new file mode 100644 index 0000000..167af3c --- /dev/null +++ b/configurationServer/gui/brandManager/brandManager.cpp @@ -0,0 +1,51 @@ +#include "brandManager.h" + +using namespace qReal; + +BrandManager::BrandManager() + : mFonts(new Fonts) + , mStyles(new Styles(*mFonts)) +{ +} + +BrandManager::~BrandManager() +{ + delete mFonts; + delete mStyles; +} + +BrandManager &BrandManager::instance() +{ + static BrandManager instance; + return instance; +} + +//void BrandManager::configure(ToolPluginManager const *toolPluginManager) +//{ +// instance().mCustomizer = toolPluginManager->customizer(); +//} + +Fonts const *BrandManager::fonts() +{ + return instance().mFonts; +} + +Styles const *BrandManager::styles() +{ + return instance().mStyles; +} + +//QString BrandManager::applicationName() +//{ +// return instance().mCustomizer->windowTitle(); +//} + +//const QImage BrandManager::applicationLogo() +//{ +// return instance().mCustomizer->applicationLogo(); +//} + +//const QIcon BrandManager::applicationIcon() +//{ +// return instance().mCustomizer->applicationIcon(); +//} diff --git a/configurationServer/gui/brandManager/brandManager.h b/configurationServer/gui/brandManager/brandManager.h new file mode 100644 index 0000000..d7e96ee --- /dev/null +++ b/configurationServer/gui/brandManager/brandManager.h @@ -0,0 +1,44 @@ +#pragma once + +//#include "pluginManager/toolPluginManager.h" +#include "fonts.h" +#include "styles.h" + +namespace qReal { + +/// Provides information about everything about application appearance: fonts, styles and so on +class BrandManager +{ +public: + static BrandManager &instance(); + + /// Retrieves from plugins customization information +// static void configure(ToolPluginManager const *toolPluginManager); + + // TODO: Pluginize two following methods + + /// Returns information about all fonts in system + static Fonts const *fonts(); + + /// Returns information about all json stylesheets in system + static Styles const *styles(); + + /// Returns application`s name and probably version + static QString applicationName(); + + /// Returns application`s logo image in wide format + static QImage const applicationLogo(); + + /// Returns small application`s icon + static QIcon const applicationIcon(); + +private: + BrandManager(); + ~BrandManager(); + +// Customizer *mCustomizer; // Doesn`t take ownership + Fonts const *mFonts; // Takes ownership + Styles const *mStyles; // Takes ownership +}; + +} diff --git a/configurationServer/gui/brandManager/brandManager.pri b/configurationServer/gui/brandManager/brandManager.pri new file mode 100644 index 0000000..eb9773a --- /dev/null +++ b/configurationServer/gui/brandManager/brandManager.pri @@ -0,0 +1,11 @@ +HEADERS += \ + $$PWD/brandManager.h \ + $$PWD/fonts.h \ + $$PWD/styles.h \ + +SOURCES += \ + $$PWD/brandManager.cpp \ + +RESOURCES += \ + $$PWD/fonts/fonts.qrc \ + $$PWD/styles/styles.qrc \ diff --git a/configurationServer/gui/brandManager/fonts.h b/configurationServer/gui/brandManager/fonts.h new file mode 100644 index 0000000..a119919 --- /dev/null +++ b/configurationServer/gui/brandManager/fonts.h @@ -0,0 +1,65 @@ +#pragma once + +#include + +#include + +namespace qReal { + +/// A class for managing all used in system fonts +class Fonts +{ +public: + Fonts() + { + initTitlesFont(); + } + + virtual ~Fonts() + { + } + + /// Returns font for inline labels on scene + QFont sceneLabelsFont() const + { + return mTitlesFont; + } + + /// Returns a path to a font for inline labels on scene if other was not selected by user + virtual QString defaultSceneLabelsFont() const + { + return ":/fonts/Pfennig.ttf"; + } + + /// Returns a path to a font for a text on styled command buttons + virtual QString commandButtonsFont() const + { + return ":/fonts/Pfennig.ttf"; + } + + /// Returns a path to a font for a styled text, non-regular one + virtual QString styledTextFont() const + { + return ":/fonts/Pfennig.ttf"; + } + +private: + void initTitlesFont() + { + if (SettingsManager::value("CustomFont").toBool()) { + mTitlesFont.fromString(SettingsManager::value("CurrentFont").toString()); + } else { + int const fontId = QFontDatabase::addApplicationFont(defaultSceneLabelsFont()); + if (fontId != -1) { + mTitlesFont.fromString(QFontDatabase::applicationFontFamilies(fontId).at(0) + ",11,-1,5,50,0,0,0,0,0"); + } + } + } + + QFont mTitlesFont; + +}; + +} + +// Implemented in .h file for correct linkage diff --git a/configurationServer/gui/brandManager/fonts/Pfennig.ttf b/configurationServer/gui/brandManager/fonts/Pfennig.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bbbe4636d3ae6e45b9964c2dd87cadd2a646a78b GIT binary patch literal 308868 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Ì>PVhnKZMoah4}SDSp8jyUq6J^ zkvzYCh_dPLLK)eSksTS?k&zu4*^!YQ`h`RdslVoBWJgAJWMoH1c4TBnMt0y^im1Je z?7$Zl=~s4SWCy;hNWZcpBRev(BO^O9vLhoqGO{BhJ2J8(BRev(BO^O9vLhoqGO`2n zF_bYQJ2J8(BRev(BO^O9vLhoqGO|Oz^QdLis{s0)N45I9kbdV;t^O{g-+5Gf6?3jv z0Wz{9BRev(BO^O9vLhoqGO{BhJ2J8(BRev(BO^O9vLhoqGO{BhJ2J8(BRev(BO^O9 zvLhoqGO{BhJ2J8(BRev(BO^O9vLhoqGO{BhJ2J8(BRev(BO^O9vLhoqGO{BhJ2J8( zBRev(L%({db@DmPoAle4>et_e^b45k*Q)>-*^!YQ8QGDM9U0k?ksTS?k&zu4*^!YQ z8QGDM9U0k?ksTS?k&zu4*^!YQ8QGDM9U0k?ksTS?k&zu4*^!YQ8QGDM9U0k?ksTS? zk&zu4*^!YQ8QGDM9U0k?ksTS?k&zu4*^!YQ8QGDM9U0k?ksTS?k&zu4*^!YQ8QGDM z9U0k?ksTS?k&zu4*^!YQ8QGDM9U0k?ksTS?k&zu4*^!YQ8QGDM9U0k?ksTS?k&zu4 z*^!YQ8QFnvnCdx8cHm2<^y^3--!r9ONAeljk&zu4*^!YQ8QGDM9U0k?ksTS?k&zu4 z*^!YQ_&O@%RCeI&sI)qg&&ZC9?8wNDjO@tBj*RTc$c~Kc$jFY2?8wNDjO@U-RvD*` zuSfpLj*RTc$c~Kc z$jFY2?8wND{ba{}vO~Z0dU>E|WXFDJlZP$&Q@t z$jOeJ?8wQEob1TS4*e>wmQmTEU&U3c?9i{`s#SLAS8>%UJ95rDaGz>Q{E?_kz{0?8wQEob1TSj-2es$&Q@t$jOeJ?8wQEob1TSj-2es$&Q@t$jOeJ z?8wQEob1TSj-2es$&Q@t$jOeJ?8wQEob1TSj-2es$&Q@t$jOeJ?8wQEob1TSj-2e! zuOVw0^$K!McI0G7PIlyEM^1L+WJgYR9QyN_VO4%k-u!4CM*2Vl_$V8ISpumcu%AHm{! zG%T)1!{Y8E*j2QvxgB>OVGHg)g2mlOuxn{?JsN&okA}tFN3iG8f*tVV3IZ(dK7z&F zN3gj22o_g`U~xSf7Iz=P;_f3@umcwCfCW2X!46ok0~YLn1v_BD4p_`PV6Udd^=SBC zM~l0U;NM4!yN}?1BQ5Seg8v<~xE>AvJ85w}8h)??7VLn<-AAyv9u14@(XhB44U6m1 zu(%!#i|f&_xE>9Q>(Q{d`v?|yAHm}8BUs#h1dF?mU~%6CY)tzx?)^CZxcdm(F~)%X z1nnnjZ=wA(E$%+TUfg{Ii@T3tarY4{?mmJAJ7B>MSg->Y?0^M3V8IU9FEJk6eFQ)5 zK7z&FN3eIX)Zd^VR}ioTcOSvx?jzW5(T}^2;QtQ&xE>8Zu1CY-dNeHVK7zfMeq4`+ zAJ?N{e?*JBkKo7MN3gj22=?d9Gwwcu{}=TCl73u|#+C#0<9amwzo8%3qv6N(Xjoj2 zhQ;-0*gwz@cEAsIz~Xu|EUrhx;_f5Zzi|t$N5lVj`f)uPeq4_(9H;Dn#ob4+xcdke zcOSvx?ju;-eFTfUk6>{<8Wz{1Vdv40>(TJzdNk}2w7B~S{wLDn?j!hdJsK9*qhWD9 z8Wv|ZEUrhx;(9bJ?mmLW^=MdJkA}tFN3gj22o`rA!7iX5?0_HFqhY}gSg->Y?0^M3 zV4unGxE>8Zbwk+!KXpUd0Y7y^*#Unu!?)0n>(SVPyN_VO4p^`Qmb#(8S;3FHk6@`A z$`1IS%k8-P2!7ms1iOVbfa}rl_i#I|N5hZn(Xc!VlpXM6-T{ldj|#^rJ79755$whE z<9amwSJIEWkKpH-tL%Uu*P~%^_Yo|vN5kR@0xa%6g2iuEu$Xtif*pn9(B^8XJjxFE zarY4{?mmLW-A4s}JqH%QS;1o70gHJDEZ6~yc?T@m0gK z?O!82)7|wVX10i3C=y&EQs@wwahJ%Xgu6`S@NFVb5I9{T%oFYwnUCYMHZY4w-*lOS@3|!$@4^>j`&VN{LetRh5JNKMcU8A_R|oqVLlwT zEy8h&ZWURK?WbdZ<7_x=Z@OKi8OOFXz}+iS9v4|MDYEofxEn;4mErCbY3+i0L}d9I zxcfxT=l zE%H(v|59v!IksJjbY6k*ue?Fza)BF%Lp)b>!QC$M>JB)>v-diYD-q9?cZs~F42Ny6 zy$lLdd zyaVgk-7oUaZE$ysybIyqeI^`^y?!g)?IQ0v3l7J;w-pXy--kThfG{^8&i5DKCPhAQ z0^DUHHzE%ooDX-M$cF?D@qQTTfA}Vmn~sLN2o7;X8{qB|`3U0q2=;w+Tx9ZOkr>Cu zmx_FBjmXE36}fp*B)L`O6G;0LH;8<)0q%N{Td?mIg!>GRyLCh)6*!ddvp0%lSBvbw zL?lNUa~ylyLb&ThJ~vO~_N^kH$M!Fj;Sk>!;lBg>@3>jyOW60N2SmPnqsUjV|IPy< zU)?71wcAC$ewN5xH;H@$VZMp9zBwpz_q8J5LjJz9Pvo8w9MVxETMOC4}`i#hR3xZA~?^q`mp+r*r_5Dwu_ zxkt=1CdDl574yuka0kSkHYlb6+ZQ3O(`UooET*vxhj^Rz!XZpE!ZxF9Emb%y%dK$x z#Vo;c$sJ;rULyv&XfUu;(J| zxi^W~hE8%a5stBeF7ZP-mQMbf6*E^Ecaml9>lW;`}SN0cej|AAnZ#n zg1cSJ#n^W-@_F&SVlFAbA+MKo!6E*ao(XpY+yOB!L%5ecAm-)B!^@HW%WsCm_Dhe3 zy9DlbF|U{hhqzvGznE8Ug}WN=PBE`q1GityWys5A*mfDhUiP4v%TdnD5&rU9#9RUY z6$p35rEqtNdG$QF2Dt0Q?8Uyl*tZvXx^e{WZZTJ3{i++qyasW;26?#}%d4?|^&?_l z+Y9%wnAdH9L)@>&{(S{F^)6 z-i+m2s&MA5cB@C;BFT4fs4f4*b4Wcm=7Xf&}{ReeQ=M6`SA5(ZbG@D z1~{bi5rq55elZ{228aEVI6l5X%*STK-7n_jtKhB`b2H+&d8?RD;FwR|CFYiKIK=;{ zD%?Y2K8<5OGanBATQ7k_xD>&zIn^ z?ehhh9RK5+#QdZ~%>5_BJt*d<*NXXBmzbZ=6Y~J_@r%2~{BjlCU1EN9 zrdjQA%8u9!Z>%YOi-`p(bL2UcoePVvUPs|_Y!(A=rp%NV8{1evyjPMU{74sK_ z|Ld`0{x%4QeUI!D^Y^ph4v6{3ez9`2ShG#6y+>?eMC^>4#bRu2XI&z8_Dy2v>=j$= z6+8D#xJSg!yH4z3{bCQtF^4}W7FurSUnKSj9DkIEJ^BQ=Ys5bBEVu(=kGVzclL~N% z<5=uJ7W29$n6SLcEJ6#V)>7?CEETZEO_VR1(|V3Ws=G5J$NI?oP2wk^f~U zi*3C_?DBnL&nSz1);zeI#GZ*TXI?Az**Nam*#8`)`CO#+-226zb&1$EY;U_+?23hO zShgdb_S?l`%xgPvdzySf+dez9k7gTwkcSgx55 zhq%^`i(S_tc0Ka40mq+_)`9X@l4TnKlg*r7(T!#9W>!TO64-zf4ucA41mg4l_>#O~^cdsysl#CuT*4(aVd z8D7#Q_Tu?)IOdY0;jnxumM_KfWozJW7yI%JaQnqxx)tsYv9D-^!~R!1Bo_K_Uv&xG zgJLg7JeOZ8_6o%NYNY?_`^4_8ioLP~cdgi~w!z&c_BEG^y?US6*JAr?Zx;JHSx z0G2mSiv7?%Vn2M1*ywt(A1RCdDDppfo!F1968rI^#omnkeL}?E(l7Q?BVuob|JEDC zeird(2%p_5c0Z2E?-P3){GZzfhy2`rk=V~8{m<_c`vv&Fi0yYAEA~sX;gI&1t75-` z{a<-d?49sqd~CmpG`@Pb*sme|ukRIm*L=9k#C~HQ+@)gw8*xBq?KkfgdpF|zmcU{8 z?GoIzV!v}1+%017xl`o`jz)fO*jr{x;;eLCy*arm;+kb~+e|Njs-`_0u4`;$5zYnc} z!?uSW7W>BrIHd7Mtp5q|{%IWUMzMd!@z7ZN=Y4QU_hB6KFv|Gw0kMC1Q0!kza2v$_ z4dEWaagW?7_V3vC_xr^D17-flO=ACfy#!_r+=CL>yCn$jkf2b4>xa8lf*JGRu$(zA z!K|%t*TEs&>=WQ7;ne@I1arFJ_QGM?oO>iF3fw}tZE)AZ-6_FbY@c_R1cx7xV19!H zN8SW?8^-ohc)qNZ+4$XiE@*HPevj`Lk*j9^T?+UUIZ}S0q4@9lu+DE}mOS74t<02O z?+;{wyvX|t2=iL+pMmQF*LeR-Z2y$^A9h5e?Dzh|<+vkI6JiQ;kj|%%EPB6@!;ie( z`>o77^1r=5kj^82;Qa+T{HT+?e}u3zib~K*)uw@ zqkp{A+}OB$QFCKcb1B?Y>gXOC=o>7ZJ={MuHaxVrw6SlnuY0Vow=^--+c#Po@9!&( z_l@oxD-Cbw%BIz8O6y1ZhDx2oL*u1213i61V||M^Z0{Qy8rZS6uXkW#r|#(-9^KJb zYF^w}I-}%w!q?QesLYi8rt|tn#|DOnkfWyN#&T0*=~<=m@$KCcK6t z`mj^^U)Xah%g}I0=1U9D92i_2c8`q>FAgWRZy!Eu$IfnS=^5VnoKqW$y9dVmQM|Ff z(OoDWv%ju;XJ0LQi;Kms{(&*KW7F{V@!j2{eI;xdbY+}gBac}L4W(Lfnie-Lc9HpG zHJYB`kpZL|_6-j2ZYXsR_3Fm%!Li{|_b%kJI~?pQF^k=$&bD()-Q#Bz`^U#e&N%(_ zv7XU^k@2y`V<-!%_4M_fYl_9Cq zVD~sGXLxk5clSVVU$M7u7iw{2XCL|qx@FJsAgXV8w0nGDS6^wn_REpc;TQGwjE^-i ziiwet;n8t+U+(Q0?L*k%p<*98$>=z<(%sYD+qZL|hb=QWFtlT007>^C@|`;;h6ct5 z`Vg768uEnLcOf68?$Y+rJ}icMi^F z=%Racnayopio_QP=(5<4kJQpSHyz)G$sPpIt4tX7|vXFw?&7 zwaupXk2Mtghj*j@j54=cW@LEuVA0dUu?DTH&A@;fc{6WM30(Kt~urfAadJ zy%81Rip=v5MLFrwf;_zpT1&3U$42^ke5ZDam%6tDOj^n!q}8KsY#d6VRf@7`?CU|i zfuZifnzl`kTkA)q13IA$LMtCsm3ron3=bhL^tZ9%^poh&`YYAzPt#mmJNrBirl)zx zX|ofWqy4wLmnYTua06O;ux}i_prNSe$3zGb8lTV&rA3QsVo|~_D$FpLfz9l%4$spv z?SNf8v*(;LZ6gbKFW`Mn+ecX+op8EUH+lo}oyJEK@^ zI<>T}55pZlfIBGbkfG69j~PJA58yb^Yyv0AROe~H30N1A$3c}wkUc&x*tZnO9vFSy0IxO(gkeY<(~%QH1Pl*!yBh{W zjxn;MDvhg*P1pD_1SHF9!q!{z^{LV~4kcUE4S?#{_@eQe+VxND>>gT#u|+QjbN%qB z6c3MTWvbdh{6~jJMhA2>vlE%bnK2c7XWuvu9LJaf{+eyr4Y z(Fkg9V7#QK^EgIAIG3iKfd0%=g>j-g3Z6q-RrHGO^#*Y&>Y;)VIQzXc59yEvbh+O)8G4%N>? z9m(Mg_M-sZLFub?jQyQsaC_+#RbowXbPgy|%Kk*tM$S=3|@IcXplMwy{!Ly{WWe zPkmLY4y7HHJdwDuUlDKf#cS#*BRg1)m@0RYdsJ3QLV1vxXvQ-(!L5Y zx2;&cW_8z=hEnJ1u5}t`Cn9YtZD`xrwYq)tnzoIl4VyP^SdWQg+qw=!yKeQm&W%W= zvbM6WtB72+uivm`H4t0j;T( zm35VkZEG4zn>JM1SE~nAw|Zlx9T`MOR5uEbt%wO@icOVsH)8|B6@3zDgH;t~9eHlU z|90&f+71Yg5^6kM>o<1QvvU6GO_hdH+s4(KP(8)YjqBGUax?{w&_>^kDnwf7VlKbh zEV@niae`j&5D2A57hT15RNB@cLiCGuj}E)|@qav!b{Uot*(0MeAUp62*tnFW8TTSJ z;#q}7^fkejBt)2!bV#=hA!MHnV(n}k+mH1zEQfGcYe_b8Pai^!!Pko|6WG%W|0w+9 z2;Ik}uJ1&c5{}$HZOyf8E99fc1#;v(pgLHeiRpVYP8*rqC(fsU?wea`C zH-UI-$LMkt`!vmF9MOp78E^+5>9#dt?;Ju_fG- zt0f#quDX$nafItf=ppz@vQTy*%woZvyoaRzSoOaUWEE9WjkWtjUz{SN#KZ49~8UZrj4dh6-v{hjFTTCYX)$NwLHMVYGq4Y;d( z9m}*H%P#oV;4E$D)=jXFSNkR8T>J1+9@~eS8byE9zMx9t`u4K_k0mUkCvQal+n^mQ zP^JpfbAqo{g>r^&GDCebs{!T6!F9y%Y7IeP`VF9BubO^fc{5 zs+C1rJqNWfj_|y5I^xt)`|KcN2;m!LOanY;OFY|M*b(d*#x;pP^fv8h+M{c^m_V!} zJXY1Irpu}n?pW=gs^Xek-B!e!Q<71}RjZY5#NEx@?nKBQme-v#dbSOr9w)GLrPjSp zd9?hh+8TSG&sptUb2)T*--Z2JA6koAGR>1)(=>|6S&b69&*{@{mg+);*Yr!MQ&r&} z*r~eF^Ip|Z`=Ork+AjTA*ZB2(ujNHss+JSC$Hh6qu;Yl|F+o!pL4Kw*VA$8G5@Sjs zH6_-u)TtyZR@ zFQaP{)gWbr_CuGJtKmV`j555$JZd{?3{yGPnydBfA*7|fNVQRWac!*N%A}OneyqJ& z>!Re(vEsCnX^ypKdl1f*qn6?jbK=Gi+QVIs)VQ=|weMeuSoL`AhuYq*cC=L5M^u|# z9rdA3bYCz2YTN#GZMa@=I#Zcmx~W#y5Ly#j@`FiN>ou^_os-)+Fjw2s^PH1l2_(uD{p<~X+8h4b? z4~B7+)^)99-N@evO0@^I;B=@~4h`Fbc&G9*rI7C2(e`nQH+42o&!@||J14YUn!c*X z!M(bs79F5bCn&oPt_x1dy9v2E>0gYmPC}eo4>~GV-O+rgUevTj`o1X2O)+fUDDSD#L8#t^4! zcdd80mUP-(WPR5(!>RZ%!jIwzU7ISQ>VqnRmRQflgU4U)jMVLiw(=DJoQ9vo`OWlm zcKUd?HbQ>9cBu8G>1X*E&xju6Y`Riwo776Kxl?V?daku)5hXmdMf8Yqgw>F>Uh3MV zmiP6DL1#+ZOO-x{j@uqD-?d&)8+EwxL~S1AdQ&IzaRM*pjob1hOjn0*J&4j!+Zwf1?e^V0QB-BZ(F9rb7`j#PT4X)n_d+N*VB zqkB|O-I=fL8M2LZ+@s8`9joK}+GwRVve2_s+gro9F^ryVnz{>J%d4yX=`ExqmV;}0 zdYB@V{`~=9FNE zz#Y{`Ekmsz*IKrX^`?9pg%Uot+SO`CTS66i2jg}e)7V{UbR6lnIa2SynzC0@bldej z(i+fls*WuN(UQBdPg~EOi>~z338$k`RbI_|t<~I^S9`r4JAJfuusT0}J-O2BENmlY zDyzW(otr5UN^%NZJN+GpkYWS#qNDOL)`QEF(@&k_sOGztb7j{Y*2YCsBW>4rTu*Sn zq-g)BwVNCL99-&Q#Hu=^{lN8wBGz0jC_`%e`S<-}DkV4e(e>I$caI;JI2F`AuI2Q% z9$lLn?YVt5MbP6Of7GX8wf{Iq=$Smom}^JZekG`dQQkdzr0ulX&1@d8v^u}mx}ExU zMALQ}QJb;V>bX`^diK@k47IaN)6)F9xs>|H_rfNA&$W1sAJeIIXg=I% zNVTVSCb>SKv8Zlq%9@^=o9TRB>*%pGUTa!I>zwCM&2i_>zf)>AvUjwvjqLU8nm)^L z`O>!9?q^zf8utGw&BtrA(xckUQ9=9kW6wGszo%&rbG_()Gr!Qj@~>tXI;zrhcIvEi zBL+Rk-I=K^S?gE&8`dyK`%~dvd%0hO-RRi;W>?F#JKCwqoIb97MI%3mW zIJke-Mtz!3?PrUy)LF9fLDTG$i(n5O+x3GB+DnEIUUf~`JoU?*_I>vog&P%X->db^ zsXEY+zfwo-0K#ipu6?y8wIBCAX6&jvnp;g#mo9JGAA5Pe)MktBOqeQx%SFhTb=<4H zXllf&^{j2=%6{I^NZI^;}iHx{>w4V=JevqyF5%8z>Nd z9qOS3)*PyP2aluvH|L2FALb#+-Ixz_UZ`CqN2YjaGzDZuAd zds8jGT5V4sHR>4S(esVzrJg!!YL-%x>EpGj5Yw;s)J8pz=AqJ1$DfYDwHdn8SyvKO z4_88W<|>J`?NuGM2k2~0&v-4J`n0BcsdM@prfQe&QPt4-{=e((F4l|C+xk$~+5)vv zP!Hy;n!nx1tDa%*deij2q%ER-(~bUIA9$?#`1if5c9c`csq^TuYg)@()1O*c_uIq2 zJA1T0J^Ji%BT>Ac2Jvbi*ZQlq;G^lNHKuK%=g!pZ*0scAjhr;RQ^|if3(}E={)Vih z!5Vut6s9dSnNYhvwh6vYY(F32^a@jn$LW>Rjo5P@*7Wzi z4s1UOAvXE_CsDc1$6k$by==y^ZKiJaCvS++Aybup6;guP|=LQM#sEH)FX0 z;oKERjahT0xz*oD*CCFLT&_f{nggvZ{k22uN@vI$khX?ciF|c27n+imPD5&~bYXuR zV%6g{)pNMjhqghH`98D{)cTahrLCj&v4*v< z3H4V&{xv4IMa!+dNBeiXuR-0WVYD<_tF^GM4&Cn*+J5JvHC+f7U-6JqXt~a3olVuc zt7pxj_7hF9_8Z7l8*7@H=URTW&uU+)oe5L5qGy@rL{rkX)-_FGC0a>)(t6aX?yH@J zE)AEP5_0c)p(~djcX0jI&X!uZ+HwC%AzWOww6*6>m0jyo>(b>=TiMmdzmIn@DDZ!O z=Ye$(z5UZbNgv}Mo}1IB;VhmgE65By12+p#(ak~4&6Rm_m>iDR3(c1!@ci6Sc*gpP za*RAlj+H0NadNzzAWxB}%F|GS6QO+zH3tlVkMmhs`*qn*C-91O1i~Cu$#@pG`I(bg7#@$HgppMp}HS{by7p=Gn zb+{Slu2k=g{Pn+3hjwzbCW}Z0=Z$8fGXihQ<%*p2I z<`nY`v(TJso@q`q4Q7#9Y)&_gcrnU%Op|FgEv9Uin5AZ!X*J8u8Rl8$O!I8>9K18^ z$MO?%mT5C9OuOkY71L=}npI}CIoq6L)|j)|(CHT(i+^GF@h~InSJLs(7Q@ zBXYm|)NC;qnCF?T=K1CY=7naP={BM1F}bOp&4+kD5|W4>$t$9&J+ zYrb!OV18)sGe0svHa{`^K0`P^IP+v`JMT_`Ga}L{L%c$ z{MkHg{$l=W{$?IAe>eXy|FmL_wKlK?JHyVjv+Qg;#}@5eJI@|w54TUS^X(D#NPCn$ z+CI@9W1nP?wNJLk+2idA_9^zM_Gz|cPqZi51@>h7bbE?@hFxe+wa>Jt$vyHT+h7;T z_vBvrzT79@l^@#0_H^55n{2afv1Pl&F15>St6gr-u+Oq*+GpG6*yq}_Y@1zS+ii!f z*iO6BuClA`+4dZ}#;&#N?0UPwo@+PSO}5K!w&&UNZPjkE7ue_7t@io$1@?t@o7`x- zZD@OJukEwj?GD>-2keXNg?7;Hv_p2-j@TF5Q9CB@w&Qlf?y|e>MRt#UiM`lfVqa=s zW?ybEwXd+Rw6C(4*~{gv_6qxIyI0;}ue4X$*VwD=Ywhdo>+L@K2Kz?)CVP#2vwe$w ztG(8~&A#2f!(M0KY2RhvZLhcQvG29-vp3lPvhTMaus7Nd+7HCv9v$ zWA>){>?sO|8DJlm>bLs4hs$so)F9rjtGtnjtY(ro){bxJSjLfcye%DaC~q=@RZ=G z!PA0LaAI&$upl@&czSS3@Qh$#aBA?(;IyD2SQIP{P7fM`rl2`!3Ch8eU}>-{XbqMJ zX9Uj*&J3O%JSTW=a8}S3tO(kJj-V2B1}lSA!Rp}b;GAGhur^p1tPeH>=LQ>tO+i<% zIXEvkKd1&xLLn}6nrwcCHPeE>EJWLt@!c= zzE^?wj^}uD?B{~pgU<(F2)-EH5qv55a`2Vl&fu%T*MhGHcLm=F{yX?)aCh*n;M>7> zf_sAR2LBU$FSs}Oe(;0fhrxZpkAfcuKMC#+ej5BN_<8U^@QdJ=!LNb?!LNhg1iuX) z41O24j4Y&nPS`oLYEh;j}_SVNqdm;q*ddp{dYZXepEnOA1R1%L=W9<%Kf}&nlc* zcy{4Ah36K|Dzp_=6xs_Ng-W5bu(Gg9J|-V8tS+1_pO8<=?Q*l=t7-B|!P|S~!}10B ztYn3A3Tp~$wrV3!4gEh0TTY3g;K9g)M~(3ePKSEj+*Qg2D?6 z+X~%80;Ys_vaA9GvuyYok-)(GcYxK(ww_MTemo0v|#4nf6 zYQw`hc*bp3w_DC^3rF$9=*(^|X0;9Pz>_~0&gyo{x$Qjzqj;!s`(WQib9<)z#rEFe z@$McxA3t8~se5O3^mHTYnZ0h&fpogZXH|THc!og}o>_4T;_+*wTddTNF80;EvnoCt zeQr6k;$rOMV(!YRjLh9JPh;s;Oh=_D}f>tHSQl zLO;yR)#G@^vu`GzJ;P$wYF`pOoWqi=b|o2bRkzybdB830>a*>@i{_p^74O^^P5I}Y zGc6bob!V=9zv# z#}B#V*G)TQ-q5s_nd{u~L#~2{x<`ibgwpUxe_v1;+7aME$64!r;fHK2>aQDa=p-85BobH}Fq z^SY)*FmHU?%FHeo%{Ui@E^X3rZPLxIN%7dJHtA+xDm>lBCf)2xHNnM<&7*jTYsQ4y z!!}PZ(_s_S*Jf?@O+Vq5bI+g3;oRNR{9C5^_e}X`Uf|055-y4t)cbDnC3Wu%eWZPi zXK_=jJKLLDoBaAxzg*^*t$w-OFWdaG;+LInx!lLI+{d%rsYTQBvfuCHUGC#u?&DqV z<6YkF!#UMyTJGat-Z^7E9-JMTF|5{wX>*Fy)aKJ@^J%m>Wol~kaklw5+kBjDl^L5E z*Ths@D|~*v$~CR2~;f>+ogl@a@sD!qrWOFLQ@azr&~B;nT19_$y0hu5`V6 z2N&+>ijTeGW3TwwD?av$kFDZk>-44R^s#pOTzC3-I+qvQw8y*7*j@L|YO8S5tZqDm z3Q?N7er&KC&kE8%JmqJu@KO!GbamF;=<2Mw(bXB=h~oFV)SDY!oi#VQI%{rpxoK{6 zrD|?;rD|?;rD|?;b=KVI>a4lZm9n|fm9n|Xr{Cn$Z}RCk`ShE7`b|FlCZB%OvU!`P z$;iC1X)7+rO+F`0J||5+@H=dbMZSN8Fh zYw`K~E%EU#@$oJ3@h$P?UgGn!#K*V9$FtOzW2rxGsZW2YKW?ed$5MaXQlF2dKK-S> zK9>3Pm-%un^YJY6$1U^uT;}Vs)u-3$<8SrhT7CSjK7Xw~o#j4Wua3>jef(Y(n^*X9 zc(rL>v0_g5_JM&V%a+$#c!f`Sh0n3qqvm#>V!KbV(lQ5674OmqFvB@KztqRx*V5QL zhvb^J#np3*KZ9EQ8Pw9)dRYJP@P&Lvb6RMZR*OH6TKsv`;?JWNfBv-i^QOh0H!c3W zY4PVxi|_p{O&#;VD8Be-Dv@TNrDj(}Exzlw_^#jLyMBwWm=@pFTYOh<@m;;ecl8$E z)mwa5Z&~6huw|Jq%(BXi@!_H2vBU6+7(6A7SHkF8v2Ab!?^sdqoNhdoikD9ebkD1d z;Q4Vp@2s0=SMW*=?q7}JEPeCV<2^YTrn;5Q(*hUQ@9f**0v$1c;0L8OgJ~63;5qjh zEAb+T?pZ#a!UfnAAe|Xq{qPkup&94kdGBtF?RJK}-FEGST{mH?0~ld3WxHV@*w{Zj zW77cM@Dy})Pt5YU2sZQ&1nqDe#s=nTJhdD=!3U_V7rW~PpVv371hbI=S6t0MeMe8Y z{k226aR!esga|%khZbfAUfeO>JccnNj{x)YBuqevRrj0;($L06=q3477NtYKH4 zV6=aDCSIAbv%6^q7r{8njw;kFBX5TXQ|O=6a5sYq2yo*Ynw2kFU9&&*pl}&Gnd@>oK>~V{WO( z+)|IZrCt{;^)y=QX|&YSXsM^sQct6$o<_NzM!B9wxt>P3o<_Nz##FtO>uHqhX_V_} zlUmjK&&#rUUY6BkURIBJSv}@u^_Z8{V{Wa- z+*&VhYdwwDdK#_uG+OIvwARyTt*6miPouS-#`1a^%j;<@ucxuRp2qTe8q4cxEU%~G z2lC}5_1Kn8#a2rTXN>Q;O^vm^O~8)A3|ks&X*D(0(rRj~rPb6}ORK4|R-UHDT6voM zV6MERc5XB^)zk8mkFv*a+2gnD@mp?n_%63Ph?ZMBYvbt zH?%0%>Z5*~8v>MxKxy`5F=F|6+qOzY9mD_wBwE6V?(4*`pMrA)SD*K61*-wnh zeqvPi6Qi;ps+3pw^jG-uukh)w@aeB`L!j~sUw%K3Df@v;*$-sOeqvSj6RWbHSe4t| zc%a!nuw6dR|mHh;*>?det zKS3+|30m1t(8_*-R_>_v(AKignV+JS{S>Y2r)XtAMJxL$TG>z0$`v>GD_49EsJOvm zx#9+yWj}>0S9}drd^#0h1AY=$_LI1>pTw2@B(7ZXHBj*_;3suuKdCGGNnN?qr{C$* z@AT>W$zIt{_R5_;{Z600pZt|OeG7E@9?T~L& zKBqqFbLyi$*S6|&3J0HOf%=@nsn02#`kcb4ubzgdf^Ms);i;h8>S=f?V4J6c`s!(T zD(JR)8lDQetzHgK1>IIJho^#WtCz$5fYa3B&Mz$4yRc;IV#(HRs<_EFmh25!@_fY7 zg|E1&1J-Nd+4@*#>to5*!ji3pC0id$wtiE^wKkSMem6%M$$>Wp=sO<4N+bW>-n`}E5`{Utspng=g>I_2DKwTm`?2)LyD2r+efXumzTMOr+kN^=efix~x~a0v z=Vw{d%=0-Dow?gB&gX1&=58+LoL?KJ&)Hq`>Dare;`ocDuP?`6to!4 z?YN0`f1Kkc*8Opgn^^bt?6`?_U(b%4Soh_0+{C&sr{gBpeLFjDHdP!qvGn!kxQTV& zj~q9#?%Tm}6YJy_mOg#QO|1L$9XGM=(|6p&x=-J6v#H{^iKS29aTDu4eScn8{CQoe zo!5?=2p7-%%6mzWp6FvF_X7Q4{OF{EnJf_vLrg z#JVrPqbAmU`5iTzDxFO;x3~_zhYQz>9W$}lr|y`Eb)ULpCf1kF(y?(feiqkdiyuE@ z;)$PN_`)yzh=@1UhJzX}e&OsaR3=7;IecB()Z$L|<|VGNn%kGM(y?Twv1Fw+x4Yl9 zuw>=5EpxwDVaZCzl7+^Sm5wEkZ(HV03M@Mc-HXS13Vkq|5m2DLFpQPM@Xo)U3v0jl z*4JE3;PTH{_s)UC@gtAE4Nu>;JA7f^Jila^+6qPC2)}3Q>PBrhf3lw6R#OVR+7Z9i z^v+*@=!VUQY|y-Ru5iC6W69EES)R9e+UvCS{w?#*fAT|cQ+IgXfIF6Mz~6S+G2`v{ z;@qkL_8&LQ_{cvG%-9;d{htT^al@qGwWO1!ZQB=2%7$v+mPL~W8%mS=H%t~zxnQzT zd0zFz1t%VVRkbv^VMF!A$+NZ`Uz%)HU+b1FrO9HYyLWP-t`;k$$wu`wYKZ+Cs-^9v ztFG!skPX#s*ivF3^(|H3(rw3Y+p=ZL@so1emMuPQByJlfXDwJUITKFQwNK7$KeswL ztNpZ(p@i+*R!kn#cLKr%4cJ#glD5(_X)58ijzyD&+BP|DK|HhY^lhceRSUYcFicyH z*ZfVEjz<}4DNY7YU(nrwV`ntPGiFpKO*i~A8z#-RQfYEd``KD2@GMxdWwNMi8?jcz z+M>x>4W(NO5~}GzDwA{Dx0SBiR+^lAVaNic>ZzXcIa@*vk z;Z!}u_}Jfqj!Dx#DbM*BZWu$AEt;Hz?98ZiRb_JCf)%B0h&4IvFoWCsR;;*cTRhvI zHo4=p<4;1ViU>I8v_+G18)Bo&c@44E;({)pfa=oa{Dyd@E{|x4XX*0D zhIqCvk7|hL=$r-2phiN|%X&;SajzQYGd=k>u<*`Uxmrq98x;zeP>+<;jQ`wa) zHw^?)%d)}6a$rePg##HgNpP&O2q6gu#1?rWtVu|~W|fi{t{nLRF0O)aX(t!>BmM&3 z8(T7ADGHZMdNb40-P8TL?SrZW+q_T0Ht%O)oA-0D&HI$WNsmV=L=+>24&U{*Rsn`u zPIf1Yr4o*;j7)hlRjEqJDAhvV6H4j0rd4mN{p)0r+s>yUb;hMs5oc`PMo|BJ;)6@m zMlHd1Rc1^^+yQSv|HK|)W*l!7!l!;y*ZR}W7`&P_Du4%xR0JBtwW?e&{zOof@*h@_ z{2fTlA%2c2yj&+w-+jK@VEI z(W>(8x{^F9)A5u3}1wbr@T{IrujB7;=Jx%7V5L#VOF;E2yC~*uB3{Uc?hdlRUAKDG- z9@<@8(PoOe)EQ|++6<4QU?V>}JdO@<%Br1~0;)r)rbfU#WWOrDJv}_j4r7zqZ2Kxe zLmcoa3CJjThi2f+Dpq508asM>(4F)!o^Yos7l+2eB%l%dFAk8zeBNl~^W;tRo1o+O zl`V)%=``X#nqEk!t#q>WfXr2x92@We{ReqJ<;yH`f9)^x*THV*^eMRjnZU>#ZkLTz zyhQl{zglJwZ{|eB-34$6R?VJcXYK*mnMEU>*8`_Wo*wGzxAP&Lz9?*dLUoG(n^Z@z zMRf#Esg7XD=7pS1(g;GLw3Uy#8AR(o)ht2w0o4#Zq#A-pR70?gmVt(w@;^z)KN;To zKT + + Pfennig.ttf + + diff --git a/configurationServer/gui/brandManager/styles.h b/configurationServer/gui/brandManager/styles.h new file mode 100644 index 0000000..57fc2ad --- /dev/null +++ b/configurationServer/gui/brandManager/styles.h @@ -0,0 +1,143 @@ +#pragma once + +#include + +//#include +#include "fonts.h" + +namespace qReal { + +/// Manages all json stylesheets in system +class Styles +{ +public: + explicit Styles(Fonts const &fonts) + : mFonts(fonts) + { + } + + virtual ~Styles() + { + } + + /// Returns json stylesheet for start tab background + virtual QString startTabBackgroundStyle() const + { +// return utils::InFile::readAll(startTabBackgroundStylePath()); + } + + /// Returns json stylesheet for start tab substrate background + virtual QString startTabSubstrateBackgroundStyle() const + { +// return utils::InFile::readAll(startTabSubstrateBackgroundStylePath()); + } + + /// Returns json stylesheet for start tab header background + virtual QString startTabHeaderBackgroundStyle() const + { +// return utils::InFile::readAll(startTabHeaderBackgroundStylePath()); + } + + /// Returns json stylesheet for recent projects section background on start tab + virtual QString startTabRecentProjectsBackgroundStyle() const + { +// return utils::InFile::readAll(startTabRecentProjectsBackgroundStylePath()); + } + + /// Returns json stylesheet for projects management section background on start tab + virtual QString startTabProjectsManagementBackgroundStyle() const + { +// return utils::InFile::readAll(startTabProjectsManagementBackgroundStylePath()); + } + + /// Returns json stylesheet for command buttons on start tab + virtual QString startTabButtonStyle() const + { +// return utils::InFile::readAll(startTabButtonStylePath()) +// .replace("@@FONT@@", mFonts.commandButtonsFont()); + } + + /// Returns json stylesheet for styled text on start tab of level 1 heading + virtual QString startTabLabelLevel1Style() const + { +// return utils::InFile::readAll(startTabLabelLevel1StylePath()) +// .replace("@@FONT@@", mFonts.styledTextFont()); + } + + /// Returns json stylesheet for styled text on start tab of level 2 heading + virtual QString startTabLabelLevel2Style() const + { +// return utils::InFile::readAll(startTabLabelLevel2StylePath()) +// .replace("@@FONT@@", mFonts.styledTextFont()); + } + +protected: + /// Returns a path to a file with json stylesheet for start tab background + virtual QString startTabBackgroundStylePath() const + { + return processUrl(":/styles/startTab/background.js"); + } + + /// Returns a path to a file with json stylesheet for start tab substrate background + virtual QString startTabSubstrateBackgroundStylePath() const + { + return processUrl(":/styles/startTab/substrate.js"); + } + + /// Returns a path to a file with json stylesheet for start tab header background + virtual QString startTabHeaderBackgroundStylePath() const + { + return processUrl(":/styles/startTab/header.js"); + } + + /// Returns a path to a file with json stylesheet for recent projects section background on start tab + virtual QString startTabRecentProjectsBackgroundStylePath() const + { + return processUrl(":/styles/startTab/recentProjectsBackground.js"); + } + + /// Returns a path to a file with json stylesheet for projects management section background on start tab + virtual QString startTabProjectsManagementBackgroundStylePath() const + { + return processUrl(":/styles/startTab/projectsManagementBackground.js"); + } + + /// Returns a path to a file with json stylesheet for command buttons on start tab + virtual QString startTabButtonStylePath() const + { + return processUrl(":/styles/startTab/button.js"); + } + + /// Returns a path to a file with json stylesheet for styled text on start tab of level 1 heading + virtual QString startTabLabelLevel1StylePath() const + { + return processUrl(":/styles/startTab/labelLevel1.js"); + } + + /// Returns a path to a file with json stylesheet for styled text on start tab of level 2 heading + virtual QString startTabLabelLevel2StylePath() const + { + return processUrl(":/styles/startTab/labelLevel2.js"); + } + + /// Returns either given url without modifications or transforms it into absolute disk location + /// for more convenient styles debugging (modifications do not need rebuilds then) + QString processUrl(QString const &resourceUrl) const + { + // TODO: uncomment one of the next scenarious + + // Scenario one: use it for releases + return resourceUrl; + + // Scenario two: use it for debugging + // QString choppedString = resourceUrl; + // choppedString.remove(0, 1); + // return QApplication::applicationDirPath() + "/../qrgui/brandManager" + choppedString; + } + + Fonts const &mFonts; +}; + +} + +// Implemented in .h file for correct linkage diff --git a/configurationServer/gui/brandManager/styles/startTab/background.js b/configurationServer/gui/brandManager/styles/startTab/background.js new file mode 100644 index 0000000..93c36b8 --- /dev/null +++ b/configurationServer/gui/brandManager/styles/startTab/background.js @@ -0,0 +1 @@ +background-color: white; diff --git a/configurationServer/gui/brandManager/styles/startTab/button.js b/configurationServer/gui/brandManager/styles/startTab/button.js new file mode 100644 index 0000000..5ab45b0 --- /dev/null +++ b/configurationServer/gui/brandManager/styles/startTab/button.js @@ -0,0 +1,20 @@ +* { + background-color: transparent; + font-family:url(@@FONT@@); + color: black; + font: bold 20px; + text-align: left; +} + +QPushButton { + border-radius: 5px; + border-color: beige; +} + +QPushButton:hover, QPushButton:pressed { + color: rgb(110, 70, 156); +} + +QWidget[enabled="true"] { + color: rgb(110, 70, 156); +} diff --git a/configurationServer/gui/brandManager/styles/startTab/header.js b/configurationServer/gui/brandManager/styles/startTab/header.js new file mode 100644 index 0000000..5012a6d --- /dev/null +++ b/configurationServer/gui/brandManager/styles/startTab/header.js @@ -0,0 +1 @@ +background-color: rgb(110, 70, 156); \ No newline at end of file diff --git a/configurationServer/gui/brandManager/styles/startTab/labelLevel1.js b/configurationServer/gui/brandManager/styles/startTab/labelLevel1.js new file mode 100644 index 0000000..f8bd91f --- /dev/null +++ b/configurationServer/gui/brandManager/styles/startTab/labelLevel1.js @@ -0,0 +1,3 @@ +font-family: url(@@FONT@@); +font: bold 35px; +color: white; \ No newline at end of file diff --git a/configurationServer/gui/brandManager/styles/startTab/labelLevel2.js b/configurationServer/gui/brandManager/styles/startTab/labelLevel2.js new file mode 100644 index 0000000..2c56e7c --- /dev/null +++ b/configurationServer/gui/brandManager/styles/startTab/labelLevel2.js @@ -0,0 +1,3 @@ +font-family: url(@@FONT@@); +font: bold 28px; +color: black; \ No newline at end of file diff --git a/configurationServer/gui/brandManager/styles/startTab/projectsManagementBackground.js b/configurationServer/gui/brandManager/styles/startTab/projectsManagementBackground.js new file mode 100644 index 0000000..309c730 --- /dev/null +++ b/configurationServer/gui/brandManager/styles/startTab/projectsManagementBackground.js @@ -0,0 +1 @@ +background-color: rgb(246, 246, 242); \ No newline at end of file diff --git a/configurationServer/gui/brandManager/styles/startTab/recentProjectsBackground.js b/configurationServer/gui/brandManager/styles/startTab/recentProjectsBackground.js new file mode 100644 index 0000000..9ee8714 --- /dev/null +++ b/configurationServer/gui/brandManager/styles/startTab/recentProjectsBackground.js @@ -0,0 +1 @@ +background-color: rgb(238, 238, 230); \ No newline at end of file diff --git a/configurationServer/gui/brandManager/styles/startTab/substrate.js b/configurationServer/gui/brandManager/styles/startTab/substrate.js new file mode 100644 index 0000000..f83ec24 --- /dev/null +++ b/configurationServer/gui/brandManager/styles/startTab/substrate.js @@ -0,0 +1 @@ +background-color: rgb(220, 220, 220); diff --git a/configurationServer/gui/brandManager/styles/styles.qrc b/configurationServer/gui/brandManager/styles/styles.qrc new file mode 100644 index 0000000..9d3552f --- /dev/null +++ b/configurationServer/gui/brandManager/styles/styles.qrc @@ -0,0 +1,12 @@ + + + startTab/background.js + startTab/button.js + startTab/header.js + startTab/labelLevel1.js + startTab/labelLevel2.js + startTab/projectsManagementBackground.js + startTab/recentProjectsBackground.js + startTab/substrate.js + + diff --git a/configurationServer/gui/gui.pro b/configurationServer/gui/gui.pro new file mode 100644 index 0000000..bb491c2 --- /dev/null +++ b/configurationServer/gui/gui.pro @@ -0,0 +1,75 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-07-03T12:21:10 +# +#------------------------------------------------- + +QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = gui +TEMPLATE = app + +CONFIG += c++11 + +SOURCES += main.cpp\ + preferencesDialog.cpp \ + preferencesPages/behaviourPage.cpp \ + preferencesPages/debuggerPage.cpp \ + preferencesPages/editorPage.cpp \ + preferencesPages/featuresPage.cpp \ + preferencesPages/miscellaniousPage.cpp \ + qrkernel/ids.cpp \ + qrkernel/settingsManager.cpp \ + qrkernel/timeMeasurer.cpp \ + qrkernel/version.cpp \ + qrutils/qRealFileDialog.cpp \ + brandManager/brandManager.cpp \ + hotKeyManager/hotKeyManager.cpp \ + hotKeyManager/hotKeyManagerPage.cpp \ + hotKeyManager/shortcutEdit.cpp \ + qrutils/qRealDialog.cpp \ + widget.cpp + +HEADERS += \ + preferencesDialog.h \ + preferencesPages/behaviourPage.h \ + preferencesPages/debuggerPage.h \ + preferencesPages/editorPage.h \ + preferencesPages/featuresPage.h \ + preferencesPages/miscellaniousPage.h \ + preferencesPages/preferencesPage.h \ + qrkernel/definitions.h \ + qrkernel/ids.h \ + qrkernel/kernelDeclSpec.h \ + qrkernel/roles.h \ + qrkernel/settingsManager.h \ + qrkernel/timeMeasurer.h \ + qrkernel/version.h \ + qrutils/qRealFileDialog.h \ + brandManager/brandManager.h \ + brandManager/fonts.h \ + brandManager/styles.h \ + hotKeyManager/hotKeyManager.h \ + hotKeyManager/hotKeyManagerPage.h \ + hotKeyManager/shortcutEdit.h \ + qrutils/qRealDialog.h \ + widget.h \ + ui_widget.h + +FORMS += \ + preferencesDialog.ui \ + preferencesPages/behaviourPage.ui \ + preferencesPages/debuggerPage.ui \ + preferencesPages/editorPage.ui \ + preferencesPages/featuresPage.ui \ + preferencesPages/miscellaniousPage.ui \ + hotKeyManager/hotKeyManagerPage.ui \ + widget.ui + +SUBDIRS += \ + qrkernel/qrkernel.pro + +OTHER_FILES += + +RESOURCES += diff --git a/configurationServer/gui/gui.pro.user b/configurationServer/gui/gui.pro.user new file mode 100644 index 0000000..11376ae --- /dev/null +++ b/configurationServer/gui/gui.pro.user @@ -0,0 +1,248 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + true + 1 + true + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.2.1 MinGW 32bit + Desktop Qt 5.2.1 MinGW 32bit + qt.521.win32_mingw48.essentials_kit + 0 + 0 + 0 + + D:/proga/SummerSchool/tools/configurationServer/gui + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Отладка + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + D:/proga/SummerSchool/tools/configurationServer/build-gui-Desktop_Qt_5_2_1_MinGW_32bit-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Выпуск + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Установка + + ProjectExplorer.BuildSteps.Deploy + + 1 + Локальная установка + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + gui + + Qt4ProjectManager.Qt4RunConfiguration:D:/proga/SummerSchool/tools/configurationServer/gui/gui.pro + + gui.pro + false + false + + 3768 + true + false + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {68757a80-8684-4ace-adf5-8193ba9b0a3b} + + + ProjectExplorer.Project.Updater.FileVersion + 15 + + diff --git a/configurationServer/gui/gui/gui.pro b/configurationServer/gui/gui/gui.pro deleted file mode 100644 index d5323b3..0000000 --- a/configurationServer/gui/gui/gui.pro +++ /dev/null @@ -1,20 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2014-07-02T16:08:37 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = gui -TEMPLATE = app - - -SOURCES += main.cpp\ - mainwindow.cpp - -HEADERS += mainwindow.h - -FORMS += mainwindow.ui diff --git a/configurationServer/gui/gui/main.cpp b/configurationServer/gui/gui/main.cpp deleted file mode 100644 index b48f94e..0000000 --- a/configurationServer/gui/gui/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "mainwindow.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - MainWindow w; - w.show(); - - return a.exec(); -} diff --git a/configurationServer/gui/gui/mainwindow.cpp b/configurationServer/gui/gui/mainwindow.cpp deleted file mode 100644 index 49d64fc..0000000 --- a/configurationServer/gui/gui/mainwindow.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "mainwindow.h" -#include "ui_mainwindow.h" - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow) -{ - ui->setupUi(this); -} - -MainWindow::~MainWindow() -{ - delete ui; -} diff --git a/configurationServer/gui/gui/mainwindow.h b/configurationServer/gui/gui/mainwindow.h deleted file mode 100644 index a3948a9..0000000 --- a/configurationServer/gui/gui/mainwindow.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include - -namespace Ui { -class MainWindow; -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - -private: - Ui::MainWindow *ui; -}; - -#endif // MAINWINDOW_H diff --git a/configurationServer/gui/gui/mainwindow.ui b/configurationServer/gui/gui/mainwindow.ui deleted file mode 100644 index 6050363..0000000 --- a/configurationServer/gui/gui/mainwindow.ui +++ /dev/null @@ -1,24 +0,0 @@ - - MainWindow - - - - 0 - 0 - 400 - 300 - - - - MainWindow - - - - - - - - - - - diff --git a/configurationServer/gui/hotKeyManager/hotKeyManager.cpp b/configurationServer/gui/hotKeyManager/hotKeyManager.cpp new file mode 100644 index 0000000..f46c571 --- /dev/null +++ b/configurationServer/gui/hotKeyManager/hotKeyManager.cpp @@ -0,0 +1,212 @@ +#include "hotKeyManager.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace qReal; + +HotKeyManager::HotKeyManager() +{ +} + +HotKeyManager::~HotKeyManager() +{ +} + +HotKeyManager& HotKeyManager::instance() +{ + static HotKeyManager instance; + return instance; +} + +void HotKeyManager::setCommand(QString const &id, QString const &label, QAction *command) +{ + command->setWhatsThis(label); + instance().registerCommand(id, command); +} + +void HotKeyManager::deleteCommand(QString const &id) +{ + resetShortcuts(id); + instance().deleteCommandPrivate(id); +} + +bool HotKeyManager::setShortcut(QString const &id, QKeySequence const &keyseq) +{ + return instance().registerShortcut(id, keyseq); +} + +void HotKeyManager::resetShortcuts(QString const &id) +{ + instance().resetShortcutsPrivate(id); +} + +void HotKeyManager::resetAllShortcuts() +{ + instance().resetAllShortcutsPrivate(); +} + +void HotKeyManager::deleteShortcut(const QString &id, const QString &shortcut) +{ + instance().deleteShortcutPrivate(id, shortcut); +} + +QHash HotKeyManager::commands() +{ + return instance().commandsPrivate(); +} + +QHash HotKeyManager::shortcuts() +{ + return instance().shortcutsPrivate(); +} + +void HotKeyManager::registerCommand(QString const &id, QAction *command) +{ + QList const shortcuts = command->shortcuts(); + + foreach (QKeySequence const &shortcut, shortcuts) { + instance().registerShortcut(id, shortcut.toString()); + } + + mCommands[id] = command; +} + +bool HotKeyManager::registerShortcut(QString const &id, QKeySequence const &keyseq) +{ + if (mCommands.contains(id)) { + QString const shortcut = keyseq.toString(); + + if (!hasPrefixOf(shortcut)) { + addPrefixes(shortcut); + mShortcuts[shortcut] = id; + mCommands[id]->setShortcuts(mCommands[id]->shortcuts() << keyseq); + return true; + } + } + return false; +} + +void HotKeyManager::registerShortcut(QString const &id, QString const &shortcut) +{ + if (!hasPrefixOf(shortcut)) { + addPrefixes(shortcut); + mShortcuts[shortcut] = id; + } +} + +void HotKeyManager::findShortcut(QString const &shortcut) +{ + if (mShortcuts.contains(shortcut) && mCommands[mShortcuts.value(shortcut)]->parentWidget()->isActiveWindow()) { + mCommands[mShortcuts.value(shortcut)]->trigger(); + } +} + +void HotKeyManager::resetShortcutsPrivate(QString const &id) +{ + if (mCommands.contains(id)) { + QStringList const shortcuts = mShortcuts.keys(id); + + foreach (QString const &shortcut, shortcuts) { + deletePrefixes(shortcut); + mShortcuts.remove(shortcut); + } + + mCommands[id]->setShortcuts(QList()); + } +} + +void HotKeyManager::resetAllShortcutsPrivate() +{ + QList const cmds = mCommands.values(); + + foreach (QAction *cmd, cmds) { + cmd->setShortcuts(QList()); + } + + mShortcuts.clear(); + mPrefixes.clear(); +} + +void HotKeyManager::deleteShortcutPrivate(const QString &id, const QString &shortcut) +{ + mShortcuts.remove(shortcut); + deletePrefixes(shortcut); + + QList shortcuts = mCommands[id]->shortcuts(); + + shortcuts.removeOne(shortcut); + mCommands[id]->setShortcuts(shortcuts); +} + +void HotKeyManager::deleteCommandPrivate(QString const &id) +{ + if (mCommands.contains(id)) { + mCommands.remove(id); + } +} + +QHash HotKeyManager::commandsPrivate() +{ + return mCommands; +} + +QHash HotKeyManager::shortcutsPrivate() +{ + return mShortcuts; +} + +bool HotKeyManager::hasPrefixOf(QString const &keyseq) +{ + if (!mPrefixes.contains(keyseq)) { + QStringList const seqlist = keyseq.split(", "); + QString prefix; + + foreach (QString const &seq, seqlist) { + prefix += seq; + if (mShortcuts.contains(prefix)) { + return true; + } + prefix += ", "; + } + return false; + } + return true; +} + +void HotKeyManager::addPrefixes(QString const &keyseq) +{ + QStringList const seqlist = keyseq.split(", "); + QString prefix; + + foreach (QString const &seq, seqlist) { + prefix += seq; + if (mPrefixes.contains(prefix)) { + ++mPrefixes[prefix]; + } else { + mPrefixes[prefix] = 1; + } + prefix += ", "; + } +} + +void HotKeyManager::deletePrefixes(QString const &keyseq) +{ + QStringList const seqlist = keyseq.split(", "); + QString prefix; + + foreach (QString const &seq, seqlist) { + prefix += seq; + --mPrefixes[prefix]; + if (mPrefixes.value(prefix) == 0) { + mPrefixes.remove(prefix); + } + prefix += ", "; + } +} diff --git a/configurationServer/gui/hotKeyManager/hotKeyManager.h b/configurationServer/gui/hotKeyManager/hotKeyManager.h new file mode 100644 index 0000000..4fa71c1 --- /dev/null +++ b/configurationServer/gui/hotKeyManager/hotKeyManager.h @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace qReal { + +enum MouseButtons +{ + None + , MouseLB + , MouseRB + , MouseMB + , MouseWU + , MouseWD +}; + +class HotKeyManager +{ +public: + static HotKeyManager& instance(); + + /// Sets a new command. Connect (on signal triggered()) and key sequences are made by component. + /// @param id Command id. + /// @param label Short description of command + /// @param command QAction object which contains shortcuts and with whom connection is performed. + static void setCommand(QString const &id, QString const &label, QAction *command); + + static void deleteCommand(QString const &id); + + /// Sets a new shortcut to existing command + /// @param id Command id + /// @param keyseq Shortcut + static bool setShortcut(QString const &id, QKeySequence const &keyseq); + + static void resetShortcuts(QString const &id); + static void resetAllShortcuts(); + static void deleteShortcut(QString const &id, QString const &shortcut); + + static QHash commands(); + static QHash shortcuts(); + +private: + HotKeyManager(); + explicit HotKeyManager(HotKeyManager const&); + ~HotKeyManager(); + + void operator=(HotKeyManager const&); + + void registerCommand(QString const &id, QAction *command); + + bool registerShortcut(QString const &id, QKeySequence const &keyseq); + void registerShortcut(QString const &id, QString const &shortcut); + + void findShortcut(QString const &shortcut); + + void resetShortcutsPrivate(QString const &id); + void resetAllShortcutsPrivate(); + void deleteShortcutPrivate(QString const &id, QString const &shortcut); + + void deleteCommandPrivate(QString const &id); + bool hasPrefixOf(QString const &keyseq); + void addPrefixes(QString const &keyseq); + void deletePrefixes(QString const &keyseq); + + QHash commandsPrivate(); + QHash shortcutsPrivate(); + + QHash mCommands; + QHash mShortcuts; + QHash mPrefixes; +}; + +} diff --git a/configurationServer/gui/hotKeyManager/hotKeyManager.pri b/configurationServer/gui/hotKeyManager/hotKeyManager.pri new file mode 100644 index 0000000..9120995 --- /dev/null +++ b/configurationServer/gui/hotKeyManager/hotKeyManager.pri @@ -0,0 +1,12 @@ +HEADERS += \ + $$PWD/hotKeyManagerPage.h \ + $$PWD/hotKeyManager.h \ + $$PWD/shortcutEdit.h + +SOURCES += \ + $$PWD/hotKeyManagerPage.cpp \ + $$PWD/hotKeyManager.cpp \ + $$PWD/shortcutEdit.cpp + +FORMS += \ + $$PWD/hotKeyManagerPage.ui diff --git a/configurationServer/gui/hotKeyManager/hotKeyManagerPage.cpp b/configurationServer/gui/hotKeyManager/hotKeyManagerPage.cpp new file mode 100644 index 0000000..9e4ebd6 --- /dev/null +++ b/configurationServer/gui/hotKeyManager/hotKeyManagerPage.cpp @@ -0,0 +1,224 @@ +#include "hotKeyManagerPage.h" +#include "ui_hotKeyManagerPage.h" + +#include +#include +#include +#include +#include +#include + +#include "hotKeyManager/hotKeyManager.h" + +using namespace qReal; + +int const maxShortcutParts = 3; // Actually, 3 = number of commas in string (= 4 shortcut parts) + // e.g. "Ctrl+X, Alt+V, Shift+G, Ctrl+Y" +int const maxShortcuts = 3; // Max number of shortcuts which we can set to one command + +PreferencesHotKeyManagerPage:: PreferencesHotKeyManagerPage(QWidget *parent) + : PreferencesPage(parent) + , mUi(new Ui::hotKeyManagerPage) + , mCurrentId("") + , mCurrentItem(NULL) + , mCurrentModifiers(Qt::NoModifier) +{ + mUi->setupUi(this); + mIcon = QIcon(":/icons/hotkeys.png"); + +// mUi->hotKeysTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive); + + // TODO: implement export/import + mUi->importPushButton->hide(); + mUi->exportPushButton->hide(); + + connect(mUi->hotKeysTable, SIGNAL(cellClicked(int,int)), this, SLOT(activateShortcutLineEdit(int,int))); + connect(mUi->hotKeysTable, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(doubleClicked(int,int))); + connect(mUi->shortcutLineEdit, SIGNAL(newModifiers(Qt::KeyboardModifiers)) + , this, SLOT(newModifiers(Qt::KeyboardModifiers))); + connect(mUi->shortcutLineEdit, SIGNAL(newKey(int)), this, SLOT(newKey(int))); + connect(mUi->resetShortcutPushButton, SIGNAL(clicked()), this, SLOT(resetShortcuts())); + connect(mUi->resetAllPushButton, SIGNAL(clicked()), this, SLOT(resetAllShortcuts())); + + restoreSettings(); +} + +PreferencesHotKeyManagerPage::~PreferencesHotKeyManagerPage() +{ + delete mUi; +} + +void PreferencesHotKeyManagerPage::save() +{ +} + +void PreferencesHotKeyManagerPage::restoreSettings() +{ + mUi->hotKeysTable->clearContents(); + initTable(); + loadHotKeys(); + mUi->hotKeysTable->sortByColumn(0, Qt::AscendingOrder); + + int const tableWidth = mUi->hotKeysTable->horizontalHeader()->width(); + mUi->hotKeysTable->setColumnWidth(0, 0.25 * tableWidth); + mUi->hotKeysTable->setColumnWidth(1, 0.5 * tableWidth); + mUi->hotKeysTable->setColumnWidth(2, 0.25 * tableWidth); +} + +void PreferencesHotKeyManagerPage::resetShortcuts() +{ + if (!mCurrentId.isEmpty()) { + if (mCurrentItem->textColor() == Qt::black) { + HotKeyManager::deleteShortcut(mCurrentId, mCurrentItem->text()); + } + + mCurrentItem->setText(""); + mUi->shortcutLineEdit->setText(""); + setTextColor(Qt::black); + } +} + +void PreferencesHotKeyManagerPage::resetAllShortcuts() +{ + if (QMessageBox::question(this, tr("Question"), tr("This will clear all "\ + "current shortcuts. Are you sure?")) == QMessageBox::Yes) { + mCurrentItem = NULL; + mCurrentId = ""; + + HotKeyManager::resetAllShortcuts(); + restoreSettings(); + } +} + +void PreferencesHotKeyManagerPage::showEvent(QShowEvent *e) +{ + restoreSettings(); + QWidget::showEvent(e); +} + +void PreferencesHotKeyManagerPage::loadHotKeys() +{ + QHash cmds = HotKeyManager::commands(); + QHash shortcuts = HotKeyManager::shortcuts(); + + QHash::iterator i; + int k; + + for (i = cmds.begin(), k = 0; i != cmds.end(); ++i, ++k) { + QStringList const sequences = shortcuts.keys(i.key()); + + mUi->hotKeysTable->item(k, 0)->setText(i.key()); + mUi->hotKeysTable->item(k, 1)->setText(i.value()->whatsThis()); + + int j = 0; + foreach (QString const &sequence, sequences) { + mUi->hotKeysTable->item(k, 2 + j)->setText(sequence); + mUi->hotKeysTable->item(k, 2 + j)->setTextColor(Qt::black); + + if (++j >= maxShortcuts) { + break; + } + } + } +} + +void PreferencesHotKeyManagerPage::initTable() +{ + int const rows = HotKeyManager::commands().size(); + mUi->hotKeysTable->setRowCount(rows); + + for (int i = 0; i < mUi->hotKeysTable->rowCount(); ++i) { + // first column - name of command, second - short description, rest - shortcuts + for (int j = 0; j < 2 + maxShortcuts; ++j) { + mUi->hotKeysTable->setItem(i, j, new QTableWidgetItem("")); + } + } +} + +void PreferencesHotKeyManagerPage::doubleClicked(const int row, const int column) +{ + mUi->shortcutLineEdit->setFocus(); + activateShortcutLineEdit(row, column); +} + +void PreferencesHotKeyManagerPage::activateShortcutLineEdit(int const row, int const column) +{ + // Columns with shortcuts start from index 2 + if (column > 1) { + if (mCurrentItem) { + mCurrentItem->setBackgroundColor(Qt::white); + } + + mCurrentId = mUi->hotKeysTable->item(row, 0)->text(); + mCurrentItem = mUi->hotKeysTable->item(row, column); + mCurrentItem->setBackgroundColor(Qt::lightGray); + + mUi->shortcutLineEdit->setText(mCurrentItem->text()); + mUi->shortcutLineEdit->setEnabled(true); + + setTextColor(mCurrentItem->textColor()); + + if (HotKeyManager::setShortcut(mCurrentId, mCurrentItem->text())) { + setTextColor(Qt::black); + } + } else { + mCurrentId = ""; + mUi->shortcutLineEdit->clear(); + mUi->shortcutLineEdit->setEnabled(false); + } +} + +void PreferencesHotKeyManagerPage::newModifiers(Qt::KeyboardModifiers modifiers) +{ + mCurrentModifiers = modifiers; +} + +void PreferencesHotKeyManagerPage::newKey(int const key) +{ + if (!mCurrentId.isEmpty()) { + if (mCurrentItem->text().isEmpty()) { + if (HotKeyManager::setShortcut(mCurrentId, QKeySequence(mCurrentModifiers + key))) { + setTextColor(Qt::black); + } else { + setTextColor(Qt::red); + } + mCurrentItem->setText(QKeySequence(mCurrentModifiers + key).toString()); + mUi->shortcutLineEdit->setText(mCurrentItem->text()); + } else { + int const parts = mCurrentItem->text().count(','); + + if (parts != maxShortcutParts) { + QString const shortcut = QString("%1, %2").arg( + mCurrentItem->text() + , QKeySequence(mCurrentModifiers + key).toString() + ); + + if (mCurrentItem->textColor() == Qt::black) { + HotKeyManager::deleteShortcut(mCurrentId, mCurrentItem->text()); + } + + if (HotKeyManager::setShortcut(mCurrentId, QKeySequence(shortcut))) { + setTextColor(Qt::black); + mCurrentItem->setText(shortcut); + mUi->shortcutLineEdit->setText(mCurrentItem->text()); + } else { + HotKeyManager::setShortcut(mCurrentId, mCurrentItem->text()); + + if (parts < maxShortcutParts - 1) { + setTextColor(Qt::red); + mCurrentItem->setText(shortcut); + mUi->shortcutLineEdit->setText(mCurrentItem->text()); + } + } + } + } + } +} + +void PreferencesHotKeyManagerPage::setTextColor(QColor const &color) +{ + mCurrentItem->setTextColor(color); + QPalette palette; + palette.setColor(QPalette::Text, color); + mUi->shortcutLineEdit->setPalette(palette); +} diff --git a/configurationServer/gui/hotKeyManager/hotKeyManagerPage.h b/configurationServer/gui/hotKeyManager/hotKeyManagerPage.h new file mode 100644 index 0000000..b413ace --- /dev/null +++ b/configurationServer/gui/hotKeyManager/hotKeyManagerPage.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +#include "preferencesPages/preferencesPage.h" + +namespace Ui { + class hotKeyManagerPage; +} + +class PreferencesHotKeyManagerPage : public PreferencesPage +{ + Q_OBJECT + +public: + explicit PreferencesHotKeyManagerPage(QWidget *parent = 0); + ~PreferencesHotKeyManagerPage(); + + void save(); + void restoreSettings(); + +private slots: + void doubleClicked(int const row, int const column); + void activateShortcutLineEdit(int const row, int const column); + void newModifiers(Qt::KeyboardModifiers modifiers); + void newKey(int const key); + void resetShortcuts(); + void resetAllShortcuts(); + +protected: + void showEvent(QShowEvent *e); + +private: + void loadHotKeys(); + void initTable(); + void setTextColor(QColor const &color); + + Ui::hotKeyManagerPage *mUi; + + QString mCurrentId; + QTableWidgetItem *mCurrentItem; + Qt::KeyboardModifiers mCurrentModifiers; +}; diff --git a/configurationServer/gui/hotKeyManager/hotKeyManagerPage.ui b/configurationServer/gui/hotKeyManager/hotKeyManagerPage.ui new file mode 100644 index 0000000..7174b14 --- /dev/null +++ b/configurationServer/gui/hotKeyManager/hotKeyManagerPage.ui @@ -0,0 +1,222 @@ + + + hotKeyManagerPage + + + + 0 + 0 + 654 + 350 + + + + Form + + + + + + Keyboard Shortcuts + + + + + + Qt::Horizontal + + + + 381 + 38 + + + + + + + + Import... + + + + + + + Export... + + + + + + + true + + + + 0 + 0 + + + + Qt::WheelFocus + + + QAbstractItemView::NoEditTriggers + + + false + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + false + + + true + + + true + + + 0 + + + 5 + + + 100 + + + true + + + false + + + 19 + + + false + + + + Command + + + + + Label + + + + + Shortcut 1 + + + + + Shortcut 2 + + + + + Shortcut 3 + + + + + + + + Reset All + + + + + + + + + + Shortcut + + + + + + Reset + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 10 + 20 + + + + + + + + Key sequence + + + + + + + false + + + false + + + false + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 2 + 20 + + + + + + + + + + + + ShortcutEdit + QLineEdit +
hotKeyManager/shortcutEdit.h
+
+
+ + +
diff --git a/configurationServer/gui/hotKeyManager/shortcutEdit.cpp b/configurationServer/gui/hotKeyManager/shortcutEdit.cpp new file mode 100644 index 0000000..c595c52 --- /dev/null +++ b/configurationServer/gui/hotKeyManager/shortcutEdit.cpp @@ -0,0 +1,34 @@ +#include "shortcutEdit.h" + +#include +#include +#include +#include +#include + +ShortcutEdit::ShortcutEdit(QWidget *parent) + : QLineEdit(parent) +{ +} + +bool ShortcutEdit::event(QEvent *event) +{ + if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + QKeyEvent *keyevent = static_cast (event); + + switch (keyevent->key()) { + case Qt::Key_Shift: + case Qt::Key_Control: + case Qt::Key_Alt: + case Qt::Key_AltGr: + emit newModifiers(keyevent->modifiers()); + break; + default: + if (event->type() == QEvent::KeyPress) { + emit newKey(keyevent->key()); + } + } + return true; + } + return QLineEdit::event(event); +} diff --git a/configurationServer/gui/hotKeyManager/shortcutEdit.h b/configurationServer/gui/hotKeyManager/shortcutEdit.h new file mode 100644 index 0000000..280781d --- /dev/null +++ b/configurationServer/gui/hotKeyManager/shortcutEdit.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +class ShortcutEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit ShortcutEdit(QWidget *parent = 0); + + bool event(QEvent *event); + +signals: + void newKey(int const key); + void newModifiers(Qt::KeyboardModifiers modifiers); +}; diff --git a/configurationServer/gui/main.cpp b/configurationServer/gui/main.cpp new file mode 100644 index 0000000..2e24f5a --- /dev/null +++ b/configurationServer/gui/main.cpp @@ -0,0 +1,15 @@ +#include +#include "preferencesDialog.h" +#include "widget.h" +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); +// PreferencesDialog w; +// w.init(nullptr, nullptr, nullptr, nullptr); +// w.show(); + Widget w; + w.init(); + w.show(); + + return a.exec(); +} diff --git a/configurationServer/gui/preferencesDialog.cpp b/configurationServer/gui/preferencesDialog.cpp new file mode 100644 index 0000000..3887060 --- /dev/null +++ b/configurationServer/gui/preferencesDialog.cpp @@ -0,0 +1,182 @@ +#include "preferencesDialog.h" +#include "ui_preferencesDialog.h" + +#include + +#include + +#include "preferencesPages/behaviourPage.h" +#include "preferencesPages/debuggerPage.h" +#include "preferencesPages/editorPage.h" +#include "preferencesPages/miscellaniousPage.h" +#include "preferencesPages/featuresPage.h" +#include "hotKeyManager/hotKeyManagerPage.h" +#include "brandManager/brandManager.h" + +using namespace qReal; +using namespace utils; + +PreferencesDialog::PreferencesDialog(QWidget *parent) + : QRealDialog("PreferencesDialog", parent) + , mUi(new Ui::PreferencesDialog) +{ + mUi->setupUi(this); +} + +PreferencesDialog::~PreferencesDialog() +{ + SettingsManager::setValue("currentPreferencesTab", mUi->listWidget->currentRow()); + delete mUi; +} + +void PreferencesDialog::init(QAction * const showGridAction, QAction * const showAlignmentAction + , QAction * const activateGridAction, QAction * const activateAlignmentAction) +{ + PreferencesPage *behaviourPage = new PreferencesBehaviourPage(mUi->pageContentWigdet); + // Debugger page removed due to #736 + PreferencesMiscellaniousPage *miscellaniousPage = new PreferencesMiscellaniousPage(mUi->pageContentWigdet); + PreferencesPage *editorPage = new PreferencesEditorPage(showGridAction + , showAlignmentAction, activateGridAction, activateAlignmentAction, mUi->pageContentWigdet); + PreferencesPage *hotKeyManagerPage = new PreferencesHotKeyManagerPage(mUi->pageContentWigdet); + + mUi->applyButton->setVisible(false); + mUi->cancelButton->setVisible(false); + mUi->okButton->setVisible(false); + + connect(mUi->listWidget, SIGNAL(clicked(QModelIndex)) + , this, SLOT(chooseTab(const QModelIndex &))); + connect(mUi->listWidget, SIGNAL(activated(const QModelIndex &)) + , this, SLOT(chooseTab(const QModelIndex &))); + connect(mUi->applyButton, SIGNAL(clicked()), this, SLOT(applyChanges())); + connect(mUi->okButton, SIGNAL(clicked()), this, SLOT(saveAndClose())); + connect(mUi->cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); + connect(mUi->exportButton, SIGNAL(clicked()), this, SLOT(exportSettings())); + connect(mUi->importButton, SIGNAL(clicked()), this, SLOT(importSettings())); + + connect(editorPage, SIGNAL(gridChanged()), this, SIGNAL(gridChanged())); + connect(editorPage, SIGNAL(fontChanged()), this, SIGNAL(fontChanged())); + connect(editorPage, SIGNAL(paletteRepresentationChanged()), this + , SIGNAL(paletteRepresentationChanged())); + connect(miscellaniousPage, SIGNAL(iconsetChanged()), this, SIGNAL(iconsetChanged())); + connect(miscellaniousPage, &PreferencesMiscellaniousPage::toolbarSizeChanged + , this, &PreferencesDialog::toolbarSizeChanged); + connect(behaviourPage, SIGNAL(usabilityTestingModeChanged(bool)) + , this, SIGNAL(usabilityTestingModeChanged(bool)), Qt::UniqueConnection); + + registerPage(tr("Behaviour"), behaviourPage); + registerPage(tr("Miscellanious"), miscellaniousPage); + registerPage(tr("Editor"), editorPage); + registerPage(tr("Shortcuts"), hotKeyManagerPage); + + int const currentTab = SettingsManager::value("currentPreferencesTab").toInt(); + mUi->listWidget->setCurrentRow(currentTab); + chooseTab(mUi->listWidget->currentIndex()); +} + +void PreferencesDialog::updatePluginDependendSettings() +{ +// setWindowIcon(BrandManager::applicationIcon()); +} + +void PreferencesDialog::applyChanges() +{ + bool shouldRestart = false; + foreach (PreferencesPage *page, mCustomPages.values()) { + page->save(); + shouldRestart |= page->mShouldRestartSystemToApply; + page->mShouldRestartSystemToApply = false; + } + + SettingsManager::instance()->saveData(); + + if (shouldRestart) { + QMessageBox::information(this, tr("Information"), tr("You should restart the system to apply changes")); + } + + emit settingsApplied(); +} + +void PreferencesDialog::restoreSettings() +{ + foreach (PreferencesPage *page, mCustomPages.values()) { + page->restoreSettings(); + } +} + +void PreferencesDialog::changeEvent(QEvent *e) +{ + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + mUi->retranslateUi(this); + foreach (PreferencesPage *page, mCustomPages.values()) + page->changeEvent(e); + break; + default: + break; + } +} + +void PreferencesDialog::showEvent(QShowEvent *e) +{ + restoreSettings(); + QRealDialog::showEvent(e); +} + +void PreferencesDialog::saveAndClose() +{ + applyChanges(); + close(); +} + +void PreferencesDialog::cancel() +{ + restoreSettings(); + close(); +} + +void PreferencesDialog::chooseTab(QModelIndex const &index) +{ + mUi->listWidget->setCurrentRow(index.row()); + mUi->pageContentWigdet->setCurrentIndex(index.row() + 1); +} + +void PreferencesDialog::registerPage(QString const &pageName, PreferencesPage * const page) +{ + mUi->pageContentWigdet->addWidget(page); + mCustomPages.insert(pageName, page); + mPagesIndexes.insert(pageName, mCustomPages.count() - 1); + mUi->listWidget->addItem(new QListWidgetItem(QIcon(page->getIcon()), pageName)); +} + +void PreferencesDialog::switchCurrentTab(QString const &tabName) +{ + if (mCustomPages.contains(tabName)) { + int const currentIndex = mPagesIndexes[tabName]; + mUi->listWidget->setCurrentRow(currentIndex); + mUi->pageContentWigdet->setCurrentIndex(currentIndex + 1); + } +} +void PreferencesDialog::changePaletteParameters() +{ + if (mCustomPages.count(tr("Editor")) > 0) { + static_cast(mCustomPages[tr("Editor")])->changePaletteParameters(); + } +} + +void PreferencesDialog::exportSettings() +{ + QString fileNameForExport = QRealFileDialog::getSaveFileName("SaveEnginePreferences", this + , tr("Save File"),"/mySettings",tr("*.ini")); + if (!fileNameForExport.endsWith(".ini")) { + fileNameForExport += ".ini"; + } + SettingsManager::instance()->saveSettings(fileNameForExport); +} + +void PreferencesDialog::importSettings() +{ + QString fileNameForImport = QRealFileDialog::getOpenFileName("OpenEnginePreferences", this + , tr("Open File"),"/mySettings",tr("*.ini")); + SettingsManager::instance()->loadSettings(fileNameForImport); +} diff --git a/configurationServer/gui/preferencesDialog.h b/configurationServer/gui/preferencesDialog.h new file mode 100644 index 0000000..73ff7af --- /dev/null +++ b/configurationServer/gui/preferencesDialog.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include "preferencesPages/preferencesPage.h" + +namespace Ui { + class PreferencesDialog; +} + +class PreferencesDialog : public utils::QRealDialog +{ + Q_OBJECT + +public: + + explicit PreferencesDialog(QWidget *parent = 0); + ~PreferencesDialog(); + + void init(QAction * const showGridAction, QAction * const showAlignmentAction + , QAction * const activateGridAction, QAction * const activateAlignmentAction); + void updatePluginDependendSettings(); + + void registerPage(QString const &pageName, PreferencesPage * const page); + void switchCurrentTab(QString const &tabName); + +protected: + void changeEvent(QEvent *e); + void showEvent(QShowEvent *e); + +signals: + void gridChanged(); + void iconsetChanged(); + void toolbarSizeChanged(int size); + void settingsApplied(); + void fontChanged(); + void paletteRepresentationChanged(); + void usabilityTestingModeChanged(bool on); + +public slots: + void changePaletteParameters(); + +private slots: + void cancel(); + void applyChanges(); + void restoreSettings(); + void saveAndClose(); + void chooseTab(const QModelIndex &); + void exportSettings(); + void importSettings(); + +private: + Ui::PreferencesDialog *mUi; + QMap mCustomPages; + QMap mPagesIndexes; +}; diff --git a/configurationServer/gui/preferencesDialog.ui b/configurationServer/gui/preferencesDialog.ui new file mode 100644 index 0000000..db7fb7c --- /dev/null +++ b/configurationServer/gui/preferencesDialog.ui @@ -0,0 +1,160 @@ + + + PreferencesDialog + + + + 0 + 0 + 892 + 593 + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Preferences + + + + :/icons/qreal.png:/icons/qreal.png + + + + + + false + + + OK + + + + + + + false + + + Cancel + + + + + + + false + + + Apply + + + + + + + + 0 + 0 + + + + + 500 + 16777215 + + + + QListView::TopToBottom + + + QListView::ListMode + + + true + + + true + + + -1 + + + + + + + + 0 + 0 + + + + true + + + + + 0 + 0 + 610 + 509 + + + + + 0 + 0 + + + + + + + + 0 + 0 + + + + + + + + + + + + + Export + + + + + + + Import + + + + + + + + diff --git a/configurationServer/gui/preferencesPages/behaviourPage.cpp b/configurationServer/gui/preferencesPages/behaviourPage.cpp new file mode 100644 index 0000000..3c6c33d --- /dev/null +++ b/configurationServer/gui/preferencesPages/behaviourPage.cpp @@ -0,0 +1,102 @@ +#include "behaviourPage.h" +#include "ui_behaviourPage.h" + +#include + +using namespace qReal; + +PreferencesBehaviourPage::PreferencesBehaviourPage(QWidget *parent) + : PreferencesPage(parent) + , mUi(new Ui::PreferencesBehaviourPage) +{ + mIcon = QIcon(":/icons/preferences/behaviour.png"); + mUi->setupUi(this); + + initLanguages(); + + connect(mUi->autoSaveCheckBox, SIGNAL(clicked(bool)), this, SLOT(showAutoSaveBox(bool))); +// connect(mUi->collectErgonomicValuesCheckBox, SIGNAL(clicked(bool)) +// , &mFilterObject, SLOT(setStatusCollectUsabilityStatistics(bool))); + restoreSettings(); +} + +PreferencesBehaviourPage::~PreferencesBehaviourPage() +{ + delete mUi; +} + +void PreferencesBehaviourPage::changeEvent(QEvent *e) +{ + switch (e->type()) { + case QEvent::LanguageChange: + mUi->retranslateUi(this); + break; + default: + break; + } +} + +void PreferencesBehaviourPage::save() +{ + QString const language = mUi->languageComboBox->itemData(mUi->languageComboBox->currentIndex()).toString(); + SettingsManager::setValue("systemLocale", language); + if (mOldLanguage != language) { + setRestartFlag(); + } + + SettingsManager::setValue("PaletteTabSwitching", mUi->paletteTabCheckBox->isChecked()); + SettingsManager::setValue("Autosave", mUi->autoSaveCheckBox->isChecked()); + SettingsManager::setValue("AutosaveInterval", mUi->autoSaveSpinBox->value()); + SettingsManager::setValue("gestureDelay", mUi->gestureDelaySpinBox->value()); + bool const usabilityTestingMode = mUi->usabilityModeCheckBox->isChecked(); + SettingsManager::setValue("usabilityTestingMode", usabilityTestingMode); + SettingsManager::setValue("collectErgonomicValues", mUi->collectErgonomicValuesCheckBox->isChecked() + || usabilityTestingMode); + SettingsManager::setValue("touchMode", mUi->touchModeCheckBox->isChecked()); + if (mUsabilityTestingMode != usabilityTestingMode) { + if (usabilityTestingMode) { + mUi->collectErgonomicValuesCheckBox->setChecked(true); + } + + mUsabilityTestingMode = usabilityTestingMode; + emit usabilityTestingModeChanged(mUsabilityTestingMode); + } +} + +void PreferencesBehaviourPage::restoreSettings() +{ + QString const locale = SettingsManager::value("systemLocale").toString(); + mOldLanguage = locale; + for (int index = 0; index < mUi->languageComboBox->count(); ++index) { + if (locale == mUi->languageComboBox->itemData(index).toString()) { + mUi->languageComboBox->setCurrentIndex(index); + } + } + + mUi->paletteTabCheckBox->setChecked(SettingsManager::value("PaletteTabSwitching").toBool()); + mUi->autoSaveCheckBox->setChecked(SettingsManager::value("Autosave").toBool()); + mUi->autoSaveSpinBox->setValue(SettingsManager::value("AutosaveInterval").toInt()); + mUi->gestureDelaySpinBox->setValue(SettingsManager::value("gestureDelay").toInt()); + mUi->collectErgonomicValuesCheckBox->setChecked(SettingsManager::value("collectErgonomicValues").toBool()); + mUsabilityTestingMode = SettingsManager::value("usabilityTestingMode").toBool(); + mUi->usabilityModeCheckBox->setChecked(mUsabilityTestingMode); + mUi->touchModeCheckBox->setChecked(SettingsManager::value("touchMode").toBool()); + + showAutoSaveBox(mUi->autoSaveCheckBox->isChecked()); + int const editorsLoadedCount = SettingsManager::value("EditorsLoadedCount").toInt(); + mUi->paletteTabCheckBox->setVisible(editorsLoadedCount != 1); +// mFilterObject.setStatusCollectUsabilityStatistics(mUi->collectErgonomicValuesCheckBox->isChecked()); +} + +void PreferencesBehaviourPage::showAutoSaveBox(bool show) +{ + mUi->autoSaveSpinBox->setVisible(show); + mUi->autoSaveLabel->setVisible(show); +} + +void PreferencesBehaviourPage::initLanguages() +{ + mUi->languageComboBox->addItem(tr("")); + mUi->languageComboBox->addItem("English", "en"); + mUi->languageComboBox->addItem(QString::fromUtf8("Русский"), "ru"); +} diff --git a/configurationServer/gui/preferencesPages/behaviourPage.h b/configurationServer/gui/preferencesPages/behaviourPage.h new file mode 100644 index 0000000..8b7e75a --- /dev/null +++ b/configurationServer/gui/preferencesPages/behaviourPage.h @@ -0,0 +1,37 @@ +#pragma once + +#include "preferencesPages/preferencesPage.h" +//#include "mainwindow/filterObject.h" + +namespace Ui { + class PreferencesBehaviourPage; +} + +class PreferencesBehaviourPage : public PreferencesPage +{ + Q_OBJECT + +public: + explicit PreferencesBehaviourPage(QWidget *parent = 0); + ~PreferencesBehaviourPage() override; + + void save() override; + void restoreSettings() override; + +signals: + void usabilityTestingModeChanged(bool on); + +protected: + void changeEvent(QEvent *e); + +private slots: + void showAutoSaveBox(bool show); + +private: + void initLanguages(); + + Ui::PreferencesBehaviourPage *mUi; +// FilterObject mFilterObject; + bool mUsabilityTestingMode; + QString mOldLanguage; +}; diff --git a/configurationServer/gui/preferencesPages/behaviourPage.ui b/configurationServer/gui/preferencesPages/behaviourPage.ui new file mode 100644 index 0000000..50ce7fb --- /dev/null +++ b/configurationServer/gui/preferencesPages/behaviourPage.ui @@ -0,0 +1,198 @@ + + + PreferencesBehaviourPage + + + + 0 + 0 + 500 + 340 + + + + + 0 + 0 + + + + + + + User Interface + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Language + + + + + + + + + + + + + Automatics + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 100000 + + + 10 + + + + + + + sec + + + + + + + msec + + + + + + + Delay after gesture + + + + + + + Palette tab switching + + + + + + + 1 + + + 10000 + + + 1 + + + 600 + + + + + + + Autosave + + + true + + + + + + + Collect ergonomic values + + + true + + + + + + + Usability testing mode + + + + + + + + + + Touch + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Touch Mode + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/configurationServer/gui/preferencesPages/debuggerPage.cpp b/configurationServer/gui/preferencesPages/debuggerPage.cpp new file mode 100644 index 0000000..7a5f4cb --- /dev/null +++ b/configurationServer/gui/preferencesPages/debuggerPage.cpp @@ -0,0 +1,48 @@ +#include "debuggerPage.h" +#include "ui_debuggerPage.h" + +#include + +using namespace qReal; + +PreferencesDebuggerPage::PreferencesDebuggerPage(QWidget *parent) + : PreferencesPage(parent) + , mUi(new Ui::PreferencesDebuggerPage) + +{ + mIcon = QIcon(":/icons/preferences/bug.png"); + mUi->setupUi(this); + + restoreSettings(); +} + +PreferencesDebuggerPage::~PreferencesDebuggerPage() +{ + delete mUi; +} + +void PreferencesDebuggerPage::changeEvent(QEvent *e) +{ + switch (e->type()) { + case QEvent::LanguageChange: + mUi->retranslateUi(this); + break; + default: + break; + } +} + +void PreferencesDebuggerPage::save() +{ + SettingsManager::setValue("debuggerTimeout", mUi->timeoutLineEdit->text()); + SettingsManager::setValue("debugColor", mUi->colorComboBox->currentText()); +} + +void PreferencesDebuggerPage::restoreSettings() +{ + mUi->timeoutLineEdit->setText(SettingsManager::value("debuggerTimeout").toString()); + mUi->colorComboBox->addItems(QColor::colorNames()); + QString curColor = SettingsManager::value("debugColor").toString(); + int curColorIndex = mUi->colorComboBox->findText(curColor); + mUi->colorComboBox->setCurrentIndex(curColorIndex); +} diff --git a/configurationServer/gui/preferencesPages/debuggerPage.h b/configurationServer/gui/preferencesPages/debuggerPage.h new file mode 100644 index 0000000..7513a42 --- /dev/null +++ b/configurationServer/gui/preferencesPages/debuggerPage.h @@ -0,0 +1,25 @@ +#pragma once + +#include "preferencesPages/preferencesPage.h" + +namespace Ui { + class PreferencesDebuggerPage; +} + +class PreferencesDebuggerPage : public PreferencesPage +{ + Q_OBJECT + +public: + explicit PreferencesDebuggerPage(QWidget *parent = 0); + ~PreferencesDebuggerPage(); + + void save(); + virtual void restoreSettings(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::PreferencesDebuggerPage *mUi; +}; diff --git a/configurationServer/gui/preferencesPages/debuggerPage.ui b/configurationServer/gui/preferencesPages/debuggerPage.ui new file mode 100644 index 0000000..df24ba1 --- /dev/null +++ b/configurationServer/gui/preferencesPages/debuggerPage.ui @@ -0,0 +1,76 @@ + + + PreferencesDebuggerPage + + + + 0 + 0 + 407 + 122 + + + + + 0 + 0 + + + + + + + Presentation + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Debug timeout (ms): + + + + + + + + + + Color of highlighting: + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/configurationServer/gui/preferencesPages/editorPage.cpp b/configurationServer/gui/preferencesPages/editorPage.cpp new file mode 100644 index 0000000..4c17705 --- /dev/null +++ b/configurationServer/gui/preferencesPages/editorPage.cpp @@ -0,0 +1,205 @@ +#include "editorPage.h" +#include "ui_editorPage.h" + +#include + +//#include "mainwindow/mainWindow.h" + +using namespace qReal; +//using namespace enums::linkShape; + +PreferencesEditorPage::PreferencesEditorPage(QAction * const showGridAction, QAction * const showAlignmentAction + , QAction * const activateGridAction, QAction * const activateAlignmentAction, QWidget *parent) + : PreferencesPage(parent) + , mUi(new Ui::PreferencesEditorPage) + , mWidthGrid(SettingsManager::value("GridWidth").toInt()) + , mIndexGrid(SettingsManager::value("IndexGrid").toInt()) + , mFontButtonWasPressed(false) + , mShowGridAction(showGridAction) + , mShowAlignmentAction(showAlignmentAction) + , mActivateGridAction(activateGridAction) + , mActivateAlignmentAction(activateAlignmentAction) +{ + mIcon = QIcon(":/icons/preferences/editor.png"); + mUi->setupUi(this); + + // changing grid size in QReal:Robots is forbidden + connect(mUi->gridWidthSlider, SIGNAL(valueChanged(int)), this, SLOT(widthGridSliderMoved(int))); + connect(mUi->indexGridSlider, SIGNAL(valueChanged(int)), this, SLOT(indexGridSliderMoved(int))); + connect(mUi->dragAreaSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(dragAreaSliderMoved(int))); + connect(mUi->fontCheckBox, SIGNAL(toggled(bool)), this, SLOT(manualFontCheckBoxChecked(bool))); + connect(mUi->fontSelectionButton, SIGNAL(clicked()),this, SLOT(fontSelectionButtonClicked())); + connect(mUi->paletteComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(paletteComboBoxClicked(int))); + + connect(mShowGridAction, SIGNAL(toggled(bool)), this, SLOT(showGrid(bool))); + connect(mShowAlignmentAction, SIGNAL(toggled(bool)), this, SLOT(showAlignment(bool))); + connect(mActivateGridAction, SIGNAL(toggled(bool)), this, SLOT(activateGrid(bool))); + connect(mActivateAlignmentAction, SIGNAL(toggled(bool)), this, SLOT(activateAlignment(bool))); + + // use customizer to blick it somehow +// mUi->indexGridSlider->setVisible(false); +// mUi->label_20->setVisible(false); + + mUi->gridWidthSlider->setValue(mWidthGrid); + mUi->indexGridSlider->setValue(mIndexGrid); + + mDragArea = mUi->dragAreaSizeSlider->value(); + SettingsManager::setValue("DragArea", mDragArea); + restoreSettings(); +} + +PreferencesEditorPage::~PreferencesEditorPage() +{ + SettingsManager::setValue("GridWidth", mWidthGrid); + SettingsManager::setValue("IndexGrid", mIndexGrid); + + delete mUi; +} + +void PreferencesEditorPage::manualFontCheckBoxChecked(bool state) +{ + mUi->fontSelectionButton->setVisible(state); +} + +void PreferencesEditorPage::fontSelectionButtonClicked() +{ + mFontButtonWasPressed = true; + + QFontDialog fontDialog(this); + fontDialog.setModal(true); + QFont font; + font.fromString(mFont); + fontDialog.setCurrentFont(font); + fontDialog.exec(); + mFont = fontDialog.currentFont().toString(); +} + +void PreferencesEditorPage::changeEvent(QEvent *e) +{ + + switch (e->type()) { + case QEvent::LanguageChange: + mUi->retranslateUi(this); + break; + default: + break; + } +} + +void PreferencesEditorPage::widthGridSliderMoved(int value) +{ + SettingsManager::setValue("GridWidth", value); + emit gridChanged(); +} + +void PreferencesEditorPage::indexGridSliderMoved(int value) +{ + SettingsManager::setValue("IndexGrid", value); + emit gridChanged(); +} + +void PreferencesEditorPage::dragAreaSliderMoved(int value) +{ + SettingsManager::setValue("DragArea", value); +} + +void PreferencesEditorPage::save() +{ + SettingsManager::setValue("EmbeddedLinkerIndent", mUi->embeddedLinkerIndentSlider->value()); + SettingsManager::setValue("EmbeddedLinkerSize", mUi->embeddedLinkerSizeSlider->value()); + SettingsManager::setValue("LineType", mUi->lineMode->currentIndex() - 1); + SettingsManager::setValue("LoopEdgeBoundsIndent", mUi->loopEdgeBoundsIndent->value()); + SettingsManager::setValue("ShowGrid", mUi->showGridCheckBox->isChecked()); + SettingsManager::setValue("ShowAlignment", mUi->showAlignmentCheckBox->isChecked()); + SettingsManager::setValue("ActivateGrid", mUi->activateGridCheckBox->isChecked()); + SettingsManager::setValue("ActivateAlignment", mUi->activateAlignmentCheckBox->isChecked()); + SettingsManager::setValue("CustomFont", mUi->fontCheckBox->isChecked()); + SettingsManager::setValue("PaletteRepresentation", mUi->paletteComboBox->currentIndex()); + SettingsManager::setValue("PaletteIconsInARowCount", mUi->paletteSpinBox->value()); + SettingsManager::setValue("MoveLabels", mUi->enableMoveLabelsCheckBox->isChecked()); + SettingsManager::setValue("ResizeLabels", mUi->enableResizeLabelsCheckBox->isChecked()); + SettingsManager::setValue("LabelsDistance", mUi->labelDistanceSlider->value()); + SettingsManager::setValue("manualFontCheckBoxChecked", mUi->fontCheckBox->isChecked()); + + emit paletteRepresentationChanged(); + + mWidthGrid = mUi->gridWidthSlider->value(); + mIndexGrid = mUi->indexGridSlider->value(); + mDragArea = mUi->dragAreaSizeSlider->value(); + SettingsManager::setValue("GridWidth", mWidthGrid); + SettingsManager::setValue("IndexGrid", mIndexGrid); + SettingsManager::setValue("DragArea", mDragArea); + + mShowGridAction->setChecked(mUi->showGridCheckBox->isChecked()); + mShowAlignmentAction->setChecked(mUi->showAlignmentCheckBox->isChecked()); + mActivateGridAction->setChecked(mUi->activateGridCheckBox->isChecked()); + mActivateAlignmentAction->setChecked(mUi->activateAlignmentCheckBox->isChecked()); + + if (mWasChecked != mUi->fontCheckBox->isChecked() || mOldFont != mFont) { + if (mFontButtonWasPressed) { + SettingsManager::setValue("CurrentFont", mFont); + } + + setRestartFlag(); + mFontButtonWasPressed = false; + } +} + +void PreferencesEditorPage::restoreSettings() +{ + mUi->showGridCheckBox->setChecked(SettingsManager::value("ShowGrid").toBool()); + mUi->showAlignmentCheckBox->setChecked(SettingsManager::value("ShowAlignment").toBool()); + mUi->activateGridCheckBox->setChecked(SettingsManager::value("ActivateGrid").toBool()); + mUi->activateAlignmentCheckBox->setChecked(SettingsManager::value("ActivateAlignment").toBool()); + mUi->embeddedLinkerIndentSlider->setValue(SettingsManager::value("EmbeddedLinkerIndent").toInt()); + mUi->embeddedLinkerSizeSlider->setValue(SettingsManager::value("EmbeddedLinkerSize").toInt()); + mUi->loopEdgeBoundsIndent->setValue(SettingsManager::value("LoopEdgeBoundsIndent").toInt()); + + mUi->enableMoveLabelsCheckBox->setChecked(SettingsManager::value("MoveLabels").toBool()); + mUi->enableResizeLabelsCheckBox->setChecked(SettingsManager::value("ResizeLabels").toBool()); + mUi->labelDistanceSlider->setValue(SettingsManager::value("LabelsDistance").toInt()); + +// LinkShape const type = static_cast(SettingsManager::value("LineType", unset).toInt()); +// mUi->lineMode->setCurrentIndex(type + 1); + + mUi->fontCheckBox->setChecked(SettingsManager::value("CustomFont").toBool()); + mUi->fontSelectionButton->setVisible(mUi->fontCheckBox->isChecked()); + mWasChecked = mUi->fontCheckBox->isChecked(); + + mUi->paletteComboBox->setCurrentIndex(SettingsManager::value("PaletteRepresentation").toInt()); + paletteComboBoxClicked(mUi->paletteComboBox->currentIndex()); + mUi->paletteSpinBox->setValue(SettingsManager::value("PaletteIconsInARowCount").toInt()); + mFont = SettingsManager::value("CurrentFont").toString(); + mOldFont = mFont; +} + +void PreferencesEditorPage::paletteComboBoxClicked(int index) +{ + mUi->paletteSpinBox->setEnabled((bool)index); +} + +void PreferencesEditorPage::changePaletteParameters() +{ + mUi->paletteComboBox->setCurrentIndex(SettingsManager::value("PaletteRepresentation").toInt()); + mUi->paletteSpinBox->setValue(SettingsManager::value("PaletteIconsInARowCount").toInt()); +} + +void PreferencesEditorPage::showGrid(bool show) +{ + mUi->showGridCheckBox->setChecked(show); +} + +void PreferencesEditorPage::showAlignment(bool show) +{ + mUi->showAlignmentCheckBox->setChecked(show); +} + +void PreferencesEditorPage::activateGrid(bool activate) +{ + mUi->activateGridCheckBox->setChecked(activate); +} + +void PreferencesEditorPage::activateAlignment(bool activate) +{ + mUi->activateAlignmentCheckBox->setChecked(activate); +} diff --git a/configurationServer/gui/preferencesPages/editorPage.h b/configurationServer/gui/preferencesPages/editorPage.h new file mode 100644 index 0000000..a677078 --- /dev/null +++ b/configurationServer/gui/preferencesPages/editorPage.h @@ -0,0 +1,61 @@ +#pragma once + +#include + +#include "preferencesPages/preferencesPage.h" + +namespace Ui { + class PreferencesEditorPage; +} + +class PreferencesEditorPage : public PreferencesPage +{ + Q_OBJECT + +public: + explicit PreferencesEditorPage(QAction * const showGridAction, QAction * const showAlignmentAction + ,QAction * const activateGridAction, QAction * const activateAlignmentAction, QWidget *parent = 0); + ~PreferencesEditorPage(); + + /// Sets value to palette combo box and spin box respectively/ + void changePaletteParameters(); + void save(); + virtual void restoreSettings(); + +protected: + void changeEvent(QEvent *e); + +signals: + void gridChanged(); + void fontChanged(); + void paletteRepresentationChanged(); + +private slots: + void widthGridSliderMoved(int value); + void indexGridSliderMoved(int value); + void dragAreaSliderMoved(int value); + void manualFontCheckBoxChecked(bool); + void fontSelectionButtonClicked(); + void paletteComboBoxClicked(int index); + + void showGrid(bool); + void showAlignment(bool); + void activateGrid(bool); + void activateAlignment(bool); + +private: + Ui::PreferencesEditorPage *mUi; + int mWidthGrid; + int mIndexGrid; + int mDragArea; + QString mFont; + + bool mFontButtonWasPressed; + bool mWasChecked; + QString mOldFont; + + QAction * const mShowGridAction; + QAction * const mShowAlignmentAction; + QAction * const mActivateGridAction; + QAction * const mActivateAlignmentAction; +}; diff --git a/configurationServer/gui/preferencesPages/editorPage.ui b/configurationServer/gui/preferencesPages/editorPage.ui new file mode 100644 index 0000000..7b7c7b5 --- /dev/null +++ b/configurationServer/gui/preferencesPages/editorPage.ui @@ -0,0 +1,687 @@ + + + PreferencesEditorPage + + + + 0 + 0 + 500 + 638 + + + + + 0 + 0 + + + + + 50 + 50 + + + + + 16777215 + 16777215 + + + + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 480 + 782 + + + + + + + Font + + + + + + + + 0 + 0 + + + + + 0 + 40 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + true + + + + 0 + 0 + + + + Use some of system fonts + + + + + + + + 0 + 0 + + + + Choose Font + + + + + + + + + + Grid + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + 0 + + + + 3 + + + 150 + + + 1 + + + 10 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + Activate alignment + + + true + + + + + + + Cell size + + + + + + + + 0 + 0 + + + + Activate grid + + + false + + + + + + + Width + + + + + + + Show grid + + + true + + + + + + + + 130 + 0 + + + + Show alignment + + + true + + + + + + + + 0 + 0 + + + + 5 + + + 150 + + + 1 + + + 10 + + + 50 + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Node Elements + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 4 + + + 20 + + + 12 + + + Qt::Horizontal + + + + + + + Drag area + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 70 + 0 + 160 + 21 + + + + Qt::Horizontal + + + + + + + + Edge + + + + + + + + 0 + 30 + + + + + 50 + 60 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 20 + + + + + unset + + + + + broken + + + + + square + + + + + curve + + + + + + + + Line mode + + + + + + + + 0 + 0 + + + + Loop edges indent + + + + + + + + 0 + 0 + + + + 1 + + + 15 + + + 2 + + + 2 + + + 2 + + + Qt::Horizontal + + + + + + + + + + Embedded Linkers + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 4 + + + 20 + + + Qt::Horizontal + + + + + + + 5 + + + 20 + + + Qt::Horizontal + + + + + + + Size + + + + + + + Indent + + + + + + + + + + Labels + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Enable move + + + true + + + + + + + Enable resize + + + true + + + + + + + Label distance + + + + + + + 500 + + + Qt::Horizontal + + + + + + + + + + Palette + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Representation + + + + + + + Count of items in a row + + + + + + + Qt::LeftToRight + + + false + + + 1 + + + true + + + + Icons and names + + + + + Icons + + + + + + + + 1 + + + 5 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + diff --git a/configurationServer/gui/preferencesPages/featuresPage.cpp b/configurationServer/gui/preferencesPages/featuresPage.cpp new file mode 100644 index 0000000..91ee78e --- /dev/null +++ b/configurationServer/gui/preferencesPages/featuresPage.cpp @@ -0,0 +1,46 @@ +#include "featuresPage.h" +#include "ui_featuresPage.h" + +#include + +using namespace qReal; + +PreferencesFeaturesPage::PreferencesFeaturesPage(QWidget *parent) + : PreferencesPage(parent) + , mUi(new Ui::PreferencesFeaturesPage) +{ + mIcon = QIcon(":/icons/preferences/features.png"); + mUi->setupUi(this); + + restoreSettings(); +} + +PreferencesFeaturesPage::~PreferencesFeaturesPage() +{ + delete mUi; +} + +void PreferencesFeaturesPage::changeEvent(QEvent *e) +{ + switch (e->type()) { + case QEvent::LanguageChange: + mUi->retranslateUi(this); + break; + default: + break; + } +} + +void PreferencesFeaturesPage::save() +{ + SettingsManager::setValue("Gestures", mUi->gesturesCheckBox->isChecked()); + SettingsManager::setValue("EmbeddedLinkers", mUi->embeddedLinkersCheckBox->isChecked()); + SettingsManager::setValue("EmbeddedControls", mUi->embeddedControlsCheckBox->isChecked()); +} + +void PreferencesFeaturesPage::restoreSettings() +{ + mUi->gesturesCheckBox->setChecked(SettingsManager::value("Gestures").toBool()); + mUi->embeddedLinkersCheckBox->setChecked(SettingsManager::value("EmbeddedLinkers").toBool()); + mUi->embeddedControlsCheckBox->setChecked(SettingsManager::value("EmbeddedControls").toBool()); +} diff --git a/configurationServer/gui/preferencesPages/featuresPage.h b/configurationServer/gui/preferencesPages/featuresPage.h new file mode 100644 index 0000000..5f68fa4 --- /dev/null +++ b/configurationServer/gui/preferencesPages/featuresPage.h @@ -0,0 +1,25 @@ +#pragma once + +#include "preferencesPages/preferencesPage.h" + +namespace Ui { + class PreferencesFeaturesPage; +} + +class PreferencesFeaturesPage : public PreferencesPage +{ + Q_OBJECT + +public: + explicit PreferencesFeaturesPage(QWidget *parent = 0); + ~PreferencesFeaturesPage(); + + void save(); + virtual void restoreSettings(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::PreferencesFeaturesPage *mUi; +}; diff --git a/configurationServer/gui/preferencesPages/featuresPage.ui b/configurationServer/gui/preferencesPages/featuresPage.ui new file mode 100644 index 0000000..1b9336e --- /dev/null +++ b/configurationServer/gui/preferencesPages/featuresPage.ui @@ -0,0 +1,98 @@ + + + PreferencesFeaturesPage + + + + 0 + 0 + 500 + 300 + + + + + 0 + 0 + + + + + + + Element controls + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Gestures + + + + + + + fast linking with mouse + + + + + + + fast linking with mouse + + + + + + + Embedded Linkers + + + + + + + fast property editing + + + + + + + Embedded Controls + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/configurationServer/gui/preferencesPages/miscellaniousPage.cpp b/configurationServer/gui/preferencesPages/miscellaniousPage.cpp new file mode 100644 index 0000000..2c83e44 --- /dev/null +++ b/configurationServer/gui/preferencesPages/miscellaniousPage.cpp @@ -0,0 +1,81 @@ +#include "miscellaniousPage.h" +#include "ui_miscellaniousPage.h" + +#include +#include + +using namespace qReal; + +PreferencesMiscellaniousPage::PreferencesMiscellaniousPage(QWidget *parent) + : PreferencesPage(parent) + , mUi(new Ui::PreferencesMiscellaniousPage) +{ + mIcon = QIcon(":/icons/preferences/miscellaneous.png"); + mUi->setupUi(this); + + connect(mUi->imagesPathBrowseButton, SIGNAL(clicked()), this, SLOT(browseImagesPath())); + connect(mUi->toolbarSizeSlider, &QSlider::valueChanged, this, &PreferencesMiscellaniousPage::toolbarSizeChanged); + + mUi->colorComboBox->addItems(QColor::colorNames()); + + restoreSettings(); +} + +PreferencesMiscellaniousPage::~PreferencesMiscellaniousPage() +{ + delete mUi; +} + +void PreferencesMiscellaniousPage::changeEvent(QEvent *e) +{ + switch (e->type()) { + case QEvent::LanguageChange: + mUi->retranslateUi(this); + break; + default: + break; + } +} + +void PreferencesMiscellaniousPage::browseImagesPath() +{ + QString const path = utils::QRealFileDialog::getExistingDirectory("OpenImagesOnMiscellaniousPage" + , this, tr("Open Directory")).replace("\\", "/"); + if (!path.isEmpty()) { + mUi->imagesPathEdit->setText(path); + } +} + +void PreferencesMiscellaniousPage::save() +{ + SettingsManager::setValue("Splashscreen", mUi->splashScreenCheckBox->isChecked()); + SettingsManager::setValue("Antialiasing", mUi->antialiasingCheckBox->isChecked()); + + SettingsManager::setValue("pathToImages", mUi->imagesPathEdit->text()); + SettingsManager::setValue("recentProjectsLimit", mUi->recentProjectsLimitSpinBox->value()); + SettingsManager::setValue("PaintOldEdgeMode", mUi->paintOldLineCheckBox->isChecked()); + SettingsManager::setValue("oldLineColor", mUi->colorComboBox->currentText()); + + SettingsManager::setValue("toolbarSize", mUi->toolbarSizeSlider->value()); + + if (mLastIconsetPath != mUi->imagesPathEdit->text()) { + emit iconsetChanged(); + } +} + +void PreferencesMiscellaniousPage::restoreSettings() +{ + mUi->antialiasingCheckBox->setChecked(SettingsManager::value("Antialiasing").toBool()); + mUi->splashScreenCheckBox->setChecked(SettingsManager::value("Splashscreen").toBool()); + + mUi->paintOldLineCheckBox->setChecked(SettingsManager::value("PaintOldEdgeMode").toBool()); + + QString curColor = SettingsManager::value("oldLineColor").toString(); + int curColorIndex = mUi->colorComboBox->findText(curColor); + mUi->colorComboBox->setCurrentIndex(curColorIndex); + + mUi->toolbarSizeSlider->setValue(SettingsManager::value("toolbarSize").toInt()); + + mLastIconsetPath = SettingsManager::value("pathToImages").toString(); + mUi->imagesPathEdit->setText(mLastIconsetPath); +} diff --git a/configurationServer/gui/preferencesPages/miscellaniousPage.h b/configurationServer/gui/preferencesPages/miscellaniousPage.h new file mode 100644 index 0000000..1db0727 --- /dev/null +++ b/configurationServer/gui/preferencesPages/miscellaniousPage.h @@ -0,0 +1,34 @@ +#pragma once + +#include "preferencesPages/preferencesPage.h" + +namespace Ui { + class PreferencesMiscellaniousPage; +} + +class PreferencesMiscellaniousPage : public PreferencesPage +{ + Q_OBJECT + +public: + explicit PreferencesMiscellaniousPage(QWidget *parent = 0); + ~PreferencesMiscellaniousPage(); + + void save(); + virtual void restoreSettings(); + +signals: + void iconsetChanged(); + void toolbarSizeChanged(int size); + +protected: + void changeEvent(QEvent *e); + +private slots: + void browseImagesPath(); + +private: + Ui::PreferencesMiscellaniousPage *mUi; + + QString mLastIconsetPath; +}; diff --git a/configurationServer/gui/preferencesPages/miscellaniousPage.ui b/configurationServer/gui/preferencesPages/miscellaniousPage.ui new file mode 100644 index 0000000..af08387 --- /dev/null +++ b/configurationServer/gui/preferencesPages/miscellaniousPage.ui @@ -0,0 +1,267 @@ + + + PreferencesMiscellaniousPage + + + + 0 + 0 + 561 + 325 + + + + + 0 + 0 + + + + + + + Graphics + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Antialiasing + + + + + + + + + + Other + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Show splashscreen + + + + + + + Color of old line: + + + + + + + + 170 + 0 + + + + true + + + + + + + true + + + Paint the old line + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + 5 + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Limit recent projects list + + + true + + + + + + + + 0 + 0 + + + + + 40 + 16777215 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + + + + + + Images + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Browse + + + + + + + + + + + + + Toolbars + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Size + + + + + + + 20 + + + 50 + + + Qt::Horizontal + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/configurationServer/gui/preferencesPages/preferencesPage.h b/configurationServer/gui/preferencesPages/preferencesPage.h new file mode 100644 index 0000000..b7fb03e --- /dev/null +++ b/configurationServer/gui/preferencesPages/preferencesPage.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +/// Abstract class for preferences page +class PreferencesPage : public QWidget +{ + Q_OBJECT + + /// @todo friend to be able to call protected changeEvent() method. It seems to be bad idea. + friend class PreferencesDialog; + +public: + explicit PreferencesPage(QWidget *parent = 0) + : QWidget(parent) + , mShouldRestartSystemToApply(false) + { + } + + virtual ~PreferencesPage() + { + } + + /// This method will be called on pressing "Apply" or "Ok" + virtual void save() = 0; + + /// This method will be called before page is shown and when user pressed "Cancel" + virtual void restoreSettings() = 0; + + /// This method will be called when need to get icon on label in form + virtual QIcon getIcon() const + { + return mIcon; + } + +protected: + /// Indicates the system to prompt system restart after settings applying. + void setRestartFlag() + { + mShouldRestartSystemToApply = true; + } + + /// An icon to be shown near this tab in preferences window + QIcon mIcon; + +private: + /// If this flag is set to true then system restart will be prompted after settings applying. + bool mShouldRestartSystemToApply; +}; diff --git a/configurationServer/gui/qrkernel/Makefile b/configurationServer/gui/qrkernel/Makefile new file mode 100644 index 0000000..6758694 --- /dev/null +++ b/configurationServer/gui/qrkernel/Makefile @@ -0,0 +1,311 @@ +############################################################################# +# Makefile for building: qrkernel +# Generated by qmake (3.0) (Qt 5.2.1) +# Project: qrkernel.pro +# Template: lib +# Command: C:\Qt\5.2.1\mingw48_32\bin\qmake.exe -spec win32-g++ CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug -o Makefile qrkernel.pro +############################################################################# + +MAKEFILE = Makefile + +first: debug +install: debug-install +uninstall: debug-uninstall +QMAKE = C:\Qt\5.2.1\mingw48_32\bin\qmake.exe +DEL_FILE = del +CHK_DIR_EXISTS= if not exist +MKDIR = mkdir +COPY = copy /y +COPY_FILE = $(COPY) +COPY_DIR = xcopy /s /q /y /i +INSTALL_FILE = $(COPY_FILE) +INSTALL_PROGRAM = $(COPY_FILE) +INSTALL_DIR = $(COPY_DIR) +DEL_FILE = del +SYMLINK = copy /y +DEL_DIR = rmdir +MOVE = move +SUBTARGETS = \ + debug \ + release + + +debug: FORCE + $(MAKE) -f $(MAKEFILE).Debug +debug-make_first: FORCE + $(MAKE) -f $(MAKEFILE).Debug +debug-all: FORCE + $(MAKE) -f $(MAKEFILE).Debug all +debug-clean: FORCE + $(MAKE) -f $(MAKEFILE).Debug clean +debug-distclean: FORCE + $(MAKE) -f $(MAKEFILE).Debug distclean +debug-install: FORCE + $(MAKE) -f $(MAKEFILE).Debug install +debug-uninstall: FORCE + $(MAKE) -f $(MAKEFILE).Debug uninstall +release: FORCE + $(MAKE) -f $(MAKEFILE).Release +release-make_first: FORCE + $(MAKE) -f $(MAKEFILE).Release +release-all: FORCE + $(MAKE) -f $(MAKEFILE).Release all +release-clean: FORCE + $(MAKE) -f $(MAKEFILE).Release clean +release-distclean: FORCE + $(MAKE) -f $(MAKEFILE).Release distclean +release-install: FORCE + $(MAKE) -f $(MAKEFILE).Release install +release-uninstall: FORCE + $(MAKE) -f $(MAKEFILE).Release uninstall + +Makefile: qrkernel.pro C:/Qt/5.2.1/mingw48_32/mkspecs/win32-g++/qmake.conf C:/Qt/5.2.1/mingw48_32/mkspecs/features/spec_pre.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/qdevice.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/device_config.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/common/shell-win32.conf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/qconfig.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_axbase.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_axbase_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_axcontainer.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_axcontainer_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_axserver.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_axserver_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_bluetooth.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_bluetooth_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_bootstrap_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_clucene_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_concurrent.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_concurrent_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_core.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_core_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_declarative.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_declarative_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_designer.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_designer_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_designercomponents_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_gui.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_gui_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_help.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_help_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_multimedia.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_multimedia_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_multimediawidgets.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_multimediawidgets_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_network.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_network_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_nfc.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_nfc_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_opengl.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_opengl_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_openglextensions.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_openglextensions_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_platformsupport_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_positioning.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_positioning_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_printsupport.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_printsupport_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_qml.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_qml_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_qmldevtools_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_qmltest.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_qmltest_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_qtmultimediaquicktools_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_quick.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_quick_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_quickparticles_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_script.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_script_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_scripttools.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_scripttools_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_sensors.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_sensors_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_serialport.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_serialport_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_sql.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_sql_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_svg.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_svg_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_testlib.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_testlib_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_uitools.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_uitools_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_webkit.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_webkit_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_webkitwidgets.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_webkitwidgets_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_widgets.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_widgets_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_winextras.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_winextras_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_xml.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_xml_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_xmlpatterns.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/modules/qt_lib_xmlpatterns_private.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/qt_functions.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/qt_config.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/win32-g++/qmake.conf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/spec_post.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/exclusive_builds.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/default_pre.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/win32/default_pre.prf \ + qrkernel.pri \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/resolve_config.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/exclusive_builds_post.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/default_post.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/c++11.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/qml_debug.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/declarative_debug.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/win32/rtti.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/warn_on.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/qt.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/resources.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/moc.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/win32/opengl.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/win32/windows.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/testcase_targets.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/exceptions.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/yacc.prf \ + C:/Qt/5.2.1/mingw48_32/mkspecs/features/lex.prf \ + qrkernel.pro \ + C:/Qt/5.2.1/mingw48_32/lib/Qt5Gui.prl \ + C:/Qt/5.2.1/mingw48_32/lib/Qt5Core.prl + $(QMAKE) -spec win32-g++ CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug -o Makefile qrkernel.pro +C:\Qt\5.2.1\mingw48_32\mkspecs\features\spec_pre.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\qdevice.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\device_config.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\common\shell-win32.conf: +C:\Qt\5.2.1\mingw48_32\mkspecs\qconfig.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_axbase.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_axbase_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_axcontainer.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_axcontainer_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_axserver.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_axserver_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_bluetooth.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_bluetooth_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_bootstrap_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_clucene_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_concurrent.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_concurrent_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_core.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_core_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_declarative.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_declarative_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_designer.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_designer_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_designercomponents_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_gui.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_gui_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_help.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_help_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_multimedia.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_multimedia_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_multimediawidgets.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_multimediawidgets_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_network.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_network_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_nfc.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_nfc_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_opengl.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_opengl_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_openglextensions.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_openglextensions_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_platformsupport_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_positioning.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_positioning_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_printsupport.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_printsupport_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_qml.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_qml_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_qmldevtools_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_qmltest.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_qmltest_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_qtmultimediaquicktools_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_quick.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_quick_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_quickparticles_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_script.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_script_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_scripttools.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_scripttools_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_sensors.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_sensors_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_serialport.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_serialport_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_sql.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_sql_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_svg.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_svg_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_testlib.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_testlib_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_uitools.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_uitools_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_webkit.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_webkit_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_webkitwidgets.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_webkitwidgets_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_widgets.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_widgets_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_winextras.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_winextras_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_xml.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_xml_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_xmlpatterns.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\modules\qt_lib_xmlpatterns_private.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\qt_functions.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\qt_config.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\win32-g++\qmake.conf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\spec_post.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\exclusive_builds.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\default_pre.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\win32\default_pre.prf: +qrkernel.pri: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\resolve_config.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\exclusive_builds_post.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\default_post.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\c++11.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\qml_debug.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\declarative_debug.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\win32\rtti.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\warn_on.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\qt.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\resources.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\moc.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\win32\opengl.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\win32\windows.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\testcase_targets.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\exceptions.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\yacc.prf: +C:\Qt\5.2.1\mingw48_32\mkspecs\features\lex.prf: +qrkernel.pro: +C:/Qt/5.2.1/mingw48_32/lib/Qt5Gui.prl: +C:/Qt/5.2.1/mingw48_32/lib/Qt5Core.prl: +qmake: FORCE + @$(QMAKE) -spec win32-g++ CONFIG+=debug CONFIG+=declarative_debug CONFIG+=qml_debug -o Makefile qrkernel.pro + +qmake_all: FORCE + +make_first: debug-make_first release-make_first FORCE +all: debug-all release-all FORCE +clean: debug-clean release-clean FORCE + -$(DEL_FILE) ..\bin\libqrkernel.a +distclean: debug-distclean release-distclean FORCE + -$(DEL_FILE) Makefile + +debug-mocclean: + $(MAKE) -f $(MAKEFILE).Debug mocclean +release-mocclean: + $(MAKE) -f $(MAKEFILE).Release mocclean +mocclean: debug-mocclean release-mocclean + +debug-mocables: + $(MAKE) -f $(MAKEFILE).Debug mocables +release-mocables: + $(MAKE) -f $(MAKEFILE).Release mocables +mocables: debug-mocables release-mocables + +check: first +FORCE: + +$(MAKEFILE).Debug: Makefile +$(MAKEFILE).Release: Makefile diff --git a/configurationServer/gui/qrkernel/definitions.h b/configurationServer/gui/qrkernel/definitions.h new file mode 100644 index 0000000..fa71685 --- /dev/null +++ b/configurationServer/gui/qrkernel/definitions.h @@ -0,0 +1,14 @@ +#pragma once + +#include "ids.h" +#include "roles.h" + +namespace qReal { + +/// Separator used in situations where there is need to form path consisting of multiple Ids. +const char ID_PATH_DIVIDER = '#'; + +/// MIME type for drag-and-drop operations inside QReal +QString const DEFAULT_MIME_TYPE = "application/x-real-uml-data"; + +} diff --git a/configurationServer/gui/qrkernel/exception/exception.cpp b/configurationServer/gui/qrkernel/exception/exception.cpp new file mode 100644 index 0000000..5cbd91f --- /dev/null +++ b/configurationServer/gui/qrkernel/exception/exception.cpp @@ -0,0 +1,16 @@ +#include "exception.h" + +#include + +using namespace qReal; + +Exception::Exception(QString const &message) + : mMessage(message) +{ + qDebug() << "QReal exception: " << message; +} + +QString Exception::message() const +{ + return mMessage; +} diff --git a/configurationServer/gui/qrkernel/exception/exception.h b/configurationServer/gui/qrkernel/exception/exception.h new file mode 100644 index 0000000..662c4a5 --- /dev/null +++ b/configurationServer/gui/qrkernel/exception/exception.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "qrkernel/kernelDeclSpec.h" + +namespace qReal { + +/// Base class for all QReal exceptions. Thrown when "something is wrong" +/// in QReal code. +class QRKERNEL_EXPORT Exception +{ +public: + /// Constructor. + /// @param message Error message. + explicit Exception(QString const &message); + + /// Get error message. + QString message() const; + +private: + /// Error message. + QString const mMessage; +}; + +} diff --git a/configurationServer/gui/qrkernel/ids.cpp b/configurationServer/gui/qrkernel/ids.cpp new file mode 100644 index 0000000..e73cba9 --- /dev/null +++ b/configurationServer/gui/qrkernel/ids.cpp @@ -0,0 +1,195 @@ +#include "ids.h" + +#include +#include + +using namespace qReal; + +Id Id::loadFromString(QString const &string) +{ + QStringList const path = string.split('/'); + Q_ASSERT(path.count() > 0 && path.count() <= 5); + Q_ASSERT(path[0] == "qrm:"); + + Id result; + switch (path.count()) { + case 5: result.mId = path[4]; + // Fall-thru + case 4: result.mElement = path[3]; + // Fall-thru + case 3: result.mDiagram = path[2]; + // Fall-thru + case 2: result.mEditor = path[1]; + // Fall-thru + } + Q_ASSERT(string == result.toString()); + return result; +} + +Id Id::createElementId(QString const &editor, QString const &diagram, QString const &element) +{ + return Id(editor, diagram, element, QUuid::createUuid().toString()); +} + +Id Id::rootId() +{ + return Id("ROOT_ID", "ROOT_ID", "ROOT_ID", "ROOT_ID"); +} + +Id::Id(QString const &editor, QString const &diagram, QString const &element, QString const &id) + : mEditor(editor) + , mDiagram(diagram) + , mElement(element) + , mId(id) +{ + Q_ASSERT(checkIntegrity()); +} + +Id::Id(Id const &base, QString const &additional) + : mEditor(base.mEditor) + , mDiagram(base.mDiagram) + , mElement(base.mElement) + , mId(base.mId) +{ + unsigned const baseSize = base.idSize(); + switch (baseSize) { + case 0: + mEditor = additional; + break; + case 1: + mDiagram = additional; + break; + case 2: + mElement = additional; + break; + case 3: + mId = additional; + break; + default: + Q_ASSERT(!"Can not add a part to Id, it will be too long"); + } + Q_ASSERT(checkIntegrity()); +} + +bool Id::isNull() const +{ + return mEditor.isEmpty() && mDiagram.isEmpty() + && mElement.isEmpty() && mId.isEmpty(); +} + +QString Id::editor() const +{ + return mEditor; +} + +QString Id::diagram() const +{ + return mDiagram; +} + +QString Id::element() const +{ + return mElement; +} + +QString Id::id() const +{ + return mId; +} + +Id Id::type() const +{ + return Id(mEditor, mDiagram, mElement); +} + +Id Id::sameTypeId() const +{ + return Id(mEditor, mDiagram, mElement, QUuid::createUuid().toString()); +} + +unsigned Id::idSize() const +{ + if (!mId.isEmpty()) { + return 4; + } if (!mElement.isEmpty()) { + return 3; + } if (!mDiagram.isEmpty()) { + return 2; + } if (!mEditor.isEmpty()) { + return 1; + } + return 0; +} + +QUrl Id::toUrl() const +{ + return QUrl(toString()); +} + +QString Id::toString() const +{ + QString path = "qrm:/" + mEditor; + if (mDiagram != "") { + path += "/" + mDiagram; + } if (mElement != "") { + path += "/" + mElement; + } if (mId != "") { + path += "/" + mId; + } + return path; +} + +bool Id::checkIntegrity() const +{ + bool emptyPartsAllowed = true; + + if (!mId.isEmpty()) { + emptyPartsAllowed = false; + } + + if (!mElement.isEmpty()) { + emptyPartsAllowed = false; + } else if (!emptyPartsAllowed) { + return false; + } + + if (!mDiagram.isEmpty()) { + emptyPartsAllowed = false; + } else if (!emptyPartsAllowed) { + return false; + } + + if (mEditor.isEmpty() && !emptyPartsAllowed) { + return false; + } + + return true; +} + +QVariant Id::toVariant() const +{ + QVariant result; + result.setValue(*this); + return result; +} + +QVariant IdListHelper::toVariant(IdList const &list) +{ + QVariant v; + v.setValue(list); + return v; +} + +QDataStream& operator<< (QDataStream &out, Id const &id) +{ + out << id.toString(); + return out; +} + +QDataStream& operator>> (QDataStream &in, Id &id) +{ + QString idString; + in >> idString; + id = Id::loadFromString(idString); + return in; +} diff --git a/configurationServer/gui/qrkernel/ids.h b/configurationServer/gui/qrkernel/ids.h new file mode 100644 index 0000000..d5ca167 --- /dev/null +++ b/configurationServer/gui/qrkernel/ids.h @@ -0,0 +1,150 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "kernelDeclSpec.h" + +namespace qReal { + +/// Identifier of model element or element type. Consists of four parts --- +/// editor (metamodel to which our element belongs to), diagram in that editor +/// (a tab in palette where this element will appear), element (type of +/// an element, actually), id (id of an element). +class QRKERNEL_EXPORT Id +{ +public: + /// Loads Id from string in format "qrm:////". + /// @param string A string from which we must load Id. + /// @returns Loaded Id. + static Id loadFromString(QString const &string); + + /// Creates element Id, assigning to its first three parts values passed as + /// parameters and generating new GUID for "id" part. + /// @param editor Editor name of an element (its metamodel). + /// @param diagram Diagram name of an element (tab in a palette). + /// @param element Type name of an element ("Class", for example). + /// @returns Created element Id. + static Id createElementId(QString const &editor, QString const &diagram, QString const &element); + + /// Root Id for a model tree stored in repository. + /// @returns Root id. + static Id rootId(); + + /// Constructor. Takes all four parts of an Id as optional parameters. + /// @param editor Editor part of an Id (metamodel name). + /// @param diagram Diagram part of an Id (palette tab name). + /// @param element Element part of an Id (element type name). + /// @param id Id part of an, mm, Id. Represents identity of a model element. + explicit Id(QString const &editor = "", QString const &diagram = "" + , QString const &element = "", QString const &id = ""); + + /// Convenience constructor, creates Id by given base Id adding new part as + /// a next section. For example, by given editor Id and diagram name + /// constructs diagram Id. + /// @param base Id that will be extended. + /// @param additional Part of Id that will be added to base Id. + Id(Id const &base, QString const &additional); + + /// Returns true if this id is an empty one (same as == Id()) + bool isNull() const; + + /// Converts Id to URI in format "qrm:////". + QUrl toUrl() const; + + /// Returns unique part of an Id. + QString id() const; + + /// Returns editor (metamodel) part of an Id. + QString editor() const; + + /// Returns diagram (palette tab) part of an Id. + QString diagram() const; + + /// Returns element (type) part of an Id. + QString element() const; + + /// Converts Id to string in format "qrm:////". + QString toString() const; + + /// Returns number of parts Id has. + unsigned idSize() const; + + /// Applicable only to element's Ids. Returns type's Id. + Id type() const; + + /// Creates Id of the same type as given Id. + Id sameTypeId() const; + + /// Cast to QVariant. Not an operator, to avoid problems with autocasts. + QVariant toVariant() const; + + // default destructor and copy constuctor are OK +private: + /// Used only for debug. Checks that Id is correct. + bool checkIntegrity() const; + + QString mEditor; + QString mDiagram; + QString mElement; + QString mId; +}; + +/// Id equality operator. Ids are equal when all their parts are equal. +inline bool operator==(Id const &i1, Id const &i2) +{ + return i1.editor() == i2.editor() + && i1.diagram() == i2.diagram() + && i1.element() == i2.element() + && i1.id() == i2.id(); +} + +/// Id inequality operator. +inline bool operator!=(Id const &i1, Id const &i2) +{ + return !(i1 == i2); +} + +/// Comparison operator for using Id in maps +inline bool operator<(Id const &i1, Id const &i2) +{ + return i1.toString() < i2.toString(); +} + +/// Hash function for Id for using it in QHash. +inline uint qHash(Id const &key) +{ + return qHash(key.editor()) ^ qHash(key.diagram()) ^ qHash(key.element()) + ^ qHash(key.id()); +} + +/// Operator for printing Id in QDebug. +inline QDebug operator<<(QDebug dbg, Id const &id) +{ + dbg << id.toString(); + return dbg.space(); +} + +/// Convenience typedef for list of Ids. +typedef QList IdList; + +/// Static class with convenience functions for Id lists. +class QRKERNEL_EXPORT IdListHelper { +public: + static QVariant toVariant(IdList const &list); +}; + +typedef Id Metatype; +} + +// qReal::Id and qReal::IdList could be used straight in QVariant +Q_DECLARE_METATYPE(qReal::Id) + +Q_DECLARE_METATYPE(qReal::IdList) + +QRKERNEL_EXPORT QDataStream& operator<< (QDataStream &out, qReal::Id const &id); +QRKERNEL_EXPORT QDataStream& operator>> (QDataStream &in, qReal::Id &id); diff --git a/configurationServer/gui/qrkernel/kernelDeclSpec.h b/configurationServer/gui/qrkernel/kernelDeclSpec.h new file mode 100644 index 0000000..f3fa22e --- /dev/null +++ b/configurationServer/gui/qrkernel/kernelDeclSpec.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#ifndef QRKERNEL_EXPORT +# if defined(QRKERNEL_LIBRARY) +# define QRKERNEL_EXPORT Q_DECL_EXPORT +# else +# define QRKERNEL_EXPORT Q_DECL_IMPORT +# endif +#endif diff --git a/configurationServer/gui/qrkernel/qrkernel.pri b/configurationServer/gui/qrkernel/qrkernel.pri new file mode 100644 index 0000000..2ca9a56 --- /dev/null +++ b/configurationServer/gui/qrkernel/qrkernel.pri @@ -0,0 +1,26 @@ +DEFINES += QRKERNEL_LIBRARY + +CONFIG += c++11 + +INCLUDEPATH += \ + $$PWD/.. + +HEADERS += \ + $$PWD/ids.h \ + $$PWD/definitions.h \ + $$PWD/exception/exception.h \ + $$PWD/roles.h \ + $$PWD/settingsManager.h \ + $$PWD/kernelDeclSpec.h \ + $$PWD/timeMeasurer.h \ + $$PWD/version.h \ + +SOURCES += \ + $$PWD/ids.cpp \ + $$PWD/exception/exception.cpp \ + $$PWD/settingsManager.cpp \ + $$PWD/timeMeasurer.cpp \ + $$PWD/version.cpp \ + +RESOURCES += \ + $$PWD/qrkernel.qrc \ diff --git a/configurationServer/gui/qrkernel/qrkernel.pro b/configurationServer/gui/qrkernel/qrkernel.pro new file mode 100644 index 0000000..0c257cc --- /dev/null +++ b/configurationServer/gui/qrkernel/qrkernel.pro @@ -0,0 +1,11 @@ +TEMPLATE = lib + +DESTDIR = ../bin + +OBJECTS_DIR = .obj +MOC_DIR = .moc +RCC_DIR = .moc + +include(qrkernel.pri) + + diff --git a/configurationServer/gui/qrkernel/qrkernel.qrc b/configurationServer/gui/qrkernel/qrkernel.qrc new file mode 100644 index 0000000..6f85c26 --- /dev/null +++ b/configurationServer/gui/qrkernel/qrkernel.qrc @@ -0,0 +1,5 @@ + + + settingsDefaultValues + + diff --git a/configurationServer/gui/qrkernel/roles.h b/configurationServer/gui/qrkernel/roles.h new file mode 100644 index 0000000..cd8539c --- /dev/null +++ b/configurationServer/gui/qrkernel/roles.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include "ids.h" + +namespace qReal { + +namespace roles { + +/// Roles that are heavily used by front-end. Should be present in all entities. +enum { + idRole = Qt::UserRole + 1 // element's ID. e.g. qReal::Id + , logicalIdRole // For elements of graphical model it is an Id of corresponding logical element, + // if any. Otherwise it's Id(). + , positionRole // element's position within current context (model knows which one it is) + , configurationRole // element's configuration (e.g. shape, size) within current context + , fromRole // for edges it's an ID of a node, which this edge starts from. is ignored for nodes + , toRole // for edges it's an ID of a node, which this edge ends on. is ignored for nodes + , fromPortRole // for edges it's a port ID, which this edge starts from. is ignored for nodes + , toPortRole // for edges it's a port ID, which this edge ends on. is ignored for nodes + , customPropertiesBeginRole // generated roles start from this one + // also, `name' is also among the mandatory attributes. it's handled by Qt::EditRole and Qt::DisplayRole +}; +} +} diff --git a/configurationServer/gui/qrkernel/settingsDefaultValues b/configurationServer/gui/qrkernel/settingsDefaultValues new file mode 100644 index 0000000..adabe1e --- /dev/null +++ b/configurationServer/gui/qrkernel/settingsDefaultValues @@ -0,0 +1,65 @@ +ActivateGrid=true +ActivateAlignment=true +Antialiasing=true +arrangeLinks=true +Autosave=true +AutosaveInterval=60 +AutosaveDirPath= +AutosaveFileName=autosave.qrs +buildedFileName=builded +builderPath=gcc +ChaoticEdition=false +CodeFileName=code.c +currentPreferencesTab=0 +debugColor=red +debuggerPath=gdb +debuggerTimeout=750 +debugWorkingDirectory= +diagramCreateSuggestion=true +EmbeddedControls=false +EmbeddedLinkers=true +EmbeddedLinkerSize=6 +gestureDelay=1000 +Gestures=true +GridWidth=10 +IndexGrid=25 +linuxButton=false +maximized=true +maxZoom=5.0 +minZoom=0.27 +OpenGL=true +otherButton=false +PaletteIconsInARowCount=3 +PaletteRepresentation=0 +PaletteTabSwitching=true +pathToQmake= +pathToMake= +pluginExtension= +pos=@Point(0 0) +prefix= +ShowAlignment=true +ShowGrid=true +size=@Size(1024 800) +Splashscreen=true +LineType=0 +MoveLabels = true +ResizeLabels = true +LabelsDistance = 100 +temp= +warningWindow=true +windowsButton=false +workingDir=./save +zoomFactor=1.08 +oldLineColor=magenta +PaintOldEdgeMode=true +pathToImages=./images/iconset1 +toolbarSize=30 +AutosaveTempFile=~tempFile +pythonPath=python +generationTimeout=100 +nodesStateButtonExpands=true +recentProjectsLimit=5 +dragArea = 12 +usabilityTestingMode=false +collectErgonomicValues=true +touchMode=false diff --git a/configurationServer/gui/qrkernel/settingsManager.cpp b/configurationServer/gui/qrkernel/settingsManager.cpp new file mode 100644 index 0000000..b5ec3d4 --- /dev/null +++ b/configurationServer/gui/qrkernel/settingsManager.cpp @@ -0,0 +1,125 @@ +#include "settingsManager.h" + +#include +#include +#include +#include + +using namespace qReal; + +SettingsManager* SettingsManager::mInstance = nullptr; + +SettingsManager::SettingsManager() + : mSettings("SPbSU", "QReal") +{ + initDefaultValues(); + load(); +} + +SettingsManager::~SettingsManager() +{ +} + +void SettingsManager::setValue(QString const &name, QVariant const &value) +{ + QVariant const oldValue = instance()->value(name); + if (oldValue != value) { + instance()->set(name, value); + emit instance()->settingsChanged(name, oldValue, value); + } +} + +QVariant SettingsManager::value(QString const &key) +{ + return instance()->get(key); +} + +QVariant SettingsManager::value(QString const &key, QVariant const &defaultValue) +{ + return instance()->get(key, defaultValue); +} + +SettingsManager* SettingsManager::instance() +{ + if (mInstance == nullptr) { + mInstance = new SettingsManager(); + } + + return mInstance; + //return nullptr; +} + +void SettingsManager::set(QString const &name, QVariant const &value) +{ + mData[name] = value; +} + +QVariant SettingsManager::get(QString const &name, QVariant const &defaultValue) const +{ + if (mData.contains(name)) { + return mData[name]; + } + + if (mDefaultValues.contains(name) && defaultValue == QVariant()) { + return mDefaultValues[name]; + } + + return defaultValue; +} + +void SettingsManager::saveData() +{ + for (QString const &name : mData.keys()) { + mSettings.setValue(name, mData[name]); + } + + mSettings.sync(); +} + +void SettingsManager::saveSettings(QString const &fileNameForExport) +{ + QSettings settingsForSave(fileNameForExport, QSettings::IniFormat); + for (QString const &name : mData.keys()) { + settingsForSave.setValue(name, mData[name]); + } + + settingsForSave.sync(); +} + +void SettingsManager::load() +{ + for (QString const &name : mSettings.allKeys()) { + mData[name] = mSettings.value(name); + } +} + +void SettingsManager::loadSettings(QString const &fileNameForImport) +{ + mergeSettings(fileNameForImport, mData); + saveData(); +} + +void SettingsManager::initDefaultValues() +{ + mergeSettings(":/settingsDefaultValues", mDefaultValues); +} + +void SettingsManager::loadDefaultSettings(QString const &filePath) +{ + instance()->mergeSettings(filePath, instance()->mDefaultValues); +} + +void SettingsManager::mergeSettings(QString const &fileNameForImport, QHash &target) +{ + QSettings settings(fileNameForImport, QSettings::IniFormat); + for (QString const &name : settings.allKeys()) { + target[name] = settings.value(name); + } +} + +void SettingsManager::clearSettings() +{ + instance()->mSettings.clear(); + instance()->mData.clear(); + instance()->mDefaultValues.clear(); +} diff --git a/configurationServer/gui/qrkernel/settingsManager.h b/configurationServer/gui/qrkernel/settingsManager.h new file mode 100644 index 0000000..3409a87 --- /dev/null +++ b/configurationServer/gui/qrkernel/settingsManager.h @@ -0,0 +1,88 @@ +#pragma once + +#include +#include +#include +#include + +#include "kernelDeclSpec.h" + +namespace qReal { + +/// Singleton class that allows to change settings in run-time +/// (replaces QSettings). Purpose of this class is to allow two instances +/// of an application coexist without changing each other's settings, +/// by storing settings separately in memory for each instance and syncing +/// them only on start/exit. +class SettingsManager : public QObject +{ + Q_OBJECT + +public: + /// Get value associated with given key from settings. + /// @param key Parameter name. + /// @returns Variant with parameter value. + static QVariant value(QString const &key); + + /// Get value associated with given key from settings with given default value. + /// @param key Parameter name. + /// @param defaultValue Default value, used when parameter not found. + /// @returns Variant with parameter value. + static QVariant value(QString const &key, QVariant const &defaultValue); + + /// Set value associated with given key. + /// @param key Parameter name. + /// @param value Parameter value. + static void setValue(QString const &key, QVariant const &value); + + /// Removes all entries in persistent external storage + static void clearSettings(); + + /// Returns an instance of a singleton. + static SettingsManager *instance(); + + /// Saves settings into persistent external storage (for example, Windows + /// registry), making them available to new instances of an application. + void saveData(); + + /// Saves settings into selected file with name fileNameForExport. + void saveSettings(QString const &fileNameForExport); + + /// Loads settings from persistent external storage into SettingsManager. + void load(); + + /// Merges settings from the given file in INI format. + void loadSettings(QString const &fileNameForImport); + + /// Merges default settings from the given file in INI format. + static void loadDefaultSettings(QString const &filePath); + +signals: + /// Emitted each time when settings with the given key were modified. + /// For connection instance() method can be useful. + void settingsChanged(QString const &name, QVariant const &oldValue, QVariant const &newValue); + +private: + /// Private constructor. + SettingsManager(); + ~SettingsManager(); + + void set(QString const &name, QVariant const &value); + QVariant get(QString const &key, QVariant const &defaultValue = QVariant()) const; + + /// Merges settings from the given file in INI format into the given map. + void mergeSettings(QString const &fileNameForImport, QHash &target); + + void initDefaultValues(); + + /// Singleton sole instance. + static SettingsManager *mInstance; + + /// In-memory settings storage. + QHash mData; + QHash mDefaultValues; + /// Persistent settings storage. + QSettings mSettings; +}; + +} diff --git a/configurationServer/gui/qrkernel/timeMeasurer.cpp b/configurationServer/gui/qrkernel/timeMeasurer.cpp new file mode 100644 index 0000000..b0ed0c1 --- /dev/null +++ b/configurationServer/gui/qrkernel/timeMeasurer.cpp @@ -0,0 +1,22 @@ +#include "timeMeasurer.h" + +#include + +using namespace qReal; + +TimeMeasurer::TimeMeasurer(QString const &methodName) + : mStartTime(QDateTime::currentDateTime()) + , mMethodName(methodName) +{ +} + +TimeMeasurer::~TimeMeasurer() +{ + QDateTime currentTime = QDateTime::currentDateTime(); + qDebug() << QString("TimeMeasurer %1: The operation lasted for %2 mseconds") + .arg(mMethodName, QString::number(static_cast(mStartTime.msecsTo(currentTime)))); +} + +void TimeMeasurer::doNothing() +{ +} diff --git a/configurationServer/gui/qrkernel/timeMeasurer.h b/configurationServer/gui/qrkernel/timeMeasurer.h new file mode 100644 index 0000000..5f0d09c --- /dev/null +++ b/configurationServer/gui/qrkernel/timeMeasurer.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "kernelDeclSpec.h" + +namespace qReal { + +/// Measures time interval between its creation and deletion, writes results +/// to qDebug. Used for profiling. +class QRKERNEL_EXPORT TimeMeasurer +{ +public: + /// Constructor. + /// @param methodName A name of a method or part of program to be measured. + explicit TimeMeasurer(QString const &methodName); + + /// Destructor. Calling it indicates end of measured interval. + ~TimeMeasurer(); + + /// This method is used to avoid unused variables problem, + /// because sometimes the functionality of the object of this class + /// is limited to the functionality in destructor. + void doNothing(); + +private: + /// Time of start of measured interval. + QDateTime mStartTime; + + /// Name of a method to measure. + QString mMethodName; +}; +} diff --git a/configurationServer/gui/qrkernel/version.cpp b/configurationServer/gui/qrkernel/version.cpp new file mode 100644 index 0000000..f365203 --- /dev/null +++ b/configurationServer/gui/qrkernel/version.cpp @@ -0,0 +1,158 @@ +#include "version.h" + +#include + +using namespace qReal; + +Version Version::fromString(QString const &version) +{ + QStringList const dashParts = version.split("-", QString::SkipEmptyParts); + QStringList const spaceParts = version.split(" ", QString::SkipEmptyParts); + if (dashParts.isEmpty() || spaceParts.isEmpty() || dashParts.count() > 2 || spaceParts.count() > 2) { + return Version(); + } + + QStringList const parts = dashParts.count() == 2 ? dashParts : spaceParts; + QString const prefix = parts[0]; + QString const suffix = parts.count() == 1 ? QString() : parts[1]; + + bool success = true; + bool currentIsOk; + + QStringList const numbers = prefix.split(".", QString::SkipEmptyParts); + if (numbers.isEmpty() || numbers.count() > 3) { + return Version(); + } + + QString const majorString = numbers[0]; + QString const minorString = numbers.count() > 1 ? numbers[1] : "0"; + QString const buildString = numbers.count() > 2 ? numbers[2] : "0"; + + int const major = majorString.toInt(¤tIsOk); + success &= currentIsOk; + int const minor = minorString.toInt(¤tIsOk); + success &= currentIsOk; + int const build = buildString.toInt(¤tIsOk); + success &= currentIsOk; + + if (suffix.isEmpty() && success) { + return Version(major, minor, build); + } + + // Splitting string into two parts: first is maximum letter prefix, second is remaining part. + QString letterSuffix; + QString numberSuffix; + bool iteratingFirstPart = true; + for (QChar const ch : suffix) { + if (!ch.isLetter() && iteratingFirstPart) { + iteratingFirstPart = false; + } + + if (iteratingFirstPart) { + letterSuffix.append(ch); + } else { + numberSuffix.append(ch); + } + } + + if (numberSuffix.isEmpty()) { + numberSuffix = "0"; + } + + Stage const stage = parseStage(letterSuffix, currentIsOk); + success &= currentIsOk; + int const stageNumber = numberSuffix.toInt(¤tIsOk); + success &= currentIsOk; + + if (!success) { + return Version(); + } + + return Version(major, minor, build, stage, stageNumber); +} + +Version::Stage Version::parseStage(QString const &stage, bool &ok) +{ + Stage result = stable; + ok = false; + if (stage.toLower() == "a" || stage.toLower() == "alpha") { + ok = true; + result = alpha; + } else if (stage.toLower() == "b" || stage.toLower() == "beta") { + ok = true; + result = beta; + } else if (stage.toLower() == "rc" || stage.toLower() == "releaseCandidate") { + ok = true; + result = releaseCandidate; + } + + return result; +} + +Version::Version() + : mMajor(-1) + , mMinor(-1) + , mBuild(-1) + , mStage(stable) + , mStageNumber(-1) +{ +} + +Version::Version(int major, int minor, int build, Version::Stage stage, int stageNumber) + : mMajor(major) + , mMinor(minor) + , mBuild(build) + , mStage(stage) + , mStageNumber(stageNumber) +{ +} + +bool Version::isValid() const +{ + return mMajor >= 0; +} + +int qReal::Version::major() const +{ + return mMajor; +} + +int qReal::Version::minor() const +{ + return mMinor; +} + +int Version::build() const +{ + return mBuild; +} + +Version::Stage Version::stage() const +{ + return mStage; +} + +int Version::stageNumber() const +{ + return mStageNumber; +} + +QString Version::toString() const +{ + return QString("%1.%2.%3").arg(QString::number(mMajor) + , QString::number(mMinor), QString::number(mBuild)) + suffixString(); +} + +QString Version::suffixString() const +{ + switch (mStage) { + case alpha: + return QString("-alpha%1").arg(QString::number(mStageNumber)); + case beta: + return QString("-beta%1").arg(QString::number(mStageNumber)); + case releaseCandidate: + return QString("-rc%1").arg(QString::number(mStageNumber)); + default: + return QString(); + } +} diff --git a/configurationServer/gui/qrkernel/version.h b/configurationServer/gui/qrkernel/version.h new file mode 100644 index 0000000..5d3bc9d --- /dev/null +++ b/configurationServer/gui/qrkernel/version.h @@ -0,0 +1,150 @@ +#pragma once + +#include +#include +#include +#include + +#include "kernelDeclSpec.h" + +namespace qReal { + +/// Represents a version of an editor. String representation is expected to consist +/// of four parts: . +/// Major, Minor, Build and Number parts are simply integer numbers. +/// Stage is one of "alpha" (or "a"), "beta" (or "b") or "rc" markers. +/// Stage part is also can be separated by spaces from the number part. +/// Minor, Build, Stage and Number parts are optional. +/// +/// Versions can be compared each to other. Version1 is less than Version2 +/// if Version1 was released earlier than Version2. Examples: +/// +/// 2.5.3 < 3.0.0 +/// 3.0.0-a < 3.0.0-rc1 +/// 3.0.0-rc1 < 3.0.0 +/// 3.0.0 == 3 +class QRKERNEL_EXPORT Version +{ +public: + /// Represents release stage. + enum Stage + { + /// Testing inside team. + alpha = 0 + /// Testing inside community. + , beta + /// Version that seems to be stable. + , releaseCandidate + /// Stable version, used when no suffix specified. + , stable + }; + + /// Constructs new Version instance from a given string. + /// Version() is returned when input string could not be parsed. + static Version fromString(QString const &version); + + /// Constructs invalid version instance. + Version(); + + /// Constructs a version object from a number parts. For constructing a version object from string + /// use fromString() method. + /// @see fromString() + Version(int major, int minor = 0, int build = 0, Stage stage = stable, int stageNumber = 0); + + /// Returns true if version string was accepted by versions parser. + bool isValid() const; + + /// Returns a major part of the version (first part) + int major() const; + + /// Returns a major part of the version (second part). 0 is returned when no minor version was specified. + int minor() const; + + /// Returns a build part of the version (third part). 0 is returned when no build version was specified. + int build() const; + + /// Returns a stage part of the version (suffix part). 'stable' is returned when no stage was specified. + Stage stage() const; + + /// Returns a stage number part of the version (optional number in stage suffix). + /// 0 is returned when no stage version was specified. + int stageNumber() const; + + /// Returns version in form. + /// @warning: returned by this method version string may differ form input one. + QString toString() const; + +private: + static Stage parseStage(QString const &stage, bool &ok); + QString suffixString() const; + + int mMajor; + int mMinor; + int mBuild; + Stage mStage; + int mStageNumber; +}; + +/// Versions equality operator. Versions are equal when all their parts are equal. +inline bool operator==(Version const &v1, Version const &v2) +{ + return v1.major() == v2.major() + && v1.minor() == v2.minor() + && v1.build() == v2.build() + && v1.stage() == v2.stage() + && v1.stageNumber() == v2.stageNumber(); +} + +/// Version inequality operator. +inline bool operator!=(Version const &v1, Version const &v2) +{ + return !(v1 == v2); +} + +/// Less comparison operator for Version class +inline bool operator<(Version const &v1, Version const &v2) +{ + return v1.major() != v2.major() ? v1.major() < v2.major() + : v1.minor() != v2.minor() ? v1.minor() < v2.minor() + : v1.build() != v2.build() ? v1.build() < v2.build() + : v1.stage() != v2.stage() ? v1.stage() < v2.stage() + : v1.stageNumber() < v2.stageNumber(); +} + +/// Greater comparison operator for Version class +inline bool operator>(Version const &v1, Version const &v2) +{ + return !(v1 == v2) && !(v1 < v2); +} + +/// Less or equal comparison operator for Version class +inline bool operator<=(Version const &v1, Version const &v2) +{ + return v1 == v2 || v1 < v2; +} + +/// Greater or equal comparison operator for Version class +inline bool operator>=(Version const &v1, Version const &v2) +{ + return !(v1 < v2); +} + +/// Version hash function for using it in QHash. +inline uint qHash(Version const &key) +{ + return qHash(key.toString()); +} + +/// Operator for printing Version into QDebug. +inline QDebug operator<<(QDebug &dbg, Version const &version) +{ + dbg << version.toString(); + return dbg.space(); +} + +} + +Q_DECLARE_METATYPE(qReal::Version) + +QRKERNEL_EXPORT QDataStream& operator<< (QDataStream &out, qReal::Version const &version); +QRKERNEL_EXPORT QDataStream& operator>> (QDataStream &in, qReal::Version &version); diff --git a/configurationServer/gui/qrutils/qRealDialog.cpp b/configurationServer/gui/qrutils/qRealDialog.cpp new file mode 100644 index 0000000..1227572 --- /dev/null +++ b/configurationServer/gui/qrutils/qRealDialog.cpp @@ -0,0 +1,58 @@ +#include "qRealDialog.h" + +#include + +using namespace utils; +using namespace qReal; + +QRealDialog::QRealDialog(QString const &id, QWidget *parent) + : QDialog(parent) + , mId(id) +{ +} + +void QRealDialog::showEvent(QShowEvent *event) +{ + QDialog::showEvent(event); + deserializeParameters(); +} + +void QRealDialog::closeEvent(QCloseEvent *event) +{ + serializeParameters(); + QDialog::closeEvent(event); +} + +void QRealDialog::serializeParameters() +{ + SettingsManager::setValue(maximizedKey(), isMaximized()); + SettingsManager::setValue(positionKey(), pos()); + SettingsManager::setValue(sizeKey(), size()); +} + +void QRealDialog::deserializeParameters() +{ + if (SettingsManager::value(maximizedKey()).toBool()) { + setWindowState(windowState() | Qt::WindowMaximized); + } else { + if (SettingsManager::value(sizeKey()).toSize().isValid()) { + move(SettingsManager::value(positionKey()).toPoint()); + resize(SettingsManager::value(sizeKey()).toSize()); + } + } +} + +QString QRealDialog::maximizedKey() const +{ + return mId + "WasMaximized"; +} + +QString QRealDialog::positionKey() const +{ + return mId + "LastPosition"; +} + +QString QRealDialog::sizeKey() const +{ + return mId + "LastSize"; +} diff --git a/configurationServer/gui/qrutils/qRealDialog.h b/configurationServer/gui/qrutils/qRealDialog.h new file mode 100644 index 0000000..0771c95 --- /dev/null +++ b/configurationServer/gui/qrutils/qRealDialog.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "utilsDeclSpec.h" + +namespace utils { + +/// A base class for all system dialogs. Provides such tools like automatic +/// serialization of dialog`s position and size +class QRealDialog : public QDialog +{ + Q_OBJECT + +public: + /// @param id The name of this dialog. Used for storing dialog`s parameters + ///in settings so should be unique. + explicit QRealDialog(QString const &id, QWidget *parent = 0); + +protected: + virtual void showEvent(QShowEvent *); + virtual void closeEvent(QCloseEvent *); + + void serializeParameters(); + void deserializeParameters(); + + /// Returns a key string used for storing maximized parameter in registry + virtual QString maximizedKey() const; + + /// Returns a key string used for storing position parameter in registry + virtual QString positionKey() const; + + /// Returns a key string used for storing size parameter in registry + virtual QString sizeKey() const; + +private: + QString const mId; +}; + +} diff --git a/configurationServer/gui/qrutils/qRealFileDialog.cpp b/configurationServer/gui/qrutils/qRealFileDialog.cpp new file mode 100644 index 0000000..66a6ef4 --- /dev/null +++ b/configurationServer/gui/qrutils/qRealFileDialog.cpp @@ -0,0 +1,88 @@ +#include "qRealFileDialog.h" + +#include + +using namespace utils; + +QString QRealFileDialog::getOpenFileName(QString const &id + , QWidget *parent + , QString const &caption + , QString const &dir + , QString const &filter + , QString *selectedFilter + , QFileDialog::Options options) +{ + QString const lastDir = lastSelectedDirectory(id, dir); + QString const result = QFileDialog::getOpenFileName(parent, caption, lastDir, filter, selectedFilter, options); + saveState(id, directoryOf(result)); + return result; +} + +QString QRealFileDialog::getSaveFileName(QString const &id + , QWidget *parent + , QString const &caption + , QString const &dir + , QString const &filter + , QString *selectedFilter + , QFileDialog::Options options) +{ + QString const lastDir = lastSelectedDirectory(id, dir); + QString const result = QFileDialog::getSaveFileName(parent, caption, lastDir, filter, selectedFilter, options); + saveState(id, directoryOf(result)); + return result; +} + +QString QRealFileDialog::getExistingDirectory(QString const &id + , QWidget *parent + , QString const &caption + , QString const &dir + , QFileDialog::Options options) +{ + QString const lastDir = lastSelectedDirectory(id, dir); + QString const result = QFileDialog::getExistingDirectory(parent, caption, lastDir, options); + saveState(id, result); + return result; +} + +QStringList QRealFileDialog::getOpenFileNames(QString const &id + , QWidget *parent + , QString const &caption + , QString const &dir + , QString const &filter + , QString *selectedFilter + , QFileDialog::Options options) +{ + QString const lastDir = lastSelectedDirectory(id, dir); + QStringList const result = QFileDialog::getOpenFileNames(parent, caption, lastDir, filter, selectedFilter, options); + if (!result.isEmpty()) { + saveState(id, directoryOf(result[0])); + } + + return result; +} + +QString QRealFileDialog::lastSelectedDirectory(QString const &id, QString const &defaultDirectory) +{ + return qReal::SettingsManager::value(lastDirectoryKey(id), defaultDirectory).toString(); +} + +QString QRealFileDialog::lastDirectoryKey(QString const &id) +{ + return id + "FileDialogLastDir"; +} + +QString QRealFileDialog::directoryOf(QString const &file) +{ + if (file.isEmpty()) { + return QString(); + } + + return QFileInfo(file).absoluteDir().absolutePath(); +} + +void QRealFileDialog::saveState(QString const &id, QString const &directory) +{ + if (!directory.isEmpty()) { + qReal::SettingsManager::setValue(lastDirectoryKey(id), directory); + } +} diff --git a/configurationServer/gui/qrutils/qRealFileDialog.h b/configurationServer/gui/qrutils/qRealFileDialog.h new file mode 100644 index 0000000..fe0728f --- /dev/null +++ b/configurationServer/gui/qrutils/qRealFileDialog.h @@ -0,0 +1,59 @@ +#pragma once + +#include + +#include "utilsDeclSpec.h" + +namespace utils { + +/// Provides a dialog that allow users to select files or directories +/// with saving in settings last selected diractory +class QRealFileDialog +{ +public: + /// Makes same as QFileDialog::getOpenFileName but with restoring selected + /// directory last time when promted dialog with the same id + static QString getOpenFileName(QString const &id + , QWidget *parent = 0 + , QString const &caption = QString() + , QString const &dir = QString() + , QString const &filter = QString() + , QString *selectedFilter = 0 + , QFileDialog::Options options = 0); + + /// Makes same as QFileDialog::getSaveFileName but with restoring selected + /// directory last time when promted dialog with the same id + static QString getSaveFileName(QString const &id + , QWidget *parent = 0 + , QString const &caption = QString() + , QString const &dir = QString() + , QString const &filter = QString() + , QString *selectedFilter = 0 + , QFileDialog::Options options = 0); + + /// Makes same as QFileDialog::getExistingDirectory but with restoring selected + /// directory last time when promted dialog with the same id + static QString getExistingDirectory(QString const &id + , QWidget *parent = 0 + , QString const &caption = QString() + , QString const &dir = QString() + , QFileDialog::Options options = QFileDialog::ShowDirsOnly); + + /// Makes same as QFileDialog::getOpenFileNames but with restoring selected + /// directory last time when promted dialog with the same id + static QStringList getOpenFileNames(QString const &id + , QWidget *parent = 0 + , QString const &caption = QString() + , QString const &dir = QString() + , QString const &filter = QString() + , QString *selectedFilter = 0 + , QFileDialog::Options options = 0); + +private: + static QString lastSelectedDirectory(QString const &id, QString const &defaultDirectory); + static QString lastDirectoryKey(QString const &id); + static QString directoryOf(QString const &file); + static void saveState(QString const &id, QString const &directory); +}; + +} diff --git a/configurationServer/gui/qrutils/utilsDeclSpec.h b/configurationServer/gui/qrutils/utilsDeclSpec.h new file mode 100644 index 0000000..79e03af --- /dev/null +++ b/configurationServer/gui/qrutils/utilsDeclSpec.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#ifndef QRUTILS_EXPORT +# if defined(QRUTILS_LIBRARY) +# define QRUTILS_EXPORT Q_DECL_EXPORT +# else +# define QRUTILS_EXPORT Q_DECL_IMPORT +# endif +#endif diff --git a/configurationServer/gui/ui_behaviourPage.h b/configurationServer/gui/ui_behaviourPage.h new file mode 100644 index 0000000..7165054 --- /dev/null +++ b/configurationServer/gui/ui_behaviourPage.h @@ -0,0 +1,219 @@ +/******************************************************************************** +** Form generated from reading UI file 'behaviourPage.ui' +** +** Created by: Qt User Interface Compiler version 5.2.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_BEHAVIOURPAGE_H +#define UI_BEHAVIOURPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_PreferencesBehaviourPage +{ +public: + QVBoxLayout *verticalLayout; + QLabel *label_2; + QFrame *frame_2; + QFormLayout *formLayout; + QLabel *label_3; + QComboBox *languageComboBox; + QLabel *label_7; + QFrame *frame_5; + QGridLayout *gridLayout; + QSpinBox *gestureDelaySpinBox; + QLabel *autoSaveLabel; + QLabel *gestureDelayTimeUnitLabel; + QLabel *gestureDelayLabel; + QCheckBox *paletteTabCheckBox; + QSpinBox *autoSaveSpinBox; + QCheckBox *autoSaveCheckBox; + QCheckBox *collectErgonomicValuesCheckBox; + QCheckBox *usabilityModeCheckBox; + QLabel *label; + QFrame *frame; + QVBoxLayout *verticalLayout_2; + QCheckBox *touchModeCheckBox; + QSpacerItem *verticalSpacer; + + void setupUi(QWidget *PreferencesBehaviourPage) + { + if (PreferencesBehaviourPage->objectName().isEmpty()) + PreferencesBehaviourPage->setObjectName(QStringLiteral("PreferencesBehaviourPage")); + PreferencesBehaviourPage->resize(500, 340); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(PreferencesBehaviourPage->sizePolicy().hasHeightForWidth()); + PreferencesBehaviourPage->setSizePolicy(sizePolicy); + verticalLayout = new QVBoxLayout(PreferencesBehaviourPage); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + label_2 = new QLabel(PreferencesBehaviourPage); + label_2->setObjectName(QStringLiteral("label_2")); + + verticalLayout->addWidget(label_2); + + frame_2 = new QFrame(PreferencesBehaviourPage); + frame_2->setObjectName(QStringLiteral("frame_2")); + frame_2->setFrameShape(QFrame::StyledPanel); + frame_2->setFrameShadow(QFrame::Raised); + formLayout = new QFormLayout(frame_2); + formLayout->setObjectName(QStringLiteral("formLayout")); + label_3 = new QLabel(frame_2); + label_3->setObjectName(QStringLiteral("label_3")); + + formLayout->setWidget(0, QFormLayout::LabelRole, label_3); + + languageComboBox = new QComboBox(frame_2); + languageComboBox->setObjectName(QStringLiteral("languageComboBox")); + + formLayout->setWidget(0, QFormLayout::FieldRole, languageComboBox); + + + verticalLayout->addWidget(frame_2); + + label_7 = new QLabel(PreferencesBehaviourPage); + label_7->setObjectName(QStringLiteral("label_7")); + + verticalLayout->addWidget(label_7); + + frame_5 = new QFrame(PreferencesBehaviourPage); + frame_5->setObjectName(QStringLiteral("frame_5")); + QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(frame_5->sizePolicy().hasHeightForWidth()); + frame_5->setSizePolicy(sizePolicy1); + frame_5->setFrameShape(QFrame::StyledPanel); + frame_5->setFrameShadow(QFrame::Raised); + gridLayout = new QGridLayout(frame_5); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gestureDelaySpinBox = new QSpinBox(frame_5); + gestureDelaySpinBox->setObjectName(QStringLiteral("gestureDelaySpinBox")); + gestureDelaySpinBox->setMaximum(100000); + gestureDelaySpinBox->setSingleStep(10); + + gridLayout->addWidget(gestureDelaySpinBox, 2, 1, 1, 1); + + autoSaveLabel = new QLabel(frame_5); + autoSaveLabel->setObjectName(QStringLiteral("autoSaveLabel")); + + gridLayout->addWidget(autoSaveLabel, 1, 2, 1, 1); + + gestureDelayTimeUnitLabel = new QLabel(frame_5); + gestureDelayTimeUnitLabel->setObjectName(QStringLiteral("gestureDelayTimeUnitLabel")); + + gridLayout->addWidget(gestureDelayTimeUnitLabel, 2, 2, 1, 1); + + gestureDelayLabel = new QLabel(frame_5); + gestureDelayLabel->setObjectName(QStringLiteral("gestureDelayLabel")); + + gridLayout->addWidget(gestureDelayLabel, 2, 0, 1, 1); + + paletteTabCheckBox = new QCheckBox(frame_5); + paletteTabCheckBox->setObjectName(QStringLiteral("paletteTabCheckBox")); + + gridLayout->addWidget(paletteTabCheckBox, 0, 0, 1, 3); + + autoSaveSpinBox = new QSpinBox(frame_5); + autoSaveSpinBox->setObjectName(QStringLiteral("autoSaveSpinBox")); + autoSaveSpinBox->setMinimum(1); + autoSaveSpinBox->setMaximum(10000); + autoSaveSpinBox->setSingleStep(1); + autoSaveSpinBox->setValue(600); + + gridLayout->addWidget(autoSaveSpinBox, 1, 1, 1, 1); + + autoSaveCheckBox = new QCheckBox(frame_5); + autoSaveCheckBox->setObjectName(QStringLiteral("autoSaveCheckBox")); + autoSaveCheckBox->setChecked(true); + + gridLayout->addWidget(autoSaveCheckBox, 1, 0, 1, 1); + + collectErgonomicValuesCheckBox = new QCheckBox(frame_5); + collectErgonomicValuesCheckBox->setObjectName(QStringLiteral("collectErgonomicValuesCheckBox")); + collectErgonomicValuesCheckBox->setChecked(true); + + gridLayout->addWidget(collectErgonomicValuesCheckBox, 3, 0, 1, 1); + + usabilityModeCheckBox = new QCheckBox(frame_5); + usabilityModeCheckBox->setObjectName(QStringLiteral("usabilityModeCheckBox")); + + gridLayout->addWidget(usabilityModeCheckBox, 4, 0, 1, 1); + + + verticalLayout->addWidget(frame_5); + + label = new QLabel(PreferencesBehaviourPage); + label->setObjectName(QStringLiteral("label")); + + verticalLayout->addWidget(label); + + frame = new QFrame(PreferencesBehaviourPage); + frame->setObjectName(QStringLiteral("frame")); + frame->setFrameShape(QFrame::StyledPanel); + frame->setFrameShadow(QFrame::Raised); + verticalLayout_2 = new QVBoxLayout(frame); + verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2")); + touchModeCheckBox = new QCheckBox(frame); + touchModeCheckBox->setObjectName(QStringLiteral("touchModeCheckBox")); + + verticalLayout_2->addWidget(touchModeCheckBox); + + + verticalLayout->addWidget(frame); + + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + verticalLayout->addItem(verticalSpacer); + + + retranslateUi(PreferencesBehaviourPage); + + QMetaObject::connectSlotsByName(PreferencesBehaviourPage); + } // setupUi + + void retranslateUi(QWidget *PreferencesBehaviourPage) + { + label_2->setText(QApplication::translate("PreferencesBehaviourPage", "User Interface", 0)); + label_3->setText(QApplication::translate("PreferencesBehaviourPage", "Language", 0)); + label_7->setText(QApplication::translate("PreferencesBehaviourPage", "Automatics", 0)); + autoSaveLabel->setText(QApplication::translate("PreferencesBehaviourPage", "sec", 0)); + gestureDelayTimeUnitLabel->setText(QApplication::translate("PreferencesBehaviourPage", "msec", 0)); + gestureDelayLabel->setText(QApplication::translate("PreferencesBehaviourPage", "Delay after gesture", 0)); + paletteTabCheckBox->setText(QApplication::translate("PreferencesBehaviourPage", "Palette tab switching", 0)); + autoSaveCheckBox->setText(QApplication::translate("PreferencesBehaviourPage", "Autosave", 0)); + collectErgonomicValuesCheckBox->setText(QApplication::translate("PreferencesBehaviourPage", "Collect ergonomic values", 0)); + usabilityModeCheckBox->setText(QApplication::translate("PreferencesBehaviourPage", "Usability testing mode", 0)); + label->setText(QApplication::translate("PreferencesBehaviourPage", "Touch", 0)); + touchModeCheckBox->setText(QApplication::translate("PreferencesBehaviourPage", "Touch Mode", 0)); + Q_UNUSED(PreferencesBehaviourPage); + } // retranslateUi + +}; + +namespace Ui { + class PreferencesBehaviourPage: public Ui_PreferencesBehaviourPage {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_BEHAVIOURPAGE_H diff --git a/configurationServer/gui/ui_debuggerPage.h b/configurationServer/gui/ui_debuggerPage.h new file mode 100644 index 0000000..6b11a08 --- /dev/null +++ b/configurationServer/gui/ui_debuggerPage.h @@ -0,0 +1,113 @@ +/******************************************************************************** +** Form generated from reading UI file 'debuggerPage.ui' +** +** Created by: Qt User Interface Compiler version 5.2.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_DEBUGGERPAGE_H +#define UI_DEBUGGERPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_PreferencesDebuggerPage +{ +public: + QVBoxLayout *verticalLayout; + QLabel *label_16; + QFrame *frame_7; + QGridLayout *gridLayout; + QLabel *label_14; + QLineEdit *timeoutLineEdit; + QLabel *label_15; + QComboBox *colorComboBox; + QSpacerItem *verticalSpacer; + + void setupUi(QWidget *PreferencesDebuggerPage) + { + if (PreferencesDebuggerPage->objectName().isEmpty()) + PreferencesDebuggerPage->setObjectName(QStringLiteral("PreferencesDebuggerPage")); + PreferencesDebuggerPage->resize(407, 122); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(PreferencesDebuggerPage->sizePolicy().hasHeightForWidth()); + PreferencesDebuggerPage->setSizePolicy(sizePolicy); + verticalLayout = new QVBoxLayout(PreferencesDebuggerPage); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + label_16 = new QLabel(PreferencesDebuggerPage); + label_16->setObjectName(QStringLiteral("label_16")); + + verticalLayout->addWidget(label_16); + + frame_7 = new QFrame(PreferencesDebuggerPage); + frame_7->setObjectName(QStringLiteral("frame_7")); + frame_7->setFrameShape(QFrame::StyledPanel); + frame_7->setFrameShadow(QFrame::Raised); + gridLayout = new QGridLayout(frame_7); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + label_14 = new QLabel(frame_7); + label_14->setObjectName(QStringLiteral("label_14")); + + gridLayout->addWidget(label_14, 0, 0, 1, 1); + + timeoutLineEdit = new QLineEdit(frame_7); + timeoutLineEdit->setObjectName(QStringLiteral("timeoutLineEdit")); + + gridLayout->addWidget(timeoutLineEdit, 0, 1, 1, 1); + + label_15 = new QLabel(frame_7); + label_15->setObjectName(QStringLiteral("label_15")); + + gridLayout->addWidget(label_15, 1, 0, 1, 1); + + colorComboBox = new QComboBox(frame_7); + colorComboBox->setObjectName(QStringLiteral("colorComboBox")); + + gridLayout->addWidget(colorComboBox, 1, 1, 1, 1); + + + verticalLayout->addWidget(frame_7); + + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + verticalLayout->addItem(verticalSpacer); + + + retranslateUi(PreferencesDebuggerPage); + + QMetaObject::connectSlotsByName(PreferencesDebuggerPage); + } // setupUi + + void retranslateUi(QWidget *PreferencesDebuggerPage) + { + label_16->setText(QApplication::translate("PreferencesDebuggerPage", "Presentation", 0)); + label_14->setText(QApplication::translate("PreferencesDebuggerPage", "Debug timeout (ms):", 0)); + label_15->setText(QApplication::translate("PreferencesDebuggerPage", "Color of highlighting:", 0)); + Q_UNUSED(PreferencesDebuggerPage); + } // retranslateUi + +}; + +namespace Ui { + class PreferencesDebuggerPage: public Ui_PreferencesDebuggerPage {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_DEBUGGERPAGE_H diff --git a/configurationServer/gui/ui_editorPage.h b/configurationServer/gui/ui_editorPage.h new file mode 100644 index 0000000..bb04265 --- /dev/null +++ b/configurationServer/gui/ui_editorPage.h @@ -0,0 +1,529 @@ +/******************************************************************************** +** Form generated from reading UI file 'editorPage.ui' +** +** Created by: Qt User Interface Compiler version 5.2.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_EDITORPAGE_H +#define UI_EDITORPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_PreferencesEditorPage +{ +public: + QVBoxLayout *verticalLayout; + QScrollArea *scrollArea; + QWidget *scrollAreaWidgetContents; + QVBoxLayout *verticalLayout_2; + QLabel *label_5; + QFrame *frame_3; + QHBoxLayout *horizontalLayout; + QCheckBox *fontCheckBox; + QPushButton *fontSelectionButton; + QLabel *label; + QFrame *frame; + QGridLayout *gridLayout; + QSlider *gridWidthSlider; + QCheckBox *activateAlignmentCheckBox; + QLabel *label_20; + QCheckBox *activateGridCheckBox; + QLabel *label_13; + QCheckBox *showGridCheckBox; + QCheckBox *showAlignmentCheckBox; + QSlider *indexGridSlider; + QSpacerItem *horizontalSpacer_2; + QSpacerItem *horizontalSpacer_3; + QLabel *label_14; + QFrame *frame_7; + QGridLayout *gridLayout_3; + QSlider *dragAreaSizeSlider; + QLabel *label_15; + QFrame *frame_6; + QSlider *horizontalSlider; + QLabel *label_9; + QFrame *frame_4; + QGridLayout *gridLayout_5; + QSpacerItem *horizontalSpacer; + QComboBox *lineMode; + QLabel *label_10; + QLabel *label_11; + QSlider *loopEdgeBoundsIndent; + QLabel *label_2; + QFrame *frame_2; + QGridLayout *gridLayout_2; + QSlider *embeddedLinkerSizeSlider; + QSlider *embeddedLinkerIndentSlider; + QLabel *label_3; + QLabel *label_4; + QLabel *label_12; + QFrame *frame_5; + QVBoxLayout *verticalLayout_3; + QCheckBox *enableMoveLabelsCheckBox; + QCheckBox *enableResizeLabelsCheckBox; + QLabel *labelDistanceLabel; + QSlider *labelDistanceSlider; + QLabel *label_8; + QFrame *frame_9; + QGridLayout *gridLayout_7; + QLabel *label_6; + QLabel *label_7; + QComboBox *paletteComboBox; + QSpinBox *paletteSpinBox; + QSpacerItem *verticalSpacer_2; + + void setupUi(QWidget *PreferencesEditorPage) + { + if (PreferencesEditorPage->objectName().isEmpty()) + PreferencesEditorPage->setObjectName(QStringLiteral("PreferencesEditorPage")); + PreferencesEditorPage->resize(500, 638); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(PreferencesEditorPage->sizePolicy().hasHeightForWidth()); + PreferencesEditorPage->setSizePolicy(sizePolicy); + PreferencesEditorPage->setMinimumSize(QSize(50, 50)); + PreferencesEditorPage->setMaximumSize(QSize(16777215, 16777215)); + verticalLayout = new QVBoxLayout(PreferencesEditorPage); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + scrollArea = new QScrollArea(PreferencesEditorPage); + scrollArea->setObjectName(QStringLiteral("scrollArea")); + scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollArea->setWidgetResizable(true); + scrollAreaWidgetContents = new QWidget(); + scrollAreaWidgetContents->setObjectName(QStringLiteral("scrollAreaWidgetContents")); + scrollAreaWidgetContents->setGeometry(QRect(0, 0, 480, 782)); + verticalLayout_2 = new QVBoxLayout(scrollAreaWidgetContents); + verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2")); + label_5 = new QLabel(scrollAreaWidgetContents); + label_5->setObjectName(QStringLiteral("label_5")); + + verticalLayout_2->addWidget(label_5); + + frame_3 = new QFrame(scrollAreaWidgetContents); + frame_3->setObjectName(QStringLiteral("frame_3")); + QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(frame_3->sizePolicy().hasHeightForWidth()); + frame_3->setSizePolicy(sizePolicy1); + frame_3->setMinimumSize(QSize(0, 40)); + frame_3->setFrameShape(QFrame::StyledPanel); + frame_3->setFrameShadow(QFrame::Raised); + horizontalLayout = new QHBoxLayout(frame_3); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); + fontCheckBox = new QCheckBox(frame_3); + fontCheckBox->setObjectName(QStringLiteral("fontCheckBox")); + fontCheckBox->setEnabled(true); + sizePolicy1.setHeightForWidth(fontCheckBox->sizePolicy().hasHeightForWidth()); + fontCheckBox->setSizePolicy(sizePolicy1); + + horizontalLayout->addWidget(fontCheckBox); + + fontSelectionButton = new QPushButton(frame_3); + fontSelectionButton->setObjectName(QStringLiteral("fontSelectionButton")); + sizePolicy1.setHeightForWidth(fontSelectionButton->sizePolicy().hasHeightForWidth()); + fontSelectionButton->setSizePolicy(sizePolicy1); + + horizontalLayout->addWidget(fontSelectionButton); + + + verticalLayout_2->addWidget(frame_3); + + label = new QLabel(scrollAreaWidgetContents); + label->setObjectName(QStringLiteral("label")); + + verticalLayout_2->addWidget(label); + + frame = new QFrame(scrollAreaWidgetContents); + frame->setObjectName(QStringLiteral("frame")); + sizePolicy1.setHeightForWidth(frame->sizePolicy().hasHeightForWidth()); + frame->setSizePolicy(sizePolicy1); + frame->setFrameShape(QFrame::StyledPanel); + frame->setFrameShadow(QFrame::Raised); + gridLayout = new QGridLayout(frame); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gridWidthSlider = new QSlider(frame); + gridWidthSlider->setObjectName(QStringLiteral("gridWidthSlider")); + sizePolicy.setHeightForWidth(gridWidthSlider->sizePolicy().hasHeightForWidth()); + gridWidthSlider->setSizePolicy(sizePolicy); + gridWidthSlider->setMinimum(3); + gridWidthSlider->setMaximum(150); + gridWidthSlider->setSingleStep(1); + gridWidthSlider->setPageStep(10); + gridWidthSlider->setOrientation(Qt::Horizontal); + + gridLayout->addWidget(gridWidthSlider, 7, 1, 1, 2); + + activateAlignmentCheckBox = new QCheckBox(frame); + activateAlignmentCheckBox->setObjectName(QStringLiteral("activateAlignmentCheckBox")); + QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Fixed); + sizePolicy2.setHorizontalStretch(0); + sizePolicy2.setVerticalStretch(0); + sizePolicy2.setHeightForWidth(activateAlignmentCheckBox->sizePolicy().hasHeightForWidth()); + activateAlignmentCheckBox->setSizePolicy(sizePolicy2); + activateAlignmentCheckBox->setChecked(true); + + gridLayout->addWidget(activateAlignmentCheckBox, 4, 0, 1, 1); + + label_20 = new QLabel(frame); + label_20->setObjectName(QStringLiteral("label_20")); + + gridLayout->addWidget(label_20, 8, 0, 1, 1); + + activateGridCheckBox = new QCheckBox(frame); + activateGridCheckBox->setObjectName(QStringLiteral("activateGridCheckBox")); + sizePolicy2.setHeightForWidth(activateGridCheckBox->sizePolicy().hasHeightForWidth()); + activateGridCheckBox->setSizePolicy(sizePolicy2); + activateGridCheckBox->setTristate(false); + + gridLayout->addWidget(activateGridCheckBox, 2, 0, 1, 1); + + label_13 = new QLabel(frame); + label_13->setObjectName(QStringLiteral("label_13")); + + gridLayout->addWidget(label_13, 7, 0, 1, 1); + + showGridCheckBox = new QCheckBox(frame); + showGridCheckBox->setObjectName(QStringLiteral("showGridCheckBox")); + showGridCheckBox->setChecked(true); + + gridLayout->addWidget(showGridCheckBox, 1, 0, 1, 1); + + showAlignmentCheckBox = new QCheckBox(frame); + showAlignmentCheckBox->setObjectName(QStringLiteral("showAlignmentCheckBox")); + showAlignmentCheckBox->setMinimumSize(QSize(130, 0)); + showAlignmentCheckBox->setChecked(true); + + gridLayout->addWidget(showAlignmentCheckBox, 3, 0, 1, 1); + + indexGridSlider = new QSlider(frame); + indexGridSlider->setObjectName(QStringLiteral("indexGridSlider")); + sizePolicy.setHeightForWidth(indexGridSlider->sizePolicy().hasHeightForWidth()); + indexGridSlider->setSizePolicy(sizePolicy); + indexGridSlider->setMinimum(5); + indexGridSlider->setMaximum(150); + indexGridSlider->setSingleStep(1); + indexGridSlider->setPageStep(10); + indexGridSlider->setValue(50); + indexGridSlider->setOrientation(Qt::Horizontal); + + gridLayout->addWidget(indexGridSlider, 8, 1, 1, 2); + + horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + gridLayout->addItem(horizontalSpacer_2, 3, 1, 1, 1); + + horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + gridLayout->addItem(horizontalSpacer_3, 4, 1, 1, 1); + + + verticalLayout_2->addWidget(frame); + + label_14 = new QLabel(scrollAreaWidgetContents); + label_14->setObjectName(QStringLiteral("label_14")); + + verticalLayout_2->addWidget(label_14); + + frame_7 = new QFrame(scrollAreaWidgetContents); + frame_7->setObjectName(QStringLiteral("frame_7")); + frame_7->setFrameShape(QFrame::StyledPanel); + frame_7->setFrameShadow(QFrame::Raised); + gridLayout_3 = new QGridLayout(frame_7); + gridLayout_3->setObjectName(QStringLiteral("gridLayout_3")); + dragAreaSizeSlider = new QSlider(frame_7); + dragAreaSizeSlider->setObjectName(QStringLiteral("dragAreaSizeSlider")); + dragAreaSizeSlider->setMinimum(4); + dragAreaSizeSlider->setMaximum(20); + dragAreaSizeSlider->setValue(12); + dragAreaSizeSlider->setOrientation(Qt::Horizontal); + + gridLayout_3->addWidget(dragAreaSizeSlider, 0, 1, 1, 1); + + label_15 = new QLabel(frame_7); + label_15->setObjectName(QStringLiteral("label_15")); + + gridLayout_3->addWidget(label_15, 0, 0, 1, 1); + + + verticalLayout_2->addWidget(frame_7); + + frame_6 = new QFrame(scrollAreaWidgetContents); + frame_6->setObjectName(QStringLiteral("frame_6")); + frame_6->setFrameShape(QFrame::StyledPanel); + frame_6->setFrameShadow(QFrame::Raised); + horizontalSlider = new QSlider(frame_6); + horizontalSlider->setObjectName(QStringLiteral("horizontalSlider")); + horizontalSlider->setGeometry(QRect(70, 0, 160, 21)); + horizontalSlider->setOrientation(Qt::Horizontal); + + verticalLayout_2->addWidget(frame_6, 0, Qt::AlignLeft); + + label_9 = new QLabel(scrollAreaWidgetContents); + label_9->setObjectName(QStringLiteral("label_9")); + + verticalLayout_2->addWidget(label_9); + + frame_4 = new QFrame(scrollAreaWidgetContents); + frame_4->setObjectName(QStringLiteral("frame_4")); + QSizePolicy sizePolicy3(QSizePolicy::Preferred, QSizePolicy::Expanding); + sizePolicy3.setHorizontalStretch(0); + sizePolicy3.setVerticalStretch(30); + sizePolicy3.setHeightForWidth(frame_4->sizePolicy().hasHeightForWidth()); + frame_4->setSizePolicy(sizePolicy3); + frame_4->setMinimumSize(QSize(50, 60)); + frame_4->setFrameShape(QFrame::StyledPanel); + frame_4->setFrameShadow(QFrame::Raised); + gridLayout_5 = new QGridLayout(frame_4); + gridLayout_5->setObjectName(QStringLiteral("gridLayout_5")); + horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + gridLayout_5->addItem(horizontalSpacer, 0, 2, 1, 1); + + lineMode = new QComboBox(frame_4); + lineMode->setObjectName(QStringLiteral("lineMode")); + QSizePolicy sizePolicy4(QSizePolicy::Preferred, QSizePolicy::Expanding); + sizePolicy4.setHorizontalStretch(0); + sizePolicy4.setVerticalStretch(0); + sizePolicy4.setHeightForWidth(lineMode->sizePolicy().hasHeightForWidth()); + lineMode->setSizePolicy(sizePolicy4); + lineMode->setMinimumSize(QSize(0, 20)); + + gridLayout_5->addWidget(lineMode, 0, 1, 1, 1); + + label_10 = new QLabel(frame_4); + label_10->setObjectName(QStringLiteral("label_10")); + + gridLayout_5->addWidget(label_10, 0, 0, 1, 1); + + label_11 = new QLabel(frame_4); + label_11->setObjectName(QStringLiteral("label_11")); + sizePolicy1.setHeightForWidth(label_11->sizePolicy().hasHeightForWidth()); + label_11->setSizePolicy(sizePolicy1); + + gridLayout_5->addWidget(label_11, 1, 0, 1, 1); + + loopEdgeBoundsIndent = new QSlider(frame_4); + loopEdgeBoundsIndent->setObjectName(QStringLiteral("loopEdgeBoundsIndent")); + sizePolicy.setHeightForWidth(loopEdgeBoundsIndent->sizePolicy().hasHeightForWidth()); + loopEdgeBoundsIndent->setSizePolicy(sizePolicy); + loopEdgeBoundsIndent->setMinimum(1); + loopEdgeBoundsIndent->setMaximum(15); + loopEdgeBoundsIndent->setSingleStep(2); + loopEdgeBoundsIndent->setPageStep(2); + loopEdgeBoundsIndent->setValue(2); + loopEdgeBoundsIndent->setOrientation(Qt::Horizontal); + + gridLayout_5->addWidget(loopEdgeBoundsIndent, 1, 1, 1, 2); + + + verticalLayout_2->addWidget(frame_4); + + label_2 = new QLabel(scrollAreaWidgetContents); + label_2->setObjectName(QStringLiteral("label_2")); + + verticalLayout_2->addWidget(label_2); + + frame_2 = new QFrame(scrollAreaWidgetContents); + frame_2->setObjectName(QStringLiteral("frame_2")); + frame_2->setFrameShape(QFrame::StyledPanel); + frame_2->setFrameShadow(QFrame::Raised); + gridLayout_2 = new QGridLayout(frame_2); + gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); + embeddedLinkerSizeSlider = new QSlider(frame_2); + embeddedLinkerSizeSlider->setObjectName(QStringLiteral("embeddedLinkerSizeSlider")); + embeddedLinkerSizeSlider->setMinimum(4); + embeddedLinkerSizeSlider->setMaximum(20); + embeddedLinkerSizeSlider->setOrientation(Qt::Horizontal); + + gridLayout_2->addWidget(embeddedLinkerSizeSlider, 0, 1, 1, 1); + + embeddedLinkerIndentSlider = new QSlider(frame_2); + embeddedLinkerIndentSlider->setObjectName(QStringLiteral("embeddedLinkerIndentSlider")); + embeddedLinkerIndentSlider->setMinimum(5); + embeddedLinkerIndentSlider->setMaximum(20); + embeddedLinkerIndentSlider->setOrientation(Qt::Horizontal); + + gridLayout_2->addWidget(embeddedLinkerIndentSlider, 1, 1, 1, 1); + + label_3 = new QLabel(frame_2); + label_3->setObjectName(QStringLiteral("label_3")); + + gridLayout_2->addWidget(label_3, 0, 0, 1, 1); + + label_4 = new QLabel(frame_2); + label_4->setObjectName(QStringLiteral("label_4")); + + gridLayout_2->addWidget(label_4, 1, 0, 1, 1); + + + verticalLayout_2->addWidget(frame_2); + + label_12 = new QLabel(scrollAreaWidgetContents); + label_12->setObjectName(QStringLiteral("label_12")); + + verticalLayout_2->addWidget(label_12); + + frame_5 = new QFrame(scrollAreaWidgetContents); + frame_5->setObjectName(QStringLiteral("frame_5")); + frame_5->setFrameShape(QFrame::StyledPanel); + frame_5->setFrameShadow(QFrame::Raised); + verticalLayout_3 = new QVBoxLayout(frame_5); + verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3")); + enableMoveLabelsCheckBox = new QCheckBox(frame_5); + enableMoveLabelsCheckBox->setObjectName(QStringLiteral("enableMoveLabelsCheckBox")); + enableMoveLabelsCheckBox->setChecked(true); + + verticalLayout_3->addWidget(enableMoveLabelsCheckBox); + + enableResizeLabelsCheckBox = new QCheckBox(frame_5); + enableResizeLabelsCheckBox->setObjectName(QStringLiteral("enableResizeLabelsCheckBox")); + enableResizeLabelsCheckBox->setChecked(true); + + verticalLayout_3->addWidget(enableResizeLabelsCheckBox); + + labelDistanceLabel = new QLabel(frame_5); + labelDistanceLabel->setObjectName(QStringLiteral("labelDistanceLabel")); + + verticalLayout_3->addWidget(labelDistanceLabel); + + labelDistanceSlider = new QSlider(frame_5); + labelDistanceSlider->setObjectName(QStringLiteral("labelDistanceSlider")); + labelDistanceSlider->setMaximum(500); + labelDistanceSlider->setOrientation(Qt::Horizontal); + + verticalLayout_3->addWidget(labelDistanceSlider); + + + verticalLayout_2->addWidget(frame_5); + + label_8 = new QLabel(scrollAreaWidgetContents); + label_8->setObjectName(QStringLiteral("label_8")); + + verticalLayout_2->addWidget(label_8); + + frame_9 = new QFrame(scrollAreaWidgetContents); + frame_9->setObjectName(QStringLiteral("frame_9")); + frame_9->setFrameShape(QFrame::StyledPanel); + frame_9->setFrameShadow(QFrame::Raised); + gridLayout_7 = new QGridLayout(frame_9); + gridLayout_7->setObjectName(QStringLiteral("gridLayout_7")); + label_6 = new QLabel(frame_9); + label_6->setObjectName(QStringLiteral("label_6")); + + gridLayout_7->addWidget(label_6, 0, 0, 1, 1); + + label_7 = new QLabel(frame_9); + label_7->setObjectName(QStringLiteral("label_7")); + + gridLayout_7->addWidget(label_7, 1, 0, 1, 1); + + paletteComboBox = new QComboBox(frame_9); + paletteComboBox->setObjectName(QStringLiteral("paletteComboBox")); + paletteComboBox->setLayoutDirection(Qt::LeftToRight); + paletteComboBox->setEditable(false); + paletteComboBox->setFrame(true); + + gridLayout_7->addWidget(paletteComboBox, 0, 1, 1, 1); + + paletteSpinBox = new QSpinBox(frame_9); + paletteSpinBox->setObjectName(QStringLiteral("paletteSpinBox")); + paletteSpinBox->setMinimum(1); + paletteSpinBox->setMaximum(5); + + gridLayout_7->addWidget(paletteSpinBox, 1, 1, 1, 1); + + + verticalLayout_2->addWidget(frame_9); + + verticalSpacer_2 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + verticalLayout_2->addItem(verticalSpacer_2); + + scrollArea->setWidget(scrollAreaWidgetContents); + + verticalLayout->addWidget(scrollArea); + + + retranslateUi(PreferencesEditorPage); + + paletteComboBox->setCurrentIndex(1); + + + QMetaObject::connectSlotsByName(PreferencesEditorPage); + } // setupUi + + void retranslateUi(QWidget *PreferencesEditorPage) + { + label_5->setText(QApplication::translate("PreferencesEditorPage", "Font", 0)); + fontCheckBox->setText(QApplication::translate("PreferencesEditorPage", "Use some of system fonts", 0)); + fontSelectionButton->setText(QApplication::translate("PreferencesEditorPage", "Choose Font", 0)); + label->setText(QApplication::translate("PreferencesEditorPage", "Grid", 0)); + activateAlignmentCheckBox->setText(QApplication::translate("PreferencesEditorPage", "Activate alignment", 0)); + label_20->setText(QApplication::translate("PreferencesEditorPage", "Cell size", 0)); + activateGridCheckBox->setText(QApplication::translate("PreferencesEditorPage", "Activate grid", 0)); + label_13->setText(QApplication::translate("PreferencesEditorPage", "Width", 0)); + showGridCheckBox->setText(QApplication::translate("PreferencesEditorPage", "Show grid", 0)); + showAlignmentCheckBox->setText(QApplication::translate("PreferencesEditorPage", "Show alignment", 0)); + label_14->setText(QApplication::translate("PreferencesEditorPage", "Node Elements", 0)); + label_15->setText(QApplication::translate("PreferencesEditorPage", "Drag area", 0)); + label_9->setText(QApplication::translate("PreferencesEditorPage", "Edge", 0)); + lineMode->clear(); + lineMode->insertItems(0, QStringList() + << QApplication::translate("PreferencesEditorPage", "unset", 0) + << QApplication::translate("PreferencesEditorPage", "broken", 0) + << QApplication::translate("PreferencesEditorPage", "square", 0) + << QApplication::translate("PreferencesEditorPage", "curve", 0) + ); + label_10->setText(QApplication::translate("PreferencesEditorPage", "Line mode", 0)); + label_11->setText(QApplication::translate("PreferencesEditorPage", "Loop edges indent", 0)); + label_2->setText(QApplication::translate("PreferencesEditorPage", "Embedded Linkers", 0)); + label_3->setText(QApplication::translate("PreferencesEditorPage", "Size", 0)); + label_4->setText(QApplication::translate("PreferencesEditorPage", "Indent", 0)); + label_12->setText(QApplication::translate("PreferencesEditorPage", "Labels", 0)); + enableMoveLabelsCheckBox->setText(QApplication::translate("PreferencesEditorPage", "Enable move", 0)); + enableResizeLabelsCheckBox->setText(QApplication::translate("PreferencesEditorPage", "Enable resize", 0)); + labelDistanceLabel->setText(QApplication::translate("PreferencesEditorPage", "Label distance", 0)); + label_8->setText(QApplication::translate("PreferencesEditorPage", "Palette", 0)); + label_6->setText(QApplication::translate("PreferencesEditorPage", " Representation ", 0)); + label_7->setText(QApplication::translate("PreferencesEditorPage", " Count of items in a row ", 0)); + paletteComboBox->clear(); + paletteComboBox->insertItems(0, QStringList() + << QApplication::translate("PreferencesEditorPage", "Icons and names", 0) + << QApplication::translate("PreferencesEditorPage", "Icons", 0) + ); + Q_UNUSED(PreferencesEditorPage); + } // retranslateUi + +}; + +namespace Ui { + class PreferencesEditorPage: public Ui_PreferencesEditorPage {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_EDITORPAGE_H diff --git a/configurationServer/gui/ui_featuresPage.h b/configurationServer/gui/ui_featuresPage.h new file mode 100644 index 0000000..3dba063 --- /dev/null +++ b/configurationServer/gui/ui_featuresPage.h @@ -0,0 +1,128 @@ +/******************************************************************************** +** Form generated from reading UI file 'featuresPage.ui' +** +** Created by: Qt User Interface Compiler version 5.2.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_FEATURESPAGE_H +#define UI_FEATURESPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_PreferencesFeaturesPage +{ +public: + QVBoxLayout *verticalLayout; + QLabel *label_1; + QFrame *frame_1; + QGridLayout *gridLayout; + QCheckBox *gesturesCheckBox; + QLabel *label; + QLabel *label_2; + QCheckBox *embeddedLinkersCheckBox; + QLabel *label_3; + QCheckBox *embeddedControlsCheckBox; + QSpacerItem *verticalSpacer; + + void setupUi(QWidget *PreferencesFeaturesPage) + { + if (PreferencesFeaturesPage->objectName().isEmpty()) + PreferencesFeaturesPage->setObjectName(QStringLiteral("PreferencesFeaturesPage")); + PreferencesFeaturesPage->resize(500, 300); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(PreferencesFeaturesPage->sizePolicy().hasHeightForWidth()); + PreferencesFeaturesPage->setSizePolicy(sizePolicy); + verticalLayout = new QVBoxLayout(PreferencesFeaturesPage); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + label_1 = new QLabel(PreferencesFeaturesPage); + label_1->setObjectName(QStringLiteral("label_1")); + + verticalLayout->addWidget(label_1); + + frame_1 = new QFrame(PreferencesFeaturesPage); + frame_1->setObjectName(QStringLiteral("frame_1")); + frame_1->setFrameShape(QFrame::StyledPanel); + frame_1->setFrameShadow(QFrame::Raised); + gridLayout = new QGridLayout(frame_1); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gesturesCheckBox = new QCheckBox(frame_1); + gesturesCheckBox->setObjectName(QStringLiteral("gesturesCheckBox")); + + gridLayout->addWidget(gesturesCheckBox, 0, 0, 1, 1); + + label = new QLabel(frame_1); + label->setObjectName(QStringLiteral("label")); + + gridLayout->addWidget(label, 0, 1, 1, 1); + + label_2 = new QLabel(frame_1); + label_2->setObjectName(QStringLiteral("label_2")); + + gridLayout->addWidget(label_2, 1, 1, 1, 1); + + embeddedLinkersCheckBox = new QCheckBox(frame_1); + embeddedLinkersCheckBox->setObjectName(QStringLiteral("embeddedLinkersCheckBox")); + + gridLayout->addWidget(embeddedLinkersCheckBox, 1, 0, 1, 1); + + label_3 = new QLabel(frame_1); + label_3->setObjectName(QStringLiteral("label_3")); + + gridLayout->addWidget(label_3, 2, 1, 1, 1); + + embeddedControlsCheckBox = new QCheckBox(frame_1); + embeddedControlsCheckBox->setObjectName(QStringLiteral("embeddedControlsCheckBox")); + + gridLayout->addWidget(embeddedControlsCheckBox, 2, 0, 1, 1); + + + verticalLayout->addWidget(frame_1); + + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + verticalLayout->addItem(verticalSpacer); + + + retranslateUi(PreferencesFeaturesPage); + + QMetaObject::connectSlotsByName(PreferencesFeaturesPage); + } // setupUi + + void retranslateUi(QWidget *PreferencesFeaturesPage) + { + label_1->setText(QApplication::translate("PreferencesFeaturesPage", "Element controls", 0)); + gesturesCheckBox->setText(QApplication::translate("PreferencesFeaturesPage", "Gestures", 0)); + label->setText(QApplication::translate("PreferencesFeaturesPage", "fast linking with mouse", 0)); + label_2->setText(QApplication::translate("PreferencesFeaturesPage", "fast linking with mouse", 0)); + embeddedLinkersCheckBox->setText(QApplication::translate("PreferencesFeaturesPage", "Embedded Linkers", 0)); + label_3->setText(QApplication::translate("PreferencesFeaturesPage", "fast property editing", 0)); + embeddedControlsCheckBox->setText(QApplication::translate("PreferencesFeaturesPage", "Embedded Controls", 0)); + Q_UNUSED(PreferencesFeaturesPage); + } // retranslateUi + +}; + +namespace Ui { + class PreferencesFeaturesPage: public Ui_PreferencesFeaturesPage {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_FEATURESPAGE_H diff --git a/configurationServer/gui/ui_hotKeyManagerPage.h b/configurationServer/gui/ui_hotKeyManagerPage.h new file mode 100644 index 0000000..c13a13a --- /dev/null +++ b/configurationServer/gui/ui_hotKeyManagerPage.h @@ -0,0 +1,184 @@ +/******************************************************************************** +** Form generated from reading UI file 'hotKeyManagerPage.ui' +** +** Created by: Qt User Interface Compiler version 5.2.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_HOTKEYMANAGERPAGE_H +#define UI_HOTKEYMANAGERPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hotKeyManager/shortcutEdit.h" + +QT_BEGIN_NAMESPACE + +class Ui_hotKeyManagerPage +{ +public: + QVBoxLayout *verticalLayout_2; + QGroupBox *keyboardShortcutsGroupBox; + QGridLayout *gridLayout; + QSpacerItem *horizontalSpacer; + QPushButton *importPushButton; + QPushButton *exportPushButton; + QTableWidget *hotKeysTable; + QPushButton *resetAllPushButton; + QGroupBox *shortcutGroupBox; + QGridLayout *gridLayout_2; + QPushButton *resetShortcutPushButton; + QSpacerItem *horizontalSpacer_2; + QLabel *label; + ShortcutEdit *shortcutLineEdit; + QSpacerItem *horizontalSpacer_3; + + void setupUi(QWidget *hotKeyManagerPage) + { + if (hotKeyManagerPage->objectName().isEmpty()) + hotKeyManagerPage->setObjectName(QStringLiteral("hotKeyManagerPage")); + hotKeyManagerPage->resize(654, 350); + verticalLayout_2 = new QVBoxLayout(hotKeyManagerPage); + verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2")); + keyboardShortcutsGroupBox = new QGroupBox(hotKeyManagerPage); + keyboardShortcutsGroupBox->setObjectName(QStringLiteral("keyboardShortcutsGroupBox")); + gridLayout = new QGridLayout(keyboardShortcutsGroupBox); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + horizontalSpacer = new QSpacerItem(381, 38, QSizePolicy::Expanding, QSizePolicy::Minimum); + + gridLayout->addItem(horizontalSpacer, 1, 1, 1, 1); + + importPushButton = new QPushButton(keyboardShortcutsGroupBox); + importPushButton->setObjectName(QStringLiteral("importPushButton")); + + gridLayout->addWidget(importPushButton, 1, 2, 1, 1); + + exportPushButton = new QPushButton(keyboardShortcutsGroupBox); + exportPushButton->setObjectName(QStringLiteral("exportPushButton")); + + gridLayout->addWidget(exportPushButton, 1, 3, 1, 1); + + hotKeysTable = new QTableWidget(keyboardShortcutsGroupBox); + if (hotKeysTable->columnCount() < 5) + hotKeysTable->setColumnCount(5); + QTableWidgetItem *__qtablewidgetitem = new QTableWidgetItem(); + hotKeysTable->setHorizontalHeaderItem(0, __qtablewidgetitem); + QTableWidgetItem *__qtablewidgetitem1 = new QTableWidgetItem(); + hotKeysTable->setHorizontalHeaderItem(1, __qtablewidgetitem1); + QTableWidgetItem *__qtablewidgetitem2 = new QTableWidgetItem(); + hotKeysTable->setHorizontalHeaderItem(2, __qtablewidgetitem2); + QTableWidgetItem *__qtablewidgetitem3 = new QTableWidgetItem(); + hotKeysTable->setHorizontalHeaderItem(3, __qtablewidgetitem3); + QTableWidgetItem *__qtablewidgetitem4 = new QTableWidgetItem(); + hotKeysTable->setHorizontalHeaderItem(4, __qtablewidgetitem4); + hotKeysTable->setObjectName(QStringLiteral("hotKeysTable")); + hotKeysTable->setEnabled(true); + hotKeysTable->setMinimumSize(QSize(0, 0)); + hotKeysTable->setFocusPolicy(Qt::WheelFocus); + hotKeysTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + hotKeysTable->setProperty("showDropIndicator", QVariant(false)); + hotKeysTable->setSelectionMode(QAbstractItemView::SingleSelection); + hotKeysTable->setSelectionBehavior(QAbstractItemView::SelectItems); + hotKeysTable->setShowGrid(false); + hotKeysTable->setWordWrap(true); + hotKeysTable->setCornerButtonEnabled(true); + hotKeysTable->setRowCount(0); + hotKeysTable->setColumnCount(5); + hotKeysTable->horizontalHeader()->setDefaultSectionSize(100); + hotKeysTable->horizontalHeader()->setHighlightSections(true); + hotKeysTable->verticalHeader()->setCascadingSectionResizes(false); + hotKeysTable->verticalHeader()->setMinimumSectionSize(19); + hotKeysTable->verticalHeader()->setStretchLastSection(false); + + gridLayout->addWidget(hotKeysTable, 0, 0, 1, 4); + + resetAllPushButton = new QPushButton(keyboardShortcutsGroupBox); + resetAllPushButton->setObjectName(QStringLiteral("resetAllPushButton")); + + gridLayout->addWidget(resetAllPushButton, 1, 0, 1, 1); + + + verticalLayout_2->addWidget(keyboardShortcutsGroupBox); + + shortcutGroupBox = new QGroupBox(hotKeyManagerPage); + shortcutGroupBox->setObjectName(QStringLiteral("shortcutGroupBox")); + gridLayout_2 = new QGridLayout(shortcutGroupBox); + gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); + resetShortcutPushButton = new QPushButton(shortcutGroupBox); + resetShortcutPushButton->setObjectName(QStringLiteral("resetShortcutPushButton")); + + gridLayout_2->addWidget(resetShortcutPushButton, 0, 4, 1, 1); + + horizontalSpacer_2 = new QSpacerItem(10, 20, QSizePolicy::Minimum, QSizePolicy::Minimum); + + gridLayout_2->addItem(horizontalSpacer_2, 0, 3, 1, 1); + + label = new QLabel(shortcutGroupBox); + label->setObjectName(QStringLiteral("label")); + + gridLayout_2->addWidget(label, 0, 1, 1, 1); + + shortcutLineEdit = new ShortcutEdit(shortcutGroupBox); + shortcutLineEdit->setObjectName(QStringLiteral("shortcutLineEdit")); + shortcutLineEdit->setEnabled(false); + shortcutLineEdit->setDragEnabled(false); + shortcutLineEdit->setReadOnly(false); + + gridLayout_2->addWidget(shortcutLineEdit, 0, 2, 1, 1); + + horizontalSpacer_3 = new QSpacerItem(2, 20, QSizePolicy::Minimum, QSizePolicy::Minimum); + + gridLayout_2->addItem(horizontalSpacer_3, 0, 0, 1, 1); + + + verticalLayout_2->addWidget(shortcutGroupBox); + + + retranslateUi(hotKeyManagerPage); + + QMetaObject::connectSlotsByName(hotKeyManagerPage); + } // setupUi + + void retranslateUi(QWidget *hotKeyManagerPage) + { + hotKeyManagerPage->setWindowTitle(QApplication::translate("hotKeyManagerPage", "Form", 0)); + keyboardShortcutsGroupBox->setTitle(QApplication::translate("hotKeyManagerPage", "Keyboard Shortcuts", 0)); + importPushButton->setText(QApplication::translate("hotKeyManagerPage", "Import...", 0)); + exportPushButton->setText(QApplication::translate("hotKeyManagerPage", "Export...", 0)); + QTableWidgetItem *___qtablewidgetitem = hotKeysTable->horizontalHeaderItem(0); + ___qtablewidgetitem->setText(QApplication::translate("hotKeyManagerPage", "Command", 0)); + QTableWidgetItem *___qtablewidgetitem1 = hotKeysTable->horizontalHeaderItem(1); + ___qtablewidgetitem1->setText(QApplication::translate("hotKeyManagerPage", "Label", 0)); + QTableWidgetItem *___qtablewidgetitem2 = hotKeysTable->horizontalHeaderItem(2); + ___qtablewidgetitem2->setText(QApplication::translate("hotKeyManagerPage", "Shortcut 1", 0)); + QTableWidgetItem *___qtablewidgetitem3 = hotKeysTable->horizontalHeaderItem(3); + ___qtablewidgetitem3->setText(QApplication::translate("hotKeyManagerPage", "Shortcut 2", 0)); + QTableWidgetItem *___qtablewidgetitem4 = hotKeysTable->horizontalHeaderItem(4); + ___qtablewidgetitem4->setText(QApplication::translate("hotKeyManagerPage", "Shortcut 3", 0)); + resetAllPushButton->setText(QApplication::translate("hotKeyManagerPage", "Reset All", 0)); + shortcutGroupBox->setTitle(QApplication::translate("hotKeyManagerPage", "Shortcut", 0)); + resetShortcutPushButton->setText(QApplication::translate("hotKeyManagerPage", "Reset", 0)); + label->setText(QApplication::translate("hotKeyManagerPage", "Key sequence", 0)); + } // retranslateUi + +}; + +namespace Ui { + class hotKeyManagerPage: public Ui_hotKeyManagerPage {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_HOTKEYMANAGERPAGE_H diff --git a/configurationServer/gui/ui_miscellaniousPage.h b/configurationServer/gui/ui_miscellaniousPage.h new file mode 100644 index 0000000..5444432 --- /dev/null +++ b/configurationServer/gui/ui_miscellaniousPage.h @@ -0,0 +1,255 @@ +/******************************************************************************** +** Form generated from reading UI file 'miscellaniousPage.ui' +** +** Created by: Qt User Interface Compiler version 5.2.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_MISCELLANIOUSPAGE_H +#define UI_MISCELLANIOUSPAGE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_PreferencesMiscellaniousPage +{ +public: + QGridLayout *gridLayout_4; + QLabel *label_5; + QFrame *frame_3; + QGridLayout *gridLayout; + QCheckBox *antialiasingCheckBox; + QLabel *label_6; + QFrame *frame_4; + QGridLayout *gridLayout_2; + QCheckBox *splashScreenCheckBox; + QLabel *label_8; + QComboBox *colorComboBox; + QCheckBox *paintOldLineCheckBox; + QSpacerItem *horizontalSpacer; + QHBoxLayout *horizontalLayout_4; + QLabel *label_9; + QSpinBox *recentProjectsLimitSpinBox; + QSpacerItem *horizontalSpacer_2; + QLabel *label_7; + QFrame *frame_5; + QGridLayout *gridLayout_3; + QPushButton *imagesPathBrowseButton; + QLineEdit *imagesPathEdit; + QLabel *label; + QFrame *frame; + QHBoxLayout *horizontalLayout; + QLabel *label_2; + QSlider *toolbarSizeSlider; + QSpacerItem *verticalSpacer; + + void setupUi(QWidget *PreferencesMiscellaniousPage) + { + if (PreferencesMiscellaniousPage->objectName().isEmpty()) + PreferencesMiscellaniousPage->setObjectName(QStringLiteral("PreferencesMiscellaniousPage")); + PreferencesMiscellaniousPage->resize(561, 325); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(PreferencesMiscellaniousPage->sizePolicy().hasHeightForWidth()); + PreferencesMiscellaniousPage->setSizePolicy(sizePolicy); + gridLayout_4 = new QGridLayout(PreferencesMiscellaniousPage); + gridLayout_4->setObjectName(QStringLiteral("gridLayout_4")); + label_5 = new QLabel(PreferencesMiscellaniousPage); + label_5->setObjectName(QStringLiteral("label_5")); + + gridLayout_4->addWidget(label_5, 0, 0, 1, 1); + + frame_3 = new QFrame(PreferencesMiscellaniousPage); + frame_3->setObjectName(QStringLiteral("frame_3")); + frame_3->setFrameShape(QFrame::StyledPanel); + frame_3->setFrameShadow(QFrame::Raised); + gridLayout = new QGridLayout(frame_3); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + antialiasingCheckBox = new QCheckBox(frame_3); + antialiasingCheckBox->setObjectName(QStringLiteral("antialiasingCheckBox")); + + gridLayout->addWidget(antialiasingCheckBox, 0, 0, 1, 1); + + + gridLayout_4->addWidget(frame_3, 1, 0, 1, 1); + + label_6 = new QLabel(PreferencesMiscellaniousPage); + label_6->setObjectName(QStringLiteral("label_6")); + + gridLayout_4->addWidget(label_6, 2, 0, 1, 1); + + frame_4 = new QFrame(PreferencesMiscellaniousPage); + frame_4->setObjectName(QStringLiteral("frame_4")); + frame_4->setFrameShape(QFrame::StyledPanel); + frame_4->setFrameShadow(QFrame::Raised); + gridLayout_2 = new QGridLayout(frame_4); + gridLayout_2->setObjectName(QStringLiteral("gridLayout_2")); + splashScreenCheckBox = new QCheckBox(frame_4); + splashScreenCheckBox->setObjectName(QStringLiteral("splashScreenCheckBox")); + + gridLayout_2->addWidget(splashScreenCheckBox, 0, 0, 1, 1); + + label_8 = new QLabel(frame_4); + label_8->setObjectName(QStringLiteral("label_8")); + + gridLayout_2->addWidget(label_8, 3, 2, 1, 1); + + colorComboBox = new QComboBox(frame_4); + colorComboBox->setObjectName(QStringLiteral("colorComboBox")); + colorComboBox->setMinimumSize(QSize(170, 0)); + colorComboBox->setFrame(true); + + gridLayout_2->addWidget(colorComboBox, 3, 3, 1, 1); + + paintOldLineCheckBox = new QCheckBox(frame_4); + paintOldLineCheckBox->setObjectName(QStringLiteral("paintOldLineCheckBox")); + paintOldLineCheckBox->setEnabled(true); + + gridLayout_2->addWidget(paintOldLineCheckBox, 3, 0, 1, 1); + + horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + gridLayout_2->addItem(horizontalSpacer, 3, 1, 1, 1); + + horizontalLayout_4 = new QHBoxLayout(); + horizontalLayout_4->setSpacing(5); + horizontalLayout_4->setObjectName(QStringLiteral("horizontalLayout_4")); + horizontalLayout_4->setSizeConstraint(QLayout::SetDefaultConstraint); + horizontalLayout_4->setContentsMargins(-1, 0, 0, -1); + label_9 = new QLabel(frame_4); + label_9->setObjectName(QStringLiteral("label_9")); + QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Maximum); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(label_9->sizePolicy().hasHeightForWidth()); + label_9->setSizePolicy(sizePolicy1); + label_9->setWordWrap(true); + + horizontalLayout_4->addWidget(label_9); + + recentProjectsLimitSpinBox = new QSpinBox(frame_4); + recentProjectsLimitSpinBox->setObjectName(QStringLiteral("recentProjectsLimitSpinBox")); + QSizePolicy sizePolicy2(QSizePolicy::Fixed, QSizePolicy::Fixed); + sizePolicy2.setHorizontalStretch(0); + sizePolicy2.setVerticalStretch(0); + sizePolicy2.setHeightForWidth(recentProjectsLimitSpinBox->sizePolicy().hasHeightForWidth()); + recentProjectsLimitSpinBox->setSizePolicy(sizePolicy2); + recentProjectsLimitSpinBox->setMaximumSize(QSize(40, 16777215)); + + horizontalLayout_4->addWidget(recentProjectsLimitSpinBox); + + horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Maximum, QSizePolicy::Minimum); + + horizontalLayout_4->addItem(horizontalSpacer_2); + + + gridLayout_2->addLayout(horizontalLayout_4, 0, 2, 1, 2); + + + gridLayout_4->addWidget(frame_4, 3, 0, 1, 1); + + label_7 = new QLabel(PreferencesMiscellaniousPage); + label_7->setObjectName(QStringLiteral("label_7")); + + gridLayout_4->addWidget(label_7, 4, 0, 1, 1); + + frame_5 = new QFrame(PreferencesMiscellaniousPage); + frame_5->setObjectName(QStringLiteral("frame_5")); + frame_5->setFrameShape(QFrame::StyledPanel); + frame_5->setFrameShadow(QFrame::Raised); + gridLayout_3 = new QGridLayout(frame_5); + gridLayout_3->setObjectName(QStringLiteral("gridLayout_3")); + imagesPathBrowseButton = new QPushButton(frame_5); + imagesPathBrowseButton->setObjectName(QStringLiteral("imagesPathBrowseButton")); + + gridLayout_3->addWidget(imagesPathBrowseButton, 0, 1, 1, 1); + + imagesPathEdit = new QLineEdit(frame_5); + imagesPathEdit->setObjectName(QStringLiteral("imagesPathEdit")); + + gridLayout_3->addWidget(imagesPathEdit, 0, 0, 1, 1); + + + gridLayout_4->addWidget(frame_5, 5, 0, 1, 1); + + label = new QLabel(PreferencesMiscellaniousPage); + label->setObjectName(QStringLiteral("label")); + + gridLayout_4->addWidget(label, 6, 0, 1, 1); + + frame = new QFrame(PreferencesMiscellaniousPage); + frame->setObjectName(QStringLiteral("frame")); + frame->setFrameShape(QFrame::StyledPanel); + frame->setFrameShadow(QFrame::Raised); + horizontalLayout = new QHBoxLayout(frame); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); + label_2 = new QLabel(frame); + label_2->setObjectName(QStringLiteral("label_2")); + + horizontalLayout->addWidget(label_2); + + toolbarSizeSlider = new QSlider(frame); + toolbarSizeSlider->setObjectName(QStringLiteral("toolbarSizeSlider")); + toolbarSizeSlider->setMinimum(20); + toolbarSizeSlider->setMaximum(50); + toolbarSizeSlider->setOrientation(Qt::Horizontal); + + horizontalLayout->addWidget(toolbarSizeSlider); + + + gridLayout_4->addWidget(frame, 7, 0, 1, 1); + + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + gridLayout_4->addItem(verticalSpacer, 8, 0, 1, 1); + + + retranslateUi(PreferencesMiscellaniousPage); + + QMetaObject::connectSlotsByName(PreferencesMiscellaniousPage); + } // setupUi + + void retranslateUi(QWidget *PreferencesMiscellaniousPage) + { + label_5->setText(QApplication::translate("PreferencesMiscellaniousPage", "Graphics", 0)); + antialiasingCheckBox->setText(QApplication::translate("PreferencesMiscellaniousPage", "Antialiasing", 0)); + label_6->setText(QApplication::translate("PreferencesMiscellaniousPage", "Other", 0)); + splashScreenCheckBox->setText(QApplication::translate("PreferencesMiscellaniousPage", "Show splashscreen", 0)); + label_8->setText(QApplication::translate("PreferencesMiscellaniousPage", "Color of old line:", 0)); + paintOldLineCheckBox->setText(QApplication::translate("PreferencesMiscellaniousPage", "Paint the old line", 0)); + label_9->setText(QApplication::translate("PreferencesMiscellaniousPage", "Limit recent projects list", 0)); + label_7->setText(QApplication::translate("PreferencesMiscellaniousPage", "Images", 0)); + imagesPathBrowseButton->setText(QApplication::translate("PreferencesMiscellaniousPage", "Browse", 0)); + label->setText(QApplication::translate("PreferencesMiscellaniousPage", "Toolbars", 0)); + label_2->setText(QApplication::translate("PreferencesMiscellaniousPage", "Size", 0)); + Q_UNUSED(PreferencesMiscellaniousPage); + } // retranslateUi + +}; + +namespace Ui { + class PreferencesMiscellaniousPage: public Ui_PreferencesMiscellaniousPage {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_MISCELLANIOUSPAGE_H diff --git a/configurationServer/gui/ui_preferencesDialog.h b/configurationServer/gui/ui_preferencesDialog.h new file mode 100644 index 0000000..2421845 --- /dev/null +++ b/configurationServer/gui/ui_preferencesDialog.h @@ -0,0 +1,153 @@ +/******************************************************************************** +** Form generated from reading UI file 'preferencesDialog.ui' +** +** Created by: Qt User Interface Compiler version 5.2.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_PREFERENCESDIALOG_H +#define UI_PREFERENCESDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_PreferencesDialog +{ +public: + QGridLayout *gridLayout; + QPushButton *okButton; + QPushButton *cancelButton; + QPushButton *applyButton; + QListWidget *listWidget; + QScrollArea *scrollArea; + QWidget *scrollAreaWidgetContents; + QVBoxLayout *verticalLayout; + QStackedWidget *pageContentWigdet; + QWidget *pageContentWigdetPage1; + QPushButton *exportButton; + QPushButton *importButton; + + void setupUi(QDialog *PreferencesDialog) + { + if (PreferencesDialog->objectName().isEmpty()) + PreferencesDialog->setObjectName(QStringLiteral("PreferencesDialog")); + PreferencesDialog->resize(892, 593); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(PreferencesDialog->sizePolicy().hasHeightForWidth()); + PreferencesDialog->setSizePolicy(sizePolicy); + PreferencesDialog->setMinimumSize(QSize(0, 0)); + PreferencesDialog->setMaximumSize(QSize(16777215, 16777215)); + QIcon icon; + icon.addFile(QStringLiteral(":/icons/qreal.png"), QSize(), QIcon::Normal, QIcon::Off); + PreferencesDialog->setWindowIcon(icon); + gridLayout = new QGridLayout(PreferencesDialog); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + okButton = new QPushButton(PreferencesDialog); + okButton->setObjectName(QStringLiteral("okButton")); + + gridLayout->addWidget(okButton, 4, 1, 1, 1); + + cancelButton = new QPushButton(PreferencesDialog); + cancelButton->setObjectName(QStringLiteral("cancelButton")); + + gridLayout->addWidget(cancelButton, 4, 2, 1, 1); + + applyButton = new QPushButton(PreferencesDialog); + applyButton->setObjectName(QStringLiteral("applyButton")); + + gridLayout->addWidget(applyButton, 4, 3, 1, 1); + + listWidget = new QListWidget(PreferencesDialog); + listWidget->setObjectName(QStringLiteral("listWidget")); + QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Expanding); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(listWidget->sizePolicy().hasHeightForWidth()); + listWidget->setSizePolicy(sizePolicy1); + listWidget->setMaximumSize(QSize(500, 16777215)); + listWidget->setFlow(QListView::TopToBottom); + listWidget->setViewMode(QListView::ListMode); + listWidget->setUniformItemSizes(true); + listWidget->setWordWrap(true); + + gridLayout->addWidget(listWidget, 1, 0, 2, 1); + + scrollArea = new QScrollArea(PreferencesDialog); + scrollArea->setObjectName(QStringLiteral("scrollArea")); + scrollArea->setMinimumSize(QSize(0, 0)); + scrollArea->setWidgetResizable(true); + scrollAreaWidgetContents = new QWidget(); + scrollAreaWidgetContents->setObjectName(QStringLiteral("scrollAreaWidgetContents")); + scrollAreaWidgetContents->setGeometry(QRect(0, 0, 610, 509)); + sizePolicy1.setHeightForWidth(scrollAreaWidgetContents->sizePolicy().hasHeightForWidth()); + scrollAreaWidgetContents->setSizePolicy(sizePolicy1); + verticalLayout = new QVBoxLayout(scrollAreaWidgetContents); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + pageContentWigdet = new QStackedWidget(scrollAreaWidgetContents); + pageContentWigdet->setObjectName(QStringLiteral("pageContentWigdet")); + sizePolicy1.setHeightForWidth(pageContentWigdet->sizePolicy().hasHeightForWidth()); + pageContentWigdet->setSizePolicy(sizePolicy1); + pageContentWigdetPage1 = new QWidget(); + pageContentWigdetPage1->setObjectName(QStringLiteral("pageContentWigdetPage1")); + pageContentWigdet->addWidget(pageContentWigdetPage1); + + verticalLayout->addWidget(pageContentWigdet); + + scrollArea->setWidget(scrollAreaWidgetContents); + + gridLayout->addWidget(scrollArea, 2, 1, 1, 3); + + exportButton = new QPushButton(PreferencesDialog); + exportButton->setObjectName(QStringLiteral("exportButton")); + + gridLayout->addWidget(exportButton, 3, 3, 1, 1); + + importButton = new QPushButton(PreferencesDialog); + importButton->setObjectName(QStringLiteral("importButton")); + + gridLayout->addWidget(importButton, 3, 2, 1, 1); + + + retranslateUi(PreferencesDialog); + + listWidget->setCurrentRow(-1); + + + QMetaObject::connectSlotsByName(PreferencesDialog); + } // setupUi + + void retranslateUi(QDialog *PreferencesDialog) + { + PreferencesDialog->setWindowTitle(QApplication::translate("PreferencesDialog", "Preferences", 0)); + okButton->setText(QApplication::translate("PreferencesDialog", "OK", 0)); + cancelButton->setText(QApplication::translate("PreferencesDialog", "Cancel", 0)); + applyButton->setText(QApplication::translate("PreferencesDialog", "Apply", 0)); + exportButton->setText(QApplication::translate("PreferencesDialog", "Export", 0)); + importButton->setText(QApplication::translate("PreferencesDialog", "Import", 0)); + } // retranslateUi + +}; + +namespace Ui { + class PreferencesDialog: public Ui_PreferencesDialog {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_PREFERENCESDIALOG_H diff --git a/configurationServer/gui/ui_widget.h b/configurationServer/gui/ui_widget.h new file mode 100644 index 0000000..44d71ca --- /dev/null +++ b/configurationServer/gui/ui_widget.h @@ -0,0 +1,90 @@ +/******************************************************************************** +** Form generated from reading UI file 'widget.ui' +** +** Created by: Qt User Interface Compiler version 5.2.1 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_WIDGET_H +#define UI_WIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_Widget +{ +public: + QHBoxLayout *horizontalLayout_2; + QListWidget *widgetListOfNames; + QWidget *widgetSettings; + QVBoxLayout *verticalLayout; + + void setupUi(QWidget *Widget) + { + if (Widget->objectName().isEmpty()) + Widget->setObjectName(QStringLiteral("Widget")); + Widget->resize(1003, 429); + horizontalLayout_2 = new QHBoxLayout(Widget); + horizontalLayout_2->setSpacing(0); + horizontalLayout_2->setContentsMargins(11, 11, 11, 11); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + horizontalLayout_2->setContentsMargins(0, 0, 0, 0); + widgetListOfNames = new QListWidget(Widget); + widgetListOfNames->setObjectName(QStringLiteral("widgetListOfNames")); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(widgetListOfNames->sizePolicy().hasHeightForWidth()); + widgetListOfNames->setSizePolicy(sizePolicy); + widgetListOfNames->setMinimumSize(QSize(200, 0)); + widgetListOfNames->setMaximumSize(QSize(200, 16777215)); + widgetListOfNames->setFlow(QListView::TopToBottom); + widgetListOfNames->setViewMode(QListView::ListMode); + widgetListOfNames->setUniformItemSizes(true); + widgetListOfNames->setWordWrap(true); + + horizontalLayout_2->addWidget(widgetListOfNames); + + widgetSettings = new QWidget(Widget); + widgetSettings->setObjectName(QStringLiteral("widgetSettings")); + verticalLayout = new QVBoxLayout(widgetSettings); + verticalLayout->setSpacing(0); + verticalLayout->setContentsMargins(11, 11, 11, 11); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + verticalLayout->setContentsMargins(0, 0, 0, 0); + + horizontalLayout_2->addWidget(widgetSettings); + + + retranslateUi(Widget); + + widgetListOfNames->setCurrentRow(-1); + + + QMetaObject::connectSlotsByName(Widget); + } // setupUi + + void retranslateUi(QWidget *Widget) + { + Widget->setWindowTitle(QApplication::translate("Widget", "Widget", 0)); + } // retranslateUi + +}; + +namespace Ui { + class Widget: public Ui_Widget {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_WIDGET_H diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp new file mode 100644 index 0000000..761781e --- /dev/null +++ b/configurationServer/gui/widget.cpp @@ -0,0 +1,26 @@ +#include "widget.h" +#include "ui_widget.h" + +#include "preferencesDialog.h" + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget) +{ + ui->setupUi(this); +} + +Widget::~Widget() +{ + delete ui; +} + +void Widget::init() +{ + PreferencesDialog * dialog = new PreferencesDialog(); + dialog->init(nullptr, nullptr, nullptr, nullptr); + ui->widgetSettings->layout()->addWidget(dialog); + dialog->setParent(ui->widgetSettings); +// ui->widgetSettings = dialog; +// dialog->show(); +} diff --git a/configurationServer/gui/widget.h b/configurationServer/gui/widget.h new file mode 100644 index 0000000..ab27735 --- /dev/null +++ b/configurationServer/gui/widget.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +namespace Ui { +class Widget; +} + +class Widget : public QWidget +{ + Q_OBJECT + +public: + explicit Widget(QWidget *parent = 0); + ~Widget(); + void init(); + +private: + Ui::Widget *ui; +}; + diff --git a/configurationServer/gui/widget.ui b/configurationServer/gui/widget.ui new file mode 100644 index 0000000..85846fb --- /dev/null +++ b/configurationServer/gui/widget.ui @@ -0,0 +1,95 @@ + + + Widget + + + + 0 + 0 + 1003 + 429 + + + + Widget + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 16777215 + + + + QListView::TopToBottom + + + QListView::ListMode + + + true + + + true + + + -1 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + From 7bbe09fdae57f8bcb93c7f1fd91c2133725c303d Mon Sep 17 00:00:00 2001 From: IlyaNikiforov Date: Fri, 4 Jul 2014 12:44:28 +0400 Subject: [PATCH 05/14] third version of server --- configurationServer/server/kernelDeclSpec.h | 11 ++ configurationServer/server/server.cpp | 115 +++++++++++---- configurationServer/server/server.h | 8 +- configurationServer/server/server.h.autosave | 49 ------- configurationServer/server/server.pro | 8 +- configurationServer/server/server.pro.user | 2 +- .../server/settingsManager.cpp | 134 ++++++++++++++++++ configurationServer/server/settingsManager.h | 91 ++++++++++++ 8 files changed, 338 insertions(+), 80 deletions(-) create mode 100644 configurationServer/server/kernelDeclSpec.h delete mode 100644 configurationServer/server/server.h.autosave create mode 100644 configurationServer/server/settingsManager.cpp create mode 100644 configurationServer/server/settingsManager.h diff --git a/configurationServer/server/kernelDeclSpec.h b/configurationServer/server/kernelDeclSpec.h new file mode 100644 index 0000000..f3fa22e --- /dev/null +++ b/configurationServer/server/kernelDeclSpec.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#ifndef QRKERNEL_EXPORT +# if defined(QRKERNEL_LIBRARY) +# define QRKERNEL_EXPORT Q_DECL_EXPORT +# else +# define QRKERNEL_EXPORT Q_DECL_IMPORT +# endif +#endif diff --git a/configurationServer/server/server.cpp b/configurationServer/server/server.cpp index 341f598..3b7ef54 100644 --- a/configurationServer/server/server.cpp +++ b/configurationServer/server/server.cpp @@ -5,10 +5,29 @@ Server::Server(QWidget *parent) : QDialog(parent), tcpServer(0), - clientSocket(0), + //clientSocket(0), networkSession(0), blockSize(0) { + /// creating widgets: + statusLabel = new QLabel; + + allText = new QTextEdit; + allText ->setReadOnly(true); + + messageText = new QLineEdit; + + sendButton = new QPushButton(tr("Send")); + sendButton->setDisabled(true); + + quitButton = new QPushButton(tr("Quit")); + quitButton->setAutoDefault(false); + + //Qmanager->setValue("abc", "def"); + //Qmanager->setValue("ghi", "jkl"); + + //allText->setText(Qmanager->); + QNetworkConfigurationManager manager; if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) { @@ -38,8 +57,25 @@ Server::Server(QWidget *parent) : /// connecting widgets: connect(sendButton, SIGNAL(clicked()), this, SLOT(sendSettings())); + connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptClientConnection())); + /// adding widgets into the window: + QHBoxLayout *messageLayout = new QHBoxLayout; + messageLayout->addWidget(messageText); + messageLayout->addWidget(sendButton); + + QHBoxLayout *quitLayout = new QHBoxLayout; + quitLayout->addStretch(1); + quitLayout->addWidget(quitButton); + quitLayout->addStretch(1); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(statusLabel); + mainLayout->addWidget(allText); + mainLayout->addLayout(messageLayout); + mainLayout->addLayout(quitLayout); + setLayout(mainLayout); setWindowTitle(tr("Chat Server")); } @@ -79,40 +115,45 @@ void Server::sessionOpened() void Server::acceptClientConnection() { - clientSocket = tcpServer->nextPendingConnection(); + QTcpSocket* clientSocket=tcpServer->nextPendingConnection(); + int idusersocs=clientSocket->socketDescriptor(); + SClients[idusersocs]=clientSocket; + connect(SClients[idusersocs], SIGNAL(readyRead()), this, SLOT(receiveMessage())); + connect(SClients[idusersocs], SIGNAL(disconnected()), this, SLOT(disconnectedFromClient())); + connect(SClients[idusersocs], SIGNAL(disconnected()), SClients[idusersocs], SLOT(deleteLater())); - connect(clientSocket, SIGNAL(readyRead()), this, SLOT(receiveMessage())); - connect(clientSocket, SIGNAL(disconnected()), this, SLOT(disconnectedFromClient())); - connect(clientSocket, SIGNAL(disconnected()), clientSocket, SLOT(deleteLater())); + allText->clear(); + allText->textCursor().insertText("Client connected!\n"); sendButton->setEnabled(true); } -//void Server::receiveMessage() -//{ -// QDataStream in(clientSocket); -// in.setVersion(QDataStream::Qt_5_2); +void Server::receiveMessage() +{ + QTcpSocket* clientSocket = (QTcpSocket*)sender(); + QDataStream in(clientSocket); + in.setVersion(QDataStream::Qt_5_2); -// if (blockSize == 0) -// { -// if (clientSocket->bytesAvailable() < (int)sizeof(quint16)) -// return; + if (blockSize == 0) + { + if (clientSocket->bytesAvailable() < (int)sizeof(quint16)) + return; -// in >> blockSize; -// } + in >> blockSize; + } -// if (clientSocket->bytesAvailable() < blockSize) -// return; + if (clientSocket->bytesAvailable() < blockSize) + return; -// blockSize = 0; -// QString newMessage; -// in >> newMessage; -// allText ->textCursor().insertText("Client: " + newMessage + '\n'); -//} + blockSize = 0; + QString newMessage; + in >> newMessage; + allText ->textCursor().insertText("Client: " + newMessage + '\n'); +} -//void Server::sendMessage() +//void Server::sendSettings() //{ -// if(clientSocket) +// if(!SClients.isEmpty()) // { // if (messageText->text().isEmpty()) // return; @@ -123,7 +164,10 @@ void Server::acceptClientConnection() // out << (quint16)messageText->text().length(); // out << messageText->text(); -// clientSocket->write(block); +// foreach(int i,SClients.keys()) +// { +// SClients[i]->write(block); +// } // allText ->textCursor().insertText("You: " + messageText->text() + '\n'); @@ -135,7 +179,28 @@ void Server::acceptClientConnection() void Server::sendSettings() { + if(!SClients.isEmpty()) + { + //if (messageText->text().isEmpty()) + // return; + sendButton->setDisabled(true); + + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out << (quint16)qReal::SettingsManager::instance()->convertToString().length(); + out << qReal::SettingsManager::instance()->convertToString(); + foreach(int i, SClients.keys()) + { + SClients[i]->write(block); + } + + allText ->textCursor().insertText("You: " + qReal::SettingsManager::instance()->convertToString() + '\n'); + + messageText->clear(); + + sendButton->setEnabled(true); + } } void Server::clientDisconnected() diff --git a/configurationServer/server/server.h b/configurationServer/server/server.h index e2df8c2..5e0548f 100644 --- a/configurationServer/server/server.h +++ b/configurationServer/server/server.h @@ -8,6 +8,8 @@ #include #include +#include "settingsManager.h" + namespace Ui { class Server; } @@ -22,9 +24,8 @@ class Server : public QDialog private slots: void sessionOpened(); void acceptClientConnection(); - //void sendMessage(); void sendSettings(); - //void receiveMessage(); + void receiveMessage(); void clientDisconnected(); private: @@ -41,8 +42,9 @@ private slots: QTcpServer *tcpServer; - QTcpSocket *clientSocket; QNetworkSession *networkSession; + QMap SClients; + //qReal::SettingsManager *Qmanager; quint16 blockSize; }; diff --git a/configurationServer/server/server.h.autosave b/configurationServer/server/server.h.autosave deleted file mode 100644 index f6a5819..0000000 --- a/configurationServer/server/server.h.autosave +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef SERVER_H -#define SERVER_H - -#include -#include -#include -#include -#include -#include - -namespace Ui { -class Server; -} - -class Server : public QDialog -{ - Q_OBJECT - -public: - explicit Server(QWidget *parent = 0); - -private slots: - void sessionOpened(); - void acceptClientConnection(); - void sendMessage(); - void receiveMessage(); - void clientDisconnected(); - -private: - /// labels: - QLabel *statusLabel; - - /// text widgets: - QLineEdit *messageText; - QTextEdit *allText; - - /// buttons: - QPushButton *sendButton; - QPushButton *quitButton; - - - QTcpServer *tcpServer; - QNetworkSession *networkSession; - QMap SClients; - - quint16 blockSize; -}; - -#endif // SERVER_H diff --git a/configurationServer/server/server.pro b/configurationServer/server/server.pro index dcd6e0e..b485fe8 100644 --- a/configurationServer/server/server.pro +++ b/configurationServer/server/server.pro @@ -1,8 +1,12 @@ -HEADERS = server.h +HEADERS = server.h \ + settingsManager.h \ + kernelDeclSpec.h SOURCES = server.cpp \ - main.cpp + main.cpp \ + settingsManager.cpp QT += network QT += core gui widgets + CONFIG += c++11 # install target.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneserver diff --git a/configurationServer/server/server.pro.user b/configurationServer/server/server.pro.user index f714fcf..b3ecc44 100644 --- a/configurationServer/server/server.pro.user +++ b/configurationServer/server/server.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget diff --git a/configurationServer/server/settingsManager.cpp b/configurationServer/server/settingsManager.cpp new file mode 100644 index 0000000..b8aeda5 --- /dev/null +++ b/configurationServer/server/settingsManager.cpp @@ -0,0 +1,134 @@ +#include "settingsManager.h" + +#include +#include +#include +#include + +using namespace qReal; + +SettingsManager* SettingsManager::mInstance = nullptr; + +SettingsManager::SettingsManager() + : mSettings("SPbSU", "QReal") +{ + initDefaultValues(); + load(); +} + +SettingsManager::~SettingsManager() +{ +} + +void SettingsManager::setValue(QString const &name, QVariant const &value) +{ + QVariant const oldValue = instance()->value(name); + if (oldValue != value) { + instance()->set(name, value); + emit instance()->settingsChanged(name, oldValue, value); + } +} + +QVariant SettingsManager::value(QString const &key) +{ + return instance()->get(key); +} + +QVariant SettingsManager::value(QString const &key, QVariant const &defaultValue) +{ + return instance()->get(key, defaultValue); +} + +SettingsManager* SettingsManager::instance() +{ + if (mInstance == nullptr) { + mInstance = new SettingsManager(); + } + + return mInstance; +} + +void SettingsManager::set(QString const &name, QVariant const &value) +{ + mData[name] = value; +} + +QVariant SettingsManager::get(QString const &name, QVariant const &defaultValue) const +{ + if (mData.contains(name)) { + return mData[name]; + } + + if (mDefaultValues.contains(name) && defaultValue == QVariant()) { + return mDefaultValues[name]; + } + + return defaultValue; +} + +void SettingsManager::saveData() +{ + for (QString const &name : mData.keys()) { + mSettings.setValue(name, mData[name]); + } + + mSettings.sync(); +} + +void SettingsManager::saveSettings(QString const &fileNameForExport) +{ + QSettings settingsForSave(fileNameForExport, QSettings::IniFormat); + for (QString const &name : mData.keys()) { + settingsForSave.setValue(name, mData[name]); + } + + settingsForSave.sync(); +} + +void SettingsManager::load() +{ + for (QString const &name : mSettings.allKeys()) { + mData[name] = mSettings.value(name); + } +} + +void SettingsManager::loadSettings(QString const &fileNameForImport) +{ + mergeSettings(fileNameForImport, mData); + saveData(); +} + +void SettingsManager::initDefaultValues() +{ + mergeSettings(":/settingsDefaultValues", mDefaultValues); +} + +void SettingsManager::loadDefaultSettings(QString const &filePath) +{ + instance()->mergeSettings(filePath, instance()->mDefaultValues); +} + +void SettingsManager::mergeSettings(QString const &fileNameForImport, QHash &target) +{ + QSettings settings(fileNameForImport, QSettings::IniFormat); + for (QString const &name : settings.allKeys()) { + target[name] = settings.value(name); + } +} + +void SettingsManager::clearSettings() +{ + instance()->mSettings.clear(); + instance()->mData.clear(); + instance()->mDefaultValues.clear(); +} + +QString SettingsManager::convertToString() +{ + QString allSettings; + QStringList keyList = mSettings.allKeys(); + for (int i = 0; i < keyList.size(); i++) + allSettings += keyList[i] + "###" + value(keyList[i]).toString() + "#*#"; + + return allSettings; +} diff --git a/configurationServer/server/settingsManager.h b/configurationServer/server/settingsManager.h new file mode 100644 index 0000000..9f680e2 --- /dev/null +++ b/configurationServer/server/settingsManager.h @@ -0,0 +1,91 @@ +#pragma once + +#include +#include +#include +#include + +#include "kernelDeclSpec.h" + +namespace qReal { + +/// Singleton class that allows to change settings in run-time +/// (replaces QSettings). Purpose of this class is to allow two instances +/// of an application coexist without changing each other's settings, +/// by storing settings separately in memory for each instance and syncing +/// them only on start/exit. +class SettingsManager : public QObject +{ + Q_OBJECT + +public: + /// Get value associated with given key from settings. + /// @param key Parameter name. + /// @returns Variant with parameter value. + static QVariant value(QString const &key); + + /// Get value associated with given key from settings with given default value. + /// @param key Parameter name. + /// @param defaultValue Default value, used when parameter not found. + /// @returns Variant with parameter value. + static QVariant value(QString const &key, QVariant const &defaultValue); + + /// Set value associated with given key. + /// @param key Parameter name. + /// @param value Parameter value. + static void setValue(QString const &key, QVariant const &value); + + /// Removes all entries in persistent external storage + static void clearSettings(); + + /// Returns an instance of a singleton. + static SettingsManager *instance(); + + /// Saves settings into persistent external storage (for example, Windows + /// registry), making them available to new instances of an application. + void saveData(); + + /// Saves settings into selected file with name fileNameForExport. + void saveSettings(QString const &fileNameForExport); + + /// Loads settings from persistent external storage into SettingsManager. + void load(); + + /// Merges settings from the given file in INI format. + void loadSettings(QString const &fileNameForImport); + + /// Merges default settings from the given file in INI format. + static void loadDefaultSettings(QString const &filePath); + + /// Convertes settings into QString + QString convertToString(); + +signals: + /// Emitted each time when settings with the given key were modified. + /// For connection instance() method can be useful. + void settingsChanged(QString const &name, QVariant const &oldValue, QVariant const &newValue); + +private: + /// Private constructor. + SettingsManager(); + ~SettingsManager(); + + void set(QString const &name, QVariant const &value); + QVariant get(QString const &key, QVariant const &defaultValue = QVariant()) const; + + /// Merges settings from the given file in INI format into the given map. + void mergeSettings(QString const &fileNameForImport, QHash &target); + + void initDefaultValues(); + + /// Singleton sole instance. + static SettingsManager *mInstance; + + /// In-memory settings storage. + QHash mData; + QHash mDefaultValues; + /// Persistent settings storage. + QSettings mSettings; +}; + +} From 903b8507b25a32b79a54b0c251bdf265616b196a Mon Sep 17 00:00:00 2001 From: dyma96 Date: Fri, 4 Jul 2014 12:53:41 +0400 Subject: [PATCH 06/14] + saveButton --- configurationServer/gui/gui.pro.user | 248 ------------------ configurationServer/gui/main.cpp | 5 +- configurationServer/gui/preferencesDialog.cpp | 5 + .../gui/preferencesPages/editorPage.cpp | 2 +- .../gui/ui_preferencesDialog.h | 7 + configurationServer/gui/widget.cpp | 6 +- 6 files changed, 17 insertions(+), 256 deletions(-) delete mode 100644 configurationServer/gui/gui.pro.user diff --git a/configurationServer/gui/gui.pro.user b/configurationServer/gui/gui.pro.user deleted file mode 100644 index 11376ae..0000000 --- a/configurationServer/gui/gui.pro.user +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - true - 1 - true - 0 - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - - ProjectExplorer.Project.Target.0 - - Desktop Qt 5.2.1 MinGW 32bit - Desktop Qt 5.2.1 MinGW 32bit - qt.521.win32_mingw48.essentials_kit - 0 - 0 - 0 - - D:/proga/SummerSchool/tools/configurationServer/gui - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - true - - false - - - true - Сборка - - Qt4ProjectManager.MakeStep - - false - - - - 2 - Сборка - - ProjectExplorer.BuildSteps.Build - - - - true - Сборка - - Qt4ProjectManager.MakeStep - - true - clean - - - 1 - Очистка - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Отладка - - Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - - D:/proga/SummerSchool/tools/configurationServer/build-gui-Desktop_Qt_5_2_1_MinGW_32bit-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - true - - false - - - true - Сборка - - Qt4ProjectManager.MakeStep - - false - - - - 2 - Сборка - - ProjectExplorer.BuildSteps.Build - - - - true - Сборка - - Qt4ProjectManager.MakeStep - - true - clean - - - 1 - Очистка - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Выпуск - - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - 2 - - - 0 - Установка - - ProjectExplorer.BuildSteps.Deploy - - 1 - Локальная установка - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - gui - - Qt4ProjectManager.Qt4RunConfiguration:D:/proga/SummerSchool/tools/configurationServer/gui/gui.pro - - gui.pro - false - false - - 3768 - true - false - false - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.EnvironmentId - {68757a80-8684-4ace-adf5-8193ba9b0a3b} - - - ProjectExplorer.Project.Updater.FileVersion - 15 - - diff --git a/configurationServer/gui/main.cpp b/configurationServer/gui/main.cpp index 2e24f5a..083c605 100644 --- a/configurationServer/gui/main.cpp +++ b/configurationServer/gui/main.cpp @@ -1,12 +1,9 @@ #include -#include "preferencesDialog.h" #include "widget.h" + int main(int argc, char *argv[]) { QApplication a(argc, argv); -// PreferencesDialog w; -// w.init(nullptr, nullptr, nullptr, nullptr); -// w.show(); Widget w; w.init(); w.show(); diff --git a/configurationServer/gui/preferencesDialog.cpp b/configurationServer/gui/preferencesDialog.cpp index 3887060..ee45b86 100644 --- a/configurationServer/gui/preferencesDialog.cpp +++ b/configurationServer/gui/preferencesDialog.cpp @@ -52,6 +52,7 @@ void PreferencesDialog::init(QAction * const showGridAction, QAction * const sho connect(mUi->cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); connect(mUi->exportButton, SIGNAL(clicked()), this, SLOT(exportSettings())); connect(mUi->importButton, SIGNAL(clicked()), this, SLOT(importSettings())); + connect(mUi->saveButton, SIGNAL(clicked()), this, SLOT(applyChanges())); connect(editorPage, SIGNAL(gridChanged()), this, SIGNAL(gridChanged())); connect(editorPage, SIGNAL(fontChanged()), this, SIGNAL(fontChanged())); @@ -179,4 +180,8 @@ void PreferencesDialog::importSettings() QString fileNameForImport = QRealFileDialog::getOpenFileName("OpenEnginePreferences", this , tr("Open File"),"/mySettings",tr("*.ini")); SettingsManager::instance()->loadSettings(fileNameForImport); + + foreach (PreferencesPage *page, mCustomPages.values()) { + page->restoreSettings(); + } } diff --git a/configurationServer/gui/preferencesPages/editorPage.cpp b/configurationServer/gui/preferencesPages/editorPage.cpp index 4c17705..c2621b4 100644 --- a/configurationServer/gui/preferencesPages/editorPage.cpp +++ b/configurationServer/gui/preferencesPages/editorPage.cpp @@ -130,7 +130,7 @@ void PreferencesEditorPage::save() SettingsManager::setValue("IndexGrid", mIndexGrid); SettingsManager::setValue("DragArea", mDragArea); - mShowGridAction->setChecked(mUi->showGridCheckBox->isChecked()); + mShowGridAction->setChecked(mUi->showGridCheckBox->isChecked()); mShowAlignmentAction->setChecked(mUi->showAlignmentCheckBox->isChecked()); mActivateGridAction->setChecked(mUi->activateGridCheckBox->isChecked()); mActivateAlignmentAction->setChecked(mUi->activateAlignmentCheckBox->isChecked()); diff --git a/configurationServer/gui/ui_preferencesDialog.h b/configurationServer/gui/ui_preferencesDialog.h index 2421845..af46118 100644 --- a/configurationServer/gui/ui_preferencesDialog.h +++ b/configurationServer/gui/ui_preferencesDialog.h @@ -40,6 +40,7 @@ class Ui_PreferencesDialog QWidget *pageContentWigdetPage1; QPushButton *exportButton; QPushButton *importButton; + QPushButton *saveButton; void setupUi(QDialog *PreferencesDialog) { @@ -73,6 +74,11 @@ class Ui_PreferencesDialog gridLayout->addWidget(applyButton, 4, 3, 1, 1); + saveButton = new QPushButton(PreferencesDialog); + saveButton->setObjectName(QStringLiteral("saveButton")); + + gridLayout->addWidget(saveButton, 3, 1, 1, 1); + listWidget = new QListWidget(PreferencesDialog); listWidget->setObjectName(QStringLiteral("listWidget")); QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Expanding); @@ -140,6 +146,7 @@ class Ui_PreferencesDialog applyButton->setText(QApplication::translate("PreferencesDialog", "Apply", 0)); exportButton->setText(QApplication::translate("PreferencesDialog", "Export", 0)); importButton->setText(QApplication::translate("PreferencesDialog", "Import", 0)); + saveButton->setText(QApplication::translate("PreferenceDialog", "Save", 0)); } // retranslateUi }; diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp index 761781e..812009c 100644 --- a/configurationServer/gui/widget.cpp +++ b/configurationServer/gui/widget.cpp @@ -3,6 +3,8 @@ #include "preferencesDialog.h" +#include + Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) @@ -18,9 +20,7 @@ Widget::~Widget() void Widget::init() { PreferencesDialog * dialog = new PreferencesDialog(); - dialog->init(nullptr, nullptr, nullptr, nullptr); + dialog->init(new QAction(dialog), new QAction(dialog), new QAction(dialog), new QAction(dialog)); ui->widgetSettings->layout()->addWidget(dialog); dialog->setParent(ui->widgetSettings); -// ui->widgetSettings = dialog; -// dialog->show(); } From 5e5e6074c6730b2db05fcb6d5b879925e9b6617f Mon Sep 17 00:00:00 2001 From: IlyaNikiforov Date: Fri, 4 Jul 2014 15:52:14 +0400 Subject: [PATCH 07/14] final version of server and new client --- configurationServer/client/8_1client.pro | 26 ++ configurationServer/client/client.cpp | 220 ++++++++++++++++ configurationServer/client/client.h | 53 ++++ configurationServer/client/client.ui | 24 ++ configurationServer/client/main.cpp | 11 + configurationServer/gui/gui.pro | 11 +- configurationServer/gui/gui.pro.user | 248 ++++++++++++++++++ .../gui/qrkernel/settingsManager.cpp | 10 + .../gui/qrkernel/settingsManager.h | 3 + configurationServer/gui/server/main.cpp | 11 + configurationServer/gui/server/server.cpp | 114 ++++++++ configurationServer/gui/server/server.h | 36 +++ configurationServer/gui/server/server.pro | 27 ++ configurationServer/gui/widget.cpp | 21 +- configurationServer/gui/widget.h | 5 + 15 files changed, 810 insertions(+), 10 deletions(-) create mode 100644 configurationServer/client/8_1client.pro create mode 100644 configurationServer/client/client.cpp create mode 100644 configurationServer/client/client.h create mode 100644 configurationServer/client/client.ui create mode 100644 configurationServer/client/main.cpp create mode 100644 configurationServer/gui/gui.pro.user create mode 100644 configurationServer/gui/server/main.cpp create mode 100644 configurationServer/gui/server/server.cpp create mode 100644 configurationServer/gui/server/server.h create mode 100644 configurationServer/gui/server/server.pro diff --git a/configurationServer/client/8_1client.pro b/configurationServer/client/8_1client.pro new file mode 100644 index 0000000..1eeb9a7 --- /dev/null +++ b/configurationServer/client/8_1client.pro @@ -0,0 +1,26 @@ +HEADERS = client.h + SOURCES = client.cpp \ + main.cpp + QT += network + QT += core gui + QT += widgets + + + # install + target.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneclient + sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS fortuneclient.pro + sources.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneclient + INSTALLS += target sources + + symbian { + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) + TARGET.CAPABILITY = "NetworkServices ReadUserData WriteUserData" + TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 + } + maemo5: include($$QT_SOURCE_TREE/examples/maemo5pkgrules.pri) + + symbian: warning(This example might not fully work on Symbian platform) + maemo5: warning(This example might not fully work on Maemo platform) + simulator: warning(This example might not fully work on Simulator platform) + +FORMS += diff --git a/configurationServer/client/client.cpp b/configurationServer/client/client.cpp new file mode 100644 index 0000000..6fd71a4 --- /dev/null +++ b/configurationServer/client/client.cpp @@ -0,0 +1,220 @@ +#include "client.h" + +Client::Client(QWidget *parent) : + QDialog(parent), + networkSession(0), + blockSize(0) +{ + + setWindowTitle(tr("Chat client")); + + /// creating buttons and text: + hostLabel = new QLabel(tr("Server IP-adress:")); + + portLabel = new QLabel(tr("Server port:")); + + portLineEdit = new QLineEdit; + portLineEdit->setValidator(new QIntValidator(1, 65535)); + + messageText = new QLineEdit; + + sendButton = new QPushButton(tr("Send")); + sendButton->setDisabled(true); + + connectButton = new QPushButton(tr("Connect")); + + quitButton = new QPushButton(tr("Quit")); + quitButton->setAutoDefault(false); + + chatText = new QTextEdit; + chatText->setReadOnly(true); + + /// adding adresses to combo box + hostAdress = new QComboBox; + QList adressList = QNetworkInterface::allAddresses(); + + for (int i = 0; i < adressList.size(); ++i) + { + hostAdress->addItem(adressList.at(i).toString()); + } + + serverSocket = new QTcpSocket; + + ///adding operation to buttons: + connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); + connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); + connect(serverSocket, SIGNAL(readyRead()), this, SLOT(receiveMessage())); + connect(connectButton, SIGNAL(clicked()), this, SLOT(connectToServer())); + connect(serverSocket, SIGNAL(disconnected()), this, SLOT(disconnectedFromServer())); + connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(displayError(QAbstractSocket::SocketError))); + + /// adding widgets into the window: + QGridLayout *connectionLayout = new QGridLayout; + connectionLayout->addWidget(hostLabel, 0, 0); + connectionLayout->addWidget(hostAdress, 0, 1); + connectionLayout->addWidget(portLabel, 1, 0); + connectionLayout->addWidget(portLineEdit, 1, 1); + + QHBoxLayout *messageLayout = new QHBoxLayout; + messageLayout->addWidget(messageText); + messageLayout->addWidget(sendButton); + + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addStretch(1); + buttonLayout->addWidget(connectButton); + buttonLayout->addStretch(1); + buttonLayout->addWidget(quitButton); + buttonLayout->addStretch(1); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addLayout(connectionLayout); + mainLayout->addWidget(chatText); + mainLayout->addLayout(messageLayout); + mainLayout->addLayout(buttonLayout); + setLayout(mainLayout); + + portLineEdit->setFocus(); + + QNetworkConfigurationManager manager; + if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) + { + // Get saved network configuration + QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); + settings.beginGroup(QLatin1String("QtNetwork")); + const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString(); + settings.endGroup(); + + // If the saved network configuration is not currently discovered use the system default + QNetworkConfiguration config = manager.configurationFromIdentifier(id); + if ((config.state() & QNetworkConfiguration::Discovered) != + QNetworkConfiguration::Discovered) + { + config = manager.defaultConfiguration(); + } + + networkSession = new QNetworkSession(config, this); + connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); + + networkSession->open(); + } +} + +void Client::receiveMessage() +{ + QDataStream in(serverSocket); + in.setVersion(QDataStream::Qt_5_2); + + if (blockSize == 0) + { + if (serverSocket->bytesAvailable() < (int)sizeof(quint16)) + return; + + in >> blockSize; + } + + if (serverSocket->bytesAvailable() < blockSize) + return; + + blockSize = 0; + QString newMessage; + in >> newMessage; + chatText->textCursor().insertText("Server: " + newMessage + '\n'); +} + +void Client::sendMessage() +{ + if (messageText->text().isEmpty()) + return; + sendButton->setEnabled(false); + + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out << (quint16)messageText->text().length(); + out << messageText->text(); + serverSocket->write(block); + + chatText->textCursor().insertText("You: " + messageText->text() + '\n'); + + messageText->clear(); + + sendButton->setEnabled(true); +} + +void Client::sessionOpened() +{ + // Save the used configuration + QNetworkConfiguration config = networkSession->configuration(); + QString id; + if (config.type() == QNetworkConfiguration::UserChoice) + id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); + else + id = config.identifier(); + + QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); + settings.beginGroup(QLatin1String("QtNetwork")); + settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); + settings.endGroup(); + + + sendButton->setEnabled(true); +} + +void Client::displayError(QAbstractSocket::SocketError socketError) +{ + serverSocket->close(); + switch (socketError) + { + case QAbstractSocket::RemoteHostClosedError: + break; + case QAbstractSocket::HostNotFoundError: + QMessageBox::information(this, tr("Chat client"), + tr("The host was not found. Please check the " + "host name and port settings.")); + break; + case QAbstractSocket::ConnectionRefusedError: + QMessageBox::information(this, tr("Chat client"), + tr("The connection was refused by the peer. " + "Make sure the fortune server is running, " + "and check that the host name and port " + "settings are correct.")); + break; + default: + QMessageBox::information(this, tr("Chat client"), + tr("The following error occurred: %1.") + .arg(serverSocket->errorString())); + } + hostAdress->setEnabled(true); + portLineEdit->setEnabled(true); +} + +void Client::connectToServer() +{ + serverSocket->connectToHost(hostAdress->currentText(), portLineEdit->text().toInt()); + + if (serverSocket->waitForConnected(5000)) + { + chatText->clear(); + chatText->textCursor().insertText("Server connected!\n"); + hostAdress->setDisabled(true); + portLineEdit->setDisabled(true); + connectButton->setDisabled(true); + sendButton->setEnabled(true); + } + else + { + hostAdress->setEnabled(true); + portLineEdit->setEnabled(true); + } +} + +void Client::disconnectedFromServer() +{ + hostAdress->setDisabled(true); + portLineEdit->setDisabled(true); + connectButton->setEnabled(true); + sendButton->setDisabled(true); + + QMessageBox::information(this, tr("Chat Client"), + tr("Server disconnected!")); +} diff --git a/configurationServer/client/client.h b/configurationServer/client/client.h new file mode 100644 index 0000000..eeea59c --- /dev/null +++ b/configurationServer/client/client.h @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Client : public QDialog +{ + Q_OBJECT + +public: + explicit Client(QWidget *parent = 0); + +private slots: + void sessionOpened(); + void displayError(QAbstractSocket::SocketError socketError); + + /// sends message + void sendMessage(); + + /// receives message + void receiveMessage(); + + void connectToServer(); + void disconnectedFromServer(); + +private: + /// buttons: + QPushButton *quitButton; + QPushButton *sendButton; + QPushButton *connectButton; + + /// labels: + QLabel *hostLabel; + QLabel *portLabel; + + /// combo box: + QComboBox *hostAdress; + + /// text widgets: + QLineEdit *portLineEdit; + QTextEdit *chatText; + QLineEdit *messageText; + + + QTcpSocket *serverSocket; + QNetworkSession *networkSession; + quint16 blockSize; +}; diff --git a/configurationServer/client/client.ui b/configurationServer/client/client.ui new file mode 100644 index 0000000..0822f8f --- /dev/null +++ b/configurationServer/client/client.ui @@ -0,0 +1,24 @@ + + Client + + + + 0 + 0 + 400 + 300 + + + + Client + + + + + + + + + + + diff --git a/configurationServer/client/main.cpp b/configurationServer/client/main.cpp new file mode 100644 index 0000000..b6ebece --- /dev/null +++ b/configurationServer/client/main.cpp @@ -0,0 +1,11 @@ +#include "client.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Client w; + w.show(); + + return a.exec(); +} diff --git a/configurationServer/gui/gui.pro b/configurationServer/gui/gui.pro index bb491c2..213c23c 100644 --- a/configurationServer/gui/gui.pro +++ b/configurationServer/gui/gui.pro @@ -5,11 +5,11 @@ #------------------------------------------------- QT += core gui +QT += network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = gui TEMPLATE = app - CONFIG += c++11 SOURCES += main.cpp\ @@ -29,7 +29,8 @@ SOURCES += main.cpp\ hotKeyManager/hotKeyManagerPage.cpp \ hotKeyManager/shortcutEdit.cpp \ qrutils/qRealDialog.cpp \ - widget.cpp + widget.cpp \ + server/server.cpp HEADERS += \ preferencesDialog.h \ @@ -55,7 +56,8 @@ HEADERS += \ hotKeyManager/shortcutEdit.h \ qrutils/qRealDialog.h \ widget.h \ - ui_widget.h + ui_widget.h \ + server/server.h FORMS += \ preferencesDialog.ui \ @@ -68,7 +70,8 @@ FORMS += \ widget.ui SUBDIRS += \ - qrkernel/qrkernel.pro + qrkernel/qrkernel.pro \ + server/server.pro OTHER_FILES += diff --git a/configurationServer/gui/gui.pro.user b/configurationServer/gui/gui.pro.user new file mode 100644 index 0000000..3b9a0d4 --- /dev/null +++ b/configurationServer/gui/gui.pro.user @@ -0,0 +1,248 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + true + 1 + true + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.2.1 MinGW 32bit + Desktop Qt 5.2.1 MinGW 32bit + qt.521.win32_mingw48.essentials_kit + 0 + 0 + 0 + + C:/Programming/Debugging + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Отладка + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + C:/Programming/Debugging + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Выпуск + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Установка + + ProjectExplorer.BuildSteps.Deploy + + 1 + Локальная установка + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + gui + + Qt4ProjectManager.Qt4RunConfiguration:C:/Programming/SummerSchool/tools/configurationServer/gui/gui.pro + + gui.pro + false + false + + 3768 + true + false + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {b98c4ef7-5a11-4065-9906-b1f08baf52f0} + + + ProjectExplorer.Project.Updater.FileVersion + 15 + + diff --git a/configurationServer/gui/qrkernel/settingsManager.cpp b/configurationServer/gui/qrkernel/settingsManager.cpp index b5ec3d4..fba04c6 100644 --- a/configurationServer/gui/qrkernel/settingsManager.cpp +++ b/configurationServer/gui/qrkernel/settingsManager.cpp @@ -123,3 +123,13 @@ void SettingsManager::clearSettings() instance()->mData.clear(); instance()->mDefaultValues.clear(); } + +QString SettingsManager::convertToString() +{ + QString allSettings; + QStringList keyList = mSettings.allKeys(); + for (int i = 0; i < keyList.size(); i++) + allSettings += keyList[i] + "###" + value(keyList[i]).toString() + "#*#"; + + return allSettings; +} diff --git a/configurationServer/gui/qrkernel/settingsManager.h b/configurationServer/gui/qrkernel/settingsManager.h index 3409a87..ac06c6f 100644 --- a/configurationServer/gui/qrkernel/settingsManager.h +++ b/configurationServer/gui/qrkernel/settingsManager.h @@ -57,6 +57,9 @@ class SettingsManager : public QObject /// Merges default settings from the given file in INI format. static void loadDefaultSettings(QString const &filePath); + /// Convertes settings into QString. + QString convertToString(); + signals: /// Emitted each time when settings with the given key were modified. /// For connection instance() method can be useful. diff --git a/configurationServer/gui/server/main.cpp b/configurationServer/gui/server/main.cpp new file mode 100644 index 0000000..f728958 --- /dev/null +++ b/configurationServer/gui/server/main.cpp @@ -0,0 +1,11 @@ +#include "server.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Server w; + w.show(); + + return a.exec(); +} diff --git a/configurationServer/gui/server/server.cpp b/configurationServer/gui/server/server.cpp new file mode 100644 index 0000000..ecd83f5 --- /dev/null +++ b/configurationServer/gui/server/server.cpp @@ -0,0 +1,114 @@ +#include +#include "server.h" + +Server::Server(QWidget *parent) : + QDialog(parent), + tcpServer(0), + //clientSocket(0), + networkSession(0), + blockSize(0) +{ + QNetworkConfigurationManager manager; + if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) + { + // Get saved network configuration + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QtNetwork")); + const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString(); + settings.endGroup(); + + // If the saved network configuration is not currently discovered use the system default + QNetworkConfiguration config = manager.configurationFromIdentifier(id); + if ((config.state() & QNetworkConfiguration::Discovered) != QNetworkConfiguration::Discovered) + { + config = manager.defaultConfiguration(); + } + + networkSession = new QNetworkSession(config, this); + connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); + + networkSession->open(); + } + else + { + sessionOpened(); + } + + connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptClientConnection())); +} + +void Server::sessionOpened() + { + // Save the used configuration + if (networkSession) + { + QNetworkConfiguration config = networkSession->configuration(); + QString id; + if (config.type() == QNetworkConfiguration::UserChoice) + id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); + else + id = config.identifier(); + + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QtNetwork")); + settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); + settings.endGroup(); + } + + tcpServer = new QTcpServer(this); + if (!tcpServer->listen(QHostAddress::LocalHost, tcpServer->serverPort())) + { + QMessageBox::critical(this, tr("qReal Server"), + tr("Unable to start the server: %1.") + .arg(tcpServer->errorString())); + close(); + return; + } + + //statusLabel->setText(tr("The server is running on\n\nIP-adress: %1\nPort: %2\n\n" + // "Run the Chat Client now.") + // .arg(tcpServer->serverAddress().toString()).arg(tcpServer->serverPort())); + } + +void Server::acceptClientConnection() +{ + QTcpSocket* clientSocket = tcpServer->nextPendingConnection(); + emit newClient(clientSocket->localAddress().toString()); + int idusersocs = clientSocket->socketDescriptor(); + SClients[idusersocs] = clientSocket; + //connect(SClients[idusersocs], SIGNAL(readyRead()), this, SLOT(sendSettings())); + connect(SClients[idusersocs], SIGNAL(disconnected()), this, SLOT(disconnectedFromClient())); + connect(SClients[idusersocs], SIGNAL(disconnected()), SClients[idusersocs], SLOT(deleteLater())); + sendSettings(); +} + +void Server::sendSettings() +{ + if(!SClients.isEmpty()) + { + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + + out << (quint16)qReal::SettingsManager::instance()->convertToString().length(); + out << qReal::SettingsManager::instance()->convertToString(); + foreach(int i, SClients.keys()) { + SClients[i]->write(block); + } + } +} + +quint16 Server::getAdress() +{ + return tcpServer->serverPort(); +} + +QString Server::getIP() +{ + return tcpServer->serverAddress().toString(); +} + +void Server::clientDisconnected() +{ + QMessageBox::information(this, tr("qReal Server"), + tr("Client disconnected!")); +} diff --git a/configurationServer/gui/server/server.h b/configurationServer/gui/server/server.h new file mode 100644 index 0000000..5fa8316 --- /dev/null +++ b/configurationServer/gui/server/server.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +#include "qrkernel/settingsManager.h" + +namespace Ui { +class Server; +} + +class Server : public QDialog +{ + Q_OBJECT + +public: + explicit Server(QWidget *parent = 0); + QString getIP(); + quint16 getAdress(); + +private slots: + void sessionOpened(); + void acceptClientConnection(); + void clientDisconnected(); + +signals: + void newClient(QString clientName); + +private: + void sendSettings(); + QMap SClients; + QTcpServer *tcpServer; + QNetworkSession *networkSession; + quint16 blockSize; +}; + diff --git a/configurationServer/gui/server/server.pro b/configurationServer/gui/server/server.pro new file mode 100644 index 0000000..b485fe8 --- /dev/null +++ b/configurationServer/gui/server/server.pro @@ -0,0 +1,27 @@ +HEADERS = server.h \ + settingsManager.h \ + kernelDeclSpec.h + SOURCES = server.cpp \ + main.cpp \ + settingsManager.cpp + QT += network + QT += core gui widgets + CONFIG += c++11 + + # install + target.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneserver + sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS fortuneserver.pro + sources.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneserver + INSTALLS += target sources + + symbian { + TARGET.UID3 = 0xA000E406 + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) + TARGET.CAPABILITY = "NetworkServices ReadUserData" + TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 + } + maemo5: include($$QT_SOURCE_TREE/examples/maemo5pkgrules.pri) + + symbian: warning(This example might not fully work on Symbian platform) + maemo5: warning(This example might not fully work on Maemo platform) + simulator: warning(This example might not fully work on Simulator platform) diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp index 812009c..4766893 100644 --- a/configurationServer/gui/widget.cpp +++ b/configurationServer/gui/widget.cpp @@ -9,18 +9,27 @@ Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { - ui->setupUi(this); + ui->setupUi(this); } Widget::~Widget() { - delete ui; + delete ui; } void Widget::init() { - PreferencesDialog * dialog = new PreferencesDialog(); - dialog->init(new QAction(dialog), new QAction(dialog), new QAction(dialog), new QAction(dialog)); - ui->widgetSettings->layout()->addWidget(dialog); - dialog->setParent(ui->widgetSettings); + server = new Server; + PreferencesDialog * dialog = new PreferencesDialog(); + dialog->init(new QAction(dialog), new QAction(dialog), new QAction(dialog), new QAction(dialog)); + ui->widgetSettings->layout()->addWidget(dialog); + dialog->setParent(ui->widgetSettings); + connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); + setWindowTitle("IP: " + server->getIP() + + " Adress: " + QString::number(server->getAdress())); +} + +void Widget::addNewClient(QString newClient) +{ + ui->widgetListOfNames->addItem("client's IP: " + newClient); } diff --git a/configurationServer/gui/widget.h b/configurationServer/gui/widget.h index ab27735..8af0f35 100644 --- a/configurationServer/gui/widget.h +++ b/configurationServer/gui/widget.h @@ -1,4 +1,5 @@ #pragma once +#include "server/server.h" #include @@ -15,7 +16,11 @@ class Widget : public QWidget ~Widget(); void init(); +private slots: + void addNewClient(QString newClient); + private: Ui::Widget *ui; + Server *server; }; From 50c8cd7f6a47b261d6f6aff51430d4c8daab84ef Mon Sep 17 00:00:00 2001 From: IlyaNikiforov Date: Mon, 7 Jul 2014 23:41:13 +0400 Subject: [PATCH 08/14] almost final version of server --- configurationServer/gui/gui.pro.user | 2 +- configurationServer/gui/main.cpp | 10 +- configurationServer/gui/preferencesDialog.cpp | 6 +- configurationServer/gui/server/server.cpp | 70 +++++---- configurationServer/gui/server/server.h | 4 - configurationServer/gui/ui_widget.h | 142 +++++++++++------- configurationServer/gui/widget.cpp | 10 +- configurationServer/gui/widget.h | 11 +- configurationServer/gui/widget.ui | 21 +-- configurationServer/server/server.pro.user | 2 +- 10 files changed, 147 insertions(+), 131 deletions(-) diff --git a/configurationServer/gui/gui.pro.user b/configurationServer/gui/gui.pro.user index 3b9a0d4..be69f5d 100644 --- a/configurationServer/gui/gui.pro.user +++ b/configurationServer/gui/gui.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget diff --git a/configurationServer/gui/main.cpp b/configurationServer/gui/main.cpp index 083c605..89711ec 100644 --- a/configurationServer/gui/main.cpp +++ b/configurationServer/gui/main.cpp @@ -3,10 +3,10 @@ int main(int argc, char *argv[]) { - QApplication a(argc, argv); - Widget w; - w.init(); - w.show(); + QApplication a(argc, argv); + Widget w; + w.init(); + w.show(); - return a.exec(); + return a.exec(); } diff --git a/configurationServer/gui/preferencesDialog.cpp b/configurationServer/gui/preferencesDialog.cpp index ee45b86..c9fa78e 100644 --- a/configurationServer/gui/preferencesDialog.cpp +++ b/configurationServer/gui/preferencesDialog.cpp @@ -181,7 +181,7 @@ void PreferencesDialog::importSettings() , tr("Open File"),"/mySettings",tr("*.ini")); SettingsManager::instance()->loadSettings(fileNameForImport); - foreach (PreferencesPage *page, mCustomPages.values()) { - page->restoreSettings(); - } + foreach (PreferencesPage *page, mCustomPages.values()) { + page->restoreSettings(); + } } diff --git a/configurationServer/gui/server/server.cpp b/configurationServer/gui/server/server.cpp index ecd83f5..558e6b6 100644 --- a/configurationServer/gui/server/server.cpp +++ b/configurationServer/gui/server/server.cpp @@ -4,7 +4,6 @@ Server::Server(QWidget *parent) : QDialog(parent), tcpServer(0), - //clientSocket(0), networkSession(0), blockSize(0) { @@ -38,45 +37,40 @@ Server::Server(QWidget *parent) : } void Server::sessionOpened() - { - // Save the used configuration - if (networkSession) - { - QNetworkConfiguration config = networkSession->configuration(); - QString id; - if (config.type() == QNetworkConfiguration::UserChoice) - id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); - else - id = config.identifier(); - - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); - settings.beginGroup(QLatin1String("QtNetwork")); - settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); - settings.endGroup(); - } +{ + // Save the used configuration + if (networkSession) + { + QNetworkConfiguration config = networkSession->configuration(); + QString id; + if (config.type() == QNetworkConfiguration::UserChoice) + id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); + else + id = config.identifier(); - tcpServer = new QTcpServer(this); - if (!tcpServer->listen(QHostAddress::LocalHost, tcpServer->serverPort())) - { - QMessageBox::critical(this, tr("qReal Server"), - tr("Unable to start the server: %1.") - .arg(tcpServer->errorString())); - close(); - return; - } + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QtNetwork")); + settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); + settings.endGroup(); + } - //statusLabel->setText(tr("The server is running on\n\nIP-adress: %1\nPort: %2\n\n" - // "Run the Chat Client now.") - // .arg(tcpServer->serverAddress().toString()).arg(tcpServer->serverPort())); - } + tcpServer = new QTcpServer(this); + if (!tcpServer->listen(QHostAddress::AnyIPv4, tcpServer->serverPort())) + { + QMessageBox::critical(this, tr("qReal Server"), + tr("Unable to start the server: %1.") + .arg(tcpServer->errorString())); + close(); + return; + } +} void Server::acceptClientConnection() { QTcpSocket* clientSocket = tcpServer->nextPendingConnection(); - emit newClient(clientSocket->localAddress().toString()); + emit newClient(clientSocket->peerAddress().toString()); int idusersocs = clientSocket->socketDescriptor(); SClients[idusersocs] = clientSocket; - //connect(SClients[idusersocs], SIGNAL(readyRead()), this, SLOT(sendSettings())); connect(SClients[idusersocs], SIGNAL(disconnected()), this, SLOT(disconnectedFromClient())); connect(SClients[idusersocs], SIGNAL(disconnected()), SClients[idusersocs], SLOT(deleteLater())); sendSettings(); @@ -104,7 +98,17 @@ quint16 Server::getAdress() QString Server::getIP() { - return tcpServer->serverAddress().toString(); + QList adressList = QNetworkInterface::allInterfaces(); + QString address; + for (int j = 0; j < adressList.size(); j++) + { + QList addressEntry = adressList[j].addressEntries(); + for (int i = 0; i < addressEntry.size(); i++) + address += addressEntry[i].ip().toString() + "\n"; + address += "\n"; + } + + return address; } void Server::clientDisconnected() diff --git a/configurationServer/gui/server/server.h b/configurationServer/gui/server/server.h index 5fa8316..62d6f6a 100644 --- a/configurationServer/gui/server/server.h +++ b/configurationServer/gui/server/server.h @@ -5,10 +5,6 @@ #include "qrkernel/settingsManager.h" -namespace Ui { -class Server; -} - class Server : public QDialog { Q_OBJECT diff --git a/configurationServer/gui/ui_widget.h b/configurationServer/gui/ui_widget.h index 44d71ca..bf8664e 100644 --- a/configurationServer/gui/ui_widget.h +++ b/configurationServer/gui/ui_widget.h @@ -18,71 +18,103 @@ #include #include #include +#include +#include QT_BEGIN_NAMESPACE class Ui_Widget { public: - QHBoxLayout *horizontalLayout_2; - QListWidget *widgetListOfNames; - QWidget *widgetSettings; - QVBoxLayout *verticalLayout; - - void setupUi(QWidget *Widget) - { - if (Widget->objectName().isEmpty()) - Widget->setObjectName(QStringLiteral("Widget")); - Widget->resize(1003, 429); - horizontalLayout_2 = new QHBoxLayout(Widget); - horizontalLayout_2->setSpacing(0); - horizontalLayout_2->setContentsMargins(11, 11, 11, 11); - horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); - horizontalLayout_2->setContentsMargins(0, 0, 0, 0); - widgetListOfNames = new QListWidget(Widget); - widgetListOfNames->setObjectName(QStringLiteral("widgetListOfNames")); - QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(widgetListOfNames->sizePolicy().hasHeightForWidth()); - widgetListOfNames->setSizePolicy(sizePolicy); - widgetListOfNames->setMinimumSize(QSize(200, 0)); - widgetListOfNames->setMaximumSize(QSize(200, 16777215)); - widgetListOfNames->setFlow(QListView::TopToBottom); - widgetListOfNames->setViewMode(QListView::ListMode); - widgetListOfNames->setUniformItemSizes(true); - widgetListOfNames->setWordWrap(true); - - horizontalLayout_2->addWidget(widgetListOfNames); - - widgetSettings = new QWidget(Widget); - widgetSettings->setObjectName(QStringLiteral("widgetSettings")); - verticalLayout = new QVBoxLayout(widgetSettings); - verticalLayout->setSpacing(0); - verticalLayout->setContentsMargins(11, 11, 11, 11); - verticalLayout->setObjectName(QStringLiteral("verticalLayout")); - verticalLayout->setContentsMargins(0, 0, 0, 0); - - horizontalLayout_2->addWidget(widgetSettings); - - - retranslateUi(Widget); - - widgetListOfNames->setCurrentRow(-1); - - - QMetaObject::connectSlotsByName(Widget); - } // setupUi - - void retranslateUi(QWidget *Widget) - { - Widget->setWindowTitle(QApplication::translate("Widget", "Widget", 0)); - } // retranslateUi + QHBoxLayout *horizontalLayout_2; + QListWidget *widgetListOfNames; + QWidget *widgetSettings; + QVBoxLayout *verticalLayout; + QTextEdit *widgetListOfIP; + QVBoxLayout *verticalLeftLayout; + QLabel *widgetNameLostOfIP; + QLabel *widgetNameListOfNames; + + void setupUi(QWidget *Widget) + { + if (Widget->objectName().isEmpty()) + Widget->setObjectName(QStringLiteral("Widget")); + Widget->resize(1003, 429); + horizontalLayout_2 = new QHBoxLayout(Widget); + horizontalLayout_2->setSpacing(0); + horizontalLayout_2->setContentsMargins(11, 11, 11, 11); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + horizontalLayout_2->setContentsMargins(0, 0, 0, 0); + + verticalLeftLayout = new QVBoxLayout(Widget); + verticalLeftLayout->setSpacing(0); + verticalLeftLayout->setContentsMargins(11, 11, 11, 11); + verticalLeftLayout->setObjectName(QStringLiteral("verticalLeftLayout")); + verticalLeftLayout->setContentsMargins(0, 0, 0, 0); + + widgetNameLostOfIP = new QLabel(Widget); + widgetNameLostOfIP->setText("Your IP-address:"); + verticalLeftLayout->addWidget(widgetNameLostOfIP); + + widgetListOfIP = new QTextEdit(Widget); + widgetListOfIP->setObjectName(QStringLiteral("widgetListOfIP")); + QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Expanding); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(widgetListOfIP->sizePolicy().hasHeightForWidth()); + widgetListOfIP->setSizePolicy(sizePolicy1); + widgetListOfIP->setMinimumSize(QSize(200, 0)); + widgetListOfIP->setMaximumSize(QSize(200, 16777215)); + widgetListOfIP->setReadOnly(true); + verticalLeftLayout->addWidget(widgetListOfIP); + + widgetNameListOfNames = new QLabel(Widget); + widgetNameListOfNames->setText("Client's IP-addresses:"); + verticalLeftLayout->addWidget(widgetNameListOfNames); + + widgetListOfNames = new QListWidget(Widget); + widgetListOfNames->setObjectName(QStringLiteral("widgetListOfNames")); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(widgetListOfNames->sizePolicy().hasHeightForWidth()); + widgetListOfNames->setSizePolicy(sizePolicy); + widgetListOfNames->setMinimumSize(QSize(200, 0)); + widgetListOfNames->setMaximumSize(QSize(200, 16777215)); + widgetListOfNames->setFlow(QListView::TopToBottom); + widgetListOfNames->setViewMode(QListView::ListMode); + widgetListOfNames->setUniformItemSizes(true); + widgetListOfNames->setWordWrap(true); + verticalLeftLayout->addWidget(widgetListOfNames); + + horizontalLayout_2->addItem(verticalLeftLayout); + + widgetSettings = new QWidget(Widget); + widgetSettings->setObjectName(QStringLiteral("widgetSettings")); + verticalLayout = new QVBoxLayout(widgetSettings); + verticalLayout->setSpacing(0); + verticalLayout->setContentsMargins(11, 11, 11, 11); + verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + verticalLayout->setContentsMargins(0, 0, 0, 0); + + horizontalLayout_2->addWidget(widgetSettings); + + retranslateUi(Widget); + + widgetListOfNames->setCurrentRow(-1); + + QMetaObject::connectSlotsByName(Widget); + } // setupUi + + void retranslateUi(QWidget *Widget) + { + Widget->setWindowTitle(QApplication::translate("Widget", "Widget", 0)); + } // retranslateUi }; namespace Ui { - class Widget: public Ui_Widget {}; + class Widget: public Ui_Widget {}; } // namespace Ui QT_END_NAMESPACE diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp index 4766893..b414dd4 100644 --- a/configurationServer/gui/widget.cpp +++ b/configurationServer/gui/widget.cpp @@ -3,11 +3,9 @@ #include "preferencesDialog.h" -#include - Widget::Widget(QWidget *parent) : - QWidget(parent), - ui(new Ui::Widget) + QWidget(parent), + ui(new Ui::Widget) { ui->setupUi(this); } @@ -25,8 +23,8 @@ void Widget::init() ui->widgetSettings->layout()->addWidget(dialog); dialog->setParent(ui->widgetSettings); connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); - setWindowTitle("IP: " + server->getIP() - + " Adress: " + QString::number(server->getAdress())); + setWindowTitle(" Adress: " + QString::number(server->getAdress())); + ui->widgetListOfIP->setText(server->getIP()); } void Widget::addNewClient(QString newClient) diff --git a/configurationServer/gui/widget.h b/configurationServer/gui/widget.h index 8af0f35..1123599 100644 --- a/configurationServer/gui/widget.h +++ b/configurationServer/gui/widget.h @@ -9,18 +9,19 @@ class Widget; class Widget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit Widget(QWidget *parent = 0); - ~Widget(); - void init(); + explicit Widget(QWidget *parent = 0); + ~Widget(); + void init(); private slots: void addNewClient(QString newClient); private: - Ui::Widget *ui; + Ui::Widget *ui; + QWidget *widgetSettings; Server *server; }; diff --git a/configurationServer/gui/widget.ui b/configurationServer/gui/widget.ui index 85846fb..a6bb566 100644 --- a/configurationServer/gui/widget.ui +++ b/configurationServer/gui/widget.ui @@ -7,30 +7,15 @@ 0 0 1003 - 429 + 437 Widget - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - + - + 0 diff --git a/configurationServer/server/server.pro.user b/configurationServer/server/server.pro.user index b3ecc44..65cb59c 100644 --- a/configurationServer/server/server.pro.user +++ b/configurationServer/server/server.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget From 8b490d1e06ffb2d7b48e45e9c502333f1ea7095d Mon Sep 17 00:00:00 2001 From: IlyaNikiforov Date: Tue, 8 Jul 2014 18:51:27 +0400 Subject: [PATCH 09/14] almost final version of server --- configurationServer/gui/gui.pro.user | 2 +- configurationServer/gui/server/server.cpp | 19 +++++++++++-------- configurationServer/gui/server/server.h | 4 +++- configurationServer/gui/ui_widget.h | 4 +++- configurationServer/gui/widget.cpp | 13 ++++++++++++- configurationServer/gui/widget.h | 1 + 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/configurationServer/gui/gui.pro.user b/configurationServer/gui/gui.pro.user index be69f5d..e76ad40 100644 --- a/configurationServer/gui/gui.pro.user +++ b/configurationServer/gui/gui.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget diff --git a/configurationServer/gui/server/server.cpp b/configurationServer/gui/server/server.cpp index 558e6b6..58b345c 100644 --- a/configurationServer/gui/server/server.cpp +++ b/configurationServer/gui/server/server.cpp @@ -4,8 +4,8 @@ Server::Server(QWidget *parent) : QDialog(parent), tcpServer(0), - networkSession(0), - blockSize(0) + networkSession(0) + //blockSize(0), { QNetworkConfigurationManager manager; if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) @@ -33,7 +33,9 @@ Server::Server(QWidget *parent) : sessionOpened(); } + mapper = new QSignalMapper; connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptClientConnection())); + connect(mapper, SIGNAL(mapped(QString)), this, SLOT(clientDisconnectedSlot(QString))); } void Server::sessionOpened() @@ -55,7 +57,7 @@ void Server::sessionOpened() } tcpServer = new QTcpServer(this); - if (!tcpServer->listen(QHostAddress::AnyIPv4, tcpServer->serverPort())) + if (!tcpServer->listen(QHostAddress::AnyIPv4, 55555)) { QMessageBox::critical(this, tr("qReal Server"), tr("Unable to start the server: %1.") @@ -71,7 +73,8 @@ void Server::acceptClientConnection() emit newClient(clientSocket->peerAddress().toString()); int idusersocs = clientSocket->socketDescriptor(); SClients[idusersocs] = clientSocket; - connect(SClients[idusersocs], SIGNAL(disconnected()), this, SLOT(disconnectedFromClient())); + connect(SClients[idusersocs], SIGNAL(disconnected()), mapper, SLOT(map())); + mapper->setMapping(SClients[idusersocs], SClients[idusersocs]->peerAddress().toString()); connect(SClients[idusersocs], SIGNAL(disconnected()), SClients[idusersocs], SLOT(deleteLater())); sendSettings(); } @@ -85,7 +88,8 @@ void Server::sendSettings() out << (quint16)qReal::SettingsManager::instance()->convertToString().length(); out << qReal::SettingsManager::instance()->convertToString(); - foreach(int i, SClients.keys()) { + foreach(int i, SClients.keys()) + { SClients[i]->write(block); } } @@ -111,8 +115,7 @@ QString Server::getIP() return address; } -void Server::clientDisconnected() +void Server::clientDisconnectedSlot(QString clientsID) { - QMessageBox::information(this, tr("qReal Server"), - tr("Client disconnected!")); + emit clientDisconnectedSignal(clientsID); } diff --git a/configurationServer/gui/server/server.h b/configurationServer/gui/server/server.h index 62d6f6a..0a8781c 100644 --- a/configurationServer/gui/server/server.h +++ b/configurationServer/gui/server/server.h @@ -17,10 +17,11 @@ class Server : public QDialog private slots: void sessionOpened(); void acceptClientConnection(); - void clientDisconnected(); + void clientDisconnectedSlot(QString clientsID); signals: void newClient(QString clientName); + void clientDisconnectedSignal(QString clientsIP); private: void sendSettings(); @@ -28,5 +29,6 @@ private slots: QTcpServer *tcpServer; QNetworkSession *networkSession; quint16 blockSize; + QSignalMapper *mapper; }; diff --git a/configurationServer/gui/ui_widget.h b/configurationServer/gui/ui_widget.h index bf8664e..ae13b83 100644 --- a/configurationServer/gui/ui_widget.h +++ b/configurationServer/gui/ui_widget.h @@ -53,7 +53,7 @@ class Ui_Widget verticalLeftLayout->setContentsMargins(0, 0, 0, 0); widgetNameLostOfIP = new QLabel(Widget); - widgetNameLostOfIP->setText("Your IP-address:"); + widgetNameLostOfIP->setText("Your IP:"); verticalLeftLayout->addWidget(widgetNameLostOfIP); widgetListOfIP = new QTextEdit(Widget); @@ -99,10 +99,12 @@ class Ui_Widget horizontalLayout_2->addWidget(widgetSettings); + retranslateUi(Widget); widgetListOfNames->setCurrentRow(-1); + QMetaObject::connectSlotsByName(Widget); } // setupUi diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp index b414dd4..eb70e83 100644 --- a/configurationServer/gui/widget.cpp +++ b/configurationServer/gui/widget.cpp @@ -23,11 +23,22 @@ void Widget::init() ui->widgetSettings->layout()->addWidget(dialog); dialog->setParent(ui->widgetSettings); connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); + connect(server, SIGNAL(clientDisconnectedSignal(QString)), this, SLOT(deleteClient(QString))); setWindowTitle(" Adress: " + QString::number(server->getAdress())); ui->widgetListOfIP->setText(server->getIP()); } void Widget::addNewClient(QString newClient) { - ui->widgetListOfNames->addItem("client's IP: " + newClient); + ui->widgetListOfNames->addItem(newClient); +} + +void Widget::deleteClient(QString clientsIP) +{ + for (int i = 0; i < ui->widgetListOfNames->count(); i++) + if (ui->widgetListOfNames->item(i)->text() == clientsIP) + { + delete ui->widgetListOfNames->item(i); + return; + } } diff --git a/configurationServer/gui/widget.h b/configurationServer/gui/widget.h index 1123599..15eeda6 100644 --- a/configurationServer/gui/widget.h +++ b/configurationServer/gui/widget.h @@ -18,6 +18,7 @@ class Widget : public QWidget private slots: void addNewClient(QString newClient); + void deleteClient(QString clientsIP); private: Ui::Widget *ui; From 09c0109d23a242347618cba7efdb75d38e2759cd Mon Sep 17 00:00:00 2001 From: IlyaNikiforov Date: Wed, 9 Jul 2014 13:12:52 +0400 Subject: [PATCH 10/14] new version --- configurationServer/gui/gui.pro.user | 2 +- configurationServer/gui/server/server.cpp | 11 +++-- configurationServer/gui/ui_widget.h | 13 +++--- configurationServer/gui/widget.cpp | 23 ++++++++- configurationServer/gui/widget.cpp.autosave | 52 +++++++++++++++++++++ 5 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 configurationServer/gui/widget.cpp.autosave diff --git a/configurationServer/gui/gui.pro.user b/configurationServer/gui/gui.pro.user index e76ad40..c388382 100644 --- a/configurationServer/gui/gui.pro.user +++ b/configurationServer/gui/gui.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget diff --git a/configurationServer/gui/server/server.cpp b/configurationServer/gui/server/server.cpp index 58b345c..699a9ad 100644 --- a/configurationServer/gui/server/server.cpp +++ b/configurationServer/gui/server/server.cpp @@ -102,14 +102,15 @@ quint16 Server::getAdress() QString Server::getIP() { - QList adressList = QNetworkInterface::allInterfaces(); + QList addressList = QNetworkInterface::allInterfaces(); QString address; - for (int j = 0; j < adressList.size(); j++) + for (int j = 0; j < addressList.size(); j++) { - QList addressEntry = adressList[j].addressEntries(); + QList addressEntry = addressList[j].addressEntries(); for (int i = 0; i < addressEntry.size(); i++) - address += addressEntry[i].ip().toString() + "\n"; - address += "\n"; + if (!addressEntry[i].ip().isLoopback() + && addressEntry[i].ip().toString().contains(".")) + address += addressEntry[i].ip().toString() + "\n"; } return address; diff --git a/configurationServer/gui/ui_widget.h b/configurationServer/gui/ui_widget.h index ae13b83..ee8bb22 100644 --- a/configurationServer/gui/ui_widget.h +++ b/configurationServer/gui/ui_widget.h @@ -30,9 +30,9 @@ class Ui_Widget QListWidget *widgetListOfNames; QWidget *widgetSettings; QVBoxLayout *verticalLayout; - QTextEdit *widgetListOfIP; + QListWidget *widgetListOfIP; QVBoxLayout *verticalLeftLayout; - QLabel *widgetNameLostOfIP; + QLabel *widgetNameListOfIP; QLabel *widgetNameListOfNames; void setupUi(QWidget *Widget) @@ -52,11 +52,11 @@ class Ui_Widget verticalLeftLayout->setObjectName(QStringLiteral("verticalLeftLayout")); verticalLeftLayout->setContentsMargins(0, 0, 0, 0); - widgetNameLostOfIP = new QLabel(Widget); - widgetNameLostOfIP->setText("Your IP:"); - verticalLeftLayout->addWidget(widgetNameLostOfIP); + widgetNameListOfIP = new QLabel(Widget); + widgetNameListOfIP->setText("Your IP:"); + verticalLeftLayout->addWidget(widgetNameListOfIP); - widgetListOfIP = new QTextEdit(Widget); + widgetListOfIP = new QListWidget(Widget); widgetListOfIP->setObjectName(QStringLiteral("widgetListOfIP")); QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Expanding); sizePolicy1.setHorizontalStretch(0); @@ -65,7 +65,6 @@ class Ui_Widget widgetListOfIP->setSizePolicy(sizePolicy1); widgetListOfIP->setMinimumSize(QSize(200, 0)); widgetListOfIP->setMaximumSize(QSize(200, 16777215)); - widgetListOfIP->setReadOnly(true); verticalLeftLayout->addWidget(widgetListOfIP); widgetNameListOfNames = new QLabel(Widget); diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp index eb70e83..86cd20a 100644 --- a/configurationServer/gui/widget.cpp +++ b/configurationServer/gui/widget.cpp @@ -25,7 +25,28 @@ void Widget::init() connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); connect(server, SIGNAL(clientDisconnectedSignal(QString)), this, SLOT(deleteClient(QString))); setWindowTitle(" Adress: " + QString::number(server->getAdress())); - ui->widgetListOfIP->setText(server->getIP()); + QString allIP = server->getIP(); + int i = 0; +// while (i < allIP.length()) +// { +// while (allIP[i] != '\n') +// i++; +// QString temp; +// for (int j = 0; j < i; j++) +// temp[j] = allIP[i + j]; +// ui->widgetListOfIP->addItem(allIP.remove(0, i)); +// i++; +// } + for(i = 0; i < allIP.count("\n"); i++) + { + QString temp = allIP; + ui->widgetListOfIP->addItem(temp.remove(temp.indexOf('\n'), temp.length() - temp.indexOf('\n'))); + //ui->widgetListOfIP->addItem(allIP.remove(0, allIP.indexOf('\n') + 1)); + allIP = allIP.remove(0, allIP.indexOf('\n') + 1); + } + ui->widgetListOfIP->addItem(allIP.remove(allIP.length() - 1, 1)); + + //ui->widgetListOfIP->addItem(server->getIP()); } void Widget::addNewClient(QString newClient) diff --git a/configurationServer/gui/widget.cpp.autosave b/configurationServer/gui/widget.cpp.autosave new file mode 100644 index 0000000..6c8165c --- /dev/null +++ b/configurationServer/gui/widget.cpp.autosave @@ -0,0 +1,52 @@ +#include "widget.h" +#include "ui_widget.h" + +#include "preferencesDialog.h" + +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::Widget) +{ + ui->setupUi(this); +} + +Widget::~Widget() +{ + delete ui; +} + +void Widget::init() +{ + server = new Server; + PreferencesDialog * dialog = new PreferencesDialog(); + dialog->init(new QAction(dialog), new QAction(dialog), new QAction(dialog), new QAction(dialog)); + ui->widgetSettings->layout()->addWidget(dialog); + dialog->setParent(ui->widgetSettings); + connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); + connect(server, SIGNAL(clientDisconnectedSignal(QString)), this, SLOT(deleteClient(QString))); + setWindowTitle("Port: " + QString::number(server->getAdress())); + QString allIP = server->getIP(); + int i = 0; + for(i = 0; i < allIP.count("\n"); i++) + { + QString temp = allIP; + ui->widgetListOfIP->addItem(temp.remove(temp.indexOf('\n'), temp.length() - temp.indexOf('\n'))); + allIP = allIP.remove(0, allIP.indexOf('\n') + 1); + } + ui->widgetListOfIP->addItem(allIP.remove(allIP.length() - 1, 1)); +} + +void Widget::addNewClient(QString newClient) +{ + ui->widgetListOfNames->addItem(newClient); +} + +void Widget::deleteClient(QString clientsIP) +{ + for (int i = 0; i < ui->widgetListOfNames->count(); i++) + if (ui->widgetListOfNames->item(i)->text() == clientsIP) + { + delete ui->widgetListOfNames->item(i); + return; + } +} From b439a6a90521c5d294ef2d3915e20b37e1174283 Mon Sep 17 00:00:00 2001 From: dyma96 Date: Wed, 9 Jul 2014 13:40:54 +0400 Subject: [PATCH 11/14] client level up. --- configurationServer/client/client.cpp | 10 +++++----- configurationServer/client/client.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/configurationServer/client/client.cpp b/configurationServer/client/client.cpp index 6fd71a4..8ebaf81 100644 --- a/configurationServer/client/client.cpp +++ b/configurationServer/client/client.cpp @@ -30,14 +30,14 @@ Client::Client(QWidget *parent) : chatText->setReadOnly(true); /// adding adresses to combo box - hostAdress = new QComboBox; - QList adressList = QNetworkInterface::allAddresses(); + hostAdress = new QLineEdit; +/* QList adressList = QNetworkInterface::allAddresses(); for (int i = 0; i < adressList.size(); ++i) { - hostAdress->addItem(adressList.at(i).toString()); + hostAdress->addItem(adressList.at(i).toString()); } - +*/ serverSocket = new QTcpSocket; ///adding operation to buttons: @@ -190,7 +190,7 @@ void Client::displayError(QAbstractSocket::SocketError socketError) void Client::connectToServer() { - serverSocket->connectToHost(hostAdress->currentText(), portLineEdit->text().toInt()); + serverSocket->connectToHost(hostAdress->text(), portLineEdit->text().toInt()); if (serverSocket->waitForConnected(5000)) { diff --git a/configurationServer/client/client.h b/configurationServer/client/client.h index eeea59c..9b93e52 100644 --- a/configurationServer/client/client.h +++ b/configurationServer/client/client.h @@ -39,7 +39,7 @@ private slots: QLabel *portLabel; /// combo box: - QComboBox *hostAdress; + QLineEdit *hostAdress; /// text widgets: QLineEdit *portLineEdit; From e1558f68e6bc60a0777f6be5f0ba25105d0c2d1b Mon Sep 17 00:00:00 2001 From: IlyaNikiforov Date: Wed, 9 Jul 2014 14:45:53 +0400 Subject: [PATCH 12/14] styleguided --- configurationServer/gui/server/server.cpp | 73 +++++++++-------------- configurationServer/gui/server/server.h | 30 ++++++---- configurationServer/gui/widget.cpp | 17 +----- 3 files changed, 48 insertions(+), 72 deletions(-) diff --git a/configurationServer/gui/server/server.cpp b/configurationServer/gui/server/server.cpp index 699a9ad..6e27f6c 100644 --- a/configurationServer/gui/server/server.cpp +++ b/configurationServer/gui/server/server.cpp @@ -1,15 +1,11 @@ -#include #include "server.h" Server::Server(QWidget *parent) : QDialog(parent), - tcpServer(0), - networkSession(0) - //blockSize(0), -{ + mTcpServer(0), + mNetworkSession(0) { QNetworkConfigurationManager manager; - if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) - { + if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) { // Get saved network configuration QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); settings.beginGroup(QLatin1String("QtNetwork")); @@ -18,35 +14,31 @@ Server::Server(QWidget *parent) : // If the saved network configuration is not currently discovered use the system default QNetworkConfiguration config = manager.configurationFromIdentifier(id); - if ((config.state() & QNetworkConfiguration::Discovered) != QNetworkConfiguration::Discovered) - { + if ((config.state() & QNetworkConfiguration::Discovered) != QNetworkConfiguration::Discovered) { config = manager.defaultConfiguration(); } - networkSession = new QNetworkSession(config, this); - connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); + mNetworkSession = new QNetworkSession(config, this); + connect(mNetworkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); - networkSession->open(); - } - else - { + mNetworkSession->open(); + } else { sessionOpened(); } - mapper = new QSignalMapper; - connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptClientConnection())); - connect(mapper, SIGNAL(mapped(QString)), this, SLOT(clientDisconnectedSlot(QString))); + mIPAddressMapper = new QSignalMapper; + connect(mTcpServer, SIGNAL(newConnection()), this, SLOT(acceptClientConnection())); + connect(mIPAddressMapper, SIGNAL(mapped(QString)), this, SIGNAL(clientDisconnected(QString))); } void Server::sessionOpened() { // Save the used configuration - if (networkSession) - { - QNetworkConfiguration config = networkSession->configuration(); + if (mNetworkSession) { + QNetworkConfiguration config = mNetworkSession->configuration(); QString id; if (config.type() == QNetworkConfiguration::UserChoice) - id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); + id = mNetworkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); else id = config.identifier(); @@ -56,12 +48,11 @@ void Server::sessionOpened() settings.endGroup(); } - tcpServer = new QTcpServer(this); - if (!tcpServer->listen(QHostAddress::AnyIPv4, 55555)) - { + mTcpServer = new QTcpServer(this); + if (!mTcpServer->listen(QHostAddress::AnyIPv4, 55555)) { QMessageBox::critical(this, tr("qReal Server"), tr("Unable to start the server: %1.") - .arg(tcpServer->errorString())); + .arg(mTcpServer->errorString())); close(); return; } @@ -69,43 +60,40 @@ void Server::sessionOpened() void Server::acceptClientConnection() { - QTcpSocket* clientSocket = tcpServer->nextPendingConnection(); + QTcpSocket* clientSocket = mTcpServer->nextPendingConnection(); emit newClient(clientSocket->peerAddress().toString()); int idusersocs = clientSocket->socketDescriptor(); - SClients[idusersocs] = clientSocket; - connect(SClients[idusersocs], SIGNAL(disconnected()), mapper, SLOT(map())); - mapper->setMapping(SClients[idusersocs], SClients[idusersocs]->peerAddress().toString()); - connect(SClients[idusersocs], SIGNAL(disconnected()), SClients[idusersocs], SLOT(deleteLater())); + mSClients[idusersocs] = clientSocket; + connect(mSClients[idusersocs], SIGNAL(disconnected()), mIPAddressMapper, SLOT(map())); + mIPAddressMapper->setMapping(mSClients[idusersocs], mSClients[idusersocs]->peerAddress().toString()); + connect(mSClients[idusersocs], SIGNAL(disconnected()), mSClients[idusersocs], SLOT(deleteLater())); sendSettings(); } void Server::sendSettings() { - if(!SClients.isEmpty()) - { + if(!mSClients.isEmpty()) { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out << (quint16)qReal::SettingsManager::instance()->convertToString().length(); out << qReal::SettingsManager::instance()->convertToString(); - foreach(int i, SClients.keys()) - { - SClients[i]->write(block); + foreach(int i, mSClients.keys()) { + mSClients[i]->write(block); } } } -quint16 Server::getAdress() +quint16 Server::getPort() { - return tcpServer->serverPort(); + return mTcpServer->serverPort(); } QString Server::getIP() { QList addressList = QNetworkInterface::allInterfaces(); QString address; - for (int j = 0; j < addressList.size(); j++) - { + for (int j = 0; j < addressList.size(); j++) { QList addressEntry = addressList[j].addressEntries(); for (int i = 0; i < addressEntry.size(); i++) if (!addressEntry[i].ip().isLoopback() @@ -115,8 +103,3 @@ QString Server::getIP() return address; } - -void Server::clientDisconnectedSlot(QString clientsID) -{ - emit clientDisconnectedSignal(clientsID); -} diff --git a/configurationServer/gui/server/server.h b/configurationServer/gui/server/server.h index 0a8781c..59fdc4a 100644 --- a/configurationServer/gui/server/server.h +++ b/configurationServer/gui/server/server.h @@ -2,33 +2,39 @@ #include #include +#include #include "qrkernel/settingsManager.h" -class Server : public QDialog -{ +class Server : public QDialog { Q_OBJECT public: explicit Server(QWidget *parent = 0); + /// returns a string, including all IPv4 addresses of this computer QString getIP(); - quint16 getAdress(); + /// returns port to coonect this server + quint16 getPort(); + +protected: + /// sends his qReal settings to client + void sendSettings(); private slots: void sessionOpened(); void acceptClientConnection(); - void clientDisconnectedSlot(QString clientsID); signals: - void newClient(QString clientName); - void clientDisconnectedSignal(QString clientsIP); + /// emits new client's IP, when connected + void newClient(QString clientIP); + /// emits IP of disconnected client + void clientDisconnected(QString clientsIP); private: - void sendSettings(); - QMap SClients; - QTcpServer *tcpServer; - QNetworkSession *networkSession; - quint16 blockSize; - QSignalMapper *mapper; + /// storage of all clients + QMap mSClients; + QTcpServer *mTcpServer; + QNetworkSession *mNetworkSession; + QSignalMapper *mIPAddressMapper; }; diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp index 86cd20a..9fbcf78 100644 --- a/configurationServer/gui/widget.cpp +++ b/configurationServer/gui/widget.cpp @@ -23,30 +23,17 @@ void Widget::init() ui->widgetSettings->layout()->addWidget(dialog); dialog->setParent(ui->widgetSettings); connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); - connect(server, SIGNAL(clientDisconnectedSignal(QString)), this, SLOT(deleteClient(QString))); - setWindowTitle(" Adress: " + QString::number(server->getAdress())); + connect(server, SIGNAL(clientDisconnected(QString)), this, SLOT(deleteClient(QString))); + setWindowTitle("Port: " + QString::number(server->getPort())); QString allIP = server->getIP(); int i = 0; -// while (i < allIP.length()) -// { -// while (allIP[i] != '\n') -// i++; -// QString temp; -// for (int j = 0; j < i; j++) -// temp[j] = allIP[i + j]; -// ui->widgetListOfIP->addItem(allIP.remove(0, i)); -// i++; -// } for(i = 0; i < allIP.count("\n"); i++) { QString temp = allIP; ui->widgetListOfIP->addItem(temp.remove(temp.indexOf('\n'), temp.length() - temp.indexOf('\n'))); - //ui->widgetListOfIP->addItem(allIP.remove(0, allIP.indexOf('\n') + 1)); allIP = allIP.remove(0, allIP.indexOf('\n') + 1); } ui->widgetListOfIP->addItem(allIP.remove(allIP.length() - 1, 1)); - - //ui->widgetListOfIP->addItem(server->getIP()); } void Widget::addNewClient(QString newClient) From 48a8fcec03892ba7c98ebaaa58fc764f7b17c05d Mon Sep 17 00:00:00 2001 From: dyma96 Date: Wed, 9 Jul 2014 14:47:33 +0400 Subject: [PATCH 13/14] Some changes of styleguide. --- configurationServer/client/8_1client.pro | 26 -- configurationServer/client/client.cpp | 220 ---------------- configurationServer/client/client.h | 53 ---- configurationServer/client/client.ui | 24 -- configurationServer/client/main.cpp | 11 - configurationServer/gui/brandManager/styles.h | 30 ++- configurationServer/gui/gui.pro.user | 248 ------------------ configurationServer/gui/preferencesDialog.cpp | 4 +- configurationServer/gui/preferencesDialog.h | 4 +- configurationServer/gui/ui_widget.h | 11 +- configurationServer/gui/widget.cpp | 57 ++-- configurationServer/gui/widget.cpp.autosave | 52 ---- configurationServer/gui/widget.h | 15 +- configurationServer/server/kernelDeclSpec.h | 11 - configurationServer/server/main.cpp | 11 - configurationServer/server/server.cpp | 211 --------------- configurationServer/server/server.h | 52 ---- configurationServer/server/server.pro | 27 -- configurationServer/server/server.pro.user | 248 ------------------ .../server/settingsManager.cpp | 134 ---------- configurationServer/server/settingsManager.h | 91 ------- 21 files changed, 58 insertions(+), 1482 deletions(-) delete mode 100644 configurationServer/client/8_1client.pro delete mode 100644 configurationServer/client/client.cpp delete mode 100644 configurationServer/client/client.h delete mode 100644 configurationServer/client/client.ui delete mode 100644 configurationServer/client/main.cpp delete mode 100644 configurationServer/gui/gui.pro.user delete mode 100644 configurationServer/gui/widget.cpp.autosave delete mode 100644 configurationServer/server/kernelDeclSpec.h delete mode 100644 configurationServer/server/main.cpp delete mode 100644 configurationServer/server/server.cpp delete mode 100644 configurationServer/server/server.h delete mode 100644 configurationServer/server/server.pro delete mode 100644 configurationServer/server/server.pro.user delete mode 100644 configurationServer/server/settingsManager.cpp delete mode 100644 configurationServer/server/settingsManager.h diff --git a/configurationServer/client/8_1client.pro b/configurationServer/client/8_1client.pro deleted file mode 100644 index 1eeb9a7..0000000 --- a/configurationServer/client/8_1client.pro +++ /dev/null @@ -1,26 +0,0 @@ -HEADERS = client.h - SOURCES = client.cpp \ - main.cpp - QT += network - QT += core gui - QT += widgets - - - # install - target.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneclient - sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS fortuneclient.pro - sources.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneclient - INSTALLS += target sources - - symbian { - include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - TARGET.CAPABILITY = "NetworkServices ReadUserData WriteUserData" - TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 - } - maemo5: include($$QT_SOURCE_TREE/examples/maemo5pkgrules.pri) - - symbian: warning(This example might not fully work on Symbian platform) - maemo5: warning(This example might not fully work on Maemo platform) - simulator: warning(This example might not fully work on Simulator platform) - -FORMS += diff --git a/configurationServer/client/client.cpp b/configurationServer/client/client.cpp deleted file mode 100644 index 8ebaf81..0000000 --- a/configurationServer/client/client.cpp +++ /dev/null @@ -1,220 +0,0 @@ -#include "client.h" - -Client::Client(QWidget *parent) : - QDialog(parent), - networkSession(0), - blockSize(0) -{ - - setWindowTitle(tr("Chat client")); - - /// creating buttons and text: - hostLabel = new QLabel(tr("Server IP-adress:")); - - portLabel = new QLabel(tr("Server port:")); - - portLineEdit = new QLineEdit; - portLineEdit->setValidator(new QIntValidator(1, 65535)); - - messageText = new QLineEdit; - - sendButton = new QPushButton(tr("Send")); - sendButton->setDisabled(true); - - connectButton = new QPushButton(tr("Connect")); - - quitButton = new QPushButton(tr("Quit")); - quitButton->setAutoDefault(false); - - chatText = new QTextEdit; - chatText->setReadOnly(true); - - /// adding adresses to combo box - hostAdress = new QLineEdit; -/* QList adressList = QNetworkInterface::allAddresses(); - - for (int i = 0; i < adressList.size(); ++i) - { - hostAdress->addItem(adressList.at(i).toString()); - } -*/ - serverSocket = new QTcpSocket; - - ///adding operation to buttons: - connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); - connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); - connect(serverSocket, SIGNAL(readyRead()), this, SLOT(receiveMessage())); - connect(connectButton, SIGNAL(clicked()), this, SLOT(connectToServer())); - connect(serverSocket, SIGNAL(disconnected()), this, SLOT(disconnectedFromServer())); - connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(displayError(QAbstractSocket::SocketError))); - - /// adding widgets into the window: - QGridLayout *connectionLayout = new QGridLayout; - connectionLayout->addWidget(hostLabel, 0, 0); - connectionLayout->addWidget(hostAdress, 0, 1); - connectionLayout->addWidget(portLabel, 1, 0); - connectionLayout->addWidget(portLineEdit, 1, 1); - - QHBoxLayout *messageLayout = new QHBoxLayout; - messageLayout->addWidget(messageText); - messageLayout->addWidget(sendButton); - - QHBoxLayout *buttonLayout = new QHBoxLayout; - buttonLayout->addStretch(1); - buttonLayout->addWidget(connectButton); - buttonLayout->addStretch(1); - buttonLayout->addWidget(quitButton); - buttonLayout->addStretch(1); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addLayout(connectionLayout); - mainLayout->addWidget(chatText); - mainLayout->addLayout(messageLayout); - mainLayout->addLayout(buttonLayout); - setLayout(mainLayout); - - portLineEdit->setFocus(); - - QNetworkConfigurationManager manager; - if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) - { - // Get saved network configuration - QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); - settings.beginGroup(QLatin1String("QtNetwork")); - const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString(); - settings.endGroup(); - - // If the saved network configuration is not currently discovered use the system default - QNetworkConfiguration config = manager.configurationFromIdentifier(id); - if ((config.state() & QNetworkConfiguration::Discovered) != - QNetworkConfiguration::Discovered) - { - config = manager.defaultConfiguration(); - } - - networkSession = new QNetworkSession(config, this); - connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); - - networkSession->open(); - } -} - -void Client::receiveMessage() -{ - QDataStream in(serverSocket); - in.setVersion(QDataStream::Qt_5_2); - - if (blockSize == 0) - { - if (serverSocket->bytesAvailable() < (int)sizeof(quint16)) - return; - - in >> blockSize; - } - - if (serverSocket->bytesAvailable() < blockSize) - return; - - blockSize = 0; - QString newMessage; - in >> newMessage; - chatText->textCursor().insertText("Server: " + newMessage + '\n'); -} - -void Client::sendMessage() -{ - if (messageText->text().isEmpty()) - return; - sendButton->setEnabled(false); - - QByteArray block; - QDataStream out(&block, QIODevice::WriteOnly); - out << (quint16)messageText->text().length(); - out << messageText->text(); - serverSocket->write(block); - - chatText->textCursor().insertText("You: " + messageText->text() + '\n'); - - messageText->clear(); - - sendButton->setEnabled(true); -} - -void Client::sessionOpened() -{ - // Save the used configuration - QNetworkConfiguration config = networkSession->configuration(); - QString id; - if (config.type() == QNetworkConfiguration::UserChoice) - id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); - else - id = config.identifier(); - - QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); - settings.beginGroup(QLatin1String("QtNetwork")); - settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); - settings.endGroup(); - - - sendButton->setEnabled(true); -} - -void Client::displayError(QAbstractSocket::SocketError socketError) -{ - serverSocket->close(); - switch (socketError) - { - case QAbstractSocket::RemoteHostClosedError: - break; - case QAbstractSocket::HostNotFoundError: - QMessageBox::information(this, tr("Chat client"), - tr("The host was not found. Please check the " - "host name and port settings.")); - break; - case QAbstractSocket::ConnectionRefusedError: - QMessageBox::information(this, tr("Chat client"), - tr("The connection was refused by the peer. " - "Make sure the fortune server is running, " - "and check that the host name and port " - "settings are correct.")); - break; - default: - QMessageBox::information(this, tr("Chat client"), - tr("The following error occurred: %1.") - .arg(serverSocket->errorString())); - } - hostAdress->setEnabled(true); - portLineEdit->setEnabled(true); -} - -void Client::connectToServer() -{ - serverSocket->connectToHost(hostAdress->text(), portLineEdit->text().toInt()); - - if (serverSocket->waitForConnected(5000)) - { - chatText->clear(); - chatText->textCursor().insertText("Server connected!\n"); - hostAdress->setDisabled(true); - portLineEdit->setDisabled(true); - connectButton->setDisabled(true); - sendButton->setEnabled(true); - } - else - { - hostAdress->setEnabled(true); - portLineEdit->setEnabled(true); - } -} - -void Client::disconnectedFromServer() -{ - hostAdress->setDisabled(true); - portLineEdit->setDisabled(true); - connectButton->setEnabled(true); - sendButton->setDisabled(true); - - QMessageBox::information(this, tr("Chat Client"), - tr("Server disconnected!")); -} diff --git a/configurationServer/client/client.h b/configurationServer/client/client.h deleted file mode 100644 index 9b93e52..0000000 --- a/configurationServer/client/client.h +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class Client : public QDialog -{ - Q_OBJECT - -public: - explicit Client(QWidget *parent = 0); - -private slots: - void sessionOpened(); - void displayError(QAbstractSocket::SocketError socketError); - - /// sends message - void sendMessage(); - - /// receives message - void receiveMessage(); - - void connectToServer(); - void disconnectedFromServer(); - -private: - /// buttons: - QPushButton *quitButton; - QPushButton *sendButton; - QPushButton *connectButton; - - /// labels: - QLabel *hostLabel; - QLabel *portLabel; - - /// combo box: - QLineEdit *hostAdress; - - /// text widgets: - QLineEdit *portLineEdit; - QTextEdit *chatText; - QLineEdit *messageText; - - - QTcpSocket *serverSocket; - QNetworkSession *networkSession; - quint16 blockSize; -}; diff --git a/configurationServer/client/client.ui b/configurationServer/client/client.ui deleted file mode 100644 index 0822f8f..0000000 --- a/configurationServer/client/client.ui +++ /dev/null @@ -1,24 +0,0 @@ - - Client - - - - 0 - 0 - 400 - 300 - - - - Client - - - - - - - - - - - diff --git a/configurationServer/client/main.cpp b/configurationServer/client/main.cpp deleted file mode 100644 index b6ebece..0000000 --- a/configurationServer/client/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "client.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - Client w; - w.show(); - - return a.exec(); -} diff --git a/configurationServer/gui/brandManager/styles.h b/configurationServer/gui/brandManager/styles.h index 57fc2ad..abb02e8 100644 --- a/configurationServer/gui/brandManager/styles.h +++ b/configurationServer/gui/brandManager/styles.h @@ -23,52 +23,60 @@ class Styles /// Returns json stylesheet for start tab background virtual QString startTabBackgroundStyle() const { -// return utils::InFile::readAll(startTabBackgroundStylePath()); + return nullptr; + // return utils::InFile::readAll(startTabBackgroundStylePath()); } /// Returns json stylesheet for start tab substrate background virtual QString startTabSubstrateBackgroundStyle() const { -// return utils::InFile::readAll(startTabSubstrateBackgroundStylePath()); + return nullptr; + // return utils::InFile::readAll(startTabSubstrateBackgroundStylePath()); } /// Returns json stylesheet for start tab header background virtual QString startTabHeaderBackgroundStyle() const { -// return utils::InFile::readAll(startTabHeaderBackgroundStylePath()); + return nullptr; + // return utils::InFile::readAll(startTabHeaderBackgroundStylePath()); } /// Returns json stylesheet for recent projects section background on start tab virtual QString startTabRecentProjectsBackgroundStyle() const { -// return utils::InFile::readAll(startTabRecentProjectsBackgroundStylePath()); + return nullptr; + // return utils::InFile::readAll(startTabRecentProjectsBackgroundStylePath()); } /// Returns json stylesheet for projects management section background on start tab virtual QString startTabProjectsManagementBackgroundStyle() const { -// return utils::InFile::readAll(startTabProjectsManagementBackgroundStylePath()); + return nullptr; + // return utils::InFile::readAll(startTabProjectsManagementBackgroundStylePath()); } /// Returns json stylesheet for command buttons on start tab virtual QString startTabButtonStyle() const { -// return utils::InFile::readAll(startTabButtonStylePath()) -// .replace("@@FONT@@", mFonts.commandButtonsFont()); + return nullptr; + // return utils::InFile::readAll(startTabButtonStylePath()) + // .replace("@@FONT@@", mFonts.commandButtonsFont()); } /// Returns json stylesheet for styled text on start tab of level 1 heading virtual QString startTabLabelLevel1Style() const { -// return utils::InFile::readAll(startTabLabelLevel1StylePath()) -// .replace("@@FONT@@", mFonts.styledTextFont()); + return nullptr; + // return utils::InFile::readAll(startTabLabelLevel1StylePath()) + // .replace("@@FONT@@", mFonts.styledTextFont()); } /// Returns json stylesheet for styled text on start tab of level 2 heading virtual QString startTabLabelLevel2Style() const { -// return utils::InFile::readAll(startTabLabelLevel2StylePath()) -// .replace("@@FONT@@", mFonts.styledTextFont()); + return nullptr; + // return utils::InFile::readAll(startTabLabelLevel2StylePath()) + // .replace("@@FONT@@", mFonts.styledTextFont()); } protected: diff --git a/configurationServer/gui/gui.pro.user b/configurationServer/gui/gui.pro.user deleted file mode 100644 index c388382..0000000 --- a/configurationServer/gui/gui.pro.user +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - true - 1 - true - 0 - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - - ProjectExplorer.Project.Target.0 - - Desktop Qt 5.2.1 MinGW 32bit - Desktop Qt 5.2.1 MinGW 32bit - qt.521.win32_mingw48.essentials_kit - 0 - 0 - 0 - - C:/Programming/Debugging - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - true - - false - - - true - Сборка - - Qt4ProjectManager.MakeStep - - false - - - - 2 - Сборка - - ProjectExplorer.BuildSteps.Build - - - - true - Сборка - - Qt4ProjectManager.MakeStep - - true - clean - - - 1 - Очистка - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Отладка - - Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - - C:/Programming/Debugging - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - true - - false - - - true - Сборка - - Qt4ProjectManager.MakeStep - - false - - - - 2 - Сборка - - ProjectExplorer.BuildSteps.Build - - - - true - Сборка - - Qt4ProjectManager.MakeStep - - true - clean - - - 1 - Очистка - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Выпуск - - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - 2 - - - 0 - Установка - - ProjectExplorer.BuildSteps.Deploy - - 1 - Локальная установка - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - gui - - Qt4ProjectManager.Qt4RunConfiguration:C:/Programming/SummerSchool/tools/configurationServer/gui/gui.pro - - gui.pro - false - false - - 3768 - true - false - false - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.EnvironmentId - {b98c4ef7-5a11-4065-9906-b1f08baf52f0} - - - ProjectExplorer.Project.Updater.FileVersion - 15 - - diff --git a/configurationServer/gui/preferencesDialog.cpp b/configurationServer/gui/preferencesDialog.cpp index c9fa78e..dbe778e 100644 --- a/configurationServer/gui/preferencesDialog.cpp +++ b/configurationServer/gui/preferencesDialog.cpp @@ -36,7 +36,7 @@ void PreferencesDialog::init(QAction * const showGridAction, QAction * const sho // Debugger page removed due to #736 PreferencesMiscellaniousPage *miscellaniousPage = new PreferencesMiscellaniousPage(mUi->pageContentWigdet); PreferencesPage *editorPage = new PreferencesEditorPage(showGridAction - , showAlignmentAction, activateGridAction, activateAlignmentAction, mUi->pageContentWigdet); + , showAlignmentAction, activateGridAction, activateAlignmentAction, mUi->pageContentWigdet); PreferencesPage *hotKeyManagerPage = new PreferencesHotKeyManagerPage(mUi->pageContentWigdet); mUi->applyButton->setVisible(false); @@ -57,7 +57,7 @@ void PreferencesDialog::init(QAction * const showGridAction, QAction * const sho connect(editorPage, SIGNAL(gridChanged()), this, SIGNAL(gridChanged())); connect(editorPage, SIGNAL(fontChanged()), this, SIGNAL(fontChanged())); connect(editorPage, SIGNAL(paletteRepresentationChanged()), this - , SIGNAL(paletteRepresentationChanged())); + , SIGNAL(paletteRepresentationChanged())); connect(miscellaniousPage, SIGNAL(iconsetChanged()), this, SIGNAL(iconsetChanged())); connect(miscellaniousPage, &PreferencesMiscellaniousPage::toolbarSizeChanged , this, &PreferencesDialog::toolbarSizeChanged); diff --git a/configurationServer/gui/preferencesDialog.h b/configurationServer/gui/preferencesDialog.h index 73ff7af..24b4180 100644 --- a/configurationServer/gui/preferencesDialog.h +++ b/configurationServer/gui/preferencesDialog.h @@ -10,7 +10,7 @@ #include "preferencesPages/preferencesPage.h" namespace Ui { - class PreferencesDialog; +class PreferencesDialog; } class PreferencesDialog : public utils::QRealDialog @@ -23,7 +23,7 @@ class PreferencesDialog : public utils::QRealDialog ~PreferencesDialog(); void init(QAction * const showGridAction, QAction * const showAlignmentAction - , QAction * const activateGridAction, QAction * const activateAlignmentAction); + , QAction * const activateGridAction, QAction * const activateAlignmentAction); void updatePluginDependendSettings(); void registerPage(QString const &pageName, PreferencesPage * const page); diff --git a/configurationServer/gui/ui_widget.h b/configurationServer/gui/ui_widget.h index ee8bb22..c5078a2 100644 --- a/configurationServer/gui/ui_widget.h +++ b/configurationServer/gui/ui_widget.h @@ -6,20 +6,15 @@ ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ -#ifndef UI_WIDGET_H -#define UI_WIDGET_H +#pragma once -#include #include #include -#include #include -#include #include #include #include #include -#include QT_BEGIN_NAMESPACE @@ -115,9 +110,7 @@ class Ui_Widget }; namespace Ui { - class Widget: public Ui_Widget {}; +class Widget: public Ui_Widget {}; } // namespace Ui QT_END_NAMESPACE - -#endif // UI_WIDGET_H diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp index 86cd20a..5923d65 100644 --- a/configurationServer/gui/widget.cpp +++ b/configurationServer/gui/widget.cpp @@ -5,61 +5,50 @@ Widget::Widget(QWidget *parent) : QWidget(parent), - ui(new Ui::Widget) + mUi(new Ui::Widget) { - ui->setupUi(this); + mUi->setupUi(this); } Widget::~Widget() { - delete ui; + delete mUi; } void Widget::init() { - server = new Server; + mServer = new Server; PreferencesDialog * dialog = new PreferencesDialog(); dialog->init(new QAction(dialog), new QAction(dialog), new QAction(dialog), new QAction(dialog)); - ui->widgetSettings->layout()->addWidget(dialog); - dialog->setParent(ui->widgetSettings); - connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); - connect(server, SIGNAL(clientDisconnectedSignal(QString)), this, SLOT(deleteClient(QString))); - setWindowTitle(" Adress: " + QString::number(server->getAdress())); - QString allIP = server->getIP(); - int i = 0; -// while (i < allIP.length()) -// { -// while (allIP[i] != '\n') -// i++; -// QString temp; -// for (int j = 0; j < i; j++) -// temp[j] = allIP[i + j]; -// ui->widgetListOfIP->addItem(allIP.remove(0, i)); -// i++; -// } - for(i = 0; i < allIP.count("\n"); i++) - { + mUi->widgetSettings->layout()->addWidget(dialog); + dialog->setParent(mUi->widgetSettings); + + connect(mServer, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); + connect(mServer, SIGNAL(clientDisconnectedSignal(QString)), this, SLOT(deleteClient(QString))); + + setWindowTitle("Port: " + QString::number(mServer->getAdress())); + + QString allIP = mServer->getIP(); + for(int i = 0; i < allIP.count("\n"); i++) { QString temp = allIP; - ui->widgetListOfIP->addItem(temp.remove(temp.indexOf('\n'), temp.length() - temp.indexOf('\n'))); - //ui->widgetListOfIP->addItem(allIP.remove(0, allIP.indexOf('\n') + 1)); + mUi->widgetListOfIP->addItem(temp.remove(temp.indexOf('\n'), temp.length() - temp.indexOf('\n'))); allIP = allIP.remove(0, allIP.indexOf('\n') + 1); } - ui->widgetListOfIP->addItem(allIP.remove(allIP.length() - 1, 1)); - //ui->widgetListOfIP->addItem(server->getIP()); + mUi->widgetListOfIP->addItem(allIP.remove(allIP.length() - 1, 1)); } -void Widget::addNewClient(QString newClient) +void Widget::addNewClient(const QString &newClient) { - ui->widgetListOfNames->addItem(newClient); + mUi->widgetListOfNames->addItem(newClient); } -void Widget::deleteClient(QString clientsIP) +void Widget::deleteClient(const QString &clientsIP) { - for (int i = 0; i < ui->widgetListOfNames->count(); i++) - if (ui->widgetListOfNames->item(i)->text() == clientsIP) - { - delete ui->widgetListOfNames->item(i); + for (int i = 0; i < mUi->widgetListOfNames->count(); i++) { + if (mUi->widgetListOfNames->item(i)->text() == clientsIP) { + delete mUi->widgetListOfNames->item(i); return; } + } } diff --git a/configurationServer/gui/widget.cpp.autosave b/configurationServer/gui/widget.cpp.autosave deleted file mode 100644 index 6c8165c..0000000 --- a/configurationServer/gui/widget.cpp.autosave +++ /dev/null @@ -1,52 +0,0 @@ -#include "widget.h" -#include "ui_widget.h" - -#include "preferencesDialog.h" - -Widget::Widget(QWidget *parent) : - QWidget(parent), - ui(new Ui::Widget) -{ - ui->setupUi(this); -} - -Widget::~Widget() -{ - delete ui; -} - -void Widget::init() -{ - server = new Server; - PreferencesDialog * dialog = new PreferencesDialog(); - dialog->init(new QAction(dialog), new QAction(dialog), new QAction(dialog), new QAction(dialog)); - ui->widgetSettings->layout()->addWidget(dialog); - dialog->setParent(ui->widgetSettings); - connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); - connect(server, SIGNAL(clientDisconnectedSignal(QString)), this, SLOT(deleteClient(QString))); - setWindowTitle("Port: " + QString::number(server->getAdress())); - QString allIP = server->getIP(); - int i = 0; - for(i = 0; i < allIP.count("\n"); i++) - { - QString temp = allIP; - ui->widgetListOfIP->addItem(temp.remove(temp.indexOf('\n'), temp.length() - temp.indexOf('\n'))); - allIP = allIP.remove(0, allIP.indexOf('\n') + 1); - } - ui->widgetListOfIP->addItem(allIP.remove(allIP.length() - 1, 1)); -} - -void Widget::addNewClient(QString newClient) -{ - ui->widgetListOfNames->addItem(newClient); -} - -void Widget::deleteClient(QString clientsIP) -{ - for (int i = 0; i < ui->widgetListOfNames->count(); i++) - if (ui->widgetListOfNames->item(i)->text() == clientsIP) - { - delete ui->widgetListOfNames->item(i); - return; - } -} diff --git a/configurationServer/gui/widget.h b/configurationServer/gui/widget.h index 15eeda6..ca39a39 100644 --- a/configurationServer/gui/widget.h +++ b/configurationServer/gui/widget.h @@ -7,6 +7,7 @@ namespace Ui { class Widget; } +/// Class of window configuration server. class Widget : public QWidget { Q_OBJECT @@ -14,15 +15,19 @@ class Widget : public QWidget public: explicit Widget(QWidget *parent = 0); ~Widget(); + + /// Initialize widget. void init(); private slots: - void addNewClient(QString newClient); - void deleteClient(QString clientsIP); + /// Slot of connect new client. + void addNewClient(QString const &newClient); + + /// Slot of delete client. + void deleteClient(QString const &clientsIP); private: - Ui::Widget *ui; - QWidget *widgetSettings; - Server *server; + Ui::Widget *mUi; + Server *mServer; }; diff --git a/configurationServer/server/kernelDeclSpec.h b/configurationServer/server/kernelDeclSpec.h deleted file mode 100644 index f3fa22e..0000000 --- a/configurationServer/server/kernelDeclSpec.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -#ifndef QRKERNEL_EXPORT -# if defined(QRKERNEL_LIBRARY) -# define QRKERNEL_EXPORT Q_DECL_EXPORT -# else -# define QRKERNEL_EXPORT Q_DECL_IMPORT -# endif -#endif diff --git a/configurationServer/server/main.cpp b/configurationServer/server/main.cpp deleted file mode 100644 index f728958..0000000 --- a/configurationServer/server/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "server.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - Server w; - w.show(); - - return a.exec(); -} diff --git a/configurationServer/server/server.cpp b/configurationServer/server/server.cpp deleted file mode 100644 index 3b7ef54..0000000 --- a/configurationServer/server/server.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include -#include "server.h" - -Server::Server(QWidget *parent) : - QDialog(parent), - tcpServer(0), - //clientSocket(0), - networkSession(0), - blockSize(0) -{ - /// creating widgets: - statusLabel = new QLabel; - - allText = new QTextEdit; - allText ->setReadOnly(true); - - messageText = new QLineEdit; - - sendButton = new QPushButton(tr("Send")); - sendButton->setDisabled(true); - - quitButton = new QPushButton(tr("Quit")); - quitButton->setAutoDefault(false); - - //Qmanager->setValue("abc", "def"); - //Qmanager->setValue("ghi", "jkl"); - - //allText->setText(Qmanager->); - - QNetworkConfigurationManager manager; - if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) - { - // Get saved network configuration - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); - settings.beginGroup(QLatin1String("QtNetwork")); - const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString(); - settings.endGroup(); - - // If the saved network configuration is not currently discovered use the system default - QNetworkConfiguration config = manager.configurationFromIdentifier(id); - if ((config.state() & QNetworkConfiguration::Discovered) != QNetworkConfiguration::Discovered) - { - config = manager.defaultConfiguration(); - } - - networkSession = new QNetworkSession(config, this); - connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); - - statusLabel->setText(tr("Opening network session.")); - networkSession->open(); - } - else - { - sessionOpened(); - } - - /// connecting widgets: - connect(sendButton, SIGNAL(clicked()), this, SLOT(sendSettings())); - connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); - connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptClientConnection())); - - /// adding widgets into the window: - QHBoxLayout *messageLayout = new QHBoxLayout; - messageLayout->addWidget(messageText); - messageLayout->addWidget(sendButton); - - QHBoxLayout *quitLayout = new QHBoxLayout; - quitLayout->addStretch(1); - quitLayout->addWidget(quitButton); - quitLayout->addStretch(1); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(statusLabel); - mainLayout->addWidget(allText); - mainLayout->addLayout(messageLayout); - mainLayout->addLayout(quitLayout); - setLayout(mainLayout); - - setWindowTitle(tr("Chat Server")); -} - -void Server::sessionOpened() - { - // Save the used configuration - if (networkSession) - { - QNetworkConfiguration config = networkSession->configuration(); - QString id; - if (config.type() == QNetworkConfiguration::UserChoice) - id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString(); - else - id = config.identifier(); - - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); - settings.beginGroup(QLatin1String("QtNetwork")); - settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); - settings.endGroup(); - } - - tcpServer = new QTcpServer(this); - if (!tcpServer->listen(QHostAddress::LocalHost, tcpServer->serverPort())) - { - QMessageBox::critical(this, tr("Chat Server"), - tr("Unable to start the server: %1.") - .arg(tcpServer->errorString())); - close(); - return; - } - - statusLabel->setText(tr("The server is running on\n\nIP-adress: %1\nPort: %2\n\n" - "Run the Chat Client now.") - .arg(tcpServer->serverAddress().toString()).arg(tcpServer->serverPort())); - } - -void Server::acceptClientConnection() -{ - QTcpSocket* clientSocket=tcpServer->nextPendingConnection(); - int idusersocs=clientSocket->socketDescriptor(); - SClients[idusersocs]=clientSocket; - connect(SClients[idusersocs], SIGNAL(readyRead()), this, SLOT(receiveMessage())); - connect(SClients[idusersocs], SIGNAL(disconnected()), this, SLOT(disconnectedFromClient())); - connect(SClients[idusersocs], SIGNAL(disconnected()), SClients[idusersocs], SLOT(deleteLater())); - - allText->clear(); - allText->textCursor().insertText("Client connected!\n"); - - sendButton->setEnabled(true); -} - -void Server::receiveMessage() -{ - QTcpSocket* clientSocket = (QTcpSocket*)sender(); - QDataStream in(clientSocket); - in.setVersion(QDataStream::Qt_5_2); - - if (blockSize == 0) - { - if (clientSocket->bytesAvailable() < (int)sizeof(quint16)) - return; - - in >> blockSize; - } - - if (clientSocket->bytesAvailable() < blockSize) - return; - - blockSize = 0; - QString newMessage; - in >> newMessage; - allText ->textCursor().insertText("Client: " + newMessage + '\n'); -} - -//void Server::sendSettings() -//{ -// if(!SClients.isEmpty()) -// { -// if (messageText->text().isEmpty()) -// return; -// sendButton->setDisabled(true); - -// QByteArray block; -// QDataStream out(&block, QIODevice::WriteOnly); - -// out << (quint16)messageText->text().length(); -// out << messageText->text(); -// foreach(int i,SClients.keys()) -// { -// SClients[i]->write(block); -// } - -// allText ->textCursor().insertText("You: " + messageText->text() + '\n'); - -// messageText->clear(); - -// sendButton->setEnabled(true); -// } -//} - -void Server::sendSettings() -{ - if(!SClients.isEmpty()) - { - //if (messageText->text().isEmpty()) - // return; - sendButton->setDisabled(true); - - QByteArray block; - QDataStream out(&block, QIODevice::WriteOnly); - - out << (quint16)qReal::SettingsManager::instance()->convertToString().length(); - out << qReal::SettingsManager::instance()->convertToString(); - foreach(int i, SClients.keys()) - { - SClients[i]->write(block); - } - - allText ->textCursor().insertText("You: " + qReal::SettingsManager::instance()->convertToString() + '\n'); - - messageText->clear(); - - sendButton->setEnabled(true); - } -} - -void Server::clientDisconnected() -{ - sendButton->setDisabled(true); - QMessageBox::information(this, tr("Chat Server"), - tr("Client disconnected!")); -} diff --git a/configurationServer/server/server.h b/configurationServer/server/server.h deleted file mode 100644 index 5e0548f..0000000 --- a/configurationServer/server/server.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef SERVER_H -#define SERVER_H - -#include -#include -#include -#include -#include -#include - -#include "settingsManager.h" - -namespace Ui { -class Server; -} - -class Server : public QDialog -{ - Q_OBJECT - -public: - explicit Server(QWidget *parent = 0); - -private slots: - void sessionOpened(); - void acceptClientConnection(); - void sendSettings(); - void receiveMessage(); - void clientDisconnected(); - -private: - /// labels: - QLabel *statusLabel; - - /// text widgets: - QLineEdit *messageText; - QTextEdit *allText; - - /// buttons: - QPushButton *sendButton; - QPushButton *quitButton; - - - QTcpServer *tcpServer; - QNetworkSession *networkSession; - QMap SClients; - //qReal::SettingsManager *Qmanager; - - quint16 blockSize; -}; - -#endif // SERVER_H diff --git a/configurationServer/server/server.pro b/configurationServer/server/server.pro deleted file mode 100644 index b485fe8..0000000 --- a/configurationServer/server/server.pro +++ /dev/null @@ -1,27 +0,0 @@ -HEADERS = server.h \ - settingsManager.h \ - kernelDeclSpec.h - SOURCES = server.cpp \ - main.cpp \ - settingsManager.cpp - QT += network - QT += core gui widgets - CONFIG += c++11 - - # install - target.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneserver - sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS fortuneserver.pro - sources.path = $$[QT_INSTALL_EXAMPLES]/network/fortuneserver - INSTALLS += target sources - - symbian { - TARGET.UID3 = 0xA000E406 - include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - TARGET.CAPABILITY = "NetworkServices ReadUserData" - TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 - } - maemo5: include($$QT_SOURCE_TREE/examples/maemo5pkgrules.pri) - - symbian: warning(This example might not fully work on Symbian platform) - maemo5: warning(This example might not fully work on Maemo platform) - simulator: warning(This example might not fully work on Simulator platform) diff --git a/configurationServer/server/server.pro.user b/configurationServer/server/server.pro.user deleted file mode 100644 index 65cb59c..0000000 --- a/configurationServer/server/server.pro.user +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - true - 1 - true - 0 - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - - ProjectExplorer.Project.Target.0 - - Desktop Qt 5.2.1 MinGW 32bit - Desktop Qt 5.2.1 MinGW 32bit - qt.521.win32_mingw48.essentials_kit - 0 - 0 - 0 - - C:/Programming/SummerSchool/tools/configurationServer/build-server-Desktop_Qt_5_2_1_MinGW_32bit-Debug - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - true - - false - - - true - Сборка - - Qt4ProjectManager.MakeStep - - false - - - - 2 - Сборка - - ProjectExplorer.BuildSteps.Build - - - - true - Сборка - - Qt4ProjectManager.MakeStep - - true - clean - - - 1 - Очистка - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Отладка - - Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - - C:/Programming/SummerSchool/tools/configurationServer/build-server-Desktop_Qt_5_2_1_MinGW_32bit-Release - - - true - qmake - - QtProjectManager.QMakeBuildStep - false - true - - false - - - true - Сборка - - Qt4ProjectManager.MakeStep - - false - - - - 2 - Сборка - - ProjectExplorer.BuildSteps.Build - - - - true - Сборка - - Qt4ProjectManager.MakeStep - - true - clean - - - 1 - Очистка - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Выпуск - - Qt4ProjectManager.Qt4BuildConfiguration - 0 - true - - 2 - - - 0 - Установка - - ProjectExplorer.BuildSteps.Deploy - - 1 - Локальная установка - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - server - - Qt4ProjectManager.Qt4RunConfiguration:C:/Programming/SummerSchool/tools/configurationServer/server/server.pro - - server.pro - false - false - - 3768 - true - false - false - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.EnvironmentId - {b98c4ef7-5a11-4065-9906-b1f08baf52f0} - - - ProjectExplorer.Project.Updater.FileVersion - 15 - - diff --git a/configurationServer/server/settingsManager.cpp b/configurationServer/server/settingsManager.cpp deleted file mode 100644 index b8aeda5..0000000 --- a/configurationServer/server/settingsManager.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "settingsManager.h" - -#include -#include -#include -#include - -using namespace qReal; - -SettingsManager* SettingsManager::mInstance = nullptr; - -SettingsManager::SettingsManager() - : mSettings("SPbSU", "QReal") -{ - initDefaultValues(); - load(); -} - -SettingsManager::~SettingsManager() -{ -} - -void SettingsManager::setValue(QString const &name, QVariant const &value) -{ - QVariant const oldValue = instance()->value(name); - if (oldValue != value) { - instance()->set(name, value); - emit instance()->settingsChanged(name, oldValue, value); - } -} - -QVariant SettingsManager::value(QString const &key) -{ - return instance()->get(key); -} - -QVariant SettingsManager::value(QString const &key, QVariant const &defaultValue) -{ - return instance()->get(key, defaultValue); -} - -SettingsManager* SettingsManager::instance() -{ - if (mInstance == nullptr) { - mInstance = new SettingsManager(); - } - - return mInstance; -} - -void SettingsManager::set(QString const &name, QVariant const &value) -{ - mData[name] = value; -} - -QVariant SettingsManager::get(QString const &name, QVariant const &defaultValue) const -{ - if (mData.contains(name)) { - return mData[name]; - } - - if (mDefaultValues.contains(name) && defaultValue == QVariant()) { - return mDefaultValues[name]; - } - - return defaultValue; -} - -void SettingsManager::saveData() -{ - for (QString const &name : mData.keys()) { - mSettings.setValue(name, mData[name]); - } - - mSettings.sync(); -} - -void SettingsManager::saveSettings(QString const &fileNameForExport) -{ - QSettings settingsForSave(fileNameForExport, QSettings::IniFormat); - for (QString const &name : mData.keys()) { - settingsForSave.setValue(name, mData[name]); - } - - settingsForSave.sync(); -} - -void SettingsManager::load() -{ - for (QString const &name : mSettings.allKeys()) { - mData[name] = mSettings.value(name); - } -} - -void SettingsManager::loadSettings(QString const &fileNameForImport) -{ - mergeSettings(fileNameForImport, mData); - saveData(); -} - -void SettingsManager::initDefaultValues() -{ - mergeSettings(":/settingsDefaultValues", mDefaultValues); -} - -void SettingsManager::loadDefaultSettings(QString const &filePath) -{ - instance()->mergeSettings(filePath, instance()->mDefaultValues); -} - -void SettingsManager::mergeSettings(QString const &fileNameForImport, QHash &target) -{ - QSettings settings(fileNameForImport, QSettings::IniFormat); - for (QString const &name : settings.allKeys()) { - target[name] = settings.value(name); - } -} - -void SettingsManager::clearSettings() -{ - instance()->mSettings.clear(); - instance()->mData.clear(); - instance()->mDefaultValues.clear(); -} - -QString SettingsManager::convertToString() -{ - QString allSettings; - QStringList keyList = mSettings.allKeys(); - for (int i = 0; i < keyList.size(); i++) - allSettings += keyList[i] + "###" + value(keyList[i]).toString() + "#*#"; - - return allSettings; -} diff --git a/configurationServer/server/settingsManager.h b/configurationServer/server/settingsManager.h deleted file mode 100644 index 9f680e2..0000000 --- a/configurationServer/server/settingsManager.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "kernelDeclSpec.h" - -namespace qReal { - -/// Singleton class that allows to change settings in run-time -/// (replaces QSettings). Purpose of this class is to allow two instances -/// of an application coexist without changing each other's settings, -/// by storing settings separately in memory for each instance and syncing -/// them only on start/exit. -class SettingsManager : public QObject -{ - Q_OBJECT - -public: - /// Get value associated with given key from settings. - /// @param key Parameter name. - /// @returns Variant with parameter value. - static QVariant value(QString const &key); - - /// Get value associated with given key from settings with given default value. - /// @param key Parameter name. - /// @param defaultValue Default value, used when parameter not found. - /// @returns Variant with parameter value. - static QVariant value(QString const &key, QVariant const &defaultValue); - - /// Set value associated with given key. - /// @param key Parameter name. - /// @param value Parameter value. - static void setValue(QString const &key, QVariant const &value); - - /// Removes all entries in persistent external storage - static void clearSettings(); - - /// Returns an instance of a singleton. - static SettingsManager *instance(); - - /// Saves settings into persistent external storage (for example, Windows - /// registry), making them available to new instances of an application. - void saveData(); - - /// Saves settings into selected file with name fileNameForExport. - void saveSettings(QString const &fileNameForExport); - - /// Loads settings from persistent external storage into SettingsManager. - void load(); - - /// Merges settings from the given file in INI format. - void loadSettings(QString const &fileNameForImport); - - /// Merges default settings from the given file in INI format. - static void loadDefaultSettings(QString const &filePath); - - /// Convertes settings into QString - QString convertToString(); - -signals: - /// Emitted each time when settings with the given key were modified. - /// For connection instance() method can be useful. - void settingsChanged(QString const &name, QVariant const &oldValue, QVariant const &newValue); - -private: - /// Private constructor. - SettingsManager(); - ~SettingsManager(); - - void set(QString const &name, QVariant const &value); - QVariant get(QString const &key, QVariant const &defaultValue = QVariant()) const; - - /// Merges settings from the given file in INI format into the given map. - void mergeSettings(QString const &fileNameForImport, QHash &target); - - void initDefaultValues(); - - /// Singleton sole instance. - static SettingsManager *mInstance; - - /// In-memory settings storage. - QHash mData; - QHash mDefaultValues; - /// Persistent settings storage. - QSettings mSettings; -}; - -} From 3f8e6bf61db3cbc03d00bc53ed18515782f73d0a Mon Sep 17 00:00:00 2001 From: dyma96 Date: Wed, 9 Jul 2014 15:31:45 +0400 Subject: [PATCH 14/14] change for program work --- configurationServer/gui/widget.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/configurationServer/gui/widget.cpp b/configurationServer/gui/widget.cpp index 5b99049..50be13a 100644 --- a/configurationServer/gui/widget.cpp +++ b/configurationServer/gui/widget.cpp @@ -25,9 +25,9 @@ void Widget::init() dialog->setParent(mUi->widgetSettings); connect(mServer, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); - connect(mServer, SIGNAL(clientDisconnectedSignal(QString)), this, SLOT(deleteClient(QString))); + connect(mServer, SIGNAL(clientDisconnected(QString)), this, SLOT(deleteClient(QString))); - setWindowTitle("Port: " + QString::number(mServer->getAdress())); + setWindowTitle("Port: " + QString::number(mServer->getPort())); QString allIP = mServer->getIP(); for(int i = 0; i < allIP.count("\n"); i++) { @@ -37,20 +37,6 @@ void Widget::init() } mUi->widgetListOfIP->addItem(allIP.remove(allIP.length() - 1, 1)); - ui->widgetSettings->layout()->addWidget(dialog); - dialog->setParent(ui->widgetSettings); - connect(server, SIGNAL(newClient(QString)), this, SLOT(addNewClient(QString))); - connect(server, SIGNAL(clientDisconnected(QString)), this, SLOT(deleteClient(QString))); - setWindowTitle("Port: " + QString::number(server->getPort())); - QString allIP = server->getIP(); - int i = 0; - for(i = 0; i < allIP.count("\n"); i++) - { - QString temp = allIP; - ui->widgetListOfIP->addItem(temp.remove(temp.indexOf('\n'), temp.length() - temp.indexOf('\n'))); - allIP = allIP.remove(0, allIP.indexOf('\n') + 1); - } - ui->widgetListOfIP->addItem(allIP.remove(allIP.length() - 1, 1)); } void Widget::addNewClient(const QString &newClient)