From 49dd3f0446d205cffba9397253e39a1626bdda21 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Sat, 14 May 2011 15:54:04 +0200 Subject: [PATCH] Improve Cue Sheet parser: Calculate duration of each track + make sure each track# isn't used multiple times + refactored error codes into an enum. --- etc/Translation/Blank.ts | 101 ++++++++++++++++++ etc/Translation/LameXP_DE.ts | 101 ++++++++++++++++++ etc/Translation/LameXP_ES.ts | 101 ++++++++++++++++++ etc/Translation/LameXP_FR.ts | 101 ++++++++++++++++++ etc/Translation/LameXP_IT.ts | 101 ++++++++++++++++++ etc/Translation/LameXP_KR.ts | 101 ++++++++++++++++++ etc/Translation/LameXP_RU.ts | 101 ++++++++++++++++++ etc/Translation/LameXP_UK.ts | 101 ++++++++++++++++++ gui/CueSheetImport.ui | 16 +-- res/localization/LameXP_DE.qm | Bin 61233 -> 61381 bytes res/localization/LameXP_ES.qm | Bin 58375 -> 58447 bytes res/localization/LameXP_FR.qm | Bin 57728 -> 57872 bytes res/localization/LameXP_IT.qm | Bin 40461 -> 40525 bytes res/localization/LameXP_KR.qm | Bin 47732 -> 47852 bytes res/localization/LameXP_RU.qm | Bin 51605 -> 51743 bytes res/localization/LameXP_UK.qm | Bin 21582 -> 21650 bytes src/Config.h | 2 +- src/Dialog_CueImport.cpp | 56 +++++++--- src/Dialog_CueImport.h | 2 + src/Model_CueSheet.cpp | 192 ++++++++++++++++++++++++++-------- src/Model_CueSheet.h | 14 ++- 21 files changed, 1024 insertions(+), 66 deletions(-) diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts index 2259d1bb..e8277f34 100644 --- a/etc/Translation/Blank.ts +++ b/etc/Translation/Blank.ts @@ -239,6 +239,95 @@ + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + + + + Discard + + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1376,6 +1465,18 @@ The LameXP shell integration has been re-enabled. + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_DE.ts b/etc/Translation/LameXP_DE.ts index 76e118cf..591f21d5 100644 --- a/etc/Translation/LameXP_DE.ts +++ b/etc/Translation/LameXP_DE.ts @@ -239,6 +239,95 @@ Version + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + Durchsuchen... + + + Discard + Schließen + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1377,6 +1466,18 @@ Don't Show Again Nicht mehr anzeigen + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_ES.ts b/etc/Translation/LameXP_ES.ts index 9e8ea6cb..09e9db73 100644 --- a/etc/Translation/LameXP_ES.ts +++ b/etc/Translation/LameXP_ES.ts @@ -239,6 +239,95 @@ Versión + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + Navegar... + + + Discard + + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1376,6 +1465,18 @@ Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_FR.ts b/etc/Translation/LameXP_FR.ts index f9eba950..52cd9c84 100644 --- a/etc/Translation/LameXP_FR.ts +++ b/etc/Translation/LameXP_FR.ts @@ -243,6 +243,95 @@ Version + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + Explorer... + + + Discard + Abandonner + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1386,6 +1475,18 @@ Ouvrir le dossier récursivement... Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_IT.ts b/etc/Translation/LameXP_IT.ts index 6d9d6d06..e70a9081 100644 --- a/etc/Translation/LameXP_IT.ts +++ b/etc/Translation/LameXP_IT.ts @@ -239,6 +239,95 @@ + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + + + + Discard + Annulla + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1377,6 +1466,18 @@ Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_KR.ts b/etc/Translation/LameXP_KR.ts index 3a887a38..6a6b3080 100644 --- a/etc/Translation/LameXP_KR.ts +++ b/etc/Translation/LameXP_KR.ts @@ -239,6 +239,95 @@ 버전 + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + 찾아보기... + + + Discard + 닫기 + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1376,6 +1465,18 @@ Don't Show Again 다시 표시하지 않음 + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_RU.ts b/etc/Translation/LameXP_RU.ts index 6ef9bb0e..d8d96de5 100644 --- a/etc/Translation/LameXP_RU.ts +++ b/etc/Translation/LameXP_RU.ts @@ -239,6 +239,95 @@ Версия + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + Выбрать... + + + Discard + Отменить + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1378,6 +1467,18 @@ Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/etc/Translation/LameXP_UK.ts b/etc/Translation/LameXP_UK.ts index 217dd0e1..620abed1 100644 --- a/etc/Translation/LameXP_UK.ts +++ b/etc/Translation/LameXP_UK.ts @@ -239,6 +239,95 @@ Версія + + CueImportDialog + + Import Cue Sheet + + + + The following Cue Sheet will be split and imported into LameXP. + + + + Loading Cue Sheet file, please be patient... + + + + An unknown error has occured! + + + + The file could not be opened for reading! + + + + The file does not look like a valid Cue Sheet disc image file! + + + + Could not find a supported audio track in the Cue Sheet! + + + + Failed to load the Cue Sheet file: + + + + Cue Sheet Error + + + + + CueSheetImport + + Import Cue Sheet + + + + Output Directory + + + + Browse... + + + + Discard + Відмінити + + + + CueSheetModel + + No. + + + + File / Track + + + + Index + + + + File %1 + + + + Track %1 + + + + Unknown Artist + + + + Unknown Title + + + DecoderRegistry @@ -1376,6 +1465,18 @@ Don't Show Again + + Import Cue Sheet + + + + Open Cue Sheet + + + + Cue Sheet File + + MetaInfo diff --git a/gui/CueSheetImport.ui b/gui/CueSheetImport.ui index 9c86aa7d..7ed6d920 100644 --- a/gui/CueSheetImport.ui +++ b/gui/CueSheetImport.ui @@ -219,6 +219,9 @@ :/icons/folder_explore.png:/icons/folder_explore.png + + false + @@ -272,9 +275,6 @@ 16 - - false - @@ -312,8 +312,10 @@ - abortButton imprtButton + abortButton + editOutputDir + browseButton treeView @@ -347,6 +349,8 @@ + + @@ -356,8 +360,8 @@ close() - 609 - 408 + 688 + 451 310 diff --git a/res/localization/LameXP_DE.qm b/res/localization/LameXP_DE.qm index c7f40f2da84adf1f75028d0a7490755ecc090720..fb7d81fc40c5b75bb60ac47d5f91db471af3b26e 100644 GIT binary patch delta 3841 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 F{|}V|j0pe$ delta 3763 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 diff --git a/res/localization/LameXP_ES.qm b/res/localization/LameXP_ES.qm index 18feb6cff0e75c0f0822ccaffe4790d0ac1b88ff..0ab8505b805d74dc2aac1247c7de37c54aefa011 100644 GIT binary patch delta 3479 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 delta 3461 zcmXX}dt8n8AAg_o+|GHh`o(~~=qA+AuYsB8VV!skc)tK0Qk;Q( z=ixOZ66m)dLsqW>N>dQfz6@A*8G*;$fYU01Ix>OZRRnqG0BiCZ;@!yB1?DjP9=+;toHIo!kRReHY_g z?h=`i7?-jSC@Mj0X?I|wJ3jPgftO!mPOEqzDg<+z_XG|;#LDVhK|ZUJKhaPDcm9WV{W^-+wl*FUJr31!~qz8a; zpK(DXkxQ*Ler{&ralXa^-)X?RuEwIY7r>V8#uB@8bBe>wSUPD1kh{XTKiZXvij8;M zP9+tG8sf%!A`#e&yBg)X?g!?@=cp<7ra z&^$xvwz&(?Y>&`m$rhkzwa`y|PQgP6Y}^g#0m1%$g&)xWlrXBsK-FIsLK`RZ51vB! ze=kfD#yqqFopv#HrrMVYvH$&^EhNrjhhxtPa~=OpbV`{2-|znjDZMWO)A|V+;-5q) zOek&q)R>$8$DSIe3>N<_V58lw-X2V z=>t?g5yKXI3VblTA)YxbPHz#+0{4p_CuRZP+QY;Yo!%boC@%dXo??^5<)wsby-~~! zJi^f+HpKP4#dYJ40_DEq*5ak?V7|C*B2~U;thg(ZcJw+R7AtI|)JH5SUqXMc6OY_} z%0f}Qu68?3*>c@`n@<#iN{FcLF_y4jue~xGe?{t&3el5m*XTQw`1GG^Q7b# zrBvisQks7SW1Y0BstMpxA?2K-a@seM@|N$UbbpjKJ~GlvL!^QsZRy$B0n+x1Y-9an zY3GV^&du@CiJmo7fK4i&aR3NiEnWF88<=ues`Z%%>>&TP z95sRXR&AFTm9X%$b#lS3F2L63@~&ANYcsCN$Ne~kn%@;v3~|#v3lc9m@U4LKc#%{QgZHm33HoVqs!Sv`PMfi6)&kIo%_HZ>=!7H6d=B zB22x)8*_wYn|xZHAmIj6U*BNnO*Fk%aFmUxreN&=iS?~F1@HNX2c0)Xn5ZDXO{V0R zBxX=xLtOu*DbMJ0lohk2U5%}gO)4F?AT#&J*T@!LRh1Z%Y zs~F|?O;`QN)AFxPH-ntG9-f&Vc|`-xtxc~6zDM3%%) zaW5MeWHa;162`Bs=I!&S!12w^MNim}*~@$+XbLIKF;~B2Aw$Z{-^JO}dH;B1z8)9C zAG(_Fma?OW@6Ert5ZcT_^Q)oGK_8E?XS|wE9%d^o|D>N2;srufOK> ztXA^}w*i*a{>RjNfs2XgEA`R(Llk3g z)&5r}Lc4W_McPtB&T1{@+*6Dj8lp$0rTfu`z$a5JeXT4&7A=0AIJTlTTZW{ugC*@P zBmTX6>`k#mK4d}1N-eP#QrNSlCHCsK+|W}j^T)R5)W2g%wQ1Cp*|J(=p%=tpjMlsz9C)p4p#`S>#ytitXpAS_ zW7k4-Qtf3A&_enW!tU*~kg#+fJf|U6pVq?u6acZZdLJ|x9L`&Oj0n=(>gJihzveujoLtJ59V0oTkt)% zgVuy}mHyvcXw4bv%!8j>*XHm;M_225g@`y9t(zTK*o>*x-KF$*?hn=@epL5VS8LhZ zNx=pGmA&ayqYSIzeq z+5WV8a%}ClJ@V!$;f}Vt{*ENZHGCiu0&v>R!nbCn)p%i^;UL&Bx6@6O78JaOxPs*b9<0O6l z(wBffQMXSd4jq&9^ytSd=(%3dhIqyH(088?CN9qU!MXYTKjEBS{`n$$WvO1VsSOFf zq+i|t25k|xN53Z6fb+Hbtt0%vx<>zX_Hy1S-kJt{H(6jQ9@)jZ=icwFAHK6U#q<20 F{{c(13N!!! diff --git a/res/localization/LameXP_FR.qm b/res/localization/LameXP_FR.qm index fb5753ba83930d5ba22aab39fd3032b001dfd0a8..f2d4b746d72e68923557e77406decfd599dab008 100644 GIT binary patch delta 3486 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 TnU`E0@WKDzJ2;|4r?378Il&RC delta 3430 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 F{s)*}sF?r& diff --git a/res/localization/LameXP_KR.qm b/res/localization/LameXP_KR.qm index 72a00e1837fb45f97b76f6abd6884508446381e2..80ef04e756e54a06f4cffa8eb6394a67bd89ca91 100644 GIT binary patch delta 3763 zcmZ8kdq9qN8@}K7Ilb@mKF|AD2T>{|(#b-!q77Mji$QF0nN6uvd}rh`K&)!R#D z$e9#ve4A}Krdir7WMLm>!kp$X-;9#)YW?^9b@x2a`}_Uw`?{|Cx_`ZRp?>sVb&-{E z9}#^(akDZ~To{n9C9 zxS1&ZNp~#S-5o2lD3qIzM4wRTtPG<3l{BFtmnf%^q8iVTk>X{FYAPq%eSxN*MCM5? zG((5j_m}RN_YuvQJ(OrsDn&cq0YZZ*I{V*9IGB=ZhY)2K)5pV+;C_~t+b0uEZlV>v zhY@WYO9jc>iCn*=igo9SoNmxITf~_&sH*-wAo(}d{dm(zG$D%4J;y@fI9>b5mS}aV ziWBhs@ne-mSpw14VwKe~SE9kiDx1t(MB4*ZKBE(fd>d3B>~kmD&{H*@13mBQRdEru zM5-uN!o*%gjz(3{1MFieR~4T*2wKOgDm!)(&B{|X>7Ehoi&nLi1>7e3aF6QB4L}$= zUUls{Aa{0BUDur^vWQb%ckN5m-%0h?d*2XMR;&J6fQ@E%sFhMYr~St?L2YBqR`;K} z0t6^(&o-#Xtw!xuL3zWygv3rmGim4~W#))#DU3w>Qe9O4>LoDGK?}%6;>t2la&Ot<0 zxy;bqT|{1KOaS{5?Ldsd5(&GlWX3lH5)DgXrd(8^B|4d@mYGEEDNJP7clTY)^gm=M z$Rz=PctK*JOj6eej~Zs#5>z-h%rY1eyCg~@*JJkj(s%m(%`(bQ>7rPY2Y zt}nCm+6JOeQ<>`eV4?z%sku0qXy+v6X!|?pJy)i&`2x}S66S|W4Tx=EE=@)uA7?Ya z=NCdjiQcSgehN`)Im`XC@hg@eiwftMSp8E2dS^M?<5>li@-6G^*+tPf_QQdGApAW0 zp}#*4A~qs@CDG`x?pWE*F0cy&C6?^cWyM4X=Caw!DRfe~t6EDqCphFyeG?6~@cUlENnahHBJ z5lyS(TKv-BK|gRUzrr+!^x#^JSeLPcyHYa>WtMU`w*be@iQKKg#VDW;_n-znwY-$; zoU#Ox-PE6FOkbb}j`B*&R`g0a@2r4;upRtBHUSkqBzJ2QDD!dw%+6AQQ5ckNW}zWzXOf;(-6I%lxVu6tE+nuRJh_ zXzkbhfhEHr+1LpFWZ*3{pTvLX*ap)o$xRWY~Q) ze?J6?+BmlM@YbSvf%&bFj3@}!pI;buEz3xyKnIU6x=rZ4zYTa$)=Fcd_pnVP~(=m}3)#J=#W4c}1wr^oHps2%qagac;42 z^woTrz&WAuU3a2FH{ts4kWR>t!i^I-7&nE&oegh^#hi2hBv2)%GYSjrJob6n5!xO zjV0Q2RI~YR69#j=W?yk0Trxv*AkGX8&bXv$Y%&w^UYgb*P@FPGb0fqSjp7^$HDPmi61<;gi-jJ z7_?ys22g;Q7$idcwc@OiRPLRb`hgBM%?Cog4LSY?t`sYEBV;7R zS?B^i8=zK=E;t{REwbf+Q#OY%HK!O#&>XLNe+OtEK)Os0}I_W;0;f909>T>iF zM7dkHQR+(kg>H)j29U2wx8o-E+4i??clA9Cr182_7W*+m?Txy6a|;aYknVzHiwf&> z7wrZSz1yK{eT)T@uIQeP2*Utbt!od*!Nb={6z7cZMu|D?L)6n(vfugue$!8Kh&hM0 ztdN}4pfDm|a&2!z`+G~nEi7=$vycq=5cAMSQpohdXv;z=T!A(`jWeb25rBH&Y$-gV z5Q(I9$9)5(h%S}7_K>17rr@9qDdi>-$nfuu##||_@ekZlVx&wDaGZZtT3e0htlm=b zC?FW=Bb6-;Cz4yGa;s@TvP9ZjUV-0frG0Y_g0e`d`Y(Ui&I1NT{z^dH9?Ft8G-ElCaIlBKq#pP()8N%y*<`(^2=9*LG7kzVFn!_l*4 zO$(l939_y8GZ?3}?A?@%QQ$256@e<>k#c+)5b}R5Cu})G9%OzgC)?qN4kP50La2T9 z9eG1lIc7xpzy zp32`joFbZ7AYa(=D@I_nd_Or5x8LdV<74MBN`vJm3exf3B)=UFe|0g-Z!bftfj#x? zMgx3(sNQjP0(>-9@8&!ZgXp~8!#D_63`@ON4A$BDH|Tv0^-w^Nesm}{v`Nz^wob#P z%V1h4+Zb2tlV2ATed3|dvd5L7e}O)CB08jxm%c1Dhe&%*zt!R}(mbNyof8RKg7nuE zbPiqA-?9VR^A77D+-=6XR{djnFx<06|718$3$fL|dfy849?`!tW1pNCihQgJ;2cr< z&d&t8-zm;t7lO{JUdo_Oz$=VZrrM++f0Gj71%VspD3Q}aW6>5RVLRTddMa}kx?>_A zQRbHSfbCl<^Pho5SH~9-n!wv{C_AjONOAI8#Mdd1^$HqCz%{nZQ)XMLv>i~G( vJfdp%!(Zr~?M>?g2Ppc$Wl59gCMBgB7A{`2G}Uw?#PR>%9sbE5e((Fd&-1*$fBvif_)(oz#kwk;X6MK{;8raYrZbLMr zn7F~%XY_aCQt^LyE8+_m#WvyzCb&nGf;8%110644qBiKBlbiZCI4#7X4z zn(UUD6J>2B7w<447ccT&pG}k@&=A|>M2Q>7=ae;3VFdZwW4&7|@^#H2ieJ$j*LgI@ zB2)6?Vvy(x@|&1Ilxj>v&!rG0N79(evt*#~Z8YXm9?`a`6mklgM^C45I>Zihn&YbH zG;UH4qL~tnw|I($l{9|Y0ixA46kYC2w9J;Kxgx=xn`nOfSfY_pw4iNIqMV1cHny0k za{%S9x=Lg@p9)P8BR|ltirzr-UpjWB#z5r%jxN??p>Tq#hnW&BmsFg9=V>V_qufZM z0$Y{w@yr~Z`0J-I1)g#>* zBBOBCqs|?OtPiU`^*(}w2dO?y$3~N~)k-#=7tPHYsx~p0scl9tAnLtC?NB$B$kt2k z)-sJK&`Ui;`3T$|sKfs1PGl9Lo;>daj%}r$$-N>{KT^ks0neGS>eX75G0sL^)F11e zU#Lq{zXFDT)Me&viNda^%O|WMO7K?y9%TjQNb09HQ_!Ej&C#&zzWS9fs5mi1{e2ed z9p=tx>QLW?5=QBY12-*Z%;Fn?;|9jMBVy)erh8BrQL8pg_mZwe#wkpXl&wULMvMph z8FC=TrzH}$HD>(Jc@p*1F{5rm7Gu^kqgy5t+3A?zrvL4JVnW{N!Jv*`@WT-}K4GGp z{;>CA=Eb4Hp%a(|#!b)jnZ^Hqzk^xU`zle$cqW~FO*HB~Q)FC<#1Ang)#*fwC1y{B zHz>M=DZA-JwB;ppsNp}*-btqN`VA1pj=5Zkwg`r!v+;v05j z=n10DUD$1VR-lpr?Dhy~Ak&H69R{&F__2EgRFr;>EvraDFH6~Dwe?8kA$z97S)!y? z?76>zQ0x-+{0JO0!;!r)2`&_Tg}pg^3tF^S3OX zFLH^UfQM%)m-w|D>-%!4gU=x@;j%Baf}mtB=OUP8Igra+wF~Q4%;E~)s-d`2uE^U4 z4J_ogAB7W7Oy_o7MV(6%xLs>1;J*90(>-s3Df_vK83*C2_S~&IStx51SLL<{ra6(T z`V*$mrHUr1}2Cmj~7E#CFxL0M+)O-i7aa0^AyZ$)OWbK0n z4)ID=0a30KZ>69C0q%SkHj-$`GTwO??At@)J&llgoFhMI9b9*54ew(Pe3O!S-#v$6 zf{XZ}{j8yl2tH&Zknwfp!}p<}qz`;#IPl*(gI`*P0*e3Ti*|P9oG|-4SmC( z@~nmUB>oSJI+#{2f5{Q8h}_Lz+jAdgR>$9}SAjvd_(y-o05;q3gzef&l;u22C{OGTihU7&mC?}@Tj9``7@~O-gvxGqL~BnAk6tt}C0clV zG8xmQlkhbC2j=Y(;dxjwk+&fHedG(#pi#nm9X1xnYxoD)XVgrM=`%D~;WgH+fNM&= zrdM!FP~2YQ*6uVIu~^fme*l=^)1VnxbOL5luL+PqG1mf3z`p;&z8f@SG@x4VXPU%s z=$uw>v(V&Z|4OugGo)@%&l;kgP=Lx89?(v@3}{yxv{QdU zqHCPB)90aO4iB^mo#qjlw9_Ums)lBwv`M`TG6uD^c5NBrx@p=C^UOh=%i0}_z~umg zw)8zJ*UZr#^PLP1%+Ox{hQ#_@)82_mBN|?*t&R!A^HS~8a#ZeTrG06E7W{0X{qBc- zc7=&t!wsS-DWXe5BwRUE^x$!D#4xent6La+F5+NAx-;gDhZr?jM6ZX46Mr&>$V|nl zpVRUBh!|^&UX9x*u3SF`h}eo5uCZ{%DlxkesvqDW<`v$=Bn=e{yeuKoYhq#8Nsw%; zxaI3yv}U1L8om`hzap0Aw#5I7#a|9K;tF+IJmFJ-^Ayo=vZ@&BFA&f3Kw#Si@w%BW zQCk=B_KRAGw6$1m)fVJBF4km}pi(#SnNJd+el5P;1a&xDiys^S`HC7Hw-t%-IXZ3b zS;Uy;*rB#L{^Y20KJf+@2V-3yJrd!Jbe<0I$B{(_op&lKnpvhB(R4S;{HzOmgUs@O z)A^xfO2&{DT}oGp6xP?s!AAftzFy@Z6fr|LGFW6t!l*KMi6K7|>&ZF`=h z=XJW%Mx{jN2XqxVRj?^<-3`eUg&ot~H0w&#En9c@HNGEVn5BE)CjgVqT-OkYgIz5p z3b(=sCK7YTg{XBeseQpK^zNu+9(oaXEoaG6jot-WOPw3);1d@lS0f`_=8PntRFJqw zvg8}$1jIT?feJWb|5Xa?1B5#_N`XOXNW`c)?l>g{HIdWMX{R(MVH6HZkml4Nf%u!v z(a>I6RQU#1kx(ho9=%PClUDA*^U`0X%>IBd=(3bMJCI0!SIRRU3%%P(JM!{Td9k!} z@?MPUx6+*9+Rc#O$;dR@U;3QV3fD0+y`~D!QH6R_tM`yunZEm_SUCO>y;}xa-3SE!G)Z3eXJS2Ykx~WCk-TD9j$S%G(dSQxUhO_)U6D)- z!TJ)TwxHf-{oZoeNWu#JF;6TTo2ftE8tKegssF?LG{k44zp>>{BAbu;m$9A@Z@vEY z@vE4aHTt&-(&^q!|HHM(R~_{~ZiAu&_sZ;gANb`Z*+zB4b1N^X|$s#%G?pPdLn-#A&F__D-Uo)Zc3OT7gZU#0sa>{Th zqn)FiJ2#m~`&=$C+K;dOz&}5)8)6W zIL&9D{H3okQ1q9-aR6!V{)g9ZmyZO3Rh5jeu7eq>MJ1gZ%B4 zAV)BK$PXnr1Z~XdsYDjzy{fe`d4?UXcK*tgycW29?^dRcIS+~FC<`-fLHHNS;uYV( zpAm{70yuT-sH8=`Lt+P&B1_;I%qV*=2LPuj%Ap0|W%PQbV)at$PHu(Dxh)`MSekP8 scMKw*809`AW8-#8%`q&H)XIywt8f>xnu?3#nf+&EtM>c-9g5Qa2hu$-Gynhq diff --git a/res/localization/LameXP_RU.qm b/res/localization/LameXP_RU.qm index a3b7020b58ca2704a5c3979c08f5edee1211e05d..6eadece49df667c8b0008bbd256519d7682d674d 100644 GIT binary patch delta 3201 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 delta 3145 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 diff --git a/res/localization/LameXP_UK.qm b/res/localization/LameXP_UK.qm index ca60b84228bdca44a43d6c0e00fd82358d3b27ea..4217f36bb25693e8bc71d02688cd975c645f3317 100644 GIT binary patch delta 1798 zcmXX`3s6*582)zm-rak5@7{|%6j0E31c)f6h+ry3g1aaxzQN}xrbhMvp>lM|U`j)U z5W_MgG*j?FKClNA4lt%E;UhvCQ8OQ*sAc6Of_=En+?j9gJ?H%A{~rHs+^zdyk1pTc zQ43%!pmqb|C?Met;v^v40!&E)CX@p6>wp)|La3Yy_;o<|MgV-PoEUF`&=d&p5#xAn z@b3`wxE|32u{IUZ#XI1qCHV&_`ci^1^tc|dPpj1Q>+9OEls59NYq8SEp9fVfLe zoRH?kiJ3?cmjnKunAniZ1|`foQ4frG1Ie|#HTqqoSbA7yOo_K)s-@m1idI$cW}8-Kb>*Lu;H1xxfkTiIyXRej*}EE00nkJtVp zb5H$xc_1(>NnaYX3~(>j@ALJdLK*t1MSc!$n61ASxD*f?oM=C;Z?{wG=obuqSJRe> zvSC>6PQWG8U~>xxtSyFVXLYnF+%VlOo7TyOnLXdtXhZTHD^FJsaS0K^PYt1q4kI()uO> z&+Hf8(f$Rzei7DHvZ3*9Lb0uyUS4*h&0DCL7XWBk!oE6M71JhEU-^^gyM%^Ylzhw@ z;rJ9<@$4qy%o1j6NR!a)D9i!ug~E+*WlGa6bkE?ypnB2e{zhQvc`@k0Nm>yh21hs1 znv3F~nfK^@xj6b^Et$59soB2*{jZ4GPqU%^Sz`9XN=n-$=EXH|U#z(K2M=cBf>?C& z0WI}`t%#o&xH+vYSncBX~0S0!P zu5EhEam_H@n8)<{mz!>VO$!IClZ?N-MWPO!6gkt4((aO?`W+*)_oY!WiJa%#QsTkC zS>Q)$mP7?SQ>E-jWaib|iM9<=PXAsEtx+o4`~|b~P^y?;#FX!q+U(v8U%1ru-1E%F zD%miX=k>X=yRMvsw#Wh3@AExCPFuN#^Y0QXH$7Se^vjW(mv5w`-E!-4hNJIaX0h`O zr{IWrc;`Zfa;SNaeEV)RU$?F0dXo9>wy!w}TmBf8$Z1Jdd`jBc_$NwG z=WkRrRI%m#&Z%0g*pr9Sf+0m_U6l+x0sq+cpwNMioS)yjK&?=V!dQV`=t z>D-mA?z4eGJC)rp?k5vLX}CaUF7?DHpqE)WQL6Hno31>_^^!Gu@w9YkI#4#J*-dQ+An+46!~Q!7#}y)eyg6j>+q4 z*xVH?Fh-5EaY|fQtBZb~&HZQ9w3AnP;Wc%wPc6fjrRGki#K=}lTn}+QQ2i`tCL31N z_UlbtKdp9H$$Z><>c2${XF{ZAom#_C^tz!#T6?acy8`%I_iSinXk ztG54CBE8+I)vbSYN?r;h#V6I(TWTc%hD86D)o32vp(AX`p(Rqd++ai&4)X6O*?djHrF8l z@ql^)5aWQ9A;i%@zjMIYaX{*9U`8GA!g>fbItQUS6bLy9F^T*7 z?uNLQ>w}6R9-jl~k|3Tt1tjD`>|Dn41PmNG9q_q|lY-tY8U3I+y6Zm89oqhbI{ieXDeMYndJ+*>|7x6jv#g|^oR=+j~7}(QzCW-`N z`WP?YBJ+`j#@{n(ss9w?qiH>XxLGbKY^t5950knHeOl+M7rwb!Rg+VHd~JEQA=i{<+y}2GOCf&_TA?J z>*Pr?74VCY^B$9#U#lA(W99rHPiCh9Hn!q~#YMJ<{C;M-%vgBSVXE=oaahPT0CwIuK(NdJ)&4Vsl zHrOW9tGSjPFYf`meQl}#fs8y>5@U%?meZ9gCC#-wDDYwEGOV$M-%+BaH~hj2cdE+*j&om}S}=yvB2O*%+RqT*RJY})Q@Lif{dzOk zi`3gzG9QtuJ}k*+OFA{{QD(ujTAPsaR4(grTbsMV1CZji#YL3%xvwsetText(QString("%1
%2").arg(tr("Import Cue Sheet"), tr("The following Cue Sheet will be split and imported into LameXP."))); @@ -92,38 +92,66 @@ int CueImportDialog::exec(const QString &cueFile) { WorkingBanner *progress = new WorkingBanner(dynamic_cast(parent())); progress->show(tr("Loading Cue Sheet file, please be patient...")); - int iResult = m_model->loadCueSheet(cueFile, QApplication::instance()); - progress->close(); - LAMEXP_DELETE(progress); - if(iResult) + QFileInfo cueFileInfo(cueFile); + m_outputDir = QFileInfo(cueFile).canonicalPath(); + + if(!cueFileInfo.exists() || !cueFileInfo.isFile() || m_outputDir.isEmpty()) + { + QString text = QString("%1
%2

