7 #include "ui_mainwindow.h" 10 #include <QFileDialog> 11 #include <QFileInfoList> 12 #include <QGraphicsPixmapItem> 13 #include <QMessageBox> 14 #include <QProgressDialog> 24 ui->controlsWidget->setController( controller );
25 ui->controlsDock->hide( );
26 ui->dockWidgetSegmentation->hide( );
27 ui->imageViewer->setController( controller );
28 ui->actionPrint->setEnabled(
false );
36 currentImageChanged( );
42 ui->toolBar->setVisible(
true );
44 QActionGroup *group =
new QActionGroup(
this );
45 actionDefaultTool = group->addAction(
"Default Tool" );
46 actionSegmentationTool = group->addAction(
"Segmentation Tool" );
47 actionDefaultTool->setCheckable(
true );
48 actionDefaultTool->setChecked(
true );
49 actionSegmentationTool->setCheckable(
true );
50 actionSegmentationTool->setChecked(
false );
52 connect( actionDefaultTool, &QAction::triggered,
this, &MainWindow::on_actionDefaultTool_triggered );
53 connect( actionSegmentationTool, &QAction::triggered,
this, &MainWindow::on_actionSegmentationTool_triggered );
55 ui->toolBar->addActions( group->actions( ) );
58 ui->actionOpen_DicomDir->setVisible(
false );
62 void MainWindow::createConnections( ) {
64 connect( ui->actionShow_controls_dock, &QAction::toggled, ui->controlsDock, &QDockWidget::setVisible );
65 connect( ui->actionHistogram_dock, &QAction::toggled, ui->dockWidgetHistogram, &QDockWidget::setVisible );
66 connect( ui->actionShow_images_dock, &QAction::toggled, ui->thumbsDock, &QDockWidget::setVisible );
67 connect( ui->actionSegmentation_dock, &QAction::toggled, ui->dockWidgetSegmentation, &QDockWidget::setVisible );
68 connect( ui->controlsDock, &QDockWidget::visibilityChanged, ui->actionShow_controls_dock, &QAction::setChecked );
69 connect( ui->thumbsDock, &QDockWidget::visibilityChanged, ui->actionShow_images_dock, &QAction::setChecked );
70 connect( ui->dockWidgetHistogram, &QDockWidget::visibilityChanged, ui->actionHistogram_dock, &QAction::setChecked );
71 connect( ui->dockWidgetSegmentation, &QDockWidget::visibilityChanged, ui->actionSegmentation_dock,
72 &QAction::setChecked );
93 void MainWindow::setupLogoview( ) {
94 QGraphicsScene *scn =
new QGraphicsScene(
this );
95 QGraphicsPixmapItem *pixmapItem =
new QGraphicsPixmapItem( QPixmap(
":/icons/logo_shadow.png" ) );
96 scn->addItem( pixmapItem );
97 scn->setSceneRect( 0, 0, pixmapItem->pixmap( ).width( ), pixmapItem->pixmap( ).height( ) );
98 ui->logoView->setScene( scn );
105 void MainWindow::on_actionRed_background_triggered( ) {
106 ui->imageViewer->setViewBgColor( Qt::red );
109 void MainWindow::on_actionGreen_background_triggered( ) {
110 ui->imageViewer->setViewBgColor( Qt::green );
113 void MainWindow::on_actionBlue_background_triggered( ) {
114 ui->imageViewer->setViewBgColor( Qt::blue );
117 void MainWindow::on_actionBlack_background_triggered( ) {
118 ui->imageViewer->setViewBgColor( Qt::black );
121 void MainWindow::on_actionWhite_background_triggered( ) {
122 ui->imageViewer->setViewBgColor( Qt::white );
125 void MainWindow::currentImageChanged( ) {
132 ui->menuOverlay->setEnabled( format->
hasOverlay( ) );
147 ui->action3_Views->setVisible( format->
has3Views( ) );
148 ui->action4_Views->setVisible( format->
has4Views( ) );
150 actionDefaultTool->setChecked(
true );
153 actionDefaultTool->setChecked(
true );
156 actionSegmentationTool->setChecked(
true );
162 void MainWindow::imageUpdated( ) {
165 QVector< double > x( hist.
size( ) ), y( hist.
size( ) );
188 void MainWindow::containerUpdated( ) {
189 COMMENT(
"MainWindow::containerUpdated( )", 0 );
190 if( controller->
size( ) <= 1 ) {
191 ui->thumbsDock->hide( );
194 ui->thumbsDock->show( );
196 bool hasImage = ( controller->
currentImage( ) != nullptr );
197 ui->toolBar->setVisible( hasImage );
198 COMMENT(
"Has Image = " << hasImage, 0 );
199 ui->menuWindow->setEnabled( hasImage );
200 ui->controlsDock->setVisible( hasImage );
201 ui->logoView->setVisible( !hasImage );
202 ui->imageViewer->setVisible( hasImage );
203 ui->menuLayout->setEnabled( hasImage );
204 ui->menuOverlay->setEnabled( hasImage );
205 ui->actionRemove_current_image->setEnabled( hasImage );
206 ui->actionAddLabel->setEnabled( hasImage );
208 ui->actionRemove_current_label->setEnabled(
false );
209 ui->dockWidgetHistogram->hide( );
211 ui->actionShow_controls_dock->setEnabled( hasImage );
212 ui->actionShow_images_dock->setEnabled( hasImage );
213 currentImageChanged( );
216 void MainWindow::on_actionOpen_image_triggered( ) {
217 QString fileName = getFileDialog( );
218 if( fileName.isEmpty( ) ) {
221 if( !loadFile( fileName ) ) {
222 QMessageBox::warning(
this,
"Warning", tr(
"Could not open file!" ) );
227 QString MainWindow::getFileDialog( ) {
228 return( QFileDialog::getOpenFileName(
229 this, tr(
"Open" ), defaultFolder,
230 tr(
"All images (*.pbm *.pbm.gz *.pgm *.pgm.gz *.ppm *.ppm.gz *.dcm " 231 "*.dcm.gz *.nii *.nii.gz *.scn *.scn.gz);; PBM images (*.pbm *.pbm.gz);; PGM images " 232 "(*.pgm *.pgm.gz);; PPM images (*.ppm *.ppm.gz);; DICOM images " 233 "(*.dcm *.dcm.gz);; NIfTI images (*.nii *.nii.gz);; SCN Files (*.scn *.scn.gz);; All files (*)" ) ) );
236 bool MainWindow::loadFile( QString filename ) {
237 COMMENT(
"Loading file: " << filename.toStdString( ), 0 );
238 controller->
clear( );
239 return( controller->
addImage( filename ) );
242 bool MainWindow::loadFolder( QString dirname ) {
243 QDir folder( dirname );
244 COMMENT(
"Reding folder: " << folder.absolutePath( ).toStdString( ) <<
".", 1 );
245 QFileInfoList list = folder.entryInfoList( QDir::NoDotAndDotDot | QDir::Files, QDir::DirsFirst | QDir::Name );
250 QProgressDialog progress(
"Reading files...",
"Abort", 0, list.size( ), this );
251 progress.setWindowModality( Qt::WindowModal );
252 int size = list.size( );
253 for(
int i = 0; i <
size; ++i ) {
254 progress.setValue( i );
255 if( progress.wasCanceled( ) ) {
258 QFileInfo fileInfo = list.at( i );
259 if( fileInfo.isFile( ) and checkExtension( fileInfo.completeSuffix( ).toLower( ) ) ) {
260 QString fileName = fileInfo.absoluteFilePath( );
261 if( controller->
addImage( fileName ) ) {
266 statusBar( )->showMessage( tr(
"Could not open file!" ), 2000 );
271 progress.setValue( list.size( ) );
276 bool MainWindow::checkExtension(
const QString &
suffix ) {
277 if( suffix ==
"scn" or suffix ==
"scn.gz" or suffix ==
"img" or suffix ==
"img.gz" or suffix ==
"hdr" or
278 suffix ==
"hdr.gz" or suffix ==
"nii" or suffix ==
"nii.gz" or suffix ==
"pnm" or suffix ==
"pnm.gz" or
279 suffix ==
"pgm" or suffix ==
"pgm.gz" or suffix ==
"pbm" or suffix ==
"pbm.gz" or suffix ==
"dcm" or
280 suffix ==
"dcm.gz" ) {
288 void MainWindow::readSettings( ) {
289 COMMENT(
"Reading QSettings", 1 );
292 settings.beginGroup(
"MainWindow" );
293 defaultFolder = settings.value(
"defaultFolder" ).toString( );
294 if( defaultFolder.isEmpty( ) ) {
295 defaultFolder = QDir::homePath( );
300 COMMENT(
"Command Line Open with " << argc <<
" arguments:", 0 );
301 if( ( argc == 3 ) && ( QString( argv[ 1 ] ) ==
"-d" ) ) {
302 loadDicomdir( QString( argv[ 2 ] ) );
306 for(
int img = 1; img < argc; ++img ) {
307 QString fileName( argv[ img ] );
308 file.setFile( fileName );
309 COMMENT(
"\tArgument[" << img <<
"] = " << fileName.toStdString( ), 0 );
310 if( file.exists( ) ) {
311 if( file.isFile( ) ) {
312 controller->
addImage( file.absoluteFilePath( ) );
314 else if( file.isDir( ) ) {
315 loadFolder( file.absoluteFilePath( ) );
319 BIAL_WARNING(
"FILE DOES NOT EXISTS! : " << file.absolutePath( ).toStdString( ) );
325 void MainWindow::on_actionQuit_triggered( ) {
329 void MainWindow::openRecentFile( ) {
330 QAction *action = qobject_cast< QAction* >( sender( ) );
332 QString fileName = action->data( ).toString( );
333 loadFile( fileName );
337 void MainWindow::updateRecentFileActions( ) {
339 QStringList files = settings.value(
"recentFileList" ).toStringList( );
342 if( numRecentFiles > 0 ) {
343 ui->menuRecent_files->setEnabled(
true );
345 for(
int i = 0; i < numRecentFiles; ++i ) {
346 QString text = QString(
"&%1 %2" ).arg( i + 1 ).arg( QFileInfo( files[ i ] ).fileName( ) );
347 recentFileActs[ i ]->setText( text );
348 recentFileActs[ i ]->setData( files[ i ] );
349 recentFileActs[ i ]->setVisible(
true );
352 recentFileActs[ i ]->setVisible(
false );
356 void MainWindow::createActions( ) {
358 recentFileActs[ i ] =
new QAction(
this );
359 recentFileActs[ i ]->setVisible(
false );
360 connect( recentFileActs[ i ], &QAction::triggered,
this, &MainWindow::openRecentFile );
361 ui->menuRecent_files->addAction( recentFileActs[ i ] );
363 updateRecentFileActions( );
365 ui->menuRecent_files->addAction( recentFileActs[ i ] );
369 void MainWindow::loadQss( ) {
370 QFile
file(
":/qss/stylesheet.qss" );
371 file.open( QFile::ReadOnly );
372 QString StyleSheet = QLatin1String( file.readAll( ) );
373 setStyleSheet( StyleSheet );
376 bool MainWindow::loadDicomdir( QString dicomFName ) {
377 COMMENT(
"Loading DicomDir file", 1 );
380 if( !dicomdir.
open( dicomFName ) ) {
381 statusBar( )->showMessage( tr(
"Could not open dicomdir" ), 2000 );
384 const QStringList files = dicomdir.
getImages( );
385 if( files.size( ) > 0 ) {
386 controller->
clear( );
387 QProgressDialog progress( tr(
"Reading dicomdir files..." ), tr(
"Abort" ), 0, files.size( ), this );
388 progress.setWindowModality( Qt::WindowModal );
389 for(
int i = 0,
size = files.size( ); i <
size; ++i ) {
390 progress.setValue( i );
391 if( progress.wasCanceled( ) ) {
394 controller->
addImage( files[ i ].trimmed( ) );
396 progress.setValue( files.size( ) );
397 if( controller->
size( ) < 1 ) {
398 statusBar( )->showMessage( tr(
"Could not load any dicomdir images" ), 2000 );
403 statusBar( )->showMessage( tr(
"Empty dicomdir!" ), 2000 );
409 void MainWindow::on_actionAddLabel_triggered( ) {
410 controller->
addLabel( getFileDialog( ) );
413 void MainWindow::on_actionOpen_folder_triggered( ) {
414 QString folderString = QFileDialog::getExistingDirectory(
this, tr(
"Open folder" ), defaultFolder );
415 COMMENT(
"Opening folder: \"" << folderString.toStdString( ) <<
"\"", 1 )
416 if( !folderString.isEmpty( ) ) {
417 controller->
clear( );
418 if( !loadFolder( folderString ) ) {
420 QMessageBox::warning(
this,
"Warning", tr(
"Could not read folder!" ) );
425 void MainWindow::on_actionOpen_DicomDir_triggered( ) {
426 QString fileName = QFileDialog::getOpenFileName(
this, tr(
"Open" ), defaultFolder, tr(
"*" ) );
427 loadDicomdir( fileName );
430 void MainWindow::on_actionAdd_image_triggered( ) {
431 controller->
addImage( getFileDialog( ) );
434 void MainWindow::on_actionRemove_current_image_triggered( ) {
438 void MainWindow::on_actionSelect_default_folder_triggered( ) {
439 QString temp = QFileDialog::getExistingDirectory(
this, tr(
"Select default folder" ), QDir::homePath( ) );
440 if( !temp.isEmpty( ) ) {
441 defaultFolder = temp;
443 settings.beginGroup(
"MainWindow" );
444 settings.setValue(
"defaultFolder", defaultFolder );
445 settings.endGroup( );
449 void MainWindow::on_actionRemove_current_label_triggered( ) {
453 void MainWindow::updateIntensity( QPointF scnPos, Qt::MouseButtons buttons,
size_t axis ) {
456 if( img !=
nullptr ) {
465 if( bial_img.ValidCoordinate( pt.
x, pt.
y, pt.
z ) ) {
466 int color = bial_img( pt.
x, pt.
y, pt.
z );
467 msg = QString(
"Axis %1 : (%2, %3, %4) = %5/%6" )
477 if( bial_img.ValidCoordinate( pt.
x, pt.
y ) ) {
478 int color = bial_img( pt.
x, pt.
y );
479 msg = QString(
"(%1, %2) = %3/%4" ).arg( (
int ) pt.
x ).arg( (
int ) pt.
y ).arg( color ).arg( max );
488 if( bial_img.ValidCoordinate( pt.
x, pt.
y, pt.
z ) ) {
489 int color =
static_cast< int >( bial_img( pt.
x, pt.
y, pt.
z ) );
490 msg = QString(
"Axis %1 : (%2, %3, %4) = %5/%6" )
500 if( bial_img.ValidCoordinate( pt.
x, pt.
y ) ) {
501 int color =
static_cast< int >( bial_img( pt.
x, pt.
y ) );
502 msg = QString(
"(%1, %2) = %3/%4" ).arg( (
int ) pt.
x ).arg( (
int ) pt.
y ).arg( color ).arg( max );
511 if( bial_img.ValidCoordinate( pt.
x, pt.
y, pt.
z ) ) {
512 int r =
static_cast< int >( bial_img( pt.
x, pt.
y, pt.
z )[ 0 ] );
513 int g =
static_cast< int >( bial_img( pt.
x, pt.
y, pt.
z )[ 1 ] );
514 int b =
static_cast< int >( bial_img( pt.
x, pt.
y, pt.
z )[ 2 ] );
515 msg = QString(
"Axis %1 : (%2, %3, %4) = %5/%6" )
527 if( bial_img.ValidCoordinate( pt.
x, pt.
y ) ) {
528 int r =
static_cast< int >( bial_img( pt.
x, pt.
y )[ 0 ] );
529 int g =
static_cast< int >( bial_img( pt.
x, pt.
y )[ 1 ] );
530 int b =
static_cast< int >( bial_img( pt.
x, pt.
y )[ 2 ] );
531 msg = QString(
"(%1, %2) = (%3, %4, %5)/%6" ).arg( (
int ) pt.
x ).arg( (
int ) pt.
y ).arg( r ).arg( g ).arg(
541 if( bial_img.ValidCoordinate( pt.
x, pt.
y, pt.
z ) ) {
542 int r =
static_cast< int >( bial_img( pt.
x, pt.
y, pt.
z )[ 0 ] );
543 int g =
static_cast< int >( bial_img( pt.
x, pt.
y, pt.
z )[ 1 ] );
544 int b =
static_cast< int >( bial_img( pt.
x, pt.
y, pt.
z )[ 2 ] );
545 msg = QString(
"Axis %1 : (%2, %3, %4) = %5/%6" )
557 if( bial_img.ValidCoordinate( pt.
x, pt.
y ) ) {
558 int r =
static_cast< int >( bial_img( pt.
x, pt.
y )[ 0 ] );
559 int g =
static_cast< int >( bial_img( pt.
x, pt.
y )[ 1 ] );
560 int b =
static_cast< int >( bial_img( pt.
x, pt.
y )[ 2 ] );
561 msg = QString(
"(%1, %2) = (%3, %4, %5)/%6" ).arg( (
int ) pt.
x ).arg( (
int ) pt.
y ).arg( r ).arg( g ).arg(
567 std::string msg(
BIAL_ERROR(
"Accessing non-initialized multi-image." ) );
568 throw( std::runtime_error( msg ) );
570 ui->statusBar->showMessage( msg, 10000 );
574 void MainWindow::on_actionAxial_triggered( ) {
579 void MainWindow::on_actionCoronal_triggered( ) {
584 void MainWindow::on_actionSagittal_triggered( ) {
589 void MainWindow::on_action3_Views_triggered( ) {
593 void MainWindow::on_action4_Views_triggered( ) {
597 void MainWindow::on_actionVertical_triggered( ) {
601 void MainWindow::on_actionHorizontal_triggered( ) {
605 void MainWindow::on_actionGrid_triggered( ) {
609 void MainWindow::on_actionWhitePen_triggered( ) {
613 void MainWindow::on_actionRedPen_triggered( ) {
617 void MainWindow::on_actionBluePen_triggered( ) {
621 void MainWindow::on_actionGreenPen_triggered( ) {
625 void MainWindow::on_actionBlackPen_triggered( ) {
629 void MainWindow::on_actionToggle_overlay_triggered( ) {
635 void MainWindow::on_actionDefaultTool_triggered( ) {
639 for(
int tool = 0; tool < img->
tools.size( ); ++tool ) {
650 ui->segmentationWidget->setTool( img->
currentTool( ) );
655 void MainWindow::on_actionSegmentationTool_triggered( ) {
659 for(
int tool = 0; tool < img->
tools.size( ); ++tool ) {
669 ui->segmentationWidget->setTool( img->
currentTool( ) );
670 ui->dockWidgetSegmentation->show( );
675 void MainWindow::on_actionEnglish_triggered( ) {
676 QTranslator translator;
677 if( not translator.load(
":/translations/bial_en.qm" ) ) {
678 QMessageBox::critical(
this,
"Erro",
"Erro carregando tradução!" );
681 qApp->installTranslator( &translator );
682 ui->retranslateUi(
this );
685 void MainWindow::on_actionPortuguese_triggered( ) {
686 QTranslator translator;
687 if( not translator.load(
":/translations/bial_br.qm" ) ) {
688 QMessageBox::critical(
this,
"Erro",
"Erro carregando tradução!" );
691 qApp->installTranslator( &translator );
692 ui->retranslateUi(
this );
695 void MainWindow::on_actionFunctional_Tool_triggered( ) {
698 ui->logoView->hide( );
708 void MainWindow::on_actionChange_default_parameters_triggered( ) {
void mouseClicked(QPointF pt, Qt::MouseButtons buttons, size_t axis)
QCPGraph * addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0)
double z
Point position in z.
bool open(const QString &filename)
int max()
max is the maximum integer intensity of the input image. Used for int and Color images.
void mouseReleased(QPointF pt, Qt::MouseButtons buttons, size_t axis)
Tool * currentTool()
currentTool returns the current Tool.
void recentFilesUpdated()
recentFilesUpdated
each data point is represented by a line parallel to the value axis, which reaches from the data poin...
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes) ...
const Bial::Signal & getHistogram() const
getHistogram returns the image histogram.
#define BIAL_ERROR(exp)
Use BIAL_ERROR to compose runtime error messages. Note that ERROR generates a string, instead of a stream, because it is better to throw an exception, rather than exiting the program. This way, the exception may be threated by a higher level program, like an user IDE.
void commandLineOpen(int argc, char *argv[])
void setRangeZoom(Qt::Orientations orientations)
Signal handeling declaration.
DisplayFormat * currentFormat()
currentFormat returns the modality of current image.
void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical)
Bial::MultiImageType getImageType() const
getImageType returns image type among int, float, Color and RealColor.
The GuiImage class is a bridge to the Bial::Image data structure to the QImage data structure...
void setInteraction(const QCP::Interaction &interaction, bool enabled=true)
The Point3D class is a Geometric representation of a point in 3D space. A point is a zerodimension...
Bial::Point3D getPosition(QPointF pos, size_t view)
getPosition transforms the scene position to the input image coordinates.
void dropImage(const QString &filePath)
void setRangeDrag(Qt::Orientations orientations)
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpHint)
size_t size() const
Returns the number of bins.
The central class of the library. This is the QWidget which displays the plot and interacts with the ...
void mouseDragged(QPointF pt, Qt::MouseButtons buttons, size_t axis)
bool removeCurrentLabel()
removeCurrentLabel removes the current label from current image.
void setCurrentToolPos(const size_t ¤tToolPos)
void setLineStyle(LineStyle ls)
Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false)
void removeCurrentImage()
removeCurrentImage removes the current image from vector.
double y
Point position in y.
The Controller class is one of the most important classes of the User Interface, and is responsible t...
float fmax()
fmax is the maximum float intensity of the input image. Used for float and RealColor images...
unsigned char suffix[65536]
QCPAxisRect * axisRect(int index=0) const
MainWindow(QWidget *parent=0)
void imageUpdated()
imageUpdated is called each time a internal property is updated, after that the image views are updat...
Bial::Image< int > & getIntImage() const
get*Image
void clear()
clear Clears the image vector, and resets thumbnails.
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom, QCPAxisRect::setRangeZoomAxes)
GuiImage * currentImage()
currentImage
void currentImageChanged()
This signal is emmited every time the current image changes.
QCPGraph * graph(int index) const
bool addLabel(QString label)
addLabel Adds a label to the current image.
void setThumbsWidget(ThumbsWidget *thumbsWidget)
setThumbsWidget setThumbsWidget sets the pointer to the thumbnails dock.
void setData(QCPDataMap *data, bool copy=false)
QVector< Tool * > tools
tools is a vector containing the image tools.
Bial::Image< Bial::Color > & getClrImage() const
const double * Data() const
Returns signal data.
#define BIAL_WARNING(exp)
Use BIAL_WARNING to print a message to the output stream warn the user that something bad may have ha...
void setLabel(const QString &str)
void containerUpdated()
This signal is emmited avery time the m_images vector is updated.
Bial::Image< float > & getFltImage() const
Bial::Image< Bial::RealColor > & getRclImage() const
void imageUpdated()
This signal is emmited every time the current image is updated.
size_t getDims() const
getDims
void dropFolder(const QString &folderPath)
bool addImage(QString fname)
addImage Adds an image to vector m_images.