QtDcmServersDicomSettingsWidget.cpp
Go to the documentation of this file.
1 /*
2  QtDcm is a C++ Qt based library for communication and conversion of Dicom images.
3  Copyright (C) 2011 Alexandre Abadie <Alexandre.Abadie@univ-rennes1.fr>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 
20 
22 
23 #include <dcmtk/dcmnet/dimse.h>
24 
25 #include <QMessageBox>
26 #include <QTcpSocket>
27 
28 #include <QtDcmPreferences.h>
29 #include <QtDcmServer.h>
30 
32  : QWidget ( parent )
33 {
34  this->setupUi ( this );
35 
36  treeWidget->setColumnWidth ( 1, 100 );
37  treeWidget->setColumnWidth ( 2, 100 );
38  treeWidget->setColumnWidth ( 3, 150 );
39 
40  serverNameEdit->setEnabled ( false );
41  serverAetitleEdit->setEnabled ( false );
42  serverPortEdit->setEnabled ( false );
43  serverHostnameEdit->setEnabled ( false );
44  removeButton->setEnabled ( false );
45  echoButton->setEnabled ( false );
46 
47 
48  this->initConnections();
49 }
50 
52 {
53 }
54 
55 void QtDcmServersDicomSettingsWidget::initConnections()
56 {
57  QObject::connect ( treeWidget, &QTreeWidget::currentItemChanged,
59  QObject::connect ( serverNameEdit, &QLineEdit::textChanged,
61  QObject::connect ( serverHostnameEdit, &QLineEdit::textChanged,
63  QObject::connect ( serverAetitleEdit, &QLineEdit::textChanged,
65  QObject::connect ( serverPortEdit, &QLineEdit::textChanged,
67  QObject::connect ( addButton, &QPushButton::clicked,
69  QObject::connect ( removeButton, &QPushButton::clicked,
71  QObject::connect ( echoButton, &QPushButton::clicked,
73 }
74 
76 {
78  treeWidget->clear();
79 
80  for ( int i = 0; i < prefs->servers().size(); i++ ) {
81  QTreeWidgetItem * item = new QTreeWidgetItem ( treeWidget );
82  item->setText ( 0, prefs->servers().at ( i ).name() );
83  item->setData ( 0, 1, QVariant ( prefs->servers().at ( i ).name() ) );
84 
85  item->setText ( 1, prefs->servers().at ( i ).aetitle() );
86  item->setData ( 1, 1, QVariant ( prefs->servers().at ( i ).aetitle() ) );
87 
88  item->setText ( 2, prefs->servers().at ( i ).port() );
89  item->setData ( 2, 1, QVariant ( prefs->servers().at ( i ).port() ) );
90 
91  item->setText ( 3, prefs->servers().at ( i ).address() );
92  item->setData ( 3, 1, QVariant ( prefs->servers().at ( i ).address() ) );
93 
94  item->setData ( 4, 1, QVariant ( i ) );
95  }
96 }
97 
99 {
101  QTreeWidgetItem * root = treeWidget->invisibleRootItem();
102 
103  QList<QtDcmServer> servers;
104  for (int i = 0; i < root->childCount() ; i++) {
105  QtDcmServer server;
106  server.setName(root->child ( i )->data ( 0, 1 ).toString());
107  server.setAetitle(root->child ( i )->data ( 1, 1 ).toString());
108  server.setPort(root->child ( i )->data ( 2, 1 ).toString());
109  server.setAddress(root->child ( i )->data ( 3, 1 ).toString());
110  servers << server;
111  }
112 
113  prefs->setServers(servers);
114 }
115 
117 {
119  QTreeWidgetItem * item = new QTreeWidgetItem ( treeWidget );
120  QtDcmServer server;
121  server.setName("Name");
122  server.setAetitle("AETITLE");
123  server.setPort("2010");
124  server.setAddress("hostname");
125 
126  item->setText ( 0, server.name() );
127  item->setData ( 0, 1, QVariant ( server.name() ) );
128 
129  item->setText ( 1, server.aetitle() );
130  item->setData ( 1, 1, QVariant ( server.aetitle() ) );
131 
132  item->setText ( 2, server.port() );
133  item->setData ( 2, 1, QVariant ( server.port().toInt() ) );
134 
135  item->setText ( 3, server.address() );
136  item->setData ( 3, 1, QVariant ( server.address() ) );
137 
138  item->setData ( 4, 1, QVariant ( prefs->servers().size() - 1 ) );
139 
140  prefs->addServer(server);
141 }
142 
144 {
145  QTreeWidgetItem * root = treeWidget->invisibleRootItem();
146  if (!treeWidget->currentItem()) {
147  return;
148  }
149 
150  const int index = root->indexOfChild ( treeWidget->currentItem());
151  QTreeWidgetItem * item = treeWidget->currentItem();
152  root->removeChild(item);
153  delete item;
154 
156 
157  if ( root->childCount() == 0 ) {
158  echoButton->setEnabled ( false );
159  removeButton->setEnabled ( false );
160  }
161 }
162 
163 void QtDcmServersDicomSettingsWidget::itemSelected ( QTreeWidgetItem* current, QTreeWidgetItem* previous )
164 {
165  echoButton->setEnabled ( true );
166  removeButton->setEnabled ( true );
167  serverNameEdit->setEnabled ( true );
168  serverAetitleEdit->setEnabled ( true );
169  serverPortEdit->setEnabled ( true );
170  serverHostnameEdit->setEnabled ( true );
171  serverNameEdit->setText ( current->data ( 0, 1 ).toString() );
172  serverAetitleEdit->setText ( current->data ( 1, 1 ).toString() );
173  serverPortEdit->setText ( current->data ( 2, 1 ).toString() );
174  serverHostnameEdit->setText ( current->data ( 3, 1 ).toString() );
175 }
176 
178 {
179  QRegExp rexp ( "[A-Z0-9._-]{1,50}" );
180  QRegExpValidator * valid = new QRegExpValidator ( rexp, this );
181  serverAetitleEdit->setValidator ( valid );
182  treeWidget->currentItem()->setText ( 1, text );
183  treeWidget->currentItem()->setData ( 1, 1, QVariant ( text ) );
184 }
185 
187 {
188  treeWidget->currentItem()->setText ( 3, text );
189  treeWidget->currentItem()->setData ( 3, 1, QVariant ( text ) );
190 }
191 
193 {
194  treeWidget->currentItem()->setText ( 0, text );
195  treeWidget->currentItem()->setData ( 0, 1, QVariant ( text ) );
196 }
197 
199 {
200  QIntValidator * valid = new QIntValidator ( 1000, 100000, this );
201  serverPortEdit->setValidator ( valid );
202  treeWidget->currentItem()->setText ( 2, text );
203  treeWidget->currentItem()->setData ( 2, 1, QVariant ( text ) );
204 }
205 
207 {
208  if ( !treeWidget->currentItem() ) {
209  return;
210  }
211 
213 
214  const QString aet = prefs->aetitle();
215  const QString serverAet = treeWidget->currentItem()->data ( 1, 1 ).toString();
216  const QString hostname = prefs->hostname();
217  const QString serverHostname = treeWidget->currentItem()->data ( 3, 1 ).toString();
218  const QString serverPort = treeWidget->currentItem()->data ( 2, 1 ).toString();
219 
220  T_ASC_Network *net = 0; // network struct, contains DICOM upper layer FSM etc.
221 
222  OFCondition cond = ASC_initializeNetwork ( NET_REQUESTOR, 0, 30 /* timeout */, &net );
223  if ( cond != EC_Normal ) {
224  QMessageBox msgBox( QApplication::activeWindow() );
225  msgBox.setIcon ( QMessageBox::Critical );
226  msgBox.setText ( "Cannot initialize network" );
227  msgBox.exec();
228 
229  ASC_dropNetwork ( &net );
230 
231  return;
232  }
233 
234  QTcpSocket * socket = new QTcpSocket(this);
235  socket->connectToHost(serverHostname, serverPort.toInt());
236  if (!socket->waitForConnected(1000)) {
237  QMessageBox msgBox( QApplication::activeWindow() );
238  msgBox.setIcon ( QMessageBox::Information );
239  msgBox.setText ( "Cannot connect to server " + serverHostname + " on port " + serverPort + " !" );
240  msgBox.exec();
241 
242  ASC_dropNetwork ( &net );
243 
244  return;
245  }
246 
247  socket->disconnectFromHost();
248  delete socket;
249 
250  T_ASC_Parameters *params; // parameters of association request
251 
252  cond = ASC_createAssociationParameters ( &params, ASC_DEFAULTMAXPDU );
253 
254  // set calling and called AE titles
255  cond = ASC_setAPTitles ( params, aet.toUtf8().data(), serverAet.toUtf8().data(), NULL );
256 
257  // the DICOM server accepts connections at server.nowhere.com port 104
258  cond = ASC_setPresentationAddresses ( params, hostname.toUtf8().data(), QString ( serverHostname + ":" + serverPort ).toLatin1().data() );
259 
260  // list of transfer syntaxes, only a single entry here
261  const char* ts[] = { UID_LittleEndianImplicitTransferSyntax };
262 
263  // add presentation context to association request
264  cond = ASC_addPresentationContext ( params, 1, UID_VerificationSOPClass, ts, 1 );
265 
266  // request DICOM association
267  T_ASC_Association *assoc = 0;
268 
269  if ( ASC_requestAssociation ( net, params, &assoc ).good() ) {
270  if ( ASC_countAcceptedPresentationContexts ( params ) == 1 ) {
271  // the remote SCP has accepted the Verification Service Class
272  DIC_US id = assoc->nextMsgID++; // generate next message ID
273  DIC_US status; // DIMSE status of C-ECHO-RSP will be stored here
274  DcmDataset *sd = NULL; // status detail will be stored here
275  // send C-ECHO-RQ and handle response
276  DIMSE_echoUser ( assoc, id, DIMSE_BLOCKING, 0, &status, &sd );
277  delete sd; // we don't care about status detail
278 
279  QMessageBox msgBox( QApplication::activeWindow() );
280  msgBox.setIcon ( QMessageBox::Information );
281  msgBox.setText ( "Echo request successful !" );
282  msgBox.exec();
283  }
284  else {
285  QMessageBox msgBox( QApplication::activeWindow() );
286  msgBox.setIcon ( QMessageBox::Critical );
287  msgBox.setText ( "Wrong presentation context, echo request failed" );
288  msgBox.exec();
289  }
290  }
291  else {
292  QMessageBox msgBox( QApplication::activeWindow() );
293  msgBox.setIcon ( QMessageBox::Critical );
294  msgBox.setText ( "Wrong dicom association, echo request failed" );
295  msgBox.exec();
296  }
297 
298  ASC_releaseAssociation ( assoc ); // release association
299  ASC_destroyAssociation ( &assoc ); // delete assoc structure
300  ASC_dropNetwork ( &net ); // delete net structure
301 
302  net = 0;
303  assoc = 0;
304 }
QString port() const
PACS server port getter (QtDcm only ports between 1000 and 100000)
Definition: QtDcmServer.h:69
void setAetitle(QString _aetitle)
PACS AETitle setter.
Definition: QtDcmServer.h:89
static QtDcmPreferences * instance()
void setAddress(QString _server)
PACS server hostname setter.
Definition: QtDcmServer.h:119
QString aetitle() const
PACS AETitle getter.
Definition: QtDcmServer.h:49
QString name() const
Description name getter.
Definition: QtDcmServer.h:59
QList< QtDcmServer > servers() const
QtDcm server list getter.
void setPort(QString port)
PACS server port setter (QtDcm only ports between 1000 and 100000)
Definition: QtDcmServer.h:109
QString hostname() const
void setServers(const QList< QtDcmServer > &servers)
QtDcm server list setter.
QString aetitle() const
QtDcm local AETitle getter.
void itemSelected(QTreeWidgetItem *current, QTreeWidgetItem *previous)
void setName(QString _name)
PACS Name setter.
Definition: QtDcmServer.h:99
QString address() const
PACS server hostname getter.
Definition: QtDcmServer.h:79
This class is a representation of a Dicom PACS server.
Definition: QtDcmServer.h:30
void addServer(const QtDcmServer &server)
Add server to the QList.
Class that manages the settings of QtDcm.
void removeServer(int index)
Remove server from the QList at position i.