Developer Documentation
QtApplication.cc
1/*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40\*===========================================================================*/
41
42
43
44
45
46//=============================================================================
47//
48// CLASS QtApplication - IMPLEMENTATION
49//
50//=============================================================================
51
52
53//== INCLUDES =================================================================
54
55
56// ACG
57#include "QtApplication.hh"
58//#include <ACG/QtWidgets/QtMacroDialog.hh>
59
60
61// Qt
62#include <QWidget>
63#include <QWheelEvent>
64
65// stdc++
66#include <fstream>
67
68
69//== NAMESPACES ===============================================================
70
71
72namespace ACG {
73namespace QtWidgets {
74
75
76//== IMPLEMENTATION ==========================================================
77
78
79// input / output for QPoint
80// static std::istream& operator>>(std::istream& _is, QPoint& _p)
81// {
82// int x, y;
83// _is >> x >> y;
84// _p.setX(x);
85// _p.setY(y);
86// return _is;
87// }
88
89// static std::ostream& operator<<(std::ostream& _os, const QPoint& _p)
90// {
91// _os << _p.x() << ' ' << _p.y();
92// return _os;
93// }
94
95
96//-----------------------------------------------------------------------------
97
98
99// input / output for QSize
100// static std::istream& operator>>(std::istream& _is, QSize& _s)
101// {
102// int w, h;
103// _is >> w >> h;
104// _s.setWidth(w);
105// _s.setHeight(h);
106// return _is;
107// }
108
109// static std::ostream& operator<<(std::ostream& _os, const QSize& _s)
110// {
111// _os << _s.width() << ' ' << _s.height();
112// return _os;
113// }
114
115
116//-----------------------------------------------------------------------------
117
118
119// static std::string read_name(std::istream& _is)
120// {
121// char cb[255];
122// _is.getline(cb, 255);
123// return std::string(cb);
124// }
125
126
127//-----------------------------------------------------------------------------
128
129
130// copy qt event
131template <class SomeEvent>
132static QEvent* clone_event(QEvent* _event)
133{ return dynamic_cast<QEvent*>(new SomeEvent(*(dynamic_cast<SomeEvent*>(_event)) )); }
134
135
136
137//-----------------------------------------------------------------------------
138
139
140QtApplication::QtApplication(int _argc, char** _argv)
141 : QApplication(_argc, _argv),
142 record_(false),
143 playback_(false),
144 play_loop_(false),
145 eventnr_(0),
146 timer_id_(0),
147 dialog_(0),
148 mainWidget_(0)
149{
150 // create new macro Dialog
151// dialog_ = new QtMacroDialog(0, "MacroDialog");
152
153
154// // connect functions to macro dialog
155// connect(dialog_, SIGNAL(play()),
156// this, SLOT(play()));
157// connect(dialog_, SIGNAL(stop()),
158// this, SLOT(stop()));
159// connect(dialog_, SIGNAL(record()),
160// this, SLOT(record()));
161// connect(dialog_, SIGNAL(loop(bool)),
162// this, SLOT(loop(bool)));
163// connect(dialog_, SIGNAL(saveFile(const char*)),
164// this, SLOT(saveFile(const char*)));
165// connect(dialog_, SIGNAL(loadFile(const char*)),
166// this, SLOT(loadFile(const char*)));
167
168}
169
170//-----------------------------------------------------------------------------
171
172
173void QtApplication::cleanUpEventBuffer()
174{
175 // delete memory of events
176 for(unsigned int i=0; i<events_.size(); i++)
177 if (events_[i].event)
178 delete events_[i].event;
179
180 events_.clear();
181}
182
183
184//-----------------------------------------------------------------------------
185
186
187void QtApplication::loop(bool _b)
188{
189 play_loop_ = _b;
190}
191
192
193//-----------------------------------------------------------------------------
194
195
196void QtApplication::play()
197{
198 // check for main widget
199 mainWidget_ = activeWindow();
200 // mainWidget_ = mainWidget();
201 if (!mainWidget_)
202 {
203 std::cerr << "No Main Widget defined!\n";
204 return;
205 }
206
207
208 // stop recording first
209 record_ = false;
210 playback_ = true;
211 eventnr_ = 0;
212
213 restoreTopLevelSizes();
214
215 mainWidgetDiff_ = mainWidget_->mapToGlobal(QPoint(0,0)) - oldMainWidgetPos_;
216
217 time_.start();
218 timer_id_ = startTimer(10);
219}
220
221
222//-----------------------------------------------------------------------------
223
224
225void QtApplication::stop()
226{
227 record_ = false;
228 playback_ = false;
229 killTimer( timer_id_ );
230}
231
232
233//-----------------------------------------------------------------------------
234
235
236void QtApplication::record()
237{
238 // check main widget
239 mainWidget_ = activeWindow();
240 // mainWidget_ = mainWidget();
241 if (!mainWidget_)
242 {
243 std::cerr << "No Main Widget defined!\n";
244 return;
245 }
246
247 // stop playback first
248 playback_ = false;
249 killTimer( timer_id_ );
250
251 record_ = true;
252
253 cleanUpEventBuffer();
254
255 storeTopLevelSizes();
256
257 // save mainWidgetPos
258 oldMainWidgetPos_ = mainWidget_->mapToGlobal(QPoint(0,0));
259
260 // start recording Time
261 time_.start();
262}
263
264
265//-----------------------------------------------------------------------------
266
267
268bool QtApplication::notify (QObject* _receiver, QEvent* _event)
269{
270// // record events
271// if (record_ && !playback_)
272// recordEvent(_receiver, _event);
273
274
275// //check for recording or playback Keypresses
276// if (_event->type() == QEvent::KeyPress)
277// {
278// switch(((QKeyEvent*) _event)->key())
279// {
280// case Qt::Key_F5:
281// dialog_->show();
282// break;
283
284// case Qt::Key_F6:
285// play();
286// break;
287
288// case Qt::Key_F7:
289// stop();
290// break;
291
292// case Qt::Key_F8:
293// record();
294// break;
295// }
296// }
297
298
299 // handle Event like Qt do
300 return QApplication::notify(_receiver, _event);
301}
302
303
304//-----------------------------------------------------------------------------
305
306
307void QtApplication::recordEvent(QObject* /* _receiver */ , QEvent* /* _event */ )
308{
309// // save only events for widgets
310// if (_receiver->inherits("QWidget"))
311// {
312// QWidget*receiver = (QWidget*)_receiver;
313
314
315// // skip events for macro dialog
316// // if (receiver->activeWindow()->windowTitle() == "MacroDialog")
317// // return;
318// // if (receiver->topLevelWidget()->name() == "MacroDialog")
319// // return;
320
321
322// // generate event footprint
323// FootPrint fp;
324// fp.event = 0;
325// fp.time = time_.elapsed();
326// fp.cursorPos = mainWidget_->mapFromGlobal(QCursor::pos());
327// // fp.name = receiver->name();
328// // fp.classname = receiver->className();
329// fp.position = receiver->pos();
330// fp.size = receiver->size();
331// // fp.parent = (receiver->parent() ?
332// // receiver->parent()->name() : "noParent");
333
334
335
336// switch(_event->type())
337// {
338
339// // mouse event ----------------------------------------------------------
340// case QEvent::MouseButtonPress:
341// case QEvent::MouseButtonRelease:
342// case QEvent::MouseMove:
343// case QEvent::MouseButtonDblClick:
344// {
345// fp.event = clone_event<QMouseEvent>(_event);
346// break;
347// }
348
349
350// // wheel event ----------------------------------------------------------
351// case QEvent::Wheel:
352// {
353// fp.event = clone_event<QWheelEvent>(_event);
354// break;
355// }
356
357
358// // key event ------------------------------------------------------------
359// case QEvent::KeyPress:
360// case QEvent::KeyRelease:
361// case QEvent::Shortcut:
362// case QEvent::ShortcutOverride:
363// {
364// QKeyEvent* e = (QKeyEvent*) _event;
365
366// // skip F5, F6, F7, F8
367// if (e->key() != Qt::Key_F5 && e->key() != Qt::Key_F6 &&
368// e->key() != Qt::Key_F7 && e->key() != Qt::Key_F8)
369// fp.event = clone_event<QKeyEvent>(_event);
370// break;
371// }
372
373
374// // context menu event ---------------------------------------------------
375// case QEvent::ContextMenu:
376// {
377// fp.event = clone_event<QContextMenuEvent>(_event);
378// break;
379// }
380
381
382// // move event -----------------------------------------------------------
383// case QEvent::Move:
384// {
385// if (_event->spontaneous())
386// fp.event = clone_event<QMoveEvent>(_event);
387// break;
388// }
389
390
391// // close event ----------------------------------------------------------
392// case QEvent::Close:
393// {
394// // can be non-spontaneous !
395// fp.event = clone_event<QCloseEvent>(_event);
396// break;
397// }
398
399
400// default: // avoid warning
401// break;
402// }
403
404
405// // if event has been handled, store it
406// if (fp.event) events_.push_back(fp);
407// }
408}
409
410
411//-----------------------------------------------------------------------------
412
413
414void QtApplication::playbackEvent(FootPrint & /* _fp */ )
415{
416// // determine widget for saved event at runtime
417// QWidget* eventWidget = findWidget(_fp);
418// if (!eventWidget) return;
419
420
421// // position and size
422// if (eventWidget->isTopLevel())
423// {
424// // restore widget size
425// if (eventWidget->size() != _fp.size)
426// eventWidget->resize(_fp.size);
427
428// // correct position wrt to main widget
429// if (eventWidget != mainWidget_)
430// {
431// QPoint newWidgetPos = _fp.position + mainWidgetDiff_;
432
433// if (newWidgetPos != eventWidget->pos())
434// eventWidget->move(newWidgetPos);
435// }
436// }
437
438
439// // global cursor position
440// QPoint globalPos = mainWidget_->mapToGlobal(_fp.cursorPos);
441// QCursor::setPos(globalPos);
442
443
444// // correct global mouse position in events
445// switch(_fp.event->type())
446// {
447
448// // mouse event ----------------------------------------------------------
449// case QEvent::MouseButtonPress:
450// case QEvent::MouseButtonRelease:
451// case QEvent::MouseMove:
452// case QEvent::MouseButtonDblClick:
453// {
454// QMouseEvent* e = (QMouseEvent*) _fp.event;
455// QMouseEvent me = QMouseEvent(e->type(),
456// e->pos(),
457// globalPos,
458// e->button(),
459// e->state());
460
461// notify((QObject*) eventWidget, &me);
462// break;
463// }
464
465
466// // wheel event ------------------------------------------------------------
467// case QEvent::Wheel:
468// {
469// QWheelEvent* e = (QWheelEvent*) _fp.event;
470// QWheelEvent we = QWheelEvent(e->pos(),
471// globalPos,
472// e->angleDelta(),
473// e->state(),
474// e->orientation());
475
476// notify((QObject*) eventWidget, &we);
477// break;
478// }
479
480
481// // context menu event -----------------------------------------------------
482// case QEvent::ContextMenu:
483// {
484// QContextMenuEvent* e = (QContextMenuEvent*) _fp.event;
485// QContextMenuEvent ce = QContextMenuEvent(e->reason(),
486// e->pos(),
487// globalPos,
488// e->state());
489
490// notify((QObject*) eventWidget, &ce);
491// break;
492// }
493
494
495// // move event -----------------------------------------------------------
496// case QEvent::Move:
497// {
498// // pos has been adjusted above, but its still needed here...
499// break;
500// }
501
502
503// // all other events... ----------------------------------------------------
504// default:
505// {
506// // send event unmodified to the widget
507// notify((QObject*) eventWidget, _fp.event);
508// break;
509// }
510// }
511}
512
513
514//-----------------------------------------------------------------------------
515
516
517QWidget* QtApplication::findWidget(FootPrint & /* _fp */ )
518{
519// QWidget *w;
520// std::vector<QWidget*> candidates;
521// QWidgetList list = allWidgets();
522
523// for (int i = 0; i < list.size(); ++i)
524// {
525// w = list.at(i);
526
527// if (_fp.name == w->name() && _fp.classname == w->className())
528// if (_fp.parent == (w->parent() ? w->parent()->name() : "noParent"))
529// candidates.push_back(w);
530// }
531
532
533
534// if (candidates.size() == 1)
535// return candidates[0];
536
537// else
538// {
539// std::cerr << "Error: found " << candidates.size()
540// << " widgets with name " << "\"" << _fp.name << "\"\n";
541// return 0;
542// }
543
544 return 0;
545}
546
547
548//-----------------------------------------------------------------------------
549
550
551void QtApplication::timerEvent(QTimerEvent* /* _e */ )
552{
553 // all events processed ?
554 if (eventnr_ < events_.size())
555 {
556 // get current event
557 FootPrint fp = events_[eventnr_];
558
559 // right time to send ?
560 if (fp.time < time_.elapsed())
561 {
562 // increase counter
563 ++eventnr_;
564
565 // send event to widget
566 playbackEvent(fp);
567 }
568 }
569
570 // restart or stop playing
571 else
572 {
573 if (play_loop_) // restart
574 {
575 eventnr_ = 0;
576 time_.start();
577 }
578 else killTimer( timer_id_ ); // stop
579 }
580}
581
582
583//-----------------------------------------------------------------------------
584
585
586void QtApplication::storeTopLevelSizes()
587{
588// // clear buffer
589// toplevels_.clear();
590
591
592// QWidgetList list = topLevelWidgets();
593// QWidget *w;
594// FootPrint fp;
595
596
597// for (int i = 0; i < list.size(); ++i)
598// {
599// w = list.at(i);
600
601// fp.name = w->name();
602// fp.classname = w->className();
603// fp.parent = w->parent() ? w->parent()->name() : "noParent";
604// fp.size = w->size();
605
606// toplevels_.push_back(fp);
607// }
608}
609
610
611//-----------------------------------------------------------------------------
612
613
614void QtApplication::restoreTopLevelSizes()
615{
616// QWidget* w;
617
618// for(FootPrintIter it=toplevels_.begin(); it!=toplevels_.end(); ++it)
619// {
620// // find widget to restore size
621// if ((w = findWidget(*it)))
622// {
623// // size differs -> restore it
624// if (w->size() != it->size)
625// w->resize(it->size);
626// }
627// }
628}
629
630
631//-----------------------------------------------------------------------------
632
633
634void QtApplication::saveFile(const char* /* _filename */ )
635{
636// std::ofstream ofs(_filename, std::ios::out);
637// if (!ofs) return;
638
639
640// // write File Signature
641// ofs << "QTMacro " << events_.size() << std::endl;
642// ofs << oldMainWidgetPos_ << std::endl;
643
644
645// // save toplevel sizes to file
646// saveTopLevelSizes(ofs);
647
648
649// // save all events
650// for(FootPrintIter it=events_.begin(); it!=events_.end(); ++it)
651// {
652// ofs << "###" << std::endl;
653
654// ofs << it->time << std::endl;
655// ofs << it->name << std::endl;
656// ofs << it->classname << std::endl;
657// ofs << it->parent << std::endl;
658// ofs << it->cursorPos << std::endl;
659// ofs << it->position << std::endl;
660// ofs << it->size << std::endl;
661// ofs << (int)it->event->type() << std::endl;
662
663
664// switch(it->event->type())
665// {
666// // mouse events ---------------------------------------------------------
667// case QEvent::MouseButtonPress:
668// case QEvent::MouseButtonRelease:
669// case QEvent::MouseMove:
670// case QEvent::MouseButtonDblClick:
671// {
672// QMouseEvent* e = (QMouseEvent*) it->event;
673// ofs << e->pos() << std::endl;
674// ofs << e->globalPos() << std::endl;
675// ofs << (int)e->button() << std::endl;
676// ofs << (int)e->state() << std::endl;
677// break;
678// }
679
680
681// // wheel events ---------------------------------------------------------
682// case QEvent::Wheel:
683// {
684// QWheelEvent* e = (QWheelEvent*) it->event;
685// ofs << e->pos() << std::endl;
686// ofs << e->globalPos() << std::endl;
687// ofs << e->angleDelta() << std::endl;
688// ofs << (int)e->state() << std::endl;
689// ofs << (int)e->orientation() << std::endl;
690// break;
691// }
692
693
694// // key events -----------------------------------------------------------
695// case QEvent::KeyPress:
696// case QEvent::KeyRelease:
697// case QEvent::Shortcut:
698// case QEvent::ShortcutOverride:
699// {
700// QKeyEvent* e = (QKeyEvent*) it->event;
701// ofs << (int)e->key() << std::endl;
702// ofs << (int)e->ascii() << std::endl;
703// ofs << (int)e->state() << std::endl;
704// ofs << (int)e->isAutoRepeat() << std::endl;
705// ofs << (int)e->count() << std::endl;
706// break;
707// }
708
709
710// // context menu events --------------------------------------------------
711// case QEvent::ContextMenu:
712// {
713// QContextMenuEvent* e = (QContextMenuEvent*) it->event;
714// ofs << (int)e->reason() << std::endl;
715// ofs << e->pos() << std::endl;
716// ofs << e->globalPos() << std::endl;
717// ofs << (int)e->state() << std::endl;
718// break;
719// }
720
721
722// // move events ----------------------------------------------------------
723// case QEvent::Move:
724// {
725// QMoveEvent* e = (QMoveEvent*) it->event;
726// ofs << e->pos() << std::endl;
727// ofs << e->oldPos() << std::endl;
728// break;
729// }
730
731
732// // close events ---------------------------------------------------------
733// case QEvent::Close:
734// {
735// // nothing has to be stored
736// break;
737// }
738
739
740// default: // avoid warning
741// break;
742// }
743// }
744
745// ofs.close();
746}
747
748
749//-----------------------------------------------------------------------------
750
751
752void QtApplication::loadFile(const char* /* _filename */ )
753{
754// std::ifstream ifs(_filename, std::ios::in);
755// if (!ifs) return;
756
757
758// // helper
759// std::string s;
760// int size = 0;
761// FootPrint fp;
762
763
764
765// // check header
766// ifs >> s;
767// if (s != "QTMacro")
768// {
769// std::cerr << "wrong file format!!!" << std::endl;
770// return;
771// }
772// ifs >> size >> oldMainWidgetPos_;
773
774
775// // alloc
776// cleanUpEventBuffer();
777// events_.clear();
778
779
780// // load toplevel sizes
781// loadTopLevelSizes(ifs);
782
783
784// // load all events
785// for(int i=0; i<size; ++i)
786// {
787// fp.event = 0;
788
789
790// // check for errors
791// ifs >> s;
792// if (s!="###")
793// {
794// std::cerr << "Event parsing error: " << s << std::endl;
795// return;
796// }
797
798
799// // general event data
800// ifs >> fp.time;
801// ifs.ignore(1, '\n');
802// fp.name = read_name(ifs);
803// fp.classname = read_name(ifs);
804// fp.parent = read_name(ifs);
805// ifs >> fp.cursorPos >> fp.position >> fp.size;
806// ifs.ignore(1, '\n');
807
808
809// // determine event type
810// int type;
811// ifs >> type;
812
813
814// // type specific data
815// switch(type)
816// {
817
818// // mouse events ---------------------------------------------------------
819// case QEvent::MouseButtonPress:
820// case QEvent::MouseButtonRelease:
821// case QEvent::MouseMove:
822// case QEvent::MouseButtonDblClick:
823// {
824// QPoint pos, globalPos;
825// int button, state;
826
827// ifs >> pos >> globalPos >> button >> state;
828
829// fp.event = new QMouseEvent((QEvent::Type)type,
830// pos,
831// globalPos,
832// button,
833// state);
834// break;
835// }
836
837
838// // mouse wheel events ---------------------------------------------------
839// case QEvent::Wheel:
840// {
841// int delta, state, orientation;
842// QPoint pos, globalPos;
843
844// // read values from file
845// ifs >> pos >> globalPos >> delta >> state >> orientation;
846
847// fp.event = new QWheelEvent(pos,
848// globalPos,
849// delta,
850// state,
851// (Qt::Orientation) orientation);
852// break;
853// }
854
855
856// // key events -----------------------------------------------------------
857// case QEvent::KeyPress:
858// case QEvent::KeyRelease:
859// case QEvent::Shortcut:
860// case QEvent::ShortcutOverride:
861// {
862// int key, ascii, state, count, isAutoRepeat;
863// char text[2];
864
865// ifs >> key >> ascii >> state >> isAutoRepeat >> count;
866
867// text[0] = (char)ascii;
868// text[1] = '\0';
869
870// fp.event = new QKeyEvent((QEvent::Type)type,
871// key,
872// ascii,
873// state,
874// QString(text),
875// isAutoRepeat,
876// count);
877// break;
878// }
879
880
881
882// // context menu events --------------------------------------------------
883// case QEvent::ContextMenu:
884// {
885// int reason, state;
886// QPoint pos, globalPos;
887
888// ifs >> reason >> pos >> globalPos >> state;
889
890// fp.event = new QContextMenuEvent((QContextMenuEvent::Reason)reason,
891// pos,
892// globalPos,
893// state);
894// break;
895// }
896
897
898// // move events ----------------------------------------------------------
899// case QEvent::Move:
900// {
901// QPoint pos, oldPos;
902
903// ifs >> pos >> oldPos;
904
905// fp.event = new QMoveEvent(pos, oldPos);
906// break;
907// }
908
909
910// // close events ---------------------------------------------------------
911// case QEvent::Close:
912// {
913// fp.event = new QCloseEvent();
914// break;
915// }
916
917
918
919// default:
920// {
921// std::cerr << "Error: unknown event type: " << type << std::endl;
922// break;
923// }
924// }
925
926
927// // store event
928// if (fp.event) events_.push_back(fp);
929// }
930
931
932// ifs.close();
933}
934
935
936//-----------------------------------------------------------------------------
937
938
939void QtApplication::saveTopLevelSizes(std::ostream & /* _os */ )
940{
941// _os << "TLS " << toplevels_.size() << std::endl;
942
943// for(FootPrintIter it=toplevels_.begin(); it!=toplevels_.end(); ++it)
944// {
945// _os << it->name << std::endl;
946// _os << it->classname << std::endl;
947// _os << it->parent << std::endl;
948// _os << it->size << std::endl;
949// }
950
951// _os << "ENDTLS" << std::endl;
952
953}
954
955
956//-----------------------------------------------------------------------------
957
958
959void QtApplication::loadTopLevelSizes(std::istream & /* _is */ )
960{
961// std::string s;
962// int size;
963// FootPrint fp;
964
965
966// // check header
967// _is >> s;
968// if (s != "TLS")
969// {
970// std::cerr << "error in toplevel block (start)\n";
971// return;
972// }
973// _is >> size;
974// _is.ignore(1, '\n');
975
976
977// // read top level sizes
978// toplevels_.clear();
979
980// for(int i=0; i<size; i++)
981// {
982// // read names
983// fp.name = read_name(_is);
984// fp.classname = read_name(_is);
985// fp.parent = read_name(_is);
986
987// // read size
988// _is >> fp.size;
989// _is.ignore(1, '\n');
990
991// // store footprint
992// toplevels_.push_back(fp);
993// }
994
995
996// _is >> s;
997// if (s != "ENDTLS")
998// {
999// std::cerr << "Error in toplevel block (end)\n";
1000// return;
1001// }
1002// _is.ignore(1, '\n');
1003}
1004
1005
1006//=============================================================================
1007} // namespace QtWidgets
1008} // namespace ACG
1009//=============================================================================
Namespace providing different geometric functions concerning angles.