diff options
Diffstat (limited to 'noatun-plugins/dub')
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>&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 |