Bug 11431: Add additional sound options
authorKyle M Hall <kyle@bywatersolutions.com>
Mon, 22 Dec 2014 10:58:48 +0000 (05:58 -0500)
committerTomas Cohen Arazi <tomascohen@theke.io>
Wed, 4 Nov 2015 15:32:57 +0000 (12:32 -0300)
This patch set replaces and extends Koha's current sound options.
This is implemented be removing the existing sound system, and
re-engineering using a table of selector/sound combinations such that
the highest precedence selector that is found in the DOM will trigger
and audio alert. The existing audio behaviors are implemented as a set
of default audio alerts.

Test Plan:
1) Apply this patch set
2) Run updatedatabase.pl
3) Enable the AudioAlerts system preference
4) Test existing sounds
5) Enter the new alerts editor in the admin section
6) Add a new audo alert with the following selector:
    "body:contains('Check in message')",
   choose any sound alert you wish, make sure it's not one of the 3
   sounds already used! Make this selector precedence 1
4) Browse to the checkins page, you should hear the default sound
5) Attempt to return an invalid barcode, you should hear your custom sound!

Signed-off-by: Nick Clemens <nick@quecheelibrary.org>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
18 files changed:
Koha/AudioAlert.pm [new file with mode: 0644]
Koha/AudioAlerts.pm [new file with mode: 0644]
Koha/Object.pm
Koha/Template/Plugin/Koha.pm
admin/audio_alerts.pl [new file with mode: 0755]
circ/circulation.pl
circ/returns.pl
koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc
koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc
koha-tmpl/intranet-tmpl/prog/en/js/staff-global.js
koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/admin/audio_alerts.tt [new file with mode: 0644]
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_client.pref
koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tt
koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/audio_alerts.tt [new file with mode: 0644]