%3").arg(tr("Failed to load the Cue Sheet file:"), QDir::toNativeSeparators(cueFile), tr("The specified file could not be found!")).replace("-", "−"); + QMessageBox::warning(progress, tr("Cue Sheet Error"), text); + progress->close(); + LAMEXP_DELETE(progress); + return CueSheetModel::ErrorIOFailure; + } + + int iResult = m_model->loadCueSheet(cueFile, QApplication::instance()); + if(iResult != CueSheetModel::ErrorSuccess) { QString errorMsg = tr("An unknown error has occured!"); switch(iResult) { - case 1: - errorMsg = tr("The file could not be opened for reading!"); + case CueSheetModel::ErrorIOFailure: + errorMsg = tr("The file could not be opened for reading. Make sure you have the required rights!"); break; - case 2: - errorMsg = tr("The file does not look like a valid Cue Sheet disc image file!"); + case CueSheetModel::ErrorBadFile: + errorMsg = tr("The provided file does not look like a valid Cue Sheet disc image file!"); break; - case 3: - errorMsg = tr("Could not find a supported audio track in the Cue Sheet!"); + case CueSheetModel::ErrorUnsupported: + errorMsg = QString("%1
%2").arg(tr("Could not find any supported audio track in the Cue Sheet image!"), tr("Note that LameXP can not handle \"binary\" Cue Sheet images.")); + break; + case CueSheetModel::ErrorInconsistent: + errorMsg = tr("The selected Cue Sheet file contains inconsistent information. Take care!"); break; } - QString text = QString("%1
%2

%3").arg(tr("Failed to load the Cue Sheet file:"), cueFile, errorMsg).replace("-", "−"); - QMessageBox::warning(dynamic_cast(parent()), tr("Cue Sheet Error"), text); + QString text = QString("%1
%2

%3").arg(tr("Failed to load the Cue Sheet file:"), QDir::toNativeSeparators(cueFile), errorMsg).replace("-", "−"); + QMessageBox::warning(progress, tr("Cue Sheet Error"), text); + progress->close(); + LAMEXP_DELETE(progress); return iResult; } - + + progress->close(); + LAMEXP_DELETE(progress); return QDialog::exec(); } void CueImportDialog::modelChanged(void) { treeView->expandAll(); + editOutputDir->setText(QDir::toNativeSeparators(m_outputDir)); +} + +void CueImportDialog::browseButtonClicked(void) +{ + QString newOutDir = QFileDialog::getExistingDirectory(this, tr("Choose Output Directory")); + if(!newOutDir.isEmpty()) + { + m_outputDir = newOutDir; + modelChanged(); + } } void CueImportDialog::importButtonClicked(void) diff --git a/src/Dialog_CueImport.h b/src/Dialog_CueImport.h index b9180559..2b35f035 100644 --- a/src/Dialog_CueImport.h +++ b/src/Dialog_CueImport.h @@ -42,9 +42,11 @@ protected: void CueImportDialog::showEvent(QShowEvent *event); private slots: + void browseButtonClicked(void); void importButtonClicked(void); void modelChanged(void); private: CueSheetModel *m_model; + QString m_outputDir; }; diff --git a/src/Model_CueSheet.cpp b/src/Model_CueSheet.cpp index 30b52e79..0a0c2a8d 100644 --- a/src/Model_CueSheet.cpp +++ b/src/Model_CueSheet.cpp @@ -24,9 +24,9 @@ #include "Genres.h" #include -#include -#include +#include #include +#include #include #include @@ -39,6 +39,7 @@ class CueSheetItem { public: virtual const char* type(void) = 0; + virtual bool isValid(void) { return false; } }; class CueSheetTrack : public CueSheetItem @@ -50,20 +51,24 @@ public: m_trackNo(trackNo) { m_startIndex = std::numeric_limits::quiet_NaN(); + m_duration = std::numeric_limits::infinity(); } int trackNo(void) { return m_trackNo; } double startIndex(void) { return m_startIndex; } + double duration(void) { return m_duration; } QString title(void) { return m_title; } QString performer(void) { return m_performer; } CueSheetFile *parent(void) { return m_parent; } void setStartIndex(double startIndex) { m_startIndex = startIndex; } - void setTitle(const QString &title) { m_title = title; } - void setPerformer(const QString &performer) { m_performer = performer; } - bool isValid(void) { return !(_isnan(m_startIndex) || (m_trackNo < 0)); } + void setDuration(double duration) { m_duration = duration; } + void setTitle(const QString &title, bool update = false) { if(!update || (m_title.isEmpty() && !title.isEmpty())) m_title = title; } + void setPerformer(const QString &performer, bool update = false) { if(!update || (m_performer.isEmpty() && !performer.isEmpty())) m_performer = performer; } + virtual bool isValid(void) { return !(_isnan(m_startIndex) || (m_trackNo < 0)); } virtual const char* type(void) { return "CueSheetTrack"; } private: int m_trackNo; double m_startIndex; + double m_duration; QString m_title; QString m_performer; CueSheetFile *m_parent; @@ -79,6 +84,7 @@ public: void clearTracks(void) { while(!m_tracks.isEmpty()) delete m_tracks.takeLast(); } CueSheetTrack *track(int index) { return m_tracks.at(index); } int trackCount(void) { return m_tracks.count(); } + virtual bool isValid(void) { return m_tracks.count() > 0; } virtual const char* type(void) { return "CueSheetFile"; } private: const QString m_fileName; @@ -134,7 +140,7 @@ QModelIndex CueSheetModel::index(int row, int column, const QModelIndex &parent) int CueSheetModel::columnCount(const QModelIndex &parent) const { - return 3; + return 4; } int CueSheetModel::rowCount(const QModelIndex &parent) const @@ -182,6 +188,9 @@ QVariant CueSheetModel::headerData (int section, Qt::Orientation orientation, in case 2: return tr("Index"); break; + case 3: + return tr("Duration"); + break; default: return QVariant(); break; @@ -207,7 +216,7 @@ QVariant CueSheetModel::data(const QModelIndex &index, int role) const return tr("File %1").arg(QString().sprintf("%02d", index.row() + 1)).append(" "); break; case 1: - return QString("[%1]").arg(QFileInfo(filePtr->fileName()).fileName()); + return QFileInfo(filePtr->fileName()).fileName(); break; default: return QVariant(); @@ -242,12 +251,48 @@ QVariant CueSheetModel::data(const QModelIndex &index, int role) const case 2: return indexToString(trackPtr->startIndex()); break; + case 3: + return indexToString(trackPtr->duration()); + break; default: return QVariant(); break; } } } + else if(role == Qt::FontRole) + { + QFont font("Monospace"); + font.setStyleHint(QFont::TypeWriter); + if((index.column() == 1)) + { + CueSheetItem *item = reinterpret_cast(index.internalPointer()); + font.setBold(dynamic_cast(item) != NULL); + } + return font; + } + else if(role == Qt::ForegroundRole) + { + if((index.column() == 1)) + { + CueSheetItem *item = reinterpret_cast(index.internalPointer()); + if(CueSheetFile *filePtr = dynamic_cast(item)) + { + return QFileInfo(filePtr->fileName()).exists() ? QColor("mediumblue") : QColor("darkred"); + } + } + else if((index.column() == 3)) + { + CueSheetItem *item = reinterpret_cast(index.internalPointer()); + if(CueSheetTrack *trackPtr = dynamic_cast(item)) + { + if(trackPtr->duration() == std::numeric_limits::infinity()) + { + return QColor("dimgrey"); + } + } + } + } return QVariant(); } @@ -268,19 +313,19 @@ int CueSheetModel::loadCueSheet(const QString &cueFileName, QCoreApplication *ap QFile cueFile(cueFileName); if(!cueFile.open(QIODevice::ReadOnly)) { - return 1; + return ErrorIOFailure; } clearData(); beginResetModel(); - int iResult = parseCueFile(cueFile, application); + int iResult = parseCueFile(cueFile, QDir(QFileInfo(cueFile).canonicalPath()), application); endResetModel(); return iResult; } -int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) +int CueSheetModel::parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplication *application) { cueFile.seek(0); qDebug("\n[Cue Sheet Import]"); @@ -319,7 +364,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) if(application) { application->processEvents(); - Sleep(25); + Sleep(10); } QByteArray lineData = cueFile.readLine(); @@ -341,14 +386,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) { if(currentTrack->isValid()) { - if(currentTrack->title().isEmpty() && !albumTitle.isEmpty()) - { - currentTrack->setTitle(albumTitle); - } - if(currentTrack->performer().isEmpty() && !albumPerformer.isEmpty()) - { - currentTrack->setPerformer(albumPerformer); - } + currentTrack->setTitle(albumTitle, true); + currentTrack->setPerformer(albumPerformer, true); currentFile->addTrack(currentTrack); currentTrack = NULL; } @@ -357,7 +396,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) LAMEXP_DELETE(currentTrack); } } - if(currentFile->trackCount() > 0) + if(currentFile->isValid()) { m_files.append(currentFile); currentFile = NULL; @@ -373,7 +412,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) } if(!rxFile.cap(2).compare("WAVE", Qt::CaseInsensitive) || !rxFile.cap(2).compare("MP3", Qt::CaseInsensitive) || !rxFile.cap(2).compare("AIFF", Qt::CaseInsensitive)) { - currentFile = new CueSheetFile(rxFile.cap(1)); + currentFile = new CueSheetFile(baseDir.absoluteFilePath(rxFile.cap(1))); + qDebug("File path: <%s>", currentFile->fileName().toUtf8().constData()); } else { @@ -396,14 +436,8 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) { if(currentTrack->isValid()) { - if(currentTrack->title().isEmpty() && !albumTitle.isEmpty()) - { - currentTrack->setTitle(albumTitle); - } - if(currentTrack->performer().isEmpty() && !albumPerformer.isEmpty()) - { - currentTrack->setPerformer(albumPerformer); - } + currentTrack->setTitle(albumTitle, true); + currentTrack->setPerformer(albumPerformer, true); currentFile->addTrack(currentTrack); currentTrack = NULL; } @@ -476,21 +510,15 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) } } - //Finally append the very last track/file + //Append the very last track/file that is still pending if(currentFile) { if(currentTrack) { if(currentTrack->isValid()) { - if(currentTrack->title().isEmpty() && !albumTitle.isEmpty()) - { - currentTrack->setTitle(albumTitle); - } - if(currentTrack->performer().isEmpty() && !albumPerformer.isEmpty()) - { - currentTrack->setPerformer(albumPerformer); - } + currentTrack->setTitle(albumTitle, true); + currentTrack->setPerformer(albumPerformer, true); currentFile->addTrack(currentTrack); currentTrack = NULL; } @@ -499,7 +527,7 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) LAMEXP_DELETE(currentTrack); } } - if(currentFile->trackCount() > 0) + if(currentFile->isValid()) { m_files.append(currentFile); currentFile = NULL; @@ -510,7 +538,72 @@ int CueSheetModel::parseCueFile(QFile &cueFile, QCoreApplication *application) } } - return (m_files.count() > 0) ? 0 : (bUnsupportedTrack ? 3 : 2); + //Finally calculate duration of each track + int nFiles = m_files.count(); + for(int i = 0; i < nFiles; i++) + { + if(application) + { + application->processEvents(); + Sleep(10); + } + + CueSheetFile *currentFile = m_files.at(i); + int nTracks = currentFile->trackCount(); + if(nTracks > 1) + { + for(int j = 1; j < nTracks; j++) + { + CueSheetTrack *currentTrack = currentFile->track(j); + CueSheetTrack *previousTrack = currentFile->track(j-1); + double duration = currentTrack->startIndex() - previousTrack->startIndex(); + previousTrack->setDuration(max(0.0, duration)); + } + } + } + + //Sanity check of track numbers + if(nFiles > 0) + { + bool trackNo[100]; + for(int i = 0; i < 100; i++) + { + trackNo[i] = false; + } + for(int i = 0; i < nFiles; i++) + { + if(application) + { + application->processEvents(); + Sleep(10); + } + CueSheetFile *currentFile = m_files.at(i); + int nTracks = currentFile->trackCount(); + if(nTracks > 1) + { + for(int j = 1; j < nTracks; j++) + { + int currentTrackNo = currentFile->track(j)->trackNo(); + if(currentTrackNo > 99) + { + qWarning("Track #%02d is invalid (maximum is 99), Cue Sheet is inconsistent!", currentTrackNo); + return ErrorInconsistent; + } + if(trackNo[currentTrackNo]) + { + qWarning("Track #%02d exists multiple times, Cue Sheet is inconsistent!", currentTrackNo); + return ErrorInconsistent; + } + trackNo[currentTrackNo] = true; + } + } + } + return ErrorSuccess; + } + else + { + return bUnsupportedTrack ? ErrorUnsupported : ErrorBadFile; + } } double CueSheetModel::parseTimeIndex(const QString &index) @@ -538,10 +631,21 @@ double CueSheetModel::parseTimeIndex(const QString &index) QString CueSheetModel::indexToString(const double index) const { - int temp = static_cast(index * 100.0); + if(index == std::numeric_limits::quiet_NaN()) + { + return QString("<-NaN!->"); + } + else if(index == std::numeric_limits::infinity() || index < 0.0) + { + return QString("??:??.??"); + } + else + { + int temp = static_cast(index * 100.0); - int msec = temp % 100; - int secs = temp / 100; + int msec = temp % 100; + int secs = temp / 100; - return QString().sprintf("%02d:%02d.%02d", (secs / 60), (secs % 60), msec); + return QString().sprintf("%02d:%02d.%02d", min(99, secs / 60), min(99, secs % 60), min(99, msec)); + } } diff --git a/src/Model_CueSheet.h b/src/Model_CueSheet.h index 5baeb26c..acb66df2 100644 --- a/src/Model_CueSheet.h +++ b/src/Model_CueSheet.h @@ -27,6 +27,7 @@ class CueSheetFile; class QApplication; +class QDir; class CueSheetModel : public QAbstractItemModel { @@ -36,6 +37,17 @@ public: CueSheetModel(); ~CueSheetModel(void); + //Error codes + enum ErrorCode + { + ErrorSuccess = 0, + ErrorIOFailure = 1, + ErrorBadFile = 2, + ErrorUnsupported = 3, + ErrorInconsistent = 4, + ErrorUnknown = 9 + }; + //Model functions QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; @@ -49,7 +61,7 @@ public: int loadCueSheet(const QString &cueFile, QCoreApplication *application = NULL); private: - int parseCueFile(QFile &cueFile, QCoreApplication *application); + int parseCueFile(QFile &cueFile, const QDir &baseDir, QCoreApplication *application); double parseTimeIndex(const QString &index); QString indexToString(const double index) const; QList m_files;