"Added translation post and screenshots"
bzr-revno: 18
138
blog/openlp-22-released.rst
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
.. title: OpenLP 2.2 Released!
|
||||||
|
.. slug: 2015/10/18/openlp-22-released
|
||||||
|
.. date: 2015-10-18 12:00:00 UTC
|
||||||
|
.. tags:
|
||||||
|
.. category:
|
||||||
|
.. link:
|
||||||
|
.. description:
|
||||||
|
.. type: text
|
||||||
|
.. previewimage: /cover-images/openlp-22-released.jpg
|
||||||
|
|
||||||
|
It's finally here! After almost three years in development, the next major version of OpenLP has arrived!
|
||||||
|
|
||||||
|
A lot of work has gone into making this new version more stable, less buggy and easier to use, resulting almost 300
|
||||||
|
bugfixes and improvements. This version also sees some changes under the hood, in terms of moving to Python 3 and adding
|
||||||
|
unit testing to increase the quality of the codebase.
|
||||||
|
|
||||||
|
New Features
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
But, without further ado, here are the new features you'll find in OpenLP 2.2:
|
||||||
|
|
||||||
|
Songs
|
||||||
|
-----
|
||||||
|
|
||||||
|
* Show active song title in preview and live pane
|
||||||
|
* Allow authors to be tagged by their type (words music etc)
|
||||||
|
* CCLI SongSelect integration
|
||||||
|
* Importers
|
||||||
|
|
||||||
|
* ProPresenter 4
|
||||||
|
* Worship Assistant
|
||||||
|
* PowerPraise
|
||||||
|
* PresentationManager
|
||||||
|
* EasyWorship Service Files (.ews)
|
||||||
|
* WorshipCenter Pro
|
||||||
|
|
||||||
|
* Songbook can be displayed in footer
|
||||||
|
* Duplicate Songs can be identified and removed manually if required.
|
||||||
|
* An improve Formatting Tags user interface
|
||||||
|
|
||||||
|
Bibles
|
||||||
|
------
|
||||||
|
|
||||||
|
* New web bible: Neue evangelistische Übersetzung (German)
|
||||||
|
* Importers
|
||||||
|
|
||||||
|
* Zefania XML format
|
||||||
|
* OSIS importer rewritten
|
||||||
|
|
||||||
|
Presentations
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* Support for presentations created in PDF format
|
||||||
|
* Support for LibreOffice 4 and 5
|
||||||
|
|
||||||
|
Projector Remote Control
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
* Projectors that support the PJLink protocol can be controlled from OpenLP (On/Off/Blank/Source Select)
|
||||||
|
|
||||||
|
Images
|
||||||
|
------
|
||||||
|
|
||||||
|
* Can be placed in groups and added to services as groups.
|
||||||
|
|
||||||
|
Remote
|
||||||
|
------
|
||||||
|
|
||||||
|
* Supports SSL for all requests. Certificates will need to be created outside of OpenLP
|
||||||
|
* Supports Authentication for all update requests
|
||||||
|
* Display thumbnails and notes when available in the Web User Interface
|
||||||
|
|
||||||
|
Custom
|
||||||
|
------
|
||||||
|
|
||||||
|
* Auto load items from saved services
|
||||||
|
* Items can be created from the Service Manager for items like bibles
|
||||||
|
|
||||||
|
Media
|
||||||
|
-----
|
||||||
|
|
||||||
|
* Support for DVD and CD clipselection and playback (requires VLC).
|
||||||
|
|
||||||
|
Services
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Items can be renamed
|
||||||
|
* Custom Items generated from Text items like bibles
|
||||||
|
* Media items can be configured to autoload and remove screen blank when added to live display
|
||||||
|
* Services can be saved without embedding media files. This will limit the portability of the files but reduces the file size (useful when media files are part of the service).
|
||||||
|
|
||||||
|
Internals
|
||||||
|
---------
|
||||||
|
|
||||||
|
* Upgraded the code to Python 3 from Python 2
|
||||||
|
* Refactored and improved the internals to:
|
||||||
|
|
||||||
|
* Improve performance and start faster
|
||||||
|
* Improve reliability of the media functionality
|
||||||
|
* Increase testability and start to introduce a comprehensive test suite
|
||||||
|
* Improve consistency of the settings
|
||||||
|
|
||||||
|
Important Notes
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**OpenLP 2.2 is not backwards compatible with 2.0.5.**
|
||||||
|
|
||||||
|
**Service Files created in 2.2 cannot be opened in 2.0.**
|
||||||
|
|
||||||
|
Once you have upgraded from 2.0.5, version 2.0.5 cannot read the upgraded files. OpenLP 2.2 will make a backup on
|
||||||
|
startup, but it is recommended that you make your own backup too.
|
||||||
|
|
||||||
|
Upgrading from versions of OpenLP before 2.0.5 are not supported. You need to upgrade to 2.0.5 first, and make sure
|
||||||
|
you run OpenLP at least once before continuing to upgrade to 2.2.
|
||||||
|
|
||||||
|
There are some known issues in OpenLP 2.2 that you should know about before upgrading:
|
||||||
|
|
||||||
|
1. Live Backgrounds does not work on Windows and Mac OS X
|
||||||
|
2. Playback of linked audio does not work on Mac OS X
|
||||||
|
|
||||||
|
We plan to fix these issues in OpenLP 2.4. We're moving to a faster release cycle, which means that OpenLP 2.4 should be released in 6 to 12 months from now.
|
||||||
|
|
||||||
|
Thanks
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
As leader of the project, I'd like to say a special thank you to the folks involved in this release. A special thank you to Tomas Groth, Jonathan Springer and Tim Bentley for their help, encouragement and preseverence.
|
||||||
|
|
||||||
|
So he got up and went to his father. But while he was still a long way off, his father saw him and was filled with compassion for him; he ran to his son, threw his arms around him and kissed him.
|
||||||
|
|
||||||
|
Luke 15:20, New International Version
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<div class="text-center"><p><a class="btn btn-success btn-lg" href="/#download"><strong>Download Now</strong></a></p></div>
|
||||||
|
|
||||||
|
[ Image Credit: `Thai Lanterns by Mark Fischer`_ ]
|
||||||
|
|
||||||
|
.. _Thai Lanterns by Mark Fischer: https://www.flickr.com/photos/fischerfotos/7455424224/
|
100
blog/want-openlp-your-language.rst
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
.. title: Want OpenLP in Your Language?
|
||||||
|
.. slug: want-openlp-your-language
|
||||||
|
.. date: 2015-10-03 01:17:00 UTC
|
||||||
|
.. tags:
|
||||||
|
.. category:
|
||||||
|
.. link:
|
||||||
|
.. description:
|
||||||
|
.. type: text
|
||||||
|
.. previewimage: /cover-images/want-openlp-your-language.jpg
|
||||||
|
|
||||||
|
If you'd like to see OpenLP in your language, now's the time! We are about 2 weeks away from the release of 2.2, and
|
||||||
|
now is your opportunity to translate OpenLP's interface into your own language.
|
||||||
|
|
||||||
|
In order for your langauge to be included you need to have completed the `translation of OpenLP 2.2`_ (you'll need to be
|
||||||
|
logged into `Transifex`_ to see this page) **by midnight UTC (GMT) on Saturday the 10th of October 2015**.
|
||||||
|
|
||||||
|
Because we believe strongly in quality over quantity at OpenLP, we will not be including any translations that are
|
||||||
|
incomplete into the final build. **This means that if you want your language to be part of the final release of version
|
||||||
|
2.2, you need to make sure it is 100% done by the end of Saturday the 10th of October**. This deadline also gives you
|
||||||
|
just over a week to complete any outstanding translations.
|
||||||
|
|
||||||
|
Languages Needing Work
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Currently, the following translations are more than 80% complete, but still need some work (ordered from most complete
|
||||||
|
to least complete). My estimate is that none of these should take longer than about 2 hours to complete.
|
||||||
|
|
||||||
|
* Polish
|
||||||
|
* French
|
||||||
|
* Lithuanian
|
||||||
|
* Russian
|
||||||
|
* Portuguese (Brazil)
|
||||||
|
* Bulgarian
|
||||||
|
|
||||||
|
The following translations are between 40% and 80% complete. Unless these are worked on this week, they probably won't
|
||||||
|
make it into the final release of OpenLP.
|
||||||
|
|
||||||
|
* Thai (Thailand)
|
||||||
|
* Tamil (Sri-Lanka)
|
||||||
|
* Greek
|
||||||
|
* Afrikaans
|
||||||
|
* Chinese (China)
|
||||||
|
* Korean
|
||||||
|
|
||||||
|
Lastly, the following translations are less than 40% complete. If any of these translations makes it into the final
|
||||||
|
release, I will be very surprised.
|
||||||
|
|
||||||
|
* Slovenian
|
||||||
|
* Italian
|
||||||
|
* Macedonian
|
||||||
|
* Ukrainian
|
||||||
|
* Norweigian Nyorsk
|
||||||
|
* Papiamento
|
||||||
|
* Turkish
|
||||||
|
* Malayalam
|
||||||
|
* Latvian
|
||||||
|
* Spanish (Colombia)
|
||||||
|
* Arabic
|
||||||
|
* Albanian
|
||||||
|
* Korean (Korea)
|
||||||
|
* Ukranian (Ukraine)
|
||||||
|
* Khmer (Cambodia)
|
||||||
|
* Russian (Russia)
|
||||||
|
* Amharic
|
||||||
|
* English (United States)
|
||||||
|
* Klingon
|
||||||
|
* Arabic (Egypt)
|
||||||
|
* Spanish (Chile)
|
||||||
|
* Vietnamese (Viet Nam)
|
||||||
|
* Vietnamese
|
||||||
|
|
||||||
|
Get started `translating OpenLP 2.2`_ (you'll need to be logged into `Transifex`_ to see this page).
|
||||||
|
|
||||||
|
Testing Out Your Translation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
To test your translation out, do the following:
|
||||||
|
|
||||||
|
1. Make sure you are running version 2.1.6
|
||||||
|
2. Install Qt Linguist
|
||||||
|
3. Windows and OS X users need to `download Qt Linguist`_
|
||||||
|
4. Ubuntu, Fedora, and other Linux and Unix users can install Qt Linguist from their package manager
|
||||||
|
5. Download the language file from Transifex
|
||||||
|
6. Open it in Qt Linguist
|
||||||
|
7. Open the File menu, select "*Release*" and save the resulting release file with only your language code as the file name (see Transifex for your language code)
|
||||||
|
8. Copy the release file to OpenLP's i18n directory
|
||||||
|
9. Windows: ``C:\Program Files\OpenLP\i18n or C:\Program Files (x86)\OpenLP\i18n``
|
||||||
|
10. Mac OS X: ``/Applications/OpenLP.app/Contents/MacOS/i18n/``
|
||||||
|
11. Linux: ``/usr/share/openlp/i18n/``
|
||||||
|
12. \*BSD: ``/usr/local/share/openlp/i18n/``
|
||||||
|
13. (Re)start Openlp and select your language
|
||||||
|
|
||||||
|
[ Image Credit: `Arddangosfa o gelf Zimbabwe yn newby Hall, Ripon`_ ]
|
||||||
|
|
||||||
|
.. _translation of OpenLP 2.2: https://www.transifex.com/openlp/openlp/openlp-22x/
|
||||||
|
.. _Transifex: https://www.transifex.com/
|
||||||
|
.. _translating OpenLP 2.2: https://www.transifex.com/openlp/openlp/openlp-22x/
|
||||||
|
.. _download Qt Linguist: http://code.google.com/p/qtlinguistdownload/downloads/list
|
||||||
|
.. _Arddangosfa o gelf Zimbabwe yn newby Hall, Ripon: https://www.flickr.com/photos/benbore/2800370449/
|
||||||
|
|
6
conf.py
@ -677,7 +677,8 @@ COPY_SOURCES = False
|
|||||||
#<link href="css/custom.css" rel="stylesheet">
|
#<link href="css/custom.css" rel="stylesheet">
|
||||||
#"""
|
#"""
|
||||||
EXTRA_HEAD_DATA = """
|
EXTRA_HEAD_DATA = """
|
||||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
<link href="/assets/css/ekko-lightbox.css" rel="stylesheet">
|
||||||
|
<script src='//www.google.com/recaptcha/api.js'></script>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Google Analytics or whatever else you use. Added to the bottom of <body>
|
# Google Analytics or whatever else you use. Added to the bottom of <body>
|
||||||
@ -691,6 +692,9 @@ EXTRA_HEAD_DATA = """
|
|||||||
#<script type="text/javascript" src="js/template.js"></script>
|
#<script type="text/javascript" src="js/template.js"></script>
|
||||||
#<script type="text/javascript" src="js/custom.js"></script>
|
#<script type="text/javascript" src="js/custom.js"></script>
|
||||||
#"""
|
#"""
|
||||||
|
BODY_END = """
|
||||||
|
<script type="text/javascript" src="/assets/js/ekko-lightbox.js"></script>
|
||||||
|
"""
|
||||||
|
|
||||||
# The possibility to extract metadata from the filename by using a
|
# The possibility to extract metadata from the filename by using a
|
||||||
# regular expression.
|
# regular expression.
|
||||||
|
BIN
files/cover-images/openlp-22-released.jpg
Normal file
After Width: | Height: | Size: 302 KiB |
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 276 KiB |
1
files/files/ftw/do_not_delete.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Don't delete this directory! It's used to store the download.cfg file for the First Time Wizard.
|
BIN
files/screenshots/configuregeneral.png
Normal file
After Width: | Height: | Size: 101 KiB |
BIN
files/screenshots/mainwindow.png
Normal file
After Width: | Height: | Size: 339 KiB |
BIN
files/screenshots/song_edit_verse_in_use.png
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
files/screenshots/songimporterchoices.png
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
files/screenshots/stage_view_song_w_note.png
Normal file
After Width: | Height: | Size: 114 KiB |
@ -318,3 +318,9 @@ article blockquote p:first-child {
|
|||||||
p.indent {
|
p.indent {
|
||||||
margin-left: 3em;
|
margin-left: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.screenshot-gallery {
|
||||||
|
display: block;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 4px solid #efefef;
|
||||||
|
}
|
||||||
|
62
themes/openlp2v2/assets/css/ekko-lightbox.css
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*!
|
||||||
|
* Lightbox for Bootstrap 3 by @ashleydw
|
||||||
|
* https://github.com/ashleydw/lightbox
|
||||||
|
*
|
||||||
|
* License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ekko-lightbox-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ekko-lightbox-nav-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 100;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ekko-lightbox-nav-overlay a {
|
||||||
|
z-index: 100;
|
||||||
|
display: block;
|
||||||
|
width: 49%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 30px;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 2px 2px 4px #000;
|
||||||
|
opacity: 0;
|
||||||
|
filter: dropshadow(color=#000000, offx=2, offy=2);
|
||||||
|
-webkit-transition: opacity 0.5s;
|
||||||
|
-moz-transition: opacity 0.5s;
|
||||||
|
-o-transition: opacity 0.5s;
|
||||||
|
transition: opacity 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ekko-lightbox-nav-overlay a:empty {
|
||||||
|
width: 49%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ekko-lightbox a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ekko-lightbox .glyphicon-chevron-left {
|
||||||
|
left: 0;
|
||||||
|
float: left;
|
||||||
|
padding-left: 15px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ekko-lightbox .glyphicon-chevron-right {
|
||||||
|
right: 0;
|
||||||
|
float: right;
|
||||||
|
padding-right: 15px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ekko-lightbox .modal-footer {
|
||||||
|
text-align: left;
|
||||||
|
}
|
@ -33,4 +33,8 @@ $(function(){
|
|||||||
$("#error-alert").removeClass("hidden");
|
$("#error-alert").removeClass("hidden");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$(document).delegate('*[data-toggle="lightbox"]', 'click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
$(this).ekkoLightbox();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
400
themes/openlp2v2/assets/js/ekko-lightbox.js
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
/*
|
||||||
|
Lightbox for Bootstrap 3 by @ashleydw
|
||||||
|
https://github.com/ashleydw/lightbox
|
||||||
|
|
||||||
|
License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var $, EkkoLightbox;
|
||||||
|
|
||||||
|
$ = jQuery;
|
||||||
|
|
||||||
|
EkkoLightbox = function(element, options) {
|
||||||
|
var content, footer, header,
|
||||||
|
_this = this;
|
||||||
|
this.options = $.extend({
|
||||||
|
title: null,
|
||||||
|
footer: null,
|
||||||
|
remote: null
|
||||||
|
}, $.fn.ekkoLightbox.defaults, options || {});
|
||||||
|
this.$element = $(element);
|
||||||
|
content = '';
|
||||||
|
this.modal_id = this.options.modal_id ? this.options.modal_id : 'ekkoLightbox-' + Math.floor((Math.random() * 1000) + 1);
|
||||||
|
header = '<div class="modal-header"' + (this.options.title || this.options.always_show_close ? '' : ' style="display:none"') + '><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h4 class="modal-title">' + (this.options.title || " ") + '</h4></div>';
|
||||||
|
footer = '<div class="modal-footer"' + (this.options.footer ? '' : ' style="display:none"') + '>' + this.options.footer + '</div>';
|
||||||
|
$(document.body).append('<div id="' + this.modal_id + '" class="ekko-lightbox modal fade" tabindex="-1"><div class="modal-dialog"><div class="modal-content">' + header + '<div class="modal-body"><div class="ekko-lightbox-container"><div></div></div></div>' + footer + '</div></div></div>');
|
||||||
|
this.modal = $('#' + this.modal_id);
|
||||||
|
this.modal_dialog = this.modal.find('.modal-dialog').first();
|
||||||
|
this.modal_content = this.modal.find('.modal-content').first();
|
||||||
|
this.modal_body = this.modal.find('.modal-body').first();
|
||||||
|
this.lightbox_container = this.modal_body.find('.ekko-lightbox-container').first();
|
||||||
|
this.lightbox_body = this.lightbox_container.find('> div:first-child').first();
|
||||||
|
this.showLoading();
|
||||||
|
this.modal_arrows = null;
|
||||||
|
this.border = {
|
||||||
|
top: parseFloat(this.modal_dialog.css('border-top-width')) + parseFloat(this.modal_content.css('border-top-width')) + parseFloat(this.modal_body.css('border-top-width')),
|
||||||
|
right: parseFloat(this.modal_dialog.css('border-right-width')) + parseFloat(this.modal_content.css('border-right-width')) + parseFloat(this.modal_body.css('border-right-width')),
|
||||||
|
bottom: parseFloat(this.modal_dialog.css('border-bottom-width')) + parseFloat(this.modal_content.css('border-bottom-width')) + parseFloat(this.modal_body.css('border-bottom-width')),
|
||||||
|
left: parseFloat(this.modal_dialog.css('border-left-width')) + parseFloat(this.modal_content.css('border-left-width')) + parseFloat(this.modal_body.css('border-left-width'))
|
||||||
|
};
|
||||||
|
this.padding = {
|
||||||
|
top: parseFloat(this.modal_dialog.css('padding-top')) + parseFloat(this.modal_content.css('padding-top')) + parseFloat(this.modal_body.css('padding-top')),
|
||||||
|
right: parseFloat(this.modal_dialog.css('padding-right')) + parseFloat(this.modal_content.css('padding-right')) + parseFloat(this.modal_body.css('padding-right')),
|
||||||
|
bottom: parseFloat(this.modal_dialog.css('padding-bottom')) + parseFloat(this.modal_content.css('padding-bottom')) + parseFloat(this.modal_body.css('padding-bottom')),
|
||||||
|
left: parseFloat(this.modal_dialog.css('padding-left')) + parseFloat(this.modal_content.css('padding-left')) + parseFloat(this.modal_body.css('padding-left'))
|
||||||
|
};
|
||||||
|
this.modal.on('show.bs.modal', this.options.onShow.bind(this)).on('shown.bs.modal', function() {
|
||||||
|
_this.modal_shown();
|
||||||
|
return _this.options.onShown.call(_this);
|
||||||
|
}).on('hide.bs.modal', this.options.onHide.bind(this)).on('hidden.bs.modal', function() {
|
||||||
|
if (_this.gallery) {
|
||||||
|
$(document).off('keydown.ekkoLightbox');
|
||||||
|
}
|
||||||
|
_this.modal.remove();
|
||||||
|
return _this.options.onHidden.call(_this);
|
||||||
|
}).modal('show', options);
|
||||||
|
return this.modal;
|
||||||
|
};
|
||||||
|
|
||||||
|
EkkoLightbox.prototype = {
|
||||||
|
modal_shown: function() {
|
||||||
|
var video_id,
|
||||||
|
_this = this;
|
||||||
|
if (!this.options.remote) {
|
||||||
|
return this.error('No remote target given');
|
||||||
|
} else {
|
||||||
|
this.gallery = this.$element.data('gallery');
|
||||||
|
if (this.gallery) {
|
||||||
|
if (this.options.gallery_parent_selector === 'document.body' || this.options.gallery_parent_selector === '') {
|
||||||
|
this.gallery_items = $(document.body).find('*[data-toggle="lightbox"][data-gallery="' + this.gallery + '"]');
|
||||||
|
} else {
|
||||||
|
this.gallery_items = this.$element.parents(this.options.gallery_parent_selector).first().find('*[data-toggle="lightbox"][data-gallery="' + this.gallery + '"]');
|
||||||
|
}
|
||||||
|
this.gallery_index = this.gallery_items.index(this.$element);
|
||||||
|
$(document).on('keydown.ekkoLightbox', this.navigate.bind(this));
|
||||||
|
if (this.options.directional_arrows && this.gallery_items.length > 1) {
|
||||||
|
this.lightbox_container.append('<div class="ekko-lightbox-nav-overlay"><a href="#" class="' + this.strip_stops(this.options.left_arrow_class) + '"></a><a href="#" class="' + this.strip_stops(this.options.right_arrow_class) + '"></a></div>');
|
||||||
|
this.modal_arrows = this.lightbox_container.find('div.ekko-lightbox-nav-overlay').first();
|
||||||
|
this.lightbox_container.find('a' + this.strip_spaces(this.options.left_arrow_class)).on('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
return _this.navigate_left();
|
||||||
|
});
|
||||||
|
this.lightbox_container.find('a' + this.strip_spaces(this.options.right_arrow_class)).on('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
return _this.navigate_right();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.options.type) {
|
||||||
|
if (this.options.type === 'image') {
|
||||||
|
return this.preloadImage(this.options.remote, true);
|
||||||
|
} else if (this.options.type === 'youtube' && (video_id = this.getYoutubeId(this.options.remote))) {
|
||||||
|
return this.showYoutubeVideo(video_id);
|
||||||
|
} else if (this.options.type === 'vimeo') {
|
||||||
|
return this.showVimeoVideo(this.options.remote);
|
||||||
|
} else if (this.options.type === 'instagram') {
|
||||||
|
return this.showInstagramVideo(this.options.remote);
|
||||||
|
} else if (this.options.type === 'url') {
|
||||||
|
return this.loadRemoteContent(this.options.remote);
|
||||||
|
} else if (this.options.type === 'video') {
|
||||||
|
return this.showVideoIframe(this.options.remote);
|
||||||
|
} else {
|
||||||
|
return this.error("Could not detect remote target type. Force the type using data-type=\"image|youtube|vimeo|instagram|url|video\"");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this.detectRemoteType(this.options.remote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
strip_stops: function(str) {
|
||||||
|
return str.replace(/\./g, '');
|
||||||
|
},
|
||||||
|
strip_spaces: function(str) {
|
||||||
|
return str.replace(/\s/g, '');
|
||||||
|
},
|
||||||
|
isImage: function(str) {
|
||||||
|
return str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
|
||||||
|
},
|
||||||
|
isSwf: function(str) {
|
||||||
|
return str.match(/\.(swf)((\?|#).*)?$/i);
|
||||||
|
},
|
||||||
|
getYoutubeId: function(str) {
|
||||||
|
var match;
|
||||||
|
match = str.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
|
||||||
|
if (match && match[2].length === 11) {
|
||||||
|
return match[2];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getVimeoId: function(str) {
|
||||||
|
if (str.indexOf('vimeo') > 0) {
|
||||||
|
return str;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getInstagramId: function(str) {
|
||||||
|
if (str.indexOf('instagram') > 0) {
|
||||||
|
return str;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
navigate: function(event) {
|
||||||
|
event = event || window.event;
|
||||||
|
if (event.keyCode === 39 || event.keyCode === 37) {
|
||||||
|
if (event.keyCode === 39) {
|
||||||
|
return this.navigate_right();
|
||||||
|
} else if (event.keyCode === 37) {
|
||||||
|
return this.navigate_left();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
navigateTo: function(index) {
|
||||||
|
var next, src;
|
||||||
|
if (index < 0 || index > this.gallery_items.length - 1) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.showLoading();
|
||||||
|
this.gallery_index = index;
|
||||||
|
this.$element = $(this.gallery_items.get(this.gallery_index));
|
||||||
|
this.updateTitleAndFooter();
|
||||||
|
src = this.$element.attr('data-remote') || this.$element.attr('href');
|
||||||
|
this.detectRemoteType(src, this.$element.attr('data-type') || false);
|
||||||
|
if (this.gallery_index + 1 < this.gallery_items.length) {
|
||||||
|
next = $(this.gallery_items.get(this.gallery_index + 1), false);
|
||||||
|
src = next.attr('data-remote') || next.attr('href');
|
||||||
|
if (next.attr('data-type') === 'image' || this.isImage(src)) {
|
||||||
|
return this.preloadImage(src, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
navigate_left: function() {
|
||||||
|
if (this.gallery_items.length === 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.gallery_index === 0) {
|
||||||
|
this.gallery_index = this.gallery_items.length - 1;
|
||||||
|
} else {
|
||||||
|
this.gallery_index--;
|
||||||
|
}
|
||||||
|
this.options.onNavigate.call(this, 'left', this.gallery_index);
|
||||||
|
return this.navigateTo(this.gallery_index);
|
||||||
|
},
|
||||||
|
navigate_right: function() {
|
||||||
|
if (this.gallery_items.length === 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.gallery_index === this.gallery_items.length - 1) {
|
||||||
|
this.gallery_index = 0;
|
||||||
|
} else {
|
||||||
|
this.gallery_index++;
|
||||||
|
}
|
||||||
|
this.options.onNavigate.call(this, 'right', this.gallery_index);
|
||||||
|
return this.navigateTo(this.gallery_index);
|
||||||
|
},
|
||||||
|
detectRemoteType: function(src, type) {
|
||||||
|
var video_id;
|
||||||
|
type = type || false;
|
||||||
|
if (type === 'image' || this.isImage(src)) {
|
||||||
|
this.options.type = 'image';
|
||||||
|
return this.preloadImage(src, true);
|
||||||
|
} else if (type === 'youtube' || (video_id = this.getYoutubeId(src))) {
|
||||||
|
this.options.type = 'youtube';
|
||||||
|
return this.showYoutubeVideo(video_id);
|
||||||
|
} else if (type === 'vimeo' || (video_id = this.getVimeoId(src))) {
|
||||||
|
this.options.type = 'vimeo';
|
||||||
|
return this.showVimeoVideo(video_id);
|
||||||
|
} else if (type === 'instagram' || (video_id = this.getInstagramId(src))) {
|
||||||
|
this.options.type = 'instagram';
|
||||||
|
return this.showInstagramVideo(video_id);
|
||||||
|
} else if (type === 'video') {
|
||||||
|
this.options.type = 'video';
|
||||||
|
return this.showVideoIframe(video_id);
|
||||||
|
} else {
|
||||||
|
this.options.type = 'url';
|
||||||
|
return this.loadRemoteContent(src);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateTitleAndFooter: function() {
|
||||||
|
var caption, footer, header, title;
|
||||||
|
header = this.modal_content.find('.modal-header');
|
||||||
|
footer = this.modal_content.find('.modal-footer');
|
||||||
|
title = this.$element.data('title') || "";
|
||||||
|
caption = this.$element.data('footer') || "";
|
||||||
|
if (title || this.options.always_show_close) {
|
||||||
|
header.css('display', '').find('.modal-title').html(title || " ");
|
||||||
|
} else {
|
||||||
|
header.css('display', 'none');
|
||||||
|
}
|
||||||
|
if (caption) {
|
||||||
|
footer.css('display', '').html(caption);
|
||||||
|
} else {
|
||||||
|
footer.css('display', 'none');
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
showLoading: function() {
|
||||||
|
this.lightbox_body.html('<div class="modal-loading">' + this.options.loadingMessage + '</div>');
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
showYoutubeVideo: function(id) {
|
||||||
|
var height, width;
|
||||||
|
width = this.checkDimensions(this.$element.data('width') || 560);
|
||||||
|
height = width / (560 / 315);
|
||||||
|
return this.showVideoIframe('//www.youtube.com/embed/' + id + '?badge=0&autoplay=1&html5=1', width, height);
|
||||||
|
},
|
||||||
|
showVimeoVideo: function(id) {
|
||||||
|
var height, width;
|
||||||
|
width = this.checkDimensions(this.$element.data('width') || 560);
|
||||||
|
height = width / (500 / 281);
|
||||||
|
return this.showVideoIframe(id + '?autoplay=1', width, height);
|
||||||
|
},
|
||||||
|
showInstagramVideo: function(id) {
|
||||||
|
var height, width;
|
||||||
|
width = this.checkDimensions(this.$element.data('width') || 612);
|
||||||
|
this.resize(width);
|
||||||
|
height = width + 80;
|
||||||
|
this.lightbox_body.html('<iframe width="' + width + '" height="' + height + '" src="' + this.addTrailingSlash(id) + 'embed/" frameborder="0" allowfullscreen></iframe>');
|
||||||
|
this.options.onContentLoaded.call(this);
|
||||||
|
if (this.modal_arrows) {
|
||||||
|
return this.modal_arrows.css('display', 'none');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showVideoIframe: function(url, width, height) {
|
||||||
|
height = height || width;
|
||||||
|
this.resize(width);
|
||||||
|
this.lightbox_body.html('<div class="embed-responsive embed-responsive-16by9"><iframe width="' + width + '" height="' + height + '" src="' + url + '" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>');
|
||||||
|
this.options.onContentLoaded.call(this);
|
||||||
|
if (this.modal_arrows) {
|
||||||
|
this.modal_arrows.css('display', 'none');
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
loadRemoteContent: function(url) {
|
||||||
|
var disableExternalCheck, width,
|
||||||
|
_this = this;
|
||||||
|
width = this.$element.data('width') || 560;
|
||||||
|
this.resize(width);
|
||||||
|
disableExternalCheck = this.$element.data('disableExternalCheck') || false;
|
||||||
|
if (!disableExternalCheck && !this.isExternal(url)) {
|
||||||
|
this.lightbox_body.load(url, $.proxy(function() {
|
||||||
|
return _this.$element.trigger('loaded.bs.modal');
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
this.lightbox_body.html('<iframe width="' + width + '" height="' + width + '" src="' + url + '" frameborder="0" allowfullscreen></iframe>');
|
||||||
|
this.options.onContentLoaded.call(this);
|
||||||
|
}
|
||||||
|
if (this.modal_arrows) {
|
||||||
|
this.modal_arrows.css('display', 'none');
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
isExternal: function(url) {
|
||||||
|
var match;
|
||||||
|
match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
|
||||||
|
if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(":(" + {
|
||||||
|
"http:": 80,
|
||||||
|
"https:": 443
|
||||||
|
}[location.protocol] + ")?$"), "") !== location.host) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
error: function(message) {
|
||||||
|
this.lightbox_body.html(message);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
preloadImage: function(src, onLoadShowImage) {
|
||||||
|
var img,
|
||||||
|
_this = this;
|
||||||
|
img = new Image();
|
||||||
|
if ((onLoadShowImage == null) || onLoadShowImage === true) {
|
||||||
|
img.onload = function() {
|
||||||
|
var image;
|
||||||
|
image = $('<img />');
|
||||||
|
image.attr('src', img.src);
|
||||||
|
image.addClass('img-responsive');
|
||||||
|
_this.lightbox_body.html(image);
|
||||||
|
if (_this.modal_arrows) {
|
||||||
|
_this.modal_arrows.css('display', 'block');
|
||||||
|
}
|
||||||
|
return image.load(function() {
|
||||||
|
_this.resize(img.width);
|
||||||
|
return _this.options.onContentLoaded.call(_this);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
img.onerror = function() {
|
||||||
|
return _this.error('Failed to load image: ' + src);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
img.src = src;
|
||||||
|
return img;
|
||||||
|
},
|
||||||
|
resize: function(width) {
|
||||||
|
var width_total;
|
||||||
|
width_total = width + this.border.left + this.padding.left + this.padding.right + this.border.right;
|
||||||
|
this.modal_dialog.css('width', 'auto').css('max-width', width_total);
|
||||||
|
this.lightbox_container.find('a').css('line-height', function() {
|
||||||
|
return $(this).parent().height() + 'px';
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
checkDimensions: function(width) {
|
||||||
|
var body_width, width_total;
|
||||||
|
width_total = width + this.border.left + this.padding.left + this.padding.right + this.border.right;
|
||||||
|
body_width = document.body.clientWidth;
|
||||||
|
if (width_total > body_width) {
|
||||||
|
width = this.modal_body.width();
|
||||||
|
}
|
||||||
|
return width;
|
||||||
|
},
|
||||||
|
close: function() {
|
||||||
|
return this.modal.modal('hide');
|
||||||
|
},
|
||||||
|
addTrailingSlash: function(url) {
|
||||||
|
if (url.substr(-1) !== '/') {
|
||||||
|
url += '/';
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.ekkoLightbox = function(options) {
|
||||||
|
return this.each(function() {
|
||||||
|
var $this;
|
||||||
|
$this = $(this);
|
||||||
|
options = $.extend({
|
||||||
|
remote: $this.attr('data-remote') || $this.attr('href'),
|
||||||
|
gallery_parent_selector: $this.attr('data-parent'),
|
||||||
|
type: $this.attr('data-type')
|
||||||
|
}, options, $this.data());
|
||||||
|
new EkkoLightbox(this, options);
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.ekkoLightbox.defaults = {
|
||||||
|
gallery_parent_selector: 'document.body',
|
||||||
|
left_arrow_class: '.glyphicon .glyphicon-chevron-left',
|
||||||
|
right_arrow_class: '.glyphicon .glyphicon-chevron-right',
|
||||||
|
directional_arrows: true,
|
||||||
|
type: null,
|
||||||
|
always_show_close: true,
|
||||||
|
loadingMessage: 'Loading...',
|
||||||
|
onShow: function() {},
|
||||||
|
onShown: function() {},
|
||||||
|
onHide: function() {},
|
||||||
|
onHidden: function() {},
|
||||||
|
onNavigate: function() {},
|
||||||
|
onContentLoaded: function() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
@ -1,4 +1,4 @@
|
|||||||
assets/css/all-nocdn.css=bootstrap.css,font-awesome.css,rst.css,code.css,colorbox.css,theme.css,animate.css,animations.css,style.css,custom.css
|
assets/css/all-nocdn.css=bootstrap.css,font-awesome.css,rst.css,code.css,colorbox.css,theme.css,animate.css,animations.css,ekko-lightbox.css,style.css,custom.css
|
||||||
assets/css/all.css=font-awesome.css,rst.css,code.css,colorbox.css,theme.css,animate.css,animations.css,style.css,custom.css
|
assets/css/all.css=font-awesome.css,rst.css,code.css,colorbox.css,theme.css,animate.css,animations.css,ekko-lightbox.css,style.css,custom.css
|
||||||
assets/js/all-nocdn.js=jquery.min.js,bootstrap.min.js,jquery.colorbox-min.js,jquery.appear.js,jquery.backstretch.js,modernizr.js,isotope.js,template.js,custom.js
|
assets/js/all-nocdn.js=jquery.min.js,bootstrap.min.js,jquery.colorbox-min.js,jquery.appear.js,jquery.backstretch.js,modernizr.js,isotope.js,ekko-lightbox.js,template.js,custom.js
|
||||||
assets/js/all.js=jquery.colorbox-min.js,jquery.appear.js,jquery.backstretch.js,modernizr.js,isotope.js,template.js,custom.js
|
assets/js/all.js=jquery.colorbox-min.js,jquery.appear.js,jquery.backstretch.js,modernizr.js,isotope.js,ekko-lightbox.js,template.js,custom.js
|
||||||
|
@ -122,6 +122,27 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="space"></div>
|
||||||
|
<div class="row">
|
||||||
|
<h2 class="text-center"><i class="fa fw fa-desktop"></i> Screenshots</h2>
|
||||||
|
<div class="col-md-offset-2 col-md-8">
|
||||||
|
<div class="space"></div>
|
||||||
|
<div class="row">
|
||||||
|
<a href="/screenshots/mainwindow.png" data-toggle="lightbox" data-gallery="screenshots" data-title="Control OpenLP from the Main Window" class="col-sm-3">
|
||||||
|
<img src="/screenshots/mainwindow.png" class="img-responsive">
|
||||||
|
</a>
|
||||||
|
<a href="/screenshots/songimporterchoices.png" data-toggle="lightbox" data-gallery="screenshots" data-title="Import Songs from Many Formats" class="col-sm-3">
|
||||||
|
<img src="/screenshots/songimporterchoices.png" class="img-responsive">
|
||||||
|
</a>
|
||||||
|
<a href="/screenshots/song_edit_verse_in_use.png" data-toggle="lightbox" data-gallery="screenshots" data-title="Editing a Song" class="col-sm-3">
|
||||||
|
<img src="/screenshots/song_edit_verse_in_use.png" class="img-responsive">
|
||||||
|
</a>
|
||||||
|
<a href="/screenshots/stage_view_song_w_note.png" data-toggle="lightbox" data-gallery="screenshots" data-title="Browser-based Stage View" class="col-sm-3">
|
||||||
|
<img src="/screenshots/stage_view_song_w_note.png" class="img-responsive">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|