diff --git a/Koha/AudioAlert.pm b/Koha/AudioAlert.pm
new file mode 100644 (file)
index 0000000..4bedbb9
--- /dev/null
@@ -0,0 +1,79 @@
+package Koha::AudioAlert;
+
+# Copyright ByWater Solutions 2014
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Carp;
+
+use Koha::Database;
+
+use base qw(Koha::Object);
+
+=head1 NAME
+
+Koha::AudioAlert - Koha Borrower Object class
+
+=head1 API
+
+=head2 Class Methods
+
+=head3 store
+
+Override base store to set default precedence
+if there is not one set already.
+
+=cut
+
+sub store {
+    my ($self) = @_;
+
+    $self->precedence( Koha::AudioAlerts->get_next_precedence() ) unless defined $self->precedence();
+
+    return $self->SUPER::store();
+}
+
+=head3 move
+
+$alert->move('up');
+
+Changes the alert's precedence up, down, top, or bottom
+
+=cut
+
+sub move {
+    my ( $self, $where ) = @_;
+
+    return Koha::AudioAlerts->move( { audio_alert => $self, where => $where } );
+}
+
+=head3 type
+
+=cut
+
+sub type {
+    return 'AudioAlert';
+}
+
+=head1 AUTHOR
+
+Kyle M Hall <kyle@bywatersolutions.com>
+
+=cut
+
+1;
diff --git a/Koha/AudioAlerts.pm b/Koha/AudioAlerts.pm
new file mode 100644 (file)
index 0000000..1127297
--- /dev/null
@@ -0,0 +1,157 @@
+package Koha::AudioAlerts;
+
+# Copyright ByWater Solutions 2014
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use Carp;
+
+use Koha::Database;
+
+use Koha::AudioAlert;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::AudioAlert - Koha Borrower Object class
+
+=head1 API
+
+=head2 Class Methods
+
+=head3 search
+
+Overrides default search such that
+the default ordering is by precedence
+
+=cut
+
+sub search {
+    my ( $self, $params, $attributes ) = @_;
+
+    $attributes->{order_by} ||= 'precedence';
+
+    return $self->SUPER::search( $params, $attributes );
+}
+
+=head3 get_next_precedence
+
+Gets the next precedence value for audio alerts
+
+=cut
+
+sub get_next_precedence {
+    my ($self) = @_;
+
+    return $self->get_last_precedence() + 1;
+}
+
+=head3 get_last_precedence
+
+Gets the last precedence value for audio alerts
+
+=cut
+
+sub get_last_precedence {
+    my ($self) = @_;
+
+    return $self->_resultset()->get_column('precedence')->max();
+}
+
+=head3 move
+
+Koha::AudioAlerts->move( { audio_alert => $audio_alert, where => $where } );
+
+Moves the given alert precedence 'up', 'down', 'top' or 'bottom'
+
+=cut
+
+sub move {
+    my ( $self, $params ) = @_;
+
+    my $alert = $params->{audio_alert};
+    my $where = $params->{where};
+
+    return unless ( $alert && $where );
+
+    if ( $where eq 'up' ) {
+        unless ( $alert->precedence() == 1 ) {
+            my ($other) = $self->search( { precedence => $alert->precedence() - 1 } );
+            $other->precedence( $alert->precedence() )->store();
+            $alert->precedence( $alert->precedence() - 1 )->store();
+        }
+    }
+    elsif ( $where eq 'down' ) {
+        unless ( $alert->precedence() == $self->get_last_precedence() ) {
+            my ($other) = $self->search( { precedence => $alert->precedence() + 1 } );
+            $other->precedence( $alert->precedence() )->store();
+            $alert->precedence( $alert->precedence() + 1 )->store();
+        }
+    }
+    elsif ( $where eq 'top' ) {
+        $alert->precedence(0)->store();
+        $self->fix_precedences();
+    }
+    elsif ( $where eq 'bottom' ) {
+        $alert->precedence( $self->get_next_precedence() )->store();
+        $self->fix_precedences();
+    }
+}
+
+=head3 fix_precedences
+
+Koha::AudioAlerts->fix_precedences();
+
+Updates precedence numbers to start with 1
+and to have no gaps
+
+=cut
+
+sub fix_precedences {
+    my ($self) = @_;
+
+    my @alerts = $self->search();
+
+    my $i = 1;
+    map { $_->precedence( $i++ )->store() } @alerts;
+}
+
+=head3 type
+
+=cut
+
+sub type {
+    return 'AudioAlert';
+}
+
+=head3 object_class
+
+=cut
+
+sub object_class {
+    return 'Koha::AudioAlert';
+}
+
+=head1 AUTHOR
+
+Kyle M Hall <kyle@bywatersolutions.com>
+
+=cut
+
+1;
index d8f2b42..93fdbe0 100644 (file)
@@ -255,7 +255,8 @@ sub AUTOLOAD {
     # Using direct setter/getter like $item->barcode() or $item->barcode($barcode);
     if ( grep {/^$method$/} @columns ) {
         if ( @_ ) {
-            return $self->_result()->set_column( $method, @_ );
+            $self->_result()->set_column( $method, @_ );
+            return $self;
         } else {
             my $value = $self->_result()->get_column( $method );
             return $value;
index 86f9e77..be69c44 100644 (file)
@@ -18,6 +18,8 @@ package Koha::Template::Plugin::Koha;
 # along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use Modern::Perl;
+use Encode qw( encode );
+use JSON;
 
 use base qw( Template::Plugin );
 
@@ -47,16 +49,20 @@ sub Preference {
 
 sub Version {
     my $version_string = Koha::version();
-    my ($major,$minor,$maintenance,$development) = split('\.',$version_string);
+    my ( $major, $minor, $maintenance, $development ) = split( '\.', $version_string );
 
     return {
         major       => $major,
         release     => $major . "." . $minor,
         maintenance => $major . "." . $minor . "." . $maintenance,
-        development => ( $development ne '000' )
-                            ? $development
-                            : undef
+        development => ( $development ne '000' ) ? $development : undef,
     };
 }
 
+sub AudioAlerts {
+    my $dbh = C4::Context->dbh;
+    my $audio_alerts = $dbh->selectall_arrayref( 'SELECT * FROM audio_alerts ORDER BY precedence', { Slice => {} } );
+    return encode_json($audio_alerts);
+}
+
 1;
diff --git a/admin/audio_alerts.pl b/admin/audio_alerts.pl
new file mode 100755 (executable)
index 0000000..f62bacd
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+
+# Copyright 2014 ByWater Solutions
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use CGI;
+use C4::Auth;
+use C4::Output;
+use Koha::AudioAlert;
+use Koha::AudioAlerts;
+
+my $cgi = new CGI;
+
+my $selector = $cgi->param('selector');
+my $sound    = $cgi->param('sound');
+my $id       = $cgi->param('id');
+my $action     = $cgi->param('action');
+my $where    = $cgi->param('where');
+my @delete   = $cgi->param('delete');
+
+my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
+    {
+        template_name   => "admin/audio_alerts.tt",
+        query           => $cgi,
+        type            => "intranet",
+        authnotrequired => 0,
+        flagsrequired   => { parameters => 'parameters_remaining_permissions' },
+        debug           => 1,
+    }
+);
+
+if ( $selector && $sound ) {
+    Koha::AudioAlert->new( { selector => $selector, sound => $sound } )->store();
+}
+
+map { Koha::AudioAlerts->find($_)->delete() } @delete;
+
+if ( $id && $action && $where && $action eq 'move' ) {
+    Koha::AudioAlerts->find($id)->move($where);
+}
+
+$template->param( audio_alerts => scalar Koha::AudioAlerts->search() );
+
+output_html_with_http_headers $cgi, $cookie, $template->output;
index bac91d7..c8e7872 100755 (executable)
@@ -601,7 +601,7 @@ $template->param(
     is_child          => ($borrowernumber && $borrower->{'category_type'} eq 'C'),
     $view             => 1,
     batch_allowed     => $batch_allowed,
-    soundon           => C4::Context->preference("SoundOn"),
+    AudioAlerts           => C4::Context->preference("AudioAlerts"),
     fast_cataloging   => $fast_cataloging,
     CircAutoPrintQuickSlip   => C4::Context->preference("CircAutoPrintQuickSlip"),
     activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
index 3948a6e..bb47552 100755 (executable)
@@ -620,7 +620,7 @@ $template->param(
     dropboxdate    => output_pref($dropboxdate),
     forgivemanualholdsexpire => $forgivemanualholdsexpire,
     overduecharges => $overduecharges,
-    soundon        => C4::Context->preference("SoundOn"),
+    AudioAlerts        => C4::Context->preference("AudioAlerts"),
     BlockReturnOfWithdrawnItems => C4::Context->preference("BlockReturnOfWithdrawnItems"),
 );
 
index 281bb54..e38b0b4 100644 (file)
@@ -64,6 +64,7 @@
     <li><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50/SRU servers</a></li>
     <li><a href="/cgi-bin/koha/admin/didyoumean.pl">Did you mean?</a></li>
     <li><a href="/cgi-bin/koha/admin/columns_settings.pl">Columns settings</a></li>
+    <li><a href="/cgi-bin/koha/admin/audio_alerts.pl">Audio alerts</a></li>
 </ul>
 </div>
 </div>
index 08d3c20..e553a86 100644 (file)
@@ -1,14 +1,16 @@
+[% USE Koha %]
+[% USE String %]
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% interface %]/[% theme %]/img/favicon.ico[% END %]" type="image/x-icon" />
+
 <link rel="stylesheet" type="text/css" href="[% interface %]/lib/jquery/jquery-ui.css" />
 <link rel="stylesheet" type="text/css" href="[% interface %]/lib/bootstrap/bootstrap.min.css" />
 <link rel="stylesheet" type="text/css" href="[% interface %]/lib/font-awesome/css/font-awesome.min.css" />
 <link rel="stylesheet" type="text/css" media="print" href="[% themelang %]/css/print.css" />
 [% INCLUDE intranetstylesheet.inc %]
-[% IF ( bidi ) %]
-   <link rel="stylesheet" type="text/css" href="[% themelang %]/css/right-to-left.css" />
-[% END %]
+[% IF ( bidi )            %]<link rel="stylesheet" type="text/css" href="[% themelang %]/css/right-to-left.css" />[% END %]
 [% IF ( IntranetUserCSS ) %]<style type="text/css">[% IntranetUserCSS %]</style>[% END %]
+
 <script type="text/javascript" src="[% interface %]/lib/jquery/jquery.js"></script>
 <script type="text/javascript" src="[% interface %]/lib/jquery/jquery-ui.js"></script>
 <script type="text/javascript" src="[% interface %]/lib/shortcut/shortcut.js"></script>
@@ -23,6 +25,7 @@
 
 <!-- koha core js -->
 <script type="text/javascript" src="[% themelang %]/js/staff-global.js"></script>
+
 [% INCLUDE 'validator-strings.inc' %]
 [% IF ( IntranetUserJS ) %]
     <script type="text/javascript">
@@ -31,6 +34,7 @@
     //]]>
     </script>
 [% END %]
+
 [% IF ( virtualshelves || intranetbookbag ) %]
 <script type="text/javascript">
     //<![CDATA[
         var MSG_NON_RESERVES_SELECTED = _("One or more selected items cannot be reserved.");
     //]]>
     </script>
-<script type="text/javascript" src="[% themelang %]/js/basket.js"></script>
+
+    <script type="text/javascript" src="[% themelang %]/js/basket.js"></script>
 [% END %]
+
 [% IF LocalCoverImages %]
-<script type="text/javascript" src="[% themelang %]/js/localcovers.js"></script>
-<script type="text/javascript">
-//<![CDATA[
-var NO_LOCAL_JACKET = _("No cover image available");
-//]]>
-</script>
+    <script type="text/javascript" src="[% themelang %]/js/localcovers.js"></script>
+    <script type="text/javascript">
+        //<![CDATA[
+            var NO_LOCAL_JACKET = _("No cover image available");
+        //]]>
+    </script>
+[% END %]
+
+[% IF Koha.Preference('AudioAlerts') %]
+    <script type="text/javascript">
+        //<![CDATA[
+            var AUDIO_ALERT_PATH = '[% interface %]/[% theme %]/sound/';
+            var AUDIO_ALERTS = JSON.parse( '[% Koha.AudioAlerts | replace( "'", "\\'" ) %]' );
+        //]]>
+
+        $( document ).ready(function() {
+            if ( AUDIO_ALERTS ) {
+                for ( var k in AUDIO_ALERTS ) {
+                    var alert = AUDIO_ALERTS[k];
+                    if ( $( alert.selector ).length ) {
+                        playSound( alert.sound );
+                        break;
+                    }
+                }
+            }
+        });
+    </script>
 [% END %]
 
 <!-- For keeping the text when navigating the search tabs -->
index d937656..f9103ce 100644 (file)
@@ -65,5 +65,6 @@
         </div>
     [% END %]
 [% END %]
+    <span id="audio-alert"></span>
     </body>
 </html>
index 2636ec8..3552e18 100644 (file)
@@ -120,3 +120,11 @@ function toUC(f) {
 function confirmDelete(message) {
     return (confirm(message) ? true : false);
 }
+
+function playSound( sound ) {
+    // This is way faster than substring
+    if ( ! ( sound.charAt(4) == ':' && sound.charAt(5) == '/' && sound.charAt(6) == '/' ) ) {
+        sound = AUDIO_ALERT_PATH + sound;
+    }
+    document.getElementById("audio-alert").innerHTML = '<audio src="' + sound + '" autoplay="autoplay" autobuffer="autobuffer"></audio>';
+}
index c85aa8e..885654a 100644 (file)
     <dd>Choose which plugins to use to suggest searches to patrons and staff.</dd>
     <dt><a href="/cgi-bin/koha/admin/columns_settings.pl">Configure columns</a></dt>
     <dd>Hide or show columns for tables.</dd>
+    <dt><a href="/cgi-bin/koha/admin/audio_alerts.pl">Audio alerts</a></dt>
+    <dd>Define which events trigger which sounds</dd>
 </dl>
 </div>
 
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/audio_alerts.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/audio_alerts.tt
new file mode 100644 (file)
index 0000000..d3471ce
--- /dev/null
@@ -0,0 +1,131 @@
+[% INCLUDE 'doc-head-open.inc' %]
+<title>Koha &rsaquo; Administration &rsaquo; Audio alerts</title>
+[% INCLUDE 'doc-head-close.inc' %]
+
+<script type="text/javascript">
+$( document ).ready(function() {
+    $.ajax({
+        //This will retrieve the contents of the folder if the folder is configured as 'browsable'
+        url: AUDIO_ALERT_PATH,
+        success: function (data) {
+            $("#fileNames").html('<ul>');
+            //List all png or jpg or gif file names in the page
+            $(data).find('a:contains("ogg")').each(function () {
+                var filename = this.href.split('/').pop();
+                $('#koha-sounds').append($('<option>', { value : filename }).text(filename));
+            });
+        }
+    });
+
+    $('#koha-sounds').on('change', function() {
+        $('#sound').val( this.value );
+    });
+
+    $('#koha-sounds').on('change', function() {
+        $('#sound').val( this.value );
+    });
+
+    $('#play-sound').on('click', function() {
+        playSound( $('#sound').val() );
+        return false;
+    });
+
+    $('#new-alert-form').on('submit', function() {
+        if ( ! $('#selector').val() ) {
+            alert(_("You must enter a selector!"));
+            return false;
+        } else if ( ! $('#sound').val() ) {
+            alert(_("You must choose a sound!"));
+            return false;
+        } else {
+            return true;
+        }
+    });
+
+    $('#delete-alert-form').on('submit', function() {
+        return confirm(_("Are you sure you want to delete the selected audio alerts?"));
+    });
+});
+</script>
+
+</head>
+<body id="admin_audio_alerts" class="admin">
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'patrons-admin-search.inc' %]
+
+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a> &rsaquo; Audio alerts</div>
+
+<div id="doc3" class="yui-t2">
+    <div id="bd">
+        <div id="yui-main">
+            <div class="yui-b">
+                <form id="new-alert-form" action="audio_alerts.pl" method="post">
+                    <fieldset class="form-inline">
+                        <legend>Add new alert</legend>
+
+                        <input id="selector" name="selector" type="text" class="input-large" placeholder="selector" />
+                        <input id="sound" name="sound" type="text" class="input-large" placeholder="sound" />
+
+                        <button id="play-sound" class="btn"><i class="icon-play"></i> Play sound</button>
+
+                        <br/>
+
+                        <select id="koha-sounds">
+                            <option value="">Select built-in sound</option>
+                        </select>
+
+                        <button id="save-alert" type="submit" class="btn"><i class="icon-hdd"></i> Save alert</button>
+                    </fieldset>
+                </form>
+
+                <form id="delete-alert-form" action="audio_alerts.pl" method="post">
+                    <table>
+                        <thead>
+                            <tr>
+                                <th>&nbsp;</th>
+                                <th>Precedence</th>
+                                <th>&nbsp;</th>
+                                <th>Selector</th>
+                                <th>Sound</th>
+                            </tr>
+                        </thead>
+
+                        <tbody>
+                            [% FOREACH a IN audio_alerts %]
+                                <tr>
+                                    <td><input type="checkbox" name="delete" value="[% a.id %]" /></td>
+                                    <td>[% a.precedence %]</td>
+                                    <td style="white-space:nowrap;">
+                                        <a title="Move alert up" href="audio_alerts.pl?action=move&amp;where=up&amp;id=[% a.id %]">
+                                            <img src="[% interface %]/[% theme %]/img/go-up.png" border="0" alt="Go up" />
+                                        </a>
+
+                                        <a title="Move alert to top" href="audio_alerts.pl?action=move&amp;where=top&amp;id=[% a.id %]">
+                                            <img src="[% interface %]/[% theme %]/img/go-top.png" border="0" alt="Go top" />
+                                        </a>
+
+                                        <a title="Move alert to bottom" href="audio_alerts.pl?action=move&amp;where=bottom&amp;id=[% a.id %]">
+                                            <img src="[% interface %]/[% theme %]/img/go-bottom.png" border="0" alt="Go bottom" />
+                                        </a>
+
+                                        <a title="Move alert down" href="audio_alerts.pl?action=move&amp;where=down&amp;id=[% a.id %]">
+                                            <img src="[% interface %]/[% theme %]/img/go-down.png" border="0" alt="Go down" />
+                                        </a>
+                                    </td>
+                                    <td>[% a.selector %]</td>
+                                    <td>[% a.sound %]</td>
+                                </tr>
+                            [% END %]
+                        </tbody>
+                    </table>
+
+                    <p/>
+                    <button id="delete-alerts" type="submit" class="btn"><i class="icon-trash"></i> Delete selected alerts</button>
+                </form>
+            </div>
+        </div>
+    <div class="yui-b">
+[% INCLUDE 'admin-menu.inc' %]
+</div>
+</div>
+[% INCLUDE 'intranet-bottom.inc' %]
index d0d2aca..6a0954d 100644 (file)
@@ -40,12 +40,6 @@ Circulation:
                   desc: latest to earliest
             - due date.
         -
-            - pref: soundon
-              choices: 
-                 yes: "Enable"
-                 no: "Don't enable"
-            - circulation sounds during checkin and checkout in the staff interface.  Not supported by all web browsers yet.
-        -
             - pref: SpecifyDueDate
               choices:
                   yes: Allow
@@ -704,7 +698,6 @@ Circulation:
                   yes: Show
                   no: "Don't show"
             - "the print receipt popup dialog when self checkout is finished"
-
     Course Reserves:
         -
             - pref: UseCourseReserves
index 9dfafd6..992f412 100644 (file)
@@ -134,3 +134,9 @@ Staff Client:
                   yes: Show
                   no: "Don't show"
             - WYSIWYG editor when editing certain HTML system preferences.
+        -
+            - pref: AudioAlerts
+              choices:
+                 yes: "Enable"
+                 no: "Don't enable"
+            - audio alerts for events defined in the audio alerts section of administration.
index 322a082..07ef6ce 100644 (file)
@@ -209,7 +209,7 @@ $(document).ready(function() {
 [% IF ( NEEDSCONFIRMATION ) %]
 <div class="yui-g">
 
-<div id="circ_needsconfirmation" class="dialog alert">
+<div id="circ_needsconfirmation" class="dialog alert audio-alert-action">
 [% IF CAN_user_circulate_force_checkout %]
   <h3>Please confirm checkout</h3>
 [% ELSE %]
@@ -403,12 +403,8 @@ $(document).ready(function() {
 
         [% IF ( IMPOSSIBLE ) %]
 
-[% IF ( soundon ) %]
-<audio src="[% interface %]/[% theme %]/sound/critical.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-[% END %]        
-
 <div class="yui-g">
-<div id="circ_impossible" class="dialog alert">
+<div id="circ_impossible" class="dialog alert audio-alert-warning">
 <!-- RESULT OF ISSUING REQUEST -->
         <ul>
         [% IF ( STATS ) %]
@@ -524,15 +520,12 @@ $(document).ready(function() {
 
 </div></div>
 [% ELSE %]
-[% IF ( soundon ) %]
-<audio src="[% interface %]/[% theme %]/sound/beep.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-[% END %]
-
   [% IF (forceallow) %]
       <div id="overridden_debarment" class="dialog alert">Restriction overridden temporarily</div>
   [% END %]
+[% END %] <!-- /impossible -->
 
-    [% END %] <!-- /impossible -->
+<span class="audio-alert-success"></span>
 
 [% IF ( issued ) %]
 <p>Item checked out</p>
index aa43b75..4fda4e1 100644 (file)
@@ -105,6 +105,7 @@ $(document).ready(function () {
 </script>
 </head>
 <body id="circ_returns" class="circ">
+<span class="audio-alert-success"></span>
 
 [% INCLUDE 'header.inc' %]
 [% INCLUDE 'checkin-search.inc' %]
@@ -199,11 +200,7 @@ $(document).ready(function () {
     [% IF ( waiting ) %]
        <!-- waiting -->
 
-[% IF ( soundon ) %]
-<audio src="[% interface %]/[% theme %]/sound/ending.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-[% END %]
-
-<div id="hold-found1" class="dialog message">
+    <div id="hold-found1" class="dialog message audio-alert-action">
         <h3>Hold found (item is already waiting):  <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
         [% IF ( reservenotes ) %]<h4>Notes: [% reservenotes %]</h4>[% END %]
         <h4>Hold for:</h4>
@@ -251,10 +248,7 @@ $(document).ready(function () {
 
     [% IF ( diffbranch ) %]
                <!-- diffbranch -->
-        [% IF ( soundon ) %]
-        <audio src="[% interface %]/[% theme %]/sound/opening.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-        [% END %]
-        <div id="transfer-needed" class="dialog message">
+        <div id="transfer-needed" class="dialog message audio-alert-action">
                <h3>Hold needing transfer found: <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
                 <h4>Hold for: </h4>
                     <ul>
@@ -298,20 +292,14 @@ $(document).ready(function () {
 
     [% IF ( transfer ) %]
     <!-- transfer: item with no reservation, must be returned according to home library circulation rules -->
-       <div id="return1" class="dialog message">
+       <div id="return1" class="dialog message audio-alert-action">
             <h3>Please return <a href="/cgi-bin/koha/catalogue/detail.pl?type=intra&amp;biblionumber=[% itembiblionumber %]">[% title or "item" |html %]</a> to [% Branches.GetName( returnbranch ) %]<br/>( <a href="#" onclick="Dopop('transfer-slip.pl?transferitem=[% itemnumber %]&amp;branchcode=[% returnbranch %]&amp;op=slip'); return true;">Print slip</a> )</h3>
         </div>
-        [% IF ( soundon ) %]
-        <audio src="[% interface %]/[% theme %]/sound/opening.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-        [% END %]
     [% END %]
 
     [% IF ( needstransfer ) %]
        <!-- needstransfer -->
-        [% IF ( soundon ) %]
-        <audio src="[% interface %]/[% theme %]/sound/opening.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-        [% END %]
-    <div id="item-transfer" class="dialog message"><h3> This item needs to be transferred to [% Branches.GetName( returnbranch ) %]</h3>
+    <div id="item-transfer" class="dialog message audio-alert-action"><h3> This item needs to be transferred to [% Branches.GetName( returnbranch ) %]</h3>
     Transfer now?<br />
     <form method="post" action="returns.pl" name="mainform" id="mainform">
     [% IF itemnumber %]
@@ -337,10 +325,7 @@ $(document).ready(function () {
 
     [% IF ( diffbranch ) %]
        <!-- diffbranch -->
-        [% IF ( soundon ) %]
-        <audio src="[% interface %]/[% theme %]/sound/opening.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-        [% END %]
-        <h3>Item consigned:</h3>
+        <h3 class="audio-alert-action">Item consigned:</h3>
         <table>
         <caption><a href="/cgi-bin/koha/catalogue/detail.pl?type=intra&amp;biblionumber=[% itembiblionumber %]">[% title |html %]</a></caption>
         <tr>
@@ -369,11 +354,7 @@ $(document).ready(function () {
     [% IF ( reserved ) %]
        <!--  reserved  -->
 
-        [% IF ( soundon ) %]
-        <audio src="[% interface %]/[% theme %]/sound/opening.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-        [% END %]
-
-       <div id="hold-found2" class="dialog message">
+    <div id="hold-found2" class="dialog message audio-alert-action">
       <h3>Hold found: <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% itembiblionumber %]">[% title |html %]</a></h3>
         [% IF ( reservenotes ) %]<h4>Notes: [% reservenotes %]</h4>[% END %]
         <h5>Hold for:</h5>
@@ -424,7 +405,7 @@ $(document).ready(function () {
 [% END %]
 
 [% IF ( errmsgloop ) %]
-    <div class="dialog alert">
+    <div class="dialog alert audio-alert-warning">
         <h3>Check in message</h3>
         [% FOREACH errmsgloo IN errmsgloop %]
                     [% IF ( errmsgloo.NotForLoanStatusUpdated ) %]
@@ -483,13 +464,7 @@ $(document).ready(function () {
                     [% END %]
 
             [% END %]
-[% IF ( soundon ) %]
-<audio src="[% interface %]/[% theme %]/sound/critical.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-[% END %]
         [% ELSE %]
-[% IF ( soundon ) %]
-<audio src="[% interface %]/[% theme %]/sound/beep.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
-[% END %]
         [% END %]
     </div>
 
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/audio_alerts.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/help/admin/audio_alerts.tt
new file mode 100644 (file)
index 0000000..eccae8b
--- /dev/null
@@ -0,0 +1,29 @@
+[% INCLUDE 'help-top.inc' %]
+
+<h1>Audio alerts</h1>
+
+<p>This section of Koha lets you specify a given sound to play when a given jQuery selector is matched.</p>
+
+<h2>Adding a new alert</h2>
+
+<p>To add a new alert:</p>
+
+<ul>
+    <li>Locate the "Add new alert" form.</li>
+    <li>Enter a selector in the "selector" input, you can see documentation on jQuery selectors <a href="http://api.jquery.com/category/selectors/">here</a>.
+    <li>Enter a sound to be played, you can either select a built-in Koha sound using the pulldown selector, or you can enter a full URL to a sound file on another server</li>
+    <li>At this point, you can preview your sound by clicking the "Play sound" button</li>
+    <li>Click "Save alert" and your done!</li>
+</ul>
+
+<h2>Sound precedence</h2>
+
+<p>Sounds will be played in order from top to bottom. That is, the first select that finds a match will have its sound played.</p>
+
+<p>To change the precedence of a given alert, use the four arrows to move it up, down, or to the top or bottom of the list.</o>
+
+<h2>Deleting alerts</h2>
+
+<p>To delete one or more alerts, check the checkboxes for those alerts you wish to delete, then click the "Delete selected alerts" button and confirm you want to delete those alerts.
+
+[% INCLUDE 'help-bottom.inc' %]