OSDN Git Service

[denncoCreator] Implement plugin cell edit feature. The work is in progress.
[dennco/denncoCreator.git] / Source / dccreator.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 Sep-30, 2012.
18 //
19 #include "TKLog.h"
20 #include "DNGlobal.h"
21 #include "dcconsole.h"
22
23 #include "dccreator.h"
24
25 #include "dccontent.h"
26 #include "dccontainer.h"
27 #include "dcscene.h"
28
29 #include "dccell.h"
30 #include "dcaxon.h"
31 #include "dcaxonterminal.h"
32 #include "dcreceptor.h"
33
34 #include "command/dccommandevent.h"
35 #include "command/dccommand.h"
36
37 #include "utils/dcdialogutil.h"
38 #include "utils/dccommandutil.h"
39 #include "dialog/dcinputreceptornamedialog.h"
40 #include "codeeditor/dccellscriptseditorwindow.h"
41
42 #include <QUndoCommand>
43 #include <map>
44
45 DCCreator::DCCreator(QMainWindow *mainwindow)
46     :  d_mainWindow(mainwindow), d_vcontent(NULL), d_scene(NULL),
47       d_persMode(DC_PERSMODE_PAGEEDIT), d_contentRootPath("")
48 {
49     d_undoStack = new QUndoStack(this);
50
51     d_console = new DCConsole;
52     TKLog::setDestination(d_console);
53 }
54
55 DCCreator::~DCCreator()
56 {
57     emit sceneChanged(this, NULL);
58     d_scene = NULL;
59
60     if (d_vcontent)
61     {
62         delete d_vcontent;
63     }
64     if (d_console)
65     {
66         delete d_console;
67     }
68 }
69
70 bool DCCreator::event(QEvent *event)
71 {
72     if (!d_scene)
73         return false;
74
75     if(event->type() == DCCommandEvent::EVENT_TYPEID)
76     {
77         DCCommandEvent *commandEvent = dynamic_cast<DCCommandEvent*>(event);
78         if (commandEvent)
79         {
80             QUndoCommand *command = commandEvent->getCommand();
81             if (command)
82             {
83                 d_undoStack->push(command);
84                 emit commandExecuted(command);
85             }
86             return true;
87         }
88     }
89     else if (event->type() == DCUndoEvent::EVENT_TYPEID)
90     {
91         d_undoStack->undo();
92         emit commandExecuted(NULL);
93         return true;
94     }
95     return false;
96 }
97
98 void DCCreator::resetVisualizer()
99 {
100     emit sceneChanged(this,0);
101 }
102
103 void DCCreator::initMode()
104 {
105     d_persMode = DC_PERSMODE_NAVIGATION;
106     d_scene->initMode(DCScene::DCV_PERSMODE_NAVIGATION, DCScene::DCV_EDITMODE_LAYOUT);
107 }
108
109 bool DCCreator::loadContent(const QString &contentRoot)
110 {
111     d_console->clearLog();
112
113     d_contentRootPath = contentRoot;
114     if (d_vcontent)
115     {
116         if (d_scene)
117             d_scene->disconnect(this);
118         resetVisualizer();
119         delete d_vcontent;
120     }
121     d_vcontent = new DCContent(this, contentRoot.toStdString());
122
123     if (d_vcontent->isValid())
124     {
125         d_scene = d_vcontent->getContainer()->getScene();
126
127         d_scene->loadSceneAll();
128
129         //setup signal - slot connection for scene
130         connect(d_scene, SIGNAL(selectedCellObjectChanged(const void*)), this, SLOT(slotSceneSelectedCellObjectChanged(const void*)));
131         connect(d_scene, SIGNAL(selectedPageChanged(const void*)), this, SLOT(slotSceneSelectedPageChanged(const void*)));
132         connect(d_scene, SIGNAL(viewAngleChanged(const void*)), this, SLOT(slotSceneViewAngleChanged(const void*)));
133         connect(d_scene, SIGNAL(viewCenterChanged(const void*)), this, SLOT(slotSceneViewCenterChanged(const void*)));
134         connect(d_scene, SIGNAL(viewScaleChanged(const void*)), this, SLOT(slotSceneViewScaleChanged(const void*)));
135         connect(d_scene, SIGNAL(viewSettingChanged(const void*)), this, SLOT(slotSceneViewSettingChanged(const void*)));
136         connect(d_scene, SIGNAL(viewEditModeChanged(const void*)), this, SLOT(slotSceneViewEditModeChanged(const void*)));
137
138         emit contentRootPathChanged(this, d_contentRootPath);
139         emit sceneChanged(this, d_scene);
140         initMode();
141
142         getMainWindow()->statusBar()->showMessage(tr("Content loaded"), 2000);
143
144         return true;
145     }
146     else
147     {
148         d_scene = NULL;
149         emit contentRootPathChanged(this, d_contentRootPath);
150         emit sceneChanged(this, NULL);
151
152         if (!dnGlobal()->isErrorStatusNormal())
153         {
154             QMessageBox msgBox(QMessageBox::Warning, QString::fromStdString(dnGlobal()->getMessage1()), QString::fromStdString(dnGlobal()->getMessage2()));
155             msgBox.setInformativeText(d_console->getLog(10));
156             msgBox.exec();
157         }
158         return false;
159     }
160 }
161
162 bool DCCreator::savePage(DCVCPage *page, bool showResultInMessageBox)
163 {
164     bool r = false;
165     if (d_scene && d_vcontent)
166     {
167         DCCellScriptsEditorWindow::saveScriptsBelongTo(page, true);
168         r = d_vcontent->saveForPage(d_vcontent->getContentRootPath(), page);
169     }
170     if (showResultInMessageBox)
171     {
172         QMessageBox msgBox;
173         if (r)
174         {
175             msgBox.setText(tr("Page is saved successfully"));
176         }
177         else
178         {
179             msgBox.setText(tr("Error!! Failed to save the page file"));
180         }
181         msgBox.exec();
182     }
183     return r;
184 }
185
186 bool DCCreator::savePage(const QSet<DCVCPage*> &pages, bool showResultInMessageBox)
187 {
188     bool r = true;
189     QSet<DCVCPage*>::const_iterator i = pages.constBegin();
190      while (i != pages.constEnd())
191      {
192          if (!savePage(*i, showResultInMessageBox))
193          {
194              r = false;
195         }
196          ++i;
197      }
198      return r;
199 }
200
201 bool DCCreator::saveAll(bool showResultInMessageBox)
202 {
203     bool r = false;
204
205     if (DCCellScriptsEditorWindow::getIsVisible())
206     {
207         DCCellScriptsEditorWindow::saveScriptsAll(true);
208     }
209
210     if (d_scene && d_vcontent)
211     {
212         r = d_vcontent->saveAll(d_vcontent->getContentRootPath());
213     }
214     if (showResultInMessageBox)
215     {
216         QMessageBox msgBox;
217         if (r)
218         {
219             msgBox.setText(tr("Content is saved successfully"));
220         }
221         else
222         {
223             msgBox.setText(tr("Error!! Failed to save content files"));
224         }
225         msgBox.exec();
226     }
227     getMainWindow()->statusBar()->showMessage(tr("Content saved"), 2000);
228
229     return r;
230 }
231
232
233 void DCCreator::selectPage(const void *requester, DCVCPage *page, bool multipleSelection)
234 {
235     if (d_scene)
236     {
237         d_scene->selectPage(requester, page, multipleSelection);
238     }
239 }
240
241 void DCCreator::unselectPage(const void *requester, DCVCPage *page)
242 {
243     if (d_scene)
244     {
245         d_scene->unselectPage(requester, page);
246     }
247 }
248
249 bool DCCreator::selectPage(const void *requester, const QString &locationPath, bool multipleSelection)
250 {
251     bool r = false;
252     if (d_scene)
253     {
254         r = d_scene->selectPage(requester, locationPath, multipleSelection);
255     }
256     return r;
257 }
258
259 bool DCCreator::unselectPage(const void *requester, const QString &locationPath)
260 {
261     bool r = false;
262     if (d_scene)
263     {
264         r = d_scene->unselectPage(requester, locationPath);
265     }
266     return r;
267 }
268
269
270 void DCCreator::unselectPageAll(const void *requester)
271 {
272     if (d_scene)
273     {
274         d_scene->unselectPageAll(requester);
275     }
276 }
277
278 void DCCreator::selectCellObject(const void *requester, DCVComponent *object, bool multipleSelection)
279 {
280     if (d_scene)
281         d_scene->selectCellObject(requester, object, multipleSelection);
282 }
283
284 void DCCreator::unselectCellObject(const void *requester, DCVComponent *object)
285 {
286     if (d_scene)
287         d_scene->unselectCellObject(requester, object);
288 }
289
290 void DCCreator::unselectCellObjectAll(const void *requester)
291 {
292     if (d_scene)
293         d_scene->unselectCellObjectAll(requester);
294 }
295
296 void DCCreator::changeSceneScale(const void *requester, float scale)
297 {
298     if (d_scene)
299     {
300         if (scale <= 10) scale =10;
301         if (scale >= 1000) scale = 1000;
302         d_scene->setScale(requester, scale);
303     }
304 }
305
306 void DCCreator::rotateScene(const void *requester, float xangle_delta, float yangle_delta)
307 {
308     if (d_scene)
309     {
310         float xangle = d_scene->getXAngle() + xangle_delta;
311         if (xangle < 0) xangle = 0;
312         if (xangle > 90) xangle = 90;
313
314         float yangle = d_scene->getYAngle() + yangle_delta;
315         while (yangle < 0) yangle += 360;
316         while (yangle > 360) yangle -= 360;
317
318         d_scene->setAngle(requester, xangle,yangle);
319     }
320 }
321
322 void DCCreator::translateBrowsModeScene(const void *requester, float dx, float dy)
323 {
324     if (d_scene)
325     {
326         float scale = d_scene->getScale();
327         float x = d_scene->getCenterX() - dx/scale*2;
328         float y = d_scene->getCenterBrowsModeY() + dy/scale*2;
329         d_scene->setBrowsModeCenter(requester, x,y);
330     }
331 }
332
333 void DCCreator::translateEditModeScene(const void *requester, float dx, float dy)
334 {
335     if (d_scene)
336     {
337         float scale = d_scene->getScale();
338         float x = d_scene->getCenterX() - dx/scale*2;
339         float y = d_scene->getCenterEditModeY() - dy/scale*2;
340         d_scene->setPageModeCenter(requester, x,y);
341     }
342 }
343
344 void DCCreator::resetSceneTranslation()
345 {
346
347 }
348
349 bool DCCreator::changePersMode(const void *requester, DCPersMode mode)
350 {
351     bool r = false;
352     if (d_scene)
353     {
354         d_persMode = mode;
355         switch(mode)
356         {
357         case DC_PERSMODE_NAVIGATION:
358             r = d_scene->changePersMode(requester, DCScene::DCV_PERSMODE_NAVIGATION);
359             break;
360         case DC_PERSMODE_PAGEEDIT:
361             r = d_scene->changePersMode(requester, DCScene::DCV_PERSMODE_PAGEEDIT);
362             break;
363         }
364         d_scene->updateVisiblity();
365     }
366     return r;
367 }
368
369 void DCCreator::doUndo(const void *requester)
370 {
371     (void)requester;
372     //TODO
373 }
374
375 void DCCreator::doUndoImmidiate()
376 {
377     d_undoStack->undo();
378 }
379
380 void DCCreator::doCommandStartAddAxonTerminalFromAxon(const void *requester, DCCell *axonCell)
381 {
382     DCCommandUtil::postStartAddAxonTerminalCommandFromAxon(requester, this, axonCell);
383 }
384
385 void DCCreator::doCommandStartAddAxonTerminalFromReceptor(const void *requester, DCCell *receptorCell)
386 {
387     DCInputReceptorNameDialog dialog(receptorCell);
388     dialog.exec();
389     if (dialog.getIsOk() && dialog.getInputText().length() > 0)
390     {
391         DCCommandUtil::postStartAddAxonTerminalCommandFromReceptor(requester, this, receptorCell, dialog.getInputText());
392     }
393 }
394
395 void DCCreator::doCommandCommitAddAxonTerminal(const void *requester, DCAxon *axon, DCCell *receptorCell)
396 {
397     DCInputReceptorNameDialog dialog(receptorCell);
398     dialog.exec();
399     if (dialog.getIsOk() && dialog.getInputText().length() > 0)
400     {
401         DCCommandUtil::postCommitAddAxonTerminalCommand(requester, this, axon, receptorCell, dialog.getInputText());
402     }
403     else
404     {
405         doCommandCancelAddAxonTerminal(requester);
406     }
407 }
408
409 void DCCreator::doCommandCommitAddAxonTerminal(const void *requester, DCCell *axonCell, DCReceptor *receptor)
410 {
411     DCCommandUtil::postCommitAddAxonTerminalCommand(requester, this, axonCell, receptor);
412 }
413
414 void DCCreator::doCommandCancelAddAxonTerminal(const void *requester)
415 {
416 //TODO:
417     // may need to consider the case multiple commands are executed after
418     // startAddAxon command is executed.
419     DCCommandUtil::postUndoRequestCommand(requester, this);
420 }
421
422 void DCCreator::doCommandRemoveAxonTerminal(const void *requester, DCCell *axonCell, DCAxonTerminal *axonTerminal)
423 {
424     DCReceptor *receptor = axonTerminal->getTarget();
425     if (!receptor)
426         return;
427
428     DCCell *targetCell = receptor->getOwnerCell();
429     if (!targetCell)
430         return;
431
432     QMessageBox msgBox;
433     msgBox.setText(tr("Delete axon terminal"));
434     QString msg;
435     msg.append("Cell ");
436     msg.append(QString::fromStdString(axonCell->getName()));
437     msg.append("\nDo you want to delete the connection to ");
438     msg.append(QString::fromStdString(targetCell->getLocation()));
439     msg.append("#");
440     msg.append(QString::fromStdString(targetCell->getName()));
441     msg.append("(");
442     msg.append(QString::fromStdString(targetCell->getReceptorName(receptor)));
443     msg.append(")?");
444     msgBox.setInformativeText(msg);
445     msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
446     msgBox.setDefaultButton(QMessageBox::Cancel);
447     int ret = msgBox.exec();
448
449     if (ret == QMessageBox::Yes)
450     {
451         DCCommandUtil::postRemoveAxonTerminalCommand(requester, this, axonCell, axonTerminal);
452     }
453 }
454
455 void DCCreator::doCommandRemoveAxonTerminal(const void *requester, DCCell *receptorCell, const QString& receptorName)
456 {
457
458     QMessageBox msgBox;
459     msgBox.setText(tr("Delete receptor"));
460     QString msg;
461     msg.append("Cell ");
462     msg.append(QString::fromStdString(receptorCell->getName()));
463     msg.append("\nDo you want to delete receptor ");
464     msg.append(receptorName);
465     msg.append("?\n");
466     msgBox.setInformativeText(msg);
467     msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes);
468     msgBox.setDefaultButton(QMessageBox::Cancel);
469     int ret = msgBox.exec();
470
471     if (ret == QMessageBox::Yes)
472     {
473         DCCommandUtil::postRemoveAxonTerminalCommand(requester, this, receptorCell, receptorName);
474     }
475 }
476
477 void DCCreator::doCommandAssignCellCodeClassToCell(const void *requester, DCCell *cell, DCCellCode *cellCode)
478 {
479     DCCommandUtil::postAssignCellCodeClassToCellCommand(requester, this, cell, cellCode);
480 }
481
482 void DCCreator::doCommandUnassignCellCodeClassFromCell(const void *requester, DCCell *cell)
483 {
484     DCCommandUtil::postUnassignCellCodeClassFromCellCommand(requester, this, cell);
485 }
486
487 void DCCreator::doCommandAddCellCodeClass(const void *requester, DCContainer *container, const QString& name, const QString& type)
488 {
489     DCCommandUtil::postAddCellCodeClassCommand(requester, this, container, name, type);
490 }
491
492 void DCCreator::doCommandChangeCellCodeClassType(const void *requester, DCCellCode* cellCode, const QString &newType)
493 {
494     DCCommandUtil::postChangeCellCodeClassTypeCommand(requester, this, cellCode, newType);
495 }
496
497 void DCCreator::doCommandAddCell(const void *requester, DCContainer *container, const QString &containerBasedPath, const QString &name, const QString &type, float pageX, float pageY)
498 {
499     DCCommandUtil::postAddCellCommand(requester, this, container, containerBasedPath, name, type, pageX, pageY);
500 }
501
502 void DCCreator::doCommandChangeCellType(const void *requester, DCCell *cell, const QString &newType)
503 {
504     DCCommandUtil::postChangeCellTypeCommand(requester, this, cell, newType);
505 }
506
507 void DCCreator::doCommandRenameCell(const void *requester, DCCell *cell, const QString &newContainerBasedPath, const QString &newName)
508 {
509     DCCommandUtil::postRenameCellCommand(requester, this, cell, newContainerBasedPath, newName);
510 }
511
512 void DCCreator::doCommandRemoveCell(const void *requester, DCContainer *container, DCCell *cell)
513 {
514     DCCommandUtil::postRemoveCellCommand(requester, this, container, cell);
515 }
516
517 void DCCreator::doCommandRemoveCellCode(const void *requester, DCContainer *container, DCCellCode *cellCode)
518 {
519     DCCommandUtil::postRemoveCellCodeCommand(requester, this, container, cellCode);
520 }
521
522 void DCCreator::doCommandAddPage(const void *requester, const QString &containerBasedPath)
523 {
524     DCCommandUtil::postAddPageCommand(requester, this, containerBasedPath);
525 }
526
527 void DCCreator::doCommandMovePage(const void *requester, const QString &oldContainerBasedPath, const QString &newContainerBasedPath)
528 {
529     DCCommandUtil::postMovePageCommand(requester, this, oldContainerBasedPath, newContainerBasedPath);
530 }
531
532 void DCCreator::doCommandRemovePage(const void *requester, DCVCPage *page)
533 {
534     DCCommandUtil::postRemovePageCommand(requester, this, page);
535 }
536
537 void DCCreator::doCommandAddDirectory(const void *requester, const QString &sysFilePath)
538 {
539     DCCommandUtil::postAddDirectoryCommand(requester, this, sysFilePath);
540 }
541
542 void DCCreator::doCommandRenameDirectory(const void *requester, const QString &oldSysFilePath, const QString &newSysFilePath)
543 {
544     DCCommandUtil::postRenameDirectoryCommand(requester, this, oldSysFilePath, newSysFilePath);
545 }
546
547 void DCCreator::doCommandRemoveDirectory(const void *requester, const QString &sysFilePath)
548 {
549     DCCommandUtil::postRemoveDirectoryCommand(requester, this, sysFilePath);
550 }
551
552 bool DCCreator::doCommandRenameReceptorName(const void *requester, DCCell *cell, const QString &oldName, const QString &newName, bool doImmediate)
553 {
554     if (doImmediate)
555     {
556         DCCommand *command = DCCommandUtil::createRenameReceptorNameCommand(requester, this, cell, oldName, newName);
557         d_undoStack->push(command);
558         return command->getCommandResult() == DCCommand::DCCOMMAND_SUCCEEDED;
559     }
560     else
561     {
562         DCCommandUtil::postRenameReceptorNameCommand(requester, this, cell, oldName, newName);
563         return true;
564     }
565 }
566
567 DCContainer* DCCreator::getCurrentContainer() const
568 {
569     if (d_vcontent)
570         return d_vcontent->getContainer();
571     else
572         return NULL;
573 }
574
575 void DCCreator::slotSceneSelectedPageChanged(const void *requester)
576 {
577     emit sceneSelectedPageChanged(requester, d_scene);
578 }
579
580 void DCCreator::slotSceneSelectedCellObjectChanged(const void *requester)
581 {
582     emit sceneSelectedCellChanged(requester, d_scene);
583 }
584
585 void DCCreator::slotSceneViewScaleChanged(const void *requester)
586 {
587     emit sceneViewScaleChanged(requester, d_scene);
588 }
589
590 void DCCreator::slotSceneViewAngleChanged(const void *requester)
591 {
592     emit sceneViewAngleChanged(requester, d_scene);
593 }
594
595 void DCCreator::slotSceneViewCenterChanged(const void *requester)
596 {
597     emit sceneViewCenterChanged(requester, d_scene);
598 }
599
600 void DCCreator::slotSceneViewSettingChanged(const void *requester)
601 {
602     emit sceneViewSettingChanged(requester, d_scene);
603 }
604
605 void DCCreator::slotSceneViewEditModeChanged(const void *requester)
606 {
607     emit sceneViewEditModeChanged(requester, d_scene);
608 }
609