PWV-1: Fixing merging issues

This commit is contained in:
Bruno Alves de Faria authored and Erik Ziegler committed 2016-11-15 08:24:30 +01:00
1 parent 481bf30a14
commit db0602def7
29 files changed
+392 -488

No files matched your search

@@ -79,7 +79,7 @@ class Bounded {
const result = {};
// Check if the element is the window
if (element === window) {
if (!element || element === window) {
const $window = $(window);
const width = $window.outerWidth();
const height = $window.outerHeight();
@@ -8,7 +8,7 @@ $themes['tide'] = {
$uiStateErrorBorder: #993333
$uiStateErrorText: #661111
$uiLightGray: #516873
$uiGrayLight: #516873
$uiGray: #263340
$uiGrayDark: #16202B
$uiGrayDarker: #151A1F
@@ -8,7 +8,7 @@ $themes['tigerlilly'] = {
$uiStateErrorBorder: #CC6666
$uiStateErrorText: #661111
$uiLightGray: #516873
$uiGrayLight: #516873
$uiGray: #263340
$uiGrayDark: #16202B
$uiGrayDarker: #151A1F
@@ -6,6 +6,8 @@ $toolbarHeight = 78px
$toolbarDrawerHeight = 62px
$studiesSidebarMenuWidth = 307px
$lesionsSidebarMenuWidth = 323px
$studyListPadding = 8%
$studyListPaddingMediumScreen = 10px
// Fonts
$logoFontFamily = "Sanchez"
@@ -1,291 +1,291 @@
import { _ } from 'meteor/underscore';
// Uses NodeJS 'net'
// https://nodejs.org/api/net.html
var net = Npm.require('net');
var Socket = net.Socket;
Connection = function(options) {
EventEmitter.call(this);
this.options = Object.assign({
maxPackageSize: C.DEFAULT_MAX_PACKAGE_SIZE,
idle: false,
reconnect: true,
vr: {
split: true
}
}, options);
this.reset();
};
util.inherits(Connection, EventEmitter);
var StoreHandle = function() {
EventEmitter.call(this);
};
util.inherits(StoreHandle, EventEmitter);
Connection.prototype.reset = function() {
this.defaultPeer = null;
this.defaultServer = null;
_.each(this.peers, peerInfo => {
_.each(peerInfo.sockets, socket => socket.emit('close'));
});
this.peers = {};
};
Connection.prototype.addPeer = function(options) {
if (!options.aeTitle || !options.host || !options.port) {
return false;
}
var peer = {
host: options.host,
port: options.port,
sockets: {}
};
this.peers[options.aeTitle] = peer;
if (options.default) {
if (options.server) {
this.defaultServer = options.aeTitle;
} else {
this.defaultPeer = options.aeTitle;
}
}
if (options.server) {
//start listening
peer.server = net.createServer();
peer.server.listen(options.port, options.host, function() {
console.log('listening on %j', this.address());
});
peer.server.on('error', function(err) {
console.log('server error %j', err);
});
peer.server.on('connection', nativeSocket => {
//incoming connections
var socket = new CSocket(nativeSocket, this.options);
this.addSocket(options.aeTitle, socket);
//close server on close socket
socket.on('close', function() {
peer.server.close();
});
});
}
};
Connection.prototype.selectPeer = function(aeTitle) {
if (!aeTitle || !this.peers[aeTitle]) {
throw 'No such peer';
}
return this.peers[aeTitle];
};
Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLength, list) {
var fileNameText = typeof file.file === 'string' ? file.file : 'buffer';
console.log('Sending file ' + fileNameText);
var useContext = socket.getContextByUID(file.context);
var self = this;
PDU.generatePDatas(useContext.id, file.file, maxSend, null, metaLength, function(err, handle) {
if (err) {
console.log('Error while sending file');
return;
}
var processNext = function() {
var next = list.shift();
if (next) {
self._sendFile(socket, sHandle, next, maxSend, metaLength, list);
} else {
socket.release();
}
};
var store = socket.storeInstance(useContext.abstractSyntax, file.uid);
handle.on('pdv', function(pdv) {
socket.sendPData(pdv);
});
handle.on('error', function(err) {
sHandle.emit('file', err, fileNameText);
processNext();
});
store.on('response', function(msg) {
var statusText = msg.getStatus().toString(16);
console.log('STORE reponse with status', statusText);
var error = null;
if (msg.failure()) {
error = new Error(statusText);
}
sHandle.emit('file', error, fileNameText);
processNext();
});
});
};
Connection.prototype.storeInstances = function(fileList) {
var contexts = {};
var read = 0;
var length = fileList.length;
var toSend = [];
var self = this;
var handle = new StoreHandle();
var lastProcessedMetaLength;
fileList.forEach(function(bufferOrFile) {
var fileNameText = typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer';
DicomMessage.readMetaHeader(bufferOrFile, function(err, metaMessage, metaLength) {
read++;
if (err) {
handle.emit('file', err, fileNameText);
if (read === length && toSend.length > 0 && lastProcessedMetaLength) {
sendProcessedFiles(self, contexts, toSend, handle, lastProcessedMetaLength);
}
return;
}
console.log('Dicom file ' + (typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer') + ' found');
lastProcessedMetaLength = metaLength;
var syntax = metaMessage.getValue(0x00020010);
var sopClassUID = metaMessage.getValue(0x00020002);
var instanceUID = metaMessage.getValue(0x00020003);
if (!contexts[sopClassUID]) {
contexts[sopClassUID] = [];
}
if (syntax && contexts[sopClassUID].indexOf(syntax) === -1) {
contexts[sopClassUID].push(syntax);
}
toSend.push({
file: bufferOrFile,
context: sopClassUID,
uid: instanceUID
});
if (read === length) {
sendProcessedFiles(self, contexts, toSend, handle, metaLength);
}
});
});
return handle;
};
// Starts to send dcm files
sendProcessedFiles = function(self, contexts, toSend, handle, metaLength) {
var useContexts = [];
_.each(contexts, (useSyntaxes, context) => {
if (useSyntaxes.length > 0) {
useContexts.push({
context: context,
syntaxes: useSyntaxes
});
} else {
throw 'No syntax specified for context ' + context;
}
});
self.associate({
contexts: useContexts
}, function(ac) {
var maxSend = ac.getMaxSize();
var next = toSend.shift();
self._sendFile(this, handle, next, maxSend, metaLength, toSend);
});
};
Connection.prototype.storeResponse = function(messageId, msg) {
var rq = this.messages[messageId];
if (rq.listener[2]) {
var status = rq.listener[2].call(this, msg);
if (status !== undefined && status !== null && rq.command.store) {
//store ok, ready to send c-store-rsp
var storeSr = rq.command.store;
var replyMessage = storeSr.replyWith(status);
replyMessage.setAffectedSOPInstanceUID(this.lastCommand.getSOPInstanceUID());
replyMessage.setReplyMessageId(this.lastCommand.messageId);
this.sendMessage(replyMessage, null, null, storeSr);
} else {
throw 'Missing store status';
}
}
};
Connection.prototype.allClosed = function() {
var allClosed = true;
for (var i in this.peers) {
if (Object.keys(peers[i].sockets).length > 0) {
allClosed = false;
break;
}
}
return allClosed;
};
Connection.prototype.addSocket = function(hostAE, socket) {
var peerInfo = this.selectPeer(hostAE);
peerInfo.sockets[socket.id] = socket;
socket.on('close', function() {
if (peerInfo.sockets[this.id]) {
delete peerInfo.sockets[this.id];
}
});
};
Connection.prototype.associate = function(options, callback) {
var hostAE = options.hostAE ? options.hostAE : this.defaultPeer;
var sourceAE = options.sourceAE ? options.sourceAE : this.defaultServer;
if (!hostAE || !sourceAE) {
throw 'Peers not provided or no defaults in settings';
}
var peerInfo = this.selectPeer(hostAE);
var nativeSocket = new Socket();
var socket = new CSocket(nativeSocket, this.options);
if (callback) {
socket.once('associated', callback);
}
console.log('Starting Connection...');
socket.setCalledAe(hostAE);
socket.setCallingAE(sourceAE);
console.log(peerInfo);
nativeSocket.connect({
host: peerInfo.host,
port: peerInfo.port
}, () => {
//connected
this.addSocket(hostAE, socket);
if (options.contexts) {
socket.setPresentationContexts(options.contexts);
} else {
throw 'Contexts must be specified';
}
socket.associate();
});
return socket;
};
import { _ } from 'meteor/underscore';
// Uses NodeJS 'net'
// https://nodejs.org/api/net.html
var net = Npm.require('net');
var Socket = net.Socket;
Connection = function(options) {
EventEmitter.call(this);
this.options = Object.assign({
maxPackageSize: C.DEFAULT_MAX_PACKAGE_SIZE,
idle: false,
reconnect: true,
vr: {
split: true
}
}, options);
this.reset();
};
util.inherits(Connection, EventEmitter);
var StoreHandle = function() {
EventEmitter.call(this);
};
util.inherits(StoreHandle, EventEmitter);
Connection.prototype.reset = function() {
this.defaultPeer = null;
this.defaultServer = null;
_.each(this.peers, peerInfo => {
_.each(peerInfo.sockets, socket => socket.emit('close'));
});
this.peers = {};
};
Connection.prototype.addPeer = function(options) {
if (!options.aeTitle || !options.host || !options.port) {
return false;
}
var peer = {
host: options.host,
port: options.port,
sockets: {}
};
this.peers[options.aeTitle] = peer;
if (options.default) {
if (options.server) {
this.defaultServer = options.aeTitle;
} else {
this.defaultPeer = options.aeTitle;
}
}
if (options.server) {
//start listening
peer.server = net.createServer();
peer.server.listen(options.port, options.host, function() {
console.log('listening on %j', this.address());
});
peer.server.on('error', function(err) {
console.log('server error %j', err);
});
peer.server.on('connection', nativeSocket => {
//incoming connections
var socket = new CSocket(nativeSocket, this.options);
this.addSocket(options.aeTitle, socket);
//close server on close socket
socket.on('close', function() {
peer.server.close();
});
});
}
};
Connection.prototype.selectPeer = function(aeTitle) {
if (!aeTitle || !this.peers[aeTitle]) {
throw 'No such peer';
}
return this.peers[aeTitle];
};
Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLength, list) {
var fileNameText = typeof file.file === 'string' ? file.file : 'buffer';
console.log('Sending file ' + fileNameText);
var useContext = socket.getContextByUID(file.context);
var self = this;
PDU.generatePDatas(useContext.id, file.file, maxSend, null, metaLength, function(err, handle) {
if (err) {
console.log('Error while sending file');
return;
}
var processNext = function() {
var next = list.shift();
if (next) {
self._sendFile(socket, sHandle, next, maxSend, metaLength, list);
} else {
socket.release();
}
};
var store = socket.storeInstance(useContext.abstractSyntax, file.uid);
handle.on('pdv', function(pdv) {
socket.sendPData(pdv);
});
handle.on('error', function(err) {
sHandle.emit('file', err, fileNameText);
processNext();
});
store.on('response', function(msg) {
var statusText = msg.getStatus().toString(16);
console.log('STORE reponse with status', statusText);
var error = null;
if (msg.failure()) {
error = new Error(statusText);
}
sHandle.emit('file', error, fileNameText);
processNext();
});
});
};
Connection.prototype.storeInstances = function(fileList) {
var contexts = {};
var read = 0;
var length = fileList.length;
var toSend = [];
var self = this;
var handle = new StoreHandle();
var lastProcessedMetaLength;
fileList.forEach(function(bufferOrFile) {
var fileNameText = typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer';
DicomMessage.readMetaHeader(bufferOrFile, function(err, metaMessage, metaLength) {
read++;
if (err) {
handle.emit('file', err, fileNameText);
if (read === length && toSend.length > 0 && lastProcessedMetaLength) {
sendProcessedFiles(self, contexts, toSend, handle, lastProcessedMetaLength);
}
return;
}
console.log('Dicom file ' + (typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer') + ' found');
lastProcessedMetaLength = metaLength;
var syntax = metaMessage.getValue(0x00020010);
var sopClassUID = metaMessage.getValue(0x00020002);
var instanceUID = metaMessage.getValue(0x00020003);
if (!contexts[sopClassUID]) {
contexts[sopClassUID] = [];
}
if (syntax && contexts[sopClassUID].indexOf(syntax) === -1) {
contexts[sopClassUID].push(syntax);
}
toSend.push({
file: bufferOrFile,
context: sopClassUID,
uid: instanceUID
});
if (read === length) {
sendProcessedFiles(self, contexts, toSend, handle, metaLength);
}
});
});
return handle;
};
// Starts to send dcm files
sendProcessedFiles = function(self, contexts, toSend, handle, metaLength) {
var useContexts = [];
_.each(contexts, (useSyntaxes, context) => {
if (useSyntaxes.length > 0) {
useContexts.push({
context: context,
syntaxes: useSyntaxes
});
} else {
throw 'No syntax specified for context ' + context;
}
});
self.associate({
contexts: useContexts
}, function(ac) {
var maxSend = ac.getMaxSize();
var next = toSend.shift();
self._sendFile(this, handle, next, maxSend, metaLength, toSend);
});
};
Connection.prototype.storeResponse = function(messageId, msg) {
var rq = this.messages[messageId];
if (rq.listener[2]) {
var status = rq.listener[2].call(this, msg);
if (status !== undefined && status !== null && rq.command.store) {
//store ok, ready to send c-store-rsp
var storeSr = rq.command.store;
var replyMessage = storeSr.replyWith(status);
replyMessage.setAffectedSOPInstanceUID(this.lastCommand.getSOPInstanceUID());
replyMessage.setReplyMessageId(this.lastCommand.messageId);
this.sendMessage(replyMessage, null, null, storeSr);
} else {
throw 'Missing store status';
}
}
};
Connection.prototype.allClosed = function() {
var allClosed = true;
for (var i in this.peers) {
if (Object.keys(peers[i].sockets).length > 0) {
allClosed = false;
break;
}
}
return allClosed;
};
Connection.prototype.addSocket = function(hostAE, socket) {
var peerInfo = this.selectPeer(hostAE);
peerInfo.sockets[socket.id] = socket;
socket.on('close', function() {
if (peerInfo.sockets[this.id]) {
delete peerInfo.sockets[this.id];
}
});
};
Connection.prototype.associate = function(options, callback) {
var hostAE = options.hostAE ? options.hostAE : this.defaultPeer;
var sourceAE = options.sourceAE ? options.sourceAE : this.defaultServer;
if (!hostAE || !sourceAE) {
throw 'Peers not provided or no defaults in settings';
}
var peerInfo = this.selectPeer(hostAE);
var nativeSocket = new Socket();
var socket = new CSocket(nativeSocket, this.options);
if (callback) {
socket.once('associated', callback);
}
console.log('Starting Connection...');
socket.setCalledAe(hostAE);
socket.setCallingAE(sourceAE);
console.log(peerInfo);
nativeSocket.connect({
host: peerInfo.host,
port: peerInfo.port
}, () => {
//connected
this.addSocket(hostAE, socket);
if (options.contexts) {
socket.setPresentationContexts(options.contexts);
} else {
throw 'Contexts must be specified';
}
socket.associate();
});
return socket;
};
@@ -12,11 +12,10 @@ body
.studylistContainer
theme('background-color', '$primaryBackgroundColor')
margin: 0 auto
margin: 2px auto 0
color: white
float: left;
width: 100%;
.tab-content
width: 100%
height: calc(100% - 91px)
@@ -31,4 +30,4 @@ body
.viewerContainer
height: 100%
width: 100%
width: 100%
@@ -4,9 +4,6 @@
font-size: 13px
font-weight: normal !important
.rows-per-page
padding-top: 20px
label
font-weight: normal
@@ -15,18 +12,23 @@
color: white
.page-number
margin: 0
text-align: right
label
font-weight: normal
ul#pagination
margin: 0
li
a
padding: 4px 8px
theme('background-color', '$primaryBackgroundColor')
theme('border-color', '$uiGray')
theme('background-color', '$uiGrayDarkest')
color: white
padding: 4px 8px
&:hover
theme('color', '$activeColor')
@@ -41,3 +43,13 @@
a:hover
color: inherit
&:not(.disabled):hover a
theme('background-color', '$uiGrayDark')
theme('color', '$activeColor')
&.active a
theme('background-color', '$uiGrayDark')
theme('color', '$activeColor')
&.disabled a
theme('color', '$uiGrayLight')
@@ -1,6 +1,6 @@
<template name="studylistResult">
<div class="studyListToolbar">
<div class="header">
<div class="studyListToolbar clearfix">
<div class="header pull-left">
Study list
</div>
<div class="studyCount pull-right">
@@ -104,4 +104,4 @@
{{/unless}}
{{/if}}
</div>
</template>
</template>
@@ -8,23 +8,21 @@ $inputBackgroundColor = #2c363f
$inputPlaceholderColor = lightgray
$studyListToolbarHeight = 75px
$tablePadding = 8%
$bodyCellHeight = 40px
.studyListToolbar
theme('background', '$uiGrayDarker')
height: $studyListToolbarHeight
border-bottom: 2px solid black
padding: 0 30px
margin-bottom: 2px
padding: 0 $studyListPadding
div
&>div
display: inline-block
.header
font-size: 22px
font-weight: 300
color: $tableTextSecondaryColor
padding: 0 10px
line-height: $studyListToolbarHeight
.studylistToolbar
@@ -35,20 +33,35 @@ $bodyCellHeight = 40px
theme('color', '$uiSkyBlue')
font-size: 40px
font-weight: 100
padding: 0 10px
line-height: $studyListToolbarHeight
.theadBackground
theme('background-color', '$uiGrayDarker')
width: 100%
height: 122px
height: 121px
position: absolute
z-index: 1
width: 100%
&:before, &:after
content: ''
display: block
left: 0
position: absolute
width: 100%
&:before
theme('background-color', '$uiGrayDarker')
height: 100%
top: 0
z-index: 1
&:after
theme('background-color', '$uiSkyBlue')
bottom: -1px
height: 1px
z-index: 3
#studyListContainer
background: black
width: 100%
padding: 0 $tablePadding
padding: 0 $studyListPadding
position: absolute
z-index: 2
@@ -64,7 +77,6 @@ $bodyCellHeight = 40px
table#tblStudyList
thead
theme('background-color', '$uiGrayDarker')
white-space: nowrap
tr
@@ -144,15 +156,10 @@ $bodyCellHeight = 40px
color: $tableTextPrimaryColor
font-weight: 300
border-top: 1px solid #436270
border-bottom: 1px solid #436270
white-space: nowrap
transition(all 0.1s ease)
&:first-child
padding-left: $tablePadding
&:last-child
padding-right: $tablePadding
&:hover, &:active, &.active
background-color: $tableHoverColor
color: white
@@ -163,7 +170,6 @@ $bodyCellHeight = 40px
border-bottom: 1px solid #436270
background-color: $tableHoverColor
@media only screen and (max-width: 1362px)
$tablePadding = 5%
@@ -238,4 +244,4 @@ $bodyCellHeight = 40px
.worklistPagination
.row
margin-left: 0
margin-right: 0
margin-right: 0
@@ -24,4 +24,4 @@
opacity: 0
overflow: hidden
position: absolute
z-index: -1
z-index: -1
@@ -19,7 +19,7 @@ const currentServerChangeHandler = () => {
return;
}
switchToTab('worklistTab');
switchToTab('studylistTab');
};
CurrentServer.find().observe({
+1
View File
@@ -1,4 +1,5 @@
import './publications.js';
import './servers.js';
import './validateServerConfiguration.js';
import './lib';
+2 -1
View File
@@ -1,4 +1,5 @@
import { Meteor } from 'meteor/meteor';
import { _ } from 'meteor/underscore';
Meteor.startup(function() {
console.log('Adding Servers from JSON Configuration');
@@ -72,7 +73,7 @@ class ServersControl {
}
static remove(serverId) {
var query = {
const query = {
_id: serverId
};
@@ -24,7 +24,7 @@
line-height: 18px
.caret-down
theme('color', '$uiLightGray')
theme('color', '$uiGrayLight')
margin: 0 4px 4px 2px
ul.dropdown-menu
@@ -1,4 +1,4 @@
.loadingTextDiv
margin: 30px
font-weight: 300
padding: 30px
text-align: center
font-weight: 300
@@ -205,10 +205,6 @@ Template.thumbnailEntry.onCreated(() => {
instance.isDragAndDrop = _.isUndefined(instance.data.viewportIndex);
});
Template.thumbnailEntry.onRendered(() => {
console.warn('thumbnailEntry onRendered');
});
Template.thumbnailEntry.events({
// Event handlers for drag and drop
'touchstart .thumbnailEntry, mousedown .thumbnailEntry'(event, instance) {