Example #1
0
// -------------------------------------------------------------------------
void ctkDICOMDatasetView::mouseMoveEvent(QMouseEvent* event){
    Q_D(ctkDICOMDatasetView);

    if(event->buttons() == Qt::RightButton){
        event->accept();
        QPoint nowPos = event->pos();
        if(nowPos.y() > d->OldMousePos.y()){
            emit requestNextImage();
            d->OldMousePos = event->pos();
        }else if(nowPos.y() < d->OldMousePos.y()){
            emit requestPreviousImage();
            d->OldMousePos = event->pos();
        }
    }else if(event->buttons() == Qt::MidButton){
        event->accept();
        QPoint nowPos = event->pos();

        this->setZoom(this->zoom() - (nowPos.y()-d->OldMousePos.y())/100.0);

        d->OldMousePos = event->pos();
    }else if(event->buttons() == Qt::LeftButton){
        event->accept();
        QPoint nowPos = event->pos();

        d->DicomIntensityWindow += (5*(nowPos.x()-d->OldMousePos.x()));
        d->DicomIntensityLevel -= (5*(nowPos.y()-d->OldMousePos.y()));
        d->AutoWindowLevel = false;

        d->setImage(d->CurrentImageIndex, false);

        d->OldMousePos = event->pos();
    }

    Superclass::mouseMoveEvent(event);
}
Example #2
0
Call::Call(int callId, QString myName)
{
#ifdef REN_DEBUG
	qWarning(QString("Call::Call(int %1, QString %2)").arg(callId).arg(myName));
#endif
	id = callId;
	sd = -1;

	dec_state = NULL;
	dec_state = speex_decoder_init(&speex_uwb_mode);
	// renyang - Initializes and allocates resources for a SpeexBits struct
	speex_bits_init(&bits);

	int enh = 1;
	speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &enh);
	speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &frame_size);

	if ((outBuffer = (float *) malloc(frame_size*4*sizeof(float)))==NULL)
		throw Error(Error::IHU_ERR_MEMORY);
	if ((soundBuffer = (float *) malloc(MAXBUFSIZE*sizeof(float)))==NULL)
		throw Error(Error::IHU_ERR_MEMORY);
	readyFrames = 0;

	rsa = new Rsa(RSA_STRENGTH);
	transmitter = new Transmitter(rsa);
	receiver = new Receiver(rsa);
	// renyang-modify 建立一個ip handler
	sctpiphandler = new SctpIPHandler();

	// renyang-modify - 當某一個ip沒有一段時間後, 沒有辦法收到data, 要處理
	connect(sctpiphandler,SIGNAL(SigAddressConfrim(QString)),this,SLOT(SlotAddressConfirm(QString)));
	// renyang-modify - 當多次沒有收到資料, 宣告這一個ip失聯
	connect(sctpiphandler,SIGNAL(SigAddressFail(QString)),this,SLOT(SlotAddressFail(QString)));
	// renyang-modify - 某一個ip有收到資料, 宣告這一個ip復活啦
	connect(sctpiphandler,SIGNAL(SigAddressAvailable(QString)),this,SLOT(SlotAddressAvailable(QString)));

	stopTimer = new QTimer(this);

	active = false;
	muteRec = false;
	mutePlay = false;
	callFree = true;
	aborted = false;
	recording = false;

	// renyang-modify - 初始化IPChanging, 表示最近沒有改變primary address
	IPChanging = false;
	// renyang-modify - 建立一個Timer來計數改完primary address後多久要改回IPChanging=false
	IPChangingTimer = new QTimer(this);
	connect(IPChangingTimer,SIGNAL(timeout()),this,SLOT(resetIPChanging()));

	// renyang-modify - 初始化傳送與接收image的index
	recvImage_index = sendImage_index = 0;

	transmitter->setMyName(myName);

	srand(time(NULL));

	connect( receiver, SIGNAL(newSocket(int,int,struct sockaddr_in)), this, SLOT(newConnection(int,int,struct sockaddr_in)) );
	connect( receiver, SIGNAL(keyRequest()), this, SLOT(sendKeyRequest()) );
	connect( receiver, SIGNAL(sendNewKey()), this, SLOT(sendKey()) );
	connect( receiver, SIGNAL(newKey(QString)), this, SLOT(receivedNewKey(QString)) );
	// renyang - 沒有再接收到client端傳送過來的訊息, 結束此Call
	connect( receiver, SIGNAL(finishSignal()), this, SLOT(stopCall()) );
	connect( receiver, SIGNAL(error(QString)), this, SLOT(abortCall(QString)) );
	connect( receiver, SIGNAL(warning(QString)), this, SLOT(warning(QString)) );
	connect( receiver, SIGNAL(message(QString)), this, SLOT(warning(QString)) );
	// renyang - 對方接受通話, 或是本地端接受通話
	connect( receiver, SIGNAL(connectedSignal()), this, SLOT(connected()) );
	connect( receiver, SIGNAL(ringSignal()), this, SLOT(playRing()) );
	connect( receiver, SIGNAL(initSignal()), this, SLOT(playInit()) );
	connect( receiver, SIGNAL(newAudioData(char*, int)), this, SLOT(decodeAudioData(char*, int)) );
	connect( receiver, SIGNAL(ringReplySignal()), transmitter, SLOT(sendRingReplyPacket()) );

	// renyang-modify - 接收由receiver傳送上來的peer address
	connect (receiver,SIGNAL(SignalgetIps(QStringList)),this,SLOT(SlotgetIps(QStringList)));
	// renyang-modify - 當Receiver接收到與之前的primary不同時, 要求改變primary address
	connect (receiver,SIGNAL(setPrimaddrSignal(QString)),this,SLOT(setPrimaddr(QString)));
	// renyang-modify - 當Receiver接收到事件時, 會通知上層的Call, 以便修改CallTab的ip list情況
	connect (receiver,SIGNAL(SigAddressEvent(QString,QString)),this,SLOT(SlotAddressEvent(QString,QString)));
	// renyang-modify - 對方要求影像
	connect (receiver,SIGNAL(requestImage()),this,SLOT(SlotGetImage()));
	// renyang-modify - 由receiver接收到image資料, 並處理這一些資料
	connect (receiver,SIGNAL(newVideoData(char *,int)),this,SLOT(decodeVideoData(char *,int)));
	// renyang-modify - 當收到想要接收目前封包的下一部分時...
	connect (receiver,SIGNAL(requestNextImage()),this,SLOT(sendVideo()));
	// renyang-modify - 接收到完整的image,準備把它放到video_label
	connect (receiver,SIGNAL(completeImage()),this,SLOT(processImage()));
	// renyang-modify - 跟對方要求影像失敗
	connect (receiver,SIGNAL(requestImageFail()),this,SLOT(SlotrequestImageFail()));
	// renyang-modify - end

	connect( transmitter, SIGNAL(ringMessage()), this, SLOT(ringMessage()) );
	connect( transmitter, SIGNAL(finishSignal()), this, SLOT(stopCall()) );
	connect( transmitter, SIGNAL(error(QString)), this, SLOT(abortCall(QString)) );
	connect( transmitter, SIGNAL(message(QString)), this, SLOT(message(QString)) );
	connect( transmitter, SIGNAL(startSignal()), this, SLOT(startRecorder()) );

	connect( stopTimer, SIGNAL(timeout()), this, SLOT(close()) );

	// renyang-modify - 初始化streamno
	streamno = 1;

}
Example #3
0
// renyang-TODO - 加入Vedio的部分吧
// renyang - 分析這一個封包是什麼種類的封包
// renyang - 依不同的封包, 做不一樣的事情
bool Receiver::processPacket(Packet *p)
{
#ifdef REN_DEBUG
	qWarning("Receiver::processPacket(Packet *p)");
#endif
	switch (p->getInfo())
	{
		case IHU_INFO_CRYPTED_AUDIO:
			if (blowfish)
			{
				// renyang - 解碼
				p->decrypt(blowfish);
			}
			else
			{
				if (!nodecrypt)
				{
					emitSignal(SIGNAL_KEYREQUEST);
				}
				break;
			}
		case IHU_INFO_AUDIO:
			// renyang - 取出資料, 並且通知有新資料到
			if (p->getDataLen() > MIN_DATA_SIZE)
			{
				emit newAudioData(p->getData(), p->getDataLen());
			}
			connected = true;
			break;
		case IHU_INFO_NEW_KEY:
			if (p->getDataLen() > MIN_DATA_SIZE)
			{
				char *out;
				int len = rsa->decrypt(p->getData(), p->getDataLen(), &out);
				if (blowfish)
					delete blowfish;
				blowfish = new Blowfish(out, len);
				emitSignal(SIGNAL_NEWKEY);
				free(out);
			}
			break;
		case IHU_INFO_KEY_REQUEST:
			if (p->getDataLen() > MIN_DATA_SIZE)
			{
				rsa->setPeerPublicKey(p->getData(), p->getDataLen());
				emitSignal(SIGNAL_SENDNEWKEY);
			}
			break;
		case IHU_INFO_RING:
			if (p->getDataLen() > MIN_DATA_SIZE)
			{
				ihu_reply = true;
				QString tempName = p->getData(); 
				if (!tempName.isEmpty())
					callerName = tempName;
			}
			emit warning(QString("!! CALL from %1 (%2) !!").arg(getIp()).arg(getCallerName()));
			emitSignal(SIGNAL_RING);
			break;
		case IHU_INFO_ANSWER:
			// renyang - 對方答應接應電話啦
			connected = true;
		case IHU_INFO_RING_REPLY:
			// renyang - 對方還沒有要接通電話
			ihu_reply = true;
			if (p->getDataLen() > MIN_DATA_SIZE)
				callerName = p->getData();
			break;
		case IHU_INFO_ERROR:
			ihu_abort = true;
		case IHU_INFO_REFUSE:
			// renyang - 對方拒絕接通電話
			ihu_refuse = true;
		case IHU_INFO_CLOSE:
			emitSignal(SIGNAL_FINISH);
			break;
		case IHU_INFO_INIT:
			emitSignal(SIGNAL_INIT);
		case IHU_INFO_RESET:
			disableDecrypt();
			break;
		// renyang - 對方要求Image(影像)
		case IHU_INFO_VIDEO_REQUEST:
			emit requestImage();
			break;
		// renyang-modify - 要求對方影像失敗
		case IHU_INFO_VIDEO_ERROR:
			emit requestImageFail();
			break;
		case IHU_INFO_VIDEO:
			// renyang-modify - 接收到片斷的image, 把資料放到Call::RecvImage中
			if (p->getDataLen() > MIN_DATA_SIZE)
			{
				emit newVideoData(p->getData(), p->getDataLen());
			}
			connected = true;
			break;
		case IHU_INFO_VIDEO_NEXT:
			emit requestNextImage();
			break;
		case IHU_INFO_VIDEO_END:
			emit completeImage();
			break;
		case IHU_INFO_VIDEO_CONFIRM:
			// renyang-modify - 只是用來確認線路是否是通的
			break;

	}
	return true;
}
//----------------------------------------------------------------------------
ctkDICOMAppWidget::ctkDICOMAppWidget(QWidget* _parent):Superclass(_parent), 
    d_ptr(new ctkDICOMAppWidgetPrivate(this))
{
  Q_D(ctkDICOMAppWidget);  

  d->setupUi(this);

  this->setSearchWidgetPopUpMode(false);

  //Hide image previewer buttons
  d->NextImageButton->hide();
  d->PrevImageButton->hide();
  d->NextSeriesButton->hide();
  d->PrevSeriesButton->hide();
  d->NextStudyButton->hide();
  d->PrevStudyButton->hide();

  //Enable sorting in tree view
  d->TreeView->setSortingEnabled(true);
  d->TreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
  d->DICOMProxyModel.setSourceModel(&d->DICOMModel);
  d->TreeView->setModel(&d->DICOMModel);

  d->ThumbnailsWidget->setThumbnailSize(
    QSize(d->ThumbnailWidthSlider->value(), d->ThumbnailWidthSlider->value()));

  connect(d->TreeView, SIGNAL(collapsed(QModelIndex)), this, SLOT(onTreeCollapsed(QModelIndex)));
  connect(d->TreeView, SIGNAL(expanded(QModelIndex)), this, SLOT(onTreeExpanded(QModelIndex)));

  //Set ToolBar button style
  d->ToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

  //Initialize Q/R widget
  d->QueryRetrieveWidget = new ctkDICOMQueryRetrieveWidget();
  d->QueryRetrieveWidget->setWindowModality ( Qt::ApplicationModal );

  //initialize directory from settings, then listen for changes
  QSettings settings;
  if ( settings.value("DatabaseDirectory", "") == "" )
    {
    QString directory = QString("./ctkDICOM-Database");
    settings.setValue("DatabaseDirectory", directory);
    settings.sync();
    }
  QString databaseDirectory = settings.value("DatabaseDirectory").toString();
  this->setDatabaseDirectory(databaseDirectory);
  d->DirectoryButton->setDirectory(databaseDirectory);

  connect(d->DirectoryButton, SIGNAL(directoryChanged(QString)), this, SLOT(setDatabaseDirectory(QString)));

  //Initialize import widget
  d->ImportDialog = new ctkFileDialog();
  QCheckBox* importCheckbox = new QCheckBox("Copy on import", d->ImportDialog);
  d->ImportDialog->setBottomWidget(importCheckbox);
  d->ImportDialog->setFileMode(QFileDialog::Directory);
  d->ImportDialog->setLabelText(QFileDialog::Accept,"Import");
  d->ImportDialog->setWindowTitle("Import DICOM files from directory ...");
  d->ImportDialog->setWindowModality(Qt::ApplicationModal);

  //connect signal and slots
  connect(d->TreeView, SIGNAL(clicked(QModelIndex)), d->ThumbnailsWidget, SLOT(onModelSelected(QModelIndex)));
  connect(d->TreeView, SIGNAL(clicked(QModelIndex)), d->ImagePreview, SLOT(onModelSelected(QModelIndex)));
  connect(d->TreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onModelSelected(QModelIndex)));

  connect(d->ThumbnailsWidget, SIGNAL(selected(ctkThumbnailLabel)), this, SLOT(onThumbnailSelected(ctkThumbnailLabel)));
  connect(d->ThumbnailsWidget, SIGNAL(doubleClicked(ctkThumbnailLabel)), this, SLOT(onThumbnailDoubleClicked(ctkThumbnailLabel)));
  connect(d->ImportDialog, SIGNAL(fileSelected(QString)),this,SLOT(onImportDirectory(QString)));

  connect(d->QueryRetrieveWidget, SIGNAL(canceled()), d->QueryRetrieveWidget, SLOT(hide()) );
  connect(d->QueryRetrieveWidget, SIGNAL(canceled()), this, SLOT(onQueryRetrieveFinished()) );

  connect(d->ImagePreview, SIGNAL(requestNextImage()), this, SLOT(onNextImage()));
  connect(d->ImagePreview, SIGNAL(requestPreviousImage()), this, SLOT(onPreviousImage()));
  connect(d->ImagePreview, SIGNAL(imageDisplayed(int,int)), this, SLOT(onImagePreviewDisplayed(int,int)));

  connect(d->SearchOption, SIGNAL(parameterChanged()), this, SLOT(onSearchParameterChanged()));

  connect(d->PlaySlider, SIGNAL(valueChanged(int)), d->ImagePreview, SLOT(displayImage(int)));
}