~ubuntu-branches/ubuntu/wily/lyricue/wily

« back to all changes in this revision

Viewing changes to .pc/manpage-name.patch/src/lyricue

  • Committer: Package Import Robot
  • Author(s): Ilya Barygin
  • Date: 2011-11-06 16:24:28 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20111106162428-o9tmwfr5hbq1884c
Tags: 3.2.1-0ubuntu1
* New upstream release (LP: #389654).
* Packaging based on upstream's PPA:
  - lists of (build-)dependencies updated
  - menu file dropped
  - postinst/postrm scripts removed, lyricue guides setup on first run
  - debian/rules: use dh sequencer
* Generate manpage with pod2man.
* extra-docs.patch: don't install some unneded files.
* manpage-name.patch: make manpage valid.
* desktop.patch: make desktop files valid.
* Convert copyright file to DEP5 format.
* Use source format 3.0 (quilt).
* Update homepage and watch file.
* Bump Standards-Version to 3.9.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env perl
 
2
my $ID = q$Id: lyricue,v 1.403 2010/08/09 05:01:05 cjdebenh Exp $;
 
3
 
 
4
#****** lyricue/pod
 
5
# NAME
 
6
#   Pod documentation
 
7
# DESCRIPTION
 
8
#   Documentation for lyricue that is displayed by perldoc
 
9
# SOURCE
 
10
#
 
11
 
 
12
=head1 NAME
 
13
 
 
14
lyricue
 
15
 
 
16
=head1 SYNOPSIS
 
17
 
 
18
lyricue [-v|-l] [-b] [-r] [-w I<server>] [-d[q]] [-s I<server>]
 
19
 
 
20
=head1 DESCRIPTION
 
21
 
 
22
This application is used to edit/display song lyrics on a second screen/projector for use at singing events such as church services.
 
23
 
 
24
=head1 OPTIONS
 
25
 
 
26
=over 4
 
27
 
 
28
=item B<-v>
 
29
 
 
30
Get lyricue version
 
31
 
 
32
=item B<-d>
 
33
 
 
34
Turn on debugging mode. Prints out debugging information. 
 
35
Use -dq to enable SQL debugging as well
 
36
 
 
37
=item B<-l>
 
38
 
 
39
List available songs. Outputs a list of songs in HTML format
 
40
 
 
41
=item B<-b>
 
42
 
 
43
Turn off background changing ability. Speeds program load
 
44
 
 
45
=item B<-s>
 
46
 
 
47
Set server to connect to for Db and screen
 
48
 
 
49
=item B<-r>
 
50
 
 
51
Set server to connect to for MySQL
 
52
 
 
53
=item B<-w>
 
54
 
 
55
Do not maximize window on startup
 
56
 
 
57
=item B<-i>
 
58
 
 
59
Import song list from a file
 
60
 
 
61
=back
 
62
 
 
63
=head1 CONFIGURATION
 
64
 
 
65
All configuration is done by editing the configuration section in the program
 
66
 
 
67
=head1 REQUIRES
 
68
 
 
69
Perl 5.6 or later, DBI::MySQL, Gtk2-Perl, MySQL database, Clutter-perl, Gstreamer
 
70
 
 
71
=head1 SEE ALSO
 
72
 
 
73
lyricue_server, lyricue_remote
 
74
 
 
75
=head1 AUTHOR
 
76
 
 
77
Chris Debenham <chris@adebenham.com>
 
78
 
 
79
=head1 COPYRIGHT
 
80
 
 
81
This program is released under the GPL (http://www.gnu.org/copyleft/gpl.html)
 
82
 
 
83
=head1 VERSION
 
84
 
 
85
Lyric_interface Version 3.2.1-1
 
86
 
 
87
=cut
 
88
 
 
89
#***
 
90
 
 
91
#****** lyricue/setup
 
92
# NAME
 
93
#   Setup section
 
94
# DESCRIPTION
 
95
#   Loads required modules, sets some global variables,
 
96
#   and other global things
 
97
# SOURCE
 
98
#
 
99
 
 
100
#
 
101
# Modules we use.
 
102
#
 
103
use strict;
 
104
use warnings;
 
105
use DBI;
 
106
use POSIX;
 
107
use locale;
 
108
use IO::Socket::INET;
 
109
use Encode;
 
110
die "The gtk2-perl bindings could not be initialized; we need them to run!\n"
 
111
  unless (Gtk2->init_check);
 
112
use Gtk2::GladeXML;
 
113
use Gtk2::Pango;
 
114
use Gtk2::Gdk::Keysyms;
 
115
use URI::file;
 
116
use XML::Simple;
 
117
use Gnome2;
 
118
use File::Temp qw/tempdir/;
 
119
use File::MimeInfo qw/globs/;
 
120
 
 
121
eval { require Locale::gettext };
 
122
 
 
123
if ($@) {
 
124
    print STDERR "Gettext not available, english text only\n";
 
125
 
 
126
    sub gettext {
 
127
        return $_[0];
 
128
    }
 
129
} else {
 
130
    import Locale::gettext;
 
131
 
 
132
    #my $old_locale = setlocale(LC_ALL);
 
133
    #setlocale(LC_ALL,"sv_SE.UTF-8");
 
134
    textdomain('lyricue');
 
135
 
 
136
    bind_textdomain_codeset('lyricue', "UTF-8");
 
137
}
 
138
binmode(STDOUT, ":utf8");
 
139
binmode(STDERR, ":utf8");
 
140
 
 
141
#
 
142
# Site Configuration.  You should only have to
 
143
# edit this section.
 
144
#
 
145
my ($globals);
 
146
 
 
147
my %lsdvd;
 
148
 
 
149
if ($^O eq 'MSWin32') {
 
150
    $globals->{'etcdir'}   = "etc/lyricue/";
 
151
    $globals->{'basedir'}  = ".lyricue/";
 
152
    $globals->{'sharedir'} = "";
 
153
} else {
 
154
    $globals->{'etcdir'}     = "/etc/lyricue/";
 
155
    $globals->{'basedir'}    = Glib::get_user_data_dir . "/lyricue/";
 
156
    $globals->{'oldbasedir'} = $ENV{'HOME'} . "/.lyricue/";
 
157
    $globals->{'sharedir'}   = "/usr/share/lyricue/";
 
158
}
 
159
 
 
160
#
 
161
# You shouldn't have to change anything after this line
 
162
#
 
163
 
 
164
# convenience variables for true and false
 
165
use constant FALSE => 0;
 
166
use constant TRUE  => 1;
 
167
 
 
168
$globals->{'version'}     = "3.2.1-1";
 
169
$globals->{'accessfile'}  = $globals->{'etcdir'} . "access.conf";
 
170
$globals->{'defaultconf'} = $globals->{'etcdir'} . "default.conf";
 
171
$globals->{'configfile'}  = $globals->{'basedir'} . "config2";
 
172
$globals->{'gladefile'}   = $globals->{'sharedir'} . "lyricue.glade";
 
173
 
 
174
$globals->{'host'}        = "localhost";
 
175
$globals->{'mysqlhost'}   = "";
 
176
$globals->{'lyricdb'}     = "lyricDb";
 
177
$globals->{'bibledb'}     = "";
 
178
$globals->{'biblename'}   = "";
 
179
$globals->{'category'}    = "";
 
180
$globals->{'access'}      = "";
 
181
$globals->{'usesword'}    = TRUE;
 
182
$globals->{'mediadb'}     = "mediaDb";
 
183
$globals->{'sortby'}      = "title";
 
184
$globals->{'bg_previews'} = TRUE;
 
185
if ($^O eq 'MSWin32') {
 
186
    $globals->{'diatheke'} = "";
 
187
} else {
 
188
    $globals->{'diatheke'} = `which diatheke`;
 
189
    chomp $globals->{'diatheke'};
 
190
}
 
191
$globals->{'unoconv'} = `which unoconv`;
 
192
chomp $globals->{'unoconv'};
 
193
$globals->{'convert'} = `which convert`;
 
194
chomp $globals->{'convert'};
 
195
$globals->{'video-thumbnailer'} = `which totem-video-thumbnailer`;
 
196
if ($globals->{'video-thumbnailer'} eq "") {
 
197
    $globals->{'video-thumbnailer'} = `which totem-gstreamer-thumbnailer`;
 
198
}
 
199
if ($globals->{'video-thumbnailer'} eq "") {
 
200
    $globals->{'video-thumbnailer'} = `which totem-video-thumbnailer`;
 
201
}
 
202
chomp $globals->{'video-thumbnailer'};
 
203
$globals->{'lyricue_server'} = `which lyricue_display`;
 
204
if ($globals->{'lyricue_server'} eq "") {
 
205
    $globals->{'lyricue_server'} = `which lyricue_server`;
 
206
}
 
207
chomp $globals->{'lyricue_server'};
 
208
 
 
209
$globals->{'server_port'}        = "2346";    #port used for lyric server
 
210
$globals->{'preview_port'}       = "2347";    #port used for preview
 
211
$globals->{'miniview_port'}      = "2348";    #port used for miniview
 
212
$globals->{'editview_port'}      = "2349";    #port used for editview
 
213
$globals->{'update_timer'}       = FALSE;
 
214
$globals->{'nav_update_timer'}   = FALSE;
 
215
$globals->{'timer'}              = FALSE;
 
216
$globals->{'debugging'}          = FALSE;
 
217
$globals->{'spell'}              = TRUE;
 
218
$globals->{'trayicon'}           = TRUE;
 
219
$globals->{'preview_pid'}        = FALSE;
 
220
$globals->{'miniview_pid'}       = FALSE;
 
221
$globals->{'hovering_over_link'} = FALSE;
 
222
$globals->{'db_adminuser'}       = "";
 
223
$globals->{'current_item'}       = -1;
 
224
$globals->{'icon_width'}         = 96;
 
225
$globals->{'icon_height'}        = 72;
 
226
$globals->{'thumb_width'}        = 128;
 
227
$globals->{'thumb_height'}       = 96;
 
228
$globals->{'firstrun'}           = FALSE;
 
229
 
 
230
# Optional modules
 
231
eval { require Gtk2::Spell };
 
232
if ($@) {
 
233
    print STDERR "Gtk-Spell not available, spell checking turned off\n";
 
234
    $globals->{'spell'} = FALSE;
 
235
} else {
 
236
    import Gtk2::Spell;
 
237
}
 
238
eval { require Gtk2::TrayIcon };
 
239
if ($@) {
 
240
    print STDERR "Gtk-Trayicon not available, Tray icon turned off\n";
 
241
    $globals->{'trayicon'} = FALSE;
 
242
} else {
 
243
    import Gtk2::TrayIcon;
 
244
}
 
245
if ($globals->{'diatheke'} eq "") {
 
246
    $globals->{'diatheke'} = "true";
 
247
}
 
248
 
 
249
# Transitions
 
250
use constant DEFAULT     =>  0;
 
251
use constant NOTRANS     =>  1;
 
252
use constant FADE        =>  2;
 
253
use constant SLIDE_TEXT  =>  3;
 
254
use constant ROTATE_TEXT =>  4;
 
255
 
 
256
# Transition directions
 
257
use constant NONE      => 0;
 
258
use constant WAIT      => 2**0;
 
259
use constant UP        => 2**1;
 
260
use constant DOWN      => 2**2;
 
261
use constant RIGHT     => 2**3;
 
262
use constant LEFT      => 2**4;
 
263
use constant X_AXIS    => 2**5;
 
264
use constant Y_AXIS    => 2**6;
 
265
use constant Z_AXIS    => 2**7;
 
266
use constant NUM_TRANS => 8;
 
267
 
 
268
# Quick globals
 
269
my $config;
 
270
my $widgets;
 
271
my $bibleMenu;
 
272
my @ASSOCIATE;
 
273
my %pageOrder;
 
274
my %selectedimages;
 
275
my ($lyricDbh, $mediaDbh, $bibleDbh);
 
276
 
 
277
my ($errorcodes);
 
278
$errorcodes->{'lyricdbopen'} = fromutf(
 
279
    gettext(
 
280
"I'm sorry but I could not open the lyric database.\nPlease confirm that Lyricue is installed correctly and MySQL is running"
 
281
    )
 
282
);
 
283
$errorcodes->{'bibledbopen'} = fromutf(
 
284
    gettext(
 
285
"I'm sorry but I could not open the bible database.\nPlease confirm that Lyricue is installed correctly and the current bible database exists.\nThe requested database was named "
 
286
    )
 
287
);
 
288
$errorcodes->{'mediadbopen'} = fromutf(
 
289
    gettext(
 
290
"I'm sorry but I could not open the media database.\nPlease confirm that Lyricue is installed correctly and MySQL is running"
 
291
    )
 
292
);
 
293
$errorcodes->{'sqlprepare'} =
 
294
  fromutf(gettext("Unable to prepare query.\nHas mysql died?"));
 
295
$errorcodes->{'sqlexecute'} =
 
296
  fromutf(gettext("Unable to execute query.\nHas mysql died?"));
 
297
$errorcodes->{'socketopen'} = fromutf(
 
298
    gettext(
 
299
"Sorry, I was unable to listen on the network.\nPlease make sure I am not already running"
 
300
    )
 
301
);
 
302
$errorcodes->{'erroropen'}    = fromutf(gettext("Could not open "));
 
303
$errorcodes->{'fileopenread'} = fromutf(
 
304
    gettext(
 
305
"Unable to read the file, are you sure it exists?\nThe file asked for was "
 
306
    )
 
307
);
 
308
$errorcodes->{'fileopenwrite'} = fromutf(
 
309
    gettext(
 
310
"Unable to write to the file, you may not have sufficent permissions.\nPlease check the permissions for "
 
311
    )
 
312
);
 
313
$errorcodes->{'usage'} = fromutf(
 
314
    gettext(
 
315
            "\nUsage: lyricue <-v|-l> <-b> <-k> <-d> <-s>\n\n"
 
316
          . "\t-v:  Prints Lyricue version information & exits\n"
 
317
          . "\t-l:  Outputs song list in HTML & exits\n"
 
318
          . "\t-b:  Loads Lyricue without background previews\n"
 
319
          . "\t-s:  Specify the host on which the lyric server is located\n"
 
320
          . "\t-r:  Specify the host on which the mysql server is located\n"
 
321
          . "\t-d:  Prints debugging messages\n"
 
322
          . "\t-w:  Don't maximize on startup\n"
 
323
          . "\t-i:  Import songlist from file\n\n"
 
324
    )
 
325
);
 
326
 
 
327
$errorcodes->{'nobible'} =
 
328
  fromutf(
 
329
    gettext("No bible has been selected\n" . "Please select one from the menu")
 
330
  );
 
331
 
 
332
# Widgets affected by access controls
 
333
# access 'e'
 
334
my @edit_items = (
 
335
    "buttonMainAdd", "buttonMainEdit", "add_song1", "edit_song1",
 
336
    "buttonQuickSave"
 
337
);
 
338
 
 
339
# access 'd'
 
340
my @delete_items = ("delete_song1");
 
341
 
 
342
# access 's'
 
343
my @display_items = (
 
344
    "previous_page1",  "next_page1",
 
345
    "display_now1",    "blank_display1",
 
346
    "buttonMainPrev",  "buttonMainNext",
 
347
    "buttonMainPoint", "buttonMainBlank",
 
348
    "notebookRight",   "buttonQuickShow",
 
349
    "buttonMainClear", "clear_text1"
 
350
);
 
351
 
 
352
# access 'p'
 
353
my @playlist_items = (
 
354
    "buttonAddToPlaylist", "playlist1",
 
355
    "vboxMainRight",       "buttonMainImage",
 
356
    "buttonMainVerse",     "buttonMainSublist"
 
357
);
 
358
 
 
359
# access 'a'
 
360
my @admin_items = ("user_administration1");
 
361
 
 
362
#***
 
363
 
 
364
#****** lyricue/main_code
 
365
# NAME
 
366
#   main_code - main code section, not in subroutine
 
367
# SYNOPSIS
 
368
#   No output
 
369
# FUNCTION
 
370
#   Figure out where to go
 
371
# INPUTS
 
372
#   Commandline
 
373
# OUTPUT
 
374
#   Everything
 
375
# SOURCE
 
376
#
 
377
if ($ARGV[0]) {
 
378
    foreach (0 .. (@ARGV - 1)) {
 
379
        if ($ARGV[$_] eq "-v") {
 
380
            print "Lyric Interface version " . $globals->{'version'} . "\n";
 
381
            exit;
 
382
        } elsif ($ARGV[$_] eq "-l") {
 
383
            print_songs();
 
384
        } elsif ($ARGV[$_] eq "-b") {
 
385
            $globals->{'bg_previews'} = FALSE;
 
386
        } elsif ($ARGV[$_] eq "-d") {
 
387
            $globals->{'debugging'} = 2;
 
388
        } elsif ($ARGV[$_] eq "-dq") {
 
389
            $globals->{'debugging'} = 2;
 
390
        } elsif ($ARGV[$_] eq "-sqlite") {
 
391
            $globals->{'force_sqlite'} = TRUE;
 
392
        } elsif ($ARGV[$_] eq "-w") {
 
393
            $globals->{'run_windowed'} = TRUE;
 
394
        } elsif ($ARGV[$_] eq "-s") {
 
395
            $globals->{'host'} = $ARGV[$_ + 1];
 
396
            $ARGV[$_ + 1] = "";
 
397
        } elsif ($ARGV[$_] eq "-r") {
 
398
            $globals->{'mysqlhost'} = $ARGV[$_ + 1];
 
399
            $ARGV[$_ + 1] = "";
 
400
        } elsif ($ARGV[$_] eq "-i") {
 
401
            import_song_from_file($ARGV[$_ + 1]);
 
402
            exit;
 
403
        } elsif ($ARGV[$_] eq "") {
 
404
 
 
405
            # ignore
 
406
        } else {
 
407
            print $errorcodes->{'usage'};
 
408
            exit;
 
409
        }
 
410
    }
 
411
}
 
412
 
 
413
# Set mysql host if not already set
 
414
if ($globals->{'mysqlhost'} eq "") {
 
415
    $globals->{'mysqlhost'} = $globals->{'host'};
 
416
}
 
417
 
 
418
# Some global stuff
 
419
my ($query, $row, $sth, $rv);
 
420
 
 
421
# Set umask
 
422
umask 0002;
 
423
 
 
424
# Check if user ~/.local/share/lyricue directory exists, otherwire create
 
425
if (-e $globals->{'basedir'}) {
 
426
    if (!-d $globals->{'basedir'}) {
 
427
        print STDERR
 
428
"Old ~/.local/share/lyricue existed but was not a directory, moving to ~/.local/share/lyricue.orig\n";
 
429
        rename $globals->{'basedir'}, $globals->{'basedir'} . ".orig";
 
430
        mkdir $globals->{'basedir'}, 0777;
 
431
    }
 
432
} else {
 
433
    if (-e $globals->{'oldbasedir'}) {
 
434
        my $movexml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
435
            'dialogConfirm', 'lyricue');
 
436
        $movexml->signal_autoconnect_from_package('');
 
437
        $movexml->get_widget('labelDelete')->set_text(
 
438
            fromutf(
 
439
                gettext(
 
440
"The directory used to hold configuration files has changed\n"
 
441
                      . "It is now ~/.local/share/lyricue\n"
 
442
                      . "If you do not wish to do this press Cancel and Lyricue will exit"
 
443
                )
 
444
            )
 
445
        );
 
446
        my $confirm = $movexml->get_widget('dialogConfirm')->run();
 
447
        if ($confirm eq "ok") {
 
448
            debug("Migrating lyricue configuration");
 
449
            system("mkdir -p " . $globals->{'basedir'});
 
450
            system( "cp -r "
 
451
                  . $globals->{'oldbasedir'} . "/* "
 
452
                  . $globals->{'basedir'});
 
453
            close_dialog($movexml->get_widget('dialogConfirm'));
 
454
        } else {
 
455
            print STDERR "Exiting as we are not migrating configuration";
 
456
            exit;
 
457
        }
 
458
    } else {
 
459
        system("mkdir -p " . $globals->{'basedir'});
 
460
    }
 
461
}
 
462
 
 
463
# Setup logging
 
464
my $logname = $globals->{'basedir'} . "/frontend.log";
 
465
rename($logname, $logname . ".old")
 
466
  or system("mv", $logname, $logname . ".old");
 
467
open(LOG, ">" . $logname);
 
468
binmode LOG, ":utf8";
 
469
debug("Lyric Interface version " . $globals->{'version'} . "\n" . $ID);
 
470
$widgets->{'main'} =
 
471
  Gtk2::GladeXML->new($globals->{'gladefile'}, 'windowMain', 'lyricue');
 
472
$widgets->{'main'}->signal_autoconnect_from_package('');
 
473
 
 
474
# Load the config file
 
475
if (-d $globals->{'basedir'}) {
 
476
    if (!-e $globals->{'configfile'}) {
 
477
        debug("Creating new configuration");
 
478
        system(
 
479
            "cp " . $globals->{'defaultconf'} . " " . $globals->{'configfile'});
 
480
        $config = load_config();
 
481
        $globals->{'firstrun'} = TRUE;
 
482
        firstrun_wizard();
 
483
        Gtk2->main();
 
484
        $globals->{'firstrun'} = FALSE;
 
485
    } else {
 
486
        debug("Loading config and access");
 
487
        $config = load_config();
 
488
    }
 
489
    $globals->{'access'} = load_access();
 
490
 
 
491
    # Open lyricDB, bibleDB and mediaDb
 
492
    db_select();
 
493
    write_config(TRUE);
 
494
}
 
495
 
 
496
if (defined $config->{'DefBible'} && ($config->{'DefBible'} ne "")) {
 
497
    my @tmpbible = split(/;/, $config->{'DefBible'}, 2);
 
498
    $globals->{'biblename'} = $tmpbible[1];
 
499
    @tmpbible = split(/:/, $tmpbible[0], 2);
 
500
    do_change_bible($tmpbible[1], $tmpbible[0]);
 
501
}
 
502
 
 
503
# Create tray icon
 
504
if ($globals->{'trayicon'}) {
 
505
    debug("Creating Tray icons");
 
506
    foreach
 
507
      my $trayicon ('trayClear', 'trayDown', 'trayUp', 'trayRight', 'trayLeft')
 
508
    {
 
509
        my ($tray);
 
510
        eval { $tray = Gtk2::TrayIcon->new("Lyricue-" . $trayicon); };
 
511
        if ($@) {
 
512
            debug("Unable to load system tray");
 
513
        } else {
 
514
            my $trayxml =
 
515
              Gtk2::GladeXML->new($globals->{'gladefile'}, $trayicon,
 
516
                'lyricue');
 
517
            $trayxml->signal_autoconnect_from_package('');
 
518
            $tray->add($trayxml->get_widget($trayicon));
 
519
            $tray->show_all;
 
520
        }
 
521
    }
 
522
}
 
523
$0 = "Lyricue Interface";
 
524
 
 
525
$globals->{'thumbnail_factory'} = Gnome2::ThumbnailFactory->new('normal');
 
526
init_mainWindow();
 
527
$widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data} = -1;
 
528
choose_playlist();
 
529
 
 
530
# Don't let them cancel out of the playlist chooser yet
 
531
$widgets->{'main'}->get_widget('toolbuttonPlayCancel')->hide;
 
532
 
 
533
# Setup background tasks
 
534
$globals->{'tracker_timer'} = Glib::Timeout->add(1000, \&check_tracker);
 
535
$globals->{'clean_idle'} = Glib::Idle->add(\&clean_database);
 
536
 
 
537
Gtk2->main();
 
538
 
 
539
# Should never get here
 
540
exit(0);
 
541
 
 
542
#***
 
543
 
 
544
#****f* lyricue/close_main
 
545
# NAME
 
546
#   close_main
 
547
# SYNOPSIS
 
548
#   close_main ()
 
549
# FUNCTION
 
550
#   Callback function to close the window
 
551
# INPUTS
 
552
#   none
 
553
# OUTPUT
 
554
#   Closes the interface
 
555
# SOURCE
 
556
#
 
557
sub close_main {
 
558
    debug("Quitting");
 
559
    do_pending();
 
560
 
 
561
    # Save current state
 
562
    unlink $globals->{'configfile'} . ".bak";
 
563
    open(CONFIG, "$globals->{'configfile'}")
 
564
      || display_fatal($errorcodes->{'fileopenread'}, $! . "\nSQL: " . $query);
 
565
    my $config = "";
 
566
    binmode(CONFIG, ":utf8");
 
567
    while (<CONFIG>) {
 
568
        if (!/^Frame/) {
 
569
            $config .= $_;
 
570
        }
 
571
    }
 
572
    close CONFIG;
 
573
    rename($globals->{'configfile'}, $globals->{'configfile'} . ".bak");
 
574
    open(CONFIG, ">$globals->{'configfile'}")
 
575
      || display_fatal($errorcodes->{'fileopenwrite'}, $! . "\nSQL: " . $query);
 
576
    binmode(CONFIG, ":utf8");
 
577
    print CONFIG $config;
 
578
    print CONFIG save_state();
 
579
    close CONFIG;
 
580
 
 
581
    $lyricDbh->disconnect;
 
582
    if (!$globals->{'usesword'}) {
 
583
        $bibleDbh->disconnect;
 
584
    }
 
585
    $mediaDbh->disconnect;
 
586
    Gtk2->main_quit;
 
587
    if ($globals->{'preview_pid'}) {
 
588
        debug("Killing $globals->{'preview_pid'}");
 
589
        kill 9, $globals->{'preview_pid'};
 
590
    }
 
591
    if ($globals->{'miniview_pid'}) {
 
592
        debug("Killing $globals->{'miniview_pid'}");
 
593
        kill 9, $globals->{'miniview_pid'};
 
594
    }
 
595
    close LOG;
 
596
    exit();
 
597
    return FALSE;
 
598
}
 
599
 
 
600
#***
 
601
 
 
602
#****f* lyricue/update_playlist
 
603
# NAME
 
604
#   update_playlist
 
605
# SYNOPSIS
 
606
#   update_playlist($selectedid)
 
607
# FUNCTION
 
608
#   Clear the playlist area and redisplay with updated info
 
609
# INPUTS
 
610
#   $selectedid - Currently selected item
 
611
# OUTPUT
 
612
#   refreshed playlist
 
613
# SOURCE
 
614
#
 
615
sub update_playlist {
 
616
    my ($selectedid) = @_;
 
617
    debug("Updating playlist");
 
618
    if (!defined $selectedid) {
 
619
        my $selection =
 
620
          $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
621
        if ($selection) {
 
622
            my ($m, $i) = $selection->get_selected;
 
623
            if ($m) {
 
624
                $selectedid = $m->get($i, 2);
 
625
            }
 
626
        }
 
627
    }
 
628
 
 
629
    my $playlist =
 
630
      $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
631
 
 
632
    my ($expanded);
 
633
    my $model = $widgets->{'main'}->get_widget('treePlaylist')->get_model();
 
634
    if ($model) {
 
635
        $widgets->{'main'}->get_widget('treePlaylist')
 
636
          ->map_expanded_rows(\&save_expanded, \$expanded);
 
637
        $model->clear;
 
638
    } else {
 
639
 
 
640
        # Column 1 -> Visible text
 
641
        # Column 2 -> Colour
 
642
        # Column 3 -> playorder
 
643
        # Column 4 -> transition
 
644
        $model =
 
645
          Gtk2::TreeStore->new('Glib::String', 'Glib::String', 'Glib::String',
 
646
            'Glib::String');
 
647
        $widgets->{'main'}->get_widget('treePlaylist')->set_model($model);
 
648
        my $column = Gtk2::TreeViewColumn->new_with_attributes(
 
649
            "",
 
650
            Gtk2::CellRendererText->new,
 
651
            markup     => 0,
 
652
            background => 1
 
653
        );
 
654
        $widgets->{'main'}->get_widget('treePlaylist')->append_column($column);
 
655
 
 
656
        $widgets->{'main'}->get_widget('treePlaylist')->set_model($model);
 
657
    }
 
658
    add_playlist($playlist, undef, $model, $selectedid, \$expanded);
 
659
    $globals->{'current_item'} = 0;
 
660
}
 
661
 
 
662
#***
 
663
 
 
664
#****f* lyricue/add_playlist
 
665
# NAME
 
666
#   add_playlist - Add a playlist to the playlist area
 
667
# SYNOPSIS
 
668
#   add_playlist ($playlist, $iter, $model, $selectedid, $expanded)
 
669
# FUNCTION
 
670
#   Add a playlist to the playlist area
 
671
# INPUTS
 
672
#   $playlist - Playlist to add
 
673
#   $iter - Where to add it in the playlist area
 
674
#   $model - The playlist tree model
 
675
#   $selectedid - The currently selected item
 
676
#   $expanded - A lookup of all items saying which are expanded
 
677
# OUTPUT
 
678
#   A bigger playlist
 
679
# SOURCE
 
680
#
 
681
sub add_playlist {
 
682
    my ($playlist, $iter, $model, $selectedid, $expanded) = @_;
 
683
    debug("Add playlist " . $playlist);
 
684
    my $query =
 
685
        "SELECT * FROM playlist WHERE playlist="
 
686
      . $playlist
 
687
      . " ORDER BY playorder";
 
688
 
 
689
    #qdebug($query);
 
690
    my $sth = $lyricDbh->prepare($query)
 
691
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
692
    my $rv = $sth->execute
 
693
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
694
    while (my $row = $sth->fetchrow_hashref()) {
 
695
 
 
696
        my $title = "";
 
697
        if ($row->{'type'} eq "back") {
 
698
            my $query2 = "SELECT description FROM media WHERE id=\""
 
699
              . $row->{'data'} . "\"";
 
700
 
 
701
            #qdebug($query2);
 
702
            my $sth2 = $mediaDbh->prepare($query2)
 
703
              || display_fatal($errorcodes->{'sqlprepare'},
 
704
                $! . "\nSQL: " . $query2);
 
705
            my $rv2 = $sth2->execute
 
706
              || display_fatal($errorcodes->{'sqlexecute'},
 
707
                $! . "\nSQL: " . $query2);
 
708
            my $row2 = $sth2->fetchrow_hashref();
 
709
            $title = "Background : " . $row2->{'description'};
 
710
        } elsif ($row->{'type'} eq "file") {
 
711
            $_ = $row->{'data'};
 
712
            if (/^(.*)\/(.*?)$/) {
 
713
                my $filename = $2;
 
714
                my $dir      = $1;
 
715
                if ($dir =~ /^\/var\/tmp\/lyricue-/) {
 
716
                    $filename =~ s/\..*?$//g;
 
717
                    $filename =~ s/_/ /g;
 
718
                    $title = "Presentation: " . $filename;
 
719
                } elsif ($dir =~ /^dvd:/) {
 
720
                    if ($filename =~ / /) {
 
721
                        $filename =~ s/ / from /;
 
722
                    }
 
723
                    $title = "DVD Title: " . $filename;
 
724
                } else {
 
725
                    $title = "File: " . $filename . " in " . $dir;
 
726
                }
 
727
            } else {
 
728
                $title = "File: " . $row->{'data'};
 
729
            }
 
730
        } elsif ($row->{'type'} eq "imag") {
 
731
            my ($type, $id) = split /;/, $row->{'data'};
 
732
            if (!defined $id) {
 
733
                $id   = $type;
 
734
                $type = "db";
 
735
            }
 
736
            if ($type eq "dir") {
 
737
                $id =~ s/^$config->{'ImageDirectory'}\///;
 
738
                $title = "Image: " . $id;
 
739
            } else {
 
740
                my $query2 =
 
741
                  "SELECT description FROM media WHERE id=\"" . $id . "\"";
 
742
 
 
743
                #qdebug($query2);
 
744
                my $sth2 = $mediaDbh->prepare($query2)
 
745
                  || display_fatal($errorcodes->{'sqlprepare'},
 
746
                    $! . "\nSQL: " . $query2);
 
747
                my $rv2 = $sth2->execute
 
748
                  || display_fatal($errorcodes->{'sqlexecute'},
 
749
                    $! . "\nSQL: " . $query2);
 
750
                my $row2 = $sth2->fetchrow_hashref();
 
751
                $title = "Image: " . $row2->{'description'};
 
752
            }
 
753
        } elsif ($row->{'type'} eq "vers") {
 
754
            $title = "Verses " . $row->{'data'};
 
755
        } elsif ($row->{'type'} eq "song") {
 
756
            my $query2 = "SELECT pagetitle, lyrics FROM page WHERE pageid="
 
757
              . $row->{'data'};
 
758
 
 
759
            #qdebug($query2);
 
760
            my $sth2 = $lyricDbh->prepare($query2)
 
761
              || display_fatal($errorcodes->{'sqlprepare'},
 
762
                $! . "\nSQL: " . $query);
 
763
            my $rv2 = $sth2->execute
 
764
              || display_fatal($errorcodes->{'sqlexecute'},
 
765
                $! . "\nSQL: " . $query);
 
766
            my $row2   = $sth2->fetchrow_hashref();
 
767
            my $lyrics = $row2->{'lyrics'};
 
768
            if ($globals->{'invert'}) {
 
769
                my @lyricl = split(/\n/, $lyrics);
 
770
                $title = $lyricl[@lyricl - 1];
 
771
            } else {
 
772
                ($title, undef) = split(/\n/, $lyrics);
 
773
            }
 
774
            if (defined $row2->{'pagetitle'} && ($row2->{'pagetitle'} ne '')) {
 
775
                $title = "<b>" . $row2->{'pagetitle'} . "</b>\n" . $title;
 
776
            }
 
777
            if (!$title) {
 
778
                $title = "";
 
779
            }
 
780
        } elsif ($row->{'type'} eq "play" | $row->{'type'} eq "sub") {
 
781
 
 
782
            my $query2 = "SELECT * FROM playlists WHERE id=" . $row->{'data'};
 
783
 
 
784
            #qdebug($query2);
 
785
            my $sth2 = $lyricDbh->prepare($query2)
 
786
              || display_fatal($errorcodes->{'sqlprepare'},
 
787
                $! . "\nSQL: " . $query);
 
788
            my $rv2 = $sth2->execute
 
789
              || display_fatal($errorcodes->{'sqlexecute'},
 
790
                $! . "\nSQL: " . $query);
 
791
            my $row2 = $sth2->fetchrow_hashref();
 
792
 
 
793
            $title = $row2->{'title'};
 
794
 
 
795
            if ($row2->{'ref'} && $row2->{'ref'} != 0) {
 
796
                $query2 =
 
797
                  "SELECT songnum FROM lyricMain WHERE id=" . $row2->{'ref'};
 
798
 
 
799
                #qdebug($query2);
 
800
                $sth2 = $lyricDbh->prepare($query2)
 
801
                  || display_fatal($errorcodes->{'sqlprepare'},
 
802
                    $! . "\nSQL: " . $query2);
 
803
                $rv2 = $sth2->execute
 
804
                  || display_fatal($errorcodes->{'sqlexecute'},
 
805
                    $! . "\nSQL: " . $query2);
 
806
                $row2 = $sth2->fetchrow_hashref();
 
807
                if ($row2->{'songnum'} != 0) {
 
808
                    $title = $row2->{'songnum'} . " - " . $title;
 
809
                }
 
810
            }
 
811
        } else {
 
812
            $title = "Unknown type";
 
813
        }
 
814
 
 
815
        # Add image name to playlist item title
 
816
        my $query3 =
 
817
          "SELECT * FROM associations WHERE playlist=" . $row->{'playorder'};
 
818
 
 
819
        #qdebug($query3);
 
820
        my $sth3 = $lyricDbh->prepare($query3)
 
821
          || display_fatal($errorcodes->{'sqlprepare'},
 
822
            $! . "\nSQL: " . $query3);
 
823
        my $rv3 = $sth3->execute
 
824
          || display_fatal($errorcodes->{'sqlexecute'},
 
825
            $! . "\nSQL: " . $query3);
 
826
        my $imagename = "";
 
827
        while (my $row3 = $sth3->fetchrow_hashref()) {
 
828
            $imagename = $row3->{'imagename'};
 
829
        }
 
830
 
 
831
        my $playorder = $row->{'playorder'};
 
832
        my $newiter   = $model->append($iter);
 
833
        $title =~ s/&/&amp;/g;
 
834
        $model->set(
 
835
            $newiter,
 
836
            0 => $title,
 
837
            1 => undef,
 
838
            2 => $row->{'playorder'},
 
839
            3 => $row->{'transition'}
 
840
        );
 
841
 
 
842
        # Set sub-item if image associated
 
843
 
 
844
        if ($imagename) {
 
845
            my ($type, $id) = split /;/, $imagename;
 
846
            if ($type eq "db") {
 
847
                my $query2 =
 
848
                  "SELECT description FROM media WHERE id=\"" . $id . "\"";
 
849
 
 
850
                #qdebug($query2);
 
851
                my $sth2 = $mediaDbh->prepare($query2)
 
852
                  || display_fatal($errorcodes->{'sqlprepare'},
 
853
                    $! . "\nSQL: " . $query2);
 
854
                my $rv2 = $sth2->execute
 
855
                  || display_fatal($errorcodes->{'sqlexecute'},
 
856
                    $! . "\nSQL: " . $query2);
 
857
                my $row2    = $sth2->fetchrow_hashref();
 
858
                my $imgiter = $model->append($newiter);
 
859
                $model->set(
 
860
                    $imgiter,
 
861
                    0 => "* Background: " . $row2->{'description'},
 
862
                    1 => "",
 
863
                    2 => $row->{'playorder'},
 
864
                    3 => $row->{'transition'}
 
865
                );
 
866
            } else {
 
867
                my $imgiter = $model->append($newiter);
 
868
                $id =~ s/^$config->{'BGDirectory'}//g;
 
869
                $model->set(
 
870
                    $imgiter,
 
871
                    0 => "* Background: " . $id,
 
872
                    1 => "",
 
873
                    2 => $row->{'playorder'},
 
874
                    3 => $row->{'transition'}
 
875
                );
 
876
            }
 
877
        }
 
878
 
 
879
        # Set sub-item if transition associated
 
880
        if (($row->{'transition'} >> (NUM_TRANS*2)) != 0) {
 
881
            my $transiter = $model->append($newiter);
 
882
            $model->set(
 
883
                $transiter,
 
884
                0 => "* Page Transition Set",
 
885
                1 => "",
 
886
                2 => $row->{'playorder'},
 
887
                3 => $row->{'transition'}
 
888
            );
 
889
        }
 
890
 
 
891
        # Add sublists/playlists
 
892
        if ($row->{'type'} eq "play" | $row->{'type'} eq "sub") {
 
893
            add_playlist($row->{'data'}, $newiter, $model, $selectedid,
 
894
                $expanded);
 
895
        }
 
896
 
 
897
        if ($$expanded->{$playorder}) {
 
898
            $widgets->{'main'}->get_widget('treePlaylist')
 
899
              ->expand_to_path($model->get_path($newiter));
 
900
        }
 
901
 
 
902
        # Select what was selected and expand its parent
 
903
        if (defined $selectedid && $row->{'playorder'} == $selectedid) {
 
904
            debug("Selecting $selectedid");
 
905
            my $path       = $model->get_path($newiter);
 
906
            my $pathstring = $path->to_string();
 
907
            $pathstring =~ s/^(.*):(.*?)$/$1/g;
 
908
            if (defined($2)) {
 
909
                $widgets->{'main'}->get_widget('treePlaylist')
 
910
                  ->expand_to_path(
 
911
                    Gtk2::TreePath->new_from_string($pathstring));
 
912
            }
 
913
            $widgets->{'main'}->get_widget('treePlaylist')
 
914
              ->get_selection->select_iter($newiter);
 
915
        }
 
916
    }
 
917
}
 
918
 
 
919
#***
 
920
 
 
921
#****f* lyricue/save_expanded
 
922
# NAME
 
923
#   save_expanded
 
924
# SYNOPSIS
 
925
#   save_expanded($tree, $path, $expanded)
 
926
# FUNCTION
 
927
#   Save the expanded state of the treeview item
 
928
# INPUTS
 
929
#   $tree - Treeview to save state of
 
930
#   $part - Item to check
 
931
#   $expanded - state lookup
 
932
# OUTPUT
 
933
#   $expanded is updated
 
934
# SOURCE
 
935
#
 
936
sub save_expanded {
 
937
    debug("Save expanded");
 
938
    my ($tree, $path, $expanded) = @_;
 
939
    my $iter = $tree->get_model->get_iter($path);
 
940
    $$expanded->{$tree->get_model->get($iter, 2)} = TRUE;
 
941
    return FALSE;
 
942
}
 
943
 
 
944
#***
 
945
 
 
946
#****f* lyricue/change_sort_order
 
947
# NAME
 
948
#   change_sort_order
 
949
# SYNOPSIS
 
950
#   change_sort_order (undef,$column)
 
951
# FUNCTION
 
952
#   Change the order by which the available songs are displayed
 
953
# INPUTS
 
954
#   undef - not used
 
955
#   $column - which column to order by
 
956
# OUTPUT
 
957
#   Calls update_available to redisplay available songs
 
958
# SOURCE
 
959
#
 
960
sub change_sort_order {
 
961
    debug("change sort order");
 
962
    my (undef, $column) = @_;
 
963
    if ($column == 1) {
 
964
        $globals->{'sortby'} = "book";
 
965
    } elsif ($column == 2) {
 
966
        $globals->{'sortby'} = "songnum";
 
967
    } elsif ($column == 3) {
 
968
        $globals->{'sortby'} = "id";
 
969
    } elsif ($column == 4) {
 
970
        $globals->{'sortby'} = "book,songnum,title";
 
971
    } elsif ($column == 5) {
 
972
        $globals->{'sortby'} = "book,title";
 
973
    } else {
 
974
        $globals->{'sortby'} = "title";
 
975
    }
 
976
    debug("Changing sort order to " . $globals->{'sortby'});
 
977
    update_available();
 
978
}
 
979
 
 
980
#***
 
981
 
 
982
#****f* lyricue/update_available
 
983
# NAME
 
984
#   update_available
 
985
# SYNOPSIS
 
986
#   update_available ()
 
987
# FUNCTION
 
988
#   Update the list of available songs, limited by keyword and sorted by orderby
 
989
# OUTPUT
 
990
#   updated list of available songs
 
991
# SOURCE
 
992
#
 
993
sub update_available {
 
994
    debug("update available");
 
995
    reset_timer($globals->{'update_timer'});
 
996
 
 
997
    my $store =
 
998
      Gtk2::ListStore->new('Glib::String', 'Glib::String', 'Glib::Uint',
 
999
        'Glib::Uint');
 
1000
 
 
1001
    if (
 
1002
        $widgets->{'main'}->get_widget('treeAvailable')->{user_data}
 
1003
        && ($widgets->{'main'}->get_widget('treeAvailable')->{user_data} eq
 
1004
            "load")
 
1005
      )
 
1006
    {
 
1007
        $widgets->{'main'}->get_widget('treeAvailable')->{data} = ();
 
1008
    } else {
 
1009
        $widgets->{'main'}->get_widget('treeAvailable')->{user_data} = "load";
 
1010
        my $column1 =
 
1011
          Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Title")),
 
1012
            Gtk2::CellRendererText->new, text => 0);
 
1013
        my $column2 =
 
1014
          Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Book")),
 
1015
            Gtk2::CellRendererText->new, text => 1);
 
1016
        my $column3 = Gtk2::TreeViewColumn->new_with_attributes(
 
1017
            fromutf(gettext("Song Number")),
 
1018
            Gtk2::CellRendererText->new, text => 2);
 
1019
        $column1->set_resizable(TRUE);
 
1020
        $column2->set_resizable(TRUE);
 
1021
        $column3->set_resizable(TRUE);
 
1022
        $widgets->{'main'}->get_widget('treeAvailable')
 
1023
          ->append_column($column1);
 
1024
        $widgets->{'main'}->get_widget('treeAvailable')
 
1025
          ->append_column($column2);
 
1026
        $widgets->{'main'}->get_widget('treeAvailable')
 
1027
          ->append_column($column3);
 
1028
        $column1->signal_connect("clicked", "change_sort_order", 0);
 
1029
        $column2->signal_connect("clicked", "change_sort_order", 1);
 
1030
        $column3->signal_connect("clicked", "change_sort_order", 2);
 
1031
    }
 
1032
    my $songname = $widgets->{'main'}->get_widget('entrySearch')->get_text();
 
1033
 
 
1034
    my $special_id = 0;
 
1035
    if (($config->{'SpecialSong'}) ne "" && ($songname eq "")) {
 
1036
        my $query =
 
1037
          "SELECT id,title,songnum,book FROM lyricMain WHERE title LIKE \"%"
 
1038
          . $config->{'SpecialSong'} . "%\"";
 
1039
        qdebug($query);
 
1040
        $sth = $lyricDbh->prepare($query)
 
1041
          || display_fatal($errorcodes->{'sqlprepare'},
 
1042
            $! . "\nSQL: " . $query);
 
1043
        $rv = $sth->execute
 
1044
          || display_fatal($errorcodes->{'sqlexecute'},
 
1045
            $! . "\nSQL: " . $query);
 
1046
        $row = $sth->fetchrow_hashref();
 
1047
        my $iter = $store->append;
 
1048
        $store->set(
 
1049
            $iter,                   0, fromutf($row->{'title'}), 1,
 
1050
            fromutf($row->{'book'}), 2, $row->{'songnum'},        3,
 
1051
            $row->{'id'}
 
1052
        );
 
1053
        $special_id = $row->{'id'};
 
1054
    }
 
1055
 
 
1056
    $query = "SELECT id,title,songnum,book FROM lyricMain WHERE id > 0";
 
1057
 
 
1058
    if (defined $special_id && ($special_id > 0)) {
 
1059
        $query .= " AND id != " . $special_id;
 
1060
    }
 
1061
 
 
1062
    # Add search term if applicable
 
1063
    #if ($keywords) {
 
1064
    #   $query .= " AND keywords LIKE \"%" . $keywords . "%\"";
 
1065
    #} elsif ($songname) {
 
1066
    if ($songname =~ /^\d+$/) {
 
1067
        $query .= " AND songnum=" . $songname;
 
1068
    } else {
 
1069
        $songname =~ s/[\s,]/%/g;
 
1070
        $query .= " AND title LIKE \"%" . $songname . "%\"";
 
1071
    }
 
1072
 
 
1073
    #}
 
1074
    $query .= " ORDER BY " . $globals->{'sortby'};
 
1075
    qdebug($query);
 
1076
    $sth = $lyricDbh->prepare($query)
 
1077
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
1078
    $rv = $sth->execute
 
1079
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
1080
 
 
1081
    while ($row = $sth->fetchrow_hashref()) {
 
1082
        my $iter = $store->append;
 
1083
        $store->set(
 
1084
            $iter,                   0, fromutf($row->{'title'}), 1,
 
1085
            fromutf($row->{'book'}), 2, $row->{'songnum'},        3,
 
1086
            $row->{'id'}
 
1087
        );
 
1088
    }
 
1089
 
 
1090
    if (($songname ne "") && ($config->{'DatabaseType'} eq "mysql")) {
 
1091
        $query =
 
1092
"SELECT id,title,songnum,book,SUBSTRING_INDEX(lyrics,'\n',1) as line FROM page,lyricMain WHERE pagenum=1 AND SUBSTRING_INDEX(lyrics,'\n',1) LIKE \"%"
 
1093
          . $songname
 
1094
          . "%\" AND page.songid=lyricMain.id AND title != SUBSTRING_INDEX(lyrics,'\n',1) ORDER BY "
 
1095
          . $globals->{'sortby'};
 
1096
        qdebug($query);
 
1097
        $sth = $lyricDbh->prepare($query)
 
1098
          || display_fatal($errorcodes->{'sqlprepare'},
 
1099
            $! . "\nSQL: " . $query);
 
1100
        $rv = $sth->execute
 
1101
          || display_fatal($errorcodes->{'sqlexecute'},
 
1102
            $! . "\nSQL: " . $query);
 
1103
 
 
1104
        while ($row = $sth->fetchrow_hashref()) {
 
1105
            my $iter = $store->append;
 
1106
            $store->set(
 
1107
                $iter,
 
1108
                0,
 
1109
                fromutf($row->{'line'}) . " (" . fromutf($row->{'title'}) . ")",
 
1110
                1,
 
1111
                $row->{'book'},
 
1112
                2,
 
1113
                $row->{'songnum'},
 
1114
                3,
 
1115
                $row->{'id'}
 
1116
            );
 
1117
        }
 
1118
    }
 
1119
 
 
1120
    $widgets->{'main'}->get_widget('treeAvailable')->set_model($store);
 
1121
    $widgets->{'main'}->get_widget('treeAvailable')
 
1122
      ->set_headers_clickable(TRUE);
 
1123
    $widgets->{'main'}->get_widget('treeAvailable')
 
1124
      ->get_selection->set_mode('multiple');
 
1125
    debug("Avail updated");
 
1126
    return FALSE;
 
1127
}
 
1128
 
 
1129
#***
 
1130
 
 
1131
#****f* lyricue/treeAvailable_row_activated
 
1132
# NAME
 
1133
#   treeAvailable_row_activated
 
1134
# SYNOPSIS
 
1135
#   treeAvailable_row_activated ($widget, $event)
 
1136
# FUNCTION
 
1137
#   Add the currently selected song to the playlist
 
1138
# INPUTS
 
1139
#   $widget - Calling widget
 
1140
#   $event - Calling event
 
1141
# OUTPUT
 
1142
#   New song on playlist
 
1143
# SOURCE
 
1144
#
 
1145
sub treeAvailable_row_activated {
 
1146
    my ($widget, $event) = @_;
 
1147
    debug("Song activated from available songs list");
 
1148
    add_to_playlist();
 
1149
}
 
1150
#***
 
1151
 
 
1152
#****f* lyricue/popup_avail_menu
 
1153
# NAME
 
1154
#   popup_avail_menu
 
1155
# SYNOPSIS
 
1156
#   popup_avail_menu ($widget, $event)
 
1157
# FUNCTION
 
1158
#   popup a menu when available songs right-clicked
 
1159
# INPUTS
 
1160
#   $widget - Calling widget
 
1161
#   $event - Calling event
 
1162
# OUTPUT
 
1163
#   Displays the right-click menu
 
1164
# SOURCE
 
1165
#
 
1166
sub popup_avail_menu {
 
1167
    my ($widget, $event) = @_;
 
1168
    debug("Button clicked on available songs list");
 
1169
    if ($event->button == 3) {
 
1170
        my $path = $widget->get_path_at_pos($event->x, $event->y);
 
1171
        $widget->get_selection->select_path($path);
 
1172
        debug($path . " path");
 
1173
        my @items = ();
 
1174
 
 
1175
        if ($globals->{'access'} =~ /e/) {
 
1176
            push @items,
 
1177
              [fromutf(gettext("/Edit Song")), undef, 'edit_song', 1, '', ''];
 
1178
        }
 
1179
        if ($globals->{'access'} =~ /d/) {
 
1180
            push @items,
 
1181
              [
 
1182
                fromutf(gettext("/Delete Song")),
 
1183
                undef, 'delete_song', 1, '', ''
 
1184
              ];
 
1185
        }
 
1186
        push @items,
 
1187
          (
 
1188
            [
 
1189
                fromutf(gettext("/Refresh List")),
 
1190
                undef, 'update_available', 1, '', ''
 
1191
            ],
 
1192
            [
 
1193
                fromutf(gettext("/Order - Songbook -> No.")),
 
1194
                undef, 'change_sort_order', 4, '', ''
 
1195
            ],
 
1196
            [
 
1197
                fromutf(gettext("/Order - Songbook -> Name.")),
 
1198
                undef, 'change_sort_order', 5, '', ''
 
1199
            ]
 
1200
          );
 
1201
        if ($globals->{'access'} =~ /p/) {
 
1202
            push @items,
 
1203
              (
 
1204
                [
 
1205
                    fromutf(gettext("/Add to Playlist")),
 
1206
                    undef, 'add_to_playlist', 1, '', ''
 
1207
                ]
 
1208
              );
 
1209
        }
 
1210
        my $factory =
 
1211
          Gtk2::ItemFactory->new('Gtk2::Menu', "<availpopup>", undef);
 
1212
        $factory->create_items(1, @items);
 
1213
        $factory->popup($event->x_root, $event->y_root, $event->button,
 
1214
            $event->time);
 
1215
        return (TRUE);
 
1216
    } else {
 
1217
        my $path   = $widget->get_path_at_pos($event->x, $event->y);
 
1218
        if (!defined $path) {
 
1219
            return FALSE;
 
1220
        }
 
1221
        debug("song selected");
 
1222
        my $model  = $widgets->{'main'}->get_widget('treeAvailable')->get_model;
 
1223
        my $iter   = $model->get_iter($path);
 
1224
        my $songid = $model->get($iter, 3);
 
1225
        my $query =
 
1226
            "SELECT pageid FROM page WHERE songid=" 
 
1227
          . $songid
 
1228
          . " ORDER BY pagenum";
 
1229
        qdebug($query);
 
1230
        $sth = $lyricDbh->prepare($query)
 
1231
          || display_fatal($errorcodes->{'sqlprepare'},
 
1232
            $! . "\nSQL: " . $query);
 
1233
        $rv = $sth->execute
 
1234
          || display_fatal($errorcodes->{'sqlexecute'},
 
1235
            $! . "\nSQL: " . $query);
 
1236
        my @row = $sth->fetchrow_array();
 
1237
 
 
1238
        if (defined $row[0]) {
 
1239
            my $pageid = $row[0];
 
1240
            preview_pageid($pageid);
 
1241
        }
 
1242
 
 
1243
        return (FALSE);
 
1244
    }
 
1245
 
 
1246
    # Tell calling code that we have not handled this event; pass it on.
 
1247
    return (FALSE);
 
1248
}
 
1249
 
 
1250
#***
 
1251
 
 
1252
#****f* lyricue/popup_play_menu
 
1253
# NAME
 
1254
#   popup_play_menu
 
1255
# SYNOPSIS
 
1256
#   popup_play_menu ($event)
 
1257
# FUNCTION
 
1258
#   popup a menu when playlist item right-clicked
 
1259
# INPUTS
 
1260
#   $event - the calling event
 
1261
# OUTPUT
 
1262
#   Displays the right-click menu
 
1263
# SOURCE
 
1264
#
 
1265
sub popup_play_menu {
 
1266
    my ($event) = @_;
 
1267
    debug("Button clicked on playlist window");
 
1268
    my $playlist =
 
1269
      $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
1270
    my $query =
 
1271
"SELECT title, data FROM playlist, playlists WHERE playlist.data = playlists.id AND playlist = "
 
1272
      . $playlist
 
1273
      . " AND type = 'sub'";
 
1274
    qdebug($query);
 
1275
    my $sth = $lyricDbh->prepare($query)
 
1276
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
1277
    my $rv = $sth->execute
 
1278
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
1279
    my (@list);
 
1280
 
 
1281
    while ($row = $sth->fetchrow_hashref()) {
 
1282
        my ($text);
 
1283
        $text->{'data'}  = $row->{'data'};
 
1284
        $text->{'title'} = $row->{'title'};
 
1285
        push @list, $text;
 
1286
        my @childid = find_more_children($row->{'data'});
 
1287
        foreach (@childid) {
 
1288
            debug("Child sublist found. ID: " . $_);
 
1289
            my $query2 = "SELECT title FROM playlists WHERE id=" . $_;
 
1290
            qdebug($query2);
 
1291
            my $sth2 = $lyricDbh->prepare($query2)
 
1292
              || display_fatal($errorcodes->{'sqlprepare'},
 
1293
                $! . "\nSQL: " . $query2);
 
1294
            my $rv2 = $sth2->execute
 
1295
              || display_fatal($errorcodes->{'sqlexecute'},
 
1296
                $! . "\nSQL: " . $query2);
 
1297
            my $row2 = $sth2->fetchrow_hashref();
 
1298
            my ($text);
 
1299
            $text->{'data'}  = $row2->{'data'};
 
1300
            $text->{'title'} = $row2->{'title'};
 
1301
            push @list, $text;
 
1302
        }
 
1303
    }
 
1304
 
 
1305
    my @items = (
 
1306
        [fromutf(gettext("/Duplicate Item")), undef, 'copy_item', 1],
 
1307
        [
 
1308
            fromutf(gettext("/Remove from Playlist")), undef,
 
1309
            'remove_from_playlist',                    1
 
1310
        ],
 
1311
        [fromutf(gettext("/Refresh Playlist")),    undef, 'update_playlist', 1],
 
1312
        [fromutf(gettext("/Invert Line Display")), undef, 'invert_lines',    1],
 
1313
        [fromutf(gettext("/Loop this playlist item")), undef, 'begin_loop', 1],
 
1314
        [
 
1315
            fromutf(gettext("/Associate background")), undef,
 
1316
            'prepare_for_association',                 1
 
1317
        ],
 
1318
        [
 
1319
            fromutf(gettext("/Dis-associate background")), undef,
 
1320
            'disassociate_bg',                             1
 
1321
        ],
 
1322
        [
 
1323
            fromutf(gettext("/Move to sublist/Main")), undef,
 
1324
            'move_item_to_sublist',                    $playlist
 
1325
        ],
 
1326
    );
 
1327
    foreach (sort { uc($a->{'title'}) cmp uc($b->{'title'}) } @list) {
 
1328
        my $item = fromutf(gettext("/Move to sublist/")) . $_->{'title'};
 
1329
        push @items, [$item, undef, 'move_item_to_sublist', $_->{'data'}],;
 
1330
    }
 
1331
    my $factory = Gtk2::ItemFactory->new('Gtk2::Menu', '<playpopup>', undef);
 
1332
    $factory->create_items(undef, @items);
 
1333
    $factory->popup($event->x_root, $event->y_root, 0, $event->time);
 
1334
}
 
1335
 
 
1336
#***
 
1337
 
 
1338
#****f* lyricue/add_song
 
1339
# NAME
 
1340
#   add_song
 
1341
# SYNOPSIS
 
1342
#   add_song ()
 
1343
# FUNCTION
 
1344
#   Called which add chosen from menu/buttons
 
1345
# INPUTS
 
1346
# OUTPUT
 
1347
#   display add window
 
1348
# SOURCE
 
1349
#
 
1350
sub add_song {
 
1351
    my $i;
 
1352
    debug("Add clicked");
 
1353
    if ($widgets->{'add'} && $widgets->{'add'}->get_widget('windowEditSong')) {
 
1354
        if (!$widgets->{'add'}->get_widget('windowEditSong')->visible) {
 
1355
            $widgets->{'add'}->get_widget('windowEditSong')->destroy;
 
1356
        } else {
 
1357
            return;
 
1358
        }
 
1359
    }
 
1360
    $widgets->{'add'} =
 
1361
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'windowEditSong', 'lyricue');
 
1362
    $widgets->{'add'}->signal_autoconnect_from_package('');
 
1363
    start_editview();
 
1364
    $widgets->{'add'}->get_widget('buttonEditPreviewServer')
 
1365
      ->signal_connect("clicked", "preview_page","SERVER");
 
1366
    $widgets->{'add'}->get_widget('notebookEditPages')->remove_page(0);
 
1367
    %pageOrder = ();
 
1368
    add_page();
 
1369
    $widgets->{'add'}->get_widget('windowEditSong')->{user_data} = 0;
 
1370
    $widgets->{'add'}->get_widget('windowEditSong')->show_all();
 
1371
    $widgets->{'add'}->get_widget('buttonEditRemovePage')->set_sensitive(FALSE);
 
1372
    $widgets->{'add'}->get_widget('remove_page1')->set_sensitive(FALSE);
 
1373
}
 
1374
 
 
1375
#***
 
1376
 
 
1377
#****f* lyricue/delete_song
 
1378
# NAME
 
1379
#   delete_song
 
1380
# SYNOPSIS
 
1381
#   delete_song ()
 
1382
# FUNCTION
 
1383
#   Confirm if a song is to be deleted
 
1384
# INPUTS
 
1385
#   calls create_dialog_delete to confirm deletion
 
1386
# SOURCE
 
1387
#
 
1388
sub delete_song {
 
1389
    debug("Delete song selected");
 
1390
    my $selection =
 
1391
      $widgets->{'main'}->get_widget('treeAvailable')->get_selection;
 
1392
    my $modelTree = $widgets->{'main'}->get_widget('treeAvailable')->get_model;
 
1393
    my @sel   = $selection->get_selected_rows;
 
1394
    my $deletexml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
1395
        'dialogSelectSongs', 'lyricue');
 
1396
    $deletexml->signal_autoconnect_from_package('');
 
1397
    $deletexml->get_widget('labelSelectSongs')->set_text(gettext("Are you sure you wish to delete "));
 
1398
    my $model = Gtk2::ListStore->new(
 
1399
        'Glib::Boolean', 'Glib::String', 'Glib::String', 'Glib::String',
 
1400
        'Glib::Uint',    'Glib::Uint'
 
1401
    );
 
1402
    my $renderer = Gtk2::CellRendererToggle->new;
 
1403
    $renderer->signal_connect(
 
1404
        toggled => sub {
 
1405
            my ($cell, $path_str, $model) = @_;
 
1406
            my $path   = Gtk2::TreePath->new_from_string($path_str);
 
1407
            my $column = 0;
 
1408
            my $iter   = $model->get_iter($path);
 
1409
            my ($toggle_item) = $model->get($iter, $column);
 
1410
            $toggle_item ^= 1;
 
1411
            debug('setting ' . $path_str . ' to ' . $toggle_item);
 
1412
 
 
1413
            # set new value
 
1414
            $model->set($iter, $column, $toggle_item);
 
1415
        },
 
1416
        $model
 
1417
    );
 
1418
    my $column1 =
 
1419
      Gtk2::TreeViewColumn->new_with_attributes("", $renderer, active => 0);
 
1420
    my $column2 =
 
1421
      Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Title")),
 
1422
        Gtk2::CellRendererText->new, text => 1);
 
1423
    my $column3 =
 
1424
      Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Artist")),
 
1425
        Gtk2::CellRendererText->new, text => 2);
 
1426
    my $column4 =
 
1427
      Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Book")),
 
1428
        Gtk2::CellRendererText->new, text => 3);
 
1429
    my $column5 =
 
1430
      Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Song Number")),
 
1431
        Gtk2::CellRendererText->new, text => 4);
 
1432
    $column1->set_resizable(TRUE);
 
1433
    $column2->set_resizable(TRUE);
 
1434
    $column3->set_resizable(TRUE);
 
1435
    $column4->set_resizable(TRUE);
 
1436
    $column5->set_resizable(TRUE);
 
1437
    $deletexml->get_widget('treeSongImport')
 
1438
      ->append_column($column1);
 
1439
    $deletexml->get_widget('treeSongImport')
 
1440
      ->append_column($column2);
 
1441
    $deletexml->get_widget('treeSongImport')
 
1442
      ->append_column($column3);
 
1443
    $deletexml->get_widget('treeSongImport')
 
1444
      ->append_column($column4);
 
1445
    $deletexml->get_widget('treeSongImport')
 
1446
      ->append_column($column5);
 
1447
    foreach my $path (@sel) {
 
1448
        my $iter = $modelTree->get_iter($path);
 
1449
        my $songid = $modelTree->get($iter, 3);
 
1450
        if (!($modelTree->get($iter, 1) eq $config->{'SpecialSong'})) {
 
1451
            $query = "SELECT title,songnum,book,artist FROM lyricMain WHERE id="
 
1452
              . $songid;
 
1453
            qdebug($query);
 
1454
            $sth = $lyricDbh->prepare($query)
 
1455
              || display_fatal($errorcodes->{'sqlprepare'},
 
1456
                $! . "\nSQL: " . $query);
 
1457
            $rv = $sth->execute
 
1458
              || display_fatal($errorcodes->{'sqlexecute'},
 
1459
                $! . "\nSQL: " . $query);
 
1460
            $row = $sth->fetchrow_hashref();
 
1461
            
 
1462
            my $newiter = $model->append;
 
1463
            $model->set(
 
1464
                $newiter,
 
1465
                0, TRUE,
 
1466
                1, $row->{'title'},
 
1467
                2, $row->{'artist'},
 
1468
                3, $row->{'book'},
 
1469
                4, $row->{'songnum'},
 
1470
                5, $songid
 
1471
            );
 
1472
        }
 
1473
    }
 
1474
    $deletexml->get_widget('treeSongImport')->set_model($model);
 
1475
    $deletexml->get_widget('treeSongImport')->set_headers_clickable(TRUE);
 
1476
    my $confirm =
 
1477
      $deletexml->get_widget('dialogSelectSongs')->run();
 
1478
    if ($confirm == 1) {
 
1479
        $model->foreach(\&do_delete_song);
 
1480
    }
 
1481
    close_dialog($deletexml->get_widget('dialogSelectSongs'));
 
1482
    update_available();
 
1483
}
 
1484
 
 
1485
#***
 
1486
 
 
1487
#****f* lyricue/do_delete_song
 
1488
# NAME
 
1489
#   do_delete_song
 
1490
# SYNOPSIS
 
1491
#   do_delete_song ($songid)
 
1492
# FUNCTION
 
1493
#   Do the actual deletion of a song including from the playlist
 
1494
# INPUTS
 
1495
#   $songid - Id of song to be deleted
 
1496
# OUTPUT
 
1497
#   One less song
 
1498
# SOURCE
 
1499
#
 
1500
sub do_delete_song {
 
1501
    my ($store, $path, $iter) = @_;
 
1502
    my ($query, $sth, $rv);
 
1503
    if ($store->get($iter,0) == FALSE) {
 
1504
        return;
 
1505
    }
 
1506
    my $songid = $store->get($iter,5);
 
1507
    debug("do delete song $songid");
 
1508
 
 
1509
    start_transaction();
 
1510
    $query = "DELETE FROM lyricMain WHERE id=" . $songid;
 
1511
    qdebug($query);
 
1512
    $sth = $lyricDbh->prepare($query)
 
1513
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
1514
    $rv = $sth->execute
 
1515
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
1516
 
 
1517
    $query = "DELETE FROM page WHERE songid=" . $songid;
 
1518
    qdebug($query);
 
1519
    $sth = $lyricDbh->prepare($query)
 
1520
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
1521
    $rv = $sth->execute
 
1522
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
1523
 
 
1524
    $query =
 
1525
"SELECT playorder FROM playlist,page WHERE playlist.data=page.pageid AND playlist.type=\"song\" AND page.songid="
 
1526
      . $songid;
 
1527
    qdebug($query);
 
1528
    $sth = $lyricDbh->prepare($query)
 
1529
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
1530
    $rv = $sth->execute
 
1531
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
1532
    my $disable = 0;
 
1533
 
 
1534
    while (my @row = $sth->fetchrow_array()) {
 
1535
 
 
1536
        my $query2 = "DELETE FROM playlist WHERE playorder=" . $row[0];
 
1537
        qdebug($query2);
 
1538
        my $sth2 = $lyricDbh->prepare($query2)
 
1539
          || display_fatal($errorcodes->{'sqlprepare'},
 
1540
            $! . "\nSQL: " . $query2);
 
1541
        my $rv2 = $sth2->execute
 
1542
          || display_fatal($errorcodes->{'sqlexecute'},
 
1543
            $! . "\nSQL: " . $query2);
 
1544
        $disable = 1;
 
1545
    }
 
1546
    end_transaction();
 
1547
    if ($disable == 1) {
 
1548
 
 
1549
        #Cancel any loop timers
 
1550
        #Continuing to loop over a modified playlists due to
 
1551
        #removed items represents a possible crash risk - better safe
 
1552
        #than sorry.
 
1553
        #
 
1554
        reset_timer($globals->{'timer'});
 
1555
 
 
1556
        #
 
1557
    }
 
1558
 
 
1559
}
 
1560
 
 
1561
#***
 
1562
 
 
1563
#****f* lyricue/do_save_song
 
1564
# NAME
 
1565
#   do_save_song
 
1566
# SYNOPSIS
 
1567
#   do_save_song ()
 
1568
# FUNCTION
 
1569
#   Save the song to the DB
 
1570
# INPUTS
 
1571
# OUTPUT
 
1572
#   One more song in the DB
 
1573
# SOURCE
 
1574
#
 
1575
sub do_save_song {
 
1576
    my ($query, $sth, $page, $songid);
 
1577
    debug("do save song");
 
1578
    my $newitem = FALSE;
 
1579
    $songid = $widgets->{'add'}->get_widget('windowEditSong')->{user_data};
 
1580
    my $numpages =
 
1581
      $widgets->{'add'}->get_widget('notebookEditPages')->get_n_pages;
 
1582
 
 
1583
    start_transaction();
 
1584
    if ($songid != 0) {
 
1585
 
 
1586
        # Remove extra pages
 
1587
        debug("Song number: " . $songid);
 
1588
        $query =
 
1589
            "DELETE FROM page WHERE songid=" 
 
1590
          . $songid
 
1591
          . " AND pagenum > "
 
1592
          . $numpages;
 
1593
        qdebug($query);
 
1594
        $sth = $lyricDbh->prepare($query)
 
1595
          || display_fatal($errorcodes->{'sqlprepare'},
 
1596
            $! . "\nSQL: " . $query);
 
1597
        $rv = $sth->execute
 
1598
          || display_fatal($errorcodes->{'sqlexecute'},
 
1599
            $! . "\nSQL: " . $query);
 
1600
 
 
1601
        $query =
 
1602
"DELETE playlist FROM playlist LEFT JOIN page ON playlist.data=page.pageid WHERE page.songid="
 
1603
          . $songid
 
1604
          . " AND page.pagenum > "
 
1605
          . $numpages;
 
1606
        qdebug($query);
 
1607
        $sth = $lyricDbh->prepare($query)
 
1608
          || display_fatal($errorcodes->{'sqlprepare'},
 
1609
            $! . "\nSQL: " . $query);
 
1610
        $sth->execute
 
1611
          || display_fatal($errorcodes->{'sqlexecute'},
 
1612
            $! . "\nSQL: " . $query);
 
1613
 
 
1614
        # Update lyricMain with new info
 
1615
        $query = "UPDATE lyricMain SET title="
 
1616
          . quote($widgets->{'add'}->get_widget('entryEditName')->get_text());
 
1617
        $query .= ", songnum="
 
1618
          . quote($widgets->{'add'}->get_widget('entryEditNumber')->get_text());
 
1619
        $query .= ", book="
 
1620
          . quote($widgets->{'add'}->get_widget('entryEditBook')->get_text());
 
1621
        $query .= ", artist="
 
1622
          . quote($widgets->{'add'}->get_widget('entryEditArtist')->get_text());
 
1623
        $query .=
 
1624
          ", copyright="
 
1625
          . quote(
 
1626
            $widgets->{'add'}->get_widget('entryEditCopyright')->get_text());
 
1627
        my $noaudit = "";
 
1628
        if (!$widgets->{'add'}->get_widget('checkEditAudit')->get_active()) {
 
1629
            $noaudit = "NOAUDIT ";
 
1630
        }
 
1631
        $query .= ", keywords="
 
1632
          . quote(
 
1633
            toutf(
 
1634
                    $noaudit
 
1635
                  . $widgets->{'add'}->get_widget('entryEditKeywords')
 
1636
                  ->get_text()
 
1637
            )
 
1638
          );
 
1639
        $query .= " WHERE id=" . $songid;
 
1640
        qdebug($query);
 
1641
        $sth = $lyricDbh->prepare($query)
 
1642
          || display_fatal($errorcodes->{'sqlprepare'},
 
1643
            $! . "\nSQL: " . $query);
 
1644
        $sth->execute
 
1645
          || display_fatal($errorcodes->{'sqlexecute'},
 
1646
            $! . "\nSQL: " . $query);
 
1647
    } else {
 
1648
 
 
1649
        # Find next id
 
1650
        $query = "SELECT MAX(id)+1 FROM lyricMain WHERE id < 2000000";
 
1651
        qdebug($query);
 
1652
        $sth = $lyricDbh->prepare($query)
 
1653
          || display_fatal($errorcodes->{'sqlprepare'},
 
1654
            $! . "\nSQL: " . $query);
 
1655
        $rv = $sth->execute
 
1656
          || display_fatal($errorcodes->{'sqlexecute'},
 
1657
            $! . "\nSQL: " . $query);
 
1658
        my @row = $sth->fetchrow_array;
 
1659
        $songid = $row[0];
 
1660
        if ((! defined $songid) || ($songid < 1)) {
 
1661
            $songid=1;
 
1662
        }
 
1663
        debug("Song number: " . $songid);
 
1664
 
 
1665
        # insert into db
 
1666
        $query =
 
1667
"INSERT INTO lyricMain ( id, title, songnum, book, artist, keywords, copyright, entered, written ) VALUES ( "
 
1668
          . $songid . ", ";
 
1669
        $query .=
 
1670
          quote(
 
1671
            toutf($widgets->{'add'}->get_widget('entryEditName')->get_text()))
 
1672
          . ",";
 
1673
        $query .=
 
1674
          quote(
 
1675
            toutf($widgets->{'add'}->get_widget('entryEditNumber')->get_text()))
 
1676
          . ",";
 
1677
        $query .=
 
1678
          quote(
 
1679
            toutf($widgets->{'add'}->get_widget('entryEditBook')->get_text()))
 
1680
          . ",";
 
1681
        $query .=
 
1682
          quote(
 
1683
            toutf($widgets->{'add'}->get_widget('entryEditArtist')->get_text()))
 
1684
          . ",";
 
1685
        $query .= quote(
 
1686
            toutf(
 
1687
                $widgets->{'add'}->get_widget('entryEditKeywords')->get_text()
 
1688
            )
 
1689
        ) . ",";
 
1690
        $query .= quote(
 
1691
            toutf(
 
1692
                $widgets->{'add'}->get_widget('entryEditCopyright')->get_text()
 
1693
            )
 
1694
        ) . ", NOW(), NOW() )";
 
1695
        qdebug($query);
 
1696
        $sth = $lyricDbh->prepare($query)
 
1697
          || display_fatal($errorcodes->{'sqlprepare'},
 
1698
            $! . "\nSQL: " . $query);
 
1699
        $sth->execute
 
1700
          || display_fatal($errorcodes->{'sqlexecute'},
 
1701
            $! . "\nSQL: " . $query);
 
1702
    }
 
1703
    foreach my $pagenum (1 .. $numpages) {
 
1704
        my $page =
 
1705
          $widgets->{'add'}->get_widget('notebookEditPages')
 
1706
          ->get_nth_page($pagenum - 1);
 
1707
        my $title =
 
1708
          $widgets->{'add'}->get_widget('notebookEditPages')
 
1709
          ->get_tab_label($page)->get_children->get_text;
 
1710
        my $text = fromutf(gettext("Page "));
 
1711
        my $lyrics =
 
1712
          $lyricDbh->quote(get_buffer_text($page->get_children->get_buffer));
 
1713
        if ($title =~ /^$text/) {
 
1714
            $text = $lyricDbh->quote("");
 
1715
        } else {
 
1716
            $text = $lyricDbh->quote($title);
 
1717
        }
 
1718
        my $pagequery = "";
 
1719
        if ($songid != 0) {
 
1720
            $query =
 
1721
                "SELECT pageid FROM page WHERE songid=" 
 
1722
              . $songid
 
1723
              . " AND pagenum="
 
1724
              . $pagenum;
 
1725
            qdebug($query);
 
1726
            $sth = $lyricDbh->prepare($query)
 
1727
              || display_fatal($errorcodes->{'sqlprepare'},
 
1728
                $! . "\nSQL: " . $query);
 
1729
            debug("Page Edit : " . $pagenum . "|" . $title);
 
1730
            $rv = $sth->execute || display_fatal($errorcodes->{'sqlexecute'},
 
1731
                $! . "\nSQL: " . $query);
 
1732
            my @row = $sth->fetchrow_array();
 
1733
            if (defined $row[0]) {
 
1734
                $pagequery =
 
1735
                    "UPDATE page SET lyrics=" 
 
1736
                  . $lyrics
 
1737
                  . ", pagetitle="
 
1738
                  . $text
 
1739
                  . " WHERE pageid="
 
1740
                  . $row[0];
 
1741
                debug("Page Edit : " . $pagenum . "|" . $title);
 
1742
            }
 
1743
        }
 
1744
        if ($pagequery eq "") {
 
1745
            $pagequery =
 
1746
                "INSERT INTO page (songid,pagenum,pagetitle,lyrics) VALUES ("
 
1747
              . $songid . ", "
 
1748
              . $pagenum . ", "
 
1749
              . $text . ", "
 
1750
              . $lyrics . ")";
 
1751
            debug("Page Add : " . $pagenum . "|" . $title);
 
1752
        }
 
1753
        qdebug($pagequery);
 
1754
        $sth = $lyricDbh->prepare($pagequery)
 
1755
          || display_fatal($errorcodes->{'sqlprepare'},
 
1756
            $! . "\nSQL: " . $pagequery);
 
1757
        $sth->execute || display_fatal($errorcodes->{'sqlexecute'},
 
1758
            $! . "\nSQL: " . $pagequery);
 
1759
    }
 
1760
    end_transaction();
 
1761
    return $songid;
 
1762
}
 
1763
 
 
1764
#***
 
1765
 
 
1766
#****f* lyricue/save_song
 
1767
# NAME
 
1768
#   save_song
 
1769
# SYNOPSIS
 
1770
#   save_song ()
 
1771
# FUNCTION
 
1772
#   Save the song, close the add window and update the available songs
 
1773
# INPUTS
 
1774
# OUTPUT
 
1775
#   Calls a few others to do anything
 
1776
# SOURCE
 
1777
#
 
1778
sub save_song {
 
1779
    debug("save song");
 
1780
    do_save_song();
 
1781
    close_add_window();
 
1782
    update_available();
 
1783
}
 
1784
 
 
1785
#***
 
1786
 
 
1787
#****f* lyricue/add_page
 
1788
# NAME
 
1789
#   add_page
 
1790
# SYNOPSIS
 
1791
#   add_page ()
 
1792
# FUNCTION
 
1793
#   Add page clicked
 
1794
# INPUTS
 
1795
# OUTPUT
 
1796
#   Adds a page to the song edit screen
 
1797
# SOURCE
 
1798
#
 
1799
sub add_page {
 
1800
    debug("Add page clicked");
 
1801
 
 
1802
    # Find free hash number
 
1803
    my $hashnum = 0;
 
1804
    while (exists $pageOrder{$hashnum}) {
 
1805
        $hashnum++;
 
1806
    }
 
1807
    debug($hashnum);
 
1808
    my $pagenum =
 
1809
      $widgets->{'add'}->get_widget('notebookEditPages')->get_current_page + 1;
 
1810
 
 
1811
    #
 
1812
    # Construct a GtkScrolledWindow 'scrollAPage'
 
1813
    $widgets->{'scrollAPage'}{$hashnum} = Gtk2::ScrolledWindow->new;
 
1814
    $widgets->{'scrollAPage'}{$hashnum}->set_policy('always', 'always');
 
1815
    $widgets->{'scrollAPage'}{$hashnum}->show;
 
1816
 
 
1817
    #
 
1818
    # Construct a GtkText 'textAPage'
 
1819
    $widgets->{'textAPage'}{$hashnum}  = Gtk2::TextView->new;
 
1820
    $widgets->{'textAPageB'}{$hashnum} = Gtk2::TextBuffer->new(undef);
 
1821
    $widgets->{'textAPage'}{$hashnum}
 
1822
      ->set_buffer($widgets->{'textAPageB'}{$hashnum});
 
1823
    $widgets->{'textAPage'}{$hashnum}->set_editable(TRUE);
 
1824
    $widgets->{'textAPage'}{$hashnum}->set_cursor_visible(TRUE);
 
1825
    $widgets->{'scrollAPage'}{$hashnum}->add($widgets->{'textAPage'}{$hashnum});
 
1826
    $widgets->{'textAPage'}{$hashnum}->show;
 
1827
 
 
1828
    #
 
1829
    # Construct a GtkLabel 'labelAPage'
 
1830
    $widgets->{'labelAPage'}{$hashnum} =
 
1831
      new Gtk2::Label(fromutf(gettext('Page') . " 1"));
 
1832
    $widgets->{'labelAPage'}{$hashnum}->set_justify('center');
 
1833
    $widgets->{'labelAPage'}{$hashnum}->set_line_wrap(0);
 
1834
    $widgets->{'labelAPage'}{$hashnum}->show;
 
1835
    $widgets->{'labelAPage'}{$hashnum}->set_alignment(0.5, 0.5);
 
1836
 
 
1837
    # And a event box so you can change it
 
1838
    $widgets->{'eventAPage'}{$hashnum} = Gtk2::EventBox->new;
 
1839
    $widgets->{'eventAPage'}{$hashnum}->{user_data} = $hashnum;
 
1840
    $widgets->{'eventAPage'}{$hashnum}->add($widgets->{'labelAPage'}{$hashnum});
 
1841
    $widgets->{'eventAPage'}{$hashnum}->set_above_child(FALSE);
 
1842
    $widgets->{'eventAPage'}{$hashnum}->set_visible_window(FALSE);
 
1843
    $widgets->{'eventAPage'}{$hashnum}
 
1844
      ->signal_connect('button-press-event', 'update_pagename');
 
1845
 
 
1846
    $pageOrder{$hashnum} = $pagenum;
 
1847
    $widgets->{'add'}->get_widget('notebookEditPages')
 
1848
      ->insert_page($widgets->{'scrollAPage'}{$hashnum},
 
1849
        $widgets->{'eventAPage'}{$hashnum}, $pagenum);
 
1850
    $widgets->{'add'}->get_widget('notebookEditPages')
 
1851
      ->set_tab_reorderable($widgets->{'scrollAPage'}{$hashnum}, TRUE);
 
1852
    renumber_pages($pagenum, $hashnum);
 
1853
    $widgets->{'add'}->get_widget('notebookEditPages')
 
1854
      ->set_current_page($pagenum);
 
1855
    $widgets->{'add'}->get_widget('notebookEditPages')->show_all();
 
1856
    $widgets->{'add'}->get_widget('buttonEditRemovePage')->set_sensitive(TRUE);
 
1857
    $widgets->{'add'}->get_widget('remove_page1')->set_sensitive(TRUE);
 
1858
 
 
1859
    return $hashnum;
 
1860
}
 
1861
 
 
1862
#***
 
1863
 
 
1864
#****f* lyricue/update_pagename
 
1865
# NAME
 
1866
#   update_pagename
 
1867
# SYNOPSIS
 
1868
#   update_pagename ()
 
1869
# FUNCTION
 
1870
#   Update the page name if double-clicked
 
1871
# SOURCE
 
1872
#
 
1873
sub update_pagename {
 
1874
    my ($widget, $event) = @_;
 
1875
    if ($event->type eq '2button-press') {
 
1876
        debug("Changing page name");
 
1877
        my $hashnum = $widget->{user_data};
 
1878
        my $entry   = Gtk2::Entry->new;
 
1879
        $entry->{user_data} = $hashnum;
 
1880
        $entry->set_text($widgets->{'labelAPage'}{$hashnum}->get_label);
 
1881
        $entry->signal_connect('activate', 'do_update_pagename');
 
1882
        $widgets->{'add'}->get_widget('notebookEditPages')
 
1883
          ->set_tab_label($widgets->{'scrollAPage'}{$hashnum}, $entry);
 
1884
    }
 
1885
}
 
1886
 
 
1887
#***
 
1888
 
 
1889
#****f* lyricue/do_update_pagename
 
1890
# NAME
 
1891
#   do_update_pagename
 
1892
# SYNOPSIS
 
1893
#   do_update_pagename ()
 
1894
# FUNCTION
 
1895
#   A newly named tab
 
1896
# INPUTS
 
1897
# SOURCE
 
1898
#
 
1899
sub do_update_pagename {
 
1900
    my ($widget, $event) = @_;
 
1901
    debug("Apply pagename change");
 
1902
    my $text    = $widget->get_text;
 
1903
    my $hashnum = $widget->{user_data};
 
1904
    $widgets->{'labelAPage'}{$hashnum}->set_label($text);
 
1905
    $widgets->{'add'}->get_widget('notebookEditPages')->set_tab_label(
 
1906
        $widgets->{'scrollAPage'}{$hashnum},
 
1907
        $widgets->{'eventAPage'}{$hashnum}
 
1908
    );
 
1909
}
 
1910
 
 
1911
#***
 
1912
 
 
1913
#****f* lyricue/renumber_pages
 
1914
# NAME
 
1915
#   renumber_pages
 
1916
# SYNOPSIS
 
1917
#   renumber_pages ($pagenum, $newitem)
 
1918
# FUNCTION
 
1919
#   Re-number the pages in a edited song
 
1920
# INPUTS
 
1921
#   $pagenum - The page number added/deleted
 
1922
#   $newitem - The new item added
 
1923
# OUTPUT
 
1924
#   Re-ordered page list
 
1925
# SOURCE
 
1926
#
 
1927
sub renumber_pages {
 
1928
    my ($pagenum, $newitem) = @_;
 
1929
    debug("renumber pages");
 
1930
    my $i;
 
1931
 
 
1932
    # Renumber pages
 
1933
    foreach $i (keys(%pageOrder)) {
 
1934
        debug("$i:$pageOrder{$i}|");
 
1935
        my $page = $pageOrder{$i};
 
1936
        if ($page == $pagenum) {
 
1937
            if ($i == $newitem) {
 
1938
                $pageOrder{$i}++;
 
1939
            } else {
 
1940
 
 
1941
                # Skip it
 
1942
            }
 
1943
        } elsif ($page > $pagenum) {
 
1944
            $pageOrder{$i}++;
 
1945
        }
 
1946
        debug("$i:$pageOrder{$i}");
 
1947
        my $text = fromutf(gettext("Page"));
 
1948
        if ($widgets->{'labelAPage'}{$i}->get_text =~ /^$text/) {
 
1949
            $widgets->{'labelAPage'}{$i}
 
1950
              ->set_text($text . " " . $pageOrder{$i});
 
1951
        }
 
1952
        $widgets->{'labelAPage'}{$i}->show();
 
1953
    }
 
1954
}
 
1955
 
 
1956
#***
 
1957
 
 
1958
#****f* lyricue/remove_page
 
1959
# NAME
 
1960
#   remove_page
 
1961
# SYNOPSIS
 
1962
#   remove_page ()
 
1963
# FUNCTION
 
1964
#   Remove a page from the song being edited
 
1965
# INPUTS
 
1966
# OUTPUT
 
1967
#   One less page
 
1968
# SOURCE
 
1969
#
 
1970
sub remove_page {
 
1971
    debug("Remove page clicked");
 
1972
 
 
1973
    my $i;
 
1974
    my $pagenum =
 
1975
      $widgets->{'add'}->get_widget('notebookEditPages')->get_current_page + 1;
 
1976
    my %newpageOrder;
 
1977
 
 
1978
    my $count = 0;
 
1979
    my $text  = fromutf(gettext("Page "));
 
1980
    foreach $i (keys(%pageOrder)) {
 
1981
        $count++;
 
1982
        debug("-$pagenum:$i:$pageOrder{$i}:");
 
1983
        if ($pageOrder{$i} < $pagenum) {
 
1984
            $newpageOrder{$i} = $pageOrder{$i};
 
1985
            if ($widgets->{'labelAPage'}{$i}->get_text =~ /^$text/) {
 
1986
                $widgets->{'labelAPage'}{$i}
 
1987
                  ->set_text(fromutf(gettext("Page ")) . $newpageOrder{$i});
 
1988
            }
 
1989
            debug("$newpageOrder{$i}");
 
1990
        } elsif ($pageOrder{$i} == $pagenum) {
 
1991
            $widgets->{'add'}->get_widget('notebookEditPages')
 
1992
              ->remove_page($pagenum - 1);
 
1993
            debug("");
 
1994
        } elsif ($pageOrder{$i} > $pagenum) {
 
1995
            $newpageOrder{$i} = $pageOrder{$i} - 1;
 
1996
            debug("$newpageOrder{$i}");
 
1997
            if ($widgets->{'labelAPage'}{$i}->get_text =~ /^$text/) {
 
1998
                $widgets->{'labelAPage'}{$i}
 
1999
                  ->set_text(fromutf(gettext("Page ")) . $newpageOrder{$i});
 
2000
            }
 
2001
        }
 
2002
    }
 
2003
    %pageOrder = %newpageOrder;
 
2004
    if ($count <= 2) {
 
2005
        $widgets->{'add'}->get_widget('buttonEditRemovePage')
 
2006
          ->set_sensitive(FALSE);
 
2007
        $widgets->{'add'}->get_widget('remove_page1')->set_sensitive(FALSE);
 
2008
    }
 
2009
}
 
2010
 
 
2011
#***
 
2012
 
 
2013
#****f* lyricue/close_add_window
 
2014
# NAME
 
2015
#   close_add_window
 
2016
# SYNOPSIS
 
2017
#   close_add_window ()
 
2018
# FUNCTION
 
2019
#   Close the add window
 
2020
# INPUTS
 
2021
# OUTPUT
 
2022
#   Add window closed
 
2023
# SOURCE
 
2024
#
 
2025
sub close_add_window {
 
2026
    debug("Close add window");
 
2027
    stop_editview();
 
2028
    $widgets->{'add'}->get_widget('windowEditSong')->destroy();
 
2029
    undef $widgets->{'add'};
 
2030
}
 
2031
 
 
2032
#***
 
2033
 
 
2034
#****f* lyricue/close_dialog
 
2035
# NAME
 
2036
#   close_dialog
 
2037
# SYNOPSIS
 
2038
#   close_dialog ($widget)
 
2039
# FUNCTION
 
2040
#   Close the calling widgets toplevel window
 
2041
# INPUTS
 
2042
#   $widget - Calling widget
 
2043
# OUTPUT
 
2044
#   window closed
 
2045
# SOURCE
 
2046
#
 
2047
sub close_dialog {
 
2048
    my ($widget) = @_;
 
2049
    debug("Close dialog: " . $widget->get_name);
 
2050
    if ($widget) {
 
2051
        $widget->get_toplevel->destroy;
 
2052
    }
 
2053
}
 
2054
 
 
2055
#***
 
2056
 
 
2057
#****f* lyricue/edit_song
 
2058
# NAME
 
2059
#   edit_song
 
2060
# SYNOPSIS
 
2061
#   edit_song ()
 
2062
# FUNCTION
 
2063
#   Edit a song
 
2064
# INPUTS
 
2065
# OUTPUT
 
2066
#   Calls create_window_add to edit the chosen song
 
2067
# SOURCE
 
2068
#
 
2069
sub edit_song {
 
2070
    my $i;
 
2071
    debug("Edit clicked");
 
2072
    my $selection =
 
2073
      $widgets->{'main'}->get_widget('treeAvailable')->get_selection;
 
2074
    my @sel   = $selection->get_selected_rows;
 
2075
    my $model = $widgets->{'main'}->get_widget('treeAvailable')->get_model;
 
2076
    my $iter  = $model->get_iter($sel[0]);
 
2077
 
 
2078
    if ($iter) {
 
2079
        my $songid = $model->get($iter, 3);
 
2080
        if (   $widgets->{'add'}
 
2081
            && $widgets->{'add'}->get_widget('windowEditSong'))
 
2082
        {
 
2083
            if (!$widgets->{'add'}->get_widget('windowEditSong')->visible) {
 
2084
                $widgets->{'add'}->get_widget('windowEditSong')->destroy;
 
2085
 
 
2086
                $widgets->{'add'} = Gtk2::GladeXML->new($globals->{'gladefile'},
 
2087
                    'windowEditSong', 'lyricue');
 
2088
                $widgets->{'add'}->signal_autoconnect_from_package('');
 
2089
                start_editview();
 
2090
                $widgets->{'add'}->get_widget('buttonEditPreviewServer')
 
2091
                  ->signal_connect("clicked", "preview_page", "SERVER");
 
2092
                %pageOrder = ();
 
2093
                update_songinfo($songid);
 
2094
            }
 
2095
        } else {
 
2096
            $widgets->{'add'} = Gtk2::GladeXML->new($globals->{'gladefile'},
 
2097
                'windowEditSong', 'lyricue');
 
2098
            $widgets->{'add'}->signal_autoconnect_from_package('');
 
2099
            $widgets->{'add'}->get_widget('buttonEditPreviewServer')
 
2100
              ->signal_connect("clicked", "preview_page", "SERVER");
 
2101
            start_editview();
 
2102
            %pageOrder = ();
 
2103
            $widgets->{'add'}->get_widget('notebookEditPages')->remove_page(0);
 
2104
            $widgets->{'add'}->get_widget('windowEditSong')->show();
 
2105
            update_songinfo($songid);
 
2106
        }
 
2107
    }
 
2108
}
 
2109
 
 
2110
#***
 
2111
 
 
2112
#****f* lyricue/do_add_verse
 
2113
# NAME
 
2114
#   do_add_verse
 
2115
# SYNOPSIS
 
2116
#   do_add_verse ($widget)
 
2117
# FUNCTION
 
2118
#   Add the chosen reading
 
2119
# INPUTS
 
2120
#   $widget - Calling widget
 
2121
# OUTPUT
 
2122
#   Verse added to playlist
 
2123
# SOURCE
 
2124
#
 
2125
sub do_add_verse {
 
2126
    my ($widget) = @_;
 
2127
    debug("Add the chosen reading");
 
2128
 
 
2129
    debug($globals->{'verses'} . "-" . $globals->{'verseEnd'});
 
2130
 
 
2131
    my $book = $widget->get_toplevel->{user_data};
 
2132
    $book =~ s/ -.*$//g;
 
2133
    my $chapter = $widget->get_toplevel->{user_data};
 
2134
    $chapter =~ s/^.*- //g;
 
2135
    insert_verse($book, $chapter, $globals->{'verses'}, $globals->{'verseEnd'});
 
2136
    close_dialog($widget);
 
2137
}
 
2138
 
 
2139
#***
 
2140
 
 
2141
#****f* lyricue/insert_verse
 
2142
# NAME
 
2143
#   insert_verse
 
2144
# SYNOPSIS
 
2145
#   insert_verse ( $book, $chapter, $start, $end)
 
2146
# FUNCTION
 
2147
#   Add the passed verse to the playlist
 
2148
# INPUTS
 
2149
#   $book - Book
 
2150
#   $chaper - Chapter
 
2151
#   $start - Start verse
 
2152
#   $end - End verse
 
2153
# OUTPUT
 
2154
#   Closes the interface
 
2155
# SOURCE
 
2156
sub insert_verse {
 
2157
    my ($book, $chapter, $start, $end) = @_;
 
2158
    debug("insert verse");
 
2159
    my $main_playlist =
 
2160
      $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
2161
    if ($main_playlist == -1) {
 
2162
        return;
 
2163
    }
 
2164
    my $verse =
 
2165
      $book . ":" . $chapter . ":" . $start . "-" . $chapter . ":" . $end;
 
2166
    debug($verse);
 
2167
 
 
2168
    my ($sth, $rv, $row, $playorder, $playlist);
 
2169
 
 
2170
    # Find next playlist entry
 
2171
    my $query = "SELECT MAX(playorder) FROM playlist";
 
2172
    qdebug($query);
 
2173
    $sth = $lyricDbh->prepare($query)
 
2174
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2175
    $rv = $sth->execute
 
2176
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2177
 
 
2178
    if ($row = $sth->fetchrow_hashref()) {
 
2179
        if ($row->{'MAX(playorder)'}) {
 
2180
            $playorder = $row->{'MAX(playorder)'} + 1;
 
2181
        } else {
 
2182
            $playorder = 1;
 
2183
        }
 
2184
    } else {
 
2185
        $playorder = 1;
 
2186
    }
 
2187
 
 
2188
    # Find next playlists entry
 
2189
    $query = "SELECT MAX(id) FROM playlists";
 
2190
    qdebug($query);
 
2191
    $sth = $lyricDbh->prepare($query)
 
2192
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2193
    $rv = $sth->execute
 
2194
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2195
    $row      = $sth->fetchrow_hashref();
 
2196
    $playlist = $row->{'MAX(id)'} + 1;
 
2197
 
 
2198
    # Add verse to main playlist
 
2199
    $query =
 
2200
        "INSERT INTO playlist (playorder,playlist,type,data) VALUES ("
 
2201
      . $playorder . ", "
 
2202
      . $main_playlist
 
2203
      . ", \"play\", "
 
2204
      . $playlist . ")";
 
2205
    qdebug($query);
 
2206
    $sth = $lyricDbh->prepare($query)
 
2207
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2208
 
 
2209
    $rv = $sth->execute
 
2210
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2211
    $playorder++;
 
2212
 
 
2213
    # Add entry to playlists table
 
2214
    $query =
 
2215
        "INSERT INTO playlists (id,title) VALUES ("
 
2216
      . $playlist . ", \""
 
2217
      . toutf($verse) . "\")";
 
2218
    qdebug($query);
 
2219
    $sth = $lyricDbh->prepare($query)
 
2220
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2221
 
 
2222
    $rv = $sth->execute
 
2223
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2224
 
 
2225
    # Get current settings
 
2226
    update_display("status", "", "");
 
2227
 
 
2228
    my $pagenum = 1;
 
2229
    my $loop    = TRUE;
 
2230
    my $minv    = $start;
 
2231
    while ($loop) {
 
2232
        my $maxv = get_max_verse($book, $chapter, $minv, $end);
 
2233
        $query =
 
2234
            "INSERT INTO playlist (playlist,playorder,type,data) VALUES ("
 
2235
          . $playlist . ", "
 
2236
          . $playorder
 
2237
          . ", \"vers\", \""
 
2238
          . $minv . "-"
 
2239
          . $maxv . "\")";
 
2240
        $playorder++;
 
2241
        qdebug($query);
 
2242
        my $sth2 = $lyricDbh->prepare($query)
 
2243
          || display_fatal($errorcodes->{'sqlprepare'},
 
2244
            $! . "\nSQL: " . $query);
 
2245
 
 
2246
        my $rv2 = $sth2->execute
 
2247
          || display_fatal($errorcodes->{'sqlexecute'},
 
2248
            $! . "\nSQL: " . $query);
 
2249
        if ($maxv >= $end) {
 
2250
            $loop = FALSE;
 
2251
        }
 
2252
        $minv = $maxv + 1;
 
2253
    }
 
2254
 
 
2255
    update_playlist();
 
2256
}
 
2257
 
 
2258
#***
 
2259
 
 
2260
#****f* lyricue/import_song
 
2261
# NAME
 
2262
#   import_song
 
2263
# SYNOPSIS
 
2264
#   import_song ()
 
2265
# FUNCTION
 
2266
#   Import a song into the add song dialog
 
2267
# INPUTS
 
2268
# OUTPUT
 
2269
#   A dialog to open song to import
 
2270
# SOURCE
 
2271
#
 
2272
sub import_song {
 
2273
    debug("import song");
 
2274
    my $filexml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
2275
        'dialogFileChooser', 'lyricue');
 
2276
    $filexml->signal_autoconnect_from_package('');
 
2277
    $filexml->get_widget('buttonFileOK')
 
2278
      ->signal_connect("clicked", "do_import_song", $filexml);
 
2279
    $filexml->get_widget('dialogFileChooser')->show_all();
 
2280
}
 
2281
 
 
2282
#***
 
2283
 
 
2284
#****f* lyricue/do_import_song
 
2285
# NAME
 
2286
#   do_import_song
 
2287
# SYNOPSIS
 
2288
#   do_import_song ($widget, $filexml)
 
2289
# FUNCTION
 
2290
#   Actually import the song into the add song dialog
 
2291
# INPUTS
 
2292
#   $widget - Calling widget
 
2293
#   $filexml - Dialog containing selected filename
 
2294
# OUTPUT
 
2295
#   Filled in add song dialog
 
2296
# SOURCE
 
2297
#
 
2298
sub do_import_song {
 
2299
    my ($widget, $filexml) = @_;
 
2300
    debug("do import song");
 
2301
    my $filename   = $filexml->get_widget('dialogFileChooser')->get_filename;
 
2302
    my $lcfilename = lc($filename);
 
2303
 
 
2304
    if (($lcfilename =~ /xmlz$/) || ($lcfilename =~ /xml$/)) {
 
2305
        import_song_xml($filename);
 
2306
    } elsif ($lcfilename =~ /txt$/) {
 
2307
        import_song_text($filename);
 
2308
    } elsif ($lcfilename =~ /sng$/) {
 
2309
        import_song_songbeamer($filename);
 
2310
    } elsif ($lcfilename =~ /usr$/) {
 
2311
        import_song_songselect($filename);
 
2312
    } elsif ($lcfilename =~ /opw$/) {
 
2313
        import_song_opw($filename);
 
2314
    } elsif ($lcfilename =~ /html$/) {
 
2315
        import_song_html($filename);
 
2316
    }
 
2317
 
 
2318
    close_dialog($widget);
 
2319
}
 
2320
 
 
2321
#***
 
2322
 
 
2323
#****f* lyricue/import_song_text
 
2324
# NAME
 
2325
#   import_song_text
 
2326
# SYNOPSIS
 
2327
#   import_song_text ()
 
2328
# FUNCTION
 
2329
#   Import a song which was stored as a text file
 
2330
# INPUTS
 
2331
#   $filename - File to import
 
2332
# OUTPUT
 
2333
#   Closes the interface
 
2334
# SOURCE
 
2335
sub import_song_text {
 
2336
    my ($filename) = @_;
 
2337
    debug("import text song");
 
2338
 
 
2339
    my ($artist, $name, $keywords, $number, $book, $copyright) = "";
 
2340
    my $hashnum = 0;
 
2341
    open(SONG, $filename) || return;
 
2342
    binmode SONG, ":encoding(utf8)";
 
2343
    while (<SONG>) {
 
2344
        if (/^Name:/) {
 
2345
            if (!$name) {
 
2346
                chomp;
 
2347
                $name = $_;
 
2348
                $name =~ s/^.*://g;
 
2349
                $name =~ s/^ *//g;
 
2350
                $widgets->{'add'}->get_widget('entryEditName')->set_text($name);
 
2351
            }
 
2352
        } elsif (/^Book:/) {
 
2353
 
 
2354
            if (!$book) {
 
2355
                chomp;
 
2356
                $book = $_;
 
2357
                $book =~ s/^.*://g;
 
2358
                $book =~ s/^ *//g;
 
2359
                $widgets->{'add'}->get_widget('entryEditBook')->set_text($book);
 
2360
            }
 
2361
        } elsif (/^Number:/) {
 
2362
 
 
2363
            if (!$number) {
 
2364
                chomp;
 
2365
                $number = $_;
 
2366
                $number =~ s/^.*://g;
 
2367
                $number =~ s/^ *//g;
 
2368
                $widgets->{'add'}->get_widget('entryEditNumber')
 
2369
                  ->set_text($number);
 
2370
            }
 
2371
        } elsif (/^Artist:/) {
 
2372
            chomp;
 
2373
            $_ =~ s/^.*://g;
 
2374
            $_ =~ s/^ *//g;
 
2375
 
 
2376
            if (!$artist) {
 
2377
                $artist = $_;
 
2378
                $widgets->{'add'}->get_widget('entryEditArtist')
 
2379
                  ->set_text($artist);
 
2380
            } else {
 
2381
                $artist = "\n" . $_;
 
2382
                $widgets->{'add'}->get_widget('entryEditArtist')
 
2383
                  ->append_text($artist);
 
2384
            }
 
2385
        } elsif (/^Keywords:/) {
 
2386
 
 
2387
            if (!$keywords) {
 
2388
                chomp;
 
2389
                $keywords = $_;
 
2390
                $keywords =~ s/^.*://g;
 
2391
                $keywords =~ s/^ *//g;
 
2392
                $widgets->{'add'}->get_widget('entryEditKeywords')
 
2393
                  ->set_text($keywords);
 
2394
            }
 
2395
        } elsif (/^Copyright/) {
 
2396
 
 
2397
            if (!$copyright) {
 
2398
                chomp;
 
2399
                $copyright = $_;
 
2400
                $copyright =~ s/^.*://g;
 
2401
                $copyright =~ s/^ *//g;
 
2402
                $widgets->{'add'}->get_widget('entryEditCopyright')
 
2403
                  ->set_text($copyright);
 
2404
            }
 
2405
        } elsif (/^--/) {
 
2406
            debug("add page");
 
2407
            $hashnum = add_page();
 
2408
        } else {
 
2409
            debug("add line");
 
2410
            my $iter = $widgets->{'textAPageB'}{$hashnum}->get_end_iter();
 
2411
            $widgets->{'textAPageB'}{$hashnum}->insert($iter, $_);
 
2412
        }
 
2413
    }
 
2414
    close SONG;
 
2415
}
 
2416
 
 
2417
#***
 
2418
 
 
2419
#****f* lyricue/import_song_xml
 
2420
# NAME
 
2421
#   import_song_xml
 
2422
# SYNOPSIS
 
2423
#   import_song_xml ($filename)
 
2424
# FUNCTION
 
2425
#   Import a song which was stored as an xml file
 
2426
# INPUTS
 
2427
#   $filename - File to import
 
2428
# OUTPUT
 
2429
#   Closes the interface
 
2430
# SOURCE
 
2431
sub import_song_xml {
 
2432
    my ($filename) = @_;
 
2433
    debug("import xml song");
 
2434
 
 
2435
    my ($xml);
 
2436
    if ($filename =~ /[zZ]$/) {
 
2437
        open my $fh, "gzip -dc \"" . $filename . "\" |";
 
2438
        $xml = XMLin($fh, ForceArray => ['page'], SuppressEmpty => '');
 
2439
        close $fh;
 
2440
    } else {
 
2441
        $xml = XMLin($filename, ForceArray => ['page'], SuppressEmpty => '');
 
2442
    }
 
2443
    $widgets->{'add'}->get_widget('entryEditName')
 
2444
      ->set_text($xml->{'song'}->{'name'});
 
2445
    $widgets->{'add'}->get_widget('entryEditBook')
 
2446
      ->set_text($xml->{'song'}->{'book'});
 
2447
    $widgets->{'add'}->get_widget('entryEditNumber')
 
2448
      ->set_text($xml->{'song'}->{'number'});
 
2449
    $widgets->{'add'}->get_widget('entryEditArtist')
 
2450
      ->set_text($xml->{'song'}->{'artist'});
 
2451
    $widgets->{'add'}->get_widget('entryEditKeywords')
 
2452
      ->set_text($xml->{'song'}->{'keywords'});
 
2453
    $widgets->{'add'}->get_widget('entryEditCopyright')
 
2454
      ->set_text($xml->{'song'}->{'copyright'});
 
2455
    my $pages     = $xml->{'song'}->{'page'};
 
2456
    my $firstpage = TRUE;
 
2457
 
 
2458
    foreach (@$pages) {
 
2459
        debug("add page");
 
2460
        if ($firstpage) {
 
2461
            $firstpage = FALSE;
 
2462
            $widgets->{'textAPageB'}{0}->set_text($_);
 
2463
        } else {
 
2464
            my $hashnum = add_page();
 
2465
            $widgets->{'textAPageB'}{$hashnum}->set_text($_);
 
2466
        }
 
2467
    }
 
2468
}
 
2469
 
 
2470
#***
 
2471
 
 
2472
#****f* lyricue/import_song_songbeamer
 
2473
# NAME
 
2474
#   import_song_songbeamer
 
2475
# SYNOPSIS
 
2476
#   import_song_songbeamer ($filename)
 
2477
# FUNCTION
 
2478
#   Import a song from Songbeamer format
 
2479
# INPUTS
 
2480
#   $filename - Filename of .sng file to import
 
2481
# OUTPUT
 
2482
#   Filled in add song dialog
 
2483
# SOURCE
 
2484
#
 
2485
sub import_song_songbeamer {
 
2486
    my ($filename) = @_;
 
2487
    debug("import songbeamer song");
 
2488
 
 
2489
    my ($artist, $name, $number, $book, $copyright, $firstpage) = "";
 
2490
    my $hashnum = 0;
 
2491
    open(SONG, $filename) || return;
 
2492
    while (<SONG>) {
 
2493
        if (/^#Title=/) {
 
2494
            if (!$name) {
 
2495
                chomp;
 
2496
                $name = $_;
 
2497
                $name =~ s/^#.*=//g;
 
2498
                $name =~ s/^ *//g;
 
2499
                $name =~ s/\r//g;
 
2500
                $widgets->{'add'}->get_widget('entryEditName')->set_text($name);
 
2501
            }
 
2502
        } elsif (/^#Songbook=/) {
 
2503
 
 
2504
            if (!$book) {
 
2505
                chomp;
 
2506
                $book = $_;
 
2507
                $book =~ s/^#.*=//g;
 
2508
                $book =~ s/^ *//g;
 
2509
                $book =~ s/\/.*$//g;
 
2510
                $book =~ s/\r//g;
 
2511
                $widgets->{'add'}->get_widget('entryEditBook')->set_text($book);
 
2512
            }
 
2513
            if (!$number) {
 
2514
                chomp;
 
2515
                $number = $_;
 
2516
                $number =~ s/^#.*=[^\/]*\///g;
 
2517
                $number =~ s/^ *//g;
 
2518
                $number =~ s/\r//g;
 
2519
                $widgets->{'add'}->get_widget('entryEditNumber')
 
2520
                  ->set_text($number);
 
2521
            }
 
2522
        } elsif (/^#Author=/) {
 
2523
            chomp;
 
2524
            $_ =~ s/^#.*=//g;
 
2525
            $_ =~ s/^ *//g;
 
2526
            $_ =~ s/\r//g;
 
2527
 
 
2528
            if (!$artist) {
 
2529
                $artist = $_;
 
2530
                $widgets->{'add'}->get_widget('entryEditArtist')
 
2531
                  ->set_text($artist);
 
2532
            } else {
 
2533
                $artist = ", " . $_;
 
2534
                $widgets->{'add'}->get_widget('entryEditArtist')
 
2535
                  ->append_text($artist);
 
2536
            }
 
2537
        } elsif (/^#Melody=/) {
 
2538
            chomp;
 
2539
            $_ =~ s/^#.*=//g;
 
2540
            $_ =~ s/^ *//g;
 
2541
            $_ =~ s/\r//g;
 
2542
 
 
2543
            if (!$artist) {
 
2544
                $artist = $_;
 
2545
                $widgets->{'add'}->get_widget('entryEditArtist')
 
2546
                  ->set_text($artist);
 
2547
            } else {
 
2548
                $artist = ", " . $_;
 
2549
                $widgets->{'add'}->get_widget('entryEditArtist')
 
2550
                  ->append_text($artist);
 
2551
            }
 
2552
        } elsif (/^#\(c\)=/) {
 
2553
 
 
2554
            if (!$copyright) {
 
2555
                chomp;
 
2556
                $copyright = $_;
 
2557
                $copyright =~ s/^#.*=//g;
 
2558
                $copyright =~ s/^ *//g;
 
2559
                $copyright =~ s/\r//g;
 
2560
                $widgets->{'add'}->get_widget('entryEditCopyright')
 
2561
                  ->set_text($copyright);
 
2562
            }
 
2563
        } elsif (/^#/) {   # many functions in SongBeamer are unknown to Lyricue
 
2564
            debug("unknown operator");
 
2565
        } elsif (/^---/) {
 
2566
            if ($firstpage) {    #no new page in the first run
 
2567
                debug("add page");
 
2568
                $hashnum = add_page();
 
2569
            } else {
 
2570
                $firstpage = "yes";
 
2571
            }
 
2572
        } else {
 
2573
            debug("add line");
 
2574
            my $iter = $widgets->{'textAPageB'}{$hashnum}->get_end_iter();
 
2575
            $widgets->{'textAPageB'}{$hashnum}->insert($iter, $_);
 
2576
        }
 
2577
    }
 
2578
    close SONG;
 
2579
}
 
2580
 
 
2581
#***
 
2582
 
 
2583
#****f* lyricue/update_songinfo
 
2584
# NAME
 
2585
#   update_songinfo
 
2586
# SYNOPSIS
 
2587
#   update_songinfo ($songid)
 
2588
# FUNCTION
 
2589
#   Fill in the add song dialog with the chosen songs details/lyrics
 
2590
# INPUTS
 
2591
#   $songid - Id of song to edit
 
2592
# OUTPUT
 
2593
#   Filled in add song dialog
 
2594
# SOURCE
 
2595
#
 
2596
sub update_songinfo {
 
2597
    my ($songid) = @_;
 
2598
    debug("Edit clicked");
 
2599
    my ($sth, $query, $hashnum);
 
2600
 
 
2601
    if ($songid) {
 
2602
        $widgets->{'add'}->get_widget('windowEditSong')->{user_data} = $songid;
 
2603
        $query =
 
2604
            "SELECT lyrics,pagetitle FROM page WHERE songid=\"" 
 
2605
          . $songid
 
2606
          . "\" ORDER BY pagenum";
 
2607
        qdebug($query);
 
2608
        $sth = $lyricDbh->prepare($query)
 
2609
          || display_fatal($errorcodes->{'sqlprepare'},
 
2610
            $! . "\nSQL: " . $query);
 
2611
        $rv = $sth->execute
 
2612
          || display_fatal($errorcodes->{'sqlexecute'},
 
2613
            $! . "\nSQL: " . $query);
 
2614
 
 
2615
        while ($row = $sth->fetchrow_hashref()) {
 
2616
            $hashnum = add_page();
 
2617
            $widgets->{'textAPageB'}{$hashnum}
 
2618
              ->set_text(fromutf($row->{'lyrics'}));
 
2619
            if ($row->{'pagetitle'} ne "") {
 
2620
                $widgets->{'labelAPage'}{$hashnum}
 
2621
                  ->set_text(fromutf($row->{'pagetitle'}));
 
2622
            }
 
2623
        }
 
2624
 
 
2625
        $query =
 
2626
"SELECT title,songnum,book,artist,keywords,copyright from lyricMain WHERE id="
 
2627
          . $songid;
 
2628
        qdebug($query);
 
2629
        $sth = $lyricDbh->prepare($query)
 
2630
          || display_fatal($errorcodes->{'sqlprepare'},
 
2631
            $! . "\nSQL: " . $query);
 
2632
        $rv = $sth->execute
 
2633
          || display_fatal($errorcodes->{'sqlexecute'},
 
2634
            $! . "\nSQL: " . $query);
 
2635
        if ($row = $sth->fetchrow_hashref()) {
 
2636
            $widgets->{'add'}->get_widget('entryEditName')
 
2637
              ->set_text(fromutf($row->{'title'}));
 
2638
            $widgets->{'add'}->get_widget('entryEditBook')
 
2639
              ->set_text(fromutf($row->{'book'}));
 
2640
            $widgets->{'add'}->get_widget('entryEditNumber')
 
2641
              ->set_text(fromutf($row->{'songnum'}));
 
2642
            $widgets->{'add'}->get_widget('entryEditArtist')
 
2643
              ->set_text(fromutf($row->{'artist'}));
 
2644
            if ($row->{'keywords'} =~ /^NOAUDIT /) {
 
2645
                $row->{'keywords'} =~ s/^NOAUDIT //g;
 
2646
                $widgets->{'add'}->get_widget('checkEditAudit')
 
2647
                  ->set_active(FALSE);
 
2648
            } else {
 
2649
                $widgets->{'add'}->get_widget('checkEditAudit')
 
2650
                  ->set_active(TRUE);
 
2651
            }
 
2652
            $widgets->{'add'}->get_widget('entryEditKeywords')
 
2653
              ->set_text(fromutf($row->{'keywords'}));
 
2654
            $widgets->{'add'}->get_widget('entryEditCopyright')
 
2655
              ->set_text(fromutf($row->{'copyright'}));
 
2656
        }
 
2657
        $widgets->{'add'}->get_widget('notebookEditPages')->set_current_page(0);
 
2658
    }
 
2659
}
 
2660
 
 
2661
#***
 
2662
 
 
2663
#****f* lyricue/add_to_playlist
 
2664
# NAME
 
2665
#   add_to_playlist
 
2666
# SYNOPSIS
 
2667
#   add_to_playlist ()
 
2668
# FUNCTION
 
2669
#   Add the chosen songs to the playlist
 
2670
# OUTPUT
 
2671
#   More songs in the playlist
 
2672
# SOURCE
 
2673
#
 
2674
sub add_to_playlist {
 
2675
    debug("Add to playlist clicked");
 
2676
    my $selection =
 
2677
      $widgets->{'main'}->get_widget('treeAvailable')->get_selection;
 
2678
    my $model = $widgets->{'main'}->get_widget('treeAvailable')->get_model;
 
2679
    my @sel   = $selection->get_selected_rows;
 
2680
    foreach my $path (@sel) {
 
2681
        add_single_song($model->get($model->get_iter($path), 3));
 
2682
    }
 
2683
 
 
2684
    update_playlist();
 
2685
}
 
2686
 
 
2687
#***
 
2688
 
 
2689
#****f* lyricue/add_single_song
 
2690
# NAME
 
2691
#   add_single_song
 
2692
# SYNOPSIS
 
2693
#   add_single_song ($availableSelection)
 
2694
# FUNCTION
 
2695
#   Add a single song to the playlist
 
2696
#   Optionally audit this addition
 
2697
# INPUTS
 
2698
#   $availableSelection - Song id to add to the playlist
 
2699
# OUTPUT
 
2700
#   One more song in the playlist
 
2701
# SOURCE
 
2702
#
 
2703
sub add_single_song {
 
2704
    my ($availableSelection) = @_;
 
2705
    debug("add single song");
 
2706
 
 
2707
    # Drop out if no playlist selected
 
2708
    if ($widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data} ==
 
2709
        -1)
 
2710
    {
 
2711
        return;
 
2712
    }
 
2713
    my ($playorder);
 
2714
 
 
2715
    my $query = "SELECT MAX(playorder) FROM playlist";
 
2716
    $sth = $lyricDbh->prepare($query)
 
2717
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2718
    $rv = $sth->execute
 
2719
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2720
    if ($row = $sth->fetchrow_hashref()) {
 
2721
        if ($row->{'MAX(playorder)'}) {
 
2722
            $playorder = $row->{'MAX(playorder)'} + 1;
 
2723
        } else {
 
2724
            $playorder = 1;
 
2725
        }
 
2726
    } else {
 
2727
        $playorder = 1;
 
2728
    }
 
2729
 
 
2730
    # Find next playlists entry
 
2731
    $query = "SELECT MAX(id) FROM playlists";
 
2732
    qdebug($query);
 
2733
    $sth = $lyricDbh->prepare($query)
 
2734
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2735
    $rv = $sth->execute
 
2736
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2737
    $row = $sth->fetchrow_hashref();
 
2738
    my $playlist = $row->{'MAX(id)'} + 1;
 
2739
 
 
2740
    $query =
 
2741
        "INSERT INTO playlist (playorder, playlist, data,type) VALUES ("
 
2742
      . $playorder . ","
 
2743
      . $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data}
 
2744
      . ","
 
2745
      . $playlist
 
2746
      . ",\"play\")";
 
2747
    qdebug($query);
 
2748
    $sth = $lyricDbh->prepare($query)
 
2749
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2750
    $rv = $sth->execute
 
2751
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2752
 
 
2753
    # Find song info
 
2754
    my $title = "";
 
2755
    $query =
 
2756
"SELECT title,pageid,keywords FROM lyricMain, page WHERE songid=id AND id="
 
2757
      . $availableSelection
 
2758
      . " ORDER BY pagenum";
 
2759
    qdebug($query);
 
2760
    $sth = $lyricDbh->prepare($query)
 
2761
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2762
    $rv = $sth->execute
 
2763
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2764
    my $audit = TRUE;
 
2765
    while ($row = $sth->fetchrow_hashref()) {
 
2766
 
 
2767
        # Add the pages
 
2768
        my $keywords = $row->{'keywords'};
 
2769
        if ($keywords =~ /^NOAUDIT /) {
 
2770
            $audit = FALSE;
 
2771
        }
 
2772
        $title = $row->{'title'};
 
2773
        $playorder++;
 
2774
        my $query2 =
 
2775
            "INSERT INTO playlist (playorder, playlist, data,type) VALUES ("
 
2776
          . $playorder . ", "
 
2777
          . $playlist . ","
 
2778
          . $row->{'pageid'}
 
2779
          . ", \"song\")";
 
2780
        qdebug($query2);
 
2781
        my $sth2 = $lyricDbh->prepare($query2)
 
2782
          || display_fatal($errorcodes->{'sqlprepare'},
 
2783
            $! . "\nSQL: " . $query2);
 
2784
        my $rv2 = $sth2->execute
 
2785
          || display_fatal($errorcodes->{'sqlexecute'},
 
2786
            $! . "\nSQL: " . $query2);
 
2787
    }
 
2788
 
 
2789
    # Add playlists entry
 
2790
    $query =
 
2791
        "INSERT INTO playlists (id,title,ref) VALUES ("
 
2792
      . $playlist . ",\""
 
2793
      . $title . "\","
 
2794
      . $availableSelection . ")";
 
2795
    $sth = $lyricDbh->prepare($query)
 
2796
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2797
    $rv = $sth->execute
 
2798
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2799
 
 
2800
    # audit this addition
 
2801
    # currently always runs due to problem with passing in widgets
 
2802
    debug("Audit: $config->{'Audit'}");
 
2803
    if ($config->{'Audit'} && $audit) {
 
2804
        $query = "SELECT MAX(id)+1 FROM audit";
 
2805
        qdebug($query);
 
2806
        $sth = $lyricDbh->prepare($query)
 
2807
          || display_fatal($errorcodes->{'sqlprepare'},
 
2808
            $! . "\nSQL: " . $query);
 
2809
        $rv = $sth->execute
 
2810
          || display_fatal($errorcodes->{'sqlexecute'},
 
2811
            $! . "\nSQL: " . $query);
 
2812
        my @row = $sth->fetchrow_array;
 
2813
        if (!defined $row[0]) {
 
2814
            $row[0] = "1";
 
2815
        }
 
2816
        $query =
 
2817
            "INSERT INTO audit (id,songid,playdate) VALUES("
 
2818
          . $row[0] . ", "
 
2819
          . $availableSelection
 
2820
          . ", NOW())";
 
2821
        debug("Auditing with: " . $query);
 
2822
        $sth = $lyricDbh->prepare($query)
 
2823
          || display_fatal($errorcodes->{'sqlprepare'},
 
2824
            $! . "\nSQL: " . $query);
 
2825
        $rv = $sth->execute
 
2826
          || display_fatal($errorcodes->{'sqlexecute'},
 
2827
            $! . "\nSQL: " . $query);
 
2828
    }
 
2829
}
 
2830
 
 
2831
#***
 
2832
 
 
2833
#****f* lyricue/remove_from_playlist
 
2834
# NAME
 
2835
#   remove_from_playlist
 
2836
# SYNOPSIS
 
2837
#   remove_from_playlist ()
 
2838
# FUNCTION
 
2839
#   Remove selected songs from the playlist
 
2840
# OUTPUT
 
2841
#   Less songs in the playlist
 
2842
# SOURCE
 
2843
#
 
2844
sub remove_from_playlist {
 
2845
    debug("remove from playlist");
 
2846
 
 
2847
    #Cancel any loop timers
 
2848
    #Continuing to loop over possibly removed playlist
 
2849
    #items represents a major crash risk - better safe
 
2850
    #than sorry.
 
2851
    #
 
2852
    reset_timer($globals->{'timer'});
 
2853
 
 
2854
    my $selection =
 
2855
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
2856
    debug("Remove from playlist clicked");
 
2857
    my ($model, $iter) = $selection->get_selected;
 
2858
    if ($iter) {
 
2859
        remove_single_item($model->get($iter, 2));
 
2860
        update_playlist();
 
2861
    }
 
2862
}
 
2863
 
 
2864
#***
 
2865
 
 
2866
#****f* lyricue/remove_single_item
 
2867
# NAME
 
2868
#   remove_single_item
 
2869
# SYNOPSIS
 
2870
#   remove_single_item ($item)
 
2871
# FUNCTION
 
2872
#   Remove a single song from the playlist
 
2873
# INPUTS
 
2874
#   $item - Playlist Id to remove
 
2875
# OUTPUT
 
2876
#   One less song on the playlist
 
2877
# SOURCE
 
2878
#
 
2879
sub remove_single_item {
 
2880
    my ($item) = @_;
 
2881
    debug("Deleting $item from playlist");
 
2882
    reset_timer($globals->{'timer'});
 
2883
    my $query = "SELECT type,data  FROM playlist WHERE playorder=" . $item;
 
2884
    qdebug($query);
 
2885
    my $sth = $lyricDbh->prepare($query)
 
2886
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2887
    my $rv = $sth->execute
 
2888
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2889
    my @row = $sth->fetchrow_array;
 
2890
 
 
2891
    if ($row[0] eq "play" | $row[0] eq "sub") {
 
2892
        $query = "SELECT playorder FROM playlist WHERE playlist=" . $row[1];
 
2893
        qdebug($query);
 
2894
        $sth = $lyricDbh->prepare($query)
 
2895
          || display_fatal($errorcodes->{'sqlprepare'},
 
2896
            $! . "\nSQL: " . $query);
 
2897
        $rv = $sth->execute
 
2898
          || display_fatal($errorcodes->{'sqlexecute'},
 
2899
            $! . "\nSQL: " . $query);
 
2900
        while (my @row2 = $sth->fetchrow_array) {
 
2901
            remove_single_item($row2[0]);
 
2902
        }
 
2903
 
 
2904
        $query = "DELETE FROM playlist WHERE playlist=" . $row[1];
 
2905
        qdebug($query);
 
2906
        $sth = $lyricDbh->prepare($query)
 
2907
          || display_fatal($errorcodes->{'sqlprepare'},
 
2908
            $! . "\nSQL: " . $query);
 
2909
        $rv = $sth->execute
 
2910
          || display_fatal($errorcodes->{'sqlexecute'},
 
2911
            $! . "\nSQL: " . $query);
 
2912
 
 
2913
        $query = "DELETE FROM playlists WHERE id=" . $row[1];
 
2914
        qdebug($query);
 
2915
        $sth = $lyricDbh->prepare($query)
 
2916
          || display_fatal($errorcodes->{'sqlprepare'},
 
2917
            $! . "\nSQL: " . $query);
 
2918
        $rv = $sth->execute
 
2919
          || display_fatal($errorcodes->{'sqlexecute'},
 
2920
            $! . "\nSQL: " . $query);
 
2921
    }
 
2922
 
 
2923
    $query = "DELETE FROM playlist WHERE playorder=" . $item;
 
2924
    qdebug($query);
 
2925
    $sth = $lyricDbh->prepare($query)
 
2926
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2927
    $rv = $sth->execute
 
2928
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2929
 
 
2930
    $query = "DELETE FROM associations WHERE playlist=" . $item;
 
2931
    qdebug($query);
 
2932
    $sth = $lyricDbh->prepare($query)
 
2933
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
2934
    $rv = $sth->execute
 
2935
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
2936
 
 
2937
    if (($row[0] eq "file") && ($row[1] =~ /^\/var\/tmp\/lyricue-/)) {
 
2938
 
 
2939
        # Removing temporary file
 
2940
        my $command = "rm " . $row[1];
 
2941
        my $dir     = $row[1];
 
2942
        $dir =~ s/^(\/var\/tmp\/lyricue-.*\/).*$/$1/g;
 
2943
 
 
2944
        # Check if used elsewhere
 
2945
        $query =
 
2946
          "SELECT playorder FROM playlist WHERE data=\"" . $row[1] . "\"";
 
2947
        qdebug($query);
 
2948
        $sth = $lyricDbh->prepare($query)
 
2949
          || display_fatal($errorcodes->{'sqlprepare'},
 
2950
            $! . "\nSQL: " . $query);
 
2951
        $rv = $sth->execute
 
2952
          || display_fatal($errorcodes->{'sqlexecute'},
 
2953
            $! . "\nSQL: " . $query);
 
2954
        if (@row = $sth->fetchrow_array) {
 
2955
            debug("Temporary file used elsewhere - not removing");
 
2956
            return;
 
2957
        }
 
2958
        debug($command);
 
2959
        system($command);
 
2960
 
 
2961
        # Check if directory empty
 
2962
        my $ret = opendir DIR, $dir;
 
2963
        if ($ret) {
 
2964
            my $found = FALSE;
 
2965
            foreach (sort readdir(DIR)) {
 
2966
                if (!/^\.*$/) {
 
2967
                    $found = TRUE;
 
2968
                }
 
2969
            }
 
2970
            if (!$found) {
 
2971
                debug("Empty directory - removing");
 
2972
                $command = "rmdir " . $dir;
 
2973
                debug($command);
 
2974
                system($command);
 
2975
            }
 
2976
        }
 
2977
    }
 
2978
}
 
2979
 
 
2980
#***
 
2981
 
 
2982
#****f* lyricue/clear_playlist
 
2983
# NAME
 
2984
#   clear_playlist
 
2985
# SYNOPSIS
 
2986
#   clear_playlist ($widget)
 
2987
# FUNCTION
 
2988
#   Clear the playlist
 
2989
# INPUTS
 
2990
#   $widget - Calling widget
 
2991
# OUTPUT
 
2992
#   No songs in playlist
 
2993
# SOURCE
 
2994
#
 
2995
sub clear_playlist {
 
2996
    my ($widget) = @_;
 
2997
    debug("Clear playlist");
 
2998
    reset_timer($globals->{'timer'});
 
2999
    my $deletexml =
 
3000
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogConfirm', 'lyricue');
 
3001
    $deletexml->signal_autoconnect_from_package('');
 
3002
    my $labelText =
 
3003
      fromutf(gettext("Are you sure you wish to clear the current playlist?"));
 
3004
    $deletexml->get_widget('labelDelete')->set_text($labelText);
 
3005
    $deletexml->get_widget('dialogConfirm')
 
3006
      ->set_title(fromutf(gettext("Confirm Clear Playlist")));
 
3007
    my $confirm = $deletexml->get_widget('dialogConfirm')->run();
 
3008
 
 
3009
    if ($confirm eq "ok") {
 
3010
        my $main_playlist =
 
3011
          $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
3012
 
 
3013
        my $query =
 
3014
          "SELECT playorder FROM playlist WHERE playlist=" . $main_playlist;
 
3015
        $sth = $lyricDbh->prepare($query)
 
3016
          || display_fatal($errorcodes->{'sqlprepare'},
 
3017
            $! . "\nSQL: " . $query);
 
3018
        $rv = $sth->execute
 
3019
          || display_fatal($errorcodes->{'sqlexecute'},
 
3020
            $! . "\nSQL: " . $query);
 
3021
        while (my @row = $sth->fetchrow_array()) {
 
3022
            remove_single_item($row[0]);
 
3023
        }
 
3024
        update_playlist();
 
3025
    }
 
3026
    close_dialog($deletexml->get_widget('dialogConfirm'));
 
3027
}
 
3028
 
 
3029
#***
 
3030
 
 
3031
#****f* lyricue/display_song
 
3032
# NAME
 
3033
#   Display_song
 
3034
# SYNOPSIS
 
3035
#   display_song (undef, $event)
 
3036
# FUNCTION
 
3037
#   Display a song if double-clicked, or popup menu if right-clicked
 
3038
# INPUTS
 
3039
#   $event - Calling event
 
3040
# OUTPUT
 
3041
#   Updated display or right-click menu is popped-up
 
3042
# SOURCE
 
3043
#
 
3044
sub display_song {
 
3045
    my ($widget, $path,, $column) = @_;
 
3046
    debug("display song");
 
3047
    reset_timer($globals->{'timer'});
 
3048
    my $selection =
 
3049
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
3050
    my ($model, $iter) = $selection->get_selected;
 
3051
    if ($iter) {
 
3052
        update_display("display", $model->get($iter, 2), "");
 
3053
    }
 
3054
    return TRUE;
 
3055
}
 
3056
 
 
3057
sub treePlaylist_cursor_changed {
 
3058
    my ($widget) = @_;
 
3059
    debug("preview playlist item");
 
3060
    my $selection =
 
3061
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
3062
    my ($model, $iter) = $selection->get_selected;
 
3063
    if ($iter) {
 
3064
        my $transition = $model->get($iter, 3);
 
3065
 
 
3066
        # Set the transition values
 
3067
        my $out_direction = mod($transition, 2**NUM_TRANS);
 
3068
        $transition = $transition >> NUM_TRANS;
 
3069
        my $in_direction = mod($transition, 2**NUM_TRANS);
 
3070
        my $effect = $transition >> NUM_TRANS;
 
3071
        if ($effect == NOTRANS ) {
 
3072
            $widgets->{'main'}->get_widget('radioTransNone')->set_active(TRUE);
 
3073
        } elsif ($effect == FADE) {
 
3074
            $widgets->{'main'}->get_widget('radioTransFade')->set_active(TRUE);
 
3075
        } elsif ($effect == SLIDE_TEXT) {
 
3076
            $widgets->{'main'}->get_widget('radioTransSlide')->set_active(TRUE);
 
3077
        } elsif ($effect == ROTATE_TEXT) {
 
3078
            $widgets->{'main'}->get_widget('radioTransRotate')
 
3079
              ->set_active(TRUE);
 
3080
        } else {
 
3081
            $widgets->{'main'}->get_widget('radioTransDefault')->set_active(TRUE);
 
3082
        }
 
3083
        my $indir = "";
 
3084
        if ($in_direction & UP)    { $indir .= "Up" }
 
3085
        if ($in_direction & DOWN)  { $indir .= "Down" }
 
3086
        if ($in_direction & LEFT)  { $indir .= "Left" }
 
3087
        if ($in_direction & RIGHT) { $indir .= "Right" }
 
3088
        if ($indir eq "") { $indir = "None" }
 
3089
        $widgets->{'main'}->get_widget("toggleIn" . $indir)->set_active(TRUE);
 
3090
        $widgets->{'main'}->get_widget("toggleRotX")
 
3091
          ->set_active($in_direction & X_AXIS);
 
3092
        $widgets->{'main'}->get_widget("toggleRotY")
 
3093
          ->set_active($in_direction & Y_AXIS);
 
3094
        $widgets->{'main'}->get_widget("toggleRotZ")
 
3095
          ->set_active($in_direction & Z_AXIS);
 
3096
 
 
3097
        my $outdir = "";
 
3098
        if ($out_direction & UP)    { $outdir .= "Up" }
 
3099
        if ($out_direction & DOWN)  { $outdir .= "Down" }
 
3100
        if ($out_direction & LEFT)  { $outdir .= "Left" }
 
3101
        if ($out_direction & RIGHT) { $outdir .= "Right" }
 
3102
        if ($outdir eq "") { $outdir = "None" }
 
3103
        $widgets->{'main'}->get_widget("toggleOut" . $outdir)->set_active(TRUE);
 
3104
    }
 
3105
    update_quickedit();
 
3106
    if ($config->{'DynamicPreview'}) {
 
3107
        preview_playlist_item();
 
3108
    }
 
3109
}
 
3110
 
 
3111
sub on_treePlaylist_button_press_event {
 
3112
    my ($widget, $event) = @_;
 
3113
 
 
3114
    # Right-click menu
 
3115
    if ($event->button == 3) {
 
3116
        popup_play_menu($event);
 
3117
        return TRUE;
 
3118
    }
 
3119
    return FALSE;
 
3120
}
 
3121
 
 
3122
#***
 
3123
 
 
3124
#****f* lyricue/display_now
 
3125
# NAME
 
3126
#   display_now
 
3127
# SYNOPSIS
 
3128
#   display_now ($widget)
 
3129
# FUNCTION
 
3130
#   Display now button clicked
 
3131
# INPUTS
 
3132
#   $widget - Calling widget
 
3133
# OUTPUT
 
3134
#   Display updated with currently selected song
 
3135
# SOURCE
 
3136
#
 
3137
sub display_now {
 
3138
    my ($widget) = @_;
 
3139
    debug("Display clicked");
 
3140
 
 
3141
    reset_timer($globals->{'timer'});
 
3142
 
 
3143
    my $selection =
 
3144
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
3145
    my ($model, $iter) = $selection->get_selected;
 
3146
    if ($iter) {
 
3147
        update_display("display", $model->get($iter, 2), "");
 
3148
    }
 
3149
}
 
3150
 
 
3151
#***
 
3152
 
 
3153
#****f* lyricue/prev_page
 
3154
# NAME
 
3155
#   prev_page
 
3156
# SYNOPSIS
 
3157
#   prev_page ()
 
3158
# FUNCTION
 
3159
#   Display the previous page in the server
 
3160
# INPUTS
 
3161
#   none
 
3162
# OUTPUT
 
3163
#   Calls update_display
 
3164
# SOURCE
 
3165
#
 
3166
sub prev_page {
 
3167
    debug("Prev clicked");
 
3168
    reset_timer($globals->{'timer'});
 
3169
    update_display("display", "prev_page", $config->{'LoopText'});
 
3170
}
 
3171
 
 
3172
#***
 
3173
 
 
3174
#****f* lyricue/next_page
 
3175
# NAME
 
3176
#   next_page
 
3177
# SYNOPSIS
 
3178
#   next_page ()
 
3179
# FUNCTION
 
3180
#   Display the next page in the server
 
3181
# INPUTS
 
3182
#   None
 
3183
# OUTPUT
 
3184
#   Calls update_display
 
3185
# SOURCE
 
3186
#
 
3187
sub next_page {
 
3188
    debug("Next clicked");
 
3189
    reset_timer($globals->{'timer'});
 
3190
    update_display("display", "next_page", $config->{'LoopText'});
 
3191
}
 
3192
 
 
3193
#***
 
3194
 
 
3195
#****f* lyricue/prev_song
 
3196
# NAME
 
3197
#   prev_song
 
3198
# SYNOPSIS
 
3199
#   prev_song ()
 
3200
# FUNCTION
 
3201
#   Display the previous song in the server
 
3202
# INPUTS
 
3203
#   none
 
3204
# OUTPUT
 
3205
#   Calls update_display
 
3206
# SOURCE
 
3207
#
 
3208
sub prev_song {
 
3209
    debug("Prev clicked");
 
3210
    reset_timer($globals->{'timer'});
 
3211
    update_display("display", "prev_song", $config->{'LoopText'});
 
3212
}
 
3213
 
 
3214
#***
 
3215
 
 
3216
#****f* lyricue/next_song
 
3217
# NAME
 
3218
#   next_song
 
3219
# SYNOPSIS
 
3220
#   next_song ()
 
3221
# FUNCTION
 
3222
#   Display the next song in the server
 
3223
# INPUTS
 
3224
#   None
 
3225
# OUTPUT
 
3226
#   Calls update_display
 
3227
# SOURCE
 
3228
#
 
3229
sub next_song {
 
3230
    debug("Next clicked");
 
3231
    reset_timer($globals->{'timer'});
 
3232
    update_display("display", "next_song", $config->{'LoopText'});
 
3233
}
 
3234
 
 
3235
#***
 
3236
 
 
3237
#****f* lyricue/blank_page
 
3238
# NAME
 
3239
#   blank_page
 
3240
# SYNOPSIS
 
3241
#   blank_page ()
 
3242
# FUNCTION
 
3243
#   Blank the server
 
3244
# INPUTS
 
3245
#   None
 
3246
# OUTPUT
 
3247
#   Calls update_display
 
3248
# SOURCE
 
3249
#
 
3250
sub blank_page {
 
3251
    my ($widget) = @_;
 
3252
    if ($globals->{'ignore_blank'}) {
 
3253
        debug("ignore blank");
 
3254
        $globals->{'ignore_blank'} = FALSE;
 
3255
        return;
 
3256
    }
 
3257
    debug("Blank page clicked");
 
3258
    reset_timer($globals->{'timer'});
 
3259
    update_display("blank", $config->{'BGImage'}, "");
 
3260
}
 
3261
 
 
3262
#***
 
3263
 
 
3264
#****f* lyricue/clear_text
 
3265
# NAME
 
3266
#   clear_text
 
3267
# SYNOPSIS
 
3268
#   clear_text ()
 
3269
# FUNCTION
 
3270
#   Clear the server text
 
3271
# INPUTS
 
3272
#   None
 
3273
# OUTPUT
 
3274
#   Calls update_display
 
3275
# SOURCE
 
3276
#
 
3277
sub clear_text {
 
3278
    my ($widget) = @_;
 
3279
    if ($globals->{'ignore_clear'}) {
 
3280
        $globals->{'ignore_clear'} = FALSE;
 
3281
        debug("ignore clear");
 
3282
        return;
 
3283
    }
 
3284
    debug("Clear text clicked");
 
3285
    reset_timer($globals->{'timer'});
 
3286
    update_display("blank", "", "");
 
3287
}
 
3288
 
 
3289
#***
 
3290
 
 
3291
#****f* lyricue/next_point
 
3292
# NAME
 
3293
#   next_point
 
3294
# SYNOPSIS
 
3295
#   next_point ()
 
3296
# FUNCTION
 
3297
#   Display the next point in the server
 
3298
# INPUTS
 
3299
#   None
 
3300
# OUTPUT
 
3301
#   Calls update_display
 
3302
# SOURCE
 
3303
#
 
3304
sub next_point {
 
3305
    debug("Next point clicked");
 
3306
    reset_timer($globals->{'timer'});
 
3307
    update_display("next_point", "", "");
 
3308
}
 
3309
 
 
3310
#***
 
3311
 
 
3312
#****f* lyricue/preview_page
 
3313
# NAME
 
3314
#   preview_page
 
3315
# SYNOPSIS
 
3316
#   preview_page ($widget)
 
3317
# FUNCTION
 
3318
#   Preview a page in the server
 
3319
# INPUTS
 
3320
#   $widget - Calling widget
 
3321
# OUTPUT
 
3322
#   Calls update_display
 
3323
# SOURCE
 
3324
#
 
3325
sub preview_page {
 
3326
    my ($widget, $type) = @_;
 
3327
    debug("preview page $type");
 
3328
    reset_timer($globals->{'timer'});
 
3329
 
 
3330
    my $current_page =
 
3331
      $widgets->{'add'}->get_widget('notebookEditPages')->get_current_page() +
 
3332
      1;
 
3333
    my $current_hash = 1;
 
3334
    debug($current_page . " page ");
 
3335
    my $label = $widgets->{'labelAPage'};
 
3336
    foreach (keys %$label) {
 
3337
        if ($widgets->{'labelAPage'}{$_}->get_text() eq
 
3338
            fromutf(gettext("Page ")) . $current_page)
 
3339
        {
 
3340
            $current_hash = $_;
 
3341
        }
 
3342
    }
 
3343
    debug($current_hash . " hash");
 
3344
 
 
3345
    #join all the strings together so update display will accept them, removing
 
3346
    #any newlines or semicolons that would upset the split on the other end.
 
3347
    my $titledata =
 
3348
        $widgets->{'add'}->get_widget('entryEditName')->get_text()
 
3349
      . "#BREAK#"
 
3350
      . $widgets->{'add'}->get_widget('entryEditArtist')->get_text()
 
3351
      . "#BREAK#"
 
3352
      . $widgets->{'add'}->get_widget('entryEditCopyright')->get_text()
 
3353
      . "#BREAK#wrap";
 
3354
    $titledata =~ s/:/#SEMI#/g;
 
3355
    my $songtext = get_buffer_text($widgets->{'textAPageB'}{$current_hash});
 
3356
    $songtext =~ s/\n/#BREAK#/g;
 
3357
    $songtext =~ s/:/#SEMI#/g;
 
3358
    if ($type eq "SERVER") {
 
3359
        update_display("preview", $titledata, $songtext);
 
3360
    } else {
 
3361
        preview_display("preview", $titledata, $songtext, "EDIT");
 
3362
    }
 
3363
}
 
3364
 
 
3365
#***
 
3366
 
 
3367
#****f* lyricue/preview_pageid
 
3368
# NAME
 
3369
#   preview_pageid
 
3370
# SYNOPSIS
 
3371
#   preview_pageid ($pageid)
 
3372
# FUNCTION
 
3373
#   Preview a pageid in the server
 
3374
# INPUTS
 
3375
#   $widget - Calling widget
 
3376
# OUTPUT
 
3377
#   Calls update_display
 
3378
# SOURCE
 
3379
#
 
3380
sub preview_pageid {
 
3381
    my ($pageid) = @_;
 
3382
    debug("preview pageid");
 
3383
    reset_timer($globals->{'timer'});
 
3384
 
 
3385
    my $query = "SELECT lyrics, pagetitle FROM page WHERE pageid=" . $pageid;
 
3386
    qdebug($query);
 
3387
    $sth = $lyricDbh->prepare($query)
 
3388
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
3389
    $rv = $sth->execute
 
3390
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
3391
    $row = $sth->fetchrow_hashref();
 
3392
    if (defined $row) {
 
3393
 
 
3394
     #join all the strings together so update display will accept them, removing
 
3395
     #any newlines or semicolons that would upset the split on the other end.
 
3396
        my $songtext  = ($row->{'lyrics'});
 
3397
        my $pagetitle = ($row->{'pagetitle'});
 
3398
        $songtext  =~ s/\n/#BREAK#/g;
 
3399
        $songtext  =~ s/:/#SEMI#/g;
 
3400
        $pagetitle =~ s/\n/#BREAK#/g;
 
3401
        $pagetitle =~ s/:/#SEMI#/g;
 
3402
 
 
3403
        preview_display("preview", $pagetitle, $songtext, "MINI");
 
3404
    }
 
3405
}
 
3406
 
 
3407
#***
 
3408
 
 
3409
#****f* lyricue/add_verse
 
3410
# NAME
 
3411
#   add_verse
 
3412
# SYNOPSIS
 
3413
#   add_verse ($widget)
 
3414
# FUNCTION
 
3415
#   Add Verse clicked
 
3416
# INPUTS
 
3417
#   $widget - Calling widget
 
3418
# OUTPUT
 
3419
#   Calls create_dialogBook
 
3420
# SOURCE
 
3421
#
 
3422
sub add_verse {
 
3423
    debug("Add verse clicked");
 
3424
 
 
3425
    if ((!defined $globals->{'bibledb'}) || ($globals->{'bibledb'} eq "")) {
 
3426
        display_message($errorcodes->{'nobible'});
 
3427
    } else {
 
3428
        my $bookxml =
 
3429
          Gtk2::GladeXML->new($globals->{'gladefile'}, 'windowBook', 'lyricue');
 
3430
        $bookxml->signal_autoconnect_from_package('');
 
3431
        $bookxml->get_widget('windowBook')->show;
 
3432
    }
 
3433
}
 
3434
 
 
3435
#***
 
3436
 
 
3437
#****f* lyricue/add_image_pl
 
3438
# NAME
 
3439
#   add_image_pl
 
3440
# SYNOPSIS
 
3441
#   add_image_pl()
 
3442
# FUNCTION
 
3443
#   Add an image to the playlist
 
3444
# INPUTS
 
3445
# OUTPUT
 
3446
#   New item on playlist
 
3447
# SOURCE
 
3448
#
 
3449
sub add_image_pl {
 
3450
    debug("Add image to playlist clicked");
 
3451
    my $widget   = $widgets->{'main'}->get_widget('iconviewImage');
 
3452
    my $selected = "";
 
3453
    my @list     = $widget->get_selected_items;
 
3454
    if (defined $list[0]) {
 
3455
        my $model = $widget->get_model;
 
3456
        my $iter  = $model->get_iter($list[0]);
 
3457
        $selected = $model->get($iter, 2);
 
3458
    }
 
3459
    if ($selected ne "") {
 
3460
        my $playlist =
 
3461
          $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
3462
        if ($playlist != -1) {
 
3463
            add_image_item($playlist, $selected);
 
3464
            update_playlist();
 
3465
        }
 
3466
    }
 
3467
}
 
3468
 
 
3469
#***
 
3470
 
 
3471
#****f* lyricue/add_image
 
3472
# NAME
 
3473
#   add_image
 
3474
# SYNOPSIS
 
3475
#   add_image ()
 
3476
# FUNCTION
 
3477
#   Load the image dialog
 
3478
# INPUTS
 
3479
# OUTPUT
 
3480
#   dialogImage loaded
 
3481
# SOURCE
 
3482
#
 
3483
sub add_image {
 
3484
    debug("Add image clicked");
 
3485
 
 
3486
    $widgets->{'image'} =
 
3487
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogImage', 'lyricue');
 
3488
    $widgets->{'image'}->signal_autoconnect_from_package('');
 
3489
    $widgets->{'image'}->get_widget('buttonImageAdd')
 
3490
      ->signal_connect('clicked', 'import_image');
 
3491
    $widgets->{'image'}->get_widget('dialogImage')->show;
 
3492
 
 
3493
    if ($widgets->{'image'}->get_widget('treeImage')->{user_data}
 
3494
        && ($widgets->{'image'}->get_widget('treeImage')->{user_data} eq "load")
 
3495
      )
 
3496
    {
 
3497
        $widgets->{'image'}->get_widget('treeImage')->{data} = ();
 
3498
    } else {
 
3499
        $widgets->{'image'}->get_widget('treeImage')->{user_data} = "load";
 
3500
        my $renderer = Gtk2::CellRendererText->new;
 
3501
        $renderer->set("editable", TRUE);
 
3502
        $renderer->signal_connect("edited", "rename_media");
 
3503
        my $column =
 
3504
          Gtk2::TreeViewColumn->new_with_attributes("Filename", $renderer,
 
3505
            text => 0);
 
3506
        $widgets->{'image'}->get_widget('treeImage')->append_column($column);
 
3507
        $widgets->{'image'}->get_widget('treeImage')
 
3508
          ->get_selection->set_mode('multiple');
 
3509
        $widgets->{'image'}->get_widget('buttonImageOK')
 
3510
          ->signal_connect('clicked', "do_add_image");
 
3511
    }
 
3512
 
 
3513
    # Fill sublists dropbox
 
3514
    my $menu = Gtk2::Menu->new();
 
3515
    $widgets->{'image'}->get_widget('optionImageSublist')->set_menu($menu);
 
3516
    my $playlist =
 
3517
      $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
3518
    my $query =
 
3519
"SELECT title, data FROM playlist, playlists WHERE playlist.data = playlists.id AND playlist = "
 
3520
      . $playlist
 
3521
      . " AND type = 'sub'";
 
3522
    qdebug($query);
 
3523
    my $sth = $lyricDbh->prepare($query)
 
3524
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
3525
    my $rv = $sth->execute
 
3526
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
3527
    my $item = Gtk2::MenuItem->new_with_label("Main");
 
3528
    $item->{'user_data'} = $playlist;
 
3529
    $item->show();
 
3530
    $menu->append($item);
 
3531
    my (@list);
 
3532
 
 
3533
    while ($row = $sth->fetchrow_hashref()) {
 
3534
        my $item = Gtk2::MenuItem->new_with_label($row->{'title'});
 
3535
        $item->{'user_data'} = $row->{'data'};
 
3536
        $item->show();
 
3537
        $menu->append($item);
 
3538
        my @childid = find_more_children($row->{'data'});
 
3539
        foreach (@childid) {
 
3540
            debug("Child sublist found. ID: " . $_);
 
3541
            my $query2 = "SELECT title FROM playlists WHERE id=" . $_;
 
3542
            qdebug($query2);
 
3543
            my $sth2 = $lyricDbh->prepare($query2)
 
3544
              || display_fatal($errorcodes->{'sqlprepare'},
 
3545
                $! . "\nSQL: " . $query2);
 
3546
            my $rv2 = $sth2->execute
 
3547
              || display_fatal($errorcodes->{'sqlexecute'},
 
3548
                $! . "\nSQL: " . $query2);
 
3549
            my $row2 = $sth2->fetchrow_hashref();
 
3550
            my $item = Gtk2::MenuItem->new_with_label($row2->{'title'});
 
3551
            $item->{'user_data'} = $row2->{'data'};
 
3552
            $item->show();
 
3553
            $menu->append($item);
 
3554
        }
 
3555
    }
 
3556
    $widgets->{'image'}->get_widget('optionImageSublist')->set_history(0);
 
3557
 
 
3558
    update_imagedir("img", "");
 
3559
}
 
3560
 
 
3561
#***
 
3562
 
 
3563
#****f* lyricue/update_imagedir
 
3564
# NAME
 
3565
#   update_imagedir
 
3566
# SYNOPSIS
 
3567
#   update_imagedir($type, $data)
 
3568
# FUNCTION
 
3569
#   Update the view of an category
 
3570
# INPUTS
 
3571
#   $type - 'img' or 'bg'
 
3572
#   $data - Category/type to load
 
3573
# OUTPUT
 
3574
#   Updated list of images
 
3575
# SOURCE
 
3576
#
 
3577
sub update_imagedir {
 
3578
    my ($type, $data) = @_;
 
3579
    my ($access, $category);
 
3580
    debug("update image directory");
 
3581
    my $main = "";
 
3582
    if ($type eq "bg") {
 
3583
        $main = $config->{'SpecialBack'};
 
3584
    } else {
 
3585
        $main = $config->{'SpecialImage'};
 
3586
    }
 
3587
    if ($data eq "") {
 
3588
        $data = $main;
 
3589
    }
 
3590
    ($access, $category) = split /;/, $data;
 
3591
    if (!defined $category) {
 
3592
        $category = $access;
 
3593
        $access   = "db";
 
3594
    }
 
3595
 
 
3596
    debug("changing to $access;$category");
 
3597
 
 
3598
    # display sorted list
 
3599
 
 
3600
    # Update categories list
 
3601
    $widgets->{'image'}->get_widget('optionImageCategory')->{'user_data'} =
 
3602
      $type;
 
3603
    $widgets->{'image'}->get_widget('treeImage')->{'user_data'} = $data;
 
3604
    my $history =
 
3605
      $widgets->{'image'}->get_widget('optionImageCategory')->get_history();
 
3606
    my $menu = Gtk2::Menu->new();
 
3607
    $widgets->{'image'}->get_widget('optionImageCategory')->set_menu($menu);
 
3608
    my $item = Gtk2::MenuItem->new_with_label($main);
 
3609
    $item->show();
 
3610
    $item->{user_data} = $main;
 
3611
    $menu->append($item);
 
3612
 
 
3613
    $query =
 
3614
        "SELECT DISTINCT category FROM media WHERE type=\"" 
 
3615
      . $type
 
3616
      . "\" AND category != \""
 
3617
      . $main
 
3618
      . "\" ORDER BY category";
 
3619
    qdebug($query);
 
3620
    $sth = $mediaDbh->prepare($query)
 
3621
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
3622
    $rv = $sth->execute
 
3623
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
3624
 
 
3625
    while ($row = $sth->fetchrow_hashref()) {
 
3626
        my $item = Gtk2::MenuItem->new_with_label($row->{'category'});
 
3627
        $item->{user_data} = "db;" . $row->{'category'};
 
3628
        $item->show();
 
3629
        $menu->append($item);
 
3630
 
 
3631
    }
 
3632
 
 
3633
    # Add categories from directories
 
3634
    my $dirname = "";
 
3635
    if ($type eq "bg") {
 
3636
        $dirname = $config->{'BGDirectory'};
 
3637
    } else {
 
3638
        $dirname = $config->{'ImageDirectory'};
 
3639
    }
 
3640
    my (@files, $file);
 
3641
    my $ret = opendir DIR, $dirname;
 
3642
    if ($ret) {
 
3643
        foreach $file (sort readdir(DIR)) {
 
3644
            if (!($file =~ /^\./) && (-d $dirname . "/" . $file)) {
 
3645
                my $item = Gtk2::MenuItem->new_with_label($file);
 
3646
                $item->{user_data} = "dir;" . $file;
 
3647
                $item->show();
 
3648
                $menu->append($item);
 
3649
            }
 
3650
        }
 
3651
        closedir DIR;
 
3652
    }
 
3653
 
 
3654
    $widgets->{'image'}->get_widget('optionImageCategory')
 
3655
      ->set_history($history);
 
3656
    my $store = Gtk2::ListStore->new('Glib::String', 'Glib::String');
 
3657
    my $iter;
 
3658
 
 
3659
    if ($access eq "dir") {
 
3660
        my $dirname = "";
 
3661
        if ($type eq "bg") {
 
3662
            $dirname = $config->{'BGDirectory'} . "/" . $category;
 
3663
        } else {
 
3664
            $dirname = $config->{'ImageDirectory'} . "/" . $category;
 
3665
        }
 
3666
        my $ret = opendir DIR, $dirname;
 
3667
        if ($ret) {
 
3668
            my $file = "";
 
3669
            foreach $file (sort readdir(DIR)) {
 
3670
                if (!($file =~ /^\./)) {
 
3671
                    $iter = $store->append;
 
3672
                    $store->set($iter, 0, $file, 1,
 
3673
                        "dir;" . $dirname . "/" . $file);
 
3674
                }
 
3675
            }
 
3676
        }
 
3677
    }
 
3678
 
 
3679
    if ($access eq "db") {
 
3680
 
 
3681
        # update list of available images
 
3682
        $query =
 
3683
            "SELECT * FROM media WHERE category LIKE \""
 
3684
          . $category
 
3685
          . "\" AND type=\""
 
3686
          . $type
 
3687
          . "\" ORDER BY description";
 
3688
        qdebug($query);
 
3689
        $sth = $mediaDbh->prepare($query)
 
3690
          || display_fatal($errorcodes->{'sqlprepare'},
 
3691
            $! . "\nSQL: " . $query);
 
3692
        $rv = $sth->execute
 
3693
          || display_fatal($errorcodes->{'sqlexecute'},
 
3694
            $! . "\nSQL: " . $query);
 
3695
        while ($row = $sth->fetchrow_hashref()) {
 
3696
            $iter = $store->append;
 
3697
            $store->set($iter, 0, $row->{'description'}, 1,
 
3698
                "db;" . $row->{'id'});
 
3699
        }
 
3700
    }
 
3701
    $widgets->{'image'}->get_widget('treeImage')->set_model($store);
 
3702
    $widgets->{'image'}->get_widget('entryImageFontColour')
 
3703
      ->set_text("Default");
 
3704
    $widgets->{'image'}->get_widget('colorbuttonFontColour')
 
3705
      ->set_color(Gtk2::Gdk::Color->parse($config->{'Colour'}));
 
3706
    $widgets->{'image'}->get_widget('entryImageShadowColour')
 
3707
      ->set_text("Default");
 
3708
    $widgets->{'image'}->get_widget('colorbuttonShadowColour')
 
3709
      ->set_color(Gtk2::Gdk::Color->parse($config->{'ShadowColour'}));
 
3710
}
 
3711
 
 
3712
#***
 
3713
 
 
3714
#****f* lyricue/change_image_category
 
3715
# NAME
 
3716
#   change_image_category
 
3717
# SYNOPSIS
 
3718
#   change_image_category()
 
3719
# FUNCTION
 
3720
#   change image category
 
3721
# INPUTS
 
3722
# OUTPUT
 
3723
# SOURCE
 
3724
#
 
3725
sub change_image_category {
 
3726
    debug("change image category");
 
3727
    my $category =
 
3728
      $widgets->{'image'}->get_widget('optionImageCategory')
 
3729
      ->get_menu->get_active->{user_data};
 
3730
    if (defined $category) {
 
3731
        if ($widgets->{'image'}->get_widget('treeImage')->{user_data} ne
 
3732
            $category)
 
3733
        {
 
3734
            update_imagedir(
 
3735
                $widgets->{'image'}->get_widget('optionImageCategory')
 
3736
                  ->{'user_data'},
 
3737
                $category
 
3738
            );
 
3739
        }
 
3740
    }
 
3741
}
 
3742
 
 
3743
#***
 
3744
 
 
3745
#****f* lyricue/update_display
 
3746
# NAME
 
3747
#   update_display
 
3748
# SYNOPSIS
 
3749
#   update_display ($command, $primary, $secondary)
 
3750
# FUNCTION
 
3751
#   Open a connection the the server and send a command. Status is returned
 
3752
# INPUTS
 
3753
#   $command - Command to send
 
3754
#   $primary - First parameter to send
 
3755
#   $secondary - Second parameter to send
 
3756
# OUTPUT
 
3757
#   Updated display
 
3758
# SOURCE
 
3759
#
 
3760
sub update_display {
 
3761
    my ($command, $primary, $secondary) = @_;
 
3762
    debug("update display");
 
3763
    my $biblechanged = "";
 
3764
 
 
3765
    if ($globals->{'access'} !~ /s/) {
 
3766
 
 
3767
        $command   = "";
 
3768
        $primary   = "";
 
3769
        $secondary = "";
 
3770
    }
 
3771
 
 
3772
    if (!defined($secondary)) {
 
3773
        $secondary = "";
 
3774
    }
 
3775
    if (!defined($primary)) {
 
3776
        $primary = "";
 
3777
    }
 
3778
    $primary   =~ s/:/#SEMI#/g;
 
3779
    $secondary =~ s/:/#SEMI#/g;
 
3780
    debug("Command: " . $command . ":" . $primary . ":" . $secondary);
 
3781
    if (
 
3782
        my $server = IO::Socket::INET->new(
 
3783
            Proto    => "tcp",
 
3784
            PeerAddr => $globals->{'host'},
 
3785
            PeerPort => $globals->{'server_port'}
 
3786
        )
 
3787
      )
 
3788
    {
 
3789
 
 
3790
        #binmode $server, ":utf8";
 
3791
        print $server toutf(
 
3792
            $command . ":" . $primary . ":" . $secondary . "\n");
 
3793
        if (defined(my $status = <$server>)) {
 
3794
            $status = fromutf($status);
 
3795
            chomp($status);
 
3796
            if ($status =~ /^pl:/) {
 
3797
                my @line = split(/:/, $status);
 
3798
                $status = fromutf(gettext("Displaying "));
 
3799
                if ($line[1] eq "v") {
 
3800
                    $status = fromutf(gettext(" verses "));
 
3801
                } else {
 
3802
                    $status = fromutf(gettext(" page ")) . $line[3];
 
3803
                    $widgets->{'main'}->get_widget('treePlaylist')
 
3804
                      ->select_item($line[2]);
 
3805
                }
 
3806
                $widgets->{'main'}->get_widget('statusPlaylist')
 
3807
                  ->push(1, $status);
 
3808
            } elsif ($status =~ /^Status,/) {
 
3809
                my @line = split(/,/, $status);
 
3810
                foreach (@line) {
 
3811
                    my @item = split(/:/, $_);
 
3812
                    if ($item[0] eq "W") {
 
3813
                        $config->{'Width'} = $item[1];
 
3814
                    } elsif ($item[0] eq "H") {
 
3815
                        $config->{'Height'} = $item[1];
 
3816
                    } elsif ($item[0] eq "F") {
 
3817
                        $config->{'Main'} = $item[1];
 
3818
                    } elsif ($item[0] eq "B") {
 
3819
                        if ($item[1] ne $globals->{'biblename'}) {
 
3820
                            $biblechanged = $item[1];
 
3821
                        }
 
3822
                    }
 
3823
                }
 
3824
            } else {
 
3825
                $widgets->{'main'}->get_widget('statusPlaylist')
 
3826
                  ->push(1, $status);
 
3827
            }
 
3828
            debug($status);
 
3829
        }
 
3830
        close($server);
 
3831
        debug("Sent ");
 
3832
        if ($biblechanged ne "") {
 
3833
            if (defined $bibleMenu->{$biblechanged}) {
 
3834
                $bibleMenu->{$biblechanged}->set_active(TRUE);
 
3835
            }
 
3836
        }
 
3837
    }
 
3838
}
 
3839
 
 
3840
#***
 
3841
 
 
3842
#****f* lyricue/preview_playlist_item
 
3843
# NAME
 
3844
#   preview_playlist_item
 
3845
# SYNOPSIS
 
3846
#   preview_playlist_item()
 
3847
# FUNCTION
 
3848
#   Preview a playlist item
 
3849
# INPUTS
 
3850
#
 
3851
# OUTPUT
 
3852
#   Updated preview
 
3853
# SOURCE
 
3854
#
 
3855
sub preview_playlist_item {
 
3856
    debug("Previewing a playlist item...");
 
3857
 
 
3858
    my $selection =
 
3859
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
3860
    my ($model, $iter) = $selection->get_selected;
 
3861
    if ($iter) {
 
3862
        # display item
 
3863
        preview_display("display", $model->get($iter, 2), undef, "MINI");
 
3864
    }
 
3865
}
 
3866
 
 
3867
#***
 
3868
 
 
3869
#****f* lyricue/preview_display
 
3870
# NAME
 
3871
#   preview_display
 
3872
# SYNOPSIS
 
3873
#   preview_display ()
 
3874
# FUNCTION
 
3875
#   1. Start new server instance for preview windows (if required)
 
3876
#   2. Issues commands to the preview server
 
3877
# INPUTS
 
3878
# OUTPUT
 
3879
#   Updated display
 
3880
# SOURCE
 
3881
#
 
3882
sub preview_display {
 
3883
    my ($command, $primary, $secondary, $mode) = @_;
 
3884
    debug("Preview display $mode");
 
3885
    if (!$config->{'DynamicPreview'} && $mode eq "MINI") {
 
3886
        return;
 
3887
    }
 
3888
    my $port = 0;
 
3889
    if ($mode eq "MINI") {
 
3890
        $port = $globals->{'preview_port'};
 
3891
    } elsif ($mode eq "EDIT") {
 
3892
        $port = $globals->{'editview_port'};
 
3893
    }
 
3894
 
 
3895
    if ($port > 0) {
 
3896
        if (!defined($secondary)) {
 
3897
            $secondary = "";
 
3898
        }
 
3899
        if (!defined($primary)) {
 
3900
            $primary = "";
 
3901
        }
 
3902
        $primary   =~ s/:/#SEMI#/g;
 
3903
        $secondary =~ s/:/#SEMI#/g;
 
3904
        debug(
 
3905
            "Preview command: " . $command . ":" . $primary . ":" . $secondary);
 
3906
 
 
3907
        if (
 
3908
            my $server = IO::Socket::INET->new(
 
3909
                Proto    => "tcp",
 
3910
                PeerAddr => "localhost",
 
3911
                PeerPort => $port
 
3912
            )
 
3913
          )
 
3914
        {
 
3915
            print $server toutf($command . ":" 
 
3916
              . $primary . ":"
 
3917
              . $secondary . "\n");
 
3918
            close($server);
 
3919
        } else {
 
3920
 
 
3921
            #tcp/ip socket failure so server must be not running yet!
 
3922
            debug("Preview not running?");
 
3923
            if (defined $widgets->{'preview'}) {
 
3924
                $widgets->{'main'}->get_widget('framePreview')->remove($widgets->{'preview'});
 
3925
                undef $widgets->{'preview'};
 
3926
            }
 
3927
            init_preview();
 
3928
        }
 
3929
    }
 
3930
}
 
3931
 
 
3932
#***
 
3933
 
 
3934
#****f* lyricue/open_dialogColour
 
3935
# NAME
 
3936
#   open_dialogColour
 
3937
# SYNOPSIS
 
3938
#   open_dialogColour($widget, $event, $item)
 
3939
# FUNCTION
 
3940
#   Load a new dialog to select a colour
 
3941
# INPUTS
 
3942
#   $widget - Calling widget
 
3943
#   $event - how we where called
 
3944
#   $item - What we want to set the colour for
 
3945
# OUTPUT
 
3946
#
 
3947
# SOURCE
 
3948
#
 
3949
sub open_dialogColour {
 
3950
    my ($widget, $event, $item) = @_;
 
3951
    debug("Opening Colour dialog");
 
3952
    debug("open_dialogColour: item=" . $item);
 
3953
    debug("open_dialogColour: widget=" . $widget->get_name());
 
3954
    my $colourxml =
 
3955
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogColour', 'lyricue');
 
3956
    $colourxml->signal_autoconnect_from_package('');
 
3957
    $colourxml->get_widget('dialogColour')
 
3958
      ->set_title(
 
3959
        fromutf(gettext("Select ")) . $item . fromutf(gettext(" Colour")));
 
3960
    $colourxml->get_widget('dialogColour')->{'user_data'} = $item;
 
3961
 
 
3962
    if ($item eq "Font") {
 
3963
        $colourxml->get_widget('colourSelect')->set_current_color(
 
3964
            Gtk2::Gdk::Color->parse(
 
3965
                $widgets->{'prefs'}->get_widget('entryPrefColour')->get_text()
 
3966
            )
 
3967
        );
 
3968
    }
 
3969
    if ($item eq "Shadow") {
 
3970
        $colourxml->get_widget('colourSelect')->set_current_color(
 
3971
            Gtk2::Gdk::Color->parse(
 
3972
                $widgets->{'prefs'}->get_widget('entryPrefShadowColour')
 
3973
                  ->get_text()
 
3974
            )
 
3975
        );
 
3976
    }
 
3977
    if ($item eq "ImageFont") {
 
3978
 
 
3979
#$colourxml->get_widget('colourSelect')->set_current_color(Gtk2::Gdk::Color->parse($widgets->{'image'}->get_widget('entryImageFontColour')->get_text()));
 
3980
        $colourxml->get_widget('colourSelect')
 
3981
          ->set_current_color($widget->get_color());
 
3982
    }
 
3983
    if ($item eq "ImageShadow") {
 
3984
 
 
3985
#$colourxml->get_widget('colourSelect')->set_current_color(Gtk2::Gdk::Color->parse($widgets->{'image'}->get_widget('entryImageShadowColour')->get_text()));
 
3986
        $colourxml->get_widget('colourSelect')
 
3987
          ->set_current_color($widget->get_color());
 
3988
    }
 
3989
    $colourxml->get_widget('buttonColourOK')
 
3990
      ->signal_connect("clicked", "change_font_colour", $colourxml);
 
3991
    $colourxml->get_widget('buttonColourCancel')
 
3992
      ->signal_connect("clicked", "close_dialog");
 
3993
    my $response = $colourxml->get_widget('dialogColour')->run();
 
3994
}
 
3995
 
 
3996
#***
 
3997
 
 
3998
#****f* lyricue/open_dialogFont
 
3999
# NAME
 
4000
#   open_dialogFont
 
4001
# SYNOPSIS
 
4002
#   open_dialogFont ($widget, $event, $font)
 
4003
# FUNCTION
 
4004
#   Load a new dialog to select a colour
 
4005
# INPUTS
 
4006
#   $widget - Calling widget
 
4007
#   $event - how we where called
 
4008
#   $font - What we want to set the colour for
 
4009
# OUTPUT
 
4010
#
 
4011
# SOURCE
 
4012
#
 
4013
sub open_dialogFont {
 
4014
    my ($widget, $event, $font) = @_;
 
4015
    debug("Opening Font dialog");
 
4016
    $widgets->{'font'} =
 
4017
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogFont', 'lyricue');
 
4018
    $widgets->{'font'}->signal_autoconnect_from_package('');
 
4019
    my $fontname = $config->{$font};
 
4020
    $widgets->{'font'}->get_widget('selectFont')->set_font_name($fontname);
 
4021
    $widgets->{'font'}->get_widget('buttonFontOK')
 
4022
      ->signal_connect("clicked", "apply_font", $font);
 
4023
    $widgets->{'font'}->get_widget('dialogFont')->show;
 
4024
    return TRUE;
 
4025
}
 
4026
 
 
4027
#***
 
4028
 
 
4029
#****f* lyricue/change_font_colour
 
4030
# NAME
 
4031
#   change_font_colour
 
4032
# SYNOPSIS
 
4033
#   change_font_colour ($widget, $colourxml)
 
4034
# FUNCTION
 
4035
#   Change the font colour
 
4036
# INPUTS
 
4037
#   $widget - Calling widget
 
4038
#   $colourxml - The Colour dialog
 
4039
# OUTPUT
 
4040
#   Updated config file and server
 
4041
# SOURCE
 
4042
#
 
4043
sub change_font_colour {
 
4044
    my ($widget, $colourxml) = @_;
 
4045
    debug("Change font colour");
 
4046
    my $item   = $colourxml->get_widget('dialogColour')->{'user_data'};
 
4047
    my $colour = $colourxml->get_widget('colourSelect')->get_current_color();
 
4048
    my $color2 =
 
4049
        sprintf("#%2.2x", ($colour->red / 256))
 
4050
      . sprintf("%2.2x", ($colour->green / 256))
 
4051
      . sprintf("%2.2x", ($colour->blue / 256));
 
4052
 
 
4053
    debug("change_font_colour: item=" . $item);
 
4054
    if ($item eq "Shadow") {
 
4055
        $widgets->{'prefs'}->get_widget('entryPrefShadowColour')
 
4056
          ->set_text($color2);
 
4057
        $widgets->{'prefs'}->get_widget('entryPrefShadowColour')
 
4058
          ->set_text($color2);
 
4059
    } elsif ($item eq "Font") {
 
4060
        $widgets->{'prefs'}->get_widget('entryPrefColour')->set_text($color2);
 
4061
    } elsif ($item eq "ImageShadow") {
 
4062
        $widgets->{'image'}->get_widget('entryImageShadowColour')
 
4063
          ->set_text($color2);
 
4064
        $widgets->{'image'}->get_widget('colorbuttonShadowColour')
 
4065
          ->set_color(Gtk2::Gdk::Color->parse($color2));
 
4066
        change_colour_media();
 
4067
    } elsif ($item eq "ImageFont") {
 
4068
        $widgets->{'image'}->get_widget('entryImageFontColour')
 
4069
          ->set_text($color2);
 
4070
        $widgets->{'image'}->get_widget('colorbuttonFontColour')
 
4071
          ->set_color(Gtk2::Gdk::Color->parse($color2));
 
4072
        change_colour_media();
 
4073
    }
 
4074
    close_dialog($widget);
 
4075
}
 
4076
 
 
4077
#***
 
4078
 
 
4079
#****f* lyricue/apply_font
 
4080
# NAME
 
4081
#   apply_font
 
4082
# SYNOPSIS
 
4083
#   apply_font ()
 
4084
# FUNCTION
 
4085
#   Apply font changes to the config file and server
 
4086
# INPUTS
 
4087
# OUTPUT
 
4088
#   Updated file and server
 
4089
# SOURCE
 
4090
#
 
4091
sub apply_font {
 
4092
    my ($widget, $type) = @_;
 
4093
    debug("Applying font: "
 
4094
          . $widgets->{'font'}->get_widget('selectFont')->get_font_name);
 
4095
    $widgets->{'prefs'}->get_widget('entryPref' . $type)
 
4096
      ->set_text($widgets->{'font'}->get_widget('selectFont')->get_font_name);
 
4097
    close_dialog($widget);
 
4098
}
 
4099
 
 
4100
#***
 
4101
 
 
4102
#****f* lyricue/changeVerseStatus
 
4103
# NAME
 
4104
#   changeVerseStatus
 
4105
# SYNOPSIS
 
4106
#   changeVerseStatus ($widget, $section, $row, $col, $rows, $max)
 
4107
# FUNCTION
 
4108
#   Make sure you can't choose multiple values for start or finish
 
4109
# INPUTS
 
4110
#   $widget - Calling widget
 
4111
#   $event
 
4112
#   $max - Maximum value
 
4113
# OUTPUT
 
4114
#   Only one value chosen in start or finish area
 
4115
# SOURCE
 
4116
#
 
4117
sub changeVerseStatus {
 
4118
    my ($widget, $event, $max) = @_;
 
4119
 
 
4120
    #debug("Change verse status");
 
4121
 
 
4122
    my $number = $widget->get_label;
 
4123
    if (defined($event->type)) {
 
4124
        my $begin = 0;
 
4125
        my $end   = 0;
 
4126
        if ($event->type eq 'button-press') {
 
4127
            if (   ($globals->{'verseEnd'} == 0)
 
4128
                && ($globals->{'verseStart'} != 0))
 
4129
            {
 
4130
                if ($number < $globals->{'verseStart'}) {
 
4131
                    $globals->{'verseEnd'}   = $globals->{'verseStart'};
 
4132
                    $globals->{'verseStart'} = $number;
 
4133
                } else {
 
4134
                    $globals->{'verseEnd'} = $number;
 
4135
                }
 
4136
                debug(  "End "
 
4137
                      . $globals->{'verseStart'} . ","
 
4138
                      . $globals->{'verseEnd'});
 
4139
                $begin = $globals->{'verseStart'};
 
4140
                $end   = $globals->{'verseEnd'};
 
4141
            } else {
 
4142
                debug("Start " . $globals->{'verseStart'});
 
4143
                $globals->{'verseStart'} = $number;
 
4144
                $globals->{'verseEnd'}   = 0;
 
4145
                $begin                   = $globals->{'verseStart'};
 
4146
                $end                     = $globals->{'verseStart'};
 
4147
            }
 
4148
            my $book =
 
4149
              $widgets->{'main'}->get_widget('entryNavVerse')->get_text();
 
4150
            my $verse = "";
 
4151
            $book =~ s/:.*$//g;
 
4152
            $verse = $book . ":" . $begin . "-" . $end;
 
4153
            $widgets->{'main'}->get_widget('entryNavVerse')->set_text($verse);
 
4154
        } elsif ($event->type eq 'enter-notify') {
 
4155
            $begin = 0;
 
4156
            if ((defined $globals->{'verseStart'}) 
 
4157
                && ($globals->{'verseStart'} != 0)
 
4158
                && ($globals->{'verseEnd'} == 0))
 
4159
            {
 
4160
                if ($number < $globals->{'verseStart'}) {
 
4161
                    $begin = $number;
 
4162
                    $end   = $globals->{'verseStart'};
 
4163
                } else {
 
4164
                    $begin = $globals->{'verseStart'};
 
4165
                    $end   = $number;
 
4166
                }
 
4167
            }
 
4168
        }
 
4169
        if ($begin != 0) {
 
4170
            foreach my $num (1 .. $max) {
 
4171
                my $button = "button" . ($num - 1);
 
4172
                if (($num >= $begin) && ($num <= $end)) {
 
4173
                    $widgets->{'bibleBrowser'}{$button}->set_active(TRUE);
 
4174
                } else {
 
4175
                    $widgets->{'bibleBrowser'}{$button}->set_active(FALSE);
 
4176
                }
 
4177
            }
 
4178
            return TRUE;
 
4179
        }
 
4180
    }
 
4181
    return FALSE;
 
4182
}
 
4183
 
 
4184
#***
 
4185
 
 
4186
#****f* lyricue/change_preview
 
4187
# NAME
 
4188
#   change_preview
 
4189
# SYNOPSIS
 
4190
#   change_preview ($widget)
 
4191
# FUNCTION
 
4192
#   Change the preview in the image dialog
 
4193
# INPUTS
 
4194
#   $widget - Calling widget
 
4195
# OUTPUT
 
4196
#   Change previews
 
4197
# SOURCe
 
4198
#
 
4199
sub change_preview {
 
4200
    debug("Changing Preview");
 
4201
    my $selection = $widgets->{'image'}->get_widget('treeImage')->get_selection;
 
4202
    my @selecteditems = $selection->get_selected_rows();
 
4203
    if ($selecteditems[0]) {
 
4204
 
 
4205
        # Find what has changed
 
4206
        my $newsel = $selecteditems[0];
 
4207
        my $iter =
 
4208
          $widgets->{'image'}->get_widget('treeImage')
 
4209
          ->get_model->get_iter($newsel);
 
4210
        my $data =
 
4211
          $widgets->{'image'}->get_widget('treeImage')
 
4212
          ->get_model->get($iter, 1);
 
4213
        my ($type, $id) = split /;/, $data;
 
4214
        my $tmp = 0;
 
4215
        foreach $tmp (@selecteditems) {
 
4216
            my $iter2 =
 
4217
              $widgets->{'image'}->get_widget('treeImage')
 
4218
              ->get_model->get_iter($tmp);
 
4219
            my $data2 =
 
4220
              $widgets->{'image'}->get_widget('treeImage')
 
4221
              ->get_model->get($iter2, 1);
 
4222
            if (!defined $selectedimages{$data2}) {
 
4223
                $data = $data2;
 
4224
                ($type, $id) = split /;/, $data;
 
4225
            }
 
4226
        }
 
4227
        %selectedimages = ();
 
4228
        foreach $tmp (@selecteditems) {
 
4229
            my $iter2 =
 
4230
              $widgets->{'image'}->get_widget('treeImage')
 
4231
              ->get_model->get_iter($tmp);
 
4232
            my $id2 =
 
4233
              $widgets->{'image'}->get_widget('treeImage')
 
4234
              ->get_model->get($iter2, 1);
 
4235
            $selectedimages{$id2} = TRUE;
 
4236
        }
 
4237
 
 
4238
        if ($globals->{'bg_previews'}) {
 
4239
            debug("sub change_preview: create_pixbuf");
 
4240
            my $scaled = create_pixbuf($data, 480, 360);
 
4241
            if ($scaled) {
 
4242
                my ($row, $query);
 
4243
                if ($type eq "db") {
 
4244
                    $query =
 
4245
                      "SELECT textcolour, shadowcolour FROM media WHERE id=\"" 
 
4246
                      . $id . "\"";
 
4247
                } else {
 
4248
                    $query =
 
4249
                      "SELECT textcolour, shadowcolour FROM media WHERE format=\"file\" AND category=\"" . $id . "\"";
 
4250
                }
 
4251
                qdebug($query);
 
4252
                my $sth = $mediaDbh->prepare($query)
 
4253
                  || display_fatal($errorcodes->{'sqlprepare'},
 
4254
                    $! . "\nSQL: " . $query);
 
4255
                my $rv = $sth->execute
 
4256
                  || display_fatal($errorcodes->{'sqlexecute'},
 
4257
                    $! . "\nSQL: " . $query);
 
4258
                $row = $sth->fetchrow_hashref();
 
4259
                if ($row) {
 
4260
                    $widgets->{'image'}->get_widget('buttonImageDelete')
 
4261
                      ->set_sensitive(TRUE);
 
4262
                    $widgets->{'image'}->get_widget('buttonImageChange')
 
4263
                      ->set_sensitive(TRUE);
 
4264
                    $widgets->{'image'}->get_widget('hboxImageColour')
 
4265
                      ->show_all;
 
4266
                } else {
 
4267
                    $row->{'textcolour'}   = "Default";
 
4268
                    $row->{'shadowcolour'} = "Default";
 
4269
                }
 
4270
 
 
4271
                #    $widgets->{'image'}->get_widget('buttonImageDelete')
 
4272
                #      ->set_sensitive(FALSE);
 
4273
                #    $widgets->{'image'}->get_widget('buttonImageChange')
 
4274
                #      ->set_sensitive(FALSE);
 
4275
                #    $widgets->{'image'}->get_widget('hboxImageColour')->hide;
 
4276
                #}
 
4277
                my $fg_span = "";
 
4278
                my $bg_span = "";
 
4279
                if (   ($row->{'textcolour'} ne "")
 
4280
                    && ($row->{'textcolour'} ne "NULL")
 
4281
                    && ($row->{'textcolour'} ne "Default"))
 
4282
                {
 
4283
                    $widgets->{'image'}->get_widget('entryImageFontColour')
 
4284
                      ->set_text($row->{'textcolour'});
 
4285
                    $widgets->{'image'}->get_widget('colorbuttonFontColour')
 
4286
                      ->set_color(
 
4287
                        Gtk2::Gdk::Color->parse($row->{'textcolour'}));
 
4288
                    $fg_span="<span color=\"".$row->{'textcolour'}."\">";
 
4289
                } else {
 
4290
                    $widgets->{'image'}->get_widget('entryImageFontColour')
 
4291
                      ->set_text("Default");
 
4292
                    $widgets->{'image'}->get_widget('colorbuttonFontColour')
 
4293
                      ->set_color(Gtk2::Gdk::Color->parse($config->{'Colour'}));
 
4294
                    $fg_span="<span color=\"".$config->{'Colour'}."\">";
 
4295
                }
 
4296
                if (   ($row->{'shadowcolour'} ne "")
 
4297
                    && ($row->{'shadowcolour'} ne "NULL")
 
4298
                    && ($row->{'shadowcolour'} ne "Default"))
 
4299
                {
 
4300
                    $widgets->{'image'}->get_widget('entryImageShadowColour')
 
4301
                      ->set_text($row->{'shadowcolour'});
 
4302
                    $widgets->{'image'}->get_widget('colorbuttonShadowColour')
 
4303
                      ->set_color(
 
4304
                        Gtk2::Gdk::Color->parse($row->{'shadowcolour'}));
 
4305
                    $bg_span="<span color=\"".$row->{'shadowcolour'}."\">";
 
4306
                } else {
 
4307
                    $widgets->{'image'}->get_widget('entryImageShadowColour')
 
4308
                      ->set_text("Default");
 
4309
                    $widgets->{'image'}->get_widget('colorbuttonShadowColour')
 
4310
                      ->set_color(
 
4311
                        Gtk2::Gdk::Color->parse($config->{'ShadowColour'}));
 
4312
                    $bg_span="<span color=\"".$config->{'ShadowColour'}."\">";
 
4313
                }
 
4314
                # Add text overlay to $scaled 
 
4315
                my $pixmap = $scaled->render_pixmap_and_mask(127);
 
4316
                my $pango_layout = $widgets->{'image'}->get_widget('imageImage')->create_pango_layout("");
 
4317
                $pango_layout->set_font_description( Gtk2::Pango::FontDescription->from_string($config->{'Main'}));
 
4318
                my $gc = Gtk2::Gdk::GC->new($pixmap);
 
4319
                $pango_layout->set_markup($bg_span.fromutf(gettext("Song Contents"))."</span>");
 
4320
                my ($text_w, $text_h) = $pango_layout->get_pixel_size();
 
4321
                my $text_x = (480-$text_w)/2;
 
4322
                my $text_y = (360-$text_h)/2;
 
4323
                $pixmap->draw_layout($gc, $text_x+2, $text_y+2, $pango_layout);
 
4324
                $pango_layout->set_markup($fg_span.fromutf(gettext("Song Contents"))."</span>");
 
4325
                $pixmap->draw_layout($gc, $text_x, $text_y, $pango_layout);
 
4326
                $widgets->{'image'}->get_widget('imageImage')
 
4327
                  ->set_from_pixmap($pixmap,undef);
 
4328
                $widgets->{'image'}->get_widget('imageImage')->{user_data} =
 
4329
                  $data;
 
4330
            }
 
4331
        }
 
4332
    }
 
4333
    return TRUE;
 
4334
}
 
4335
 
 
4336
#***
 
4337
 
 
4338
#****f* lyricue/set_default_backdrop
 
4339
# NAME
 
4340
#   set_default_backdrop
 
4341
# SYNOPSIS
 
4342
#   set_default_backdrop ($widget)
 
4343
# FUNCTION
 
4344
#   Change the default background in the config file
 
4345
# INPUTS
 
4346
#   $widget - Calling widget
 
4347
# OUTPUT
 
4348
#   Updated config file
 
4349
# SOURCE
 
4350
#
 
4351
sub set_default_backdrop {
 
4352
    my ($widget) = @_;
 
4353
    debug("Set default backdrop");
 
4354
    my $image = $widgets->{'image'}->get_widget('imageImage')->{user_data};
 
4355
    if ($image) {
 
4356
        my $scaled = create_pixbuf(
 
4357
            $image,
 
4358
            $globals->{'icon_width'},
 
4359
            $globals->{'icon_height'}
 
4360
        );
 
4361
        if ($scaled) {
 
4362
            $widgets->{'prefs'}->get_widget('imagePrefBG')
 
4363
              ->set_from_pixbuf($scaled);
 
4364
            $widgets->{'prefs'}->get_widget('imagePrefBG')->{user_data} =
 
4365
              $image;
 
4366
        }
 
4367
    }
 
4368
    close_dialog($widget);
 
4369
}
 
4370
 
 
4371
#***
 
4372
 
 
4373
#****f* lyricue/print_songs
 
4374
# NAME
 
4375
#   print_songs
 
4376
# SYNOPSIS
 
4377
#   print_songs ()
 
4378
# FUNCTION
 
4379
#   Print a html formatted list of available songs
 
4380
# OUTPUT
 
4381
#   HTML list of songs to standard out
 
4382
# SOURCE
 
4383
#
 
4384
sub print_songs {
 
4385
    debug("Print html formatted song list");
 
4386
    my $lyricDbh =
 
4387
      db_connect($globals->{'lyricdb'}, $errorcodes->{'lyricdbopen'});
 
4388
    my $query = "SELECT COUNT(id) FROM lyricMain WHERE id > 0;";
 
4389
    my $sth   = $lyricDbh->prepare($query)
 
4390
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
4391
    my $rv = $sth->execute
 
4392
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
4393
    my @totals = $sth->fetchrow_array();
 
4394
 
 
4395
    $query =
 
4396
"SELECT title,book,songnum,artist FROM lyricMain WHERE id > 0 ORDER BY title;";
 
4397
    $sth = $lyricDbh->prepare($query)
 
4398
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
4399
    $rv = $sth->execute
 
4400
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
4401
 
 
4402
    print "<HTML>\n<HEAD><TITLE>Lyricue Song List</TITLE></HEAD>\n";
 
4403
    print "<CENTER><H1>Lyricue Song List</H1></CENTER><BR>\n";
 
4404
    print "<H2>Total number of songs available : <B>"
 
4405
      . $totals[0]
 
4406
      . "</B></H2>\n";
 
4407
    print "<TABLE WIDTH=100% BORDER=1>\n";
 
4408
    print
 
4409
"<TR><TH>Song Name</TH><TH>Song Book</TH><TH>Song Number</TH><TH>Artist</TH></TR>\n";
 
4410
    my @row;
 
4411
 
 
4412
    while (@row = $sth->fetchrow_array()) {
 
4413
        print "<TR>";
 
4414
        foreach (@row) {
 
4415
            if ($_ eq "") {
 
4416
                $_ = "&nbsp;";
 
4417
            }
 
4418
            print "<TD>" . $_ . "</TD>";
 
4419
        }
 
4420
        print "</TR>\n";
 
4421
    }
 
4422
    print "</TABLE>\n</BODY>\n</HTML>\n";
 
4423
    $lyricDbh->disconnect;
 
4424
    exit;
 
4425
}
 
4426
 
 
4427
#***
 
4428
 
 
4429
#****f* lyricue/backdrop_clicked
 
4430
# NAME
 
4431
#   backdrop_clicked
 
4432
# SYNOPSIS
 
4433
#   backdrop_clicked ($widget)
 
4434
# FUNCTION
 
4435
#   A background has been clicked son change the bg in the server and update the two previews on the main window
 
4436
# INPUTS
 
4437
#   $widget - Calling widget
 
4438
# OUTPUT
 
4439
#   Updated bg
 
4440
# SOURCE
 
4441
#
 
4442
sub backdrop_clicked {
 
4443
    my ($widget, $event) = @_;
 
4444
    if ($event->type eq 'button-press') {
 
4445
        return;
 
4446
    }
 
4447
    debug("Backdrop clicked");
 
4448
    my $selected = "";
 
4449
    my @list     = $widget->get_selected_items;
 
4450
    if (defined $list[0]) {
 
4451
        my $model = $widget->get_model;
 
4452
        my $iter  = $model->get_iter($list[0]);
 
4453
        $selected = $model->get($iter, 2);
 
4454
    }
 
4455
    if ($selected eq "") {
 
4456
        return;
 
4457
    }
 
4458
 
 
4459
    #$widget->unselect_all;
 
4460
 
 
4461
    if (@ASSOCIATE) {
 
4462
        associate_bg($selected);
 
4463
    } else {
 
4464
        debug("Changing backdrop to " . $selected);
 
4465
        if ($globals->{'bg_previews'}) {
 
4466
            my $prevFile = $selected;
 
4467
            my $scaled   = create_pixbuf(
 
4468
                $widgets->{'buttonCurr'}->{user_data},
 
4469
                $globals->{'icon_width'},
 
4470
                $globals->{'icon_height'}
 
4471
            );
 
4472
 
 
4473
            if ($scaled) {
 
4474
                $widgets->{'pixmapPrev'}->set_from_pixbuf($scaled);
 
4475
                $widgets->{'buttonPrev'}->{user_data} =
 
4476
                  $widgets->{'buttonCurr'}->{user_data};
 
4477
            }
 
4478
 
 
4479
            $scaled = create_pixbuf(
 
4480
                $prevFile,
 
4481
                $globals->{'icon_width'},
 
4482
                $globals->{'icon_height'}
 
4483
            );
 
4484
            if ($scaled) {
 
4485
                $widgets->{'pixmapCurr'}->set_from_pixbuf($scaled);
 
4486
                $widgets->{'buttonCurr'}->{user_data} = $prevFile;
 
4487
            }
 
4488
            update_display("backdrop", $prevFile, "");
 
4489
            preview_display("backdrop", $prevFile, "", "MINI");
 
4490
        }
 
4491
    }
 
4492
}
 
4493
 
 
4494
#***
 
4495
 
 
4496
#****f* lyricue/backdrop_preview_clicked
 
4497
# NAME
 
4498
#   backdrop_preview_clicked
 
4499
# SYNOPSIS
 
4500
#   backdrop_preview_clicked($widget)
 
4501
# FUNCTION
 
4502
#   Changing backdrop to
 
4503
# INPUTS
 
4504
#   $widget -
 
4505
# OUTPUT
 
4506
# SOURCE
 
4507
#
 
4508
sub backdrop_preview_clicked {
 
4509
    my ($widget) = @_;
 
4510
    my $selected = $widget->{user_data};
 
4511
    debug("Changing backdrop to " . $selected);
 
4512
    if ($globals->{'bg_previews'}) {
 
4513
        my $prevFile = $selected;
 
4514
        my $scaled   = create_pixbuf(
 
4515
            $widgets->{'buttonCurr'}->{user_data},
 
4516
            $globals->{'icon_width'},
 
4517
            $globals->{'icon_height'}
 
4518
        );
 
4519
 
 
4520
        if ($scaled) {
 
4521
            $widgets->{'pixmapPrev'}->set_from_pixbuf($scaled);
 
4522
            $widgets->{'buttonPrev'}->{user_data} =
 
4523
              $widgets->{'buttonCurr'}->{user_data};
 
4524
        }
 
4525
 
 
4526
        $scaled = create_pixbuf(
 
4527
            $prevFile,
 
4528
            $globals->{'icon_width'},
 
4529
            $globals->{'icon_height'}
 
4530
        );
 
4531
        if ($scaled) {
 
4532
            $widgets->{'pixmapCurr'}->set_from_pixbuf($scaled);
 
4533
            $widgets->{'buttonCurr'}->{user_data} = $prevFile;
 
4534
        }
 
4535
        update_display("backdrop", $prevFile, "");
 
4536
        preview_display("backdrop", $prevFile, "", "MINI");
 
4537
    }
 
4538
}
 
4539
 
 
4540
#***
 
4541
 
 
4542
#****f* lyricue/do_add_image
 
4543
# NAME
 
4544
#   do_add_image
 
4545
# SYNOPSIS
 
4546
#   do_add_image ()
 
4547
# FUNCTION
 
4548
#   Add an image to the playlist
 
4549
# OUTPUT
 
4550
#   Image added to playlist
 
4551
# SOURCE
 
4552
#
 
4553
sub do_add_image {
 
4554
    my ($widget) = @_;
 
4555
    debug("do add image");
 
4556
    my $selection = $widgets->{'image'}->get_widget('treeImage')->get_selection;
 
4557
    my @list      = $selection->get_selected_rows();
 
4558
    my $model     = $widgets->{'image'}->get_widget('treeImage')->get_model();
 
4559
    my $playlist =
 
4560
      $widgets->{'image'}->get_widget('optionImageSublist')
 
4561
      ->get_menu->get_active->{'user_data'};
 
4562
    foreach (@list) {
 
4563
        my $image = $model->get($model->get_iter($_), 1);
 
4564
        add_image_item($playlist, $image);
 
4565
    }
 
4566
    close_dialog($widget);
 
4567
    update_playlist();
 
4568
}
 
4569
 
 
4570
#***
 
4571
 
 
4572
#****f* lyricue/add_image_item
 
4573
# NAME
 
4574
#   add_image_item
 
4575
# SYNOPSIS
 
4576
#   add_image_item($playlist, $image)
 
4577
# FUNCTION
 
4578
#           debug($image);
 
4579
# INPUTS
 
4580
#   $playlist -
 
4581
#    $image -
 
4582
# OUTPUT
 
4583
# SOURCE
 
4584
#
 
4585
sub add_image_item {
 
4586
    my ($playlist, $image) = @_;
 
4587
    my $playorder = 1;
 
4588
 
 
4589
    my $query = "SELECT MAX(playorder) FROM playlist";
 
4590
    qdebug($query);
 
4591
    my $sth = $lyricDbh->prepare($query)
 
4592
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
4593
    my $rv = $sth->execute
 
4594
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
4595
 
 
4596
    if ($row = $sth->fetchrow_hashref()) {
 
4597
        if ($row->{'MAX(playorder)'}) {
 
4598
            $playorder = $row->{'MAX(playorder)'} + 1;
 
4599
        }
 
4600
    }
 
4601
 
 
4602
    debug($image);
 
4603
    $query =
 
4604
        "INSERT INTO playlist (playorder, playlist, type, data) VALUES ("
 
4605
      . $playorder . ", "
 
4606
      . $playlist
 
4607
      . ", \"imag\", \""
 
4608
      . $image . "\")";
 
4609
    qdebug($query);
 
4610
    $sth = $lyricDbh->prepare($query)
 
4611
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
4612
    $rv = $sth->execute
 
4613
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
4614
    $playorder++;
 
4615
 
 
4616
}
 
4617
 
 
4618
#***
 
4619
 
 
4620
#****f* lyricue/show_about
 
4621
# NAME
 
4622
#   show_about
 
4623
# SYNOPSIS
 
4624
#   chose_about()
 
4625
# FUNCTION
 
4626
#   Open the About dialog
 
4627
# OUTPUT
 
4628
#   About dialog
 
4629
# SOURCE
 
4630
#
 
4631
sub show_about {
 
4632
    debug("Showing About dialog");
 
4633
    my $xml =
 
4634
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'windowAbout', 'lyricue');
 
4635
    $xml->signal_autoconnect_from_package('');
 
4636
    my $abouttext = $xml->get_widget('labelVersion')->get_text();
 
4637
    $abouttext =~ s/#VERSION#/$globals->{'version'}/g;
 
4638
    $xml->get_widget('labelVersion')->set_text($abouttext);
 
4639
    $xml->get_widget('windowAbout')->show();
 
4640
}
 
4641
 
 
4642
#***
 
4643
 
 
4644
#****f* lyricue/choose_playlist
 
4645
# NAME
 
4646
#   choose_playlist
 
4647
# SYNOPSIS
 
4648
#   choose_playlist ( )
 
4649
# FUNCTION
 
4650
#   Open a dialog to choose your main playlist
 
4651
# OUTPUT
 
4652
#   Search dialog
 
4653
# SOURCE
 
4654
#
 
4655
sub choose_playlist {
 
4656
    debug("Choose playlist");
 
4657
    $widgets->{'main'}->get_widget('vboxChoosePlay')->show_all;
 
4658
    $widgets->{'main'}->get_widget('scrollPlaylist')->hide;
 
4659
    $widgets->{'main'}->get_widget('toolbarPlaylist')->hide;
 
4660
    update_cplayclist();
 
4661
}
 
4662
 
 
4663
#***
 
4664
 
 
4665
#****f* lyricue/close_playlist_chooser
 
4666
# NAME
 
4667
#   close_playlist_chooser
 
4668
# SYNOPSIS
 
4669
#   close_playlist_chooser ( )
 
4670
# FUNCTION
 
4671
#   Close the playlist chooser
 
4672
# SOURCE
 
4673
#
 
4674
sub close_playlist_chooser {
 
4675
    debug("Close playlist chooser");
 
4676
    $widgets->{'main'}->get_widget('vboxChoosePlay')->hide;
 
4677
    $widgets->{'main'}->get_widget('scrollPlaylist')->show_all;
 
4678
    $widgets->{'main'}->get_widget('toolbarPlaylist')->show_all;
 
4679
}
 
4680
 
 
4681
#***
 
4682
 
 
4683
#****f* lyricue/create_dialog_prefs
 
4684
# NAME
 
4685
#   create_dialog_prefs
 
4686
# SYNOPSIS
 
4687
#   create_dialog_prefs()
 
4688
# FUNCTION
 
4689
#   Open the preferences dialog
 
4690
# OUTPUT
 
4691
#   preferences dialog
 
4692
# SOURCE
 
4693
#
 
4694
sub create_dialog_prefs {
 
4695
    debug("Creating preferences dialog");
 
4696
    $config = load_config();
 
4697
    $widgets->{'prefs'} =
 
4698
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogPrefs', 'lyricue');
 
4699
    $widgets->{'prefs'}->signal_autoconnect_from_package('');
 
4700
    $widgets->{'prefs'}->get_widget('spinPrefHeight')
 
4701
      ->set_value($config->{'Height'});
 
4702
    $widgets->{'prefs'}->get_widget('spinPrefWidth')
 
4703
      ->set_value($config->{'Width'});
 
4704
    $widgets->{'prefs'}->get_widget('spinPrefOverscanV')
 
4705
      ->set_value($config->{'OverscanV'});
 
4706
    $widgets->{'prefs'}->get_widget('spinPrefOverscanH')
 
4707
      ->set_value($config->{'OverscanH'});
 
4708
    $widgets->{'prefs'}->get_widget('checkPrefXinerama')
 
4709
      ->set_active($config->{'Xinerama'});
 
4710
    $widgets->{'prefs'}->get_widget('entryPrefWindowOffset')
 
4711
      ->set_text($config->{'GeometryOverride'});
 
4712
 
 
4713
    if ($config->{'VerticalLocation'}) {
 
4714
        $widgets->{'prefs'}->get_widget('comboPrefVertical')
 
4715
          ->prepend_text($config->{'VerticalLocation'});
 
4716
    }
 
4717
    $widgets->{'prefs'}->get_widget('comboPrefVertical')->set_active(0);
 
4718
    if ($config->{'HorizontalLocation'}) {
 
4719
        $widgets->{'prefs'}->get_widget('comboPrefHorizontal')
 
4720
          ->prepend_text($config->{'HorizontalLocation'});
 
4721
    }
 
4722
    $widgets->{'prefs'}->get_widget('comboPrefHorizontal')->set_active(0);
 
4723
    if ($config->{'Justification'}) {
 
4724
        $widgets->{'prefs'}->get_widget('comboPrefJustification')
 
4725
          ->prepend_text($config->{'Justification'});
 
4726
    }
 
4727
    $widgets->{'prefs'}->get_widget('comboPrefJustification')->set_active(0);
 
4728
    if ($config->{'DefaultTransition'}) {
 
4729
        $widgets->{'prefs'}->get_widget('comboPrefDefTrans')
 
4730
          ->prepend_text($config->{'DefaultTransition'});
 
4731
    }
 
4732
    $widgets->{'prefs'}->get_widget('comboPrefDefTrans')->set_active(0);
 
4733
 
 
4734
    $widgets->{'prefs'}->get_widget('entryPrefHeader')
 
4735
      ->set_text($config->{'Header'});
 
4736
    $widgets->{'prefs'}->get_widget('entryPrefMain')
 
4737
      ->set_text($config->{'Main'});
 
4738
    $widgets->{'prefs'}->get_widget('entryPrefFooter')
 
4739
      ->set_text($config->{'Footer'});
 
4740
    $widgets->{'prefs'}->get_widget('entryPrefOSD')->set_text($config->{'OSD'});
 
4741
    $widgets->{'prefs'}->get_widget('entryPrefColour')
 
4742
      ->set_text($config->{'Colour'});
 
4743
    $widgets->{'prefs'}->get_widget('entryPrefShadowColour')
 
4744
      ->set_text($config->{'ShadowColour'});
 
4745
    $widgets->{'prefs'}->get_widget('spinPrefShadow')
 
4746
      ->set_value($config->{'ShadowSize'});
 
4747
    $widgets->{'prefs'}->get_widget('checkPrefLoop')
 
4748
      ->set_active($config->{'Loop'});
 
4749
    $widgets->{'prefs'}->get_widget('checkPrefAudit')
 
4750
      ->set_active($config->{'Audit'});
 
4751
    $widgets->{'prefs'}->get_widget('checkPrefView')
 
4752
      ->set_active($config->{'DynamicPreview'});
 
4753
    $widgets->{'prefs'}->get_widget('checkPrefMiniview')
 
4754
      ->set_active($config->{'Miniview'});
 
4755
    my $scaled = create_pixbuf(
 
4756
        $config->{'BGImage'},
 
4757
        $globals->{'icon_width'},
 
4758
        $globals->{'icon_height'}
 
4759
    );
 
4760
 
 
4761
    if ($scaled) {
 
4762
        $widgets->{'prefs'}->get_widget('imagePrefBG')
 
4763
          ->set_from_pixbuf($scaled);
 
4764
        $widgets->{'prefs'}->get_widget('imagePrefBG')->{user_data} =
 
4765
          $config->{'BGImage'};
 
4766
    }
 
4767
 
 
4768
    my (@list);
 
4769
    my $bibles = $config->{'Bibles'};
 
4770
    foreach (sort keys %$bibles) {
 
4771
        my $bible = $_ . ":" . $config->{'Bibles'}->{$_};
 
4772
        push @list, $bible;
 
4773
    }
 
4774
 
 
4775
    $widgets->{'prefs'}->get_widget('comboPrefBible')
 
4776
      ->set_popdown_strings(@list);
 
4777
    $widgets->{'prefs'}->get_widget('entryPrefBible')
 
4778
      ->set_text($config->{'DefBible'});
 
4779
    $widgets->{'prefs'}->get_widget('entryPrefSpecialSong')
 
4780
      ->set_text($config->{'SpecialSong'});
 
4781
    $widgets->{'prefs'}->get_widget('entryPrefSpecialImage')
 
4782
      ->set_text($config->{'SpecialImage'});
 
4783
    $widgets->{'prefs'}->get_widget('entryPrefSpecialBack')
 
4784
      ->set_text($config->{'SpecialBack'});
 
4785
    $config->{'ImageDirectory'} =~ s/^\~/$ENV{'HOME'}/;
 
4786
    $widgets->{'prefs'}->get_widget('filePrefSpecialImagedir')
 
4787
      ->set_label($config->{'ImageDirectory'});
 
4788
    $widgets->{'prefs'}->get_widget('filePrefSpecialImagedir')->{'user_data'} =
 
4789
      "img";
 
4790
    $config->{'BGDirectory'} =~ s/^\~/$ENV{'HOME'}/;
 
4791
    $widgets->{'prefs'}->get_widget('filePrefSpecialBGdir')
 
4792
      ->set_label($config->{'BGDirectory'});
 
4793
    $widgets->{'prefs'}->get_widget('filePrefSpecialBGdir')->{'user_data'} =
 
4794
      "bg";
 
4795
 
 
4796
    if ($config->{'DatabaseType'} eq "mysql") {
 
4797
        $widgets->{'prefs'}->get_widget('radioPrefDBMysql')->set_active(TRUE);
 
4798
    } else {
 
4799
        $widgets->{'prefs'}->get_widget('radioPrefDBSqlite')->set_active(TRUE);
 
4800
    }
 
4801
    $widgets->{'prefs'}->get_widget('entryPrefHeader')
 
4802
      ->signal_connect("button_press_event", "open_dialogFont", "Header");
 
4803
    $widgets->{'prefs'}->get_widget('entryPrefMain')
 
4804
      ->signal_connect("button_press_event", "open_dialogFont", "Main");
 
4805
    $widgets->{'prefs'}->get_widget('entryPrefFooter')
 
4806
      ->signal_connect("button_press_event", "open_dialogFont", "Footer");
 
4807
    $widgets->{'prefs'}->get_widget('entryPrefOSD')
 
4808
      ->signal_connect("button_press_event", "open_dialogFont", "OSD");
 
4809
    $widgets->{'prefs'}->get_widget('entryPrefColour')
 
4810
      ->signal_connect("button_press_event", "open_dialogColour", "Font");
 
4811
    $widgets->{'prefs'}->get_widget('entryPrefShadowColour')
 
4812
      ->signal_connect("button_press_event", "open_dialogColour", "Shadow");
 
4813
}
 
4814
 
 
4815
#***
 
4816
 
 
4817
#****f* lyricue/change_windowoffset
 
4818
# NAME
 
4819
#   change_windowoffset
 
4820
# SYNOPSIS
 
4821
#   change_windowoffset
 
4822
# FUNCTION
 
4823
#   Show window for offset setting
 
4824
# INPUTS
 
4825
# OUTPUT
 
4826
#   Application loaded on second head
 
4827
# SOURCE
 
4828
#
 
4829
#***
 
4830
sub change_windowoffset {
 
4831
    debug ("Showing offset window");
 
4832
    my $offsetxml = Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogWindowOffset', 'lyricue');
 
4833
    $offsetxml->signal_autoconnect_from_package('');
 
4834
    $offsetxml->get_widget('dialogWindowOffset')->parse_geometry($widgets->{'prefs'}->get_widget('entryPrefWindowOffset')->get_text);
 
4835
    my $confirm = $offsetxml->get_widget('dialogWindowOffset')->run();
 
4836
    if ($confirm == 1) {
 
4837
        my ($x, $y)= $offsetxml->get_widget('dialogWindowOffset')->get_position;
 
4838
        $widgets->{'prefs'}->get_widget('entryPrefWindowOffset')->set_text("+".$x."+".$y);
 
4839
    }
 
4840
    close_dialog($offsetxml->get_widget('dialogWindowOffset'));
 
4841
}
 
4842
 
 
4843
#****f* lyricue/change_pref_xinerama
 
4844
# NAME
 
4845
#   change_pref_xinerama
 
4846
# SYNOPSIS
 
4847
#   change_pref_xinerama($widget)
 
4848
# FUNCTION
 
4849
#   Show/Hide xinerama-specific bits
 
4850
# INPUTS
 
4851
#   $widget - Calling widget
 
4852
# OUTPUT
 
4853
#   Stuff shown or hidden
 
4854
# SOURCE
 
4855
#
 
4856
sub change_pref_xinerama {
 
4857
    my ($widget) = @_;
 
4858
    debug ("Hide/Show xinerama stuff");
 
4859
    foreach my $name ('buttonPrefWindowOffset', 'labelPrefWindowOffset', 'entryPrefWindowOffset') {
 
4860
        if ($widget->get_active) {
 
4861
            $widgets->{'prefs'}->get_widget($name)->show;
 
4862
        } else {
 
4863
            $widgets->{'prefs'}->get_widget($name)->hide;
 
4864
        }
 
4865
    }
 
4866
}
 
4867
#***
 
4868
 
 
4869
#****f* lyricue/execute_app
 
4870
# NAME
 
4871
#   execute_app
 
4872
# SYNOPSIS
 
4873
#   execute_app ($widget, $app)
 
4874
# FUNCTION
 
4875
#   Run and application on the second head
 
4876
# INPUTS
 
4877
#   $widget - Calling widget
 
4878
#   $app - Application to run
 
4879
# OUTPUT
 
4880
#   Application loaded on second head
 
4881
# SOURCE
 
4882
#
 
4883
sub execute_app {
 
4884
    my ($widget, $app) = @_;
 
4885
    my $command = "";
 
4886
    if ($widget eq "") {
 
4887
        $command = $app;
 
4888
    } else {
 
4889
        $command = $config->{'App'}[$app];
 
4890
        $command =~ s/^.*?;//g;
 
4891
    }
 
4892
    debug("Executing app: " . $command);
 
4893
    if ($config->{'Xinerama'}) {
 
4894
        if ($command =~ /;$/) {
 
4895
            $command =~ s/;$//;
 
4896
            system($command . " &");
 
4897
        } else {
 
4898
            my $geom = "+" .  ($widgets->{'main'}->get_widget('windowMain')->get_screen->get_width - 100) . "+100";
 
4899
            if ($config->{'GeometryOverride'}) {
 
4900
               $geom = $config->{'GeometryOverride'};
 
4901
            }
 
4902
            system($command. " --geometry " . $geom . " &");
 
4903
        }
 
4904
    } else {
 
4905
        system("DISPLAY=:0.1 " . $command . " &");
 
4906
    }
 
4907
}
 
4908
 
 
4909
#***
 
4910
 
 
4911
#****f* lyricue/quote
 
4912
# NAME
 
4913
#   quote
 
4914
# SYNOPSIS
 
4915
#   quote ()
 
4916
# FUNCTION
 
4917
#   Quote a string for use in db queries
 
4918
# INPUTS
 
4919
#   @_ - String to be quoted
 
4920
# OUTPUT
 
4921
#   Quoted string
 
4922
# SOURCE
 
4923
#
 
4924
sub quote {
 
4925
    return $lyricDbh->quote(@_);
 
4926
}
 
4927
 
 
4928
#***
 
4929
 
 
4930
#****f* lyricue/honourise_song_lyrics
 
4931
# NAME
 
4932
#   honourise_song_lyrics
 
4933
# SYNOPSIS
 
4934
#   honourise_song_lyrics ($widget)
 
4935
# FUNCTION
 
4936
#   Change lyrics to 'honourise' them by changing 'jesus' to 'Jesus' etc
 
4937
# INPUTS
 
4938
#   $widget - Calling widget
 
4939
# OUTPUT
 
4940
#   Better lyrics
 
4941
# SOURCE
 
4942
#
 
4943
sub honourise_song_lyrics {
 
4944
    my ($widget) = @_;
 
4945
    my ($tmppage, $page, $numchars, $key);
 
4946
    my %hash;
 
4947
 
 
4948
    debug("Start of honourising lyrics...");
 
4949
 
 
4950
    foreach $page (keys(%pageOrder)) {
 
4951
        $tmppage = get_buffer_text($widgets->{'textAPageB'}{$page});
 
4952
        debug(  "Page contents of page " 
 
4953
              . $page
 
4954
              . " before honourisation:\n"
 
4955
              . $tmppage);
 
4956
 
 
4957
        # this hash is adapted from bible parsing perl script
 
4958
        # it will correct american spelling in any songs entered
 
4959
        # and will perform the honourise process -
 
4960
        # capitalising holy names and correcting errors like
 
4961
        # "Sons of god" to "sons of God"
 
4962
        %hash = (
 
4963
            "honor"      => "honour",
 
4964
            "color"      => "colour",
 
4965
            "labor"      => "labour",
 
4966
            "neighbor"   => "neighbour",
 
4967
            "center"     => "centre",
 
4968
            "dialog"     => "dialogue",
 
4969
            "gray"       => "grey",
 
4970
            "humor"      => "humour",
 
4971
            "harbor"     => "harbour",
 
4972
            "thru"       => "through",
 
4973
            "plow"       => "plough",
 
4974
            "favor"      => "favour",
 
4975
            "son"        => "Son",
 
4976
            "reaSon"     => "reason",
 
4977
            "Sons"       => "sons",
 
4978
            "god"        => "God",
 
4979
            "spirit"     => "Spirit",
 
4980
            "jesus"      => "Jesus",
 
4981
            "lord"       => "Lord",
 
4982
            "emmanuel"   => "Emmanuel",
 
4983
            "immanuel"   => "Immanuel",
 
4984
            "jehovah"    => "Jehovah",
 
4985
            "he"         => "He",
 
4986
            "him"        => "Him",
 
4987
            "his"        => "His",
 
4988
            "History"    => "history",
 
4989
            "messiah"    => "Messiah",
 
4990
            "father"     => "Father",
 
4991
            "king"       => "King",
 
4992
            "christ"     => "Christ",
 
4993
            "great i am" => "Great I Am",
 
4994
            "hosanna"    => "Hosanna",
 
4995
            "yahweh"     => "Yahweh"
 
4996
        );
 
4997
 
 
4998
        foreach $key (keys %hash) {
 
4999
            $tmppage =~ s/^$key([ \n])/$hash{$key}$1/g;
 
5000
            $tmppage =~ s/([ \n])$key$/$1$hash{$key}/g;
 
5001
            $tmppage =~ s/([ \n])$key([ \n])/$1$hash{$key}$2/g;
 
5002
        }
 
5003
        debug(  "Page contents of page " 
 
5004
              . $page
 
5005
              . " after honourisation:\n"
 
5006
              . $tmppage);
 
5007
        $widgets->{'textAPageB'}{$page}->set_text($tmppage);
 
5008
 
 
5009
    }
 
5010
 
 
5011
    debug("End of honourising lyrics...");
 
5012
}
 
5013
 
 
5014
#***
 
5015
 
 
5016
#****f* lyricue/select_bible_db
 
5017
# NAME
 
5018
#   select_bible_db
 
5019
# SYNOPSIS
 
5020
#   select_bible_db ($bible_database)
 
5021
# FUNCTION
 
5022
#   Change the bible db used by the server
 
5023
# INPUTS
 
5024
#   $bible_database - DB name to change it to
 
5025
# OUTPUT
 
5026
#   Verses displayed in chosen bible
 
5027
# SOURCE
 
5028
#
 
5029
sub select_bible_db {
 
5030
    my ($widget, $bibledb) = @_;
 
5031
 
 
5032
    if ($widget && ($widget->get_active)) {
 
5033
        debug("Changing bible to $bibledb");
 
5034
        my @line = split(/;/, $bibledb, 2);
 
5035
        do_change_bible($line[0], $line[1]);
 
5036
        if ((!defined $config->{'DefBible'}) || ($config->{'DefBible'} eq "")) {
 
5037
            $config->{'DefBible'} =
 
5038
              $line[1] . ":" . $line[0] . ";" . $widget->get('label');
 
5039
            debug("No default bible set previously, setting to "
 
5040
                  . $config->{'DefBible'});
 
5041
            write_config(FALSE);
 
5042
        }
 
5043
    }
 
5044
}
 
5045
 
 
5046
#***
 
5047
 
 
5048
#****f* lyricue/do_change_bible
 
5049
# NAME
 
5050
#   do_change_bible
 
5051
# SYNOPSIS
 
5052
#   do_change_bible ($type, $bibledb)
 
5053
# FUNCTION
 
5054
#   Change currently used bible
 
5055
# INPUTS
 
5056
#   $type - bible type (sword/db)
 
5057
#   $bibledb - Bible name
 
5058
# OUTPUT
 
5059
#   Calls update_playlist
 
5060
# SOURCE
 
5061
#
 
5062
sub do_change_bible {
 
5063
    my ($type, $bibledb) = @_;
 
5064
    debug("Change bible");
 
5065
    $globals->{'bibledb'} = $bibledb;
 
5066
    if (!$globals->{'usesword'}) {
 
5067
        $bibleDbh->disconnect;
 
5068
    }
 
5069
    if ($type eq "db") {
 
5070
        $globals->{'usesword'} = FALSE;
 
5071
        my ($table, $dbname) = split(/@/, $globals->{'bibledb'}, 2);
 
5072
        if ($dbname eq "") {
 
5073
            $dbname               = $table;
 
5074
            $table                = "verse";
 
5075
            $globals->{'bibledb'} = $table . "@" . $dbname;
 
5076
        }
 
5077
        $bibleDbh = db_connect($dbname, $errorcodes->{'bibledbopen'} . $dbname);
 
5078
    } else {
 
5079
        $globals->{'usesword'} = TRUE;
 
5080
    }
 
5081
    update_display("change_to_db", $bibledb, $type);
 
5082
    preview_display("change_to_db", $bibledb, $type, "MINI");
 
5083
}
 
5084
 
 
5085
#***
 
5086
 
 
5087
#****f* lyricue/invert_lines
 
5088
# NAME
 
5089
#   invert_lines
 
5090
# SYNOPSIS
 
5091
#   invert_lines ()
 
5092
# FUNCTION
 
5093
#   Change value so that playlist items text shows the last line of each page rather than the first
 
5094
# INPUTS
 
5095
# OUTPUT
 
5096
#   Calls update_playlist
 
5097
# SOURCE
 
5098
#
 
5099
sub invert_lines {
 
5100
    debug("Invert line display");
 
5101
    $globals->{'invert'} = !$globals->{'invert'};
 
5102
    update_playlist();
 
5103
}
 
5104
 
 
5105
#***
 
5106
 
 
5107
#****f* lyricue/export_song
 
5108
# NAME
 
5109
#   export_song
 
5110
# SYNOPSIS
 
5111
#   export_song ()
 
5112
# FUNCTION
 
5113
#   Show a dialog to choose where to save an exported song to
 
5114
# OUTPUT
 
5115
#   File dialog displayed
 
5116
# SOURCE
 
5117
#
 
5118
sub export_song {
 
5119
    debug("Export song");
 
5120
    my $filexml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
5121
        'dialogFileChooser', 'lyricue');
 
5122
    $filexml->signal_autoconnect_from_package('');
 
5123
    $filexml->get_widget('buttonFileOK')
 
5124
      ->signal_connect("clicked", "complete_export_song", $filexml);
 
5125
    $filexml->get_widget('dialogFileChooser')->show_all();
 
5126
}
 
5127
 
 
5128
#***
 
5129
 
 
5130
#****f* lyricue/complete_export_song
 
5131
# NAME
 
5132
#   complete_export_song
 
5133
# SYNOPSIS
 
5134
#   complete_export_song ($widget, $filexml)
 
5135
# FUNCTION
 
5136
#   Export a song to the chosen filename
 
5137
# INPUTS
 
5138
#   $widget - Calling widget
 
5139
#   $filexml - File dialog
 
5140
# OUTPUT
 
5141
#   File containing song
 
5142
# SOURCE
 
5143
#
 
5144
sub complete_export_song {
 
5145
    my ($widget, $filexml) = @_;
 
5146
    my ($tmppage, $page, $numchars, $key);
 
5147
    debug("Exporting song");
 
5148
    my $export = $filexml->get_widget('dialogFileChooser')->get_filename;
 
5149
    close_dialog($widget);
 
5150
    debug(" to file: " . $export);
 
5151
 
 
5152
    # Find maximum number of pages
 
5153
    my $maxpages = 1;
 
5154
    while (exists $pageOrder{$maxpages}) {
 
5155
        $maxpages++;
 
5156
    }
 
5157
 
 
5158
    #decrement maxpages so export works properly
 
5159
    $maxpages = $maxpages - 1;
 
5160
 
 
5161
    my @pages = ();
 
5162
    foreach $page (sort { $pageOrder{$a} cmp $pageOrder{$b} } keys %pageOrder) {
 
5163
        my $tmppage = get_buffer_text($widgets->{'textAPageB'}{$page});
 
5164
 
 
5165
        push @pages, $tmppage;
 
5166
    }
 
5167
    my $song = {
 
5168
        'name' => [$widgets->{'add'}->get_widget('entryEditName')->get_text()],
 
5169
        'number' =>
 
5170
          [$widgets->{'add'}->get_widget('entryEditNumber')->get_text()],
 
5171
        'book' => [$widgets->{'add'}->get_widget('entryEditBook')->get_text()],
 
5172
        'artist' =>
 
5173
          [$widgets->{'add'}->get_widget('entryEditArtist')->get_text()],
 
5174
        'keywords' =>
 
5175
          [$widgets->{'add'}->get_widget('entryEditKeywords')->get_text()],
 
5176
        'copyright' =>
 
5177
          [$widgets->{'add'}->get_widget('entryEditCopyright')->get_text()],
 
5178
        'page' => \@pages
 
5179
    };
 
5180
 
 
5181
    my $out = {'song' => [$song]};
 
5182
 
 
5183
    my $writer = XML::Simple->new();
 
5184
    open my $fh, ">" . $export . "";
 
5185
    $writer->XMLout($out, OutputFile => $fh, RootName => 'lyricue');
 
5186
    close $fh;
 
5187
 
 
5188
}
 
5189
 
 
5190
#***
 
5191
 
 
5192
#****f* lyricue/do_adv_search
 
5193
# NAME
 
5194
#   do_adv_search
 
5195
# SYNOPSIS
 
5196
#   do_adv_search ()
 
5197
# FUNCTION
 
5198
#   Do an advanced search where it searchs lyrics instead of song titles
 
5199
# OUTPUT
 
5200
#   List of suitable songs
 
5201
# SOURCE
 
5202
#
 
5203
sub do_adv_search {
 
5204
    my $search_text =
 
5205
      $widgets->{'search'}->get_widget('entrySearchSongs')->get_text();
 
5206
    if ($search_text ne "") {
 
5207
        debug("Searching for " . $search_text);
 
5208
        my $store = $widgets->{'search'}->get_widget('treeSearch')->get_model();
 
5209
        if ($store) {
 
5210
            $store->clear;
 
5211
        } else {
 
5212
            $store = Gtk2::ListStore->new(
 
5213
                'Glib::String', 'Glib::String',
 
5214
                'Glib::String', 'Glib::String',
 
5215
                'Glib::String'
 
5216
            );
 
5217
            $widgets->{'search'}->get_widget('treeSearch')->set_model($store);
 
5218
            my $column = Gtk2::TreeViewColumn->new_with_attributes(
 
5219
                fromutf(gettext("Title")),
 
5220
                Gtk2::CellRendererText->new, text => 0);
 
5221
            $widgets->{'search'}->get_widget('treeSearch')
 
5222
              ->append_column($column);
 
5223
            $column = Gtk2::TreeViewColumn->new_with_attributes(
 
5224
                fromutf(gettext("Artist")),
 
5225
                Gtk2::CellRendererText->new, text => 1);
 
5226
            $widgets->{'search'}->get_widget('treeSearch')
 
5227
              ->append_column($column);
 
5228
            $column = Gtk2::TreeViewColumn->new_with_attributes(
 
5229
                fromutf(gettext("Book")),
 
5230
                Gtk2::CellRendererText->new, text => 2);
 
5231
            $widgets->{'search'}->get_widget('treeSearch')
 
5232
              ->append_column($column);
 
5233
            $column = Gtk2::TreeViewColumn->new_with_attributes(
 
5234
                fromutf(gettext("Song No")),
 
5235
                Gtk2::CellRendererText->new, text => 3);
 
5236
            $widgets->{'search'}->get_widget('treeSearch')
 
5237
              ->append_column($column);
 
5238
        }
 
5239
        my $query =
 
5240
"SELECT id,title,songnum,book,artist,count(id) as count FROM lyricMain,page WHERE lyricMain.id=page.songid AND (page.lyrics LIKE \"%"
 
5241
          . $search_text
 
5242
          . "%\" OR title LIKE \"%"
 
5243
          . $search_text
 
5244
          . "%\" OR artist LIKE \"%"
 
5245
          . $search_text
 
5246
          . "%\" OR keywords LIKE \"%"
 
5247
          . $search_text
 
5248
          . "%\") GROUP BY id ORDER BY count DESC";
 
5249
        qdebug($query);
 
5250
        $sth = $lyricDbh->prepare($query)
 
5251
          || display_fatal($errorcodes->{'sqlprepare'},
 
5252
            $! . "\nSQL: " . $query);
 
5253
        $rv = $sth->execute
 
5254
          || display_fatal($errorcodes->{'sqlexecute'},
 
5255
            $! . "\nSQL: " . $query);
 
5256
        while ($row = $sth->fetchrow_hashref()) {
 
5257
            my $iter = $store->append;
 
5258
            $store->set(
 
5259
                $iter,             0, $row->{'title'},   1,
 
5260
                $row->{'artist'},  2, $row->{'book'}, 3,
 
5261
                $row->{'songnum'}, 4, $row->{'id'}
 
5262
            );
 
5263
        }
 
5264
    }
 
5265
}
 
5266
 
 
5267
#***
 
5268
 
 
5269
#****f* lyricue/update_adv_search
 
5270
# NAME
 
5271
#   update_adv_search
 
5272
# SYNOPSIS
 
5273
#   update_adv_search ($widget)
 
5274
# FUNCTION
 
5275
#   Update list of matching songs
 
5276
# INPUTS
 
5277
#   $widget - Calling widget
 
5278
# OUTPUT
 
5279
#   Updated dialog
 
5280
# SOURCE
 
5281
#
 
5282
sub update_adv_search {
 
5283
    my ($widget) = @_;
 
5284
    my $selection =
 
5285
      $widgets->{'search'}->get_widget('treeSearch')->get_selection;
 
5286
    my ($model, $iter) = $selection->get_selected;
 
5287
    if ($iter) {
 
5288
        my $songid = $model->get($iter, 4);
 
5289
        debug("Songid \"" . $songid . "\" selected");
 
5290
        my $query =
 
5291
            "SELECT lyrics FROM page WHERE songid=" 
 
5292
          . $songid
 
5293
          . " ORDER BY pagenum";
 
5294
        $sth = $lyricDbh->prepare($query)
 
5295
          || display_fatal($errorcodes->{'sqlprepare'},
 
5296
            $! . "\nSQL: " . $query);
 
5297
        $rv = $sth->execute
 
5298
          || display_fatal($errorcodes->{'sqlexecute'},
 
5299
            $! . "\nSQL: " . $query);
 
5300
        my $lyrics = "";
 
5301
 
 
5302
        while ($row = $sth->fetchrow_hashref()) {
 
5303
            $lyrics .= $row->{'lyrics'} . "\n\n";
 
5304
        }
 
5305
        $widgets->{'search'}->get_widget('textSearch')
 
5306
          ->get_buffer->set_text($lyrics);
 
5307
    }
 
5308
}
 
5309
 
 
5310
#***
 
5311
 
 
5312
#****f* lyricue/move_item
 
5313
# NAME
 
5314
#   move_item
 
5315
# SYNOPSIS
 
5316
#   move_item ($direction)
 
5317
# FUNCTION
 
5318
#   Move item in the playlist up/down
 
5319
# INPUTS
 
5320
#   $direction - Direction to move item
 
5321
# OUTPUT
 
5322
#   Re-ordered playlist
 
5323
# SOURCE
 
5324
#
 
5325
sub move_item {
 
5326
    my ($source, $placement, $dest) = @_;
 
5327
    debug("Moving " . $source . " to " . $placement . " " . $dest);
 
5328
    my $query = "SELECT playlist FROM playlist WHERE playorder=" . $source;
 
5329
    qdebug($query);
 
5330
    my $sth = $lyricDbh->prepare($query)
 
5331
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5332
    my $rv = $sth->execute
 
5333
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5334
    my @playlist = $sth->fetchrow_array;
 
5335
 
 
5336
    # Get list of items in this playlist
 
5337
    $query =
 
5338
        "SELECT playorder FROM playlist WHERE playlist="
 
5339
      . $playlist[0]
 
5340
      . " ORDER BY playorder";
 
5341
    qdebug($query);
 
5342
    $sth = $lyricDbh->prepare($query)
 
5343
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5344
    $rv = $sth->execute
 
5345
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5346
    my @items = ();
 
5347
    while (my @row = $sth->fetchrow_array) {
 
5348
        push @items, $row[0];
 
5349
    }
 
5350
 
 
5351
    my $sourceitem = 0;
 
5352
    my $destitem   = 0;
 
5353
    foreach my $i (0 .. @items - 1) {
 
5354
        debug($i . "-" . $items[$i]);
 
5355
        if ($items[$i] == $source) {
 
5356
            $sourceitem = $i;
 
5357
        }
 
5358
        if ($items[$i] == $dest) {
 
5359
            $destitem = $i;
 
5360
        }
 
5361
    }
 
5362
    debug($sourceitem . ":" . $destitem);
 
5363
 
 
5364
    if ($placement eq "before") {
 
5365
        $destitem--;
 
5366
    } elsif ($placement eq "after") {
 
5367
        $destitem++;
 
5368
    }
 
5369
    $dest = $items[$destitem];
 
5370
    debug($source . ":" . $dest);
 
5371
 
 
5372
    while ($source != $dest) {
 
5373
        debug("Moving " . $source . " to " . $dest);
 
5374
        if ($source < $dest) {
 
5375
            start_transaction();
 
5376
            {
 
5377
                renumber_item($source,                 -1);
 
5378
                renumber_item($items[$sourceitem + 1], $source);
 
5379
                renumber_item(-1,                      $items[$sourceitem + 1]);
 
5380
                $lyricDbh->commit();
 
5381
            };
 
5382
            end_transaction($@);
 
5383
            $sourceitem++;
 
5384
        } else {
 
5385
            start_transaction();
 
5386
            {
 
5387
                renumber_item($source,                 -1);
 
5388
                renumber_item($items[$sourceitem - 1], $source);
 
5389
                renumber_item(-1,                      $items[$sourceitem - 1]);
 
5390
            };
 
5391
            end_transaction($@);
 
5392
            $sourceitem--;
 
5393
        }
 
5394
        $source = $items[$sourceitem];
 
5395
    }
 
5396
    update_playlist($dest);
 
5397
}
 
5398
 
 
5399
#***
 
5400
 
 
5401
#****f* lyricue/move_item_up
 
5402
# NAME
 
5403
#   move_item_up
 
5404
# SYNOPSIS
 
5405
#   move_item_up ()
 
5406
# FUNCTION
 
5407
#   Move item in the playlist up
 
5408
# OUTPUT
 
5409
#   Calls move_item to do it
 
5410
# SOURCE
 
5411
#
 
5412
sub move_item_up {
 
5413
    my $selection =
 
5414
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
5415
    my ($model, $iter) = $selection->get_selected;
 
5416
    if ($iter) {
 
5417
        my $item = $model->get($iter, 2);
 
5418
        move_item($item, 'before', $item);
 
5419
    }
 
5420
}
 
5421
 
 
5422
#***
 
5423
 
 
5424
#****f* lyricue/move_item_down
 
5425
# NAME
 
5426
#   move_item_down
 
5427
# SYNOPSIS
 
5428
#   move_item_down ()
 
5429
# FUNCTION
 
5430
#   Move item in the playlist down
 
5431
# OUTPUT
 
5432
#   Calls move_item to do it
 
5433
# SOURCE
 
5434
#
 
5435
sub move_item_down {
 
5436
    my $selection =
 
5437
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
5438
    my ($model, $iter) = $selection->get_selected;
 
5439
    if ($iter) {
 
5440
        my $item = $model->get($iter, 2);
 
5441
        move_item($item, 'after', $item);
 
5442
    }
 
5443
}
 
5444
 
 
5445
#***
 
5446
 
 
5447
#****f* lyricue/renumber_item
 
5448
# NAME
 
5449
#   renumber_item
 
5450
# SYNOPSIS
 
5451
#   renumber_item ($before,$after)
 
5452
# FUNCTION
 
5453
#   Renumber an item in the playlist
 
5454
# INPUTS
 
5455
#   $before - playlist id to change from
 
5456
#   $after - playlist id to change to
 
5457
# OUTPUT
 
5458
#   Renumbered verse in playlist/lyrics
 
5459
# SOURCE
 
5460
#
 
5461
sub renumber_item {
 
5462
    my ($before, $after) = @_;
 
5463
    debug("Renumber item");
 
5464
    my $query = "SELECT * FROM playlist WHERE playorder=" . $before;
 
5465
    qdebug($query);
 
5466
    $sth = $lyricDbh->prepare($query)
 
5467
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5468
    $rv = $sth->execute
 
5469
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5470
    $row = $sth->fetchrow_hashref();
 
5471
 
 
5472
    $query =
 
5473
      "UPDATE playlist SET playorder=" . $after . " WHERE playorder=" . $before;
 
5474
    qdebug($query);
 
5475
    $sth = $lyricDbh->prepare($query)
 
5476
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5477
    $rv = $sth->execute
 
5478
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5479
 
 
5480
    $query =
 
5481
        "UPDATE associations SET playlist=" 
 
5482
      . $after
 
5483
      . " WHERE playlist="
 
5484
      . $before;
 
5485
    qdebug($query);
 
5486
    $sth = $lyricDbh->prepare($query)
 
5487
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5488
    $rv = $sth->execute
 
5489
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5490
}
 
5491
 
 
5492
#***
 
5493
 
 
5494
#****f* lyricue/add_copyright_preset
 
5495
# NAME
 
5496
#   add_copyright_preset
 
5497
# SYNOPSIS
 
5498
#   add_copyright_preset ($widget, $preset)
 
5499
# FUNCTION
 
5500
#   Add preset copyright text from menu to text entry
 
5501
# INPUTS
 
5502
#   $widget - Calling widget
 
5503
#   $preset - preset number to add
 
5504
# OUTPUT
 
5505
#   Preset in copyright entry
 
5506
# SOURCE
 
5507
#
 
5508
sub add_copyright_preset {
 
5509
    debug("Add preset");
 
5510
    my ($widget, $preset) = @_;
 
5511
    $widgets->{'add'}->get_widget('entryEditCopyright')
 
5512
      ->set_text("Preset:" . $preset);
 
5513
}
 
5514
 
 
5515
#***
 
5516
 
 
5517
#****f* lyricue/debug
 
5518
# NAME
 
5519
#   debug
 
5520
# SYNOPSIS
 
5521
#   debug ($text)
 
5522
# FUNCTION
 
5523
#   Always write to logfile
 
5524
#   Print $text if $globals->{'debugging'} is set
 
5525
# INPUTS
 
5526
#   $text - the text to output
 
5527
# OUTPUT
 
5528
#   Text to Logfile and possible STDERR
 
5529
# SOURCE
 
5530
#
 
5531
sub debug {
 
5532
    my $text = shift;
 
5533
    chomp($text);
 
5534
    if ($text) {
 
5535
        my ($sec, $min, $hour, undef) = localtime(time);
 
5536
        $text =
 
5537
          sprintf("%02d:%02d:%02d|INTERFACE: %s\n", $hour, $min, $sec, $text);
 
5538
        print LOG $text;
 
5539
        if ($globals->{'debugging'}) {
 
5540
            print STDERR $text;
 
5541
        }
 
5542
    }
 
5543
    return TRUE;
 
5544
}
 
5545
 
 
5546
#***
 
5547
 
 
5548
#****f* lyricue/qdebug
 
5549
# NAME
 
5550
#   qdebug
 
5551
# SYNOPSIS
 
5552
#   qdebug ($text)
 
5553
# FUNCTION
 
5554
#   Debug data
 
5555
# INPUTS
 
5556
#   $text - the text to output
 
5557
# OUTPUT
 
5558
#   Call to debug
 
5559
# SOURCE
 
5560
#
 
5561
sub qdebug {
 
5562
    if ($globals->{'debugging'} == 2) {
 
5563
        debug(@_);
 
5564
    }
 
5565
}
 
5566
 
 
5567
#***
 
5568
 
 
5569
#****f* lyricue/select_playlist
 
5570
# NAME
 
5571
#   select_playlist
 
5572
# SYNOPSIS
 
5573
#   select_playlist ($widget)
 
5574
# FUNCTION
 
5575
#   Select the main playlist
 
5576
# INPUTS
 
5577
#   $widget - calling widget
 
5578
# OUTPUT
 
5579
#   Closed selection dialog
 
5580
# SOURCE
 
5581
#
 
5582
sub select_playlist {
 
5583
    my ($widget) = @_;
 
5584
    debug("Selecting a main playlist");
 
5585
 
 
5586
    my $playlist   = "";
 
5587
    my $playlistid = 0;
 
5588
    my $selection =
 
5589
      $widgets->{'main'}->get_widget('treeChoosePlay')->get_selection;
 
5590
    if ($selection) {
 
5591
        my ($m, $i) = $selection->get_selected;
 
5592
        if ($m) {
 
5593
            $playlist   = $m->get($i, 0);
 
5594
            $playlistid = $m->get($i, 1);
 
5595
        }
 
5596
    }
 
5597
 
 
5598
    if ($playlist eq "") {
 
5599
        return;
 
5600
    }
 
5601
    if ($playlistid) {
 
5602
        $widgets->{'main'}->get_widget('labelCurrentPlaylist')
 
5603
          ->set_text($playlist);
 
5604
        $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data} =
 
5605
          $playlistid;
 
5606
        update_playlist();
 
5607
        close_playlist_chooser();
 
5608
    }
 
5609
}
 
5610
 
 
5611
#***
 
5612
 
 
5613
#****f* lyricue/select_playlist_click
 
5614
# NAME
 
5615
#   select_playlist_click
 
5616
# SYNOPSIS
 
5617
#   select_playlist_click ($widget, $event)
 
5618
# FUNCTION
 
5619
#   Select the main playlist on double-click
 
5620
# INPUTS
 
5621
#   $widget - calling widget
 
5622
#   $event - calling event
 
5623
# OUTPUT
 
5624
#   Closed selection dialog
 
5625
# SOURCE
 
5626
#
 
5627
sub select_playlist_click {
 
5628
    my ($widget, $event) = @_;
 
5629
    debug("select_playlist_click");
 
5630
    if ($event->type eq '2button-press') {
 
5631
        select_playlist($widget);
 
5632
    }
 
5633
}
 
5634
 
 
5635
#***
 
5636
 
 
5637
#****f* lyricue/new_playlist
 
5638
# NAME
 
5639
#   new_playlist
 
5640
# SYNOPSIS
 
5641
#   new_playlist ($widget)
 
5642
# FUNCTION
 
5643
#   Create a new playlist
 
5644
# INPUTS
 
5645
#   $widget - Calling widget
 
5646
# OUTPUT
 
5647
#   Closed
 
5648
# SOURCE
 
5649
#
 
5650
sub new_playlist {
 
5651
    my ($widget) = @_;
 
5652
    debug("Creating a new playlist");
 
5653
    my $playlist = "";
 
5654
    my $newxml   = Gtk2::GladeXML->new($globals->{'gladefile'},
 
5655
        'dialogPromptEntry', 'lyricue');
 
5656
    $newxml->signal_autoconnect_from_package('');
 
5657
    $newxml->get_widget('dialogPromptEntry')
 
5658
      ->set_title(fromutf(gettext("Create new playlist")));
 
5659
    $newxml->get_widget('labelPromptE')
 
5660
      ->set_text(fromutf(gettext("Name of playlist")));
 
5661
 
 
5662
    my $response = $newxml->get_widget('dialogPromptEntry')->run();
 
5663
    if ($response eq "ok") {
 
5664
        $playlist = $newxml->get_widget('entryPromptE')->get_text();
 
5665
    }
 
5666
    close_dialog($newxml->get_widget('dialogPromptEntry'));
 
5667
    if ($playlist eq "") {
 
5668
        return;
 
5669
    }
 
5670
 
 
5671
    my $query = "SELECT MAX(id)+1 FROM playlists";
 
5672
    my $sth   = $lyricDbh->prepare($query)
 
5673
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5674
    my $rv = $sth->execute
 
5675
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5676
    my @row = $sth->fetchrow_array();
 
5677
    $query =
 
5678
        "INSERT INTO playlists (id,title) VALUES ("
 
5679
      . $row[0] . ", \""
 
5680
      . $playlist . "\")";
 
5681
    $sth = $lyricDbh->prepare($query)
 
5682
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5683
    $rv = $sth->execute
 
5684
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5685
    $query = "SELECT id FROM playlists WHERE title LIKE \"" . $playlist . "\"";
 
5686
    $sth   = $lyricDbh->prepare($query)
 
5687
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5688
    $rv = $sth->execute
 
5689
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5690
    @row = $sth->fetchrow_array();
 
5691
 
 
5692
    if ($row[0]) {
 
5693
        $widgets->{'main'}->get_widget('labelCurrentPlaylist')
 
5694
          ->set_text($playlist);
 
5695
        $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data} =
 
5696
          $row[0];
 
5697
        update_playlist();
 
5698
        close_playlist_chooser();
 
5699
    }
 
5700
}
 
5701
 
 
5702
#***
 
5703
 
 
5704
#****f* lyricue/rename_playlist
 
5705
# NAME
 
5706
#   rename_playlist
 
5707
# SYNOPSIS
 
5708
#   rename_playlist ($widget)
 
5709
# FUNCTION
 
5710
#   Rename a playlist
 
5711
# INPUTS
 
5712
#   $widget - Calling widget
 
5713
# OUTPUT
 
5714
#   Closed
 
5715
# SOURCE
 
5716
sub rename_playlist {
 
5717
    my ($widget) = @_;
 
5718
    debug("Renaming playlist");
 
5719
    my $playlist = "";
 
5720
    my $selection =
 
5721
      $widgets->{'main'}->get_widget('treeChoosePlay')->get_selection;
 
5722
    if ($selection) {
 
5723
        my ($m, $i) = $selection->get_selected;
 
5724
        if ($m) {
 
5725
            $playlist = $m->get($i, 0);
 
5726
        }
 
5727
    }
 
5728
 
 
5729
    if ($playlist eq "") {
 
5730
        return;
 
5731
    }
 
5732
 
 
5733
    my $query = "SELECT id FROM playlists WHERE title=\"" . $playlist . "\"";
 
5734
    my $sth   = $lyricDbh->prepare($query)
 
5735
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5736
    my $rv = $sth->execute
 
5737
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5738
    my @row = $sth->fetchrow_array();
 
5739
    if ($row[0]) {
 
5740
        my $renamexml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
5741
            'dialogPromptEntry', 'lyricue');
 
5742
        $renamexml->signal_autoconnect_from_package('');
 
5743
        my $labelText = fromutf(gettext("Renaming ")) . $playlist;
 
5744
        $renamexml->get_widget('dialogPromptEntry')->set_title($labelText);
 
5745
        $renamexml->get_widget('labelPromptE')->set_text($labelText);
 
5746
        $renamexml->get_widget('labelPromptE')->{user_data} = $row[0];
 
5747
        $renamexml->get_widget('entryPromptE')->set_text($playlist);
 
5748
        $renamexml->get_widget('buttonPromptEOK')
 
5749
          ->signal_connect("clicked", "do_rename_playlist", $renamexml);
 
5750
    }
 
5751
}
 
5752
 
 
5753
#***
 
5754
 
 
5755
#****f* lyricue/do_rename_playlist
 
5756
# NAME
 
5757
#   do_rename_playlist
 
5758
# SYNOPSIS
 
5759
#   do_rename_playlist ($widget, $renamexml)
 
5760
# FUNCTION
 
5761
#   Rename a playlist
 
5762
# INPUTS
 
5763
#   $widget - Calling widget
 
5764
#   $renamexml - Dialog widgets
 
5765
# OUTPUT
 
5766
#   Closed
 
5767
# SOURCE
 
5768
#
 
5769
sub do_rename_playlist {
 
5770
    my ($widget, $renamexml) = @_;
 
5771
    debug("Do rename playlist");
 
5772
    my $query =
 
5773
        "UPDATE playlists SET title=\""
 
5774
      . $renamexml->get_widget('entryPromptE')->get_text
 
5775
      . "\" WHERE id="
 
5776
      . $renamexml->get_widget('labelPromptE')->{user_data};
 
5777
    qdebug($query);
 
5778
    my $sth = $lyricDbh->prepare($query)
 
5779
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5780
    my $rv = $sth->execute
 
5781
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5782
    update_cplayclist();
 
5783
    close_dialog($widget);
 
5784
}
 
5785
 
 
5786
#***
 
5787
 
 
5788
#****f* lyricue/delete_playlist
 
5789
# NAME
 
5790
#   delete_playlist
 
5791
# SYNOPSIS
 
5792
#   delete_playlist ($widget)
 
5793
# FUNCTION
 
5794
#   Delete a playlist
 
5795
# INPUTS
 
5796
#   $widget - Calling widget
 
5797
# OUTPUT
 
5798
#   Closed
 
5799
# SOURCE
 
5800
sub delete_playlist {
 
5801
    my ($widget) = @_;
 
5802
    debug("Deleting a playlist");
 
5803
 
 
5804
    my $playlist = "";
 
5805
    my $selection =
 
5806
      $widgets->{'main'}->get_widget('treeChoosePlay')->get_selection;
 
5807
    if ($selection) {
 
5808
        my ($m, $i) = $selection->get_selected;
 
5809
        if ($m) {
 
5810
            $playlist = $m->get($i, 1);
 
5811
        }
 
5812
    }
 
5813
 
 
5814
    if ($playlist eq "") {
 
5815
        return;
 
5816
    }
 
5817
 
 
5818
    my $query = "DELETE FROM playlists WHERE id=" . $playlist;
 
5819
    qdebug($query);
 
5820
    my $sth = $lyricDbh->prepare($query)
 
5821
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5822
    my $rv = $sth->execute
 
5823
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5824
 
 
5825
    $query =
 
5826
      "DELETE FROM playlist WHERE data=" . $playlist . " AND type=\"play\"";
 
5827
    qdebug($query);
 
5828
    $sth = $lyricDbh->prepare($query)
 
5829
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5830
    $rv = $sth->execute
 
5831
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5832
 
 
5833
    $query = "SELECT playorder FROM playlist WHERE playlist=" . $playlist;
 
5834
    qdebug($query);
 
5835
    $sth = $lyricDbh->prepare($query)
 
5836
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5837
    $rv = $sth->execute
 
5838
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5839
    while (my @row = $sth->fetchrow_array()) {
 
5840
        remove_single_item($row[0]);
 
5841
    }
 
5842
 
 
5843
    update_cplayclist();
 
5844
}
 
5845
 
 
5846
#***
 
5847
 
 
5848
#****f* lyricue/update_cplayclist
 
5849
# NAME
 
5850
#   update_cplayclist
 
5851
# SYNOPSIS
 
5852
#   update_cplayclist ($widget)
 
5853
# FUNCTION
 
5854
#   Update the clist
 
5855
# INPUTS
 
5856
#   $widget - The clist to update
 
5857
# OUTPUT
 
5858
# SOURCE
 
5859
#
 
5860
sub update_cplayclist {
 
5861
    my ($selection, $renderer, $column);
 
5862
    debug("Update Choose playlist");
 
5863
    my $store = $widgets->{'main'}->get_widget('treeChoosePlay')->get_model();
 
5864
    if ($store) {
 
5865
        $store->clear;
 
5866
    } else {
 
5867
        $store = Gtk2::ListStore->new('Glib::String', 'Glib::Int');
 
5868
        $widgets->{'main'}->get_widget('treeChoosePlay')->set_model($store);
 
5869
        $renderer = Gtk2::CellRendererText->new;
 
5870
        $selection =
 
5871
          $widgets->{'main'}->get_widget('treeChoosePlay')->get_selection;
 
5872
        $column =
 
5873
          Gtk2::TreeViewColumn->new_with_attributes("Playlist", $renderer,
 
5874
            text => 0);
 
5875
        $widgets->{'main'}->get_widget('treeChoosePlay')
 
5876
          ->append_column($column);
 
5877
    }
 
5878
 
 
5879
    my $query =
 
5880
"SELECT title,id FROM playlists LEFT JOIN playlist ON playlist.data=playlists.id AND playlist.data NOT LIKE '%-%' AND (type='play' OR type='sub') WHERE data IS NULL AND playlists.id > 0 ORDER BY id";
 
5881
    qdebug($query);
 
5882
    my $sth = $lyricDbh->prepare($query)
 
5883
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
5884
    my $rv = $sth->execute
 
5885
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
5886
    my @row;
 
5887
    while (@row = $sth->fetchrow_array()) {
 
5888
        my $iter = $store->append;
 
5889
        $store->set($iter, 0, fromutf($row[0]), 1, $row[1]);
 
5890
    }
 
5891
}
 
5892
 
 
5893
#***
 
5894
 
 
5895
#****f* lyricue/copy_item
 
5896
# NAME
 
5897
#   copy_item
 
5898
# SYNOPSIS
 
5899
#   copy_item ()
 
5900
# FUNCTION
 
5901
#   Copy the selected item in the playlist
 
5902
# OUTPUT
 
5903
#   Extra item in the playlist
 
5904
# SOURCE
 
5905
#
 
5906
sub copy_item {
 
5907
    my $selection =
 
5908
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
5909
    my ($model, $iter) = $selection->get_selected;
 
5910
    if ($iter) {
 
5911
        debug("Duplicate item clicked ");
 
5912
 
 
5913
        my $item  = $model->get($iter, 2);
 
5914
        my $query = "SELECT * FROM playlist WHERE playorder=" . $item;
 
5915
        my $sth   = $lyricDbh->prepare($query)
 
5916
          || display_fatal($errorcodes->{'sqlprepare'},
 
5917
            $! . "\nSQL: " . $query);
 
5918
        my $rv = $sth->execute
 
5919
          || display_fatal($errorcodes->{'sqlexecute'},
 
5920
            $! . "\nSQL: " . $query);
 
5921
        my $row = $sth->fetchrow_hashref();
 
5922
 
 
5923
        if ($row->{'type'} ne "play") {
 
5924
            my $query = "SELECT MAX(playorder) FROM playlist";
 
5925
            my $sth   = $lyricDbh->prepare($query)
 
5926
              || display_fatal($errorcodes->{'sqlprepare'},
 
5927
                $! . "\nSQL: " . $query);
 
5928
            my $rv = $sth->execute
 
5929
              || display_fatal($errorcodes->{'sqlexecute'},
 
5930
                $! . "\nSQL: " . $query);
 
5931
            my @row2 = $sth->fetchrow_array();
 
5932
            $row2[0]++;
 
5933
 
 
5934
            $query =
 
5935
                "INSERT INTO playlist (playorder,playlist,data,type) VALUES ("
 
5936
              . $row2[0] . ", "
 
5937
              . $row->{'playlist'} . ", \""
 
5938
              . $row->{'data'}
 
5939
              . "\", \""
 
5940
              . $row->{'type'} . "\")";
 
5941
            qdebug($query);
 
5942
            $sth = $lyricDbh->prepare($query)
 
5943
              || display_fatal($errorcodes->{'sqlprepare'},
 
5944
                $! . "\nSQL: " . $query);
 
5945
            $rv = $sth->execute
 
5946
              || display_fatal($errorcodes->{'sqlexecute'},
 
5947
                $! . "\nSQL: " . $query);
 
5948
        }
 
5949
 
 
5950
        update_playlist();
 
5951
    }
 
5952
}
 
5953
 
 
5954
#***
 
5955
 
 
5956
#****f* lyricue/begin_loop
 
5957
# NAME
 
5958
#   begin_loop
 
5959
# SYNOPSIS
 
5960
#   begin_loop ()
 
5961
# FUNCTION
 
5962
#   Initialise the automatic page looping
 
5963
# OUTPUT
 
5964
#   Gtk timer set
 
5965
# SOURCE
 
5966
#
 
5967
sub begin_loop {
 
5968
    debug("Initialising a playlist item loop");
 
5969
 
 
5970
    my $selection =
 
5971
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
5972
    my ($model, $iter) = $selection->get_selected;
 
5973
    if ($iter) {
 
5974
        my $loopxml =
 
5975
          Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogLoop', 'lyricue');
 
5976
        $loopxml->signal_autoconnect_from_package('');
 
5977
        $loopxml->get_widget('dialogLoop')->{user_data} = $model->get($iter, 2);
 
5978
        $loopxml->get_widget('buttonLoopOK')
 
5979
          ->signal_connect('clicked', "establish_timer", $loopxml);
 
5980
    }
 
5981
}
 
5982
 
 
5983
#***
 
5984
 
 
5985
#****f* lyricue/establish_timer
 
5986
# NAME
 
5987
#   establish_timer
 
5988
# SYNOPSIS
 
5989
#   establish_timer ($widget, $loopxml)
 
5990
# FUNCTION
 
5991
#   Create a new timer
 
5992
# OUTPUT
 
5993
#   Gtk timer set
 
5994
# SOURCE
 
5995
#
 
5996
sub establish_timer {
 
5997
    my ($widget, $loopxml) = @_;
 
5998
 
 
5999
    reset_timer($globals->{'timer'});
 
6000
 
 
6001
    my $seconds = $loopxml->get_widget('spinLoopSeconds')->get_value_as_int();
 
6002
    my $milliseconds =
 
6003
      $loopxml->get_widget('spinLoopMilliseconds')->get_value_as_int();
 
6004
 
 
6005
    debug("Seconds = " . $seconds . " ||| Milliseconds = " . $milliseconds);
 
6006
 
 
6007
    my $interval = ($seconds * 1000) + $milliseconds;
 
6008
    if ($interval < 50) {
 
6009
        $interval = 50;
 
6010
        debug("Interval too small - defaulting to 50 milliseconds");
 
6011
    }
 
6012
 
 
6013
#Find the id of the list we will be looping (could be a playlist, sublist or song)
 
6014
    my $query = "SELECT data FROM playlist WHERE playorder ="
 
6015
      . $loopxml->get_widget('dialogLoop')->{user_data};
 
6016
    qdebug($query);
 
6017
    my $sth = $lyricDbh->prepare($query)
 
6018
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
6019
    my $rv = $sth->execute
 
6020
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
6021
    my @row    = $sth->fetchrow_array();
 
6022
    my $parent = $row[0];
 
6023
 
 
6024
    update_display("display", $loopxml->get_widget('dialogLoop')->{user_data},
 
6025
        "");
 
6026
 
 
6027
    my @data = ("display", "next_page", "loop;".$parent);
 
6028
 
 
6029
    $globals->{'timer'} = Glib::Timeout->add($interval, \&update_loop, \@data);
 
6030
    debug("Set loop advance timer to " . $interval . " milliseconds.");
 
6031
    close_dialog($widget);
 
6032
}
 
6033
 
 
6034
#***
 
6035
 
 
6036
### FIXME ###
 
6037
#***
 
6038
 
 
6039
#****f* lyricue/update_loop
 
6040
# NAME
 
6041
#   update_loop
 
6042
# SYNOPSIS
 
6043
#   update_loop($data)
 
6044
# FUNCTION
 
6045
#   Loop triggered
 
6046
# INPUTS
 
6047
#   $data -
 
6048
# OUTPUT
 
6049
# SOURCE
 
6050
#
 
6051
sub update_loop {
 
6052
    my ($data) = @_;
 
6053
    debug("Loop triggered");
 
6054
    update_display($$data[0], $$data[1], $$data[2]);
 
6055
    return TRUE;
 
6056
}
 
6057
 
 
6058
#***
 
6059
 
 
6060
#****f* lyricue/load_config
 
6061
# NAME
 
6062
#   load_config
 
6063
# SYNOPSIS
 
6064
#   load_config()
 
6065
# FUNCTION
 
6066
#   Loading Preferences
 
6067
# INPUTS
 
6068
# OUTPUT
 
6069
# SOURCE
 
6070
#
 
6071
sub load_config {
 
6072
    my ($conf);
 
6073
    debug("Loading Preferences");
 
6074
    my $bibleCount = 0;
 
6075
    my $appCount   = 0;
 
6076
    $conf->{'App'}[$appCount++] = gettext("Load Lyricue Display").";lyricue_display";
 
6077
    $conf->{'App'}[$appCount++] = gettext("Close Lyricue Display").";lyricue_remote close";
 
6078
    open(CONFIG, $globals->{'configfile'})
 
6079
      || display_fatal($errorcodes->{'fileopenread'} . $globals->{'configfile'},
 
6080
        $! . "\nSQL: " . $query);
 
6081
    binmode(CONFIG, ":utf8");
 
6082
    $conf->{'Width'}  = 0;
 
6083
    $conf->{'Height'} = 0;
 
6084
 
 
6085
    while (<CONFIG>) {
 
6086
        chomp;
 
6087
        my @line = split(/=/);
 
6088
        if ($line[0]) {
 
6089
            $line[0] =~ s/ *$//g;
 
6090
        }
 
6091
        if ($line[1]) {
 
6092
            $line[1] =~ s/ *$//g;
 
6093
        }
 
6094
        if (!$line[1]) {
 
6095
            $line[1] = "";
 
6096
        }
 
6097
        $line[1] =~ s/^ *//g;
 
6098
        if ($line[0] eq "App") {
 
6099
            my $found = FALSE;
 
6100
            foreach my $app (gettext("Load Lyricue Display"), gettext("Close Lyricue Display"), "Load Lyricue Display", "Close Lyricue Display") {
 
6101
                if ($line[1] =~ /^$app;/) {
 
6102
                    $found=TRUE;
 
6103
                }
 
6104
            }
 
6105
            if (!$found) {
 
6106
                $conf->{'App'}[$appCount++] = $line[1];
 
6107
            }
 
6108
        } else {
 
6109
            $conf->{$line[0]} = $line[1];
 
6110
        }
 
6111
    }
 
6112
    close CONFIG;
 
6113
 
 
6114
    $conf->{'BibleCount'} = $bibleCount;
 
6115
    $conf->{'AppCount'}   = $appCount;
 
6116
    $conf->{'Bibles'}     = get_bibles();
 
6117
    if (!defined $conf->{'HighlightColour'}) {
 
6118
        $conf->{'HighlightColour'} = "yellow";
 
6119
    }
 
6120
    if (defined $globals->{'force_sqlite'} && ($globals->{'force_sqlite'})) {
 
6121
        $conf->{'DatabaseType'} = "SQLite";
 
6122
    }
 
6123
    if (!defined $conf->{'TrayIcons'}) {
 
6124
        $conf->{'TrayIcons'} = "1";
 
6125
    }
 
6126
    if ($conf->{'TrayIcons'} ne "1") {
 
6127
        $globals->{'trayicon'} = FALSE;
 
6128
    }
 
6129
    if (!defined $conf->{'DatabaseType'}) {
 
6130
        $conf->{'DatabaseType'} = "mysql";
 
6131
    }
 
6132
    $conf->{'LoopText'} = "";
 
6133
    if (defined $conf->{'Loop'}) {
 
6134
        if ($conf->{'Loop'} eq "1") {
 
6135
            $conf->{'LoopText'} = "loop";
 
6136
        }
 
6137
    }
 
6138
    if (!($conf->{'BGImage'} =~ /;/)) {
 
6139
        $conf->{'BGImage'} = "db;" . $conf->{'BGImage'};
 
6140
    }
 
6141
    if (!($conf->{'ImageDirectory'})) {
 
6142
        $conf->{'ImageDirectory'} =
 
6143
          Glib::get_user_special_dir('pictures') . "/";
 
6144
    }
 
6145
    if (!($conf->{'BGDirectory'})) {
 
6146
        $conf->{'BGDirectory'} = Glib::get_user_special_dir('pictures') . "/";
 
6147
    }
 
6148
 
 
6149
    if ($conf->{'CentreX'}) {
 
6150
        if ($conf->{'CentreX'}) {
 
6151
            $conf->{'HorizontalLocation'} = "Centre";
 
6152
        } else {
 
6153
            $conf->{'HorizontalLocation'} = "Left";
 
6154
        }
 
6155
    }
 
6156
 
 
6157
    if ($conf->{'CentreY'}) {
 
6158
        if ($conf->{'CentreY'}) {
 
6159
            $conf->{'VerticalLocation'} = "Centre";
 
6160
        } else {
 
6161
            $conf->{'VerticalLocation'} = "Top";
 
6162
        }
 
6163
    }
 
6164
    if(!defined $conf->{'DefaultTransition'}) {
 
6165
        $conf->{'DefaultTransition'} = "Fade";
 
6166
    }
 
6167
    if (   (!defined $conf->{'ProjectorHost'})
 
6168
        || ($globals->{'host'} ne "localhost"))
 
6169
    {
 
6170
        $conf->{'ProjectorHost'} = $globals->{'host'};
 
6171
    } else {
 
6172
        $globals->{'host'} = $conf->{'ProjectorHost'};
 
6173
    }
 
6174
    if (   (!defined $conf->{'DBHost'})
 
6175
        || ($globals->{'mysqlhost'} ne "localhost"))
 
6176
    {
 
6177
        $conf->{'DBHost'} = $globals->{'mysqlhost'};
 
6178
    } else {
 
6179
        $globals->{'mysqlhost'} = $conf->{'DBHost'};
 
6180
    }
 
6181
 
 
6182
    return $conf;
 
6183
}
 
6184
 
 
6185
#***
 
6186
 
 
6187
#***
 
6188
 
 
6189
#****f* lyricue/save_state
 
6190
# NAME
 
6191
#   save_state
 
6192
# SYNOPSIS
 
6193
#   save_state()
 
6194
# FUNCTION
 
6195
#
 
6196
# INPUTS
 
6197
# OUTPUT
 
6198
# SOURCE
 
6199
#
 
6200
sub save_state {
 
6201
    $config->{'FrameLeft'} =
 
6202
      $widgets->{'main'}->get_widget('hpanedMainLeft')->get_position();
 
6203
    $config->{'FrameRight'} =
 
6204
      $widgets->{'main'}->get_widget('hpanedMainRight')->get_position();
 
6205
    my ($width, $height) =
 
6206
      $widgets->{'main'}->get_widget('windowMain')->get_size();
 
6207
    if (defined $widgets->{'main'}->get_widget('vpanedMain')) {
 
6208
        $config->{'FrameMain'} =
 
6209
          ($height -
 
6210
              $widgets->{'main'}->get_widget('vpanedMain')->get_position());
 
6211
    }
 
6212
}
 
6213
 
 
6214
#***
 
6215
 
 
6216
#****f* lyricue/save_and_close_prefs
 
6217
# NAME
 
6218
#   save_and_close_prefs
 
6219
# SYNOPSIS
 
6220
#   save_and_close_prefs()
 
6221
# FUNCTION
 
6222
#   Save and close preferences
 
6223
# INPUTS
 
6224
# OUTPUT
 
6225
# SOURCE
 
6226
#
 
6227
sub save_and_close_prefs {
 
6228
    debug("Save and close preferences");
 
6229
    save_preferences();
 
6230
    $globals->{'configured'} = TRUE;
 
6231
    close_dialog($widgets->{'prefs'}->get_widget('dialogPrefs'));
 
6232
}
 
6233
 
 
6234
#***
 
6235
 
 
6236
#****f* lyricue/save_preferences
 
6237
# NAME
 
6238
#   save_preferences
 
6239
# SYNOPSIS
 
6240
#   save_preferences()
 
6241
# FUNCTION
 
6242
#   Saving preferences
 
6243
# INPUTS
 
6244
# OUTPUT
 
6245
# SOURCE
 
6246
#
 
6247
sub save_preferences {
 
6248
    debug("Saving preferences");
 
6249
    $config->{'Main'} =
 
6250
      $widgets->{'prefs'}->get_widget('entryPrefMain')->get_text();
 
6251
    $config->{'Header'} =
 
6252
      $widgets->{'prefs'}->get_widget('entryPrefHeader')->get_text();
 
6253
    $config->{'Footer'} =
 
6254
      $widgets->{'prefs'}->get_widget('entryPrefFooter')->get_text();
 
6255
    $config->{'OSD'} =
 
6256
      $widgets->{'prefs'}->get_widget('entryPrefOSD')->get_text();
 
6257
    $config->{'Colour'} =
 
6258
      $widgets->{'prefs'}->get_widget('entryPrefColour')->get_text();
 
6259
    $config->{'ShadowColour'} =
 
6260
      $widgets->{'prefs'}->get_widget('entryPrefShadowColour')->get_text();
 
6261
    $config->{'ShadowSize'} =
 
6262
      $widgets->{'prefs'}->get_widget('spinPrefShadow')->get_value();
 
6263
    $config->{'Height'} =
 
6264
      $widgets->{'prefs'}->get_widget('spinPrefHeight')->get_value();
 
6265
    $config->{'Width'} =
 
6266
      $widgets->{'prefs'}->get_widget('spinPrefWidth')->get_value();
 
6267
    $config->{'OverscanH'} =
 
6268
      $widgets->{'prefs'}->get_widget('spinPrefOverscanH')->get_value();
 
6269
    $config->{'OverscanV'} =
 
6270
      $widgets->{'prefs'}->get_widget('spinPrefOverscanV')->get_value();
 
6271
    $config->{'Loop'} =
 
6272
      $widgets->{'prefs'}->get_widget('checkPrefLoop')->get_active() ? 1 : 0;
 
6273
    $config->{'Audit'} =
 
6274
      $widgets->{'prefs'}->get_widget('checkPrefAudit')->get_active() ? 1 : 0;
 
6275
    $config->{'DynamicPreview'} =
 
6276
      $widgets->{'prefs'}->get_widget('checkPrefView')->get_active() ? 1 : 0;
 
6277
    $config->{'Miniview'} =
 
6278
      $widgets->{'prefs'}->get_widget('checkPrefMiniview')->get_active()
 
6279
      ? 1
 
6280
      : 0;
 
6281
    $config->{'Xinerama'} =
 
6282
      $widgets->{'prefs'}->get_widget('checkPrefXinerama')->get_active()
 
6283
      ? 1
 
6284
      : 0;
 
6285
    $config->{'GeometryOverride'} = 
 
6286
      $widgets->{'prefs'}->get_widget('entryPrefWindowOffset')->get_text();
 
6287
    my $set = "";
 
6288
 
 
6289
    foreach my $value ("Top", "Bottom", "Centre") {
 
6290
        if (
 
6291
            fromutf(gettext($value)) eq ucfirst(
 
6292
                $widgets->{'prefs'}->get_widget('comboPrefVertical')
 
6293
                  ->get_active_text()
 
6294
            )
 
6295
          )
 
6296
        {
 
6297
            $set = $value;
 
6298
        }
 
6299
    }
 
6300
    if ($set eq "") {
 
6301
        $set =
 
6302
          $widgets->{'prefs'}->get_widget('comboPrefVertical')
 
6303
          ->get_active_text();
 
6304
    }
 
6305
    $config->{'VerticalLocation'} = $set;
 
6306
    $set = "";
 
6307
    my $set2 = "";
 
6308
    foreach my $value ("Left", "Right", "Centre") {
 
6309
        if (
 
6310
            fromutf(gettext($value)) eq ucfirst(
 
6311
                $widgets->{'prefs'}->get_widget('comboPrefHorizontal')
 
6312
                  ->get_active_text()
 
6313
            )
 
6314
          )
 
6315
        {
 
6316
            $set = $value;
 
6317
        }
 
6318
        if (
 
6319
            fromutf(gettext($value)) eq ucfirst(
 
6320
                $widgets->{'prefs'}->get_widget('comboPrefJustification')
 
6321
                  ->get_active_text()
 
6322
            )
 
6323
          )
 
6324
        {
 
6325
            $set2 = $value;
 
6326
        }
 
6327
    }
 
6328
    if ($set eq "") {
 
6329
        $set =
 
6330
          $widgets->{'prefs'}->get_widget('comboPrefHorizontal')
 
6331
          ->get_active_text();
 
6332
    }
 
6333
    if ($set2 eq "") {
 
6334
        $set2 =
 
6335
          $widgets->{'prefs'}->get_widget('comboPrefJustification')
 
6336
          ->get_active_text();
 
6337
    }
 
6338
    $config->{'HorizontalLocation'} = $set;
 
6339
    $config->{'Justification'}      = $set2;
 
6340
    $set = "";
 
6341
    foreach my $value ("Fade", "None") {
 
6342
        if (
 
6343
            fromutf(gettext($value)) eq ucfirst(
 
6344
                $widgets->{'prefs'}->get_widget('comboPrefDefTrans')
 
6345
                  ->get_active_text()
 
6346
            )
 
6347
          )
 
6348
        {
 
6349
            $set = $value;
 
6350
        }
 
6351
    }
 
6352
    if ($set eq "") {
 
6353
        $set =
 
6354
          $widgets->{'prefs'}->get_widget('comboPrefDefTrans')
 
6355
          ->get_active_text();
 
6356
    }
 
6357
    $config->{'DefaultTransition'} = $set;
 
6358
 
 
6359
    $config->{'BGImage'} =
 
6360
      $widgets->{'prefs'}->get_widget('imagePrefBG')->{user_data};
 
6361
    $config->{'SpecialSong'} =
 
6362
      $widgets->{'prefs'}->get_widget('entryPrefSpecialSong')->get_text();
 
6363
    $config->{'SpecialImage'} =
 
6364
      $widgets->{'prefs'}->get_widget('entryPrefSpecialImage')->get_text();
 
6365
    $config->{'SpecialBack'} =
 
6366
      $widgets->{'prefs'}->get_widget('entryPrefSpecialBack')->get_text();
 
6367
    $config->{'ImageDirectory'} =
 
6368
      $widgets->{'prefs'}->get_widget('filePrefSpecialImagedir')->get_label();
 
6369
    $config->{'ImageDirectory'} =~ s/^\~/$ENV{'HOME'}/;
 
6370
    $config->{'BGDirectory'} =
 
6371
      $widgets->{'prefs'}->get_widget('filePrefSpecialBGdir')->get_label();
 
6372
    $config->{'BGDirectory'} =~ s/^\~/$ENV{'HOME'}/;
 
6373
    $config->{'TrayIcons'} = $config->{'TrayIcons'};
 
6374
 
 
6375
    my $db_changed = FALSE;
 
6376
    if ($widgets->{'prefs'}->get_widget('radioPrefDBMysql')->get_active()) {
 
6377
        if ($config->{'DatabaseType'} ne "mysql") {
 
6378
            $db_changed = TRUE;
 
6379
        }
 
6380
        $config->{'DatabaseType'} = "mysql";
 
6381
    } else {
 
6382
        if ($config->{'DatabaseType'} ne "SQLite") {
 
6383
            $db_changed = TRUE;
 
6384
        }
 
6385
        $config->{'DatabaseType'} = "SQLite";
 
6386
    }
 
6387
 
 
6388
    $config->{'DefBible'} =
 
6389
      $widgets->{'prefs'}->get_widget('entryPrefBible')->get_text();
 
6390
 
 
6391
    save_state();
 
6392
    write_config(FALSE);
 
6393
 
 
6394
    if ($db_changed) {
 
6395
        db_restart();
 
6396
    }
 
6397
 
 
6398
    init_preview();
 
6399
    init_miniview();
 
6400
 
 
6401
    preview_display("reconfig", "", "", "MINI");
 
6402
    update_display("reconfig", "", "");
 
6403
    preview_display("display", "current", "", "MINI");
 
6404
    update_display("display", "current", "");
 
6405
}
 
6406
 
 
6407
#***
 
6408
 
 
6409
#****f* lyricue/write_config
 
6410
# NAME
 
6411
#   write_config
 
6412
# SYNOPSIS
 
6413
#   write_config()
 
6414
# FUNCTION
 
6415
#   Writing preferences
 
6416
# INPUTS
 
6417
# OUTPUT
 
6418
# SOURCE
 
6419
#
 
6420
sub write_config {
 
6421
    my ($dbonly) = @_;
 
6422
    debug("Writing preferences");
 
6423
 
 
6424
    # Backup config table
 
6425
    my $query = "DELETE FROM config_old";
 
6426
    my $sth = $lyricDbh->prepare($query)
 
6427
      || display_fatal($errorcodes->{'sqlprepare'},
 
6428
        $! . "\nSQL: " . $query);
 
6429
    my $rv = $sth->execute
 
6430
      || display_fatal($errorcodes->{'sqlexecute'},
 
6431
        $! . "\nSQL: " . $query);
 
6432
    $query = "INSERT config_old SELECT * from config";
 
6433
    $sth = $lyricDbh->prepare($query)
 
6434
      || display_fatal($errorcodes->{'sqlprepare'},
 
6435
        $! . "\nSQL: " . $query);
 
6436
    $rv = $sth->execute
 
6437
      || display_fatal($errorcodes->{'sqlexecute'},
 
6438
        $! . "\nSQL: " . $query);
 
6439
    $query = "DELETE FROM config";
 
6440
    $sth = $lyricDbh->prepare($query)
 
6441
      || display_fatal($errorcodes->{'sqlprepare'},
 
6442
        $! . "\nSQL: " . $query);
 
6443
    $rv = $sth->execute
 
6444
      || display_fatal($errorcodes->{'sqlexecute'},
 
6445
        $! . "\nSQL: " . $query);
 
6446
 
 
6447
    if (!$dbonly) {
 
6448
        # Backup file
 
6449
        unlink $globals->{'configfile'} . ".bak";
 
6450
        rename($globals->{'configfile'}, $globals->{'configfile'} . ".bak");
 
6451
    
 
6452
        open(CONFIG, ">$globals->{'configfile'}")
 
6453
          || display_fatal($errorcodes->{'fileopenwrite'}, $!);
 
6454
        binmode(CONFIG, ":utf8");
 
6455
    }
 
6456
 
 
6457
    foreach (sort keys(%$config)) {
 
6458
        if ((!/^Bible/) && (!/^App/) && (!/^LoopText/)) {
 
6459
            if (!$dbonly) {
 
6460
                print CONFIG $_ . " = " . $config->{$_} . "\n";
 
6461
            }
 
6462
            $query = "INSERT INTO config ( config_key, config_value ) VALUES (\"".$_."\", \"".$config->{$_}."\")";
 
6463
            qdebug($query);
 
6464
            $sth = $lyricDbh->prepare($query)
 
6465
              || display_fatal($errorcodes->{'sqlprepare'},
 
6466
                $! . "\nSQL: " . $query);
 
6467
            $rv = $sth->execute
 
6468
              || display_fatal($errorcodes->{'sqlexecute'},
 
6469
                $! . "\nSQL: " . $query);
 
6470
        }
 
6471
    }
 
6472
    foreach (0 .. $config->{'AppCount'} - 1) {
 
6473
        if (!$dbonly) {
 
6474
            print CONFIG "App = " . $config->{'App'}[$_] . "\n";
 
6475
        }
 
6476
        $query = "INSERT INTO config ( config_key, config_value ) VALUES ( \"App\", \"".$config->{'App'}[$_]."\")";
 
6477
        qdebug($query);
 
6478
        $sth = $lyricDbh->prepare($query)
 
6479
          || display_fatal($errorcodes->{'sqlprepare'},
 
6480
            $! . "\nSQL: " . $query);
 
6481
        $rv = $sth->execute
 
6482
          || display_fatal($errorcodes->{'sqlexecute'},
 
6483
            $! . "\nSQL: " . $query);
 
6484
    }
 
6485
    if (!$dbonly) {
 
6486
        close CONFIG;
 
6487
        preview_display("reconfig", "", "", "MINI");
 
6488
        update_display("reconfig", "", "");
 
6489
        update_display("status", "", "");
 
6490
    }
 
6491
}
 
6492
 
 
6493
#***
 
6494
 
 
6495
# Add the filename to the playlist
 
6496
#***
 
6497
 
 
6498
#****f* lyricue/file_ok_sel
 
6499
# NAME
 
6500
#   file_ok_sel
 
6501
# SYNOPSIS
 
6502
#   file_ok_sel($widget, $filexml)
 
6503
# FUNCTION
 
6504
#   Add filename to playlist
 
6505
# INPUTS
 
6506
#   $widget -
 
6507
#    $filexml -
 
6508
# OUTPUT
 
6509
# SOURCE
 
6510
#
 
6511
sub file_ok_sel {
 
6512
    my ($widget, $filexml) = @_;
 
6513
    debug("Add filename to playlist");
 
6514
    my $main_playlist =
 
6515
      $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
6516
    my @filenames = $filexml->get_widget('dialogFileChooser')->get_filenames;
 
6517
    foreach (@filenames) {
 
6518
        do_add_file($_, $main_playlist);
 
6519
    }
 
6520
    update_playlist();
 
6521
    close_dialog($widget);
 
6522
}
 
6523
 
 
6524
#***
 
6525
 
 
6526
#  Add the filename to the playlist
 
6527
#***
 
6528
 
 
6529
#****f* lyricue/do_add_file
 
6530
# NAME
 
6531
#   do_add_file
 
6532
# SYNOPSIS
 
6533
#   do_add_file($file, $playlist)
 
6534
# FUNCTION
 
6535
#   do_add_file: file=
 
6536
# INPUTS
 
6537
#   $file -
 
6538
#    $playlist -
 
6539
# OUTPUT
 
6540
# SOURCE
 
6541
#
 
6542
sub do_add_file {
 
6543
    my ($file, $playlist) = @_;
 
6544
    debug("do_add_file: file=" . $file);
 
6545
    if ($globals->{'unoconv'} ne "") {
 
6546
        if (($file =~ /ppt$/i) || ($file =~ /odp$/i) || ($file =~ /pptx$/)) {
 
6547
 
 
6548
            # Add presentation
 
6549
            debug("Adding ppt/odp presentation");
 
6550
            my $dialog = Gtk2::MessageDialog->new(
 
6551
                $widgets->{'main'}->get_widget('windowMain'),
 
6552
                'destroy-with-parent', 'info', 'none',
 
6553
                gettext("Importing presentation"));
 
6554
            $dialog->show_all();
 
6555
            do_pending();
 
6556
            my $target = $file;
 
6557
            $target =~ s/^.*\///g;
 
6558
            $target =~ s/'//g; # fix handling of ' in filename
 
6559
 
 
6560
            # Add 'ppt' to end of 'pptx' files so unoconv will handle them
 
6561
            if ($target =~ /pptx$/ ) {
 
6562
                $target .= ".ppt";
 
6563
            }
 
6564
            my $tmpdir = tempdir("lyricue-XXXX", DIR => "/var/tmp", CLEANUP => 0);
 
6565
            my $command =
 
6566
              "cp \"" . $file . "\" \"" . $tmpdir . "/" . $target . "\"";
 
6567
            debug($command);
 
6568
            system($command);
 
6569
            do_pending();
 
6570
 
 
6571
            my $try=0;
 
6572
            while ($try <=2) {
 
6573
                $try++;
 
6574
                $command =
 
6575
                    $globals->{'unoconv'}
 
6576
                  . " -f html \""
 
6577
                  . $tmpdir . "/"
 
6578
                  . $target . "\"";
 
6579
                debug($command);
 
6580
                system($command);
 
6581
                do_pending();
 
6582
    
 
6583
                # Import directory
 
6584
                my $ret = opendir DIR, $tmpdir;
 
6585
                if ($ret) {
 
6586
                    foreach my $filename (sort readdir(DIR)) {
 
6587
                        if (($filename =~ /\.html$/) || ($filename eq $target)) {
 
6588
                            unlink $tmpdir . "/" . $filename;
 
6589
                        } elsif ($filename =~ /^img.*jpg$/) {
 
6590
                            my $count = $filename;
 
6591
                            $count =~ s/^.*[^0-9]([0-9]*)\..*$/$1/g;
 
6592
                            $count++;
 
6593
                            rename $tmpdir . "/" . $filename,
 
6594
                              $tmpdir . "/page_" . $count . ".jpg";
 
6595
                            $try = 10; # Don't retry
 
6596
                        }
 
6597
                    }
 
6598
                    closedir DIR;
 
6599
                }
 
6600
                $command =
 
6601
                  "rm " . $tmpdir . "/*.html \"" . $tmpdir . "/" . $target . "\"";
 
6602
                debug($command);
 
6603
                system($command);
 
6604
            }
 
6605
 
 
6606
            do_add_directory($tmpdir, $target);
 
6607
            $dialog->destroy;
 
6608
            return;
 
6609
        }
 
6610
    }
 
6611
    if ($globals->{'convert'} ne "") {
 
6612
        if (($file =~ /pdf$/)) {
 
6613
 
 
6614
            # Add pdf file
 
6615
            my $target = $file;
 
6616
            debug("Adding pdf presentation");
 
6617
            my $dialog = Gtk2::MessageDialog->new(
 
6618
                $widgets->{'main'}->get_widget('windowMain'),
 
6619
                'destroy-with-parent', 'info', 'none',
 
6620
                gettext("Importing presentation"));
 
6621
            $dialog->show_all();
 
6622
            do_pending();
 
6623
            $target =~ s/^.*\///g;
 
6624
            $target =~ s/'//g; # fix handling of ' in filename
 
6625
            my $tmpdir = tempdir("lyricue-XXXX", DIR => "/var/tmp", CLEANUP => 0);
 
6626
            my $command =
 
6627
              $globals->{'convert'} . " \"" . $file . "\" " . $tmpdir . "/temp.jpg";
 
6628
            debug($command);
 
6629
            system($command);
 
6630
 
 
6631
            # Clean up directory
 
6632
            my $ret = opendir DIR, $tmpdir;
 
6633
            debug($tmpdir);
 
6634
            if ($ret) {
 
6635
                foreach my $filename (sort readdir(DIR)) {
 
6636
                    debug($filename);
 
6637
                    if ($filename =~ /^temp.*jpg$/) {
 
6638
                        my $count = $filename;
 
6639
                        $count =~ s/^.*([0-9]+).*$/$1/g;
 
6640
                        $count++;
 
6641
                        rename $tmpdir . "/" . $filename,
 
6642
                          $tmpdir . "/page_" . $count . ".jpg";
 
6643
                    }
 
6644
                }
 
6645
                closedir DIR;
 
6646
            }
 
6647
            do_add_directory($tmpdir, $target);
 
6648
            $dialog->destroy;
 
6649
            return;
 
6650
        }
 
6651
    }
 
6652
    if (($file ne "") && ((-r $file) || ($file =~ /:\/\//))) {
 
6653
 
 
6654
        # Find next playorder
 
6655
        my $playorder = 1;
 
6656
        my $query     = "SELECT MAX(playorder) FROM playlist";
 
6657
        qdebug($query);
 
6658
        my $sth = $lyricDbh->prepare($query)
 
6659
          || display_fatal($errorcodes->{'sqlprepare'},
 
6660
            $! . "\nSQL: " . $query);
 
6661
        my $rv = $sth->execute
 
6662
          || display_fatal($errorcodes->{'sqlexecute'},
 
6663
            $! . "\nSQL: " . $query);
 
6664
        my @row;
 
6665
        if (@row = $sth->fetchrow_array()) {
 
6666
 
 
6667
            if ($row[0]) {
 
6668
                $playorder = $row[0] + 1;
 
6669
            }
 
6670
        }
 
6671
 
 
6672
        # Add item to playlist
 
6673
        my $main_playlist =
 
6674
          $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
6675
        $query =
 
6676
            "INSERT INTO playlist (playorder, playlist, type, data) VALUES ("
 
6677
          . $playorder . ", "
 
6678
          . $playlist
 
6679
          . ", \"file\", \""
 
6680
          . $file . "\")";
 
6681
        qdebug($query);
 
6682
        $sth = $lyricDbh->prepare($query)
 
6683
          || display_fatal($errorcodes->{'sqlprepare'},
 
6684
            $! . "\nSQL: " . $query);
 
6685
        $rv = $sth->execute
 
6686
          || display_fatal($errorcodes->{'sqlexecute'},
 
6687
            $! . "\nSQL: " . $query);
 
6688
    }
 
6689
}
 
6690
 
 
6691
#***
 
6692
 
 
6693
#****f* lyricue/create_sublist
 
6694
# NAME
 
6695
#   create_sublist
 
6696
# SYNOPSIS
 
6697
#   create_sublist ()
 
6698
# FUNCTION
 
6699
#   Display the 'new sublist' dialog
 
6700
# INPUTS
 
6701
# OUTPUT
 
6702
#   Dialog
 
6703
# SOURCE
 
6704
#
 
6705
sub create_sublist {
 
6706
    my ($widget) = @_;
 
6707
    debug("Create sublist");
 
6708
    create_dialogSublist($widget);
 
6709
}
 
6710
 
 
6711
#***
 
6712
 
 
6713
#***
 
6714
 
 
6715
#****f* lyricue/new_sublist_from_xml
 
6716
# NAME
 
6717
#   new_sublist_from_xml
 
6718
# SYNOPSIS
 
6719
#   new_sublist_from_xml($widget, $sublistxml)
 
6720
# FUNCTION
 
6721
#
 
6722
# INPUTS
 
6723
#   $widget -
 
6724
#    $sublistxml -
 
6725
# OUTPUT
 
6726
# SOURCE
 
6727
#
 
6728
sub new_sublist_from_xml {
 
6729
    my ($widget, $sublistxml) = @_;
 
6730
    new_sublist($sublistxml->get_widget('entryPromptE')->get_text());
 
6731
    close_dialog($sublistxml->get_widget('dialogPromptEntry'));
 
6732
}
 
6733
 
 
6734
#***
 
6735
 
 
6736
#****f* lyricue/new_sublist
 
6737
# NAME
 
6738
#   new_sublist
 
6739
# SYNOPSIS
 
6740
#   new_sublist ()
 
6741
# FUNCTION
 
6742
#   Create sublist entry in database
 
6743
# INPUTS
 
6744
# OUTPUT
 
6745
#   Closes sublist dialog
 
6746
#   Adds sublist to current playlist
 
6747
#   Calls update_playlist to refresh playlist
 
6748
#   Returns sublist id
 
6749
# SOURCE
 
6750
#
 
6751
sub new_sublist {
 
6752
    my ($sublist) = @_;
 
6753
    debug("new sublist");
 
6754
    my ($row, $sth, $rv, $parentid);
 
6755
 
 
6756
    #Determine the id of the main playlist
 
6757
    $parentid =
 
6758
      $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
6759
 
 
6760
    #Find out the id for the playlists table
 
6761
    my $playlistsid = 1;
 
6762
    $query = "SELECT MAX(id) FROM playlists";
 
6763
    $sth   = $lyricDbh->prepare($query)
 
6764
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
6765
    $rv = $sth->execute
 
6766
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
6767
    if ($row = $sth->fetchrow_hashref()) {
 
6768
        if ($row->{'MAX(id)'}) {
 
6769
            $playlistsid = $row->{'MAX(id)'} + 1;
 
6770
        }
 
6771
    }
 
6772
 
 
6773
    #Find out the playorder for the playlist table
 
6774
    my $playorder = 1;
 
6775
    $query = "SELECT MAX(playorder) FROM playlist";
 
6776
    $sth   = $lyricDbh->prepare($query)
 
6777
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
6778
    $rv = $sth->execute
 
6779
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
6780
    if ($row = $sth->fetchrow_hashref()) {
 
6781
        if ($row->{'MAX(playorder)'}) {
 
6782
            $playorder = $row->{'MAX(playorder)'} + 1;
 
6783
        }
 
6784
    }
 
6785
 
 
6786
    #create sublist playlist
 
6787
    $query =
 
6788
        "INSERT INTO playlists (id, title, ref) VALUES ("
 
6789
      . $playlistsid . " ,'"
 
6790
      . $sublist . "','')";
 
6791
    $sth = $lyricDbh->prepare($query)
 
6792
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
6793
    $rv = $sth->execute
 
6794
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
6795
 
 
6796
    #link sublist to main playlist
 
6797
    $query =
 
6798
      "INSERT INTO playlist (playorder,playlist,type,data,transition) VALUES ("
 
6799
      . $playorder . ", "
 
6800
      . $parentid
 
6801
      . ", \"sub\","
 
6802
      . $playlistsid . " ,0)";
 
6803
    qdebug($query);
 
6804
    $sth = $lyricDbh->prepare($query)
 
6805
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
6806
    $rv = $sth->execute
 
6807
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
6808
 
 
6809
    update_playlist();
 
6810
    return $playlistsid;
 
6811
}
 
6812
 
 
6813
#***
 
6814
 
 
6815
#****f* lyricue/move_item_to_sublist
 
6816
# NAME
 
6817
#   move_item_to_sublist
 
6818
# SYNOPSIS
 
6819
#   move_item_to_sublist ($item, $sublistid)
 
6820
# FUNCTION
 
6821
#   Move a playlist item to become a child of a sublist
 
6822
# INPUTS
 
6823
#   $item - playorder of the item to be moved
 
6824
#   $sublistid - id of the sublist the item is to be a child of
 
6825
# OUTPUT
 
6826
#   Alters database entry for playlist item to make sublist its parent
 
6827
#   Calls update_playlist to refresh playlist
 
6828
# SOURCE
 
6829
#
 
6830
sub move_item_to_sublist {
 
6831
    my ($widget, $sublistid) = @_;
 
6832
    debug("move item to sublist");
 
6833
    my $selection =
 
6834
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
6835
    my ($model, $iter) = $selection->get_selected;
 
6836
    if ($iter) {
 
6837
        my $plitem = $model->get($iter, 2);
 
6838
        debug("Moving item " . $plitem . " to playlist " . $sublistid);
 
6839
 
 
6840
        my $query =
 
6841
            "UPDATE playlist SET playlist = "
 
6842
          . $sublistid
 
6843
          . " WHERE playorder = "
 
6844
          . $plitem;
 
6845
        qdebug($query);
 
6846
        my $sth = $lyricDbh->prepare($query)
 
6847
          || display_fatal($errorcodes->{'sqlprepare'},
 
6848
            $! . "\nSQL: " . $query);
 
6849
        my $rv = $sth->execute
 
6850
          || display_fatal($errorcodes->{'sqlexecute'},
 
6851
            $! . "\nSQL: " . $query);
 
6852
 
 
6853
        update_playlist();
 
6854
    }
 
6855
}
 
6856
 
 
6857
#***
 
6858
 
 
6859
#****f* lyricue/find_more_children
 
6860
# NAME
 
6861
#   find_more_children
 
6862
# SYNOPSIS
 
6863
#   find_more_children ($parentid)
 
6864
# FUNCTION
 
6865
#   Find all the children of a given playlist item
 
6866
# INPUTS
 
6867
#   $parentid - The playlist id of the 'parent'
 
6868
# OUTPUT
 
6869
#   Returns an array of playlist ids representing children of the parent
 
6870
# SOURCE
 
6871
#
 
6872
sub find_more_children {
 
6873
    my ($parentid) = @_;
 
6874
    debug("Looking for children");
 
6875
    my @kiddies;
 
6876
 
 
6877
    my $query =
 
6878
        "SELECT data FROM playlist WHERE playlist = "
 
6879
      . $parentid
 
6880
      . " AND type = 'sub'";
 
6881
 
 
6882
    qdebug($query);
 
6883
    my $sth = $lyricDbh->prepare($query)
 
6884
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
6885
    my $rv = $sth->execute
 
6886
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
6887
    while ($row = $sth->fetchrow_hashref()) {
 
6888
        @kiddies = (@kiddies, $row->{'data'});
 
6889
        @kiddies = (@kiddies, find_more_children($row->{'data'}));
 
6890
    }
 
6891
 
 
6892
    return @kiddies;
 
6893
}
 
6894
 
 
6895
#***
 
6896
 
 
6897
#****f* lyricue/associate_bg
 
6898
# NAME
 
6899
#   associate_bg
 
6900
# SYNOPSIS
 
6901
#   associate_bg ($imagefile)
 
6902
# FUNCTION
 
6903
#   To associate the an background image with a playlist item
 
6904
# INPUTS
 
6905
#   $imagefile - file path & name of image to associate with item
 
6906
# OUTPUT
 
6907
#   Stores image name, playlist order pair in db 'associations' table
 
6908
# SOURCE
 
6909
#
 
6910
sub associate_bg {
 
6911
    my ($imagefile) = @_;
 
6912
 
 
6913
    debug("Associating bg " . $imagefile . " with " . $ASSOCIATE[0]);
 
6914
 
 
6915
    my $query = "DELETE FROM associations WHERE playlist=" . $ASSOCIATE[0];
 
6916
    my $sth   = $lyricDbh->prepare($query)
 
6917
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
6918
    $sth->execute
 
6919
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
6920
 
 
6921
    $query =
 
6922
"INSERT INTO associations (id,playlist,imagename, absoluteparent) VALUES(0, "
 
6923
      . $ASSOCIATE[0] . ", '"
 
6924
      . $imagefile . "',"
 
6925
      . $ASSOCIATE[1] . ")";
 
6926
    $sth = $lyricDbh->prepare($query)
 
6927
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
6928
    $sth->execute
 
6929
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
6930
 
 
6931
    update_playlist();
 
6932
    @ASSOCIATE = ();
 
6933
}
 
6934
 
 
6935
#***
 
6936
 
 
6937
#****f* lyricue/prepare_for_association
 
6938
# NAME
 
6939
#   prepare_for_association
 
6940
# SYNOPSIS
 
6941
#   prepare_for_association  ()
 
6942
# FUNCTION
 
6943
#   Set up the ASSOCIATE array
 
6944
# INPUTS
 
6945
# OUTPUT
 
6946
#   Updated ASSOCIATE array
 
6947
# SOURCE
 
6948
#
 
6949
sub prepare_for_association {
 
6950
    my ($widget) = @_;
 
6951
    debug("prepare for association");
 
6952
    my $selection =
 
6953
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
6954
    my ($model, $iter) = $selection->get_selected;
 
6955
    if ($iter) {
 
6956
 
 
6957
        # Change ASSOCIATE array to contain playorder of list item,
 
6958
        # main playlist id
 
6959
        @ASSOCIATE = (
 
6960
            $model->get($iter, 2),
 
6961
            $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data}
 
6962
        );
 
6963
        debug("Waiting for an image click in order to associate");
 
6964
    }
 
6965
 
 
6966
}
 
6967
 
 
6968
#***
 
6969
 
 
6970
#****f* lyricue/disassociate_bg
 
6971
# NAME
 
6972
#   disassociate_bg
 
6973
# SYNOPSIS
 
6974
#   disassociate_bg ()
 
6975
# FUNCTION
 
6976
#   To disssociate the current background image from a playlist item
 
6977
# INPUTS
 
6978
# OUTPUT
 
6979
#   If an association record exists in db, it is removed.
 
6980
# SOURCE
 
6981
#
 
6982
sub disassociate_bg {
 
6983
    my ($widget) = @_;
 
6984
 
 
6985
    my $selection =
 
6986
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
6987
    my ($model, $iter) = $selection->get_selected;
 
6988
    if ($iter) {
 
6989
        debug("Disassociating image from " . $model->get($iter, 2));
 
6990
        my $query =
 
6991
          "DELETE FROM associations WHERE playlist=" . $model->get($iter, 2);
 
6992
 
 
6993
        my $sth = $lyricDbh->prepare($query)
 
6994
          || display_fatal($errorcodes->{'sqlprepare'},
 
6995
            $! . "\nSQL: " . $query);
 
6996
        $sth->execute
 
6997
          || display_fatal($errorcodes->{'sqlexecute'},
 
6998
            $! . "\nSQL: " . $query);
 
6999
 
 
7000
        update_playlist();
 
7001
    }
 
7002
}
 
7003
 
 
7004
#***
 
7005
 
 
7006
#****f* lyricue/clear_associations
 
7007
# NAME
 
7008
#   clear_associations
 
7009
# SYNOPSIS
 
7010
#   clear_associations ()
 
7011
# FUNCTION
 
7012
#   Clears all image-playlist item associations linked to current playlist
 
7013
# INPUTS
 
7014
# OUTPUT
 
7015
#   Clears the associations table in lyricDb
 
7016
# SOURCE
 
7017
#
 
7018
sub clear_associations {
 
7019
    my ($widget) = @_;
 
7020
    debug("Disassociating images from all playlist items");
 
7021
    my $parentid =
 
7022
      $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
7023
 
 
7024
    my $query = "DELETE FROM associations WHERE absoluteparent=" . $parentid;
 
7025
    qdebug($query);
 
7026
    my $sth = $lyricDbh->prepare($query)
 
7027
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
7028
    $sth->execute
 
7029
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
7030
 
 
7031
    update_playlist();
 
7032
}
 
7033
 
 
7034
#***
 
7035
 
 
7036
#***
 
7037
 
 
7038
#****f* lyricue/init_mainWindow
 
7039
# NAME
 
7040
#   init_mainWindow
 
7041
# SYNOPSIS
 
7042
#   init_mainWindow()
 
7043
# FUNCTION
 
7044
#   Initializing main window
 
7045
# INPUTS
 
7046
# OUTPUT
 
7047
# SOURCE
 
7048
#
 
7049
sub init_mainWindow {
 
7050
    debug("Initializing main window");
 
7051
 
 
7052
    # Setup file chooser
 
7053
 
 
7054
    # Setup bible browser
 
7055
    biblebrowser_init();
 
7056
 
 
7057
    # Load bg thumbnails
 
7058
    my $scaled = create_pixbuf(
 
7059
        $config->{'BGImage'},
 
7060
        $globals->{'icon_width'},
 
7061
        $globals->{'icon_height'}
 
7062
    );
 
7063
    if ($scaled) {
 
7064
        my $pixmap = Gtk2::Image->new_from_pixbuf($scaled);
 
7065
        $widgets->{'pixmapCurr'} = $pixmap;
 
7066
        $widgets->{'buttonCurr'} = new Gtk2::Button();
 
7067
        $widgets->{'buttonCurr'}->add($widgets->{'pixmapCurr'});
 
7068
        $widgets->{'buttonCurr'}->{user_data} = $config->{'BGImage'};
 
7069
        $widgets->{'main'}->get_widget('vboxCurrentBG')
 
7070
          ->pack_start($widgets->{'buttonCurr'}, FALSE, FALSE, 0);
 
7071
        $widgets->{'pixmapCurr'}->show();
 
7072
        $widgets->{'buttonCurr'}->show();
 
7073
        $widgets->{'buttonCurr'}
 
7074
          ->signal_connect("clicked", "backdrop_preview_clicked");
 
7075
    }
 
7076
    $scaled = create_pixbuf(
 
7077
        $config->{'BGImage'},
 
7078
        $globals->{'icon_width'},
 
7079
        $globals->{'icon_height'}
 
7080
    );
 
7081
    if ($scaled) {
 
7082
        my $pixmap = Gtk2::Image->new_from_pixbuf($scaled);
 
7083
        $widgets->{'pixmapPrev'} = $pixmap;
 
7084
        $widgets->{'buttonPrev'} = new Gtk2::Button();
 
7085
        $widgets->{'buttonPrev'}->add($widgets->{'pixmapPrev'});
 
7086
        $widgets->{'buttonPrev'}->{user_data} = $config->{'BGImage'};
 
7087
        $widgets->{'main'}->get_widget('vboxPrevBG')
 
7088
          ->pack_start($widgets->{'buttonPrev'}, FALSE, FALSE, 0);
 
7089
        $widgets->{'pixmapPrev'}->show();
 
7090
        $widgets->{'buttonPrev'}->show();
 
7091
        $widgets->{'buttonPrev'}
 
7092
          ->signal_connect("clicked", "backdrop_preview_clicked");
 
7093
    }
 
7094
 
 
7095
    # Update list of background/image directories
 
7096
    bgdir_list("bg");
 
7097
    bgdir_list("img");
 
7098
 
 
7099
    # Setup Available list and blank playlist
 
7100
    $widgets->{'main'}->get_widget('treeAvailable')->set_enable_search(TRUE);
 
7101
    $widgets->{'main'}->get_widget('treeAvailable')->set_search_column(0);
 
7102
    update_available();
 
7103
    $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data} = 0;
 
7104
 
 
7105
    # Update the bible menu
 
7106
    load_biblemenu();
 
7107
 
 
7108
    # Update the application menu
 
7109
    my $menutop2 = Gtk2::Menu->new();
 
7110
    my $group2   = 0;
 
7111
    my @appMenu  = ();
 
7112
    foreach (0 .. $config->{'AppCount'} - 1) {
 
7113
        my $app = $config->{'App'}[$_];
 
7114
        $app =~ s/^(.*?);.*$/$1/g;
 
7115
 
 
7116
        $appMenu[$_] = Gtk2::MenuItem->new_with_label($app);
 
7117
        $appMenu[$_]->signal_connect("activate", "execute_app", $_);
 
7118
        $appMenu[$_]->show;
 
7119
        $menutop2->append($appMenu[$_]);
 
7120
    }
 
7121
    $widgets->{'main'}->get_widget('applications1')->set_submenu($menutop2);
 
7122
 
 
7123
    # DRAG and DROP
 
7124
    $widgets->{'main'}->get_widget('treeAvailable')
 
7125
      ->drag_source_set(['button1_mask'], ['copy'],
 
7126
        {'target' => "STRING", 'flags' => [], 'info' => 0});
 
7127
    $widgets->{'main'}->get_widget('iconviewBack')
 
7128
      ->drag_source_set(['button1_mask'], ['copy'],
 
7129
        {'target' => "STRING", 'flags' => [], 'info' => 0});
 
7130
    $widgets->{'main'}->get_widget('iconviewImage')
 
7131
      ->drag_source_set(['button1_mask'], ['copy'],
 
7132
        {'target' => "STRING", 'flags' => [], 'info' => 0});
 
7133
    $widgets->{'main'}->get_widget('treePlaylist')->drag_source_set(
 
7134
        'button1_mask',
 
7135
        ['move', 'copy'],
 
7136
        {'target' => "STRING", 'flags' => [], 'info' => 0}
 
7137
    );
 
7138
    $widgets->{'main'}->get_widget('treePlaylist')->drag_dest_set(
 
7139
        'all',
 
7140
        ['copy', 'move'],
 
7141
        {'target' => "STRING", 'flags' => [], 'info' => 0}
 
7142
    );
 
7143
 
 
7144
    init_preview();
 
7145
    init_miniview();
 
7146
 
 
7147
    # Show the window finally
 
7148
    $widgets->{'main'}->get_widget('windowMain')->show;
 
7149
    if (!(defined($globals->{'run_windowed'}) && ($globals->{'run_windowed'})))
 
7150
    {
 
7151
        $widgets->{'main'}->get_widget('windowMain')->maximize;
 
7152
    }
 
7153
 
 
7154
    do_pending();
 
7155
 
 
7156
    # Adjust frame sizes
 
7157
    my ($width, $height) =
 
7158
      $widgets->{'main'}->get_widget('windowMain')->get_size();
 
7159
    if ((defined $config->{'FrameRight'}) && ($config->{'FrameRight'} != 0)) {
 
7160
        $widgets->{'main'}->get_widget('hpanedMainRight')
 
7161
          ->set_position($config->{'FrameRight'});
 
7162
        $widgets->{'main'}->get_widget('hpanedMainLeft')
 
7163
          ->set_position($config->{'FrameLeft'});
 
7164
    } else {
 
7165
        if ($globals->{'access'} =~ /p/) {
 
7166
            $widgets->{'main'}->get_widget('hpanedMainLeft')
 
7167
              ->set_position($width / 5 * 2);
 
7168
            $widgets->{'main'}->get_widget('hpanedMainRight')
 
7169
              ->set_position($width / 5 * 2);
 
7170
        }
 
7171
    }
 
7172
    if (defined $widgets->{'main'}->get_widget('vpanedMain')) {
 
7173
        if ((defined $config->{'FrameMain'}) && ($config->{'FrameMain'} != 0)) {
 
7174
            $widgets->{'main'}->get_widget('vpanedMain')
 
7175
              ->set_position($height - $config->{'FrameMain'});
 
7176
        } else {
 
7177
            $widgets->{'main'}->get_widget('vpanedMain')
 
7178
              ->set_position($height - 125);
 
7179
        }
 
7180
    }
 
7181
 
 
7182
    $globals->{'hand_cursor'} = Gtk2::Gdk::Cursor->new('hand2');
 
7183
    $globals->{'text_cursor'} = Gtk2::Gdk::Cursor->new('xterm');
 
7184
}
 
7185
 
 
7186
#***
 
7187
 
 
7188
#****f* lyricue/bgdir_list
 
7189
# NAME
 
7190
#   bgdir_list
 
7191
# SYNOPSIS
 
7192
#   bgdir_list($type)
 
7193
# FUNCTION
 
7194
#   Loading ".$type." directory list
 
7195
# INPUTS
 
7196
#   $type -
 
7197
# OUTPUT
 
7198
# SOURCE
 
7199
#
 
7200
sub bgdir_list {
 
7201
    my ($type) = @_;
 
7202
    debug("Loading " . $type . " directory list");
 
7203
    my $counter = 0;
 
7204
    my $cat     = "";
 
7205
    my $store   = Gtk2::ListStore->new('Glib::String', 'Glib::String');
 
7206
    my $iter    = $store->append;
 
7207
    $store->set($iter, 0, fromutf(gettext("Select Category")), 1, "");
 
7208
 
 
7209
    my ($combo, $special, $dirname);
 
7210
    if ($type eq "bg") {
 
7211
        $combo   = $widgets->{'main'}->get_widget('comboBGDirList');
 
7212
        $special = $config->{'SpecialBack'};
 
7213
        $dirname = $config->{'BGDirectory'};
 
7214
    } else {
 
7215
        $combo   = $widgets->{'main'}->get_widget('comboImgDirList');
 
7216
        $special = $config->{'SpecialImage'};
 
7217
        $dirname = $config->{'ImageDirectory'};
 
7218
    }
 
7219
    $combo->set_model($store);
 
7220
    my $renderer = Gtk2::CellRendererText->new;
 
7221
    $combo->pack_start($renderer, TRUE);
 
7222
    $combo->add_attribute($renderer, text => 0);
 
7223
    my @dbcategories  = ();
 
7224
    my @dircategories = ();
 
7225
    if ($special ne "") {
 
7226
        my ($type, $id) = split /;/, $special;
 
7227
        if (!defined $id) {
 
7228
            $id   = $type;
 
7229
            $type = "db";
 
7230
        }
 
7231
        $id = "00000" . $id;
 
7232
        if ($type eq "db") {
 
7233
            push @dbcategories, $id;
 
7234
        } else {
 
7235
            push @dircategories, $id;
 
7236
        }
 
7237
    }
 
7238
 
 
7239
    # Add categories from mediaDb
 
7240
    my $query =
 
7241
        "SELECT DISTINCT category FROM media WHERE type=\"" 
 
7242
      . $type
 
7243
      . "\" AND category !=\""
 
7244
      . $special
 
7245
      . "\" ORDER BY category";
 
7246
    my $sth = $mediaDbh->prepare($query)
 
7247
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
7248
    my $rv = $sth->execute
 
7249
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
7250
    while ($row = $sth->fetchrow_hashref()) {
 
7251
        push @dbcategories, $row->{'category'};
 
7252
    }
 
7253
 
 
7254
    foreach $cat (sort @dbcategories) {
 
7255
        $cat =~ s/^00000//g;
 
7256
        debug("Adding image dir button for db-" . $cat);
 
7257
        my $iter = $store->append;
 
7258
        $store->set($iter, 0, $cat, 1, "db");
 
7259
 
 
7260
    }
 
7261
 
 
7262
    # Add categories from directories
 
7263
    my (@files, $file);
 
7264
    $dirname =~ s/^\~/$ENV{'HOME'}/;
 
7265
    my $ret = opendir DIR, $dirname;
 
7266
    if ($ret) {
 
7267
        foreach $file (sort readdir(DIR)) {
 
7268
            if (!($file =~ /^\./) && (-d $dirname . "/" . $file)) {
 
7269
                push @dircategories, $file;
 
7270
            }
 
7271
        }
 
7272
        closedir DIR;
 
7273
    }
 
7274
 
 
7275
    # Add a blank entry for files not in a subdirectory
 
7276
    push @dircategories, "/";
 
7277
 
 
7278
    foreach $cat (sort @dircategories) {
 
7279
        $cat =~ s/^00000//g;
 
7280
        debug("Adding image dir button for dir-" . $cat);
 
7281
        my $iter = $store->append;
 
7282
        $store->set($iter, 0, $cat, 1, "dir");
 
7283
    }
 
7284
    $combo->set_active(0);
 
7285
}
 
7286
 
 
7287
#***
 
7288
 
 
7289
#****f* lyricue/bgdir_change
 
7290
# NAME
 
7291
#   bgdir_change
 
7292
# SYNOPSIS
 
7293
#   bgdir_change ($directory)
 
7294
# FUNCTION
 
7295
#   Clears background image preview buttions
 
7296
#   Calls imgdir_load to create new buttons
 
7297
# INPUTS
 
7298
#   $category - background image category to load images from
 
7299
#   $type - 'dir' or 'db'
 
7300
# OUTPUT
 
7301
#   Updated background preview buttons
 
7302
# SOURCE
 
7303
#
 
7304
sub bgdir_change {
 
7305
    my ($widget) = @_;
 
7306
    my $iter = $widget->get_active_iter;
 
7307
    my ($category, $type) = $widget->get_model->get($iter, 0, 1);
 
7308
    debug(  "Changing background source category to "
 
7309
          . $category
 
7310
          . " of type "
 
7311
          . $type);
 
7312
    debug("Destroying old images");
 
7313
    $globals->{'category'} = $category;
 
7314
    imgdir_load($widgets->{'main'}->get_widget('iconviewBack'),
 
7315
        "bg", $category, $type);
 
7316
    debug("Background category change complete");
 
7317
}
 
7318
 
 
7319
#***
 
7320
#****f* lyricue/imgdir_change
 
7321
# NAME
 
7322
#   imgdir_change
 
7323
# SYNOPSIS
 
7324
#   imgdir_change ($directory)
 
7325
# FUNCTION
 
7326
#   Clears image preview buttions
 
7327
#   Calls imgdir_load to create new buttons
 
7328
# INPUTS
 
7329
#   $category - image category to load images from
 
7330
#   $type - 'dir' or 'db'
 
7331
# OUTPUT
 
7332
#   Updated background preview buttons
 
7333
# SOURCE
 
7334
#
 
7335
sub imgdir_change {
 
7336
    my ($widget) = @_;
 
7337
    my $iter = $widget->get_active_iter;
 
7338
    my ($category, $type) = $widget->get_model->get($iter, 0, 1);
 
7339
    debug(
 
7340
        "Changing image source category to " . $category . " of type " . $type);
 
7341
    debug("Destroying old images");
 
7342
    $globals->{'category'} = $category;
 
7343
    imgdir_load($widgets->{'main'}->get_widget('iconviewImage'),
 
7344
        "img", $category, $type);
 
7345
    debug("Image category change complete");
 
7346
}
 
7347
 
 
7348
#***
 
7349
 
 
7350
#****f* lyricue/imgdir_load
 
7351
# NAME
 
7352
#   imgdir_load
 
7353
# SYNOPSIS
 
7354
#   imgdir_load ($category)
 
7355
# FUNCTION
 
7356
#   Create new preview pixmaps and buttons
 
7357
# INPUTS
 
7358
#   $category - background image category to load images from
 
7359
# OUTPUT
 
7360
#   Updated background preview buttons
 
7361
# SOURCE
 
7362
#
 
7363
sub imgdir_load {
 
7364
    my ($iconview, $section, $category, $type) = @_;
 
7365
    my $counter = 0;
 
7366
 
 
7367
    # update list of available backdrops
 
7368
    debug("Loading new preview images from: " . $type . ";" . $category);
 
7369
 
 
7370
    $iconview->hide();
 
7371
    my $store =
 
7372
      Gtk2::ListStore->new('Glib::String', 'Gtk2::Gdk::Pixbuf', 'Glib::String');
 
7373
    $iconview->set_model($store);
 
7374
    $iconview->set_text_column(0);
 
7375
    $iconview->set_pixbuf_column(1);
 
7376
 
 
7377
    if ($type eq "db") {
 
7378
        my $query =
 
7379
            "SELECT id,description FROM media WHERE category=\""
 
7380
          . $category
 
7381
          . "\" AND type=\"bg\" ORDER BY description";
 
7382
        my $sth = $mediaDbh->prepare($query)
 
7383
          || display_fatal($errorcodes->{'sqlprepare'},
 
7384
            $! . "\nSQL: " . $query);
 
7385
        my $rv = $sth->execute
 
7386
          || display_fatal($errorcodes->{'sqlexecute'},
 
7387
            $! . "\nSQL: " . $query);
 
7388
        while ($row = $sth->fetchrow_hashref()) {
 
7389
 
 
7390
            do_pending();
 
7391
            my $iter = $store->append;
 
7392
            $store->set($iter, 0, $row->{'description'}, 2,
 
7393
                $type . ";" . $row->{'id'});
 
7394
        }
 
7395
    } else {
 
7396
        my $dirname = "";
 
7397
        if ($section eq "bg") {
 
7398
            $dirname = $config->{'BGDirectory'} . "/" . $category;
 
7399
        } else {
 
7400
            $dirname = $config->{'ImageDirectory'} . "/" . $category;
 
7401
        }
 
7402
        my (@files, $file);
 
7403
        my $ret = opendir DIR, $dirname;
 
7404
        if ($ret) {
 
7405
            foreach $file (sort readdir(DIR)) {
 
7406
                if ((!($file =~ /^\./)) && (!(-d $dirname."/".$file))) {
 
7407
                    do_pending();
 
7408
                    my $iter = $store->append;
 
7409
                    $file = fromutf($file);
 
7410
                    $store->set($iter, 0, $file, 2,
 
7411
                        $type . ";" . $dirname . "/" . $file);
 
7412
                    print $type . ";" . $dirname . "/" . $file . "\n";
 
7413
                }
 
7414
            }
 
7415
            closedir DIR;
 
7416
        }
 
7417
    }
 
7418
 
 
7419
    $iconview->show();
 
7420
    $globals->{'thumb_idle'} = Glib::Idle->add(\&imgdir_thumbnails, $iconview);
 
7421
}
 
7422
 
 
7423
#***
 
7424
 
 
7425
#****f* lyricue/imgdir_thumbnails
 
7426
# NAME
 
7427
#   imgdir_thumbnails
 
7428
# SYNOPSIS
 
7429
#   imgdir_thumbnails ()
 
7430
# FUNCTION
 
7431
#   Load thumbnails for imagdir
 
7432
# INPUTS
 
7433
#
 
7434
# OUTPUT
 
7435
#   Thumbnails
 
7436
# SOURCE
 
7437
#
 
7438
sub imgdir_thumbnails {
 
7439
    my ($iconview) = @_;
 
7440
    debug("Loading thumbnails");
 
7441
    my $store = $iconview->get_model;
 
7442
    my $iter  = $store->get_iter_first;
 
7443
    while (defined $iter) {
 
7444
        my $id = $store->get_value($iter, 2);
 
7445
        my $scaled = create_pixbuf(
 
7446
            $id,
 
7447
            $globals->{'icon_width'},
 
7448
            $globals->{'icon_height'}
 
7449
        );
 
7450
        if ($scaled) {
 
7451
            $store->set($iter, 1, $scaled);
 
7452
        }
 
7453
        my $nextiter = $store->iter_next($iter);
 
7454
        $iter = $nextiter;
 
7455
        do_pending();
 
7456
    }
 
7457
}
 
7458
 
 
7459
#***
 
7460
 
 
7461
#****f* lyricue/spell_check
 
7462
# NAME
 
7463
#   spell_check
 
7464
# SYNOPSIS
 
7465
#   spell_check ()
 
7466
# FUNCTION
 
7467
#   Use aspell to check spellling for a song
 
7468
# INPUTS
 
7469
#   $oldwidgets
 
7470
# OUTPUT
 
7471
#   Dialog listing spelling errors on each page
 
7472
# SOURCE
 
7473
#
 
7474
sub spell_check {
 
7475
    my ($widget) = @_;
 
7476
    my ($page);
 
7477
    if ($globals->{'spell'}) {
 
7478
        debug("Running spell checker");
 
7479
 
 
7480
        foreach $page (
 
7481
            sort { $pageOrder{$a} cmp $pageOrder{$b} }
 
7482
            keys %pageOrder
 
7483
          )
 
7484
        {
 
7485
            if (!defined $widgets->{'spellAPage'}{$page}) {
 
7486
                $widgets->{'spellAPage'}{$page} =
 
7487
                  Gtk2::Spell->new($widgets->{'textAPage'}{$page});
 
7488
            }
 
7489
 
 
7490
        }
 
7491
    }
 
7492
}
 
7493
 
 
7494
#***
 
7495
 
 
7496
#****f* lyricue/create_search
 
7497
# NAME
 
7498
#   create_search
 
7499
# SYNOPSIS
 
7500
#   create_search ($topwidgets)
 
7501
# FUNCTION
 
7502
#   Create the dialog for advanced search
 
7503
# INPUTS
 
7504
#   $topwidgets - Widgets of main window
 
7505
# OUTPUT
 
7506
#   Search dialog
 
7507
# SOURCE
 
7508
#
 
7509
sub create_search {
 
7510
    debug("Advanced search dialog opened");
 
7511
    $widgets->{'search'} =
 
7512
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogSearch', 'lyricue');
 
7513
    $widgets->{'search'}->signal_autoconnect_from_package('');
 
7514
    my @target_table = ({'target' => "STRING", 'flags' => [], 'info' => 0},);
 
7515
    $widgets->{'search'}->get_widget('treeSearch')
 
7516
      ->drag_source_set(['button1_mask'], ['copy'], @target_table);
 
7517
    $widgets->{'main'}->get_widget('treePlaylist')
 
7518
      ->drag_dest_set('all', ['copy'], @target_table);
 
7519
    my $search_text = $widgets->{'main'}->get_widget('entrySearch')->get_text();
 
7520
    $widgets->{'search'}->get_widget('entrySearchSongs')
 
7521
      ->set_text($search_text);
 
7522
    do_adv_search();
 
7523
}
 
7524
 
 
7525
#***
 
7526
 
 
7527
#***
 
7528
 
 
7529
#****f* lyricue/add_file
 
7530
# NAME
 
7531
#   add_file
 
7532
# SYNOPSIS
 
7533
#   add_file()
 
7534
# FUNCTION
 
7535
#   Open a file dialog
 
7536
# INPUTS
 
7537
# OUTPUT
 
7538
# SOURCE
 
7539
#
 
7540
sub add_file {
 
7541
    debug("Open a file dialog");
 
7542
    my $filexml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
7543
        'dialogFileChooser', 'lyricue');
 
7544
    $filexml->signal_autoconnect_from_package('');
 
7545
    $filexml->get_widget('dialogFileChooser')
 
7546
      ->set_preview_widget(Gtk2::Image->new());
 
7547
    $filexml->get_widget('dialogFileChooser')->set_preview_widget_active(FALSE);
 
7548
    $filexml->get_widget('dialogFileChooser')
 
7549
      ->signal_connect("update-preview", "update_file_preview");
 
7550
    $filexml->get_widget('buttonFileOK')
 
7551
      ->signal_connect("clicked", "file_ok_sel", $filexml);
 
7552
    $filexml->get_widget('dialogFileChooser')->show_all();
 
7553
}
 
7554
 
 
7555
sub update_file_preview {
 
7556
    my ($chooser) = @_;
 
7557
    my $image     = $chooser->get_preview_widget;
 
7558
    my $filename  = $chooser->get_preview_filename;
 
7559
    if (defined $filename && ($filename ne "")) {
 
7560
        my $pixbuf = create_pixbuf(
 
7561
            "dir;" . $filename,
 
7562
            $globals->{'thumb_width'},
 
7563
            $globals->{'thumb_height'}
 
7564
        );
 
7565
        if (defined $pixbuf) {
 
7566
            $image->set_from_pixbuf($pixbuf);
 
7567
            $chooser->set_preview_widget_active(TRUE);
 
7568
            return;
 
7569
        }
 
7570
    }
 
7571
    $chooser->set_preview_widget_active(FALSE);
 
7572
}
 
7573
 
 
7574
#***
 
7575
 
 
7576
#****f* lyricue/add_directory
 
7577
# NAME
 
7578
#   add_directory
 
7579
# SYNOPSIS
 
7580
#   add_directory()
 
7581
# FUNCTION
 
7582
#   Add a directory to the playlist
 
7583
# INPUTS
 
7584
# OUTPUT
 
7585
# SOURCE
 
7586
#
 
7587
sub add_directory {
 
7588
    debug("Add a directory to the playlist");
 
7589
    my $d = Gtk2::FileChooserDialog->new(
 
7590
        fromutf(gettext("Choose a Directory")),
 
7591
        $widgets->{'main'}->get_widget('windowMain'), 'select-folder',
 
7592
        fromutf(gettext("Cancel")) => "cancel",
 
7593
        fromutf(gettext("OK"))     => "accept",
 
7594
    );
 
7595
 
 
7596
    my $response = $d->run();
 
7597
    my $dirname  = $d->get_filename();
 
7598
    if ("accept" eq $response) {
 
7599
        debug("Choosing" . $dirname);
 
7600
    }
 
7601
    $d->destroy;
 
7602
    do_add_directory($dirname, "");
 
7603
}
 
7604
 
 
7605
#***
 
7606
 
 
7607
#****f* lyricue/do_add_directory
 
7608
# NAME
 
7609
#   do_add_directory
 
7610
# SYNOPSIS
 
7611
#   do_add_directory($dirname,$sublist)
 
7612
# FUNCTION
 
7613
#   Sublist name:
 
7614
# INPUTS
 
7615
#   $dirname -
 
7616
#   $sublist -
 
7617
# OUTPUT
 
7618
# SOURCE
 
7619
#
 
7620
sub do_add_directory {
 
7621
    my ($dirname, $sublist) = @_;
 
7622
 
 
7623
    my (@files, $file);
 
7624
    opendir DIR, $dirname || return 0;
 
7625
    foreach $file (sort readdir(DIR)) {
 
7626
        my $type = globs($dirname . "/" . $file);
 
7627
        if (($type =~ /^audio/) || ($type =~ /^video/) || ($type =~ /^image/)) {
 
7628
            push @files, $dirname . "/" . $file;
 
7629
        }
 
7630
    }
 
7631
    closedir DIR;
 
7632
    if (@files) {
 
7633
        if ($sublist eq "") {
 
7634
            my $sublistxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
7635
                'dialogPromptEntry', 'lyricue');
 
7636
            $sublistxml->signal_autoconnect_from_package('');
 
7637
            $sublistxml->get_widget('dialogPromptEntry')
 
7638
              ->set_title(fromutf(gettext("Create new sublist")));
 
7639
            $sublistxml->get_widget('labelPromptE')
 
7640
              ->set_text(fromutf(gettext("Name of sublist")));
 
7641
 
 
7642
            my $response = $sublistxml->get_widget('dialogPromptEntry')->run();
 
7643
            if ($response eq "ok") {
 
7644
                $sublist = $sublistxml->get_widget('entryPromptE')->get_text();
 
7645
                close_dialog($sublistxml->get_widget('dialogPromptEntry'));
 
7646
            } else {
 
7647
                close_dialog($sublistxml->get_widget('dialogPromptEntry'));
 
7648
                return;
 
7649
            }
 
7650
            debug("Sublist name: " . $sublist);
 
7651
        }
 
7652
        my $playlist = new_sublist($sublist);
 
7653
 
 
7654
        @files = sort alphanum @files;
 
7655
 
 
7656
        foreach $file (@files) {
 
7657
            do_add_file($file, $playlist);
 
7658
        }
 
7659
    }
 
7660
    update_playlist();
 
7661
}
 
7662
 
 
7663
#***
 
7664
 
 
7665
#****f* lyricue/add_background
 
7666
# NAME
 
7667
#   add_background
 
7668
# SYNOPSIS
 
7669
#   add_background($widget)
 
7670
# FUNCTION
 
7671
#   add background
 
7672
# INPUTS
 
7673
#   $widget -
 
7674
# OUTPUT
 
7675
# SOURCE
 
7676
#
 
7677
sub add_background {
 
7678
    debug("add background");
 
7679
    my ($widget) = @_;
 
7680
    change_bgimage($widget);
 
7681
}
 
7682
 
 
7683
#***
 
7684
 
 
7685
#****f* lyricue/change_bgimage
 
7686
# NAME
 
7687
#   change_bgimage
 
7688
# SYNOPSIS
 
7689
#   change_bgimage($widget)
 
7690
# FUNCTION
 
7691
#   Change backdrop dialog opened
 
7692
# INPUTS
 
7693
#   $widget -
 
7694
# OUTPUT
 
7695
# SOURCE
 
7696
#
 
7697
sub change_bgimage {
 
7698
    my ($widget) = @_;
 
7699
    my $bgimage = "";
 
7700
    debug("Change backdrop dialog opened");
 
7701
    $widgets->{'image'} =
 
7702
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogImage', 'lyricue');
 
7703
    $widgets->{'image'}->signal_autoconnect_from_package('');
 
7704
    $widgets->{'image'}->get_widget('dialogImage')
 
7705
      ->set_title(fromutf(gettext("Choose a Background")));
 
7706
    $widgets->{'image'}->get_widget('buttonImageAdd')
 
7707
      ->signal_connect('clicked', 'import_background');
 
7708
    $widgets->{'image'}->get_widget('hboxImageSublist')->hide;
 
7709
    $widgets->{'image'}->get_widget('dialogImage')->show;
 
7710
 
 
7711
    if ($widgets->{'image'}->get_widget('treeImage')->{user_data}
 
7712
        && ($widgets->{'image'}->get_widget('treeImage')->{user_data} eq "load")
 
7713
      )
 
7714
    {
 
7715
        $widgets->{'image'}->get_widget('treeImage')->{data} = ();
 
7716
    } else {
 
7717
        if ($widget->get_name() eq "buttonPrefBackground") {
 
7718
            $bgimage =
 
7719
              $widgets->{'prefs'}->get_widget('imagePrefBG')->{user_data};
 
7720
            $widgets->{'image'}->get_widget('buttonImageOK')
 
7721
              ->set_label(fromutf(gettext("Set as Default")));
 
7722
            $widgets->{'image'}->get_widget('buttonImageOK')
 
7723
              ->signal_connect('clicked', "set_default_backdrop");
 
7724
            $widgets->{'image'}->get_widget('buttonImageAdd')->hide();
 
7725
            $widgets->{'image'}->get_widget('buttonImageDelete')->hide();
 
7726
            $widgets->{'image'}->get_widget('buttonImageChange')->hide();
 
7727
        } else {
 
7728
            $widgets->{'image'}->get_widget('buttonImageCancel')->hide();
 
7729
            $widgets->{'image'}->get_widget('buttonImageOK')
 
7730
              ->signal_connect('clicked', "close_dialog");
 
7731
            $widgets->{'image'}->get_widget('hboxImageColour')->show();
 
7732
            $widgets->{'image'}->get_widget('colorbuttonFontColour')
 
7733
              ->signal_connect("button_press_event", "open_dialogColour",
 
7734
                "ImageFont");
 
7735
 
 
7736
            #$widgets->{'image'}->get_widget('entryImageFontColour')
 
7737
            #->signal_connect("changed", "change_colour_media");
 
7738
            $widgets->{'image'}->get_widget('colorbuttonShadowColour')
 
7739
              ->signal_connect("button_press_event", "open_dialogColour",
 
7740
                "ImageShadow");
 
7741
 
 
7742
            #$widgets->{'image'}->get_widget('entryImageShadowColour')
 
7743
            #->signal_connect("changed", "change_colour_media");
 
7744
        }
 
7745
        $widgets->{'image'}->get_widget('treeImage')->{user_data} = "load";
 
7746
        my $renderer = Gtk2::CellRendererText->new;
 
7747
        $renderer->set("editable", TRUE);
 
7748
        $renderer->signal_connect("edited", "rename_media");
 
7749
        my $column =
 
7750
          Gtk2::TreeViewColumn->new_with_attributes("Filename", $renderer,
 
7751
            text => 0);
 
7752
        $widgets->{'image'}->get_widget('treeImage')->append_column($column);
 
7753
    }
 
7754
    update_imagedir("bg", "");
 
7755
    return TRUE;
 
7756
}
 
7757
 
 
7758
#***
 
7759
 
 
7760
#****f* lyricue/create_dialogSublist
 
7761
# NAME
 
7762
#   create_dialogSublist
 
7763
# SYNOPSIS
 
7764
#   create_dialogSublist ($widgets)
 
7765
# FUNCTION
 
7766
#   Create the dialog for adding a sublist
 
7767
# INPUTS
 
7768
#   $widgets - Widgets of main window
 
7769
# OUTPUT
 
7770
#   Dialog
 
7771
# SOURCE
 
7772
#
 
7773
sub create_dialogSublist {
 
7774
    debug("create sublist dialog");
 
7775
    my $sublistxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
7776
        'dialogPromptEntry', 'lyricue');
 
7777
    $sublistxml->signal_autoconnect_from_package('');
 
7778
    $sublistxml->get_widget('dialogPromptEntry')
 
7779
      ->set_title(fromutf(gettext("Create new sublist")));
 
7780
    $sublistxml->get_widget('labelPromptE')
 
7781
      ->set_text(fromutf(gettext("Name of sublist")));
 
7782
    $sublistxml->get_widget('buttonPromptEOK')
 
7783
      ->signal_connect("clicked", "new_sublist_from_xml", $sublistxml);
 
7784
}
 
7785
 
 
7786
#***
 
7787
 
 
7788
#***
 
7789
 
 
7790
#****f* lyricue/get_buffer_text
 
7791
# NAME
 
7792
#   get_buffer_text
 
7793
# SYNOPSIS
 
7794
#   get_buffer_text($widget)
 
7795
# FUNCTION
 
7796
#
 
7797
# INPUTS
 
7798
#   $widget -
 
7799
# OUTPUT
 
7800
# SOURCE
 
7801
#
 
7802
sub get_buffer_text {
 
7803
    my ($widget) = @_;
 
7804
    return $widget->get_text($widget->get_bounds, FALSE);
 
7805
}
 
7806
 
 
7807
#***
 
7808
 
 
7809
#****f* lyricue/on_treeAvailable_drag_data_get
 
7810
# NAME
 
7811
#   on_treeAvailable_drag_data_get
 
7812
# SYNOPSIS
 
7813
#   on_treeAvailable_drag_data_get($widget, $context, $data, $info, $time)
 
7814
# FUNCTION
 
7815
#   Dragged from available songs
 
7816
# INPUTS
 
7817
#   $widget -
 
7818
#    $context -
 
7819
#    $data -
 
7820
#    $info -
 
7821
#    $time -
 
7822
# OUTPUT
 
7823
# SOURCE
 
7824
#
 
7825
sub on_treeAvailable_drag_data_get {
 
7826
    my ($widget, $context, $data, $info, $time) = @_;
 
7827
    debug("Dragged from available songs");
 
7828
    my $selection = $widget->get_selection;
 
7829
    my @sel       = $selection->get_selected_rows;
 
7830
    my $model     = $widgets->{'main'}->get_widget('treeAvailable')->get_model;
 
7831
    my $iter      = $model->get_iter($sel[0]);
 
7832
    if ($iter) {
 
7833
        $data->set($data->target, 8, $model->get($iter, 3));
 
7834
    }
 
7835
}
 
7836
 
 
7837
#***
 
7838
 
 
7839
#****f* lyricue/on_iconviewBack_drag_data_get
 
7840
# NAME
 
7841
#   on_iconviewBack_drag_data_get
 
7842
# SYNOPSIS
 
7843
#   on_iconviewBack_drag_data_get($widget, $context, $data, $info, $time)
 
7844
# FUNCTION
 
7845
#   Dragged from Backgrounds
 
7846
# INPUTS
 
7847
#   $widget -
 
7848
#    $context -
 
7849
#    $data -
 
7850
#    $info -
 
7851
#    $time -
 
7852
# OUTPUT
 
7853
# SOURCE
 
7854
#
 
7855
sub on_iconviewBack_drag_data_get {
 
7856
    my ($widget, $context, $data, $info, $time) = @_;
 
7857
    debug("Dragged from Backgrounds");
 
7858
    my $selected = "";
 
7859
    my @list     = $widget->get_selected_items;
 
7860
    if (defined $list[0]) {
 
7861
        my $model = $widget->get_model;
 
7862
        my $iter  = $model->get_iter($list[0]);
 
7863
        $selected = $model->get($iter, 2);
 
7864
    }
 
7865
    if ($selected ne "") {
 
7866
        $data->set($data->target, 8, "bg:" . $selected);
 
7867
    }
 
7868
}
 
7869
 
 
7870
#***
 
7871
 
 
7872
#****f* lyricue/on_iconviewImage_drag_data_get
 
7873
# NAME
 
7874
#   on_iconviewImage_drag_data_get
 
7875
# SYNOPSIS
 
7876
#   on_iconviewImage_drag_data_get($widget, $context, $data, $info, $time)
 
7877
# FUNCTION
 
7878
#   Dragged from Images
 
7879
# INPUTS
 
7880
#   $widget -
 
7881
#    $context -
 
7882
#    $data -
 
7883
#    $info -
 
7884
#    $time -
 
7885
# OUTPUT
 
7886
# SOURCE
 
7887
#
 
7888
sub on_iconviewImage_drag_data_get {
 
7889
    my ($widget, $context, $data, $info, $time) = @_;
 
7890
    debug("Dragged from Images");
 
7891
    my $selected = "";
 
7892
    my @list     = $widget->get_selected_items;
 
7893
    if (defined $list[0]) {
 
7894
        my $model = $widget->get_model;
 
7895
        my $iter  = $model->get_iter($list[0]);
 
7896
        $selected = $model->get($iter, 2);
 
7897
    }
 
7898
    if ($selected ne "") {
 
7899
        $data->set($data->target, 8, "img:" . $selected);
 
7900
    }
 
7901
}
 
7902
 
 
7903
#***
 
7904
 
 
7905
#****f* lyricue/on_treeSearch_drag_data_get
 
7906
# NAME
 
7907
#   on_treeSearch_drag_data_get
 
7908
# SYNOPSIS
 
7909
#   on_treeSearch_drag_data_get($widget, $context, $data, $info, $time)
 
7910
# FUNCTION
 
7911
#   Dragged from advanced search
 
7912
# INPUTS
 
7913
#   $widget -
 
7914
#    $context -
 
7915
#    $data -
 
7916
#    $info -
 
7917
#    $time -
 
7918
# OUTPUT
 
7919
# SOURCE
 
7920
#
 
7921
sub on_treeSearch_drag_data_get {
 
7922
    my ($widget, $context, $data, $info, $time) = @_;
 
7923
    debug("Dragged from advanced search");
 
7924
    my $selection = $widget->get_selection;
 
7925
    my ($model, $iter) = $selection->get_selected;
 
7926
    if ($iter) {
 
7927
        $data->set($data->target, 8, $model->get($iter, 4));
 
7928
    }
 
7929
}
 
7930
 
 
7931
#***
 
7932
 
 
7933
#****f* lyricue/on_treePlaylist_drag_data_get
 
7934
# NAME
 
7935
#   on_treePlaylist_drag_data_get
 
7936
# SYNOPSIS
 
7937
#   on_treePlaylist_drag_data_get($widget, $context, $data, $info, $time)
 
7938
# FUNCTION
 
7939
#   Dragged from playlist
 
7940
# INPUTS
 
7941
#   $widget -
 
7942
#    $context -
 
7943
#    $data -
 
7944
#    $info -
 
7945
#    $time -
 
7946
# OUTPUT
 
7947
# SOURCE
 
7948
#
 
7949
sub on_treePlaylist_drag_data_get {
 
7950
    my ($widget, $context, $data, $info, $time) = @_;
 
7951
    debug("Dragged from Playlist");
 
7952
    my $selection = $widget->get_selection;
 
7953
    my ($model, $iter) = $selection->get_selected;
 
7954
    if ($iter) {
 
7955
        $data->set($data->target, 8, "song:" . $model->get($iter, 2));
 
7956
        return TRUE;
 
7957
    }
 
7958
    return FALSE;
 
7959
}
 
7960
 
 
7961
#***
 
7962
 
 
7963
#****f* lyricue/on_treePlaylist_drag_data_received
 
7964
# NAME
 
7965
#   on_treePlaylist_drag_data_received
 
7966
# SYNOPSIS
 
7967
#   on_treePlaylist_drag_data_received($widget, $context, $x, $y, $data, $info, $time)
 
7968
# FUNCTION
 
7969
#   Dropped on playlist
 
7970
# INPUTS
 
7971
#   $widget -
 
7972
#    $context -
 
7973
#    $x -
 
7974
#    $y -
 
7975
#    $data -
 
7976
#    $info -
 
7977
#    $time -
 
7978
# OUTPUT
 
7979
# SOURCE
 
7980
#
 
7981
sub on_treePlaylist_drag_data_received {
 
7982
    my ($widget, $context, $x, $y, $data, $info, $time) = @_;
 
7983
    my ($u1, $file);
 
7984
    debug("Dropped on playlist");
 
7985
 
 
7986
    # Catch duplicate events
 
7987
    if (defined($globals->{'drop_time'}) && ($globals->{'drop_time'} == $time))
 
7988
    {
 
7989
        return;
 
7990
    }
 
7991
    $globals->{'drop_time'} = $time;
 
7992
 
 
7993
    if (($data->length >= 0) && ($data->format == 8)) {
 
7994
        debug("Received: " . $data->data);
 
7995
        if ($data->data =~ /^file:/i) {
 
7996
            for my $uri (split(/\n/, $data->data)) {
 
7997
                $u1 = URI->new($uri);
 
7998
                debug("received URI: " . $uri);
 
7999
                $file = fromutf("UTF-8", $u1->file);
 
8000
                debug("Recieved file: " . $file);
 
8001
                my $main_playlist =
 
8002
                  $widgets->{'main'}->get_widget('labelCurrentPlaylist')
 
8003
                  ->{user_data};
 
8004
                do_add_file($file, $main_playlist);
 
8005
                update_playlist();
 
8006
            }
 
8007
        } elsif ($data->data =~ /^img:/) {
 
8008
            my $selected = $data->data;
 
8009
            $selected =~ s/^img://g;
 
8010
            my $playlist =
 
8011
              $widgets->{'main'}->get_widget('labelCurrentPlaylist')
 
8012
              ->{user_data};
 
8013
            add_image_item($playlist, $selected);
 
8014
            update_playlist();
 
8015
        } elsif ($data->data =~ /^bg:/) {
 
8016
            my $selected = fromutf($data->data);
 
8017
            $selected =~ s/^bg://g;
 
8018
            my $playlist =
 
8019
              $widgets->{'main'}->get_widget('labelCurrentPlaylist')
 
8020
              ->{user_data};
 
8021
            my ($path, $drop);
 
8022
            ($path, $drop) = $widget->get_dest_row_at_pos($x, $y);
 
8023
            debug($path . ":" . $drop);
 
8024
            if ($drop =~ /^into/) {
 
8025
                my $iter = $widget->get_model->get_iter($path);
 
8026
                my $item = $widget->get_model->get($iter, 2);
 
8027
                @ASSOCIATE = ($item, $playlist);
 
8028
                debug($item . ":" . $playlist . ":" . $selected);
 
8029
                associate_bg($selected);
 
8030
                update_playlist();
 
8031
            }
 
8032
        } elsif ($data->data =~ /^song:/) {
 
8033
            my $song = $data->data;
 
8034
            $song =~ s/^song://g;
 
8035
            my ($path, $drop) = $widget->get_dest_row_at_pos($x, $y);
 
8036
            my $iter = $widget->get_model->get_iter($path);
 
8037
            my $item = $widget->get_model->get($iter, 2);
 
8038
            debug($song . " - " . $drop . " - " . $item);
 
8039
            move_item($song, $drop, $item);
 
8040
        } else {
 
8041
            if ($data->data != 0) {
 
8042
                add_single_song($data->data);
 
8043
                update_playlist();
 
8044
            }
 
8045
        }
 
8046
        $context->finish(1, 0, $time);
 
8047
        return;
 
8048
    }
 
8049
    $context->finish(0, 0, $time);
 
8050
}
 
8051
 
 
8052
#***
 
8053
 
 
8054
#****f* lyricue/display_message
 
8055
# NAME
 
8056
#   display_message
 
8057
# SYNOPSIS
 
8058
#   display_message($message, $details)
 
8059
# FUNCTION
 
8060
#       debug($message);
 
8061
# INPUTS
 
8062
#   $message -
 
8063
#    $details -
 
8064
# OUTPUT
 
8065
# SOURCE
 
8066
#
 
8067
sub display_message {
 
8068
    my ($message, $details) = @_;
 
8069
    debug($message);
 
8070
    my $errorxml =
 
8071
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogError', 'lyricue');
 
8072
    $errorxml->signal_autoconnect_from_package('');
 
8073
    $errorxml->get_widget('labelError')->set_text($message);
 
8074
    if ((!defined $details) || ($details eq "")) {
 
8075
        $errorxml->get_widget('expanderDetails')->hide();
 
8076
    } else {
 
8077
        $errorxml->get_widget('labelErrorDetails')->set_text($details);
 
8078
    }
 
8079
    my $confirm = $errorxml->get_widget('dialogError')->run();
 
8080
    close_dialog($errorxml->get_widget('dialogError'));
 
8081
}
 
8082
 
 
8083
#***
 
8084
 
 
8085
#****f* lyricue/display_fatal
 
8086
# NAME
 
8087
#   display_fatal
 
8088
# SYNOPSIS
 
8089
#   display_fatal($message, $error)
 
8090
# FUNCTION
 
8091
#
 
8092
# INPUTS
 
8093
#   $message -
 
8094
#    $error -
 
8095
# OUTPUT
 
8096
# SOURCE
 
8097
#
 
8098
sub display_fatal {
 
8099
    my ($message, $error) = @_;
 
8100
    print STDERR "\n\n-------------\n";
 
8101
    print STDERR "FATAL ERROR!!\n";
 
8102
    print STDERR "-------------\n";
 
8103
    print STDERR "Error description\n";
 
8104
    print STDERR $message . "\n";
 
8105
    print STDERR "------------------\n";
 
8106
    my $errorxml =
 
8107
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogError', 'lyricue');
 
8108
    $errorxml->signal_autoconnect_from_package('');
 
8109
    $errorxml->get_widget('labelError')->set_text($message);
 
8110
 
 
8111
    if ($error eq "") {
 
8112
        $errorxml->get_widget('expanderDetails')->hide();
 
8113
    } else {
 
8114
        $errorxml->get_widget('labelErrorDetails')->set_text($error);
 
8115
    }
 
8116
    my $confirm = $errorxml->get_widget('dialogError')->run();
 
8117
    close_dialog($errorxml->get_widget('dialogError'));
 
8118
    print STDERR "Full error message\n";
 
8119
    print STDERR "------------------\n";
 
8120
    die($error);
 
8121
}
 
8122
 
 
8123
#***
 
8124
 
 
8125
#****f* lyricue/transition_type_changed
 
8126
# NAME
 
8127
#   transition_type_changed
 
8128
# SYNOPSIS
 
8129
#   transition_type_changed()
 
8130
# FUNCTION
 
8131
#   Change the list of transition options
 
8132
# INPUTS
 
8133
# OUTPUT
 
8134
# SOURCE
 
8135
sub transition_type_changed {
 
8136
    my ($widget) = @_;
 
8137
    debug("Transition type changed");
 
8138
    my $item = $widget->get_name;
 
8139
    if ($item eq "radioTransFade") {
 
8140
    } elsif ($item eq "radioTransWipe") {
 
8141
    } elsif ($item eq "radioTransSlide") {
 
8142
        if ($widget->get_active) {
 
8143
            $widgets->{'main'}->get_widget('tableTransDir')->show_all();
 
8144
        } else {
 
8145
            $widgets->{'main'}->get_widget('tableTransDir')->hide();
 
8146
        }
 
8147
    } elsif ($item eq "radioTransRotate") {
 
8148
        if ($widget->get_active) {
 
8149
            $widgets->{'main'}->get_widget('tableTransRot')->show_all();
 
8150
        } else {
 
8151
            $widgets->{'main'}->get_widget('tableTransRot')->hide();
 
8152
        }
 
8153
    }
 
8154
}
 
8155
 
 
8156
sub transition_dir_changed {
 
8157
    my ($widget) = @_;
 
8158
    debug("Direction changed");
 
8159
    if ($widget->get_active == FALSE) {
 
8160
        return;
 
8161
    }
 
8162
    my @dirs = (
 
8163
        'UpLeft',   'Up',   'UpRight', 'Left', 'None', 'Right',
 
8164
        'DownLeft', 'Down', 'DownRight'
 
8165
    );
 
8166
    if ($widget->get_name() =~ /^toggleIn/) {
 
8167
        foreach (@dirs) {
 
8168
            my $w = "toggleIn" . $_;
 
8169
            if ($widget->get_name eq $w) {
 
8170
                $widgets->{'main'}->get_widget($w)->set_active(TRUE);
 
8171
            } else {
 
8172
                $widgets->{'main'}->get_widget($w)->set_active(FALSE);
 
8173
            }
 
8174
        }
 
8175
    } elsif ($widget->get_name =~ /^toggleOut/) {
 
8176
        foreach (@dirs) {
 
8177
            my $w = "toggleOut" . $_;
 
8178
            if ($widget->get_name eq $w) {
 
8179
                $widgets->{'main'}->get_widget($w)->set_active(TRUE);
 
8180
            } else {
 
8181
                $widgets->{'main'}->get_widget($w)->set_active(FALSE);
 
8182
            }
 
8183
        }
 
8184
    }
 
8185
}
 
8186
 
 
8187
#***
 
8188
 
 
8189
#****f* lyricue/apply_transition_selected
 
8190
# NAME
 
8191
#   apply_transition_selected
 
8192
# SYNOPSIS
 
8193
#   apply_transition_selected()
 
8194
# FUNCTION
 
8195
#   Apply transition to selected items
 
8196
# INPUTS
 
8197
# OUTPUT
 
8198
# SOURCE
 
8199
#
 
8200
sub apply_transition_selected {
 
8201
    debug("Apply transition to selected items");
 
8202
    if ($widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data} ==
 
8203
        -1)
 
8204
    {
 
8205
        return;
 
8206
    }
 
8207
    my $trans_type = calculate_transition();
 
8208
    my $selection =
 
8209
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
8210
    if ($selection) {
 
8211
        my @list  = $selection->get_selected_rows();
 
8212
        my $model = $widgets->{'main'}->get_widget('treePlaylist')->get_model();
 
8213
        foreach (@list) {
 
8214
            apply_transition($model->get($model->get_iter($_), 2), $trans_type);
 
8215
        }
 
8216
    }
 
8217
    update_playlist();
 
8218
}
 
8219
 
 
8220
#***
 
8221
 
 
8222
#****f* lyricue/apply_transition_playlist
 
8223
# NAME
 
8224
#   apply_transition_playlist
 
8225
# SYNOPSIS
 
8226
#   apply_transition_playlist()
 
8227
# FUNCTION
 
8228
#   Apply transition to playlist
 
8229
# INPUTS
 
8230
# OUTPUT
 
8231
# SOURCE
 
8232
#
 
8233
sub apply_transition_playlist {
 
8234
    debug("Apply transition to playlist");
 
8235
    my $playlist =
 
8236
      $widgets->{'main'}->get_widget('labelCurrentPlaylist')->{user_data};
 
8237
    if ($playlist == -1) {
 
8238
        return;
 
8239
    }
 
8240
    my $trans_type = calculate_transition();
 
8241
    my $query = "SELECT playorder FROM playlist WHERE playlist=" . $playlist;
 
8242
    qdebug($query);
 
8243
    my $sth = $lyricDbh->prepare($query)
 
8244
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
8245
    my $rv = $sth->execute
 
8246
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
8247
    while (my @row = $sth->fetchrow_array()) {
 
8248
        apply_transition($row[0], $trans_type);
 
8249
    }
 
8250
    update_playlist();
 
8251
}
 
8252
 
 
8253
#***
 
8254
 
 
8255
#****f* lyricue/calculate_transition
 
8256
# NAME
 
8257
#   calculate_transition
 
8258
# SYNOPSIS
 
8259
#   calculate_transition()
 
8260
# FUNCTION
 
8261
#
 
8262
# INPUTS
 
8263
# OUTPUT
 
8264
# SOURCE
 
8265
#
 
8266
sub calculate_transition {
 
8267
    debug("Calculating transition code");
 
8268
    my $trans_type = DEFAULT;
 
8269
    if ($widgets->{'main'}->get_widget('radioTransNone')->get_active()) {
 
8270
        $trans_type = NOTRANS;
 
8271
    } elsif ($widgets->{'main'}->get_widget('radioTransFade')->get_active()) {
 
8272
        $trans_type = FADE;
 
8273
    } elsif ($widgets->{'main'}->get_widget('radioTransSlide')->get_active()) {
 
8274
        $trans_type = SLIDE_TEXT;
 
8275
    } elsif ($widgets->{'main'}->get_widget('radioTransRotate')->get_active()) {
 
8276
        $trans_type = ROTATE_TEXT;
 
8277
    }
 
8278
 
 
8279
    my @dirs = (
 
8280
        'UpLeft',   'Up',   'UpRight', 'Left', 'None', 'Right',
 
8281
        'DownLeft', 'Down', 'DownRight'
 
8282
    );
 
8283
    my $indir  = "";
 
8284
    my $outdir = "";
 
8285
    foreach (@dirs) {
 
8286
        if ($widgets->{'main'}->get_widget("toggleIn" . $_)->get_active()) {
 
8287
            $indir = $_;
 
8288
        }
 
8289
        if ($widgets->{'main'}->get_widget("toggleOut" . $_)->get_active()) {
 
8290
            $outdir = $_;
 
8291
        }
 
8292
    }
 
8293
 
 
8294
    # Set in direction
 
8295
    $trans_type = $trans_type << NUM_TRANS;
 
8296
    $_          = $indir;
 
8297
    if (/Up/) {
 
8298
        $trans_type = $trans_type + UP;
 
8299
    } elsif (/Down/) {
 
8300
        $trans_type = $trans_type + DOWN;
 
8301
    }
 
8302
    if (/Left/) {
 
8303
        $trans_type = $trans_type + LEFT;
 
8304
    } elsif (/Right/) {
 
8305
        $trans_type = $trans_type + RIGHT;
 
8306
    }
 
8307
 
 
8308
    if ($widgets->{'main'}->get_widget('toggleRotX')->get_active()) {
 
8309
        $trans_type = $trans_type + X_AXIS;
 
8310
    }
 
8311
    if ($widgets->{'main'}->get_widget('toggleRotY')->get_active()) {
 
8312
        $trans_type = $trans_type + Y_AXIS;
 
8313
    }
 
8314
    if ($widgets->{'main'}->get_widget('toggleRotZ')->get_active()) {
 
8315
        $trans_type = $trans_type + Z_AXIS;
 
8316
    }
 
8317
 
 
8318
    # Set out direction
 
8319
    $trans_type = $trans_type << NUM_TRANS;
 
8320
    $_          = $outdir;
 
8321
    if (/Up/) {
 
8322
        $trans_type = $trans_type + UP;
 
8323
    } elsif (/Down/) {
 
8324
        $trans_type = $trans_type + DOWN;
 
8325
    }
 
8326
    if (/Left/) {
 
8327
        $trans_type = $trans_type + LEFT;
 
8328
    } elsif (/Right/) {
 
8329
        $trans_type = $trans_type + RIGHT;
 
8330
    }
 
8331
 
 
8332
    if ($widgets->{'main'}->get_widget('toggleRotX')->get_active()) {
 
8333
        $trans_type = $trans_type + X_AXIS;
 
8334
    }
 
8335
    if ($widgets->{'main'}->get_widget('toggleRotY')->get_active()) {
 
8336
        $trans_type = $trans_type + Y_AXIS;
 
8337
    }
 
8338
    if ($widgets->{'main'}->get_widget('toggleRotZ')->get_active()) {
 
8339
        $trans_type = $trans_type + Z_AXIS;
 
8340
    }
 
8341
    return $trans_type;
 
8342
}
 
8343
 
 
8344
#***
 
8345
 
 
8346
#****f* lyricue/apply_transition
 
8347
# NAME
 
8348
#   apply_transition
 
8349
# SYNOPSIS
 
8350
#   apply_transition($item, $trans_type)
 
8351
# FUNCTION
 
8352
#   Applying transition to
 
8353
# INPUTS
 
8354
#   $item -
 
8355
#    $trans_type -
 
8356
# OUTPUT
 
8357
# SOURCE
 
8358
#
 
8359
sub apply_transition {
 
8360
    my ($item, $trans_type) = @_;
 
8361
    debug("Applying transition to " . $item);
 
8362
 
 
8363
    my $query = "SELECT type,data FROM playlist WHERE playorder=" . $item;
 
8364
    qdebug($query);
 
8365
    my $sth = $lyricDbh->prepare($query)
 
8366
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
8367
    my $rv = $sth->execute
 
8368
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
8369
    my @row = $sth->fetchrow_array();
 
8370
    if ($row[0] eq "play") {
 
8371
        $query =
 
8372
            "UPDATE playlist SET transition="
 
8373
          . $trans_type
 
8374
          . " WHERE playorder="
 
8375
          . $item
 
8376
          . " OR playlist="
 
8377
          . $row[1];
 
8378
    } else {
 
8379
        $query =
 
8380
            "UPDATE playlist SET transition="
 
8381
          . $trans_type
 
8382
          . " WHERE playorder="
 
8383
          . $item;
 
8384
    }
 
8385
    qdebug($query);
 
8386
    $sth = $lyricDbh->prepare($query)
 
8387
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
8388
    $rv = $sth->execute
 
8389
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
8390
}
 
8391
 
 
8392
#***
 
8393
 
 
8394
#****f* lyricue/mod
 
8395
# NAME
 
8396
#   mod
 
8397
# SYNOPSIS
 
8398
#   mod($inp, $div)
 
8399
# FUNCTION
 
8400
#
 
8401
# INPUTS
 
8402
#   $inp -
 
8403
#    $div -
 
8404
# OUTPUT
 
8405
# SOURCE
 
8406
#
 
8407
sub mod {
 
8408
    my ($inp, $div) = @_;
 
8409
    my $rem = (($inp / $div) - (int($inp / $div))) * $div;
 
8410
    return $rem;
 
8411
}
 
8412
 
 
8413
#***
 
8414
 
 
8415
#****f* lyricue/user_admin
 
8416
# NAME
 
8417
#   user_admin
 
8418
# SYNOPSIS
 
8419
#   user_admin()
 
8420
# FUNCTION
 
8421
#   User access administration
 
8422
# INPUTS
 
8423
# OUTPUT
 
8424
# SOURCE
 
8425
#
 
8426
sub user_admin {
 
8427
    debug("User access administration");
 
8428
    $widgets->{'admin'} =
 
8429
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogAdmin', 'lyricue');
 
8430
    $widgets->{'admin'}->signal_autoconnect_from_package('');
 
8431
    eval { open(ACCESS, $globals->{'accessfile'}); };
 
8432
    if ($@) {
 
8433
        debug("No existing access.conf");
 
8434
    } else {
 
8435
        my $users = 0;
 
8436
        my (@username, @useraccess);
 
8437
        while (<ACCESS>) {
 
8438
            ($username[$users], $useraccess[$users]) = split(/=/, $_, 2);
 
8439
            $username[$users]   =~ s/ *$//g;
 
8440
            $useraccess[$users] =~ s/ *$//g;
 
8441
            $users++;
 
8442
        }
 
8443
        close ACCESS;
 
8444
        $widgets->{'admin'}->get_widget('tableAccess')->resize($users, 6);
 
8445
        foreach my $count (0 .. ($users - 1)) {
 
8446
            debug("Users: " . $username[$count]);
 
8447
            $widgets->{'adminUsername'}[$count] =
 
8448
              Gtk2::Label->new($username[$count]);
 
8449
            $widgets->{'admin'}->get_widget('tableAccess')
 
8450
              ->attach($widgets->{'adminUsername'}[$count],
 
8451
                0, 1, $count + 2, $count + 3, 'fill', 'expand', 0, 0);
 
8452
 
 
8453
            $widgets->{'adminPlaylist'}[$count] = Gtk2::CheckButton->new();
 
8454
            $widgets->{'admin'}->get_widget('tableAccess')
 
8455
              ->attach($widgets->{'adminPlaylist'}[$count],
 
8456
                1, 2, $count + 2, $count + 3, 'fill', 'expand', 0, 0);
 
8457
            $widgets->{'adminEdit'}[$count] = Gtk2::CheckButton->new();
 
8458
            $widgets->{'admin'}->get_widget('tableAccess')
 
8459
              ->attach($widgets->{'adminEdit'}[$count],
 
8460
                2, 3, $count + 2, $count + 3, 'fill', 'expand', 0, 0);
 
8461
            $widgets->{'adminDelete'}[$count] = Gtk2::CheckButton->new();
 
8462
            $widgets->{'admin'}->get_widget('tableAccess')
 
8463
              ->attach($widgets->{'adminDelete'}[$count],
 
8464
                3, 4, $count + 2, $count + 3, 'fill', 'expand', 0, 0);
 
8465
            $widgets->{'adminDisplay'}[$count] = Gtk2::CheckButton->new();
 
8466
            $widgets->{'admin'}->get_widget('tableAccess')
 
8467
              ->attach($widgets->{'adminDisplay'}[$count],
 
8468
                4, 5, $count + 2, $count + 3, 'fill', 'expand', 0, 0);
 
8469
            $widgets->{'adminAdmin'}[$count] = Gtk2::CheckButton->new();
 
8470
            $widgets->{'admin'}->get_widget('tableAccess')
 
8471
              ->attach($widgets->{'adminAdmin'}[$count],
 
8472
                5, 6, $count + 2, $count + 3, 'fill', 'expand', 0, 0);
 
8473
            $_ = $useraccess[$count];
 
8474
 
 
8475
            if (/p/) {
 
8476
                $widgets->{'adminPlaylist'}[$count]->set_active(TRUE);
 
8477
            }
 
8478
            if (/e/) { $widgets->{'adminEdit'}[$count]->set_active(TRUE); }
 
8479
            if (/d/) {
 
8480
                $widgets->{'adminDelete'}[$count]->set_active(TRUE);
 
8481
            }
 
8482
            if (/s/) {
 
8483
                $widgets->{'adminDisplay'}[$count]->set_active(TRUE);
 
8484
            }
 
8485
            if (/a/) { $widgets->{'adminAdmin'}[$count]->set_active(TRUE); }
 
8486
        }
 
8487
        $widgets->{'admin'}->get_widget('tableAccess')->show_all();
 
8488
    }
 
8489
    my $confirm = $widgets->{'admin'}->get_widget('dialogAdmin')->run();
 
8490
    if ($confirm eq "ok") {
 
8491
        open(ACCESS, ">" . $globals->{'accessfile'})
 
8492
          || display_fatal(
 
8493
            $errorcodes->{'fileopenwrite'} . $globals->{'accessfile'},
 
8494
            $! . "\nSQL: " . $query);
 
8495
        my $users =
 
8496
          ($widgets->{'admin'}->get_widget('tableAccess')->get('n-rows') - 2);
 
8497
        foreach my $count (0 .. ($users - 1)) {
 
8498
            my $out = $widgets->{'adminUsername'}[$count]->get_text() . " = ";
 
8499
            if ($widgets->{'adminPlaylist'}[$count]->get_active()) {
 
8500
                $out .= "p";
 
8501
            }
 
8502
            if ($widgets->{'adminEdit'}[$count]->get_active()) {
 
8503
                $out .= "e";
 
8504
            }
 
8505
            if ($widgets->{'adminDelete'}[$count]->get_active()) {
 
8506
                $out .= "d";
 
8507
            }
 
8508
            if ($widgets->{'adminDisplay'}[$count]->get_active()) {
 
8509
                $out .= "s";
 
8510
            }
 
8511
            if ($widgets->{'adminAdmin'}[$count]->get_active()) {
 
8512
                $out .= "a";
 
8513
            }
 
8514
            print ACCESS $out . "\n";
 
8515
        }
 
8516
        close ACCESS;
 
8517
    }
 
8518
    $widgets->{'admin'}->get_widget('dialogAdmin')->destroy();
 
8519
    $globals->{'access'} = load_access();
 
8520
 
 
8521
}
 
8522
 
 
8523
#***
 
8524
 
 
8525
#****f* lyricue/load_access
 
8526
# NAME
 
8527
#   load_access
 
8528
# SYNOPSIS
 
8529
#   load_access()
 
8530
# FUNCTION
 
8531
#   Loading access settings
 
8532
# INPUTS
 
8533
# OUTPUT
 
8534
# SOURCE
 
8535
#
 
8536
sub load_access {
 
8537
    debug("Loading access settings");
 
8538
    my $access = "blank";
 
8539
 
 
8540
    # Load the access settings (ignore if using sqlite)
 
8541
    if (($config->{'DatabaseType'} eq "SQLite") || ($^O eq 'MSWin32')) {
 
8542
        $access = "spade";
 
8543
    } else {
 
8544
        open(ACCESS, $globals->{'accessfile'})
 
8545
          || display_fatal(
 
8546
            $errorcodes->{'fileopenread'} . $globals->{'accessfile'},
 
8547
            $! . "\nSQL: " . $query);
 
8548
        my $username = getpwuid($<);
 
8549
        while (<ACCESS>) {
 
8550
            chomp;
 
8551
            if (/^$username/) {
 
8552
                $access = $_;
 
8553
                $access =~ s/^.*= *//g;
 
8554
            }
 
8555
        }
 
8556
        close ACCESS;
 
8557
    }
 
8558
    if ($access eq "blank") {
 
8559
        $access = "spade";
 
8560
        #my $accessxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
8561
        #    'dialogConfirm', 'lyricue');
 
8562
        #$accessxml->signal_autoconnect_from_package('');
 
8563
        #my $labelText .= fromutf(
 
8564
        #    gettext(
 
8565
# "This user has no access entry.\nBy default they will have full access.\nTo fix please edit /etc/lyricue/access.conf and add an entry for this user.\nClick OK to continue anyway or Cancel to Exit"
 
8566
        #    )
 
8567
        #);
 
8568
        #$accessxml->get_widget('labelDelete')->set_text($labelText);
 
8569
        #$accessxml->get_widget('dialogConfirm')->set_title(fromutf(gettext("User access level")));
 
8570
 
 
8571
        #my $confirm = $accessxml->get_widget('dialogConfirm')->run();
 
8572
        #if ($confirm ne "ok") {
 
8573
        #    close_main();
 
8574
        #}
 
8575
        #close_dialog($accessxml->get_widget('dialogConfirm'));
 
8576
    }
 
8577
    debug("Access set at " . $access);
 
8578
 
 
8579
    $_ = $access;
 
8580
    my @remove_items = ();
 
8581
    my @show_items   = ();
 
8582
    if (!/e/) {
 
8583
        push @remove_items, @edit_items;
 
8584
    } else {
 
8585
        push @show_items, @edit_items;
 
8586
    }
 
8587
 
 
8588
    if (!/d/) {
 
8589
        push @remove_items, @delete_items;
 
8590
    } else {
 
8591
        push @show_items, @delete_items;
 
8592
    }
 
8593
 
 
8594
    if (!/s/) {
 
8595
        push @remove_items, @display_items;
 
8596
    } else {
 
8597
        push @show_items, @display_items;
 
8598
    }
 
8599
 
 
8600
    if (!/p/) {
 
8601
        push @remove_items, @playlist_items;
 
8602
    } else {
 
8603
        push @show_items, @playlist_items;
 
8604
    }
 
8605
 
 
8606
    if (!/a/) {
 
8607
        push @remove_items, @admin_items;
 
8608
    } else {
 
8609
        push @show_items, @admin_items;
 
8610
    }
 
8611
    if (!-w $globals->{'accessfile'}) {
 
8612
        push @remove_items, "user_administration1";
 
8613
    }
 
8614
 
 
8615
    foreach my $item (@show_items) {
 
8616
        debug("Showing $item");
 
8617
        if (defined $widgets->{'main'}->get_widget($item)) {
 
8618
            $widgets->{'main'}->get_widget($item)->show();
 
8619
        }
 
8620
    }
 
8621
 
 
8622
    foreach my $item (@remove_items) {
 
8623
        debug("Hiding $item");
 
8624
        if (defined $widgets->{'main'}->get_widget($item)) {
 
8625
            $widgets->{'main'}->get_widget($item)->hide();
 
8626
        }
 
8627
    }
 
8628
    return $access;
 
8629
}
 
8630
 
 
8631
#***
 
8632
 
 
8633
#****f* lyricue/add_user
 
8634
# NAME
 
8635
#   add_user
 
8636
# SYNOPSIS
 
8637
#   add_user()
 
8638
# FUNCTION
 
8639
#   Adding a user
 
8640
# INPUTS
 
8641
# OUTPUT
 
8642
# SOURCE
 
8643
#
 
8644
sub add_user {
 
8645
    debug("Adding a user");
 
8646
    my $userxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
8647
        'dialogPromptEntry', 'lyricue');
 
8648
    $userxml->signal_autoconnect_from_package('');
 
8649
    $userxml->get_widget('dialogPromptEntry')
 
8650
      ->set_title(fromutf(gettext("Add a user")));
 
8651
    $userxml->get_widget('labelPromptE')
 
8652
      ->set_text(fromutf(gettext("Enter username")));
 
8653
    my $confirm = $userxml->get_widget('dialogPromptEntry')->run();
 
8654
    if ($confirm eq "ok") {
 
8655
        my $users =
 
8656
          ($widgets->{'admin'}->get_widget('tableAccess')->get('n-rows') - 2);
 
8657
        debug("Users :" . $users);
 
8658
        $widgets->{'admin'}->get_widget('tableAccess')->resize($users + 3, 6);
 
8659
        $widgets->{'adminUsername'}[$users] =
 
8660
          Gtk2::Label->new($userxml->get_widget('entryPromptE')->get_text());
 
8661
        $widgets->{'admin'}->get_widget('tableAccess')
 
8662
          ->attach($widgets->{'adminUsername'}[$users],
 
8663
            0, 1, $users + 2, $users + 3, 'fill', 'expand', 0, 0);
 
8664
        $widgets->{'adminPlaylist'}[$users] = Gtk2::CheckButton->new();
 
8665
        $widgets->{'admin'}->get_widget('tableAccess')
 
8666
          ->attach($widgets->{'adminPlaylist'}[$users],
 
8667
            1, 2, $users + 2, $users + 3, 'fill', 'expand', 0, 0);
 
8668
        $widgets->{'adminEdit'}[$users] = Gtk2::CheckButton->new();
 
8669
        $widgets->{'admin'}->get_widget('tableAccess')
 
8670
          ->attach($widgets->{'adminEdit'}[$users],
 
8671
            2, 3, $users + 2, $users + 3, 'fill', 'expand', 0, 0);
 
8672
        $widgets->{'adminDelete'}[$users] = Gtk2::CheckButton->new();
 
8673
        $widgets->{'admin'}->get_widget('tableAccess')
 
8674
          ->attach($widgets->{'adminDelete'}[$users],
 
8675
            3, 4, $users + 2, $users + 3, 'fill', 'expand', 0, 0);
 
8676
        $widgets->{'adminDisplay'}[$users] = Gtk2::CheckButton->new();
 
8677
        $widgets->{'admin'}->get_widget('tableAccess')
 
8678
          ->attach($widgets->{'adminDisplay'}[$users],
 
8679
            4, 5, $users + 2, $users + 3, 'fill', 'expand', 0, 0);
 
8680
        $widgets->{'adminAdmin'}[$users] = Gtk2::CheckButton->new();
 
8681
        $widgets->{'admin'}->get_widget('tableAccess')
 
8682
          ->attach($widgets->{'adminAdmin'}[$users],
 
8683
            5, 6, $users + 2, $users + 3, 'fill', 'expand', 0, 0);
 
8684
    }
 
8685
    $widgets->{'admin'}->get_widget('tableAccess')->show_all();
 
8686
    close_dialog($userxml->get_widget('dialogPromptEntry'));
 
8687
}
 
8688
 
 
8689
#***
 
8690
 
 
8691
#****f* lyricue/search_changed
 
8692
# NAME
 
8693
#   search_changed
 
8694
# SYNOPSIS
 
8695
#   search_changed()
 
8696
# FUNCTION
 
8697
#   Search changed
 
8698
# INPUTS
 
8699
# OUTPUT
 
8700
# SOURCE
 
8701
#
 
8702
sub search_changed {
 
8703
    debug("Search changed");
 
8704
    reset_timer($globals->{'update_timer'});
 
8705
    $globals->{'update_timer'} = Glib::Timeout->add(500, \&update_available);
 
8706
}
 
8707
 
 
8708
#***
 
8709
 
 
8710
#****f* lyricue/search_activated
 
8711
# NAME
 
8712
#   search_activated
 
8713
# SYNOPSIS
 
8714
#   search_activated()
 
8715
# FUNCTION
 
8716
#   Search activated
 
8717
# INPUTS
 
8718
# OUTPUT
 
8719
# SOURCE
 
8720
#
 
8721
sub search_activated{
 
8722
    debug("Search activated");
 
8723
    my $model  = $widgets->{'main'}->get_widget('treeAvailable')->get_model;
 
8724
    my $iter   = $model->get_iter_first;
 
8725
    if (defined $iter) {
 
8726
        my $songid = $model->get($iter, 3);
 
8727
        add_single_song($songid);
 
8728
        update_playlist();
 
8729
    }
 
8730
}
 
8731
 
 
8732
#***
 
8733
 
 
8734
#****f* lyricue/init_preview
 
8735
# NAME
 
8736
#   init_preview
 
8737
# SYNOPSIS
 
8738
#   init_preview()
 
8739
# FUNCTION
 
8740
#   init preview
 
8741
# INPUTS
 
8742
# OUTPUT
 
8743
# SOURCE
 
8744
#
 
8745
sub init_preview {
 
8746
    debug("init preview");
 
8747
 
 
8748
    # Start/stop preview as needed
 
8749
    if ($config->{'DynamicPreview'}) {
 
8750
        if (!defined($widgets->{'preview'})) {
 
8751
            $widgets->{'main'}->get_widget('labelPreview')->show();
 
8752
            $widgets->{'main'}->get_widget('framePreview')->show();
 
8753
            $widgets->{'main'}->get_widget('framePreview')
 
8754
              ->set_size_request(100, 75);
 
8755
            $widgets->{'preview'} = Gtk2::Socket->new;
 
8756
            $widgets->{'preview'}->show;
 
8757
            $widgets->{'main'}->get_widget('framePreview')
 
8758
              ->add($widgets->{'preview'});
 
8759
            $widgets->{'preview'}->set_size_request(-1, -1);
 
8760
 
 
8761
            debug(
 
8762
                sprintf(
 
8763
                    "%s -r %s -m %d -p %d",
 
8764
                    $globals->{'lyricue_server'} , $globals->{'mysqlhost'}, $widgets->{'preview'}->get_id,
 
8765
                    $globals->{'preview_port'}
 
8766
                )
 
8767
            );
 
8768
 
 
8769
            $globals->{'preview_pid'} = fork;
 
8770
            if ($globals->{'preview_pid'} < 0) {
 
8771
                display_fatal(
 
8772
                    "Unable to start the lyricue server as a preview window",
 
8773
                    $! . "\nSQL: " . $query);
 
8774
            }
 
8775
            if ($globals->{'preview_pid'} == 0) {
 
8776
                my $debug_cmd = "";
 
8777
                if ($globals->{'debugging'}) {
 
8778
                    $debug_cmd = "-d";
 
8779
                }
 
8780
                exec(
 
8781
                    sprintf(
 
8782
                        "%s -r %s -m %d -p %d %s\n",
 
8783
                        $globals->{'lyricue_server'} ,
 
8784
                        $globals->{'mysqlhost'},
 
8785
                        $widgets->{'preview'}->get_id,
 
8786
                        $globals->{'preview_port'},
 
8787
                        $debug_cmd
 
8788
                    )
 
8789
                );
 
8790
            }
 
8791
            $widgets->{'preview'}->signal_connect(
 
8792
                'plug-removed' => sub {
 
8793
                    debug("Lyricue preview died..restarting\n");
 
8794
                    $widgets->{'main'}->get_widget('framePreview')
 
8795
                      ->remove($widgets->{'preview'});
 
8796
                    init_preview();
 
8797
                    1;
 
8798
                }
 
8799
            );
 
8800
        }
 
8801
    } else {
 
8802
        if ($widgets->{'preview'}) {
 
8803
            $widgets->{'preview'}->destroy;
 
8804
            undef $widgets->{'preview'};
 
8805
            kill 9, $globals->{'preview_pid'};
 
8806
        }
 
8807
        $widgets->{'main'}->get_widget('framePreview')->hide();
 
8808
        $widgets->{'main'}->get_widget('labelPreview')->hide();
 
8809
    }
 
8810
}
 
8811
 
 
8812
#***
 
8813
 
 
8814
#****f* lyricue/init_miniview
 
8815
# NAME
 
8816
#   init_miniview
 
8817
# SYNOPSIS
 
8818
#   init_miniview()
 
8819
# FUNCTION
 
8820
#   init miniview
 
8821
# INPUTS
 
8822
# OUTPUT
 
8823
# SOURCE
 
8824
#
 
8825
sub init_miniview {
 
8826
    debug("init miniview");
 
8827
 
 
8828
    # Start/stop miniview as needed
 
8829
    if ($config->{'Miniview'}) {
 
8830
        if (!defined($widgets->{'miniview'})) {
 
8831
            update_display("status", "previewon", "");
 
8832
            $widgets->{'main'}->get_widget('labelCurrent')->show();
 
8833
            $widgets->{'main'}->get_widget('frameCurrent')->show();
 
8834
            $widgets->{'miniview'} = Gtk2::Socket->new;
 
8835
            $widgets->{'miniview'}->set_size_request(100, 75);
 
8836
            $widgets->{'miniview'}->show;
 
8837
            $widgets->{'main'}->get_widget('frameCurrent')
 
8838
              ->add($widgets->{'miniview'});
 
8839
            $widgets->{'main'}->get_widget('frameCurrent')
 
8840
              ->set_size_request(-1, -1);
 
8841
            debug(
 
8842
                sprintf(
 
8843
                    "%s -r %s -m %d -p %d\n",
 
8844
                    $globals->{'lyricue_server'},
 
8845
                    $globals->{'mysqlhost'},
 
8846
                    $widgets->{'miniview'}->get_id,
 
8847
                    $globals->{'miniview_port'}
 
8848
                )
 
8849
            );
 
8850
 
 
8851
            $globals->{'miniview_pid'} = fork;
 
8852
            if ($globals->{'miniview_pid'} < 0) {
 
8853
                display_fatal(
 
8854
                    "Unable to start the lyricue server as a preview window",
 
8855
                    $! . "\nSQL: " . $query);
 
8856
            }
 
8857
            if ($globals->{'miniview_pid'} == 0) {
 
8858
                exec(
 
8859
                    sprintf(
 
8860
                        "%s -r %s -m %d -p %d\n",
 
8861
                        $globals->{'lyricue_server'},
 
8862
                        $globals->{'mysqlhost'},
 
8863
                        $widgets->{'miniview'}->get_id,
 
8864
                        $globals->{'miniview_port'}
 
8865
                    )
 
8866
                );
 
8867
            }
 
8868
 
 
8869
            $widgets->{'miniview'}->signal_connect(
 
8870
                'plug-removed' => sub {
 
8871
                    debug("Lyricue miniview died..restarting");
 
8872
                    $widgets->{'main'}->get_widget('frameCurrent')
 
8873
                      ->remove($widgets->{'miniview'});
 
8874
                    init_miniview();
 
8875
                    1;
 
8876
                }
 
8877
            );
 
8878
        }
 
8879
    } else {
 
8880
        if ($widgets->{'miniview'}) {
 
8881
            $widgets->{'miniview'}->destroy;
 
8882
            undef $widgets->{'miniview'};
 
8883
            kill 9, $globals->{'miniview_pid'};
 
8884
        }
 
8885
        update_display("status", "previewoff", "");
 
8886
        $widgets->{'main'}->get_widget('frameCurrent')->hide();
 
8887
        $widgets->{'main'}->get_widget('labelCurrent')->hide();
 
8888
    }
 
8889
}
 
8890
 
 
8891
#***
 
8892
 
 
8893
#****f* lyricue/quick_save
 
8894
# NAME
 
8895
#   quick_save
 
8896
# SYNOPSIS
 
8897
#   quick_save()
 
8898
# FUNCTION
 
8899
#   Quick Save
 
8900
# INPUTS
 
8901
# OUTPUT
 
8902
# SOURCE
 
8903
#
 
8904
sub quick_save {
 
8905
    debug("Quick Save");
 
8906
    my $buffer    = $widgets->{'main'}->get_widget('textQuick')->get_buffer();
 
8907
    my $songtext  = $buffer->get_text($buffer->get_bounds, FALSE);
 
8908
    my $playorder = $widgets->{'main'}->get_widget('textQuick')->{user_data};
 
8909
    my $query = "SELECT data,type FROM playlist WHERE playorder=" . $playorder;
 
8910
    qdebug($query);
 
8911
    $sth = $lyricDbh->prepare($query)
 
8912
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
8913
    $rv = $sth->execute
 
8914
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
8915
    my @row = $sth->fetchrow_array();
 
8916
 
 
8917
    if ($row[1] eq "play") {
 
8918
        $query =
 
8919
            "SELECT data,type FROM playlist WHERE playlist="
 
8920
          . $row[0]
 
8921
          . " ORDER BY playorder";
 
8922
        qdebug($query);
 
8923
        $sth = $lyricDbh->prepare($query)
 
8924
          || display_fatal($errorcodes->{'sqlprepare'},
 
8925
            $! . "\nSQL: " . $query);
 
8926
        $rv = $sth->execute
 
8927
          || display_fatal($errorcodes->{'sqlexecute'},
 
8928
            $! . "\nSQL: " . $query);
 
8929
        @row = $sth->fetchrow_array();
 
8930
    }
 
8931
 
 
8932
    if ($row[1] eq "song") {
 
8933
        if (!defined $row[0]) { $row[0] = ""; }
 
8934
 
 
8935
        $query =
 
8936
            "UPDATE page SET lyrics="
 
8937
          . $lyricDbh->quote($songtext)
 
8938
          . " WHERE pageid="
 
8939
          . $row[0];
 
8940
        qdebug($query);
 
8941
        $sth = $lyricDbh->prepare($query)
 
8942
          || display_fatal($errorcodes->{'sqlprepare'},
 
8943
            $! . "\nSQL: " . $query);
 
8944
        $sth->execute
 
8945
          || display_fatal($errorcodes->{'sqlexecute'},
 
8946
            $! . "\nSQL: " . $query);
 
8947
    }
 
8948
}
 
8949
 
 
8950
# Just put the text in the quickview section onto the screen
 
8951
#***
 
8952
 
 
8953
#****f* lyricue/quick_show
 
8954
# NAME
 
8955
#   quick_show
 
8956
# SYNOPSIS
 
8957
#   quick_show()
 
8958
# FUNCTION
 
8959
#   Quickshow textarea
 
8960
# INPUTS
 
8961
# OUTPUT
 
8962
# SOURCE
 
8963
#
 
8964
sub quick_show {
 
8965
    debug("Quickshow textarea");
 
8966
    my $buffer = $widgets->{'main'}->get_widget('textQuick')->get_buffer();
 
8967
    my $songtext = $buffer->get_text($buffer->get_bounds, FALSE);
 
8968
    $songtext =~ s/\n/#BREAK#/g;
 
8969
    $songtext =~ s/:/#SEMI#/g;
 
8970
    update_display("preview", "ignore", $songtext);
 
8971
}
 
8972
 
 
8973
#***
 
8974
 
 
8975
#****f* lyricue/quick_osd
 
8976
# NAME
 
8977
#   quick_osd
 
8978
# SYNOPSIS
 
8979
#   quick_osd()
 
8980
# FUNCTION
 
8981
#   Quickshow OSD
 
8982
# INPUTS
 
8983
# OUTPUT
 
8984
# SOURCE
 
8985
#
 
8986
sub quick_osd {
 
8987
    my ($widget) = @_;
 
8988
    debug("Update OSD");
 
8989
debug($widget->get_name);
 
8990
    my $songtext = "";
 
8991
    if (($widgets->{'main'}->get_widget('buttonQuickOSD')->get_active()) || ($widget->get_name eq "entryMainOSD")) {
 
8992
        $songtext = $widgets->{'main'}->get_widget('entryMainOSD')->get_text;
 
8993
        $songtext =~ s/\n/#BREAK#/g;
 
8994
        $songtext =~ s/:/#SEMI#/g;
 
8995
    }
 
8996
    update_display("osd", "default", $songtext);
 
8997
}
 
8998
 
 
8999
#***
 
9000
 
 
9001
#****f* lyricue/resize_preview
 
9002
# NAME
 
9003
#   resize_preview
 
9004
# SYNOPSIS
 
9005
#   resize_preview($widget, $event)
 
9006
# FUNCTION
 
9007
#   Called when the preview windows are resized
 
9008
# INPUTS
 
9009
#   $widget -
 
9010
#    $event -
 
9011
# OUTPUT
 
9012
# SOURCE
 
9013
#
 
9014
sub resize_preview {
 
9015
    my ($widget, $event) = @_;
 
9016
 
 
9017
   #print $event."\n";
 
9018
   #debug ("Resizing previews");
 
9019
   #my $pos = $widgets->{'main'}->get_widget('hpanedMainRight')->get_position();
 
9020
   #my ($width,$height) = $widgets->{'preview'}->get_size();
 
9021
   #print ("$width * $height\n");
 
9022
    return FALSE;
 
9023
}
 
9024
 
 
9025
# Return a Gdk::Pixbuf of the given media at the given res
 
9026
#***
 
9027
 
 
9028
#****f* lyricue/create_pixbuf
 
9029
# NAME
 
9030
#   create_pixbuf
 
9031
# SYNOPSIS
 
9032
#   create_pixbuf($data, $width, $height)
 
9033
# FUNCTION
 
9034
#
 
9035
# INPUTS
 
9036
#   $data -
 
9037
#    $width -
 
9038
#    $height -
 
9039
# OUTPUT
 
9040
# SOURCE
 
9041
#
 
9042
sub create_pixbuf {
 
9043
    my ($data, $width, $height) = @_;
 
9044
    my ($pixbuf);
 
9045
    my ($type, $id) = split /;/, $data;
 
9046
    if ($type eq "dir") {
 
9047
        if (-d $id) {
 
9048
            return;
 
9049
        }
 
9050
        if (($width > $globals->{'thumb_width'}) || ($width == 0)) {
 
9051
 
 
9052
            # Bigger than cache value so just send new pixbuf
 
9053
            eval {
 
9054
                $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file_at_scale($id, $width,
 
9055
                    $height, TRUE);
 
9056
            };
 
9057
            # Try thumbnailing with video thumbnailer
 
9058
            my $thumbfile = "/tmp/lyricue-tmpthumb.png";
 
9059
            if (-e $thumbfile) {
 
9060
                unlink $thumbfile;
 
9061
            }
 
9062
            if ($@) {
 
9063
                $id =~  s/\/*/\//g;
 
9064
                my $command =
 
9065
                        $globals->{'video-thumbnailer'}
 
9066
                      . " --time=2 \""
 
9067
                      . $id . "\" \""
 
9068
                      . $thumbfile . "\"";
 
9069
                system($command);
 
9070
                if (-e $thumbfile) {
 
9071
                    $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($thumbfile);
 
9072
                    $pixbuf = $pixbuf->scale_simple($width, $height, 'bilinear');
 
9073
                } else {
 
9074
                    return undef;
 
9075
                }
 
9076
            } else {
 
9077
                return $pixbuf;
 
9078
            }
 
9079
        }
 
9080
        my $mtime = (stat($id))[9];
 
9081
        $id =~  s/\/+/\//g;
 
9082
        my $filename =
 
9083
          $globals->{'thumbnail_factory'}->lookup("file://" . $id, $mtime);
 
9084
        if (!defined $filename) {
 
9085
            if ($globals->{'thumbnail_factory'}
 
9086
                ->has_valid_failed_thumbnail("file://" . $id, $mtime))
 
9087
            {
 
9088
                return undef;
 
9089
            } else {
 
9090
                $pixbuf =
 
9091
                  $globals->{'thumbnail_factory'}
 
9092
                  ->generate_thumbnail("file://" . $id, $mtime);
 
9093
                if ($pixbuf) {
 
9094
                    $globals->{'thumbnail_factory'}
 
9095
                      ->save_thumbnail($pixbuf, "file://" . $id, $mtime);
 
9096
                    $pixbuf = $pixbuf->scale_simple($width, $height, 'bilinear');
 
9097
                } else {
 
9098
 
 
9099
                    # Try thumbnailing with video thumbnailer
 
9100
                    my $thumbfile = "/tmp/lyricue-tmpthumb.png";
 
9101
                    if (-e $thumbfile) {
 
9102
                        unlink $thumbfile;
 
9103
                    }
 
9104
                    my $command =
 
9105
                        $globals->{'video-thumbnailer'}
 
9106
                      . " --time=2 \""
 
9107
                      . $id . "\" \""
 
9108
                      . $thumbfile . "\"";
 
9109
                    system($command);
 
9110
                    if (-e $thumbfile) {
 
9111
                        $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($thumbfile);
 
9112
                        $globals->{'thumbnail_factory'}
 
9113
                          ->save_thumbnail($pixbuf, "file://" . $id, $mtime);
 
9114
                        $pixbuf = $pixbuf->scale_simple($width, $height, 'bilinear');
 
9115
                    } else {
 
9116
                        return undef;
 
9117
                    }
 
9118
                }
 
9119
            }
 
9120
        } else {
 
9121
            $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file_at_scale($filename, $width, $height, TRUE);
 
9122
        }
 
9123
        return $pixbuf;
 
9124
    } else {
 
9125
        my $query = "SELECT format, description, data FROM media WHERE id=\"" 
 
9126
          . $id . "\"";
 
9127
        qdebug($query);
 
9128
        my $sth = $mediaDbh->prepare($query)
 
9129
          || display_fatal($errorcodes->{'sqlprepare'},
 
9130
            $! . "\nSQL: " . $query);
 
9131
        my $rv = $sth->execute
 
9132
          || display_fatal($errorcodes->{'sqlexecute'},
 
9133
            $! . "\nSQL: " . $query);
 
9134
        my $row = $sth->fetchrow_hashref();
 
9135
        if ($row->{'format'} eq "bg") {
 
9136
            my @xpm = ("1 1 1 1", "  c " . $row->{'description'}, " ");
 
9137
            $pixbuf = Gtk2::Gdk::Pixbuf->new_from_xpm_data(@xpm);
 
9138
        } else {
 
9139
            my $pixbuf_loader = Gtk2::Gdk::PixbufLoader->new();
 
9140
            eval { $pixbuf_loader->write($row->{'data'}); };
 
9141
            eval { $pixbuf_loader->close() };
 
9142
            if ($@) {
 
9143
                my @xpm = ("1 1 1 1", "  c " . $row->{'description'}, " ");
 
9144
                $pixbuf = Gtk2::Gdk::Pixbuf->new_from_xpm_data(@xpm);
 
9145
            } else {
 
9146
                $pixbuf = $pixbuf_loader->get_pixbuf();
 
9147
            }
 
9148
        }
 
9149
 
 
9150
        if ($width == 0) {
 
9151
            return $pixbuf;
 
9152
        } else {
 
9153
            return $pixbuf->scale_simple($width, $height, 'nearest');
 
9154
        }
 
9155
    }
 
9156
}
 
9157
 
 
9158
#***
 
9159
 
 
9160
#****f* lyricue/import_image
 
9161
# NAME
 
9162
#   import_image
 
9163
# SYNOPSIS
 
9164
#   import_image()
 
9165
# FUNCTION
 
9166
#
 
9167
# INPUTS
 
9168
# OUTPUT
 
9169
# SOURCE
 
9170
#
 
9171
sub import_image {
 
9172
    import_media("img");
 
9173
}
 
9174
 
 
9175
#***
 
9176
 
 
9177
#****f* lyricue/import_background
 
9178
# NAME
 
9179
#   import_background
 
9180
# SYNOPSIS
 
9181
#   import_background()
 
9182
# FUNCTION
 
9183
#
 
9184
# INPUTS
 
9185
# OUTPUT
 
9186
# SOURCE
 
9187
#
 
9188
sub import_background {
 
9189
    import_media("bg");
 
9190
}
 
9191
 
 
9192
#***
 
9193
 
 
9194
#****f* lyricue/import_media
 
9195
# NAME
 
9196
#   import_media
 
9197
# SYNOPSIS
 
9198
#   import_media($type)
 
9199
# FUNCTION
 
9200
#   Import media
 
9201
# INPUTS
 
9202
#   $type -
 
9203
# OUTPUT
 
9204
# SOURCE
 
9205
#
 
9206
sub import_media {
 
9207
    my ($type) = @_;
 
9208
    debug("Import media to db of type:" . $type);
 
9209
    my $filexml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
9210
        'dialogFileChooser', 'lyricue');
 
9211
    $filexml->signal_autoconnect_from_package('');
 
9212
    $filexml->get_widget('buttonFileOK')
 
9213
      ->signal_connect("clicked", "select_category", $filexml);
 
9214
    $filexml->get_widget('dialogFileChooser')->{user_data} = $type;
 
9215
    $filexml->get_widget('dialogFileChooser')->set_select_multiple(TRUE);
 
9216
    $filexml->get_widget('dialogFileChooser')->show_all();
 
9217
}
 
9218
 
 
9219
#***
 
9220
 
 
9221
#****f* lyricue/select_category
 
9222
# NAME
 
9223
#   select_category
 
9224
# SYNOPSIS
 
9225
#   select_category($widget, $filexml)
 
9226
# FUNCTION
 
9227
#   select category
 
9228
# INPUTS
 
9229
#   $widget -
 
9230
#    $filexml -
 
9231
# OUTPUT
 
9232
# SOURCE
 
9233
#
 
9234
sub select_category {
 
9235
    my ($widget, $filexml) = @_;
 
9236
    debug("select category");
 
9237
    my $hashnum   = 0;
 
9238
    my @filenames = $filexml->get_widget('dialogFileChooser')->get_filenames;
 
9239
    debug(@filenames);
 
9240
    my $type = $filexml->get_widget('dialogFileChooser')->{user_data};
 
9241
    close_dialog($filexml->get_widget('dialogFileChooser'));
 
9242
    my $choosexml =
 
9243
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogSelectCategory');
 
9244
 
 
9245
    my $query =
 
9246
        "SELECT DISTINCT category FROM media WHERE type=\"" 
 
9247
      . $type
 
9248
      . "\" ORDER BY category";
 
9249
    qdebug($query);
 
9250
    my $sth = $mediaDbh->prepare($query)
 
9251
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
9252
    my $rv = $sth->execute
 
9253
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
9254
    my @row;
 
9255
    my $model = Gtk2::ListStore->new('Glib::String');
 
9256
    $choosexml->get_widget('comboSelectCategory')->set_model($model);
 
9257
    $choosexml->get_widget('comboSelectCategory')->set_text_column(0);
 
9258
 
 
9259
    while (@row = $sth->fetchrow_array()) {
 
9260
        $choosexml->get_widget('comboSelectCategory')->append_text($row[0]);
 
9261
    }
 
9262
    my $confirm = $choosexml->get_widget('dialogSelectCategory')->run;
 
9263
    if ($confirm == 1) {
 
9264
        if ($choosexml->get_widget('comboSelectCategory')->get_active_text() eq
 
9265
            "")
 
9266
        {
 
9267
            return;
 
9268
        }
 
9269
        debug("Importing media");
 
9270
        my $category =
 
9271
          $choosexml->get_widget('comboSelectCategory')->get_active_text();
 
9272
        my $filename = "";
 
9273
        foreach $filename (@filenames) {
 
9274
            my $format = $filename;
 
9275
            $format =~ s/^.*\.//g;
 
9276
            my $description = $filename;
 
9277
            $description =~ s/^.*\///g;
 
9278
            $description =~ s/\..*?$//g;
 
9279
            my $owner = getpwuid($<);
 
9280
            debug("Category: $category\nFilename: $filename");
 
9281
            open(MEDIA, $filename);
 
9282
            my $data = "";
 
9283
 
 
9284
            while (<MEDIA>) {
 
9285
                $data .= $_;
 
9286
            }
 
9287
            close MEDIA;
 
9288
            debug("Length: " . length($data));
 
9289
            my $sth = $mediaDbh->prepare(
 
9290
q{INSERT INTO media(category, subcategory, type, format, insertedby, insertdate, description, data) VALUES (?,?,?,?,?,NOW(),?,?)}
 
9291
            );
 
9292
            my $rv =
 
9293
              $sth->execute($category, "", $type, $format, $owner, $description,
 
9294
                $data);
 
9295
        }
 
9296
    }
 
9297
    close_dialog($choosexml->get_widget('dialogSelectCategory'));
 
9298
    my $category =
 
9299
      $widgets->{'image'}->get_widget('optionImageCategory')
 
9300
      ->get_menu->get_active->{user_data};
 
9301
    update_imagedir(
 
9302
        $widgets->{'image'}->get_widget('optionImageCategory')->{'user_data'},
 
9303
        $category);
 
9304
}
 
9305
 
 
9306
#***
 
9307
 
 
9308
#****f* lyricue/update_category
 
9309
# NAME
 
9310
#   update_category
 
9311
# SYNOPSIS
 
9312
#   update_category($selection, $choosexml)
 
9313
# FUNCTION
 
9314
#   Selected a category
 
9315
# INPUTS
 
9316
#   $selection -
 
9317
#    $choosexml -
 
9318
# OUTPUT
 
9319
# SOURCE
 
9320
#
 
9321
sub update_category {
 
9322
    my ($selection, $choosexml) = @_;
 
9323
    debug("Selected a category");
 
9324
 
 
9325
    my ($model, $iter) = $selection->get_selected;
 
9326
    if ($iter) {
 
9327
        $choosexml->get_widget('entryChoosePlay')
 
9328
          ->set_text($model->get($iter, 0));
 
9329
    }
 
9330
}
 
9331
 
 
9332
#***
 
9333
 
 
9334
#****f* lyricue/update_quickedit
 
9335
# NAME
 
9336
#   update_quickedit
 
9337
# SYNOPSIS
 
9338
#   update_quickedit()
 
9339
# FUNCTION
 
9340
#   Updating Quick edit
 
9341
# INPUTS
 
9342
# OUTPUT
 
9343
# SOURCE
 
9344
#
 
9345
sub update_quickedit {
 
9346
    debug("Updating Quick edit");
 
9347
    my $selection =
 
9348
      $widgets->{'main'}->get_widget('treePlaylist')->get_selection;
 
9349
    my ($model, $iter) = $selection->get_selected;
 
9350
    if ($iter) {
 
9351
        my $quicktext = "";
 
9352
 
 
9353
        my $plnumber = $model->get($iter, 2);
 
9354
        my $loop = 0;
 
9355
 
 
9356
        # Find the items lyrics for Quick Editing
 
9357
        while ($loop == 0) {
 
9358
            my $query =
 
9359
              "SELECT type,data,playlist FROM playlist WHERE playorder="
 
9360
              . $plnumber;
 
9361
            qdebug($query);
 
9362
            $sth = $lyricDbh->prepare($query)
 
9363
              || display_fatal($errorcodes->{'sqlprepare'},
 
9364
                $! . "\nSQL: " . $query);
 
9365
            $rv = $sth->execute
 
9366
              || display_fatal($errorcodes->{'sqlexecute'},
 
9367
                $! . "\nSQL: " . $query);
 
9368
            my @row = $sth->fetchrow_array();
 
9369
            if (defined($row[0])) {
 
9370
                if ($row[0] eq "song") {
 
9371
                    $query =
 
9372
"SELECT lyrics FROM playlist as pl, page as pa WHERE pl.data=pa.pageid AND pl.playorder="
 
9373
                      . $plnumber;
 
9374
                    qdebug($query);
 
9375
                    $sth = $lyricDbh->prepare($query)
 
9376
                      || display_fatal($errorcodes->{'sqlprepare'},
 
9377
                        $! . "\nSQL: " . $query);
 
9378
                    $rv = $sth->execute
 
9379
                      || display_fatal($errorcodes->{'sqlexecute'},
 
9380
                        $! . "\nSQL: " . $query);
 
9381
                    my @row2 = $sth->fetchrow_array();
 
9382
                    if (!defined $row2[0]) { $row2[0] = ""; }
 
9383
                    $quicktext = $row2[0];
 
9384
                    $loop      = 1;
 
9385
                    $widgets->{'main'}->get_widget('textQuick')
 
9386
                      ->set_wrap_mode('none');
 
9387
                    $quicktext = $quicktext;
 
9388
                } elsif ($row[0] eq "play") {
 
9389
                    $query =
 
9390
                        "SELECT playorder FROM playlist WHERE playlist="
 
9391
                      . $row[1]
 
9392
                      . " ORDER BY playorder";
 
9393
                    qdebug($query);
 
9394
                    $sth = $lyricDbh->prepare($query)
 
9395
                      || display_fatal($errorcodes->{'sqlprepare'},
 
9396
                        $! . "\nSQL: " . $query);
 
9397
                    $rv = $sth->execute
 
9398
                      || display_fatal($errorcodes->{'sqlexecute'},
 
9399
                        $! . "\nSQL: " . $query);
 
9400
                    my @row = $sth->fetchrow_array();
 
9401
                    $plnumber = $row[0];
 
9402
                    $loop     = 0;
 
9403
                } elsif ($row[0] eq "vers") {
 
9404
                    my ($startv, $endv) = split(/-/, $row[1], 2);
 
9405
                    $query = "SELECT title FROM playlists WHERE id=" . $row[2];
 
9406
                    qdebug($query);
 
9407
                    $sth = $lyricDbh->prepare($query)
 
9408
                      || display_fatal($errorcodes->{'sqlprepare'},
 
9409
                        $! . "\nSQL: " . $query);
 
9410
                    $rv = $sth->execute
 
9411
                      || display_fatal($errorcodes->{'sqlexecute'},
 
9412
                        $! . "\nSQL: " . $query);
 
9413
                    my @row = $sth->fetchrow_array();
 
9414
                    my @line = split(/:/, $row[0]);
 
9415
                    if ($globals->{'usesword'}) {
 
9416
                        my $command = sprintf(
 
9417
"%s -b %s -e UTF8 -k '%s' %d:%d-%d:%d |tr \\\\n \' \'",
 
9418
                            $globals->{'diatheke'}, $globals->{'bibledb'},
 
9419
                            $line[0],               $line[1],
 
9420
                            $startv,                $line[1],
 
9421
                            $endv,                  $line[0]
 
9422
                        );
 
9423
                        debug($command);
 
9424
                        my $command_out = fromutf(`$command`);
 
9425
                        ($line[0], undef) = split(/\s\d/, $command_out, 2);
 
9426
                        my @command_lines = split(/$line[0] /, $command_out);
 
9427
                        my $lineno = 0;
 
9428
                        foreach $lineno (1 .. @command_lines) {
 
9429
                            my $line2 = $command_lines[$lineno - 1];
 
9430
                            chomp($line2);
 
9431
                            if ($line2 ne "") {
 
9432
                                if ($lineno != @command_lines) {
 
9433
                                    $line2 .= "\n";
 
9434
                                }
 
9435
                                $quicktext .= $line2;
 
9436
                            }
 
9437
                        }
 
9438
                    } else {
 
9439
                        my ($table, $dbname) =
 
9440
                          split(/@/, $globals->{'bibledb'}, 2);
 
9441
                        $query =
 
9442
                            "SELECT chapternum,versenum,verse FROM " 
 
9443
                          . $table
 
9444
                          . " WHERE book=\""
 
9445
                          . $line[0]
 
9446
                          . "\" AND chapternum="
 
9447
                          . $line[1]
 
9448
                          . " AND versenum>="
 
9449
                          . $startv
 
9450
                          . " AND versenum <= "
 
9451
                          . $endv;
 
9452
                        qdebug($query);
 
9453
                        $sth = $bibleDbh->prepare($query)
 
9454
                          || display_fatal(
 
9455
                            $errorcodes->{'sqlprepare'},
 
9456
                            $! . "\nSQL: " . $query
 
9457
                          );
 
9458
                        $rv = $sth->execute
 
9459
                          || display_fatal(
 
9460
                            $errorcodes->{'sqlexecute'},
 
9461
                            $! . "\nSQL: " . $query
 
9462
                          );
 
9463
 
 
9464
                        while (@row = $sth->fetchrow_array()) {
 
9465
                            $quicktext .=
 
9466
                              $row[0] . ":" . $row[1] . "   " . $row[2] . "\n";
 
9467
                        }
 
9468
                        $quicktext = fromutf($quicktext);
 
9469
                    }
 
9470
                    $loop = 1;
 
9471
                    $widgets->{'main'}->get_widget('textQuick')
 
9472
                      ->set_wrap_mode('word');
 
9473
                } elsif ($row[0] eq "imag") {
 
9474
                    $quicktext = "Image";
 
9475
                    $loop      = 1;
 
9476
                } elsif ($row[0] eq "back") {
 
9477
                    $quicktext = "Background";
 
9478
                    $loop      = 1;
 
9479
                } else {
 
9480
                    $loop = 1;
 
9481
                }
 
9482
            } else {
 
9483
                $loop = 1;
 
9484
            }
 
9485
        }
 
9486
 
 
9487
        $widgets->{'main'}->get_widget('textQuick')
 
9488
          ->get_buffer->set_text($quicktext);
 
9489
        $widgets->{'main'}->get_widget('textQuick')->{user_data} =
 
9490
          $model->get($iter, 2);
 
9491
        $sth->finish;
 
9492
    }
 
9493
}
 
9494
 
 
9495
#***
 
9496
 
 
9497
#****f* lyricue/media_move
 
9498
# NAME
 
9499
#   media_move
 
9500
# SYNOPSIS
 
9501
#   media_move()
 
9502
# FUNCTION
 
9503
#   Moving media
 
9504
# INPUTS
 
9505
# OUTPUT
 
9506
# SOURCE
 
9507
#
 
9508
sub media_move {
 
9509
    debug("Moving media");
 
9510
    my $selection = $widgets->{'image'}->get_widget('treeImage')->get_selection;
 
9511
    my @selecteditems = $selection->get_selected_rows();
 
9512
    my @id            = ();
 
9513
    my $type =
 
9514
      $widgets->{'image'}->get_widget('optionImageCategory')->{'user_data'};
 
9515
    if ($selecteditems[0]) {
 
9516
        foreach (@selecteditems) {
 
9517
            my $iter =
 
9518
              $widgets->{'image'}->get_widget('treeImage')
 
9519
              ->get_model->get_iter($_);
 
9520
            push @id,
 
9521
              $widgets->{'image'}->get_widget('treeImage')
 
9522
              ->get_model->get($iter, 1);
 
9523
        }
 
9524
    }
 
9525
    if (@id) {
 
9526
        my $choosexml =
 
9527
          Gtk2::GladeXML->new($globals->{'gladefile'}, 'windowChoosePlay');
 
9528
        $choosexml->get_widget('windowChoosePlay')
 
9529
          ->set_title(fromutf(gettext("Select Category")));
 
9530
        $choosexml->get_widget('buttonLoad')->set_label("Select");
 
9531
        $choosexml->get_widget('buttonDelete')->hide();
 
9532
        $choosexml->get_widget('buttonRename')->hide();
 
9533
        $choosexml->get_widget('buttonLoad')
 
9534
          ->signal_connect("clicked", "do_move_media", $choosexml);
 
9535
        $choosexml->get_widget('buttonNew')
 
9536
          ->signal_connect("clicked", "do_move_media", $choosexml);
 
9537
        $choosexml->get_widget('buttonCancel')
 
9538
          ->signal_connect("clicked", "close_dialog");
 
9539
        $choosexml->get_widget('windowChoosePlay')->show;
 
9540
        $choosexml->get_widget('treeChoosePlay')->{'user_data'}   = $type;
 
9541
        $choosexml->get_widget('windowChoosePlay')->{'user_data'} = \@id;
 
9542
        my $store = $choosexml->get_widget('treeChoosePlay')->get_model();
 
9543
 
 
9544
        if ($store) {
 
9545
            $store->clear;
 
9546
        } else {
 
9547
            $store = Gtk2::ListStore->new('Glib::String');
 
9548
            $choosexml->get_widget('treeChoosePlay')->set_model($store);
 
9549
            my $renderer = Gtk2::CellRendererText->new;
 
9550
            my $selection =
 
9551
              $choosexml->get_widget('treeChoosePlay')->get_selection;
 
9552
            $selection->signal_connect("changed", "update_category",
 
9553
                $choosexml);
 
9554
            my $column =
 
9555
              Gtk2::TreeViewColumn->new_with_attributes("Category", $renderer,
 
9556
                text => 0);
 
9557
            $choosexml->get_widget('treeChoosePlay')->append_column($column);
 
9558
        }
 
9559
 
 
9560
        my $query =
 
9561
            "SELECT DISTINCT category FROM media WHERE type=\"" 
 
9562
          . $type
 
9563
          . "\" ORDER BY category";
 
9564
        my $sth = $mediaDbh->prepare($query)
 
9565
          || display_fatal($errorcodes->{'sqlprepare'},
 
9566
            $! . "\nSQL: " . $query);
 
9567
        my $rv = $sth->execute
 
9568
          || display_fatal($errorcodes->{'sqlexecute'},
 
9569
            $! . "\nSQL: " . $query);
 
9570
        my @row;
 
9571
        while (@row = $sth->fetchrow_array()) {
 
9572
            my $iter = $store->append;
 
9573
            $store->set($iter, 0, $row[0]);
 
9574
        }
 
9575
    }
 
9576
}
 
9577
 
 
9578
#***
 
9579
 
 
9580
#****f* lyricue/do_move_media
 
9581
# NAME
 
9582
#   do_move_media
 
9583
# SYNOPSIS
 
9584
#   do_move_media($widget, $choosexml)
 
9585
# FUNCTION
 
9586
#   Moving media
 
9587
# INPUTS
 
9588
#   $widget -
 
9589
#    $choosexml -
 
9590
# OUTPUT
 
9591
# SOURCE
 
9592
#
 
9593
sub do_move_media {
 
9594
    my ($widget, $choosexml) = @_;
 
9595
    debug("Moving media");
 
9596
    if ($choosexml->get_widget('entryChoosePlay')->get_text() ne "") {
 
9597
        my $type     = $choosexml->get_widget('treeChoosePlay')->{'user_data'};
 
9598
        my $category = $choosexml->get_widget('entryChoosePlay')->get_text();
 
9599
        my $id = $choosexml->get_widget('windowChoosePlay')->{'user_data'};
 
9600
        foreach (@$id) {
 
9601
            my $query =
 
9602
                "UPDATE media SET category=\""
 
9603
              . $category
 
9604
              . "\" WHERE id=\""
 
9605
              . $_ . "\"";
 
9606
            qdebug($query);
 
9607
            $sth = $mediaDbh->prepare($query)
 
9608
              || display_fatal($errorcodes->{'sqlprepare'},
 
9609
                $! . "\nSQL: " . $query);
 
9610
            $rv = $sth->execute
 
9611
              || display_fatal($errorcodes->{'sqlexecute'},
 
9612
                $! . "\nSQL: " . $query);
 
9613
        }
 
9614
    }
 
9615
    close_dialog($widget);
 
9616
    my $category =
 
9617
      $widgets->{'image'}->get_widget('optionImageCategory')
 
9618
      ->get_menu->get_active->{user_data};
 
9619
    update_imagedir(
 
9620
        $widgets->{'image'}->get_widget('optionImageCategory')->{'user_data'},
 
9621
        $category);
 
9622
}
 
9623
 
 
9624
#***
 
9625
 
 
9626
#****f* lyricue/media_delete
 
9627
# NAME
 
9628
#   media_delete
 
9629
# SYNOPSIS
 
9630
#   media_delete()
 
9631
# FUNCTION
 
9632
#   Deleting media
 
9633
# INPUTS
 
9634
# OUTPUT
 
9635
# SOURCE
 
9636
#
 
9637
sub media_delete {
 
9638
    debug("Deleting media");
 
9639
    my $selection = $widgets->{'image'}->get_widget('treeImage')->get_selection;
 
9640
    my @selecteditems = $selection->get_selected_rows();
 
9641
    my @id            = ();
 
9642
    if ($selecteditems[0]) {
 
9643
        my $title = "";
 
9644
        foreach (@selecteditems) {
 
9645
            my $iter =
 
9646
              $widgets->{'image'}->get_widget('treeImage')
 
9647
              ->get_model->get_iter($_);
 
9648
            push @id,
 
9649
              $widgets->{'image'}->get_widget('treeImage')
 
9650
              ->get_model->get($iter, 1);
 
9651
            $title .= "\""
 
9652
              . $widgets->{'image'}->get_widget('treeImage')
 
9653
              ->get_model->get($iter, 0) . "\", ";
 
9654
        }
 
9655
        if ($title ne "") {
 
9656
            $title =~ s/, $//;
 
9657
            debug("Deleting $title");
 
9658
            my $labelText =
 
9659
              fromutf(gettext("Are you sure you wish to delete ")) 
 
9660
              . $title . "\n";
 
9661
            my $deletexml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
9662
                'dialogConfirm', 'lyricue');
 
9663
            $deletexml->signal_autoconnect_from_package('');
 
9664
            $deletexml->get_widget('labelDelete')->set_text($labelText);
 
9665
            $deletexml->get_widget('dialogConfirm')
 
9666
              ->set_title(fromutf(gettext("Confirm Delete Image")));
 
9667
            my $confirm = $deletexml->get_widget('dialogConfirm')->run();
 
9668
 
 
9669
            if ($confirm eq "ok") {
 
9670
 
 
9671
                foreach (@id) {
 
9672
                    $_ =~ s/^db;//g;
 
9673
                    my $query = "DELETE FROM media WHERE id=" . $_;
 
9674
                    qdebug($query);
 
9675
                    my $sth = $mediaDbh->prepare($query)
 
9676
                      || display_fatal($errorcodes->{'sqlprepare'},
 
9677
                        $! . "\nSQL: " . $query);
 
9678
                    my $rv = $sth->execute
 
9679
                      || display_fatal($errorcodes->{'sqlexecute'},
 
9680
                        $! . "\nSQL: " . $query);
 
9681
 
 
9682
                    close_dialog($deletexml->get_widget('dialogConfirm'));
 
9683
                    my $category =
 
9684
                      $widgets->{'image'}->get_widget('optionImageCategory')
 
9685
                      ->get_menu->get_active->{user_data};
 
9686
                    update_imagedir(
 
9687
                        $widgets->{'image'}->get_widget('optionImageCategory')
 
9688
                          ->{'user_data'},
 
9689
                        $category
 
9690
                    );
 
9691
                }
 
9692
            }
 
9693
        }
 
9694
    }
 
9695
 
 
9696
}
 
9697
 
 
9698
#***
 
9699
 
 
9700
#****f* lyricue/rename_media
 
9701
# NAME
 
9702
#   rename_media
 
9703
# SYNOPSIS
 
9704
#   rename_media($widget, $id, $newname)
 
9705
# FUNCTION
 
9706
#   rename media
 
9707
# INPUTS
 
9708
#   $widget -
 
9709
#    $id -
 
9710
#    $newname -
 
9711
# OUTPUT
 
9712
# SOURCE
 
9713
#
 
9714
sub rename_media {
 
9715
    my ($widget, $id, $newname) = @_;
 
9716
    debug("rename media");
 
9717
    my $oldname = $widget->get('text');
 
9718
    if ($oldname ne $newname) {
 
9719
        my $iter =
 
9720
          $widgets->{'image'}->get_widget('treeImage')
 
9721
          ->get_model->get_iter_from_string($id);
 
9722
        $id =
 
9723
          $widgets->{'image'}->get_widget('treeImage')
 
9724
          ->get_model->get($iter, 1);
 
9725
        debug("Renaming media from $oldname to $newname");
 
9726
        my $query = "UPDATE media SET description=\"$newname\" WHERE id=$id";
 
9727
        qdebug($query);
 
9728
        my $sth = $mediaDbh->prepare($query)
 
9729
          || display_fatal($errorcodes->{'sqlprepare'},
 
9730
            $! . "\nSQL: " . $query);
 
9731
        my $rv = $sth->execute
 
9732
          || display_fatal($errorcodes->{'sqlexecute'},
 
9733
            $! . "\nSQL: " . $query);
 
9734
        update_imagedir(
 
9735
            $widgets->{'image'}->get_widget('optionImageCategory')
 
9736
              ->{'user_data'},
 
9737
            $widgets->{'image'}->get_widget('optionImageCategory')
 
9738
              ->get_menu->get_active->{user_data}
 
9739
        );
 
9740
    }
 
9741
}
 
9742
 
 
9743
#***
 
9744
 
 
9745
#****f* lyricue/change_colour_media
 
9746
# NAME
 
9747
#   change_colour_media
 
9748
# SYNOPSIS
 
9749
#   change_colour_media($widget)
 
9750
# FUNCTION
 
9751
#   change colour media
 
9752
# INPUTS
 
9753
#   $widget -
 
9754
# OUTPUT
 
9755
# SOURCE
 
9756
#
 
9757
sub change_colour_media {
 
9758
    my ($widget) = @_;
 
9759
    debug("change colour media");
 
9760
    my $fontcolour =
 
9761
      $widgets->{'image'}->get_widget('entryImageFontColour')->get('text');
 
9762
    my $shadowcolour =
 
9763
      $widgets->{'image'}->get_widget('entryImageShadowColour')->get('text');
 
9764
    my $id = $widgets->{'image'}->get_widget('imageImage')->{user_data};
 
9765
 
 
9766
    if (defined($id)) {
 
9767
        my ($type, $id) = split /;/, $id;
 
9768
        if (!defined $id) {
 
9769
            $id   = $type;
 
9770
            $type = "db";
 
9771
        }
 
9772
        $id = substr $id, -100;
 
9773
 
 
9774
        if ($type eq "db") {
 
9775
            debug("change_colour_media: $fontcolour, $shadowcolour, $id");
 
9776
            my $query =
 
9777
"UPDATE media SET textcolour=\"$fontcolour\", shadowcolour=\"$shadowcolour\" WHERE id=$id";
 
9778
            qdebug($query);
 
9779
            my $sth = $mediaDbh->prepare($query)
 
9780
              || display_fatal($errorcodes->{'sqlprepare'},
 
9781
                $! . "\nSQL: " . $query);
 
9782
            my $rv = $sth->execute
 
9783
              || display_fatal($errorcodes->{'sqlexecute'},
 
9784
                $! . "\nSQL: " . $query);
 
9785
        } elsif ($type eq "dir") {
 
9786
            debug("change_colour_media: $fontcolour, $shadowcolour, $id");
 
9787
            my $query = "DELETE FROM media WHERE format=\"file\" AND category=\"".$id."\"";
 
9788
            qdebug($query);
 
9789
            my $sth = $mediaDbh->prepare($query)
 
9790
              || display_fatal($errorcodes->{'sqlprepare'},
 
9791
                $! . "\nSQL: " . $query);
 
9792
            my $rv = $sth->execute
 
9793
              || display_fatal($errorcodes->{'sqlexecute'},
 
9794
                $! . "\nSQL: " . $query);
 
9795
            $query = "INSERT INTO media (format, category, textcolour, shadowcolour) VALUES (\"file\", \"$id\", \"$fontcolour\", \"$shadowcolour\")";
 
9796
            qdebug($query);
 
9797
            $sth = $mediaDbh->prepare($query)
 
9798
              || display_fatal($errorcodes->{'sqlprepare'},
 
9799
                $! . "\nSQL: " . $query);
 
9800
            $rv = $sth->execute
 
9801
              || display_fatal($errorcodes->{'sqlexecute'},
 
9802
                $! . "\nSQL: " . $query);
 
9803
        }
 
9804
    }
 
9805
    change_preview();
 
9806
}
 
9807
 
 
9808
#***
 
9809
 
 
9810
#****f* lyricue/restore_db
 
9811
# NAME
 
9812
#   restore_db
 
9813
# SYNOPSIS
 
9814
#   restore_db()
 
9815
# FUNCTION
 
9816
#   Restoring DB
 
9817
# INPUTS
 
9818
# OUTPUT
 
9819
# SOURCE
 
9820
#
 
9821
sub restore_db {
 
9822
    debug("Restoring DB");
 
9823
 
 
9824
    # Get filename of DB
 
9825
    my $fileDialog = Gtk2::GladeXML->new($globals->{'gladefile'},
 
9826
        'dialogFileChooser', 'lyricue');
 
9827
    $fileDialog->get_widget('dialogFileChooser')
 
9828
      ->set_title(fromutf(gettext("Select Database Backup file")));
 
9829
    my $response = $fileDialog->get_widget('dialogFileChooser')->run();
 
9830
    if ($response) {
 
9831
        my $filename =
 
9832
          $fileDialog->get_widget('dialogFileChooser')->get_filename;
 
9833
        close_dialog($fileDialog->get_widget('dialogFileChooser'));
 
9834
 
 
9835
        my $confirmDialog = Gtk2::GladeXML->new($globals->{'gladefile'},
 
9836
            'dialogConfirm', 'lyricue');
 
9837
        $confirmDialog->signal_autoconnect_from_package('');
 
9838
        $confirmDialog->get_widget('dialogConfirm')
 
9839
          ->set_title(fromutf(gettext("Confirm Restore Database")));
 
9840
        $confirmDialog->get_widget('labelDelete')->set_text(
 
9841
            fromutf(
 
9842
                gettext(
 
9843
"WARNING: Restoring this database will overwrite your current database"
 
9844
                )
 
9845
            )
 
9846
        );
 
9847
        my $confirm = $confirmDialog->get_widget('dialogConfirm')->run();
 
9848
 
 
9849
        if ($confirm eq "ok") {
 
9850
 
 
9851
            debug("ok");
 
9852
            open(INPUT, "gzip -dc " . $filename . "|");
 
9853
            my $table = "";
 
9854
            my $db    = "";
 
9855
            my $dbh   = "";
 
9856
            while (<INPUT>) {
 
9857
                chomp;
 
9858
                if (/^USE/) {
 
9859
                    $db = $_;
 
9860
                    $db =~ s/^USE (.*);.*$/$1/g;
 
9861
                    $db =~ s/\`//g;
 
9862
                    debug($db . " - database");
 
9863
                    if ($db eq "lyricDb") {
 
9864
                        $dbh = $lyricDbh;
 
9865
                    } elsif ($db eq "mediaDb") {
 
9866
                        $dbh = $mediaDbh;
 
9867
                    } else {
 
9868
                        $dbh = "";
 
9869
                    }
 
9870
                } elsif (/^INSERT INTO/) {
 
9871
                    if ($dbh ne "") {
 
9872
                        my $insert   = $_;
 
9873
                        my $tmptable = $insert;
 
9874
                        $tmptable =~ s/^INSERT INTO `(.*?)`.*$/$1/g;
 
9875
                        if ($tmptable ne $table) {
 
9876
                            $table = $tmptable;
 
9877
                            my $query = "DELETE FROM " . $table;
 
9878
                            my $sth   = $dbh->prepare($query)
 
9879
                              || display_fatal(
 
9880
                                $errorcodes->{'sqlprepare'},
 
9881
                                $! . "\nSQL: " . $query
 
9882
                              );
 
9883
                            my $rv = $sth->execute
 
9884
                              || display_fatal(
 
9885
                                $errorcodes->{'sqlexecute'},
 
9886
                                $! . "\nSQL: " . $query
 
9887
                              );
 
9888
                        }
 
9889
                        my $sth = $dbh->prepare($insert)
 
9890
                          || display_fatal(
 
9891
                            $errorcodes->{'sqlprepare'},
 
9892
                            $! . "\nSQL: " . $query
 
9893
                          );
 
9894
                        my $rv = $sth->execute
 
9895
                          || display_fatal(
 
9896
                            $errorcodes->{'sqlexecute'},
 
9897
                            $! . "\nSQL: " . $query
 
9898
                          );
 
9899
 
 
9900
                    }
 
9901
                }
 
9902
            }
 
9903
        }
 
9904
        close_dialog($confirmDialog->get_widget('dialogConfirm'));
 
9905
    } else {
 
9906
        close_dialog($fileDialog->get_widget('dialogFileChooser'));
 
9907
    }
 
9908
}
 
9909
 
 
9910
#***
 
9911
 
 
9912
#****f* lyricue/import_songs
 
9913
# NAME
 
9914
#   import_songs
 
9915
# SYNOPSIS
 
9916
#   import_songs($filename)
 
9917
# FUNCTION
 
9918
#   Import the songs from a single xml file
 
9919
# INPUTS
 
9920
#   $filename - file to import songs from
 
9921
# OUTPUT
 
9922
# SOURCE
 
9923
#
 
9924
sub import_songs {
 
9925
    my ($filename) = @_;
 
9926
    debug("Importing songs from xml file");
 
9927
 
 
9928
    my ($fh);
 
9929
    if ($filename =~ /[zZ]$/) {
 
9930
        open $fh, "gzip -dc \"" . $filename . "\" |";
 
9931
    } else {
 
9932
        open $fh, $filename;
 
9933
    }
 
9934
    binmode($fh, ":utf8");
 
9935
 
 
9936
    my $xml = XMLin(
 
9937
        $fh,
 
9938
        ForceArray    => ['song', 'page'],
 
9939
        SuppressEmpty => '',
 
9940
        NoAttr        => 1,
 
9941
        KeyAttr       => []
 
9942
    );
 
9943
    close $fh;
 
9944
    my $songs = $xml->{'song'};
 
9945
 
 
9946
    $widgets->{'select_songs'} = Gtk2::GladeXML->new($globals->{'gladefile'},
 
9947
        'dialogSelectSongs', 'lyricue');
 
9948
    $widgets->{'select_songs'}->signal_autoconnect_from_package('');
 
9949
 
 
9950
    my $model = Gtk2::ListStore->new(
 
9951
        'Glib::Boolean', 'Glib::String', 'Glib::String', 'Glib::String',
 
9952
        'Glib::Uint',    'Glib::Uint'
 
9953
    );
 
9954
    my $renderer = Gtk2::CellRendererToggle->new;
 
9955
    $renderer->signal_connect(
 
9956
        toggled => sub {
 
9957
            my ($cell, $path_str, $model) = @_;
 
9958
            my $path   = Gtk2::TreePath->new_from_string($path_str);
 
9959
            my $column = 0;
 
9960
            my $iter   = $model->get_iter($path);
 
9961
            my ($toggle_item) = $model->get($iter, $column);
 
9962
            $toggle_item ^= 1;
 
9963
            debug 'setting ' . $path_str . ' to ' . $toggle_item;
 
9964
 
 
9965
            # set new value
 
9966
            $model->set($iter, $column, $toggle_item);
 
9967
        },
 
9968
        $model
 
9969
    );
 
9970
    my $column1 =
 
9971
      Gtk2::TreeViewColumn->new_with_attributes("", $renderer, active => 0);
 
9972
    my $column2 =
 
9973
      Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Title")),
 
9974
        Gtk2::CellRendererText->new, text => 1);
 
9975
    my $column3 =
 
9976
      Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Artist")),
 
9977
        Gtk2::CellRendererText->new, text => 2);
 
9978
    my $column4 =
 
9979
      Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Book")),
 
9980
        Gtk2::CellRendererText->new, text => 3);
 
9981
    my $column5 =
 
9982
      Gtk2::TreeViewColumn->new_with_attributes(fromutf(gettext("Song Number")),
 
9983
        Gtk2::CellRendererText->new, text => 4);
 
9984
    $column1->set_resizable(TRUE);
 
9985
    $column2->set_resizable(TRUE);
 
9986
    $column3->set_resizable(TRUE);
 
9987
    $column4->set_resizable(TRUE);
 
9988
    $column5->set_resizable(TRUE);
 
9989
    $widgets->{'select_songs'}->get_widget('treeSongImport')
 
9990
      ->append_column($column1);
 
9991
    $widgets->{'select_songs'}->get_widget('treeSongImport')
 
9992
      ->append_column($column2);
 
9993
    $widgets->{'select_songs'}->get_widget('treeSongImport')
 
9994
      ->append_column($column3);
 
9995
    $widgets->{'select_songs'}->get_widget('treeSongImport')
 
9996
      ->append_column($column4);
 
9997
    $widgets->{'select_songs'}->get_widget('treeSongImport')
 
9998
      ->append_column($column5);
 
9999
 
 
10000
    my @sorted_songs = sort {$a->{'name'} cmp $b->{'name'}} @$songs;
 
10001
    foreach my $songnum (0 .. (@sorted_songs - 1)) {
 
10002
        debug("Adding " . $songnum . ":" . $sorted_songs[$songnum]->{'name'});
 
10003
        my $iter = $model->append;
 
10004
        $model->set(
 
10005
            $iter,                         0,
 
10006
            TRUE,                          1,
 
10007
            $sorted_songs[$songnum]->{'name'},   2,
 
10008
            $sorted_songs[$songnum]->{'artist'}, 3,
 
10009
            $sorted_songs[$songnum]->{'book'},   4,
 
10010
            $sorted_songs[$songnum]->{'number'}, 5,
 
10011
            $songnum
 
10012
        );
 
10013
    }
 
10014
    $widgets->{'select_songs'}->get_widget('treeSongImport')->set_model($model);
 
10015
    $widgets->{'select_songs'}->get_widget('treeSongImport')
 
10016
      ->set_headers_clickable(TRUE);
 
10017
    my $confirm =
 
10018
      $widgets->{'select_songs'}->get_widget('dialogSelectSongs')->run();
 
10019
    if ($confirm == 1) {
 
10020
        $model->foreach(\&do_import_songs, $songs);
 
10021
        update_available();
 
10022
    }
 
10023
    close_dialog($widgets->{'select_songs'}->get_widget('dialogSelectSongs'));
 
10024
}
 
10025
 
 
10026
#***
 
10027
 
 
10028
#****f* lyricue/import_selection
 
10029
# NAME
 
10030
#   import_selection
 
10031
# SYNOPSIS
 
10032
#   import_selection($filename)
 
10033
# FUNCTION
 
10034
#   Change the selection in the import dialog
 
10035
# OUTPUT
 
10036
sub import_selection {
 
10037
    my ($widget) = @_;
 
10038
    debug("Selection changing");
 
10039
    my $model =
 
10040
      $widgets->{'select_songs'}->get_widget('treeSongImport')->get_model;
 
10041
    my $toggle = FALSE;
 
10042
    if ($widget->get_name() eq "buttonImportAll") {
 
10043
        $toggle = TRUE;
 
10044
    }
 
10045
    $model->foreach(
 
10046
        sub {
 
10047
            my ($store, $path, $iter, $toggle) = @_;
 
10048
            $store->set($iter, 0, $toggle);
 
10049
        },
 
10050
        $toggle
 
10051
    );
 
10052
}
 
10053
 
 
10054
#***
 
10055
 
 
10056
#****f* lyricue/do_import_songs
 
10057
# NAME
 
10058
#   do_import_songs
 
10059
# SYNOPSIS
 
10060
#   do_import_songs($store, $path, $iter, $songs)
 
10061
# FUNCTION
 
10062
#   Import each individual song if marked for import
 
10063
# INPUTS
 
10064
#   $store - List store
 
10065
#   $path - Path of item being checked
 
10066
#   $iter - Iter of item
 
10067
#   $songs - Parsed xml input
 
10068
# OUTPUT
 
10069
sub do_import_songs {
 
10070
    my ($store, $path, $iter, $songs) = @_;
 
10071
    my $songnum = $store->get($iter, 5);
 
10072
    if ($store->get($iter, 0)) {
 
10073
        my $song = @$songs[$songnum];
 
10074
        debug("Importing " . $song->{'name'});
 
10075
 
 
10076
        # Find next id
 
10077
        my $query = "SELECT MAX(id)+1 FROM lyricMain WHERE id < 2000000";
 
10078
        my $sth   = $lyricDbh->prepare($query)
 
10079
          || display_fatal($errorcodes->{'sqlprepare'},
 
10080
            $! . "\nSQL: " . $query);
 
10081
        my $rv = $sth->execute
 
10082
          || display_fatal($errorcodes->{'sqlexecute'},
 
10083
            $! . "\nSQL: " . $query);
 
10084
        my @row    = $sth->fetchrow_array;
 
10085
        my $songid = $row[0];
 
10086
        if ((! defined $songid) || ($songid < 1)) {
 
10087
            $songid = 1;
 
10088
        }
 
10089
        $query =
 
10090
"INSERT INTO lyricMain ( id, title, songnum, book, artist, keywords, copyright, entered, written ) VALUES ( ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";
 
10091
        $sth = $lyricDbh->prepare($query)
 
10092
          || display_fatal($errorcodes->{'sqlprepare'},
 
10093
            $! . "\nSQL: " . $query);
 
10094
        $rv =
 
10095
          $sth->execute($songid, $song->{'name'}, $song->{'number'},
 
10096
            $song->{'book'}, $song->{'artist'}, $song->{'keywords'},
 
10097
            $song->{'copyright'})
 
10098
          || display_fatal($errorcodes->{'sqlexecute'},
 
10099
            $! . "\nSQL: " . $query);
 
10100
 
 
10101
        my $pages   = $song->{'page'};
 
10102
        my $pagenum = 0;
 
10103
        foreach (@$pages) {
 
10104
            $pagenum++;
 
10105
            debug("Page Add : " . $pagenum);
 
10106
            $query =
 
10107
                "INSERT INTO page (songid,pagenum,lyrics) VALUES (" 
 
10108
              . $songid . ", "
 
10109
              . $pagenum . ", "
 
10110
              . quote($_) . ")";
 
10111
            qdebug($query);
 
10112
            $sth = $lyricDbh->prepare($query)
 
10113
              || display_fatal($errorcodes->{'sqlprepare'},
 
10114
                $! . "\nSQL: " . $query);
 
10115
            $sth->execute || display_fatal($errorcodes->{'sqlexecute'},
 
10116
                $! . "\nSQL: " . $query);
 
10117
        }
 
10118
    }
 
10119
}
 
10120
 
 
10121
#***
 
10122
 
 
10123
#****f* lyricue/export_songs
 
10124
# NAME
 
10125
#   export_songs
 
10126
# SYNOPSIS
 
10127
#   export_songs($filename)
 
10128
# FUNCTION
 
10129
#   Export the songs into a single xml file
 
10130
# INPUTS
 
10131
#   $filename - file to save songs as
 
10132
# OUTPUT
 
10133
# SOURCE
 
10134
#
 
10135
sub export_songs {
 
10136
    my ($filename) = @_;
 
10137
 
 
10138
    my @songs = ();
 
10139
 
 
10140
    my $query = "SELECT * FROM lyricMain";
 
10141
    qdebug($query);
 
10142
    my $sth = $lyricDbh->prepare($query)
 
10143
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
10144
    my $rv = $sth->execute
 
10145
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
10146
    while (my $row = $sth->fetchrow_hashref()) {
 
10147
        my $query2 =
 
10148
            "SELECT lyrics FROM page WHERE songid="
 
10149
          . $row->{'id'}
 
10150
          . " ORDER BY pagenum";
 
10151
        my $sth2 = $lyricDbh->prepare($query2)
 
10152
          || display_fatal($errorcodes->{'sqlprepare'},
 
10153
            $! . "\nSQL: " . $query2);
 
10154
        my $rv2 = $sth2->execute
 
10155
          || display_fatal($errorcodes->{'sqlexecute'},
 
10156
            $! . "\nSQL: " . $query2);
 
10157
        my @pages = ();
 
10158
        while (my $row2 = $sth2->fetchrow_hashref()) {
 
10159
            push @pages, $row2->{'lyrics'};
 
10160
        }
 
10161
 
 
10162
        my $song = {
 
10163
            'name'      => [$row->{'title'}],
 
10164
            'number'    => [$row->{'songnum'}],
 
10165
            'book'      => [$row->{'book'}],
 
10166
            'artist'    => [$row->{'artist'}],
 
10167
            'keywords'  => [$row->{'keywords'}],
 
10168
            'copyright' => [$row->{'copyright'}],
 
10169
            'page'      => \@pages
 
10170
        };
 
10171
        push @songs, $song;
 
10172
    }
 
10173
    my $out = {'song' => \@songs};
 
10174
    my $writer = XML::Simple->new();
 
10175
    open my $fh, "| gzip -c - > \"" . $filename . "\"";
 
10176
    binmode($fh, ":utf8");
 
10177
    $writer->XMLout($out, OutputFile => $fh, RootName => 'lyricue');
 
10178
    close $fh;
 
10179
 
 
10180
}
 
10181
 
 
10182
#***
 
10183
 
 
10184
#****f* lyricue/backup_db
 
10185
# NAME
 
10186
#   backup_db
 
10187
# SYNOPSIS
 
10188
#   backup_db()
 
10189
# FUNCTION
 
10190
#   Backup DB selected
 
10191
# INPUTS
 
10192
# OUTPUT
 
10193
# SOURCE
 
10194
#
 
10195
sub backup_db {
 
10196
    debug("Backup DB selected");
 
10197
    $widgets->{'backupdb'} =
 
10198
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogDatabase', 'lyricue');
 
10199
    $widgets->{'backupdb'}->signal_autoconnect_from_package('');
 
10200
    $widgets->{'backupdb'}->get_widget('entryPrefDBFilename')
 
10201
      ->set_text($ENV{"HOME"} . "/Lyricue_DB.gz");
 
10202
    my $response = $widgets->{'backupdb'}->get_widget('dialogDatabase')->run();
 
10203
    if ($response eq "ok") {
 
10204
        my $filename =
 
10205
          $widgets->{'backupdb'}->get_widget('entryPrefDBFilename')->get_text();
 
10206
        if (!($filename =~ /\.gz$/)) {
 
10207
            $filename .= ".gz";
 
10208
        }
 
10209
        my $databases = "";
 
10210
        if ($widgets->{'backupdb'}->get_widget('checkLyricdb')->get_active()) {
 
10211
            $databases .= "lyricDb ";
 
10212
        }
 
10213
        if ($widgets->{'backupdb'}->get_widget('checkMediadb')->get_active()) {
 
10214
            $databases .= "mediaDb ";
 
10215
        }
 
10216
 
 
10217
        my $command =
 
10218
"mysqldump --skip-extended-insert --no-create-db --no-create-info --complete-insert --user=lyric --password='' --databases "
 
10219
          . $databases
 
10220
          . " | gzip -c > "
 
10221
          . $filename;
 
10222
        debug($command);
 
10223
        system $command;
 
10224
        if ($? == -1) {
 
10225
            debug("Failed to execute: " . $command);
 
10226
        } else {
 
10227
            debug("Backed up to " . $filename);
 
10228
        }
 
10229
    }
 
10230
    close_dialog($widgets->{'backupdb'}->get_widget('dialogDatabase'));
 
10231
}
 
10232
 
 
10233
#***
 
10234
 
 
10235
#****f* lyricue/backup_db_browse
 
10236
# NAME
 
10237
#   backup_db_browse
 
10238
# SYNOPSIS
 
10239
#   backup_db_browse()
 
10240
# FUNCTION
 
10241
#   Browsing for BackupDB filename
 
10242
# INPUTS
 
10243
# OUTPUT
 
10244
# SOURCE
 
10245
#
 
10246
sub backup_db_browse {
 
10247
    debug("Browsing for BackupDB filename");
 
10248
    my $fileDialog = Gtk2::GladeXML->new($globals->{'gladefile'},
 
10249
        'dialogFileChooser', 'lyricue');
 
10250
    $fileDialog->get_widget('dialogFileChooser')
 
10251
      ->set_filename(
 
10252
        $widgets->{'backupdb'}->get_widget('entryPrefDBFilename')->get_text());
 
10253
    my $response = $fileDialog->get_widget('dialogFileChooser')->run();
 
10254
    if ($response) {
 
10255
        my $filename =
 
10256
          $fileDialog->get_widget('dialogFileChooser')->get_filename;
 
10257
        if (!($filename =~ /\.gz$/)) {
 
10258
            $filename .= ".gz";
 
10259
        }
 
10260
        $widgets->{'backupdb'}->get_widget('entryPrefDBFilename')
 
10261
          ->set_text($filename);
 
10262
    }
 
10263
    close_dialog($fileDialog->get_widget('dialogFileChooser'));
 
10264
}
 
10265
 
 
10266
#***
 
10267
 
 
10268
#****f* lyricue/get_bibles
 
10269
# NAME
 
10270
#   get_bibles
 
10271
# SYNOPSIS
 
10272
#   get_bibles()
 
10273
# FUNCTION
 
10274
#   Getting available bibles
 
10275
# INPUTS
 
10276
# OUTPUT
 
10277
# SOURCE
 
10278
#
 
10279
sub get_bibles {
 
10280
    my $bibles;
 
10281
    debug("Getting available bibles");
 
10282
 
 
10283
    if ($^O ne 'MSWin32') {
 
10284
 
 
10285
        # Bibles provided by Sword libraries
 
10286
        open(SWORD, $globals->{'diatheke'} . " -b system -k modulelist|");
 
10287
        while (<SWORD>) {
 
10288
            if (/^Biblical Texts:/) {
 
10289
                while (<SWORD>) {
 
10290
                    if (/^Commentaries:/) {
 
10291
                        while (<SWORD>) { }
 
10292
                    } else {
 
10293
                        chomp;
 
10294
                        my @bible = split(/:/, $_, 2);
 
10295
                        $bible[0] =~ s/\s+$//;
 
10296
                        $bible[1] =~ s/^\s+//;
 
10297
                        $bibles->{$bible[0]} = "sword;" . $bible[1];
 
10298
                    }
 
10299
                }
 
10300
            }
 
10301
        }
 
10302
        close SWORD;
 
10303
    }
 
10304
 
 
10305
    # Bible databases found
 
10306
    my $dbs = $globals->{'db_available_db'};
 
10307
    foreach (keys %$dbs) {
 
10308
        my $dbname = $_;
 
10309
        my $db = db_connect($dbname, $errorcodes->{'bibledbopen'});
 
10310
        if (defined $db) {
 
10311
            my @tables = $db->tables;
 
10312
            my $table;
 
10313
            foreach (@tables) {
 
10314
                my $tablename = $_;
 
10315
                $tablename =~ s/^.*`(.*)`$/$1/g;
 
10316
                $tablename =~ s/^"(.*)"$/$1/g;
 
10317
                my $tmpfields =
 
10318
                  $db->selectall_arrayref("describe " . $tablename);
 
10319
                if (!defined $tmpfields) {
 
10320
                    next;
 
10321
                }
 
10322
                my @fields = @{$tmpfields};
 
10323
                my $a      = $fields[0]->[0];
 
10324
                if ($a eq "verseid") {
 
10325
                    my $query =
 
10326
                        "SELECT verse FROM "
 
10327
                      . $tablename
 
10328
                      . " WHERE book=\"Bible\";";
 
10329
                    qdebug($query);
 
10330
                    my $sth = $db->prepare($query)
 
10331
                      || display_fatal($errorcodes->{'sqlprepare'},
 
10332
                        $! . "\nSQL: " . $query);
 
10333
                    my $rv = $sth->execute
 
10334
                      || display_fatal($errorcodes->{'sqlexecute'},
 
10335
                        $! . "\nSQL: " . $query);
 
10336
                    my $row = $sth->fetchrow_hashref();
 
10337
                    if (defined $row->{'verse'}) {
 
10338
                        $bibles->{$tablename . "@" . $dbname} =
 
10339
                          "db;" . $row->{'verse'};
 
10340
                    }
 
10341
                    $sth->finish;
 
10342
                }
 
10343
            }
 
10344
            $db->disconnect();
 
10345
        }
 
10346
    }
 
10347
 
 
10348
    return $bibles;
 
10349
}
 
10350
 
 
10351
#***
 
10352
 
 
10353
#****f* lyricue/navigator_changed
 
10354
# NAME
 
10355
#   navigator_changed
 
10356
# SYNOPSIS
 
10357
#   navigator_changed()
 
10358
# FUNCTION
 
10359
#   Navigator changed
 
10360
# INPUTS
 
10361
# OUTPUT
 
10362
# SOURCE
 
10363
#
 
10364
sub navigator_changed {
 
10365
    debug("Navigator changed");
 
10366
    reset_timer($globals->{'nav_update_timer'});
 
10367
    $globals->{'nav_update_timer'} =
 
10368
      Glib::Timeout->add(500, \&navigator_update);
 
10369
}
 
10370
 
 
10371
#***
 
10372
 
 
10373
#****f* lyricue/navigator_update
 
10374
# NAME
 
10375
#   navigator_update
 
10376
# SYNOPSIS
 
10377
#   navigator_update()
 
10378
# FUNCTION
 
10379
#   Updating navigator
 
10380
# INPUTS
 
10381
# OUTPUT
 
10382
# SOURCE
 
10383
#
 
10384
sub navigator_update {
 
10385
    debug("Updating navigator");
 
10386
    reset_timer($globals->{'nav_update_timer'});
 
10387
    if ((!defined $globals->{'bibledb'}) || ($globals->{'bibledb'} eq "")) {
 
10388
        display_message($errorcodes->{'nobible'});
 
10389
        return;
 
10390
    }
 
10391
    my $buffer = Gtk2::TextBuffer->new();
 
10392
    $buffer->set_text("");
 
10393
    my $iter  = $buffer->get_iter_at_offset(0);
 
10394
    my $verse = $widgets->{'main'}->get_widget('entryNavVerse')->get_text();
 
10395
    $verse =~ s/ (\D)/_$1/g;
 
10396
    my ($book, $chapter, $startverse, $endverse) =
 
10397
      split(/[ :\-,]/, $verse, 4);
 
10398
 
 
10399
    my $browser = "";
 
10400
    if (defined $book) {
 
10401
        $book =~ s/_/ /g;
 
10402
    } else {
 
10403
        $book    = "";
 
10404
        $browser = "init";
 
10405
        biblebrowser_init();
 
10406
    }
 
10407
 
 
10408
    if ((!defined $chapter) or ($chapter eq "") or ($chapter =~ /\D/)) {
 
10409
        $chapter = 1;
 
10410
        if ($browser eq "") {
 
10411
            $browser = "chapter";
 
10412
            biblebrowser_chapter(NULL, $book, "entry");
 
10413
        }
 
10414
    }
 
10415
    if (   (!defined $startverse)
 
10416
        or ($startverse eq "")
 
10417
        or ($startverse =~ /\D/))
 
10418
    {
 
10419
        $startverse = 1;
 
10420
    }
 
10421
    if (   (!defined $endverse)
 
10422
        or ($endverse eq "")
 
10423
        or ($endverse =~ /\D/)
 
10424
        or ($endverse < $startverse))
 
10425
    {
 
10426
        $endverse = $startverse;
 
10427
    }
 
10428
    debug(  "Book " 
 
10429
          . $book
 
10430
          . " chapter "
 
10431
          . $chapter
 
10432
          . " verses "
 
10433
          . $startverse . "-"
 
10434
          . $endverse);
 
10435
    if ($browser eq "") {
 
10436
        $browser = "verse";
 
10437
        my $newbook = "";
 
10438
        if (!$globals->{'usesword'}) {
 
10439
            my ($table, $dbname) = split(/@/, $globals->{'bibledb'}, 2);
 
10440
            my $query =
 
10441
                "SELECT DISTINCT(book) FROM " 
 
10442
              . $table
 
10443
              . " WHERE book LIKE \""
 
10444
              . $book . "%\"";
 
10445
            qdebug($query);
 
10446
            my $sth = $bibleDbh->prepare($query)
 
10447
              || display_fatal($errorcodes->{'sqlprepare'},
 
10448
                $! . "\nSQL: " . $query);
 
10449
            my $rv = $sth->execute
 
10450
              || display_fatal($errorcodes->{'sqlexecute'},
 
10451
                $! . "\nSQL: " . $query);
 
10452
            my @bookrow = $sth->fetchrow_array();
 
10453
            if ((defined $bookrow[0]) && ($book ne "")) {
 
10454
                $newbook = $bookrow[0];
 
10455
            }
 
10456
        } else {
 
10457
            my $command = sprintf(
 
10458
                "%s -b %s -e UTF8 -k '%s' 1:1 | head -1",
 
10459
                $globals->{'diatheke'},
 
10460
                $globals->{'bibledb'}, $book
 
10461
            );
 
10462
            qdebug($command);
 
10463
            my $command_out = fromutf(`$command`);
 
10464
            ($newbook, undef) = split(/\s\d/, $command_out, 2);
 
10465
        }
 
10466
        my $text = $widgets->{'main'}->get_widget('entryNavVerse')->get_text();
 
10467
        $text =~ s/$book[ :\-]/$newbook /i;
 
10468
        $widgets->{'main'}->get_widget('entryNavVerse')->set_text($text);
 
10469
        $widgets->{'main'}->get_widget('entryNavVerse')->set_position(-1);
 
10470
        biblebrowser_verse(NULL, 0, "entry");
 
10471
        foreach my $num ($startverse .. $endverse) {
 
10472
            my $button = "button" . ($num - 1);
 
10473
            if (defined $widgets->{'bibleBrowser'}{$button}) {
 
10474
                $widgets->{'bibleBrowser'}{$button}->set_active(TRUE);
 
10475
            }
 
10476
        }
 
10477
    }
 
10478
    if ($globals->{'usesword'}) {
 
10479
        my $command = sprintf(
 
10480
            "%s -b %s -e UTF8 -k '%s' %d:%d-%d |tr \\\\n \' \'",
 
10481
            $globals->{'diatheke'},
 
10482
            $globals->{'bibledb'}, $book, $chapter, $startverse, $endverse,
 
10483
            $book
 
10484
        );
 
10485
        qdebug($command);
 
10486
        my $command_out = fromutf(`$command`);
 
10487
        ($book, undef) = split(/\s\d/, $command_out, 2);
 
10488
        my @command_lines = split(/$book /, $command_out);
 
10489
        my $mark          = 0;
 
10490
        my $lineno        = 0;
 
10491
        foreach $lineno (1 .. @command_lines) {
 
10492
            my $line2 = $command_lines[$lineno - 1];
 
10493
            chomp($line2);
 
10494
            if ($line2 ne "") {
 
10495
                if ($lineno != @command_lines) {
 
10496
                    $line2 .= "\n";
 
10497
                }
 
10498
                $buffer->create_mark($mark, $iter, TRUE);
 
10499
                insert_link($buffer, $iter, $mark, $line2);
 
10500
                $mark++;
 
10501
            }
 
10502
        }
 
10503
        $buffer->create_mark($mark, $iter, TRUE);
 
10504
 
 
10505
        # remove the trailing bible name
 
10506
        #$quicktext =~ s/\($globals->{'bibledb'}\)/\n/g;
 
10507
    } else {
 
10508
        my ($table, $dbname) = split(/@/, $globals->{'bibledb'}, 2);
 
10509
        $query =
 
10510
          "SELECT book FROM " . $table . " WHERE book LIKE \"" . $book . "%\"";
 
10511
        qdebug($query);
 
10512
        $sth = $bibleDbh->prepare($query)
 
10513
          || display_fatal($errorcodes->{'sqlprepare'},
 
10514
            $! . "\nSQL: " . $query);
 
10515
        $rv = $sth->execute
 
10516
          || display_fatal($errorcodes->{'sqlexecute'},
 
10517
            $! . "\nSQL: " . $query);
 
10518
        my @bookrow = $sth->fetchrow_array();
 
10519
        if ((defined $bookrow[0]) && ($book ne "")) {
 
10520
            $book = $bookrow[0];
 
10521
            my ($table, $dbname) = split(/@/, $globals->{'bibledb'}, 2);
 
10522
            $query =
 
10523
                "SELECT book,chapternum,versenum,verse FROM " 
 
10524
              . $table
 
10525
              . " WHERE book LIKE \""
 
10526
              . $book
 
10527
              . "%\" AND chapternum="
 
10528
              . $chapter
 
10529
              . " AND versenum>="
 
10530
              . $startverse
 
10531
              . " AND versenum <= "
 
10532
              . $endverse
 
10533
              . " ORDER BY versenum";
 
10534
            qdebug($query);
 
10535
            $sth = $bibleDbh->prepare($query)
 
10536
              || display_fatal($errorcodes->{'sqlprepare'},
 
10537
                $! . "\nSQL: " . $query);
 
10538
            $rv = $sth->execute
 
10539
              || display_fatal($errorcodes->{'sqlexecute'},
 
10540
                $! . "\nSQL: " . $query);
 
10541
            my $mark = 0;
 
10542
            while (my @row = $sth->fetchrow_array()) {
 
10543
                my $verse = $row[1] . ":" . $row[2] . " " . $row[3] . "\n";
 
10544
                $buffer->create_mark($mark, $iter, TRUE);
 
10545
                insert_link($buffer, $iter, $mark, $verse);
 
10546
                $mark++;
 
10547
            }
 
10548
            $buffer->create_mark($mark, $iter, TRUE);
 
10549
        }
 
10550
    }
 
10551
 
 
10552
    $widgets->{'main'}->get_widget('entryNavVerse')->{user_data} =
 
10553
      $book . " " . $chapter . ":" . $startverse . "-" . $endverse;
 
10554
    my $oldtext = get_buffer_text(
 
10555
        $widgets->{'main'}->get_widget('textNavView')->get_buffer());
 
10556
    my $quicktext = get_buffer_text($buffer);
 
10557
    if ($oldtext ne $quicktext) {
 
10558
        $widgets->{'main'}->get_widget('textNavView')->set_buffer($buffer);
 
10559
        if ($widgets->{'main'}->get_widget('checkNavAuto')->get_active()) {
 
10560
            navigator_show();
 
10561
        }
 
10562
    }
 
10563
}
 
10564
 
 
10565
#***
 
10566
 
 
10567
#****f* lyricue/navigator_enter
 
10568
# NAME
 
10569
#   navigator_enter
 
10570
# SYNOPSIS
 
10571
#   navigator_enter()
 
10572
# FUNCTION
 
10573
#
 
10574
# INPUTS
 
10575
# OUTPUT
 
10576
# SOURCE
 
10577
#
 
10578
sub navigator_enter {
 
10579
    navigator_update();
 
10580
    navigator_show();
 
10581
}
 
10582
 
 
10583
#***
 
10584
 
 
10585
#****f* lyricue/navigator_show
 
10586
# NAME
 
10587
#   navigator_show
 
10588
# SYNOPSIS
 
10589
#   navigator_show()
 
10590
# FUNCTION
 
10591
#   Bible navigator showing on server
 
10592
# INPUTS
 
10593
# OUTPUT
 
10594
# SOURCE
 
10595
#
 
10596
sub navigator_show {
 
10597
    debug("Bible navigator showing on server");
 
10598
    my $buffer = $widgets->{'main'}->get_widget('textNavView')->get_buffer();
 
10599
    my $songtext = $buffer->get_text($buffer->get_bounds, FALSE);
 
10600
    $songtext =~ s/\n/#BREAK#/g;
 
10601
    $songtext =~ s/:/#SEMI#/g;
 
10602
 
 
10603
    my $verse =
 
10604
      $widgets->{'main'}->get_widget('entryNavVerse')->{user_data}
 
10605
      . "#BREAK##BREAK##BREAK#wrap";
 
10606
 
 
10607
    update_display("preview", $verse, $songtext);
 
10608
}
 
10609
 
 
10610
#***
 
10611
 
 
10612
#****f* lyricue/navigator_add
 
10613
# NAME
 
10614
#   navigator_add
 
10615
# SYNOPSIS
 
10616
#   navigator_add()
 
10617
# FUNCTION
 
10618
#   Adding verses from Bible navigator to playlist
 
10619
# INPUTS
 
10620
# OUTPUT
 
10621
# SOURCE
 
10622
#
 
10623
sub navigator_add {
 
10624
    debug("Adding verses from Bible navigator to playlist");
 
10625
    my $verse = $widgets->{'main'}->get_widget('entryNavVerse')->{user_data};
 
10626
    $verse =~ s/ (\D)/_$1/;
 
10627
    my ($book, $chapter, $startverse, $endverse) =
 
10628
      split(/[ :\-,]/, $verse, 4);
 
10629
    $book =~ s/_/ /g;
 
10630
    insert_verse($book, $chapter, $startverse, $endverse);
 
10631
}
 
10632
 
 
10633
#***
 
10634
 
 
10635
#****f* lyricue/navigator_next
 
10636
# NAME
 
10637
#   navigator_next
 
10638
# SYNOPSIS
 
10639
#   navigator_next()
 
10640
# FUNCTION
 
10641
#   Showing next verse
 
10642
# INPUTS
 
10643
# OUTPUT
 
10644
# SOURCE
 
10645
#
 
10646
sub navigator_next {
 
10647
    debug("Showing next verse");
 
10648
    my $verse = $widgets->{'main'}->get_widget('entryNavVerse')->{user_data};
 
10649
    $verse =~ s/ (\D)/_$1/;
 
10650
    my ($book, $chapter, $startverse, $endverse) =
 
10651
      split(/[ :\-,]/, $verse, 4);
 
10652
    $book =~ s/_/ /g;
 
10653
    my $loop = TRUE;
 
10654
    $endverse++;
 
10655
    while ($loop) {
 
10656
        my $maxv = get_max_verse($book, $chapter, $startverse, $endverse);
 
10657
        print $maxv. "\n";
 
10658
        if ($maxv < $endverse) {
 
10659
            $startverse++;
 
10660
        } else {
 
10661
            $loop = FALSE;
 
10662
        }
 
10663
    }
 
10664
    if (!$globals->{'usesword'}) {
 
10665
        my ($table, $dbname) = split(/@/, $globals->{'bibledb'}, 2);
 
10666
        my $query =
 
10667
            "SELECT MAX(versenum) FROM " 
 
10668
          . $table
 
10669
          . " WHERE book=\""
 
10670
          . $book
 
10671
          . "\" AND chapternum="
 
10672
          . $chapter;
 
10673
        qdebug($query);
 
10674
        my $sth = $bibleDbh->prepare($query)
 
10675
          || display_fatal($errorcodes->{'sqlprepare'},
 
10676
            $! . "\nSQL: " . $query);
 
10677
        my $rv = $sth->execute
 
10678
          || display_fatal($errorcodes->{'sqlexecute'},
 
10679
            $! . "\nSQL: " . $query);
 
10680
        my @row = $sth->fetchrow_array();
 
10681
 
 
10682
        if ($endverse > $row[0]) {
 
10683
            $endverse = $row[0];
 
10684
        }
 
10685
        if ($startverse > $row[0]) {
 
10686
            $startverse = $row[0];
 
10687
        }
 
10688
    }
 
10689
 
 
10690
    $verse = $book . " " . $chapter . ":" . $startverse . "-" . $endverse;
 
10691
    $widgets->{'main'}->get_widget('entryNavVerse')->set_text($verse);
 
10692
    navigator_update();
 
10693
    navigator_show();
 
10694
}
 
10695
 
 
10696
#***
 
10697
 
 
10698
#****f* lyricue/navigator_prev
 
10699
# NAME
 
10700
#   navigator_prev
 
10701
# SYNOPSIS
 
10702
#   navigator_prev()
 
10703
# FUNCTION
 
10704
#   Showing next verse
 
10705
# INPUTS
 
10706
# OUTPUT
 
10707
# SOURCE
 
10708
#
 
10709
sub navigator_prev {
 
10710
    debug("Showing previous verse");
 
10711
    my $verse = $widgets->{'main'}->get_widget('entryNavVerse')->{user_data};
 
10712
    $verse =~ s/ (\D)/_$1/;
 
10713
    my ($book, $chapter, $startverse, $endverse) =
 
10714
      split(/[ :\-,]/, $verse, 4);
 
10715
    $book =~ s/_/ /g;
 
10716
    my $loop = TRUE;
 
10717
    $startverse--;
 
10718
    if ($startverse < 1) {
 
10719
        $startverse = 1;
 
10720
    }
 
10721
    $endverse = get_max_verse($book, $chapter, $startverse, $endverse);
 
10722
    $verse = $book . " " . $chapter . ":" . $startverse . "-" . $endverse;
 
10723
    $widgets->{'main'}->get_widget('entryNavVerse')->set_text($verse);
 
10724
    navigator_update();
 
10725
    navigator_show();
 
10726
}
 
10727
 
 
10728
#***
 
10729
 
 
10730
#****f* lyricue/reset_timer
 
10731
# NAME
 
10732
#   reset_timer
 
10733
# SYNOPSIS
 
10734
#   reset_timer($timer)
 
10735
# FUNCTION
 
10736
#   Cancelling timer
 
10737
# INPUTS
 
10738
#   $timer -
 
10739
# OUTPUT
 
10740
# SOURCE
 
10741
#
 
10742
sub reset_timer {
 
10743
    my ($timer) = @_;
 
10744
    if ($timer) {
 
10745
        debug("Cancelling timer");
 
10746
        Glib::Source->remove($timer);
 
10747
        $timer = FALSE;
 
10748
    }
 
10749
}
 
10750
 
 
10751
#***
 
10752
 
 
10753
#****f* lyricue/do_pending
 
10754
# NAME
 
10755
#   do_pending
 
10756
# SYNOPSIS
 
10757
#   do_pending()
 
10758
# FUNCTION
 
10759
#
 
10760
# INPUTS
 
10761
# OUTPUT
 
10762
# SOURCE
 
10763
#
 
10764
sub do_pending {
 
10765
    while (Gtk2->events_pending) {
 
10766
        Gtk2->main_iteration;
 
10767
    }
 
10768
}
 
10769
 
 
10770
#***
 
10771
 
 
10772
#****f* lyricue/get_max_verse
 
10773
# NAME
 
10774
#   get_max_verse
 
10775
# SYNOPSIS
 
10776
#   get_max_verse($book, $chapter, $startverse, $endverse)
 
10777
# FUNCTION
 
10778
#
 
10779
# INPUTS
 
10780
#   $book -
 
10781
#    $chapter -
 
10782
#    $startverse -
 
10783
#    $endverse -
 
10784
# OUTPUT
 
10785
# SOURCE
 
10786
#
 
10787
sub get_max_verse {
 
10788
    my ($book, $chapter, $startverse, $endverse) = @_;
 
10789
 
 
10790
    if ($config->{'Main'} eq "") {
 
10791
        $config = load_config();
 
10792
    }
 
10793
    if ($config->{'Width'} == 0) {
 
10794
        $config->{'Width'}  = 800;
 
10795
        $config->{'Height'} = 600;
 
10796
    }
 
10797
    debug("Get max verse that fits within ".$config->{'Width'}."x".$config->{'Height'});
 
10798
 
 
10799
    my $pageHeight = 0;
 
10800
 
 
10801
    my $layout =
 
10802
      $widgets->{'main'}->get_widget('windowMain')->create_pango_layout("");
 
10803
    $layout->set_wrap('word');
 
10804
    $layout->set_width(($config->{'Width'} - $config->{'OverscanH'}) * PANGO_SCALE);
 
10805
    $layout->set_font_description(
 
10806
        Gtk2::Pango::FontDescription->from_string($config->{'Main'}));
 
10807
    my $page = "";
 
10808
    my (@command_out);
 
10809
 
 
10810
    if (!$globals->{'usesword'}) {
 
10811
        my ($table, $dbname) = split(/@/, $globals->{'bibledb'}, 2);
 
10812
 
 
10813
        $query =
 
10814
            "SELECT * FROM " 
 
10815
          . $table
 
10816
          . " WHERE book=\""
 
10817
          . $book
 
10818
          . "\" AND chapternum="
 
10819
          . $chapter
 
10820
          . " AND versenum>="
 
10821
          . $startverse
 
10822
          . " AND versenum <= "
 
10823
          . $endverse
 
10824
          . " ORDER BY versenum";
 
10825
        qdebug($query);
 
10826
        $sth = $bibleDbh->prepare($query)
 
10827
          || display_fatal($errorcodes->{'sqlprepare'},
 
10828
            $! . "\nSQL: " . $query);
 
10829
 
 
10830
        $rv = $sth->execute
 
10831
          || display_fatal($errorcodes->{'sqlexecute'},
 
10832
            $! . "\nSQL: " . $query);
 
10833
    }
 
10834
 
 
10835
    my $loop     = TRUE;
 
10836
    my $versenum = $startverse;
 
10837
    while ($loop) {
 
10838
        my $line = "";
 
10839
        if ($globals->{'usesword'}) {
 
10840
            my $command = sprintf(
 
10841
"%s -b %s -e UTF8 -k '%s' %d:%d-%d | sed -e 's/^%s //g' | head -n -1",
 
10842
                $globals->{'diatheke'},
 
10843
                $globals->{'bibledb'}, $book, $chapter, $startverse, $versenum,
 
10844
                $book
 
10845
            );
 
10846
            qdebug($command);
 
10847
            $line = `$command`;
 
10848
            $versenum++;
 
10849
            if ($versenum > $endverse - 1) { $loop = FALSE; }
 
10850
            chomp($line);
 
10851
        } else {
 
10852
            if (!defined $line) { $loop = FALSE; }
 
10853
            if ($row = $sth->fetchrow_hashref()) {
 
10854
                $line =
 
10855
                    $row->{'chapternum'} . ":"
 
10856
                  . $row->{'versenum'} . "   "
 
10857
                  . $row->{'verse'};
 
10858
                $versenum = $row->{'versenum'};
 
10859
            } else {
 
10860
                return $versenum;
 
10861
            }
 
10862
        }
 
10863
 
 
10864
        $layout->set_text($page . "\n" . $line);
 
10865
        my ($pageWidth, $pageHeight) = $layout->get_pixel_size;
 
10866
 
 
10867
        if ($pageHeight > $config->{'Height'} - (100 + $config->{'OverscanV'})) {
 
10868
            if ($versenum > $startverse) { $versenum--; }
 
10869
            return $versenum;
 
10870
        } else {
 
10871
            $page = $page . "\n" . $line;
 
10872
        }
 
10873
    }
 
10874
    if ($versenum > $endverse) {
 
10875
        $versenum = $endverse;
 
10876
    }
 
10877
    return $versenum;
 
10878
}
 
10879
 
 
10880
# Inserts a piece of text into the buffer, giving it the usual
 
10881
# appearance of a hyperlink in a web browser: blue and underlined.
 
10882
# Additionally, attaches some data on the tag, to make it recognizable
 
10883
# as a link.
 
10884
#
 
10885
#***
 
10886
 
 
10887
#****f* lyricue/insert_link
 
10888
# NAME
 
10889
#   insert_link
 
10890
# SYNOPSIS
 
10891
#   insert_link($buffer, $iter, $mark, $verse)
 
10892
# FUNCTION
 
10893
#
 
10894
# INPUTS
 
10895
#   $buffer -
 
10896
#    $iter -
 
10897
#    $mark -
 
10898
#    $verse -
 
10899
# OUTPUT
 
10900
# SOURCE
 
10901
#
 
10902
sub insert_link {
 
10903
    my ($buffer, $iter, $mark, $verse) = @_;
 
10904
    my $tag = $buffer->create_tag(
 
10905
        undef,
 
10906
        foreground => "blue",
 
10907
        underline  => 'single'
 
10908
    );
 
10909
    $tag->{markname} = $mark;
 
10910
    $buffer->create_mark($mark, $iter, TRUE);
 
10911
    my ($chap, $num, $text) = split(/[:\ ]/, $verse, 3);
 
10912
    $verse = $chap . ":" . $num;
 
10913
    $text  = " " . $text;
 
10914
    $buffer->insert_with_tags($iter, $verse, $tag);
 
10915
    $buffer->insert($iter, $text);
 
10916
}
 
10917
 
 
10918
# Looks at all tags covering the position of iter in the text view,
 
10919
# and if one of them is a link, follow it by showing the page identified
 
10920
# by the data attached to it.
 
10921
#
 
10922
#***
 
10923
 
 
10924
#****f* lyricue/follow_if_link
 
10925
# NAME
 
10926
#   follow_if_link
 
10927
# SYNOPSIS
 
10928
#   follow_if_link($text_view, $iter)
 
10929
# FUNCTION
 
10930
#   Showing $book $verse
 
10931
# INPUTS
 
10932
#   $text_view -
 
10933
#    $iter -
 
10934
# OUTPUT
 
10935
# SOURCE
 
10936
#
 
10937
sub follow_if_link {
 
10938
    my ($text_view, $iter) = @_;
 
10939
    my $verse = $widgets->{'main'}->get_widget('entryNavVerse')->{user_data};
 
10940
    $verse =~ s/ (\D)/_$1/;
 
10941
    my ($book, $chapter, $startverse, $endverse) =
 
10942
      split(/[ :\-,]/, $verse, 4);
 
10943
    $book =~ s/_/ /g;
 
10944
    foreach my $tag ($iter->get_tags) {
 
10945
        my $buffer    = $text_view->get_buffer();
 
10946
        my $mark      = $buffer->get_mark($tag->{markname});
 
10947
        my $startiter = $buffer->get_iter_at_mark($mark);
 
10948
        my $enditer =
 
10949
          $buffer->get_iter_at_mark($buffer->get_mark($tag->{markname} + 1));
 
10950
        my $quicktext = $buffer->get_text($startiter, $enditer, FALSE);
 
10951
        if ($verse ne "") {
 
10952
            debug("Showing $book $verse");
 
10953
            debug($quicktext);
 
10954
            last;
 
10955
        }
 
10956
    }
 
10957
}
 
10958
 
 
10959
#***
 
10960
 
 
10961
#****f* lyricue/navigator_event_after
 
10962
# NAME
 
10963
#   navigator_event_after
 
10964
# SYNOPSIS
 
10965
#   navigator_event_after($text_view, $event)
 
10966
# FUNCTION
 
10967
#   Navigator text clicked
 
10968
# INPUTS
 
10969
#   $text_view -
 
10970
#    $event -
 
10971
# OUTPUT
 
10972
# SOURCE
 
10973
#
 
10974
sub navigator_event_after {
 
10975
    my ($text_view, $event) = @_;
 
10976
    debug("Navigator text clicked");
 
10977
    return FALSE unless $event->type eq 'button-release';
 
10978
    return FALSE unless $event->button == 1;
 
10979
    my $buffer = $text_view->get_buffer;
 
10980
 
 
10981
    # we shouldn't follow a link if the user has selected something
 
10982
    my ($start, $end) = $buffer->get_selection_bounds;
 
10983
    return FALSE if defined $end and $start->get_offset != $end->get_offset;
 
10984
    my ($x, $y) =
 
10985
      $text_view->window_to_buffer_coords('widget', $event->x, $event->y);
 
10986
    my $iter = $text_view->get_iter_at_location($x, $y);
 
10987
    follow_if_link($text_view, $iter);
 
10988
    return FALSE;
 
10989
}
 
10990
 
 
10991
#***
 
10992
 
 
10993
#****f* lyricue/text_set_cursor_if_appropriate
 
10994
# NAME
 
10995
#   text_set_cursor_if_appropriate
 
10996
# SYNOPSIS
 
10997
#   text_set_cursor_if_appropriate($text_view, $x, $y)
 
10998
# FUNCTION
 
10999
#
 
11000
# INPUTS
 
11001
#   $text_view -
 
11002
#    $x -
 
11003
#    $y -
 
11004
# OUTPUT
 
11005
# SOURCE
 
11006
#
 
11007
sub text_set_cursor_if_appropriate {
 
11008
    my ($text_view, $x, $y) = @_;
 
11009
    $globals->{'hovering'} = FALSE;
 
11010
    my $buffer = $text_view->get_buffer;
 
11011
    my $iter = $text_view->get_iter_at_location($x, $y);
 
11012
    foreach my $tag ($iter->get_tags) {
 
11013
        if (defined $tag->{markname}) {
 
11014
            $globals->{'hovering'} = TRUE;
 
11015
            last;
 
11016
        }
 
11017
    }
 
11018
 
 
11019
    if ($globals->{'hovering'} != $globals->{'hovering_over_link'}) {
 
11020
        $globals->{'hovering_over_link'} = $globals->{'hovering'};
 
11021
        $text_view->get_window('text')->set_cursor(
 
11022
              $globals->{'hovering_over_link'}
 
11023
            ? $globals->{'hand_cursor'}
 
11024
            : $globals->{'text_cursor'}
 
11025
        );
 
11026
    }
 
11027
}
 
11028
 
 
11029
# Update the cursor image if the pointer moved.
 
11030
#
 
11031
#***
 
11032
 
 
11033
#****f* lyricue/text_motion_notify_event
 
11034
# NAME
 
11035
#   text_motion_notify_event
 
11036
# SYNOPSIS
 
11037
#   text_motion_notify_event($text_view, $event)
 
11038
# FUNCTION
 
11039
#
 
11040
# INPUTS
 
11041
#   $text_view -
 
11042
#    $event -
 
11043
# OUTPUT
 
11044
# SOURCE
 
11045
#
 
11046
sub text_motion_notify_event {
 
11047
    my ($text_view, $event) = @_;
 
11048
    my ($x, $y) =
 
11049
      $text_view->window_to_buffer_coords('widget', $event->x, $event->y);
 
11050
    text_set_cursor_if_appropriate($text_view, $x, $y);
 
11051
    $text_view->window->get_pointer;
 
11052
    return FALSE;
 
11053
}
 
11054
 
 
11055
# Also update the cursor image if the window becomes visible
 
11056
# (e.g. when a window covering it got iconified).
 
11057
#
 
11058
#***
 
11059
 
 
11060
#****f* lyricue/text_visibility_notify_event
 
11061
# NAME
 
11062
#   text_visibility_notify_event
 
11063
# SYNOPSIS
 
11064
#   text_visibility_notify_event($text_view, $event)
 
11065
# FUNCTION
 
11066
#
 
11067
# INPUTS
 
11068
#   $text_view -
 
11069
#    $event -
 
11070
# OUTPUT
 
11071
# SOURCE
 
11072
#
 
11073
sub text_visibility_notify_event {
 
11074
    my ($text_view, $event) = @_;
 
11075
    my (undef, $wx, $wy, undef) = $text_view->window->get_pointer;
 
11076
    my ($bx, $by) = $text_view->window_to_buffer_coords('widget', $wx, $wy);
 
11077
    text_set_cursor_if_appropriate($text_view, $bx, $by);
 
11078
    return FALSE;
 
11079
}
 
11080
 
 
11081
#***
 
11082
 
 
11083
#****f* lyricue/import_song_from_file
 
11084
# NAME
 
11085
#   import_song_from_file
 
11086
# SYNOPSIS
 
11087
#   import_song_from_file($filename)
 
11088
# FUNCTION
 
11089
#
 
11090
# INPUTS
 
11091
#   $filename -
 
11092
# OUTPUT
 
11093
# SOURCE
 
11094
#
 
11095
sub import_song_from_file {
 
11096
    my ($filename) = @_;
 
11097
    import_songs($filename);
 
11098
}
 
11099
 
 
11100
#***
 
11101
 
 
11102
#****f* lyricue/import_song_songselect
 
11103
# NAME
 
11104
#   import_song_songselect
 
11105
# SYNOPSIS
 
11106
#   import_song_songselect($filename)
 
11107
# FUNCTION
 
11108
#   import songselect song
 
11109
# INPUTS
 
11110
#   $filename -
 
11111
# OUTPUT
 
11112
# SOURCE
 
11113
#
 
11114
sub import_song_songselect {
 
11115
    my ($filename) = @_;
 
11116
    debug("import songselect song");
 
11117
    open(SONG, $filename) || return;
 
11118
    my $hashnum = 0;
 
11119
 
 
11120
    while (<SONG>) {
 
11121
        $_ =~ s/
 
 
b'//g;'
 
11122
        chomp;
 
11123
        my @line = split(/=/, $_, 2);
 
11124
        $_ = $line[0];
 
11125
        if (/Title/) {
 
11126
            $widgets->{'add'}->get_widget('entryEditName')->set_text($line[1]);
 
11127
        } elsif (/Author/) {
 
11128
            $widgets->{'add'}->get_widget('entryEditArtist')
 
11129
              ->set_text($line[1]);
 
11130
        } elsif (/Copyright/) {
 
11131
            $widgets->{'add'}->get_widget('entryEditCopyright')
 
11132
              ->set_text($line[1]);
 
11133
        } elsif (/Themes/) {
 
11134
            $line[1] =~ s/\/t/ /g;
 
11135
            $widgets->{'add'}->get_widget('entryEditKeywords')
 
11136
              ->set_text($line[1]);
 
11137
        } elsif (/Words/) {
 
11138
            my @words = split(/\/t/, $line[1]);
 
11139
            foreach (@words) {
 
11140
                if ($_ ne "") {
 
11141
                    $_ =~ s/\/n/\n/g;
 
11142
                    chomp;
 
11143
                    if ($hashnum == 0) {
 
11144
                        $widgets->{'textAPageB'}{$hashnum}->set_text($_);
 
11145
                        $hashnum++;
 
11146
                    } else {
 
11147
                        $hashnum = add_page();
 
11148
                        $widgets->{'textAPageB'}{$hashnum}->set_text($_);
 
11149
                    }
 
11150
                }
 
11151
            }
 
11152
        }
 
11153
    }
 
11154
    close SONG;
 
11155
 
 
11156
}
 
11157
 
 
11158
#***
 
11159
 
 
11160
#****f* lyricue/import_song_opw
 
11161
# NAME
 
11162
#   import_song_opw
 
11163
# SYNOPSIS
 
11164
#   import_song_opw($filename)
 
11165
# FUNCTION
 
11166
#   import opw song
 
11167
# INPUTS
 
11168
#   $filename -
 
11169
# OUTPUT
 
11170
# SOURCE
 
11171
#
 
11172
sub import_song_opw {
 
11173
    my ($filename) = @_;
 
11174
    debug("import opw song");
 
11175
    my $input   = "";
 
11176
    my $hashnum = 0;
 
11177
 
 
11178
    open(OPW, $filename) || die("Unable to open $filename");
 
11179
    while (<OPW>) {
 
11180
        $input .= fromutf("cp-1252", $_);
 
11181
    }
 
11182
    close OPW;
 
11183
 
 
11184
    $input =~ /bundel>(.*)<\/bundel/;
 
11185
    $widgets->{'add'}->get_widget('entryEditBook')->set_text($1);
 
11186
 
 
11187
    $input =~ /nummer>(.*)<\/nummer/;
 
11188
    $widgets->{'add'}->get_widget('entryEditNumber')->set_text($1);
 
11189
 
 
11190
    $input =~ /titel>(.*)<\/titel/;
 
11191
    $widgets->{'add'}->get_widget('entryEditName')->set_text($1);
 
11192
 
 
11193
    $input =~ /copyrights>(.*)<\/copyrights/;
 
11194
    $widgets->{'add'}->get_widget('entryEditCopyright')->set_text($1);
 
11195
 
 
11196
    $input =~ /beginregel>(.*)<\/beginregel/;
 
11197
    $widgets->{'add'}->get_widget('entryEditKeywords')->set_text($1);
 
11198
 
 
11199
    $input =~ /tekst>(.*)<\/tekst/s;
 
11200
    my $lyrics = $1;
 
11201
    $lyrics =~ s/
 
 
b'//g;'
 
11202
    my @lyrics = split(/\n \n/, $lyrics);
 
11203
 
 
11204
    foreach (@lyrics) {
 
11205
        if ($_ ne "") {
 
11206
            chomp;
 
11207
            $_ =~ s/ *$//g;
 
11208
            $_ =~ s/^[0-9]*\. //g;
 
11209
            if ($hashnum == 0) {
 
11210
                $widgets->{'textAPageB'}{$hashnum}->set_text($_);
 
11211
                $hashnum++;
 
11212
            } else {
 
11213
                $hashnum = add_page();
 
11214
                $widgets->{'textAPageB'}{$hashnum}->set_text($_);
 
11215
            }
 
11216
        }
 
11217
    }
 
11218
}
 
11219
 
 
11220
#***
 
11221
 
 
11222
#****f* lyricue/import_song_html
 
11223
# NAME
 
11224
#   import_song_html
 
11225
# SYNOPSIS
 
11226
#   import_song_html($filename)
 
11227
# FUNCTION
 
11228
#   import HTML/Opensong song
 
11229
# INPUTS
 
11230
#   $filename -
 
11231
# OUTPUT
 
11232
# SOURCE
 
11233
#
 
11234
sub import_song_html {
 
11235
    my ($filename) = @_;
 
11236
    debug("import HTML/Opensong song");
 
11237
    my ($name, $author) = "";
 
11238
    my $input   = "";
 
11239
    my $page    = "";
 
11240
    my $hashnum = 0;
 
11241
 
 
11242
    open(HTML, $filename) || die("Unable to open $filename");
 
11243
    while (<HTML>) {
 
11244
        chomp;
 
11245
        if (/div id="title"/) {
 
11246
            $name = $_;
 
11247
            $name =~ s/^.*id=\"title\">(.*)<\/div>.*$/$1/g;
 
11248
            $widgets->{'add'}->get_widget('entryEditName')->set_text($name);
 
11249
        } elsif (/div id="author"/) {
 
11250
            $author = $_;
 
11251
            $author =~ s/^.*id="author">(.*)<\/div>.*/$1/g;
 
11252
            $widgets->{'add'}->get_widget('entryEditArtist')->set_text($author);
 
11253
        } elsif (/div class="heading"/) {
 
11254
 
 
11255
            # new page
 
11256
            debug("add page");
 
11257
            if ($page ne "") {
 
11258
                my $iter = $widgets->{'textAPageB'}{$hashnum}->get_end_iter();
 
11259
                $widgets->{'textAPageB'}{$hashnum}->insert($iter, $page);
 
11260
                $page    = "";
 
11261
                $hashnum = add_page();
 
11262
            }
 
11263
        } elsif (/td class="lyrics"/) {
 
11264
            my $line = $_;
 
11265
            $line =~ s/^.*class="lyrics">(.*)<\/td>.*/$1/g;
 
11266
            $line =~ s/&nbsp;/ /g;
 
11267
            $page .= $line;
 
11268
        } elsif (/<\/table>/) {
 
11269
            debug("add line");
 
11270
            $page .= "
 
 
b'";'
 
11271
        }
 
11272
    }
 
11273
    close HTML;
 
11274
    if ($page ne "") {
 
11275
        my $iter = $widgets->{'textAPageB'}{$hashnum}->get_end_iter();
 
11276
        $widgets->{'textAPageB'}{$hashnum}->insert($iter, $page);
 
11277
        $page = "";
 
11278
    }
 
11279
}
 
11280
 
 
11281
####
 
11282
# Install database functions
 
11283
####
 
11284
#***
 
11285
 
 
11286
#****f* lyricue/db_check_app
 
11287
# NAME
 
11288
#   db_check_app
 
11289
# SYNOPSIS
 
11290
#   db_check_app()
 
11291
# FUNCTION
 
11292
#   Checking for database servers
 
11293
# INPUTS
 
11294
# OUTPUT
 
11295
# SOURCE
 
11296
#
 
11297
sub db_check_app {
 
11298
    debug("Checking for database servers");
 
11299
    if (defined $globals->{'force_sqlite'} && ($globals->{'force_sqlite'})) {
 
11300
        debug("Forcing usage of SQLite3");
 
11301
        $config->{'DatabaseType'} = "SQLite";
 
11302
        return;
 
11303
    }
 
11304
    my @ary    = DBI->available_drivers(1);
 
11305
    my $mysql  = FALSE;
 
11306
    my $sqlite = FALSE;
 
11307
    foreach (@ary) {
 
11308
        if ($_ eq "mysql") {
 
11309
            $mysql = TRUE;
 
11310
        } elsif ($_ eq "SQLite") {
 
11311
            $sqlite = TRUE;
 
11312
        }
 
11313
    }
 
11314
    if ($mysql) {
 
11315
        $config->{'DatabaseType'} = "mysql";
 
11316
    } elsif ($sqlite) {
 
11317
        $config->{'DatabaseType'} = "SQLite";
 
11318
    } else {
 
11319
        die("No supported DB found");
 
11320
    }
 
11321
}
 
11322
 
 
11323
#***
 
11324
 
 
11325
#****f* lyricue/db_get_admin
 
11326
# NAME
 
11327
#   db_get_admin
 
11328
# SYNOPSIS
 
11329
#   db_get_admin()
 
11330
# FUNCTION
 
11331
#   Get the db admin login information
 
11332
# INPUTS
 
11333
# OUTPUT
 
11334
# SOURCE
 
11335
#
 
11336
sub db_get_admin {
 
11337
    debug("Get the db admin login information");
 
11338
 
 
11339
    my $dbh;
 
11340
    eval {
 
11341
        $dbh = DBI->connect(
 
11342
            "DBI:"
 
11343
              . $config->{'DatabaseType'}
 
11344
              . ":mysql:"
 
11345
              . $globals->{'mysqlhost'},
 
11346
            "root", ""
 
11347
        );
 
11348
    };
 
11349
    if ($dbh) {
 
11350
        $globals->{'db_adminuser'}     = "root";
 
11351
        $globals->{'db_adminpassword'} = "";
 
11352
        return;
 
11353
    }
 
11354
 
 
11355
    if ($config->{'DatabaseType'} eq "mysql") {
 
11356
        my $adminxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
11357
            'dialogAdminLogin', 'lyricue');
 
11358
        $adminxml->signal_autoconnect_from_package('');
 
11359
        my $confirm = $adminxml->get_widget('dialogAdminLogin')->run();
 
11360
        if ($confirm == 0) {
 
11361
            $globals->{'db_adminuser'} =
 
11362
              $adminxml->get_widget('entryAdminLogin')->get_text();
 
11363
            $globals->{'db_adminpassword'} =
 
11364
              $adminxml->get_widget('entryAdminPass')->get_text();
 
11365
        } else {
 
11366
            my $confirmxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
11367
                'dialogConfirm', 'lyricue');
 
11368
            $confirmxml->signal_autoconnect_from_package('');
 
11369
            $confirmxml->get_widget('labelDelete')
 
11370
              ->set_text(
 
11371
                fromutf(gettext("Are you sure you want to exit Lyricue?")));
 
11372
            $confirm = $confirmxml->get_widget('dialogConfirm')->run();
 
11373
            close_dialog($adminxml->get_widget('dialogAdminLogin'));
 
11374
            if ($confirm eq "ok") {
 
11375
                debug("Exiting on request");
 
11376
                exit 1;
 
11377
            } else {
 
11378
                db_get_admin();
 
11379
                return;
 
11380
            }
 
11381
 
 
11382
        }
 
11383
        close_dialog($adminxml->get_widget('dialogAdminLogin'));
 
11384
    } else {
 
11385
        $globals->{'db_adminuser'}     = "lyricue";
 
11386
        $globals->{'db_adminpassword'} = "";
 
11387
 
 
11388
    }
 
11389
    eval {
 
11390
        $dbh = DBI->connect(
 
11391
            "DBI:"
 
11392
              . $config->{'DatabaseType'}
 
11393
              . ":mysql:"
 
11394
              . $globals->{'mysqlhost'},
 
11395
            $globals->{'db_adminuser'}, $globals->{'db_adminpassword'}
 
11396
        );
 
11397
    };
 
11398
 
 
11399
    if (!$dbh) {
 
11400
        debug("Password incorrect - retry");
 
11401
        db_get_admin();
 
11402
    }
 
11403
}
 
11404
 
 
11405
#***
 
11406
 
 
11407
#****f* lyricue/db_install_user
 
11408
# NAME
 
11409
#   db_install_user
 
11410
# SYNOPSIS
 
11411
#   db_install_user()
 
11412
# FUNCTION
 
11413
#   Install lyric database user
 
11414
# INPUTS
 
11415
# OUTPUT
 
11416
# SOURCE
 
11417
#
 
11418
sub db_install_user {
 
11419
    debug("Install lyric database user");
 
11420
    my ($dbh);
 
11421
    db_get_admin();
 
11422
    if ($config->{'DatabaseType'} eq "mysql") {
 
11423
        eval {
 
11424
            $dbh = DBI->connect(
 
11425
                "DBI:"
 
11426
                  . $config->{'DatabaseType'}
 
11427
                  . ":mysql:"
 
11428
                  . $globals->{'mysqlhost'},
 
11429
                $globals->{'db_adminuser'}, $globals->{'db_adminpassword'}
 
11430
            );
 
11431
        };
 
11432
        if ($@) {
 
11433
            my $labelText = fromutf(
 
11434
 
 
11435
                gettext(
 
11436
"Unable to login to database as admin, maybe the database is down.\nPlease re-enter your database admin login and retry"
 
11437
                )
 
11438
            );
 
11439
            my $loginxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
11440
                'dialogConfirm', 'lyricue');
 
11441
            $loginxml->signal_autoconnect_from_package('');
 
11442
            $loginxml->get_widget('dialogConfirm')
 
11443
              ->set_title(fromutf(gettext("Login Error")));
 
11444
            $loginxml->get_widget('labelDelete')->set_text($labelText);
 
11445
            my $confirm = $loginxml->get_widget('dialogConfirm')->run();
 
11446
            if ($confirm eq "ok") {
 
11447
                close_dialog($loginxml->get_widget('dialogConfirm'));
 
11448
                db_install_user();
 
11449
                return;
 
11450
            } else {
 
11451
                display_fatal($errorcodes->{'lyricdbopen'}, $DBI::errstr);
 
11452
            }
 
11453
        }
 
11454
    }
 
11455
    my $sth = $dbh->prepare("select * from user where User='lyric'");
 
11456
    my $rv  = $sth->execute;
 
11457
    db_reload();
 
11458
    if ($sth->rows) {
 
11459
        debug("User already setup\n");
 
11460
    } else {
 
11461
        debug("Creating mysql user..");
 
11462
        $sth = $dbh->prepare(
 
11463
"insert into user set Host='%',User='lyric',Password='',Select_priv='Y',Insert_priv='Y', Update_priv='Y',Delete_priv='Y',Lock_tables_priv='Y',"
 
11464
        );
 
11465
        $sth->execute;
 
11466
        $sth = $dbh->prepare(
 
11467
"insert into user set Host='localhost',User='lyric',Password='',Select_priv='Y',Insert_priv='Y', Update_priv='Y',Delete_priv='Y',Lock_tables_priv='Y'"
 
11468
        );
 
11469
        $sth->execute;
 
11470
        $sth = $dbh->prepare("flush privileges");
 
11471
        $sth->execute;
 
11472
        debug("Done\n");
 
11473
    }
 
11474
    db_check_databases();
 
11475
}
 
11476
 
 
11477
#***
 
11478
 
 
11479
#****f* lyricue/db_check_databases
 
11480
# NAME
 
11481
#   db_check_databases
 
11482
# SYNOPSIS
 
11483
#   db_check_databases()
 
11484
# FUNCTION
 
11485
#   Update/install databases
 
11486
# INPUTS
 
11487
# OUTPUT
 
11488
# SOURCE
 
11489
#
 
11490
sub db_check_databases {
 
11491
    debug("Update/install databases");
 
11492
    if ($config->{'DatabaseType'} eq "mysql") {
 
11493
        my @dbs = DBI->data_sources($config->{'DatabaseType'},
 
11494
            {"host" => $globals->{'mysqlhost'}, "user" => "lyric"});
 
11495
 
 
11496
        foreach (@dbs) {
 
11497
            $_ =~ s/^DBI:.*://g;
 
11498
            $globals->{'db_available_db'}{$_} = TRUE;
 
11499
        }
 
11500
    } else {
 
11501
        opendir(DIR, $globals->{'basedir'});
 
11502
        while (readdir(DIR)) {
 
11503
            if (/.db$/) {
 
11504
                $_ =~ s/.db$//g;
 
11505
                $globals->{'db_available_db'}{$_} = TRUE;
 
11506
            }
 
11507
        }
 
11508
    }
 
11509
 
 
11510
    if ($globals->{'db_available_db'}{'lyricDb'}) {
 
11511
        db_updatedb_lyricDb();
 
11512
    } else {
 
11513
        db_installdb($globals->{'sharedir'} . "mysql/Create_lyricDb.sql",
 
11514
            "lyricDb");
 
11515
    }
 
11516
 
 
11517
    if ($globals->{'db_available_db'}{'mediaDb'}) {
 
11518
        db_updatedb_mediaDb();
 
11519
    } else {
 
11520
        debug("Creating mediaDb");
 
11521
        db_installdb($globals->{'sharedir'} . "mysql/Create_mediaDb.sql",
 
11522
            "mediaDb");
 
11523
        db_reload();
 
11524
 
 
11525
        # Don't do this anymore - leave stuff in their homes
 
11526
        #debug("Importing existing backgrounds/images\n");
 
11527
 
 
11528
       # NOTE FAILS WITH SQLITE
 
11529
       #if ($config->{'DatabaseType'} eq "mysql") {
 
11530
       #    system("import_media img " . $globals->{'sharedir'} . "images");
 
11531
       #    system("import_media bg " . $globals->{'sharedir'} . "backgrounds");
 
11532
       #}
 
11533
        debug("Done\n");
 
11534
    }
 
11535
}
 
11536
 
 
11537
#***
 
11538
 
 
11539
#****f* lyricue/db_reload
 
11540
# NAME
 
11541
#   db_reload
 
11542
# SYNOPSIS
 
11543
#   db_reload()
 
11544
# FUNCTION
 
11545
#   Reload db
 
11546
# INPUTS
 
11547
# OUTPUT
 
11548
# SOURCE
 
11549
#
 
11550
sub db_reload {
 
11551
    debug("Reload db");
 
11552
    if ($globals->{'db_adminuser'} eq "") {
 
11553
        db_get_admin();
 
11554
    }
 
11555
    if ($config->{'DatabaseType'} eq "mysql") {
 
11556
        my $drh = DBI->install_driver('mysql');
 
11557
        my $rc  = $drh->func(
 
11558
            "reload",
 
11559
            [
 
11560
                $globals->{'mysqlhost'}, $globals->{'db_adminuser'},
 
11561
                $globals->{'adminpassword'},
 
11562
            ],
 
11563
            'admin'
 
11564
        );
 
11565
    }
 
11566
}
 
11567
 
 
11568
#***
 
11569
 
 
11570
#****f* lyricue/db_installdb
 
11571
# NAME
 
11572
#   db_installdb
 
11573
# SYNOPSIS
 
11574
#   db_installdb($db_file, $db_name)
 
11575
# FUNCTION
 
11576
#   Install db from
 
11577
# INPUTS
 
11578
#   $db_file -
 
11579
#    $db_name -
 
11580
# OUTPUT
 
11581
# SOURCE
 
11582
#
 
11583
sub db_installdb {
 
11584
    my ($db_file, $db_name) = @_;
 
11585
    debug("Install db from " . $db_file);
 
11586
    if ($globals->{'db_adminuser'} eq "") {
 
11587
        db_get_admin();
 
11588
    }
 
11589
    if ($config->{'DatabaseType'} eq "mysql") {
 
11590
        system( "cat " 
 
11591
              . $db_file
 
11592
              . " | mysql -f -h "
 
11593
              . $globals->{'mysqlhost'} . " -u "
 
11594
              . $globals->{'db_adminuser'}
 
11595
              . " --password=\""
 
11596
              . $globals->{'db_adminpassword'}."\"");
 
11597
    } else {
 
11598
        my $dbh = db_connect($db_name, "Unable to create DB:" . $db_name);
 
11599
        open(DB, $db_file);
 
11600
        my $query = "";
 
11601
        while (<DB>) {
 
11602
            $_ =~ s/^CREATE DATABASE*;$//g;
 
11603
            $_ =~ s/^USE *;$//g;
 
11604
            if (   (/^ *UNIQUE KEY/)
 
11605
                || (/^--/)
 
11606
                || (/^CREATE DATABASE /)
 
11607
                || (/^USE /))
 
11608
            {
 
11609
                $_ = "";
 
11610
            }
 
11611
            $_ =~ s/(PRIMARY KEY .*),$/$1/g;
 
11612
            $_ =~ s/auto_increment,$/,/g;
 
11613
            $_ =~ s/TYPE=MyISAM;$/;/g;
 
11614
            $_ =~ s/unsigned NOT NULL/NOT NULL/g;
 
11615
            $_ =~ s/int(11)/INTEGER/g;
 
11616
            $_ =~ s/\\'/''/g;
 
11617
            $_ =~ s/\\n/\n/g;
 
11618
 
 
11619
            if (!/;$/) {
 
11620
                $query .= $_;
 
11621
            } else {
 
11622
                $query .= $_;
 
11623
                if ($query ne "") {
 
11624
                    $dbh->do($query);
 
11625
                }
 
11626
                $query = "";
 
11627
            }
 
11628
        }
 
11629
        $dbh->disconnect();
 
11630
    }
 
11631
}
 
11632
 
 
11633
#***
 
11634
 
 
11635
#****f* lyricue/db_updatedb_mediaDb
 
11636
# NAME
 
11637
#   db_updatedb_mediaDb
 
11638
# SYNOPSIS
 
11639
#   db_updatedb_mediaDb()
 
11640
# FUNCTION
 
11641
#   Update the mediaDb table if needed
 
11642
# INPUTS
 
11643
# OUTPUT
 
11644
# SOURCE
 
11645
#
 
11646
sub db_updatedb_mediaDb {
 
11647
    debug("Update the mediaDb table if needed");
 
11648
    my $dbh = db_connect($globals->{'mediadb'}, "");
 
11649
    if ($config->{'DatabaseType'} eq "mysql") {
 
11650
        my $fields = $dbh->selectall_arrayref("describe media");
 
11651
        my $trans;
 
11652
        foreach (@$fields) {
 
11653
            $trans->{$_->[0]} = 1;
 
11654
        }
 
11655
        if (!defined $trans->{'textcolour'}) {
 
11656
            debug("Text Colouring fields not found\n");
 
11657
            debug("Upgrading database from 1.9 to 1.9.4\n");
 
11658
            db_installdb($globals->{'sharedir'} . "mysql/Update_1.9.4.sql",
 
11659
                "lyricDb");
 
11660
            debug("Done\n");
 
11661
        }
 
11662
    }
 
11663
}
 
11664
 
 
11665
#***
 
11666
 
 
11667
#****f* lyricue/db_updatedb_lyricDb
 
11668
# NAME
 
11669
#   db_updatedb_lyricDb
 
11670
# SYNOPSIS
 
11671
#   db_updatedb_lyricDb()
 
11672
# FUNCTION
 
11673
#   Update the lyricDb table if needed
 
11674
# INPUTS
 
11675
# OUTPUT
 
11676
# SOURCE
 
11677
#
 
11678
sub db_updatedb_lyricDb {
 
11679
    debug("Update the lyricDb table if needed");
 
11680
    my $dbh = db_connect($globals->{'lyricdb'}, $errorcodes->{'lyricdbopen'});
 
11681
    my @tables = $dbh->tables;
 
11682
    my $table;
 
11683
    foreach (@tables) {
 
11684
        $_ =~ s/^.*`(.*)`$/$1/g;
 
11685
        $_ =~ s/^"(.*)"$/$1/g;
 
11686
        $table->{$_} = 1;
 
11687
    }
 
11688
    if (!defined $table->{'associations'}) {
 
11689
        debug("Associations table not found\n");
 
11690
        debug("Upgrading database from < 1.2 to 1.2\n");
 
11691
        db_installdb($globals->{'sharedir'} . "mysql/Update_1.2.sql",
 
11692
            "lyricDb");
 
11693
        debug("Done\n");
 
11694
    }
 
11695
    if (!defined $table->{'config'}) {
 
11696
        debug("Configuration tables not found\n");
 
11697
        debug("Upgrading database from < 2.4 to 2.4\n");
 
11698
        db_installdb($globals->{'sharedir'} . "mysql/Update_2.4.sql",
 
11699
            "lyricDb");
 
11700
        debug("Done\n");
 
11701
    }
 
11702
    if ($config->{'DatabaseType'} eq "mysql") {
 
11703
        my $fields = $dbh->selectall_arrayref("describe playlist");
 
11704
        my $trans;
 
11705
        foreach (@$fields) {
 
11706
            $trans->{$_->[0]} = 1;
 
11707
        }
 
11708
        if (!defined $trans->{'transition'}) {
 
11709
            debug("Transition field not found\n");
 
11710
            debug("Upgrading database from 1.2 to 1.9\n");
 
11711
            db_installdb($globals->{'sharedir'} . "mysql/Update_1.9.sql",
 
11712
                "lyricDb");
 
11713
            debug("Done\n");
 
11714
        }
 
11715
    }
 
11716
 
 
11717
    # Increase data size - does nothing if already done - only works for mysql
 
11718
    if ($config->{'DatabaseType'} eq "mysql") {
 
11719
        my $fields = $dbh->selectall_arrayref("describe playlist");
 
11720
        my $pl;
 
11721
        foreach (@$fields) {
 
11722
            $pl->{$_->[0]} = $_->[1];
 
11723
        }
 
11724
        if ($pl->{'data'} ne "varchar(256)") {
 
11725
            db_installdb($globals->{'sharedir'} . "mysql/Update_1.9.7.sql",
 
11726
                "lyricDb");
 
11727
        }
 
11728
    }
 
11729
 
 
11730
    # Add page title
 
11731
    if ($config->{'DatabaseType'} eq "mysql") {
 
11732
        my $fields = $dbh->selectall_arrayref("describe page");
 
11733
        my $page;
 
11734
        foreach (@$fields) {
 
11735
            $page->{$_->[0]} = $_->[1];
 
11736
        }
 
11737
        if (!defined $page->{'pagetitle'}) {
 
11738
            db_installdb($globals->{'sharedir'} . "mysql/Update_2.1.0.sql",
 
11739
                "lyricDb");
 
11740
        }
 
11741
    }
 
11742
 
 
11743
    # Ensure all tables are in UTF8 characterset
 
11744
    my @toconvert = ();
 
11745
    foreach my $tname (keys %$table) {
 
11746
        my $fields = $dbh->selectall_arrayref("show create table " . $tname);
 
11747
        foreach (@$fields) {
 
11748
            if (!($_->[1] =~ /CHARSET=utf8/)) {
 
11749
                push @toconvert, $tname;
 
11750
            }
 
11751
        }
 
11752
 
 
11753
    }
 
11754
    if (@toconvert > 0) {
 
11755
        if ($globals->{'db_adminuser'} eq "") {
 
11756
            db_get_admin();
 
11757
        }
 
11758
        eval {
 
11759
            $dbh = DBI->connect(
 
11760
                "DBI:"
 
11761
                  . $config->{'DatabaseType'}
 
11762
                  . ":mysql:"
 
11763
                  . $globals->{'mysqlhost'},
 
11764
                $globals->{'db_adminuser'}, $globals->{'db_adminpassword'}
 
11765
            );
 
11766
        };
 
11767
        if ($dbh) {
 
11768
            foreach (@toconvert) {
 
11769
                debug("Converting " . $_ . " to utf8");
 
11770
                $dbh->do("ALTER TABLE lyricDb." 
 
11771
                      . $_
 
11772
                      . " CONVERT TO CHARACTER SET utf8");
 
11773
            }
 
11774
        }
 
11775
    }
 
11776
 
 
11777
}
 
11778
 
 
11779
#***
 
11780
 
 
11781
#****f* lyricue/check_tracker
 
11782
# NAME
 
11783
#   check_tracker
 
11784
# SYNOPSIS
 
11785
#   check_tracker()
 
11786
# FUNCTION
 
11787
#
 
11788
# INPUTS
 
11789
# OUTPUT
 
11790
# SOURCE
 
11791
#
 
11792
sub check_tracker {
 
11793
 
 
11794
    #debug("Check tracker");
 
11795
    my $query = "SELECT ref,title FROM playlists WHERE id=-1";
 
11796
 
 
11797
    #qdebug($query); # Commented out because it's too noisy
 
11798
    my $sth = $lyricDbh->prepare($query)
 
11799
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
11800
    my $rv = $sth->execute
 
11801
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
11802
    my @row = $sth->fetchrow_array();
 
11803
 
 
11804
    #Mark the row
 
11805
    if (@row && ($row[0] ne $globals->{'current_item'})) {
 
11806
        $globals->{'previous_item'} = $globals->{'current_item'};
 
11807
        $globals->{'current_item'}  = $row[0];
 
11808
        my $model = $widgets->{'main'}->get_widget('treePlaylist')->get_model();
 
11809
        if ($model) {
 
11810
            $globals->{'current_item_path'} = "";
 
11811
            $model->foreach(\&update_current);
 
11812
            if ($globals->{'current_item_path'} ne "") {
 
11813
                my $path = Gtk2::TreePath->new_from_string(
 
11814
                    $globals->{'current_item_path'});
 
11815
                while ($path->up()) {
 
11816
                    if ($path->get_depth() > 0) {
 
11817
                        my $iter = $model->get_iter($path);
 
11818
                        if ($iter) {
 
11819
                            $model->set($iter, 1, $config->{'HighlightColour'});
 
11820
                        }
 
11821
                    }
 
11822
                }
 
11823
            FALSE}
 
11824
        }
 
11825
    }
 
11826
    if (defined($row[1]) && $row[1] ne "") {
 
11827
        my $blank_text = $widgets->{'main'}->get_widget('buttonMainClear')->get_active();
 
11828
        my $blank_bg = $widgets->{'main'}->get_widget('buttonMainBlank')->get_active();
 
11829
        my $blank_text_new = $blank_text;
 
11830
        my $blank_bg_new = $blank_bg;
 
11831
        if ($row[1] =~ /^blank_bg/) {
 
11832
            $row[1] =~ s/^blank_bg//g;
 
11833
            $blank_bg_new = TRUE;
 
11834
            $blank_text_new = FALSE;
 
11835
        } elsif ($row[1] =~ /^blank_text/) {
 
11836
            $row[1] =~ s/^blank_text//g;
 
11837
            $blank_bg_new = FALSE;
 
11838
            $blank_text_new = TRUE;
 
11839
        } else {
 
11840
            $blank_bg_new = FALSE;
 
11841
            $blank_text_new = FALSE;
 
11842
        }
 
11843
        if ($blank_bg != $blank_bg_new) {
 
11844
            $globals->{'ignore_blank'} = TRUE;
 
11845
            $widgets->{'main'}->get_widget('buttonMainBlank')->set_active($blank_bg_new);
 
11846
        }
 
11847
        if ($blank_text != $blank_text_new) {
 
11848
            $globals->{'ignore_clear'} = TRUE;
 
11849
            $widgets->{'main'}->get_widget('buttonMainClear')->set_active($blank_text_new);
 
11850
        }
 
11851
        my ($position, $duration, $status) = split(/;/, $row[1], 3);
 
11852
        my $hscale = $widgets->{'main'}->get_widget('hscaleMediaPosition');
 
11853
        if (defined $globals->{'video_skip_signal'}) {
 
11854
            $hscale->signal_handler_disconnect($globals->{'video_skip_signal'});
 
11855
        }
 
11856
        if ($duration <= 0) {
 
11857
            $hscale->set_range(0, 1000);
 
11858
        } else {
 
11859
            $hscale->set_range(0, $duration);
 
11860
        }
 
11861
        $hscale->set_value($position);
 
11862
        $position = sprintf("%d:%02d", $position / 60, $position % 60);
 
11863
        $duration = sprintf("%d:%02d", $duration / 60, $duration % 60);
 
11864
        $widgets->{'main'}->get_widget('labelMediaPosition')
 
11865
          ->set_text($position . "/" . $duration);
 
11866
        if ($status) {
 
11867
            $widgets->{'main'}->get_widget('buttonMediaPlay')->hide;
 
11868
            $widgets->{'main'}->get_widget('buttonMediaPause')->show_all;
 
11869
        } else {
 
11870
            $widgets->{'main'}->get_widget('buttonMediaPlay')->show_all;
 
11871
            $widgets->{'main'}->get_widget('buttonMediaPause')->hide;
 
11872
        }
 
11873
        do_pending();
 
11874
        $globals->{'video_skip_signal'} =
 
11875
          $hscale->signal_connect('value-changed', "video_skip");
 
11876
    }
 
11877
    return TRUE;
 
11878
}
 
11879
 
 
11880
#***
 
11881
 
 
11882
#****f* lyricue/video_skip
 
11883
# NAME
 
11884
#   video_skip
 
11885
# SYNOPSIS
 
11886
#   video_skip()
 
11887
# FUNCTION
 
11888
#   Tell server to skip to position
 
11889
# INPUTS
 
11890
# OUTPUT
 
11891
# SOURCE
 
11892
#
 
11893
sub video_skip {
 
11894
    my ($hscale) = @_;
 
11895
    debug("Skipping to " . $hscale->get_value());
 
11896
    update_display("media", "skip", $hscale->get_value());
 
11897
}
 
11898
 
 
11899
#****f* lyricue/update_current
 
11900
# NAME
 
11901
#   update_current
 
11902
# SYNOPSIS
 
11903
#   update_current($store, $path, $iter)
 
11904
# FUNCTION
 
11905
#
 
11906
# INPUTS
 
11907
#   $store -
 
11908
#    $path -
 
11909
#    $iter -
 
11910
# OUTPUT
 
11911
# SOURCE
 
11912
#
 
11913
sub update_current {
 
11914
    my ($store, $path, $iter) = @_;
 
11915
    my $playlistid = $store->get($iter, 2);
 
11916
    if ($playlistid eq $globals->{'current_item'}) {
 
11917
        $store->set($iter, 1, $config->{'HighlightColour'});
 
11918
        $globals->{'current_item_path'} = $path->to_string;
 
11919
    } else {
 
11920
        if ($globals->{'current_item_path'} ne "") {
 
11921
            if (
 
11922
                !$path->is_ancestor(
 
11923
                    Gtk2::TreePath->new_from_string(
 
11924
                        $globals->{'current_item_path'}
 
11925
                    )
 
11926
                )
 
11927
              )
 
11928
            {
 
11929
                $store->set($iter, 1, undef);
 
11930
            }
 
11931
        } else {
 
11932
            $store->set($iter, 1, undef);
 
11933
        }
 
11934
    }
 
11935
    return FALSE;
 
11936
}
 
11937
 
 
11938
#***
 
11939
 
 
11940
#****f* lyricue/clear_search
 
11941
# NAME
 
11942
#   clear_search
 
11943
# SYNOPSIS
 
11944
#   clear_search()
 
11945
# FUNCTION
 
11946
#   Clear search entry
 
11947
# INPUTS
 
11948
# OUTPUT
 
11949
# SOURCE
 
11950
#
 
11951
sub clear_search {
 
11952
    debug("Clear search entry");
 
11953
    $widgets->{'main'}->get_widget('entrySearch')->set_text("");
 
11954
    $widgets->{'main'}->get_widget('entrySearch')->grab_focus();
 
11955
}
 
11956
 
 
11957
#***
 
11958
 
 
11959
#****f* lyricue/db_connect
 
11960
# NAME
 
11961
#   db_connect
 
11962
# SYNOPSIS
 
11963
#   db_connect($dbname, $dberror)
 
11964
# FUNCTION
 
11965
#
 
11966
# INPUTS
 
11967
#   $dbname -
 
11968
#    $dberror -
 
11969
# OUTPUT
 
11970
# SOURCE
 
11971
#
 
11972
sub db_connect {
 
11973
    my ($dbname, $dberror) = @_;
 
11974
    my ($dbh);
 
11975
    if ($config->{'DatabaseType'} eq "SQLite") {
 
11976
        $dbh =
 
11977
          DBI->connect("dbi:SQLite:" . $globals->{'basedir'} . $dbname . ".db",
 
11978
            "", "")
 
11979
          || display_fatal($dberror, $DBI::errstr);
 
11980
    } else {
 
11981
        $dbh = DBI->connect(
 
11982
            "DBI:"
 
11983
              . $config->{'DatabaseType'}
 
11984
              . ":database=$dbname;host=$globals->{'mysqlhost'}",
 
11985
            "lyric",
 
11986
            "",
 
11987
            {mysql_enable_utf8 => 1}
 
11988
        ) || display_fatal($dberror, $DBI::errstr);
 
11989
        $dbh->do('SET NAMES utf8');
 
11990
    }
 
11991
    return $dbh;
 
11992
}
 
11993
 
 
11994
#***
 
11995
 
 
11996
#****f* lyricue/prefs_select_mysql
 
11997
# NAME
 
11998
#   prefs_select_mysql
 
11999
# SYNOPSIS
 
12000
#   prefs_select_mysql()
 
12001
# FUNCTION
 
12002
#   Selecting MySQL DB
 
12003
# INPUTS
 
12004
# OUTPUT
 
12005
# SOURCE
 
12006
#
 
12007
sub prefs_select_mysql {
 
12008
    if ($config->{'DatabaseType'} ne "mysql") {
 
12009
        debug("Selecting MySQL DB");
 
12010
        $config->{'DatabaseType'} = "mysql";
 
12011
        db_restart();
 
12012
    }
 
12013
}
 
12014
 
 
12015
#***
 
12016
 
 
12017
#****f* lyricue/prefs_select_sqlite
 
12018
# NAME
 
12019
#   prefs_select_sqlite
 
12020
# SYNOPSIS
 
12021
#   prefs_select_sqlite()
 
12022
# FUNCTION
 
12023
#   Selecting SQLite DB
 
12024
# INPUTS
 
12025
# OUTPUT
 
12026
# SOURCE
 
12027
#
 
12028
sub prefs_select_sqlite {
 
12029
    if ($config->{'DatabaseType'} ne "SQLite") {
 
12030
        debug("Selecting SQLite DB");
 
12031
        $config->{'DatabaseType'} = "SQLite";
 
12032
        db_restart();
 
12033
    }
 
12034
}
 
12035
 
 
12036
#***
 
12037
 
 
12038
#****f* lyricue/db_restart
 
12039
# NAME
 
12040
#   db_restart
 
12041
# SYNOPSIS
 
12042
#   db_restart()
 
12043
# FUNCTION
 
12044
#   Reconnecting to DBs
 
12045
# INPUTS
 
12046
# OUTPUT
 
12047
# SOURCE
 
12048
#
 
12049
sub db_restart {
 
12050
    debug("Reconnecting to DBs");
 
12051
    $lyricDbh->disconnect();
 
12052
    $mediaDbh->disconnect();
 
12053
    db_select();
 
12054
    if (defined $config->{'DefBible'} && ($config->{'DefBible'} ne "")) {
 
12055
        my @tmpbible = split(/;/, $config->{'DefBible'}, 2);
 
12056
        $globals->{'biblename'} = $tmpbible[1];
 
12057
        @tmpbible = split(/:/, $tmpbible[0], 2);
 
12058
        do_change_bible($tmpbible[1], $tmpbible[0]);
 
12059
    }
 
12060
    choose_playlist();
 
12061
}
 
12062
 
 
12063
#***
 
12064
 
 
12065
#****f* lyricue/db_select
 
12066
# NAME
 
12067
#   db_select
 
12068
# SYNOPSIS
 
12069
#   db_select()
 
12070
# FUNCTION
 
12071
#
 
12072
# INPUTS
 
12073
# OUTPUT
 
12074
# SOURCE
 
12075
#
 
12076
sub db_select {
 
12077
 
 
12078
    # Open lyricDB, bibleDB and mediaDb
 
12079
    if ($config->{'DatabaseType'} eq "mysql") {
 
12080
        my $sqldb = DBI->connect(
 
12081
            "DBI:"
 
12082
              . $config->{'DatabaseType'}
 
12083
              . ":mysql:"
 
12084
              . $globals->{'mysqlhost'},
 
12085
            "lyric", ""
 
12086
        ) || db_install_user();
 
12087
        if ($sqldb) {
 
12088
            $sqldb->disconnect(); ## ERROR HERE ### Can't call 'disconnect' without a package or object reference
 
12089
        }
 
12090
    }
 
12091
    db_check_databases();
 
12092
    $lyricDbh = db_connect($globals->{'lyricdb'}, $errorcodes->{'lyricdbopen'});
 
12093
    if ($config->{'DatabaseType'} eq "SQLite") {
 
12094
 
 
12095
        # Define a NOW command in sqlite
 
12096
        $lyricDbh->func('NOW', 0, sub { return time }, 'create_function');
 
12097
    }
 
12098
    $mediaDbh = db_connect($globals->{'mediadb'}, $errorcodes->{'mediadbopen'});
 
12099
    $config->{'Bibles'} = get_bibles();
 
12100
}
 
12101
 
 
12102
#***
 
12103
 
 
12104
#****f* lyricue/add_to_playlist_search
 
12105
# NAME
 
12106
#   add_to_playlist_search
 
12107
# SYNOPSIS
 
12108
#   add_to_playlist_search($widget)
 
12109
# FUNCTION
 
12110
#   Songid \"" . $songid . "\" selected
 
12111
# INPUTS
 
12112
#   $widget -
 
12113
# OUTPUT
 
12114
# SOURCE
 
12115
#
 
12116
sub add_to_playlist_search {
 
12117
    my ($widget) = @_;
 
12118
    my $selection =
 
12119
      $widgets->{'search'}->get_widget('treeSearch')->get_selection;
 
12120
    my ($model, $iter) = $selection->get_selected;
 
12121
    if ($iter) {
 
12122
        my $songid = $model->get($iter, 4);
 
12123
        debug("Songid \"" . $songid . "\" selected");
 
12124
        add_single_song($songid);
 
12125
        update_playlist();
 
12126
    }
 
12127
}
 
12128
 
 
12129
#***
 
12130
 
 
12131
#****f* lyricue/on_hboxBackImage_drag_data_received
 
12132
# NAME
 
12133
#   on_hboxBackImage_drag_data_received
 
12134
# SYNOPSIS
 
12135
#   on_hboxBackImage_drag_data_received($widget, $context, $x, $y, $data, $info, $time)
 
12136
# FUNCTION
 
12137
#   Dropped on backgrounds
 
12138
# INPUTS
 
12139
#   $widget -
 
12140
#    $context -
 
12141
#    $x -
 
12142
#    $y -
 
12143
#    $data -
 
12144
#    $info -
 
12145
#    $time -
 
12146
# OUTPUT
 
12147
# SOURCE
 
12148
#
 
12149
sub on_hboxBackImage_drag_data_received {
 
12150
    debug("Dropped on backgrounds");
 
12151
    my ($widget, $context, $x, $y, $data, $info, $time) = @_;
 
12152
    my $category = $globals->{'category'};
 
12153
 
 
12154
    if (($category ne "") && ($data->length >= 0) && ($data->format == 8)) {
 
12155
        debug("Recieved " . $data->data);
 
12156
        if ($data->data) {
 
12157
            my @uris = split(/\n/, $data->data);
 
12158
            my ($filename, $format, $description);
 
12159
            my $owner = getpwuid($<);
 
12160
            my @date  = localtime(time);
 
12161
            my $time  = sprintf(
 
12162
                "%04d-%02d-%02d %02d:%02d:%02d",
 
12163
                $date[5] + 1900,
 
12164
                $date[4], $date[3], $date[2], $date[1], $date[0]
 
12165
            );
 
12166
            for my $uri (@uris) {
 
12167
                $filename = URI->new($uri);
 
12168
                debug("Category: $category, Filename: " . $filename->file);
 
12169
 
 
12170
                $format = $filename->file;
 
12171
                $format =~ s/^.*\.//g;
 
12172
                $description = $filename->file;
 
12173
                $description =~ s/^.*\///g;
 
12174
                $description =~ s/\..*?$//g;
 
12175
 
 
12176
                open(MEDIA, $filename->file);
 
12177
                my $filedata = "";
 
12178
 
 
12179
                while (<MEDIA>) {
 
12180
                    $filedata .= $_;
 
12181
                }
 
12182
                close MEDIA;
 
12183
                debug("Length: " . length($filedata));
 
12184
                my $sth = $mediaDbh->prepare(
 
12185
q{INSERT INTO media(category, subcategory, type, format, insertedby, insertdate, description, data) VALUES (?,?,?,?,?,?,?,?)}
 
12186
                );
 
12187
                my $rv =
 
12188
                  $sth->execute($category, "", "bg", $format, $owner, $time,
 
12189
                    $description, $filedata);
 
12190
            }
 
12191
            bgdir_change($widget, $category);
 
12192
        }
 
12193
 
 
12194
        $context->finish(1, 0, $time);
 
12195
        return;
 
12196
    } else {
 
12197
        debug("global category=$category");
 
12198
    }
 
12199
}
 
12200
 
 
12201
#***
 
12202
 
 
12203
#****f* lyricue/alphanum
 
12204
# NAME
 
12205
#   alphanum
 
12206
# SYNOPSIS
 
12207
#   alphanum()
 
12208
# FUNCTION
 
12209
#
 
12210
# INPUTS
 
12211
# OUTPUT
 
12212
# SOURCE
 
12213
#
 
12214
sub alphanum {
 
12215
 
 
12216
    # $a and $b are automagically passed to alphanum.
 
12217
    # A copy of them has to be made, or else we will edit the global $a and $b
 
12218
    my $a_copy = $a;
 
12219
    my $b_copy = $b;
 
12220
    my $n      = 0;
 
12221
    while ($n == 0) {
 
12222
 
 
12223
        # Get next "chunk"
 
12224
        # (A chunk is either a group of letters or a group of numbers)
 
12225
 
 
12226
        my ($a_chunk) = $a_copy =~ /([\D]+|[\d]+)/;
 
12227
        $a_copy =
 
12228
          substr($a_copy, length($a_chunk), length($a_copy) - length($a_chunk));
 
12229
 
 
12230
        my ($b_chunk) = $b_copy =~ /([\D]+|[\d]+)/;
 
12231
        $b_copy =
 
12232
          substr($b_copy, length($b_chunk), length($b_copy) - length($b_chunk));
 
12233
 
 
12234
        # Compare the chunks
 
12235
 
 
12236
        # Case 1: They both contain letters
 
12237
        if (($a_chunk =~ /\D+/) && ($b_chunk =~ /\D+/)) {
 
12238
            $n = $a_chunk cmp $b_chunk;
 
12239
        }
 
12240
 
 
12241
        # Case 2: They both contain numbers
 
12242
        else {
 
12243
            if (($a_chunk =~ /\d+/) && ($b_chunk =~ /\d+/)) {
 
12244
                $n = $a_chunk <=> $b_chunk;
 
12245
            }
 
12246
 
 
12247
            # Case 3: One has letters, one has numbers; or one is empty
 
12248
            else {
 
12249
                $n = $a_chunk cmp $b_chunk;
 
12250
 
 
12251
             # If these are equal, make one (which one is arbitrary) come before
 
12252
             # the other   (or else we'll be stuck in this "while $n==0" loop)
 
12253
                if ($n == 0) { $n = 1 }
 
12254
            }
 
12255
        }
 
12256
    }
 
12257
    return $n;
 
12258
}
 
12259
 
 
12260
#***
 
12261
 
 
12262
#****f* lyricue/fromutf
 
12263
# NAME
 
12264
#   fromutf
 
12265
# SYNOPSIS
 
12266
#   fromutf($line)
 
12267
# FUNCTION
 
12268
#
 
12269
# INPUTS
 
12270
#   $line -
 
12271
# OUTPUT
 
12272
# SOURCE
 
12273
#
 
12274
sub fromutf {
 
12275
    my ($line) = @_;
 
12276
    utf8::decode($line) unless utf8::is_utf8($line);
 
12277
    return $line;
 
12278
}
 
12279
 
 
12280
#***
 
12281
 
 
12282
#****f* lyricue/toutf
 
12283
# NAME
 
12284
#   toutf
 
12285
# SYNOPSIS
 
12286
#   toutf($line)
 
12287
# FUNCTION
 
12288
#
 
12289
# INPUTS
 
12290
#   $line -
 
12291
# OUTPUT
 
12292
# SOURCE
 
12293
#
 
12294
sub toutf {
 
12295
    my ($line) = @_;
 
12296
    return Encode::encode("utf8", $line);
 
12297
}
 
12298
 
 
12299
#***
 
12300
 
 
12301
#****f* lyricue/pause_media
 
12302
# NAME
 
12303
#   pause_media
 
12304
# SYNOPSIS
 
12305
#   pause_media()
 
12306
# FUNCTION
 
12307
#   Play/Pause media
 
12308
# INPUTS
 
12309
# OUTPUT
 
12310
# SOURCE
 
12311
#
 
12312
sub pause_media {
 
12313
    debug("Play/Pause media");
 
12314
    update_display("media", "pause", "");
 
12315
}
 
12316
 
 
12317
#***
 
12318
 
 
12319
#****f* lyricue/media_v4l
 
12320
# NAME
 
12321
#   media_v4l
 
12322
# SYNOPSIS
 
12323
#   media_v4l()
 
12324
# FUNCTION
 
12325
#   Starting Live Video
 
12326
# INPUTS
 
12327
# OUTPUT
 
12328
# SOURCE
 
12329
#
 
12330
sub media_v4l {
 
12331
    debug("Starting Live Video");
 
12332
    update_display("backdrop", "uri;v4l2#SEMI#//");
 
12333
}
 
12334
 
 
12335
#***
 
12336
 
 
12337
#****f* lyricue/media_dvd
 
12338
# NAME
 
12339
#   media_dvd
 
12340
# SYNOPSIS
 
12341
#   media_dvd()
 
12342
# FUNCTION
 
12343
#   Starting DVD Video
 
12344
# INPUTS
 
12345
# OUTPUT
 
12346
# SOURCE
 
12347
#
 
12348
sub media_dvd {
 
12349
    debug("Checking DVD");
 
12350
    $widgets->{'dialogDvd'} =
 
12351
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogDvd', 'lyricue');
 
12352
    $widgets->{'dialogDvd'}->signal_autoconnect_from_package('');
 
12353
    my $vbox = $widgets->{'dialogDvd'}->get_widget('vboxDvd');
 
12354
    my $com  = `lsdvd -Op`;
 
12355
 
 
12356
    #my $com = `./lsdvd-test.sh -Op`;
 
12357
    $com =~ s/^our //g;
 
12358
    eval $com;
 
12359
 
 
12360
    my $tracks        = $lsdvd{'track'};
 
12361
    my $longest_track = $lsdvd{'longest_track'};
 
12362
    if (!defined $longest_track) {
 
12363
        display_message(
 
12364
            fromutf(gettext("No DVD titles found")),
 
12365
            fromutf(
 
12366
                gettext(
 
12367
"Unable to open the dvd.  There may be no media in the drive"
 
12368
                )
 
12369
            )
 
12370
        );
 
12371
        return;
 
12372
    }
 
12373
    my $longest =
 
12374
      Gtk2::RadioButton->new(undef, "Longest title (" . $longest_track . ")");
 
12375
    $longest->{user_data} = $longest_track;
 
12376
    $vbox->add($longest);
 
12377
    $longest->show();
 
12378
    foreach (@$tracks) {
 
12379
        my $radio =
 
12380
          Gtk2::RadioButton->new($longest,
 
12381
            "Title " . $_->{"ix"} . " - " . sec_to_time($_->{"length"}));
 
12382
        debug("Title " . $_->{"ix"} . " - " . sec_to_time($_->{"length"}));
 
12383
        $radio->{user_data} = $_->{"ix"};
 
12384
        $vbox->add($radio);
 
12385
        $radio->show();
 
12386
        if ($_->{"ix"} == $longest_track) {
 
12387
            select_dvdtitle($longest, $_->{"length"});
 
12388
        }
 
12389
        $radio->signal_connect(toggled => \&select_dvdtitle, $_->{"length"});
 
12390
 
 
12391
    }
 
12392
    $longest->set_active(TRUE);
 
12393
    $widgets->{'dialogDvd'}->get_widget('comboDvdEnd')->set_active(0);
 
12394
    my $confirm = $widgets->{'dialogDvd'}->get_widget('dialogDvd')->run();
 
12395
    if ($confirm == 0) {
 
12396
        my $selected = 0;
 
12397
        my $group    = $longest->get_group;
 
12398
        my $length   = 0;
 
12399
        foreach my $r (@$group) {
 
12400
            if ($r->get_active) {
 
12401
                $selected = $r->{user_data};
 
12402
            }
 
12403
        }
 
12404
        debug("Adding DVD title:" . $selected);
 
12405
        my $type =
 
12406
          $widgets->{'dialogDvd'}->get_widget('comboDvdEnd')->get_active;
 
12407
        my $start = time_to_sec(
 
12408
            $widgets->{'dialogDvd'}->get_widget('entryDvdStart')->get_text);
 
12409
        my $end = time_to_sec(
 
12410
            $widgets->{'dialogDvd'}->get_widget('entryDvdEnd')->get_text);
 
12411
        my $total =
 
12412
          $widgets->{'dialogDvd'}->get_widget('entryDvdEnd')->{user_data};
 
12413
        if ($type == 1) {
 
12414
            $end = $start + $end;
 
12415
        }
 
12416
        if (($start eq 0) && (($end - 1) < $total) && (($end + 1) > $total)) {
 
12417
            do_add_file("dvd://" . $selected,
 
12418
                $widgets->{'main'}->get_widget('labelCurrentPlaylist')
 
12419
                  ->{user_data});
 
12420
        } else {
 
12421
            do_add_file(
 
12422
                "dvd://"
 
12423
                  . $selected . " "
 
12424
                  . sec_to_time($start) . "-"
 
12425
                  . sec_to_time($end),
 
12426
                $widgets->{'main'}->get_widget('labelCurrentPlaylist')
 
12427
                  ->{user_data}
 
12428
            );
 
12429
        }
 
12430
        update_playlist();
 
12431
    }
 
12432
    close_dialog($widgets->{'dialogDvd'}->get_widget('dialogDvd'));
 
12433
}
 
12434
 
 
12435
#***
 
12436
 
 
12437
#****f* lyricue/select_dvdtitle
 
12438
# NAME
 
12439
#   select_dvdtitle
 
12440
# SYNOPSIS
 
12441
#   select_dvdtitle($widget, $length)
 
12442
# FUNCTION
 
12443
#   Fill in the start/end times for dvd media
 
12444
# INPUTS
 
12445
# OUTPUT
 
12446
# SOURCE
 
12447
#
 
12448
 
 
12449
sub select_dvdtitle {
 
12450
    my ($widget, $length) = @_;
 
12451
    if ($widget->get_active) {
 
12452
        $widgets->{'dialogDvd'}->get_widget('comboDvdEnd')->set_active(0);
 
12453
        $widgets->{'dialogDvd'}->get_widget('entryDvdStart')
 
12454
          ->set_text(sec_to_time(0));
 
12455
        $widgets->{'dialogDvd'}->get_widget('entryDvdEnd')
 
12456
          ->set_text(sec_to_time($length));
 
12457
        $widgets->{'dialogDvd'}->get_widget('entryDvdEnd')->{user_data} =
 
12458
          $length;
 
12459
    }
 
12460
}
 
12461
 
 
12462
#***
 
12463
 
 
12464
#****f* lyricue/sec_to_time
 
12465
# NAME
 
12466
#   sec_to_time
 
12467
# SYNOPSIS
 
12468
#   sec_to_time($seconds)
 
12469
# FUNCTION
 
12470
#   Convert seconds to pretty 0:00:00 format
 
12471
# INPUTS
 
12472
# OUTPUT
 
12473
# SOURCE
 
12474
#
 
12475
 
 
12476
sub sec_to_time {
 
12477
    my ($seconds) = @_;
 
12478
    if (!defined $seconds) {
 
12479
        $seconds = 0;
 
12480
    }
 
12481
    my @parts = gmtime($seconds);
 
12482
    if ($parts[2] == 0) {
 
12483
        return sprintf("%d:%02d", @parts[1, 0]);
 
12484
    } else {
 
12485
        return sprintf("%d:%02d:%02d", @parts[2, 1, 0]);
 
12486
    }
 
12487
}
 
12488
 
 
12489
#***
 
12490
 
 
12491
#****f* lyricue/time_to_sec
 
12492
# NAME
 
12493
#   time_to_sec
 
12494
# SYNOPSIS
 
12495
#   time_to_sec($time)
 
12496
# FUNCTION
 
12497
#   Convert pretty 0:00:00 format to seconds
 
12498
# INPUTS
 
12499
# OUTPUT
 
12500
# SOURCE
 
12501
#
 
12502
 
 
12503
sub time_to_sec {
 
12504
    my ($time) = @_;
 
12505
    if (!defined $time) {
 
12506
        return 0;
 
12507
    }
 
12508
    my @parts = split(/:/, $time);
 
12509
    if (defined $parts[2]) {
 
12510
        return ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
 
12511
    } elsif (defined $parts[1]) {
 
12512
        return ($parts[0] * 60) + $parts[1];
 
12513
    } else {
 
12514
        return $parts[0];
 
12515
    }
 
12516
}
 
12517
 
 
12518
#***
 
12519
 
 
12520
#****f* lyricue/install_bibles
 
12521
# NAME
 
12522
#   install_bibles
 
12523
# SYNOPSIS
 
12524
#   install_bibles()
 
12525
# FUNCTION
 
12526
#   Loading bible install window
 
12527
# INPUTS
 
12528
# OUTPUT
 
12529
# SOURCE
 
12530
#
 
12531
sub install_bibles {
 
12532
    debug("Loading bible install window");
 
12533
    $widgets->{'bible'} = Gtk2::GladeXML->new($globals->{'gladefile'},
 
12534
        'windowBibleManager', 'lyricue');
 
12535
    $widgets->{'bible'}->signal_autoconnect_from_package('');
 
12536
    $widgets->{'bible'}->get_widget('buttonBibleSword')->{'user_data'} =
 
12537
      "http://crosswire.org/sword/modules/ModDisp.jsp?modType=Bibles";
 
12538
    $widgets->{'bible'}->get_widget('buttonBibleDB')->{'user_data'} =
 
12539
      "http://www.lyricue.org/bibles";
 
12540
    $widgets->{'bible'}->get_widget('windowBibleManager')->show_all();
 
12541
}
 
12542
 
 
12543
#***
 
12544
 
 
12545
#****f* lyricue/do_install_bible
 
12546
# NAME
 
12547
#   do_install_bible
 
12548
# SYNOPSIS
 
12549
#   do_install_bible()
 
12550
# FUNCTION
 
12551
#   No file selected
 
12552
# INPUTS
 
12553
# OUTPUT
 
12554
# SOURCE
 
12555
#
 
12556
sub do_install_bible {
 
12557
    my $dbfilename =
 
12558
      $widgets->{'bible'}->get_widget('fileBibleInstall')->get_filename();
 
12559
    close_dialog($widgets->{'bible'}->get_widget('windowBibleManager'));
 
12560
    if (!defined $dbfilename) {
 
12561
        debug("No file selected");
 
12562
        return;
 
12563
    }
 
12564
    debug("Installing bible from " . $dbfilename);
 
12565
 
 
12566
    my $message = "";
 
12567
 
 
12568
    my $tmpdir = tempdir("lyricue-XXXX", TMPDIR => 1, CLEANUP => 1);
 
12569
    if ($dbfilename =~ /sql.gz$/i) {
 
12570
 
 
12571
        # Compressed bibleDb
 
12572
        my $command =
 
12573
          "gzip -dc \"" . $dbfilename . "\" > " . $tmpdir . "/bibleDb.sql";
 
12574
        debug($command);
 
12575
        system($command);
 
12576
        $dbfilename = $tmpdir . "/bibleDb.sql";
 
12577
    }
 
12578
    if ($dbfilename =~ /sql$/i) {
 
12579
 
 
12580
        # Uncompressed bibleDb
 
12581
        open(DB, $dbfilename);
 
12582
        debug("bibleDb: " . $dbfilename);
 
12583
        my $dbname = "bibleDb";
 
12584
        while (<DB>) {
 
12585
            if (/^CREATE DATABASE.*;$/) {
 
12586
                $dbname = $_;
 
12587
                $dbname =~ s/^CREATE DATABASE (.*);$/$1/g;
 
12588
                last;
 
12589
            }
 
12590
        }
 
12591
        close DB;
 
12592
        if ($dbname ne "") {
 
12593
            db_installdb($dbfilename, $dbname);
 
12594
            $message = gettext("Bible installed from ") . $dbfilename;
 
12595
        } else {
 
12596
            $message = gettext("Unable to load from ") . $dbfilename;
 
12597
        }
 
12598
    } elsif ($dbfilename =~ /zip$/i) {
 
12599
 
 
12600
        # Sword bible
 
12601
        my $command = "unzip \"" . $dbfilename . "\" -d \$HOME/.sword/";
 
12602
        debug($command);
 
12603
        system($command);
 
12604
        $message = "Sword bible extracted to ~/.sword";
 
12605
    }
 
12606
 
 
12607
    my $donexml =
 
12608
      Gtk2::GladeXML->new($globals->{'gladefile'}, 'dialogError', 'lyricue');
 
12609
    $donexml->signal_autoconnect_from_package('');
 
12610
    $donexml->get_widget('labelError')->set_text($message);
 
12611
    $donexml->get_widget('expanderDetails')->hide();
 
12612
    my $confirm = $donexml->get_widget('dialogError')->run();
 
12613
    close_dialog($donexml->get_widget('dialogError'));
 
12614
 
 
12615
    load_biblemenu();
 
12616
}
 
12617
 
 
12618
#***
 
12619
 
 
12620
#****f* lyricue/load_link
 
12621
# NAME
 
12622
#   load_link
 
12623
# SYNOPSIS
 
12624
#   load_link($widget)
 
12625
# FUNCTION
 
12626
#   Load URL:
 
12627
# INPUTS
 
12628
#   $widget -
 
12629
# OUTPUT
 
12630
# SOURCE
 
12631
#
 
12632
sub load_link {
 
12633
    my ($widget) = @_;
 
12634
    debug("Load URL:" . $widget->{'user_data'});
 
12635
    my $command = "xdg-open " . $widget->{'user_data'};
 
12636
    system($command);
 
12637
}
 
12638
 
 
12639
#***
 
12640
 
 
12641
#****f* lyricue/load_biblemenu
 
12642
# NAME
 
12643
#   load_biblemenu
 
12644
# SYNOPSIS
 
12645
#   load_biblemenu()
 
12646
# FUNCTION
 
12647
#   Populate biblemenu
 
12648
# INPUTS
 
12649
# OUTPUT
 
12650
# SOURCE
 
12651
#
 
12652
sub load_biblemenu {
 
12653
    debug("Populate biblemenu");
 
12654
    my $menutop = Gtk2::Menu->new();
 
12655
    my $group   = -1;
 
12656
 
 
12657
    my $bibleMenuAdd =
 
12658
      Gtk2::MenuItem->new_with_label(gettext("Install new bibles"));
 
12659
    $bibleMenuAdd->signal_connect("activate", "install_bibles");
 
12660
    $bibleMenuAdd->show();
 
12661
    $menutop->append($bibleMenuAdd);
 
12662
 
 
12663
    db_check_databases();
 
12664
    $config->{'Bibles'} = get_bibles();
 
12665
    my $bibles = $config->{'Bibles'};
 
12666
    my ($defbible, undef) = split(/\:/, $config->{'DefBible'}, 2);
 
12667
    my @swordBibles = ();
 
12668
    my @dbBibles = ();
 
12669
    foreach (sort keys %$bibles) {
 
12670
        if (/@/) {
 
12671
            push @dbBibles, $_;
 
12672
        } else {
 
12673
            push @swordBibles, $_;
 
12674
        }
 
12675
    }
 
12676
    
 
12677
    foreach (@dbBibles, "", @swordBibles) {
 
12678
        if ($_ eq "") {
 
12679
            my $sep = Gtk2::SeparatorMenuItem->new;
 
12680
            $sep->show;
 
12681
            $menutop->append($sep);
 
12682
        } else {
 
12683
            my @bible = split(/;/, $config->{'Bibles'}->{$_}, 2);
 
12684
            $bibleMenu->{$_} =
 
12685
              Gtk2::RadioMenuItem->new_with_label($group, $bible[1]);
 
12686
            if ($group == -1) {
 
12687
                $group = $bibleMenu->{$_}->get_group;
 
12688
            }
 
12689
            $bibleMenu->{$_}
 
12690
              ->signal_connect("toggled", "select_bible_db", $bible[0] . ";" . $_);
 
12691
            if (defined($defbible) && ($_ eq $defbible)) {
 
12692
                $bibleMenu->{$_}->set_active(TRUE);
 
12693
            }
 
12694
            $bibleMenu->{$_}->show;
 
12695
            $menutop->append($bibleMenu->{$_});
 
12696
        }
 
12697
    }
 
12698
    $widgets->{'main'}->get_widget('bible1')->set_submenu($menutop);
 
12699
}
 
12700
 
 
12701
#***
 
12702
 
 
12703
#****f* lyricue/open_dirchooser
 
12704
# NAME
 
12705
#   open_dirchooser
 
12706
# SYNOPSIS
 
12707
#   open_dirchooser($widget)
 
12708
# FUNCTION
 
12709
#   Opening Directory chooser
 
12710
# INPUTS
 
12711
#   $widget -
 
12712
# OUTPUT
 
12713
# SOURCE
 
12714
#
 
12715
sub open_dirchooser {
 
12716
    my ($widget) = @_;
 
12717
    debug("Opening Directory chooser");
 
12718
    my $directoryxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
12719
        'dialogDirChooser', 'lyricue');
 
12720
    $directoryxml->signal_autoconnect_from_package('');
 
12721
    my $dir = $widget->get_label();
 
12722
    $dir =~ s/^~/$ENV{'HOME'}/;
 
12723
    $directoryxml->get_widget('dialogDirChooser')->set_filename($dir);
 
12724
    my $confirm = $directoryxml->get_widget('dialogDirChooser')->run();
 
12725
 
 
12726
    if ($confirm eq "ok") {
 
12727
        $dir = $directoryxml->get_widget('dialogDirChooser')->get_filename();
 
12728
        $dir =~ s/^$ENV{'HOME'}/~/;
 
12729
        if ($widget->{'user_data'} eq "img") {
 
12730
            $widgets->{'prefs'}->get_widget('filePrefSpecialImagedir')
 
12731
              ->set_label($dir);
 
12732
        } elsif ($widget->{'user_data'} eq "bg") {
 
12733
            $widgets->{'prefs'}->get_widget('filePrefSpecialBGdir')
 
12734
              ->set_label($dir);
 
12735
        } elsif ($widget->{'user_data'} eq "fr_img") {
 
12736
            $widgets->{'firstrunxml'}->get_widget('fileFRImagedir')
 
12737
              ->set_label($dir);
 
12738
        } elsif ($widget->{'user_data'} eq "fr_bg") {
 
12739
            $widgets->{'firstrunxml'}->get_widget('fileFRBGdir')
 
12740
              ->set_label($dir);
 
12741
        }
 
12742
    }
 
12743
    close_dialog($directoryxml->get_widget('dialogDirChooser'));
 
12744
}
 
12745
 
 
12746
#***
 
12747
 
 
12748
#****f* lyricue/import_db
 
12749
# NAME
 
12750
#   import_db
 
12751
# SYNOPSIS
 
12752
#   import_db()
 
12753
# FUNCTION
 
12754
#   Import DB selected
 
12755
# INPUTS
 
12756
# OUTPUT
 
12757
# SOURCE
 
12758
#
 
12759
sub import_db {
 
12760
    debug("Import DB selected");
 
12761
    my $importxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
12762
        'dialogImportData', 'lyricue');
 
12763
    $importxml->signal_autoconnect_from_package('');
 
12764
    my $filter = Gtk2::FileFilter->new();
 
12765
    $filter->add_pattern("*.xmlz");
 
12766
    $filter->add_pattern("*.xml");
 
12767
    $importxml->get_widget('fileImportData')->set_filter($filter);
 
12768
    my $confirm = $importxml->get_widget('dialogImportData')->run();
 
12769
    debug(":" . $confirm);
 
12770
 
 
12771
    if ($confirm == 0) {
 
12772
        my $filename = $importxml->get_widget('fileImportData')->get_filename();
 
12773
        if (defined $filename) {
 
12774
            close_dialog($importxml->get_widget('dialogImportData'));
 
12775
            import_songs($filename);
 
12776
            return;
 
12777
        }
 
12778
    }
 
12779
    close_dialog($importxml->get_widget('dialogImportData'));
 
12780
}
 
12781
 
 
12782
#***
 
12783
 
 
12784
#****f* lyricue/export_db
 
12785
# NAME
 
12786
#   export_db
 
12787
# SYNOPSIS
 
12788
#   export_db()
 
12789
# FUNCTION
 
12790
#   Export DB selected
 
12791
# INPUTS
 
12792
# OUTPUT
 
12793
# SOURCE
 
12794
#
 
12795
sub export_db {
 
12796
    debug("Export DB selected");
 
12797
    my $exportxml = Gtk2::GladeXML->new($globals->{'gladefile'},
 
12798
        'dialogFileChooser', 'lyricue');
 
12799
    $exportxml->signal_autoconnect_from_package('');
 
12800
    my $filter = Gtk2::FileFilter->new;
 
12801
    $filter->add_pattern("*.xmlz");
 
12802
    $exportxml->get_widget('dialogFileChooser')->set_filter($filter);
 
12803
    $exportxml->get_widget('dialogFileChooser')->set_filename("lyricue.xmlz");
 
12804
    my $confirm = $exportxml->get_widget('dialogFileChooser')->run();
 
12805
 
 
12806
    if ($confirm) {
 
12807
        my $filename =
 
12808
          $exportxml->get_widget('dialogFileChooser')->get_filename;
 
12809
 
 
12810
        $filename =~ s/\..*?$//g;
 
12811
        $filename .= ".xmlz";
 
12812
        if (defined $filename) {
 
12813
            export_songs($filename);
 
12814
        }
 
12815
        close_dialog($exportxml->get_widget('dialogFileChooser'));
 
12816
    }
 
12817
}
 
12818
 
 
12819
#***
 
12820
 
 
12821
#****f* lyricue/biblebrowser_init
 
12822
# NAME
 
12823
#   biblebrowser_init
 
12824
# SYNOPSIS
 
12825
#   biblebrowser_init()
 
12826
# FUNCTION
 
12827
#
 
12828
# INPUTS
 
12829
# OUTPUT
 
12830
# SOURCE
 
12831
#
 
12832
sub biblebrowser_init {
 
12833
    my @items = ('Old Testament', 'New Testament');
 
12834
    biblebrowser_loaditems("book", \@items, 2);
 
12835
}
 
12836
 
 
12837
#***
 
12838
 
 
12839
#****f* lyricue/biblebrowser_book
 
12840
# NAME
 
12841
#   biblebrowser_book
 
12842
# SYNOPSIS
 
12843
#   biblebrowser_book()
 
12844
# FUNCTION
 
12845
#   Looking up
 
12846
# INPUTS
 
12847
# OUTPUT
 
12848
# SOURCE
 
12849
#
 
12850
sub biblebrowser_book {
 
12851
    my ($widget, $section) = @_;
 
12852
    debug("Looking up " . $section);
 
12853
    my @items = ();
 
12854
    if ($section eq "Old Testament") {
 
12855
        @items = (
 
12856
            'Genesis',      'Exodus',        'Leviticus', 'Numbers',
 
12857
            'Deuteronomy',  'Joshua',        'Judges',    'Ruth',
 
12858
            '1 Samuel',     '2 Samuel',      '1 Kings',   '2 Kings',
 
12859
            '1 Chronicles', '2 Chronicles',  'Ezra',      'Nehemiah',
 
12860
            'Esther',       'Job',           'Psalms',    'Proverbs',
 
12861
            'Ecclesiastes', 'Song of Songs', 'Isaiah',    'Jeremiah',
 
12862
            'Lamentations', 'Ezekiel',       'Daniel',    'Hosea',
 
12863
            'Joel',         'Amos',          'Obadiah',   'Jonah',
 
12864
            'Micah',        'Nahum',         'Habakkuk',  'Zephaniah',
 
12865
            'Haggai',       'Zechariah',     'Malachi'
 
12866
        );
 
12867
    } else {
 
12868
        @items = (
 
12869
            'Matthew',         'Mark',
 
12870
            'Luke',            'John',
 
12871
            'Acts',            'Romans',
 
12872
            '1 Corinthians',   '2 Corinthians',
 
12873
            'Galatians',       'Ephesians',
 
12874
            'Philippians',     'Colossians',
 
12875
            '1 Thessalonians', '2 Thessalonians',
 
12876
            '1 Timothy',       '2 Timothy',
 
12877
            'Titus',           'Philemon',
 
12878
            'Hebrews',         'James',
 
12879
            '1 Peter',         '2 Peter',
 
12880
            '1 John',          '2 John',
 
12881
            '3 John',          'Jude',
 
12882
            'Revelation'
 
12883
        );
 
12884
    }
 
12885
    biblebrowser_loaditems("chapter", \@items, 3);
 
12886
}
 
12887
 
 
12888
#***
 
12889
 
 
12890
#****f* lyricue/biblebrowser_chapter
 
12891
# NAME
 
12892
#   biblebrowser_chapter
 
12893
# SYNOPSIS
 
12894
#   biblebrowser_chapter($widget, $book, $source)
 
12895
# FUNCTION
 
12896
#   Looking up book
 
12897
# INPUTS
 
12898
#   $widget -
 
12899
#    $book -
 
12900
#    $source -
 
12901
# OUTPUT
 
12902
# SOURCE
 
12903
#
 
12904
sub biblebrowser_chapter {
 
12905
    my ($widget, $book, $source) = @_;
 
12906
    debug("Looking up book " . $book);
 
12907
    my $translated_book = gettext($book);
 
12908
    my $cont            = FALSE;
 
12909
    my $maxchap         = 0;
 
12910
    if ($globals->{'usesword'}) {
 
12911
 
 
12912
        # Find proper book name
 
12913
        my $command = sprintf(
 
12914
            "%s -b %s -e UTF8 -k '%s' 1:1 '%s' 1:1",
 
12915
            $globals->{'diatheke'},
 
12916
            $globals->{'bibledb'}, $book, $translated_book
 
12917
        );
 
12918
        qdebug($command);
 
12919
        $maxchap = fromutf(`$command`);
 
12920
        ($book, undef) = split(/\s\d/, $maxchap, 2);
 
12921
 
 
12922
        $command = sprintf(
 
12923
            "%s -b %s -e UTF8 -k '%s' | grep '^%s'| tail -2 | head -1",
 
12924
            $globals->{'diatheke'},
 
12925
            $globals->{'bibledb'}, $book, $book
 
12926
        );
 
12927
        qdebug($command);
 
12928
        $maxchap = fromutf(`$command`);
 
12929
        $maxchap =~ s/^$book ([0-9]*):[0-9].*$/$1/g;
 
12930
        if ($maxchap) {
 
12931
            $cont = TRUE;
 
12932
        }
 
12933
    } else {
 
12934
        my ($table, $dbname) = split(/@/, $globals->{'bibledb'}, 2);
 
12935
        my $query =
 
12936
            "SELECT MAX(chapternum) FROM " 
 
12937
          . $table
 
12938
          . " WHERE book like \""
 
12939
          . toutf($book)
 
12940
          . "%\" or book like \""
 
12941
          . toutf($translated_book) . "%\"";
 
12942
        qdebug($query);
 
12943
        $sth = $bibleDbh->prepare($query)
 
12944
          || display_fatal($errorcodes->{'sqlprepare'},
 
12945
            $! . "\nSQL: " . $query);
 
12946
        $rv = $sth->execute
 
12947
          || display_fatal($errorcodes->{'sqlexecute'},
 
12948
            $! . "\nSQL: " . $query);
 
12949
        if (my @row = $sth->fetchrow_array) {
 
12950
            $cont    = TRUE;
 
12951
            $maxchap = $row[0];
 
12952
        }
 
12953
        $sth->finish;
 
12954
    }
 
12955
 
 
12956
    if ($cont) {
 
12957
        my @items = ();
 
12958
        foreach (1 .. $maxchap) {
 
12959
            push @items, $_;
 
12960
        }
 
12961
        biblebrowser_loaditems("verse", \@items, 8);
 
12962
        if ($source ne "entry") {
 
12963
            $widgets->{'main'}->get_widget('entryNavVerse')
 
12964
              ->set_text($book . " ");
 
12965
            $widgets->{'main'}->get_widget('entryNavVerse')->set_position(-1);
 
12966
        }
 
12967
    }
 
12968
}
 
12969
 
 
12970
#***
 
12971
 
 
12972
#****f* lyricue/biblebrowser_verse
 
12973
# NAME
 
12974
#   biblebrowser_verse
 
12975
# SYNOPSIS
 
12976
#   biblebrowser_verse($widget, $chapter, $source)
 
12977
# FUNCTION
 
12978
#   biblebrowser_verse called from ".$source.":
 
12979
# INPUTS
 
12980
#   $widget -
 
12981
#    $chapter -
 
12982
#    $source -
 
12983
# OUTPUT
 
12984
# SOURCE
 
12985
#
 
12986
sub biblebrowser_verse {
 
12987
    my ($widget, $chapter, $source) = @_;
 
12988
    debug("biblebrowser_verse called from " . $source . ":" . $chapter);
 
12989
    my $book = $widgets->{'main'}->get_widget('entryNavVerse')->get_text();
 
12990
    $book =~ s/ *$//g;
 
12991
    if ($chapter == 0) {
 
12992
        $chapter = $book;
 
12993
        $chapter =~ s/^.*( [0-9:\-]*)/$1/;
 
12994
        my $verse = "";
 
12995
        ($chapter, $verse) = split(/:/, $chapter);
 
12996
        $book =~ s/ [0-9:\-]*$//;
 
12997
        if ((!defined $verse) || ((defined $verse) && ($verse eq ""))) {
 
12998
            $globals->{'verseStart'} = 0;
 
12999
            $globals->{'verseEnd'}   = 0;
 
13000
        }
 
13001
    }
 
13002
    if ($source ne "entry") {
 
13003
        $widgets->{'main'}->get_widget('entryNavVerse')
 
13004
          ->set_text($book . " " . $chapter);
 
13005
        $widgets->{'main'}->get_widget('entryNavVerse')->set_position(-1);
 
13006
    }
 
13007
    debug("Looking up book " . $book . " chapter " . $chapter);
 
13008
    my $maxverse = 0;
 
13009
    if ($globals->{'usesword'}) {
 
13010
        my $command = sprintf(
 
13011
            "%s -b %s -e UTF8 -k '%s' %d | grep '^%s' | tail -1",
 
13012
            $globals->{'diatheke'},
 
13013
            $globals->{'bibledb'}, $book, $chapter, $book
 
13014
        );
 
13015
        qdebug($command);
 
13016
        $maxverse = fromutf(`$command`);
 
13017
        $maxverse =~ s/^$book [0-9]*:([0-9]*):.*$/$1/g;
 
13018
    } else {
 
13019
        my ($table, $dbname) = split(/@/, $globals->{'bibledb'}, 2);
 
13020
        my $query =
 
13021
            "SELECT MAX(versenum) FROM " 
 
13022
          . $table
 
13023
          . " WHERE book=\""
 
13024
          . toutf($book)
 
13025
          . "\" AND chapternum=\""
 
13026
          . $chapter . "\"";
 
13027
        qdebug($query);
 
13028
        $sth = $bibleDbh->prepare($query)
 
13029
          || display_fatal($errorcodes->{'sqlprepare'},
 
13030
            $! . "\nSQL: " . $query);
 
13031
        $rv = $sth->execute
 
13032
          || display_fatal($errorcodes->{'sqlexecute'},
 
13033
            $! . "\nSQL: " . $query);
 
13034
 
 
13035
        if (my @row = $sth->fetchrow_array) {
 
13036
            $maxverse = $row[0];
 
13037
        }
 
13038
    }
 
13039
 
 
13040
    if ($maxverse) {
 
13041
        my @items = ();
 
13042
        foreach (1 .. $maxverse) {
 
13043
            push @items, $_;
 
13044
        }
 
13045
        biblebrowser_loaditems("verses", \@items, 8);
 
13046
        if ($source ne "entry") {
 
13047
            $widgets->{'main'}->get_widget('entryNavVerse')
 
13048
              ->set_text($book . " " . $chapter);
 
13049
            $widgets->{'main'}->get_widget('entryNavVerse')->set_position(-1);
 
13050
        }
 
13051
    }
 
13052
}
 
13053
 
 
13054
#***
 
13055
 
 
13056
#****f* lyricue/biblebrowser_loaditems
 
13057
# NAME
 
13058
#   biblebrowser_loaditems
 
13059
# SYNOPSIS
 
13060
#   biblebrowser_loaditems($section, $items, $cols)
 
13061
# FUNCTION
 
13062
#   Filling bible section
 
13063
# INPUTS
 
13064
#   $section -
 
13065
#    $items -
 
13066
#    $cols -
 
13067
# OUTPUT
 
13068
# SOURCE
 
13069
#
 
13070
sub biblebrowser_loaditems {
 
13071
    my ($section, $items, $cols) = @_;
 
13072
    debug("Filling bible section");
 
13073
    my $buttons = $widgets->{'bibleBrowser'};
 
13074
    foreach (keys %$buttons) {
 
13075
        $widgets->{'bibleBrowser'}{$_}->destroy();
 
13076
        delete $widgets->{'bibleBrowser'}{$_};
 
13077
    }
 
13078
 
 
13079
    my $size   = @$items;
 
13080
    my $buffer = Gtk2::TextBuffer->new();
 
13081
    $widgets->{'main'}->get_widget('textBible')->set_buffer($buffer);
 
13082
    my $sizegroup = Gtk2::SizeGroup->new('both');
 
13083
    foreach my $itemnum (0 .. ($size - 1)) {
 
13084
        if ($section eq "verses") {
 
13085
            $widgets->{'bibleBrowser'}{'button' . $itemnum} =
 
13086
              Gtk2::ToggleButton->new(@$items[$itemnum]);
 
13087
            $widgets->{'bibleBrowser'}{'button' . $itemnum}
 
13088
              ->signal_connect("event", "changeVerseStatus", $size);
 
13089
            $widgets->{'bibleBrowser'}{'button' . $itemnum}->show();
 
13090
        } else {
 
13091
            $widgets->{'bibleBrowser'}{'button' . $itemnum} =
 
13092
              Gtk2::Button->new(fromutf(gettext(@$items[$itemnum])));
 
13093
            $widgets->{'bibleBrowser'}{'button' . $itemnum}
 
13094
              ->signal_connect("clicked", "biblebrowser_" . $section,
 
13095
                @$items[$itemnum]);
 
13096
        }
 
13097
        $sizegroup->add_widget($widgets->{'bibleBrowser'}{'button' . $itemnum});
 
13098
        $widgets->{'bibleBrowser'}{'button' . $itemnum}->show;
 
13099
        my $anchor = $buffer->create_child_anchor($buffer->get_end_iter);
 
13100
        $widgets->{'main'}->get_widget('textBible')
 
13101
          ->add_child_at_anchor($widgets->{'bibleBrowser'}{'button' . $itemnum},
 
13102
            $anchor);
 
13103
    }
 
13104
    $widgets->{'main'}->get_widget('textBible')->show_all();
 
13105
}
 
13106
 
 
13107
#***
 
13108
 
 
13109
#****f* lyricue/firstrun_wizard
 
13110
# NAME
 
13111
#   firstrun_wizard
 
13112
# SYNOPSIS
 
13113
#   firstrun_wizard()
 
13114
# FUNCTION
 
13115
#
 
13116
# INPUTS
 
13117
# OUTPUT
 
13118
# SOURCE
 
13119
#
 
13120
sub firstrun_wizard {
 
13121
    debug("First Run Wizard");
 
13122
    $config = load_config();
 
13123
    $widgets->{'firstrunxml'} = Gtk2::GladeXML->new($globals->{'gladefile'},
 
13124
        'assistantFirstRun', 'lyricue');
 
13125
    $widgets->{'firstrunxml'}->signal_autoconnect_from_package('');
 
13126
    $widgets->{'firstrun'} =
 
13127
      $widgets->{'firstrunxml'}->get_widget('assistantFirstRun');
 
13128
    $widgets->{'firstrun'}->show_all();
 
13129
}
 
13130
 
 
13131
#***
 
13132
 
 
13133
#****f* lyricue/firstrun_cancel
 
13134
# NAME
 
13135
#   firstrun_cancel
 
13136
# SYNOPSIS
 
13137
#   firstrun_cancel()
 
13138
# FUNCTION
 
13139
#   Cancelled Wizard
 
13140
# INPUTS
 
13141
# OUTPUT
 
13142
# SOURCE
 
13143
#
 
13144
sub firstrun_cancel {
 
13145
    debug("Cancelled Wizard");
 
13146
    firstrun_close();
 
13147
}
 
13148
 
 
13149
#***
 
13150
 
 
13151
#****f* lyricue/firstrun_close
 
13152
# NAME
 
13153
#   firstrun_close
 
13154
# SYNOPSIS
 
13155
#   firstrun_close()
 
13156
# FUNCTION
 
13157
#   Closing Wizard
 
13158
# INPUTS
 
13159
# OUTPUT
 
13160
# SOURCE
 
13161
#
 
13162
sub firstrun_close {
 
13163
    debug("Closing Wizard");
 
13164
    close_dialog($widgets->{'firstrun'});
 
13165
    if ($globals->{'firstrun'}) {
 
13166
        Gtk2->main_quit();
 
13167
    }
 
13168
}
 
13169
 
 
13170
#***
 
13171
 
 
13172
#****f* lyricue/firstrun_prepare
 
13173
# NAME
 
13174
#   firstrun_prepare
 
13175
# SYNOPSIS
 
13176
#   firstrun_prepare()
 
13177
# FUNCTION
 
13178
#   prepare page:
 
13179
# INPUTS
 
13180
# OUTPUT
 
13181
# SOURCE
 
13182
#
 
13183
sub firstrun_prepare {
 
13184
    debug("Firstrun prepare page:" . $widgets->{'firstrun'}->get_current_page);
 
13185
    my $page =
 
13186
      $widgets->{'firstrun'}
 
13187
      ->get_nth_page($widgets->{'firstrun'}->get_current_page);
 
13188
    my $font   = "Serif 30";
 
13189
    my $header = gettext("First-run wizard");
 
13190
 
 
13191
    if ($widgets->{'firstrun'}->get_current_page == 0) {
 
13192
 
 
13193
        # Intro
 
13194
        $header = gettext("Welcome");
 
13195
        $widgets->{'firstrun'}->set_page_complete($page, TRUE);
 
13196
    } elsif ($widgets->{'firstrun'}->get_current_page == 1) {
 
13197
        $header = gettext("Location");
 
13198
        $widgets->{'firstrunxml'}->get_widget('entryFRHostDB')
 
13199
          ->set_text($globals->{'mysqlhost'});
 
13200
        $widgets->{'firstrunxml'}->get_widget('entryFRHostServer')
 
13201
          ->set_text($globals->{'host'});
 
13202
        $widgets->{'firstrun'}->set_page_complete($page, TRUE);
 
13203
    } elsif ($widgets->{'firstrun'}->get_current_page == 2) {
 
13204
        $globals->{'mysqlhost'} =
 
13205
          $widgets->{'firstrunxml'}->get_widget('entryFRHostDB')->get_text();
 
13206
 
 
13207
        # Database
 
13208
        $header = gettext("Database login");
 
13209
        firstrun_pw_check();
 
13210
    } elsif ($widgets->{'firstrun'}->get_current_page == 3) {
 
13211
 
 
13212
        # Server
 
13213
        $header = gettext("Projector settings");
 
13214
        $widgets->{'firstrunxml'}->get_widget('spinFRWidth')
 
13215
          ->set_value($config->{'Width'});
 
13216
        $widgets->{'firstrunxml'}->get_widget('spinFRHeight')
 
13217
          ->set_value($config->{'Height'});
 
13218
        if ($config->{'VerticalLocation'}) {
 
13219
            $widgets->{'firstrunxml'}->get_widget('comboFRVertical')
 
13220
              ->prepend_text($config->{'VerticalLocation'});
 
13221
        }
 
13222
        $widgets->{'firstrunxml'}->get_widget('comboFRVertical')->set_active(0);
 
13223
        if ($config->{'HorizontalLocation'}) {
 
13224
            $widgets->{'firstrunxml'}->get_widget('comboFRHorizontal')
 
13225
              ->prepend_text($config->{'HorizontalLocation'});
 
13226
        }
 
13227
        $widgets->{'firstrunxml'}->get_widget('comboFRHorizontal')
 
13228
          ->set_active(0);
 
13229
        if ($config->{'Justification'}) {
 
13230
            $widgets->{'firstrunxml'}->get_widget('comboFRJustification')
 
13231
              ->prepend_text($config->{'Justification'});
 
13232
        }
 
13233
        $widgets->{'firstrunxml'}->get_widget('comboFRJustification')
 
13234
          ->set_active(0);
 
13235
        $widgets->{'firstrun'}->set_page_complete($page, TRUE);
 
13236
    } elsif ($widgets->{'firstrun'}->get_current_page == 4) {
 
13237
 
 
13238
        # Fonts
 
13239
        $header = gettext("Fonts");
 
13240
        $widgets->{'firstrun'}->set_page_complete($page, TRUE);
 
13241
        $widgets->{'firstrunxml'}->get_widget('fontFRMain')
 
13242
          ->set_font_name($config->{'Main'});
 
13243
        $widgets->{'firstrunxml'}->get_widget('fontFRHeader')
 
13244
          ->set_font_name($config->{'Header'});
 
13245
        $widgets->{'firstrunxml'}->get_widget('fontFRFooter')
 
13246
          ->set_font_name($config->{'Footer'});
 
13247
        $widgets->{'firstrunxml'}->get_widget('fontFROSD')
 
13248
          ->set_font_name($config->{'OSD'});
 
13249
    } elsif ($widgets->{'firstrun'}->get_current_page == 5) {
 
13250
 
 
13251
        # Directories
 
13252
        $header = gettext("Image Directories");
 
13253
        $widgets->{'firstrunxml'}->get_widget('fileFRBGdir')
 
13254
          ->set_label($config->{'BGDirectory'});
 
13255
        $widgets->{'firstrunxml'}->get_widget('fileFRBGdir')->{'user_data'} =
 
13256
          "fr_bg";
 
13257
        $widgets->{'firstrunxml'}->get_widget('fileFRImagedir')
 
13258
          ->set_label($config->{'ImageDirectory'});
 
13259
        $widgets->{'firstrunxml'}->get_widget('fileFRImagedir')->{'user_data'} =
 
13260
          "fr_img";
 
13261
        $widgets->{'firstrun'}->set_page_complete($page, TRUE);
 
13262
    } elsif ($widgets->{'firstrun'}->get_current_page == 6) {
 
13263
 
 
13264
        # Special items
 
13265
        $header = gettext("Most-used items");
 
13266
        $widgets->{'firstrunxml'}->get_widget('entryFRSong')
 
13267
          ->set_text($config->{'SpecialSong'});
 
13268
        $widgets->{'firstrunxml'}->get_widget('entryFRImage')
 
13269
          ->set_text($config->{'SpecialImage'});
 
13270
        $widgets->{'firstrunxml'}->get_widget('entryFRBack')
 
13271
          ->set_text($config->{'SpecialBack'});
 
13272
        my $bibles = $config->{'Bibles'};
 
13273
        my $store = Gtk2::ListStore->new('Glib::String', 'Glib::String');
 
13274
        $widgets->{'firstrunxml'}->get_widget('comboFRBible')->remove_text(0);
 
13275
        my ($iter, $activeiter);
 
13276
 
 
13277
        foreach (sort keys %$bibles) {
 
13278
            my ($type, $bible) = split(/;/, $config->{'Bibles'}->{$_});
 
13279
            $iter = $store->append;
 
13280
            $store->set($iter, 0, $bible, 1,
 
13281
                $_ . ":" . $config->{'Bibles'}->{$_});
 
13282
            if ($config->{'DefBible'} eq $_ . ":" . $config->{'Bibles'}->{$_}) {
 
13283
                $activeiter = $iter;
 
13284
            }
 
13285
        }
 
13286
        $widgets->{'firstrunxml'}->get_widget('comboFRBible')
 
13287
          ->set_model($store);
 
13288
        if (defined $activeiter) {
 
13289
            $widgets->{'firstrunxml'}->get_widget('comboFRBible')
 
13290
              ->set_active_iter($activeiter);
 
13291
        }
 
13292
        $widgets->{'firstrun'}->set_page_complete($page, TRUE);
 
13293
    } elsif ($widgets->{'firstrun'}->get_current_page == 7) {
 
13294
 
 
13295
        # Confirm
 
13296
        $header = gettext("Confirm");
 
13297
        $widgets->{'firstrun'}->set_page_complete($page, TRUE);
 
13298
    }
 
13299
 
 
13300
    $header = fromutf($header);
 
13301
    my $layout = $page->create_pango_layout($header);
 
13302
    my $desc   = Gtk2::Pango::FontDescription->from_string($font);
 
13303
    $layout->set_font_description($desc);
 
13304
    my ($text_width, $text_height) = $layout->get_pixel_size;
 
13305
    my $pixmap = Gtk2::Gdk::Pixmap->new(undef, $text_width, $text_height, 24);
 
13306
    $pixmap->draw_rectangle($page->get_style->white_gc,
 
13307
        TRUE, 0, 0, $text_width, $text_height);
 
13308
    $pixmap->draw_layout($page->get_style->text_gc($page->state), 0, 0,
 
13309
        $layout);
 
13310
    my $pixbuf =
 
13311
      Gtk2::Gdk::Pixbuf->get_from_drawable($pixmap, undef, 0, 0, 0, 0,
 
13312
        $text_width, $text_height);
 
13313
    $widgets->{'firstrun'}->set_page_header_image($page, $pixbuf);
 
13314
}
 
13315
 
 
13316
#***
 
13317
 
 
13318
#****f* lyricue/firstrun_pw_changed
 
13319
# NAME
 
13320
#   firstrun_pw_changed
 
13321
# SYNOPSIS
 
13322
#   firstrun_pw_changed()
 
13323
# FUNCTION
 
13324
#   Firstrun login changed
 
13325
# INPUTS
 
13326
# OUTPUT
 
13327
# SOURCE
 
13328
#
 
13329
sub firstrun_pw_changed {
 
13330
    debug("Firstrun login changed");
 
13331
    reset_timer($globals->{'nav_update_timer'});
 
13332
    $globals->{'fr_update_timer'} =
 
13333
      Glib::Timeout->add(500, \&firstrun_pw_check);
 
13334
}
 
13335
 
 
13336
#***
 
13337
 
 
13338
#****f* lyricue/firstrun_pw_check
 
13339
# NAME
 
13340
#   firstrun_pw_check
 
13341
# SYNOPSIS
 
13342
#   firstrun_pw_check()
 
13343
# FUNCTION
 
13344
#   Checking login
 
13345
# INPUTS
 
13346
# OUTPUT
 
13347
# SOURCE
 
13348
#
 
13349
sub firstrun_pw_check {
 
13350
    debug("Checking login");
 
13351
    reset_timer($globals->{'fr_update_timer'});
 
13352
    $globals->{'db_adminuser'} =
 
13353
      $widgets->{'firstrunxml'}->get_widget('entryFRUsername')->get_text();
 
13354
    $globals->{'db_adminpassword'} =
 
13355
      $widgets->{'firstrunxml'}->get_widget('entryFRPassword')->get_text();
 
13356
    my $page =
 
13357
      $widgets->{'firstrun'}
 
13358
      ->get_nth_page($widgets->{'firstrun'}->get_current_page);
 
13359
    my ($dbh);
 
13360
    eval {
 
13361
        $dbh = DBI->connect(
 
13362
            "DBI:"
 
13363
              . $config->{'DatabaseType'}
 
13364
              . ":mysql:"
 
13365
              . $globals->{'mysqlhost'},
 
13366
            $globals->{'db_adminuser'}, $globals->{'db_adminpassword'}
 
13367
        );
 
13368
    };
 
13369
 
 
13370
    if ($dbh) {
 
13371
        debug("Login accepted");
 
13372
        $widgets->{'firstrun'}->set_page_complete($page, TRUE);
 
13373
        $widgets->{'firstrunxml'}->get_widget('labelFRDBCheck')
 
13374
          ->set_markup(gettext("<i>Username/Password accepted</i>"));
 
13375
    } else {
 
13376
        debug("Login failed");
 
13377
        $widgets->{'firstrun'}->set_page_complete($page, FALSE);
 
13378
        $widgets->{'firstrunxml'}->get_widget('labelFRDBCheck')
 
13379
          ->set_markup(gettext("<i>Username/Password failed</i>"));
 
13380
    }
 
13381
}
 
13382
 
 
13383
#***
 
13384
 
 
13385
#****f* lyricue/firstrun_apply
 
13386
# NAME
 
13387
#   firstrun_apply
 
13388
# SYNOPSIS
 
13389
#   firstrun_apply()
 
13390
# FUNCTION
 
13391
#   Apply Wizard
 
13392
# INPUTS
 
13393
# OUTPUT
 
13394
# SOURCE
 
13395
#
 
13396
sub firstrun_apply {
 
13397
    debug("Apply Wizard");
 
13398
 
 
13399
    # Confirmed changes - so save them
 
13400
 
 
13401
    $config->{'Main'} =
 
13402
      $widgets->{'firstrunxml'}->get_widget('fontFRMain')->get_font_name();
 
13403
    $config->{'Header'} =
 
13404
      $widgets->{'firstrunxml'}->get_widget('fontFRHeader')->get_font_name();
 
13405
    $config->{'Footer'} =
 
13406
      $widgets->{'firstrunxml'}->get_widget('fontFRFooter')->get_font_name();
 
13407
    $config->{'OSD'} =
 
13408
      $widgets->{'firstrunxml'}->get_widget('fontFROSD')->get_font_name();
 
13409
    $config->{'Height'} =
 
13410
      $widgets->{'firstrunxml'}->get_widget('spinFRHeight')->get_value();
 
13411
    $config->{'Width'} =
 
13412
      $widgets->{'firstrunxml'}->get_widget('spinFRWidth')->get_value();
 
13413
    my $set = "";
 
13414
 
 
13415
    foreach my $value ("Top", "Bottom", "Centre") {
 
13416
 
 
13417
        if (
 
13418
            fromutf(gettext($value)) eq ucfirst(
 
13419
                $widgets->{'firstrunxml'}->get_widget('comboFRVertical')
 
13420
                  ->get_active_text()
 
13421
            )
 
13422
          )
 
13423
        {
 
13424
            $set = $value;
 
13425
        }
 
13426
    }
 
13427
    if ($set eq "") {
 
13428
        $set =
 
13429
          $widgets->{'firstrunxml'}->get_widget('comboFRVertical')
 
13430
          ->get_active_text();
 
13431
    }
 
13432
    $config->{'VerticalLocation'} = $set;
 
13433
    $set = "";
 
13434
    my $set2 = "";
 
13435
    foreach my $value ("Left", "Right", "Centre") {
 
13436
        if (
 
13437
            fromutf(gettext($value)) eq ucfirst(
 
13438
                $widgets->{'firstrunxml'}->get_widget('comboFRHorizontal')
 
13439
                  ->get_active_text()
 
13440
            )
 
13441
          )
 
13442
        {
 
13443
            $set = $value;
 
13444
        }
 
13445
        if (
 
13446
            fromutf(gettext($value)) eq ucfirst(
 
13447
                $widgets->{'firstrunxml'}->get_widget('comboFRJustification')
 
13448
                  ->get_active_text()
 
13449
            )
 
13450
          )
 
13451
        {
 
13452
            $set2 = $value;
 
13453
        }
 
13454
    }
 
13455
    if ($set eq "") {
 
13456
        $set =
 
13457
          $widgets->{'firstrunxml'}->get_widget('comboFRHorizontal')
 
13458
          ->get_active_text();
 
13459
    }
 
13460
    if ($set2 eq "") {
 
13461
        $set2 =
 
13462
          $widgets->{'firstrunxml'}->get_widget('comboFRJustification')
 
13463
          ->get_active_text();
 
13464
    }
 
13465
    $config->{'HorizontalLocation'} = $set;
 
13466
    $config->{'Justification'}      = $set2;
 
13467
 
 
13468
#$config->{'BGImage'} = $widgets->{'prefs'}->get_widget('imagePrefBG')->{user_data};
 
13469
    $config->{'SpecialSong'} =
 
13470
      $widgets->{'firstrunxml'}->get_widget('entryFRSong')->get_text();
 
13471
    $config->{'SpecialImage'} =
 
13472
      $widgets->{'firstrunxml'}->get_widget('entryFRImage')->get_text();
 
13473
    $config->{'SpecialBack'} =
 
13474
      $widgets->{'firstrunxml'}->get_widget('entryFRBack')->get_text();
 
13475
    my $iter =
 
13476
      $widgets->{'firstrunxml'}->get_widget('comboFRBible')->get_active_iter;
 
13477
    if ($iter) {
 
13478
        $config->{'DefBible'} =
 
13479
          $widgets->{'firstrunxml'}->get_widget('comboFRBible')
 
13480
          ->get_model->get($iter, 1);
 
13481
    }
 
13482
    $config->{'ImageDirectory'} =
 
13483
      $widgets->{'firstrunxml'}->get_widget('fileFRImagedir')->get_label();
 
13484
    $config->{'BGDirectory'} =
 
13485
      $widgets->{'firstrunxml'}->get_widget('fileFRBGdir')->get_label();
 
13486
    $config->{'DBHost'} =
 
13487
      $widgets->{'firstrunxml'}->get_widget('entryFRHostDB')->get_text();
 
13488
    $config->{'ProjectorHost'} =
 
13489
      $widgets->{'firstrunxml'}->get_widget('entryFRHostServer')->get_text();
 
13490
    $globals->{'host'}      = $config->{'ProjectorHost'};
 
13491
    $globals->{'mysqlhost'} = $config->{'DBHost'};
 
13492
 
 
13493
    db_select();
 
13494
    write_config(FALSE);
 
13495
 
 
13496
    if (!$globals->{'firstrun'}) {
 
13497
        init_preview();
 
13498
        init_miniview();
 
13499
 
 
13500
        preview_display("reconfig", "", "", "MINI");
 
13501
        update_display("reconfig", "", "");
 
13502
        preview_display("display", "current", "", "MINI");
 
13503
        update_display("display", "current", "");
 
13504
    }
 
13505
}
 
13506
 
 
13507
#***
 
13508
 
 
13509
#****f* lyricue/firstrun_bible
 
13510
# NAME
 
13511
# SYNOPSIS
 
13512
#   firstrun_bible()
 
13513
# FUNCTION
 
13514
#
 
13515
# INPUTS
 
13516
# OUTPUT
 
13517
# SOURCE
 
13518
#
 
13519
sub firstrun_bible {
 
13520
}
 
13521
 
 
13522
#***
 
13523
 
 
13524
#****f* lyricue/online-help
 
13525
# NAME
 
13526
#   online_help
 
13527
# SYNOPSIS
 
13528
#   online_help()
 
13529
# FUNCTION
 
13530
#   Load documentation in browser
 
13531
# SOURCE
 
13532
#
 
13533
sub online_help {
 
13534
    debug("Load Documentation");
 
13535
    my $command = "xdg-open ghelp:lyricue";
 
13536
    system($command);
 
13537
}
 
13538
 
 
13539
#***
 
13540
 
 
13541
#****f* lyricue/start_transaction
 
13542
# NAME
 
13543
#   start_transaction
 
13544
# SYNOPSIS
 
13545
#   start_transaction()
 
13546
# FUNCTION
 
13547
#   Mark the start of a bunch of queries to be run in a single transaction
 
13548
# SOURCE
 
13549
#
 
13550
sub start_transaction {
 
13551
    my $globals->{'old_re'} = $lyricDbh->{RaiseError};
 
13552
    $lyricDbh->{RaiseError} = 1;
 
13553
    $lyricDbh->{AutoCommit} = 0;
 
13554
}
 
13555
 
 
13556
#***
 
13557
 
 
13558
#****f* lyricue/end_transaction
 
13559
# NAME
 
13560
#   end_transaction
 
13561
# SYNOPSIS
 
13562
#   end_transaction()
 
13563
# FUNCTION
 
13564
#   Mark the end of a bunch of queries to be run in a single transaction
 
13565
# SOURCE
 
13566
#
 
13567
sub end_transaction {
 
13568
    $lyricDbh->rollback() if $@;
 
13569
    $lyricDbh->{AutoCommit} = 1;
 
13570
    $lyricDbh->{RaiseError} = $globals->{'old_re'};
 
13571
}
 
13572
 
 
13573
#***
 
13574
 
 
13575
#****f* lyricue/clean_database
 
13576
# NAME
 
13577
#   clean_database
 
13578
# SYNOPSIS
 
13579
#   clean_database()
 
13580
# FUNCTION
 
13581
#   Rescan the image/backgrounds directories
 
13582
#   Cleans up old associations
 
13583
#   Cleans up left-over playlist items
 
13584
# SOURCE
 
13585
#
 
13586
sub clean_database {
 
13587
    debug("Cleaning database");
 
13588
    my $query = "SELECT description,category FROM media WHERE format=\"file\"";
 
13589
    qdebug($query);
 
13590
    my $sth = $mediaDbh->prepare($query)
 
13591
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
13592
    my $rv = $sth->execute
 
13593
      || display_fatal($errorcodes->{'sqlexecute'}, $! . "\nSQL: " . $query);
 
13594
    while ($row = $sth->fetchrow_hashref()) {
 
13595
        my @mystat = stat($row->{'category'});
 
13596
        if (!(@mystat)) {
 
13597
 
 
13598
            # file no longer exists so remove it from db
 
13599
            my $query2 = "DELETE FROM media WHERE format=\"file\" AND category="
 
13600
              . quote($row->{'category'});
 
13601
            qdebug($query2);
 
13602
            my $sth2 = $mediaDbh->prepare($query2)
 
13603
              || display_fatal($errorcodes->{'sqlprepare'},
 
13604
                $! . "\nSQL: " . $query2);
 
13605
            my $rv2 = $sth2->execute
 
13606
              || display_fatal($errorcodes->{'sqlexecute'},
 
13607
                $! . "\nSQL: " . $query2);
 
13608
        }
 
13609
    }
 
13610
 
 
13611
    # Remove leftover playlist item from failed re-orders
 
13612
    $query = "DELETE FROM playlist WHERE playorder=-1";
 
13613
    qdebug($query);
 
13614
    $sth = $lyricDbh->prepare($query)
 
13615
      || display_fatal($errorcodes->{'sqlprepare'}, $! . "\nSQL: " . $query);
 
13616
    $rv = $sth->execute;    # Don't worry if it fails
 
13617
    return FALSE;
 
13618
}
 
13619
 
 
13620
#***
 
13621
sub start_editview {
 
13622
    if (defined ($widgets->{'EditPreview'})) {
 
13623
        stop_editview();
 
13624
    }
 
13625
    $widgets->{'EditPreview'} = Gtk2::Socket->new;
 
13626
    $widgets->{'EditPreview'}->show;
 
13627
    $widgets->{'EditPreview'}->set_size_request(-1, -1);
 
13628
    $widgets->{'add'}->get_widget('frameEditPreview')->show;
 
13629
    $widgets->{'add'}->get_widget('frameEditPreview')->add($widgets->{'EditPreview'});
 
13630
    my $command = sprintf( "%s -r %s -m %d -p %d",
 
13631
                    $globals->{'lyricue_server'} , $globals->{'mysqlhost'}, $widgets->{'EditPreview'}->get_id, $globals->{'editview_port'});
 
13632
    debug($command);
 
13633
    $globals->{'editview_pid'} = fork;
 
13634
    if ($globals->{'editview_pid'} < 0) {
 
13635
        display_fatal(
 
13636
          "Unable to start the lyricue server as a preview window",
 
13637
          $! . "\nSQL: " . $query);
 
13638
    }
 
13639
    if ($globals->{'editview_pid'} == 0) {
 
13640
        exec($command);
 
13641
    }
 
13642
    $widgets->{'EditPreview'}->signal_connect(
 
13643
        'plug-removed' => sub {
 
13644
            debug("Lyricue edit preview died..restarting\n");
 
13645
            $widgets->{'main'}->get_widget('frameEditPreview')
 
13646
               ->remove($widgets->{'preview'});
 
13647
            start_editview();
 
13648
            1;
 
13649
        }
 
13650
    );
 
13651
}
 
13652
 
 
13653
sub stop_editview {
 
13654
    if (defined ($globals->{'editview_pid'})) {
 
13655
        kill 9, $globals->{'editview_pid'};
 
13656
    }
 
13657
    if (defined ($widgets->{'EditPreview'})) {
 
13658
        $widgets->{'EditPreview'}->destroy;
 
13659
        undef $widgets->{'EditPreview'};
 
13660
    }
 
13661
}
 
13662
 
 
13663
sub toggle_blur {
 
13664
    debug("Toggle Blur");
 
13665
    my ($widget) = @_;
 
13666
    if ($widget->get_active()) {
 
13667
        update_display("blur",1);
 
13668
    } else {
 
13669
        update_display("blur",0);
 
13670
    }
 
13671
}
 
13672
 
 
13673
sub change_fade {
 
13674
    debug("Changing fade amount");
 
13675
    my ($widget) = @_;
 
13676
    update_display("fade",$widget->get_value());
 
13677
}
 
13678
 
 
13679
sub start_display {
 
13680
    debug("Start lyricue display");
 
13681
    execute_app("",$globals->{'lyricue_server'});
 
13682
}