logplus/WellLogUI/src/DrawCurveView.cpp
2025-10-29 17:23:30 +08:00

1209 lines
35 KiB
C++

#include "DrawCurveView.h"
#include <QPainter>
#include <QLine>
#include <qfontmetrics.h>
#include <QPainter>
#include <QScrollBar>
#include <QMenu>
#include <qpushbutton.h>
#include "ShowCurve.h"
#include "editEnd.h"
#include "SmoothTool.h"
#include "AngleAdjTool.h"
#include "WellLogTableDialogNew.h"
//#include "math.h"
#define _USE_MATH_DEFINES // 必须放在包含头文件之前
#include <math.h> // 或 #include <cmath>
DrawCurveView::DrawCurveView(QWidget *parent) :
QWidget(parent),
isInit(false),
mouseDrawDepth(0),
mouseDrawValue(0),
tishiEditTime(0),
frontPos(QPoint(0,0))
{
press_noRelease_mode = false;
m_values=NULL;
CurrentPos=0;
setMouseTracking(true);
pressPoint = -9999;
releasePoint = -9999;
pressEdit = -9999;
releaseEdit = -9999;
EditMode = false;
editLock = false;
ifContinue = false;
hasSelect = false;
sTool = new SmoothTool();
angTool = new AngleAdjTool();
msgBox2 = new editEnd();
connect(msgBox2, SIGNAL(sendSmData(int)), this, SLOT(saveSmooth_SLOT(int)));
connect(msgBox2, SIGNAL(sendContinueSignal()), this, SLOT(continueEditNoSave_SLOT()));
connect(sTool, SIGNAL(sendDataSmoothSign(float,float,int,int,int)), this, SLOT(receiveSmoothData(float,float,int,int,int)));
connect(sTool, SIGNAL(cancelSmooth()), this, SLOT(cancelSmoothEdit()));
connect(sTool, SIGNAL(SaveSmooth()), this, SLOT(overEditSave()));
connect(angTool, SIGNAL(sendAngleData(float,float,float,float,float)), this, SLOT(receiveAngleData(float,float,float,float,float)));
connect(angTool, SIGNAL(cancelAngle()), this, SLOT(cancelAngleEdit()));
}
DrawCurveView::~DrawCurveView(){
if(EditMode && editIndexNum!=0){
delete []editIndex;
delete []editValue;
//delete []onceEditIndex;
}
delete sTool;
delete angTool;
delete msgBox2;
}
void DrawCurveView::initCurveViewQMenu(){
QMenu menu;
//添加菜单项,指定图标、名称、响应函数
menu.addAction(QString("曲线绘制"),this,SLOT(editIfBegin_Slot()));
menu.addAction(QString("平滑处理"),this,SLOT(smoothWin_Slot()));
menu.addAction(QString("基线校正"),this,SLOT(AngAdjWin_SLOT()));
menu.exec(QCursor::pos());
}
void DrawCurveView::initCurveEditQMenu(){
QMenu menu;
//添加菜单项,指定图标、名称、响应函数
menu.addAction(QString("完成编辑"),this,SLOT(finishEdit_SLOT()));
menu.exec(QCursor::pos());
}
int DrawCurveView::calMousePoint()
{
return lastPos.y() / m_height * PageSize + 0.5 + CurrentPos;
}
void DrawCurveView::mousePressEvent(QMouseEvent *event){
lastPos = event->pos();
if(rlev == 0 || m_height == 0)return;
int tempPoint = calMousePoint();
// 处于编辑状态
if (event->buttons() & Qt::LeftButton && EditMode && !editLock)
{
//editStrValue = (tempPoint < pressEdit) ? pressEdit + 1 : tempPoint;
//editStrValue = (tempPoint > releaseEdit) ? releaseEdit : tempPoint;
if(tempPoint < pressEdit)
editStrValue = pressEdit;
else if(tempPoint > releaseEdit)
editStrValue = releaseEdit;
else
editStrValue = tempPoint;
lastEditPos = editStrValue;
onceEditNum = 0;
genEditLine();
update();
}
if (event->buttons() & Qt::RightButton){
if(!EditMode && tempPoint < releasePoint && tempPoint > pressPoint ) initCurveViewQMenu();
else if(EditMode/* && tempPoint<releaseEdit && tempPoint>pressEdit*/) initCurveEditQMenu();
return;
}
if(EditMode){
if(tempPoint > releaseEdit || tempPoint < pressEdit)
emit editModeTips();
return;
}
if(pressPoint != -9999){
if(pressPoint < tempPoint && tempPoint < releasePoint && !EditMode){
editIfBegin();
}
pressPoint = -9999;
emit unableEditButtons();
update();
return;
}
else{
pressPoint = tempPoint;
press_noRelease_mode = true;
press_noRelease_point = tempPoint;
update();
return;
}
}
void DrawCurveView::mouseReleaseEvent(QMouseEvent *event){
if (event->button() != Qt::LeftButton){
return;
}
if(EditMode){
editStrValue = -9999;;
onceEditNum = 0;
return;
}
if(releasePoint != -9999 && hasSelect){
releasePoint = -9999;
hasSelect = false;
update();
return;
}
if(rlev == 0 || m_height == 0)return;
if(press_noRelease_mode){
//计算释放位置
QPoint Pos = event->pos();
float curSdep = CurrentPos*rlev + sdep;
float mouseDepth = Pos.y() * PageSize / m_height * rlev + curSdep;
if(mouseDepth > edep) mouseDepth = edep;
releasePoint = (mouseDepth - curSdep) / rlev + 0.5 + CurrentPos;
if(pressPoint > releasePoint){
int temp = releasePoint; releasePoint = pressPoint; pressPoint = temp;
}
if(releasePoint - pressPoint > 1){
emit enableEditButtons();
hasSelect = true;
}
else{
emit R2L();
releasePoint = -9999;
pressPoint = -9999;
}
press_noRelease_mode = false;
}
update();
}
void DrawCurveView::mouseMoveEvent(QMouseEvent *event){
lastPos = event->pos();
if (event->buttons() & Qt::LeftButton && EditMode && !editLock)
genEditLine();
if(rlev == 0 || m_height == 0) return;
//更新鼠标位置曲线信息显示
float mouseDepth, mouseValue;
ShowCurve* fParent= (ShowCurve *)(this->parent()->parent());
float curSdep = CurrentPos * rlev + sdep;
mouseDepth = lastPos.y() * PageSize / m_height * rlev + curSdep;
int itemp = (mouseDepth-curSdep) / rlev + 0.5 + CurrentPos;
//没有完成框选情况下,实时更新鼠标的可能释放位置
if(press_noRelease_mode){
press_noRelease_point = itemp;
if(press_noRelease_point < pressPoint){
int t = pressPoint;
pressPoint = press_noRelease_point;
press_noRelease_point = t;
}
}
if(itemp >= m_count) mouseValue=-99999.;
else mouseValue= m_values[itemp];
fParent->mouseMkChange(mouseDepth, mouseValue);
mouseDrawDepth = mouseDepth;
mouseDrawValue = mouseValue;
update();
}
void DrawCurveView::wheelEvent(QWheelEvent *event) // 滚轮事件
{
if(event->delta() > 0){
emit verticalSliderUP();
}else{
emit verticalSliderDOWN();
}
}
void DrawCurveView::usevalueDrawPoint(QPainter *painter){
if(rlev == 0 || m_height == 0) return;
/*
float mouseDepth, mouseValue;
float curSdep = CurrentPos * rlev + sdep;
mouseDepth = lastPos.y() * PageSize / m_height * rlev + curSdep;
int itemp = (mouseDepth-curSdep) / rlev + 0.5;
if(itemp + CurrentPos >= m_count)
mouseValue = -99999.;
else
mouseValue = m_values[itemp + CurrentPos];
*/
//mouse position
float x = lastPos.x()/*(mouseValue-m_Xmin)/(m_Xmax-m_Xmin)*m_width*/;
float y = lastPos.y()/*(float)(m_height * itemp / PageSize)*/;
int wTemp = 4;
float hTemp = 15;
float min_hTemp = 2;
float jTemp = 6;
float reduce_rate = 0.6;
int forceP_index = x / jTemp;
float guanRate = (lastPos.x() - frontPos.x()) / m_width;
for(int i = 0; i < m_width / jTemp; i++)
{
float draw_reduce_rate = reduce_rate;
float draw_hTemp = hTemp;
//float guanRateTemp = guanRate;
int cha = forceP_index - i;
//bool isGuanSide = (cha * guanRateTemp > 0) ? true : false;
cha = (cha < 0) ? -cha : cha;
//guanRateTemp = (guanRateTemp < 0) ? -guanRateTemp : guanRateTemp;
for(int chaN = 0; chaN < cha; chaN++)
{
draw_reduce_rate /= 0.9;
if(draw_reduce_rate >= 1 || draw_reduce_rate < 0) break;
draw_hTemp *= draw_reduce_rate;
if(draw_hTemp <= min_hTemp)
{
draw_hTemp = min_hTemp;
break;
}
}
painter->fillRect(jTemp * i - wTemp / 2, m_height - draw_hTemp, wTemp, hTemp, QColor(128, 128, 255, 128));
}
forceP_index = y / jTemp;
for(int i = 0; i < m_height / jTemp; i++)
{
float draw_reduce_rate = reduce_rate;
float draw_hTemp = hTemp;
int cha = forceP_index - i;
cha = (cha < 0) ? -cha : cha;
for(int chaN = 0; chaN < cha; chaN++)
{
draw_reduce_rate /= 0.9;
if(draw_reduce_rate >= 1 || draw_reduce_rate < 0) break;
draw_hTemp *= draw_reduce_rate;
if(draw_hTemp <= min_hTemp)
{
draw_hTemp = min_hTemp;
break;
}
}
painter->fillRect(m_width - draw_hTemp, jTemp * i - wTemp / 2, hTemp, wTemp, QColor(128, 128, 255, 128));
}
frontPos = lastPos;
//横轴数值显示
QFont UVDP_fontGray2("Arial", 8, QFont::Bold, false);
UVDP_fontGray2.setBold(false);
painter->setFont(UVDP_fontGray2);
painter->setPen(Qt::blue);
painter->drawText(x, m_height - hTemp - 14, QString(" value"));
painter->drawText(x, m_height - hTemp + 2, QString(" %1").arg((m_Xmax - m_Xmin) / m_width * lastPos.x() + m_Xmin));
//纵轴数值显示
painter->drawText(m_width - hTemp - 45, y + 12, QString(" depth"));
painter->drawText(m_width - hTemp - 45, y + 28, QString(" ") + QString::number(mouseDrawDepth, 'f', 2));
/*
QFont UVDP_fontGray("Arial", 8, QFont::Bold, false);
UVDP_fontGray.setBold(false);
painter->setFont(UVDP_fontGray);
painter->setPen(Qt::gray);
painter->drawText(m_width - 60, y + 13, QString("%1").arg(mouseDrawValue));
painter->drawText(m_width - 60, y - 5, QString("%1").arg(mouseDrawDepth));
*/
}
void DrawCurveView::drawMousePosLine(QPainter *painter){
QPen pen(Qt::gray, 2, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin);
painter->setPen(pen);
float w = width() - 65;
if(w < 0) w = 0;
//绘制横向线
//painter->drawLine(0, lastPos.y(), w, lastPos.y());
//绘制纵向线
//painter->drawLine(lastPos.x(), 0, lastPos.x(), height());
}
void DrawCurveView::button_AngAdjWin()
{
if(!EditMode && releasePoint != -9999 && pressPoint != -9999 )
AngAdjWin();
}
void DrawCurveView::AngAdjWin_SLOT()
{
AngAdjWin();
}
void DrawCurveView::AngAdjWin(){
angTool->setSliderRange(int(m_width));
angTool->setAngDep(sdep,edep,pressPoint * rlev + sdep, releasePoint * rlev + sdep);
angTool->setEachSetValue(1 / m_width * (m_Xmax-m_Xmin));
float *temp = new float[releasePoint - pressPoint + 1];
for(int i = 0; i < releasePoint - pressPoint + 1; i++)
temp[i] = m_values[i+pressPoint];
int maxN = (edep - sdep) / rlev;
int N = releasePoint - pressPoint + 1;
if(N>maxN) N = maxN;
angTool->calcuCurAve(temp, N);
angTool->setLineEditable();
angTool->show();
}
void DrawCurveView::receiveAngleData(float sd, float ed, float headOffset, float tailOffset, float angle)
{
if(!EditMode){
whichMode = 2;
EditMode = true;
float curSdep = CurrentPos * rlev + sdep;
pressEdit = (sd - curSdep) / rlev + 0.5 + CurrentPos;
releaseEdit = (ed - curSdep) / rlev + 0.5 + CurrentPos;
pressPoint = -9999;
releasePoint = -9999;
hasSelect = false;
initEditPart();
}
else{
oriCur2Edit();
editValue[releaseEdit - pressEdit] = m_values[releaseEdit];
}
float eachValue = (1 / m_width * (m_Xmax-m_Xmin)) * headOffset;
for(int i = 0; i < releaseEdit-pressEdit+1; i++){
editValue[i] += eachValue;
float offsetValue;
offsetValue = (i*rlev) * tan(angle*M_PI/180.0f);
editValue[i] += offsetValue;
}
angTool->calcuCurAve(editValue, releaseEdit - pressEdit + 1);
initeditIndex();
update();
}
void DrawCurveView::cancelAngleEdit(){
if(EditMode != true) return;
for(int i = pressEdit; i < releaseEdit; i++)
editValue[i - pressEdit] = m_values[i];
editValue[releaseEdit - pressEdit] = m_values[releaseEdit];
}
void DrawCurveView::smoothWin()
{
sTool->setSmoothDep(sdep,edep,pressPoint * rlev + sdep, releasePoint * rlev + sdep);
sTool->setLineEditable();
sTool->show();
}
void DrawCurveView::button_smoothWin()
{
if(!EditMode && releasePoint != -9999 && pressPoint != -9999 )
smoothWin();
}
void DrawCurveView::smoothWin_Slot()
{
smoothWin();
}
void linearSmooth3( float in[], float out[], int N, float rate[], int count){
float *temp = new float[N];
for(int j = 0; j < N; j++)
temp[j] = in[j];
for(int c = 0; c < count; c++){
int i;
if ( N < 3 ){
for ( i = 0; i <= N - 1; i++ )
out[i] = temp[i];
}
else{
out[0] = ( 5.0 * temp[0] + 2.0 * temp[1] - temp[2] ) / 6.0;
for ( i = 1; i <= N - 2; i++ )
out[i] = ( rate[0] * temp[i - 1] + rate[1] * temp[i] + rate[2] * temp[i + 1] ) / 3.0;
out[N - 1] = ( 5.0 * temp[N - 1] + 2.0 * temp[N - 2] - temp[N - 3] ) / 6.0;
}
for(int j = 0; j < N; j++)
temp[j] = out[j];
}
delete []temp;
}
void linearSmooth5( float in[], float out[], int N, float rate[], int count ){
float *temp = new float[N];
for(int j = 0; j < N; j++)
temp[j] = in[j];
for(int c = 0; c < count; c++){
int i;
if (N <= 5)
for ( i = 0; i < N; i++ ) out[i] = temp[i];
else{
float tmpY = (3.0 * temp[0] + 2.0 * temp[1] + temp[2] - temp[4]) / 5.0;
out[0] = tmpY;
tmpY = (4.0 * temp[0] + 3.0 * temp[1] + 2 * temp[2] + temp[3]) / 10.0;
out[1] = tmpY;
for (int i = 2; i <= N - 3; i++){
tmpY = (rate[0] * temp[i - 2] + rate[1] * temp[i - 1] + rate[2] *temp[i] + rate[3] *temp[i + 1] + rate[4] * temp[i + 2]) / 5.0;
out[i] = tmpY;
}
tmpY = (4.0 * temp[N - 1] + 3.0 * temp[N - 2] + 2 * temp[N - 3] + temp[N - 4]) / 10.0;
out[N - 2] = tmpY;
tmpY = (3.0 * temp[N - 1] + 2.0 * temp[N - 2] + temp[N - 3] - temp[N - 5]) / 5.0;
out[N - 1] = tmpY;
}
for(int j = 0; j < N; j++)
temp[j] = out[j];
}
delete []temp;
}
void linearSmooth7( float in[], float out[], int N, float rate[], int count ){
float *temp = new float[N];
for(int j = 0; j < N; j++)
temp[j] = in[j];
float tmpY;
for(int c = 0; c < count; c++){
int i;
if (N <= 7)
for ( i = 0; i < N; i++ ) out[i] = temp[i];
else{
out[0] = temp[0];
out[1] = temp[1];
out[2] = temp[2];
for (int i = 3; i <= N - 4; i++){
tmpY = (rate[0] * temp[i-3] + rate[1] * temp[i-2] + rate[2] *temp[i-1] + rate[3] *temp[i] + rate[4] * temp[i+1] + rate[5] * temp[i+2] + rate[6] * temp[i+3]) / 7.0;
out[i] = tmpY;
}
out[N - 3] = temp[N - 3];
out[N - 2] = temp[N - 2];
out[N - 1] = temp[N - 1];
}
for(int j = 0; j < N; j++)
temp[j] = out[j];
}
delete []temp;
}
void DrawCurveView::receiveSmoothData(float sd, float ed, int mode, int cal, int count){
if(!EditMode){
whichMode = 2;
EditMode = true;
float curSdep = CurrentPos * rlev + sdep;
pressEdit = (sd - curSdep) / rlev + 0.5 + CurrentPos;
releaseEdit = (ed - curSdep) / rlev + 0.5 + CurrentPos;
pressPoint = -9999;
releasePoint = -9999;
hasSelect = false;
initEditPart();
}
else{
oriCur2Edit();
editValue[releaseEdit - pressEdit] = m_values[releaseEdit];
}
float rate[7];
if(cal == 0)
for(int i = 0; i < 7; i++)
rate[i] = 1;
else if(cal == 2){
if(mode == 0){rate[0] = 0.5;rate[1] = 2;rate[2] = 0.5;}
else if(mode == 1){rate[0] = 0.4;rate[1] = 0.85;rate[2] = 2.5;rate[3] = 0.85;rate[4] = 0.4;}
else if(mode == 2){rate[0] = 0.25;rate[1] = 0.5;rate[2] = 1;rate[3] = 3.5;rate[4] = 1;rate[5] = 0.5;rate[6] = 0.25;}
}
else if(cal == 3){
if(mode == 0){rate[0] = 1.25;rate[1] = 0.5;rate[2] = 1.25;}
else if(mode == 1){rate[0] = 1.3;rate[1] = 0.9;rate[2] = 0.6;rate[3] = 0.9;rate[4] = 1.3;}
else if(mode == 2){rate[0] = 1.75;rate[1] = 0.9;rate[2] = 0.6;rate[3] = 0.5;rate[4] = 0.6;rate[5] = 0.9;rate[6] = 1.75;}
}
switch(mode){
case 0:
linearSmooth3(editValue, editValue, releaseEdit - pressEdit + 1, rate, count);
break;
case 1:
linearSmooth5(editValue, editValue, releaseEdit - pressEdit + 1, rate, count);
break;
case 2:
linearSmooth7(editValue, editValue, releaseEdit - pressEdit + 1, rate, count);
break;
}
initeditIndex();
update();
}
void DrawCurveView::cancelSmoothEdit(){
if(EditMode != true) return;
for(int i = pressEdit; i < releaseEdit; i++)
editValue[i - pressEdit] = m_values[i];
editValue[releaseEdit - pressEdit] = m_values[releaseEdit];
}
void DrawCurveView::button_editIfBegin(){
if(!EditMode && releasePoint != -9999 && pressPoint != -9999 )
editIfBegin();
}
void DrawCurveView::editIfBegin_Slot(){
editIfBegin();
}
void DrawCurveView::editIfBegin(){
whichMode = 2;
EditMode = true;
pressEdit = pressPoint;
releaseEdit = releasePoint;
releasePoint = -9999;
hasSelect = false;
pressPoint = -9999;
initEditPart();
}
void DrawCurveView::initeditIndex(){
for(int i = 0; i < releaseEdit - pressEdit; i++)
editIndex[i] = pressEdit + i;
editIndexNum = releaseEdit - pressEdit;
curEdit = releaseEdit-1;
}
void DrawCurveView::initEditPart(){
//eg. 2~5
editValue = new float[releaseEdit - pressEdit + 1]; //4
oriCur2Edit();
curEdit = pressEdit;
editIndexNum = 1;
editIndex = new int[releaseEdit - pressEdit + 1]; //4
editIndex[0] = pressEdit; //[0] == 2
editIndex[releaseEdit - pressEdit] = releaseEdit; //[3]==5
initeditIndex();
//onceEditIndex = new int[releaseEdit - pressEdit + 1];
//backup
tempPEdit = pressEdit;
tempREdit = releaseEdit;
emit unableEditButtons();
}
void DrawCurveView::oriCur2Edit(){
for(int i = pressEdit; i < releaseEdit + 1; i++)
editValue[i - pressEdit] = m_values[i];
}
void DrawCurveView::sortEdit(){
for(int i = 1; i < editIndexNum-1; i++)
if(editIndex[i] > editIndex[i+1]){
int tempIndex2 = editIndex[i+1];
editIndex[i+1] = editIndex[i];
editIndex[i] = tempIndex2;
}
}
void DrawCurveView::changeEditStrValue(int itemp){
int a = editStrValue - itemp;
int b = lastEditPos - itemp;
if(a * b < 0){
editStrValue = lastEditPos;
onceEditNum = 0;
}
}
bool DrawCurveView::isIneditRange(int i){
if(i < 0 || i >= releaseEdit - pressEdit + 1)
return false;
else
return true;
}
void DrawCurveView::genEditLine(){
if(!EditMode)return;
if(curEdit == -9999 || releaseEdit == -9999) return;
int itemp = lastPos.y() * PageSize / m_height + 0.5 + CurrentPos;//当前深度下标
float ivalue = lastPos.x() / m_width * (m_Xmax - m_Xmin) + m_Xmin; //计算曲线值
if(itemp < pressEdit && itemp > releaseEdit){
tempCurEdit = curEdit;
curEdit = releaseEdit;
return;
}
//修正当前绘制朝向
//changeEditStrValue(itemp);
//修改头尾下标
int headP, tailP = 0;
if(editStrValue < itemp){ headP = editStrValue; tailP = itemp;}
else{ headP = itemp; tailP = editStrValue;}
//赋予新值
if(!isIneditRange(itemp - pressEdit)) return;
editValue[itemp - pressEdit] = ivalue;
//单位差
if(!isIneditRange(headP - pressEdit) || !isIneditRange(tailP - pressEdit)) return;
float oneIndexAdd = (tailP == headP) ? (0) : (editValue[tailP - pressEdit] - editValue[headP - pressEdit]) / (tailP - headP);
for(int i = 0; i < tailP - headP; i++){
editValue[headP - pressEdit + i] = editValue[headP - pressEdit] + (i * oneIndexAdd);
}
/*
int spIndex = -9999;
int eqIndex = -9999;
for(int i = 0; i < releaseEdit - pressEdit + 1; i++)
{
//寻找更改位置
if(itemp < editIndex[i] && eqIndex == -9999 && spIndex == -9999)
spIndex = i;
else if(itemp == editIndex[i] && eqIndex == -9999 && spIndex == -9999)
eqIndex = i;
bool inThis = false;
for(int j = 0; j < onceEditNum; j++)
if(editIndex[i] == onceEditIndex[j]){
inThis = true;
break;
}
if(headP < editIndex[i] && editIndex[i] < tailP && !inThis){
for(int j = i; j < editIndexNum-1; j++)
editIndex[j] = editIndex[j+1];
editIndexNum--;
}
else if(editIndex[i] > tailP) break;
}
//放置更改
if(spIndex != -9999){
for(int j = editIndexNum; j >= spIndex; j--)
editIndex[j+1] = editIndex[j];
editIndex[spIndex] = itemp;
editIndexNum++;
editValue[itemp - pressEdit] = ivalue;
}
else if(eqIndex != -9999)
editValue[itemp - pressEdit] = ivalue;
//_ASSERTE( _CrtCheckMemory( ) );
//跟新本次修改index集
int ifi = 0;
for(ifi; ifi < onceEditNum; ifi++)
if(itemp == onceEditIndex[ifi]) break;
if(ifi == onceEditNum)
onceEditIndex[onceEditNum++] = itemp;
*/
editStrValue = itemp;
//sortEdit();
}
void DrawCurveView::finishEdit_SLOT()
{
tempCurEdit = curEdit;
curEdit = releaseEdit;
overEdit();
}
void DrawCurveView::drawEditLine(QPainter *painter){
if(!EditMode || pressEdit == -9999 || releaseEdit == -9999)return;
if(releaseEdit <= CurrentPos || pressEdit >= (PageSize + CurrentPos))
return;
int inNum = 0;//画布上的edit点计数
QPointF *points = new QPointF[PageSize + 1/*editIndexNum + 10*/];
int startPoint = (pressEdit < CurrentPos) ? CurrentPos : pressEdit;
int endPoint = (releaseEdit > (PageSize + CurrentPos)) ? (PageSize + CurrentPos) : releaseEdit;
for(int i = startPoint; i < (endPoint + 1); i++){
if(!isIneditRange(i - pressEdit)) continue;
points[inNum++] = coordCurvePoint(i - CurrentPos, editValue[i - pressEdit]);
}
/*
//获取画布范围内的edit点集合
int i = 0;
for(i; i < editIndexNum; i++){
if(editIndex[i] < CurrentPos || editIndex[i] > CurrentPos+PageSize) continue;
points[inNum] = coordCurvePoint(editIndex[i] - CurrentPos, editValue[editIndex[i] - pressEdit]);
if(points[inNum].x() < 0)
points[inNum].setX(0);
inNum++;
}
if(whichMode == 2 && editIndex[i-1] < releaseEdit - 1){
for(int j = editIndex[i-1]+1; j < releaseEdit; j++){
points[inNum] = coordCurvePoint(j - CurrentPos, editValue[j - pressEdit]);
if(points[inNum].x() < 0) points[inNum].setX(0);
inNum++;
if(inNum >= editIndexNum + 10)break;
}
}
*/
//红色虚线绘笔
QPen pen(Qt::red, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
painter->setPen(pen);
painter->drawPolyline(points, inNum);
delete []points;
/*
if(curEdit >= releaseEdit && !editLock)
overEdit();
*/
}
void DrawCurveView::saveSmooth_SLOT(int mode)
{
float rate[5] = {1,1,1,1,1};
switch(mode){
case 1:
linearSmooth3(tempEditValue, editValue, tempREdit - tempPEdit + 1, rate, 1);
break;
case 2:
linearSmooth5(tempEditValue, editValue, tempREdit - tempPEdit + 1, rate, 1);
break;
case 3:
for(int i = 0; i < tempREdit - tempPEdit + 1; i++)
editValue[i] = tempEditValue[i];
}
update();
}
void DrawCurveView::overEdit(){
if(!EditMode) return;
editLock = true;
bool re = saveEdit(1);
EditMode = false;
if(!re)return;
curEdit = -9999;
pressPoint = -9999;
releasePoint = -9999;
pressEdit = -9999;
releaseEdit = -9999;
editIndexNum = 0;
delete []editValue;
delete []editIndex;
//delete []onceEditIndex;
editLock = false;
ifContinue = false;
hasSelect = false;
}
void DrawCurveView::overEditSave(){
if(!EditMode) return;
editLock = true;
bool re = saveEdit(3);
EditMode = false;
if(!re)return;
curEdit = -9999;
pressPoint = -9999;
releasePoint = -9999;
pressEdit = -9999;
releaseEdit = -9999;
editIndexNum = 0;
delete []editValue;
delete []editIndex;
//delete []onceEditIndex;
editLock = false;
ifContinue = false;
hasSelect = false;
}
void DrawCurveView::continueEditNoSave_SLOT()
{
ifContinue = true;
}
bool DrawCurveView::saveEdit(int smooth){
if(whichMode == 1){
editIndex[editIndexNum++] = editIndex[tempREdit - tempPEdit];
float sValue,eValue,x;
int j=1;
for(int i=1; i<editIndexNum; i++){
sValue = editValue[editIndex[i-1]-tempPEdit];
eValue = editValue[editIndex[i]-tempPEdit];
x = eValue - sValue;
for(j; j<(tempREdit - tempPEdit + 1); j++){
if((editIndex[i] - tempPEdit) != j){
editValue[j] = sValue + x / (editIndex[i]-editIndex[i-1]) * (j + tempPEdit - editIndex[i-1]);
editValue[j] = float(int(editValue[j] * 10000)) / 10000;
}
else break;
}
}
}
else if(whichMode ==2){
float sValue,eValue,x;
int j=1;
for(int i=1; i<editIndexNum; i++){
sValue = editValue[editIndex[i-1]-tempPEdit];
eValue = editValue[editIndex[i]-tempPEdit];
x = eValue - sValue;
for(j; j<(tempCurEdit - tempPEdit + 1); j++){
if((editIndex[i] - tempPEdit) != j){
editValue[j] = sValue + x / (editIndex[i]-editIndex[i-1]) * (j + tempPEdit - editIndex[i-1]);
editValue[j] = float(int(editValue[j] * 10000)) / 10000;
}
else break;
}
}
}
tempEditValue = new float[tempREdit - tempPEdit + 1];
for(int i = 0; i < tempREdit - tempPEdit + 1; i++)
tempEditValue[i] = editValue[i];
if(smooth==3) {
for(int i = 0; i < (tempREdit - tempPEdit + 1); i++)
m_values[tempPEdit+i] = tempEditValue[i]/*editValue[i]*/;
delete []tempEditValue;
update();
CLogIO *logio=new CLogIO();
logio->Open(fileName.toStdString().c_str(),CSlfIO::modeWrite);
int aindex=logio->OpenCurve(curveName.toStdString().c_str());
if(aindex>=0)logio->WriteCurve(aindex, tempPEdit * rlev + sdep, tempREdit - tempPEdit + 1, &m_values[tempPEdit]);
logio->CloseCurve(aindex);
delete logio;
QMessageBox::information(NULL, "", "保存完成!");
return true;
}
int result = msgBox2->exec();
if(result == QDialog::Accepted){
smooth = msgBox2->SmoothResult();
float *tempValueList = new float[tempREdit - tempPEdit + 1];
float rate[5] = {1,1,1,1,1};
switch(smooth){
case 1:
linearSmooth3(tempEditValue, tempValueList, tempREdit - tempPEdit + 1, rate, 1);
break;
case 2:
linearSmooth5(tempEditValue, tempValueList, tempREdit - tempPEdit + 1, rate, 1);
break;
}
if(smooth == 3){
for(int i = 0; i < (tempREdit - tempPEdit + 1); i++)
m_values[tempPEdit+i] = tempEditValue[i]/*editValue[i]*/;
}
else{
for(int i = 0; i < (tempREdit - tempPEdit + 1); i++)
m_values[tempPEdit+i] = tempValueList[i]/*editValue[i]*/;
}
delete []tempValueList;
delete []tempEditValue;
update();
CLogIO *logio=new CLogIO();
logio->Open(fileName.toStdString().c_str(),CSlfIO::modeWrite);
int aindex=logio->OpenCurve(curveName.toStdString().c_str());
if(aindex>=0)logio->WriteCurve(aindex, tempPEdit * rlev + sdep, tempREdit - tempPEdit + 1, &m_values[tempPEdit]);
logio->CloseCurve(aindex);
delete logio;
QMessageBox::information(NULL, "", "保存完成!");
return true;
}
else{
if(ifContinue){
ifContinue = false;
for(int i = 0; i < tempREdit - tempPEdit + 1; i++)
editValue[i] = tempEditValue[i];
delete []tempEditValue;
initeditIndex();
editLock = false;
update();
return false;
}
else{
delete []tempEditValue;
return true;
}
}
}
void DrawCurveView::drawEditTishi(QPainter *painter)
{
QFont UVDP_fontGray("Arial", tishiEditTime / 10, QFont::Bold, false);
UVDP_fontGray.setBold(false);
painter->setFont(UVDP_fontGray);
painter->setPen(Qt::gray);
painter->drawText(tishiEdit, QString("编辑中"));
tishiEditTime--;
}
void DrawCurveView::paintEvent(QPaintEvent *evt)
{
if(m_count <= 0) return;
QPainter paint;
paint.begin(this);
paint.setBrush(Qt::white);
paint.drawRect(rect());
paint.save();
QPen pen(Qt::red);//lightGray);
pen.setStyle(Qt::SolidLine);
pen.setWidth(1);
paint.setPen(pen);
//int y1=rect().bottom(),y2=rect().top();
//paint.drawLine(rect().left()+5,rect().top()+5,rect().right()-5,rect().top()+5);
drawCoord(&paint);
// pen.setWidth(2);
pen.setColor(Qt::darkGray);
paint.setPen(pen);
drawDataPoints(&paint);
usevalueDrawPoint(&paint);
drawMousePosLine(&paint);
if(EditMode){
drawEditLine(&paint);
//if(tishiEditTime > 0)
// drawEditTishi(&paint);
}
paint.restore();
paint.end();
}
void DrawCurveView::initView()
{
/*int width=this->width();
int height=this->height();
rthy=QRect(0,0,width,height);
rthy1=QRect(0,0,width,30);
rthyt=QRect(0+2,30,width-4,height-30);*/
m_width=this->width();
m_height=this->height();
}
void DrawCurveView::drawCoord(QPainter *painter)
{
if(!isInit )
{
return;
}
}
//计算参数在当前画布上的坐标
QPointF DrawCurveView::coordCurvePoint(int iy,float value)
{
float x = (value - m_Xmin) / (m_Xmax - m_Xmin) * m_width;
float y = (float)(m_height * iy / PageSize);
return QPoint(x,y);
}
void DrawCurveView::setValues(float *values)
{
if(NULL != m_values)
{
m_values=NULL;
}
m_values=values;
}
void DrawCurveView::setCount(int count)
{
m_count=count;
}
void DrawCurveView::drawDataPoints(QPainter *painter)
{
bool ifDrawEdit = false;//是否需要绘制编辑区域(蓝色)
bool ifEditMode = false;//是否有选中曲线
if(press_noRelease_mode) ifDrawEdit = true;
if(pressPoint != -9999 && releasePoint != -9999){
ifEditMode = true;
ifDrawEdit = true;
if(releasePoint <= CurrentPos || pressPoint >= (PageSize + CurrentPos)) ifDrawEdit = false;
//if(CurrentPos <= pressPoint && pressPoint < (PageSize + CurrentPos)) ifDrawEdit = true;
//if(CurrentPos < releasePoint && releasePoint <= (PageSize + CurrentPos)) ifDrawEdit = true;
}
if(pressEdit != -9999 && releaseEdit != -9999){
ifEditMode = true;
ifDrawEdit = true;
if(releaseEdit <= CurrentPos || pressEdit >= (PageSize + CurrentPos)) ifDrawEdit = false;
//if(CurrentPos <= pressEdit && pressEdit < (PageSize + CurrentPos)) ifDrawEdit = true;
//if(CurrentPos < releaseEdit && releaseEdit <= (PageSize + CurrentPos)) ifDrawEdit = true;
}
//绘制常规曲线
float value=0;
//获得当前页point
QPolygonF polygon;
QPointF *points = new QPointF[PageSize];
for(int i = 0; i < PageSize; i++)
{
value = (i + CurrentPos >= m_count) ? -9999999. : m_values[i + CurrentPos];
//获取该点在画布上的位置
points[i] = coordCurvePoint(i, value);
if(points[i].x() < 0)
points[i].setX(0);
polygon<<points[i];
}
if(ifDrawEdit == true){
int fPoint, bPoint;
if(press_noRelease_mode){
if(pressPoint < CurrentPos) fPoint = CurrentPos; //编辑区域上界在画布上方
else fPoint = pressPoint;
if(press_noRelease_point > CurrentPos + PageSize) bPoint = CurrentPos + PageSize; //编辑区域下界在画布下方
else bPoint = press_noRelease_point;
}
else if(!EditMode){
if(pressPoint < CurrentPos) fPoint = CurrentPos; //编辑区域上界在画布上方
else fPoint = pressPoint;
if(releasePoint > CurrentPos + PageSize) bPoint = CurrentPos + PageSize - 1; //编辑区域下界在画布下方
else bPoint = releasePoint;
}
else{
if(pressEdit < CurrentPos) fPoint = CurrentPos;
else fPoint = pressEdit;
if(releaseEdit > CurrentPos + PageSize) bPoint = CurrentPos+PageSize-1;
else bPoint = releaseEdit;
}
painter->setPen(Qt::gray);
painter->drawPolyline(points, fPoint - CurrentPos);
//添加编辑区域背景色
painter->setBrush(QColor(0xDD, 0xDD, 0xDD));
painter->drawRect( 0,
points[fPoint - CurrentPos].y(),
width(),
points[bPoint - CurrentPos].y() - points[fPoint - CurrentPos].y()
);
//绘制编辑区域的蓝色线段
QPen pen(Qt::blue, 1, Qt::DashLine, Qt::RoundCap, Qt::RoundJoin);
painter->setPen(pen);
painter->drawPolyline(&points[fPoint - CurrentPos], (bPoint - fPoint));
//绘制剩余的灰色线段
QPen pen1(Qt::gray, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
painter->setPen(pen1);
painter->drawPolyline(&points[bPoint - CurrentPos], PageSize - (bPoint - CurrentPos));
}
else{
if(ifEditMode || EditMode)
painter->setPen(Qt::gray);
else
painter->setPen(Qt::darkBlue);
painter->drawPolyline(points, PageSize);
}
delete []points;
//绘制联动红点
if(rlev == 0)return;
float curSdep = CurrentPos * rlev + sdep;
float curEdep = (CurrentPos + PageSize-1) * rlev + sdep;
if(curEdep > edep) curEdep = edep;
if(curSdep > edep) curSdep = edep;
if(userCurrentPos > curSdep && userCurrentPos < curEdep)
{
int itemp = (userCurrentPos - curSdep) / rlev + 0.5;
if(itemp + CurrentPos >= m_count) value=-9999999.;
else
{
value = m_values[itemp + CurrentPos];
userPos = itemp;
}
float x = (value - m_Xmin) / (m_Xmax - m_Xmin) * m_width;
float y = (float)(m_height * itemp / PageSize);
QPen pen(Qt::red, 8, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin);
pen.setCapStyle(Qt::RoundCap);
painter->setPen(pen);
painter->drawPoint(x, y);
userCurrentValue = value;
ShowCurve* fParent= (ShowCurve *)(this->parent()->parent());
fParent->lineEdit_curValue_Change(value);
}
}