CStoreQtProgress.cxx
/*=========================================================================
Program: GDCM (Grassroots DICOM). A DICOM library
Copyright (c) 2006-2011 Mathieu Malaterre
All rights reserved.
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*
* This small example show how one can use the virtual function
* mechanism of the SimpleSubjectWatcher class to redirect progress
* report to a custom Qt classes
*
* http://doc.qt.nokia.com/latest/qprogressdialog.html
*
* Usage:
* CStoreQtProgress dicom.example.com 11112 gdcmData/MR_Spectroscopy_SIEMENS_OF.dcm
*
*/
#include "gdcmServiceClassUser.h"
#include "gdcmSimpleSubjectWatcher.h"
#include "gdcmProgressEvent.h"
#include "gdcmDirectory.h"
#include "gdcmPresentationContextGenerator.h"
#include <QApplication>
#include <QProgressDialog>
#include <QVBoxLayout>
namespace gdcm {
/*
* This class is a little more complicated than what this example demonstrate
* This watcher is capable of handling nested progress. Since the Progress
* grows from [0 to 1] on a per file basis and we only have one instance of a
* watcher per association, we need some calculation to compute the global
* (total) progress
* In fact we simply divide the per-file progress by the number of files.
*
* This QtWatcher class will then update the progress bar according to the
* progress.
*/
class MyQtWatcher : public SimpleSubjectWatcher
{
size_t nfiles;
double progress;
size_t index;
double refprogress;
QWidget* win;
QProgressDialog* qtprogress;
public:
MyQtWatcher(Subject * s, const char *comment = "", QWidget *w = NULL, QProgressDialog* p = NULL, size_t n = 1):
SimpleSubjectWatcher(s,comment),nfiles(n),progress(0),index(0),refprogress(0),win(w),qtprogress(p){}
void ShowIteration()
{
index++;
assert( index <= nfiles );
// update refprogess (we are moving to the next file)
refprogress = progress;
}
void ShowProgress(Subject *, const Event &evt)
{
// Retrieve the ProgressEvent:
const ProgressEvent &pe = dynamic_cast<const ProgressEvent&>(evt);
// compute global progress:
progress = refprogress + (1. / (double)nfiles ) * pe.GetProgress();
// Print Global and local progress to stdout:
std::cout << "Global Progress: " << progress << " per file progress " << pe.GetProgress() << std::endl;
//set progress value in the QtProgress bar
int i = (int)(progress * 100 + 0.5); // round to next int
qtprogress->setValue(i);
win->show();
}
virtual void ShowDataSet(Subject *caller, const Event &evt)
{
(void)caller;
(void)evt;
}
};
} // end namespace gdcm
int main(int argc, char *argv[])
{
if( argc < 4 )
{
std::cerr << argv[0] << " remote_server port filename" << std::endl;
return 1;
}
QApplication a(argc, argv);
std::ostringstream error_log;
gdcm::Trace::SetErrorStream( error_log );
const char *remote = argv[1];
int portno = atoi(argv[2]);
const char *filename = argv[3];
QVBoxLayout* layout = new QVBoxLayout;
QWidget* win = new QWidget;
QProgressDialog* progress = new QProgressDialog("Sending data...", "Cancel", 0, 100);
progress->setWindowModality(Qt::WindowModal);
layout->addWidget(progress,Qt::AlignCenter);
win->setLayout(layout);
gdcm::SmartPointer<gdcm::ServiceClassUser> scup = new gdcm::ServiceClassUser;
gdcm::ServiceClassUser &scu = *scup;
//gdcm::SimpleSubjectWatcher w( &scu, "TestServiceClassUser" );
// let's use a more complicated progress reported in this example
gdcm::MyQtWatcher w( &scu, "QtWatcher", win, progress );
scu.SetHostname( remote );
scu.SetPort( (uint16_t)portno );
scu.SetTimeout( 1000 );
scu.SetCalledAETitle( "GDCM_STORE" );
if( !scu.InitializeConnection() )
{
std::cerr << "Could not InitializeConnection" << std::endl;
return 1;
}
gdcm::Directory::FilenamesType filenames;
filenames.push_back( filename );
// setup the PC(s) based on the filenames:
gdcm::PresentationContextGenerator generator;
if( !generator.GenerateFromFilenames(filenames) )
{
std::cerr << "Could not GenerateFromFilenames" << std::endl;
return 1;
}
// Setup PresentationContext(s)
scu.SetPresentationContexts( generator.GetPresentationContexts() );
// Start ASSOCIATION
if( !scu.StartAssociation() )
{
std::cerr << "Could not Start" << std::endl;
return 1;
}
// Send C-STORE
if( !scu.SendStore( filename ) )
{
std::cerr << "Could not Store" << std::endl;
std::cerr << "Error log is:" << std::endl;
std::cerr << error_log.str() << std::endl;
return 1;
}
// Stop ASSOCIATION
if( !scu.StopAssociation() )
{
std::cerr << "Could not Stop" << std::endl;
return 1;
}
win->show();
return a.exec();
}
gdcm::Directory::FilenamesType
std::vector< FilenameType > FilenamesType
Definition gdcmDirectory.h:49
gdcm::PresentationContextGenerator
PresentationContextGenerator.
Definition gdcmPresentationContextGenerator.h:54
gdcm::PresentationContextGenerator::GenerateFromFilenames
bool GenerateFromFilenames(const Directory::FilenamesType &files)
gdcm::PresentationContextGenerator::GetPresentationContexts
PresentationContextArrayType const & GetPresentationContexts()
Definition gdcmPresentationContextGenerator.h:83
gdcm::ServiceClassUser
ServiceClassUser.
Definition gdcmServiceClassUser.h:37
gdcm::ServiceClassUser::SetTimeout
void SetTimeout(double t)
set/get Timeout
gdcm::ServiceClassUser::SetPresentationContexts
void SetPresentationContexts(std::vector< PresentationContext > const &pcs)
Set the Presentation Context used for the Association.
gdcm::ServiceClassUser::SendStore
bool SendStore(const char *filename)
Execute a C-STORE on file on disk, named filename.
gdcm::ServiceClassUser::StopAssociation
bool StopAssociation()
Stop the running association.
gdcm::ServiceClassUser::SetHostname
void SetHostname(const char *hostname)
Set the name of the called hostname (hostname or IP address).
gdcm::ServiceClassUser::SetPort
void SetPort(uint16_t port)
Set port of remote host (called application).
gdcm::ServiceClassUser::StartAssociation
bool StartAssociation()
Start the association. Need to call SetPresentationContexts before.
gdcm::ServiceClassUser::InitializeConnection
bool InitializeConnection()
gdcm::ServiceClassUser::SetCalledAETitle
void SetCalledAETitle(const char *aetitle)
set called ae title
gdcm::SmartPointer
Class for Smart Pointer.
Definition gdcmSmartPointer.h:40
gdcm::Trace::SetErrorStream
static void SetErrorStream(std::ostream &os)
Explicitly set the stream which receive Error messages:
gdcmDirectory.h
gdcmPresentationContextGenerator.h
gdcmProgressEvent.h
gdcmServiceClassUser.h
gdcmSimpleSubjectWatcher.h
gdcm
Definition gdcmASN1.h:21