OSDN Git Service

1f3eed7bdfe77a4fe72aa51b5a5cda9b19fe4220
[dennco/dennco.git] / Source / layer3 / QtDennco / mainwindow.cpp
1 //  Copyright (c) 2012 Dennco Project
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 //
17 //  Created by tkawata on 2/25/2012.
18 //
19 #include "mainwindow.h"
20 #include "ui_mainwindow.h"
21
22 #include <QFileDialog>
23 #include <QDir>
24 #include <QDebug>
25 #include <QWebFrame>
26 #include <QLocalSocket>
27
28 #include "TKLog.h"
29 #include "DNGlobal.h"
30 #include "DNAlert.h"
31 #include "DNEngine.h"
32 #include "TKConsole.h"
33 #include "dnwebinterface.h"
34 #include "DNSettings.h"
35 #include "versioninfo.h"
36
37 //static
38 QColor MainWindow::NORMAL_COLOR(0,0,0);
39 //static
40 QColor MainWindow::WARN_COLOR(0xff, 0x95, 0x2b);
41 //static
42 QColor MainWindow::ERROR_COLOR(0xff, 0,0);
43 //static
44 QWidget *MainWindow::instance = NULL;
45
46 MainWindow::MainWindow(QWidget *parent) :
47     QMainWindow(parent),
48     ui(new Ui::MainWindow),
49     mEngine(NULL), mWebInterface(NULL), mControlledByCreator(false), mCreatorIPCServer(NULL)
50 {
51     QStringList arguments = qApp->arguments();
52     for (int i = 0; i < arguments.length(); i++)
53     {
54         if (!mControlledByCreator && arguments.at(i) == "-creatorControlled")
55         {
56             i++;
57             if (i < arguments.length() && arguments.at(i).indexOf("denncoCreator_") == 0)
58             {
59                 mCreatorIPCServer = new QLocalServer(this);
60                 if (mCreatorIPCServer->listen(arguments.at(i)))
61                 {
62                     mControlledByCreator = true;
63                 }
64             }
65         }
66     }
67
68     instance = this;
69     ui->setupUi(this);
70
71     QString windowTitle = "dennco engine - ";
72     windowTitle.append(ENGINE_VERSION);
73
74     this->setWindowTitle(windowTitle);
75
76     if (!mControlledByCreator)
77     {
78         QString defaultPath(QDir::homePath());
79         QString contentPath = QString::fromStdString(DNSettings::getValue(DNSettings::CONTEXT_PATH, defaultPath.toStdString()));
80
81         ui->filePath->setText(contentPath);
82
83         ui->console->document()->setMaximumBlockCount(500);
84         QFont monofont("Courier");
85         monofont.setStyleHint(QFont::Monospace);
86         ui->console->setFont(monofont);
87         TKLog::setDestination(this);
88         connect(this, SIGNAL(consoleUpdated()), this, SLOT(update()), Qt::AutoConnection);
89
90         std::string savedWindowStateStr = DNSettings::getValue(DNSettings::WINDOWLAYOUT,"");
91         QByteArray savedWindowStateQArray(savedWindowStateStr.c_str());
92         restoreState(QByteArray::fromHex(savedWindowStateQArray));
93
94         std::string savedWindowGeometoryStr = DNSettings::getValue(DNSettings::WINDOWGEOMETORY,"");
95         QByteArray savedWindowGeometoryQArray(savedWindowGeometoryStr.c_str());
96         restoreGeometry(QByteArray::fromHex(savedWindowGeometoryQArray));
97     }
98     else
99     {
100         ui->filePath->setText("");
101         ui->filePath->setEnabled(false);
102         ui->chooseDirButton->setVisible(false);
103
104         ui->console->document()->setMaximumBlockCount(500);
105         QFont monofont("Courier");
106         monofont.setStyleHint(QFont::Monospace);
107         ui->console->setFont(monofont);
108         TKLog::setDestination(this);
109         connect(this, SIGNAL(consoleUpdated()), this, SLOT(update()), Qt::AutoConnection);
110
111         std::string savedWindowStateStr = DNSettings::getValue(DNSettings::CREATORCONTROLLED_WINDOWLAYOUT,"");
112         QByteArray savedWindowStateQArray(savedWindowStateStr.c_str());
113         restoreState(QByteArray::fromHex(savedWindowStateQArray));
114
115         std::string savedWindowGeometoryStr = DNSettings::getValue(DNSettings::CREATORCONTROLLED_WINDOWGEOMETORY,"");
116         QByteArray savedWindowGeometoryQArray(savedWindowGeometoryStr.c_str());
117         restoreGeometry(QByteArray::fromHex(savedWindowGeometoryQArray));
118
119         connect(mCreatorIPCServer, SIGNAL(newConnection()), this, SLOT(on_newRequestFromCreator()));
120     }
121 }
122
123 MainWindow::~MainWindow()
124 {
125     if (mCreatorIPCServer)
126         delete mCreatorIPCServer;
127
128     instance = 0;
129     delete ui;
130 }
131
132 void MainWindow::closeEvent(QCloseEvent *event)
133 {
134     if (!mControlledByCreator)
135     {
136         QByteArray savingWindowStateQArray = saveState().toHex();
137         DNSettings::setValue(DNSettings::WINDOWLAYOUT, savingWindowStateQArray.constData());
138
139         QByteArray savingWindowGeometoryQArray = saveGeometry().toHex();
140         DNSettings::setValue(DNSettings::WINDOWGEOMETORY, savingWindowGeometoryQArray.constData());
141     }
142     else
143     {
144         QByteArray savingWindowStateQArray = saveState().toHex();
145         DNSettings::setValue(DNSettings::CREATORCONTROLLED_WINDOWLAYOUT, savingWindowStateQArray.constData());
146
147         QByteArray savingWindowGeometoryQArray = saveGeometry().toHex();
148         DNSettings::setValue(DNSettings::CREATORCONTROLLED_WINDOWGEOMETORY, savingWindowGeometoryQArray.constData());
149     }
150
151     stopEngine();
152     deleteCurrentEngine();
153     QMainWindow::closeEvent(event);
154 }
155
156
157 void MainWindow::on_chooseDirButton_clicked()
158 {
159     if (QString::compare(ui->startButton->text(), "Stop", Qt::CaseInsensitive) == 0)
160     {
161         DNAlert::show("Please stop engine", "Dennco engine is running.\nPlease stop engine before switching directory.");
162         return;
163     }
164     QString dirPath = QFileDialog::getExistingDirectory(this,"Set dennco setting file",ui->filePath->text());
165     qDebug()<< dirPath;
166     if (dirPath.length() > 0)
167     {
168         ui->filePath->setText(dirPath);
169
170         DNSettings::setValue(DNSettings::CONTEXT_PATH, dirPath.toStdString());
171     }
172 }
173
174
175 void MainWindow::on_startButton_clicked()
176 {
177     qDebug()<< "start button clicked";
178     if (QString::compare(ui->startButton->text(), "Start", Qt::CaseInsensitive) == 0)
179     {
180         deleteCurrentEngine();
181
182         if (startEngine())
183         {
184             ui->startButton->setText("Stop");
185         }
186     }
187     else
188     {
189         stopEngine();
190         ui->startButton->setText("Start");
191     }
192 }
193
194 bool MainWindow::startEngine()
195 {
196     bool initializationFailed = false;
197
198     mEngine = new DNEngine(ui->filePath->text().toLocal8Bit().data());
199     if (!dnGlobal()->isErrorStatusNormal())
200     {
201         DNAlert::show(dnGlobal()->getMessage1(), dnGlobal()->getMessage2());
202         dnGlobal()->resetErrorStatus();
203         initializationFailed = true;
204     }
205     else if (!mEngine->isValid())
206     {
207         DNAlert::show("DNEngine initialize error", "ERROR. DNEngine not configured properly");
208         initializationFailed = true;
209     }
210
211     if (!initializationFailed)
212     {
213         mEngine->startEngine();
214         loadUI();
215     }
216     return !initializationFailed;
217 }
218
219 bool MainWindow::stopEngine()
220 {
221     if (mEngine)
222     {
223         mEngine->stopEngine();
224     }
225     return true;
226 }
227
228 void MainWindow::loadUI()
229 {
230     QString path = "file:///";
231     path.append(ui->filePath->text().append(QString::fromStdString(mEngine->getUIPath())));
232     QUrl pathUrl(path);
233     ui->webView->load(pathUrl);
234     mWebInterface = new DNWebInterface(mEngine);
235     attachWebInterface();
236 }
237
238 void MainWindow::attachWebInterface()
239 {
240     if (!mWebInterface)
241         return;
242
243     QWebPage *page = ui->webView->page();
244     if (page)
245     {
246         QWebFrame *frame = page->mainFrame();
247         if (frame)
248         {
249             frame->addToJavaScriptWindowObject("engine", mWebInterface);
250             connect(frame, SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(attachWebInterface()));
251             connect(frame, SIGNAL(initialLayoutCompleted()), this, SLOT(adjustWindowSize()));
252         }
253     }
254 }
255
256 void MainWindow::adjustWindowSize()
257 {
258     int hadjust = ui->webView->page()->mainFrame()->scrollBarMaximum(Qt::Horizontal);
259     int vadjust = ui->webView->page()->mainFrame()->scrollBarMaximum(Qt::Vertical);
260     hadjust = hadjust > 0 ? hadjust : 0;
261     vadjust = vadjust > 0 ? vadjust : 0;
262     QSize currentSize = size();
263     resize(currentSize.width() + hadjust, currentSize.height() + vadjust);
264 }
265
266 void MainWindow::deleteCurrentEngine()
267 {
268     if (mEngine)
269     {
270         delete mEngine;
271         mEngine = NULL;
272     }
273     if (mWebInterface)
274     {
275         delete mWebInterface;
276         mWebInterface = NULL;
277     }
278 }
279
280 void MainWindow::paintEvent( QPaintEvent * event )
281 {
282     mConsoleLock.lock();
283     while (!mPendingConsoleMessages.isEmpty())
284     {
285         PendingConsoleMessage aMessage = mPendingConsoleMessages.dequeue();
286         switch(aMessage.messageType)
287         {
288         case TKLog::NORMAL :
289             ui->console->setTextColor(NORMAL_COLOR);
290             break;
291         case TKLog::WARNING :
292             ui->console->setTextColor(WARN_COLOR);
293             break;
294         case TKLog::ERROR :
295             ui->console->setTextColor(ERROR_COLOR);
296             break;
297         }
298         ui->console->append(aMessage.text);
299     }
300     mConsoleLock.unlock();
301
302     QMainWindow::paintEvent(event);
303 }
304
305
306 void MainWindow::vprintf(TKLog::MessageType type, const char *fmt, va_list ap)
307 {
308     QString msg = QString().vsprintf(fmt,ap);
309 #ifdef DEBUG
310     qDebug() << msg << endl;
311 #endif
312     mConsoleLock.lock();
313     PendingConsoleMessage newMessage;
314     newMessage.messageType = type;
315     newMessage.text = msg;
316     mPendingConsoleMessages.enqueue(newMessage);
317     mConsoleLock.unlock();
318     emit consoleUpdated();
319 }
320
321 void MainWindow::vDebugPrintf(const char *fmt, va_list ap)
322 {
323 #ifdef DEBUG
324     QString msg = QString().vsprintf(fmt,ap);
325     qDebug() << "DEBUG:" << msg << endl;
326 #endif
327 }
328
329 void MainWindow::on_newRequestFromCreator()
330 {
331     QLocalSocket *clientConnection = mCreatorIPCServer->nextPendingConnection();
332     connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater()));
333
334     while(clientConnection->state() == QLocalSocket::ConnectedState || clientConnection->state() == QLocalSocket::ConnectingState)
335     {
336         clientConnection->waitForReadyRead();
337         QString readString = clientConnection->readAll();
338         QStringList requestData = readString.split(",");
339
340         if (requestData.length() < 1)
341             continue;
342
343         if (requestData.at(0) == "load" && requestData.length() == 2)
344         {
345     #ifdef DEBUG
346             qDebug() << "DEBUG: recieved load  request from denncoCreator. New contant path:" << requestData.at(1) << endl;
347     #endif
348             ui->filePath->setText(requestData.at(1));
349
350             clientConnection->disconnectFromServer();
351
352             if (QString::compare(ui->startButton->text(), "Start", Qt::CaseInsensitive) != 0)
353             {
354                 stopEngine();
355             }
356
357             deleteCurrentEngine();
358
359             if (startEngine())
360             {
361                 ui->startButton->setText("Stop");
362             }
363             break;
364         }
365         else if (requestData.at(0) == "close")
366         {
367             close();
368             break;
369         }
370     }
371 }
372