summaryrefslogtreecommitdiffstats
path: root/noatun-plugins/dub
diff options
context:
space:
mode:
Diffstat (limited to 'noatun-plugins/dub')
-rw-r--r--noatun-plugins/dub/AUTHORS1
-rw-r--r--noatun-plugins/dub/BUGS8
-rw-r--r--noatun-plugins/dub/COPYING340
-rw-r--r--noatun-plugins/dub/ChangeLog38
-rw-r--r--noatun-plugins/dub/INSTALL167
-rw-r--r--noatun-plugins/dub/Makefile.am11
-rw-r--r--noatun-plugins/dub/NEWS35
-rw-r--r--noatun-plugins/dub/README22
-rw-r--r--noatun-plugins/dub/TODO20
-rw-r--r--noatun-plugins/dub/configure.in.in4
-rw-r--r--noatun-plugins/dub/design.txt43
-rw-r--r--noatun-plugins/dub/dub.kdevprj198
-rw-r--r--noatun-plugins/dub/dub/Makefile.am20
-rw-r--r--noatun-plugins/dub/dub/dub.cpp641
-rw-r--r--noatun-plugins/dub/dub/dub.h207
-rw-r--r--noatun-plugins/dub/dub/dub.plugin69
-rw-r--r--noatun-plugins/dub/dub/dubapp.cpp98
-rw-r--r--noatun-plugins/dub/dub/dubapp.h83
-rw-r--r--noatun-plugins/dub/dub/dubconfigmodule.cpp125
-rw-r--r--noatun-plugins/dub/dub/dubconfigmodule.h40
-rw-r--r--noatun-plugins/dub/dub/dubplaylist.cpp158
-rw-r--r--noatun-plugins/dub/dub/dubplaylist.h77
-rw-r--r--noatun-plugins/dub/dub/dubplaylistitem.cpp83
-rw-r--r--noatun-plugins/dub/dub/dubplaylistitem.h55
-rw-r--r--noatun-plugins/dub/dub/dubprefs.ui187
-rw-r--r--noatun-plugins/dub/dub/dubui.rc8
-rw-r--r--noatun-plugins/dub/dub/dubview.cpp63
-rw-r--r--noatun-plugins/dub/dub/dubview.h52
-rw-r--r--noatun-plugins/dub/dub/fileselectorwidget.cpp183
-rw-r--r--noatun-plugins/dub/dub/fileselectorwidget.h74
-rw-r--r--noatun-plugins/dub/dub/random.h43
-rw-r--r--noatun-plugins/dub/dub/templates/cpp_template15
-rw-r--r--noatun-plugins/dub/dub/templates/header_template21
33 files changed, 3189 insertions, 0 deletions
diff --git a/noatun-plugins/dub/AUTHORS b/noatun-plugins/dub/AUTHORS
new file mode 100644
index 0000000..debb2b3
--- /dev/null
+++ b/noatun-plugins/dub/AUTHORS
@@ -0,0 +1 @@
+Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>
diff --git a/noatun-plugins/dub/BUGS b/noatun-plugins/dub/BUGS
new file mode 100644
index 0000000..345c920
--- /dev/null
+++ b/noatun-plugins/dub/BUGS
@@ -0,0 +1,8 @@
+open bugs:
+----------
+* closing dub window quits noatun
+* same crash from changing from SPL -> dub
+
+fixed:
+------
+* <mETz> changing from dub -> spl does not close the window
diff --git a/noatun-plugins/dub/COPYING b/noatun-plugins/dub/COPYING
new file mode 100644
index 0000000..37ba36f
--- /dev/null
+++ b/noatun-plugins/dub/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, 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 or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+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 Program or any portion
+of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) 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; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, 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 executable. However, as a
+special exception, the source code 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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+ 5. 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 Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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 to
+this License.
+
+ 7. 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 Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), 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 Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; 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.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/noatun-plugins/dub/ChangeLog b/noatun-plugins/dub/ChangeLog
new file mode 100644
index 0000000..452cb3a
--- /dev/null
+++ b/noatun-plugins/dub/ChangeLog
@@ -0,0 +1,38 @@
+2003-03-02 Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>
+ * fix: use a local copy of KFileItem taken from list view
+ Can't trust KDirOperator not to destruct it.
+
+2003-02-26 Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>
+ * implement shuffle/linear sequencer
+ - use libc random number generator, and init seed with time()
+ * implement shuffle/recursive sequencer
+ - use a simple minded selection-randomizer in dir tree
+ * add a wrapper for libc random functions
+
+2003-02-24 Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>
+ * implement Linear_Recursive sequencer
+ * disable unimplemented play options
+ * fix: open debugging early termination in playlist getFirst
+ * Recursive_Seq:
+ - code stabilized
+ - greatly simplify traversal code
+ - iterators suck (see DubInfo::past_begin)
+ - restart preorder traversal if finished
+ - add prev_preorder traversal
+ - fix: preorder traversal, there were a quite a few obscure bugs
+ - fix: remove code to skip from basic traversal class
+ - verbose debug logging
+
+2003-02-23 Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>
+ * Recursive_Seq:
+ - fix: compare recursion root change too with canonical dirs
+ - fix: avoid reading parent directories. I incidentally had this
+ backwards, reading only parent dirs.
+ - implement preorder traversal (next only)
+ - debugging output
+ - partially fix iteration of dirs and files in recursive sequencer
+ - start writing preorder traversal
+ * fix: read config module options
+ * fix: show media home on startup / when changed
+ * remove obsolete file traversal functions
+ * comment out debug output in playlistitem
diff --git a/noatun-plugins/dub/INSTALL b/noatun-plugins/dub/INSTALL
new file mode 100644
index 0000000..02a4a07
--- /dev/null
+++ b/noatun-plugins/dub/INSTALL
@@ -0,0 +1,167 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes a while. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 4. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/noatun-plugins/dub/Makefile.am b/noatun-plugins/dub/Makefile.am
new file mode 100644
index 0000000..e7268ab
--- /dev/null
+++ b/noatun-plugins/dub/Makefile.am
@@ -0,0 +1,11 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+
+SUBDIRS = dub
+
+EXTRA_DIST = dub.kdevprj AUTHORS COPYING ChangeLog INSTALL README TODO BUGS
+
+####### kdevelop will overwrite this part!!! (end)############
+# not a GNU package. You can remove this line, if
+# have all needed files, that a GNU package needs
+AUTOMAKE_OPTIONS = foreign
+
diff --git a/noatun-plugins/dub/NEWS b/noatun-plugins/dub/NEWS
new file mode 100644
index 0000000..500795c
--- /dev/null
+++ b/noatun-plugins/dub/NEWS
@@ -0,0 +1,35 @@
+dub-0.5
+-------
+
+Beta release. Two play modes: all files, single directory. Normal and
+shuffle play orders. Enjoy!
+
+
+dub-0.4
+-------
+
+Alpha release of dub. It includes two play modes: all files and single
+directory. Currently only normal (linear) ordering of files is supported.
+
+
+dub-0.3
+-------
+
+ Break DubApp into two classes
+ Read UI options
+ Fix: it's no use to return to first item in linear sequencer
+ if no next is found
+
+
+dub-0.2
+-------
+
+ Clean up cruft, remove unused doc class
+ Implement a noatun config module
+ Write some text docs
+
+
+dub-0.1
+-------
+
+ Play and Next working to some extent, eh :)
diff --git a/noatun-plugins/dub/README b/noatun-plugins/dub/README
new file mode 100644
index 0000000..f4cd6b4
--- /dev/null
+++ b/noatun-plugins/dub/README
@@ -0,0 +1,22 @@
+Dub Playlist
+------------
+
+A directory based playlist that's meant to be fast, simple and with the
+kind of functionality you'd expect from a digital player.
+
+Dub name was inspired from the continuous automated mix of digital music
+in Neuromancer. I'm not a Rasta but I still like that idea. As a tribute to
+William Gibson I decided to actually write such a program. That's where this
+code should be going! Read design.txt also.
+
+Author's note: Those who turn tail-recursive functions into iterations will
+be shot! GCC has tail-recursion optimization.
+
+Author's second note: Yes, I know other people have done things that an
+automated dj program could be based on. I'm still more interested in playing
+with a few clustering algorithms to get the result I want, I think deriving
+the features isn't the hard part. Any ideas welcome.
+
+__
+Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>
+
diff --git a/noatun-plugins/dub/TODO b/noatun-plugins/dub/TODO
new file mode 100644
index 0000000..bb9cee1
--- /dev/null
+++ b/noatun-plugins/dub/TODO
@@ -0,0 +1,20 @@
+ToDo List for dub playlist
++-+-+-++-+-+-++-+-+-++-+-+
+
+Any help welcome!
+Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr
+
+
+For v1.0
+=-=-=-=-
+
+- Repeat
+- Single
+- UI/playlist order consistency
+- implement missing playlist APIs (only getAfter significant)
+
+Misc.
+=-=-=
+
+- Make sure the view has finished loading when querying a file
+- Drag'n'drop support for files and directories.
diff --git a/noatun-plugins/dub/configure.in.in b/noatun-plugins/dub/configure.in.in
new file mode 100644
index 0000000..d4179d6
--- /dev/null
+++ b/noatun-plugins/dub/configure.in.in
@@ -0,0 +1,4 @@
+#MIN_CONFIG
+
+AM_INIT_AUTOMAKE(dub,0.2)
+
diff --git a/noatun-plugins/dub/design.txt b/noatun-plugins/dub/design.txt
new file mode 100644
index 0000000..618c849
--- /dev/null
+++ b/noatun-plugins/dub/design.txt
@@ -0,0 +1,43 @@
+Design
+------
+
+Dub Playlist
+------------
+
+Dub considers the filesystem as its database. User specifies one or more
+directories as the directories in which dub will scan for all or particular
+media types.
+
+The scanning is initiated on demand, so that dub does not perform redundant
+disk access which is expensive.
+
+Design Goals
+------------
+
+v1.0
+----
+
+User interface:
+
+ * settings: select directories that contain media files.
+
+ * list/tree view to browse files: this should scan directories like a file
+manager would, consider re-using code from elsewhere
+
+ * add file: symlink to a directory as Njaard suggests
+
+v2.0
+----
+
+implement filters: directory-wise filtering of media types.
+
+implement database: for storing properties of media files, such as tags in
+mp3s so that alternative queries can be made.
+
+user interface: improved tree view that accesses the db to fetch info
+about files
+
+v3.0
+----
+
+music playing: implement an automated dj process.
diff --git a/noatun-plugins/dub/dub.kdevprj b/noatun-plugins/dub/dub.kdevprj
new file mode 100644
index 0000000..1f1d8b6
--- /dev/null
+++ b/noatun-plugins/dub/dub.kdevprj
@@ -0,0 +1,198 @@
+[AUTHORS]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[BUGS]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[COPYING]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[ChangeLog]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[Config for BinMakefileAm]
+addcxxflags=
+bin_program=dub
+cflags=
+cppflags=
+cxxflags=\s-O0 -g3 -Wall
+ldadd=\s-lkfile -lkdeui -lkdecore -lqt
+ldflags=\s \s
+
+[General]
+AMChanged=false
+author=Eray Ozkural (exa)
+configure_args=\s--build=i386-linux --host=i386-linux --target=i386-linux --prefix=/usr/local/kde3 --with-qt-dir=/usr/local/qt --enable-debug --disable-fast-perl --disable-rpath
+email=erayo@cs.bilkent.edu.tr
+kdevprj_version=1.3
+lfv_open_groups=Headers,Sources,User Interface
+make_options=\s-j1
+makefiles=Makefile.am,dub/Makefile.am
+modifyMakefiles=true
+project_name=Dub
+project_type=kde2_normal
+sgml_file=/home/exa/code/projects/kde/dub/doc/en/index.docbook
+short_info=Dub is a playlist plugin for noatun
+sub_dir=dub/
+version=0.1
+version_control=CVS
+workspace=1
+
+[INSTALL]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[LFV Groups]
+GNU=AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,NEWS
+Headers=*.h,*.hh,*.hxx,*.hpp,*.H
+Others=*
+Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l
+Translations=*.po
+User Interface=*.kdevdlg,*.ui,*.rc
+groups=Headers,Sources,User Interface,Translations,GNU,Others
+
+[Makefile.am]
+files=dub.kdevprj,AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,BUGS
+sub_dirs=dub
+type=normal
+
+[README]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[TODO]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[dub.kdevprj]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[dub/BUGS]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[dub/Makefile.am]
+files=dub/main.cpp,dub/dub.cpp,dub/dub.h,dub/dubdoc.cpp,dub/dubdoc.h,dub/dubview.cpp,dub/dubview.h,dub/dubui.rc,dub/dub.plugin,dub/fileselectorwidget.cpp,dub/fileselectorwidget.h,dub/dubplaylist.cpp,dub/dubplaylist.h,dub/dubplaylistitem.cpp,dub/dubplaylistitem.h,dub/BUGS,dub/dubprefs.ui
+sharedlib_LDFLAGS=
+sharedlib_rootname=noatundub
+sub_dirs=
+type=shared_library
+
+[dub/dub.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[dub/dub.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[dub/dub.plugin]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[dub/dubdoc.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[dub/dubdoc.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[dub/dubplaylist.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[dub/dubplaylist.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[dub/dubplaylistitem.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[dub/dubplaylistitem.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[dub/dubprefs.ui]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[dub/dubui.rc]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[dub/dubview.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[dub/dubview.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[dub/fileselectorwidget.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[dub/fileselectorwidget.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[dub/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
diff --git a/noatun-plugins/dub/dub/Makefile.am b/noatun-plugins/dub/dub/Makefile.am
new file mode 100644
index 0000000..f49684c
--- /dev/null
+++ b/noatun-plugins/dub/dub/Makefile.am
@@ -0,0 +1,20 @@
+kde_module_LTLIBRARIES = noatundub.la
+
+INCLUDES = $(all_includes)
+
+noatundub_la_SOURCES = dubprefs.ui dubplaylistitem.cpp dubplaylist.cpp \
+fileselectorwidget.cpp dubview.cpp dubapp.cpp dub.cpp dubconfigmodule.cpp
+
+EXTRA_DIST = dubui.rc dub.plugin BUGS \
+ dub.h dubdoc.h dubview.h fileselectorwidget.h dubplaylist.h dubplaylistitem.h
+
+noatundub_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+noatundub_la_LIBADD = $(LIB_KIO) -lnoatun
+
+noatun_DATA = dub.plugin
+noatundir = $(kde_datadir)/noatun
+
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp *.h -o $(podir)/dub.pot
diff --git a/noatun-plugins/dub/dub/dub.cpp b/noatun-plugins/dub/dub/dub.cpp
new file mode 100644
index 0000000..4faf221
--- /dev/null
+++ b/noatun-plugins/dub/dub/dub.cpp
@@ -0,0 +1,641 @@
+/***************************************************************************
+ dub.cpp - description
+ -------------------
+ begin : Tue Oct 23 01:44:51 EEST 2001
+ copyright : (C) 2001 by Eray Ozkural (exa)
+ email : erayo@cs.bilkent.edu.tr
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// include files for QT
+#include <qdir.h>
+#include <qprinter.h>
+#include <qpainter.h>
+
+// include files for KDE
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <kmenubar.h>
+#include <kstatusbar.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstdaction.h>
+#include <kurl.h>
+#include <kurlrequester.h>
+#include <noatun/playlist.h>
+
+#include <vector>
+#include <algorithm>
+using std::vector;
+using std::iterator;
+
+// application specific includes
+#include "dub.h"
+#include "dub.moc"
+#include "dubview.h"
+#include "dubplaylist.h"
+#include "dubprefs.h"
+#include "dubconfigmodule.h"
+
+#include "random.h"
+int Random::seed;
+
+#define ID_STATUS_MSG 1
+
+Dub::Dub(DubPlaylist* plist)
+ : DubApp(0)
+ , playlist(*plist)
+ , dubconfig(*plist->dubconfig)
+ , activeFile(0)
+ , linear_onedir(this)
+ , linear_recursive(this)
+ , shuffle_onedir(this)
+ , shuffle_recursive(this)
+{
+ connect( view->dirOperator(),
+ SIGNAL(fileSelected(const KFileItem*)),
+ this,
+ SLOT(fileSelected(const KFileItem*)) );
+ connect( dubconfig.prefs->mediaDirectory,
+ SIGNAL( urlSelected (const QString &) ),
+ this,
+ SLOT( mediaHomeSelected (const QString &) ) );
+ connect( this,
+ SIGNAL(setMediaHome(KURL)),
+ view,
+ SLOT(setDir(KURL)) );
+ configure_sequencing();
+ emit setMediaHome(dubconfig.mediaDirectory);
+}
+
+/** File selected */
+void Dub::fileSelected(const KFileItem * file) {
+ kdDebug(90010) << "dub: file selected " << file << endl;
+ activeFile = const_cast<KFileItem *>(file);
+ playlist.setCurrent(file, true);
+}
+
+void Dub::mediaHomeSelected(const QString& url) {
+ kdDebug(90010) << "media home selected:" << endl;
+ emit setMediaHome( KURL(url) );
+}
+
+/** changes the active file to the next item
+ */
+void Dub::selectNextFile() {
+ configure_sequencing();
+ sequencer->next();
+}
+
+/** No descriptions */
+KFileItem* Dub::queryRoot() {
+ return view->dirLister()->rootItem();
+}
+
+/** First file in the directory */
+const KFileItem* Dub::queryFirstFile() {
+ return sequencer->first();
+}
+
+/** Select previous file */
+void Dub::selectPreviousFile() {
+ configure_sequencing();
+ sequencer->prev();
+}
+
+void Dub::configure_sequencing()
+{
+ switch (dubconfig.playMode) {
+ case DubConfigModule::allFiles:
+ if (dubconfig.playOrder==DubConfigModule::normal) {
+ linear_recursive.init(dubconfig.mediaDirectory);
+ sequencer = &linear_recursive;
+ }
+ else if (dubconfig.playOrder==DubConfigModule::shuffle) {
+ shuffle_recursive.init(dubconfig.mediaDirectory);
+ sequencer = &shuffle_recursive;
+ }
+ break;
+ case DubConfigModule::recursiveDir:
+ linear_recursive.init(view->currentDirectory().path());
+ sequencer = &linear_recursive;
+ break;
+ case DubConfigModule::oneDir:
+ if (dubconfig.playOrder==DubConfigModule::normal)
+ sequencer = &linear_onedir;
+ else if (dubconfig.playOrder==DubConfigModule::shuffle) {
+ shuffle_onedir.init(view->currentDirectory().path());
+ sequencer = &shuffle_onedir;
+ }
+ break;
+ }
+}
+
+void Dub::Sequencer::set_file(KFileItem** file, KFileItem* val) {
+ assert(val);
+ if (*file)
+ delete *file;
+ *file = new KFileItem(*val);
+ kdDebug(90010) << "set_file to " << val->url() << endl;
+}
+
+KFileItem* Dub::Linear_Seq::first(QPtrList<KFileItem> & items)
+{
+ // find first file
+ KFileItem* firstFile = 0;
+ for (KFileItem* item = items.first(); item; item = items.next() ) {
+ if (item->isFile()) {
+ firstFile = item;
+ break;
+ }
+ }
+ return firstFile;
+}
+
+KFileItem* Dub::Linear_Seq::last(QPtrList<KFileItem> & items)
+{
+ // find last file
+ KFileItem* lastFile = 0;
+ for (KFileItem* item = items.last(); item; item = items.prev() ) {
+ if (item->isFile()) {
+ lastFile = item;
+ break;
+ }
+ }
+ return lastFile;
+}
+
+bool Dub::Linear_Seq::find(QPtrList<KFileItem> & items, KFileItem* a_file)
+{
+ // find file
+ for (KFileItem *file=items.first(); file; file=items.next() )
+ if (file->isFile() && file->cmp(*a_file)) {
+ kdDebug(90010) << " found " << (file->url()) << endl;
+ return true;
+ }
+ return false;
+}
+
+KFileItem* Dub::Linear_Seq::next(QPtrList<KFileItem> & items,
+ KFileItem** active_file)
+{
+ KFileItem* ret = 0;
+ assert(active_file);
+ bool found = false;
+ if (*active_file) {
+ if (find(items, *active_file)) {
+ KFileItem* next = items.next();
+ for (; next && !next->isFile(); next = items.next()) ; // find next file
+ if (next && next->isFile())
+ set_file(active_file, next);
+ found = true;
+ ret = next;
+ }
+ }
+ if (!found) { // try to get the first one then
+ KFileItem *fst = first(items);
+ if (fst) {
+ set_file(active_file, fst);
+ ret = fst;
+ }
+ }
+ return ret;
+}
+
+KFileItem* Dub::Linear_Seq::prev(QPtrList<KFileItem> & items,
+ KFileItem** active_file)
+{
+ KFileItem* ret = 0;
+ assert(active_file);
+ bool found = false;
+ if (*active_file) {
+ // locate current item
+ if (find(items, *active_file)) {
+ KFileItem* prev = items.prev();
+ for (; prev && !prev->isFile(); prev = items.prev()) ; // find prev file
+ if (prev && prev->isFile()) {
+ set_file(active_file, prev);
+ found = true;
+ ret = prev;
+ }
+ }
+ }
+ if (!found) { // try to get the last one then
+ KFileItem *lst = last(items);
+ if (lst) {
+ set_file(active_file, lst);
+ ret = lst;
+ }
+ }
+ return ret;
+}
+
+KFileItem* Dub::Linear_OneDir::first()
+{
+ KFileItem* first = Linear_Seq::first(dub.view->items());
+ if (first)
+ set_file(&first_file, first);
+ else {
+ if (first_file) { // invalidate first
+ delete first_file;
+ first_file = 0;
+ }
+ }
+ return first_file;
+}
+
+//KFileItem* Dub::Linear_OneDir::getAfter(KFileItem* item)
+//{
+
+//}
+
+void Dub::Linear_OneDir::next()
+{
+ KFileItem *f = Linear_Seq::next(dub.view->items(), &dub.activeFile);
+ if (f) {
+ dub.view->selectFile(f);
+ }
+}
+
+void Dub::Linear_OneDir::prev()
+{
+ KFileItem *f = Linear_Seq::prev(dub.view->items(), &dub.activeFile);
+ if (f) {
+ dub.view->selectFile(f);
+ }
+}
+
+Dub::Dir_Node::Dir_Node(QString d, bool forward)
+ : dir(d), past_begin(false)
+{
+ kdDebug(90010) << "cons dir node " << d << endl;
+ // process entry list, form a list of subdirs and normal files
+ file_items.setAutoDelete(true);
+ QDir dir_obj(dir);
+ QFileInfoList* entries =
+ const_cast<QFileInfoList*>(dir_obj.entryInfoList());
+ for ( QFileInfo *file = entries->first(); file; file = entries->next() ) {
+ if (file->isDir() && file->absFilePath().length()>d.length()) {
+ kdDebug(90010) << "dub: dir " << file->absFilePath() << endl;
+ subdirs.append(file->absFilePath());
+ }
+ if (file->isFile()) {
+ // price for portability
+ kdDebug(90010) << "dub: file " << file->absFilePath() << endl;
+ KFileItem* item = new KFileItem(KFileItem::Unknown, KFileItem::Unknown,
+ file->absFilePath(), true);
+ file_items.append(item);
+ }
+ } // for
+
+ init_traversal(forward);
+
+ kdDebug(90010) << "dir node cons end" << endl;
+}
+
+void Dub::Dir_Node::init_traversal(bool forward)
+{
+ kdDebug(90010) << "init traversal" << endl;
+ // initialize traversal information
+ if (forward) {
+ current_subdir = subdirs.begin();
+ file_items.first();
+ }
+ else {
+ current_subdir = subdirs.end();
+ if (current_subdir!=subdirs.begin())
+ current_subdir--; // last item
+ else
+ past_begin=true;
+ file_items.last();
+ }
+ current_file = file_items.current();
+ kdDebug(90010) << "current subdir " << *current_subdir << endl;
+ kdDebug(90010) << "current file " << current_file << endl;
+}
+
+Dub::Recursive_Seq::Recursive_Seq()
+{
+ play_stack.setAutoDelete(true);
+}
+
+void Dub::Recursive_Seq::init(const KURL & root)
+{
+ QString new_root = canonical_path(root.path());
+ if (recursion_root != new_root) {
+ // change recursion stack
+ recursion_root = new_root;
+ kdDebug(90010) << "rec: new root is " << recursion_root << endl;
+ play_stack.clear();
+ push_dir(recursion_root); // start pre-order traversal
+ }
+}
+
+// get canonical path, we need this
+QString Dub::Recursive_Seq::canonical_path(QString dir)
+{
+// kdDebug(90010) << "canonical_path " << dir << endl;
+ //assert(dir.isLocalFile());
+ QDir path(dir);
+ return path.canonicalPath();
+}
+
+// check if dir is contained in the stack
+bool Dub::Recursive_Seq::check_dir(QString dir)
+{
+ kdDebug(90010) << "check_dir " << dir << endl;
+ bool found = false;
+ for ( Dir_Node *cur_dir = play_stack.first();
+ !found && cur_dir; cur_dir = play_stack.next() ) {
+ if (cur_dir->dir==dir)
+ found = true;
+ }
+ return found;
+}
+
+bool Dub::Recursive_Seq::push_dir(QString dir, bool forward)
+{
+ kdDebug(90010) << "push_dir " << dir << ", forward?" << forward << endl;
+ QString cpath = canonical_path(dir);
+ if (check_dir(cpath)) // is it in stack?
+ return false; // avoid infinite recursion
+ else {
+ Dir_Node* node = new Dir_Node(cpath, forward);
+ play_stack.append(node);
+ kdDebug(90010) << "stack after push:" << endl;
+ print_stack();
+ return true;
+ }
+}
+
+bool Dub::Recursive_Seq::pop_dir()
+{
+ assert(!play_stack.isEmpty());
+ kdDebug(90010) << "pop_dir" << endl;
+ play_stack.removeLast();
+ return !play_stack.isEmpty();
+}
+
+bool Dub::Recursive_Seq::advance(bool forward)
+{
+ Dir_Node* top = play_stack.getLast();
+ kdDebug(90010) << "first child " << top->subdirs.first() << endl;
+ kdDebug(90010) << "current child " << *top->current_subdir << endl;
+ kdDebug(90010) << "last child " << top->subdirs.last() << endl;
+ if (forward) {
+ top->current_subdir++; // advance dir
+ return top->current_subdir!=top->subdirs.end();
+ }
+ else
+ if (top->current_subdir!=top->subdirs.begin()) {
+ top->current_subdir--;
+ return true;
+ }
+ else {
+ top->past_begin=true;
+ return false;
+ }
+}
+
+void Dub::Recursive_Seq::pop_preorder(bool forward)
+{
+ if (pop_dir()) { // pop visited
+ advance(forward); // advance to next node
+ Dir_Node* top = play_stack.getLast();
+ kdDebug(90010) << "new child " << *top->current_subdir << endl;
+ if (forward)
+ next_preorder(); // continue processing
+ else
+ prev_preorder(); // continue processing
+ }
+ else {
+ kdDebug(90010) << "push root" << endl;
+ push_dir(recursion_root, forward); // back to the beginning if at end
+ }
+}
+
+void Dub::Recursive_Seq::next_preorder()
+{
+ assert(!play_stack.isEmpty()); // recursion stack cannot be empty
+ kdDebug(90010) << "next_preorder, stack:" << endl;
+ print_stack();
+ Dir_Node* top = play_stack.getLast();
+ if (top->subdirs.isEmpty() || top->current_subdir==top->subdirs.end()) {
+ kdDebug(90010) << "rec: subtrees done" << endl;
+ pop_preorder(true); // pop if subtrees done
+ }
+ else {
+ QString subdir = *top->current_subdir; // we have a subdir
+ push_dir(subdir, true); // push directory w/ forward iterators
+ }
+}
+
+void Dub::Recursive_Seq::prev_preorder()
+{
+ assert(!play_stack.isEmpty()); // recursion stack cannot be empty
+ kdDebug(90010) << "prev_preorder, stack:" << endl;
+ print_stack();
+ Dir_Node* top = play_stack.getLast();
+ if (top->subdirs.isEmpty() || top->past_begin) { // subtrees done?
+ kdDebug(90010) << "rec: subtrees done" << endl;
+ pop_preorder(false);
+ }
+ else {
+ QString subdir = *top->current_subdir;
+ kdDebug(90010) << "we have children, pushing now " << subdir << endl;
+ push_dir(subdir, false); // push directory w/ backward iterators
+ }
+}
+
+void Dub::Recursive_Seq::print_stack() {
+ for ( Dir_Node *cur_dir = play_stack.first();
+ cur_dir; cur_dir = play_stack.next() ) {
+ kdDebug(90010) << cur_dir->dir << endl;
+ }
+}
+
+Dub::Linear_Recursive::Linear_Recursive(Dub* d)
+ : Sequencer(d) {
+ kdDebug(90010) << "cons linear/recursive" << endl;
+}
+
+KFileItem* Dub::Linear_Recursive::first()
+{
+ KFileItem* first = bottom_dir()->file_items.getFirst();
+ return first;
+}
+
+void Dub::Linear_Recursive::next()
+{
+ assert(!play_stack.isEmpty());
+ Dir_Node* top = top_dir();
+ QString dir = top->dir;
+ top->current_file = top->file_items.next();
+ kdDebug(90010) << "dub current dir: " << dir << endl;
+ kdDebug(90010) << "dub current file: " << top->current_file << endl;
+ bool cycle = false;
+ while (!top_dir()->current_file && !cycle) {
+ next_preorder(); // traverse until a non-empty dir or cycle
+ if (top_dir()->dir==dir) {
+ kdDebug(90010) << "we got a cycle" << endl;
+ cycle = true;
+ top_dir()->init_traversal(true);
+ }
+ }
+ top = play_stack.getLast();
+ kdDebug(90010) << "dub new dir: " << *top->current_subdir << endl;
+ kdDebug(90010) << "dub new file: " << top->current_file << endl;
+ if (top->current_file) {
+ kdDebug(90010) << "dub new file: " << top->current_file->url() << endl;
+ dub.activeFile = top->current_file;
+ dub.fileSelected(dub.activeFile);
+ }
+}
+
+void Dub::Linear_Recursive::prev()
+{
+ assert(!play_stack.isEmpty());
+ Dir_Node* top = top_dir();
+ QString dir = top->dir;
+ top->current_file = top->file_items.prev();
+ kdDebug(90010) << "dub current dir: " << dir << endl;
+ kdDebug(90010) << "dub current file: " << top->current_file << endl;
+ bool cycle = false;
+ while (!top_dir()->current_file && !cycle) {
+ prev_preorder(); // traverse until a non-empty dir or cycle
+ if (top_dir()->dir==dir) {
+ kdDebug(90010) << "we got a cycle" << endl;
+ cycle = true;
+ top_dir()->init_traversal(false);
+ }
+ }
+ top = play_stack.getLast();
+ kdDebug(90010) << "dub new dir: " << *top->current_subdir << endl;
+ kdDebug(90010) << "dub new file: " << top->current_file << endl;
+ if (top->current_file) {
+ kdDebug(90010) << "dub new file: " << top->current_file->url() << endl;
+ dub.activeFile = top->current_file;
+ dub.fileSelected(dub.activeFile);
+ }
+}
+
+void Dub::Shuffle_OneDir::init(const QString& dir)
+{
+ if (shuffle_dir != dir) {
+ kdDebug(90010) << "shuffle/onedir init" << endl;
+ shuffle_dir = dir;
+ play_index = 0;
+
+ // make a deep copy
+ items.clear();
+ QPtrList<KFileItem> & view_items = dub.view->items(); //
+ for (KFileItem *file=view_items.first(); file; file=view_items.next() )
+ if (file->isFile()) // add only files
+ items.append(new KFileItem(*file));
+
+ int num_items = items.count();
+ play_order.resize(num_items);
+ if (num_items) { // generate shuffled order
+ kdDebug(90010) << num_items << " file items" << endl;
+ for (int i=0; i<num_items; i++)
+ play_order[i] = i;
+ Random random;
+ Random::init();
+ std::random_shuffle(play_order.begin(), play_order.end(), random);
+ }
+ }
+}
+
+KFileItem* Dub::Shuffle_OneDir::first()
+{
+ return 0;
+}
+
+void Dub::Shuffle_OneDir::next()
+{
+ kdDebug(90010) << "shuffle/onedir next" << endl;
+ if (!items.isEmpty()) {
+ play_index = ++play_index % play_order.size();
+ dub.activeFile = items.at(play_order[play_index]);
+ if (dub.activeFile)
+ dub.fileSelected(dub.activeFile);
+ }
+}
+
+void Dub::Shuffle_OneDir::prev()
+{
+ kdDebug(90010) << "shuffle/onedir prev" << endl;
+ if (!items.isEmpty()) {
+ play_index = --play_index % play_order.size();
+ dub.activeFile = items.at(play_order[play_index]);
+ if (dub.activeFile)
+ dub.fileSelected(dub.activeFile);
+ }
+}
+
+KFileItem* Dub::Shuffle_Recursive::random_file()
+{
+ assert(!play_stack.isEmpty());
+ play_stack.clear();
+ push_dir(recursion_root); // start pre-order traversal
+ KFileItem* selected = 0;
+ double file_probability = 0.3;
+ Random::init();
+ while (!top_dir()->subdirs.isEmpty() && !selected) {
+ if (top_dir()->file_items.isEmpty()) {
+ int ix = Random::random_int(top_dir()->subdirs.count());
+ push_dir(top_dir()->subdirs[ix]);
+ }
+ else {
+ if (Random::random_double(1.0)<file_probability) {
+ int ix = Random::random_int(top_dir()->file_items.count());
+ selected = top_dir()->file_items.at(ix);
+ }
+ else {
+ int ix = Random::random_int(top_dir()->subdirs.count());
+ push_dir(top_dir()->subdirs[ix]);
+ }
+ }
+ }
+ if (!selected) {
+ if (!top_dir()->file_items.isEmpty()) {
+ int ix = Random::random_int(top_dir()->file_items.count());
+ selected = top_dir()->file_items.at(ix);
+ }
+ }
+ return selected;
+}
+
+KFileItem* Dub::Shuffle_Recursive::first()
+{
+ return random_file();
+}
+
+void Dub::Shuffle_Recursive::next()
+{
+ KFileItem* file = random_file();
+ if (file) {
+ kdDebug(90010) << "shuffle/rec: new file: " << file->url() << endl;
+ dub.activeFile = file;
+ dub.fileSelected(file);
+ }
+}
+
+void Dub::Shuffle_Recursive::prev()
+{
+ KFileItem* file = random_file();
+ if (file) {
+ kdDebug(90010) << "shuffle/rec: new file: " << file->url() << endl;
+ dub.activeFile = file;
+ dub.fileSelected(file);
+ }
+}
diff --git a/noatun-plugins/dub/dub/dub.h b/noatun-plugins/dub/dub/dub.h
new file mode 100644
index 0000000..5317f86
--- /dev/null
+++ b/noatun-plugins/dub/dub/dub.h
@@ -0,0 +1,207 @@
+// -*-c++-*-
+/***************************************************************************
+ dub.h - description
+ -------------------
+ begin : Tue Oct 23 01:44:51 EEST 2001
+ copyright : (C) 2001 by Eray Ozkural (exa)
+ email : erayo@cs.bilkent.edu.tr
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef Dub_Interface
+#define Dub_Interface
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// KDE includes
+#include <kapplication.h>
+#include <kmainwindow.h>
+#include <kurl.h>
+#include <noatun/plugin.h>
+#include <noatun/playlist.h>
+
+// sys includes
+#include <vector>
+#include <list>
+
+// forward decl
+class KFileItem;
+class KDirLister;
+class DubPlaylist;
+
+// application specific includes
+#include "dubapp.h"
+#include "dubconfigmodule.h"
+
+// dub specific application code
+class Dub : public DubApp
+{
+ Q_OBJECT
+
+public:
+
+ Dub(DubPlaylist* plist);
+
+public slots:
+ /** A file selected */
+ void fileSelected(const KFileItem*);
+ void mediaHomeSelected(const QString& url);
+
+ signals:
+void setMediaHome(KURL);
+ // xemacs rules
+
+public:
+
+ /** playlist object to interface noatun
+ */
+ DubPlaylist& playlist;
+ /** noatun configuration object
+ */
+ DubConfigModule& dubconfig;
+
+ KFileItem* getActiveFile() { return activeFile; }
+ /** find root */
+ KFileItem* queryRoot();
+ /** First file in the sequence */
+ const KFileItem* queryFirstFile();
+ /** Select next file in order */
+ void selectNextFile();
+ /** Select previous file in order */
+ void selectPreviousFile();
+
+public:
+
+ /* The chosen file */
+ KFileItem* activeFile;
+
+private:
+
+ void configure_sequencing();
+
+ // expansion slot :P
+ struct Sequencer {
+ Sequencer(Dub* d) : dub(*d) {}
+ virtual KFileItem* first() = 0;
+ virtual void next() = 0;
+ virtual void prev() = 0;
+ Dub& dub;
+ void set_file(KFileItem** file, KFileItem* val);
+ };
+ Sequencer* sequencer;
+
+ // possible sequencers are linear/oneDir, linear/recursive,
+ // shuffle/oneDir, shuffle/recursive, repeat, single
+
+ // linear sequencing subsystem
+ struct Linear_Seq : public Sequencer {
+ Linear_Seq(Dub* d) : Sequencer(d) {}
+ KFileItem* first(QPtrList<KFileItem> & items);
+ KFileItem* last(QPtrList<KFileItem> & items);
+ KFileItem* next(QPtrList<KFileItem> & items, KFileItem** active_file);
+ KFileItem* prev(QPtrList<KFileItem> & items, KFileItem** active_file);
+ bool find(QPtrList<KFileItem> & items, KFileItem* a_file);
+ };
+
+ // sequencer that traverses current directory in view order
+ struct Linear_OneDir : public Linear_Seq {
+ Linear_OneDir(Dub* d) : Linear_Seq(d), first_file(0) {}
+ virtual ~Linear_OneDir() {}
+ KFileItem* first();
+ void next();
+ void prev();
+ KFileItem* first_file;
+ };
+ Linear_OneDir linear_onedir;
+
+ // directory node for recursive play
+ struct Dir_Node
+ {
+ Dir_Node(QString dir, bool forward = true);
+ QString dir;
+ QStringList subdirs;
+ QStringList::iterator current_subdir;
+ QPtrList<KFileItem> file_items;
+ KFileItem* current_file;
+ void init_traversal(bool forward);
+ bool past_begin; // stupid iterators
+ };
+
+ // recursive play sequencing subsystem
+ struct Recursive_Seq {
+ Recursive_Seq();
+ void init(const KURL & root);
+ QString canonical_path(QString dir);
+ bool check_dir(QString dir);
+ Dir_Node* top_dir() { return play_stack.getLast(); }
+ Dir_Node* bottom_dir() { return play_stack.getFirst(); }
+ bool push_dir(QString dir, bool forward = true);
+ bool pop_dir();
+ bool advance(bool forward = true);
+ void pop_preorder(bool forward = true);
+ void next_preorder();
+ void prev_preorder();
+ void print_stack();
+
+ QString recursion_root;
+ QPtrList<Dir_Node> play_stack;
+ };
+
+ // sequencer to make a preorder walk of the directory tree
+ struct Linear_Recursive
+ : public Sequencer, public Recursive_Seq {
+ Linear_Recursive(Dub* d);
+ virtual ~Linear_Recursive() {};
+ KFileItem* first();
+ void next();
+ void prev();
+ };
+ Linear_Recursive linear_recursive;
+
+ // shuffle/onedir sequencer
+ struct Shuffle_OneDir
+ : public Sequencer {
+ Shuffle_OneDir(Dub* d) : Sequencer(d) {
+ items.setAutoDelete(true);
+ }
+ virtual ~Shuffle_OneDir() {};
+ void init(const QString& dir);
+ KFileItem* first();
+ void next();
+ void prev();
+ void init();
+
+ int play_index;
+ std::vector<int> play_order;
+ KURL shuffle_dir;
+ QPtrList<KFileItem> items;
+ };
+ Shuffle_OneDir shuffle_onedir;
+
+ // shuffle/recursive sequencer
+ struct Shuffle_Recursive
+ : public Sequencer, public Recursive_Seq {
+ Shuffle_Recursive(Dub* d) : Sequencer(d) {}
+ virtual ~Shuffle_Recursive() {}
+ KFileItem* random_file();
+ KFileItem* first();
+ void next();
+ void prev();
+
+ QString shuffle_root;
+ };
+ Shuffle_Recursive shuffle_recursive;
+
+};
+
+#endif // DUB_H
diff --git a/noatun-plugins/dub/dub/dub.plugin b/noatun-plugins/dub/dub/dub.plugin
new file mode 100644
index 0000000..c844c01
--- /dev/null
+++ b/noatun-plugins/dub/dub/dub.plugin
@@ -0,0 +1,69 @@
+Filename=noatundub.la
+Author=Eray (exa) Ozkural
+Site=http://www.cs.bilkent.edu.tr/~erayo
+Type=playlist
+License=GPL
+Name=Dub
+Name[af]=Hersien
+Name[eo]=Nomilo
+Name[hi]=डब
+Name[km]=ដាក់​ឈ្មោះ
+Name[ne]=डब
+Name[ta]=பதிவு
+Name[tr]=Ünvan
+Name[xh]=Nika igama lesiteketiso
+Comment=Dub playlist plugin
+Comment[bg]=Приставка за списък за изпълнение, базирана на директории
+Comment[bs]=Dub dodatak za playlistu
+Comment[ca]=Connector de la llista de reproducció Dub
+Comment[cs]=Modul seznamu skladeb "Dub"
+Comment[da]=Dub-spilleliste-plugin
+Comment[de]=Dub Wiedergabelisten-Modul
+Comment[el]=Πρόσθετο λίστας αναπαραγωγής Dub
+Comment[eo]=Kromaĵo por nomi ludlistojn
+Comment[es]=Complemento de doblaje de la lista de reproducción
+Comment[et]=Dubi esitusnimekirja plugin
+Comment[eu]=Dut erreprodukzio-zerrendaren plugina
+Comment[fa]=وصلۀ فهرست پخش Dub
+Comment[fi]=Dub soittolistasovelma
+Comment[fr]=Module de liste de doublage
+Comment[fy]=Dub Ofspyllistplugin
+Comment[ga]=Breiseán seinmliosta Dub
+Comment[gl]=Plugin de lista de reproduición de Dub
+Comment[he]=תוסף רשימת הניגון Dub
+Comment[hi]=डब प्लेलिस्ट प्लगइन
+Comment[hr]=Dodatak albuma za Dub
+Comment[hu]=Dub lejátszási lista modulként
+Comment[is]=Tól til að spila Dub lagalista
+Comment[it]=Plugin per le Playlist di Dub
+Comment[ja]=Dub プレイリスト プラグイン
+Comment[ka]=Dub სიმღერათა სიის მოდული
+Comment[kk]=Dub орындау тізімінің плагин модулі
+Comment[km]=ដាក់​ឈ្មោះ​កម្មវិធី​ជំនួយ​បញ្ជី​ចាក់
+Comment[lt]=Dub gaidaraščio priedas
+Comment[mk]=Приклучок за листа со нумери Dub
+Comment[ms]=Plugin senarai main Dub
+Comment[nb]=Dub programtillegg for spilleliste
+Comment[nds]=Dub-Afspeellistmoduul
+Comment[ne]=डब प्लेसूची प्लगइन
+Comment[nl]=Dub Afspeellijstplugin
+Comment[nn]=Dub-programtillegg for speleliste
+Comment[pl]=Lista odtwarzania pozwalająca wybierać wprost z systemu plików
+Comment[pt]='Plugin' da lista Dub
+Comment[pt_BR]=Plug-in de Lista de reprodução do Dub
+Comment[ru]=Модуль списка произведений Dub
+Comment[sk]=Modul pre Dub playlist
+Comment[sl]=Vstavek predvajalnega seznama za Dub
+Comment[sr]=Прикључак за Dub-ову листу нумера
+Comment[sr@Latn]=Priključak za Dub-ovu listu numera
+Comment[sv]=Spellistan Dub
+Comment[ta]= இயங்குபட்டியல் சொருகுப்பொருளை பதிவு செய்
+Comment[tg]=Модули рӯйхати баровардҳои Dub
+Comment[tr]=Dub çalma listesi eklentisi
+Comment[uk]=Втулок списку композицій Dub
+Comment[uz]=Dub oʻynash roʻyxati plagini
+Comment[uz@cyrillic]=Dub ўйнаш рўйхати плагини
+Comment[vi]=Bổ sung danh mục nhạc Dub
+Comment[zh_CN]=Dub 播放列表插件
+Comment[zh_TW]=Dub 播放清單外掛程式
+
diff --git a/noatun-plugins/dub/dub/dubapp.cpp b/noatun-plugins/dub/dub/dubapp.cpp
new file mode 100644
index 0000000..7097940
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubapp.cpp
@@ -0,0 +1,98 @@
+//
+//
+// C++ Implementation for module: DubApp
+//
+// Description:
+//
+//
+// Author: Eray (exa) Ozkural, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+// include files for QT
+#include <qdir.h>
+#include <qprinter.h>
+#include <qpainter.h>
+
+// include files for KDE
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <kmenubar.h>
+#include <kstatusbar.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kstdaction.h>
+#include <noatun/playlist.h>
+
+// application specific includes
+#include "dubapp.h"
+#include "dubapp.moc"
+#include "dubview.h"
+
+#define ID_STATUS_MSG 1
+
+DubApp::DubApp(QWidget* parent, const char* name)
+ : KMainWindow(parent, name)
+{
+ kdDebug(90010) << "cons dubapp" << endl;
+ config=kapp->config();
+
+ // call inits to invoke all other construction parts
+ initStatusBar();
+ initActions();
+ initView();
+ setAutoSaveSettings();
+}
+
+DubApp::~DubApp()
+{
+ kdDebug(90010) << "destruct dubapp" << endl;
+}
+
+void DubApp::initActions()
+{
+ fileClose = KStdAction::close(this, SLOT(close()), actionCollection());
+ setStandardToolBarMenuEnabled(true);
+ createStandardStatusBarAction();
+
+ fileClose->setStatusText(i18n("Close playlist window"));
+
+ // use the absolute path to your dubui.rc file for testing purpose in createGUI();
+ createGUI();
+}
+
+
+void DubApp::initStatusBar()
+{
+ // status bar
+ statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG);
+}
+
+void DubApp::initView()
+{
+ // create the main widget here that is managed by KTMainWindow's view-region and
+ // connect the widget to your document to display document contents.
+
+ view = new DubView(this);
+ setCentralWidget(view);
+ setCaption("Dub Playlist",false);
+}
+
+// slots
+
+void DubApp::slotStatusMsg(const QString &text)
+{
+ // change status message permanently
+ statusBar()->clear();
+ statusBar()->changeItem(text, ID_STATUS_MSG);
+}
+
+// events
+
+void DubApp::closeEvent(QCloseEvent*)
+{
+ hide();
+}
diff --git a/noatun-plugins/dub/dub/dubapp.h b/noatun-plugins/dub/dub/dubapp.h
new file mode 100644
index 0000000..e06a2fe
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubapp.h
@@ -0,0 +1,83 @@
+// -*-c++-*-
+//
+// C++ Interface for module: DubApp
+//
+// Description: KDE application entry point for dub playlist
+// Stripped down main window code from kapptemplate
+//
+// Author: Eray (exa) Ozkural, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef DubApp_Interface
+#define DubApp_Interface
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// include files for KDE
+#include <kapplication.h>
+#include <kmainwindow.h>
+#include <kaccel.h>
+#include <kaction.h>
+
+// forward declaration of the Dub classes
+class DubView;
+
+// Application stuff
+class DubApp : public KMainWindow
+{
+ Q_OBJECT
+
+ friend class DubView;
+
+public:
+ /** construtor of DubApp, calls all init functions to create the application.
+ */
+ DubApp(QWidget* parent, const char* name="Dub Playlist");
+ ~DubApp();
+
+ void initActions();
+ /** sets up the statusbar for the main window by initialzing a statuslabel.
+ */
+ void initStatusBar();
+ /** initializes the document object of the main window that is connected to the view in initView().
+ * @see initView();
+ */
+ void initView();
+
+ DubView *view;
+ DubView* getView() {
+ return view;
+ }
+
+protected:
+ virtual void closeEvent(QCloseEvent*e);
+
+private:
+ KConfig *config;
+ /** view is the main widget which represents your working area. The View
+ * class should handle all events of the view widget. It is kept empty so
+ * you can create your view according to your application's needs by
+ * changing the view class.
+ */
+
+ // KAction pointers to enable/disable actions
+ //KAction* fileQuit;
+ KAction* fileClose;
+
+ // signals and slots
+
+public slots:
+ /** changes the statusbar contents for the standard label permanently, used to indicate current actions.
+ * @param text the text that is displayed in the statusbar
+ */
+ void slotStatusMsg(const QString &text);
+ /** get a pointer to view object */
+
+};
+
+#endif
diff --git a/noatun-plugins/dub/dub/dubconfigmodule.cpp b/noatun-plugins/dub/dub/dubconfigmodule.cpp
new file mode 100644
index 0000000..ff1f3dd
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubconfigmodule.cpp
@@ -0,0 +1,125 @@
+//
+//
+// C++ Implementation: cpp
+//
+// Description:
+//
+//
+// Author: Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>, (C) 2003
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include <kconfig.h>
+#include <kdialog.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kurlrequester.h>
+#include <kdebug.h>
+
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+
+#include "dubconfigmodule.h"
+
+DubConfigModule::DubConfigModule(QObject* parent)
+ : CModule(i18n("Dub"), i18n("Folder-Based Playlist"), "noatun", parent)
+ , playMode(oneDir)
+ , playOrder(normal)
+{
+ QVBoxLayout *vbox = new QVBoxLayout(this);
+ vbox->setAutoAdd(true);
+ vbox->setSpacing( 0 );
+ vbox->setMargin( 0 );
+
+ prefs = new DubPrefs(this);
+ prefs->mediaDirectory->setMode(KFile::Directory);
+
+ reopen();
+}
+
+DubConfigModule::~DubConfigModule()
+{
+}
+
+void DubConfigModule::save(void)
+{
+ KConfig* config(KGlobal::config());
+ config->setGroup("DubPlaylist");
+
+ mediaDirectory = prefs->mediaDirectory->url();
+
+ QButton* selectedMode = prefs->playMode->selected();
+ if (selectedMode==prefs->allFiles)
+ playMode = DubConfigModule::allFiles;
+ else
+ if (selectedMode==prefs->recursiveDir)
+ playMode = DubConfigModule::recursiveDir;
+ else
+ playMode = DubConfigModule::oneDir;
+
+ QButton* selectedOrder = prefs->playOrder->selected();
+ if (selectedOrder==prefs->shuffle)
+ playOrder = DubConfigModule::shuffle;
+ else
+ if (selectedOrder==prefs->repeat)
+ playOrder = DubConfigModule::repeat;
+ else
+ if (selectedOrder==prefs->single)
+ playOrder = DubConfigModule::single;
+ else
+ playOrder = DubConfigModule::normal;
+
+ config->writePathEntry("MediaDirectory", mediaDirectory);
+ config->writeEntry("PlayMode", (int) playMode);
+ config->writeEntry("PlayOrder", (int) playOrder);
+}
+
+void DubConfigModule::reopen(void)
+{
+ kdDebug(90010) << "dubconfig: reopen" << endl;
+ KConfig* config(KGlobal::config());
+ config->setGroup("DubPlaylist");
+ mediaDirectory = config->readPathEntry("MediaDirectory", "~/");
+ kdDebug(90010) << "dub: media home is " << mediaDirectory << endl;
+ playMode = (PlayMode) config->readNumEntry("PlayMode", DubConfigModule::oneDir);
+ playOrder = (PlayOrder) config->readNumEntry("PlayOrder", DubConfigModule::normal);
+ apply();
+}
+
+void DubConfigModule::apply()
+{
+ prefs->mediaDirectory->setURL(mediaDirectory);
+ // what a horrible repetition, but it's not worthwhile doing any better ;)
+ switch (playMode) {
+ case allFiles:
+ prefs->playMode->setButton(prefs->playMode->id(prefs->allFiles));
+ break;
+ case oneDir:
+ prefs->playMode->setButton(prefs->playMode->id(prefs->oneDir));
+ break;
+ case recursiveDir:
+ prefs->playMode->setButton(prefs->playMode->id(prefs->recursiveDir));
+ break;
+ }
+ switch (playOrder) {
+ case normal:
+ prefs->playOrder->setButton(prefs->playOrder->id(prefs->normal));
+ break;
+ case shuffle:
+ prefs->playOrder->setButton(prefs->playOrder->id(prefs->shuffle));
+ break;
+ case repeat:
+ prefs->playOrder->setButton(prefs->playOrder->id(prefs->repeat));
+ break;
+ case single:
+ prefs->playOrder->setButton(prefs->playOrder->id(prefs->single));
+ break;
+ }
+}
+
+
+#include "dubconfigmodule.moc"
diff --git a/noatun-plugins/dub/dub/dubconfigmodule.h b/noatun-plugins/dub/dub/dubconfigmodule.h
new file mode 100644
index 0000000..cfb662b
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubconfigmodule.h
@@ -0,0 +1,40 @@
+// -*-c++-*-
+#ifndef DUBCONFIGMODULE_H
+#define DUBCONFIGMODULE_H
+
+
+#include <noatun/pref.h>
+#include "dubprefs.h"
+
+/**
+ * Noatun configuration module for dub
+
+ * Eray Ozkural (exa)
+ **/
+class DubConfigModule : public CModule
+{
+Q_OBJECT
+public:
+ enum PlayOrder { normal, shuffle, repeat, single };
+ enum PlayMode { allFiles, oneDir, recursiveDir };
+
+ DubConfigModule(QObject *parent);
+
+ ~DubConfigModule();
+
+ virtual void save(void);
+ virtual void reopen(void);
+
+ void apply();
+
+ /** The directory in which media files are stored */
+ QString mediaDirectory;
+ PlayMode playMode;
+ PlayOrder playOrder;
+
+ const DubPrefs* getPrefs() { return prefs; }
+ //private:
+ DubPrefs* prefs;
+};
+
+#endif
diff --git a/noatun-plugins/dub/dub/dubplaylist.cpp b/noatun-plugins/dub/dub/dubplaylist.cpp
new file mode 100644
index 0000000..6803214
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubplaylist.cpp
@@ -0,0 +1,158 @@
+//
+//
+// C++ Implementation: dubplaylist.cpp
+//
+// Description:
+//
+//
+// Author: Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>, (C) 2001
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+//#include dubplaylist.cpp
+
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <noatun/playlist.h>
+#include <klocale.h>
+
+#include "dub.h"
+#include "dubconfigmodule.h"
+
+#include "dubplaylist.h"
+
+// plugin interface
+extern "C" Plugin *create_plugin()
+{
+ KGlobal::locale()->insertCatalogue("dub");
+ DubPlaylist* dub = new DubPlaylist;
+ return dub;
+}
+
+/** Construct playlist object */
+DubPlaylist::DubPlaylist()
+ : Playlist(0, "Dub Playlist")
+ , dub(0)
+ , visible(false)
+{
+ kdDebug(90010) << "dub: cons playlist" << endl;
+}
+
+DubPlaylist::~DubPlaylist(){
+ kdDebug(90010) << "dub: destruct playlist " << endl;
+ // destroy app
+ delete dub;
+}
+
+void DubPlaylist::reset() {
+ kdDebug(90010) << "dub: reset" << endl;
+}
+
+void DubPlaylist::clear() {
+ kdDebug(90010) << "dub: clear" << endl;
+}
+
+void DubPlaylist::addFile(const KURL&, bool play) {
+ KMessageBox::information(0, i18n("Adding files not supported yet, see configuration"));
+}
+
+PlaylistItem DubPlaylist::next() {
+ kdDebug(90010) << "dub: next" << endl;
+ dub->selectNextFile();
+ updateCurrent();
+ return currentItem;
+}
+
+PlaylistItem DubPlaylist::current() {
+ if (!currentItem.isNull())
+ kdDebug(90010) << "dub: current item:" << currentItem.data()->url().prettyURL() << endl;
+ return currentItem;
+}
+
+PlaylistItem DubPlaylist::previous() {
+ kdDebug(90010) << "dub: previous" << endl;
+ dub->selectPreviousFile();
+ updateCurrent();
+ return currentItem;
+}
+
+PlaylistItem DubPlaylist::getFirst() const {
+ kdDebug(90010) << "dub: getFirst" << endl;
+ const KFileItem* first = dub->queryFirstFile();
+ if (first) {
+ kdDebug(90010) << "dub: first " << first->url() << endl;
+ DubPlaylistItem* firstData = new DubPlaylistItem(*first);
+ return PlaylistItem(firstData);
+ }
+ else
+ return 0;
+}
+
+PlaylistItem DubPlaylist::getAfter(const PlaylistItem &item) const {
+ kdDebug(90010) << "dub: getAfter" << endl;
+ return 0;
+}
+
+bool DubPlaylist::listVisible() const {
+ kdDebug(90010) << "dub: listVisible" << endl;
+ return visible;
+}
+
+void DubPlaylist::init() {
+ kdDebug(90010) << "dub: init" << endl;
+ dubconfig = new DubConfigModule(this); // we pass this around to dub app
+ dub = new Dub(this);
+ kdDebug(90010) << "dub: init: test playlist() " << endl;
+ playlist();
+}
+
+void DubPlaylist::showList() {
+ kdDebug(90010) << "dub: showList" << endl;
+ visible = true;
+ Q_ASSERT(dub);
+ dub->show();
+}
+
+void DubPlaylist::hideList() {
+ kdDebug(90010) << "dub: hideList" << endl;
+ visible = false;
+ Q_ASSERT(dub);
+ dub->hide();
+}
+
+//void DubPlaylist::remove(const PlaylistItem&) {
+// KMessageBox::information(0, "Removing files not supported yet, see configuration");
+//}
+
+//void DubPlaylist::sort() {
+// kdDebug(90010) << "sort" << endl;
+//}
+
+Playlist* DubPlaylist::playlist() {
+ kdDebug(90010) << "dub: playlist pointer " << this << endl;
+ return static_cast<Playlist*>(this);
+}
+
+void DubPlaylist::setCurrent(const KFileItem* file, bool play) {
+ Q_ASSERT(file);
+ currentItem = new DubPlaylistItem(*file);
+ if (play)
+ emit playCurrent();
+}
+
+void DubPlaylist::setCurrent(const PlaylistItem &play)
+{
+ currentItem=play;
+ emit playCurrent();
+}
+
+/** No descriptions */
+void DubPlaylist::updateCurrent() {
+ KFileItem* active = dub->getActiveFile();
+ if ( active ) {
+ currentItem = new DubPlaylistItem(*active);
+ emit playCurrent();
+ }
+}
diff --git a/noatun-plugins/dub/dub/dubplaylist.h b/noatun-plugins/dub/dub/dubplaylist.h
new file mode 100644
index 0000000..d250926
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubplaylist.h
@@ -0,0 +1,77 @@
+// -*-c++-*-
+//
+// C++ Interface dubplaylist.h
+//
+// Description:
+//
+//
+// Author: Eray Ozkural (exa), (C) 2001
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef DUBPLAYLIST_H
+#define DUBPLAYLIST_H
+
+class Dub;
+class DubConfigModule;
+
+#include <kfileitem.h>
+#include <noatun/playlist.h>
+#include <noatun/plugin.h>
+
+#include "dubplaylistitem.h"
+
+/**Playlist class. Implements the noatun playlist interface
+ *@author Eray Ozkural (exa)
+ */
+
+class DubPlaylist : public Playlist, public Plugin {
+public:
+
+ DubPlaylist();
+ ~DubPlaylist();
+
+ virtual void reset();
+
+ virtual void clear();
+ virtual void addFile(const KURL&, bool play=false);
+ /**
+ * Cycle everthing through forward
+ **/
+ virtual PlaylistItem next();
+ /**
+ * return the one that might/should be playing now
+ **/
+ virtual PlaylistItem current();
+ /**
+ * Cycle through backwards
+ **/
+ virtual PlaylistItem previous();
+ virtual PlaylistItem getFirst() const;
+ virtual PlaylistItem getAfter(const PlaylistItem &item) const;
+
+ virtual bool listVisible() const;
+ virtual void init();
+ virtual Playlist* playlist();
+
+ virtual void setCurrent(const PlaylistItem &play);
+
+public slots:
+ virtual void showList();
+ virtual void hideList();
+ virtual void setCurrent(const KFileItem* file, bool play = false);
+ void updateCurrent();
+// virtual void remove(const PlaylistItem&);
+// virtual void sort();
+
+ DubConfigModule *dubconfig;
+
+private:
+ Dub *dub;
+ PlaylistItem currentItem;
+ bool visible;
+};
+
+#endif
diff --git a/noatun-plugins/dub/dub/dubplaylistitem.cpp b/noatun-plugins/dub/dub/dubplaylistitem.cpp
new file mode 100644
index 0000000..d38eb24
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubplaylistitem.cpp
@@ -0,0 +1,83 @@
+//
+//
+// C++ Implementation: dubplaylistitem.cpp
+//
+// Description:
+//
+//
+// Author: Eray Ozkural (exa) <erayo@cs.bilkent.edu.tr>, (C) 2001
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+//#include dubplaylistitem.cpp
+
+
+#include "dubplaylistitem.h"
+#include <kfile.h>
+#include <kfileitem.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+
+DubPlaylistItem::DubPlaylistItem(const KFileItem& fItem)
+ : fileItem(fItem)
+{
+// kdDebug(90010) << "construct playlist item " << fItem.url().prettyURL() << endl;
+
+// PlaylistItemData::addRef();
+ PlaylistItemData::added();
+}
+
+DubPlaylistItem::~DubPlaylistItem(){
+// kdDebug(90010) << "destruct playlist item " << fileItem.url().prettyURL() << endl;
+
+// PlaylistItemData::removed();
+ PlaylistItemData::removeRef();
+}
+
+QString DubPlaylistItem::property(const QString &key, const QString &def) const {
+// kdDebug(90010) << "property " << key << endl;
+ if (isProperty(key)) {
+ kdDebug(90010) << key << " -> " << property_map.find(key).data() << endl;
+ return property_map.find(key).data();
+ }
+ else
+ return def;
+}
+
+void DubPlaylistItem::setProperty(const QString &key, const QString &val) {
+// kdDebug(90010) << "set property" << endl;
+ property_map[key] = val;
+}
+
+void DubPlaylistItem::clearProperty(const QString &key) {
+// kdDebug(90010) << "clear property" << endl;
+ property_map.remove(key);
+}
+
+QStringList DubPlaylistItem::properties() const {
+// kdDebug(90010) << "properties" << endl;
+ QStringList list;
+ for (Properties::const_iterator i=property_map.begin();
+ i!=property_map.end(); i++) {
+ list.append(i.data());
+ }
+ return list;
+}
+
+bool DubPlaylistItem::isProperty(const QString &key) const {
+// kdDebug(90010) << "is property? " << key << endl;
+ return (property_map.find(key) != property_map.end());
+}
+
+KURL DubPlaylistItem::url() const {
+// kdDebug(90010) << "item url" << endl;
+
+ return fileItem.url();
+}
+/** No descriptions */
+void DubPlaylistItem::remove() {
+ KMessageBox::information(0, i18n("Do you really want to delete this file?"));
+}
diff --git a/noatun-plugins/dub/dub/dubplaylistitem.h b/noatun-plugins/dub/dub/dubplaylistitem.h
new file mode 100644
index 0000000..6f7a96d
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubplaylistitem.h
@@ -0,0 +1,55 @@
+//
+//
+// C++ Interface dubplaylistitem.h
+//
+// Description:
+//
+//
+// Author: Eray Ozkural (exa), (C) 2001
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+
+#ifndef DUBPLAYLISTITEM_H
+#define DUBPLAYLISTITEM_H
+
+#include <kfileitem.h>
+#include <dubplaylistitem.h>
+
+#include <noatun/playlist.h>
+
+/**noatun playlistitem implementation
+ *@author Eray Ozkural (exa)
+ */
+
+class KFileItem;
+
+class DubPlaylistItem : public PlaylistItemData {
+public:
+ DubPlaylistItem(const KFileItem&);
+ virtual ~DubPlaylistItem();
+
+ virtual QString property(const QString &, const QString & = 0) const;
+ virtual void setProperty(const QString &, const QString &);
+ virtual void clearProperty(const QString &);
+ virtual QStringList properties() const;
+ virtual bool isProperty(const QString &) const;
+ virtual KURL url() const;
+ KFileItem& getFileItem() {
+ return fileItem;
+ }
+ /** No descriptions */
+ virtual void remove();
+
+private:
+ KFileItem fileItem;
+ typedef QMap<QString,QString> Properties;
+ Properties property_map;
+
+// virtual QString file() const;
+
+};
+
+#endif
diff --git a/noatun-plugins/dub/dub/dubprefs.ui b/noatun-plugins/dub/dub/dubprefs.ui
new file mode 100644
index 0000000..6b27195
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubprefs.ui
@@ -0,0 +1,187 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>DubPrefs</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>DubPrefs</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>451</width>
+ <height>349</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Dub Preferences</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Media home:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>mediaDirectory</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Top-level folder where my media files are stored</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>playMode</cstring>
+ </property>
+ <property name="title">
+ <string>Play Mode</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>allFiles</cstring>
+ </property>
+ <property name="text">
+ <string>All media files</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>All media files found under Media Home</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>oneDir</cstring>
+ </property>
+ <property name="text">
+ <string>Selected folder</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Play current folder only</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>recursiveDir</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>All files under selected folder</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Choose media files from current folder and all its subfolders</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>playOrder</cstring>
+ </property>
+ <property name="title">
+ <string>Play Order</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>normal</cstring>
+ </property>
+ <property name="text">
+ <string>Normal</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Play files in normal order</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>shuffle</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Shuffle</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Randomized order</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>repeat</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Repeat</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Repeat the same file forever</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>single</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Single</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Play a single file and stop</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/noatun-plugins/dub/dub/dubui.rc b/noatun-plugins/dub/dub/dubui.rc
new file mode 100644
index 0000000..1b735ef
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubui.rc
@@ -0,0 +1,8 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="dub" version="1">
+<MenuBar>
+ <Menu name="file"><text>&amp;File</text>
+ <Action name="file_new_window"/>
+ </Menu>
+</MenuBar>
+</kpartgui>
diff --git a/noatun-plugins/dub/dub/dubview.cpp b/noatun-plugins/dub/dub/dubview.cpp
new file mode 100644
index 0000000..e1e4713
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubview.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ dubview.cpp - description
+ -------------------
+ begin : Tue Oct 23 01:44:51 EEST 2001
+ copyright : (C) 2001 by Eray Ozkural (exa)
+ email : erayo@cs.bilkent.edu.tr
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+// include files for Qt
+#include <qprinter.h>
+#include <qpainter.h>
+#include <kdebug.h>
+
+// application specific includes
+#include "dubview.h"
+#include "dubview.moc"
+#include "dub.h"
+#include "fileselectorwidget.h"
+
+//DubView::DubView(QWidget *parent, const char *name) : QWidget(parent, name)
+//{
+// setBackgroundMode(PaletteBase);
+//}
+
+DubView::DubView(QWidget *parent) : FileSelectorWidget(parent)
+{
+ kdDebug(90010) << "dub view cons" << endl;
+ setBackgroundMode(PaletteBase);
+}
+
+DubView::~DubView()
+{
+}
+
+void DubView::print(QPrinter *pPrinter)
+{
+ QPainter printpainter;
+ printpainter.begin(pPrinter);
+
+ // TODO: add your printing code here
+
+ printpainter.end();
+}
+/** Return item list of view */
+QPtrList<KFileItem>& DubView::items()
+{
+ return const_cast<QPtrList<KFileItem>&>( *dirOperator()->view()->items() );
+}
+
+/** Select a file */
+void DubView::selectFile(KFileItem* file){
+ dirOperator()->view()->setCurrentItem( file );
+ dirOperator()->view()->ensureItemVisible( file );
+}
diff --git a/noatun-plugins/dub/dub/dubview.h b/noatun-plugins/dub/dub/dubview.h
new file mode 100644
index 0000000..c768ca6
--- /dev/null
+++ b/noatun-plugins/dub/dub/dubview.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ dubview.h - description
+ -------------------
+ begin : Tue Oct 23 01:44:51 EEST 2001
+ copyright : (C) 2001 by Eray Ozkural (exa)
+ email : erayo@cs.bilkent.edu.tr
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef DUBVIEW_H
+#define DUBVIEW_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// include files for Qt
+#include <qwidget.h>
+
+#include <fileselectorwidget.h>
+
+// the viewing widget for the playlist
+class DubView : public FileSelectorWidget
+{
+ Q_OBJECT
+ public:
+ /** Constructor for the main view */
+ DubView(QWidget *parent = 0);
+ /** Destructor for the main view */
+ ~DubView();
+
+
+ /** contains the implementation for printing functionality */
+ void print(QPrinter *pPrinter);
+ /** Return item list of view */
+ QPtrList<KFileItem>& items();
+ /** select a particular file */
+ void selectFile(KFileItem* file);
+
+ private:
+
+};
+
+#endif // DUBVIEW_H
diff --git a/noatun-plugins/dub/dub/fileselectorwidget.cpp b/noatun-plugins/dub/dub/fileselectorwidget.cpp
new file mode 100644
index 0000000..153af20
--- /dev/null
+++ b/noatun-plugins/dub/dub/fileselectorwidget.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+ * Copyright (C) 2001 by Hugo Varotto *
+ * hugo@varotto-usa.com *
+ * *
+ * Based on Kate's fileselector widget by *
+ * Matt Newell *
+ * (C) 2001 by Matt Newell *
+ * newellm@proaxis.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version *
+ * *
+ ***************************************************************************/
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qstrlist.h>
+#include <qtooltip.h>
+
+#include <kiconloader.h>
+#include <kurlcombobox.h>
+#include <kurlcompletion.h>
+#include <kprotocolinfo.h>
+#include <kdiroperator.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kcombobox.h>
+
+#include <kdebug.h>
+
+//#include "fileselector_part.h"
+#include "fileselectorwidget.h"
+
+
+FileSelectorWidget::FileSelectorWidget(QWidget *parent)
+ : QWidget(parent, "file selector widget")
+{
+
+ // widgets and layout
+
+ QVBoxLayout* lo = new QVBoxLayout(this);
+
+ QHBox *hlow = new QHBox (this);
+ lo->addWidget(hlow);
+
+ home = new QPushButton( hlow );
+ home->setPixmap(SmallIcon("gohome"));
+ QToolTip::add(home, i18n("Home folder"));
+ up = new QPushButton( /*i18n("&Up"),*/ hlow );
+ up->setPixmap(SmallIcon("up"));
+ QToolTip::add(up, i18n("Up one level"));
+ back = new QPushButton( /*i18n("&Back"),*/ hlow );
+ back->setPixmap(SmallIcon("back"));
+ QToolTip::add(back, i18n("Previous folder"));
+ forward = new QPushButton( /*i18n("&Next"),*/ hlow );
+ forward->setPixmap(SmallIcon("forward"));
+ QToolTip::add(forward, i18n("Next folder"));
+
+ // HACK
+ QWidget* spacer = new QWidget(hlow);
+ hlow->setStretchFactor(spacer, 1);
+ hlow->setMaximumHeight(up->height());
+
+ cmbPath = new KURLComboBox( KURLComboBox::Directories, true, this, "path combo" );
+ cmbPath->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
+ KURLCompletion* cmpl = new KURLCompletion();
+ cmbPath->setCompletionObject( cmpl );
+ lo->addWidget(cmbPath);
+
+ dir = new KDirOperator(QString::null, this, "operator");
+ dir->setView(KFile::Detail);
+ lo->addWidget(dir);
+ lo->setStretchFactor(dir, 2);
+
+ QHBox* filterBox = new QHBox(this);
+ filterIcon = new QLabel(filterBox);
+ filterIcon->setPixmap( BarIcon("filter") );
+ filter = new KHistoryCombo(filterBox, "filter");
+ filter->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
+ filterBox->setStretchFactor(filter, 2);
+ lo->addWidget(filterBox);
+
+ // slots and signals
+
+ connect( filter, SIGNAL( activated(const QString&) ), SLOT( slotFilterChange(const QString&) ) );
+ connect( filter, SIGNAL( returnPressed(const QString&) ),filter, SLOT( addToHistory(const QString&) ) );
+
+ connect( home, SIGNAL( clicked() ), dir, SLOT( home() ) );
+ connect( up, SIGNAL( clicked() ), dir, SLOT( cdUp() ) );
+ connect( back, SIGNAL( clicked() ), dir, SLOT( back() ) );
+ connect( forward, SIGNAL( clicked() ), dir, SLOT( forward() ) );
+
+ connect( cmbPath, SIGNAL( urlActivated( const KURL& )),
+ this, SLOT( cmbPathActivated( const KURL& ) ));
+ connect( cmbPath, SIGNAL( returnPressed( const QString& )),
+ this, SLOT( cmbPathReturnPressed( const QString& ) ));
+ connect(dir, SIGNAL(urlEntered(const KURL&)),
+ this, SLOT(dirUrlEntered(const KURL&)) );
+
+ connect(dir, SIGNAL(finishedLoading()),
+ this, SLOT(dirFinishedLoading()) );
+
+
+ connect(dir, SIGNAL(fileHighlighted(const KFileItem *)),
+ SLOT(fileHighlighted(const KFileItem *)));
+ connect(dir, SIGNAL(fileSelected(const KFileItem *)),
+ SLOT(fileSelected(const KFileItem *)));
+
+ kdDebug(90010) << "connected stuff!" << endl;
+}
+
+
+FileSelectorWidget::~FileSelectorWidget()
+{}
+
+KURL FileSelectorWidget::currentDirectory()
+{
+ return dirLister()->url();
+}
+
+void FileSelectorWidget::slotFilterChange( const QString & nf )
+{
+ dir->setNameFilter( nf );
+ dir->rereadDir();
+}
+
+void FileSelectorWidget::cmbPathActivated( const KURL& u )
+{
+ dir->setURL( u, true );
+}
+
+void FileSelectorWidget::cmbPathReturnPressed( const QString& u )
+{
+ dir->setFocus();
+ dir->setURL( KURL(u), true );
+}
+
+
+void FileSelectorWidget::dirUrlEntered( const KURL& u )
+{
+ cmbPath->removeURL( u );
+ QStringList urls = cmbPath->urls();
+ urls.prepend( u.url() );
+ while ( urls.count() >= (uint)cmbPath->maxItems() )
+ urls.remove( urls.last() );
+ cmbPath->setURLs( urls );
+}
+
+
+void FileSelectorWidget::dirFinishedLoading()
+{
+ // HACK - enable the nav buttons
+ // have to wait for diroperator...
+ up->setEnabled( dir->actionCollection()->action( "up" )->isEnabled() );
+ back->setEnabled( dir->actionCollection()->action( "back" )->isEnabled() );
+ forward->setEnabled( dir->actionCollection()->action( "forward" )->isEnabled() );
+ home->setEnabled( dir->actionCollection()->action( "home" )->isEnabled() );
+}
+
+
+void FileSelectorWidget::focusInEvent(QFocusEvent*)
+{
+ dir->setFocus();
+}
+
+void FileSelectorWidget::setDir( KURL u )
+{
+ dir->setURL(u, true);
+}
+
+void FileSelectorWidget::fileHighlighted(const KFileItem *) {
+ kdDebug(90010) << "file highlighted!" << endl;
+}
+
+void FileSelectorWidget::fileSelected(const KFileItem * ) {
+ kdDebug(90010) << "file selected!" << endl;
+}
+#include "fileselectorwidget.moc"
+
diff --git a/noatun-plugins/dub/dub/fileselectorwidget.h b/noatun-plugins/dub/dub/fileselectorwidget.h
new file mode 100644
index 0000000..724173a
--- /dev/null
+++ b/noatun-plugins/dub/dub/fileselectorwidget.h
@@ -0,0 +1,74 @@
+/*-*-c++-*-*****************************************************************
+ * Copyright (C) 2001 by Bernd Gehrmann bernd@kdevelop.org *
+ * Copyright (C) 2002 by Eray Ozkural erayo@cs.bilkent.edu.tr *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _FILESELECTORWIDGET_H_
+#define _FILESELECTORWIDGET_H_
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qstrlist.h>
+#include <qtooltip.h>
+
+#include <klistview.h>
+#include <qvbox.h>
+#include <qwidget.h>
+#include <kfile.h>
+#include <kurlcombobox.h>
+#include <kurlcompletion.h>
+#include <kcombobox.h>
+#include <kprotocolinfo.h>
+#include <kdiroperator.h>
+
+class DubPlayListItem;
+
+class FileSelectorWidget : public QWidget
+{
+ Q_OBJECT
+
+ friend class DubPlayListItem;
+
+public:
+ FileSelectorWidget(QWidget *parent);
+ ~FileSelectorWidget();
+
+ KDirOperator* dirOperator() {return dir;}
+ KDirLister* dirLister() { return dir->dirLister(); }
+ KURL currentDirectory();
+
+public slots:
+ void slotFilterChange(const QString&);
+ void setDir(KURL);
+
+private slots:
+ void cmbPathActivated( const KURL& u );
+ void cmbPathReturnPressed( const QString& u );
+ void dirUrlEntered( const KURL& u );
+ void dirFinishedLoading();
+ void fileHighlighted(const KFileItem *);
+ void fileSelected(const KFileItem *);
+// void setCurrentDocDir();
+
+protected:
+ void focusInEvent(QFocusEvent*);
+
+private:
+
+ KURLComboBox *cmbPath;
+ KHistoryCombo * filter;
+ QLabel* filterIcon;
+ KDirOperator * dir;
+ QPushButton *home, *up, *back, *forward, *cfdir;
+
+};
+
+#endif
diff --git a/noatun-plugins/dub/dub/random.h b/noatun-plugins/dub/dub/random.h
new file mode 100644
index 0000000..cf2a970
--- /dev/null
+++ b/noatun-plugins/dub/dub/random.h
@@ -0,0 +1,43 @@
+//
+//
+// C++ Interface for module: Random
+//
+// Description:
+//
+//
+// Author: exa
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef Random_Interface
+#define Random_Interface
+
+#include <cstdlib>
+#include <time.h>
+
+// wrapper for random functions
+class Random {
+public:
+ int operator() (int N) {
+ return random_int (N);
+ }
+
+ static void init() {
+ seed += time(0);
+ srandom(seed);
+ }
+ static double random_double (double upper_bound) {
+ return double(random()) * upper_bound / RAND_MAX;
+ }
+
+ static int random_int (int upper_bound) {
+ return random() % upper_bound;
+ }
+private:
+ static int seed;
+};
+
+#endif
+
diff --git a/noatun-plugins/dub/dub/templates/cpp_template b/noatun-plugins/dub/dub/templates/cpp_template
new file mode 100644
index 0000000..9973050
--- /dev/null
+++ b/noatun-plugins/dub/dub/templates/cpp_template
@@ -0,0 +1,15 @@
+//
+//
+// C++ Implementation: |FILENAME|
+//
+// Description:
+//
+//
+// Author: |AUTHOR| <|EMAIL|>, (C) |YEAR|
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+//#include |FILENAME|
+
diff --git a/noatun-plugins/dub/dub/templates/header_template b/noatun-plugins/dub/dub/templates/header_template
new file mode 100644
index 0000000..9ec0a73
--- /dev/null
+++ b/noatun-plugins/dub/dub/templates/header_template
@@ -0,0 +1,21 @@
+//
+//
+// C++ Interface |FILENAME|
+//
+// Description:
+//
+//
+// Author: |AUTHOR|, (C) |YEAR|
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef |FILENAME|_Interface
+#define |FILENAME|_Interface
+
+#include "General.hxx"
+
+
+
+#endif