diff options
Diffstat (limited to 'cmpcj')
67 files changed, 5197 insertions, 1170 deletions
diff --git a/cmpcj/.classpath b/cmpcj/.classpath index 6c1a5de..1d90eb6 100644 --- a/cmpcj/.classpath +++ b/cmpcj/.classpath @@ -1,9 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src"/> - <classpathentry kind="src" path="res"/> - <classpathentry kind="lib" path="lib/glazedlists_java15.jar"/> + <classpathentry excluding="**/*.java" kind="src" path="res"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="lib" path="lib/docking-frames-common-1.1.1-SNAPSHOT.jar"/> + <classpathentry kind="lib" path="lib/docking-frames-core-1.1.1-SNAPSHOT.jar"/> + <classpathentry kind="lib" path="lib/glazedlists_java15.jar"/> <classpathentry kind="lib" path="lib/gson-2.2.2.jar"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/cmpcj/lib/docking-frames-common-1.1.1-SNAPSHOT.jar b/cmpcj/lib/docking-frames-common-1.1.1-SNAPSHOT.jar Binary files differnew file mode 100644 index 0000000..6070a60 --- /dev/null +++ b/cmpcj/lib/docking-frames-common-1.1.1-SNAPSHOT.jar diff --git a/cmpcj/lib/docking-frames-core-1.1.1-SNAPSHOT.jar b/cmpcj/lib/docking-frames-core-1.1.1-SNAPSHOT.jar Binary files differnew file mode 100644 index 0000000..de3b3a3 --- /dev/null +++ b/cmpcj/lib/docking-frames-core-1.1.1-SNAPSHOT.jar diff --git a/cmpcj/lib/docking-frames.license b/cmpcj/lib/docking-frames.license new file mode 100644 index 0000000..5ab7695 --- /dev/null +++ b/cmpcj/lib/docking-frames.license @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/cmpcj/lib/license.txt b/cmpcj/lib/glazedlists.license index bd0ca47..bd0ca47 100644 --- a/cmpcj/lib/license.txt +++ b/cmpcj/lib/glazedlists.license diff --git a/cmpcj/lib/gson.license b/cmpcj/lib/gson.license new file mode 100644 index 0000000..892eaed --- /dev/null +++ b/cmpcj/lib/gson.license @@ -0,0 +1,203 @@ +Google Gson
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2008-2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/cmpcj/res/de/schwarzrot/control/app/lang/images.properties b/cmpcj/res/de/schwarzrot/control/app/lang/images.properties new file mode 100644 index 0000000..0301bff --- /dev/null +++ b/cmpcj/res/de/schwarzrot/control/app/lang/images.properties @@ -0,0 +1,26 @@ +SupportedMediaType.Genre.default: images/sr_default.png +SupportedMediaType.Audio.default: images/sr_music.png +SupportedMediaType.Movie.default: images/sr_movies.png +SupportedMediaType.IMovie.default: images/sr_movies_i.png +SupportedMediaType.DVDImage.default: images/sr_dvd.png +SupportedMediaType.IDVDImage.default: images/sr_dvd_i.png +SupportedMediaType.LegacyVdrRecording.default: images/sr_lvdr.png +SupportedMediaType.ILegacyVdrRecording.default: images/sr_lvdr_i.png +SupportedMediaType.VdrRecording.default: images/sr_vdr.png +SupportedMediaType.IVdrRecording.default: images/sr_vdr_i.png +SupportedMediaType.Picture.default: images/sr_photos.png +SupportedMediaType.Unknown.default: images/sr_default.png + +SupportedMediaType.Genre.active: images/sradefault.png +SupportedMediaType.Audio.active: images/sramusic.png +SupportedMediaType.Movie.active: images/sramovies.png +SupportedMediaType.IMovie.active: images/sramovies_i.png +SupportedMediaType.DVDImage.active: images/sradvd.png +SupportedMediaType.IDVDImage.active: images/sradvd_i.png +SupportedMediaType.LegacyVdrRecording.active: images/sralvdr.png +SupportedMediaType.ILegacyVdrRecording.active: images/sralvdr_i.png +SupportedMediaType.VdrRecording.active: images/sravdr.png +SupportedMediaType.IVdrRecording.active: images/sravdr_i.png +SupportedMediaType.Picture.active: images/sraphotos.png +SupportedMediaType.Unknown.active: images/sradefault.png + diff --git a/cmpcj/res/de/schwarzrot/control/app/lang/messages.properties b/cmpcj/res/de/schwarzrot/control/app/lang/messages.properties new file mode 100644 index 0000000..b3a5f8d --- /dev/null +++ b/cmpcj/res/de/schwarzrot/control/app/lang/messages.properties @@ -0,0 +1,76 @@ +MCC_0=remove genre ... +MCC_12=Select the server to connect to +MCC_13=Select Server +MCC_14=localhost +MCC_15=should connect to\ +MCC_16=: +MCC_17=create genre ... +MCC_18=\ Filter:\ +MCC_19=Server +MCC_20=Edit +MCC_21=Window +MCC_22=Help +MCC_29=Genres +MCC_31=Medialist +MCC_33=Mediatypes +MCC_35=Properties +MCC_4=use +MCC_5=\ as input ... +MCC_6=Couldn't use system look and feel. +MCC_7=Compound media player + +AboutDialog.title=About +AboutDialog.app.info=<html><h2>CMP java client</h2></html> +AboutDialog.about.text=<html><center>written by <i>Geronimo@vdr-portal.de</i><br/>\ +(c) 2012 - some rights reserved.<br/>\ +published using the license <strong>cc-by-sa</strong><br/><br/>\ +plays media from remote systems<br/>\ +and<br/>\ +allows to (re)organize them.</center></html> +AboutDialog.contribution=<html>This application uses these libraries:<ul>\ +<li>glazedlists - from http://www.glazedlists.com</li>\ +<li>docking frames - from http://code.google.com/p/docking-frames</li>\ +<li>gson - from http://code.google.com/p/google-gson</li>\ +</ul></html> +AboutDialog.Close=Close +Commands.SrvOpen=Connect +Commands.SrvRefresh=Refresh +Commands.SrvClose=Disconnect +Commands.SrvShutdown=Shutdown +Commands.TransmitChanges=Transmit changes +Commands.Preferences=Preferences +Commands.HelpHelp=Help +Commands.HelpAbout=About + +Commands.SrvOpen.short.desc=connect to selected server +Commands.SrvRefresh.short.desc=refresh server (rescan for new media) +Commands.SrvClose.short.desc=disconnect from server +Commands.SrvShutdown.short.desc=shut server down +Commands.TransmitChanges.short.desc=transmit changes to server. Server will execute changes +Commands.Preferences.short.desc=edit preferences +Commands.HelpHelp.short.desc=help +Commands.HelpAbout.short.desc=all about CMP + +Commands.SrvOpen.long.desc=long: connect +Commands.SrvRefresh.long.desc=long: refresh +Commands.SrvClose.long.desc=long: disconnect +Commands.SrvShutdown.long.desc=long: shutdown +Commands.TransmitChanges.long.desc=long: transmit changes +Commands.Preferences.long.desc=long: preferences +Commands.HelpHelp.long.desc=long: help +Commands.HelpAbout.long.desc=long: about + +ConfigDialog.title=Preferences +ConfigDialog.Approve=OK +ConfigDialog.Cancel=Cancel +ServerDefinitionTableFormat.col0=Hostname +ServerDefinitionTableFormat.col1=Port +PlayerDefinitionTableFormat.col0=Mediatype +PlayerDefinitionTableFormat.col1=executable + +PTF_0=Name +PTF_1=Value + +MTF_0=Type +MTF_1=Format +MTF_2=Name diff --git a/cmpcj/res/de/schwarzrot/control/app/lang/messages_de.properties b/cmpcj/res/de/schwarzrot/control/app/lang/messages_de.properties new file mode 100644 index 0000000..6cad2a1 --- /dev/null +++ b/cmpcj/res/de/schwarzrot/control/app/lang/messages_de.properties @@ -0,0 +1,77 @@ +MCC_0=Sparte löschen ... +MCC_12=Server für Verbindung auswählen +MCC_13=Server auswählen +MCC_14=lokaler Rechner +MCC_15=sollte Verbindung aufbauen zu\ +MCC_16=: +MCC_17=Sparte anlegen ... +MCC_18=\ Filter:\ +MCC_19=Server +MCC_20=Editieren +MCC_21=Fenster +MCC_22=Hilfe +MCC_29=Sparten +MCC_31=Medienliste +MCC_33=Medientyp +MCC_35=Eigenschaften +MCC_4=verwende\ +MCC_5=\ als Eingabe ... +MCC_6=kann systemspezifisches Aussehen nicht festlegen. +MCC_7=CMP Medien Übersicht + +AboutDialog.title=Über +AboutDialog.app.info=<html><h2>CMP - Medien-Übersicht</h2></html> +AboutDialog.about.text=<html><center>geschrieben von <i>Geronimo@vdr-portal.de</i><br/>\ +(c) 2012 - einige Rechte vorbehalten.<br/>\ +veröffentlicht unter der Lizenz <strong>cc-by-sa</strong><br/><br/>\ +spielt Medien von entfernten Systemen<br/>\ +und<br/>\ +erlaubt es, diese zu (re)organisieren.</center></html> +AboutDialog.contribution=<html>Diese Anwendung verwendet folgende Bibliotheken:<ul>\ +<li>glazedlists - von http://www.glazedlists.com</li>\ +<li>docking frames - von http://code.google.com/p/docking-frames</li>\ +<li>gson - von http://code.google.com/p/google-gson</li>\ +</ul></html> +AboutDialog.Close=Schließen +Commands.SrvOpen=Verbinden +Commands.SrvRefresh=Aktualisieren +Commands.SrvClose=Trennen +Commands.SrvShutdown=Herunterfahren +Commands.TransmitChanges=Änderungen übertragen +Commands.Preferences=Eigenschaften +Commands.HelpHelp=Hilfe +Commands.HelpAbout=Über + +Commands.SrvOpen.short.desc=mit ausgewähltem Server verbinden +Commands.SrvRefresh.short.desc=Server aktualisieren (neu einlesen) +Commands.SrvClose.short.desc=von aktivem Server trennen +Commands.SrvShutdown.short.desc=Server beenden +Commands.TransmitChanges.short.desc=Änderungen an Server übermitteln. Dieser führt die Änderungen durch +Commands.Preferences.short.desc=Eigenschaften bearbeiten +Commands.HelpHelp.short.desc=Hilfe +Commands.HelpAbout.short.desc=das Wichtigste im Überblick + +Commands.SrvOpen.long.desc=Lang: Verbinden +Commands.SrvRefresh.long.desc=Lang: Aktualisieren +Commands.SrvClose.long.desc=Lang: Trennen +Commands.SrvShutdown.long.desc=Lang: Beenden +Commands.TransmitChanges.long.desc=Lang: Änderungen übertragen +Commands.Preferences.long.desc=Lang: Eigenschaften +Commands.HelpHelp.long.desc=Lang: Hilfe +Commands.HelpAbout.long.desc=Lang: Über + +ConfigDialog.title=Einstellungen +ConfigDialog.Approve=OK +ConfigDialog.Cancel=Abbrechen +ServerDefinitionTableFormat.col0=Medienserver +ServerDefinitionTableFormat.col1=Port +PlayerDefinitionTableFormat.col0=Medien-Typ +PlayerDefinitionTableFormat.col1=Spieler-Pfad + +PTF_0=Name +PTF_1=Wert + +MTF_0=Typ +MTF_1=Format +MTF_2=Name +
\ No newline at end of file diff --git a/cmpcj/src/de/schwarzrot/base/dock/BasicDockable.java b/cmpcj/src/de/schwarzrot/base/dock/BasicDockable.java new file mode 100644 index 0000000..534ca2b --- /dev/null +++ b/cmpcj/src/de/schwarzrot/base/dock/BasicDockable.java @@ -0,0 +1,75 @@ +/** + * ======================== legal notice ====================== + * + * File: BasicDockable.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.base.dock; + + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import bibliothek.gui.dock.common.DefaultSingleCDockable; + + +public class BasicDockable extends DefaultSingleCDockable { + public BasicDockable(String id, String title, JComponent content) { + super(id, title, content); + } + + + public JMenuItem createMenuItem() { + final JCheckBoxMenuItem item = new JCheckBoxMenuItem(getTitleText(), getTitleIcon()); + + item.setSelected(isVisible()); + item.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (item.isSelected()) + doShow(); + else + doClose(); + } + }); + return item; + } + + + public void doClose() { + setVisible(false); + } + + + public void doShow() { + setVisible(true); + } + + + public JComponent getContent() { + return content; + } + + private JComponent content; +} diff --git a/cmpcj/src/de/schwarzrot/base/table/PropertyTableFormat.java b/cmpcj/src/de/schwarzrot/base/table/PropertyTableFormat.java new file mode 100644 index 0000000..fd62769 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/base/table/PropertyTableFormat.java @@ -0,0 +1,86 @@ +/** + * ======================== legal notice ====================== + * + * File: PropertyTableFormat.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.base.table; + + +import java.util.Map; +import java.util.Map.Entry; +import ca.odell.glazedlists.gui.TableFormat; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.base.util.MessageBundle; +import de.schwarzrot.control.app.CMPMessageBundle; + + +public class PropertyTableFormat implements TableFormat<Map.Entry<String, Object>> { + private static MessageBundle bundle; + + + @Override + public int getColumnCount() { + return 2; + } + + + @Override + public String getColumnName(int column) { + if (bundle == null) + bundle = ApplicationServiceProvider.getService(MessageBundle.class); + + switch (column) { + case 0: + return bundle.getMessage(CMPMessageBundle.PTF_0); + case 1: + return bundle.getMessage(CMPMessageBundle.PTF_1); + default: + throw new IndexOutOfBoundsException(); + } + } + + + @Override + public Object getColumnValue(Entry<String, Object> e, int column) { + switch (column) { + case 0: + return e.getKey(); + case 1: + return e.getValue(); + default: + throw new IndexOutOfBoundsException(); + } + } + + + public int getColumnWidth(int column) { + switch (column) { + case 0: + return 100; + case 1: + return -1; + default: + throw new IndexOutOfBoundsException(); + } + } +} diff --git a/cmpcj/src/de/schwarzrot/base/util/AbstractDialog.java b/cmpcj/src/de/schwarzrot/base/util/AbstractDialog.java new file mode 100644 index 0000000..80fed51 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/base/util/AbstractDialog.java @@ -0,0 +1,174 @@ +/** + * ======================== legal notice ====================== + * + * File: AbstractDialog.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.base.util; + + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JPanel; + + +public abstract class AbstractDialog extends JDialog { + public static final int RESET_OPTION = -1; + public static final int CLOSE_OPTION = 0; + public static final int CANCEL_OPTION = 1; + public static final int APPROVE_OPTION = 2; + private static final long serialVersionUID = 713L; + public enum DialogMode { + CLOSE, CANCEL, CANCEL_APPROVE, RESET_CANCEL_APPROVE + } + public enum Orientation { + Left, Center, Right + }; + + + protected AbstractDialog(Window parent, boolean modal, DialogMode dialogMode, Orientation buttonOrientation) { + super(parent, "dummy", modal ? JDialog.ModalityType.APPLICATION_MODAL : JDialog.ModalityType.MODELESS); + msgBundle = ApplicationServiceProvider.getService(MessageBundle.class); + setTitle(msgBundle.getMessage(getClass().getSimpleName() + ".title")); + this.dialogMode = dialogMode; + this.buttonOrientation = buttonOrientation; + msgBundle = ApplicationServiceProvider.getService(MessageBundle.class); + } + + + public JComponent createButtons() { + JPanel rv = new JPanel(); + JButton button = null; + + switch (buttonOrientation) { + case Left: + rv.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 5)); + break; + + case Right: + rv.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 5)); + break; + + default: + rv.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 5)); + break; + } + + switch (dialogMode) { + case RESET_CANCEL_APPROVE: + button = createButton(".Reset"); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + result = RESET_OPTION; + performReset(); + setVisible(false); + } + }); + rv.add(button); + case CANCEL_APPROVE: + button = createButton(".Approve"); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + result = APPROVE_OPTION; + performApprove(); + setVisible(false); + } + }); + rv.add(button); + case CANCEL: + button = createButton(".Cancel"); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + result = CANCEL_OPTION; + performCancel(); + setVisible(false); + } + }); + rv.add(button); + break; + default: + button = createButton(".Close"); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + result = CLOSE_OPTION; + performClose(); + setVisible(false); + } + }); + rv.add(button); + } + return rv; + } + + + public abstract JComponent createContentPane(); + + + public int showDialog(Window parent) { + getContentPane().add(createContentPane(), BorderLayout.CENTER); + getContentPane().add(createButtons(), BorderLayout.SOUTH); + pack(); + setLocationRelativeTo(parent); + setVisible(true); + dispose(); + + return result; + } + + + protected JButton createButton(String buttonID) { + JButton button = new JButton(msgBundle.getMessage(getClass().getSimpleName() + buttonID)); + + return button; + } + + + protected void performApprove() { + } + + + protected void performCancel() { + } + + + protected void performClose() { + } + + + protected void performReset() { + } + + protected MessageBundle msgBundle; + private int result = CLOSE_OPTION; + private DialogMode dialogMode; + private Orientation buttonOrientation; +} diff --git a/cmpcj/src/de/schwarzrot/base/util/ActionManager.java b/cmpcj/src/de/schwarzrot/base/util/ActionManager.java new file mode 100644 index 0000000..35ea31d --- /dev/null +++ b/cmpcj/src/de/schwarzrot/base/util/ActionManager.java @@ -0,0 +1,61 @@ +/** + * ======================== legal notice ====================== + * + * File: ActionManager.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.base.util; + + +import java.util.HashMap; +import java.util.Map; +import javax.swing.Action; +import javax.swing.JMenuItem; + + +public class ActionManager<E extends Enum<E>> { + public ActionManager() { + knownCallbacks = new HashMap<Enum<E>, CallbackDefinition<E>>(); + } + + + public void addCallbackDefinition(CallbackDefinition<E> callbackDefinition) { + knownCallbacks.put(callbackDefinition.getCallbackKey(), callbackDefinition); + } + + + public JMenuItem createMenuItem(Enum<E> cmd) { + return null; + } + + + public Action getAction(Enum<E> cmd) { + Action rv = null; + + if (knownCallbacks.containsKey(cmd)) + rv = knownCallbacks.get(cmd); + + return rv; + } + + private Map<Enum<E>, CallbackDefinition<E>> knownCallbacks; +} diff --git a/cmpcj/src/de/schwarzrot/base/util/ApplicationServiceProvider.java b/cmpcj/src/de/schwarzrot/base/util/ApplicationServiceProvider.java new file mode 100644 index 0000000..04aee17 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/base/util/ApplicationServiceProvider.java @@ -0,0 +1,51 @@ +/** + * ======================== legal notice ====================== + * + * File: ApplicationServiceProvider.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.base.util; + + +import java.util.HashMap; +import java.util.Map; + + +public class ApplicationServiceProvider { + private static Map<Class<?>, Object> knownServices = new HashMap<Class<?>, Object>(); + + + @SuppressWarnings("unchecked") + public static <S extends Object> S getService(Class<S> clazz) { + return (S) knownServices.get(clazz); + } + + + public static <S extends Object> boolean hasService(Class<S> clazz) { + return knownServices.containsKey(clazz); + } + + + public static <S extends Object> void registerService(Class<S> clazz, S service) { + knownServices.put(clazz, service); + } +} diff --git a/cmpcj/src/de/schwarzrot/base/util/CallbackDefinition.java b/cmpcj/src/de/schwarzrot/base/util/CallbackDefinition.java new file mode 100644 index 0000000..92aa930 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/base/util/CallbackDefinition.java @@ -0,0 +1,62 @@ +/** + * ======================== legal notice ====================== + * + * File: CallbackDefinition.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.base.util; + + +import javax.swing.AbstractAction; + + +public abstract class CallbackDefinition<E extends Enum<E>> extends AbstractAction { + private static final long serialVersionUID = 713L; + private static final String IDENTIFIER = "CBIdentifier"; + + + public CallbackDefinition(E key) { + this(key, true); + } + + + public CallbackDefinition(E key, boolean enabled) { + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + String actionKey = key.getClass().getSimpleName() + "." + key.name(); + + putValue(IDENTIFIER, key); + putValue(ACTION_COMMAND_KEY, actionKey); + putValue(NAME, mb.getMessage(actionKey)); + putValue(LARGE_ICON_KEY, null); + putValue(SMALL_ICON, null); + putValue(SHORT_DESCRIPTION, mb.getMessage(actionKey + ".short.desc")); + putValue(LONG_DESCRIPTION, mb.getMessage(actionKey + ".long.desc")); + putValue(ACCELERATOR_KEY, null); + setEnabled(enabled); + } + + + @SuppressWarnings("unchecked") + public E getCallbackKey() { + return (E) getValue(IDENTIFIER); + } +} diff --git a/cmpcj/src/de/schwarzrot/base/util/ImageFactory.java b/cmpcj/src/de/schwarzrot/base/util/ImageFactory.java new file mode 100644 index 0000000..612f4cb --- /dev/null +++ b/cmpcj/src/de/schwarzrot/base/util/ImageFactory.java @@ -0,0 +1,74 @@ +/** + * ======================== legal notice ====================== + * + * File: ImageFactory.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.base.util; + + +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.ResourceBundle; +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; + + +public class ImageFactory { + public ImageIcon getIcon(String key) { + return getIcon(key, 16, 16); + } + + + public ImageIcon getIcon(String key, int width, int height) { + if (!iconPool.containsKey(key)) + iconPool.put(key, new ImageIcon(getImage(key, width, height))); + + return iconPool.get(key); + } + + + public Image getImage(String key, int width, int height) { + ClassLoader cl = getClass().getClassLoader(); + BufferedImage img = null; + URL url; + + try { + String imgPath = RESOURCE_BUNDLE.getString(key); + url = cl.getResource(imgPath); + img = ImageIO.read(url); + + return img.getScaledInstance(width, height, Image.SCALE_SMOOTH); + } catch (Throwable t) { + System.err.println("failed to read key: " + key); + t.printStackTrace(); + } + return null; + } + + private Map<String, ImageIcon> iconPool = new HashMap<String, ImageIcon>(); + private final String BUNDLE_NAME = "de.schwarzrot.control.app.lang.images"; + private final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); +} diff --git a/cmpcj/src/de/schwarzrot/base/util/MessageBundle.java b/cmpcj/src/de/schwarzrot/base/util/MessageBundle.java new file mode 100644 index 0000000..4442efa --- /dev/null +++ b/cmpcj/src/de/schwarzrot/base/util/MessageBundle.java @@ -0,0 +1,31 @@ +/** + * ======================== legal notice ====================== + * + * File: MessageBundle.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.base.util; + + +public interface MessageBundle { + public String getMessage(String key); +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/app/IMediaPlayer.java b/cmpcj/src/de/schwarzrot/base/util/SuccessHandler.java index d68adbc..9f0af4b 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/app/IMediaPlayer.java +++ b/cmpcj/src/de/schwarzrot/base/util/SuccessHandler.java @@ -1,8 +1,8 @@ /** * ======================== legal notice ====================== * - * File: IMediaPlayer.java - * Created: + * File: SuccessHandler.java + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,24 +23,12 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.app; +package de.schwarzrot.base.util; -import de.schwarzrot.cmpc.domain.Config; +public interface SuccessHandler { + public void handleFailure(Throwable t); -public interface IMediaPlayer { - public Config getConfig(); - - - public String getCurrentMediaCenter(); - - - public boolean isDebug(); - - - public void selectApp(); - - - public void startApp(String name, int port); + public void handleSuccess(); } diff --git a/cmpcj/src/de/schwarzrot/cmpc/app/SRMediaPlayer.java b/cmpcj/src/de/schwarzrot/cmpc/app/SRMediaPlayer.java deleted file mode 100644 index 0448549..0000000 --- a/cmpcj/src/de/schwarzrot/cmpc/app/SRMediaPlayer.java +++ /dev/null @@ -1,190 +0,0 @@ -/** - * ======================== legal notice ====================== - * - * File: SRMediaPlayer.java Created: Author: <a - * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend - * (client) part of compound media player uses external players to play the - * media - * - * CMP - compound media player - * - * is a client/server mediaplayer intended to play any media from any - * workstation without the need to export or mount shares. cmps is an easy to - * use backend with a (ready to use) HTML-interface. Additionally the backend - * supports authentication via HTTP-digest authorization. cmpc is a client with - * vdr-like osd-menues. - * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under - * Creative Commons by-sa For details see - * http://creativecommons.org/licenses/by-sa/3.0/ - * - * The cmp project's homepage is at - * http://projects.vdr-developer.org/projects/cmp - * - * -------------------------------------------------------------- - */ -package de.schwarzrot.cmpc.app; - - -import java.awt.CardLayout; -import java.awt.Container; -import java.io.File; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.UIManager; -import javax.swing.UIManager.LookAndFeelInfo; -import de.schwarzrot.cmpc.domain.Config; -import de.schwarzrot.cmpc.ui.AppSelector; -import de.schwarzrot.cmpc.ui.MediaClient; - - -public class SRMediaPlayer implements IMediaPlayer { - private static final String DEFAULT_TITLE = "client"; - private static final String USER_HOME = "user.home"; - private static final String TITLE_MASK = "Compound Media Player (%s)"; - private static final String MAIN = "MediaServerSelector"; - private static final String CLIENT = "MediaClient"; - - - public SRMediaPlayer(String[] args, ConfigFactory cf) { - for (String a : args) { - if (a.compareTo("-d") == 0 || a.compareTo("--debug") == 0) - debug = true; - } - configFactory = cf; - } - - - public void createAndShowGUI() { - JFrame.setDefaultLookAndFeelDecorated(false); - - config = configFactory.getConfig(); - try { - for (LookAndFeelInfo lfi : UIManager.getInstalledLookAndFeels()) { - if ("Nimbus".equals(lfi.getName())) { - UIManager.setLookAndFeel(lfi.getClassName()); - JFrame.setDefaultLookAndFeelDecorated(true); - } - } - } catch (Throwable t) { - t.printStackTrace(); - System.exit(-1); - } - mainFrame = new JFrame("JMediaPlayer"); - - //Add components to it. - Container contentPane = mainFrame.getContentPane(); - setupMainView(contentPane); - - mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setTitle(DEFAULT_TITLE); - mainFrame.setSize(1000, 700); - mainFrame.setLocationRelativeTo(null); //center it - mainFrame.setVisible(true); - } - - - @Override - public Config getConfig() { - return config; - } - - - public ConfigFactory getConfigFactory() { - return configFactory; - } - - - @Override - public String getCurrentMediaCenter() { - return currentMediaCenter; - } - - - @Override - public boolean isDebug() { - return debug; - } - - - @Override - public void selectApp() { - setTitle(DEFAULT_TITLE); - switchView(MAIN); - } - - - public void setConfigFactory(ConfigFactory configFactory) { - this.configFactory = configFactory; - } - - - @Override - public void startApp(String name, int port) { - currentMediaCenter = name; - setTitle(name); - switchView(CLIENT); - try { - mediaClientPane.startConnection(name, port); - } catch (Throwable t) { - mediaClientPane.setActive(false); - switchView(MAIN); - } - } - - - protected void setTitle(String title) { - mainFrame.setTitle(String.format(TITLE_MASK, title)); - } - - - protected void setupMainView(Container clientArea) { - stakker = new CardLayout(); - switchingPane = new JPanel(stakker); - mediaClientPane = new MediaClient(CLIENT, this); - appSelectorPane = new AppSelector(MAIN, config.getKnownServers()); - - mediaClientPane.setup(this); - appSelectorPane.setup(this); - - switchingPane.add(appSelectorPane, MAIN); - switchingPane.add(mediaClientPane, CLIENT); - clientArea.add(switchingPane); - } - - - protected void switchView(String name) { - stakker.show(switchingPane, name); - } - - - public static void main(final String[] args) { - appInfo(); - javax.swing.SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - File configDir = new File(System.getProperty(USER_HOME), ".cmp"); - SRMediaPlayer app = new SRMediaPlayer(args, new ConfigFactory(configDir)); - app.createAndShowGUI(); - } - }); - } - - - protected static void appInfo() { - System.err.println("cmpcj - the java frontend of CMP (compound media player)"); - System.err.println(" serves to browse a medialist from remote systems and to start a player"); - System.err.println(" for selected media."); - System.err.println(" (c) 2012 - Reinhard Mantey - some rights reserved."); - System.err.println(" CMP is published as open source under Creative Commons by-sa"); - } - private boolean debug = false; - private JFrame mainFrame; - private Config config; - private CardLayout stakker; - private JPanel switchingPane; - private MediaClient mediaClientPane; - private AppSelector appSelectorPane; - private ConfigFactory configFactory; - private String currentMediaCenter; -} diff --git a/cmpcj/src/de/schwarzrot/cmpc/domain/Media.java b/cmpcj/src/de/schwarzrot/cmpc/domain/Media.java deleted file mode 100644 index a7e575f..0000000 --- a/cmpcj/src/de/schwarzrot/cmpc/domain/Media.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * ======================== legal notice ====================== - * - * File: Media.java Created: Author: <a - * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend - * (client) part of compound media player uses external players to play the - * media - * - * CMP - compound media player - * - * is a client/server mediaplayer intended to play any media from any - * workstation without the need to export or mount shares. cmps is an easy to - * use backend with a (ready to use) HTML-interface. Additionally the backend - * supports authentication via HTTP-digest authorization. cmpc is a client with - * vdr-like osd-menues. - * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under - * Creative Commons by-sa For details see - * http://creativecommons.org/licenses/by-sa/3.0/ - * - * The cmp project's homepage is at - * http://projects.vdr-developer.org/projects/cmp - * - * -------------------------------------------------------------- - */ -package de.schwarzrot.cmpc.domain; - - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; - - -public class Media { - public enum SupportedMediaType { - Invalid, Audio, Movie, IMovie, DVDImage, IDVDImage, LegacyVdrRecording, ILegacyVdrRecording, VdrRecording, IVdrRecording, Picture, Unknown - }; - - - public String getFormat() { - return format; - } - - - public int getHeight() { - return height; - } - - - public String getName() { - return name; - } - - - public String getPath() { - return path; - } - - - public String getSearch() { - return search; - } - - - public SupportedMediaType getType() { - return type; - } - - - public int getWidth() { - return width; - } - - - public boolean isHD() { - return height > 576; - } - - - public void setFormat(String format) { - this.format = format; - } - - - public void setHeight(int height) { - this.height = height; - } - - - public void setName(String name) { - this.name = name; - } - - - public void setPath(String path) { - this.path = path; - try { - search = URLDecoder.decode(path, "utf8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - } - - - public void setType(int type) { - if (type == SupportedMediaType.Audio.ordinal()) - this.type = SupportedMediaType.Audio; - else if (type == SupportedMediaType.Movie.ordinal()) - this.type = SupportedMediaType.Movie; - else if (type == SupportedMediaType.IMovie.ordinal()) - this.type = SupportedMediaType.IMovie; - else if (type == SupportedMediaType.DVDImage.ordinal()) - this.type = SupportedMediaType.DVDImage; - else if (type == SupportedMediaType.IDVDImage.ordinal()) - this.type = SupportedMediaType.IDVDImage; - else if (type == SupportedMediaType.LegacyVdrRecording.ordinal()) - this.type = SupportedMediaType.LegacyVdrRecording; - else if (type == SupportedMediaType.ILegacyVdrRecording.ordinal()) - this.type = SupportedMediaType.ILegacyVdrRecording; - else if (type == SupportedMediaType.VdrRecording.ordinal()) - this.type = SupportedMediaType.VdrRecording; - else if (type == SupportedMediaType.IVdrRecording.ordinal()) - this.type = SupportedMediaType.IVdrRecording; - else if (type == SupportedMediaType.Picture.ordinal()) - this.type = SupportedMediaType.Picture; - else - this.type = SupportedMediaType.Invalid; - } - - - public void setWidth(int width) { - this.width = width; - } - - private String name; - private SupportedMediaType type; - private String format; - private String path; - private String search; - private int width; - private int height; -} diff --git a/cmpcj/src/de/schwarzrot/cmpc/domain/MediaType.java b/cmpcj/src/de/schwarzrot/cmpc/domain/MediaType.java deleted file mode 100644 index 57f320f..0000000 --- a/cmpcj/src/de/schwarzrot/cmpc/domain/MediaType.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * ======================== legal notice ====================== - * - * File: MediaType.java Created: Author: <a - * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend - * (client) part of compound media player uses external players to play the - * media - * - * CMP - compound media player - * - * is a client/server mediaplayer intended to play any media from any - * workstation without the need to export or mount shares. cmps is an easy to - * use backend with a (ready to use) HTML-interface. Additionally the backend - * supports authentication via HTTP-digest authorization. cmpc is a client with - * vdr-like osd-menues. - * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under - * Creative Commons by-sa For details see - * http://creativecommons.org/licenses/by-sa/3.0/ - * - * The cmp project's homepage is at - * http://projects.vdr-developer.org/projects/cmp - * - * -------------------------------------------------------------- - */ -package de.schwarzrot.cmpc.domain; - - -public class MediaType { - public String getName() { - return name; - } - - - public long getStart() { - return start; - } - - - public void setName(String name) { - this.name = name; - } - - - public void setStart(long start) { - this.start = start; - } - - private String name; - private long start; -} diff --git a/cmpcj/src/de/schwarzrot/cmpc/ui/AppSelector.java b/cmpcj/src/de/schwarzrot/cmpc/ui/AppSelector.java deleted file mode 100644 index 75d3e3c..0000000 --- a/cmpcj/src/de/schwarzrot/cmpc/ui/AppSelector.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * ======================== legal notice ====================== - * - * File: AppSelector.java - * Created: - * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> - * Project: cmpc - a java frontend (client) part of compound media player - * uses external players to play the media - * - * CMP - compound media player - * - * is a client/server mediaplayer intended to play any media from any workstation - * without the need to export or mount shares. cmps is an easy to use backend - * with a (ready to use) HTML-interface. Additionally the backend supports - * authentication via HTTP-digest authorization. - * cmpc is a client with vdr-like osd-menues. - * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! - * published under Creative Commons by-sa - * For details see http://creativecommons.org/licenses/by-sa/3.0/ - * - * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp - * - * -------------------------------------------------------------- - */ -package de.schwarzrot.cmpc.ui; - - -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.util.List; -import javax.swing.AbstractAction; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JPanel; -import de.schwarzrot.cmpc.app.IMediaPlayer; -import de.schwarzrot.cmpc.domain.MediaServer; - - -public class AppSelector extends JComponent { - private static final long serialVersionUID = 713L; - - - public AppSelector(String id, List<MediaServer> mediaServerHosts) { - this.myPanelName = id; - this.knownMediaCenters = mediaServerHosts; - } - - - @Override - public String getName() { - return myPanelName; - } - - - public void setup(final IMediaPlayer mp) { - setLayout(new GridLayout(1, 2)); - JPanel knownHosts = new JPanel(); - - knownHosts.setLayout(new GridLayout(knownMediaCenters.size(), 1)); - for (MediaServer ms : knownMediaCenters) { - JButton bt = new JButton(ms.getHostName()); - AbstractAction a = new AbstractAction() { - private static final long serialVersionUID = 713L; - - - @Override - public void actionPerformed(ActionEvent e) { - String host = (String) this.getValue("mediaCenterHost"); - Integer port = (Integer) this.getValue("mediaCenterPort"); - - System.out.println("shall connect " + host + ":" + port); - mp.startApp(host, port); - } - }; - a.putValue("mediaCenterHost", ms.getHostName()); - a.putValue("mediaCenterPort", ms.getPort()); - bt.addActionListener(a); - knownHosts.add(bt); - } - add(knownHosts); - JButton setup = new JButton("Setup"); - - add(setup); - doLayout(); - } - - private String myPanelName; - private List<MediaServer> knownMediaCenters; -} diff --git a/cmpcj/src/de/schwarzrot/cmpc/ui/MediaClient.java b/cmpcj/src/de/schwarzrot/cmpc/ui/MediaClient.java deleted file mode 100644 index 70da17f..0000000 --- a/cmpcj/src/de/schwarzrot/cmpc/ui/MediaClient.java +++ /dev/null @@ -1,270 +0,0 @@ -/** - * ======================== legal notice ====================== - * - * File: MediaClient.java Created: Author: <a - * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend - * (client) part of compound media player uses external players to play the - * media - * - * CMP - compound media player - * - * is a client/server mediaplayer intended to play any media from any - * workstation without the need to export or mount shares. cmps is an easy to - * use backend with a (ready to use) HTML-interface. Additionally the backend - * supports authentication via HTTP-digest authorization. cmpc is a client with - * vdr-like osd-menues. - * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under - * Creative Commons by-sa For details see - * http://creativecommons.org/licenses/by-sa/3.0/ - * - * The cmp project's homepage is at - * http://projects.vdr-developer.org/projects/cmp - * - * -------------------------------------------------------------- - */ -package de.schwarzrot.cmpc.ui; - - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Image; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.image.BufferedImage; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import javax.imageio.ImageIO; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JTextField; -import javax.swing.table.DefaultTableCellRenderer; -import ca.odell.glazedlists.EventList; -import ca.odell.glazedlists.FilterList; -import ca.odell.glazedlists.SortedList; -import ca.odell.glazedlists.swing.DefaultEventTableModel; -import ca.odell.glazedlists.swing.GlazedListsSwing; -import ca.odell.glazedlists.swing.TableComparatorChooser; -import ca.odell.glazedlists.swing.TextComponentMatcherEditor; -import de.schwarzrot.cmpc.app.IMediaPlayer; -import de.schwarzrot.cmpc.domain.Media; -import de.schwarzrot.cmpc.domain.PlayerDefinition; -import de.schwarzrot.cmpc.util.MediaClientExecutor; -import de.schwarzrot.cmpc.util.MediaComparator; -import de.schwarzrot.cmpc.util.MediaExecutor; -import de.schwarzrot.cmpc.util.MediaListLoader; -import de.schwarzrot.cmpc.util.MediaTableFormat; -import de.schwarzrot.cmpc.util.MediaTextFilterator; -import de.schwarzrot.cmpc.util.MediaTypeSelect; - - -public class MediaClient extends JComponent implements MediaClientExecutor { - private static final long serialVersionUID = 713L; - - - public MediaClient(String id, IMediaPlayer player) { - this.myPanelName = id; - this.player = player; - setLayout(new BorderLayout()); - listLoader = new MediaListLoader(); - mediaPool = listLoader.getMediaPool(); - } - - - @Override - public String getName() { - return myPanelName; - } - - - public boolean isActive() { - return active; - } - - - @Override - public void playMedia(Media m) { - List<String> command = new ArrayList<String>(); - PlayerDefinition pd = player.getConfig().getPlayerMap().get(m.getType()); - StringBuilder sb = new StringBuilder("http://"); - - sb.append(curHostName); - sb.append(":"); - sb.append(curPort); - sb.append(m.getPath()); - - command.add(pd.getExecutable()); - for (String param : pd.getParameters()) { - command.add(param); - } - command.add(sb.toString()); - ProcessBuilder pb = new ProcessBuilder(command); - - pb.redirectErrorStream(true); - try { - Process proc = pb.start(); - BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); - String line; - - if (player.isDebug()) { - while ((line = br.readLine()) != null) { - System.err.println(line); - } - } else { - while ((line = br.readLine()) != null) - ; - } - } catch (Throwable t) { - t.printStackTrace(); - } - } - - - public void setActive(boolean active) { - this.active = active; - } - - - public void setup(final IMediaPlayer mp) { - add(createClientPane(), BorderLayout.CENTER); - } - - - public void startConnection(String hostname, int port) { - setHost(hostname); - setPort(port); - mediaPool.getReadWriteLock().writeLock().lock(); - mediaPool.clear(); - mediaPool.getReadWriteLock().writeLock().unlock(); - listLoader.loadMedia(curHostName, curPort); - } - - - protected JComponent createClientPane() { - JPanel clientPane = new JPanel(); - - loadImages(); - mediaPool.getReadWriteLock().readLock().lock(); - try { - SortedList<Media> sortedMedias = new SortedList<Media>(GlazedListsSwing.swingThreadProxyList(mediaPool), - new MediaComparator()); - MediaTypeSelect mtSelect = new MediaTypeSelect(sortedMedias); - FilterList<Media> filteredMedias = new FilterList<Media>(sortedMedias, mtSelect); - JTextField filterEdit = new JTextField(30); - FilterList<Media> textFilteredMedia = new FilterList<Media>(filteredMedias, - new TextComponentMatcherEditor<Media>(filterEdit, new MediaTextFilterator())); - MediaTableFormat tf = new MediaTableFormat(); - DefaultEventTableModel<Media> mediaTableModel = new DefaultEventTableModel<Media>(textFilteredMedia, tf); - JTable mediaJTable = new JTable(mediaTableModel); - @SuppressWarnings({ "unused", "rawtypes" }) - TableComparatorChooser tableSorter = TableComparatorChooser.install(mediaJTable, sortedMedias, - TableComparatorChooser.MULTIPLE_COLUMN_MOUSE_WITH_UNDO); - JScrollPane mediaTableScrollPane = new JScrollPane(mediaJTable); - JScrollPane mediaTypesScrollPane = new JScrollPane(mtSelect.getJList()); - JLabel filter = new JLabel(" Filter: "); - JButton exitButton = new JButton(images[0]); - JButton preferences = new JButton(images[1]); - - filter.setForeground(Color.GRAY); - filterEdit.setBackground(Color.LIGHT_GRAY); - exitButton.setBackground(Color.BLACK); - preferences.setBackground(Color.BLACK); - exitButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - player.selectApp(); - } - }); - mediaTypesScrollPane.setPreferredSize(new Dimension(100, 100)); - mediaTypesScrollPane.setBackground(Color.BLACK); - int mx = mediaJTable.getColumnModel().getColumnCount(); - for (int i = 0; i < mx; ++i) { - int cw = tf.getColumnWidth(i); - - if (cw > 0) - mediaJTable.getColumnModel().getColumn(i).setMaxWidth(cw); - } - mediaJTable.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer()); - mediaJTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer()); - mediaJTable.addMouseListener(new MediaExecutor(mediaJTable, textFilteredMedia, this)); - clientPane.setLayout(new GridBagLayout()); - - clientPane.add(exitButton, new GridBagConstraints(0, 0, 1, 2, 0.0, 0.0, GridBagConstraints.CENTER, - GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - clientPane.add(preferences, new GridBagConstraints(1, 0, 1, 2, 0.0, 0.0, GridBagConstraints.CENTER, - GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - - clientPane.add(mediaTypesScrollPane, new GridBagConstraints(0, 2, 2, 1, 0.0, 0.0, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - - clientPane.add(filter, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, - GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 10, 0)); - - clientPane.add(filterEdit, new GridBagConstraints(3, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, - GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - - clientPane.add(mediaTableScrollPane, new GridBagConstraints(2, 1, 2, 2, 1.0, 1.0, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - clientPane.setOpaque(true); - clientPane.setBackground(Color.BLACK); - } finally { - mediaPool.getReadWriteLock().readLock().unlock(); - } - return clientPane; - } - - - protected void loadImages() { - BufferedImage img = null; - ClassLoader cl = getClass().getClassLoader(); - URL url; - - images = new ImageIcon[iconFiles.length]; - for (int i = 0; i < iconFiles.length; ++i) { - try { - url = cl.getResource(iconFiles[i]); - - img = ImageIO.read(url); - images[i] = new ImageIcon(img.getScaledInstance(64, 64, Image.SCALE_SMOOTH)); - } catch (Throwable t) { - System.err.println("failed to read image from " + iconFiles[i]); - t.printStackTrace(); - } - } - } - - - protected void setHost(String hostname) { - curHostName = hostname; - } - - - protected void setPort(Integer port) { - curPort = port; - } - - private IMediaPlayer player; - private MediaListLoader listLoader; - private EventList<Media> mediaPool; - private String myPanelName; - private int curPort; - private String curHostName; - private boolean active; - private ImageIcon[] images; - private static final String[] iconFiles; - static { - iconFiles = new String[] { "images/black_exit.png", "images/black_preferences.png" }; - } -} diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaListLoader.java b/cmpcj/src/de/schwarzrot/cmpc/util/MediaListLoader.java deleted file mode 100644 index 983fdd3..0000000 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaListLoader.java +++ /dev/null @@ -1,124 +0,0 @@ -/** - * ======================== legal notice ====================== - * - * File: MediaListLoader.java Created: Author: <a - * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend - * (client) part of compound media player uses external players to play the - * media - * - * CMP - compound media player - * - * is a client/server mediaplayer intended to play any media from any - * workstation without the need to export or mount shares. cmps is an easy to - * use backend with a (ready to use) HTML-interface. Additionally the backend - * supports authentication via HTTP-digest authorization. cmpc is a client with - * vdr-like osd-menues. - * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under - * Creative Commons by-sa For details see - * http://creativecommons.org/licenses/by-sa/3.0/ - * - * The cmp project's homepage is at - * http://projects.vdr-developer.org/projects/cmp - * - * -------------------------------------------------------------- - */ -package de.schwarzrot.cmpc.util; - - -import java.net.ConnectException; -import java.net.URL; -import java.net.URLConnection; -import java.util.Date; -import ca.odell.glazedlists.BasicEventList; -import ca.odell.glazedlists.EventList; -import de.schwarzrot.cmpc.domain.Media; -import de.schwarzrot.cmpc.domain.PlayList; - - -public class MediaListLoader implements Runnable { - public EventList<Media> getMediaPool() { - return mediaPool; - } - - - public void loadMedia(String hostname, int port) { - this.hostName = hostname; - this.port = port; - - Thread backgroundThread = new Thread(this); - - backgroundThread.setName("load media list from " + hostName); - backgroundThread.setDaemon(true); - backgroundThread.start(); - } - - - @Override - public void run() { - URL request = null; - Date start, end; - - try { - start = new Date(); - request = new URL("http", hostName, port, "/?format=json"); - URLConnection conn = request.openConnection(); - final PlayList firstPlaylist = jsonParser.parseListChunk(conn.getInputStream()); - - mediaPool.getReadWriteLock().writeLock().lock(); - for (Media m : firstPlaylist.getResults()) { - mediaPool.add(m); - } - mediaPool.getReadWriteLock().writeLock().unlock(); - - end = new Date(); - System.out.println("processing of first playlist-part took " + (end.getTime() - start.getTime()) + " ms."); - PlayList next; - long total = firstPlaylist.getTotal(); - long n = firstPlaylist.getResults().size(); - String uri; - - start = new Date(); - try { - while (n < total) { - uri = String.format("/?start=%d&limit=%d&format=json", n, 100); - request = new URL("http", hostName, port, uri); - conn = request.openConnection(); - next = jsonParser.parseListChunk(conn.getInputStream()); - mediaPool.getReadWriteLock().writeLock().lock(); - for (Media m : next.getResults()) { - mediaPool.add(m); - } - mediaPool.getReadWriteLock().writeLock().unlock(); - n += next.getResults().size(); - Thread.sleep(10); - } - } catch (Throwable t) { - System.out.println("Oups, media list contains now #" + mediaPool.size() + " entries."); - System.err.println("Error on chunk #" + n); - t.printStackTrace(); - } finally { - try { - mediaPool.getReadWriteLock().writeLock().unlock(); - } catch (Throwable t) { - } - } - end = new Date(); - System.out.println("processing of rest of playlist took " + (end.getTime() - start.getTime()) + " ms."); - } catch (ConnectException ce) { - System.out.println("media server " + hostName + " is not available ..."); - } catch (Throwable t) { - t.printStackTrace(); - } finally { - try { - mediaPool.getReadWriteLock().writeLock().unlock(); - } catch (Throwable t) { - } - } - } - - private String hostName; - private int port; - private MedialistParser jsonParser = new MedialistParser(); - private EventList<Media> mediaPool = new BasicEventList<Media>(); -} diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaTableFormat.java b/cmpcj/src/de/schwarzrot/cmpc/util/MediaTableFormat.java deleted file mode 100644 index d427e83..0000000 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaTableFormat.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * ======================== legal notice ====================== - * - * File: MediaTableFormat.java Created: Author: <a - * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend - * (client) part of compound media player uses external players to play the - * media - * - * CMP - compound media player - * - * is a client/server mediaplayer intended to play any media from any - * workstation without the need to export or mount shares. cmps is an easy to - * use backend with a (ready to use) HTML-interface. Additionally the backend - * supports authentication via HTTP-digest authorization. cmpc is a client with - * vdr-like osd-menues. - * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under - * Creative Commons by-sa For details see - * http://creativecommons.org/licenses/by-sa/3.0/ - * - * The cmp project's homepage is at - * http://projects.vdr-developer.org/projects/cmp - * - * -------------------------------------------------------------- - */ -package de.schwarzrot.cmpc.util; - - -import ca.odell.glazedlists.gui.TableFormat; -import de.schwarzrot.cmpc.domain.Media; - - -public class MediaTableFormat implements TableFormat<Media> { - @Override - public int getColumnCount() { - return 5; - } - - - @Override - public String getColumnName(int column) { - switch (column) { - case 0: - return "Type"; - case 1: - return "Format"; - case 2: - return "Width"; - case 3: - return "Height"; - case 4: - return "Name"; - default: - throw new IllegalStateException(); - } - } - - - @Override - public Object getColumnValue(Media m, int column) { - switch (column) { - case 0: - return m.getType(); - case 1: - return m.getFormat(); - case 2: - return m.getWidth(); - case 3: - return m.getHeight(); - case 4: - return m.getName(); - default: - throw new IllegalStateException(); - } - } - - - public int getColumnWidth(int column) { - switch (column) { - case 0: - return 80; - case 1: - return 100; - case 2: - return 60; - case 3: - return 60; - case 4: - return -1; - default: - throw new IllegalStateException(); - } - } -} diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaTextFilterator.java b/cmpcj/src/de/schwarzrot/cmpc/util/MediaTextFilterator.java deleted file mode 100644 index aa035d9..0000000 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaTextFilterator.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * ======================== legal notice ====================== - * - * File: MediaTextFilterator.java Created: Author: <a - * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend - * (client) part of compound media player uses external players to play the - * media - * - * CMP - compound media player - * - * is a client/server mediaplayer intended to play any media from any - * workstation without the need to export or mount shares. cmps is an easy to - * use backend with a (ready to use) HTML-interface. Additionally the backend - * supports authentication via HTTP-digest authorization. cmpc is a client with - * vdr-like osd-menues. - * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under - * Creative Commons by-sa For details see - * http://creativecommons.org/licenses/by-sa/3.0/ - * - * The cmp project's homepage is at - * http://projects.vdr-developer.org/projects/cmp - * - * -------------------------------------------------------------- - */ -package de.schwarzrot.cmpc.util; - - -import java.util.List; -import ca.odell.glazedlists.TextFilterator; -import de.schwarzrot.cmpc.domain.Media; - - -public class MediaTextFilterator implements TextFilterator<Media> { - @Override - public void getFilterStrings(List<String> baseList, Media m) { - baseList.add(m.getName()); - baseList.add(m.getSearch()); - baseList.add(m.getFormat()); - } -} diff --git a/cmpcj/src/de/schwarzrot/control/app/AboutDialog.java b/cmpcj/src/de/schwarzrot/control/app/AboutDialog.java new file mode 100644 index 0000000..7a361cf --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/app/AboutDialog.java @@ -0,0 +1,69 @@ +/** + * ======================== legal notice ====================== + * + * File: AboutDialog.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.app; + + +import java.awt.Dimension; +import java.awt.Window; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import de.schwarzrot.base.util.AbstractDialog; + + +public class AboutDialog extends AbstractDialog { + private static final long serialVersionUID = 713L; + + + public AboutDialog(Window parent) { + super(parent, true, DialogMode.CLOSE, Orientation.Center); + } + + + @Override + public JComponent createContentPane() { + JPanel rv = new JPanel(); + + rv.setLayout(new BoxLayout(rv, BoxLayout.Y_AXIS)); + rv.setBorder(new EmptyBorder(20, 20, 20, 20)); + JLabel appInfo = new JLabel(msgBundle.getMessage(getClass().getSimpleName() + ".app.info"), JLabel.CENTER); + + rv.add(appInfo); + JLabel aboutText = new JLabel(msgBundle.getMessage(getClass().getSimpleName() + ".about.text"), JLabel.CENTER); + + rv.add(aboutText); + rv.add(Box.createRigidArea(new Dimension(0, 30))); + JLabel contribution = new JLabel(msgBundle.getMessage(getClass().getSimpleName() + ".contribution"), + JLabel.LEFT); + + rv.add(contribution); + + return rv; + } +} diff --git a/cmpcj/src/de/schwarzrot/control/app/CMPCJ.java b/cmpcj/src/de/schwarzrot/control/app/CMPCJ.java new file mode 100644 index 0000000..639d9fc --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/app/CMPCJ.java @@ -0,0 +1,736 @@ +/** + * ======================== legal notice ====================== + * + * File: MCC.java Created: 13. June 2012, 04:57 Author: <a + * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend + * (client) part of compound media player uses external players to play the + * media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any + * workstation without the need to export or mount shares. cmps is an easy to + * use backend with a (ready to use) HTML-interface. Additionally the backend + * supports authentication via HTTP-digest authorization. cmpc is a client with + * vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under + * Creative Commons by-sa For details see + * http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at + * http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.app; + + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import javax.swing.AbstractAction; +import javax.swing.DropMode; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.KeyStroke; +import javax.swing.UIManager; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeModel; +import bibliothek.gui.dock.common.CControl; +import bibliothek.gui.dock.common.CGrid; +import ca.odell.glazedlists.BasicEventList; +import ca.odell.glazedlists.EventList; +import ca.odell.glazedlists.FilterList; +import ca.odell.glazedlists.GlazedLists; +import ca.odell.glazedlists.SortedList; +import ca.odell.glazedlists.event.ListEvent; +import ca.odell.glazedlists.event.ListEventListener; +import ca.odell.glazedlists.swing.DefaultEventSelectionModel; +import ca.odell.glazedlists.swing.DefaultEventTableModel; +import ca.odell.glazedlists.swing.GlazedListsSwing; +import ca.odell.glazedlists.swing.TableComparatorChooser; +import ca.odell.glazedlists.swing.TextComponentMatcherEditor; +import de.schwarzrot.base.dock.BasicDockable; +import de.schwarzrot.base.table.PropertyTableFormat; +import de.schwarzrot.base.util.ActionManager; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.base.util.CallbackDefinition; +import de.schwarzrot.base.util.ImageFactory; +import de.schwarzrot.base.util.MessageBundle; +import de.schwarzrot.base.util.SuccessHandler; +import de.schwarzrot.control.client.CMPClient; +import de.schwarzrot.control.client.MediaClientExecutor; +import de.schwarzrot.control.config.ConfigDialog; +import de.schwarzrot.control.config.ConfigFactory; +import de.schwarzrot.control.dnd.ListSelectionSourceTransferHandler; +import de.schwarzrot.control.dnd.TreeSourceAndDestTransferHandler; +import de.schwarzrot.control.support.MediaTextFilterator; +import de.schwarzrot.control.support.MediaTypeSelector; +import de.schwarzrot.control.support.SelectedMedia; +import de.schwarzrot.control.support.TreeSelectionFilter; +import de.schwarzrot.control.table.MediaTableFormat; +import de.schwarzrot.media.domain.AbstractMediaNode; +import de.schwarzrot.media.domain.Config; +import de.schwarzrot.media.domain.Genre; +import de.schwarzrot.media.domain.Media; +import de.schwarzrot.media.domain.MediaServer; +import de.schwarzrot.media.domain.PlayerDefinition; +import de.schwarzrot.media.service.DataManager; +import de.schwarzrot.media.service.MediaExecutor; +import de.schwarzrot.media.util.ListLoader; +import de.schwarzrot.media.util.MedialistParser; + + +public class CMPCJ extends WindowAdapter implements PropertyChangeListener, SuccessHandler, + ListEventListener<AbstractMediaNode>, MediaClientExecutor { + private static final String PREFFERRED_LOOK_N_FEEL = "Nimbus"; //$NON-NLS-1$ + private static final String USER_HOME = "user.home"; //$NON-NLS-1$ + private static final String DOCKING_CONFIG = "srdocking.conf"; //$NON-NLS-1$ + enum Commands { + SrvOpen, SrvRefresh, SrvClose, SrvShutdown, TransmitChanges, Preferences, HelpHelp, HelpAbout + }; + + + public CMPCJ(String[] args, ConfigFactory configFactory) { + nodeCache = new HashMap<File, DefaultMutableTreeNode>(); + changes = new BasicEventList<AbstractMediaNode>(); + rootNode = new DefaultMutableTreeNode(setupServices(args, configFactory)); + changes.addListEventListener(this); + } + + + public void createAndShow() { + @SuppressWarnings("unchecked") + ActionManager<Commands> am = ApplicationServiceProvider.getService(ActionManager.class); + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + + mediaList = new SortedList<Media>(GlazedListsSwing.swingThreadProxyList(new BasicEventList<Media>())); + try { + String lookNFeel = UIManager.getSystemLookAndFeelClassName(); + + for (UIManager.LookAndFeelInfo lfi : UIManager.getInstalledLookAndFeels()) { + if (PREFFERRED_LOOK_N_FEEL.equals(lfi.getName())) + lookNFeel = lfi.getClassName(); + } + UIManager.setLookAndFeel(lookNFeel); + } catch (Exception e) { + System.err.println(mb.getMessage(CMPMessageBundle.MCC_6)); + } + am.addCallbackDefinition(new CallbackDefinition<Commands>(Commands.SrvOpen) { + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doConnectServer(); + } + }); + am.addCallbackDefinition(new CallbackDefinition<Commands>(Commands.SrvRefresh, false) { + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doServerRescan(); + } + }); + am.addCallbackDefinition(new CallbackDefinition<Commands>(Commands.SrvClose, false) { + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doDisconnectServer(); + } + }); + am.addCallbackDefinition(new CallbackDefinition<Commands>(Commands.SrvShutdown, false) { + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doShutdownServer(); + } + }); + am.addCallbackDefinition(new CallbackDefinition<Commands>(Commands.TransmitChanges, false) { + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doTransmitChanges(); + } + }); + am.addCallbackDefinition(new CallbackDefinition<Commands>(Commands.Preferences) { + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doConfigureClient(); + } + }); + am.addCallbackDefinition(new CallbackDefinition<Commands>(Commands.HelpHelp, false) { + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doShowHelp(); + } + }); + am.addCallbackDefinition(new CallbackDefinition<Commands>(Commands.HelpAbout) { + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doShowAbout(); + } + }); + JMenuBar menuBar = new JMenuBar(); + frame = new JFrame(mb.getMessage(CMPMessageBundle.MCC_7)); + control = new CControl(frame); + frame.addWindowListener(this); + frame.add(setupPerspective(frame)); + frame.setJMenuBar(menuBar); + frame.pack(); + frame.setSize(1200, 800); + frame.setLocationRelativeTo(null); + restorePerspective(); + createMenu(menuBar); + frame.setVisible(true); + } + + + @Override + public void handleFailure(Throwable t) { + // loading list from server failed ... + if (t instanceof UnknownHostException) { + //TODO: tell the user ... + } + t.printStackTrace(); + tree.updateUI(); + updateServerActions(false); + } + + + @Override + public void handleSuccess() { + // loading list from server was successful + tree.updateUI(); + updateServerActions(true); + } + + + @Override + public void listChanged(ListEvent<AbstractMediaNode> arg0) { + // get rid of changes made by user + @SuppressWarnings("unchecked") + ActionManager<Commands> am = ApplicationServiceProvider.getService(ActionManager.class); + boolean changesExists = changes.size() > 0; + + System.out.println("changes updated ..."); + am.getAction(Commands.TransmitChanges).setEnabled(changesExists); + } + + + @Override + public void playMedia(Media m) { + Config config = ApplicationServiceProvider.getService(Config.class); + List<String> command = new ArrayList<String>(); + PlayerDefinition pd = config.getPlayerMap().get(m.getType()); + StringBuilder sb = new StringBuilder("http://"); + + sb.append(clientStub.getServerDefinition().getHostName()); + sb.append(":"); + sb.append(clientStub.getServerDefinition().getPort()); + sb.append(m.getURI()); + + command.add(pd.getExecutable()); + for (String param : pd.getParameters()) { + command.add(param); + } + command.add(sb.toString()); + ProcessBuilder pb = new ProcessBuilder(command); + + pb.redirectErrorStream(true); + try { + Process proc = pb.start(); + BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); + String line; + + if (config.isDebug()) { + while ((line = br.readLine()) != null) { + System.err.println(line); + } + } else { + while ((line = br.readLine()) != null) + ; + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + + + @Override + public void propertyChange(PropertyChangeEvent evt) { + propertyList.getReadWriteLock().writeLock().lock(); + propertyList.clear(); + if (selectedMedia.getMedia() != null) + propertyList.addAll(selectedMedia.getMedia().getProperties().entrySet()); + propertyList.getReadWriteLock().writeLock().unlock(); + } + + + @Override + public void windowClosing(WindowEvent e) { + savePerspective(); + control.destroy(); + System.exit(0); + } + + + @Override + public void windowOpened(WindowEvent e) { + doConnectServer(); + } + + + protected JComponent createMediaTableView() { + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + JTextField filterEdit = new JTextField(30); + mediaTypeSelector = new MediaTypeSelector(mediaList); + FilterList<Media> typeFilteredMedias = new FilterList<Media>(mediaList, mediaTypeSelector); + FilterList<Media> filteredMedias = new FilterList<Media>(typeFilteredMedias, new TreeSelectionFilter(tree)); + FilterList<Media> textFilteredMedias = new FilterList<Media>(filteredMedias, + new TextComponentMatcherEditor<Media>(filterEdit, new MediaTextFilterator())); + MediaTableFormat mtf = new MediaTableFormat(); + DefaultEventTableModel<Media> mediaTableModel = new DefaultEventTableModel<Media>(textFilteredMedias, mtf); + selectedMedia = new SelectedMedia(textFilteredMedias); + DefaultEventSelectionModel<Media> selectionModel = new DefaultEventSelectionModel<Media>(textFilteredMedias); + JTable mediaJTable = new JTable(mediaTableModel); + + selectedMedia.addPropertyChangeListener(this); + selectionModel.addListSelectionListener(selectedMedia); + mediaJTable.setDragEnabled(true); + mediaJTable.setTransferHandler(new ListSelectionSourceTransferHandler(selectionModel)); + mediaJTable.setSelectionModel(selectionModel); + mediaJTable.addMouseListener(new MediaExecutor(mediaJTable, textFilteredMedias, this)); + @SuppressWarnings({ "rawtypes", "unused" }) + TableComparatorChooser tableSorter = TableComparatorChooser.install(mediaJTable, mediaList, + TableComparatorChooser.MULTIPLE_COLUMN_MOUSE_WITH_UNDO); + JScrollPane mediaTableScrollPane = new JScrollPane(mediaJTable); + int mx = mediaJTable.getColumnModel().getColumnCount(); + + for (int i = 0; i < mx; ++i) { + int cw = mtf.getColumnWidth(i); + + if (cw > 0) + mediaJTable.getColumnModel().getColumn(i).setMaxWidth(cw); + } + JPanel tablePane = new JPanel(); + JLabel lFilter = new JLabel(mb.getMessage(CMPMessageBundle.MCC_18)); + + tablePane.setLayout(new GridBagLayout()); + tablePane.add(lFilter, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, + GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + tablePane.add(filterEdit, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, + GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + tablePane.add(mediaTableScrollPane, new GridBagConstraints(0, 1, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, + GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + + return tablePane; + } + + + protected JComponent createMediaTypeList() { + JPanel rv = new JPanel(); + + return rv; + } + + + protected void createMenu(JMenuBar menuBar) { + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + @SuppressWarnings("unchecked") + ActionManager<Commands> am = ApplicationServiceProvider.getService(ActionManager.class); + JMenu mServer = new JMenu(mb.getMessage(CMPMessageBundle.MCC_19)); + JMenu mEdit = new JMenu(mb.getMessage(CMPMessageBundle.MCC_20)); + JMenu mWindow = new JMenu(mb.getMessage(CMPMessageBundle.MCC_21)); + JMenu mHelp = new JMenu(mb.getMessage(CMPMessageBundle.MCC_22)); + + mServer.add(new JMenuItem(am.getAction(Commands.SrvOpen))); + mServer.add(new JMenuItem(am.getAction(Commands.SrvRefresh))); + mServer.add(new JMenuItem(am.getAction(Commands.SrvClose))); + mServer.add(new JSeparator()); + mServer.add(new JMenuItem(am.getAction(Commands.SrvShutdown))); + mEdit.add(new JMenuItem(am.getAction(Commands.TransmitChanges))); + mEdit.add(new JSeparator()); + mEdit.add(new JMenuItem(am.getAction(Commands.Preferences))); + mWindow.add(cdGenreTree.createMenuItem()); + mWindow.add(cdMediaTypes.createMenuItem()); + mWindow.add(cdProperties.createMenuItem()); + //TODO: not yet + // mHelp.add(new JMenuItem(getAction(Commands.HelpHelp))); + // mHelp.add(new JSeparator()); + mHelp.add(new JMenuItem(am.getAction(Commands.HelpAbout))); + + menuBar.add(mServer); + menuBar.add(mEdit); + menuBar.add(mWindow); + menuBar.add(mHelp); + } + + + protected JComponent createPropertyView() { + if (selectedMedia.getMedia() != null) + propertyList = GlazedLists.eventList(selectedMedia.getMedia().getProperties().entrySet()); + else + propertyList = new BasicEventList<Map.Entry<String, Object>>(); + SortedList<Map.Entry<String, Object>> psl = new SortedList<Map.Entry<String, Object>>(propertyList, + new Comparator<Map.Entry<String, Object>>() { + @Override + public int compare(Entry<String, Object> a, Entry<String, Object> b) { + return a.getKey().compareToIgnoreCase(b.getKey()); + } + }); + PropertyTableFormat ptf = new PropertyTableFormat(); + DefaultEventTableModel<Map.Entry<String, Object>> tm = new DefaultEventTableModel<Map.Entry<String, Object>>( + psl, ptf); + JTable propertyTable = new JTable(tm); + JScrollPane psp = new JScrollPane(propertyTable); + int mx = propertyTable.getColumnModel().getColumnCount(); + + for (int i = 0; i < mx; ++i) { + int cw = ptf.getColumnWidth(i); + + if (cw > 0) + propertyTable.getColumnModel().getColumn(i).setMaxWidth(cw); + } + return psp; + } + + + protected JComponent createTreeView() { + TreeModel tm = new DefaultTreeModel(rootNode); + tree = new JTree(tm); + tree.setDragEnabled(true); + tree.setEditable(true); + tree.getActionMap().put("removeGenre", new AbstractAction() { //$NON-NLS-1$ + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doRemoveGenre(); + } + }); + tree.getActionMap().put("createGenre", new AbstractAction() { //$NON-NLS-1$ + private static final long serialVersionUID = 713L; + + + @Override + public void actionPerformed(ActionEvent e) { + doCreateGenre(); + } + }); + tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "removeGenre"); //$NON-NLS-1$ + tree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), "createGenre"); //$NON-NLS-1$ + tree.setDropMode(DropMode.USE_SELECTION); + tree.setTransferHandler(new TreeSourceAndDestTransferHandler(tree, nodeCache, changes)); + JScrollPane treeView = new JScrollPane(tree); + + return treeView; + } + + + protected void doConfigureClient() { + ConfigDialog cd = new ConfigDialog(frame); + + cd.showDialog(frame); + } + + + protected void doConnectServer() { + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + Config config = ApplicationServiceProvider.getService(Config.class); + Object ms = JOptionPane.showInputDialog(frame, mb.getMessage(CMPMessageBundle.MCC_12), mb + .getMessage(CMPMessageBundle.MCC_13), JOptionPane.PLAIN_MESSAGE, null, config.getKnownServers() + .toArray(), mb.getMessage(CMPMessageBundle.MCC_14)); + + if (ms instanceof MediaServer) { + System.out.println(mb.getMessage(CMPMessageBundle.MCC_15) + ((MediaServer) ms).getHostName() + + mb.getMessage(CMPMessageBundle.MCC_16) + ((MediaServer) ms).getPort()); + + clientStub = new CMPClient((MediaServer) ms); + ApplicationServiceProvider.registerService(ListLoader.class, clientStub); + DataManager dm = ApplicationServiceProvider.getService(DataManager.class); + + dm.load(rootNode, mediaList, this); + } + } + + + // respond to tree action + protected void doCreateGenre() { + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + + System.out.println(mb.getMessage(CMPMessageBundle.MCC_17)); + + //TODO: ask user for genre name and create node and cache entries + tree.updateUI(); + }; + + + protected void doDisconnectServer() { + ApplicationServiceProvider.registerService(MediaServer.class, null); + mediaList.getReadWriteLock().writeLock().lock(); + mediaList.clear(); + mediaList.getReadWriteLock().writeLock().unlock(); + ((DefaultMutableTreeNode) tree.getModel().getRoot()).removeAllChildren(); + tree.updateUI(); + selectedMedia.clear(); + updateServerActions(false); + clientStub = null; + } + + + // respond to tree action + protected void doRemoveGenre() { + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + + System.out.println(mb.getMessage(CMPMessageBundle.MCC_0)); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getSelectionPath().getLastPathComponent(); + if (node == null) + return; + Genre g = (Genre) node.getUserObject(); + + if (g.getMediaList().size() > 0 || g.getChildren().size() > 0) { + //TODO: ask user and/or pop some warning + } else { + nodeCache.remove(g.getRealPath()); + ((DefaultMutableTreeNode) node.getParent()).remove(node); + tree.updateUI(); + } + } + + + protected void doServerRescan() { + clientStub.execServerRescan(); + } + + + protected void doShowAbout() { + AboutDialog dlgAbout = new AboutDialog(frame); + + dlgAbout.showDialog(frame); + } + + + protected void doShowHelp() { + } + + + protected void doShutdownServer() { + clientStub.execServerShutdown(); + doDisconnectServer(); + } + + + protected void doTransmitChanges() { + clientStub.transmitChanges(changes); + } + + + protected void restoreAppStatus() { + Config config = ApplicationServiceProvider.getService(Config.class); + + try { + if (config != null) { + if (config.getMainWidth() > 0 && config.getMainHeight() > 0) + frame.setSize(config.getMainWidth(), config.getMainHeight()); + + if (config.getPosX() > 0 || config.getPosY() > 0) + frame.setLocation(config.getPosX(), config.getPosY()); + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + + + protected void restorePerspective() { + File dockableSettings = new File(configDirectory, DOCKING_CONFIG); + + try { + if (dockableSettings.exists() && dockableSettings.canRead()) + control.getResources().readFile(dockableSettings); + } catch (Throwable t) { + t.printStackTrace(); + } + restoreAppStatus(); + } + + + protected void saveAppStatus() { + Config config = ApplicationServiceProvider.getService(Config.class); + ConfigFactory cf = ApplicationServiceProvider.getService(ConfigFactory.class); + + try { + Dimension mainDim = frame.getSize(); + Point mainPos = frame.getLocation(); + + config.setMainWidth(mainDim.width); + config.setMainHeight(mainDim.height); + config.setPosX(mainPos.x); + config.setPosY(mainPos.y); + + cf.putConfig(config); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + + protected void savePerspective() { + File dockableSettings = new File(configDirectory, DOCKING_CONFIG); + + try { + if (!dockableSettings.exists()) + dockableSettings.getParentFile().mkdirs(); + control.getResources().writeFile(dockableSettings); + } catch (Throwable t) { + t.printStackTrace(); + } + saveAppStatus(); + } + + + protected JComponent setupPerspective(JFrame frame) { + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + + cdGenreTree = new BasicDockable("genreTree", mb.getMessage(CMPMessageBundle.MCC_29), createTreeView()); //$NON-NLS-1$ + cdMediaList = new BasicDockable("mediaList", mb.getMessage(CMPMessageBundle.MCC_31), createMediaTableView()); //$NON-NLS-1$ + cdMediaTypes = new BasicDockable( + "mediaTypes", mb.getMessage(CMPMessageBundle.MCC_33), mediaTypeSelector.getComponent()); //$NON-NLS-1$ + cdProperties = new BasicDockable("properties", mb.getMessage(CMPMessageBundle.MCC_35), createPropertyView()); //$NON-NLS-1$ + CGrid grid = new CGrid(control); + + grid.add(0, 0, 1, 2, cdGenreTree); + grid.add(1, 0, 1, 1, cdMediaList); + grid.add(2, 0, 1, 2, cdMediaTypes); + grid.add(1, 1, 1, 1, cdProperties); + + cdMediaList.setStackable(false); + cdMediaList.setExternalizable(false); + cdMediaList.setMinimizable(false); + control.getContentArea().deploy(grid); + + return control.getContentArea(); + } + + + protected Genre setupServices(String[] args, ConfigFactory configFactory) { + MessageBundle mb = new CMPMessageBundle(); + configDirectory = configFactory.getConfigDirectory(); + ApplicationServiceProvider.registerService(Config.class, configFactory.getConfig()); + ApplicationServiceProvider.registerService(ConfigFactory.class, configFactory); + ApplicationServiceProvider.registerService(MessageBundle.class, mb); + if (args.length > 0) { + File tmp = new File(args[0]); + + if (tmp.exists() && tmp.canRead()) { + System.out.println(mb.getMessage(CMPMessageBundle.MCC_4) + " " + tmp.getAbsolutePath() + + mb.getMessage(CMPMessageBundle.MCC_5)); + + input = tmp; + } + } + ApplicationServiceProvider.registerService(ActionManager.class, new ActionManager<Commands>()); + ApplicationServiceProvider.registerService(DataManager.class, new DataManager(input)); + ApplicationServiceProvider.registerService(ImageFactory.class, new ImageFactory()); + ApplicationServiceProvider.registerService(MedialistParser.class, new MedialistParser()); + + File base = new File("/"); //$NON-NLS-1$ + Genre root = new Genre(base); + + // ApplicationServiceProvider.registerService(FilesystemListLoader.class, new FilesystemListLoader(base)); + + return root; + } + + + protected void updateServerActions(boolean connected) { + @SuppressWarnings("unchecked") + ActionManager<Commands> am = ApplicationServiceProvider.getService(ActionManager.class); + + am.getAction(Commands.SrvOpen).setEnabled(!connected); + am.getAction(Commands.SrvClose).setEnabled(connected); + am.getAction(Commands.SrvRefresh).setEnabled(connected); + am.getAction(Commands.SrvShutdown).setEnabled(connected); + } + + + public static void main(final String[] args) { + javax.swing.SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + File configDir = new File(System.getProperty(USER_HOME), ".cmp"); //$NON-NLS-1$ + CMPCJ app = new CMPCJ(args, new ConfigFactory(configDir, "CMPCJ")); + + app.createAndShow(); + } + }); + } + + private DefaultMutableTreeNode rootNode; + private SortedList<Media> mediaList; + private SelectedMedia selectedMedia; + private EventList<AbstractMediaNode> changes; + private Map<File, DefaultMutableTreeNode> nodeCache; + private EventList<Map.Entry<String, Object>> propertyList; + private MediaTypeSelector mediaTypeSelector; + private CMPClient clientStub; + private CControl control; + private JFrame frame; + private BasicDockable cdMediaList; + private BasicDockable cdGenreTree; + private BasicDockable cdMediaTypes; + private BasicDockable cdProperties; + private File configDirectory; + private JTree tree; + private File input; +} diff --git a/cmpcj/src/de/schwarzrot/control/app/CMPMessageBundle.java b/cmpcj/src/de/schwarzrot/control/app/CMPMessageBundle.java new file mode 100644 index 0000000..33c4854 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/app/CMPMessageBundle.java @@ -0,0 +1,73 @@ +/** + * ======================== legal notice ====================== + * + * File: MCCMessageBundle.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.app; + + +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import de.schwarzrot.base.util.MessageBundle; + + +public class CMPMessageBundle implements MessageBundle { + public static final String MCC_0 = "MCC_0"; + public static final String MCC_12 = "MCC_12"; + public static final String MCC_13 = "MCC_13"; + public static final String MCC_14 = "MCC_14"; + public static final String MCC_15 = "MCC_15"; + public static final String MCC_16 = "MCC_16"; + public static final String MCC_17 = "MCC_17"; + public static final String MCC_18 = "MCC_18"; + public static final String MCC_19 = "MCC_19"; + public static final String MCC_20 = "MCC_20"; + public static final String MCC_21 = "MCC_21"; + public static final String MCC_22 = "MCC_22"; + public static final String MCC_29 = "MCC_29"; + public static final String MCC_31 = "MCC_31"; + public static final String MCC_33 = "MCC_33"; + public static final String MCC_35 = "MCC_35"; + public static final String MCC_4 = "MCC_4"; + public static final String MCC_5 = "MCC_5"; + public static final String MCC_6 = "MCC_6"; + public static final String MCC_7 = "MCC_7"; + public static final String PTF_0 = "PTF_0"; + public static final String PTF_1 = "PTF_1"; + public static final String MTF_0 = "MTF_0"; + public static final String MTF_1 = "MTF_1"; + public static final String MTF_2 = "MTF_2"; + + + @Override + public String getMessage(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + private final String BUNDLE_NAME = "de.schwarzrot.control.app.lang.messages"; //$NON-NLS-1$ + private final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); +} diff --git a/cmpcj/src/de/schwarzrot/control/client/CMPClient.java b/cmpcj/src/de/schwarzrot/control/client/CMPClient.java new file mode 100644 index 0000000..38c6ccb --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/client/CMPClient.java @@ -0,0 +1,171 @@ +/** + * ======================== legal notice ====================== + * + * File: CMPClient.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.client; + + +import java.net.ConnectException; +import java.net.URL; +import java.net.URLConnection; +import java.net.UnknownHostException; +import java.util.Date; +import ca.odell.glazedlists.EventList; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.media.domain.AbstractMediaNode; +import de.schwarzrot.media.domain.Media; +import de.schwarzrot.media.domain.MediaServer; +import de.schwarzrot.media.domain.PlayList; +import de.schwarzrot.media.util.ElementConsumer; +import de.schwarzrot.media.util.ListLoader; +import de.schwarzrot.media.util.MedialistParser; + + +public class CMPClient implements ListLoader<Media> { + public CMPClient(MediaServer serverDefinition) { + server = serverDefinition; + } + + + public void execServerRescan() { + try { + URL request = new URL("http", server.getHostName(), server.getPort(), "/refresh"); + URLConnection conn = request.openConnection(); + + conn.connect(); + conn.getContentLength(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + + public void execServerShutdown() { + try { + URL request = new URL("http", server.getHostName(), server.getPort(), "/stop"); + URLConnection conn = request.openConnection(); + + conn.connect(); + conn.getContentLength(); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + + public MediaServer getServerDefinition() { + return server; + } + + + @Override + public long[] loadFirst(ElementConsumer<Media> consumer) { + MedialistParser jsonParser = ApplicationServiceProvider.getService(MedialistParser.class); + URL request = null; + Date start, end; + long[] rv = new long[2]; + + try { + start = new Date(); + request = new URL("http", server.getHostName(), server.getPort(), "/?format=json"); + URLConnection conn = request.openConnection(); + final PlayList firstPlaylist = jsonParser.parseListChunk(conn.getInputStream()); + + for (Media m : firstPlaylist.getResults()) + consumer.consumeElement(m); + + end = new Date(); + rv[0] = firstPlaylist.getResults().size(); + rv[1] = firstPlaylist.getTotal(); + System.out.println("processing of first playlist-part took " + (end.getTime() - start.getTime()) + " ms."); + } catch (UnknownHostException uhe) { + throw new RuntimeException("failed to connect to " + server.getHostName(), uhe); + } catch (ConnectException ce) { + throw new RuntimeException("connection failure with " + server.getHostName(), ce); + } catch (Throwable t) { + t.printStackTrace(); + } + return rv; + } + + + @Override + public long loadRest(long[] listInfo, ElementConsumer<Media> consumer) { + MedialistParser jsonParser = ApplicationServiceProvider.getService(MedialistParser.class); + URL request = null; + Date start, end; + long rv = 0; + + try { + PlayList next; + URLConnection conn; + long total = listInfo[1]; + long n = listInfo[0]; + long elementsRead = 0; + String uri; + + start = new Date(); + try { + while (n < total) { + uri = String.format("/?start=%d&limit=%d&format=json", n, 100); + request = new URL("http", server.getHostName(), server.getPort(), uri); + conn = request.openConnection(); + next = jsonParser.parseListChunk(conn.getInputStream()); + for (Media m : next.getResults()) + consumer.consumeElement(m); + elementsRead = next.getResults().size(); + n += elementsRead; + rv += elementsRead; + Thread.sleep(10); + } + } catch (UnknownHostException uhe) { + throw new RuntimeException("failed to connect to " + server.getHostName(), uhe); + } catch (ConnectException ce) { + throw new RuntimeException("connection failure with " + server.getHostName(), ce); + } catch (Throwable t) { + System.err.println("Error on chunk #" + n); + t.printStackTrace(); + } + end = new Date(); + System.out.println("processing of rest of playlist took " + (end.getTime() - start.getTime()) + " ms."); + } catch (Throwable t) { + t.printStackTrace(); + } + return rv; + } + + + public void transmitChanges(EventList<AbstractMediaNode> changes) { + for (AbstractMediaNode n : changes) { + System.out.println("geänderter Eintrag: " + n.getClass().getSimpleName() + " - " + n.getName()); //$NON-NLS-1$ + System.out.println("\tverschieben von " + n.getOriginalPath().getAbsolutePath() + " nach " + + n.getRealPath().getAbsolutePath()); + + //TODO: really create jobs for changes, so backend can participate on work + + } + } + + private MediaServer server; +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaClientExecutor.java b/cmpcj/src/de/schwarzrot/control/client/MediaClientExecutor.java index 620c373..4ad39f2 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaClientExecutor.java +++ b/cmpcj/src/de/schwarzrot/control/client/MediaClientExecutor.java @@ -2,7 +2,7 @@ * ======================== legal notice ====================== * * File: MediaClientExecutor.java - * Created: + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,10 +23,10 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.util; +package de.schwarzrot.control.client; -import de.schwarzrot.cmpc.domain.Media; +import de.schwarzrot.media.domain.Media; public interface MediaClientExecutor { diff --git a/cmpcj/src/de/schwarzrot/control/config/ConfigDialog.java b/cmpcj/src/de/schwarzrot/control/config/ConfigDialog.java new file mode 100644 index 0000000..2acb026 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/config/ConfigDialog.java @@ -0,0 +1,131 @@ +/** + * ======================== legal notice ====================== + * + * File: ConfigDialog.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.config; + + +import java.awt.Window; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import ca.odell.glazedlists.BasicEventList; +import ca.odell.glazedlists.EventList; +import ca.odell.glazedlists.GlazedLists; +import ca.odell.glazedlists.swing.DefaultEventTableModel; +import de.schwarzrot.base.util.AbstractDialog; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.control.table.PlayerDefinitionTableFormat; +import de.schwarzrot.control.table.ServerDefinitionTableFormat; +import de.schwarzrot.media.domain.AbstractMediaNode; +import de.schwarzrot.media.domain.Config; +import de.schwarzrot.media.domain.MediaServer; +import de.schwarzrot.media.domain.PlayerDefinition; + + +public class ConfigDialog extends AbstractDialog { + private static final long serialVersionUID = 713L; + + + public ConfigDialog(Window parent) { + super(parent, true, DialogMode.CANCEL_APPROVE, Orientation.Right); + config = ApplicationServiceProvider.getService(Config.class); + } + + + @Override + public JComponent createContentPane() { + JTabbedPane rv = new JTabbedPane(); + + rv.addTab("server", createServerTable()); + rv.addTab("player", createPlayerTable()); + + return rv; + } + + + protected JComponent createPlayerTable() { + playerDefinitions = new BasicEventList<PlayerDefinition>(); + for (AbstractMediaNode.SupportedMediaType mt : AbstractMediaNode.SupportedMediaType.values()) { + if (mt == AbstractMediaNode.SupportedMediaType.Unknown) + break; + PlayerDefinition pd = config.getPlayerMap().get(mt); + + pd.setMediaType(mt); + playerDefinitions.add(pd); + } + PlayerDefinitionTableFormat ptf = new PlayerDefinitionTableFormat(); + DefaultEventTableModel<PlayerDefinition> tm = new DefaultEventTableModel<PlayerDefinition>(playerDefinitions, + ptf); + JTable playerTable = new JTable(tm); + JScrollPane playerTableScrollPane = new JScrollPane(playerTable); + int mx = playerTable.getColumnModel().getColumnCount(); + + for (int i = 0; i < mx; ++i) { + int cw = ptf.getColumnWidth(i); + + if (cw > 0) { + playerTable.getColumnModel().getColumn(i).setPreferredWidth(cw); + playerTable.getColumnModel().getColumn(i).setMaxWidth(cw); + } + } + return playerTableScrollPane; + } + + + protected JComponent createServerTable() { + serverDefinitions = GlazedLists.eventList(config.getKnownServers()); + ServerDefinitionTableFormat stf = new ServerDefinitionTableFormat(); + DefaultEventTableModel<MediaServer> tm = new DefaultEventTableModel<MediaServer>(serverDefinitions, stf); + JTable serverTable = new JTable(tm); + JScrollPane serverTableScrollPane = new JScrollPane(serverTable); + int mx = serverTable.getColumnModel().getColumnCount(); + + for (int i = 0; i < mx; ++i) { + int cw = stf.getColumnWidth(i); + + if (cw > 0) { + serverTable.getColumnModel().getColumn(i).setPreferredWidth(cw); + serverTable.getColumnModel().getColumn(i).setMaxWidth(cw); + } + } + return serverTableScrollPane; + } + + + @Override + protected void performApprove() { + System.out.println("should save config now!?!"); + List<MediaServer> cfgServers = config.getKnownServers(); + + cfgServers.clear(); + cfgServers.addAll(serverDefinitions); + } + + private EventList<MediaServer> serverDefinitions; + private EventList<PlayerDefinition> playerDefinitions; + private Config config; +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/app/ConfigFactory.java b/cmpcj/src/de/schwarzrot/control/config/ConfigFactory.java index f1c4685..5424ef5 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/app/ConfigFactory.java +++ b/cmpcj/src/de/schwarzrot/control/config/ConfigFactory.java @@ -2,7 +2,7 @@ * ======================== legal notice ====================== * * File: ConfigFactory.java - * Created: + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,27 +23,30 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.app; +package de.schwarzrot.control.config; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; +import java.io.PrintWriter; import java.util.regex.Matcher; import java.util.regex.Pattern; -import de.schwarzrot.cmpc.domain.Config; -import de.schwarzrot.cmpc.domain.Media; -import de.schwarzrot.cmpc.domain.MediaServer; -import de.schwarzrot.cmpc.domain.PlayerDefinition; +import de.schwarzrot.media.domain.Config; +import de.schwarzrot.media.domain.Media; +import de.schwarzrot.media.domain.MediaServer; +import de.schwarzrot.media.domain.PlayerDefinition; public class ConfigFactory { protected static final Pattern SETUP_MASK = Pattern.compile("^\\s*(\\S+)\\s*=\\s*(.+)$"); - public ConfigFactory(File configDirectory) { + public ConfigFactory(File configDirectory, String applicationID) { baseDir = configDirectory; + appID = applicationID; } @@ -55,6 +58,17 @@ public class ConfigFactory { } + public File getConfigDirectory() { + return baseDir; + } + + + public void putConfig(Config config) { + if (config != null) + writeConfig(config); + } + + protected Config readConfig() { File setupFile = new File(baseDir, "srclient.conf"); BufferedReader br = null; @@ -111,6 +125,32 @@ public class ConfigFactory { } } } + } else if (key.compareToIgnoreCase("size") == 0) { + String[] parts = value.split("\\s*x\\s*"); + + if (parts.length > 1) { + try { + rv.setMainWidth(Integer.decode(parts[0])); + } catch (Throwable t) { + } + try { + rv.setMainHeight(Integer.decode(parts[1])); + } catch (Throwable t) { + } + } + } else if (key.compareToIgnoreCase("pos") == 0) { + String[] parts = value.split("\\s*\\/\\s*"); + + if (parts.length > 1) { + try { + rv.setPosX(Integer.decode(parts[0])); + } catch (Throwable t) { + } + try { + rv.setPosY(Integer.decode(parts[1])); + } catch (Throwable t) { + } + } } } } @@ -127,6 +167,59 @@ public class ConfigFactory { } return rv; } + + + protected void writeConfig(Config config) { + File setupFile = new File(baseDir, "srclient.conf"); + PrintWriter out = null; + StringBuilder sb = null; + + if (!setupFile.exists()) + setupFile.getParentFile().mkdirs(); + try { + out = new PrintWriter(new FileWriter(setupFile)); + + sb = new StringBuilder("#\n# configuration for "); + sb.append(appID).append("\n#"); + out.println(sb.toString()); + for (MediaServer server : config.getKnownServers()) { + sb = new StringBuilder("server = "); + sb.append(server.getHostName()).append(":").append(server.getPort()); + out.println(sb.toString()); + } + out.println(); + sb = new StringBuilder("#\n# currently supported media types ("); + sb.append(Media.SupportedMediaType.LegacyVdrRecording.name()); + sb.append(" is the old PES format):\n"); + sb.append("# "); + sb.append("#"); + out.println(sb.toString()); + for (Media.SupportedMediaType mt : config.getPlayerMap().keySet()) { + PlayerDefinition player = config.getPlayerMap().get(mt); + + sb = new StringBuilder("player = "); + sb.append(mt.name()).append(" : ").append(player.getExecutable()); + for (String p : player.getParameters()) { + sb.append(" ").append(p); + } + out.println(sb.toString()); + } + out.println(); + sb = new StringBuilder("size = "); + sb.append(config.getMainWidth()).append(" x ").append(config.getMainHeight()); + out.println(sb.toString()); + + sb = new StringBuilder("pos = "); + sb.append(config.getPosX()).append(" / ").append(config.getPosY()); + out.println(sb.toString()); + } catch (Throwable t) { + t.printStackTrace(); + } finally { + if (out != null) + out.close(); + } + } private Config config; private File baseDir; + private final String appID; } diff --git a/cmpcj/src/de/schwarzrot/control/dnd/FilelistTransferable.java b/cmpcj/src/de/schwarzrot/control/dnd/FilelistTransferable.java new file mode 100644 index 0000000..678bbc1 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/dnd/FilelistTransferable.java @@ -0,0 +1,72 @@ +/** + * ======================== legal notice ====================== + * + * File: FilelistTransferable.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.dnd; + + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.File; +import java.io.IOException; +import java.util.List; + + +public class FilelistTransferable implements Transferable { + public FilelistTransferable(List<File> fileList) { + files = fileList; + } + + + protected FilelistTransferable() { + } + + + @Override + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + if (DataFlavor.javaFileListFlavor.equals(flavor)) + return files; + throw new UnsupportedFlavorException(flavor); + } + + + @Override + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { DataFlavor.javaFileListFlavor }; + } + + + @Override + public boolean isDataFlavorSupported(DataFlavor flavor) { + return DataFlavor.javaFileListFlavor.equals(flavor); + } + + + protected void setFileList(List<File> list) { + files = list; + } + + private List<File> files; +} diff --git a/cmpcj/src/de/schwarzrot/control/dnd/ListSelectionSourceTransferHandler.java b/cmpcj/src/de/schwarzrot/control/dnd/ListSelectionSourceTransferHandler.java new file mode 100644 index 0000000..e396e17 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/dnd/ListSelectionSourceTransferHandler.java @@ -0,0 +1,69 @@ +/** + * ======================== legal notice ====================== + * + * File: ListSelectionSourceTransferHandler.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.dnd; + + +import java.awt.datatransfer.Transferable; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.TransferHandler; +import ca.odell.glazedlists.EventList; +import ca.odell.glazedlists.swing.DefaultEventSelectionModel; +import de.schwarzrot.media.domain.Media; + + +public class ListSelectionSourceTransferHandler extends TransferHandler { + private static final long serialVersionUID = 713L; + + + public ListSelectionSourceTransferHandler(DefaultEventSelectionModel<Media> selectionModel) { + sm = selectionModel; + } + + + @Override + public Transferable createTransferable(JComponent c) { + if (sm.isSelectionEmpty()) + return null; + EventList<Media> selection = sm.getSelected(); + List<File> transferList = new ArrayList<File>(); + + for (Media m : selection) { + transferList.add(m.getRealPath()); + } + return new FilelistTransferable(transferList); + } + + + @Override + public int getSourceActions(JComponent c) { + return TransferHandler.LINK; + } + + private DefaultEventSelectionModel<Media> sm; +} diff --git a/cmpcj/src/de/schwarzrot/control/dnd/TreePathTransferable.java b/cmpcj/src/de/schwarzrot/control/dnd/TreePathTransferable.java new file mode 100644 index 0000000..a54be35 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/dnd/TreePathTransferable.java @@ -0,0 +1,74 @@ +/** + * ======================== legal notice ====================== + * + * File: TreePathTransferable.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.dnd; + + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import javax.swing.tree.TreePath; + + +public class TreePathTransferable implements Transferable { + public static final DataFlavor TreePathFlavor; + + + public TreePathTransferable(TreePath path) { + data = path; + } + + + @Override + public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { + if (TreePathFlavor.equals(flavor)) + return data; + throw new UnsupportedFlavorException(flavor); + } + + + @Override + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { TreePathFlavor }; + } + + + @Override + public boolean isDataFlavorSupported(DataFlavor flavor) { + return TreePathFlavor.equals(flavor); + } + + private TreePath data; + static { + DataFlavor tmp = null; + + try { + tmp = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + TreePath.class.getName()); + } catch (ClassNotFoundException e) { + } + TreePathFlavor = tmp; + } +} diff --git a/cmpcj/src/de/schwarzrot/control/dnd/TreeSourceAndDestTransferHandler.java b/cmpcj/src/de/schwarzrot/control/dnd/TreeSourceAndDestTransferHandler.java new file mode 100644 index 0000000..d9c3285 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/dnd/TreeSourceAndDestTransferHandler.java @@ -0,0 +1,207 @@ +/** + * ======================== legal notice ====================== + * + * File: TreeSourceAndDestTransferHandler.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.dnd; + + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.io.File; +import java.util.List; +import java.util.Map; +import javax.swing.JComponent; +import javax.swing.JTree; +import javax.swing.TransferHandler; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import ca.odell.glazedlists.EventList; +import de.schwarzrot.media.domain.AbstractMediaNode; +import de.schwarzrot.media.domain.Genre; +import de.schwarzrot.media.domain.Media; + + +public class TreeSourceAndDestTransferHandler extends TransferHandler { + private static final long serialVersionUID = 713L; + + + public TreeSourceAndDestTransferHandler(JTree tree, Map<File, DefaultMutableTreeNode> cache, + EventList<AbstractMediaNode> changes) { + this.tree = tree; + nodeCache = cache; + this.changes = changes; + } + + + // dest + @Override + public boolean canImport(TransferHandler.TransferSupport support) { + if (!support.isDrop()) + return false; + support.setShowDropLocation(true); + + if (support.isDataFlavorSupported(TreePathTransferable.TreePathFlavor) && support.getDropAction() == MOVE) + return true; + if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) + return true; + + return false; + } + + + // source + @Override + public Transferable createTransferable(JComponent c) { + if (c != tree) + return null; + TreePath selectionPath = tree.getSelectionPath(); + + return new TreePathTransferable(selectionPath); + } + + + // source + @Override + public void exportDone(JComponent c, Transferable data, int action) { + tree.updateUI(); + } + + + // source + @Override + public int getSourceActions(JComponent c) { + return MOVE; + } + + + // dest + @Override + public boolean importData(TransferHandler.TransferSupport support) { + if (!canImport(support)) + return false; + JTree.DropLocation dl = (JTree.DropLocation) support.getDropLocation(); + TreePath targetPath = tree.getClosestPathForLocation(dl.getDropPoint().x, dl.getDropPoint().y); + DefaultMutableTreeNode targetNode = (DefaultMutableTreeNode) targetPath.getLastPathComponent(); + + if (support.isDataFlavorSupported(TreePathTransferable.TreePathFlavor)) { + // move a genre in tree + try { + TreePath sourcePath = (TreePath) support.getTransferable().getTransferData( + TreePathTransferable.TreePathFlavor); + DefaultMutableTreeNode transferNode = (DefaultMutableTreeNode) sourcePath.getLastPathComponent(); + DefaultMutableTreeNode sourceParentNode = (DefaultMutableTreeNode) transferNode.getParent(); + Genre target = (Genre) targetNode.getUserObject(); + Genre transfer = (Genre) transferNode.getUserObject(); + + // System.out.println("importData() targetPath: " + targetPath); + // System.out.println("importData() sourcePath: " + sourcePath); + + sourceParentNode.remove(transferNode); + targetNode.add(transferNode); + nodeCache.remove(transfer.getRealPath()); + // System.out.println("old path of genre to move: " + transfer.getRealPath().getAbsolutePath()); + transfer.setParent(target); + // System.out.println("new path of moved genre: " + transfer.getRealPath().getAbsolutePath()); + nodeCache.put(transfer.getRealPath(), transferNode); + transfer.update(); + refreshNodeCache(); + if (!changes.contains(transfer)) { + changes.getReadWriteLock().writeLock().lock(); + changes.add(transfer); + changes.getReadWriteLock().writeLock().unlock(); + } + } catch (Throwable t) { + t.printStackTrace(); + } + } else if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { + // move media files from one genre to another (no visible tree change) + try { + @SuppressWarnings("unchecked") + List<File> fileList = (List<File>) support.getTransferable().getTransferData( + DataFlavor.javaFileListFlavor); + + for (File f : fileList) + move2TargetNode(targetNode, f); // each media can have different parent, so don't optimize here + } catch (Throwable t) { + t.printStackTrace(); + } + } + return false; + } + + + protected void cacheNode(DefaultMutableTreeNode node) { + Genre g = (Genre) node.getUserObject(); + + nodeCache.put(g.getRealPath(), node); + for (int i = 0; i < node.getChildCount(); ++i) { + DefaultMutableTreeNode sub = (DefaultMutableTreeNode) node.getChildAt(i); + + cacheNode(sub); + } + } + + + protected void move2TargetNode(DefaultMutableTreeNode targetNode, File mediaPath) { + if (targetNode == null || mediaPath == null) + return; + Genre targetGenre = (Genre) targetNode.getUserObject(); + DefaultMutableTreeNode node = nodeCache.get(mediaPath.getParentFile()); + + if (targetGenre != null && node != null) { + Media transferMedia = null; + Genre sourceGenre = (Genre) node.getUserObject(); + + for (Media m : sourceGenre.getMediaList()) { + if (m.getRealPath().equals(mediaPath)) { + transferMedia = m; + break; + } + } + + if (transferMedia != null) { + System.out.println("old path of media to transfer: " + transferMedia.getRealPath().getAbsolutePath()); + transferMedia.setParent(targetGenre); + System.out.println("new path of transferred media: " + transferMedia.getRealPath().getAbsolutePath()); + if (!changes.contains(transferMedia)) { + changes.getReadWriteLock().writeLock().lock(); + changes.add(transferMedia); + changes.getReadWriteLock().writeLock().unlock(); + } + } + } + } + + + protected void refreshNodeCache() { + nodeCache.clear(); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getModel().getRoot(); + + cacheNode(node); + } + + private JTree tree; + private EventList<AbstractMediaNode> changes; + private Map<File, DefaultMutableTreeNode> nodeCache; +} diff --git a/cmpcj/src/de/schwarzrot/control/support/GenreSelector.java b/cmpcj/src/de/schwarzrot/control/support/GenreSelector.java new file mode 100644 index 0000000..9566ae8 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/support/GenreSelector.java @@ -0,0 +1,46 @@ +/** + * ======================== legal notice ====================== + * + * File: GenreSelector.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.support; + + +import ca.odell.glazedlists.matchers.Matcher; +import de.schwarzrot.media.domain.Genre; +import de.schwarzrot.media.domain.Media; + + +public class GenreSelector implements Matcher<Media> { + public GenreSelector(Genre genre) { + g = genre; + } + + + @Override + public boolean matches(Media m) { + return m.getRealPath().getAbsolutePath().startsWith(g.getRealPath().getAbsolutePath()); + } + + private Genre g; +}
\ No newline at end of file diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaPool2TypeList.java b/cmpcj/src/de/schwarzrot/control/support/MediaList2TypeList.java index de93246..8445db8 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaPool2TypeList.java +++ b/cmpcj/src/de/schwarzrot/control/support/MediaList2TypeList.java @@ -1,8 +1,8 @@ /** * ======================== legal notice ====================== * - * File: MediaPool2TypeList.java - * Created: + * File: MediaList2TypeList.java + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,17 +23,18 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.util; +package de.schwarzrot.control.support; import ca.odell.glazedlists.EventList; import ca.odell.glazedlists.TransformedList; import ca.odell.glazedlists.event.ListEvent; -import de.schwarzrot.cmpc.domain.Media; +import de.schwarzrot.media.domain.AbstractMediaNode; +import de.schwarzrot.media.domain.Media; -public class MediaPool2TypeList extends TransformedList<Media, Media.SupportedMediaType> { - public MediaPool2TypeList(EventList<Media> source) { +public class MediaList2TypeList extends TransformedList<Media, AbstractMediaNode.SupportedMediaType> { + public MediaList2TypeList(EventList<Media> source) { super(source); source.addListEventListener(this); } diff --git a/cmpcj/src/de/schwarzrot/control/support/MediaTextFilterator.java b/cmpcj/src/de/schwarzrot/control/support/MediaTextFilterator.java new file mode 100644 index 0000000..b36f582 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/support/MediaTextFilterator.java @@ -0,0 +1,41 @@ +/** + * ======================== legal notice ====================== + * + * File: MediaTextFilterator.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.support; + + +import java.util.List; +import ca.odell.glazedlists.TextFilterator; +import de.schwarzrot.media.domain.Media; + + +public class MediaTextFilterator implements TextFilterator<Media> { + @Override + public void getFilterStrings(List<String> baseList, Media m) { + baseList.add(m.getName()); + baseList.add(m.getRealPath().getAbsolutePath()); + baseList.add(m.getSearch()); + } +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaTypeSelect.java b/cmpcj/src/de/schwarzrot/control/support/MediaTypeSelector.java index bde865a..f60ddc4 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaTypeSelect.java +++ b/cmpcj/src/de/schwarzrot/control/support/MediaTypeSelector.java @@ -1,40 +1,39 @@ /** * ======================== legal notice ====================== * - * File: MediaTypeSelect.java Created: Author: <a - * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend - * (client) part of compound media player uses external players to play the - * media + * File: MediaTypeSelector.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media * * CMP - compound media player * - * is a client/server mediaplayer intended to play any media from any - * workstation without the need to export or mount shares. cmps is an easy to - * use backend with a (ready to use) HTML-interface. Additionally the backend - * supports authentication via HTTP-digest authorization. cmpc is a client with - * vdr-like osd-menues. + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under - * Creative Commons by-sa For details see - * http://creativecommons.org/licenses/by-sa/3.0/ + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ * - * The cmp project's homepage is at - * http://projects.vdr-developer.org/projects/cmp + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.util; +package de.schwarzrot.control.support; import java.awt.Color; import java.awt.Component; -import java.awt.Image; -import java.awt.image.BufferedImage; -import java.net.URL; -import javax.imageio.ImageIO; +import java.awt.Dimension; import javax.swing.ImageIcon; +import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JList; +import javax.swing.JScrollPane; import javax.swing.ListCellRenderer; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; @@ -44,10 +43,12 @@ import ca.odell.glazedlists.matchers.AbstractMatcherEditor; import ca.odell.glazedlists.matchers.Matcher; import ca.odell.glazedlists.swing.DefaultEventListModel; import ca.odell.glazedlists.swing.DefaultEventSelectionModel; -import de.schwarzrot.cmpc.domain.Media; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.base.util.ImageFactory; +import de.schwarzrot.media.domain.Media; -public class MediaTypeSelect extends AbstractMatcherEditor<Media> implements ListSelectionListener { +public class MediaTypeSelector extends AbstractMatcherEditor<Media> implements ListSelectionListener { public class MediaTypeCellRenderer extends JLabel implements ListCellRenderer { private static final long serialVersionUID = 713L; @@ -85,34 +86,24 @@ public class MediaTypeSelect extends AbstractMatcherEditor<Media> implements Lis protected void loadImages() { - BufferedImage img = null; - ClassLoader cl = getClass().getClassLoader(); - URL url; - - stdImages = new ImageIcon[iconFiles.length]; - for (int i = 0; i < iconFiles.length; ++i) { - try { - url = cl.getResource(iconFiles[i]); - - img = ImageIO.read(url); - stdImages[i] = new ImageIcon(img.getScaledInstance(110, 110, Image.SCALE_SMOOTH)); - } catch (Throwable t) { - System.err.println("failed to read image from " + iconFiles[i]); - t.printStackTrace(); - } + ImageFactory imgFak = ApplicationServiceProvider.getService(ImageFactory.class); + int i = 0; + + stdImages = new ImageIcon[Media.SupportedMediaType.values().length]; + for (Media.SupportedMediaType smt : Media.SupportedMediaType.values()) { + StringBuilder sb = new StringBuilder(smt.getClass().getSimpleName()); + + sb.append(".").append(smt.name()).append(".default"); + stdImages[i++] = imgFak.getIcon(sb.toString(), 110, 110); } - selImages = new ImageIcon[activeIconFiles.length]; - for (int i = 0; i < activeIconFiles.length; ++i) { - try { - url = cl.getResource(activeIconFiles[i]); - - img = ImageIO.read(url); - selImages[i] = new ImageIcon(img.getScaledInstance(110, 110, Image.SCALE_SMOOTH)); - } catch (Throwable t) { - System.err.println("failed to read image from " + activeIconFiles[i]); - t.printStackTrace(); - } + i = 0; + selImages = new ImageIcon[Media.SupportedMediaType.values().length]; + for (Media.SupportedMediaType smt : Media.SupportedMediaType.values()) { + StringBuilder sb = new StringBuilder(smt.getClass().getSimpleName()); + + sb.append(".").append(smt.name()).append(".active"); + selImages[i++] = imgFak.getIcon(sb.toString(), 110, 110); } } @@ -121,8 +112,8 @@ public class MediaTypeSelect extends AbstractMatcherEditor<Media> implements Lis } - public MediaTypeSelect(EventList<Media> source) { - EventList<Media.SupportedMediaType> mediaTypeNonUnique = new MediaPool2TypeList(source); + public MediaTypeSelector(EventList<Media> source) { + EventList<Media.SupportedMediaType> mediaTypeNonUnique = new MediaList2TypeList(source); mediaTypeList = new UniqueList<Media.SupportedMediaType>(mediaTypeNonUnique); DefaultEventListModel<Media.SupportedMediaType> mediaTypeListModel = new DefaultEventListModel<Media.SupportedMediaType>( @@ -137,6 +128,13 @@ public class MediaTypeSelect extends AbstractMatcherEditor<Media> implements Lis mediaTypeJList.addListSelectionListener(this); mediaTypeJList.setCellRenderer(new MediaTypeCellRenderer()); mediaTypeJList.setBackground(Color.BLACK); + mediaTypeJList.setMinimumSize(new Dimension(100, 100)); + mediaTypeComponent = new JScrollPane(mediaTypeJList); + } + + + public JComponent getComponent() { + return mediaTypeComponent; } @@ -147,7 +145,7 @@ public class MediaTypeSelect extends AbstractMatcherEditor<Media> implements Lis @Override public void valueChanged(ListSelectionEvent e) { - Matcher<Media> newMatcher = new MediaForTypeMatcher(selectedTypes); + Matcher<Media> newMatcher = new MediatypeMatcher(selectedTypes); fireChanged(newMatcher); } @@ -155,16 +153,5 @@ public class MediaTypeSelect extends AbstractMatcherEditor<Media> implements Lis private EventList<Media.SupportedMediaType> mediaTypeList; private EventList<Media.SupportedMediaType> selectedTypes; private JList mediaTypeJList; - private static final String[] iconFiles; - private static final String[] activeIconFiles; - static { - iconFiles = new String[] { "images/sr_default.png", "images/sr_music.png", "images/sr_movies.png", - "images/sr_movies_i.png", "images/sr_dvd.png", "images/sr_dvd_i.png", "images/sr_lvdr.png", - "images/sr_lvdr_i.png", "images/sr_vdr.png", "images/sr_vdr_i.png", "images/sr_photos.png", - "images/sr_default.png" }; - activeIconFiles = new String[] { "images/sradefault.png", "images/sramusic.png", "images/sramovies.png", - "images/sramovies_i.png", "images/sradvd.png", "images/sradvd_i.png", "images/sralvdr.png", - "images/sralvdr_i.png", "images/sravdr.png", "images/sravdr_i.png", "images/sraphotos.png", - "images/sradefault.png" }; - } + private JScrollPane mediaTypeComponent; } diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaForTypeMatcher.java b/cmpcj/src/de/schwarzrot/control/support/MediatypeMatcher.java index 18820cf..a01b43a 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaForTypeMatcher.java +++ b/cmpcj/src/de/schwarzrot/control/support/MediatypeMatcher.java @@ -1,8 +1,8 @@ /** * ======================== legal notice ====================== * - * File: MediaForTypeMatcher.java - * Created: + * File: MediatypeMatcher.java + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,18 +23,19 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.util; +package de.schwarzrot.control.support; import java.util.Collection; import java.util.HashSet; import java.util.Set; import ca.odell.glazedlists.matchers.Matcher; -import de.schwarzrot.cmpc.domain.Media; +import de.schwarzrot.media.domain.AbstractMediaNode; +import de.schwarzrot.media.domain.Media; -public class MediaForTypeMatcher implements Matcher<Media> { - public MediaForTypeMatcher(Collection<Media.SupportedMediaType> mediaTypes) { +public class MediatypeMatcher implements Matcher<Media> { + public MediatypeMatcher(Collection<AbstractMediaNode.SupportedMediaType> mediaTypes) { this.mediaTypes.addAll(mediaTypes); } @@ -50,5 +51,5 @@ public class MediaForTypeMatcher implements Matcher<Media> { return mediaTypes.contains(mt); } - private Set<Media.SupportedMediaType> mediaTypes = new HashSet<Media.SupportedMediaType>(); + private Set<AbstractMediaNode.SupportedMediaType> mediaTypes = new HashSet<Media.SupportedMediaType>(); } diff --git a/cmpcj/src/de/schwarzrot/control/support/SelectedMedia.java b/cmpcj/src/de/schwarzrot/control/support/SelectedMedia.java new file mode 100644 index 0000000..efde378 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/support/SelectedMedia.java @@ -0,0 +1,85 @@ +/** + * ======================== legal notice ====================== + * + * File: SelectedMedia.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.support; + + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import ca.odell.glazedlists.EventList; +import ca.odell.glazedlists.swing.DefaultEventSelectionModel; +import de.schwarzrot.media.domain.Media; + + +public class SelectedMedia implements ListSelectionListener { + public static final String MEDIA_PROPERTY = "media"; + + + public SelectedMedia(EventList<Media> source) { + pcs = new PropertyChangeSupport(this); + mediaList = source; + } + + + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + + public void clear() { + pcs.firePropertyChange(MEDIA_PROPERTY, this.media, this.media = null); + } + + + public Media getMedia() { + return media; + } + + + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + + @Override + public void valueChanged(ListSelectionEvent e) { + if (e.getValueIsAdjusting()) + return; + if (e.getSource() instanceof DefaultEventSelectionModel) { + @SuppressWarnings("unchecked") + DefaultEventSelectionModel<Media> sm = (DefaultEventSelectionModel<Media>) e.getSource(); + + if (sm.isSelectionEmpty()) + return; + pcs.firePropertyChange(MEDIA_PROPERTY, this.media, this.media = mediaList.get(sm.getLeadSelectionIndex())); + } + } + + private Media media; + private PropertyChangeSupport pcs; + private EventList<Media> mediaList; +} diff --git a/cmpcj/src/de/schwarzrot/control/support/TreeSelectionFilter.java b/cmpcj/src/de/schwarzrot/control/support/TreeSelectionFilter.java new file mode 100644 index 0000000..99d1646 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/support/TreeSelectionFilter.java @@ -0,0 +1,59 @@ +/** + * ======================== legal notice ====================== + * + * File: TreeSelectionFilter.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.support; + + +import javax.swing.JTree; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import ca.odell.glazedlists.matchers.AbstractMatcherEditor; +import ca.odell.glazedlists.matchers.Matcher; +import de.schwarzrot.media.domain.Genre; +import de.schwarzrot.media.domain.Media; + + +public class TreeSelectionFilter extends AbstractMatcherEditor<Media> implements TreeSelectionListener { + public TreeSelectionFilter(JTree tree) { + this.tree = tree; + tree.addTreeSelectionListener(this); + } + + + @Override + public void valueChanged(TreeSelectionEvent e) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); + + if (node == null) + return; + Genre g = (Genre) node.getUserObject(); + Matcher<Media> newMatcher = new GenreSelector(g); + + fireChanged(newMatcher); + } + + private JTree tree; +} diff --git a/cmpcj/src/de/schwarzrot/control/table/MediaTableFormat.java b/cmpcj/src/de/schwarzrot/control/table/MediaTableFormat.java new file mode 100644 index 0000000..88bdea1 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/table/MediaTableFormat.java @@ -0,0 +1,91 @@ +/** + * ======================== legal notice ====================== + * + * File: MediaTableFormat.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.table; + + +import ca.odell.glazedlists.gui.TableFormat; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.base.util.MessageBundle; +import de.schwarzrot.control.app.CMPMessageBundle; +import de.schwarzrot.media.domain.Media; + + +public class MediaTableFormat implements TableFormat<Media> { + private static MessageBundle bundle; + + + @Override + public int getColumnCount() { + return 3; + } + + + @Override + public String getColumnName(int column) { + if (bundle == null) + bundle = ApplicationServiceProvider.getService(MessageBundle.class); + + switch (column) { + case 0: + return bundle.getMessage(CMPMessageBundle.MTF_0); + case 1: + return bundle.getMessage(CMPMessageBundle.MTF_1); + case 2: + return bundle.getMessage(CMPMessageBundle.MTF_2); + default: + throw new IndexOutOfBoundsException(); + } + } + + + @Override + public Object getColumnValue(Media m, int column) { + switch (column) { + case 0: + return m.getType(); + case 1: + return m.getFormat(); + case 2: + return m.getName(); + default: + throw new IndexOutOfBoundsException(); + } + } + + + public int getColumnWidth(int column) { + switch (column) { + case 0: + return 80; + case 1: + return 110; + case 2: + return -1; + default: + throw new IndexOutOfBoundsException(); + } + } +} diff --git a/cmpcj/src/de/schwarzrot/control/table/PlayerDefinitionTableFormat.java b/cmpcj/src/de/schwarzrot/control/table/PlayerDefinitionTableFormat.java new file mode 100644 index 0000000..cadc6d7 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/table/PlayerDefinitionTableFormat.java @@ -0,0 +1,114 @@ +/** + * ======================== legal notice ====================== + * + * File: PlayerDefinitionTableFormat.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.table; + + +import ca.odell.glazedlists.gui.WritableTableFormat; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.base.util.MessageBundle; +import de.schwarzrot.media.domain.PlayerDefinition; + + +public class PlayerDefinitionTableFormat implements WritableTableFormat<PlayerDefinition> { + private static MessageBundle bundle; + protected static final String KEY_0 = PlayerDefinitionTableFormat.class.getSimpleName() + ".col0"; + protected static final String KEY_1 = PlayerDefinitionTableFormat.class.getSimpleName() + ".col1"; + + + @Override + public int getColumnCount() { + return 2; + } + + + @Override + public String getColumnName(int column) { + if (bundle == null) + bundle = ApplicationServiceProvider.getService(MessageBundle.class); + + switch (column) { + case 0: + return bundle.getMessage(KEY_0); + case 1: + return bundle.getMessage(KEY_1); + default: + throw new IndexOutOfBoundsException(); + } + } + + + @Override + public Object getColumnValue(PlayerDefinition pd, int column) { + switch (column) { + case 0: + return pd.getMediaType().name(); + case 1: + return pd.getCommandLine(); + default: + throw new IndexOutOfBoundsException(); + } + } + + + public int getColumnWidth(int column) { + switch (column) { + case 0: + return 150; + case 1: + return -1; + default: + throw new IndexOutOfBoundsException(); + } + } + + + @Override + public boolean isEditable(PlayerDefinition pd, int column) { + switch (column) { + case 0: + return false; + case 1: + return true; + default: + throw new IndexOutOfBoundsException(); + } + } + + + @Override + public PlayerDefinition setColumnValue(PlayerDefinition pd, Object value, int column) { + switch (column) { + case 0: + break; + case 1: + pd.setCommandLine(value.toString()); + break; + default: + throw new IndexOutOfBoundsException(); + } + return pd; + } +} diff --git a/cmpcj/src/de/schwarzrot/control/table/ServerDefinitionTableFormat.java b/cmpcj/src/de/schwarzrot/control/table/ServerDefinitionTableFormat.java new file mode 100644 index 0000000..2e4c630 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/table/ServerDefinitionTableFormat.java @@ -0,0 +1,119 @@ +/** + * ======================== legal notice ====================== + * + * File: ServerDefinitionTableFormat.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.control.table; + + +import ca.odell.glazedlists.gui.WritableTableFormat; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.base.util.MessageBundle; +import de.schwarzrot.media.domain.MediaServer; + + +public class ServerDefinitionTableFormat implements WritableTableFormat<MediaServer> { + private static MessageBundle bundle; + protected static final String KEY_0 = ServerDefinitionTableFormat.class.getSimpleName() + ".col0"; + protected static final String KEY_1 = ServerDefinitionTableFormat.class.getSimpleName() + ".col1"; + + + @Override + public int getColumnCount() { + return 2; + } + + + @Override + public String getColumnName(int column) { + if (bundle == null) + bundle = ApplicationServiceProvider.getService(MessageBundle.class); + + switch (column) { + case 0: + return bundle.getMessage(KEY_0); + case 1: + return bundle.getMessage(KEY_1); + default: + throw new IndexOutOfBoundsException(); + } + } + + + @Override + public Object getColumnValue(MediaServer sd, int column) { + switch (column) { + case 0: + return sd.getHostName(); + case 1: + return sd.getPort(); + default: + throw new IndexOutOfBoundsException(); + } + } + + + public int getColumnWidth(int column) { + switch (column) { + case 0: + return -1; + case 1: + return 80; + default: + throw new IndexOutOfBoundsException(); + } + } + + + @Override + public boolean isEditable(MediaServer sd, int column) { + switch (column) { + case 0: + case 1: + return true; + default: + throw new IndexOutOfBoundsException(); + } + } + + + @Override + public MediaServer setColumnValue(MediaServer sd, Object value, int column) { + switch (column) { + case 0: + sd.setHostName(value.toString()); + break; + + case 1: + try { + sd.setPort(Integer.decode(value.toString())); + } catch (Throwable t) { + } + break; + + default: + throw new IndexOutOfBoundsException(); + } + return sd; + } +} diff --git a/cmpcj/src/de/schwarzrot/media/domain/AbstractMediaNode.java b/cmpcj/src/de/schwarzrot/media/domain/AbstractMediaNode.java new file mode 100644 index 0000000..573726c --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/AbstractMediaNode.java @@ -0,0 +1,249 @@ +/** + * ======================== legal notice ====================== + * + * File: AbstractMediaNode.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +import java.io.File; +import java.io.Serializable; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.util.Map; +import java.util.TreeMap; + + +public abstract class AbstractMediaNode implements Serializable, Comparable<AbstractMediaNode> { + public static final String FORMAT_PROPERTY = "format"; + public static final String NAME_PROPERTY = "name"; + public static final String PATH_PROPERTY = "path"; + public static final String TYPE_PROPERTY = "type"; + public static final String SEARCH_PROPERTY = "search"; + private static final long serialVersionUID = 713L; + public enum SupportedMediaType { + Genre, // + Audio, // + Movie, IMovie, DVDImage, IDVDImage, // + LegacyVdrRecording, ILegacyVdrRecording, VdrRecording, IVdrRecording, // + Picture, // + Unknown + } + + + protected AbstractMediaNode(AbstractMediaNode parent, SupportedMediaType type, String mimeType, File path) { + properties = new TreeMap<String, Object>(); + setParent(parent); + setType(type); + setMimeType(mimeType); + setRealPath(path); + originalPath = realPath; + } + + + @Override + public int compareTo(AbstractMediaNode o) { + if (o == null) + return -1; + + if (this != o) { + int rv = type.ordinal() - o.getType().ordinal(); + + if (rv == 0) + rv = getName().compareToIgnoreCase(o.getName()); + + return rv; + } + return 0; + } + + + public String getFormat() { + return format; + } + + + public String getMimeType() { + return mimeType; + } + + + public String getName() { + return name; + } + + + public File getOriginalPath() { + return originalPath; + } + + + public AbstractMediaNode getParent() { + return parent; + } + + + public Map<String, Object> getProperties() { + return properties; + } + + + public File getRealPath() { + return realPath; + } + + + public String getSearch() { + return search; + } + + + public SupportedMediaType getType() { + return type; + } + + + public URI getURI() { + return uri; + } + + + public void setFormat(String format) { + this.format = format; + properties.put(FORMAT_PROPERTY, format); + } + + + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + + public void setName(String name) { + this.name = name; + properties.put(NAME_PROPERTY, name); + } + + + public void setParent(AbstractMediaNode parent) { + if ((this.parent = parent) != null) + refresh(); + } + + + public void setPath(String path) { + if (uri == null) { + try { + // properties.put(PATH_PROPERTY, path); + uri = new URI(path); + properties.put(PATH_PROPERTY, uri.toString()); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + try { + File tmp = new File(URLDecoder.decode(path, "UTF-8")); + + if (path != null && originalPath == null) + originalPath = tmp; + setRealPath(tmp); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + + public void setProperty(String key, Object value) { + properties.put(key, value); + } + + + public void setRealPath(File realPath) { + this.realPath = realPath; + if (name == null && realPath != null) + setName(realPath.getName()); + } + + + public void setSearch(String search) { + this.search = search; + properties.put(SEARCH_PROPERTY, search); + } + + + public void setType(int type) { + if (type == SupportedMediaType.Audio.ordinal()) + this.type = SupportedMediaType.Audio; + else if (type == SupportedMediaType.Movie.ordinal()) + this.type = SupportedMediaType.Movie; + else if (type == SupportedMediaType.IMovie.ordinal()) + this.type = SupportedMediaType.IMovie; + else if (type == SupportedMediaType.DVDImage.ordinal()) + this.type = SupportedMediaType.DVDImage; + else if (type == SupportedMediaType.IDVDImage.ordinal()) + this.type = SupportedMediaType.IDVDImage; + else if (type == SupportedMediaType.LegacyVdrRecording.ordinal()) + this.type = SupportedMediaType.LegacyVdrRecording; + else if (type == SupportedMediaType.ILegacyVdrRecording.ordinal()) + this.type = SupportedMediaType.ILegacyVdrRecording; + else if (type == SupportedMediaType.VdrRecording.ordinal()) + this.type = SupportedMediaType.VdrRecording; + else if (type == SupportedMediaType.IVdrRecording.ordinal()) + this.type = SupportedMediaType.IVdrRecording; + else if (type == SupportedMediaType.Picture.ordinal()) + this.type = SupportedMediaType.Picture; + else + throw new EnumConstantNotPresentException(SupportedMediaType.class, "unknown ordinal #" + type); + properties.put(TYPE_PROPERTY, this.type); + } + + + @Override + public String toString() { + return getName(); + } + + + protected void refresh() { + if (parent != null && realPath != null) + realPath = new File(parent.getRealPath(), realPath.getName()); + } + + + protected void setType(SupportedMediaType type) { + this.type = type; + properties.put(TYPE_PROPERTY, this.type); + } + + private File realPath; + private File originalPath; + private URI uri; + private SupportedMediaType type; + private AbstractMediaNode parent; + private String name; + private String mimeType; + private String search; + private String format; + private Map<String, Object> properties; +} diff --git a/cmpcj/src/de/schwarzrot/media/domain/Audio.java b/cmpcj/src/de/schwarzrot/media/domain/Audio.java new file mode 100644 index 0000000..7e3bf20 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/Audio.java @@ -0,0 +1,72 @@ +/** + * ======================== legal notice ====================== + * + * File: Audio.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + + +public class Audio extends Media { + private static final long serialVersionUID = 713L; + private static final Map<String, String> knownExtensions; + + + public Audio(Genre parent, File path, String mimeType) { + super(parent, SupportedMediaType.Audio, mimeType, path); + } + + + public static String getContentType(String extension) { + return knownExtensions.get(extension); + } + + + public static boolean isSupportedExtension(String extension) { + return knownExtensions.containsKey(extension); + } + + static { + knownExtensions = new HashMap<String, String>(); + + knownExtensions.put("aac", "audio/aac"); + knownExtensions.put("aif", "audio/x-aiff"); + knownExtensions.put("aiff", "audio/x-aiff"); + knownExtensions.put("aifc", "audio/x-aiff"); + knownExtensions.put("au", "audio/x-au"); + knownExtensions.put("fla", "audio/flac"); + knownExtensions.put("flac", "audio/flac"); + knownExtensions.put("oga", "audio/ogg"); + knownExtensions.put("ogg", "audio/ogg"); + knownExtensions.put("mka", "audio/x-matroska"); + knownExtensions.put("mp3", "audio/mpeg"); + knownExtensions.put("mp4", "audio/x-mpeg4"); + knownExtensions.put("m4a", "audio/x-m4"); + knownExtensions.put("mpp", "audio/x-musepack"); + knownExtensions.put("ram", "audio/x-realaudio"); + } +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/domain/Config.java b/cmpcj/src/de/schwarzrot/media/domain/Config.java index f803811..d273972 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/domain/Config.java +++ b/cmpcj/src/de/schwarzrot/media/domain/Config.java @@ -2,7 +2,7 @@ * ======================== legal notice ====================== * * File: Config.java - * Created: + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,7 +23,7 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.domain; +package de.schwarzrot.media.domain; import java.util.ArrayList; @@ -49,25 +49,80 @@ public class Config { } + public int getMainHeight() { + return mainHeight; + } + + + public int getMainWidth() { + return mainWidth; + } + + public Map<Media.SupportedMediaType, PlayerDefinition> getPlayerMap() { return playerMap; } + public int getPosX() { + return posX; + } + + + public int getPosY() { + return posY; + } + + + public boolean isDebug() { + return debug; + } + + public void putPlayer(Media.SupportedMediaType type, PlayerDefinition pd) { playerMap.put(type, pd); } + public void setDebug(boolean debug) { + this.debug = debug; + } + + public void setKnownServers(List<MediaServer> knownServers) { this.knownServers = knownServers; } + public void setMainHeight(int mainHeight) { + this.mainHeight = mainHeight; + } + + + public void setMainWidth(int mainWidth) { + this.mainWidth = mainWidth; + } + + public void setPlayerMap(Map<Media.SupportedMediaType, PlayerDefinition> playerMap) { this.playerMap = playerMap; } + + public void setPosX(int posX) { + this.posX = posX; + } + + + public void setPosY(int posY) { + this.posY = posY; + } + private List<MediaServer> knownServers; private Map<Media.SupportedMediaType, PlayerDefinition> playerMap; + private boolean debug; + private int posX; + private int posY; + private int mainWidth; + private int mainHeight; } diff --git a/cmpcj/src/de/schwarzrot/media/domain/DVDImage.java b/cmpcj/src/de/schwarzrot/media/domain/DVDImage.java new file mode 100644 index 0000000..ff5451a --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/DVDImage.java @@ -0,0 +1,47 @@ +/** + * ======================== legal notice ====================== + * + * File: DVDImage.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +import java.io.File; + + +public class DVDImage extends Movie { + private static final long serialVersionUID = 713L; + private static final String DVDContentType = "video/mpeg"; + private static final String BASE_DIR = "VIDEO_TS"; + private static final String KEY_FILE = "VIDEO_TS.IFO"; + + + public DVDImage(Genre parent, File path) { + super(parent, SupportedMediaType.DVDImage, DVDContentType, path); + } + + + public static boolean isKeyFile(File file2Check) { + return file2Check.getName().equals(KEY_FILE) && file2Check.getParentFile().getName().equals(BASE_DIR); + } +} diff --git a/cmpcj/src/de/schwarzrot/media/domain/Genre.java b/cmpcj/src/de/schwarzrot/media/domain/Genre.java new file mode 100644 index 0000000..5bbb463 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/Genre.java @@ -0,0 +1,121 @@ +/** + * ======================== legal notice ====================== + * + * File: Genre.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + + +public class Genre extends AbstractMediaNode { + private static final long serialVersionUID = 713L; + private static final String MIME_TYPE = "text/plain"; + + + public Genre(File path) { + this(null, path); + } + + + public Genre(Genre parent, File path) { + super(parent, SupportedMediaType.Genre, MIME_TYPE, path); + mediaList = new ArrayList<Media>(); + children = new ArrayList<Genre>(); + if (parent != null) + parent.addGenre(this); + } + + + public void addGenre(Genre g) { + children.add(g); + } + + + public void addMedia(Media m) { + mediaList.add(m); + } + + + public List<Genre> getChildren() { + return children; + } + + + public List<Media> getMediaList() { + return mediaList; + } + + + public void removeGenre(Genre g) { + children.remove(g); + } + + + public void removeMedia(Media m) { + mediaList.remove(m); + } + + + public void setChildren(List<Genre> children) { + this.children = children; + } + + + public void setMediaList(List<Media> mediaList) { + this.mediaList = mediaList; + } + + + public void setParent(Genre parent) { + Genre oldParent = (Genre) getParent(); + + super.setParent(parent); + if (oldParent != null) + oldParent.removeGenre(this); + parent.addGenre(this); + } + + + @Override + public String toString() { + return getName(); + } + + + public void update() { + // instances has moved, so all children and media members must be updated + for (Genre g : children) { + g.refresh(); + g.update(); + } + for (Media m : mediaList) + m.refresh(); + } + + private List<Media> mediaList; + private List<Genre> children; +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaComparator.java b/cmpcj/src/de/schwarzrot/media/domain/LegacyVdrRecording.java index a719032..b98688f 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaComparator.java +++ b/cmpcj/src/de/schwarzrot/media/domain/LegacyVdrRecording.java @@ -1,8 +1,8 @@ /** * ======================== legal notice ====================== * - * File: MediaComparator.java - * Created: + * File: LegacyVdrRecording.java + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,18 +23,17 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.util; +package de.schwarzrot.media.domain; -import java.util.Comparator; -import de.schwarzrot.cmpc.domain.Media; +import java.io.File; -public class MediaComparator implements Comparator<Media> { - @Override - public int compare(Media a, Media b) { - if (a.getType() == b.getType()) - return a.getName().compareToIgnoreCase(b.getName()); - return a.getType().ordinal() - b.getType().ordinal(); +public class LegacyVdrRecording extends VdrRecording { + private static final long serialVersionUID = 713L; + + + public LegacyVdrRecording(Genre parent, File path) { + super(parent, SupportedMediaType.LegacyVdrRecording, DEFAULT_MIME_TYPE, path); } } diff --git a/cmpcj/src/de/schwarzrot/media/domain/Media.java b/cmpcj/src/de/schwarzrot/media/domain/Media.java new file mode 100644 index 0000000..6cc4aac --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/Media.java @@ -0,0 +1,55 @@ +/** + * ======================== legal notice ====================== + * + * File: Media.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +import java.io.File; + + +public class Media extends AbstractMediaNode { + private static final long serialVersionUID = 713L; + + + public Media() { + super(null, SupportedMediaType.Unknown, null, null); + } + + + public Media(Genre parent, SupportedMediaType type, String mimeType, File path) { + super(parent, type, mimeType, path); + parent.addMedia(this); + } + + + public void setParent(Genre parent) { + Genre oldParent = (Genre) getParent(); + + super.setParent(parent); + if (oldParent != null) + oldParent.removeMedia(this); + parent.addMedia(this); + } +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/domain/MediaServer.java b/cmpcj/src/de/schwarzrot/media/domain/MediaServer.java index e6f2683..a8968c4 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/domain/MediaServer.java +++ b/cmpcj/src/de/schwarzrot/media/domain/MediaServer.java @@ -2,7 +2,7 @@ * ======================== legal notice ====================== * * File: MediaServer.java - * Created: + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,7 +23,7 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.domain; +package de.schwarzrot.media.domain; public class MediaServer { @@ -46,6 +46,12 @@ public class MediaServer { this.port = port; } + + @Override + public String toString() { + return hostName; + } + private String hostName; private int port; } diff --git a/cmpcj/src/de/schwarzrot/media/domain/MediaType.java b/cmpcj/src/de/schwarzrot/media/domain/MediaType.java new file mode 100644 index 0000000..b571090 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/MediaType.java @@ -0,0 +1,55 @@ +/** + * ======================== legal notice ====================== + * + * File: MediaType.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +public class MediaType { + public static final String NAME_PROPERTY = "name"; + public static final String START_PROPERTY = "start"; + + + public String getName() { + return name; + } + + + public long getStart() { + return start; + } + + + public void setName(String name) { + this.name = name; + } + + + public void setStart(long start) { + this.start = start; + } + + private String name; + private long start; +} diff --git a/cmpcj/src/de/schwarzrot/media/domain/Movie.java b/cmpcj/src/de/schwarzrot/media/domain/Movie.java new file mode 100644 index 0000000..1191da3 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/Movie.java @@ -0,0 +1,88 @@ +/** + * ======================== legal notice ====================== + * + * File: Movie.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + + +public class Movie extends Media { + private static final long serialVersionUID = 713L; + private static final Map<String, String> knownExtensions; + + + public Movie(Genre parent, File path, String mimeType) { + this(parent, SupportedMediaType.Movie, mimeType, path); + } + + + public Movie(Genre parent, SupportedMediaType type, String mimeType, File path) { + super(parent, type, mimeType, path); + } + + + public boolean isInterlaced() { + return interlaced; + } + + + public void setInterlaced(boolean interlaced) { + this.interlaced = interlaced; + setType(getType().ordinal() + 1); + } + + + public static String getContentType(String extension) { + return knownExtensions.get(extension); + } + + + public static boolean isSupportedExtension(String extension) { + return knownExtensions.containsKey(extension); + } + + boolean interlaced; + static { + knownExtensions = new HashMap<String, String>(); + + knownExtensions.put("aac", "audio/aac"); + knownExtensions.put("asd", "video/x-ms-asf"); + knownExtensions.put("asf", "video/x-ms-asf"); + knownExtensions.put("avi", "video/x-msvideo"); + knownExtensions.put("dv", "video/x-dv"); + knownExtensions.put("flv", "video/x-flv"); + knownExtensions.put("gl", "video/x-gl"); + knownExtensions.put("iso", "application/x-iso9660-image"); + knownExtensions.put("ogv", "video/ogg"); + knownExtensions.put("mkv", "video/x-matroska"); + knownExtensions.put("mov", "video/quicktime"); + knownExtensions.put("mpg", "video/mpeg"); + knownExtensions.put("mpeg", "video/mpeg"); + knownExtensions.put("swf", "application/x-shockwave-flash"); + } +} diff --git a/cmpcj/src/de/schwarzrot/media/domain/Picture.java b/cmpcj/src/de/schwarzrot/media/domain/Picture.java new file mode 100644 index 0000000..4d0cab9 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/Picture.java @@ -0,0 +1,78 @@ +/** + * ======================== legal notice ====================== + * + * File: Picture.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + + +public class Picture extends Media { + private static final long serialVersionUID = 713L; + private static final Map<String, String> knownExtensions; + + + public Picture(Genre parent, File path, String mimeType) { + super(parent, SupportedMediaType.Picture, mimeType, path); + } + + + public static String getContentType(String extension) { + return knownExtensions.get(extension); + } + + + public static boolean isSupportedExtension(String extension) { + return knownExtensions.containsKey(extension); + } + + static { + knownExtensions = new HashMap<String, String>(); + + knownExtensions.put("aac", "audio/aac"); + knownExtensions.put("bmp", "image/x-windows-bmp"); + knownExtensions.put("gif", "image/gif"); + knownExtensions.put("jff", "image/jpeg"); + knownExtensions.put("jfif", "image/jpeg"); + knownExtensions.put("jif", "image/jpeg"); + knownExtensions.put("jp2", "image/jp2"); + knownExtensions.put("jpe", "image/jpeg"); + knownExtensions.put("jpeg", "image/jpeg"); + knownExtensions.put("jpg", "image/jpeg"); + knownExtensions.put("jpm", "image/jpm"); + knownExtensions.put("jpx", "image/jpx"); + knownExtensions.put("pbm", "image/x-portable-bitmap"); + knownExtensions.put("pct", "image/x-pict"); + knownExtensions.put("pcx", "image/x-pcx"); + knownExtensions.put("png", "image/png"); + knownExtensions.put("pnm", "image/x-portable-anymap"); + knownExtensions.put("ppm", "image/x-portable-pixmap"); + knownExtensions.put("qti", "image/quicktime"); + knownExtensions.put("ras", "image/x-cmu-raster"); + knownExtensions.put("rgb", "image/x-rgb"); + } +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/domain/PlayList.java b/cmpcj/src/de/schwarzrot/media/domain/PlayList.java index e1aa7d2..ec7a393 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/domain/PlayList.java +++ b/cmpcj/src/de/schwarzrot/media/domain/PlayList.java @@ -2,7 +2,7 @@ * ======================== legal notice ====================== * * File: PlayList.java - * Created: + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,13 +23,18 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.domain; +package de.schwarzrot.media.domain; import java.util.List; public class PlayList { + public static final String TOTAL_PROPERTY = "total"; + public static final String RESULTS_PROPERTY = "results"; + public static final String TYPES_PROPERTY = "types"; + + public List<Media> getResults() { return results; } diff --git a/cmpcj/src/de/schwarzrot/cmpc/domain/PlayerDefinition.java b/cmpcj/src/de/schwarzrot/media/domain/PlayerDefinition.java index 5bc4df0..05b9bbc 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/domain/PlayerDefinition.java +++ b/cmpcj/src/de/schwarzrot/media/domain/PlayerDefinition.java @@ -2,7 +2,7 @@ * ======================== legal notice ====================== * * File: PlayerDefinition.java - * Created: + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,7 +23,7 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.domain; +package de.schwarzrot.media.domain; import java.util.ArrayList; @@ -41,25 +41,75 @@ public class PlayerDefinition { } + public String getCommandLine() { + if (commandLine == null) + assembleCommandLine(); + return commandLine; + } + + public String getExecutable() { return executable; } + public AbstractMediaNode.SupportedMediaType getMediaType() { + return mediaType; + } + + public List<String> getParameters() { return parameters; } + public void setCommandLine(String commandLine) { + this.commandLine = commandLine; + decodeCommandLine(); + } + + public void setExecutable(String executable) { this.executable = executable; + assembleCommandLine(); + } + + + public void setMediaType(AbstractMediaNode.SupportedMediaType mediaType) { + this.mediaType = mediaType; } public void setParameters(List<String> parameters) { this.parameters = parameters; + assembleCommandLine(); + } + + + protected void assembleCommandLine() { + if (executable == null || parameters == null || parameters.size() < 1) + return; + StringBuilder sb = new StringBuilder(executable); + + for (String p : parameters) { + sb.append(" ").append(p); + } + commandLine = sb.toString(); + } + + + protected void decodeCommandLine() { + String[] parts = commandLine.split("\\s+"); + + executable = parts[0]; + parameters.clear(); + for (int i = 1; i < parts.length; ++i) { + parameters.add(parts[i]); + } } + private AbstractMediaNode.SupportedMediaType mediaType; private String executable; + private String commandLine; private List<String> parameters; } diff --git a/cmpcj/src/de/schwarzrot/media/domain/VdrRecording.java b/cmpcj/src/de/schwarzrot/media/domain/VdrRecording.java new file mode 100644 index 0000000..b11cb03 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/domain/VdrRecording.java @@ -0,0 +1,67 @@ +/** + * ======================== legal notice ====================== + * + * File: VdrRecording.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.domain; + + +import java.io.File; + + +public class VdrRecording extends Movie { + private static final long serialVersionUID = 713L; + protected static final String DEFAULT_MIME_TYPE = "video/mpeg"; + protected static final String KEY_FILE = "00001.vdr"; + + + public VdrRecording(Genre parent, File path) { + this(parent, SupportedMediaType.VdrRecording, DEFAULT_MIME_TYPE, path); + } + + + protected VdrRecording(Genre parent, SupportedMediaType type, String mimeType, File path) { + super(parent, type, mimeType, path); + } + + + @Override + public String getName() { + return getRealPath().getParentFile().getName(); + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(getName()); + + sb.append(" (").append(super.getName()).append(")"); + + return sb.toString(); + } + + + public static boolean isKeyFile(File file2Check) { + return file2Check.getName().equals(KEY_FILE); + } +} diff --git a/cmpcj/src/de/schwarzrot/media/service/DataManager.java b/cmpcj/src/de/schwarzrot/media/service/DataManager.java new file mode 100644 index 0000000..3d6940f --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/service/DataManager.java @@ -0,0 +1,152 @@ +/** + * ======================== legal notice ====================== + * + * File: DataManager.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.service; + + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; +import javax.swing.SwingUtilities; +import javax.swing.tree.DefaultMutableTreeNode; +import ca.odell.glazedlists.EventList; +import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.base.util.SuccessHandler; +import de.schwarzrot.media.domain.AbstractMediaNode; +import de.schwarzrot.media.domain.Genre; +import de.schwarzrot.media.domain.Media; +import de.schwarzrot.media.util.ElementConsumer; +import de.schwarzrot.media.util.ListLoader; + + +public class DataManager implements Runnable, ElementConsumer<Media> { + public DataManager(File input) { + this.input = input; + nodeCache = new HashMap<File, DefaultMutableTreeNode>(); + } + + + @Override + public void consumeElement(Media m) { + if (m.getParent() == null) + m.setParent(getGenre(m.getRealPath().getParentFile())); + + mediaList.getReadWriteLock().writeLock().lock(); + mediaList.add(m); + mediaList.getReadWriteLock().writeLock().unlock(); + } + + + public void load(DefaultMutableTreeNode root, EventList<Media> mediaList, SuccessHandler successHandler) { + Thread backgroundThread = new Thread(this); + + nodeCache.clear(); + resultHandler = successHandler; + rootNode = root; + nodeCache.put(new File("/"), rootNode); + this.mediaList = mediaList; + backgroundThread.setName("load media list"); + backgroundThread.setDaemon(true); + backgroundThread.start(); + } + + + @Override + public void run() { + @SuppressWarnings("unchecked") + ListLoader<Media> ll = ApplicationServiceProvider.getService(ListLoader.class); + + try { + long[] info = ll.loadFirst(this); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + resultHandler.handleSuccess(); // feedback to main thread + } + }); + ll.loadRest(info, this); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + resultHandler.handleSuccess(); // feedback to main thread + } + }); + } catch (final Throwable t) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + resultHandler.handleFailure(t); // feedback to main thread + } + }); + } + } + + + protected void createGenre(File path) { + File tmp = path; + Stack<File> unknownGenres = new Stack<File>(); + + while (tmp != null && !nodeCache.containsKey(tmp)) { + unknownGenres.push(tmp); + tmp = tmp.getParentFile(); + } + DefaultMutableTreeNode treeNode = tmp == null ? rootNode : nodeCache.get(tmp); + AbstractMediaNode media = (AbstractMediaNode) treeNode.getUserObject(); + DefaultMutableTreeNode subNode = null; + Genre g = null; + + if (media != null && media instanceof Genre) + g = (Genre) media; + + while (unknownGenres.size() > 0) { + tmp = unknownGenres.pop(); + g = new Genre(g, tmp); + subNode = new DefaultMutableTreeNode(g); + nodeCache.put(tmp, subNode); + treeNode.add(subNode); + treeNode = subNode; + } + } + + + protected Genre getGenre(File path) { + if (!nodeCache.containsKey(path)) + createGenre(path); + DefaultMutableTreeNode n = nodeCache.get(path); + AbstractMediaNode rv = (AbstractMediaNode) n.getUserObject(); + + if (rv instanceof Genre) + return (Genre) rv; + return null; + } + + @SuppressWarnings("unused") + private File input; + private SuccessHandler resultHandler; + private DefaultMutableTreeNode rootNode; + private EventList<Media> mediaList; + private Map<File, DefaultMutableTreeNode> nodeCache; +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MediaExecutor.java b/cmpcj/src/de/schwarzrot/media/service/MediaExecutor.java index 8cdea21..0cd6fe7 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MediaExecutor.java +++ b/cmpcj/src/de/schwarzrot/media/service/MediaExecutor.java @@ -2,7 +2,7 @@ * ======================== legal notice ====================== * * File: MediaExecutor.java - * Created: + * Created: 13. June 2012, 04:57 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: cmpc - a java frontend (client) part of compound media player * uses external players to play the media @@ -23,14 +23,15 @@ * * -------------------------------------------------------------- */ -package de.schwarzrot.cmpc.util; +package de.schwarzrot.media.service; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JTable; import ca.odell.glazedlists.EventList; -import de.schwarzrot.cmpc.domain.Media; +import de.schwarzrot.control.client.MediaClientExecutor; +import de.schwarzrot.media.domain.Media; public class MediaExecutor extends MouseAdapter { diff --git a/cmpcj/src/de/schwarzrot/media/service/MediaFactory.java b/cmpcj/src/de/schwarzrot/media/service/MediaFactory.java new file mode 100644 index 0000000..ff31822 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/service/MediaFactory.java @@ -0,0 +1,137 @@ +/** + * ======================== legal notice ====================== + * + * File: MediaFactory.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.service; + + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; +import de.schwarzrot.media.domain.AbstractMediaNode; +import de.schwarzrot.media.domain.Audio; +import de.schwarzrot.media.domain.DVDImage; +import de.schwarzrot.media.domain.Genre; +import de.schwarzrot.media.domain.LegacyVdrRecording; +import de.schwarzrot.media.domain.Media; +import de.schwarzrot.media.domain.Movie; +import de.schwarzrot.media.domain.Picture; +import de.schwarzrot.media.domain.VdrRecording; + + +public class MediaFactory { + public MediaFactory(File baseDir) { + this.baseDir = baseDir; + prefix = baseDir.getAbsolutePath(); + mediaCache = new HashMap<File, AbstractMediaNode>(); + mediaCache.put(baseDir, new Genre(baseDir)); + } + + + //TODO: + // here we can't rely on file system information. + // may be we got files from remote system ... + // so instead to use lookahead for multifile movies, we need to go back + // from keyfiles + public Media createMedia(File mayBeMedia) { + if (!mayBeMedia.getAbsolutePath().startsWith(prefix)) + return null; + String xt = mayBeMedia.getName().substring(mayBeMedia.getName().lastIndexOf(".") + 1); + Genre parent = null; + Media rv = null; + + if (VdrRecording.isKeyFile(mayBeMedia)) { + parent = getGenre(mayBeMedia.getParentFile().getParentFile().getParentFile()); + + rv = new VdrRecording(parent, mayBeMedia.getParentFile()); + } else if (LegacyVdrRecording.isKeyFile(mayBeMedia)) { + parent = getGenre(mayBeMedia.getParentFile().getParentFile().getParentFile()); + + rv = new LegacyVdrRecording(parent, mayBeMedia.getParentFile()); + } else if (DVDImage.isKeyFile(mayBeMedia)) { + parent = getGenre(mayBeMedia.getParentFile().getParentFile().getParentFile()); + + rv = new DVDImage(parent, mayBeMedia.getParentFile().getParentFile()); + } else if (Movie.isSupportedExtension(xt)) { + parent = getGenre(mayBeMedia.getParentFile()); + rv = new Movie(parent, mayBeMedia, Movie.getContentType(xt)); + } else if (Audio.isSupportedExtension(xt)) { + parent = getGenre(mayBeMedia.getParentFile()); + rv = new Audio(parent, mayBeMedia, Audio.getContentType(xt)); + } else if (Picture.isSupportedExtension(xt)) { + parent = getGenre(mayBeMedia.getParentFile()); + rv = new Picture(parent, mayBeMedia, Picture.getContentType(xt)); + } + if (rv != null) + mediaCache.put(mayBeMedia, rv); + + return rv; + } + + + public Map<File, AbstractMediaNode> getCache() { + return mediaCache; + } + + + public Genre getGenre(File mayBeGenre) { + if (!mayBeGenre.isDirectory()) + return null; + + if (!mediaCache.containsKey(mayBeGenre)) + createGenre(mayBeGenre); + AbstractMediaNode rv = mediaCache.get(mayBeGenre); + + if (rv instanceof Genre) + return (Genre) rv; + return null; + } + + + protected void createGenre(File shouldBeGenre) { + File tmp = shouldBeGenre; + Stack<File> unknownGenres = new Stack<File>(); + + while (tmp != null && !mediaCache.containsKey(tmp)) { + unknownGenres.push(tmp); + tmp = tmp.getParentFile(); + } + AbstractMediaNode node = mediaCache.get(tmp != null ? tmp : baseDir); + Genre g = null; + + if (node != null && node instanceof Genre) + g = (Genre) node; + + while (unknownGenres.size() > 0) { + tmp = unknownGenres.pop(); + g = new Genre(g, tmp); + mediaCache.put(tmp, g); + } + } + + private Map<File, AbstractMediaNode> mediaCache; + private File baseDir; + private String prefix; +} diff --git a/cmpcj/src/de/schwarzrot/media/util/ElementConsumer.java b/cmpcj/src/de/schwarzrot/media/util/ElementConsumer.java new file mode 100644 index 0000000..e50894d --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/util/ElementConsumer.java @@ -0,0 +1,31 @@ +/** + * ======================== legal notice ====================== + * + * File: ElementConsumer.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.util; + + +public interface ElementConsumer<E> { + public void consumeElement(E element); +} diff --git a/cmpcj/src/de/schwarzrot/media/util/ListLoader.java b/cmpcj/src/de/schwarzrot/media/util/ListLoader.java new file mode 100644 index 0000000..5542cf2 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/util/ListLoader.java @@ -0,0 +1,34 @@ +/** + * ======================== legal notice ====================== + * + * File: ListLoader.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.util; + + +public interface ListLoader<E> { + public long[] loadFirst(ElementConsumer<E> consumer); + + + public long loadRest(long[] listInfo, ElementConsumer<E> consumer); +} diff --git a/cmpcj/src/de/schwarzrot/cmpc/util/MedialistParser.java b/cmpcj/src/de/schwarzrot/media/util/MedialistParser.java index 4b46a13..756c795 100644 --- a/cmpcj/src/de/schwarzrot/cmpc/util/MedialistParser.java +++ b/cmpcj/src/de/schwarzrot/media/util/MedialistParser.java @@ -1,16 +1,39 @@ -package de.schwarzrot.cmpc.util; +/** + * ======================== legal notice ====================== + * + * File: MedialistParser.java + * Created: 13. June 2012, 04:57 + * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> + * Project: cmpc - a java frontend (client) part of compound media player + * uses external players to play the media + * + * CMP - compound media player + * + * is a client/server mediaplayer intended to play any media from any workstation + * without the need to export or mount shares. cmps is an easy to use backend + * with a (ready to use) HTML-interface. Additionally the backend supports + * authentication via HTTP-digest authorization. + * cmpc is a client with vdr-like osd-menues. + * + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! + * published under Creative Commons by-sa + * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * + * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * + * -------------------------------------------------------------- + */ +package de.schwarzrot.media.util; -import java.io.File; -import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import com.google.gson.stream.JsonReader; -import de.schwarzrot.cmpc.domain.Media; -import de.schwarzrot.cmpc.domain.MediaType; -import de.schwarzrot.cmpc.domain.PlayList; +import de.schwarzrot.media.domain.Media; +import de.schwarzrot.media.domain.MediaType; +import de.schwarzrot.media.domain.PlayList; public class MedialistParser { @@ -34,28 +57,6 @@ public class MedialistParser { } - // @Test - public void testJSonParsing() { - FileInputStream fis = null; - - try { - fis = new FileInputStream(new File("test.json")); - parseListChunk(fis); - fis.close(); - fis = null; - } catch (Throwable t) { - t.printStackTrace(); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (Throwable t) { - } - } - } - } - - protected Media readMedia(JsonReader reader) { Media rv = new Media(); @@ -64,20 +65,16 @@ public class MedialistParser { while (reader.hasNext()) { String name = reader.nextName(); - if ("name".equals(name)) { + if (Media.NAME_PROPERTY.equals(name)) { rv.setName(reader.nextString()); - } else if ("type".equals(name)) { + } else if (Media.TYPE_PROPERTY.equals(name)) { rv.setType(reader.nextInt()); - } else if ("format".equals(name)) { + } else if (Media.FORMAT_PROPERTY.equals(name)) { rv.setFormat(reader.nextString()); - } else if ("width".equals(name)) { - rv.setWidth(reader.nextInt()); - } else if ("height".equals(name)) { - rv.setHeight(reader.nextInt()); - } else if ("path".equals(name)) { + } else if (Media.PATH_PROPERTY.equals(name)) { rv.setPath(reader.nextString()); } else { - reader.skipValue(); + rv.setProperty(name, reader.nextString()); } } reader.endObject(); @@ -112,9 +109,9 @@ public class MedialistParser { while (reader.hasNext()) { String name = reader.nextName(); - if ("name".equals(name)) { + if (MediaType.NAME_PROPERTY.equals(name)) { rv.setName(reader.nextString()); - } else if ("start".equals(name)) { + } else if (MediaType.START_PROPERTY.equals(name)) { rv.setStart(reader.nextLong()); } else { reader.skipValue(); @@ -136,11 +133,11 @@ public class MedialistParser { while (reader.hasNext()) { String name = reader.nextName(); - if ("total".equals(name)) { + if (PlayList.TOTAL_PROPERTY.equals(name)) { rv.setTotal(reader.nextLong()); - } else if ("types".equals(name)) { + } else if (PlayList.TYPES_PROPERTY.equals(name)) { rv.setTypes(readTypeArray(reader)); - } else if ("results".equals(name)) { + } else if (PlayList.RESULTS_PROPERTY.equals(name)) { rv.setResults(readMediaArray(reader)); } else { reader.skipValue(); |