summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmpcj/.classpath6
-rw-r--r--cmpcj/lib/docking-frames-common-1.1.1-SNAPSHOT.jarbin0 -> 807029 bytes
-rw-r--r--cmpcj/lib/docking-frames-core-1.1.1-SNAPSHOT.jarbin0 -> 2327294 bytes
-rw-r--r--cmpcj/lib/docking-frames.license504
-rw-r--r--cmpcj/lib/glazedlists.license (renamed from cmpcj/lib/license.txt)0
-rw-r--r--cmpcj/lib/gson.license203
-rw-r--r--cmpcj/res/de/schwarzrot/control/app/lang/images.properties26
-rw-r--r--cmpcj/res/de/schwarzrot/control/app/lang/messages.properties76
-rw-r--r--cmpcj/res/de/schwarzrot/control/app/lang/messages_de.properties77
-rw-r--r--cmpcj/src/de/schwarzrot/base/dock/BasicDockable.java75
-rw-r--r--cmpcj/src/de/schwarzrot/base/table/PropertyTableFormat.java86
-rw-r--r--cmpcj/src/de/schwarzrot/base/util/AbstractDialog.java174
-rw-r--r--cmpcj/src/de/schwarzrot/base/util/ActionManager.java61
-rw-r--r--cmpcj/src/de/schwarzrot/base/util/ApplicationServiceProvider.java51
-rw-r--r--cmpcj/src/de/schwarzrot/base/util/CallbackDefinition.java62
-rw-r--r--cmpcj/src/de/schwarzrot/base/util/ImageFactory.java74
-rw-r--r--cmpcj/src/de/schwarzrot/base/util/MessageBundle.java31
-rw-r--r--cmpcj/src/de/schwarzrot/base/util/SuccessHandler.java (renamed from cmpcj/src/de/schwarzrot/cmpc/app/IMediaPlayer.java)24
-rw-r--r--cmpcj/src/de/schwarzrot/cmpc/app/SRMediaPlayer.java190
-rw-r--r--cmpcj/src/de/schwarzrot/cmpc/domain/Media.java141
-rw-r--r--cmpcj/src/de/schwarzrot/cmpc/domain/MediaType.java51
-rw-r--r--cmpcj/src/de/schwarzrot/cmpc/ui/AppSelector.java90
-rw-r--r--cmpcj/src/de/schwarzrot/cmpc/ui/MediaClient.java270
-rw-r--r--cmpcj/src/de/schwarzrot/cmpc/util/MediaListLoader.java124
-rw-r--r--cmpcj/src/de/schwarzrot/cmpc/util/MediaTableFormat.java94
-rw-r--r--cmpcj/src/de/schwarzrot/cmpc/util/MediaTextFilterator.java41
-rw-r--r--cmpcj/src/de/schwarzrot/control/app/AboutDialog.java69
-rw-r--r--cmpcj/src/de/schwarzrot/control/app/CMPCJ.java736
-rw-r--r--cmpcj/src/de/schwarzrot/control/app/CMPMessageBundle.java73
-rw-r--r--cmpcj/src/de/schwarzrot/control/client/CMPClient.java171
-rw-r--r--cmpcj/src/de/schwarzrot/control/client/MediaClientExecutor.java (renamed from cmpcj/src/de/schwarzrot/cmpc/util/MediaClientExecutor.java)6
-rw-r--r--cmpcj/src/de/schwarzrot/control/config/ConfigDialog.java131
-rw-r--r--cmpcj/src/de/schwarzrot/control/config/ConfigFactory.java (renamed from cmpcj/src/de/schwarzrot/cmpc/app/ConfigFactory.java)107
-rw-r--r--cmpcj/src/de/schwarzrot/control/dnd/FilelistTransferable.java72
-rw-r--r--cmpcj/src/de/schwarzrot/control/dnd/ListSelectionSourceTransferHandler.java69
-rw-r--r--cmpcj/src/de/schwarzrot/control/dnd/TreePathTransferable.java74
-rw-r--r--cmpcj/src/de/schwarzrot/control/dnd/TreeSourceAndDestTransferHandler.java207
-rw-r--r--cmpcj/src/de/schwarzrot/control/support/GenreSelector.java46
-rw-r--r--cmpcj/src/de/schwarzrot/control/support/MediaList2TypeList.java (renamed from cmpcj/src/de/schwarzrot/cmpc/util/MediaPool2TypeList.java)13
-rw-r--r--cmpcj/src/de/schwarzrot/control/support/MediaTextFilterator.java41
-rw-r--r--cmpcj/src/de/schwarzrot/control/support/MediaTypeSelector.java (renamed from cmpcj/src/de/schwarzrot/cmpc/util/MediaTypeSelect.java)111
-rw-r--r--cmpcj/src/de/schwarzrot/control/support/MediatypeMatcher.java (renamed from cmpcj/src/de/schwarzrot/cmpc/util/MediaForTypeMatcher.java)15
-rw-r--r--cmpcj/src/de/schwarzrot/control/support/SelectedMedia.java85
-rw-r--r--cmpcj/src/de/schwarzrot/control/support/TreeSelectionFilter.java59
-rw-r--r--cmpcj/src/de/schwarzrot/control/table/MediaTableFormat.java91
-rw-r--r--cmpcj/src/de/schwarzrot/control/table/PlayerDefinitionTableFormat.java114
-rw-r--r--cmpcj/src/de/schwarzrot/control/table/ServerDefinitionTableFormat.java119
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/AbstractMediaNode.java249
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/Audio.java72
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/Config.java (renamed from cmpcj/src/de/schwarzrot/cmpc/domain/Config.java)59
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/DVDImage.java47
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/Genre.java121
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/LegacyVdrRecording.java (renamed from cmpcj/src/de/schwarzrot/cmpc/util/MediaComparator.java)21
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/Media.java55
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/MediaServer.java (renamed from cmpcj/src/de/schwarzrot/cmpc/domain/MediaServer.java)10
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/MediaType.java55
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/Movie.java88
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/Picture.java78
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/PlayList.java (renamed from cmpcj/src/de/schwarzrot/cmpc/domain/PlayList.java)9
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/PlayerDefinition.java (renamed from cmpcj/src/de/schwarzrot/cmpc/domain/PlayerDefinition.java)54
-rw-r--r--cmpcj/src/de/schwarzrot/media/domain/VdrRecording.java67
-rw-r--r--cmpcj/src/de/schwarzrot/media/service/DataManager.java152
-rw-r--r--cmpcj/src/de/schwarzrot/media/service/MediaExecutor.java (renamed from cmpcj/src/de/schwarzrot/cmpc/util/MediaExecutor.java)7
-rw-r--r--cmpcj/src/de/schwarzrot/media/service/MediaFactory.java137
-rw-r--r--cmpcj/src/de/schwarzrot/media/util/ElementConsumer.java31
-rw-r--r--cmpcj/src/de/schwarzrot/media/util/ListLoader.java34
-rw-r--r--cmpcj/src/de/schwarzrot/media/util/MedialistParser.java (renamed from cmpcj/src/de/schwarzrot/cmpc/util/MedialistParser.java)81
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
new file mode 100644
index 0000000..6070a60
--- /dev/null
+++ b/cmpcj/lib/docking-frames-common-1.1.1-SNAPSHOT.jar
Binary files differ
diff --git a/cmpcj/lib/docking-frames-core-1.1.1-SNAPSHOT.jar b/cmpcj/lib/docking-frames-core-1.1.1-SNAPSHOT.jar
new file mode 100644
index 0000000..de3b3a3
--- /dev/null
+++ b/cmpcj/lib/docking-frames-core-1.1.1-SNAPSHOT.jar
Binary files differ
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();