From ffd947b39a65169e6c5847bae50b1890a256d191 Mon Sep 17 00:00:00 2001 From: lh <2334563547@qq.com> Date: Tue, 8 Sep 2026 11:13:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(nmSubWxs):=20=E6=94=AF=E6=8C=81=E4=BA=95?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E9=A2=84=E8=A7=88=E5=88=87=E6=8D=A2=E5=B9=B6?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=9B=B2=E7=BA=BF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 支持编辑井切换压力和流量记录进行预览 - 完善编辑井及包含井的曲线 Tooltip 信息 - 移除编辑井预览下拉中的无效“无”选项 --- Bin/Config/Lang/cn/nmNum_cn.qm | Bin 136015 -> 136577 bytes Bin/Config/Lang/cn/nmNum_cn.ts | 9 +- .../nmNum/nmSubWxs/nmWellPressureFlowPage.h | 22 +- Src/nmNum/nmSubWxs/nmWellPressureFlowPage.cpp | 278 +++++++++++++++--- Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp | 59 +++- 5 files changed, 309 insertions(+), 59 deletions(-) diff --git a/Bin/Config/Lang/cn/nmNum_cn.qm b/Bin/Config/Lang/cn/nmNum_cn.qm index c9591eb6a887621039bf3dad2d9cec6c2f5bf457..920aec6bf0580507044031f7fd8d6ed610947d0c 100644 GIT binary patch delta 9891 zcmai)d0b6v^#9kh&)NIT=O}YHDk@S*6QNRMtPGV)C>o@sG@-5>nTJH}+=?<5k~A11 zWT*_$Bq5X`!@a~cyWC5^)p@?J-|P4K{`33m-9Gl&=Xut%)@Kb{-63&ezIaDBl9AHg zSQGgR0A>NncS6nv$T6ZUen|NNfuED85tRASNFRXo&ifYu>AnfM1c+%Q<#o>tgEDa_DoA6YC-w}QQILG0KD)=E(B6^hF37g(zMRo ztAV7o^A3z!&F}dO zul*>^3IM#X;;uO4e*kUhAV?xPOPS!rI|z*Z4Zon5pgU#Zayt12jfNxx0x2!fHGHCg zcqSp60kYBPoow&Wk_^}bFlRoHK=cN`3V_@plyyI~B;5}3RRTL{R1`pHDUhArcvfg( z*nAWqx+{>@MkFqJCpu}|31lcR7N3BuG2*?2b~9=dL3kw`NJ}gT>y6N57J{%b7>IBr zWzk~F8!aHb9}UF+4G7yUft<~!th)=Wunx%7Bf#3m02!0Uw+I~#1G0dfXbWV?aLQ%D zz|M3<(`=$#_L6sCEvy2)fz7A_vhWvWgn;sQbIOE6l*bz>n|ATptXeZ*D6so+PZlF7 zBOEDj4gxlRK0x_qEeVDSTVxARW=nawua-o|ld`Cd@)oY{1O{))D9U&1fUOb&8GMa$ zsG4%=5G^%i$6#RVt^s+b3+y8^{Nh2%L#dR1;{x$>QWFkb58U{Eh>L$&y{6+|jKAXmLX)Xxi8ivFm{F(`(PRkS@01;Y(?5hD$1^&>U<&H|iL(t#8#0<#gxK=j{&IerZ`4W-QI zDVx2({0j#1y*@DX>RNy)C&5zo8i@ULu(7oPsE-4iaTsY$*T4?$0OA zY=DtRMx(1MwA7GIzk}o5w?JSqxa9Z(F@6EA6W5?*o&(npSAa-OV7%L9AOlyz#O3xt zybeB;4h>D5DDBcH<2F#HW>X#zcM=Vif0%a=oAllT zZkhh5Fzu8clfdm2nrWOKpCBG@S{4UhiKv-6S(M|ro&j|AG(m1ISSW@Cn96dd`743$1}X-3fE2#iLc)VeZ;f zK$b3~+%bnTpM|-*ynzVj!@MnMl&&U}35_tX!Wv-hY%R&mzqRa2_BPND3g1y)Qu5gn z?dlId&144pQ07`~a zek|3J-1^8Xq-v`gTZoRqL;g|<(Xso`H+5lo7D1;@hPbWq zXwtVp@{&vd=WmdnCIpB%4F@HcfaFbp+!6sm(R|AG^KjTK9$h#P^2dh(IkTOzE(i+j z@i59u;I#EvAP9nRkg#HCs?P*+ISiUNNr43Pg-6m{ASZjl<3`+`K@WKI5XE)J3Cg$sz~9HG15vfW zhx8I4!wlhT9fnx)1p*J&0ok*d-zIZpN`3hnneoUnQ_}a48ervY(*M#^fYKsjaCSK6 ztSVwM6m1_@LQI>{3IRsMYzZckz$?UlX+MCDv%I<7&h-9zGDma|Ksku`sat_ed`yDA z?m=PlBEgyq0KKbg8mFv>-EeLJ2}eZ@_13Z};-6thBmW(XgLadCmM$i_`>X<=;ZG5759 zVLH`>sE;ut+|Wk5vnd}B(314Ep&asq8R3EdUg6I;Wm=%IoSCtPF~I*&7-&W%GF~mo zKzxTX{xuc={g+TquV*3~aH;3NFi{U`0e;`b#C$eD-yg%oekljI*2=7Yxe8#EhFSaf zM^uDFX8kd5jEOqR6Hb(;pD-IN@j08WFlnV&*VKkG8FKzEQ3yxj1H|B07& zw#=p93W4}|^X4kGW?KVu2N(c(Ept~Ns}*|%bH7^|kc1GX^|(8LB#e2Mcmv1?bLM%4 z1fc2!n)J;0$0 zln;}&BvXxeqb`n2a~mJj#X&}(i(r7+S|Ibb^95aunUk;hrY^>s#~A`ki6_<@%LJB# zvC7?OOnH1EW!rLrrF$ii^}7VttFch>S}Yj-!U|x1Pl00+TD8?y;H29QWV1vtW(CUr z;*kR95oq<;U6gCu1Y@}Y=+O~^ai*03M^;gu$P>6`+5jJ~(>pXVOE9q-jcxElFtO7W zriKY7?L{|BnJ! z{Dhu<(^_!p`vM@#-wQ71`CyF81ecHU$f<&=c^;sF8!rXds<4<5%LUhuVQt!WPH-y% zZ>Td7)PBU`r)R35@eYP*e_KJ@l~Vvm^#yMn-vK#wMew$<6-dkz!FzZ7!OQyuU#5=4 zdiXx2MIPnoRf6vxAF)Wt6?ELf1mJT)NE*%poJ|vo8hX0{Ir2s*8H^sYWT{Z@jn`!- zDeH+)nTW;AW>d4H{^6^5y05nMB3}HYIl;XxU!WgRun70~)iF0w?w!4Mv9sIGy zxGntS+&nCimBNfk=Yi2-V|<;oS5DU&Gw*iD%+kn)%VWeH1p(vR}GQztb*Zj7NH)Ot}iEvCFXk@CSH z%18KvpML=v(tl6s!5YDoa=?xD^6g; z9H}Moj-xC!6kfj;gWXDBVa=%5KziL1)@U#$MlKiD=5Ikyc_XY_mWG|>VPU;D#!zdH zuw^R70^=xr{IVX)Qa-#@eC9npgC&a9I<|3KFnYOMIXu znc0sODhC4ei=&)+n`N```PC}QmQ$?g77t*a$IAD`0&&mc6M8smdW5h&8ixaHeM#9i zmeun|yG~KE>VL6Gp3}tkpNyV5Ih57Ex(?v+B6i^G4_GaqVFyP(L)q`i4oSoiKYD{T zn}$iJ`7S$@^9C}!7dte@5Wsf^Yt0k@vEIqrte=2|<80Q>Z5&$Hh#fI!C1}XnJnbLk zdM4|d{{su!?d-&Ec>uqDX-T5rvJwBNuQDNMhfP|N=xFw8Q8(_c=Q^2nI)*ITXIF`9kz*DLHk{$$%- za)Ed#dH3GNn)8M1e*qX@KOM9rxAi%A91Y~=JC2yxW8oy@#Pjjo70W0cf;kD>snDsM zZdL#m8#lSW^#@Q%^*IA2+HA86XA*`AERj%->c^Q>FUN+Xo-^;jc-6VaS@cCSU90AX zEi8dP&{)n{D~F-c6`YM-R~$I4D-ZNUS3AjFGA01QKe)@15kM;QxyoY_fGy)F?{(qsv_}KzN-4+f<{pek zSM0Kddzje>$;aV4=5q_NHo{zvJ7c_}`IXfF?hC}-H((K&Hy)O;| zGU^fc{sYG4l)2oeIXEsbJtpE@P}fX%Qw~j|EFLcs{V)V_r$M9_fN_}~sU>N)6`7Lbu%wwM8WryVG7_XOa&~#p$D7X&8;IXbK#AGlIr?NyLL;Ub0zlcJu(3HK+ zdDnh+jQ$utp`V>k-ZqgY2fw{}t7tV$2D0@oWvZ_zaU>ql!Ed6Cg%~DZuZlJnRp2mW zxoG2`cs=Sb(Uz4;fK9I{o2*4ib?Mj{P8My`;41V!@d|ZMlFu8djWyo+qWtw^v8{X} zD*Unp;GRZQv=yCh)k0Cp{V0@#-=@5%5J{$*Pk|L^H zWrbyJzNkus)yqm9(Y3qJfmn4BH8pymR=*V8{nrtzg*;KS0%J0~m*~l?CLq%ui`rTO zF_rM)e2rSotZ3xls*Uv$MB?tXYw>5}#eEDzaF4#?zNdBpnc&Ww_qUMRr;7(=;>Ra< z^Fes&d`@g%iIymd=Ck{&HKt}_*GCv{L#I++3`U;9Mn6J4sUi>u(`}UbgDCITYDq$R ziKp~m2_$s5c#18CeNRX6lvXUPdat5%-zc8`8!lpaw%B_E`t}u8{M!?hSB|5MRck3A zbvQ-QS2NYo{5*YQO}9ScXon7fI&X3G8XfGElf=sx6=QkePPwd)cm=91R1OobXjB7y zdn=CnZj5TvDqf}Q3FN|S@!BjGAO;SU=3bQBmxis~#bZW#^a z?mEfvA+vF^AeJ~)xB^&|Nn9$o0QqB-Wb6tw((pEk>l*BSERFeXhK`!j&yxB39RS3Z z5`PX|F4chY))2|UTPVKU3nXEaF)YSQC1D5f-|LS{BDx>MbpD*Ox?K|ChDTM~TN3Ns zirvgYN!(N1&)j{I#JjmT;G8T;DkMM-xJa^A;#mxNAjwHV`%E7sIW(dPOPE#8l0z+L z@r;8dM;fgG2LD01bh9LX*BXEWHIn1S)p&STlxez>vhpja)1M_bHe$}&vQu&+7sotr z3njH3!-4RRBz500Znut>)Z3x+5=PR%&&6b;mfX+j2O!u^Y3(3s-VojmBb1XoiooJ( zcCqADNEyyXBl(sAYK_rU$!Gh`xX^==Zx7xBIIfWVyo4KUXqEgLgSoq7l$FXZ>6$~fv6Kf(k^ae(SU7~B}GzQ=e_`Wxs(qsX-Q7sk?P`oaQ>K< zy5jYX%xi`}{2(+ZAnmv6%lkaQw&{ zG19>LxA^|Sm$H7iH0U&1FwsFv;>}4zvTV>IC#B(kreLwdO5+Zr0j_`L6O0@+A+MzC z3I^h94NGbAW+k@A_odqh-9yKDCf&Y;LC0#8?wGY4NPL_0564MZi(5)}{acGUsE;(K zbQQq4Z_+%p6FI(1S`d8_4^kyPo`{}e>n1JSh@OyGmt(TpVB*_mGMEIb(%CLnd}YIy7lXY+GfrKc!fo4x{AlWh!<6mIE;|)sb;n z7~YquuA5+oQ6=l*k3UOlWZf;UVL1^a>)pQ+-Fl$RU`-&F3EQLTEY|7#aEISG*@8`?hQt-@!w^L>&$YzW} zx3l>uoAKu}e6OW1o4v9P$gJD`gSgBY~ehNXN>sR2Dl5rN#U|S;9ZbI0G%0t%=vi0ZJjIXP|5iKAS`u z%hpHZoG)u3zip76VTDSTE@;F#iM=dieFX-_G1+e8ZaB-)$o80A!5L5`|6-7_M)#2{ zZ-grj&JtvK@hDV9D$4dC*_o%!m_d)p&V0lJo$^Fhb{lITS+lHscq))?jk1bGs3={g z$gX#ej8?_Ts*{A69I|C?Y!&v5?`40RU;_WPMfNH6DS%VE?4KfZlv8oCA4cf*-TY)f z{Rt|M!ExEIxYbyhMaVkTm{t1Z%E`|}l-fi&lbs3>(N8XZj1E3&zFcaDM=*JoT-L`6 z%aILoS%D3J*(|w!+6v6RZ{&tQ1pr~G@X zB9)KYaS+p;m3*|Z6x(@^n{ubSxWjdYau;C|ws%>Saa}1J`^sHy!f^p@@(HOZaWU`Z z6Rx0TWae_W2`o;mf63jFVzCSUOgSN$GVufD^~G|JV^6T!+a>oXMCp&8CZGE7BuZ01 z`HY$7$=C)(;vdKrdnj+0$vyv^k2zwF+<)wE*k^F^fI2kY+5Y?~Q)AQ7m*f#|aD(fX z$m4h80grK&|1PvZ1-&d^J?}ffP#<~X!6@{-i#$8TPB%$czU#m97%G3u_veIQDBR}V zhp07Y9OXI1c%DoVWsI-raZ!+ERf&xo0O_x6{jloGF$Y1$>!h**`-tM4833QQvDD}a~l!N^9rFS@@+oxax3BVXX zg*fIJHbSuqnHf$=MiwX(8QrjNa#eIu;pgmng-*{94018$-5m;@R5gId3Ptyl2CUZ{ zv=oq7FaCm=TDp)?n7=o`@$Oar1um;KSrOqm5C?WSipWiv+BGSPSlcS>ChQdP4z&RB zwTi@hH2@=yDiWVg$9m2{v3Xige0};4<+eSPdv_?dDOTYO-A3^T@xVTAfg;^~9li&f zO*yShk-^rYyI3mrZbI!FTBq3O{1hWe_^+bi#eV$aS4FWWieQ3TapEG1q>D;XCilfx zDyI~eW}{s1;Hy%_Eg$^BK`#_fGtrLVsd)Yre<%w^&CgE_R1c+CAcmtWzSE#7}*WV zUQTGZxC~{#NqbP!)0O(>D6&=ylm>^;#heEzO?M9i2sBfgwPW$uH;&TGNon3I8i?dC zrNx0(biLEc(FQMY6r1;4`v*K^mD4XC#RxG`&S2N#Ytp}zzfJH&ZL(C(8M);f#Wl6ajE9nSjNj>h+ zWVrHFdpWM$TzTFT4H^&1+Ew`P3->5%&tmLeidWV?>4KfbbxIElW!=Z)Sp5*bW~d|6 zu#Hz(8Z$O^ysf3L#v@+k_!V_2^nl9wJ-YENQ|pCWd(c{1>Pt zIoD3vV5*w@4D-q2M=Fndj{q`GP@Wu5`Inn&rXi0t=wGVE*Y5zCKVKDg8yoswda5Yz zsrV)@PPOcNSFDM*C{+oq>oLCmR;|8&8H?^}RiavoU-(Lywpo=J?+DQS3FV}{s&%(7 zqE&YA?!z3d25(ax=z&(WcupC(L3LoG4SFT04&`med3HBdK{KA(lOd|(NdnA3#r%a~ z#->jvtE!*4V`b7)b<+rq-={`(OM_mt;+d-DWIn#Ub5ylF{(^_Qk5^b(I7z>%UOirk zrWkR@E;X4}AIsRfnez7Budvj)e;V7SB+1Y{Er<8-(ZatnNg-71NPE zDVG?gd)t$~r7MS#7=fX3;m1`My%cfpJM_Q^dw@=j!vFmO%CWIg%YyX77c5ENKZY2U zzPBOc@$Rife%_iMp5OlW-4hnX1_$YnjR@4`sLV9)S<{q>lIyNe3NlW}P4~}OxA}U9+(Y3P=~c6J|L^H3?wW8*=Kro{*tDpi zWg$V!^&`T=;zsEQEC>sT4OcpuqIVk;I_% zt0PHZN?$sYI{_yD|BVKX)HfQIUX(-nrAOQ@LD>HRJ6g~D delta 9474 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�DvEx;-2Sk<~o zu9znERH=o-uqQEBZS~oL`hP%`m2Ci|i=Zm>#PAGgQWceIuwtF3DyqZPY7JDy&84_J zebq@{G|oa^RkIXdpT1aCa~uP&beXE=ej6_}R2KX7;N^<-? zWo4b+rFzY@)`i=YMO5rJBBa$=yT@ zg-_~bH_u|VTc=LY$ngDFDbv=g6XKl!4DM5o+@W51N*;jWdsAX$W&qD1&)rDg7o5e%(0GDS~y)4fmlaA>LE zW^Fk{+N6GVZ!s3?Yba|H)n8&UhS;_0-?rZPCFSZrzF0nrZPkBfOau7KNBw6NuI)=N zwDA3Fhl{M4KPB(2NUW$Nzdso+${6TCs!GNTBwx6a@}Xo2Gq&qrp_}Jr1bbHo`o|3n z^7ZlBAoaGGzjE!tApd@hq(xA8{AcbrYj%v$+-WnX8%0Kh#TkXpj+q-aEiT3=cGh&G tnCW5DLt>|g8bwbJiHy$JHI$f?40R<}Lox#Pk%Jjy{vin^hPfm(?0*kRHu3-f diff --git a/Bin/Config/Lang/cn/nmNum_cn.ts b/Bin/Config/Lang/cn/nmNum_cn.ts index f1bdacd1..6a8259c4 100644 --- a/Bin/Config/Lang/cn/nmNum_cn.ts +++ b/Bin/Config/Lang/cn/nmNum_cn.ts @@ -5220,6 +5220,9 @@ Please check your input coordinates. Unknown未知 None无 (unnamed)(未命名) + Curve name: %1曲线名称:%1 + Gauge Code: %1记录编号:%1 + Measurement time: %1测量时间:%1 (Empty)(空) (Corrupt)(损坏) (Invalid)(无效) @@ -7213,7 +7216,11 @@ Average pressure in contour: %2 MPa Pressure Record压力记录 Flow Record流量记录 Display Phase显示相 - This page only displays the selected record.此页面仅展示当前选中的记录。 + (unnamed)(未命名) + Curve name: %1曲线名称:%1 + Gauge Code: %1记录编号:%1 + Measurement time: %1测量时间:%1 + Preview only; calculation settings are unchanged.仅切换页面预览,不影响计算配置。 (Invalid) (无效) (Empty) (空) (Corrupt) (损坏) diff --git a/Include/nmNum/nmSubWxs/nmWellPressureFlowPage.h b/Include/nmNum/nmSubWxs/nmWellPressureFlowPage.h index 65097ad4..28badf99 100644 --- a/Include/nmNum/nmSubWxs/nmWellPressureFlowPage.h +++ b/Include/nmNum/nmSubWxs/nmWellPressureFlowPage.h @@ -59,6 +59,12 @@ private slots: /** @brief 将流量曲线点击时间映射为表格行选择。 */ void slotFlowChartPointClicked(double dTimePoint); + /** @brief 切换压力记录预览,仅刷新页面,不修改井的计算记录选择。 */ + void slotPressureGaugePreviewChanged(int nIndex); + + /** @brief 切换流量记录预览,仅刷新页面,不修改井的计算记录选择。 */ + void slotFlowGaugePreviewChanged(int nIndex); + /** @brief 切换显示相下拉框,仅重新按新相取点刷新视图,不改变井数据。 */ void slotDisplayPhaseChanged(int nIndex); @@ -72,10 +78,10 @@ private: /** @brief 创建顶部压力/流量记录与显示相三个下拉框所在行。 */ void createRecordSelectionBar(); - /** @brief 按 m_pWell->getPressureRecords() 填充压力记录下拉框,恢复当前选中项。 */ + /** @brief 填充压力记录预览下拉框,优先恢复页面预览项。 */ void populatePressureGaugeCombo(); - /** @brief 按 m_pWell->getFlowRecords() 填充流量记录下拉框,恢复当前选中项。 */ + /** @brief 填充流量记录预览下拉框,优先恢复页面预览项。 */ void populateFlowGaugeCombo(); /** @brief 按当前选中流量记录的真实相填充显示相下拉框;至多 1 项时隐藏整行。 */ @@ -84,7 +90,10 @@ private: /** @brief 返回记录的默认显示相:优先井别参考相,否则记录中第一个有真实数据的相。 */ NM_PHASE_TYPE defaultDisplayPhase(const nmFlowGaugeRecord* pRecord) const; - /** @brief 按 m_pWell->getSelectedFlowGaugeCode() 在流量记录列表中查找当前选中记录。 */ + /** @brief 在缓存中查找当前预览的压力记录。 */ + const nmPressureGaugeRecord* currentPressureRecord() const; + + /** @brief 在缓存中查找当前预览的流量记录。 */ const nmFlowGaugeRecord* currentFlowRecord() const; /** @brief 重新获取框架单位组并同步双行表头。 */ @@ -162,11 +171,14 @@ private: int m_nSelectedFlowSegment; QWidget* m_pRecordSelectionBar; ///< 顶部压力/流量记录与显示相下拉框所在行容器。 - QComboBox* m_pPressureGaugeCombo; ///< 当前压力记录只读展示,itemData 存 Gauge Code。 - QComboBox* m_pFlowGaugeCombo; ///< 当前流量记录只读展示,itemData 存 Gauge Code。 + QComboBox* m_pPressureGaugeCombo; ///< 压力记录预览选择,itemData 存 Gauge Code。 + QComboBox* m_pFlowGaugeCombo; ///< 流量记录预览选择,itemData 存 Gauge Code。 QComboBox* m_pDisplayPhaseCombo; ///< 显示相下拉框,itemData 存 NM_PHASE_TYPE。 QWidget* m_pDisplayPhaseContainer; ///< 承载显示相下拉框与标签,整体隐藏用。 QPushButton* m_pCheckDataButton; ///< 临时“检查数据”诊断按钮,只读展示用。 NM_PHASE_TYPE m_eDisplayPhase; ///< 当前预览的流量相,纯展示状态,不写回井对象。 + QString m_sPreviewPressureGaugeCode; ///< 当前页面预览的压力记录,不持久化。 + QString m_sPreviewFlowGaugeCode; ///< 当前页面预览的流量记录,不持久化。 + QVector m_vecPressureGaugeRecords; ///< 压力记录页面缓存。 QVector m_vecFlowGaugeRecords; ///< 每次填充流量下拉框时缓存的记录列表,供 currentFlowRecord() 安全返回内部指针。 }; diff --git a/Src/nmNum/nmSubWxs/nmWellPressureFlowPage.cpp b/Src/nmNum/nmSubWxs/nmWellPressureFlowPage.cpp index 1529215b..cc68567e 100644 --- a/Src/nmNum/nmSubWxs/nmWellPressureFlowPage.cpp +++ b/Src/nmNum/nmSubWxs/nmWellPressureFlowPage.cpp @@ -127,7 +127,71 @@ QString formatGaugeRecordLabel(const QString& sGaugeName, return sGaugeCode.isEmpty() ? sGaugeName : sGaugeCode; } -// 统一向压力/流量记录下拉框追加一项:身份无效的记录禁用不可选,空/损坏记录仍可选但追加提示后缀。 +QString gaugeMetadataText(const QString& sText) +{ + return sText.trimmed().isEmpty() + ? nmWellPressureFlowPage::tr("(none)") : sText; +} + +QString gaugeNameText(const QString& sGaugeName) +{ + return sGaugeName.trimmed().isEmpty() + ? nmWellPressureFlowPage::tr("(unnamed)") : sGaugeName; +} + +QString gaugeRecordToolTip(const QString& sGaugeName, + const QString& sGaugeCode, + const QString& sGaugeTime) +{ + QStringList listLines; + listLines << nmWellPressureFlowPage::tr("Curve name: %1") + .arg(gaugeNameText(sGaugeName)); + listLines << nmWellPressureFlowPage::tr("Gauge Code: %1") + .arg(gaugeMetadataText(sGaugeCode)); + listLines << nmWellPressureFlowPage::tr("Measurement time: %1") + .arg(gaugeMetadataText(sGaugeTime)); + return listLines.join(QLatin1String("\n")); +} + +void disableGaugeComboItem(QComboBox* pCombo, int nItemIndex) +{ + QStandardItemModel* pModel = + qobject_cast(pCombo->model()); + if (pModel == nullptr) + { + return; + } + QStandardItem* pItem = pModel->item(nItemIndex); + if (pItem != nullptr) + { + pItem->setFlags(pItem->flags() & ~Qt::ItemIsEnabled); + } +} + +void updatePreviewComboToolTip(QComboBox* pCombo) +{ + if (pCombo == nullptr || pCombo->currentIndex() < 0 || + pCombo->itemData(pCombo->currentIndex()).toString().isEmpty()) + { + if (pCombo != nullptr) + { + pCombo->setToolTip(QString()); + } + return; + } + + QString sToolTip = pCombo->itemData( + pCombo->currentIndex(), Qt::ToolTipRole).toString(); + if (!sToolTip.isEmpty()) + { + sToolTip += QLatin1Char('\n'); + } + sToolTip += nmWellPressureFlowPage::tr( + "Preview only; calculation settings are unchanged."); + pCombo->setToolTip(sToolTip); +} + +// 统一向压力/流量记录下拉框追加一项;异常记录保留状态提示但不可选。 void appendGaugeComboItem(QComboBox* pCombo, const QString& sGaugeName, const QString& sGaugeCode, @@ -151,18 +215,13 @@ void appendGaugeComboItem(QComboBox* pCombo, } pCombo->addItem(sLabel, sGaugeCode); - if (eStatus == NM_GaugeRecord_InvalidIdentity) + const int nItemIndex = pCombo->count() - 1; + pCombo->setItemData(nItemIndex, + gaugeRecordToolTip(sGaugeName, sGaugeCode, sGaugeTime), + Qt::ToolTipRole); + if (eStatus != NM_GaugeRecord_Usable) { - QStandardItemModel* pModel = - qobject_cast(pCombo->model()); - if (pModel != nullptr) - { - QStandardItem* pItem = pModel->item(pCombo->count() - 1); - if (pItem != nullptr) - { - pItem->setFlags(pItem->flags() & ~Qt::ItemIsEnabled); - } - } + disableGaugeComboItem(pCombo, nItemIndex); } } @@ -686,6 +745,10 @@ void nmWellPressureFlowPage::setWell(nmDataWellBase* pWell) } m_pWell = pWell; + m_sPreviewPressureGaugeCode = pWell == nullptr + ? QString() : pWell->getSelectedPressureGaugeCode(); + m_sPreviewFlowGaugeCode = pWell == nullptr + ? QString() : pWell->getSelectedFlowGaugeCode(); resetDataViews(); } @@ -697,17 +760,34 @@ void nmWellPressureFlowPage::refreshData() return; } - // 第一步:先刷新记录下拉框,确保当前选中 Code、显示相与后续取点保持一致。 + // 第一步:恢复页面自己的预览记录,不修改井对象保存的计算记录选择。 populatePressureGaugeCombo(); populateFlowGaugeCombo(); populateDisplayPhaseCombo(currentFlowRecord()); - // 第二步:井数据只复制到页面基准副本,后续显示换算不会回写井对象; - // 流量点按当前展示相读取,切换展示相不影响井别、m_nIndexF 或求解器输入。 - QVector vecRawPressurePoints = - m_pWell->getPressurePoints(); - QVector vecRawFlowPoints = - m_pWell->getFlowPoints(m_eDisplayPhase); + // 第二步:直接从预览记录复制数据,后续记录、相别和单位切换都不回写井对象。 + const nmPressureGaugeRecord* pPressureRecord = currentPressureRecord(); + const nmFlowGaugeRecord* pFlowRecord = currentFlowRecord(); + QVector vecRawPressurePoints = pPressureRecord == nullptr + ? QVector() : pPressureRecord->vecPressurePoints; + QVector vecRawFlowPoints; + if (pFlowRecord != nullptr) + { + switch (m_eDisplayPhase) + { + case PHASE_Oil: + vecRawFlowPoints = pFlowRecord->vecOilPoints; + break; + case PHASE_Gas: + vecRawFlowPoints = pFlowRecord->vecGasPoints; + break; + case PHASE_Water: + vecRawFlowPoints = pFlowRecord->vecWaterPoints; + break; + default: + break; + } + } // 第三步:单位服务可能晚于页面构造完成,再刷新一次可用单位组。 initializeUnitSupport(); @@ -750,6 +830,8 @@ void nmWellPressureFlowPage::refreshData() void nmWellPressureFlowPage::clearData() { m_pWell = nullptr; + m_sPreviewPressureGaugeCode.clear(); + m_sPreviewFlowGaugeCode.clear(); resetDataViews(); } @@ -841,6 +923,47 @@ void nmWellPressureFlowPage::slotFlowChartPointClicked(double dTimePoint) findFlowSegmentByTableTime(dTableTimePoint)); } +void nmWellPressureFlowPage::slotPressureGaugePreviewChanged(int nIndex) +{ + if (m_pWell == nullptr || nIndex < 0) + { + return; + } + + const QString sGaugeCode = + m_pPressureGaugeCombo->itemData(nIndex).toString(); + if (sGaugeCode.isEmpty() || + sGaugeCode == m_sPreviewPressureGaugeCode) + { + updatePreviewComboToolTip(m_pPressureGaugeCombo); + return; + } + + m_sPreviewPressureGaugeCode = sGaugeCode; + refreshData(); +} + +void nmWellPressureFlowPage::slotFlowGaugePreviewChanged(int nIndex) +{ + if (m_pWell == nullptr || nIndex < 0) + { + return; + } + + const QString sGaugeCode = + m_pFlowGaugeCombo->itemData(nIndex).toString(); + if (sGaugeCode.isEmpty() || sGaugeCode == m_sPreviewFlowGaugeCode) + { + updatePreviewComboToolTip(m_pFlowGaugeCombo); + return; + } + + m_sPreviewFlowGaugeCode = sGaugeCode; + m_eDisplayPhase = defaultDisplayPhase(currentFlowRecord()); + m_nSelectedFlowSegment = -1; + refreshData(); +} + void nmWellPressureFlowPage::slotDisplayPhaseChanged(int nIndex) { if (m_pWell == nullptr || nIndex < 0) @@ -1025,16 +1148,14 @@ void nmWellPressureFlowPage::createRecordSelectionBar() m_pPressureGaugeCombo = new QComboBox(m_pRecordSelectionBar); m_pPressureGaugeCombo->setEnabled(false); m_pPressureGaugeCombo->setMinimumWidth(160); - m_pPressureGaugeCombo->setToolTip( - tr("This page only displays the selected record.")); + m_pPressureGaugeCombo->setMaxVisibleItems(16); QLabel* pFlowLabel = new QLabel( tr("Flow Record"), m_pRecordSelectionBar); m_pFlowGaugeCombo = new QComboBox(m_pRecordSelectionBar); m_pFlowGaugeCombo->setEnabled(false); m_pFlowGaugeCombo->setMinimumWidth(160); - m_pFlowGaugeCombo->setToolTip( - tr("This page only displays the selected record.")); + m_pFlowGaugeCombo->setMaxVisibleItems(16); // 显示相是纯展示状态,整体容器随记录是否为多相含数据而隐藏/显示。 m_pDisplayPhaseContainer = new QWidget(m_pRecordSelectionBar); @@ -1063,6 +1184,14 @@ void nmWellPressureFlowPage::createRecordSelectionBar() pBarLayout->addStretch(1); pBarLayout->addWidget(m_pCheckDataButton); + connect(m_pPressureGaugeCombo, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotPressureGaugePreviewChanged(int))); + connect(m_pFlowGaugeCombo, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotFlowGaugePreviewChanged(int))); connect(m_pDisplayPhaseCombo, SIGNAL(currentIndexChanged(int)), this, @@ -1090,25 +1219,48 @@ void nmWellPressureFlowPage::populatePressureGaugeCombo() return; } - QVector vecRecords = - m_pWell->getPressureRecords(); - m_pPressureGaugeCombo->setEnabled(false); - m_pPressureGaugeCombo->addItem(tr("None"), QString()); + m_vecPressureGaugeRecords = m_pWell->getPressureRecords(); - const QString sSelectedCode = m_pWell->getSelectedPressureGaugeCode(); - int nCurrentIndex = 0; - for (int nIndex = 0; nIndex < vecRecords.size(); ++nIndex) + int nPreviewIndex = -1; + int nCalculationIndex = -1; + int nFirstUsableIndex = -1; + const QString sCalculationCode = + m_pWell->getSelectedPressureGaugeCode(); + for (int nIndex = 0; nIndex < m_vecPressureGaugeRecords.size(); ++nIndex) { - const nmPressureGaugeRecord& oRecord = vecRecords[nIndex]; + const nmPressureGaugeRecord& oRecord = + m_vecPressureGaugeRecords[nIndex]; appendGaugeComboItem(m_pPressureGaugeCombo, oRecord.sGaugeName, oRecord.sGaugeCode, oRecord.sGaugeTime, oRecord.eStatus); - if (oRecord.sGaugeCode == sSelectedCode) + const int nItemIndex = m_pPressureGaugeCombo->count() - 1; + if (oRecord.eStatus != NM_GaugeRecord_Usable) { - nCurrentIndex = nIndex + 1; + continue; + } + if (nFirstUsableIndex < 0) + { + nFirstUsableIndex = nItemIndex; + } + if (oRecord.sGaugeCode == m_sPreviewPressureGaugeCode) + { + nPreviewIndex = nItemIndex; + } + if (oRecord.sGaugeCode == sCalculationCode) + { + nCalculationIndex = nItemIndex; } } + const int nCurrentIndex = nPreviewIndex >= 0 + ? nPreviewIndex : (nCalculationIndex >= 0 + ? nCalculationIndex : (nFirstUsableIndex >= 0 + ? nFirstUsableIndex : -1)); m_pPressureGaugeCombo->setCurrentIndex(nCurrentIndex); + m_pPressureGaugeCombo->setEnabled(nFirstUsableIndex >= 0); + m_sPreviewPressureGaugeCode = nCurrentIndex >= 0 + ? m_pPressureGaugeCombo->itemData(nCurrentIndex).toString() + : QString(); + updatePreviewComboToolTip(m_pPressureGaugeCombo); m_pPressureGaugeCombo->blockSignals(bSignalsWereBlocked); } @@ -1132,23 +1284,45 @@ void nmWellPressureFlowPage::populateFlowGaugeCombo() // 缓存整份记录列表供 currentFlowRecord() 安全返回内部指针,记录内容切换记录时不变。 m_vecFlowGaugeRecords = m_pWell->getFlowRecords(); - m_pFlowGaugeCombo->setEnabled(false); - m_pFlowGaugeCombo->addItem(tr("None"), QString()); - const QString sSelectedCode = m_pWell->getSelectedFlowGaugeCode(); - int nCurrentIndex = 0; + int nPreviewIndex = -1; + int nCalculationIndex = -1; + int nFirstUsableIndex = -1; + const QString sCalculationCode = m_pWell->getSelectedFlowGaugeCode(); for (int nIndex = 0; nIndex < m_vecFlowGaugeRecords.size(); ++nIndex) { const nmFlowGaugeRecord& oRecord = m_vecFlowGaugeRecords[nIndex]; appendGaugeComboItem(m_pFlowGaugeCombo, oRecord.sGaugeName, oRecord.sGaugeCode, oRecord.sGaugeTime, oRecord.eStatus); - if (oRecord.sGaugeCode == sSelectedCode) + const int nItemIndex = m_pFlowGaugeCombo->count() - 1; + if (oRecord.eStatus != NM_GaugeRecord_Usable) + { + continue; + } + if (nFirstUsableIndex < 0) + { + nFirstUsableIndex = nItemIndex; + } + if (oRecord.sGaugeCode == m_sPreviewFlowGaugeCode) + { + nPreviewIndex = nItemIndex; + } + if (oRecord.sGaugeCode == sCalculationCode) { - nCurrentIndex = nIndex + 1; + nCalculationIndex = nItemIndex; } } + const int nCurrentIndex = nPreviewIndex >= 0 + ? nPreviewIndex : (nCalculationIndex >= 0 + ? nCalculationIndex : (nFirstUsableIndex >= 0 + ? nFirstUsableIndex : -1)); m_pFlowGaugeCombo->setCurrentIndex(nCurrentIndex); + m_pFlowGaugeCombo->setEnabled(nFirstUsableIndex >= 0); + m_sPreviewFlowGaugeCode = nCurrentIndex >= 0 + ? m_pFlowGaugeCombo->itemData(nCurrentIndex).toString() + : QString(); + updatePreviewComboToolTip(m_pFlowGaugeCombo); m_pFlowGaugeCombo->blockSignals(bSignalsWereBlocked); } @@ -1273,17 +1447,25 @@ NM_PHASE_TYPE nmWellPressureFlowPage::defaultDisplayPhase( return PHASE_UNKNOWN; } -const nmFlowGaugeRecord* nmWellPressureFlowPage::currentFlowRecord() const +const nmPressureGaugeRecord* nmWellPressureFlowPage::currentPressureRecord() const { - if (m_pWell == nullptr) + for (int nIndex = 0; nIndex < m_vecPressureGaugeRecords.size(); ++nIndex) { - return nullptr; + if (m_vecPressureGaugeRecords[nIndex].sGaugeCode == + m_sPreviewPressureGaugeCode) + { + return &m_vecPressureGaugeRecords[nIndex]; + } } + return nullptr; +} - const QString sSelectedCode = m_pWell->getSelectedFlowGaugeCode(); +const nmFlowGaugeRecord* nmWellPressureFlowPage::currentFlowRecord() const +{ for (int nIndex = 0; nIndex < m_vecFlowGaugeRecords.size(); ++nIndex) { - if (m_vecFlowGaugeRecords[nIndex].sGaugeCode == sSelectedCode) + if (m_vecFlowGaugeRecords[nIndex].sGaugeCode == + m_sPreviewFlowGaugeCode) { return &m_vecFlowGaugeRecords[nIndex]; } @@ -1686,6 +1868,11 @@ void nmWellPressureFlowPage::resetDataViews() m_vecRawFlowPoints.clear(); m_vecTableFlowPoints.clear(); m_nSelectedFlowSegment = -1; + if (m_pWell == nullptr) + { + m_sPreviewPressureGaugeCode.clear(); + m_sPreviewFlowGaugeCode.clear(); + } // 井绑定切换或清空时先清空并禁用三个记录/相下拉框,等待 refreshData() 重新填充。 if (m_pPressureGaugeCombo != nullptr) @@ -1693,6 +1880,7 @@ void nmWellPressureFlowPage::resetDataViews() bool bSignalsWereBlocked = m_pPressureGaugeCombo->blockSignals(true); m_pPressureGaugeCombo->clear(); m_pPressureGaugeCombo->setEnabled(false); + m_pPressureGaugeCombo->setToolTip(QString()); m_pPressureGaugeCombo->blockSignals(bSignalsWereBlocked); } if (m_pFlowGaugeCombo != nullptr) @@ -1700,8 +1888,10 @@ void nmWellPressureFlowPage::resetDataViews() bool bSignalsWereBlocked = m_pFlowGaugeCombo->blockSignals(true); m_pFlowGaugeCombo->clear(); m_pFlowGaugeCombo->setEnabled(false); + m_pFlowGaugeCombo->setToolTip(QString()); m_pFlowGaugeCombo->blockSignals(bSignalsWereBlocked); } + m_vecPressureGaugeRecords.clear(); m_vecFlowGaugeRecords.clear(); if (m_pDisplayPhaseCombo != nullptr) { diff --git a/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp b/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp index 5a82e1b7..023a5e9e 100644 --- a/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp +++ b/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -125,6 +126,46 @@ QString gaugeRecordLabel(const QString& sGaugeName, return sLabel; } +QString gaugeRecordToolTip(const QString& sGaugeName, + const QString& sGaugeCode, const QString& sGaugeTime) +{ + const QString sName = sGaugeName.trimmed().isEmpty() + ? nmWxIncludeOtherWells::tr("(unnamed)") : sGaugeName; + const QString sCode = sGaugeCode.trimmed().isEmpty() + ? nmWxIncludeOtherWells::tr("None") : sGaugeCode; + const QString sTime = sGaugeTime.trimmed().isEmpty() + ? nmWxIncludeOtherWells::tr("None") : sGaugeTime; + QStringList listLines; + listLines << nmWxIncludeOtherWells::tr("Curve name: %1").arg(sName); + listLines << nmWxIncludeOtherWells::tr("Gauge Code: %1").arg(sCode); + listLines << nmWxIncludeOtherWells::tr("Measurement time: %1").arg(sTime); + return listLines.join(QLatin1String("\n")); +} + +void appendGaugeRecordItem(QComboBox* pComboBox, + const QString& sGaugeName, const QString& sGaugeCode, + const QString& sGaugeTime) +{ + pComboBox->addItem(gaugeRecordLabel( + sGaugeName, sGaugeCode, sGaugeTime), sGaugeCode); + pComboBox->setItemData(pComboBox->count() - 1, + gaugeRecordToolTip(sGaugeName, sGaugeCode, sGaugeTime), + Qt::ToolTipRole); +} + +void updateGaugeComboToolTip(QComboBox* pComboBox) +{ + if(pComboBox == nullptr || pComboBox->currentIndex() < 0) { + return; + } + QString sToolTip = pComboBox->itemData( + pComboBox->currentIndex(), Qt::ToolTipRole).toString(); + if(sToolTip.isEmpty()) { + sToolTip = pComboBox->currentText(); + } + pComboBox->setToolTip(sToolTip); +} + // 流动段索引是一基索引;统计段数时必须先排除框架可能写入的公共占位行。 int flowRecordSegmentCount(const nmFlowGaugeRecord& oRecord) { @@ -588,6 +629,7 @@ void nmWxIncludeOtherWells::populateRateCombo( const bool bSignalsWereBlocked = pComboBox->blockSignals(true); pComboBox->clear(); pComboBox->addItem(tr("None"), QString()); + pComboBox->setItemData(0, tr("None"), Qt::ToolTipRole); // 选择控件只展示当前相真正可用的记录;异常记录仍可在“检查数据”中查看。 for(int nIndex = 0; nIndex < data.m_vecFlowRecords.size(); ++nIndex) { @@ -595,9 +637,8 @@ void nmWxIncludeOtherWells::populateRateCombo( if(!isSelectableFlowPhase(oRecord, ePhase)) { continue; } - pComboBox->addItem(gaugeRecordLabel( - oRecord.sGaugeName, oRecord.sGaugeCode, oRecord.sGaugeTime), - oRecord.sGaugeCode); + appendGaugeRecordItem(pComboBox, + oRecord.sGaugeName, oRecord.sGaugeCode, oRecord.sGaugeTime); } int nCurrentIndex = 0; @@ -608,7 +649,7 @@ void nmWxIncludeOtherWells::populateRateCombo( } } pComboBox->setCurrentIndex(nCurrentIndex); - pComboBox->setToolTip(pComboBox->currentText()); + updateGaugeComboToolTip(pComboBox); pComboBox->blockSignals(bSignalsWereBlocked); } @@ -621,20 +662,20 @@ void nmWxIncludeOtherWells::populatePressureCombo( const bool bSignalsWereBlocked = pComboBox->blockSignals(true); pComboBox->clear(); pComboBox->addItem(tr("None"), QString()); + pComboBox->setItemData(0, tr("None"), Qt::ToolTipRole); for(int nIndex = 0; nIndex < data.m_vecPressureRecords.size(); ++nIndex) { const nmPressureGaugeRecord& oRecord = data.m_vecPressureRecords[nIndex]; if(!isSelectablePressureRecord(oRecord)) { continue; } - pComboBox->addItem(gaugeRecordLabel( - oRecord.sGaugeName, oRecord.sGaugeCode, oRecord.sGaugeTime), - oRecord.sGaugeCode); + appendGaugeRecordItem(pComboBox, + oRecord.sGaugeName, oRecord.sGaugeCode, oRecord.sGaugeTime); } const int nCurrentIndex = pComboBox->findData( data.m_sPressureGaugeCode); pComboBox->setCurrentIndex(nCurrentIndex < 0 ? 0 : nCurrentIndex); - pComboBox->setToolTip(pComboBox->currentText()); + updateGaugeComboToolTip(pComboBox); pComboBox->blockSignals(bSignalsWereBlocked); } @@ -779,7 +820,7 @@ void nmWxIncludeOtherWells::onPressureSourceChanged(int nIndex) } m_vecWellData[nRow].m_sPressureGaugeCode = pComboBox->itemData(nIndex).toString(); - pComboBox->setToolTip(pComboBox->currentText()); + updateGaugeComboToolTip(pComboBox); } void nmWxIncludeOtherWells::onFlowSegmentChanged(int nIndex)