OSDN Git Service

[denncoCreator] reworked the code editor. Its now opened on a separate window.
[dennco/denncoCreator.git] / Source / visualizer / eventhandler / dcvlayoutmodehandler.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 "dcvlayoutmodehandler.h"
20
21 #include "dcglvisualizerwidget.h"
22 #include "dcvcomponent.h"
23 #include "dcvcpage.h"
24 #include "dcvcaxon.h"
25 #include "dcscene.h"
26 #include "dccreator.h"
27 #include "dcglwidget.h"
28
29 #include "dccontainer.h"
30 #include "dccell.h"
31
32 #include "dialog/dcaddcelldialog.h"
33 #include "dialog/dcinputnewpagenamedialog.h"
34 #include "dialog/dcrenamecelldialog.h"
35 #include "codeeditor/dccellscriptseditorwindow.h"
36
37 #include <typeinfo>
38 #include <QList>
39
40 DCVLayoutModeHandler::DCVLayoutModeHandler(DCUIGraphicsScene *widget, DCCreator *creator, DCScene *scene) :
41     DCVEventHandler(widget, creator, scene), d_inResigingDrag(false)
42 {
43
44 }
45
46 DCVLayoutModeHandler::~DCVLayoutModeHandler()
47 {
48
49 }
50
51 int DCVLayoutModeHandler::getHandlerType() const
52 {
53     return DCScene::DCV_EDITMODE_LAYOUT;
54 }
55
56 void DCVLayoutModeHandler::mousePressEvent(QGraphicsSceneMouseEvent *event)
57 {
58     bool shift = event->modifiers() & Qt::ShiftModifier;
59
60     QPointF mousePos = event->scenePos();
61
62     DCVComponent *obj = getView()->getObjectAt(mousePos.x(), mousePos.y());
63     if (!obj)
64         return;
65
66     if (!obj->getIsSelectable())
67         return;
68
69     DCVCPage *page = dynamic_cast<DCVCPage*>(obj->getPageBelonging());
70     if (!page)
71         return;
72
73     switch(getScene()->getPersMode())
74     {
75     case DCScene::DCV_PERSMODE_NAVIGATION:
76         {
77             if (obj != page)
78             {
79                 float pageX, pageZ;
80                 getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), page, &pageX, &pageZ);
81                 getController()->selectPage(this, page, shift);
82                 getController()->selectCellObject(this, obj);
83                 if (obj->startDrag(pageX, 0, pageZ, false))
84                 {
85                     getView()->requestRedraw(true);
86                     d_draggedObject.assign(obj);
87                     d_inResigingDrag = false;
88                 }
89             }
90             else
91             {
92                 d_draggedObject.assign(obj);
93                 d_inResigingDrag = false;
94             }
95         }
96         break;
97
98     case DCScene::DCV_PERSMODE_PAGEEDIT:
99         {
100             float pageX, pageZ;
101             float objX, objZ;
102             getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), obj, &objX, &objZ);
103             getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), page, &pageX, &pageZ);
104             d_inResigingDrag = obj->isResizingArea(objX,0,objZ);
105             getController()->selectCellObject(this, obj);
106             if (obj->startDrag(pageX, 0, pageZ, d_inResigingDrag))
107             {
108                 getView()->requestRedraw(true);
109             }
110             d_draggedObject.assign(obj);
111         }
112         break;
113     }
114
115     event->accept();
116 }
117
118 void DCVLayoutModeHandler::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
119 {
120     DCVComponent *obj = d_draggedObject.ref();
121
122     if (!obj)
123         return;
124
125     if (obj->getOwnerCell() && !obj->getOwnerCell()->getVComponent()->getIsSelectable())
126         return;
127
128     DCVComponent *page = obj->getPageBelonging();
129     if (!page)
130         return;
131
132     switch(getScene()->getPersMode())
133     {
134     case DCScene::DCV_PERSMODE_NAVIGATION:
135         {
136             getController()->changePersMode(this, DCCreator::DC_PERSMODE_PAGEEDIT);
137             d_draggedObject.assign(NULL);
138         }
139
140         break;
141
142     case DCScene::DCV_PERSMODE_PAGEEDIT:
143          {
144             if (obj == page)
145             {
146                 getController()->changePersMode(this, DCCreator::DC_PERSMODE_NAVIGATION);
147                 d_draggedObject.assign(NULL);
148             }
149             else
150             {
151                 if (typeid(*obj) == typeid(DCVCAxon))
152                 {
153                     getController()->doCommandStartAddAxonTerminalFromAxon(this, obj->getOwnerCell());
154                 }
155                 else
156                 {
157                     DCCellScriptsEditorWindow::startEditing(d_draggedObject.ref()->getOwnerCell());
158                 }
159             }
160         }
161         break;
162     }
163
164     event->accept();
165 }
166
167 void DCVLayoutModeHandler::mouseMoveEvent(QGraphicsSceneMouseEvent *event, int clickTimeElapsed)
168 {
169     QPointF mousePos = event->scenePos();
170     QPointF mousePrevPos = event->lastScenePos();
171
172     // This method will be called continuously while the mouse is moving.
173     // Some process we want to execute here may become heavyer and it will affect the performance.
174     // To privent this to affect the performance, we only execute the potentially heavyer
175     // process 12.5 times in a second in maximum.
176     static int lastCheckTime = 0;
177     bool canProcessHeavyTask = clickTimeElapsed - lastCheckTime < 0 || clickTimeElapsed - lastCheckTime >= 80;
178     if (canProcessHeavyTask)
179         lastCheckTime = clickTimeElapsed;
180
181
182     if (event->buttons() == Qt::LeftButton)
183     {
184         //dragging
185         bool shift = event->modifiers() & Qt::ShiftModifier;
186         float dx = mousePos.x() - mousePrevPos.x();
187         float dy = mousePos.y() - mousePrevPos.y();
188
189         switch(getScene()->getPersMode())
190         {
191         case DCScene::DCV_PERSMODE_NAVIGATION:
192             if (getScene()->getNavModeSelectedCellMovable() && d_draggedObject.ref() && d_draggedObject.ref()->getPageBelonging() && d_draggedObject.ref() != d_draggedObject.ref()->getPageBelonging())
193             {
194                 float pageX, pageZ;
195                 getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), d_draggedObject.ref()->getPageBelonging(), &pageX, &pageZ);
196
197                 if (d_draggedObject.ref()->dragging(pageX, 0, pageZ, false))
198                 {
199                     DCGLWidget::singleton()->setCursor(Qt::OpenHandCursor);
200                     getView()->requestRedraw(false);
201                 }
202             }
203             else if (!shift)
204             {
205                 getController()->rotateScene(this, dy / 5.0, dx / 5.0);
206             }
207             else
208             {
209                 getController()->translateBrowsModeScene(this, dx, dy);
210             }
211             break;
212
213         case DCScene::DCV_PERSMODE_PAGEEDIT:
214             if (d_draggedObject.ref() && d_draggedObject.ref()->getPageBelonging())
215             {
216                 if (d_draggedObject.ref() == d_draggedObject.ref()->getPageBelonging())
217                 {
218                     getController()->translateEditModeScene(this, dx, dy);
219                 }
220                 else
221                 {
222                     float pageX, pageZ;
223                     getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), d_draggedObject.ref()->getPageBelonging(), &pageX, &pageZ);
224                     if (d_draggedObject.ref()->dragging(pageX, 0, pageZ, d_inResigingDrag))
225                     {
226                         if (d_inResigingDrag)
227                         {
228                             DCGLWidget::singleton()->setCursor(Qt::SizeFDiagCursor);
229                         }
230                         else
231                         {
232                             DCGLWidget::singleton()->setCursor(Qt::OpenHandCursor);
233                         }
234                         getView()->requestRedraw(false);
235                     }
236                 }
237             }
238             break;
239         }
240     }
241     else
242     {
243         //mouse moving
244         if (canProcessHeavyTask)
245         {
246             DCVComponent *obj = getView()->getObjectAt(mousePos.x(), mousePos.y());
247             float objX, objZ;
248             if (obj)
249                 getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), obj, &objX, &objZ);
250             if (obj && obj->isResizingArea(objX,0,objZ))
251             {
252                 DCGLWidget::singleton()->setCursor(Qt::SizeFDiagCursor);
253             }
254             else
255             {
256                 DCGLWidget::singleton()->setCursor(Qt::ArrowCursor);
257             }
258         }
259     }
260
261     event->accept();
262 }
263
264 void DCVLayoutModeHandler::mouseReleaseEvent(QGraphicsSceneMouseEvent *event, bool wasDrag)
265 {
266     bool shift = event->modifiers() & Qt::ShiftModifier;
267     QPointF mousePos = event->scenePos();
268
269     switch(getScene()->getPersMode())
270     {
271     case DCScene::DCV_PERSMODE_NAVIGATION:
272     {
273         DCVCPage *page = NULL;
274         if (d_draggedObject.ref())
275         {
276             page = d_draggedObject.ref()->getPageBelonging();
277             float pageX, pageZ;
278             getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), page, &pageX, &pageZ);
279             if (d_draggedObject.ref()->endDrag(pageX, 0, pageZ, d_inResigingDrag))
280             {
281                 getView()->requestRedraw(true);
282             }
283         }
284
285         if (!wasDrag)
286         {
287             if (page)
288             {
289                 getController()->selectPage(this, page, shift);
290             }
291             else
292             {
293                 getController()->unselectPageAll(this);
294             }
295         }
296     }
297         break;
298
299     case DCScene::DCV_PERSMODE_PAGEEDIT:
300         if (d_draggedObject.ref() && d_draggedObject.ref()->getPageBelonging())
301         {
302             float pageX, pageZ;
303             getView()->toObjectCoordinateXZ(mousePos.x(), mousePos.y(), d_draggedObject.ref()->getPageBelonging(), &pageX, &pageZ);
304             if (d_draggedObject.ref()->endDrag(pageX, 0, pageZ, d_inResigingDrag))
305             {
306                 getView()->requestRedraw(true);
307             }
308         }
309         break;
310     }
311     event->accept();
312 }
313
314 void DCVLayoutModeHandler::wheelEvent(QGraphicsSceneWheelEvent  *event)
315 {
316     if (event->isAccepted()) return;
317
318     getController()->changeSceneScale(this, getScene()->getScale() + event->delta()/5);
319
320     event->accept();
321 }
322
323 void DCVLayoutModeHandler::keyPressEvent(QKeyEvent *event)
324 {
325     switch(event->key())
326     {
327     case Qt::Key_Enter:
328     case Qt::Key_Return:
329     {
330         switch(getScene()->getPersMode())
331         {
332         case DCScene::DCV_PERSMODE_NAVIGATION:
333             if (getScene()->getSelectedPages().length() > 0)
334             {
335                 getController()->changePersMode(this, DCCreator::DC_PERSMODE_PAGEEDIT);
336             }
337             break;
338
339         case DCScene::DCV_PERSMODE_PAGEEDIT:
340             if (getScene()->getSelectedCellObjects().length() == 1)
341             {
342                 DCCellScriptsEditorWindow::startEditing(getScene()->getSelectedCellObjects().at(0)->getOwnerCell());
343             }
344             break;
345
346         }
347     }
348         break;
349
350     case Qt::Key_Escape:
351     {
352         switch(getScene()->getPersMode())
353         {
354         case DCScene::DCV_PERSMODE_NAVIGATION:
355             getController()->unselectPageAll(this);
356             break;
357
358         case DCScene::DCV_PERSMODE_PAGEEDIT:
359             getController()->changePersMode(this, DCCreator::DC_PERSMODE_NAVIGATION);
360             break;
361         }
362     }
363         break;
364     }
365 }
366
367 void DCVLayoutModeHandler::keyReleaseEvent(QKeyEvent *event)
368 {
369
370 }
371
372 void DCVLayoutModeHandler::showContextMenu(const QPoint &pos)
373 {
374     QPoint globalPos = DCGLWidget::singleton()->mapToGlobal(pos);
375
376     QAction *actionRenameCell = NULL;
377     QAction *actinAddPage = NULL;
378     QAction *actionEditPage = NULL;
379     QAction *actionRemovePage = NULL;
380     QAction *actionSavePage = NULL;
381     QAction *actionSaveAll = NULL;
382     QAction *actionEditCellCode = NULL;
383     QAction *actionAddCell = NULL;
384     QAction *actionRemoveCell = NULL;
385     QAction *actionFinishEditMode = NULL;
386
387     DCCell* selectedCell = NULL;
388     DCVCPage* selectedPage = NULL;
389
390     DCVComponent *obj = getView()->getObjectAt(pos.x(), pos.y());
391     if (obj && obj->getIsSelectable())
392     {
393         selectedCell = obj->getOwnerCell();
394         selectedPage = obj->getPageBelonging();
395     }
396
397     QMenu menu;
398     switch(getScene()->getPersMode())
399     {
400     case DCScene::DCV_PERSMODE_NAVIGATION:
401         actionAddCell = menu.addAction(tr("Add cell ..."));
402         if (selectedCell)
403         {
404             actionRenameCell = menu.addAction(tr("Rename / move cell..."));
405             menu.addSeparator();
406             actionRemoveCell = menu.addAction(tr("Remove cell"));
407         }
408         menu.addSeparator();
409         actinAddPage = menu.addAction(tr("Add page ..."));
410         if (selectedPage)
411         {
412             actionEditPage = menu.addAction(tr("Edit page ..."));
413             actionRemovePage = menu.addAction(tr("Remove page ..."));
414             actionSavePage = menu.addAction(tr("Save page"));
415             menu.addSeparator();
416         }
417         actionSaveAll = menu.addAction(tr("Save all"));
418
419         break;
420
421     case DCScene::DCV_PERSMODE_PAGEEDIT:
422
423         actionAddCell = menu.addAction(tr("Add cell ..."));
424         if (selectedCell)
425         {
426             actionRenameCell = menu.addAction(tr("Rename / move cell..."));
427             actionEditCellCode = menu.addAction(tr("Edit cell code..."));
428             menu.addSeparator();
429             actionRemoveCell = menu.addAction(tr("Remove cell"));
430         }
431         menu.addSeparator();
432
433         actionSavePage =  menu.addAction(tr("Save page"));
434         menu.addSeparator();
435         actionSaveAll = menu.addAction(tr("Save all"));
436         menu.addSeparator();
437         actionFinishEditMode = menu.addAction(tr("Finish edit mode"));
438
439         break;
440     }
441
442     QAction* selectedItem = menu.exec(globalPos);
443     if (selectedItem)
444     {
445         DCContainer *container = getController()->getCurrentContainer();
446         if (selectedItem == actinAddPage)
447         {
448             QString sysFilePath = QString::fromStdString(container->getContainerRootPath());
449
450             if (selectedPage)
451             {
452                 sysFilePath = QFileInfo(sysFilePath + selectedPage->getLocationPath()).dir().absolutePath();
453             }
454             QString containerBasedPath = container->sysFilePathToContainerBasedPath(sysFilePath);
455
456             DCInputNewPageNameDialog dialog(sysFilePath, tr("Add page"));
457             if (dialog.exec())
458             {
459                 QString pageName = dialog.getName();
460                 if (pageName.length() > 0)
461                 {
462                     QString pathName = containerBasedPath;
463                     if (containerBasedPath.length()>1)
464                         pathName.append("/");
465                     pathName.append(pageName);
466                     getController()->doCommandAddPage(this, pathName);
467                 }
468             }
469         }
470         else if (selectedItem == actionRenameCell)
471         {
472             if (selectedCell)
473             {
474                 DCRenameCellDialog dialog(getController()->getCurrentContainer(), getController(), selectedCell);
475                 dialog.exec();
476
477             }
478         }
479         else if (selectedItem == actionEditPage)
480         {
481             getController()->changePersMode(this, DCCreator::DC_PERSMODE_PAGEEDIT);
482         }
483         else if (selectedItem == actionRemovePage)
484         {
485             if (getScene()->getSelectedPages().length() > 0)
486             {
487                 QList<DCVCPage*>  pages = getScene()->getSelectedPages();
488                 for (int i = 0; i < pages.length(); i++)
489                 {
490                     getController()->doCommandRemovePage(this, pages.at(i));
491                 }
492             }
493         }
494         else if (selectedItem == actionSavePage)
495         {
496             if (getScene()->getSelectedPages().length() > 0)
497             {
498                 bool r = true;
499                 QList<DCVCPage*>  pages = getScene()->getSelectedPages();
500                 if (!getController()->savePage(pages.toSet()))
501                 {
502                     r = false;
503                 }
504                 QMessageBox msgBox;
505                 if (r)
506                 {
507                     msgBox.setText(tr("Page is saved successfully"));
508                 }
509                 else
510                 {
511                     msgBox.setText(tr("Error!! Failed to save the page file"));
512                 }
513                 msgBox.exec();
514             }
515         }
516         else if (selectedItem == actionSaveAll)
517         {
518             getController()->saveAll(true);
519
520         }
521         else if (selectedItem == actionEditCellCode)
522         {
523             if (selectedCell)
524             {
525                 DCCellScriptsEditorWindow::startEditing(selectedCell);
526             }
527         }
528         else if (selectedItem == actionAddCell)
529         {
530             if (selectedPage)
531             {
532                 float pageX = 0;
533                 float pageY = 0;
534                 getView()->toObjectCoordinateXZ(pos.x(), pos.y(),selectedPage, &pageX, &pageY );
535                 DCAddCellDialog dialog(getController()->getCurrentContainer(), getController(), selectedPage->getLocationPath(), pageX, pageY);
536                 dialog.exec();
537             }
538         }
539         else if (selectedItem == actionRemoveCell)
540         {
541             getController()->doCommandRemoveCell(this, getController()->getCurrentContainer(), selectedCell);
542         }
543         else if (selectedItem == actionFinishEditMode)
544         {
545             getController()->changePersMode(this, DCCreator::DC_PERSMODE_NAVIGATION);
546         }
547     }
548     else
549     {
550         // nothing was chosen
551     }
552 }
553
554 void DCVLayoutModeHandler::selectedPageChanged(const void *requester)
555 {
556
557 }