mainwindow.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. #include "mainwindow.h"
  2. #include "annotationxml.h"
  3. #include "ui_mainwindow.h"
  4. #include <QImage>
  5. #include <QDebug>
  6. #include <QLabel>
  7. #include <QWidget>
  8. #include <QPainter>
  9. #include <QFileDialog>
  10. #include <QToolButton>
  11. #include <QGridLayout>
  12. #include <QMessageBox>
  13. #include <QStatusBar>
  14. #include <QTreeView>
  15. #include <QMenu>
  16. #include <QCursor>
  17. #include <QInputDialog>
  18. #include <QDateTime>
  19. #include <CSVReader.h>
  20. #include "changemask.h"
  21. #include "changepacket.h"
  22. #include "tinyxml2.h"
  23. #include "classoptions.h"
  24. #include "requestfromserver.h"
  25. // Hilfstexte
  26. QString toolTitel[] = { "Objekte Verstecken", "Verschieben", "Neues Objekt", "Kopieren", "Einfügen", "Löschen", "Zerschneiden", "Vergrößern", "Allgemeine Information" };
  27. QString toolBeschreibung[] {"Klicken sie mit der Linken Maustaste auf ein Objekt um es zu verstecken, oder wieder sichtbar zu machen.\nVersteckte Objekte werden von anderen Werkzeugen ignoriert.",
  28. "Halten sie die linke Maustaste gedrückt, um die Ecke eines Objektes zu verschieben, wenn sich die Maus in der Nähe befindet.\nBefindet sich keine Ecke in der Nähe der Maus, so wird eine neue Ecke erzeugt.",
  29. "Klicken sie mit der Linken Maustaste an die Stellen, wo die Ecken des neuen Objektes sind.\nUm den Vorgang abzuschließen klicken sie erneut auf die erste Ecke.\nMit Rechtsklick kann die vorherige Ecke wieder entfernt werden.",
  30. "Klicken sie mit der linken Maustaste auf das Objekt, welches sie kopieren möchten.",
  31. "Klicken sie mit der linken Maustaste auf ein Objekt, um die ID und die Klasse des kopierten Objektes auf dieses zu übertragen.\nKlicken sie an eine freie Stelle um eine Kopie des kopierten Objektes einzufügen.\nHalten sie die rechte Maustaste gedrückt, um das kopierte Objekt zu drehen.",
  32. "Halten sie die linke Maustaste gedrückt, um einen Bereich festzulegen, in dem alle Eckpunkte gelöscht werden sollen.",
  33. "Klicken sie auf zwei Eckpunkte eines Objektes, um es in zwei verschiedene Objekte zu zerschneiden.",
  34. "Halte die linke Maustaste gedrückt um ein Gebiet zu makieren, an welches herangezoomt werden soll.",
  35. "Klicken sie auf Öffnen und wählen sie einen Ordner aus, um eine annotierte Sequenz zu laden oder eine neue Sequenz zu erstellen."};
  36. // Inhalt der MainWindow Klasse
  37. //------------------------------
  38. MainWindow::MainWindow( QApplication *app, QWidget *parent ) :
  39. QMainWindow(parent),
  40. app( app ),
  41. ui(new Ui::MainWindow),
  42. contextMenu( 0 ),
  43. seq( 0 ),
  44. m( 0 ),
  45. serverAddress( "tcp://ob:55556" )
  46. {
  47. ui->setupUi(this);
  48. setWindowTitle( "Annotation GUI v. 1.0" );
  49. status = new QLabel( "fertig" );
  50. ui->statusBar->layout()->setSizeConstraint(QLayout::SetMinimumSize);
  51. status->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
  52. ui->statusBar->layout()->addWidget( status );
  53. ui->statusBar->addWidget( status );
  54. workModel = new ArbeitsModel( this );
  55. ArbeitsController::initStaticController( workModel );
  56. v = new ArbeitsView( workModel, ui->viewWidget );
  57. v->setController( ArbeitsController::getController( MOVE ) );
  58. workModel->addView( v );
  59. ui->toolTitel->setText( toolTitel[ USERMODE_COUNT ] );
  60. ui->toolBeschreibung->setText( toolBeschreibung[ USERMODE_COUNT ] );
  61. ui->framesTree->setContextMenuPolicy( Qt::CustomContextMenu );
  62. ui->viewWidget->setContextMenuPolicy( Qt::CustomContextMenu );
  63. QList<QToolButton *> btnList = ui->buttons->findChildren<QToolButton*>();
  64. for( auto i = btnList.begin(); i != btnList.end(); i++ )
  65. {
  66. (*i)->setIconSize( (*i)->size() );
  67. }
  68. }
  69. MainWindow::~MainWindow()
  70. {
  71. if( seq )
  72. {
  73. QMessageBox::StandardButton reply = QMessageBox::question(this, "Achtung", "Möchten sie die Annotationen speichern?",
  74. QMessageBox::Yes|QMessageBox::No);
  75. if (reply == QMessageBox::Yes) {
  76. seq->saveToPath( status );
  77. }
  78. seq->refRelease();
  79. }
  80. delete status;
  81. delete ui;
  82. delete m;
  83. delete contextMenu;
  84. }
  85. // Erstellt den Navigationsbaum
  86. void MainWindow::setupFrameTree()
  87. {
  88. ui->framesTree->setUpdatesEnabled(false);
  89. if( !seq )
  90. return;
  91. if( !m )
  92. {
  93. m = new FrameTreeModel();
  94. seq->refNew();
  95. m->setSequenz( seq );
  96. ui->framesTree->setModel( m );
  97. ui->framesTree->setSelectionMode( ui->framesTree->MultiSelection );
  98. }
  99. ui->framesTree->collapseAll();
  100. setFrameTreeSelection();
  101. repaintFrameTree();
  102. ui->framesTree->setUpdatesEnabled(true);
  103. }
  104. // Aktualisiert die Ausgefählten Objekte im Navigationsbaum
  105. void MainWindow::setFrameTreeSelection()
  106. {
  107. ui->framesTree->expand( m->getCameraSelectionIndex() );
  108. ui->framesTree->expand( m->getFrameSelectionIndex() );
  109. ui->framesTree->selectionModel()->select( m->getCameraSelectionIndex(), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
  110. ui->framesTree->selectionModel()->select( m->getFrameSelectionIndex(), QItemSelectionModel::Select | QItemSelectionModel::Rows );
  111. QList<QModelIndex> indices = m->getSelectedPackages();
  112. for( auto index = indices.begin(); index != indices.end(); index++ )
  113. ui->framesTree->selectionModel()->select( *index, QItemSelectionModel::Select | QItemSelectionModel::Rows );
  114. ui->framesTree->scrollTo(m->getFrameSelectionIndex());
  115. ui->framesTree->repaint();
  116. }
  117. // Zeichnet den Navigazionsbaum neu
  118. void MainWindow::repaintFrameTree()
  119. {
  120. m->update();
  121. ui->framesTree->repaint();
  122. }
  123. // Setzt den Controller der Arbeitsfläche
  124. void MainWindow::setMode( UserMode m )
  125. {
  126. if( workModel->getMode() == m )
  127. ArbeitsController::getController( m )->restartController();
  128. workModel->setMode( m );
  129. v->setController( ArbeitsController::getController( m ) );
  130. ui->toolTitel->setText( toolTitel[ workModel->getMode() ] );
  131. ui->toolBeschreibung->setText( toolBeschreibung[ workModel->getMode() ] );
  132. }
  133. // Gibt die geladene Sequenz zurück
  134. Sequenz *MainWindow::getSequenz()
  135. {
  136. return seq;
  137. }
  138. // Wählt alle Buttons für die Werkzeuge ab
  139. void MainWindow::unselectButttons()
  140. {
  141. QList<QToolButton *> btnList = ui->buttons->findChildren<QToolButton*>();
  142. for( auto i = btnList.begin(); i != btnList.end(); i++ )
  143. {
  144. (*i)->setChecked( false );
  145. }
  146. }
  147. // Fragt nach Vorabannotationen beim Server
  148. void MainWindow::requestFromServer()
  149. {
  150. if( serverAddress != "" )
  151. {
  152. Frame *f = seq->getFrame();
  153. RequestFromServer rfs( serverAddress, f );
  154. rfs.exec();
  155. f->setObjects( rfs.getObjects() );
  156. f->applyMask(*((Kamera*)f->getParent())->getMask());
  157. if( !seq->hasAnnotatedObjects() )
  158. {
  159. int id = 0;
  160. for( auto obj = f->getObjects().begin(); obj != f->getObjects().end(); obj++ )
  161. {
  162. (*obj)->setId( QString::number( id ) );
  163. seq->addObjectName( QString::number( id ) );
  164. id++;
  165. }
  166. }
  167. }
  168. else
  169. seq->getFrame()->setObjects( std::vector< std::vector< cv::Point > >());
  170. setupFrameTree();
  171. v->repaint();
  172. }
  173. // Öffnet eine Sequenz
  174. void MainWindow::on_actionOpen_triggered()
  175. {
  176. QString path = QFileDialog::getExistingDirectory(this,
  177. tr("Open Image Directory"),
  178. "/studi-tmp/kstrohm",
  179. QFileDialog::ShowDirsOnly |
  180. QFileDialog::DontResolveSymlinks);
  181. if( path == "" )
  182. return;
  183. status->setText( "Lade Annotation ..." );
  184. AnnotationLoader loader( path, status );
  185. if( seq )
  186. seq->refRelease();
  187. seq = loader.getSequenz();
  188. if( !seq )
  189. {
  190. QMessageBox::StandardButton reply = QMessageBox::question(this, "Achtung", "In dem ausgewählten Ordner wurde keine Annotierte Sequenz gefunden. Möchten sie eine neue Sequenz erstellen?",
  191. QMessageBox::Yes|QMessageBox::No);
  192. if (reply == QMessageBox::Yes) {
  193. AnnotationCreator creator( path, status );
  194. seq = creator.getSequenz();
  195. if( !seq )
  196. {
  197. QMessageBox::critical( this, "Fehler", "Es ist ein Fehler beim erstellen der Sequenz aufgetreten." );
  198. }
  199. }
  200. }
  201. status->setText( "fertig" );
  202. if( seq )
  203. {
  204. ui->framesTree->setModel( 0 );
  205. delete m;
  206. m = 0;
  207. Frame *f = seq->getFrame();
  208. workModel->setFrame( f );
  209. workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
  210. workModel->notifyViews();
  211. if( f->isNotAnnotated() )
  212. requestFromServer();
  213. else
  214. setupFrameTree();
  215. setMode( MOVE );
  216. }
  217. }
  218. // Wechselt zum nächsten Bild
  219. void MainWindow::on_actionNext_triggered()
  220. {
  221. ui->framesTree->selectionModel()->clear();
  222. int oldCam = seq->getSelectedCamera();
  223. QModelIndex camIndex = m->getCameraSelectionIndex();
  224. ui->framesTree->collapse( m->getFrameSelectionIndex() );
  225. seq->nextFrame();
  226. if(oldCam != seq->getSelectedCamera())
  227. ui->framesTree->collapse( camIndex );
  228. Frame *f = seq->getFrame();
  229. workModel->setFrame( f );
  230. workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
  231. workModel->notifyViews();
  232. if( f->isNotAnnotated() )
  233. requestFromServer();
  234. else
  235. setFrameTreeSelection();
  236. }
  237. // Wechselt zum vorherigen Bild
  238. void MainWindow::on_actionBefore_triggered()
  239. {
  240. ui->framesTree->selectionModel()->clear();
  241. int oldCam = seq->getSelectedCamera();
  242. QModelIndex camIndex = m->getCameraSelectionIndex();
  243. ui->framesTree->collapse( m->getFrameSelectionIndex() );
  244. seq->previousFrame();
  245. if(oldCam != seq->getSelectedCamera())
  246. ui->framesTree->collapse( camIndex );
  247. Frame *f = seq->getFrame();
  248. workModel->setFrame( f );
  249. workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
  250. workModel->notifyViews();
  251. if( f->isNotAnnotated() )
  252. requestFromServer();
  253. else
  254. setFrameTreeSelection();
  255. }
  256. // Wechselt zum nächsten Bild
  257. void MainWindow::on_next_clicked()
  258. {
  259. on_actionNext_triggered();
  260. }
  261. // Wechselt zum vorherigen Bild
  262. void MainWindow::on_before_clicked()
  263. {
  264. on_actionBefore_triggered();
  265. }
  266. // Setzt die Vergrößerung der Arbeitsfläche zurück
  267. void MainWindow::on_zoom_out_clicked()
  268. {
  269. workModel->resetZoom();
  270. workModel->notifyViews();
  271. }
  272. // Wechselt in den ZOOM_IN Modus
  273. void MainWindow::on_zoom_in_clicked()
  274. {
  275. unselectButttons();
  276. ui->zoom_in->setChecked( true );
  277. setMode( ZOOM_IN );
  278. v->repaint();
  279. }
  280. // Wechselt in den DELETE Modus
  281. void MainWindow::on_remove_clicked()
  282. {
  283. unselectButttons();
  284. ui->remove->setChecked( true );
  285. setMode( DELETE );
  286. v->repaint();
  287. }
  288. // Wechselt in den NEW Modus
  289. void MainWindow::on_polygon_clicked()
  290. {
  291. unselectButttons();
  292. ui->polygon->setChecked( true );
  293. setMode( NEW );
  294. }
  295. // Wechselt in den MOVE Modus
  296. void MainWindow::on_move_clicked()
  297. {
  298. unselectButttons();
  299. ui->move->setChecked( true );
  300. setMode( MOVE );
  301. }
  302. // Wechselt zum angeklickten Bild des Navigationsbaumes
  303. void MainWindow::on_framesTree_clicked(const QModelIndex &index)
  304. {
  305. if( ((FrameTreeNode*)index.internalPointer())->getDepth() == 2 )
  306. ((_ObjectPolygon*)index.internalPointer())->setSelected( ui->framesTree->selectionModel()->isSelected( index ) );
  307. ui->framesTree->selectionModel()->clear();
  308. int cam, fr;
  309. if( m && m->clickedOnFrame( index, cam, fr ) )
  310. {
  311. if( cam != seq->getSelectedCamera() || fr != seq->getSelectedFrame() )
  312. {
  313. if(cam != seq->getSelectedCamera())
  314. ui->framesTree->collapse( m->getCameraSelectionIndex() );
  315. ui->framesTree->collapse( m->getFrameSelectionIndex() );
  316. seq->selectFrame( cam, fr );
  317. Frame *f = seq->getFrame();
  318. workModel->setFrame( f );
  319. workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
  320. workModel->notifyViews();
  321. if( f->isNotAnnotated() )
  322. requestFromServer();
  323. }
  324. }
  325. if( ((FrameTreeNode*)index.internalPointer())->getDepth() == 0 )
  326. {
  327. if( ((FrameTreeNode*)index.internalPointer())->getIndex() != seq->getSelectedCamera() )
  328. {
  329. ui->framesTree->collapse( m->getCameraSelectionIndex() );
  330. ui->framesTree->collapse( m->getFrameSelectionIndex() );
  331. seq->selectFrame( ((FrameTreeNode*)index.internalPointer())->getIndex(), 0 );
  332. Frame *f = seq->getFrame();
  333. workModel->setFrame( f );
  334. workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
  335. workModel->notifyViews();
  336. if( f->isNotAnnotated() )
  337. requestFromServer();
  338. }
  339. }
  340. if( ((FrameTreeNode*)index.internalPointer())->getDepth() == 2 )
  341. {
  342. if( ((FrameTreeNode*)index.internalPointer())->getParent()->getParent()->getIndex() != seq->getSelectedCamera() )
  343. ui->framesTree->collapse( m->getCameraSelectionIndex() );
  344. if( ((FrameTreeNode*)index.internalPointer())->getParent()->getIndex() != seq->getSelectedFrame() )
  345. ui->framesTree->collapse( m->getFrameSelectionIndex() );
  346. seq->selectFrame( ((FrameTreeNode*)index.internalPointer())->getParent()->getParent()->getIndex(),
  347. ((FrameTreeNode*)index.internalPointer())->getParent()->getIndex() );
  348. Frame *f = seq->getFrame();
  349. workModel->setFrame( f );
  350. workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
  351. workModel->notifyViews();
  352. if( f->isNotAnnotated() )
  353. requestFromServer();
  354. }
  355. setFrameTreeSelection();
  356. v->repaint();
  357. }
  358. // Wechselt in den SELECT Modus
  359. void MainWindow::on_select_clicked()
  360. {
  361. unselectButttons();
  362. ui->select->setChecked( true );
  363. setMode( SELECT );
  364. }
  365. // Zeigt ein Rechtsklick Menü im Navigationsbaum an
  366. void MainWindow::on_framesTree_customContextMenuRequested(const QPoint &pos)
  367. {
  368. QModelIndex index = ui->framesTree->indexAt( pos );
  369. ui->framesTree->selectionModel()->select( index, QItemSelectionModel::Select | QItemSelectionModel::Rows );
  370. on_framesTree_clicked( index );
  371. QAction *trunc = 0;
  372. if( contextMenu )
  373. delete contextMenu;
  374. contextMenu = new QMenu( ui->framesTree );
  375. switch( ((FrameTreeNode*)index.internalPointer())->getDepth() )
  376. {
  377. case 0:
  378. contextMenu->addAction( "Maske Bearbeiten ..." );
  379. break;
  380. case 1:
  381. contextMenu->addAction( "Vom Server abfragen ..." );
  382. break;
  383. case 2:
  384. contextMenu->addAction( "Objekt ID bearbeiten ..." );
  385. contextMenu->addAction( "Objekt Klasse bearbeiten ..." );
  386. contextMenu->addAction( "Objekt löschen" );
  387. if( ((_ObjectPolygon*)index.internalPointer())->getPolygonList().size() > 1 )
  388. contextMenu->addAction( "Objekt nach Polygonen aufteilen" );
  389. trunc = contextMenu->addAction( "Abgeschnitten" );
  390. trunc->setCheckable( true );
  391. trunc->setText( "Abgeschnitten" );
  392. trunc->setChecked( ((_ObjectPolygon*)index.internalPointer())->isTruncated() );
  393. break;
  394. }
  395. QAction *action = contextMenu->exec( QCursor::pos() );
  396. if( !action )
  397. return;
  398. if( action->text() == "Maske Bearbeiten ..." )
  399. {
  400. ChangeMask chm( ((Kamera*)index.internalPointer())->getMask(), (Kamera*)index.internalPointer() );
  401. chm.exec();
  402. ((Kamera*)index.internalPointer())->getMask()->unloadMask();
  403. setupFrameTree();
  404. }
  405. if( action->text() == "Vom Server abfragen ..." )
  406. requestFromServer();
  407. if( action->text() == "Objekt ID bearbeiten ..." )
  408. {
  409. ChangePacket chp( ObjectPolygon( (_ObjectPolygon*)index.internalPointer() ), seq );
  410. chp.exec();
  411. workModel->notifyViews();
  412. setupFrameTree();
  413. }
  414. if( action->text() == "Objekt Klasse bearbeiten ..." )
  415. {
  416. QList< Sequenz::SegmentationClass > classes = seq->getClasses();
  417. QList< QString > classNames;
  418. QString packetId = ((_ObjectPolygon*)index.internalPointer())->getId();
  419. int currentClass = seq->getClassOfObject( packetId );
  420. int classId = -1;
  421. foreach( auto c, classes )
  422. {
  423. if( currentClass == c.id )
  424. classId = classNames.size();
  425. classNames.append( c.name );
  426. }
  427. QString className = QInputDialog::getItem( this, "Klasse Bearbeiten", "Klasse von Objekt " + packetId, classNames, classId, false );
  428. seq->setClassOfObject( packetId, seq->getClassId( className ) );
  429. setupFrameTree();
  430. }
  431. if( action->text() == "Objekt Löschen" )
  432. {
  433. Frame *f = seq->getFrame();
  434. f->removeObject( ObjectPolygon( (_ObjectPolygon*)index.internalPointer() ) );
  435. setupFrameTree();
  436. v->repaint();
  437. }
  438. if( action->text() == "Objekt nach Polygonen aufteilen" )
  439. {
  440. seq->getFrame()->disconnectObject( ObjectPolygon( ((_ObjectPolygon*)index.internalPointer()) ) );
  441. setupFrameTree();
  442. v->repaint();
  443. }
  444. if( action == trunc )
  445. ((_ObjectPolygon*)index.internalPointer())->setTruncated( !((_ObjectPolygon*)index.internalPointer())->isTruncated() );
  446. }
  447. // Speichert die geladene Sequenz
  448. void MainWindow::on_actionSave_triggered()
  449. {
  450. if( !seq )
  451. return;
  452. status->setText( "speichere Annotation ..." );
  453. seq->saveToPath( status );
  454. status->setText( "fertig" );
  455. }
  456. // Wechselt in den Modus PIPETTE_SELECT
  457. void MainWindow::on_pipette_clicked()
  458. {
  459. unselectButttons();
  460. ui->pipette->setChecked( true );
  461. setMode( PIPETTE_SELECT );
  462. }
  463. // Wechselt in den CUT Modus
  464. void MainWindow::on_cut_clicked()
  465. {
  466. unselectButttons();
  467. ui->cut->setChecked( true );
  468. setMode( CUT );
  469. }
  470. // Zeigt die Option zum einstellen der Serveradresse an
  471. void MainWindow::on_actionServer_address_triggered()
  472. {
  473. serverAddress = QInputDialog::getText( this, "Server Adresse ändern", "Server Adresse:", QLineEdit::Normal, serverAddress );
  474. }
  475. // Zeigt die Klassen Verwaltungsoberfläche an
  476. void MainWindow::on_actionKlassen_verwalten_triggered()
  477. {
  478. if( seq )
  479. {
  480. ClassOptions cop( seq, this );
  481. cop.exec();
  482. }
  483. else
  484. QMessageBox::critical( this, "Fehler", "Sie müssen zunächst eine Sequenz geöffnet haben, bevor sie die Klassen verwalten können." );
  485. }
  486. // Zeigt ein Rechtsklick Menü auf der Arbeitsfläche an
  487. void MainWindow::on_viewWidget_customContextMenuRequested(const QPoint &pos)
  488. {
  489. QPoint rPos = pos - v->pos();
  490. if( !seq || !seq->getFrame() )
  491. {
  492. v->mouseReleaseEvent( 0 );
  493. return;
  494. }
  495. QPoint tPos = workModel->inverseTranslate( rPos );
  496. int pIndex;
  497. ObjectPolygon obj = seq->getFrame()->getObjectAt( tPos, pIndex );
  498. if( obj.isNull() )
  499. return;
  500. v->mouseReleaseEvent( 0 );
  501. if( contextMenu )
  502. delete contextMenu;
  503. contextMenu = new QMenu( ui->viewWidget );
  504. contextMenu->addAction( "Objekt ID bearbeiten ..." );
  505. contextMenu->addAction( "Objekt Klasse bearbeiten ..." );
  506. contextMenu->addAction( "Objekt Loeschen" );
  507. if( obj->getPolygonList().size() > 1 )
  508. contextMenu->addAction( "Objekt nach Polygonen aufteilen" );
  509. QAction *trunc = contextMenu->addAction( "Abgeschnitten" );
  510. trunc->setCheckable( true );
  511. trunc->setText( "Abgeschnitten" );
  512. trunc->setChecked( obj->isTruncated() );
  513. QAction *action = contextMenu->exec( QCursor::pos() );
  514. if( !action )
  515. return;
  516. if( action->text() == "Objekt ID bearbeiten ..." )
  517. {
  518. ChangePacket chp( obj, seq );
  519. chp.exec();
  520. workModel->notifyViews();
  521. setupFrameTree();
  522. }
  523. if( action->text() == "Objekt Klasse bearbeiten ..." )
  524. {
  525. QList< Sequenz::SegmentationClass > classes = seq->getClasses();
  526. QList< QString > classNames;
  527. QString packetId = obj->getId();
  528. int currentClass = seq->getClassOfObject( packetId );
  529. int classId = -1;
  530. foreach( auto c, classes )
  531. {
  532. if( currentClass == c.id )
  533. classId = classNames.size();
  534. classNames.append( c.name );
  535. }
  536. QString className = QInputDialog::getItem( this, "Klasse Bearbeiten", "Klasse von Objekt " + packetId, classNames, classId, false );
  537. seq->setClassOfObject( packetId, seq->getClassId( className ) );
  538. setupFrameTree();
  539. }
  540. if( action->text() == "Objekt Loeschen" )
  541. {
  542. Frame *f = seq->getFrame();
  543. f->removeObject( obj );
  544. setupFrameTree();
  545. v->repaint();
  546. }
  547. if( action->text() == "Objekt nach Polygonen aufteilen" )
  548. {
  549. seq->getFrame()->disconnectObject( obj );
  550. setupFrameTree();
  551. v->repaint();
  552. }
  553. if( action == trunc )
  554. obj->setTruncated( !obj->isTruncated() );
  555. }
  556. // Setzt das anzeigen der Maske in der Arbeitsfläche
  557. void MainWindow::on_actionMake_anzeigen_toggled(bool checked)
  558. {
  559. workModel->setShowMask( checked );
  560. workModel->notifyViews();
  561. }
  562. // Setzt die Option des einfärbens von Objekten in der Arbeitsfläche
  563. void MainWindow::on_actionObjekte_faerben_triggered(bool checked)
  564. {
  565. workModel->setShowColors( checked );
  566. workModel->notifyViews();
  567. }
  568. // Setzt die Option des Anzeigens von IDs in der Arbeitsfläche
  569. void MainWindow::on_actionIDs_anzeigen_triggered(bool checked)
  570. {
  571. workModel->setShowId( checked );
  572. workModel->notifyViews();
  573. }
  574. // Zeigt die Maskenbearbeitungsoberfläche
  575. void MainWindow::on_actionMaske_bearbeiten_triggered()
  576. {
  577. if( !seq )
  578. return;
  579. ChangeMask chm( seq->getCameras().at( seq->getSelectedCamera() )->getMask(), seq->getCameras().at( seq->getSelectedCamera() ) );
  580. chm.exec();
  581. setupFrameTree();
  582. }