001    /**
002     * iFish - An iRiver iHP jukebox database creation tool
003     *
004     * Copyright (C) 2009 Richard "Shred" Körber
005     *   http://ifish.shredzone.org
006     *
007     * This program is free software: you can redistribute it and/or modify
008     * it under the terms of the GNU General Public License as published by
009     * the Free Software Foundation, either version 3 of the License, or
010     * (at your option) any later version.
011     *
012     * This program is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015     * GNU General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
019     */
020    package net.shredzone.ifish;
021    
022    import java.util.Locale;
023    import java.util.prefs.Preferences;
024    
025    import net.shredzone.ifish.i18n.L;
026    
027    /**
028     * This singleton contains iFish global preferences and their default values.
029     *
030     * @author  Richard Körber &lt;dev@shredzone.de&gt;
031     * @version $Id: IFishPrefs.java 291 2009-04-28 21:29:27Z shred $
032     */
033    public class IFishPrefs {
034      public static final String PREFS_DIRECTORY    = "database.dir";
035      public static final String PREFS_COMPATIBILITY = "database.compatibility";
036      public static final String PREFS_CHARSET      = "database.charset";
037      public static final String PREFS_CHARSET_ID3V1 = "database.charset.id3v1";
038      public static final String PREFS_CHARSET_ID3V2 = "database.charset.id3v2";
039      public static final String PREFS_REBUILD      = "database.alwaysrebuild";
040      public static final String PREFS_CHECKDATE    = "database.checkdate";
041      public static final String PREFS_CHECKTRACKS  = "database.checktracks";
042      public static final String PREFS_PL_COMMENT   = "database.playlists";
043      public static final String PREFS_PL_NEW       = "database.pl.newentrant";
044      public static final String PREFS_PL_NAME      = "database.pl.name";
045      public static final String PREFS_PL_BASEDIR   = "database.pl.basedir";
046      public static final String PREFS_DELMAC       = "database.delmac";
047      public static final String PREFS_DIR_RENAME   = "rename.dir.mode";
048      public static final String PREFS_FILE_RENAME  = "rename.file.mode";
049      public static final String PREFS_LAF          = "gui.laf";
050      public static final String PREFS_LANGUAGE     = "gui.language";
051      public static final String PREFS_PLAYER_PLAY  = "player.play";
052      public static final String PREFS_PLAYER_PAUSE = "player.pause";
053      public static final String PREFS_PLAYER_STOP  = "player.stop";
054      public static final String PREFS_FIRSTTIME    = "firsttime";
055      
056      // For backward compatibility reasons, IFishPane is still used as basic
057      // class for the preference node.
058      final static Preferences prefs = java.util.prefs.Preferences.userNodeForPackage( IFishPane.class );
059      private static IFishPrefs instance = null;
060      
061      private IFishPrefs() {}
062      
063      /**
064       * All available languages.
065       */
066      public final static Locale[] LOCALES = new Locale[] {
067        // Please sort in alphabetical sequence of the translated language name!
068        new Locale("cs"),   // Čeština
069        Locale.GERMAN,      // Deutsch
070        Locale.ENGLISH,     // English
071        Locale.FRENCH,      // Français
072      };
073      
074      /**
075       * Get the singleton instance of IFishPrefs.
076       * 
077       * @return  IFishPrefs
078       */
079      public static IFishPrefs instance() {
080        if( instance==null ) {
081          instance = new IFishPrefs();
082        }
083        return instance;
084      }
085      
086      /**
087       * Get the Preferences node that is actually storing the preferences. You
088       * can use the returned object e.g. for adding PreferenceChangeListeners.
089       * 
090       * @return    Preferences node actually storing the preferences.
091       */
092      public Preferences getNode() {
093        return prefs;
094      }
095      
096      /**
097       * Check if this is the first time iFish is used. In this case, a welcome
098       * popup will open after startup.
099       * The default is true.
100       * 
101       * @return  true: first time
102       */
103      public boolean isFirstTime() {
104        return prefs.getBoolean( PREFS_FIRSTTIME, true );
105      }
106      
107      /**
108       * Set if this is the first time iFish is used.
109       * 
110       * @param b   true: first time, false: more than once.
111       */
112      public void setFirstTime( boolean b ) {
113        prefs.putBoolean( PREFS_FIRSTTIME, b );
114      }
115      
116      /**
117       * Get the look and feel to be used.
118       * The default is no look and feel (empty string).
119       * 
120       * @return    Look and Feel, may be empty but never null.
121       */
122      public String getLAF() {
123        return prefs.get( PREFS_LAF, "" );
124      }
125      
126      /**
127       * Set the look and feel to be used.
128       * 
129       * @param laf   Look and Feel, may be empty but never null.
130       */
131      public void setLAF( String laf ) {
132        prefs.put( PREFS_LAF, laf );
133      }
134      
135      /**
136       * Get the language to be used.
137       * 
138       * @return Selected language, null if no special language is selected
139       */
140      public Locale getLanguage() {
141        String lname = prefs.get( PREFS_LANGUAGE, "" );
142        if( lname.length()==0 )
143          return null;
144        return new Locale( lname );
145      }
146      
147      /**
148       * Set the language to be used.
149       * 
150       * @param locale  Locale to be used next time iFish is started. If null
151       *    is passed, iFish will select the language according to the underlying
152       *    OS language next time.
153       */
154      public void setLanguage( Locale locale ) {
155        if( locale==null ) {
156          prefs.put( PREFS_LANGUAGE, "" );
157        }else {
158          prefs.put( PREFS_LANGUAGE, locale.getLanguage() );
159        }
160      }
161      
162      /**
163       * Get the playlist's base directory on the jukebox harddisk.
164       * The default is "ifish".
165       * 
166       * @return  Playlist's base directory.
167       */
168      public String getPLBaseDir() {
169        return prefs.get( PREFS_PL_BASEDIR, "ifish");
170      }
171      
172      /**
173       * Set the playlist's base directory.
174       * 
175       * @param dir   Playlist's base directory.
176       */
177      public void setPLBaseDir( String dir ) {
178        prefs.put( PREFS_PL_BASEDIR, dir );
179      }
180      
181      /**
182       * Get the directory renaming mode.
183       * The default is 0.
184       * 
185       * @return  Directory renaming mode.
186       */
187      public int getDirRename() {
188        return prefs.getInt( PREFS_DIR_RENAME, 0 );
189      }
190      
191      /**
192       * Set the directory renaming more.
193       * 
194       * @param mode    Directory renaming mode.
195       */
196      public void setDirRename( int mode ) {
197        prefs.putInt( PREFS_DIR_RENAME, mode );
198      }
199    
200      /**
201       * Get the file renaming mode.
202       * The default is 3.
203       * 
204       * @return  File renaming mode.
205       */
206      public int getFileRename() {
207        return prefs.getInt( PREFS_FILE_RENAME, 3 );
208      }
209      
210      /**
211       * Set the file renaming more.
212       * 
213       * @param mode    File renaming mode.
214       */
215      public void setFileRename( int mode ) {
216        prefs.putInt( PREFS_FILE_RENAME, mode );
217      }
218      
219      /**
220       * Get the jukebox base directory. This is either the mount point or the
221       * drive letter, depending on the operating system. This may also be any
222       * other directory.
223       * The default is an empty string, meaning that no base directory has been
224       * set yet.
225       * 
226       * @return    Base Directory
227       */
228      public String getDirectory() {
229        return prefs.get( PREFS_DIRECTORY, "" );
230      }
231      
232      /**
233       * Set the jukebox base directory. This is either the mount point or the
234       * drive letter, depending on the operating system. This may also be any
235       * other directory.
236       * 
237       * @param   dir     Base Directory
238       */
239      public void setDirectory( String dir ) {
240        prefs.put( PREFS_DIRECTORY, dir );
241      }
242      
243      /**
244       * Get the play command for the external player. "{}" will be replaced
245       * with the selected files on invocation.
246       * Default is an empty string, meaning that no player command has been set.
247       * 
248       * @return  Play command.
249       */
250      public String getPlayerPlay() {
251        return prefs.get( PREFS_PLAYER_PLAY, "" );
252      }
253      
254      /**
255       * Set the play command for the external player. "{}" will be replaced
256       * with the selected files on invocation.
257       * 
258       * @param cmd   Play command.
259       */
260      public void setPlayerPlay( String cmd ) {
261        prefs.put( PREFS_PLAYER_PLAY, cmd );
262      }
263    
264      /**
265       * Get the pause command for the external player. "{}" will be replaced
266       * with the selected files on invocation.
267       * Default is an empty string, meaning that no player command has been set.
268       * 
269       * @return  Pause command.
270       */
271      public String getPlayerPause() {
272        return prefs.get( PREFS_PLAYER_PAUSE, "" );
273      }
274      
275      /**
276       * Set the pause command for the external player. "{}" will be replaced
277       * with the selected files on invocation.
278       * 
279       * @param cmd   Pause command.
280       */
281      public void setPlayerPause( String cmd ) {
282        prefs.put( PREFS_PLAYER_PAUSE, cmd );
283      }
284    
285      /**
286       * Get the stop command for the external player. "{}" will be replaced
287       * with the selected files on invocation.
288       * Default is an empty string, meaning that no player command has been set.
289       * 
290       * @return  Stop command.
291       */
292      public String getPlayerStop() {
293        return prefs.get( PREFS_PLAYER_STOP, "" );
294      }
295      
296      /**
297       * Set the stop command for the external player. "{}" will be replaced
298       * with the selected files on invocation.
299       * 
300       * @param cmd   Stop command.
301       */
302      public void setPlayerStop( String cmd ) {
303        prefs.put( PREFS_PLAYER_STOP, cmd );
304      }
305      
306      /**
307       * Get the Charset to be used in the database file. This is only used
308       * if the compatibility mode is enabled.
309       * Default is "ISO-8859-1".
310       * 
311       * @return    Charset to be used
312       */
313      public String getCharset() {
314        return prefs.get( PREFS_CHARSET, "ISO-8859-1" );
315      }
316      
317      /**
318       * Set the Charset to be used in the database file. This is only used
319       * if the compatibility mode is enabled.
320       * 
321       * @param charset   Charset to be used
322       */
323      public void setCharset( String charset ) {
324        prefs.put( PREFS_CHARSET, charset );
325      }
326      
327      /**
328       * Get the Charset to be used for reading mp3 tag ID3v1 files.
329       * Defaults to the system's charset, unless it's an UTF charset.
330       * 
331       * @return    Charset to be used
332       */
333      public String getID3v1Charset() {
334        String charset = System.getProperty( "file.encoding", "ISO-8859-1" );
335        if( charset.startsWith("UTF") ) charset = "ISO-8859-1";  // no UTF encoding!
336        return prefs.get( PREFS_CHARSET_ID3V1, charset );
337      }
338      
339      /**
340       * Set the Charset to be used for reading mp3 tag ID3v1 files.
341       * 
342       * @param charset   Charset to be used
343       */
344      public void setID3v1Charset( String charset ) {
345        prefs.put( PREFS_CHARSET_ID3V1, charset );
346      }
347    
348      /**
349       * Get the Charset to be used for reading mp3 tag ID3v2 files that are not
350       * UTF encoded.
351       * Defaults to "ISO-8859-1" since this is the charset mentioned in the ID3
352       * documentation. Anyhow some broken tools also use other charsets there.
353       * 
354       * @return    Charset to be used
355       */
356      public String getID3v2Charset() {
357        return prefs.get( PREFS_CHARSET_ID3V2, "ISO-8859-1" );
358      }
359      
360      /**
361       * Set the Charset to be used for reading mp3 tag ID3v2 files that are not
362       * UTF encoded.
363       * 
364       * @param charset   Charset to be used
365       */
366      public void setID3v2Charset( String charset ) {
367        prefs.put( PREFS_CHARSET_ID3V2, charset );
368      }
369      
370      /**
371       * Check if Compatibility mode is enabled. In this case, the database file
372       * is written in an old format, using the given charset. Otherwise the
373       * database file is always written in UTF-8, which might disturb other
374       * database tools.
375       * Defaults to false.
376       * 
377       * @return  Compatibility mode enabled?
378       */
379      public boolean isCompatibility() {
380        return prefs.getBoolean( PREFS_COMPATIBILITY, false );
381      }
382    
383      /**
384       * Set if Compatibility mode is enabled. In this case, the database file
385       * is written in an old format, using the given charset. Otherwise the
386       * database file is always written in UTF-8, which might disturb other
387       * database tools.
388       * 
389       * @param b   true: enable compatibility mode
390       */
391      public void setCompatibility( boolean b ) {
392        prefs.putBoolean( PREFS_COMPATIBILITY, b );
393      }
394      
395      /**
396       * Check if playlists are to be generated by tag comments.
397       * Defaults to true.
398       * 
399       * @return    Generate playlists by tag comments?
400       */
401      public boolean isPLComment() {
402        return prefs.getBoolean( PREFS_PL_COMMENT, true );
403      }
404      
405      /**
406       * Set if playlists are to be generated by tag comments.
407       * 
408       * @param b   Generate playlists by tag comments
409       */
410      public void setPLComment( boolean b ) {
411        prefs.putBoolean( PREFS_PL_COMMENT, b );
412      }
413    
414      /**
415       * Check if the entire database is always to be recreated. Otherwise only
416       * changes to the files are regarded.
417       * Defaults to false.
418       * 
419       * @return    Rebuild database
420       */
421      public boolean isRebuild() {
422        return prefs.getBoolean( PREFS_REBUILD, false );
423      }
424      
425      /**
426       * Set if the entire database is always to be recreated. Otherwise only
427       * changes to the files are regarded.
428       * 
429       * @param b   Rebuild database
430       */
431      public void setRebuild( boolean b ) {
432        prefs.putBoolean( PREFS_REBUILD, b );
433      }
434      
435      /**
436       * Check if also the file date should be considered to find out if a file
437       * has been changed.
438       * Defaults to true.
439       * 
440       * @return    Check file date for changes.
441       */
442      public boolean isCheckDate() {
443        return prefs.getBoolean( PREFS_CHECKDATE, true );
444      }
445    
446      /**
447       * Set if also the file date should be considered to find out if a file
448       * has been changed.
449       * 
450       * @param b   Check file date for changes.
451       */
452      public void setCheckDate( boolean b ) {
453        prefs.putBoolean( PREFS_CHECKDATE, b );
454      }
455      
456      /**
457       * Check if MacOS X resource fork emulation files are to be deleted.
458       * Defaults to false, since this operation will delete files.
459       * 
460       * @return    Delete MacOS X resource fork emulation files.
461       */
462      public boolean isDelMac() {
463        return prefs.getBoolean( PREFS_DELMAC, false );
464      }
465    
466      /**
467       * Set if MacOS X resource fork emulation files are to be deleted. This will
468       * delete all files starting with "._"!
469       * 
470       * @param b   Delete MacOS X resource fork emulation files.
471       */
472      public void setDelMac( boolean b ) {
473        prefs.putBoolean( PREFS_DELMAC, b );
474      }
475    
476      /**
477       * Check if a playlist about new entrances is to be created.
478       * Defaults to true.
479       * 
480       * @return  Create a playlist about all new entrances.
481       */
482      public boolean isPLNew() {
483        return prefs.getBoolean( PREFS_PL_NEW, true );
484      }
485      
486      /**
487       * Set if a playlist about new entrances is to be created.
488       * 
489       * @param b   true: Create a playlist about all new entrances.
490       */
491      public void setPLNew( boolean b ) {
492        prefs.putBoolean( PREFS_PL_NEW, b );
493      }
494      
495      /**
496       * Check if the tag's track number is to be prepended to the file name.
497       * A track number is only prepended if the file name does not start with
498       * a number.
499       * Defaults to false, since it might rename a large number of files.
500       * 
501       * @return    Prepend the track number.
502       */
503      public boolean isCheckTracks() {
504        return prefs.getBoolean( PREFS_CHECKTRACKS, false );
505      }
506      
507      /**
508       * Set if the tag's track number is to be prepended to the file name.
509       * A track number is only prepended if the file name does not start with
510       * a number.
511       * 
512       * @param b     true: Prepend the track number.
513       */
514      public void setCheckTracks( boolean b ) {
515        prefs.putBoolean( PREFS_CHECKTRACKS, b );
516      }
517      
518      /**
519       * Get the playlist name template for new entrances playlists. "{s}" will
520       * be replaced by the date of the last database update. "{d}" will be
521       * replaced by the current date.
522       * Defaults to a name which is language dependent.
523       * 
524       * @return  Playlist name template.
525       */
526      public String getPLName() {
527        return prefs.get( PREFS_PL_NAME, L.tr("a.syncdb.newplname") );
528      }
529      
530      /**
531       * Get the playlist name template for new entrances playlists. "{s}" will
532       * be replaced by the date of the last database update. "{d}" will be
533       * replaced by the current date.
534       * 
535       * @param name      Playlist name template
536       */
537      public void setPLName( String name ) {
538        prefs.put( PREFS_PL_NAME, name );
539      }
540    
541    }