Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
berry120 committed Dec 30, 2023
2 parents dd1306e + b683a4e commit d2a83cf
Show file tree
Hide file tree
Showing 31 changed files with 506 additions and 348 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ Quelea/build/*
Quelea/out-mac/*
Quelea/dist/*
Quelea/nbproject/*
.idea/*
Quelea/.idea/*
Quelea/output/*
Quelea/.gradle/*
Quelea/.nb-gradle/*
Quelea/bin/*

Thumbs.db
gs.msi
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ It's also fantastic when someone contributes a new translation, and we gladly ac

It's always fantastic when new code contributors come on board! We generally accept bug fixes, so long as the commit comments are clear, the fixes clearly won't introduce any new issues (or at least have a very low probability of doing so), and the code is well written and clearly documented. In the case where any of these aren't the case, then we won't accept right away, but where possible we'll happily work with you to bring your contribution to the point where we can accept it.

We're usually a little more cagey about accepting pull requests for new features out of the blue - they're great to have, but we have to make sure that they're implemented well, not rushed, and the core team agrees on any UX implications they may have. If you're thinking of a new feature, then talk to us first (feel free to create an issue for it if one doesn't exist already.)
However, please be aware the bar is set far higher for pull requests for new features out of the blue - especially if these haven't been discussed and agreed with the core team in advance. **There's a good chance these could just be closed if we don't agree that the feature(s) being added are a priority.** New features may seem great to have, but we have to make sure that they're implemented well, not rushed, and the core team agrees on any UX implications they may have. If you're thinking of a new feature, then talk to us first (feel free to create an issue for it if one doesn't exist already.) Additional features also present an ongoing maintenance burden to the core contributors, as they'd have to be supported & maintained long after the original PR author may have disappeared.

In short, please **only submit a PR for a new feature if you're prepared for the good possibility that PR is rejected.**

Major refactorings of the project, or a significant part of it, are very unlikely to be accepted unless specifically discussed and agreed in advance. (This is usually something that we'd leave to the core developers though.)

Expand Down
17 changes: 11 additions & 6 deletions Quelea/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ task createQueleaExe64(type: edu.sc.seis.launch4j.tasks.Launch4jLibraryTask) { /
outfile = "Quelea64.exe"
}

task downloadGStreamer {
def f = new File('gs.msi')
if (!f.exists()) {
new URL('https://gstreamer.freedesktop.org/data/pkg/windows/1.22.8/msvc/gstreamer-1.0-msvc-x86_64-1.22.8.msi').withInputStream{ i -> f.withOutputStream{ it << i }}
}
}

task copyToDist {
doLast {
copy {from configurations.runtimeClasspath into project.distdir + "/lib"} //libraries
Expand Down Expand Up @@ -176,7 +183,7 @@ task zipMacPackr(type: Zip) {
runPackr.finalizedBy(zipMacPackr);

task dist(type: GradleBuild) {
tasks = ['labelcheck', 'createQueleaExe64', 'copyToDist', 'runPackr', 'izpack', 'innosetup', 'releaseSummary']
tasks = ['labelcheck', 'downloadGStreamer', 'createQueleaExe64', 'copyToDist', 'runPackr', 'izpack', 'innosetup', 'releaseSummary']
}

dependencies {
Expand All @@ -185,14 +192,12 @@ dependencies {
implementation 'com.googlecode.paradoxdriver:paradoxdriver:1.5.0'
implementation 'com.github.berry120.jopenlyrics:jopenlyrics:2.0'
implementation group: 'org.hsqldb', name: 'hsqldb', version: '2.6.0'
implementation group: 'org.apache.poi', name: 'poi-scratchpad', version: '5.0.0'
implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.0.0'
implementation group: 'org.apache.poi', name: 'poi', version: '5.0.0'
implementation group: 'org.apache.poi', name: 'poi-scratchpad', version: '5.2.5'
implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.2.5'
implementation group: 'org.apache.poi', name: 'poi', version: '5.2.5'
implementation group: 'org.xerial', name: 'sqlite-jdbc', version: '3.36.0.3'
implementation group: 'org.apache.avalon.framework', name: 'avalon-framework-api', version: '4.3.1'
implementation group: 'org.apache.avalon.framework', name: 'avalon-framework-impl', version: '4.3.1'
implementation group: 'org.jcodec', name: 'jcodec', version: '0.2.5'
implementation group: 'org.jcodec', name: 'jcodec-javase', version: '0.2.5'

implementation 'net.java.dev.jna:jna:5.10.0'
implementation 'net.java.dev.jna:jna-platform:5.10.0'
Expand Down
4 changes: 4 additions & 0 deletions Quelea/changelogs/changelog-2024.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ quelea (2024.0) stable
* Allow renaming of image group
* Prevent blacked stage view option
* Regression: VLCARG files will no longer work (afraid this is a necessary casualty of moving to GStreamer)
* Logo display now supports video files
* Unsupported videos now have clear unsupported preview image
* Allow multiple selection in song database
* Critical fix: Using the French language no longer crashes Quelea when opening the options dialog
* Various minor bugfixes
Binary file added Quelea/icons/unsupported vid preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Quelea/icons/vid preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 10 additions & 3 deletions Quelea/languages/fr.lang
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ small.bible.text.options=Options des miniatures (Bible)
small.bible.size.label=Taille de la miniature (Bible)
general.interface.options=Options Général de l'interface
interface.options.options=Options de l'interface
mobile.remote.heading=Contrôle à distance
mobile.remote.heading=Contrôle mobile à distance
schedule.options=Options de plannification du service
small.song.size.label=Taille de la miniature (Chant)
small.bible.position.label=Position de la miniature
Expand Down Expand Up @@ -781,7 +781,7 @@ remote.wrong.content = Un contenu de page incorrect a été trouvé. Réessayer.
remote.information.title = Informations
remote.choose.action = Choisissez une action pour $1
remote.double.press.description = Sélectionnez ce que vous voulez faire si vous appuyez sur deux boutons en même temps lorsque vous naviguez avec l'une des deux options ci-dessus.
remote.control.app.name = Quelea Mobile Remote
remote.control.app.name = Commande à distance de Quelea
remote.no.wifi = Vous n'êtes pas connecté à un wifi. Veuillez définir l'URL manuellement ou vous connecter à un réseau Wi-Fi.
remote.search.tooltip = Ajouter un chant ou un passage biblique
remote.about.translating = A propos de la traduction de l'application
Expand All @@ -800,7 +800,14 @@ translation.text.options=Options de texte de traduction
general.text.options=Options générale de texte
use.default.translation.label=Utiliser la traduction par défaut
translation.name.label=Nom de la traduction
pco.days.previous.setting=Jours precedent à importer
pco.days.previous.setting=Jours précédent à importer
bible.load.error.title=Erreur de chargement de la bible
bible.load.error.question=Impossible de lire la bible - Elle est probablement corrompu ou dans un format invalide
ccli.licence=Licence CCLI
dialog.image.group.title=Renommer le groupe d'images
dialog.image.group.header=Groupe d'images
gstreamer.warning.message=Quelea ne trouve pas GStreamer sur votre système. Sans lui, Quelea ne peut pas lire les vidéos, l'audio, et afficher des chants sur un fond vidéo. Voulez-vous le télécharger maintenant? Vous devrez redémarrer Quelea après avoir installé GStreamer pour que les changements prennent effet.
black.stage.view=Vue scène en noir avec écran principale
gstreamer.warning.title=GStreamer est introuvable
download.gstreamer=Télécharger GStreamer
continue.without.gstreamer=Continuer sans GStreamer
1 change: 1 addition & 0 deletions Quelea/languages/gb.lang
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ cant.save.schedule.text=Sorry, an error occurred and the schedule couldn't be sa
error.removing.song.db=There was an error removing the song from the database.
confirm.remove.text=Confirm remove
confirm.remove.question=Really remove $1 from the database? This action cannot be undone.
confirm.remove.bulk.question=Really remove $1 songs from the database? This action cannot be undone.
quick.edit.text=Quick Edit
library.preview.song.text=Preview song
video.error.unsupported=Sorry, the video file you selected isn't supported.
Expand Down
2 changes: 2 additions & 0 deletions Quelea/quelea64.iss
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Type: filesandordirs; Name: "{app}/winjre"
Type: filesandordirs; Name: "{app}/winjre64"

[Files]
Source: gs.msi; DestDir: {tmp}; Flags: deleteafterinstall;
Source: "build/launch4j/Quelea64.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "dist/Quelea.jar"; DestDir: "{app}"; Flags: ignoreversion
Source: "fopcfg.xml"; DestDir: "{app}"; Flags: ignoreversion
Expand Down Expand Up @@ -89,4 +90,5 @@ Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFil
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; IconFilename: "{app}\icons\logo.ico"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

[Run]
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\gs.msi"" /qb- INSTALLLEVEL=1000"; WorkingDir: {tmp};
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: shellexec postinstall skipifsilent
47 changes: 37 additions & 10 deletions Quelea/src/main/java/org/quelea/data/db/SongManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import javafx.application.Platform;
import org.hibernate.ObjectNotFoundException;
import org.hibernate.Session;
Expand All @@ -42,6 +44,7 @@
/**
* Manage songs persistent operations.
* <p/>
*
* @author Michael
*/
public final class SongManager {
Expand All @@ -66,6 +69,7 @@ private SongManager() {
* Get the singleton instance of this class. Return null if there was an
* error with the database.
* <p/>
*
* @return the singleton instance of this class.
*/
public static synchronized SongManager get() {
Expand All @@ -82,6 +86,7 @@ public static synchronized SongManager get() {
/**
* Get the underlying search index used by this database.
* <p/>
*
* @return the search index.
*/
public SongSearchIndex getIndex() {
Expand All @@ -91,6 +96,7 @@ public SongSearchIndex getIndex() {
/**
* Register a database listener with this database.
* <p/>
*
* @param listener the listener.
*/
public void registerDatabaseListener(DatabaseListener listener) {
Expand All @@ -113,6 +119,7 @@ public synchronized SongDisplayable[] getSongs() {
/**
* Get all the songs in the database.
* <p/>
*
* @return an array of all the songs in the database.
*/
public synchronized SongDisplayable[] getSongs(LoadingPane loadingPane) {
Expand Down Expand Up @@ -190,9 +197,10 @@ public boolean addSong(final Collection<SongDisplayable> song, final boolean fir
/**
* Add a song to the database.
* <p/>
* @param songs the songs to add.
*
* @param songs the songs to add.
* @param fireUpdate true if the update should be fired to listeners when
* adding this song, false otherwise.
* adding this song, false otherwise.
* @return true if the operation succeeded, false otherwise.
*/
public synchronized boolean addSong(final SongDisplayable[] songs, final boolean fireUpdate) {
Expand Down Expand Up @@ -240,6 +248,7 @@ public synchronized boolean addSong(final SongDisplayable[] songs, final boolean
/**
* Update a song in the database.
* <p/>
*
* @param song the song to update.
* @return true if the operation succeeded, false otherwise.
*/
Expand All @@ -250,9 +259,10 @@ public synchronized boolean updateSong(final SongDisplayable song) {
/**
* Update a song in the database.
* <p/>
* @param song the song to update.
*
* @param song the song to update.
* @param addIfNotFound true if the song should be added if it's not found,
* false otherwise.
* false otherwise.
* @return true if the operation succeeded, false otherwise.
*/
public synchronized boolean updateSong(final SongDisplayable song, boolean addIfNotFound) {
Expand Down Expand Up @@ -302,24 +312,41 @@ public synchronized boolean updateSong(final SongDisplayable song, boolean addIf
/**
* Remove a song from the database.
* <p/>
*
* @param song the song to remove.
* @return true if the operation succeeded, false otherwise.
*/
public synchronized boolean removeSong(final SongDisplayable song) {
LOGGER.log(Level.INFO, "Removing song {0}", song.getID());
return removeSongs(List.of(song));
}

/**
* Remove songs from the database.
* <p/>
*
* @param songs the songs to remove.
* @return true if the operation succeeded, false otherwise.
*/
public synchronized boolean removeSongs(final List<SongDisplayable> songs) {
List<Long> ids = songs.stream().map(SongDisplayable::getID).collect(Collectors.toList());
LOGGER.log(Level.INFO, "Removing songs {0}", ids);
cacheSongs.clear();
try {
HibernateUtil.execute((Session session) -> {
Song deletedSong = new SongDao(session).getSongById(song.getID());
session.delete(deletedSong);
for (SongDisplayable song : songs) {
Song deletedSong = new SongDao(session).getSongById(song.getID());
session.delete(deletedSong);
}
});
} catch (IllegalStateException ex) {
LOGGER.log(Level.WARNING, "Couldn't remove song " + song.getID(), ex);
LOGGER.log(Level.WARNING, "Couldn't remove songs " + ids, ex);
return false;
}
index.remove(song);
for (SongDisplayable song : songs) {
index.remove(song);
}
fireUpdate();
LOGGER.log(Level.INFO, "Removed song {0}", song.getID());
LOGGER.log(Level.INFO, "Removed song {0}", ids);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,13 @@ public String getEngKey(String label) {
return label;
}
int pos = 0;
var labArr = labels.keySet().toArray();
for (String s : labels.stringPropertyNames()) {
if (getLabel(s).equalsIgnoreCase(label)) {
return engLabels.get(labels.keySet().toArray()[pos]).toString();
Object foundKey = engLabels.get(labArr[pos]);
if (foundKey != null) {
return foundKey.toString();
}
}
pos++;
}
Expand Down
50 changes: 34 additions & 16 deletions Quelea/src/main/java/org/quelea/services/utils/GStreamerUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,43 @@

import com.sun.jna.Platform;
import com.sun.jna.platform.win32.Kernel32;
import org.freedesktop.gstreamer.PluginFeature;
import org.freedesktop.gstreamer.Registry;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

import static java.lang.System.getenv;

public class GStreamerUtils {

private static final Logger LOGGER = LoggerUtils.getLogger();
public static final String DEFAULT_WINDOWS_PATH = "C:\\gstreamer\\1.0\\msvc_x86_64";

private GStreamerUtils() {
}

/**
* Sometimes the default plugin priorities cause issues on some systems.
* <p>
* This method will reorganise plugin priorities for maximum compatibility.
* It can be overridden by various properties defined in quelea.properties.
*/
public static void setFeaturePriorities() {
if (QueleaProperties.get().getDisableDirectShowForWVC1()) {
try (var feature = Registry.get().lookupFeature("dshowvdec_wvc1")) {
if (feature != null) {
feature.setRank(PluginFeature.Rank.NONE.intValue());
}
}
}
}

/**
* Configures paths to the GStreamer libraries. On Windows queries various
* GStreamer environment variables, and then sets up the PATH environment
Expand All @@ -26,19 +49,21 @@ private GStreamerUtils() {
public static void configurePaths() {
System.setProperty("jna.debug_load", "true");
if (Platform.isWindows()) {
LOGGER.log(Level.INFO, "Detected Windows");
String gstPath = System.getProperty("gstreamer.path", findWindowsLocation());
LOGGER.log(Level.INFO, "gst path is " + gstPath);
if (!gstPath.isEmpty()) {
String systemPath = System.getenv("PATH");
String systemPath = getenv("PATH");
if (systemPath == null || systemPath.trim().isEmpty()) {
Kernel32.INSTANCE.SetEnvironmentVariable("PATH", gstPath);
} else {
Kernel32.INSTANCE.SetEnvironmentVariable("PATH", gstPath
+ File.pathSeparator + systemPath);
Kernel32.INSTANCE.SetEnvironmentVariable("PATH", gstPath + File.pathSeparator + systemPath);
}
}
} else if (Platform.isMac()) {
String gstPath = System.getProperty("gstreamer.path",
"/Library/Frameworks/GStreamer.framework/Libraries/");
LOGGER.log(Level.INFO, "Detected Mac OS");
String gstPath = System.getProperty("gstreamer.path", "/Library/Frameworks/GStreamer.framework/Libraries/");
LOGGER.log(Level.INFO, "gst path is " + gstPath);
if (!gstPath.isEmpty()) {
String jnaPath = System.getProperty("jna.library.path", "").trim();
if (jnaPath.isEmpty()) {
Expand All @@ -47,12 +72,11 @@ public static void configurePaths() {
System.setProperty("jna.library.path", jnaPath + File.pathSeparator + gstPath);
}
}
} else if (System.getenv("SNAP") != null) {
} else if (getenv("SNAP") != null) {
LOGGER.log(Level.INFO, "Detected Snap Linux");
System.setProperty("jna.tmpdir", System.getProperty("java.io.tmpdir"));

String gstPath = new File(System.getenv("SNAP"), System.getProperty("gstreamer.path",
"/usr/lib/x86_64-linux-gnu/")).getAbsolutePath();
String gstPath = new File(getenv("SNAP"), System.getProperty("gstreamer.path", "/usr/lib/x86_64-linux-gnu/")).getAbsolutePath();
LOGGER.log(Level.INFO, "gst path is " + gstPath);

if (!gstPath.isEmpty()) {
Expand All @@ -77,15 +101,9 @@ public static void configurePaths() {
*
* @return location or empty string
*/
static String findWindowsLocation() {
private static String findWindowsLocation() {
if (Platform.is64Bit()) {
return Stream.of("GSTREAMER_1_0_ROOT_MSVC_X86_64",
"GSTREAMER_1_0_ROOT_MINGW_X86_64",
"GSTREAMER_1_0_ROOT_X86_64")
.map(System::getenv)
.filter(Objects::nonNull)
.map(p -> p.endsWith("\\") ? p + "bin\\" : p + "\\bin\\")
.findFirst().orElse("");
return Stream.of(getenv("GSTREAMER_1_0_ROOT_MSVC_X86_64"), getenv("GSTREAMER_1_0_ROOT_MINGW_X86_64"), getenv("GSTREAMER_1_0_ROOT_X86_64"), DEFAULT_WINDOWS_PATH).filter(Objects::nonNull).map(p -> p.endsWith("\\") ? p + "bin\\" : p + "\\bin\\").filter(p -> Files.exists(Path.of(p))).findFirst().orElse("");
} else {
return "";
}
Expand Down
Loading

0 comments on commit d2a83cf

Please sign in to comment.