diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-03-17 00:22:52 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-03-17 00:22:52 +0000 |
| commit | 2e504b33eb9f38cac629ad31b7c107fb0cf5efda (patch) | |
| tree | 9c571653f312597b744896d45e27d422acbeea88 | |
| parent | a4c19a34244aeaf183c25878933b570fc5c0ee34 (diff) | |
| parent | 48b2c7b8ec57e72f2f27d5080e54e4b3c3fcda3d (diff) | |
Merge master.
47 files changed, 1656 insertions, 875 deletions
@@ -2,8 +2,51 @@ * Add subtitle view. +2014-03-17 Carl Hetherington <cth@carlh.net> + + * Improve appearance of config dialog on OS X. + +2014-03-15 Carl Hetherington <cth@carlh.net> + + * Improve appearance of new film and KDM dialogs on OS X. + + * Fix KDM dialog to predictably set up its initial range to + a week from now. + + * Remove support for FFmpeg post-processing filters as they apparently + do not support > 8bpp. I don't think they are worth the pain of + quantizing and then telling the user what has happened. + +2014-03-12 Carl Hetherington <cth@carlh.net> + + * Version 1.66.1 released. + +2014-03-12 Carl Hetherington <cth@carlh.net> + + * Hopefully fix i18n on OS X (#324). + +2014-03-10 Carl Hetherington <cth@carlh.net> + + * Version 1.66.0 released. + +2014-03-09 Carl Hetherington <cth@carlh.net> + + * Version 1.65.2 released. + +2014-03-09 Carl Hetherington <cth@carlh.net> + + * Restore old behaviour of "no-stretch" mode with crop. + + * Fix display of no-scale display mode in the player. + 2014-03-08 Carl Hetherington <cth@carlh.net> + * Version 1.65.1 released. + +2014-03-08 Carl Hetherington <cth@carlh.net> + + * Fix incorrect audio analyses on multiple-stream content. + * Support for unsigned 8-bit audio (hmm!). 2014-03-06 Carl Hetherington <cth@carlh.net> diff --git a/debian/changelog b/debian/changelog index 5ce77d8af..2a1593a5b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -dcpomatic (1.65.0-1) UNRELEASED; urgency=low +dcpomatic (1.66.1-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. @@ -101,8 +101,12 @@ dcpomatic (1.65.0-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. * New upstream release. + * New upstream release. + * New upstream release. + * New upstream release. + * New upstream release. - -- Carl Hetherington <carl@d1stkfactory> Thu, 06 Mar 2014 18:28:57 +0000 + -- Carl Hetherington <carl@d1stkfactory> Wed, 12 Mar 2014 00:12:04 +0000 dcpomatic (0.87-1) UNRELEASED; urgency=low diff --git a/icons/colour_conversions.png b/icons/colour_conversions.png Binary files differnew file mode 100644 index 000000000..5cd2b32bf --- /dev/null +++ b/icons/colour_conversions.png diff --git a/icons/colour_conversions.svg b/icons/colour_conversions.svg new file mode 100644 index 000000000..59b35c14f --- /dev/null +++ b/icons/colour_conversions.svg @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg3882" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="colour_conversions.svg" + inkscape:export-filename="/home/carl/src/dcpomatic/icons/colour_conversions.png" + inkscape:export-xdpi="8.3965015" + inkscape:export-ydpi="8.3965015"> + <defs + id="defs3884" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1" + inkscape:cx="465.68138" + inkscape:cy="520" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1366" + inkscape:window-height="714" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata3887"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.62992096;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3941" + width="100" + height="300" + x="193.66678" + y="335.36218" /> + <rect + style="color:#000000;fill:#00ff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.62992096;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3941-5" + width="100" + height="300" + x="293.66678" + y="335.36218" /> + <rect + style="color:#000000;fill:#0000ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.62992096;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3941-5-1" + width="100" + height="300" + x="393.66678" + y="335.36218" /> + <rect + style="color:#000000;fill:none;stroke:none;stroke-width:10.62992095999999975;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4026" + width="343" + height="343" + x="172" + y="315.36218" /> + </g> +</svg> diff --git a/icons/defaults.png b/icons/defaults.png Binary files differnew file mode 100644 index 000000000..9fd41a935 --- /dev/null +++ b/icons/defaults.png diff --git a/icons/defaults.svg b/icons/defaults.svg new file mode 100644 index 000000000..ab254950d --- /dev/null +++ b/icons/defaults.svg @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg2" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="defaults.svg" + inkscape:export-filename="/home/carl/src/dcpomatic/icons/defaults.png" + inkscape:export-xdpi="9.7627115" + inkscape:export-ydpi="9.7627115"> + <defs + id="defs4" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1" + inkscape:cx="204.5" + inkscape:cy="520" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1366" + inkscape:window-height="714" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + id="g3807" + style="stroke-width:10.62992096;stroke-miterlimit:4;stroke-dasharray:none" + transform="translate(0,4.4578857e-5)"> + <path + inkscape:connector-curvature="0" + id="path2985" + d="m 98,422.36218 19,19 31.68172,-54.87435" + style="fill:none;stroke:#800000;stroke-width:10.62992096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path3755" + d="m 167,421.36218 181,0" + style="color:#000000;fill:none;stroke:#008080;stroke-width:10.62992096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + </g> + <g + transform="translate(0,87.718611)" + id="g3807-6" + style="stroke-width:10.62992096;stroke-miterlimit:4;stroke-dasharray:none"> + <path + inkscape:connector-curvature="0" + id="path2985-6" + d="m 98,422.36218 19,19 31.68172,-54.87435" + style="fill:none;stroke:#800000;stroke-width:10.62992096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path3755-0" + d="m 167,421.36218 181,0" + style="color:#000000;fill:none;stroke:#008080;stroke-width:10.62992096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + </g> + <g + transform="translate(0,175.43718)" + id="g3807-6-8" + style="stroke-width:10.62992096;stroke-miterlimit:4;stroke-dasharray:none"> + <path + inkscape:connector-curvature="0" + id="path2985-6-6" + d="m 98,422.36218 19,19 31.68172,-54.87435" + style="fill:none;stroke:#800000;stroke-width:10.62992096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path3755-0-9" + d="m 167,421.36218 181,0" + style="color:#000000;fill:none;stroke:#008080;stroke-width:10.62992096;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + </g> + <rect + style="color:#000000;fill:none;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3880" + width="295" + height="295" + x="74" + y="360.36218" /> + </g> +</svg> diff --git a/icons/kdm_email.png b/icons/kdm_email.png Binary files differnew file mode 100644 index 000000000..28701ee49 --- /dev/null +++ b/icons/kdm_email.png diff --git a/icons/kdm_email.svg b/icons/kdm_email.svg new file mode 100644 index 000000000..ace413dae --- /dev/null +++ b/icons/kdm_email.svg @@ -0,0 +1,197 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg4217" + viewBox="0 0 744.09449 1052.3622" + version="1.0" + inkscape:version="0.48.4 r9939" + width="100%" + height="100%" + sodipodi:docname="kdm_email.svg" + inkscape:export-filename="/home/carl/src/dcpomatic/icons/kdm_email.png" + inkscape:export-xdpi="6.5100002" + inkscape:export-ydpi="6.5100002"> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1366" + inkscape:window-height="714" + id="namedview6320" + showgrid="false" + inkscape:zoom="0.60313323" + inkscape:cx="-87.032436" + inkscape:cy="195.645" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg4217" /> + <defs + id="defs4219"> + <linearGradient + id="linearGradient3594" + y2="742.5" + gradientUnits="userSpaceOnUse" + x2="-886.76001" + gradientTransform="matrix(-0.84033,-0.84033,-0.84033,0.84033,214.12,-1075.4)" + y1="742.5" + x1="-772.01001"> + <stop + id="stop4687" + stop-color="#fff" + offset="0" /> + <stop + id="stop4689" + stop-color="#fff" + stop-opacity="0" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient3601" + y2="613.94" + gradientUnits="userSpaceOnUse" + x2="385.04001" + gradientTransform="matrix(0.70711,-0.70711,0.70711,0.70711,-126.18,372.21)" + y1="63.870998" + x1="386.39001"> + <stop + id="stop3797" + stop-color="#ffe800" + offset="0" /> + <stop + id="stop3799" + stop-color="#dfb300" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient3609" + y2="161.84" + gradientUnits="userSpaceOnUse" + x2="212.92999" + y1="358.29999" + x1="409.38"> + <stop + id="stop4034" + stop-color="#dfb300" + offset="0" /> + <stop + id="stop3374" + stop-color="#dfb300" + offset=".5" /> + <stop + id="stop3376" + stop-color="#dfb300" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient3632" + y2="448.35001" + gradientUnits="userSpaceOnUse" + x2="382.89999" + gradientTransform="matrix(0.70711,-0.70711,0.70711,0.70711,-126.18,372.21)" + y1="448.35001" + x1="403.63"> + <stop + id="stop3636" + stop-color="#ffe800" + stop-opacity=".39216" + offset="0" /> + <stop + id="stop3638" + stop-color="#dfb300" + stop-opacity=".39216" + offset="1" /> + </linearGradient> + </defs> + <g + id="layer1" + transform="translate(-77.797413,384.00351)"> + <path + id="path6625" + d="m 227.2,177.73 c -46.65,46.65 -46.67,122.4 -0.03,169.04 30.92,30.92 74.6,41.33 114.12,31.27 l 22.3,22.29 39.67,4.86 4.91,39.73 39.68,4.86 4.89,39.7 39.72,4.91 4.86,39.68 70.53,-5.91 5.66,-0.46 1.07,-12.21 5.62,-63.77 L 558.13,429.65 536.1,407.62 514.05,385.57 492.02,363.55 469.97,341.5 447.92,319.45 425.87,297.4 c 12.55,-40.94 2.66,-87.25 -29.71,-119.62 -46.64,-46.64 -122.32,-46.69 -168.96,-0.05 z m 24.21,24.32 c 21.41,-21.41 52.07,-25.54 68.44,-9.17 16.37,16.37 12.26,47.05 -9.14,68.46 -21.41,21.41 -52.07,25.49 -68.44,9.12 -16.37,-16.37 -12.27,-47.01 9.14,-68.41 z" + style="color:#000000;fill:url(#linearGradient3601)" + inkscape:connector-curvature="0" /> + <path + id="path6871" + d="m 388.43,339.03 c -1.68,1.68 -2.88,3.59 -3.69,5.59 -0.74,1.82 -1.28,3.93 -1.28,6.32 0,2.4 0.52,4.53 1.26,6.35 0.77,1.9 2.01,3.91 3.69,5.59 L 551.53,526 l 3.27,3.27 4.62,-0.38 5.68,-0.46 8.39,-0.71 0.75,-8.4 1.06,-12.19 0.4,-4.64 -3.29,-3.3 -160.16,-160.16 c -1.68,-1.68 -3.68,-2.91 -5.59,-3.69 -1.81,-0.73 -3.92,-1.28 -6.32,-1.28 -2.4,0 -4.51,0.55 -6.32,1.28 -1.91,0.78 -3.91,2.01 -5.59,3.69 z" + style="color:#000000;fill:url(#linearGradient3632)" + inkscape:connector-curvature="0" /> + <path + id="path2365" + d="m 239.44,192.85 c -2.29,2.41 -4.43,4.92 -6.43,7.49 2.5,-3.23 5.25,-6.31 8.22,-9.28 -0.6,0.6 -1.21,1.18 -1.79,1.79 z m 3.62,-3.58 c 4.29,-4.07 8.84,-7.67 13.61,-10.83 -4.76,3.15 -9.33,6.77 -13.61,10.83 z m -11.62,13.17 c -0.93,1.27 -1.81,2.53 -2.67,3.82 0.85,-1.29 1.74,-2.56 2.67,-3.82 z m -2.81,4.05 c -0.89,1.35 -1.76,2.74 -2.58,4.13 0.82,-1.4 1.68,-2.77 2.58,-4.13 z m -2.58,4.13 c -1.66,2.8 -3.16,5.65 -4.51,8.57 1.35,-2.91 2.86,-5.78 4.51,-8.57 z m -4.51,8.57 c -1.35,2.92 -2.55,5.9 -3.6,8.91 1.05,-3.01 2.25,-6 3.6,-8.91 z m -3.6,8.91 c -1.05,3 -1.97,6.05 -2.72,9.12 0.75,-3.08 1.67,-6.12 2.72,-9.12 z m -2.72,9.12 c -0.31,1.27 -0.58,2.53 -0.84,3.8 0.26,-1.27 0.53,-2.53 0.84,-3.8 z m 43.53,-60.1 c 1.38,-0.87 2.79,-1.69 4.2,-2.48 -1.41,0.79 -2.82,1.61 -4.2,2.48 z m 8.49,-4.73 c 1.44,-0.71 2.88,-1.37 4.35,-2.01 -1.46,0.63 -2.92,1.3 -4.35,2.01 z m 17.89,-6.76 c 1.53,-0.41 3.06,-0.77 4.6,-1.11 -1.54,0.34 -3.07,0.7 -4.6,1.11 z m 4.62,-1.13 c 1.54,-0.34 3.09,-0.62 4.64,-0.88 -1.55,0.26 -3.1,0.54 -4.64,0.88 z m -75.52,77.34 c -0.16,0.79 -0.29,1.58 -0.42,2.36 0.13,-0.77 0.27,-1.58 0.42,-2.36 z m -0.42,2.36 c -0.13,0.78 -0.27,1.55 -0.38,2.33 0.11,-0.79 0.24,-1.55 0.38,-2.33 z m -0.69,4.67 c -0.09,0.78 -0.17,1.57 -0.24,2.36 0.07,-0.78 0.15,-1.58 0.24,-2.36 z m -0.44,4.73 c -0.06,0.78 -0.1,1.56 -0.13,2.34 0.03,-0.79 0.07,-1.56 0.13,-2.34 z m 93.47,-91.26 c 1.18,-0.06 2.37,-0.1 3.56,-0.12 -1.2,0.02 -2.37,0.06 -3.56,0.12 z m 4.71,-0.12 c 0.78,0 1.57,0.01 2.36,0.03 -0.79,-0.02 -1.57,-0.03 -2.36,-0.03 z m -98.18,105.52 c 0.11,1.58 0.25,3.16 0.44,4.73 -0.19,-1.57 -0.33,-3.16 -0.44,-4.73 z M 322.66,162.93 c 1.56,0.19 3.12,0.4 4.68,0.66 -1.56,-0.26 -3.12,-0.47 -4.68,-0.66 z m -108.85,114.2 c 0.13,0.78 0.26,1.58 0.42,2.36 -0.15,-0.77 -0.29,-1.58 -0.42,-2.36 z m 0.42,2.36 c 0.14,0.77 0.31,1.54 0.48,2.3 -0.17,-0.77 -0.33,-1.52 -0.48,-2.3 z m 1.61,6.92 c 0.21,0.77 0.41,1.55 0.64,2.32 -0.23,-0.76 -0.44,-1.55 -0.64,-2.32 z m 1.35,4.57 c 0.24,0.76 0.49,1.51 0.75,2.26 -0.27,-0.75 -0.51,-1.5 -0.75,-2.26 z m 0.75,2.26 c 0.25,0.71 0.5,1.43 0.77,2.14 -0.26,-0.7 -0.52,-1.43 -0.77,-2.14 z m 1.7,4.48 c 0.3,0.75 0.61,1.48 0.93,2.21 -0.32,-0.73 -0.63,-1.47 -0.93,-2.21 z m 0.93,2.21 c 0.32,0.74 0.63,1.48 0.97,2.21 -0.34,-0.72 -0.65,-1.47 -0.97,-2.21 z m 0.97,2.21 c 0.34,0.73 0.7,1.45 1.06,2.17 -0.36,-0.72 -0.72,-1.44 -1.06,-2.17 z m 2.14,4.31 c 0.38,0.72 0.78,1.43 1.17,2.15 -0.39,-0.71 -0.79,-1.43 -1.17,-2.15 z M 359.25,174.91 c 1.12,0.63 2.23,1.28 3.34,1.97 -1.11,-0.69 -2.22,-1.34 -3.34,-1.97 z M 227.33,312.79 c 0.38,0.61 0.77,1.23 1.17,1.84 -0.4,-0.61 -0.79,-1.22 -1.17,-1.84 z m 1.57,2.46 c 0.42,0.62 0.85,1.24 1.28,1.85 -0.43,-0.62 -0.86,-1.23 -1.28,-1.85 z m 2.72,3.86 c 0.95,1.3 1.95,2.57 2.98,3.83 -1.02,-1.25 -2.03,-2.54 -2.98,-3.83 z M 371.07,182.75 c 1.3,1.01 2.61,2.04 3.87,3.12 -1.27,-1.09 -2.56,-2.1 -3.87,-3.12 z M 244.92,333.79 c 38.64,34.9 98.35,33.74 135.59,-3.49 37.23,-37.24 38.39,-96.96 3.49,-135.59 31.41,35.32 -20.5,44.27 -57.68,81.45 -37.17,37.17 -46.08,89.04 -81.4,57.63 z" + style="color:#000000;fill:url(#linearGradient3609)" + inkscape:connector-curvature="0" /> + <path + id="path6632" + d="m 239.44,192.87 c -36.65,38.56 -36.03,99.58 1.8,137.42 38.44,38.43 46.67,-15.69 85.1,-54.13 38.43,-38.43 92.59,-46.69 54.15,-85.12 -38.43,-38.44 -100.81,-38.41 -139.25,0.03 -0.6,0.6 -1.22,1.19 -1.8,1.8 z m 11.99,9.17 c 21.4,-21.41 52.05,-25.51 68.42,-9.14 16.37,16.37 12.27,47.02 -9.14,68.43 -21.4,21.4 -52.05,25.5 -68.42,9.13 -16.37,-16.37 -12.27,-47.02 9.14,-68.42 z" + style="color:#000000;fill:url(#linearGradient3594)" + inkscape:connector-curvature="0" /> + </g> + <metadata + id="metadata6318"> + <rdf:RDF> + <cc:Work> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <cc:license + rdf:resource="http://creativecommons.org/licenses/publicdomain/" /> + <dc:publisher> + <cc:Agent + rdf:about="http://openclipart.org/"> + <dc:title>Openclipart</dc:title> + </cc:Agent> + </dc:publisher> + <dc:title>Key</dc:title> + <dc:date>2007-02-27T15:15:43</dc:date> + <dc:description>A key icon.</dc:description> + <dc:source>http://openclipart.org/detail/3330/key-by-barretr</dc:source> + <dc:creator> + <cc:Agent> + <dc:title>barretr</dc:title> + </cc:Agent> + </dc:creator> + <dc:subject> + <rdf:Bag> + <rdf:li>clip art</rdf:li> + <rdf:li>clipart</rdf:li> + <rdf:li>icon</rdf:li> + <rdf:li>image</rdf:li> + <rdf:li>key</rdf:li> + <rdf:li>media</rdf:li> + <rdf:li>png</rdf:li> + <rdf:li>public domain</rdf:li> + <rdf:li>svg</rdf:li> + </rdf:Bag> + </dc:subject> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/licenses/publicdomain/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <rect + style="color:#000000;fill:#ff0000;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6322" + width="442.68826" + height="442.68826" + x="84.558434" + y="505.21939" /> +</svg> diff --git a/icons/servers.png b/icons/servers.png Binary files differnew file mode 100644 index 000000000..b3781e45c --- /dev/null +++ b/icons/servers.png diff --git a/icons/tms.png b/icons/tms.png Binary files differnew file mode 100644 index 000000000..60e3cc2ff --- /dev/null +++ b/icons/tms.png diff --git a/icons/tms.svg b/icons/tms.svg new file mode 100644 index 000000000..c1815b9b3 --- /dev/null +++ b/icons/tms.svg @@ -0,0 +1,192 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg4047" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="tms.svg" + inkscape:export-filename="/home/carl/src/dcpomatic/icons/tms.png" + inkscape:export-xdpi="11.282503" + inkscape:export-ydpi="11.282503"> + <defs + id="defs4049"> + <linearGradient + inkscape:collect="always" + id="linearGradient6220"> + <stop + style="stop-color:#280b0b;stop-opacity:1;" + offset="0" + id="stop6222" /> + <stop + style="stop-color:#280b0b;stop-opacity:0;" + offset="1" + id="stop6224" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient6212"> + <stop + style="stop-color:#280b0b;stop-opacity:1;" + offset="0" + id="stop6214" /> + <stop + style="stop-color:#280b0b;stop-opacity:0;" + offset="1" + id="stop6216" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient6204"> + <stop + style="stop-color:#280b0b;stop-opacity:1;" + offset="0" + id="stop6206" /> + <stop + style="stop-color:#280b0b;stop-opacity:0;" + offset="1" + id="stop6208" /> + </linearGradient> + <linearGradient + id="linearGradient6065" + osb:paint="solid"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop6067" /> + </linearGradient> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="252.46881 : 700.96181 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="945.56329 : 858.96181 : 1" + inkscape:persp3d-origin="602.51605 : 274.56811 : 1" + id="perspective4055" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient6204" + id="linearGradient6210" + x1="310.2699" + y1="446.39062" + x2="115.85081" + y2="662.24622" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient6212" + id="linearGradient6218" + x1="254.40172" + y1="409.5137" + x2="532.05225" + y2="261.88489" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient6220" + id="linearGradient6226" + x1="358.52518" + y1="490.35175" + x2="581.59894" + y2="475.05954" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.7002102" + inkscape:cx="334.00378" + inkscape:cy="602.77323" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + showguides="true" + inkscape:guide-bbox="true" + objecttolerance="10000" + inkscape:window-width="1366" + inkscape:window-height="714" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1"> + <sodipodi:guide + orientation="0,1" + position="-88,846" + id="guide6105" /> + </sodipodi:namedview> + <metadata + id="metadata4052"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="fill:url(#linearGradient6226);fill-opacity:1;stroke:#4d4d4d;stroke-width:12;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 323.35383,442.15071 -0.58817,142.87283 73.44365,-49.82452 -2.19901,-140.69539 z" + id="path6121" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:url(#linearGradient6210);stroke:#4d4d4d;stroke-width:12;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1" + d="m 323.35382,439.86652 -87.07405,-40.13194 0,126.71456 86.48589,58.35081 z" + id="path6123" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:url(#linearGradient6218);fill-opacity:1;stroke:#4d4d4d;stroke-width:12;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 236.28706,399.69135 64.7791,-37.11367 93.23766,31.49886 -69.74842,46.49277 z" + id="path6125" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:none;stroke:#ff0000;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 339.3698,456.5535 12.93958,-9.4106" + id="path6127" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#ff0000;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 339.95796,471.84573 12.93958,-9.4106" + id="path6127-4" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#00ff00;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 340.54612,487.13795 12.93958,-9.4106" + id="path6127-4-9" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#00ff00;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 367.6016,534.77913 12.93958,-9.4106" + id="path6127-4-9-1" + inkscape:connector-curvature="0" /> + <rect + style="color:#000000;fill:#ff0000;fill-opacity:0;fill-rule:nonzero;stroke:none;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6202" + width="255.26256" + height="255.26256" + x="188.21201" + y="346.56711" /> + </g> +</svg> diff --git a/platform/osx/Info.plist.in b/platform/osx/Info.plist.in index 0f6774138..f2675e3f6 100644 --- a/platform/osx/Info.plist.in +++ b/platform/osx/Info.plist.in @@ -30,6 +30,5 @@ <string>MainMenu</string> <key>NSPrincipalClass</key> <string>NSApplication</string> - @ENV@ </dict> </plist> diff --git a/platform/osx/make_dmg.sh b/platform/osx/make_dmg.sh index 7e9390e2c..cabc47741 100644 --- a/platform/osx/make_dmg.sh +++ b/platform/osx/make_dmg.sh @@ -104,6 +104,14 @@ done cp build/platform/osx/Info.plist $WORK/$approot cp icons/dcpomatic.icns $WORK/$resources/DCP-o-matic.icns +# i18n: .mo files +for lang in de_DE es_ES fr_FR it_IT sv_SE; do + mkdir $WORK/$resources/$lang + cp build/src/lib/mo/$lang/*.mo $WORK/$resources/$lang + cp build/src/wx/mo/$lang/*.mo $WORK/$resources/$lang + cp build/src/tools/mo/$lang/*.mo $WORK/$resources/$lang +done + tmp_dmg=$WORK/dcpomatic_tmp.dmg dmg="$WORK/DCP-o-matic $version.dmg" vol_name=DCP-o-matic-$version diff --git a/run/dcpomatic b/run/dcpomatic index f3f1b84ff..544ffc040 100755 --- a/run/dcpomatic +++ b/run/dcpomatic @@ -1,24 +1,106 @@ #!/bin/bash -export LD_LIBRARY_PATH=build/src/lib:build/src/wx:build/src/asdcplib/src:$LD_LIBRARY_PATH -if [ "$1" == "--debug" ]; then - shift - gdb --args build/src/tools/dcpomatic $* -elif [ "$1" == "--valgrind" ]; then - shift - valgrind --tool="memcheck" build/src/tools/dcpomatic $* -elif [ "$1" == "--callgrind" ]; then - shift - valgrind --tool="callgrind" build/src/tools/dcpomatic $* -elif [ "$1" == "--massif" ]; then - shift - valgrind --tool="massif" build/src/tools/dcpomatic $* -elif [ "$1" == "--i18n" ]; then - shift - LANGUAGE=de_DE.UTF8 LANG=de_DE.UTF8 LC_ALL=de_DE.UTF8 build/src/tools/dcpomatic "$*" -elif [ "$1" == "--perf" ]; then - shift - perf record build/src/tools/dcpomatic $* +if [ `uname -s` == "Darwin" ]; then + # Some time ago we could start DCP-o-matic on OS X just by running the executable, in + # the same way as Linux. This doesn't work any more. + + ENV=$HOME/Environments/osx/64/lib + DEP=$HOME/cdist/64/lib + + app=build/platform/osx/DCP-o-matic.app + macos=$app/Contents/MacOS + lib=$app/Contents/lib + resources=$app/Contents/Resources + mkdir -p $macos $lib $resources + + cp build/src/tools/dcpomatic $macos + cp build/src/lib/libdcpomatic.dylib $lib + cp build/src/wx/libdcpomatic-wx.dylib $lib + cp $DEP/libcxml.dylib $lib + cp $DEP/libdcp.dylib $lib + cp $DEP/libasdcp-libdcp.dylib $lib + cp $DEP/libkumu-libdcp.dylib $lib + cp $DEP/libopenjpeg*.dylib $lib + cp $DEP/libavdevice*.dylib $lib + cp $DEP/libavformat*.dylib $lib + cp $DEP/libavfilter*.dylib $lib + cp $DEP/libavutil*.dylib $lib + cp $DEP/libavcodec*.dylib $lib + cp $DEP/libswscale*.dylib $lib + cp $DEP/libpostproc*.dylib $lib + cp $DEP/libswresample*.dylib $lib + cp $ENV/libboost_system.dylib $lib + cp $ENV/libboost_filesystem.dylib $lib + cp $ENV/libboost_thread.dylib $lib + cp $ENV/libboost_date_time.dylib $lib + cp $ENV/libxml++-2.6*.dylib $lib + cp $ENV/libxml2*.dylib $lib + cp $ENV/libglibmm-2.4*.dylib $lib + cp $ENV/libgobject*.dylib $lib + cp $ENV/libgthread*.dylib $lib + cp $ENV/libgmodule*.dylib $lib + cp $ENV/libsigc*.dylib $lib + cp $ENV/libglib-2*.dylib $lib + cp $ENV/libintl*.dylib $lib + cp $ENV/libsndfile*.dylib $lib + cp $ENV/libMagick++*.dylib $lib + cp $ENV/libMagickCore*.dylib $lib + cp $ENV/libMagickWand*.dylib $lib + cp $ENV/libssh*.dylib $lib + cp $ENV/libwx*.dylib $lib + cp $ENV/libfontconfig*.dylib $lib + cp $ENV/libfreetype*.dylib $lib + cp $ENV/libexpat*.dylib $lib + cp $ENV/libltdl*.dylib $lib + cp $ENV/libxmlsec1*.dylib $lib + cp $ENV/libzip*.dylib $lib + cp $ENV/libquickmail*.dylib $lib + cp $ENV/libcurl*.dylib $lib + cp $ENV/libffi*.dylib $lib + cp icons/defaults.png $resources + cp icons/servers.png $resources + cp icons/tms.png $resources + cp icons/colour_conversions.png $resources + cp icons/kdm_email.png $resources + + sed -e "s/@VERSION@/test/g" platform/osx/Info.plist.in > $app/Contents/Info.plist + + for obj in $macos/dcpomatic $lib/*.dylib; do + deps=`otool -L $obj | awk '{print $1}' | egrep "(/Users/carl|libboost|libssh|libltdl)"` + changes="" + for dep in $deps; do + base=`basename $dep` + changes="$changes -change $dep @executable_path/../lib/$base" + done + if test "x$changes" != "x"; then + install_name_tool $changes $obj + fi + done + + open $app + else - build/src/tools/dcpomatic $* + export LD_LIBRARY_PATH=build/src/lib:build/src/wx:build/src/asdcplib/src:$LD_LIBRARY_PATH + if [ "$1" == "--debug" ]; then + shift + gdb --args build/src/tools/dcpomatic $* + elif [ "$1" == "--valgrind" ]; then + shift + valgrind --tool="memcheck" build/src/tools/dcpomatic $* + elif [ "$1" == "--callgrind" ]; then + shift + valgrind --tool="callgrind" build/src/tools/dcpomatic $* + elif [ "$1" == "--massif" ]; then + shift + valgrind --tool="massif" build/src/tools/dcpomatic $* + elif [ "$1" == "--i18n" ]; then + shift + LANGUAGE=de_DE.UTF8 LANG=de_DE.UTF8 LC_ALL=de_DE.UTF8 build/src/tools/dcpomatic "$*" + elif [ "$1" == "--perf" ]; then + shift + perf record build/src/tools/dcpomatic $* + else + build/src/tools/dcpomatic $* + fi fi + diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index 01d1ecc38..6da5afa0c 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -141,7 +141,9 @@ AudioContent::audio_analysis_path () const return boost::filesystem::path (); } - return film->audio_analysis_path (dynamic_pointer_cast<const AudioContent> (shared_from_this ())); + boost::filesystem::path p = film->audio_analysis_dir (); + p /= digest (); + return p; } string diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 18d88bccb..cecc8f13d 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -57,9 +57,9 @@ public: virtual int output_audio_frame_rate () const = 0; virtual AudioMapping audio_mapping () const = 0; virtual void set_audio_mapping (AudioMapping) = 0; + virtual boost::filesystem::path audio_analysis_path () const; boost::signals2::connection analyse_audio (boost::function<void()>); - boost::filesystem::path audio_analysis_path () const; void set_audio_gain (float); void set_audio_delay (int); diff --git a/src/lib/config.h b/src/lib/config.h index 14cd640ee..68aae7414 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -66,6 +66,7 @@ public: void set_use_any_servers (bool u) { _use_any_servers = u; + write (); } bool use_any_servers () const { @@ -75,6 +76,7 @@ public: /** @param s New list of servers */ void set_servers (std::vector<std::string> s) { _servers = s; + write (); } /** @return Host names / IP addresses of J2K encoding servers that should definitely be used */ @@ -182,35 +184,42 @@ public: /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; + write (); } void set_default_directory (boost::filesystem::path d) { _default_directory = d; + write (); } /** @param p New server port */ void set_server_port_base (int p) { _server_port_base = p; + write (); } /** @param i IP address of a TMS that we can copy DCPs to */ void set_tms_ip (std::string i) { _tms_ip = i; + write (); } /** @param p Path on a TMS that we should write DCPs to */ void set_tms_path (std::string p) { _tms_path = p; + write (); } /** @param u User name to log into the TMS with */ void set_tms_user (std::string u) { _tms_user = u; + write (); } /** @param p Password to log into the TMS with */ void set_tms_password (std::string p) { _tms_password = p; + write (); } void add_cinema (boost::shared_ptr<Cinema> c) { @@ -223,74 +232,92 @@ public: void set_allowed_dcp_frame_rates (std::list<int> const & r) { _allowed_dcp_frame_rates = r; + write (); } void set_default_dci_metadata (DCIMetadata d) { _default_dci_metadata = d; + write (); } void set_language (std::string l) { _language = l; + write (); } void unset_language () { _language = boost::none; + write (); } void set_default_still_length (int s) { _default_still_length = s; + write (); } void set_default_container (Ratio const * c) { _default_container = c; + write (); } void set_default_dcp_content_type (DCPContentType const * t) { _default_dcp_content_type = t; + write (); } void set_dcp_metadata (dcp::XMLMetadata m) { _dcp_metadata = m; + write (); } void set_default_j2k_bandwidth (int b) { _default_j2k_bandwidth = b; + write (); } void set_default_audio_delay (int d) { _default_audio_delay = d; + write (); } void set_colour_conversions (std::vector<PresetColourConversion> const & c) { _colour_conversions = c; + write (); } void set_mail_server (std::string s) { _mail_server = s; + write (); } void set_mail_user (std::string u) { _mail_user = u; + write (); } void set_mail_password (std::string p) { _mail_password = p; + write (); } void set_kdm_from (std::string f) { _kdm_from = f; + write (); } void set_kdm_email (std::string e) { _kdm_email = e; + write (); } void set_check_for_updates (bool c) { _check_for_updates = c; + write (); } void set_check_for_test_updates (bool c) { _check_for_test_updates = c; + write (); } void write () const; diff --git a/src/lib/content.cc b/src/lib/content.cc index 814d9c1a5..1fb4681a2 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -195,7 +195,10 @@ Content::clone () const xmlpp::Document doc; xmlpp::Node* node = doc.create_root_node ("Content"); as_xml (node); - return content_factory (film, cxml::NodePtr (new cxml::Node (node)), Film::current_state_version); + + /* notes is unused here (we assume) */ + list<string> notes; + return content_factory (film, cxml::NodePtr (new cxml::Node (node)), Film::current_state_version, notes); } string diff --git a/src/lib/content_factory.cc b/src/lib/content_factory.cc index 825c80498..092efd790 100644 --- a/src/lib/content_factory.cc +++ b/src/lib/content_factory.cc @@ -25,17 +25,18 @@ #include "util.h" using std::string; +using std::list; using boost::shared_ptr; shared_ptr<Content> -content_factory (shared_ptr<const Film> film, cxml::NodePtr node, int version) +content_factory (shared_ptr<const Film> film, cxml::NodePtr node, int version, list<string>& notes) { string const type = node->string_child ("Type"); boost::shared_ptr<Content> content; if (type == "FFmpeg") { - content.reset (new FFmpegContent (film, node, version)); + content.reset (new FFmpegContent (film, node, version, notes)); } else if (type == "Image") { content.reset (new ImageContent (film, node, version)); } else if (type == "Sndfile") { diff --git a/src/lib/content_factory.h b/src/lib/content_factory.h index 071d925e0..2eeebbc9f 100644 --- a/src/lib/content_factory.h +++ b/src/lib/content_factory.h @@ -19,5 +19,5 @@ class Film; -extern boost::shared_ptr<Content> content_factory (boost::shared_ptr<const Film>, cxml::NodePtr, int); +extern boost::shared_ptr<Content> content_factory (boost::shared_ptr<const Film>, cxml::NodePtr, int, std::list<std::string> &); extern boost::shared_ptr<Content> content_factory (boost::shared_ptr<const Film>, boost::filesystem::path); diff --git a/src/lib/cross.cc b/src/lib/cross.cc index 786f4b997..8785553cb 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -310,8 +310,11 @@ Waker::nudge () Waker::Waker () { -#ifdef DCPOMATIC_OSX - IOPMAssertionCreateWithName (kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR ("Encoding DCP"), &_assertion_id); +#ifdef DCPOMATIC_OSX + /* We should use this */ + // IOPMAssertionCreateWithName (kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR ("Encoding DCP"), &_assertion_id); + /* but it's not available on 10.5, so we use this */ + IOPMAssertionCreate (kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &_assertion_id); #endif } diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 2b535a2ab..90c00283d 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -58,7 +58,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> f, boost::filesystem::path } -FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version) +FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version, list<string>& notes) : Content (f, node) , VideoContent (f, node, version) , AudioContent (f, node) @@ -82,7 +82,12 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::N c = node->node_children ("Filter"); for (list<cxml::NodePtr>::iterator i = c.begin(); i != c.end(); ++i) { - _filters.push_back (Filter::from_id ((*i)->content ())); + Filter const * f = Filter::from_id ((*i)->content ()); + if (f) { + _filters.push_back (f); + } else { + notes.push_back (String::compose (_("DCP-o-matic no longer supports the `%1' filter, so it has been turned off."), (*i)->content())); + } } _first_video = node->optional_number_child<double> ("FirstVideo"); @@ -213,13 +218,13 @@ FFmpegContent::technical_summary () const ss = _subtitle_stream->technical_summary (); } - pair<string, string> filt = Filter::ffmpeg_strings (_filters); + string filt = Filter::ffmpeg_string (_filters); return Content::technical_summary() + " - " + VideoContent::technical_summary() + " - " + AudioContent::technical_summary() + " - " + String::compose ( - "ffmpeg: audio %1, subtitle %2, filters %3 %4", as, ss, filt.first, filt.second + "ffmpeg: audio %1, subtitle %2, filters %3", as, ss, filt ); } @@ -470,3 +475,23 @@ FFmpegContent::identifier () const return s.str (); } +boost::filesystem::path +FFmpegContent::audio_analysis_path () const +{ + shared_ptr<const Film> film = _film.lock (); + if (!film) { + return boost::filesystem::path (); + } + + /* We need to include the stream ID in this path so that we get different + analyses for each stream. + */ + + boost::filesystem::path p = film->audio_analysis_dir (); + string name = digest (); + if (audio_stream ()) { + name += "_" + audio_stream()->identifier (); + } + p /= name; + return p; +} diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 935d9560d..e4c4a8a52 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -127,7 +127,7 @@ class FFmpegContent : public VideoContent, public AudioContent, public SubtitleC { public: FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path); - FFmpegContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int version); + FFmpegContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int version, std::list<std::string> &); FFmpegContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >); boost::shared_ptr<FFmpegContent> shared_from_this () { @@ -150,6 +150,7 @@ public: int output_audio_frame_rate () const; AudioMapping audio_mapping () const; void set_audio_mapping (AudioMapping); + boost::filesystem::path audio_analysis_path () const; void set_filters (std::vector<Filter const *> const &); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d37399eb3..32b00a1d6 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -487,14 +487,9 @@ FFmpegDecoder::decode_video_packet () list<pair<shared_ptr<Image>, int64_t> > images = graph->process (_frame); - string post_process = Filter::ffmpeg_strings (_ffmpeg_content->filters()).second; - for (list<pair<shared_ptr<Image>, int64_t> >::iterator i = images.begin(); i != images.end(); ++i) { shared_ptr<Image> image = i->first; - if (!post_process.empty ()) { - image = image->post_process (post_process, true); - } if (i->second != AV_NOPTS_VALUE) { video (image, false, ContentTime::from_seconds (i->second * av_q2d (_format_context->streams[_video_stream]->time_base)) + _pts_offset); diff --git a/src/lib/film.cc b/src/lib/film.cc index 21e7383bf..cc80f5bc2 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -232,11 +232,9 @@ Film::filename_safe_name () const } boost::filesystem::path -Film::audio_analysis_path (shared_ptr<const AudioContent> c) const +Film::audio_analysis_dir () const { - boost::filesystem::path p = dir ("analysis"); - p /= c->digest(); - return p; + return dir ("analysis"); } /** Add suitable Jobs to the JobManager to create a DCP for this Film */ @@ -383,8 +381,10 @@ Film::write_metadata () const _dirty = false; } -/** Read state from our metadata file */ -void +/** Read state from our metadata file. + * @return Notes about things that the user should know about, or empty. + */ +list<string> Film::read_metadata () { LocaleGuard lg; @@ -432,9 +432,13 @@ Film::read_metadata () _three_d = f.bool_child ("ThreeD"); _interop = f.bool_child ("Interop"); _key = dcp::Key (f.string_child ("Key")); - _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version); + + list<string> notes; + /* This method is the only one that can return notes (so far) */ + _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version, notes); _dirty = false; + return notes; } /** Given a directory name, return its full path within the Film's directory. @@ -923,6 +927,7 @@ Film::set_sequence_video (bool s) signal_changed (SEQUENCE_VIDEO); } +/** @return Size of the largest possible image in whatever resolution we are using */ dcp::Size Film::full_frame () const { @@ -937,6 +942,13 @@ Film::full_frame () const return dcp::Size (); } +/** @return Size of the frame */ +dcp::Size +Film::frame_size () const +{ + return fit_ratio_within (container()->ratio(), full_frame ()); +} + dcp::KDM Film::make_kdm ( shared_ptr<dcp::Certificate> target, diff --git a/src/lib/film.h b/src/lib/film.h index f776a3f72..9d1445d92 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -63,7 +63,7 @@ public: boost::filesystem::path info_path (int, Eyes) const; boost::filesystem::path internal_video_mxf_dir () const; boost::filesystem::path internal_video_mxf_filename () const; - boost::filesystem::path audio_analysis_path (boost::shared_ptr<const AudioContent>) const; + boost::filesystem::path audio_analysis_dir () const; boost::filesystem::path video_mxf_filename () const; boost::filesystem::path audio_mxf_filename () const; @@ -83,7 +83,7 @@ public: boost::filesystem::path file (boost::filesystem::path f) const; boost::filesystem::path dir (boost::filesystem::path d) const; - void read_metadata (); + std::list<std::string> read_metadata (); void write_metadata () const; boost::shared_ptr<xmlpp::Document> metadata () const; @@ -96,6 +96,7 @@ public: } dcp::Size full_frame () const; + dcp::Size frame_size () const; std::list<boost::filesystem::path> dcps () const; diff --git a/src/lib/filter.cc b/src/lib/filter.cc index 640a531e8..a7dd9c5ce 100644 --- a/src/lib/filter.cc +++ b/src/lib/filter.cc @@ -24,7 +24,6 @@ #include "filter.h" extern "C" { #include <libavfilter/avfilter.h> -#include <libpostproc/postprocess.h> } #include "i18n.h" @@ -36,15 +35,13 @@ vector<Filter const *> Filter::_filters; /** @param i Our id. * @param n User-visible name. * @param c User-visible category. - * @param v String for a FFmpeg video filter descriptor, or "". - * @param p String for a FFmpeg post-processing descriptor, or "". + * @param v String for a FFmpeg video filter descriptor. */ -Filter::Filter (string i, string n, string c, string v, string p) +Filter::Filter (string i, string n, string c, string v) : _id (i) , _name (n) , _category (c) , _vf (v) - , _pp (p) { } @@ -65,75 +62,41 @@ Filter::setup_filters () { /* Note: "none" is a magic id name, so don't use it here */ - maybe_add (N_("pphb"), _("Horizontal deblocking filter"), _("De-blocking"), N_(""), N_("hb")); - maybe_add (N_("ppvb"), _("Vertical deblocking filter"), _("De-blocking"), N_(""), N_("vb")); - maybe_add (N_("ppha"), _("Horizontal deblocking filter A"), _("De-blocking"), N_(""), N_("ha")); - maybe_add (N_("ppva"), _("Vertical deblocking filter A"), _("De-blocking"), N_(""), N_("va")); - maybe_add (N_("pph1"), _("Experimental horizontal deblocking filter 1"), _("De-blocking"), N_(""), N_("h1")); - maybe_add (N_("pphv"), _("Experimental vertical deblocking filter 1"), _("De-blocking"), N_(""), N_("v1")); - maybe_add (N_("ppdr"), _("Deringing filter"), _("Misc"), N_(""), N_("dr")); - maybe_add (N_("pplb"), _("Linear blend deinterlacer"), _("De-interlacing"), N_(""), N_("lb")); - maybe_add (N_("ppli"), _("Linear interpolating deinterlacer"), _("De-interlacing"), N_(""), N_("li")); - maybe_add (N_("ppci"), _("Cubic interpolating deinterlacer"), _("De-interlacing"), N_(""), N_("ci")); - maybe_add (N_("ppmd"), _("Median deinterlacer"), _("De-interlacing"), N_(""), N_("md")); - maybe_add (N_("ppfd"), _("FFMPEG deinterlacer"), _("De-interlacing"), N_(""), N_("fd")); - maybe_add (N_("ppl5"), _("FIR low-pass deinterlacer"), _("De-interlacing"), N_(""), N_("l5")); - maybe_add (N_("mcdeint"), _("Motion compensating deinterlacer"), _("De-interlacing"), N_("mcdeint"), N_("")); - maybe_add (N_("kerndeint"), _("Kernel deinterlacer"), _("De-interlacing"), N_("kerndeint"), N_("")); - maybe_add (N_("yadif"), _("Yet Another Deinterlacing Filter"), _("De-interlacing"), N_("yadif"), N_("")); - maybe_add (N_("pptn"), _("Temporal noise reducer"), _("Noise reduction"), N_(""), N_("tn")); - maybe_add (N_("ppfq"), _("Force quantizer"), _("Misc"), N_(""), N_("fq")); - maybe_add (N_("gradfun"), _("Gradient debander"), _("Misc"), N_("gradfun"), N_("")); - maybe_add (N_("unsharp"), _("Unsharp mask and Gaussian blur"), _("Misc"), N_("unsharp"), N_("")); - maybe_add (N_("denoise3d"), _("3D denoiser"), _("Noise reduction"), N_("denoise3d"), N_("")); - maybe_add (N_("hqdn3d"), _("High quality 3D denoiser"), _("Noise reduction"), N_("hqdn3d"), N_("")); - maybe_add (N_("telecine"), _("Telecine filter"), _("Misc"), N_("telecine"), N_("")); - maybe_add (N_("ow"), _("Overcomplete wavelet denoiser"), _("Noise reduction"), N_("mp=ow"), N_("")); + maybe_add (N_("mcdeint"), _("Motion compensating deinterlacer"), _("De-interlacing"), N_("mcdeint")); + maybe_add (N_("kerndeint"), _("Kernel deinterlacer"), _("De-interlacing"), N_("kerndeint")); + maybe_add (N_("yadif"), _("Yet Another Deinterlacing Filter"), _("De-interlacing"), N_("yadif")); + maybe_add (N_("gradfun"), _("Gradient debander"), _("Misc"), N_("gradfun")); + maybe_add (N_("unsharp"), _("Unsharp mask and Gaussian blur"), _("Misc"), N_("unsharp")); + maybe_add (N_("denoise3d"), _("3D denoiser"), _("Noise reduction"), N_("denoise3d")); + maybe_add (N_("hqdn3d"), _("High quality 3D denoiser"), _("Noise reduction"), N_("hqdn3d")); + maybe_add (N_("telecine"), _("Telecine filter"), _("Misc"), N_("telecine")); + maybe_add (N_("ow"), _("Overcomplete wavelet denoiser"), _("Noise reduction"), N_("mp=ow")); } void -Filter::maybe_add (string i, string n, string c, string v, string p) +Filter::maybe_add (string i, string n, string c, string v) { - if (!v.empty ()) { - if (avfilter_get_by_name (i.c_str())) { - _filters.push_back (new Filter (i, n, c, v, p)); - } - } else if (!p.empty ()) { - pp_mode* m = pp_get_mode_by_name_and_quality (p.c_str(), PP_QUALITY_MAX); - if (m) { - _filters.push_back (new Filter (i, n, c, v, p)); - pp_free_mode (m); - } + if (avfilter_get_by_name (i.c_str())) { + _filters.push_back (new Filter (i, n, c, v)); } } /** @param filters Set of filters. - * @return A pair; .first is a string to pass to FFmpeg for the video filters, - * .second is a string to pass for the post-processors. + * @return String to pass to FFmpeg for the video filters. */ -pair<string, string> -Filter::ffmpeg_strings (vector<Filter const *> const & filters) +string +Filter::ffmpeg_string (vector<Filter const *> const & filters) { string vf; - string pp; for (vector<Filter const *>::const_iterator i = filters.begin(); i != filters.end(); ++i) { - if (!(*i)->vf().empty ()) { - if (!vf.empty ()) { - vf += N_(","); - } - vf += (*i)->vf (); - } - - if (!(*i)->pp().empty ()) { - if (!pp.empty()) { - pp += N_(","); - } - pp += (*i)->pp (); + if (!vf.empty ()) { + vf += N_(","); } + vf += (*i)->vf (); } - return make_pair (vf, pp); + return vf; } /** @param d Our id. diff --git a/src/lib/filter.h b/src/lib/filter.h index 5971cd5cf..258e74991 100644 --- a/src/lib/filter.h +++ b/src/lib/filter.h @@ -29,12 +29,16 @@ #include <boost/utility.hpp> /** @class Filter - * @brief A class to describe one of FFmpeg's video or post-processing filters. + * @brief A class to describe one of FFmpeg's video filters. + * + * We don't support FFmpeg's post-processing filters here as they cannot cope with greater than + * 8bpp. FFmpeg quantizes e.g. yuv422p10le down to yuv422p before running such filters, which + * we don't really want to do. */ class Filter : public boost::noncopyable { public: - Filter (std::string, std::string, std::string, std::string, std::string); + Filter (std::string, std::string, std::string, std::string); /** @return our id */ std::string id () const { @@ -51,11 +55,6 @@ public: return _vf; } - /** @return string for a FFmpeg post-processing descriptor */ - std::string pp () const { - return _pp; - } - std::string category () const { return _category; } @@ -63,7 +62,7 @@ public: static std::vector<Filter const *> all (); static Filter const * from_id (std::string); static void setup_filters (); - static std::pair<std::string, std::string> ffmpeg_strings (std::vector<Filter const *> const &); + static std::string ffmpeg_string (std::vector<Filter const *> const &); private: @@ -74,12 +73,10 @@ private: std::string _category; /** string for a FFmpeg video filter descriptor */ std::string _vf; - /** string for a FFmpeg post-processing descriptor */ - std::string _pp; /** all available filters */ static std::vector<Filter const *> _filters; - static void maybe_add (std::string, std::string, std::string, std::string, std::string); + static void maybe_add (std::string, std::string, std::string, std::string); }; #endif diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 48d94e175..5add16d19 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -60,7 +60,7 @@ FilterGraph::FilterGraph (shared_ptr<const FFmpegContent> content, dcp::Size s, { _frame = av_frame_alloc (); - string filters = Filter::ffmpeg_strings (content->filters()).first; + string filters = Filter::ffmpeg_string (content->filters()); if (filters.empty ()) { filters = "copy"; } diff --git a/src/lib/image.cc b/src/lib/image.cc index 98645c299..c3b1ca77a 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -168,51 +168,6 @@ Image::scale (dcp::Size out_size, Scaler const * scaler, AVPixelFormat out_forma return scaled; } -/** Run a FFmpeg post-process on this image and return the processed version. - * @param pp Flags for the required set of post processes. - * @return Post-processed image. - */ -shared_ptr<Image> -Image::post_process (string pp, bool aligned) const -{ - shared_ptr<Image> out (new Image (pixel_format(), size (), aligned)); - - int pp_format = 0; - switch (pixel_format()) { - case PIX_FMT_YUV420P: - pp_format = PP_FORMAT_420; - break; - case PIX_FMT_YUV422P10LE: - case PIX_FMT_YUV422P: - case PIX_FMT_UYVY422: - pp_format = PP_FORMAT_422; - break; - case PIX_FMT_YUV444P: - case PIX_FMT_YUV444P9BE: - case PIX_FMT_YUV444P9LE: - case PIX_FMT_YUV444P10BE: - case PIX_FMT_YUV444P10LE: - pp_format = PP_FORMAT_444; - default: - throw PixelFormatError ("post_process", pixel_format()); - } - - pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX); - pp_context* context = pp_get_context (size().width, size().height, pp_format | PP_CPU_CAPS_MMX2); - - pp_postprocess ( - (const uint8_t **) data(), stride(), - out->data(), out->stride(), - size().width, size().height, - 0, 0, mode, context, 0 - ); - - pp_free_mode (mode); - pp_free_context (context); - - return out; -} - shared_ptr<Image> Image::crop (Crop crop, bool aligned) const { diff --git a/src/lib/image.h b/src/lib/image.h index 3220a23b4..5eba11041 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -58,7 +58,6 @@ public: int lines (int) const; boost::shared_ptr<Image> scale (dcp::Size, Scaler const *, AVPixelFormat, bool aligned) const; - boost::shared_ptr<Image> post_process (std::string, bool aligned) const; boost::shared_ptr<Image> crop (Crop c, bool aligned) const; boost::shared_ptr<Image> crop_scale_window (Crop c, dcp::Size, dcp::Size, Scaler const *, AVPixelFormat, bool aligned) const; diff --git a/src/lib/player.cc b/src/lib/player.cc index e89e84aa6..f83e4ed26 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -81,7 +81,7 @@ Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p) _playlist_changed_connection = _playlist->Changed.connect (bind (&Player::playlist_changed, this)); _playlist_content_changed_connection = _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2, _3)); _film_changed_connection = _film->Changed.connect (bind (&Player::film_changed, this, _1)); - set_video_container_size (fit_ratio_within (_film->container()->ratio (), _film->full_frame ())); + set_video_container_size (_film->frame_size ()); } void diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index b7b4c20f7..c46e65d8b 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -113,11 +113,11 @@ Playlist::video_identifier () const /** @param node <Playlist> node */ void -Playlist::set_from_xml (shared_ptr<const Film> film, shared_ptr<const cxml::Node> node, int version) +Playlist::set_from_xml (shared_ptr<const Film> film, shared_ptr<const cxml::Node> node, int version, list<string>& notes) { list<cxml::NodePtr> c = node->node_children ("Content"); for (list<cxml::NodePtr>::iterator i = c.begin(); i != c.end(); ++i) { - _content.push_back (content_factory (film, *i, version)); + _content.push_back (content_factory (film, *i, version, notes)); } sort (_content.begin(), _content.end(), ContentSorter ()); diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 35709f109..444eb9ae5 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -57,7 +57,7 @@ public: ~Playlist (); void as_xml (xmlpp::Node *); - void set_from_xml (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int); + void set_from_xml (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int, std::list<std::string> &); void add (boost::shared_ptr<Content>); void remove (boost::shared_ptr<Content>); diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 11310c5da..c3aea2b0f 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -442,19 +442,30 @@ VideoContentScale::name () const return _("No scale"); } +/** @param display_container Size of the container that we are displaying this content in. + * @param film_container The size of the film's image. + */ dcp::Size -VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size container) const +VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size display_container, dcp::Size film_container) const { if (_ratio) { - return fit_ratio_within (_ratio->ratio (), container); + return fit_ratio_within (_ratio->ratio (), display_container); } - /* Force scale if the container is smaller than the content's image */ - if (_scale || container.width < c->video_size().width || container.height < c->video_size().height) { - return fit_ratio_within (c->video_size().ratio (), container); + libdcp::Size const ac = c->video_size_after_crop (); + + /* Force scale if the film_container is smaller than the content's image */ + if (_scale || film_container.width < ac.width || film_container.height < ac.height) { + return fit_ratio_within (ac.ratio (), display_container); } - return c->video_size (); + /* Scale the image so that it will be in the right place in film_container, even if display_container is a + different size. + */ + return libdcp::Size ( + c->video_size().width * float(display_container.width) / film_container.width, + c->video_size().height * float(display_container.height) / film_container.height + ); } void diff --git a/src/lib/video_content.h b/src/lib/video_content.h index a82c6c221..d2b19480f 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -45,7 +45,7 @@ public: VideoContentScale (bool); VideoContentScale (boost::shared_ptr<cxml::Node>); - dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size) const; + dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size, dcp::Size) const; std::string id () const; std::string name () const; void as_xml (xmlpp::Node *) const; @@ -64,7 +64,9 @@ public: } private: + /** a ratio to stretch the content to, or 0 for no stretch */ Ratio const * _ratio; + /** true if we want to scale the content */ bool _scale; static std::vector<VideoContentScale> _scales; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 33b7dd51e..125efd644 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -45,6 +45,9 @@ #include "i18n.h" +/* OS X strikes again */ +#undef set_key + using std::make_pair; using std::pair; using std::string; @@ -91,7 +94,7 @@ Writer::Writer (shared_ptr<const Film> f, weak_ptr<Job> j) _picture_mxf.reset (new dcp::MonoPictureMXF (dcp::Fraction (_film->video_frame_rate (), 1))); } - _picture_mxf->set_size (fit_ratio_within (_film->container()->ratio(), _film->full_frame ())); + _picture_mxf->set_size (_film->frame_size ()); if (_film->encrypted ()) { _picture_mxf->set_key (_film->key ()); diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 6b534f4de..2f64371ae 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,6 +29,7 @@ #include <wx/generic/aboutdlgg.h> #include <wx/stdpaths.h> #include <wx/cmdline.h> +#include <wx/preferences.h> #include "wx/film_viewer.h" #include "wx/film_editor.h" #include "wx/job_manager_view.h" @@ -114,7 +115,7 @@ private: }; -void +static void maybe_save_then_delete_film () { if (!film) { @@ -135,6 +136,30 @@ maybe_save_then_delete_film () film.reset (); } +static void +check_film_state_version (int v) +{ + if (v == 4) { + error_dialog ( + 0, + _("This film was created with an old version of DVD-o-matic and may not load correctly " + "in this version. Please check the film's settings carefully.") + ); + } +} + +static void +load_film (boost::filesystem::path file) +{ + film.reset (new Film (file)); + list<string> const notes = film->read_metadata (); + check_film_state_version (film->state_version ()); + for (list<string>::const_iterator i = notes.begin(); i != notes.end(); ++i) { + error_dialog (0, std_to_wx (*i)); + } + film->log()->set_level (log_level); +} + #define ALWAYS 0x0 #define NEEDS_FILM 0x1 #define NOT_DURING_DCP_CREATION 0x2 @@ -142,14 +167,14 @@ maybe_save_then_delete_film () map<wxMenuItem*, int> menu_items; -void +static void add_item (wxMenu* menu, wxString text, int id, int sens) { wxMenuItem* item = menu->Append (id, text); menu_items.insert (make_pair (item, sens)); } -void +static void set_menu_sensitivity () { list<shared_ptr<Job> > jobs = JobManager::instance()->get (); @@ -194,7 +219,7 @@ enum { ID_tools_check_for_updates }; -void +static void setup_menu (wxMenuBar* m) { wxMenu* file = new wxMenu; @@ -256,6 +281,7 @@ public: : wxFrame (NULL, -1, title) , _hints_dialog (0) , _servers_list_dialog (0) + , _config_dialog (0) { #if defined(DCPOMATIC_WINDOWS) && defined(DCPOMATIC_WINDOWS_CONSOLE) AllocConsole(); @@ -326,17 +352,6 @@ public: overall_panel->SetSizer (main_sizer); } - void check_film_state_version (int v) - { - if (v == 4) { - error_dialog ( - this, - _("This film was created with an old version of DVD-o-matic and may not load correctly " - "in this version. Please check the film's settings carefully.") - ); - } - } - private: void set_film () @@ -416,10 +431,7 @@ private: if (r == wxID_OK) { maybe_save_then_delete_film (); try { - film.reset (new Film (wx_to_std (c->GetPath ()))); - film->read_metadata (); - check_film_state_version (film->state_version ()); - film->log()->set_level (log_level); + load_film (wx_to_std (c->GetPath ())); set_film (); } catch (std::exception& e) { wxString p = c->GetPath (); @@ -450,10 +462,10 @@ private: void edit_preferences () { - ConfigDialog* d = new ConfigDialog (this); - d->ShowModal (); - d->Destroy (); - Config::instance()->write (); + if (!_config_dialog) { + _config_dialog = create_config_dialog (); + } + _config_dialog->Show (this); } void jobs_make_dcp () @@ -592,6 +604,7 @@ private: HintsDialog* _hints_dialog; ServersListDialog* _servers_list_dialog; + wxPreferencesEditor* _config_dialog; }; static const wxCmdLineEntryDesc command_line_description[] = { @@ -645,9 +658,7 @@ class App : public wxApp if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) { try { - film.reset (new Film (film_to_load)); - film->read_metadata (); - film->log()->set_level (log_level); + load_film (film_to_load); } catch (exception& e) { error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), film_to_load, e.what()))); } @@ -677,7 +688,7 @@ class App : public wxApp _timer->Start (1000); if (film) { - _frame->check_film_state_version (film->state_version ()); + check_film_state_version (film->state_version ()); } UpdateChecker::instance()->StateChanged.connect (boost::bind (&App::update_checker_state_changed, this)); diff --git a/src/wx/about_dialog.cc b/src/wx/about_dialog.cc index 3c0730870..01332dfcc 100644 --- a/src/wx/about_dialog.cc +++ b/src/wx/about_dialog.cc @@ -91,92 +91,96 @@ AboutDialog::AboutDialog (wxWindow* parent) add_section (_("Written by"), written_by); wxArrayString translated_by; - translated_by.Add (wxT ("Adam Klotblixt")); - translated_by.Add (wxT ("Lilian Lefranc")); translated_by.Add (wxT ("Manuel AC")); - translated_by.Add (wxT ("Markus Raab")); translated_by.Add (wxT ("Massimiliano Broggi")); - translated_by.Add (wxT ("Olivier Perriere")); - translated_by.Add (wxT ("Thierry Journet")); translated_by.Add (wxT ("William Fanelli")); + translated_by.Add (wxT ("Thierry Journet")); + translated_by.Add (wxT ("Adam Klotblixt")); + translated_by.Add (wxT ("Lilian Lefranc")); + translated_by.Add (wxT ("Olivier Perriere")); + translated_by.Add (wxT ("Markus Raab")); add_section (_("Translated by"), translated_by); + wxArrayString artwork_by; + artwork_by.Add (wxT ("David Vignoni")); + add_section (_("Artwork by"), artwork_by); + wxArrayString supported_by; + supported_by.Add (wxT ("Manual AC")); + supported_by.Add (wxT ("Kambiz Afshar")); + supported_by.Add (wxT ("Jeff Boot")); + supported_by.Add (wxT ("Kieran Carroll")); + supported_by.Add (wxT ("Frank Cianciolo")); + supported_by.Add (wxT ("Cinema Clarici")); supported_by.Add (wxT ("Adam Colt")); - supported_by.Add (wxT ("Adam Klotblixt")); - supported_by.Add (wxT ("Aldo Midali")); supported_by.Add (wxT ("Andres Fink")); - supported_by.Add (wxT ("Andrä Steiner")); - supported_by.Add (wxT ("Carsten Kurz")); - supported_by.Add (wxT ("Cinema Clarici")); supported_by.Add (wxT ("Evan Freeze")); - supported_by.Add (wxT ("Filip Kovcin")); + supported_by.Add (wxT ("Rodolfo Giuliano")); supported_by.Add (wxT ("Flor Guillaume")); - supported_by.Add (wxT ("Frank Cianciolo")); - supported_by.Add (wxT ("Frank de Wulf")); + supported_by.Add (wxT ("Jonathan Jensen")); + supported_by.Add (wxT ("Adam Klotblixt")); + supported_by.Add (wxT ("Filip Kovcin")); + supported_by.Add (wxT ("Carsten Kurz")); + supported_by.Add (wxT ("Lilian Lefranc")); + supported_by.Add (wxT ("Sean Leigh")); + supported_by.Add (wxT ("Olivier Lemaire")); supported_by.Add (wxT ("Gavin Lewarne")); + supported_by.Add (wxT ("Theo Lipfert")); + supported_by.Add (wxT ("Mattias Mattsson")); + supported_by.Add (wxT ("Kjarten Michaelsen")); + supported_by.Add (wxT ("Aldo Midali")); + supported_by.Add (wxT ("Sylvain Mielle")); + supported_by.Add (wxT ("Lindsay Morris")); + supported_by.Add (wxT ("Tim O'Brien")); supported_by.Add (wxT ("Ivan Pullman")); - supported_by.Add (wxT ("Jeff Boot")); - supported_by.Add (wxT ("Jonathan Jensen")); + supported_by.Add (wxT ("Andrä Steiner")); supported_by.Add (wxT ("Jussi Siponen")); - supported_by.Add (wxT ("Kambiz Afshar")); - supported_by.Add (wxT ("Kieran Carroll")); - supported_by.Add (wxT ("Kjarten Michaelsen")); supported_by.Add (wxT ("Lasse Salling")); - supported_by.Add (wxT ("Lilian Lefranc")); - supported_by.Add (wxT ("Lindsay Morris")); - supported_by.Add (wxT ("Manual AC")); - supported_by.Add (wxT ("Mattias Mattsson")); supported_by.Add (wxT ("Mike Stiebing")); - supported_by.Add (wxT ("Olivier Lemaire")); supported_by.Add (wxT ("Randy Stankey")); - supported_by.Add (wxT ("Rodolfo Giuliano")); - supported_by.Add (wxT ("Sean Leigh")); - supported_by.Add (wxT ("Sylvain Mielle")); - supported_by.Add (wxT ("Theo Lipfert")); - supported_by.Add (wxT ("Tim O'Brien")); supported_by.Add (wxT ("Wolfgang Woehl")); supported_by.Add (wxT ("Wolfram Weber")); + supported_by.Add (wxT ("Frank de Wulf")); add_section (_("Supported by"), supported_by); wxArrayString tested_by; - tested_by.Add (wxT ("Ada de Kamper")); - tested_by.Add (wxT ("Adam Colt")); - tested_by.Add (wxT ("Adam Keay")); - tested_by.Add (wxT ("Anders Nordentoft-Madsen")); - tested_by.Add (wxT ("Andreas Eli")); - tested_by.Add (wxT ("Andreas Weiss")); - tested_by.Add (wxT ("Bill Lam")); - tested_by.Add (wxT ("Brad Miller")); - tested_by.Add (wxT ("Carsten Kurz")); + tested_by.Add (wxT ("Trever Anderson")); + tested_by.Add (wxT ("Mike Blakesley")); tested_by.Add (wxT ("David Booty")); - tested_by.Add (wxT ("Denzil Kriekenbeek")); - tested_by.Add (wxT ("Gavin Lewarne")); - tested_by.Add (wxT ("Greg Rooke")); - tested_by.Add (wxT ("Gérald Maruccia")); + tested_by.Add (wxT ("Roop Chand")); + tested_by.Add (wxT ("Adam Colt")); tested_by.Add (wxT ("John Convertino")); + tested_by.Add (wxT ("Andreas Eli")); + tested_by.Add (wxT ("Maurizio Giampà ")); + tested_by.Add (wxT ("Luke Granger-Brown")); + tested_by.Add (wxT ("Steve Guttag")); + tested_by.Add (wxT ("Patrick Haderer")); tested_by.Add (wxT ("Jonathan Jensen")); - tested_by.Add (wxT ("Karim Senoucci")); + tested_by.Add (wxT ("Thierry Journet")); + tested_by.Add (wxT ("Ada de Kamper")); + tested_by.Add (wxT ("Stefan Karner")); + tested_by.Add (wxT ("Adam Keay")); + tested_by.Add (wxT ("Simon Kesselman")); + tested_by.Add (wxT ("Pepijn Klijs")); + tested_by.Add (wxT ("Denzil Kriekenbeek")); + tested_by.Add (wxT ("Carsten Kurz")); + tested_by.Add (wxT ("Bill Lam")); tested_by.Add (wxT ("Lilian Lefranc")); - tested_by.Add (wxT ("Luke Granger-Brown")); - tested_by.Add (wxT ("Markus Raab")); + tested_by.Add (wxT ("Olivier Lemaire")); + tested_by.Add (wxT ("Gavin Lewarne")); tested_by.Add (wxT ("Mattias Mattsson")); - tested_by.Add (wxT ("Maurizio Giampà ")); + tested_by.Add (wxT ("Gérald Maruccia")); + tested_by.Add (wxT ("Will Meadows")); + tested_by.Add (wxT ("Brad Miller")); + tested_by.Add (wxT ("Anders Nordentoft-Madsen")); tested_by.Add (wxT ("Mauro Ottonello")); - tested_by.Add (wxT ("Mike Blakesley")); - tested_by.Add (wxT ("Olivier Lemaire")); - tested_by.Add (wxT ("Patrick Haderer")); - tested_by.Add (wxT ("Paul Willmott")); - tested_by.Add (wxT ("Pepijn Klijs")); tested_by.Add (wxT ("Peter Puchner")); - tested_by.Add (wxT ("Roop Chand")); - tested_by.Add (wxT ("Simon Kesselman")); + tested_by.Add (wxT ("Markus Raab")); + tested_by.Add (wxT ("Greg Rooke")); + tested_by.Add (wxT ("Karim Senoucci")); tested_by.Add (wxT ("Simon Vannarath")); - tested_by.Add (wxT ("Stefan Karner")); - tested_by.Add (wxT ("Steve Guttag")); - tested_by.Add (wxT ("Thierry Journet")); - tested_by.Add (wxT ("Trever Anderson")); - tested_by.Add (wxT ("Will Meadows")); + tested_by.Add (wxT ("Andreas Weiss")); + tested_by.Add (wxT ("Paul Willmott")); tested_by.Add (wxT ("Wolfgang Woehl")); add_section (_("Tested by"), tested_by); diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 911cb4b3f..44745006c 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,7 +25,9 @@ #include <boost/lexical_cast.hpp> #include <boost/filesystem.hpp> #include <wx/stdpaths.h> -#include <wx/notebook.h> +#include <wx/preferences.h> +#include <wx/filepicker.h> +#include <wx/spinctrl.h> #include <dcp/colour_matrix.h> #include "lib/config.h" #include "lib/ratio.h" @@ -35,6 +37,7 @@ #include "lib/colour_conversion.h" #include "config_dialog.h" #include "wx_util.h" +#include "editable_list.h" #include "filter_dialog.h" #include "dir_picker_ctrl.h" #include "dci_metadata_dialog.h" @@ -44,561 +47,691 @@ using std::vector; using std::string; using std::list; +using std::cout; using boost::bind; using boost::shared_ptr; using boost::lexical_cast; -ConfigDialog::ConfigDialog (wxWindow* parent) - : wxDialog (parent, wxID_ANY, _("DCP-o-matic Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +class Page { - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _notebook = new wxNotebook (this, wxID_ANY); - s->Add (_notebook, 1); - - make_misc_panel (); - _notebook->AddPage (_misc_panel, _("Miscellaneous"), true); - make_defaults_panel (); - _notebook->AddPage (_defaults_panel, _("Defaults"), false); - make_servers_panel (); - _notebook->AddPage (_servers_panel, _("Encoding servers"), false); - make_colour_conversions_panel (); - _notebook->AddPage (_colour_conversions_panel, _("Colour conversions"), false); - make_metadata_panel (); - _notebook->AddPage (_metadata_panel, _("Metadata"), false); - make_tms_panel (); - _notebook->AddPage (_tms_panel, _("TMS"), false); - make_kdm_email_panel (); - _notebook->AddPage (_kdm_email_panel, _("KDM email"), false); - - wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); - overall_sizer->Add (s, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER); - - wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); - if (buttons) { - overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); - } - - SetSizer (overall_sizer); - overall_sizer->Layout (); - overall_sizer->SetSizeHints (this); -} +public: + Page (wxSize panel_size, int border) + : _panel_size (panel_size) + , _border (border) + {} + +protected: + wxSize _panel_size; + int _border; +}; -void -ConfigDialog::make_misc_panel () +class GeneralPage : public wxStockPreferencesPage, public Page { - _misc_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _misc_panel->SetSizer (s); - - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); - - _set_language = new wxCheckBox (_misc_panel, wxID_ANY, _("Set language")); - table->Add (_set_language, 1); - _language = new wxChoice (_misc_panel, wxID_ANY); - _language->Append (wxT ("English")); - _language->Append (wxT ("Français")); - _language->Append (wxT ("Italiano")); - _language->Append (wxT ("Español")); - _language->Append (wxT ("Svenska")); - _language->Append (wxT ("Deutsch")); - table->Add (_language); - - wxStaticText* restart = add_label_to_sizer (table, _misc_panel, _("(restart DCP-o-matic to see language changes)"), false); - wxFont font = restart->GetFont(); - font.SetStyle (wxFONTSTYLE_ITALIC); - font.SetPointSize (font.GetPointSize() - 1); - restart->SetFont (font); - table->AddSpacer (0); - - add_label_to_sizer (table, _misc_panel, _("Threads to use for encoding on this host"), true); - _num_local_encoding_threads = new wxSpinCtrl (_misc_panel); - table->Add (_num_local_encoding_threads, 1); - - add_label_to_sizer (table, _misc_panel, _("Outgoing mail server"), true); - _mail_server = new wxTextCtrl (_misc_panel, wxID_ANY); - table->Add (_mail_server, 1, wxEXPAND | wxALL); - - add_label_to_sizer (table, _misc_panel, _("Mail user name"), true); - _mail_user = new wxTextCtrl (_misc_panel, wxID_ANY); - table->Add (_mail_user, 1, wxEXPAND | wxALL); - - add_label_to_sizer (table, _misc_panel, _("Mail password"), true); - _mail_password = new wxTextCtrl (_misc_panel, wxID_ANY); - table->Add (_mail_password, 1, wxEXPAND | wxALL); - - wxStaticText* plain = add_label_to_sizer (table, _misc_panel, _("(password will be stored on disk in plaintext)"), false); - plain->SetFont (font); - table->AddSpacer (0); - - add_label_to_sizer (table, _misc_panel, _("From address for KDM emails"), true); - _kdm_from = new wxTextCtrl (_misc_panel, wxID_ANY); - table->Add (_kdm_from, 1, wxEXPAND | wxALL); +public: + GeneralPage (wxSize panel_size, int border) + : wxStockPreferencesPage (Kind_General) + , Page (panel_size, border) + {} - _check_for_updates = new wxCheckBox (_misc_panel, wxID_ANY, _("Check for updates on startup")); - table->Add (_check_for_updates, 1, wxEXPAND | wxALL); - table->AddSpacer (0); + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, _border); + + _set_language = new wxCheckBox (panel, wxID_ANY, _("Set language")); + table->Add (_set_language, 1); + _language = new wxChoice (panel, wxID_ANY); + _language->Append (wxT ("English")); + _language->Append (wxT ("Français")); + _language->Append (wxT ("Italiano")); + _language->Append (wxT ("Español")); + _language->Append (wxT ("Svenska")); + _language->Append (wxT ("Deutsch")); + table->Add (_language); + + wxStaticText* restart = add_label_to_sizer (table, panel, _("(restart DCP-o-matic to see language changes)"), false); + wxFont font = restart->GetFont(); + font.SetStyle (wxFONTSTYLE_ITALIC); + font.SetPointSize (font.GetPointSize() - 1); + restart->SetFont (font); + table->AddSpacer (0); + + add_label_to_sizer (table, panel, _("Threads to use for encoding on this host"), true); + _num_local_encoding_threads = new wxSpinCtrl (panel); + table->Add (_num_local_encoding_threads, 1); + + add_label_to_sizer (table, panel, _("Outgoing mail server"), true); + _mail_server = new wxTextCtrl (panel, wxID_ANY); + table->Add (_mail_server, 1, wxEXPAND | wxALL); + + add_label_to_sizer (table, panel, _("Mail user name"), true); + _mail_user = new wxTextCtrl (panel, wxID_ANY); + table->Add (_mail_user, 1, wxEXPAND | wxALL); + + add_label_to_sizer (table, panel, _("Mail password"), true); + _mail_password = new wxTextCtrl (panel, wxID_ANY); + table->Add (_mail_password, 1, wxEXPAND | wxALL); + + wxStaticText* plain = add_label_to_sizer (table, panel, _("(password will be stored on disk in plaintext)"), false); + plain->SetFont (font); + table->AddSpacer (0); + + add_label_to_sizer (table, panel, _("From address for KDM emails"), true); + _kdm_from = new wxTextCtrl (panel, wxID_ANY); + table->Add (_kdm_from, 1, wxEXPAND | wxALL); + + _check_for_updates = new wxCheckBox (panel, wxID_ANY, _("Check for updates on startup")); + table->Add (_check_for_updates, 1, wxEXPAND | wxALL); + table->AddSpacer (0); + + _check_for_test_updates = new wxCheckBox (panel, wxID_ANY, _("Check for testing updates as well as stable ones")); + table->Add (_check_for_test_updates, 1, wxEXPAND | wxALL); + table->AddSpacer (0); + + Config* config = Config::instance (); + + _set_language->SetValue (config->language ()); + + if (config->language().get_value_or ("") == "fr") { + _language->SetSelection (1); + } else if (config->language().get_value_or ("") == "it") { + _language->SetSelection (2); + } else if (config->language().get_value_or ("") == "es") { + _language->SetSelection (3); + } else if (config->language().get_value_or ("") == "sv") { + _language->SetSelection (4); + } else if (config->language().get_value_or ("") == "de") { + _language->SetSelection (5); + } else { + _language->SetSelection (0); + } + + setup_language_sensitivity (); + + _set_language->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::set_language_changed, this)); + _language->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&GeneralPage::language_changed, this)); + + _num_local_encoding_threads->SetRange (1, 128); + _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ()); + _num_local_encoding_threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&GeneralPage::num_local_encoding_threads_changed, this)); + + _mail_server->SetValue (std_to_wx (config->mail_server ())); + _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::mail_server_changed, this)); + _mail_user->SetValue (std_to_wx (config->mail_user ())); + _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::mail_user_changed, this)); + _mail_password->SetValue (std_to_wx (config->mail_password ())); + _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::mail_password_changed, this)); + _kdm_from->SetValue (std_to_wx (config->kdm_from ())); + _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::kdm_from_changed, this)); + _check_for_updates->SetValue (config->check_for_updates ()); + _check_for_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_updates_changed, this)); + _check_for_test_updates->SetValue (config->check_for_test_updates ()); + _check_for_test_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_test_updates_changed, this)); + + return panel; + } - _check_for_test_updates = new wxCheckBox (_misc_panel, wxID_ANY, _("Check for testing updates as well as stable ones")); - table->Add (_check_for_test_updates, 1, wxEXPAND | wxALL); - table->AddSpacer (0); - - Config* config = Config::instance (); +private: + void setup_language_sensitivity () + { + _language->Enable (_set_language->GetValue ()); + } - _set_language->SetValue (config->language ()); + void set_language_changed () + { + setup_language_sensitivity (); + if (_set_language->GetValue ()) { + language_changed (); + } else { + Config::instance()->unset_language (); + } + } - if (config->language().get_value_or ("") == "fr") { - _language->SetSelection (1); - } else if (config->language().get_value_or ("") == "it") { - _language->SetSelection (2); - } else if (config->language().get_value_or ("") == "es") { - _language->SetSelection (3); - } else if (config->language().get_value_or ("") == "sv") { - _language->SetSelection (4); - } else if (config->language().get_value_or ("") == "de") { - _language->SetSelection (5); - } else { - _language->SetSelection (0); - } - - setup_language_sensitivity (); - - _set_language->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::set_language_changed, this)); - _language->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ConfigDialog::language_changed, this)); - - _num_local_encoding_threads->SetRange (1, 128); - _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ()); - _num_local_encoding_threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ConfigDialog::num_local_encoding_threads_changed, this)); - - _mail_server->SetValue (std_to_wx (config->mail_server ())); - _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::mail_server_changed, this)); - _mail_user->SetValue (std_to_wx (config->mail_user ())); - _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::mail_user_changed, this)); - _mail_password->SetValue (std_to_wx (config->mail_password ())); - _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::mail_password_changed, this)); - _kdm_from->SetValue (std_to_wx (config->kdm_from ())); - _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::kdm_from_changed, this)); - _check_for_updates->SetValue (config->check_for_updates ()); - _check_for_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::check_for_updates_changed, this)); - _check_for_test_updates->SetValue (config->check_for_test_updates ()); - _check_for_test_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::check_for_test_updates_changed, this)); -} + void language_changed () + { + switch (_language->GetSelection ()) { + case 0: + Config::instance()->set_language ("en"); + break; + case 1: + Config::instance()->set_language ("fr"); + break; + case 2: + Config::instance()->set_language ("it"); + break; + case 3: + Config::instance()->set_language ("es"); + break; + case 4: + Config::instance()->set_language ("sv"); + break; + case 5: + Config::instance()->set_language ("de"); + break; + } + } + + void mail_server_changed () + { + Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ())); + } + + void mail_user_changed () + { + Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ())); + } + + void mail_password_changed () + { + Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ())); + } + + void kdm_from_changed () + { + Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ())); + } -void -ConfigDialog::make_defaults_panel () -{ - _defaults_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _defaults_panel->SetSizer (s); + void check_for_updates_changed () + { + Config::instance()->set_check_for_updates (_check_for_updates->GetValue ()); + } + + void check_for_test_updates_changed () + { + Config::instance()->set_check_for_test_updates (_check_for_test_updates->GetValue ()); + } - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); + void num_local_encoding_threads_changed () + { + Config::instance()->set_num_local_encoding_threads (_num_local_encoding_threads->GetValue ()); + } + + wxCheckBox* _set_language; + wxChoice* _language; + wxSpinCtrl* _num_local_encoding_threads; + wxTextCtrl* _mail_server; + wxTextCtrl* _mail_user; + wxTextCtrl* _mail_password; + wxTextCtrl* _kdm_from; + wxCheckBox* _check_for_updates; + wxCheckBox* _check_for_test_updates; +}; + +class DefaultsPage : public wxPreferencesPage, public Page +{ +public: + DefaultsPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} + + wxString GetName () const + { + return _("Defaults"); + } +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const { - add_label_to_sizer (table, _defaults_panel, _("Default duration of still images"), true); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _default_still_length = new wxSpinCtrl (_defaults_panel); - s->Add (_default_still_length); - add_label_to_sizer (s, _defaults_panel, _("s"), false); - table->Add (s, 1); + return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE); } +#endif - add_label_to_sizer (table, _defaults_panel, _("Default directory for new films"), true); + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, _border); + + { + add_label_to_sizer (table, panel, _("Default duration of still images"), true); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _still_length = new wxSpinCtrl (panel); + s->Add (_still_length); + add_label_to_sizer (s, panel, _("s"), false); + table->Add (s, 1); + } + + add_label_to_sizer (table, panel, _("Default directory for new films"), true); #ifdef DCPOMATIC_USE_OWN_DIR_PICKER - _default_directory = new DirPickerCtrl (_defaults_panel); + _directory = new DirPickerCtrl (panel); #else - _default_directory = new wxDirPickerCtrl (_defaults_panel, wxDD_DIR_MUST_EXIST); + _directory = new wxDirPickerCtrl (panel, wxDD_DIR_MUST_EXIST); #endif - table->Add (_default_directory, 1, wxEXPAND); - - add_label_to_sizer (table, _defaults_panel, _("Default DCI name details"), true); - _default_dci_metadata_button = new wxButton (_defaults_panel, wxID_ANY, _("Edit...")); - table->Add (_default_dci_metadata_button); + table->Add (_directory, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("Default DCI name details"), true); + _dci_metadata_button = new wxButton (panel, wxID_ANY, _("Edit...")); + table->Add (_dci_metadata_button); + + add_label_to_sizer (table, panel, _("Default container"), true); + _container = new wxChoice (panel, wxID_ANY); + table->Add (_container); + + add_label_to_sizer (table, panel, _("Default content type"), true); + _dcp_content_type = new wxChoice (panel, wxID_ANY); + table->Add (_dcp_content_type); + + { + add_label_to_sizer (table, panel, _("Default JPEG2000 bandwidth"), true); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _j2k_bandwidth = new wxSpinCtrl (panel); + s->Add (_j2k_bandwidth); + add_label_to_sizer (s, panel, _("Mbit/s"), false); + table->Add (s, 1); + } + + { + add_label_to_sizer (table, panel, _("Default audio delay"), true); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _audio_delay = new wxSpinCtrl (panel); + s->Add (_audio_delay); + add_label_to_sizer (s, panel, _("ms"), false); + table->Add (s, 1); + } - add_label_to_sizer (table, _defaults_panel, _("Default container"), true); - _default_container = new wxChoice (_defaults_panel, wxID_ANY); - table->Add (_default_container); + add_label_to_sizer (table, panel, _("Default issuer"), true); + _issuer = new wxTextCtrl (panel, wxID_ANY); + table->Add (_issuer, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("Default creator"), true); + _creator = new wxTextCtrl (panel, wxID_ANY); + table->Add (_creator, 1, wxEXPAND); + + Config* config = Config::instance (); + + _still_length->SetRange (1, 3600); + _still_length->SetValue (config->default_still_length ()); + _still_length->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::still_length_changed, this)); + + _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ())); + _directory->Bind (wxEVT_COMMAND_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this)); + + _dci_metadata_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&DefaultsPage::edit_dci_metadata_clicked, this, parent)); + + vector<Ratio const *> ratio = Ratio::all (); + int n = 0; + for (vector<Ratio const *>::iterator i = ratio.begin(); i != ratio.end(); ++i) { + _container->Append (std_to_wx ((*i)->nickname ())); + if (*i == config->default_container ()) { + _container->SetSelection (n); + } + ++n; + } + + _container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::container_changed, this)); + + vector<DCPContentType const *> const ct = DCPContentType::all (); + n = 0; + for (vector<DCPContentType const *>::const_iterator i = ct.begin(); i != ct.end(); ++i) { + _dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); + if (*i == config->default_dcp_content_type ()) { + _dcp_content_type->SetSelection (n); + } + ++n; + } + + _dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::dcp_content_type_changed, this)); + + _j2k_bandwidth->SetRange (50, 250); + _j2k_bandwidth->SetValue (config->default_j2k_bandwidth() / 1000000); + _j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this)); + + _audio_delay->SetRange (-1000, 1000); + _audio_delay->SetValue (config->default_audio_delay ()); + _audio_delay->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::audio_delay_changed, this)); + + _issuer->SetValue (std_to_wx (config->dcp_metadata().issuer)); + _issuer->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&DefaultsPage::issuer_changed, this)); + _creator->SetValue (std_to_wx (config->dcp_metadata().creator)); + _creator->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&DefaultsPage::creator_changed, this)); + + return panel; + } - add_label_to_sizer (table, _defaults_panel, _("Default content type"), true); - _default_dcp_content_type = new wxChoice (_defaults_panel, wxID_ANY); - table->Add (_default_dcp_content_type); +private: + void j2k_bandwidth_changed () + { + Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000); + } + + void audio_delay_changed () + { + Config::instance()->set_default_audio_delay (_audio_delay->GetValue()); + } + void directory_changed () { - add_label_to_sizer (table, _defaults_panel, _("Default JPEG2000 bandwidth"), true); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _default_j2k_bandwidth = new wxSpinCtrl (_defaults_panel); - s->Add (_default_j2k_bandwidth); - add_label_to_sizer (s, _defaults_panel, _("Mbit/s"), false); - table->Add (s, 1); + Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ())); } + void edit_dci_metadata_clicked (wxWindow* parent) { - add_label_to_sizer (table, _defaults_panel, _("Default audio delay"), true); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _default_audio_delay = new wxSpinCtrl (_defaults_panel); - s->Add (_default_audio_delay); - add_label_to_sizer (s, _defaults_panel, _("ms"), false); - table->Add (s, 1); + DCIMetadataDialog* d = new DCIMetadataDialog (parent, Config::instance()->default_dci_metadata ()); + d->ShowModal (); + Config::instance()->set_default_dci_metadata (d->dci_metadata ()); + d->Destroy (); } - Config* config = Config::instance (); + void still_length_changed () + { + Config::instance()->set_default_still_length (_still_length->GetValue ()); + } - _default_still_length->SetRange (1, 3600); - _default_still_length->SetValue (config->default_still_length ()); - _default_still_length->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ConfigDialog::default_still_length_changed, this)); - - _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ())); - _default_directory->Bind (wxEVT_COMMAND_DIRPICKER_CHANGED, boost::bind (&ConfigDialog::default_directory_changed, this)); - - _default_dci_metadata_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ConfigDialog::edit_default_dci_metadata_clicked, this)); - - vector<Ratio const *> ratio = Ratio::all (); - int n = 0; - for (vector<Ratio const *>::iterator i = ratio.begin(); i != ratio.end(); ++i) { - _default_container->Append (std_to_wx ((*i)->nickname ())); - if (*i == config->default_container ()) { - _default_container->SetSelection (n); - } - ++n; + void container_changed () + { + vector<Ratio const *> ratio = Ratio::all (); + Config::instance()->set_default_container (ratio[_container->GetSelection()]); } - - _default_container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ConfigDialog::default_container_changed, this)); - vector<DCPContentType const *> const ct = DCPContentType::all (); - n = 0; - for (vector<DCPContentType const *>::const_iterator i = ct.begin(); i != ct.end(); ++i) { - _default_dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); - if (*i == config->default_dcp_content_type ()) { - _default_dcp_content_type->SetSelection (n); - } - ++n; + void dcp_content_type_changed () + { + vector<DCPContentType const *> ct = DCPContentType::all (); + Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]); } - _default_dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ConfigDialog::default_dcp_content_type_changed, this)); - - _default_j2k_bandwidth->SetRange (50, 250); - _default_j2k_bandwidth->SetValue (config->default_j2k_bandwidth() / 1000000); - _default_j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ConfigDialog::default_j2k_bandwidth_changed, this)); - - _default_audio_delay->SetRange (-1000, 1000); - _default_audio_delay->SetValue (config->default_audio_delay ()); - _default_audio_delay->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ConfigDialog::default_audio_delay_changed, this)); -} - -void -ConfigDialog::make_tms_panel () -{ - _tms_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _tms_panel->SetSizer (s); - - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); - - add_label_to_sizer (table, _tms_panel, _("IP address"), true); - _tms_ip = new wxTextCtrl (_tms_panel, wxID_ANY); - table->Add (_tms_ip, 1, wxEXPAND); - - add_label_to_sizer (table, _tms_panel, _("Target path"), true); - _tms_path = new wxTextCtrl (_tms_panel, wxID_ANY); - table->Add (_tms_path, 1, wxEXPAND); - - add_label_to_sizer (table, _tms_panel, _("User name"), true); - _tms_user = new wxTextCtrl (_tms_panel, wxID_ANY); - table->Add (_tms_user, 1, wxEXPAND); - - add_label_to_sizer (table, _tms_panel, _("Password"), true); - _tms_password = new wxTextCtrl (_tms_panel, wxID_ANY); - table->Add (_tms_password, 1, wxEXPAND); - - Config* config = Config::instance (); + void issuer_changed () + { + libdcp::XMLMetadata m = Config::instance()->dcp_metadata (); + m.issuer = wx_to_std (_issuer->GetValue ()); + Config::instance()->set_dcp_metadata (m); + } - _tms_ip->SetValue (std_to_wx (config->tms_ip ())); - _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::tms_ip_changed, this)); - _tms_path->SetValue (std_to_wx (config->tms_path ())); - _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::tms_path_changed, this)); - _tms_user->SetValue (std_to_wx (config->tms_user ())); - _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::tms_user_changed, this)); - _tms_password->SetValue (std_to_wx (config->tms_password ())); - _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::tms_password_changed, this)); -} - -void -ConfigDialog::make_metadata_panel () -{ - _metadata_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _metadata_panel->SetSizer (s); - - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); - - add_label_to_sizer (table, _metadata_panel, _("Issuer"), true); - _issuer = new wxTextCtrl (_metadata_panel, wxID_ANY); - table->Add (_issuer, 1, wxEXPAND); - - add_label_to_sizer (table, _metadata_panel, _("Creator"), true); - _creator = new wxTextCtrl (_metadata_panel, wxID_ANY); - table->Add (_creator, 1, wxEXPAND); - - Config* config = Config::instance (); - - _issuer->SetValue (std_to_wx (config->dcp_metadata().issuer)); - _issuer->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::issuer_changed, this)); - _creator->SetValue (std_to_wx (config->dcp_metadata().creator)); - _creator->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::creator_changed, this)); -} - -static string -server_column (string s) -{ - return s; -} - -void -ConfigDialog::make_servers_panel () -{ - _servers_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _servers_panel->SetSizer (s); - - _use_any_servers = new wxCheckBox (_servers_panel, wxID_ANY, _("Use all servers")); - s->Add (_use_any_servers, 0, wxALL, DCPOMATIC_SIZER_X_GAP); + void creator_changed () + { + libdcp::XMLMetadata m = Config::instance()->dcp_metadata (); + m.creator = wx_to_std (_creator->GetValue ()); + Config::instance()->set_dcp_metadata (m); + } - vector<string> columns; - columns.push_back (wx_to_std (_("IP address / host name"))); - _servers_list = new EditableList<std::string, ServerDialog> ( - _servers_panel, - columns, - boost::bind (&Config::servers, Config::instance()), - boost::bind (&Config::set_servers, Config::instance(), _1), - boost::bind (&server_column, _1) - ); - - s->Add (_servers_list, 1, wxEXPAND | wxALL, DCPOMATIC_SIZER_X_GAP); - - _use_any_servers->SetValue (Config::instance()->use_any_servers ()); - _use_any_servers->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::use_any_servers_changed, this)); -} - -void -ConfigDialog::use_any_servers_changed () -{ - Config::instance()->set_use_any_servers (_use_any_servers->GetValue ()); -} - -void -ConfigDialog::language_changed () -{ - switch (_language->GetSelection ()) { - case 0: - Config::instance()->set_language ("en"); - break; - case 1: - Config::instance()->set_language ("fr"); - break; - case 2: - Config::instance()->set_language ("it"); - break; - case 3: - Config::instance()->set_language ("es"); - break; - case 4: - Config::instance()->set_language ("sv"); - break; - case 5: - Config::instance()->set_language ("de"); - break; + wxSpinCtrl* _j2k_bandwidth; + wxSpinCtrl* _audio_delay; + wxButton* _dci_metadata_button; + wxSpinCtrl* _still_length; +#ifdef DCPOMATIC_USE_OWN_DIR_PICKER + DirPickerCtrl* _directory; +#else + wxDirPickerCtrl* _directory; +#endif + wxChoice* _container; + wxChoice* _dcp_content_type; + wxTextCtrl* _issuer; + wxTextCtrl* _creator; +}; + +class EncodingServersPage : public wxPreferencesPage, public Page +{ +public: + EncodingServersPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} + + wxString GetName () const + { + return _("Servers"); } -} - -void -ConfigDialog::tms_ip_changed () -{ - Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ())); -} - -void -ConfigDialog::tms_path_changed () -{ - Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ())); -} - -void -ConfigDialog::tms_user_changed () -{ - Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ())); -} -void -ConfigDialog::tms_password_changed () -{ - Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ())); -} +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const + { + return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE); + } +#endif -void -ConfigDialog::num_local_encoding_threads_changed () -{ - Config::instance()->set_num_local_encoding_threads (_num_local_encoding_threads->GetValue ()); -} + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, _panel_size); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + _use_any_servers = new wxCheckBox (panel, wxID_ANY, _("Use all servers")); + s->Add (_use_any_servers, 0, wxALL, _border); + + vector<string> columns; + columns.push_back (wx_to_std (_("IP address / host name"))); + _servers_list = new EditableList<string, ServerDialog> ( + panel, + columns, + boost::bind (&Config::servers, Config::instance()), + boost::bind (&Config::set_servers, Config::instance(), _1), + boost::bind (&EncodingServersPage::server_column, this, _1) + ); + + s->Add (_servers_list, 1, wxEXPAND | wxALL, _border); + + _use_any_servers->SetValue (Config::instance()->use_any_servers ()); + _use_any_servers->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&EncodingServersPage::use_any_servers_changed, this)); + + return panel; + } -void -ConfigDialog::default_directory_changed () -{ - Config::instance()->set_default_directory (wx_to_std (_default_directory->GetPath ())); -} +private: -void -ConfigDialog::edit_default_dci_metadata_clicked () -{ - DCIMetadataDialog* d = new DCIMetadataDialog (this, Config::instance()->default_dci_metadata ()); - d->ShowModal (); - Config::instance()->set_default_dci_metadata (d->dci_metadata ()); - d->Destroy (); -} - -void -ConfigDialog::set_language_changed () -{ - setup_language_sensitivity (); - if (_set_language->GetValue ()) { - language_changed (); - } else { - Config::instance()->unset_language (); + void use_any_servers_changed () + { + Config::instance()->set_use_any_servers (_use_any_servers->GetValue ()); } -} - -void -ConfigDialog::setup_language_sensitivity () -{ - _language->Enable (_set_language->GetValue ()); -} -void -ConfigDialog::default_still_length_changed () -{ - Config::instance()->set_default_still_length (_default_still_length->GetValue ()); -} + string server_column (string s) + { + return s; + } -void -ConfigDialog::default_container_changed () -{ - vector<Ratio const *> ratio = Ratio::all (); - Config::instance()->set_default_container (ratio[_default_container->GetSelection()]); -} + wxCheckBox* _use_any_servers; + EditableList<string, ServerDialog>* _servers_list; +}; -void -ConfigDialog::default_dcp_content_type_changed () +class ColourConversionsPage : public wxPreferencesPage, public Page { - vector<DCPContentType const *> ct = DCPContentType::all (); - Config::instance()->set_default_dcp_content_type (ct[_default_dcp_content_type->GetSelection()]); -} +public: + ColourConversionsPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} + + wxString GetName () const + { + return _("Colour Conversions"); + } -void -ConfigDialog::issuer_changed () -{ - dcp::XMLMetadata m = Config::instance()->dcp_metadata (); - m.issuer = wx_to_std (_issuer->GetValue ()); - Config::instance()->set_dcp_metadata (m); -} +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const + { + return wxBitmap ("colour_conversions", wxBITMAP_TYPE_PNG_RESOURCE); + } +#endif + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, _panel_size); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + vector<string> columns; + columns.push_back (wx_to_std (_("Name"))); + wxPanel* list = new EditableList<PresetColourConversion, PresetColourConversionDialog> ( + panel, + columns, + boost::bind (&Config::colour_conversions, Config::instance()), + boost::bind (&Config::set_colour_conversions, Config::instance(), _1), + boost::bind (&ColourConversionsPage::colour_conversion_column, this, _1), + 300 + ); + + s->Add (list, 1, wxEXPAND | wxALL, _border); + return panel; + } -void -ConfigDialog::creator_changed () -{ - dcp::XMLMetadata m = Config::instance()->dcp_metadata (); - m.creator = wx_to_std (_creator->GetValue ()); - Config::instance()->set_dcp_metadata (m); -} +private: + string colour_conversion_column (PresetColourConversion c) + { + return c.name; + } +}; -void -ConfigDialog::default_j2k_bandwidth_changed () +class TMSPage : public wxPreferencesPage, public Page { - Config::instance()->set_default_j2k_bandwidth (_default_j2k_bandwidth->GetValue() * 1000000); -} +public: + TMSPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} -void -ConfigDialog::default_audio_delay_changed () -{ - Config::instance()->set_default_audio_delay (_default_audio_delay->GetValue()); -} + wxString GetName () const + { + return _("TMS"); + } -static std::string -colour_conversion_column (PresetColourConversion c) -{ - return c.name; -} +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const + { + return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE); + } +#endif -void -ConfigDialog::make_colour_conversions_panel () -{ - vector<string> columns; - columns.push_back (wx_to_std (_("Name"))); - _colour_conversions_panel = new EditableList<PresetColourConversion, PresetColourConversionDialog> ( - _notebook, - columns, - boost::bind (&Config::colour_conversions, Config::instance()), - boost::bind (&Config::set_colour_conversions, Config::instance(), _1), - boost::bind (&colour_conversion_column, _1), - 300 - ); -} + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, _panel_size); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, _border); + + add_label_to_sizer (table, panel, _("IP address"), true); + _tms_ip = new wxTextCtrl (panel, wxID_ANY); + table->Add (_tms_ip, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("Target path"), true); + _tms_path = new wxTextCtrl (panel, wxID_ANY); + table->Add (_tms_path, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("User name"), true); + _tms_user = new wxTextCtrl (panel, wxID_ANY); + table->Add (_tms_user, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("Password"), true); + _tms_password = new wxTextCtrl (panel, wxID_ANY); + table->Add (_tms_password, 1, wxEXPAND); + + Config* config = Config::instance (); + + _tms_ip->SetValue (std_to_wx (config->tms_ip ())); + _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_ip_changed, this)); + _tms_path->SetValue (std_to_wx (config->tms_path ())); + _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_path_changed, this)); + _tms_user->SetValue (std_to_wx (config->tms_user ())); + _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_user_changed, this)); + _tms_password->SetValue (std_to_wx (config->tms_password ())); + _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_password_changed, this)); + + return panel; + } -void -ConfigDialog::mail_server_changed () -{ - Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ())); -} +private: + void tms_ip_changed () + { + Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ())); + } + + void tms_path_changed () + { + Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ())); + } + + void tms_user_changed () + { + Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ())); + } + + void tms_password_changed () + { + Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ())); + } -void -ConfigDialog::mail_user_changed () -{ - Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ())); -} + wxTextCtrl* _tms_ip; + wxTextCtrl* _tms_path; + wxTextCtrl* _tms_user; + wxTextCtrl* _tms_password; +}; -void -ConfigDialog::mail_password_changed () +class KDMEmailPage : public wxPreferencesPage, public Page { - Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ())); -} +public: -void -ConfigDialog::kdm_from_changed () -{ - Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ())); -} + KDMEmailPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} + + wxString GetName () const + { + return _("KDM Email"); + } -void -ConfigDialog::make_kdm_email_panel () -{ - _kdm_email_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _kdm_email_panel->SetSizer (s); +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const + { + return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE); + } +#endif - _kdm_email = new wxTextCtrl (_kdm_email_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - s->Add (_kdm_email, 1, wxEXPAND | wxALL, 12); + wxWindow* CreateWindow (wxWindow* parent) + { + /* We have to force both width and height of this one */ +#ifdef DCPOMATIC_OSX + wxPanel* panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, wxSize (480, 128)); +#else + wxPanel* panel = new wxPanel (parent); +#endif + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + _kdm_email = new wxTextCtrl (panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (480, 128), wxTE_MULTILINE); + s->Add (_kdm_email, 1, wxEXPAND | wxALL, _border); + + _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_email_changed, this)); + _kdm_email->SetValue (wx_to_std (Config::instance()->kdm_email ())); + + return panel; + } - _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::kdm_email_changed, this)); - _kdm_email->SetValue (wx_to_std (Config::instance()->kdm_email ())); -} +private: + void kdm_email_changed () + { + Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ())); + } -void -ConfigDialog::kdm_email_changed () -{ - Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ())); -} + wxTextCtrl* _kdm_email; +}; -void -ConfigDialog::check_for_updates_changed () +wxPreferencesEditor* +create_config_dialog () { - Config::instance()->set_check_for_updates (_check_for_updates->GetValue ()); -} + wxPreferencesEditor* e = new wxPreferencesEditor (); -void -ConfigDialog::check_for_test_updates_changed () -{ - Config::instance()->set_check_for_test_updates (_check_for_test_updates->GetValue ()); +#ifdef DCPOMATIC_OSX + /* Width that we force some of the config panels to be on OSX so that + the containing window doesn't shrink too much when we select those panels. + This is obviously an unpleasant hack. + */ + wxSize ps = wxSize (480, -1); + int const border = 16; +#else + wxSize ps = wxDefaultSize; + int const border = 8; +#endif + + e->AddPage (new GeneralPage (ps, border)); + e->AddPage (new DefaultsPage (ps, border)); + e->AddPage (new EncodingServersPage (ps, border)); + e->AddPage (new ColourConversionsPage (ps, border)); + e->AddPage (new TMSPage (ps, border)); + e->AddPage (new KDMEmailPage (ps, border)); + return e; } diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index 8a17de58d..183a23440 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,103 +18,9 @@ */ /** @file src/config_dialog.h - * @brief A dialogue to edit DCP-o-matic configuration. + * @brief A dialog to edit DCP-o-matic configuration. */ -#include <wx/wx.h> -#include <wx/spinctrl.h> -#include <wx/listctrl.h> -#include <wx/filepicker.h> -#include "wx_util.h" -#include "editable_list.h" - -class DirPickerCtrl; -class wxNotebook; -class PresetColourConversion; -class PresetColourConversionDialog; -class ServerDialog; - -/** @class ConfigDialog - * @brief A dialogue to edit DCP-o-matic configuration. - */ -class ConfigDialog : public wxDialog -{ -public: - ConfigDialog (wxWindow *); - -private: - void set_language_changed (); - void language_changed (); - void tms_ip_changed (); - void tms_path_changed (); - void tms_user_changed (); - void tms_password_changed (); - void num_local_encoding_threads_changed (); - void default_still_length_changed (); - void default_directory_changed (); - void edit_default_dci_metadata_clicked (); - void default_container_changed (); - void default_dcp_content_type_changed (); - void issuer_changed (); - void creator_changed (); - void default_j2k_bandwidth_changed (); - void default_audio_delay_changed (); - void mail_server_changed (); - void mail_user_changed (); - void mail_password_changed (); - void kdm_from_changed (); - void kdm_email_changed (); - void use_any_servers_changed (); - - void setup_language_sensitivity (); - - void make_misc_panel (); - void make_defaults_panel (); - void make_servers_panel (); - void make_tms_panel (); - void make_metadata_panel (); - void make_colour_conversions_panel (); - void make_kdm_email_panel (); - - void check_for_updates_changed (); - void check_for_test_updates_changed (); - - wxNotebook* _notebook; - wxPanel* _misc_panel; - wxPanel* _defaults_panel; - wxPanel* _servers_panel; - wxPanel* _tms_panel; - EditableList<PresetColourConversion, PresetColourConversionDialog>* _colour_conversions_panel; - wxPanel* _metadata_panel; - wxCheckBox* _set_language; - wxChoice* _language; - wxChoice* _default_container; - wxChoice* _default_dcp_content_type; - wxTextCtrl* _tms_ip; - wxTextCtrl* _tms_path; - wxTextCtrl* _tms_user; - wxTextCtrl* _tms_password; - wxSpinCtrl* _num_local_encoding_threads; - wxTextCtrl* _mail_server; - wxTextCtrl* _mail_user; - wxTextCtrl* _mail_password; - wxTextCtrl* _kdm_from; - wxSpinCtrl* _default_still_length; -#ifdef DCPOMATIC_USE_OWN_DIR_PICKER - DirPickerCtrl* _default_directory; -#else - wxDirPickerCtrl* _default_directory; -#endif - wxButton* _default_dci_metadata_button; - wxTextCtrl* _issuer; - wxTextCtrl* _creator; - wxSpinCtrl* _default_j2k_bandwidth; - wxSpinCtrl* _default_audio_delay; - wxPanel* _kdm_email_panel; - wxTextCtrl* _kdm_email; - wxCheckBox* _use_any_servers; - wxCheckBox* _check_for_updates; - wxCheckBox* _check_for_test_updates; - EditableList<std::string, ServerDialog>* _servers_list; -}; +class wxPreferencesEditor; +wxPreferencesEditor* create_config_dialog (); diff --git a/src/wx/editable_list.h b/src/wx/editable_list.h index 20d180f20..470be2d09 100644 --- a/src/wx/editable_list.h +++ b/src/wx/editable_list.h @@ -18,6 +18,7 @@ */ #include <wx/wx.h> +#include <wx/listctrl.h> template<class T, class S> class EditableList : public wxPanel diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index f426a7c6e..7e1b61811 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -429,7 +429,7 @@ FilmViewer::player_changed (bool frequent) if (frequent) { return; } - + calculate_sizes (); fetch_current_frame_again (); } diff --git a/src/wx/kdm_dialog.cc b/src/wx/kdm_dialog.cc index 5410f6cec..1f4d62bde 100644 --- a/src/wx/kdm_dialog.cc +++ b/src/wx/kdm_dialog.cc @@ -83,15 +83,20 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film) wxFlexGridSizer* table = new wxFlexGridSizer (3, 2, 6); add_label_to_sizer (table, this, _("From"), true); - _from_date = new wxDatePickerCtrl (this, wxID_ANY); + wxDateTime from; + from.SetToCurrent (); + _from_date = new wxDatePickerCtrl (this, wxID_ANY, from); table->Add (_from_date, 1, wxEXPAND); - _from_time = new wxTimePickerCtrl (this, wxID_ANY); + _from_time = new wxTimePickerCtrl (this, wxID_ANY, from); table->Add (_from_time, 1, wxEXPAND); - + add_label_to_sizer (table, this, _("Until"), true); - _until_date = new wxDatePickerCtrl (this, wxID_ANY); + wxDateTime to = from; + /* 1 week from now */ + to.Add (wxDateSpan (0, 0, 1, 0)); + _until_date = new wxDatePickerCtrl (this, wxID_ANY, to); table->Add (_until_date, 1, wxEXPAND); - _until_time = new wxTimePickerCtrl (this, wxID_ANY); + _until_time = new wxTimePickerCtrl (this, wxID_ANY, to); table->Add (_until_time, 1, wxEXPAND); vertical->Add (table, 0, wxEXPAND | wxALL, 6); @@ -117,7 +122,7 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film) } } - table = new wxFlexGridSizer (3, 2, 6); + table = new wxFlexGridSizer (2, 2, 6); _write_to = new wxRadioButton (this, wxID_ANY, _("Write to")); table->Add (_write_to, 1, wxEXPAND); @@ -125,13 +130,12 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film) #ifdef DCPOMATIC_USE_OWN_DIR_PICKER _folder = new DirPickerCtrl (this); #else - _folder = new wxDirPickerCtrl (this, wxID_ANY); + _folder = new wxDirPickerCtrl (this, wxID_ANY, wxEmptyString, wxDirSelectorPromptStr, wxDefaultPosition, wxSize (300, -1)); #endif _folder->SetPath (wxStandardPaths::Get().GetDocumentsDir()); table->Add (_folder, 1, wxEXPAND); - table->AddSpacer (0); _email = new wxRadioButton (this, wxID_ANY, _("Send by email")); table->Add (_email, 1, wxEXPAND); @@ -144,6 +148,8 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film) vertical->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); } + _write_to->SetValue (true); + _targets->Bind (wxEVT_COMMAND_TREE_SEL_CHANGED, boost::bind (&KDMDialog::setup_sensitivity, this)); _add_cinema->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::add_cinema_clicked, this)); diff --git a/src/wx/new_film_dialog.cc b/src/wx/new_film_dialog.cc index e0ad2c457..f6d910282 100644 --- a/src/wx/new_film_dialog.cc +++ b/src/wx/new_film_dialog.cc @@ -50,7 +50,7 @@ NewFilmDialog::NewFilmDialog (wxWindow* parent) #ifdef DCPOMATIC_USE_OWN_DIR_PICKER _folder = new DirPickerCtrl (this); #else - _folder = new wxDirPickerCtrl (this, wxID_ANY); + _folder = new wxDirPickerCtrl (this, wxID_ANY, wxEmptyString, wxDirSelectorPromptStr, wxDefaultPosition, wxSize (300, -1)); #endif if (!_directory) { diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc index eb45d4bc8..533545f64 100644 --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@ -240,12 +240,11 @@ VideoPanel::film_content_changed (int property) _colour_conversion->SetLabel (preset ? std_to_wx (cc[preset.get()].name) : _("Custom")); } else if (property == FFmpegContentProperty::FILTERS) { if (fcs) { - pair<string, string> p = Filter::ffmpeg_strings (fcs->filters ()); - if (p.first.empty () && p.second.empty ()) { + string const p = Filter::ffmpeg_string (fcs->filters ()); + if (p.empty ()) { _filters->SetLabel (_("None")); } else { - string const b = p.first + " " + p.second; - _filters->SetLabel (std_to_wx (b)); + _filters->SetLabel (std_to_wx (p)); } } } @@ -305,8 +304,8 @@ VideoPanel::setup_description () ++lines; } - dcp::Size const container_size = fit_ratio_within (_editor->film()->container()->ratio (), _editor->film()->full_frame ()); - dcp::Size const scaled = vcs->scale().size (vcs, container_size); + dcp::Size const container_size = _editor->film()->frame_size (); + dcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size); if (scaled != vcs->video_size_after_crop ()) { d << wxString::Format ( @@ -33,8 +33,6 @@ def static_ffmpeg(conf): conf.env.STLIB_SWSCALE = ['swscale'] conf.check_cfg(package='libswresample', args='--cflags', uselib_store='SWRESAMPLE', mandatory=True) conf.env.STLIB_SWRESAMPLE = ['swresample'] - conf.check_cfg(package='libpostproc', args='--cflags', uselib_store='POSTPROC', mandatory=True) - conf.env.STLIB_POSTPROC = ['postproc'] def dynamic_ffmpeg(conf): conf.check_cfg(package='libavformat', args='--cflags --libs', uselib_store='AVFORMAT', mandatory=True) @@ -43,7 +41,6 @@ def dynamic_ffmpeg(conf): conf.check_cfg(package='libavutil', args='--cflags --libs', uselib_store='AVUTIL', mandatory=True) conf.check_cfg(package='libswscale', args='--cflags --libs', uselib_store='SWSCALE', mandatory=True) conf.check_cfg(package='libswresample', args='--cflags --libs', uselib_store='SWRESAMPLE', mandatory=True) - conf.check_cfg(package='libpostproc', args='--cflags --libs', uselib_store='POSTPROC', mandatory=True) def static_openjpeg(conf): conf.check_cfg(package='libopenjpeg', args='--cflags', atleast_version='1.5.0', uselib_store='OPENJPEG', mandatory=True) |
