c522b9e939ed1aecb5c3e3482e50005dc41f685d
[scilab.git] / scilab / modules / graphic_objects / src / cpp / ScilabView.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 #include <iostream>
14 #include <map>
15 #include <cstring>
16 #include <limits.h>
17
18 #include "ScilabView.hxx"
19 #include "CallGraphicController.hxx"
20
21 extern "C"
22 {
23 #include "CurrentObject.h"
24 #include "createGraphicObject.h"
25 #include "setGraphicObjectProperty.h"
26 #include "getGraphicObjectProperty.h"
27 #include "graphicObjectProperties.h"
28 #include "getScilabJavaVM.h"
29 #include "deleteGraphicObject.h"
30 }
31
32 /**
33  * C Wrapping functions
34  * \{
35  */
36 void ScilabNativeView__createObject(int iUID)
37 {
38     ScilabView::createObject(iUID);
39 }
40
41 void ScilabNativeView__deleteObject(int iUID)
42 {
43     ScilabView::deleteObject(iUID);
44 }
45
46 void ScilabNativeView__updateObject(int iUID, int iProperty)
47 {
48     ScilabView::updateObject(iUID, iProperty);
49 }
50
51 void ScilabNativeView__setCurrentFigure(int iUID)
52 {
53     ScilabView::setCurrentFigure(iUID);
54 }
55
56 void ScilabNativeView__setCurrentSubWin(int iUID)
57 {
58     ScilabView::setCurrentSubWin(iUID);
59 }
60
61 void ScilabNativeView__setCurrentObject(int iUID)
62 {
63     ScilabView::setCurrentObject(iUID);
64 }
65
66 int ScilabNativeView__getValidDefaultFigureId()
67 {
68     return ScilabView::getValidDefaultFigureId();
69 }
70
71 /**
72  * \}
73  */
74
75 int ScilabView::getValidDefaultFigureId()
76 {
77     if (m_figureList.empty())
78     {
79         return 0;
80     }
81     else
82     {
83         int max = INT_MIN;
84         for (__figureList_iterator it = m_figureList.begin(); it != m_figureList.end(); ++it)
85         {
86             if (it->second > max)
87             {
88                 max = it->second;
89             }
90         }
91
92         return max + 1;
93     }
94 }
95
96 bool ScilabView::isEmptyFigureList()
97 {
98     return m_figureList.empty();
99 }
100
101 int ScilabView::getFigureFromIndex(int figNum)
102 {
103     __figureList_iterator it;
104
105     for (it = m_figureList.begin(); it != m_figureList.end(); ++it)
106     {
107         if (it->second == figNum)
108         {
109             return it->first;
110         }
111     }
112     return 0;
113 }
114
115 bool ScilabView::existsFigureId(int id)
116 {
117     __figureList_iterator it;
118
119     for (it = m_figureList.begin(); it != m_figureList.end(); ++it)
120     {
121         if (it->second == id)
122         {
123             return true;
124         }
125     }
126     return false;
127 }
128
129 void ScilabView::getFiguresId(int ids[])
130 {
131     //__figureList_iterator it;
132     //int i = (int)(m_figureList.size() - 1);
133
134     //for (it = m_figureList.begin(); it != m_figureList.end(); ++it, --i)
135     //{
136     //    //std::cerr << "[ScilabView] DEBUG " << it->first << " <-> " << it->second << std::endl;
137     //    ids[i] = it->second;
138     //}
139
140     __figureList_reverse_iterator it;
141     int i = (int)(m_figureList.size() - 1);
142
143     for (it = m_figureList.rbegin(); it != m_figureList.rend(); ++it, --i)
144     {
145         //std::cerr << "[ScilabView] DEBUG " << it->first << " <-> " << it->second << std::endl;
146         ids[i] = it->second;
147     }
148 }
149
150 int ScilabView::getNbFigure(void)
151 {
152     return (int)m_figureList.size();
153 }
154
155 void ScilabView::createObject(int iUID)
156 {
157     //std::cerr << "[ScilabView] ++ createObject UID=" << iUID << std::endl;
158     int iType = -1;
159     int *piType = &iType;
160
161     getGraphicObjectProperty(iUID, __GO_TYPE__, jni_int, (void **)&piType);
162     if (iType != -1 && iType == __GO_FIGURE__)
163     {
164         m_figureList[iUID] = -1;
165         setCurrentFigure(iUID);
166     }
167
168     // Register object handle.
169     getObjectHandle(iUID);
170
171     PathItem* item = new PathItem();
172     item->uid = iUID;
173
174     m_pathList[iUID] = item;
175
176     //get existing information from current object
177     updateObject(iUID, __GO_PARENT__);
178     updateObject(iUID, __GO_CHILDREN__);
179     updateObject(iUID, __GO_TAG__);
180 }
181
182 void ScilabView::deleteObject(int iUID)
183 {
184     //std::cerr << "[ScilabView] -- deleteObject UID=" << iUID << std::endl;
185     int iType = -1;
186     int *piType = &iType;
187     int iParentUID = 0;
188
189     /*
190     ** If deleting a figure, remove from figure list.
191     */
192     m_figureList.erase(iUID);
193
194     /*
195     ** If deleting current figure find another current one,
196     ** if there is no more figure : NULL
197     */
198     if (m_currentFigure == iUID) // Deleting current figure
199     {
200         int iAxesUID = 0;
201         int* piAxesUID = &iAxesUID;
202
203         if (getNbFigure() != 0)
204         {
205             m_currentFigure = m_figureList.begin()->first;
206             getGraphicObjectProperty(m_currentFigure, __GO_SELECTED_CHILD__, jni_int,  (void**)&piAxesUID);
207             setCurrentSubWin(iAxesUID);
208         }
209         else
210         {
211             setCurrentFigure(0);
212             setCurrentSubWin(0);
213         }
214     }
215
216     /*
217     ** If deleting current entity, set parent as new current.
218     */
219     if (m_currentObject == iUID) // Deleting current object
220     {
221         iParentUID = getParentObject(iUID);
222         setCurrentObject(iParentUID);
223     }
224
225     // Remove the corresponding handle.
226     __handleList_iterator it = m_handleList.find(iUID);
227     if (it != m_handleList.end())
228     {
229         m_uidList.erase(it->second);
230         m_handleList.erase(it);
231     }
232
233     deleteDataObject(iUID);
234
235     m_pathList.erase(iUID);
236 }
237
238 void ScilabView::updateObject(int iUID, int iProperty)
239 {
240     //std::cerr << "[ScilabView] == updateObject UID=" << iUID << " PROPERTY=" << pstProperty << std::endl;
241
242     /*
243     ** Take care of update if the value update is ID and object type is a Figure I manage.
244     */
245     switch (iProperty)
246     {
247         case __GO_ID__ :
248         {
249             if (m_figureList.find(iUID) != m_figureList.end())
250             {
251                 int iNewId = 0;
252                 int *piNewId = &iNewId;
253
254                 getGraphicObjectProperty(iUID, __GO_ID__, jni_int, (void **)&piNewId);
255
256                 m_figureList[iUID] = iNewId;
257                 //std::cerr << "### [ScilabView] updateMap UID=" << iUID << " id=" << iNewId << std::endl;
258             }
259             break;
260         }
261         case __GO_CHILDREN__ :
262         {
263             int childrenCount = 0;
264             int* pChildrenCount = &childrenCount;
265             getGraphicObjectProperty(iUID, __GO_CHILDREN_COUNT__, jni_int, (void**)&pChildrenCount);
266
267             __pathList_iterator it = m_pathList.find(iUID);
268             if (it != m_pathList.end())
269             {
270                 //update existing item
271
272                 PathItem* item = (*it).second;
273                 //reset children
274                 item->children.clear();
275                 if (childrenCount != 0)
276                 {
277                     int* children = NULL;
278                     getGraphicObjectProperty(iUID, __GO_CHILDREN__, jni_int_vector, (void**)&children);
279                     item->children.assign(children, children + childrenCount);
280                 }
281             }
282             break;
283         }
284         case __GO_PARENT__ :
285         {
286             int iParent = 0;
287             int* piParent = &iParent;
288             getGraphicObjectProperty(iUID, __GO_PARENT__, jni_int, (void**)&piParent);
289
290             __pathList_iterator it = m_pathList.find(iUID);
291
292             if (it != m_pathList.end())
293             {
294                 //update existing item
295
296                 PathItem* item = (*it).second;
297                 item->parent = iParent;
298             }
299         }
300         case __GO_TAG__ :
301         {
302             int iType = 0;
303             int* piType = &iType;
304             getGraphicObjectProperty(iUID, __GO_TYPE__, jni_int, (void**)&piType);
305
306             char* tag = NULL;
307             getGraphicObjectProperty(iUID, __GO_TAG__, jni_string, (void**)&tag);
308
309             if (tag[0] != 0 && iType == __GO_FIGURE__)
310             {
311                 //not empty string
312
313                 //add figure in list of path starter
314                 m_pathFigList[tag] = iUID;
315             }
316
317             __pathList_iterator it = m_pathList.find(iUID);
318
319             if (it != m_pathList.end())
320             {
321                 //update existing item
322
323                 PathItem* item = (*it).second;
324                 item->tag = tag;
325                 free(tag);
326             }
327             break;
328         }
329         default:
330             break;
331     }
332 }
333
334 /*
335 ** Register ScilabView to Controller.
336 ** Must be done after Graphics models are created.
337 */
338 void ScilabView::registerToController(void)
339 {
340     org_scilab_modules_graphic_objects::CallGraphicController::registerScilabView(getScilabJavaVM());
341     m_figureList.get_allocator().allocate(4096);
342     m_handleList.get_allocator().allocate(4096);
343     m_uidList.get_allocator().allocate(4096);
344 }
345
346 /*
347 ** Reove ScilabView from Controller.
348 */
349 void ScilabView::unregisterToController(void)
350 {
351     org_scilab_modules_graphic_objects::CallGraphicController::unregisterScilabView(getScilabJavaVM());
352 }
353
354 /*
355 ** Set Current Figure UID
356 */
357 void ScilabView::setCurrentFigure(int UID)
358 {
359     m_currentFigure = UID;
360 }
361
362 /*
363 ** Get Current Figure UID
364 */
365 int ScilabView::getCurrentFigure()
366 {
367     //std::cerr << "[ScilaView] currentFigure = " << (m_currentFigure == 0 ? "NULL !!" : m_currentFigure) << std::endl;
368     return m_currentFigure;
369 }
370
371 /*
372 ** Set Current Object UID
373 */
374 void ScilabView::setCurrentObject(int UID)
375 {
376     m_currentObject = UID;
377 }
378
379 /*
380 ** Get Current Figure UID
381 */
382 int ScilabView::getCurrentObject()
383 {
384     //std::cerr << "[ScilaView] currentObject = " << m_currentObject << std::endl;
385     return m_currentObject;
386 }
387
388 /*
389 ** Set Current SubWin UID
390 */
391 void ScilabView::setCurrentSubWin(int UID)
392 {
393     m_currentSubWin = UID;
394 }
395
396 /*
397 ** Get Current Figure UID
398 */
399 int ScilabView::getCurrentSubWin()
400 {
401     //std::cerr << "[ScilaView] currentSubWin = " << m_currentSubWin << std::endl;
402     return m_currentSubWin;
403 }
404
405 /*
406 ** Scilab only can store long as handle
407 */
408 long ScilabView::getObjectHandle(int UID)
409 {
410     /*
411      * if (UID != NULL)
412      * {
413      * std::cerr << "UID = " << UID << std::endl;
414      * }
415      * else
416      * {
417      * std::cerr << "UID is null :-S" << std::endl;
418      * }
419      * __handleList_iterator it2;
420      * std::cerr << "[DEBUG] +++ handleMap +++" << std::endl;
421      * for (it2 = m_handleList.begin() ; it2 != m_handleList.end() ; ++it2)
422      * {
423      * std::cerr << "UID " << it2->first << " <-> handle " << it2->second << std::endl;
424      * }
425      * std::cerr << "[DEBUG] +++ handleMap +++" << std::endl;
426      */
427     __handleList_iterator it = m_handleList.find(UID);
428
429     if (it != m_handleList.end())
430     {
431         return it->second;
432     }
433
434     // increase maximum value
435     // register new handle and return it.
436     m_topHandleValue++;
437     m_handleList[UID] = m_topHandleValue;
438     m_uidList[m_topHandleValue] = UID;
439
440     return m_topHandleValue;
441 }
442
443 int ScilabView::getObjectFromHandle(long handle)
444 {
445     __uidList_iterator it = m_uidList.find(handle);
446     if (it == m_uidList.end())
447     {
448         return 0;
449     }
450
451     return it->second;
452 }
453
454 int ScilabView::getFigureModel(void)
455 {
456     //std::cerr << "[ScilabView] getFigureModel = " << (m_figureModel == 0 ? "!! NULL !!" : m_figureModel) << std::endl;
457     return m_figureModel;
458 }
459
460 void ScilabView::setFigureModel(int UID)
461 {
462     m_figureModel = UID;
463 }
464
465 int ScilabView::getAxesModel(void)
466 {
467     //std::cerr << "[ScilabView] getAxesModel = " << (m_axesModel == 0 ? "!! NULL !!" : m_axesModel) << std::endl;
468     return m_axesModel;
469 }
470
471 void ScilabView::setAxesModel(int UID)
472 {
473     m_axesModel = UID;
474 }
475
476 PathItem* ScilabView::getItem(int uid)
477 {
478     __pathList_iterator it = m_pathList.find(uid);
479     if (it != m_pathList.end())
480     {
481         return it->second;
482     }
483
484     return NULL;
485 }
486
487 PathItem* ScilabView::getItem(std::string _pstTag)
488 {
489     __pathList_iterator it = m_pathList.begin();
490     for (; it != m_pathList.end(); it++)
491     {
492         PathItem * item = it->second;
493         if (item->tag == _pstTag)
494         {
495             return item;
496         }
497     }
498
499     return NULL;
500 }
501
502 PathItem* ScilabView::getFigureItem(std::string _pstTag)
503 {
504     __pathFigList_iterator it = m_pathFigList.find(_pstTag);
505     if (it != m_pathFigList.end())
506     {
507         return getItem(it->second);
508     }
509
510     return NULL;
511 }
512
513 int ScilabView::search_path(char* _pstPath)
514 {
515     PathItem* path = NULL;
516     char* pstSubPath = strtok(_pstPath, "/");
517     bool bDeep = false;
518     while (pstSubPath != NULL)
519     {
520         if (pstSubPath[0] == 0)
521         {
522             //"" ?
523             break;
524         }
525
526         if (pstSubPath[0] != '*')
527         {
528             //search in direct children
529             if (path == NULL)
530             {
531                 path = ScilabView::getFigureItem(_pstPath);
532                 if (path == NULL)
533                 {
534                     path = ScilabView::getItem(_pstPath);
535                     if (path == NULL)
536                     {
537                         break;
538                     }
539                 }
540             }
541             else
542             {
543                 path = search_children(path, pstSubPath, bDeep);
544                 if (path == NULL)
545                 {
546                     break;
547                 }
548
549                 bDeep = false;
550             }
551         }
552         else
553         {
554             //search in all path children
555             bDeep = true;
556         }
557
558         pstSubPath = strtok(NULL, "/");
559     }
560
561     if (path == NULL)
562     {
563         return 0;
564     }
565
566     return path->uid;
567 }
568
569 PathItem* ScilabView::search_children(PathItem* _path, std::string _subPath, bool _bDeep)
570 {
571     PathItem::__child_iterator it = _path->children.begin();
572     for (; it != _path->children.end() ; it++)
573     {
574         PathItem* child = ScilabView::getItem(*it);
575         if (child->tag == _subPath)
576         {
577             return child;
578         }
579         else if (_bDeep)
580         {
581             PathItem *item = search_children(child, _subPath, _bDeep);
582             if (item)
583             {
584                 return item;
585             }
586         }
587     }
588
589     return NULL;
590 }
591
592 std::string ScilabView::get_path(int uid)
593 {
594     PathItem* item = getItem(uid);
595     if (item->tag == "")
596     {
597         //impossible to create a useful path from object without tag
598         return "";
599     }
600
601     std::string path = item->tag;
602
603     while (item->parent != 0)
604     {
605         item = getItem(item->parent);
606         if (item->tag == "")
607         {
608             if (path[0] == '*')
609             {
610                 //we have already */ just continue
611                 continue;
612             }
613             else
614             {
615                 //add */ instead of /
616                 path = "*/" + path;
617             }
618         }
619         else
620         {
621             path = item->tag + "/" + path;
622         }
623     }
624
625     if (path[0] == '*')
626     {
627         //path must start by mane
628         return "";
629     }
630
631     return path;
632 }
633
634 /*
635 ** Allocate static class variable.
636 */
637 ScilabView::__figureList ScilabView::m_figureList = *new __figureList();
638 ScilabView::__handleList ScilabView::m_handleList = *new __handleList();
639 ScilabView::__uidList ScilabView::m_uidList = *new __uidList();
640 long ScilabView::m_topHandleValue = 0;
641 int ScilabView::m_currentFigure;
642 int ScilabView::m_currentObject;
643 int ScilabView::m_currentSubWin;
644 int ScilabView::m_figureModel;
645 int ScilabView::m_axesModel;
646 ScilabView::__pathList ScilabView::m_pathList = *new __pathList();
647 ScilabView::__pathFigList ScilabView::m_pathFigList = *new __pathFigList();