mainwindow.cpp 22 KB

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